overloads and parents. __traits confusion

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Aug 12 02:51:21 PDT 2014


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)));


More information about the Digitalmars-d-learn mailing list