c++ 为什么我似乎可以在return语句中复制std::unique_ptr?[副本]

gc0ot86w  于 2023-10-21  发布在  其他
关注(0)|答案(3)|浏览(99)

此问题已在此处有答案

10年前关闭。

可能重复:

Returning unique_ptr from functions
20.7.1.2 [unique.ptr.single]这样定义复制构造函数:

// disable copy from lvalue
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;

那么,为什么下面的代码编译得很好呢?

#include <memory>
#include <iostream>

std::unique_ptr< int > bar()
{
  std::unique_ptr< int > p( new int(4));
  return p;
}

int main()
{
  auto p = bar();

  std::cout<<*p<<std::endl;
}

我是这样编译的:

g++ -O3  -Wall -Wextra -pedantic -std=c++0x kel.cpp

编译器:g++版本4.6.1 20110908(Red Hat 4.6.1-9)

57hvy0tb

57hvy0tb1#

在return语句中,如果你返回一个局部变量,表达式被视为右值,因此会自动 * 移动 *。因此,它类似于:

return std::move(p);

它调用unique_ptr(unique_ptr&&)构造函数。
在main函数中,bar()产生一个临时值,它是一个右值,并且也被正确地移动到main中的p中。

aamkag61

aamkag612#

它不是 * 复制 *,而是 * 移动 *。
return语句相当于这样:

return std::move(p);

从教育学的Angular 来说,这是语义上的等价。实际上,编译器可以优化代码,省略对移动构造函数的调用。但只有当你把它写为:

return p; //It gives the compiler an opportunity to optimize this.

建议这样做。然而,如果你这样写,编译器就没有机会优化了:

return std::move(p); //No (or less) opportunity to optimize this.

这是**不推荐。:-)

plicqrtu

plicqrtu3#

我认为从左值复制是禁用的,但“bar()”是一个右值,所以它是可以的。你一定要能够从右值复制。

相关问题