variadic template (tsz. variadic templates)
A variadic template használata során egy sablonparaméterből és egy parameter pack-ből álló lista fogad be tetszőleges számú típus- vagy értékparamétert:
template<typename First, typename... Rest>
void myFunction(First first, Rest... rest) {
// első paraméter: first
// maradék paraméterek: rest...
}
#include <iostream>
void print() {
std::cout << "Vége\n";
}
template<typename First, typename... Rest>
void print(First first, Rest... rest) {
std::cout << first << " ";
print(rest...); // rekurzív hívás
}
int main() {
print(1, 2.5, "szöveg", 'x');
}
📌 Ez a példa tetszőleges számú és típusú argumentumot fogad el és sorban kiírja őket. A rekurzió addig bontja le a Rest...
listát, míg ki nem fogy.
Tuple
jellegű példatemplate<typename... Ts>
class MyTuple {};
// példányosítás:
MyTuple<int, double, std::string> t;
Ez csak mutatja, hogy az std::tuple
mögött egy variadic template van. A teljes implementáció template rekurziót is alkalmaz.
A ...
operátor a sablonparaméterlista végén, illetve a használatnál egyaránt fontos. Például:
template<typename... Args>
void logAll(Args... args) {
(std::cout << ... << args) << '\n'; // C++17 fold expression
}
Ez a fold expression egy C++17-es újdonság, mellyel a paramétereket egyetlen kifejezésben ki lehet bontani.
template<typename First, typename... Rest>
void foo(First f, Rest... r) {
// csinálj valamit f-fel
foo(r...); // maradék újrahívása
}
void foo() {
// üres lista esetén végrehajtandó alap eset
}
fold expression
:template<typename... Args>
void foo(Args... args) {
(..., std::cout << args); // C++17: left fold
}
sizeof...
template<typename... Args>
void countArgs(Args... args) {
std::cout << "Argumentumok száma: " << sizeof...(Args) << "\n";
}
Ez kiírja, hogy hány típusargumentumot kapott a sablon.
template<typename T>
void printType() {
std::cout << typeid(T).name() << "\n";
}
template<typename... Ts>
void printAllTypes() {
(printType<Ts>(), ...); // C++17 fold
}
std::tuple
, std::variant
belső implementációmake_shared<T>(...)
)std::is_same<Ts...>
vizsgálat)interface<F, Args...>
jelleggel
Előny | Leírás |
---|---|
✅ Tetszőleges számú típus/érték paramétert kezel | Nem kell külön példányokat írni 1, 2, 3 stb. paraméterre |
✅ Típusbiztonságos | Fordítási időben ellenőrizhető |
✅ Kombinálható constexpr -ral, if constexpr -ral, fold -dal
|
Nagyon hatékony metaprogramozás |
✅ Átláthatóbb modern C++ (C++17+) esetén | Pl. fold expression segítségével |
❌ Nehéz olvasni, ha túl sok réteg van | Főleg rekurzió és sablonhiba esetén |