Getting active value in std::visit without knowing which value is active
Ask yourself the question:
What is the return type of std::visit
if you don't know what part of the variant
is active?
That is the question that the compiler must answer. And the answer can't be "it depends" - you (as in, the compiler) must decide on exactly one type at compile-time. The visit
call cannot possibly return different types at runtime.
If you want to work with different types "at runtime", you must be in a function templated on the type you want to work with. In other words, there must be different functions (or function template instantiations) to handle the "write an int to cout
" and "write a string to cout
" cases. You cannot do this in the same (non-templated) function.
The straightforward solution here is thus to put the std::cout <<
into your templated visitor function - that's the point of visiting: Specifying what is supposed to happen in each case.
If you want to "use the obtained value maybe also for [some] other [purpose]", then that "other purpose" should also be part of the/a visitor. Only then can you have that "other purpose" handle the different cases at once (e.g. in a templated function). Otherwise you must decide at compile-time already which type shall be used - the compiler is not going to leave that choice open for later (run time).
Return type of visitor function should be identical.
Create printer visitor instead:
struct PrinterVisitor {
template<typename T>
void operator()(const T& t) const
{
std::cout << t;
}
};
int main()
{
std::variant<int, std::string> v;
v = "hello";
std::visit(PrinterVisitor{}, v); // expect "hello"
}
And in your case, you can even have lambda:
int main()
{
std::variant<int, std::string> v;
v = "hello";
std::visit([](const auto& t){std::cout << t;}, v); // expect "hello"
}