Search code examples
c++c++17variadic-templatesfold-expression

How to use fold expression to instantiate each type in a variadic template function?


I am trying to create an "object manager" that will create and store instances of a template class. The class takes one template argument and inherits from a base class to allow instances with different template args to be stored in the same container. The types that will be used as template arguments will be provided by the user in a variadic template function.

Below is a minimal example that illustrates the issue:

struct A
{
    int m_a = 0;
};

template<typename T>
struct B : public A
{
    int m_b = 1;
    T m_t;
};

template<typename... Types> std::vector<A*> generate_a_vec()
{
    std::vector<A*> a_vec; // <--- Need to initialize with a new B<T> for each T in "Types"
    return a_vec;
}

int main()
{
    std::vector<A*> a_vec = generate_a_vec<int, float, bool>();

    for(A* a : a_vec)
    {
       std::cout << a->m_a << std::endl;
    }

    return 0;
}

Let's assume every T we will use has a default constructor. Is there a way to use a fold expression to create a B<T> with new for each type in Types and add the resulting pointers to the vector in generate_a_vec()?


Solution

  • If I understand correctly what do you want, you're looking for

    std::vector<A*> a_vec { new B<Types>{}... };
    

    But this isn't "fold expression"; it's a simple variadic template pack expansion and it's available starting from C++11.

    An example of "fold expression" (available from C++17) can be the following

    std::vector<A*> a_vec;
    
    ( a_vec.push_back( new B<Types>{} ), ... );
    

    where variadic template pack is folding expanded using the comma operator