C++ 为什么我可以复制唯一的ptr?

C++ 为什么我可以复制唯一的ptr?,c++,g++,c++11,unique-ptr,C++,G++,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; g++ -O3 -Wall -Wextra -pedantic -std=c++0x kel.cpp 那么,为什么下面的代码编译得很好呢

可能重复:

20.7.1.2[unique.ptr.single]对复制构造函数的定义如下:

// disable copy from lvalue
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
g++ -O3  -Wall -Wextra -pedantic -std=c++0x kel.cpp
那么,为什么下面的代码编译得很好呢

#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++版本4.6.1 20110908(Red Hat 4.6.1-9)

我认为从左值复制是禁用的,但是“bar()”是右值,所以可以。您肯定需要能够从右值进行复制。

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

  return std::move(p);
它调用
unique\u ptr(unique\u ptr&&)
构造函数


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

中,它是未复制的,它是移动的

return语句相当于以下语句:

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. 

这是建议的。:-)

+1,感谢您告诉我们您使用的编译器以及您是如何编译代码的。StackOverflow上罕见的一幕。看到了吗,实际上,这是从右值移动,而不是复制。不,子对象不会自动移动。12.8/31中有一个与我的问题完全相同的例子。你和纳瓦兹都是right@Xeo你说得对。这不是一个问题吗?是的,这里有“它因此与:
返回std::move(p);
”几乎——后者不抑制(N)RVO吗?@ildjarn-Hmm,也许。标准的措辞是这样描述的:“当满足复制省略的标准时,它是一个左值,它被视为重载解析的右值。”我不知道这是否会影响它。不管怎样,我还是要改写。