digitalmars.D.learn - Passing template alias to a function
- Andrey Zherikov (31/31) Aug 06 This is simplified code that illustrates the issue I've faced:
- monkyyy (40/71) Aug 06 ```d
- Andrey Zherikov (12/28) Aug 07 I don't want to change function parameter to `A!...` because
- monkyyy (28/59) Aug 07 I believe your being silly but:
- monkyyy (4/4) Aug 07 On Thursday, 7 August 2025 at 17:33:07 UTC, monkyyy wrote:
- Andrey Zherikov (3/8) Aug 07 Thanks for your answers. I've decided that this doesn't worth
This is simplified code that illustrates the issue I've faced: ```d struct A(T) {} alias B(T) = A!T; void f(T)(B!T b) {} f(B!string.init); // Error: template `f` is not callable using argument types `!()(A!string)` //f(B!string.init); // ^ // Candidate is: `f(T)(B!T b)` //void f(T)(B!T b) {} // ^ ``` I know that I can do `alias B = A` in this specific example, but in the actual code, I'm trying to do `alias B(T) = A!(H!T)` which leads to the same error: ```d struct A(T) {} struct H(T) {} alias B(T) = A!(H!T); void f(T)(B!T b) {} f(B!string.init); // Error: template `f` is not callable using argument types `!()(A!(H!string))` //f(B!string.init); // ^ // Candidate is: `f(T)(B!T b)` //void f(T)(B!T b) {} // ^ ```
Aug 06
On Wednesday, 6 August 2025 at 22:41:28 UTC, Andrey Zherikov wrote:This is simplified code that illustrates the issue I've faced: ```d struct A(T) {} alias B(T) = A!T; void f(T)(B!T b) {} f(B!string.init); // Error: template `f` is not callable using argument types `!()(A!string)` //f(B!string.init); // ^ // Candidate is: `f(T)(B!T b)` //void f(T)(B!T b) {} // ^ ``` I know that I can do `alias B = A` in this specific example, but in the actual code, I'm trying to do `alias B(T) = A!(H!T)` which leads to the same error: ```d struct A(T) {} struct H(T) {} alias B(T) = A!(H!T); void f(T)(B!T b) {} f(B!string.init); // Error: template `f` is not callable using argument types `!()(A!(H!string))` //f(B!string.init); // ^ // Candidate is: `f(T)(B!T b)` //void f(T)(B!T b) {} // ^ ``````d struct A(T) {} struct H(T) {} alias B(T) = A!(H!T); void f(T)(A!(H!T) b) {} void g(T)(A!T b) {} void h(B_)(B_ b)if(is(B_==A!(H!T),T)){} unittest{ f(B!string.init); g(B!int.init); h(B!bool.init); } ``` I dont think you should actually try to pull patterns out of `h`, and just go with a `void i(T...)(T args)` if you have something complex to match but without a usecase, who knows --- I think your mistaken about aliased types existing, Idk what the spec says but these seem awfully "eager" ```d alias C(T,int i)=A!(H!T); void j(T)(T b){ pragma(msg,typeof(b).stringof); } unittest{ j(C!(float,10).init);//A!(H!float) pragma(msg,typeof(C!(float,10).init).stringof);//A!(H!float) } ``` As far as I know there is no way to recover the 'i' so does `C!(float,10)` even exist? ```d alias foo=int; unittest{ pragma(msg,__traits(identifier,foo));//Error: argument `int` has no identifier } ```
Aug 06
On Wednesday, 6 August 2025 at 23:58:03 UTC, monkyyy wrote:```d struct A(T) {} struct H(T) {} alias B(T) = A!(H!T); void f(T)(A!(H!T) b) {} void g(T)(A!T b) {} void h(B_)(B_ b)if(is(B_==A!(H!T),T)){} unittest{ f(B!string.init); g(B!int.init); h(B!bool.init); } ``` I dont think you should actually try to pull patterns out of `h`, and just go with a `void i(T...)(T args)` if you have something complex to match but without a usecase, who knowsI don't want to change function parameter to `A!...` because `A!...` is implementation details of `B`: ```d // module a public struct A(T) {} // module b private struct H(T) {} public alias B(T) = A!(H!T); // module main void f(T)(B!T b) {} ```
Aug 07
On Thursday, 7 August 2025 at 16:58:34 UTC, Andrey Zherikov wrote:On Wednesday, 6 August 2025 at 23:58:03 UTC, monkyyy wrote:I believe your being silly but: ```d --- a.d public struct A(T) {} --- b.d import a; private struct H(T) {} public alias B(T) = A!(H!T); public template enforceB(T){ static assert(is(T==A!(H!S),S)); enum enforceB=true; } public template getBargs(T){ enum _=is(T==A!(H!S),S); alias getBargs=S; } --- main.d import b; void f(B_)(B_ b)if(enforceB!B_){ pragma(msg,getBargs!B_.stringof); } unittest{ f(B!string.init); f(B!int.init); } ``````d struct A(T) {} struct H(T) {} alias B(T) = A!(H!T); void f(T)(A!(H!T) b) {} void g(T)(A!T b) {} void h(B_)(B_ b)if(is(B_==A!(H!T),T)){} unittest{ f(B!string.init); g(B!int.init); h(B!bool.init); } ``` I dont think you should actually try to pull patterns out of `h`, and just go with a `void i(T...)(T args)` if you have something complex to match but without a usecase, who knowsI don't want to change function parameter to `A!...` because `A!...` is implementation details of `B`: ```d // module a public struct A(T) {} // module b private struct H(T) {} public alias B(T) = A!(H!T); // module main void f(T)(B!T b) {} ```
Aug 07
On Thursday, 7 August 2025 at 17:33:07 UTC, monkyyy wrote:Note I believe `getBargs` will break if H ever doesnt contain a T so despite your trying to hide implementation details your exposing them all the same
Aug 07
On Thursday, 7 August 2025 at 17:38:41 UTC, monkyyy wrote:On Thursday, 7 August 2025 at 17:33:07 UTC, monkyyy wrote:Thanks for your answers. I've decided that this doesn't worth pursuing.Note I believe `getBargs` will break if H ever doesnt contain a T so despite your trying to hide implementation details your exposing them all the same
Aug 07