C++ Variadic Template Unpacking

67 views Asked by At

Given the following code:

void foo(int x, int y, int z, int u)
{
}

template<typename... Args> class A;

template<> class A<>{};

template<typename T, typename... Args>
class A<T, Args...> : public A<Args...>
{
public:
    A(){}
    
    A(T a, Args... v) : m(a), A<Args...>(v...)
    {
    }
    
    void call()
    {
        foo(m, A<V>::m...);     
    }
    
    T m;
};

A<int, int, int> a{1, 2, 3};
a.call();

How do I unpack the template variable params in the function foo as follows?

foo(m, A<int, int>::m, A<int>::m);

However the code above unpacks the params as:

foo(m, A<int>::m, A<int>::m);
1

There are 1 answers

3
Neeraj Roy On

It seems a couple of issues in your code need to be addressed. First, you must unpack the template arguments in the call function properly, and second, you should ensure that the template parameter pack Args is consistently used throughout your code.

Here is the corrected version of your code (corrected version of my corrected version of your code):

#include <iostream>

void foo(int x, int y, int z, int u)
{
    std::cout << x << " " << y << " " << z << " " << u << std::endl;
}

template <typename... Args>
class A;

template <>
class A<> {};

template <typename T, typename... Args>
class A<T, Args...> : public A<Args...>
{
public:
    A() {}

    A(T a, Args... v) : m(a), A<Args...>(v...) {}

    void call()
    {
        callHelper(static_cast<A<Args...>*>(this));
    }

private:
    T m;

    template <typename U, typename... Us>
    void callHelper(U* u, Us*... us)
    {
        foo(m, u->m, us->m...);
    }
};

int main()
{
    A<int, int, int> a{1, 2, 3};
    a.call();

    return 0;
}

Changes made:

  1. Use static_cast to access the member m from the call function's base class (A<Args...>).
  2. Add #include <iostream> to use std::cout in the foo function.

With these changes, the code should now correctly unpack the template variable parameters in the foo function as follows:

foo(m, A<int, int>::m, A<int>::m);

This ensures that each instantiation of the A class contributes its member m to the parameter list of the foo function in the correct order. I hope this helps you.

After the edit: In this version, I added a callHelper function inside the A class template, which recursively unpacks the template parameters and calls the foo function. This should resolve the compilation error you encountered. I appreciate your understanding, and I hope this helps!