Hello all, Suppose I want to define a tuple type which may have a variable length, e.g.:
template Tup(ID, Properties...) { static if(Properties.length == 0) alias Tuple!(ID, "id") Tup; else alias Tuple!(ID, "id", Properties) Tup; } Now, it's trivial to include an arbitrary selection of named values in this, e.g. auto t1 = Tup!(size_t, real, "value")(3, 4.5); writeln(t1); writeln(t1.id, " ", t1.value); auto t2 = Tup!(size_t, real, "value", bool, "active")(3, 4.5, true); writeln(t2); writeln(t2.id, " ", t2.value, " ", t2.active); However, suppose now I want to define a container struct which holds an array of tuples of the specified type. Here's what I came up with: struct Container(ID, Properties...) { Tup!(ID, Properties)[] contents; void add(ID i, Properties p) { static if(Properties.length == 0) contents ~= Tup!(ID)(i); else contents ~= Tup!(ID, Properties)(i, p); } } Now, if I make properties empty, this works just fine: auto c1 = Container!(size_t)(); c1.add(3); c1.add(7); c1.add(2); writeln(c1); foreach(t, tup; c1.contents) writeln("[", t, "] ", tup.id); writeln(); ... and likewise if I pass the container a list of value types without value names: auto c2 = Container!(size_t, real, real)(); c2.add(5, 3.2, 5.6); writeln(c2); writeln(); ... but if I try asking the container to store a tuple with _named_ values, e.g. auto c3 = Container!(size_t, real, "value")(); then compilation fails with the following error message: -------------------------------------------------------------------------------- tupcontainer.d(7): Error: tuple Properties is used as a type tupcontainer.d(12): Error: template std.typecons.Tuple!(ulong,"id",real,"value").Tuple.__ctor does not match any function template declaration /usr/local/include/d2/std/typecons.d(406): Error: template std.typecons.Tuple!(ulong,"id",real,"value").Tuple.__ctor cannot deduce template function from argument types !()(ulong,_error_) tupcontainer.d(51): Error: template instance tupcontainer.Container!(ulong,real,"value") error instantiating -------------------------------------------------------------------------------- I'm confused as to why the Container struct cannot take these template parameters when the corresponding parameters work just fine for Tup. Can anyone advise what the problem is and if it's possible to get the Container working as envisioned? Full sample code attached just for clarity. :-) Thanks and best wishes, -- Joe
import std.stdio, std.typecons; struct Container(ID, Properties...) { Tup!(ID, Properties)[] contents; void add(ID i, Properties p) { static if(Properties.length == 0) contents ~= Tup!(ID)(i); else contents ~= Tup!(ID, Properties)(i, p); } } template Tup(ID, Properties...) { static if(Properties.length == 0) alias Tuple!(ID, "id") Tup; else alias Tuple!(ID, "id", Properties) Tup; } void main() { writeln(); auto c1 = Container!(size_t)(); c1.add(3); c1.add(7); c1.add(2); writeln(c1); foreach(t, tup; c1.contents) writeln("[", t, "] ", tup.id); writeln(); auto c2 = Container!(size_t, real, real)(); c2.add(5, 3.2, 5.6); writeln(c2); writeln(); auto t1 = Tup!(size_t, real, "value")(3, 4.5); writeln(t1); writeln(t1.id, " ", t1.value); auto t2 = Tup!(size_t, real, "value", bool, "active")(3, 4.5, true); writeln(t2); writeln(t2.id, " ", t2.value, " ", t2.active); auto c3 = Container!(size_t, real, "value")(); // this falls over }