不确定这是个好主意,但我想您可以为 std::variant 定义一个 operator<<()。
只是为了好玩,我已经意识到您可以在以下示例中看到的那个(我想可以简化一点)
#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;
}
-- 编辑--
另一种编写streamV() 辅助函数的方法,不使用T0, Ts... 类型但使用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); }
-- 编辑 2--
正如 T.C. 指出的那样。 (谢谢!)我只(使用streamV())实现了一个效率较低、不太有趣和不太有用的std::visit() 版本。
使用std::visit() 我的示例可能会变得更简单
#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;
}
我再说一遍:只是为了好玩,因为我认为在标准类型上定义 operator<<() 不是一个好主意。
我建议 T.C. 的解决方案。将变体实例封装在特定类中流式传输。