c++ - 将 std::variant 转换为具有子集类型的另一个 std::variant
问题描述
给定一个 类型的变量std::variant<A,B,C>
,我检查过它不包含C
. 我怎样才能将其转换为std::variant<A,B>
?
std::variant<A,B> convert(std::variant<A,B,C> value) {
if (std::holds_alternative<C>(value)) {
// die.
}
return ... // what to do here?
}
我知道如何使用此处描述的访问者进行相反的操作(转换为超集变体) ,但这种方法不适用于这种情况。
解决方案
您可以简单地运行 trough std::visit
,使用接收 lambda 表达式,它只“吃”您想要的类型并创建新的变体类型。
提示:由于您转换的变体类型可能是“空的”,因为您必须返回一些东西,即使传入变体的类型不是您定义的有效类型,您也必须提供一些“虚拟类型”。为此目的std::monotype
已经定义。
使用 c++20 概念更容易,但我还为您提供了手工制作 lambda 的“老式”方式:
struct A{};
struct B{};
struct C{};
using VARIANT_ALL = std::variant<A,B,C>;
using VARIANT_SUB = std::variant<std::monostate,A,B>;
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template < typename CHECK_ME >
concept IS_WANTED = std::is_same_v<CHECK_ME, A> || std::is_same_v<CHECK_ME, B >;
VARIANT_SUB GetSubset( const VARIANT_ALL& vin )
{
return std::visit( overloaded
{
[]( const A& x ){ return VARIANT_SUB{x};},
[]( const B& x ){ return VARIANT_SUB{x};},
[]( auto& ) { return VARIANT_SUB{};}
}, vin
);
}
VARIANT_SUB GetSubset2( const VARIANT_ALL& vin )
{
return std::visit( overloaded
{
[] < IS_WANTED TYPE >( const TYPE& x ){ return VARIANT_SUB{x};},
[]( auto& ) { return VARIANT_SUB{};}
}, vin
);
}
int main()
{
VARIANT_ALL va=A{};
VARIANT_ALL vb=B{};
VARIANT_ALL vc=C{};
auto vva = GetSubset( va );
auto vvb = GetSubset( vb );
auto vvc = GetSubset( vc );
std::cout << std::holds_alternative<A>( vva ) << std::endl;
std::cout << std::holds_alternative<B>( vvb ) << std::endl;
std::cout << std::holds_alternative<std::monostate>( vvc ) << std::endl;
auto vva2 = GetSubset2( va );
auto vvb2 = GetSubset2( vb );
auto vvc2 = GetSubset2( vc );
std::cout << std::holds_alternative<A>( vva2 ) << std::endl;
std::cout << std::holds_alternative<B>( vvb2 ) << std::endl;
std::cout << std::holds_alternative<std::monostate>( vvc2 ) << std::endl;
}
推荐阅读
- angular - 当graphQl发送错误对象以及数据对象时如何获取数据对象,因为在查询中找不到某些东西
- node.js - 有没有办法使用 jimp for node js 比较两个图像
- laravel - 在 laravel 中获取 Unix 时间戳
- javascript - 子集堆积条形图
- c# - Tesseract OCR 字符串操作问题
- javascript - 在不使用字符串方法和不使用数组的情况下对整数进行排序
- python - Python:多个 for 循环
- docker - Docker ENTRYPOINT 最大字符数
- javascript - 动态键中的动态子对象
- routes - 如何使用带有查询字符串的赛普拉斯路由