Search code examples
c++variadic-templates

Handling multiple occurrences of the same type in a variadic template parameter pack


How can I process a variadic template function in C++ to handle multiple occurrences of the same type within the template parameter pack and then pass these arguments to another variadic function?

I have the following variadic template function run that takes multiple arguments and prints them:

#include <iostream>

template<typename... Args>
void run(Args... var)
{
    (std::cout << ... << var) << std::endl;
}

I want to create another variadic template function processArgs that:

  1. Handles multiple occurrences of the same type within the template parameter pack.
  2. Processes these arguments and assigns them specific values.
  3. Passes the collected arguments to the run function.

For instance, if I call processArgs<int, double, int, int, double>(), I want it to:

  1. Create integer variables, double variables, etc., for each type in the parameter pack.
  2. Assign specific values to these variables (e.g., incrementing values for each instance of the same type).
  3. Pass these variables to the run function, so it behaves as if run(42, 3.14, 43, 44, 4.14) was called.

Here is the desired outcome:

int main()
{
    processArgs<int, double, int, int, double>();
    // Should result in calling: run(42, 3.14, 43, 44, 4.14), i don't care what the numbers are, it's just random
    return 0;
}

How can I implement this processArgs function to achieve the described behavior?


Solution

  • You can use class template and static data member to achieve what you want:

    #include <iostream>
    #include <iomanip>
    //wrapper 
    template<typename T>
    struct Wrapper
    {
        static T value;
        Wrapper()
        {
            
            value++;
        } 
        
    };
    template<typename T> T Wrapper<T>::value{};
    //specialization for random values for your types. Use random values here.
    template<> int Wrapper<int>::value = 42;
    template<> double Wrapper<double>::value = 3.14; 
    
    template<typename... Args>
    void run(Args... var)
    {
         
        ((std::cout << var << ' '), ...) <<std::endl;
    }
    template<typename... T> void processArgs()
    {
        run(std::forward<T>((Wrapper<T>().value)-1)...);
    }
    int main()
    {
        processArgs<int, double, int, int, double>(); 
        
        return 0;
    }
    

    Working demo