为什么允许我复制unique_ptr

Why am I allowed to copy unique_ptr?

本文关键字:ptr unique 复制 允许我 为什么      更新时间:2023-10-16

可能重复:
从函数返回unique_ptr

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)

在return语句中,如果返回局部变量,则表达式将被视为右值,从而自动移动。因此,它类似于:

  return std::move(p);

它调用unique_ptr(unique_ptr&&)构造函数。

在主函数中,bar()生成一个临时值,它是一个右值,并且也被适当地移动到main中的p中。

它不是复制的,它是移动的

返回语句等效于:

return std::move(p);

从教学意义上讲,这在语义上是等价的。实际上,编译器可能会优化代码,从而省略对move构造函数的调用。但只有当你把它写成:时,这才有可能

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

这是建议的。然而,如果您编写以下内容,编译器就没有机会进行优化:

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

这是不推荐的。:-)

我认为从左值复制是禁用的,但"bar()"是右值,所以没关系。你肯定需要能够从右值复制。