C++如何重载=运算符以支持对象创建时使用初始化列表赋值
核心问题原因
你混淆了对象初始化和对象赋值的逻辑,A obj={...}属于初始化阶段,走构造函数调用流程,根本不会触发你重载的operator=,所以修改operator=完全解决不了这个问题。
报错的本质是C++的隐式转换规则限制:隐式转换序列中最多只能存在1次用户定义的转换步骤。
- 第一种写法
obj={...}是赋值操作:obj已经完成默认构造,花括号列表只需要做1次隐式转换生成vector<int>,即可匹配你写的赋值运算符,因此编译通过。 - 第二种写法是拷贝初始化:需要把花括号列表转换成
A类型,现有路径为花括号初始化列表 -> vector<int> -> A,包含两次用户定义的隐式转换,不符合C++标准要求,因此报错。
解决方法
给类新增接受std::initializer_list<int>的构造函数和对应的赋值运算符即可,修改后的完整代码如下:
#include <iostream> #include <vector> #include <initializer_list> // 新增头文件 using namespace std; class A{ public: A() = default; // 新增initializer_list构造函数 A(initializer_list<int> list) : a1(list) {} // 原有vector构造函数可按需保留 A(vector<int> values) : a1(std::move(values)) {} // 新增initializer_list版本的赋值运算符 A& operator=(initializer_list<int> list) { a1 = list; return *this; } // 原有vector版本的赋值运算符可按需保留 A& operator=(vector<int> values) { a1 = std::move(values); return *this; } private: vector<int> a1; };
修改后两种写法都可以正常编译运行。如果你不需要支持vector直接构造/赋值,也可以删掉对应的两个函数,只保留initializer_list版本即可满足需求。
内容的提问来源于stack exchange,提问作者Grovereiner
相关产品推荐
相关产品推荐

