向空std::unique_ptr赋值make_unique是否需要使用std::move?
空std::unique_ptr赋值临时对象时,是否需要std::move?
先看你给出的代码示例:
#include <memory> using namespace std; int main() { unique_ptr<int> a; // Do something.... // Case 1 a = make_unique<int>(5); // Case 2 a = std::move(make_unique<int>(5)); return 0; }
嘿,这个问题问得挺细致的!咱们来好好掰扯掰扯这两种写法的区别——其实结论是:它们本质上完全没有差异,下面给你拆解清楚为什么:
核心原理:std::unique_ptr的移动语义
std::unique_ptr是独占式智能指针,它禁用了拷贝构造和拷贝赋值,只支持移动构造和移动赋值。移动赋值运算符的签名大致是这样的:
unique_ptr& operator=(unique_ptr&& other) noexcept;
注意这里的参数是unique_ptr&&——也就是右值引用,只有右值才能匹配这个运算符。
两种写法的本质
Case 1:直接赋值临时对象
make_unique<int>(5)返回的是一个临时的std::unique_ptr<int>对象,而临时对象本身就是右值。编译器会自动匹配移动赋值运算符,把这个临时对象的资源转移给a,不需要额外的std::move。Case 2:显式使用std::move
std::move的作用是把一个左值转换成右值引用,但这里的make_unique返回的已经是右值了,所以std::move(make_unique<int>(5))其实是多此一举——它不会改变这个临时对象的右值属性,编译器处理起来和Case1完全一致,生成的机器码没有任何区别。
总结建议
- 两种写法在功能、性能上完全等价,编译后的代码没有差异
- 直接用Case1的写法更简洁,是业界推荐的常规写法
- Case2的写法虽然语法上没问题,但属于冗余代码,没必要额外添加
内容的提问来源于stack exchange,提问作者AhSeng Fan
相关产品推荐
相关产品推荐

