传入std::unique_ptr到自定义vector类报已删除函数错误,用move仍无效如何解决
问题原因与解决方案
核心错误原因
- 你定义的
Add方法参数为const T& v,即使你对入参调用std::move,最终传入函数的是const右值引用类型 std::unique_ptr的移动构造函数签名为unique_ptr(unique_ptr&& u) noexcept,仅接收非const的右值引用,无法匹配const右值引用,因此编译器会尝试调用已被删除的拷贝构造函数,触发报错- 额外逻辑错误:你对const修饰的变量调用
std::move没有实际意义,move操作会修改原对象的所有权,const修饰符本身就禁止了这类修改行为
修复方案
方案1:新增右值引用重载的Add方法
针对左值、右值分别做拷贝、移动处理,兼容支持拷贝的类型和仅支持移动的类型:
template<typename T> class VectorSelectable { public: // 处理左值,执行拷贝逻辑(仅适用于支持拷贝的类型) void Add(const T& v) { m_Items.push_back(v); } // 处理右值,执行移动逻辑 void Add(T&& v) { m_Items.push_back(std::move(v)); } private: vector<T> m_Items; };
方案2:使用转发引用统一处理左右值
用完美转发减少重复代码,自动匹配拷贝/移动逻辑:
template<typename T> class VectorSelectable { public: template<typename U> void Add(U&& v) { m_Items.push_back(std::forward<U>(v)); } private: vector<T> m_Items; };
调用侧优化建议
你当前的调用代码vec.Add(move(make_unique<FunctionType>()))可以简化为vec.Add(make_unique<FunctionType>()),因为make_unique返回的本身就是右值,不需要额外调用std::move。
内容的提问来源于stack exchange,提问作者Max Peglar-Willis
相关产品推荐
相关产品推荐

