C++ Variadic Templates

Basic Concepts

  • Definition: Variadic templates declare a template parameter pack or function parameter pack using ellipsis (…).

  • Pack Expansion: This refers to the process of expanding the elements of a parameter pack one by one.

  • Pack Expansion Pattern: Followed by ellipsis (…), indicating that the pattern is applied to each element in the parameter pack. For example, if we have a parameter pack Args… containing int, double, char, then Args*… will expand toint*, double*, char*

  • Pack Expansion Principle: The compiler applies the pattern multiple times at compile time based on the number of elements in the parameter pack, each time applying one element from the parameter pack. This process occurs at compile time, effectively functioning as a compile-time loop.

  • Variadic Template Function Syntax:

     template <typename... Args>  void func(Args... args){}
  • Variadic Class Template Syntax:

    template <typename...Args>class Tuple{};
    
    

Application Examples

Variadic templates are primarily used for functions that need to handle an arbitrary number and types of parameters; type calculations and type checks are performed at compile time.

Encapsulating Multi-Parameter Print Output

// Pack expansion, a pattern recursively expanding inline void testPrint() {    std::cout << " " << std::endl;}template<typename T, typename... Args>void testPrint(T first, Args... args) {    std::cout << " " << first << " ";    testPrint(args...);             // Expand the function parameter pack, each time one parameter is used for first, the rest form a new parameter pack}

Encapsulating Type Constructor
template<typename T ,typename... Args>std::unique_ptr<T> make_unique(Args&&... args) {    std::cout << " sizeof = " << sizeof...(Args) << std::endl;    std::unique_ptr<T> tmp = std::make_unique<T>(std::forward<Args>(args)...);          // Expand multiple parameters sequentially as constructor parameters. If the parameters do not match the constructor parameters, an error is reported.    return tmp;}template<typename... Args>auto make_tuple(Args... args) {    return std::tuple<Args...>(args...);    // Here there are two pack expansions:    // 1. std::tuple<Args...> expands Args pack into multiple template parameters    // 2. (args...) expands args pack into multiple constructor parameters}

Leave a Comment