Yes, there is a workaround in the general case. It's called:
Partial ordering. To get forward references as well, move methods into class namespace.
However
Nothing is gonna save you here. You cannot get hope to get the compiler to recover the static type of an argument, unless you already know it at compile time. This should be kinda obvious.
I mean, what should be the return type of foo()
? How could it possibly contain all possible element types? Right. That's why you had the variant to begin with.
Three ways forward:
know the type statically:
const auto& baz = boost::get<double>(variant);
return the typeid instead:
std::type_info const& typeinfo_value = variant.type();
branch out and create separate paths to handle all cases. Boost has the static_visitor for this case:
struct Visitor : boost::static_visitor<std::string> { std::string operator()(std::string const&) const { return "std::string"; } std::string operator()(int) const { return "int"; } std::string operator()(double) const { return "double"; } template <typename... T> std::string operator()(boost::variant<T...> const& v) const { return boost::apply_visitor(*this, v); } }; int main() { static const Visitor _visitor; variant = 0.5f; std::cout << "The actual type is " << _visitor(variant) << "\n"; }