www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - TemplateOf behavior

reply Alex <sascha.orlov gmail.com> writes:
//code starts

import std.traits;

void main()
{
	static assert(__traits(isSame, TemplateOf!(T!arr), T));
}

size_t[] arr;

struct T(alias S)
{
	mixin Contents!() contents;

	this(Args)(ref Args args)
	{
		contents.__ctor(42);
	}
}

static assert(__traits(isSame, TemplateOf!(T!arr), T));

mixin template Contents()
{
	int dummy;
	this(int dummy)
	{
		//static assert(__traits(isSame, TemplateOf!(T!arr), T));
	}
}

//code ends

Given the code above, why the static assert inside the mixing 
template constructor yields false, while the others yield true?
Jan 06 2018
parent reply ag0aep6g <anonymous example.com> writes:
On Saturday, 6 January 2018 at 19:58:10 UTC, Alex wrote:
 Given the code above, why the static assert inside the mixing 
 template constructor yields false, while the others yield true?
Let's resolve the mixin and write out the `T` template in the verbose form. It looks like this then: ---- template T(alias S) { struct T { this(int dummy) { static assert(__traits(isSame, TemplateOf!(T!arr), T)); } } } ---- Now it's a bit more obvious why the assert fails. At the location of the assert, `T` refers to the struct, not the template. To refer to the template, you can prepend a dot, which means that the lookup is done at the module level instead of searching upwards from the local level [1]. Like so: ---- static assert(__traits(isSame, TemplateOf!(.T!arr), .T)); ---- You don't actually need the dot with `T!arr`. The compiler is apparently smart enough to figure out that you mean the template in that case. But it doesn't hurt, either. [1] https://dlang.org/spec/module.html#module_scope_operators
Jan 06 2018
parent Alex <sascha.orlov gmail.com> writes:
On Saturday, 6 January 2018 at 22:25:48 UTC, ag0aep6g wrote:
 On Saturday, 6 January 2018 at 19:58:10 UTC, Alex wrote:
 ----
 template T(alias S)
 {
     struct T
     {
         this(int dummy)
         {
             static assert(__traits(isSame, TemplateOf!(T!arr), 
 T));
         }
     }
 }
 ----

 Now it's a bit more obvious why the assert fails. At the 
 location of the assert, `T` refers to the struct, not the 
 template. To refer to the template, you can prepend a dot, 
 which means that the lookup is done at the module level instead 
 of searching upwards from the local level [1]. Like so:

 ----
 static assert(__traits(isSame, TemplateOf!(.T!arr), .T));
 ----

 You don't actually need the dot with `T!arr`. The compiler is 
 apparently smart enough to figure out that you mean the 
 template in that case. But it doesn't hurt, either.


 [1] https://dlang.org/spec/module.html#module_scope_operators
Ah... thanks! I chose the other way round, and compare typeof(this) directly now. My false reasoning was, that template parameters are merged to the type before analyzing the types itself.
Jan 06 2018