如何为包含重复类型的std::variant赋值?
如何为包含重复类型的std::variant赋值?
当std::variant包含重复类型时,直接赋值会因为类型歧义导致编译失败,比如std::variant<int,int> foo; foo = 1;无法通过编译,原因是编译器无法确定要将值赋给哪个int类型的变体成员。以下是几种可行的解决方法:
方法1:使用emplace成员函数(推荐)
emplace可以直接在指定索引的位置构造并赋值目标值,同时自动切换变体的活跃成员:
#include <variant> #include <cassert> int main() { std::variant<int, int> foo; foo.emplace<1>(10); // 明确指定为索引1的成员赋值 assert(foo.index() == 1); assert(std::get<1>(foo) == 10); return 0; }
方法2:使用std::get结合赋值
通过std::get<索引>获取对应成员的引用进行赋值,但需要注意:如果变体当前的活跃成员不是目标索引,直接调用std::get会抛出std::bad_variant_access异常。如果是默认构造的std::variant<int,int>,其活跃成员默认是索引0,若要切换到索引1,建议先使用emplace激活目标成员,再赋值:
#include <variant> #include <cassert> int main() { std::variant<int, int> foo; // 先激活索引1的成员 foo.emplace<1>(0); // 再赋值 std::get<1>(foo) = 10; assert(foo.index() == 1); assert(std::get<1>(foo) == 10); return 0; }
方法3:使用std::in_place_index构造临时变体赋值
可以通过带std::in_place_index标签的构造函数创建临时变体,再赋值给目标对象:
#include <variant> #include <cassert> int main() { std::variant<int, int> foo; foo = std::variant<int, int>(std::in_place_index<1>, 10); assert(foo.index() == 1); assert(std::get<1>(foo) == 10); return 0; }
对之前错误尝试的说明
foo = 1编译失败:因为两个变体成员都是int,编译器无法推导应匹配哪个赋值运算符重载。get<foo, 0> = 1写法错误:std::get的模板参数应为索引值(而非对象),正确写法是std::get<0>(foo) = 1,但仅当活跃成员为索引0时可用,否则会抛出异常。
内容的提问来源于stack exchange,提问作者Algorithmic Canary
相关产品推荐
相关产品推荐

