Thread overview | ||||||
---|---|---|---|---|---|---|
|
August 11, 2014 overloads and parents. __traits confusion | ||||
---|---|---|---|---|
| ||||
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() */ } |
August 12, 2014 Re: overloads and parents. __traits confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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.
|
August 12, 2014 Re: overloads and parents. __traits confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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
|
August 12, 2014 Re: overloads and parents. __traits confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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)));
|
Copyright © 1999-2021 by the D Language Foundation