Not sure if this is a good idea, but I suppose you could define operator<<() for std::variant .
Just for fun, I realized the one you can see in the following example (I suppose you can simplify it a bit)
#include <variant> #include <iostream> template <std::size_t I, typename T0, typename ... Ts> std::enable_if_t<(I == 1U+sizeof...(Ts)), std::ostream &> streamV (std::ostream & s, std::variant<T0, Ts...> const &) { return s; } template <std::size_t I, typename T0, typename ... Ts> std::enable_if_t<(I < 1U+sizeof...(Ts)), std::ostream &> streamV (std::ostream & s, std::variant<T0, Ts...> const & v) { return I == v.index() ? s << std::get<I>(v) : streamV<I+1U>(s, v); } template <typename T0, typename ... Ts> std::ostream & operator<< (std::ostream & s, std::variant<T0, Ts...> const & v) { return streamV<0U>(s, v); } int main () { std::variant<int, std::string> a, b; a = 1; b = "hi"; std::cout << a << b << std::endl; }
- EDIT -
Another way to write a helper function is streamV() , without the types T0, Ts... , but using std::variant_size_v
template <std::size_t I, typename V> std::enable_if_t<(I == std::variant_size_v<V>), std::ostream &> streamV (std::ostream & s, V const &) { return s; } template <std::size_t I, typename V> std::enable_if_t<(I < std::variant_size_v<V>), std::ostream &> streamV (std::ostream & s, V const & v) { return I == v.index() ? s << std::get<I>(v) : streamV<I+1U>(s, v); }
- EDIT 2 -
As TC pointed out (thanks!) I only (with streamV() ) implemented a less efficient, less interesting and less useful version of std::visit() .
Using std::visit() , my example can be much simpler
#include <variant> #include <iostream> template <typename T0, typename ... Ts> std::ostream & operator<< (std::ostream & s, std::variant<T0, Ts...> const & v) { std::visit([&](auto && arg){ s << arg;}, v); return s; } int main () { std::variant<int, std::string> a, b; a = 1; b = "hi"; std::cout << a << b << std::endl; }
I repeat: just for fun, because I don't think that a good idea defines operator<<() over a standard type.
I propose a solution from TC that go around the instance option for a thread in a specific class.