vendredi 12 juin 2015

Is it possible to automatically extract type from discriminated union?

Is it possible to extract the type of a discriminated union to initialize an "auto" variable? It's easy enough is you pass the type to a template, but I'd like something "auto". A solution using a visitor function or using a bounded list of types (such as an mpl::vector) would be great.

An example is shown below:

#include <iostream>
#include <typeindex>
#include <cassert>

struct d_union {
    template <typename T>
    d_union(T t) {
        *reinterpret_cast<T*>(data) = t;
        _type_id = &typeid(T);
    }

    template <typename T>
    const T* get_pointer() const {
        if (_type_id == &typeid(T))
            return reinterpret_cast<const T*>(data);
        else
            return nullptr;
    }

    template <typename T>
    const T get() const {
        assert (_type_id == &typeid(T));
        return *get_pointer<T>();
    }

    alignas(8) char data[8];
    const std::type_info *_type_id;
};


std::ostream& operator<<(std::ostream&os, const d_union &u) {
    if (auto ip = u.get_pointer<int>())
        os << *ip;
    if (auto fp = u.get_pointer<float>())
        os << *fp;
    return os;
}

int main() {

    d_union _i = d_union(42);
    d_union _f = d_union(3.14f);

    std::cout << "d_union(42) = "   << _i << std::endl;
    std::cout << "d_union(3.14) = " << _f << std::endl;

    int _get_i = _i.get<int>();
    std::cout << "d_union(42).get<int>() = " << _get_i << std::endl;

    // auto _get_auto = _i.get();
    // std::cout << "d_union(42).get()" << _get_auto << std::endl;

}

Any possible solutions would be appreciated!

Thanks

Aucun commentaire:

Enregistrer un commentaire