ต่อไปนี้นำมาจากการพูดคุย"Variadic Templates are Funadic"โดย Andrei Alexandrescu ใน GoingNative 2012 ฉันสามารถแนะนำได้เพื่อเป็นการแนะนำที่ดีเกี่ยวกับเทมเพลตแบบต่างๆ
มีสองสิ่งที่หนึ่งสามารถทำได้กับแพ็คตัวแปร สามารถนำไปใช้sizeof...(vs)
เพื่อรับจำนวนองค์ประกอบและขยายได้
กฎการขยายตัว
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)
การขยายตัวดำเนินไปสู่ภายนอก เมื่อขยายสองรายการในขั้นตอนการล็อกรายการเหล่านั้นจะต้องมีขนาดเท่ากัน
ตัวอย่างเพิ่มเติม:
gun(A<Ts...>::hun(vs)...);
ขยายทั้งหมดTs
ในรายการแม่แบบข้อโต้แย้งของA
แล้วฟังก์ชั่นได้รับการขยายตัวที่มีทั้งหมดhun
vs
gun(A<Ts...>::hun(vs...));
ขยายทั้งหมดTs
ในรายการอาร์กิวเมนต์แม่แบบA
และทุกเป็นข้อโต้แย้งฟังก์ชั่นสำหรับvs
hun
gun(A<Ts>::hun(vs)...);
ขยายฟังก์ชันhun
ด้วยTs
และvs
ในขั้นตอนการล็อก
บันทึก:
Ts
ไม่ใช่ประเภทและvs
ไม่ใช่ค่า! เป็นนามแฝงสำหรับรายการประเภท / ค่า ทั้งสองรายการอาจว่างเปล่า ทั้งสองเชื่อฟังเฉพาะการกระทำที่เฉพาะเจาะจง ดังนั้นสิ่งต่อไปนี้เป็นไปไม่ได้:
typedef Ts MyList;
Ts var;
auto copy = vs;
ตำแหน่งการขยายตัว
อาร์กิวเมนต์ของฟังก์ชัน
template <typename... Ts>
void fun(Ts... vs)
รายการตัวเริ่มต้น
any a[] = { vs... };
ตัวระบุฐาน
template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { };
รายการเริ่มต้นสมาชิก
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}
รายการอาร์กิวเมนต์ชั่วคราว
std::map<Ts...> m;
จะคอมไพล์ก็ต่อเมื่อมีข้อโต้แย้งที่เป็นไปได้
บันทึกรายการ
template <class... Ts> void fun(Ts... vs) {
auto g = [&vs...] { return gun(vs...); }
g();
}
รายการคุณสมบัติ
struct [[ Ts... ]] IAmFromTheFuture {};
มันอยู่ในข้อกำหนด แต่ยังไม่มีแอตทริบิวต์ที่สามารถแสดงเป็นประเภทได้
...
จะมาก่อนตัวระบุที่ถูกนำมาใช้ เมื่อใช้แพ็คอย่างใดอย่างหนึ่งหรือทั้งสองประเภท...
มาหลังจากรูปแบบนิพจน์เพื่อขยาย