【发布时间】:2020-04-05 17:34:47
【问题描述】:
我已经修改了来自this answer 的一些代码来处理目标变体是源变体子集的情况,如下所示:
template <class... Args>
struct variant_cast_proxy
{
std::variant<Args...> v;
template <class... ToArgs>
operator std::variant<ToArgs...>() const
{
return std::visit(
[](auto&& arg) -> std::variant<ToArgs...> {
if constexpr (std::is_convertible_v<decltype(arg), std::variant<ToArgs...>>)
return arg;
else
throw std::runtime_error("bad variant cast");
},
v
);
}
};
template <class... Args>
auto variant_cast(const std::variant<Args...>& v) -> variant_cast_proxy<Args...>
{
return { v };
}
struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
struct F {};
int main() {
std::variant<A, B, C, D> v1 = B();
std::variant<B,C> v2;
v2 = variant_cast(v1);
}
上述方法有效,但我希望它能够处理在编译时可以检测到错误转换的情况。以上处理了运行时所有错误的转换,但运行时和编译时错误都是可能的。如果 v 持有 C 类型的值,则将 std::variant<A,B,C> 类型的 v 转换为 std::variant<A,B> 应该在运行时失败,但是例如
std::variant<A, B, C, D> v1 = B();
std::variant<E,F> v2;
v2 = variant_cast(v1)
甚至不应该编译。
我相信这可以通过 std::enable_if 完成,但我不确定它似乎需要测试可变参数包的集合包含,我不知道该怎么做。
【问题讨论】:
-
有趣...我也使用链接帖子中的代码,但是当我编译您的示例时,出现以下编译器错误:
error: could not convert ‘arg’ from ‘const A’ to ‘std::variant<E, F>’
标签: c++ c++17 std-variant