[英]return std::move a class with a unique_ptr member
为什么我不能使用std::move
语义(我认为)返回包含std::unique_ptr
的 class ,如下例所示? 我认为返回会调用 class A
的移动ctor,这将std::move
std::unique_ptr
。 (我使用的是 gcc 11.2,C++20)
例子:
#include <memory>
class A {
public:
explicit A(std::unique_ptr<int> m): m_(std::move(m)) {}
private:
std::unique_ptr<int> m_;
};
A makit(int num) {
auto m = std::make_unique<int>(num);
return std::move(A(m)); // error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]'x86-64 gcc 11.2 #1
}
int main() {
auto a = makit(42);
return 0;
}
我相信解决方案是返回一个std::unique_ptr
,但在我放弃之前,我想知道为什么移动方法不起作用。
我认为返回会调用 class A 的移动 ctor,这将
std::move
std::unique_ptr
。
都是真的,但移动构造函数只移动A
的成员。 它不能为您移动不相关的卫星唯一指针。
在表达式A(m)
中,您使用m
作为左值。 这将尝试复制m
以初始化A::A
的参数m
(顺便说一句,可怕的命名方案来解释所有这些)。 如果你移动那个,即A(std::move(m))
,表达式就会变得格式良好。
在这个问题上, std::move(A(...))
中的外部std::move
是多余的。 A(...)
已经是A
类型的右值。 额外的std::move
在这里没有什么好处。
简而言之,您不应该使用std::move
返回A
,因为编译器会为您完成优化工作(通过称为 RVO 的技巧: 什么是复制省略和返回值优化? )。
另一点是m_(std::move(m))
中的std::move
::move 是完全没有必要的,因为无论是否使用std::move
都会发生unique_ptr
的处理。 请记住, std::move
不保证移动操作,也不阻止在所有情况下应对。
总之,您最好使用return A( std::move(m) );
并且不return std::move(A(m));
. 在您的 return 语句中, A(m)
已经是一个纯右值,您不需要使用std::move
将其转换为xvalue以有效地返回它。 只需按值返回它,编译器就会为您解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.