www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing template alias to a function

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
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
parent reply monkyyy <crazymonkyyy gmail.com> writes:
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
parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
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 knows
I 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
parent reply monkyyy <crazymonkyyy gmail.com> writes:
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:
 ```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 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) {} ```
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); } ```
Aug 07
parent reply monkyyy <crazymonkyyy gmail.com> writes:
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
parent Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Thursday, 7 August 2025 at 17:38:41 UTC, monkyyy wrote:
 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
Thanks for your answers. I've decided that this doesn't worth pursuing.
Aug 07