www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - overloads and parents. __traits confusion

reply "John Colvin" <john.loughran.colvin gmail.com> writes:
can someone talk me through the reasoning behind this:

import std.typetuple;

void foo(T)(T v){}
void foo(){}

version(ThisCompiles)
{
     alias Parent = TypeTuple!(__traits(parent, foo))[0];

     pragma(msg, __traits(getOverloads, Parent, "foo"));
// tuple()
}
else
{
     alias Parent = TypeTuple!(__traits(parent, foo!float))[0];

     pragma(msg, __traits(getOverloads, Parent, "foo"));
/*
/d54/f131.d(8): Error: foo (float v) is not callable using 
argument types () /d54/f131.d(8): Error: (__error).foo cannot be 
resolved
tuple()
*/
}
Aug 11 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Monday, 11 August 2014 at 13:00:27 UTC, John Colvin wrote:
     alias Parent = TypeTuple!(__traits(parent, foo!float))[0];
Say hello to optional parens - you are trying to call foo!float() here and apply result to trait.
Aug 11 2014
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 12 August 2014 at 05:23:53 UTC, Dicebot wrote:
 On Monday, 11 August 2014 at 13:00:27 UTC, John Colvin wrote:
    alias Parent = TypeTuple!(__traits(parent, foo!float))[0];
Say hello to optional parens - you are trying to call foo!float() here and apply result to trait.
I thought so. Ugh. This works though: void foo(float v){} void foo(int a){} alias Parent = TypeTuple!(__traits(parent, foo))[0]; pragma(msg, __traits(getOverloads, Parent, "foo")); so it seems that instantiated function templates in this case are called parenthesis-free, whereas normal functions are passed by name/alias/whatever. All expressions that are used as compile-time args (whether in udas, traits or as template arguments) should require parenthesis to be called. Anything else is madness. A!(foo1().foo2()) //pass result A!(foo1.foo2()) //pass result A!(foo1.foo2) //pass function A!(foo1) //pass function foo(foo1) //pass result
Aug 12 2014
prev sibling parent "anonymous" <anonymous example.com> writes:
On Monday, 11 August 2014 at 13:00:27 UTC, John Colvin wrote:
 can someone talk me through the reasoning behind this:

 import std.typetuple;

 void foo(T)(T v){}
 void foo(){}

 version(ThisCompiles)
 {
     alias Parent = TypeTuple!(__traits(parent, foo))[0];

     pragma(msg, __traits(getOverloads, Parent, "foo"));
 // tuple()
 }
 else
 {
     alias Parent = TypeTuple!(__traits(parent, foo!float))[0];

     pragma(msg, __traits(getOverloads, Parent, "foo"));
 /*
 /d54/f131.d(8): Error: foo (float v) is not callable using 
 argument types () /d54/f131.d(8): Error: (__error).foo cannot 
 be resolved
 tuple()
 */
 }
(I'm not sure if the following is completely correct, but it makes a lot of sense to me at the moment.) For clarity, the verbose version of that template: template foo(T) /* the (eponymous) template */ { void foo(T v) {} /* the function; the eponymous member */ } foo is the template: `foo.stringof` = "foo(T)(T v)". Its parent is the module: `__traits(parent, foo).stringof` = "module test". This is what you use in version(ThisCompiles). No problems. foo!float is an instance of the template. Since the template is eponymous, instantiations resolve to the eponymous member, always. So foo!float is the function: `foo!float.mangleof.demangle` = "pure nothrow nogc safe void test7.foo!(float).foo(float)" Its parent is the template instance, which resolves right back to the function: `__traits(parent, foo!float).mangleof.demangle` = "pure nothrow nogc safe void test7.foo!(float).foo(float)" (just foo!float again) Apparently, you cannot get out of an eponymous template instantiation with __traits(parent, ...). Maybe __traits(parent, ...) of an eponymous template instance should be the parent of the template. The current behaviour seems useless to me. Simple test case without functions (no additional trouble from optional parentheses): struct S(T) {} /* All print "S!int": */ pragma(msg, S!int); pragma(msg, __traits(parent, S!int)); pragma(msg, __traits(parent, __traits(parent, S!int)));
Aug 12 2014