C++ के Variadic Templates
In this page:
template <typename... Args>
void function_name(Args... args) {
// sizeof...(args) is the number of arguments
}
Variadic Templates क्या हैं?
Variadic templates arbitrary, potentially अलग types के variable संख्या में arguments accept करते हैं, आपको पुराने C-style variable arguments (जैसे printf का ...) का एक type-safe, compile-time-checked alternative देते हुए।
उदाहरण: What are Variadic Templates?
// Include std::cout and std::cin
#include <iostream>
// Declare a template so this works with any suitable type
template <typename... Args>
void printAll(Args... args) {
(std::cout << ... << args) << std::endl;
}
// Program execution starts in main()
int main() {
printAll(1, 2.5, "text");
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Parameter Packs
Ellipsis symbol (...) एक parameter pack नाम की चीज़ declare करता है, जो किसी भी संख्या में template type parameters या function arguments के लिए खड़ा हो सकता है — zero, एक, या कई — पूरी तरह इस पर determined कि template actually कैसे इस्तेमाल होता है।
उदाहरण: Parameter Packs
// Include std::cout and std::cin
#include <iostream>
// Declare a template so this works with any suitable type
template <typename... Args>
int countArgs(Args... args) {
// Send sizeof...(args) back to the caller
return sizeof...(args);
}
// Program execution starts in main()
int main() {
// Print to the console with cout
std::cout << countArgs(1, 2, 3, 4) << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Recursive Pack Expansion
एक parameter pack के contents process करने के लिए, आप आमतौर पर इसे recursively unpack करते हैं: function पहला argument handle करता है, फिर pack के बाकी के साथ खुद को दोबारा call करता है, हर recursive call में एक argument peel off करते हुए जब तक कोई न बचे।
उदाहरण: Recursive Pack Expansion
// Include std::cout and std::cin
#include <iostream>
void printAll() {}
// Declare a template so this works with any suitable type
template <typename T, typename... Rest>
void printAll(T first, Rest... rest) {
// Print to the console with cout
std::cout << first << " ";
printAll(rest...);
}
// Program execution starts in main()
int main() {
printAll(1, 2, 3);
// Print to the console with cout
std::cout << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Base Cases Define करना
Recursive variadic templates को recursion actually रोकने के लिए एक base-case overload चाहिए — आमतौर पर function का एक version जो zero arguments लेता है — जिसे compiler parameter pack पूरी तरह consumed होने के बाद select करता है।
उदाहरण: Defining Base Cases
#include <iostream>
void printAll() {
std::cout << std::endl; // base case: stops the recursion
}
template <typename T, typename... Rest>
void printAll(T first, Rest... rest) {
std::cout << first << " ";
printAll(rest...);
}
int main() {
printAll(1, 2, 3);
return 0;
}
Login to try C/C++/Java/PHP code in the editor
Variadic Struct Nesting
Parameter packs को struct definitions के अंदर भी expand किया जा सकता है, जो exactly वह technique है जो standard library std::tuple जैसी variable-length structures implement करने के लिए internally इस्तेमाल करती है।
उदाहरण: Variadic Struct Nesting
// Include std::cout and std::cin
#include <iostream>
// Declare a template so this works with any suitable type
template <typename... Types>
// Define a structure type named Tuple
struct Tuple {};
// Declare a template so this works with any suitable type
template <typename First, typename... Rest>
struct Tuple<First, Rest...> {
First value;
Tuple<Rest...> rest;
};
// Program execution starts in main()
int main() {
Tuple<int, double> t;
t.value = 5;
t.rest.value = 3.14;
// Print to the console with cout
std::cout << t.value << " " << t.rest.value << std::endl;
// Return 0 to signal that the program finished successfully
return 0;
}
Login to try C/C++/Java/PHP code in the editor
- recursive pack expansion के लिए base case भूल जाना, जो compile होने में fail होता है।
- एक pack declare या expand करते समय
...को गलत जगह रखना। sizeof...(args)कोsizeof(args)से confuse करना।
- Templates आपको ऐसा code लिखने देते हैं जो अलग types के साथ काम करे।
- Function templates और class templates ज़रूरत के हिसाब से type-specific code generate करते हैं।
- Template specialization और variadic templates special cases और variable संख्या में arguments handle करते हैं।
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: