如何将EmptyDouble类型std::variant转换为EmptyDoubleOrInt作为函数入参
C++ std::variant 范围子集类型转换方案
你可以通过std::visit实现无需判断当前存储类型的转换,EmptyDouble的所有可选类型都是EmptyDoubleOrInt的子集,每个持有的值都可以直接构造目标类型的variant,具体实现如下:
适配需求的DoSomething实现
#include <variant> #include <utility> // 你已经定义的类型声明 typedef std::variant<boost::blank, double> EmptyDouble; typedef std::variant<boost::blank, double, int> EmptyDoubleOrInt; EmptyDoubleOrInt DoSomething(const EmptyDouble& input) { return std::visit([](auto&& val) -> EmptyDoubleOrInt { return std::forward<decltype(val)>(val); }, input); }
实现后你就可以直接使用SomeFunction(DoSomething(emptyDouble))完成调用,全程不需要手动判断EmptyDouble当前存储的具体类型,std::visit会自动匹配当前活跃的类型传入lambda完成构造。
通用扩展实现
如果后续有其他类似的「小范围variant转大范围variant」的需求,可以封装通用转换模板:
template <typename TargetVariant, typename SourceVariant> TargetVariant variant_cast(SourceVariant&& src) { return std::visit([](auto&& value) -> TargetVariant { return std::forward<decltype(value)>(value); }, std::forward<SourceVariant>(src)); }
使用时直接指定目标variant类型即可:
SomeFunction(variant_cast<EmptyDoubleOrInt>(emptyDouble));
注意事项
- 该方案仅适用于源variant的所有可选类型都可被目标variant合法接收的场景,你当前的场景完全符合条件
- 方案仅依赖C++17及以上的标准库特性,无需引入额外第三方依赖
内容的提问来源于stack exchange,提问作者Meng
相关产品推荐
相关产品推荐

