Search code examples
c++c++17variadic-templatesstdtupleparameter-pack

"iterating" over a std::tuple and having access to all the constructors


I am new to variadic templates, and I'm having a difficult time implementing this container class. What I want is to take a list of types, and then create a std::tuple that holds std::vectors of each type. The specific difficulty I was having is "iterating" over this std::tuple.

I was reading this answer, and it mentions that you can use std::apply for this. I'm not sure if I understand the purpose of a "fold expression." Here's what I tried:

#include <iostream>
#include <tuple>
#include <vector>

template<typename... Types>
class VecCollection {
public:
    std::tuple<std::vector<Types>...> m_stuff; // inside or outside?
    VecCollection(unsigned vec_length, Types... things) 
        : m_stuff(std::make_tuple(std::vector<Types>(things)...)) 
    {
        std::apply(
            [](auto&&... vecs) { 
                for(int i = 0; i < 3; ++i) {
                    vecs.push_back(Types()...);
                }
            }, 
            m_stuff);
    }
};



int main() {
    VecCollection<int, float>(3, 2.6, 400);
    return 0;
}

It compiles if I remove the apply call inside the constructor. I think the problem is Types().... Do I have access to each constructor in a general way?

Would it be easier if I just went back to run-time polymorphism and held onto a bunch of pointers to a base class for all these Types?


Solution

  • try this.

    template<typename... Types>
    class VecCollection {
    public:
        std::tuple<std::vector<Types>...> m_stuff; // inside or outside?
    
        VecCollection(unsigned vec_length, Types... things)
            : m_stuff(std::make_tuple(std::vector<Types>(things)...))
        {
            std::apply(
                [](auto&&... vecs) {
                    for(int i = 0; i < 3; ++i) {
                        ((vecs.push_back(Types()), ...));
                    }
                },
                m_stuff);
        }
    };