自定义std::vector替代类需双层花括号初始化?如何改为单层?
嘿,这个问题其实是C++派生类构造函数继承规则和初始化列表匹配逻辑导致的,咱们一步步拆解:
首先说为什么单层花括号不行:
你的myvector继承自_vector<T>(也就是绑定了自定义分配器的std::vector),而std::vector本身有一个接受std::initializer_list<T>的构造函数。但C++不会默认让派生类继承基类的构造函数——除非你显式声明。所以当你写mine::myvector<int> mvi = {1,2,3};时,编译器找不到myvector自身对应的初始化列表构造函数,自然无法匹配。
那双层花括号为什么能编译?
因为你的myvector是空派生类(没有自定义成员、没有用户声明的构造函数),属于C++中的聚合类型。外层花括号触发聚合初始化逻辑,内层花括号则直接用来初始化基类_vector<T>,相当于显式调用了基类的初始化列表构造函数。
让myvector支持单层花括号初始化的两种方法
方法1:显式继承基类的所有构造函数
这是最简洁的方式,直接让myvector继承基类_vector<T>的全部构造函数,包括接受初始化列表的版本:
namespace mine { template<class T> using _vector = std::vector<T, my_allocator<T>>; template<class T> class myvector : public _vector<T> { public: // 继承基类的所有构造函数 using _vector<T>::_vector; }; };
修改后就能像原生std::vector一样使用单层花括号:
mine::myvector<int> mvi = {1, 2, 3}; // 现在可以正常编译
方法2:手动添加初始化列表构造函数
如果你不想继承基类的全部构造函数,可以单独实现一个接受std::initializer_list的构造函数,把参数转发给基类:
namespace mine { template<class T> using _vector = std::vector<T, my_allocator<T>>; template<class T> class myvector : public _vector<T> { public: // 手动实现初始化列表构造,转发给基类 myvector(std::initializer_list<T> init, const my_allocator<T>& alloc = my_allocator<T>()) : _vector<T>(init, alloc) {} }; };
这种方式更灵活,如果你需要在初始化时添加自定义逻辑,可以在这里扩展。
补充小知识点
当你显式继承基类构造函数后,myvector就不再是聚合类型了,但此时它拥有了自己的初始化列表构造函数,所以单层花括号能直接匹配构造逻辑,和原生std::vector的行为完全一致。
内容的提问来源于stack exchange,提问作者joxeankoret

