Thread overview
UDAs on templates
Oct 16, 2013
John Colvin
Oct 16, 2013
Dicebot
Oct 16, 2013
Dicebot
Oct 16, 2013
Max Samukha
Oct 16, 2013
Max Samukha
Oct 16, 2013
Max Samukha
Oct 16, 2013
Dicebot
Oct 16, 2013
Max Samukha
Oct 16, 2013
Jacob Carlborg
October 16, 2013
It seems that __traits(getAttributes, T) returns an empty tuple for any template (or template function) T, no matter what UDAs T has been given.

Am I doing something wrong?

@(1) void foo(T)(){}

pragma(msg, __traits(getAttributes, foo)); // tuple()
pragma(msg, __traits(getAttributes, foo!int)); // tuple(1)
October 16, 2013
On Wednesday, 16 October 2013 at 12:26:34 UTC, John Colvin wrote:
> It seems that __traits(getAttributes, T) returns an empty tuple for any template (or template function) T, no matter what UDAs T has been given.
>
> Am I doing something wrong?
>
> @(1) void foo(T)(){}
>
> pragma(msg, __traits(getAttributes, foo)); // tuple()
> pragma(msg, __traits(getAttributes, foo!int)); // tuple(1)

I think this gets re-written like this:

template foo(T)
{
    @(1) void foo() {}
}

..which does explain the observed behavior. As a workaround you can define some default guard value of T and assert inside foo() call if it is actually ever used.
October 16, 2013
(quick experiments show that one can't attached UDA to template symbol itself by any means - weird limitation, don't know the rationale behind this)
October 16, 2013
On Wednesday, 16 October 2013 at 12:37:23 UTC, Dicebot wrote:
> (quick experiments show that one can't attached UDA to template symbol itself by any means - weird limitation, don't know the rationale behind this)

It is understandable why the attribute is transferred to the instantiation of the function template, though I'd rather have the same set of attributes on both the template and its instantiations in this case. There is no reason why attributes cannot be applied to templates themselves. I think that's a bug.
October 16, 2013
On Wednesday, 16 October 2013 at 13:12:39 UTC, Max Samukha wrote:
> I'd rather have the same set of attributes on both the template and its instantiations

Impossible, ignore
October 16, 2013
On Wednesday, 16 October 2013 at 13:14:31 UTC, Max Samukha wrote:
> On Wednesday, 16 October 2013 at 13:12:39 UTC, Max Samukha wrote:
>> I'd rather have the same set of attributes on both the template and its instantiations
>
> Impossible, ignore

@(1)
template Foo(T : int) {}

@(2)
template Foo(T : short) {}

__traits(getAttributes, Foo) == ?

The current semantics seems quite reasonable.
October 16, 2013
On Wednesday, 16 October 2013 at 13:24:59 UTC, Max Samukha wrote:
> @(1)
> template Foo(T : int) {}
>
> @(2)
> template Foo(T : short) {}
>
> __traits(getAttributes, Foo) == ?
>
> The current semantics seems quite reasonable.

@(1)
void foo(int) {}

@(2)
void foo(double) {}

pragma(msg, __traits(getAttributes, foo));

void main() {}

// Compilation output:
//
// tuple(1)
October 16, 2013
On Wednesday, 16 October 2013 at 13:38:44 UTC, Dicebot wrote:
> On Wednesday, 16 October 2013 at 13:24:59 UTC, Max Samukha wrote:
>> @(1)
>> template Foo(T : int) {}
>>
>> @(2)
>> template Foo(T : short) {}
>>
>> __traits(getAttributes, Foo) == ?
>>
>> The current semantics seems quite reasonable.
>
> @(1)
> void foo(int) {}
>
> @(2)
> void foo(double) {}
>
> pragma(msg, __traits(getAttributes, foo));
>
> void main() {}
>
> // Compilation output:
> //
> // tuple(1)

That sucks. Then, getAttributes (and other traits dealing with overload sets) should return an empty set, a union or accept a pattern to match against the members of the overload set.
October 16, 2013
On 2013-10-16 16:05, Max Samukha wrote:

> That sucks. Then, getAttributes (and other traits dealing with overload
> sets) should return an empty set, a union or accept a pattern to match
> against the members of the overload set.

Currenrly one need to call __traits(getOverloads) and then iterate of the result and call __traits(getAttributes) on each item.

-- 
/Jacob Carlborg