dimanche 23 octobre 2016

Type Erasure for objects containing a std::tuple in c++11

Lets say I have a generic class Container that contains any type of tuple, and has a function template<typename T> T& get<T>(); that returns a reference to the element in the tuple. My very simple implementation looks like this:

template<typename... Ts>
class Container
{
    std::tuple<Ts...> contents;

public:
    Container(const Ts&... ts) : contents(ts...) {}

    template <typename T>
    T& get()
    {
        //TypeIndex is some meta-programming struct to find index of T in Ts
        return std::get<TypeIndex<T, Ts...>::value>(contents);
    }
};

Are there any good type erasure techniques to turn Container into a regular class without altering the get function signature? As in calling get<T>() without knowing the tuples full type list? Something like this:

Struct A { int x; }
Struct B { int y; }
Struct C { int z; }

int main()
{
Container container(A(), B()); //Underlying storage is a std::tuple<A, B>

A& a = container.get<A>(); //Doesn't know the tuples type list but assumes A is in there.

C& c = container.get<C>(); //C isn't in the tuples type list, crash program.

}

boost::any is the usual go-to solution for these types of problems, but doesn't solve this particular problem because I would have to know the actual type of the underlying tuple to cast.

Aucun commentaire:

Enregistrer un commentaire