Das Folgende stammt aus dem Vortrag "Variadic Templates are Funadic" von Andrei Alexandrescu auf der GoingNative 2012. Ich kann es für eine gute Einführung in Variadic Templates empfehlen.
Es gibt zwei Dinge, die man mit einem variadic Pack machen kann. Es ist möglich sizeof...(vs)
, die Anzahl der Elemente zu ermitteln und zu erweitern.
Erweiterungsregeln
Use Expansion
Ts... T1, ..., Tn
Ts&&... T1&&, ..., Tn&&
x<Ts,Y>::z... x<T1,Y>::z, ..., x<Tn,Y>::z
x<Ts&,Us>... x<T1&,U1>, ..., x<Tn&,Un>
func(5,vs)... func(5,v1), ..., func(5,vn)
Die Expansion erfolgt nach innen nach außen. Wenn Sie zwei Listen im Sperrschritt erweitern, müssen sie dieselbe Größe haben.
Mehr Beispiele:
gun(A<Ts...>::hun(vs)...);
Erweitert alle Ts
in der Vorlagenargumentliste von A
und dann wird die Funktion hun
mit allen erweitert vs
.
gun(A<Ts...>::hun(vs...));
Erweitert alle Ts
in der Vorlagenargumentliste von A
und alle vs
als Funktionsargumente für hun
.
gun(A<Ts>::hun(vs)...);
Erweitert die Funktion hun
mit Ts
und vs
im Sperrschritt.
Hinweis:
Ts
ist kein Typ und vs
kein Wert! Sie sind Aliase für eine Liste von Typen / Werten. Jede Liste ist möglicherweise leer. Beide gehorchen nur bestimmten Handlungen. Folgendes ist also nicht möglich:
typedef Ts MyList; // error!
Ts var; // error!
auto copy = vs; // error!
Erweiterungsorte
Funktionsargumente
template <typename... Ts>
void fun(Ts... vs)
Initialisierungslisten
any a[] = { vs... };
Basisspezifizierer
template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { /**/ };
Mitgliederinitialisierungslisten
// Inside struct D
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}
Tempate Argumentlisten
std::map<Ts...> m;
Wird nur kompiliert, wenn eine mögliche Übereinstimmung für die Argumente vorliegt.
Erfassungslisten
template <class... Ts> void fun(Ts... vs) {
auto g = [&vs...] { return gun(vs...); }
g();
}
Attributlisten
struct [[ Ts... ]] IAmFromTheFuture {};
Es ist in der Spezifikation enthalten, aber es gibt noch kein Attribut, das als Typ ausgedrückt werden kann.
...
kommt das vor der Einführung des Bezeichners. Wenn Sie eine oder beide Arten von Paketen verwenden, wird...
das Ausdrucksmuster nach dem Ausdruck erweitert.