std.algorithm.countUntil and alias

Paul Backus snarwin at gmail.com
Wed Oct 23 12:46:24 UTC 2024


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


More information about the Digitalmars-d-learn mailing list