digitalmars.D - Strange tuple behavior
- Michael Arntzenius (54/54) Nov 12 2006 Tuples behave rather oddly if you're not using them as parameters to a
- Michael A (4/4) Nov 12 2006 Whoops! A little correction:
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
Whoops! A little correction: writefln(typeid(typeof(m.myval))); should be: writefln(typeid(typeof(m.otherval)));
Nov 12 2006