C++构造函数中如何用unique_ptr初始化vector并传递给基类?
嘿,你已经精准抓住问题关键了——初始化列表的元素是const的,没法对它们执行移动操作,而std::unique_ptr又禁用了拷贝构造,这就触发了那个attempting to reference a deleted function错误。你的核心思路完全没问题:把单个移动过来的unique_ptr塞进vector再传给基类,只是实现方式踩了初始化列表的坑。
下面给你两种可行的解决办法,都能在构造函数初始化列表里完成需求:
方法1:用Lambda在初始化列表里构造并填充vector
这是最直观的方式,通过一个临时lambda来构造vector,用emplace_back移动元素进去,再把vector返回给基类构造函数:
term_array::term_array(std::unique_ptr<term>&& opd) : term([]() mutable { // 必须加mutable,否则无法修改捕获的opd std::vector<std::unique_ptr<term>> vec; vec.emplace_back(std::move(opd)); return vec; }()) { // 派生类自身的构造逻辑 }
这里的mutable是关键:lambda默认捕获的变量是const属性,加上它才能对opd执行std::move操作。
方法2:用移动迭代器配合vector范围构造函数
可以把单个opd当成单元素数组,用std::make_move_iterator将普通指针转换成移动迭代器,绕过初始化列表的const限制:
term_array::term_array(std::unique_ptr<term>&& opd) : term(std::vector<std::unique_ptr<term>>( std::make_move_iterator(&opd), std::make_move_iterator(&opd + 1) )) { // 派生类自身的构造逻辑 }
vector的范围构造函数会通过移动迭代器把opd移动到容器里,完全不会触发拷贝操作。
额外优化建议(如果能修改基类)
如果基类term允许新增构造函数,可以直接给它加一个接受单个std::unique_ptr<term>&&的版本,这样代码会更简洁:
// 基类term新增构造函数 term::term(std::unique_ptr<term>&& opd) { internal_vector.emplace_back(std::move(opd)); } // 派生类构造函数直接调用 term_array::term_array(std::unique_ptr<term>&& opd) : term(std::move(opd)) { // ... }
内容的提问来源于stack exchange,提问作者Duke
相关产品推荐
相关产品推荐

