variadic function (tsz. variadic functions)
stdarg.h
)A C-szintű variádikus függvények a stdarg.h
könyvtárral működnek, amelyet C++-ban is használhatunk.
🔹 Példa C-szerű variádikus függvényre:
#include <iostream>
#include <cstdarg> // Variádikus argumentumok kezelése
// Variádikus függvény: összeadja a számokat
int osszeg(int db, ...) {
va_list args; // Argumentum lista
va_start(args, db); // Argumentumok kezdete
int sum = 0;
for (int i = 0; i < db; i++) {
sum += va_arg(args, int); // Következő argumentum lekérése
}
va_end(args); // Argumentum lista lezárása
return sum;
}
int main() {
std::cout << "Osszeg: " << osszeg(3, 1, 2, 3) << std::endl; // 6
std::cout << "Osszeg: " << osszeg(5, 10, 20, 30, 40, 50) << std::endl; // 150
return 0;
}
📌 Hogyan működik?
1. Az első paraméter (db
) megmondja, hány argumentumot várunk.
2. va_list
típusú változót hozunk létre az argumentumok tárolására.
3. va_start(args, db)
beállítja az argumentumlistát.
4. A va_arg(args, int)
paranccsal sorban lekérjük az argumentumokat.
5. A va_end(args)
felszabadítja az argumentumlistát.
❌ Hátrányai:
- Nem típusbiztos (bármilyen típusú adatot átadhatunk, de a fordító nem ellenőrzi).
- Az argumentumok számát manuálisan kell kezelni.
template
)C++-ban típusbiztos és könnyebben kezelhető variádikus függvényeket hozhatunk létre sablonokkal (template).
#include <iostream>
// Alapfüggvény (rekurzió vége)
void kiir() {
std::cout << std::endl;
}
// Variádikus sablonfüggvény
template <typename First, typename... Rest>
void kiir(First elso, Rest... tobbi) {
std::cout << elso << " ";
kiir(tobbi...); // Rekurzív hívás a maradék argumentumokra
}
int main() {
kiir(1, 2.5, "Hello", 'A');
// Kimenet: 1 2.5 Hello A
return 0;
}
kiir()
alapfüggvény egy üres függvény, amely csak egy új sort ír ki.kiir(First elso, Rest... tobbi)
) egy első paramétert (elso
) és egy maradék paramétercsomagot (Rest... tobbi
) vesz fel.✅ Előnyei a sablonos megoldásnak:
- Típusbiztos: a fordító ellenőrzi az argumentumokat.
- Egyszerűbb szintaxis: nem kell manuálisan számolni az argumentumokat.
- Átláthatóbb és hatékonyabb, mint a stdarg.h
-s megoldás.
std::initializer_list
segítségévelHa ugyanolyan típusú változó számú paramétert szeretnénk átadni, az std::initializer_list
egyszerűbb megoldás.
#include <iostream>
#include <initializer_list>
int osszeg(std::initializer_list<int> szamok) {
int sum = 0;
for (int szam : szamok) {
sum += szam;
}
return sum;
}
int main() {
std::cout << osszeg({1, 2, 3, 4, 5}) << std::endl; // 15
}
✅ Miért jó az initializer_list
?
- Nem kell sablonokat használni.
- Könnyen olvasható és rövidebb szintaxis.
- De! Csak azonos típusú argumentumokat kezelhet.
std::tuple
és std::apply
segítségévelA std::tuple
lehetővé teszi, hogy különböző típusú értékeket tároljunk egyetlen objektumban.
A std::apply
segít ezeket függvényparaméterként átadni.
std::tuple
+ std::apply
használatára:#include <iostream>
#include <tuple>
#include <utility>
// Egyszerű függvény három paraméterrel
void mutat(int a, double b, const std::string &c) {
std::cout << "int: " << a << ", double: " << b << ", string: " << c << std::endl;
}
int main() {
auto args = std::make_tuple(42, 3.14, "Hello");
std::apply(mutat, args); // Argumentumokat tuple-ből adja át
return 0;
}
✅ Előnyök:
- A függvényhívás dinamikusan történhet tuple-ből.
- Nincs szükség ...
operátorra vagy sablonrekurzióra.
📌 Variádikus függvények típusai C++-ban:
| Megoldás | Előnyök | Hátrányok | |———-|——–|———-| | C-szintű (stdarg.h
) | Egyszerű, működik C-ben is | Nem típusbiztos, bonyolultabb | | Sablon-alapú (template
) | Típusbiztos, elegáns | Rekurzív megvalósítás bonyolult lehet | | std::initializer_list
| Könnyen olvasható | Csak azonos típusú paraméterekkel működik | | std::tuple
és std::apply
| Rugalmas, dinamikus | Összetettebb szintaxis |
✅ Legjobb választás?
- Ha vegyes típusokat kell kezelni: Variádikus sablonok (template
)
- Ha azonos típusú paraméterekkel dolgozunk: std::initializer_list
- Ha tuple adatokkal dolgozunk: std::apply
C++-ban a modern variádikus függvények típusbiztonságot és nagyobb rugalmasságot kínálnak, mint a régi stdarg.h
megoldás!