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
Typically, when you override the global stream operators for a custom class type, you should implement them in terms of calls to member methods and let the class decide how to stream itself, eg:
That being said, if you want something a little more "auto" when
operator<<
is invoked, maybe you could try something like this (not perfect, but close to what you might be looking for consideringd_union
does not know what it is holding until runtime, and if you addedoperator=
then it could even change type dynamically):Then you would just have to populate
registerOutputProcs()
with the various data types that you wantd_union
to support.