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:
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:
// Solution #1
struct MyStruct {
static Test test = Test.Three;
}
The other is to use an instance of MyTest
instead of an alias
:
// Solution #2
MyStruct myInstance;
auto idx2 = countUntil!(e => e == myInstance.test)([EnumMembers!Test]);