www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Strange tuple behavior

reply Michael Arntzenius <daekhare gmail.com> writes:
Tuples behave rather oddly if you're not using them as parameters to a
function. A few examples:

struct Test(T, R...) {
    T myval;
    R[0] otherval;
}
void main() {
    Test!(int, char) m;
    writefln(typeid(typeof(m.myval)));
}

The output of this program is "char[0]", not "char" as expected. It
seems that when the tuple has one member, it behaves almost as if it
were that member, at least for purposes of defining types. The
behavior becomes even stranger (and more annoying) when the tuple has
multiple members:

struct Test(T, R...) {
    T myval;
    R[0] otherval;
}
alias Test!(int, char, float) MyTest;

With this code, the dmd compiler gives the following error:

no size for type (char _R_0, float _R_1)
no size for type (char _R_0, float _R_1)
foo.d(23): template instance foo.Test!(int,char,float) error instantiating

The compiler seems to be treating the tuple as a composite type,
"(char _R_0, float _R_1)", which of course has certain problems
associated with it, namely that it has no size, and thus cannot be
made into an array type R[0], instead of taking R[0] to be the char
type, as I would expect.

Another problem which is more understandable, but equally annoying, is
that the compiler won't expand a tuple when it's used as the parameter
to another template outside of a function:

struct Test(T, R...) {
    T myval;
    static if(R.length) Test!(R) inner;
}
alias Test!(int, char) MyTest;

The compiler gives the following error in response to the above:

foo.d(17): no size for type (char _R_0)
no size for type (char _R_0)
foo.d(19): template instance foo.Test!((char _R_0)) error instantiating
foo.d(22): template instance foo.Test!(int,char) error instantiating

In this case, the compiler seems to be passing the template parameter
R as some strange tuple-type instead of expanding it into the
parameters for Test, as would be preferable. If this behavior were
allowed, one could (for example) create a template which generated a
tagged union automatically given a tuple parameter of types to be
contained in the union, by using recursive templates.

I would suggest that tuples should be made to behave more consistently
like arrays, not just inside functions, as the example given for
variadic functions on the Digital Mars website shows, but also outside
functions, so that if R is a tuple, R[0] always refers to the first
member of that tuple, R[1] to the second, etc. I also propose that
tuples be expanded when used as the last parameter to a template.
Nov 12 2006
parent Michael A <daekharel gmail.com> writes:
Whoops! A little correction:

    writefln(typeid(typeof(m.myval)));

should be:

    writefln(typeid(typeof(m.otherval)));
Nov 12 2006