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]);
```

Reply via email to