Und mal wieder variadische Templates...
-
Habe noch einmal etwas nachgedacht.
int... foo()
wäre nat. eine Funktion, die ein Pack zurückgibt. Ich würde so etwas entweder ganz verbieten, oder, wenn wie hier die Ellipse nicht auf ein Pack einwirken kann, dies so interpretieren, dass das Pack aus einem einzelnen Element bestehen soll.
Bei Referenz-/Objektdefinitionen können wir einfach verlangen, dass stehts eine Initialisiererlist angegeben werden muss, aus der dann die Anzahl bestimmt werden kann.
Die Möglichkeit Packs zurückzugeben, ist eigentlich weitgehend redundant. Mir fällt eigentlich nur ein nützlicher Fall ein, um damit auf eine spezielle Syntax zum Deklarieren von anonymen Packs verzichten zu können.
template <typename... T> constexpr T&&... value_pack(T&&... args) { return... std::forward<T>(args)...; // oder ggf. mit einfachem return, falls hier die Syntax kontextabhängig modifiziert wird } template <typename... T> struct identity { using... types = T...; }; template <typename T> struct identity { using type = T; using... types = T; }; // pack aus Werten: value_pack(1,2,3) // pack aus Typen identity<char,int,double>::types
using... a = int, char, long; using... b = float, double; using... c = pair<a, b>...; c == pair<int,float>, pair<char,double> // sonst inkonsistent
ill-formed
int... a = 1, 2, 3; int... b = 4, 5; using... c = matrix<a, b>...; c == matrix<1, 4>, pair<2, 5> // sonst inkonsistent
ill-formed
int... a = 1, 2, 3; int... b = 4, 5; int c = (a + b) *...; c == (1+4) * (2+5) // sonst inkonsistent
ill-formed
int... a = foo<1,2>::pack; int... b = foo<3,4,5>::pack; using... c = matrix<a,b>... ... c == matrix<1,3>, matrix<2,4>
ill-formed (schon unter der ersten Ellipse)
int... a = foo<1,2>::pack; int... b = foo<3,4,5>::pack; using... ab = a, b; // Pseudo-Syntax int... c = identity<ab...>... // Eher 1,3,2,4 int... c = (ab...) ... // Eher 1,3,2,4 int... c = ab... ... // Kaum 1,2,3,4,5
ebenfalls ill-formed
in keinen von deinen Beispielen tritt die Form pack::nested_pack auf.