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