为什么我可以复制unique_ptr?

时间:2012-03-22 17:14:52

标签: c++ g++ c++11 unique-ptr

  

可能重复:
  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)

3 个答案:

答案 0 :(得分:43)

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

  return std::move(p);

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

在主要功能中,bar()会产生一个临时值,这是一个右值,并且也会正确移动到p中的main

答案 1 :(得分:16)

已复制已移动

return语句等同于:

return std::move(p);

迂腐地说,这是语义等价的。实际上,编译器可以优化代码,从而忽略对move-constructor的调用。但只有当你把它写成:

时才有可能
return p; //It gives the compiler an opportunity to optimize this. 

这是推荐的。但是,如果您编写此代码,编译器将无法进行优化:

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

建议。 : - )

答案 2 :(得分:1)

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