Re: Template constraint on alias template parameter.
On Thursday, 6 August 2020 at 18:09:50 UTC, ag0aep6g wrote: [snip] `is(...)` only works on types. You're looking for `__traits(isSame, T, Foo)`. For `is(T!U == Foo!U, U)` to work, the compiler would have to guess U. If the first guess doesn't work, it would have to guess again, and again, and again, until it finds a U that does work. Could take forever. Thanks for the explanation!
Re: Template constraint on alias template parameter.
On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote: The code below compiles, but I want to put an additional constraint on the `test` function is only called with a Foo struct. I tried things like is(T == Foo) and is(T : Foo), but those don't work. However, something like is(T!int : Foo!int) works, but is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, U) doesn't work? struct Foo(T) { T x; } void test(alias T)() if (__traits(isTemplate, T)) { import std.stdio: writeln; writeln("there"); } void main() { test!Foo(); } `is(...)` only works on types. You're looking for `__traits(isSame, T, Foo)`. For `is(T!U == Foo!U, U)` to work, the compiler would have to guess U. If the first guess doesn't work, it would have to guess again, and again, and again, until it finds a U that does work. Could take forever.
Re: Template constraint on alias template parameter.
On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote: [snip] It seems as if the T is properly Foo(T) and can only be instantiated with actual types. Something like below works and might work for me. template test(alias T) if (__traits(isTemplate, T)) { void test(U)(U x) if (is(T!U : Foo!U)) { import std.stdio: writeln; writeln("there"); } }
Template constraint on alias template parameter.
The code below compiles, but I want to put an additional constraint on the `test` function is only called with a Foo struct. I tried things like is(T == Foo) and is(T : Foo), but those don't work. However, something like is(T!int : Foo!int) works, but is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, U) doesn't work? struct Foo(T) { T x; } void test(alias T)() if (__traits(isTemplate, T)) { import std.stdio: writeln; writeln("there"); } void main() { test!Foo(); }
Re: Alias template parameter to a private function
On Thursday, 29 June 2017 at 20:21:13 UTC, Ali Çehreli wrote: A workaround is to use a lambda: filter!(a => isValid(a))(array) Thanks! Nice trick, this is definitely going into my company's codebase :-) Such limitations are pretty annoying. There were a number of similar issues in recent dmd releases. Please file a bug if it's not already there: Thanks, will do!
Re: Alias template parameter to a private function
On 06/24/2017 02:04 AM, Sebastien Alaiwan wrote: > private: > > void privateFunction1() > { > auto array = [0, 1, 2, 3, 4, 5]; > auto result = filter!isValid(array); // error: 'isValid' is private > } > bool isValid(int i) > { > return i % 2 == 0; > } A workaround is to use a lambda: filter!(a => isValid(a))(array) Such limitations are pretty annoying. There were a number of similar issues in recent dmd releases. Please file a bug if it's not already there: https://issues.dlang.org/ Ali
Re: Alias template parameter to a private function
up please!
Alias template parameter to a private function
Hi, I'm trying to call std.algorithm.iteration.filter with a private function as a predicate. Here's a reduced example code: // yo.d import std.algorithm; void moduleEntryPoint() { privateFunction1(); privateFunction2(); } private: void privateFunction1() { auto array = [0, 1, 2, 3, 4, 5]; auto result = filter!isValid(array); // error: 'isValid' is private } void privateFunction2() { auto array = [0, 1, 2, 3, 4, 5]; auto result = filter!isValid(array); // error: 'isValid' is private } bool isValid(int i) { return i % 2 == 0; } Here's the compiler output: /usr/include/dmd/phobos/std/algorithm/iteration.d(1132): Error: function yo.isValid is not accessible from module iteration yo.d(14): Error: template instance std.algorithm.iteration.filter!(isValid).filter!(int[]) error instantiating This seems like the compiler, when instanciating the calls to 'filter', is resolving 'isValid' from std.algorithm.iteration scope (however, this isn't actually the case, see below). I was expecting this identifier to be resolved from yo.d, where we have access to the private functions. Surprisingly, the following works: void privateFunction2() { static bool isValid(int i) { return i % 2 == 0; } auto array = [0, 1, 2, 3, 4, 5]; auto result = filter!isValid(array); // error: 'isValid' is private } This makes the instanciation of 'filter' "see" 'isValid', however, now, the other privateFunctions can't use it. Am I missing something here? Thanks!
Re: Factory using an alias template parameter to set a member of the new tool ?
On Thursday, 9 February 2017 at 15:00:21 UTC, angel wrote: On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote: On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote: I'm looking for a better way to do this, if possible: Or actually, maybe this will suite your case better: ``` template namedTool(T, alias Variable) { enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ T.stringof ~ ";" ~ Variable ~ ".name = \"" ~ Variable ~ "\";"; } void main() { mixin(namedTool!(Tool, "grep")); assert(grep.name == "grep"); } ``` Thanks for trying. I know that it doesn't make much sense but it would have been a cool sugar for the tool class. Mixins are not good for me because of completion in the IDE.
Re: Factory using an alias template parameter to set a member of the new tool ?
On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote: On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote: I'm looking for a better way to do this, if possible: ``` class Tool { string name; } T namedTool(alias Variable, T)() { T result = new T; result.name = Variable.stringof; return result; } void main() { Tool grep; grep = namedTool!(grep,Tool); assert(grep.name == "grep"); } ``` Ideally this would work like this: ``` Tool grep = namedTool!Tool; assert(grep.name == "grep"); ``` Possible ? Sorry, but this does not make much sense to me ... You expect "namedTool!Tool" to know that the name of the Tool must be set to "grep". The expression evaluation proceeds from right to left, so at the time of analyzing "namedTool!Tool", the compiler knows nothing about "grep". On the other hand, if you supplied the "grep" variable, the compiler could infer its type, like this: ``` ... auto namedTool(alias Variable)() { alias T = typeof(Variable); T result = new T; result.name = Variable.stringof; return result; } void main() { Tool grep; grep = namedTool!(grep); assert(grep.name == "grep"); } ``` Or actually, maybe this will suite your case better: ``` template namedTool(T, alias Variable) { enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ T.stringof ~ ";" ~ Variable ~ ".name = \"" ~ Variable ~ "\";"; } void main() { mixin(namedTool!(Tool, "grep")); assert(grep.name == "grep"); } ```
Re: Factory using an alias template parameter to set a member of the new tool ?
On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote: I'm looking for a better way to do this, if possible: ``` class Tool { string name; } T namedTool(alias Variable, T)() { T result = new T; result.name = Variable.stringof; return result; } void main() { Tool grep; grep = namedTool!(grep,Tool); assert(grep.name == "grep"); } ``` Ideally this would work like this: ``` Tool grep = namedTool!Tool; assert(grep.name == "grep"); ``` Possible ? Sorry, but this does not make much sense to me ... You expect "namedTool!Tool" to know that the name of the Tool must be set to "grep". The expression evaluation proceeds from right to left, so at the time of analyzing "namedTool!Tool", the compiler knows nothing about "grep". On the other hand, if you supplied the "grep" variable, the compiler could infer its type, like this: ``` ... auto namedTool(alias Variable)() { alias T = typeof(Variable); T result = new T; result.name = Variable.stringof; return result; } void main() { Tool grep; grep = namedTool!(grep); assert(grep.name == "grep"); } ```
Factory using an alias template parameter to set a member of the new tool ?
I'm looking for a better way to do this, if possible: ``` class Tool { string name; } T namedTool(alias Variable, T)() { T result = new T; result.name = Variable.stringof; return result; } void main() { Tool grep; grep = namedTool!(grep,Tool); assert(grep.name == "grep"); } ``` Ideally this would work like this: ``` Tool grep = namedTool!Tool; assert(grep.name == "grep"); ``` Possible ?
Re: alias template parameter
On Friday, 21 June 2013 at 14:08:43 UTC, Sergei Nosov wrote: If I have a function auto apply(alias fun, T...)(T args) { return fun(args); } And then I have int y = 2; apply!(x => y)(1); How in the world does this work? Is the context address known at compile-time? No, but because lambdas are always unique, there will always be a dedicated template instance for every time you do this. The compiler will then hard-wire that instance to make it able to access the context pointer. By the way, you can also pass local variables by alias, in which case the same will happen. I guess it does so by passing the offset of the variable in the current stack frame (unless it's inlined and optimized, of course), but I don't know the details. I guess it's up to the compiler.
Re: alias template parameter
On Friday, 21 June 2013 at 14:08:43 UTC, Sergei Nosov wrote: Hi! I've been thinking about how alias template parameters work and I'm really confused =) It makes perfect sense for literals, names, etc. But what I can't get is how does it work for delegates. If I have a function auto apply(alias fun, T...)(T args) { return fun(args); } And then I have int y = 2; apply!(x => y)(1); How in the world does this work? Is the context address known at compile-time? y is allocated on the heap and the pointer is implicitly passed to the apply, or is a field of a struct if you use map!(x => y) instead.
alias template parameter
Hi! I've been thinking about how alias template parameters work and I'm really confused =) It makes perfect sense for literals, names, etc. But what I can't get is how does it work for delegates. If I have a function auto apply(alias fun, T...)(T args) { return fun(args); } And then I have int y = 2; apply!(x => y)(1); How in the world does this work? Is the context address known at compile-time?