nie jestem pewien, że to dobry pomysł, ale przypuszczam, że można zdefiniować operator<<()
dla std::variant
.
Tak dla zabawy mam sobie sprawę z jednego można zobaczyć w poniższym przykładzie (przypuszczam można uprościć trochę)
#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 -
Innym sposobem Napisać funkcję streamV()
pomocnika, bez typów T0, Ts...
ale stosując 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); }
- EDYTUJ 2 -
Jak wskazano przez T.C. (dzięki!) Mam tylko (z streamV()
) zaimplementowaną mniej wydajną, mniej interesującą i mniej użyteczną wersję std::visit()
.
Korzystanie std::visit()
moim przykładem może stać się o wiele prostsze
#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;
}
Powtarzam: tylko dla zabawy, bo nie sądzę, że to dobry pomysł określić operator<<()
ponad standardowego typu.
Proponuję rozwiązanie od T.C. które kopiują warianty instancji do strumienia w określonej klasie.
coś wzdłuż tych linii: 'std :: wizyty ([] (const auto & v) {std :: cout << v;}, a);' –
Boost.Variant obsługuje operatora wstawiania, nie jest dla mnie jasne, dlaczego zostało to pominięte w 'std :: variant'. http://www.boost.org/doc/libs/1_65_1/doc/html/boost/operator_idp789915280.html – GManNickG