Rebind template(bug?)

Engine Machine via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 21 12:29:26 PDT 2016


On Sunday, 21 August 2016 at 06:28:25 UTC, Jack Applegame wrote:
> On Sunday, 21 August 2016 at 00:06:07 UTC, Engine Machine wrote:
>> On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:
>>> On 08/21/2016 12:11 AM, Engine Machine wrote:
>>>> Is there a way to rebind the arguments of a template?
>>>>
>>>> template foo(X)
>>>> {
>>>>    // X is like A!(a,b,c)
>>>>    Y = Rebind!(X,d,e,f);
>>>>    // Y is like A!(d,e,f);
>>>> }
>>>>
>>>> foo(A!(a,b,c));
>>>>
>>>> ?
>>>
>>> template Rebind(alias instance, newArgs...)
>>> {
>>>     import std.traits: TemplateOf;
>>>     alias tmpl = TemplateOf!instance;
>>>     alias Rebind = tmpl!newArgs;
>>> }
>>
>> This doesn't work because the rebound type is of type tmpl and 
>> not the original
>>
>> e.g.,
>>
>> Rebind!(T!b, a)
>>
>> is tmpl!a not T!a.
>
> You are wrong. tmpl is just alias of template T. So tmpl!a and 
> T!a are the same type.
>
> alias X = T!(int, short, char);
> alias Y = Rebind!(X, short, char, int);
> static assert(is(Y == T!(short, char, int))); // passes

I know you like to play the right or wrong game, but did you ever 
learn that a single example does not prove the truth of something?

How about something more complex?

import std.stdio;
import std.meta, std.traits;  	

class base { }

template Rebind(alias instance, newArgs...)
{
     import std.traits: TemplateOf;
     alias tmpl = TemplateOf!instance;
	static if (newArgs.length > 0)
	    alias Rebind = tmpl!newArgs;
	else
		alias Rebind = base;
}

template EraseLast(A...)
{
	static if (A.length > 0)
		alias EraseLast = Erase!(A[$-1], A);
	else
		alias EraseLast = base;
}



class T(A...) : Rebind!(T!A, EraseLast!A)
{
	int x;
	static if (A.length > 0 && A[0] == "Animal")
	{
		int y;
		static if (A.length > 1 && A[1] == "Dog")
		{
			int z;
			static if (A.length > 2 && A[2] == "Pug")
				int s;
		}

	}
}


pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal", "Dog")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : base));
pragma(msg, is(T!("Animal", "Dog") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog") : base));
pragma(msg, is(T!("Animal") : base));

// all true



void main()
{
         auto t = new T!("Animal", "Dog", "Pug")();
	T!("Animal", "Dog") q = t;
         //T!("Animal", "Dog", "Pug") q = t; works but then q is 
not the super of t
	t.x = 3;
	t.y = 4;
	t.z = 6;
	t.s = 123;

	q.y = 1;
	writeln(t, ", ", typeof(t).stringof);
	writeln(q, ", ", typeof(q).stringof);
	writeln("---");
	writeln(t.x);
	writeln(t.y);
	writeln(t.z);
	writeln(t.s);
	writeln("---");
	writeln(q.x);
	writeln(q.y);
	writeln(q.z);
	writeln("---");
	writeln(t.y);
	writeln("---");
	writeln(&t);
	writeln(&q);

}

Since the pragma's are true, it is obvious that the inheritance 
should work chain works. Yet q is not a reference to t as it 
should be, why is this? If aliases were truly aliases as you 
think(your generic response) then it should work because rebind 
and erase only use aliases.












More information about the Digitalmars-d-learn mailing list