On Wednesday, 23 October 2024 at 12:32:09 UTC, Anton Pastukhov
wrote:
I'm struggling with this code. Why `countUntil` won't work with
aliases?
```
import std.traits : EnumMembers;
import std.algorithm : countUntil;
enum Test: string {
One = "one",
Two = "two",
Three = "three"
}
struct MyStruct {
Test test = Test.Three;
}
void main() {
auto myStruct = MyStruct();
// this works as expected
auto idx = countUntil!(e => e ==
myStruct.test)([EnumMembers!Test]);
// this triggers error: app.d(22): Error: none of the
overloads of template `std.algorithm.searching.countUntil` are
callable using argument types `!((e) => e == myAlias)(Test[])`
alias myAlias = MyStruct.test;
auto idx2 = countUntil!(e => e ==
myAlias)([EnumMembers!Test]);
}
```
The problem is that there's a compilation error inside the body
of your lambda, but it doesn't get displayed, because it happens
inside a `__traits(compiles)` check (inside `countUntil`).
Attempting to call the lambda on its own, without using
`countUntil`, reveals the error:
```d
alias myAlias = MyStruct.test;
alias myLambda = e => e == myAlias;
myLambda(Test.One);
// Error: accessing non-static variable `test` requires an
instance of `MyStruct`
```
There are two possible solutions to this. One is to make
`MyStruct.test` a `static` variable:
```d
// Solution #1
struct MyStruct {
static Test test = Test.Three;
}
```
The other is to use an instance of `MyTest` instead of an `alias`:
```d
// Solution #2
MyStruct myInstance;
auto idx2 = countUntil!(e => e ==
myInstance.test)([EnumMembers!Test]);
```