26

可能重复:
从函数返回 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)

4

3 回答 3

47

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

  return std::move(p);

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

在 main 函数中,bar()产生一个临时值,它是一个右值,并且也被正确地移动到pin 中main

于 2012-03-22T17:18:27.807 回答
17

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

return 语句等价于:

return std::move(p);

学究式地说,这在语义上是等价的。实际上,编译器可以优化代码,省略对移动构造函数的调用。但这只有在您将其编写为时才有可能:

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

这是推荐的。但是,如果你这样写,编译器就没有机会优化:

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

建议这样做。:-)

于 2012-03-22T17:18:47.447 回答
1

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

于 2012-03-22T17:17:08.943 回答