为什么我可以复制unique_ptr?

BЈо*_*вић 23 c++ g++ unique-ptr c++11

可能重复:
从函数返回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;
Run Code Online (Sandbox Code Playgroud)

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

我编译它像这样:

g++ -O3  -Wall -Wextra -pedantic -std=c++0x kel.cpp
Run Code Online (Sandbox Code Playgroud)

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

R. *_*des 44

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

  return std::move(p);
Run Code Online (Sandbox Code Playgroud)

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

在main函数中,bar()生成一个临时的,它是一个rvalue,并且也可以正确地移入pin中main.

  • "*因此它是相同的:`return std :: move(p);`*"几乎 - 后者不会抑制(N)RVO? (4认同)

Naw*_*waz 16

没有被 复制,它被移动了.

return语句等同于:

return std::move(p);
Run Code Online (Sandbox Code Playgroud)

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

return p; //It gives the compiler an opportunity to optimize this. 
Run Code Online (Sandbox Code Playgroud)

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

return std::move(p); //No (or less) opportunity to optimize this. 
Run Code Online (Sandbox Code Playgroud)

这是推荐使用.:-)