Thread overview
Passing template alias to a function
Aug 06
monkyyy
Aug 07
monkyyy
Aug 07
monkyyy
August 06

This is simplified code that illustrates the issue I've faced:

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:

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) {}
//     ^
August 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:

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:

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) {}
//     ^
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"

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?

alias foo=int;
unittest{
    pragma(msg,__traits(identifier,foo));//Error: argument `int` has no identifier
}
August 07

On Wednesday, 6 August 2025 at 23:58:03 UTC, monkyyy wrote:

>
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:

// 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) {}
August 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:

>
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:

// 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:

#!opend -unittest -main -run main.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);
}
August 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

August 08

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.