Không chắc đó là một ý tưởng tốt nhưng tôi cho rằng bạn có thể xác định một operator<<()
cho std::variant
.
Just for fun tôi đã nhận ra một trong những bạn có thể thấy trong ví dụ sau (Tôi cho rằng có thể được đơn giản hóa một chút)
#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 -
Một cách khác để viết hàm streamV()
helper, mà không có sự T0, Ts...
loại nhưng sử dụng 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); }
- CHỈNH SỬA 2 -
Được chỉ định bởi T.C. (cảm ơn!) Tôi chỉ (với streamV()
) đã triển khai phiên bản kém hiệu quả, ít thú vị và ít hữu ích hơn của std::visit()
.
Sử dụng std::visit()
ví dụ của tôi có thể trở thành rất nhiều đơn giản
#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;
}
Tôi lặp lại: chỉ để cho vui, bởi vì tôi không nghĩ rằng đó là một ý tưởng tốt xác định operator<<()
qua một loại tiêu chuẩn.
Tôi đề xuất giải pháp từ T.C. bao gồm trường hợp biến thể để phát trực tuyến trong một lớp cụ thể.
cái gì đó dọc những dòng này: 'std :: lần ([] (const auto & v) {std :: cout << v;}, a);' –
Boost.Variant hỗ trợ một toán tử chèn, nó không rõ ràng với tôi tại sao điều này bị bỏ qua từ 'std :: variant'. http://www.boost.org/doc/libs/1_65_1/doc/html/boost/operator_idp789915280.html – GManNickG