将 std::variant<A, B> 转换为 std::variant<A, B, C>

  • 本文关键字:std variant 转换 c++ c++17
  • 更新时间 :
  • 英文 :


我有以下代码:

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();
}

最新更新