如何在值类型std::variant与指针类型std::variant之间拷贝值?
问题描述
我有两个std::variant(已简化,实际包含更多类型):
std::variant<int *, double *> PtrVariant; std::variant<int, double> ValueVariant;
我想要在它们之间拷贝值。
直接用以下写法无法生效:
ValueVariant = *PtrVariant;
以下写法可以生效,但需要手动检查类型:
if (std::holds_alternative<int>(ValueVariant)) ValueVariant = *std::get<int *>(PtrVariant); else if (std::holds_alternative<double>(ValueVariant)) ValueVariant = *std::get<double *>(PtrVariant);
请问是否存在无需检查variant所持类型就能完成值拷贝的方法?
解决方案
当然有,你可以用std::visit自动处理variant的类型分发,完全不需要手动写类型检查分支。
核心实现是给std::visit传递一个通用lambda,它能接收任意类型的指针,解引用后直接赋值给ValueVariant——std::variant本身支持从对应值类型直接赋值,会自动匹配并切换到对应的状态。
示例代码:
std::visit([&](auto* ptr) { ValueVariant = *ptr; }, PtrVariant);
原理说明
std::visit会根据PtrVariant当前持有的实际类型,自动实例化并调用lambda的对应版本。比如PtrVariant持有int*时,lambda会被实例化为接受int*的版本,解引用得到int后赋值给ValueVariant,此时ValueVariant会自动切换到int类型状态;持有double*时逻辑同理。- 这种方式不需要手动枚举所有类型,后续给两个variant添加更多匹配的类型对(比如
float*和float),代码也无需修改,扩展性更强。
注意事项
如果PtrVariant持有的指针类型在ValueVariant中没有对应的非指针类型,编译会直接报错——这其实是编译期的类型匹配检查,能提前避免运行时错误。
内容的提问来源于stack exchange,提问作者PiotrK
相关产品推荐
相关产品推荐

