Shouldn't __traits return Tuples?

Max Samukha samukha at voliacable.com.removethis
Tue Mar 31 01:55:22 PDT 2009


On Mon, 30 Mar 2009 22:04:57 +0200, Trass3r <mrmocool at gmx.de> wrote:

>Max Samukha schrieb:
>> It's possible to statically unroll the foreach's with a template
>> generating a tuple of consequtive integers (not tested):
>> 
>> template Sequence(size_t count, size_t index = 0)
>> {
>>    static if (index < count)
>>       alias Tuple!(index, Sequence!(count, index + 1)) Sequence;  
>>    ...
>> }
>> 
>> enum members = __traits (allMembers, Class);
>> foreach (i; Sequence!(members.length))
>> {
>>      enum funcs = __traits (getVirtualFunctions, Class, members[i]);
>>      foreach (j; Sequence!(funcs.length))
>>      {
>>          // do stuff
>>      }
>> }
>
>Well this is interesting. That code yields:
>variable main.main._funcs_field_0 cannot be declared to be a function.
>
>
>class Class
>{
>	int foo(int i)
>	{
>	return 1;
>	}
>}
>[...]
>
>auto funcs = __traits(getVirtualFunctions, Class, members[i])(1);
>
>yields
>Error: function expected before (), not tuple(foo) of type (int(int i))
>
>So it is a tuple although the docs tell us it's an array?
>

Yeah, __traits returns expressions of various types depending on the
Id. In case of getVirtualFunctions, it's a tuple expression. You may
want to look through traits.c in dmd sources to see what's going on.

>
>Strangely this doesn't work either:
>
>enum members = __traits (allMembers, Class);
>foreach (i; Sequence!(members.length))
>{
>	
>      foreach (j; __traits(getVirtualFunctions, Class, members[i]))
>      {
>		writefln(typeid(typeof(j)));
>          // do stuff
>      }
>}
>
>Though it correctly gets foo() (leaving out typeof above yields 
>"function main.Class.foo is used as a type") it doesn't compile when 
>adding typeof:
>
>"variable main.main.i voids have no value"

__traits is buggy. You could try to do what you want like this:

template isFunction(C, string member)
{
    enum isFunction = is(typeof(mixin("C." ~ member)) == function);
}

void main()
{
    //SpinLock lock;

    enum members = __traits(allMembers, Class);
    foreach (i; Sequence!(members.length))
    {
        static if (isFunction!(Class, members[i]))
        {
            foreach (j; __traits(getVirtualFunctions, Class,
members[i]))
                writefln(members[i], ": ", typeid(typeof(j)));
        }
    }
} 




More information about the Digitalmars-d mailing list