Variant implementation in C++ I've been fiddling with templates and compile time stuff i implemented a variant container and wanted some opinions and recommendations this is just a learning exercise, a couple template classes not included here are tl_type_at which gives the type in a typelist at a given index; and tl_index_of which gives the index of the first occurrence of the given type in a typelist:

template &lt;size_t Index, typename T, typename ... Ts&gt;
struct variant_deleter
{
    variant_deleter&lt;Index + 1, Ts...&gt; next;
    void operator()(size_t HeldIndex, void* HeldPtr) const
    {
        if(Index == HeldIndex)
            delete static_cast&lt;T*&gt;(HeldPtr);
        else
            next(HeldIndex, HeldPtr);
    }
};

template &lt;size_t Index, typename T&gt;
struct variant_deleter&lt;Index, T&gt;
{
    void operator()(size_t HeldIndex, void* HeldPtr) const
    {
        if(Index == HeldIndex)
            delete static_cast&lt;T*&gt;(HeldPtr);
        }
};

struct bad_variant_access {};

template &lt;typename T, typename ... Ts&gt;
struct variant
{
    typedef typelist&lt;T, Ts...&gt; types;

    variant()
        : union_(new T())
        , held_(0)
    {}
    template &lt;typename I&gt;
    variant(I Init)
        : union_(new typename tl_type_at&lt; tl_index_of&lt;I, types&gt;::index, types &gt;::type())
        , held_(tl_index_of&lt;I, types&gt;::index)
    {}
    ~variant()
    { variant&lt;T, Ts...&gt;::deleter_(held_, union_); }

    template &lt;typename P&gt;
    variant&lt;T, Ts...&gt;&amp; operator=(const P&amp; rhs)
    {
        union_ = new(union_) P(rhs);
        held_ = tl_index_of&lt;P, types&gt;::index;
        return *this;
    }

    template &lt;typename G&gt;
    G&amp; get()
    {
        if(held_ == tl_index_of&lt;G, types&gt;::index)
            return *static_cast&lt;G*&gt;(union_);
        else
            throw bad_variant_access {};
    }
private:
    void* union_;
    size_t held_;
    static const variant_deleter&lt;0, T, Ts...&gt; deleter_;
};
Some issues:


the assignment operator doesn't call the destructor of the existing data, before setting a new value (results in UB, likely a resource leak).
by default you do not instantiate an empty variant with the default constructor; the first type in the union may not even be default-constructible.
bad_variant_access should probably inherit from a standard exception (std::runtime_error or std::logic_error are common as base classes).