Variadic template class that stores a vector of each type given I'm exploring the possibility to generalise a class of mine that stores some entities. I like it to be able to keep entities of several type, given as template arguments. To explore the possibilities I wrote the following class, that does exactly that. I'm however unsure if anything that I do here is a) save and b) as easy as it gets. I'm not very deep into metaprograming. I'm looking for tips how to improve and pitfalls.

#include &lt;iostream&gt;
#include &lt;tuple&gt;
#include &lt;vector&gt;

template&lt;typename... Ts&gt;
class A
{
    template&lt;typename T&gt;
    using container = std::vector&lt;T&gt;;

public:
    template&lt;typename T&gt;
    void add(T e) {
        std::get&lt;container&lt;T&gt;&gt;(m_tupel).emplace_back(e);
    }

    template&lt;typename T&gt;
    container&lt;T&gt;&amp; get() {
        return std::get&lt;container&lt;T&gt;&gt;(m_tupel);
    }

private:
    std::tuple&lt;container&lt;Ts&gt;...&gt; m_tupel;
};

int main() 
{ 
    A&lt;int, bool, double, float&gt; a;
    a.add(3);
    a.add(33);
    a.add(3.14);
    a.add(333);
    a.add(31.4);

    const auto&amp; cDouble = a.get&lt;double&gt;();
    const auto&amp; cInt = a.get&lt;int&gt;();

    for(auto i : cDouble)
        std::cout&lt;&lt;i&lt;&lt;" ";
    std::cout&lt;&lt;"\n";
    for(auto i : cInt)
        std::cout&lt;&lt;i&lt;&lt;" ";
}
A few points of criticism of your approach:

Prefer protected to private

This isn't really about your overall design, but - unless you have very good reason, use protected rather than private member. In few cases is it useful to hide data from your subclasses.

"Where did my data go?!"

Suppose you have vectors types T_1 and T_2 in your tuple, and you add() an element of type T_3, which may be implicitly cast into both a T_1 and a T_2. Where will it go? The answer is: It depends on which casting is preferred, which in turns depends both on language defaults and on your own choices of constructors and casting operations for T_1, T_2 and T_3. 

Do you remember with certainty which implicit casts are preferred over which? I know I don't, and I write C++ all the time. Now, ok, maybe you're a smart guy and have that all memorized. What about the next person reading your code? And what if it's in code which itself is templated? And what if somebody adds or removes some T_1, T_2 or T_3 code? It seems to me this is just asking for trouble. 

If your data goes in a vector other than the one you expect, you'll have to start searching vectors you have trouble even referring to, for that data.

So, you asked about what's "safe" - I would say this is not too safe.

Motivation

This is not a problem with the code, it's a problem with your presentation. Why would you need a tuple of vectors of arbitrary types? Are you really sure that's what you need? Not, say, an array of std::variants like one of the comments suggests? Or a class with named vector, e.g.

struct A {
    std::vector&lt;Foo&gt; foos;
    std::vector&lt;Bar&gt; bars;
}


Now, this is much less "fancy" and "hi-tech" and modern-C++'ish, but it is simpler and easier to debug. There are also other points in the design space. I just find it a bit hard to believe that you would really need a completely generic tuple of typed vectors.