我有以下代码:
std::variant<A, B> foo();
std::variant<A, B, C> bar();
std::variant<A, B, C> foobar(bool a) {
if (a) {
return foo();
} else {
return bar();
}
}
但是,这不会在 gcc 上编译:
error: could not convert ‘foo()’ from ‘variant<A, B>’ to ‘variant<A,B,C>’.
有没有一种优雅的方法将std::variant<A, B>
转换为std::variant<A, B, C>
?
原则上,该标准可以允许隐式(如果保证成功(或显式(否则(从std::variant<T...>
到std::variant<U...>
的转换,如果前者中的所有类型在后者中至少发生的频率相同,因为存在明确和明显的映射。
不幸的是,它根本没有。
因此,您必须编写自己的转换函数。
有没有一种优雅的方法可以将
std::variant<A, B>
转换为std::variant<A, B, C>
?
不,我想。
我能想象到的最好的通过std::visit()
;
std::variant<A, B, C> foobar (bool a)
{
if (a)
return std::visit([](auto && val) -> std::variant<A, B, C>
{ return {std::forward<decltype(val)>(val)}; },
foo());
else
return bar();
}
更通用的解决方案可能是convVariant()
函数
template <typename R, typename T>
R convVariant (T && t)
{
return std::visit([](auto && val) -> R
{ return {std::forward<decltype(val)>(val)}; },
std::forward<T>(t));
}
所以foobar()
成为
std::variant<A, B, C> foobar (bool a)
{
if (a)
return convVariant<std::variant<A, B, C>>(foo());
else
return bar();
}