Thread overview | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 20, 2016 Rebind template | ||||
---|---|---|---|---|
| ||||
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)); ? |
August 20, 2016 Re: Rebind template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Saturday, 20 August 2016 at 22:11:40 UTC, 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));
>
> ?
I'd also be happy if I could just remove the last element from A.
template EraseLast(X)
{
// returns A!(a,b) when X = A!(a,b,c)
}
|
August 21, 2016 Re: Rebind template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | 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;
}
|
August 21, 2016 Re: Rebind template | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | 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.
|
August 21, 2016 Re: Rebind template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | 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
|
August 21, 2016 Re: Rebind template(bug?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | 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.
|
August 21, 2016 Re: Rebind template(bug?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
> [...]
The problem of this code has nothing to do with aliases. They work correctly. The problem is variable shadowing. In the following code, Child has two x variables, one of which is only accessible from a Parent reference, the other only from a Child reference.
class Parent
{
int x;
}
class Child: Parent
{
int x; // this shadows Parent.x
int y;
}
void main()
{
Child child = new Child();
Parent parent = child;
child.x = child.y = 3;
parent.x = 2;
assert(child.x == 3);
assert((cast(Child)parent).x == 3);
assert((cast(Parent)child).x == 2);
assert(parent is child); // same object (remember that a class is already a pointer);
assert(&parent != &child); // but there are two different pointers on the stack (pointing to the same object)
}
|
August 21, 2016 Re: Rebind template(bug?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lodovico Giaretta | On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta wrote:
> On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
>> [...]
>
> The problem of this code has nothing to do with aliases. They work correctly. The problem is variable shadowing. In the following code, Child has two x variables, one of which is only accessible from a Parent reference, the other only from a Child reference.
>
> class Parent
> {
> int x;
> }
> class Child: Parent
> {
> int x; // this shadows Parent.x
> int y;
> }
>
> void main()
> {
> Child child = new Child();
> Parent parent = child;
>
> child.x = child.y = 3;
> parent.x = 2;
>
> assert(child.x == 3);
> assert((cast(Child)parent).x == 3);
> assert((cast(Parent)child).x == 2);
>
> assert(parent is child); // same object (remember that a class is already a pointer);
> assert(&parent != &child); // but there are two different pointers on the stack (pointing to the same object)
> }
A patch to your code that makes it work, with the parts not displayed unchanged:
class base
{
int x;
}
class T(A...) : Rebind!(T!A, EraseLast!A)
{
static if(A[$-1] == "Animal")
int y;
else static if (A[$-1] == "Dog")
int z;
else static if (A[$-1] == "Pug")
int s;
}
|
August 21, 2016 Re: Rebind template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Saturday, 20 August 2016 at 22:18:57 UTC, Engine Machine wrote: > On Saturday, 20 August 2016 at 22:11:40 UTC, 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)); >> >> ? > > I'd also be happy if I could just remove the last element from A. > > template EraseLast(X) > { > // returns A!(a,b) when X = A!(a,b,c) > } Check for ApplyLeft and ApplyRight in std.meta, maybe it can help you. http://dlang.org/phobos/std_meta.html#.ApplyLeft http://dlang.org/phobos/std_meta.html#.ApplyRight |
August 21, 2016 Re: Rebind template(bug?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Engine Machine | On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
> 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?
Your demagogy will not help you learn the basics of the D language. And you're wrong again, young arrogant padawan.
|
Copyright © 1999-2021 by the D Language Foundation