【问题标题】:Why am I allowed to copy unique_ptr? [duplicate]为什么我可以复制 unique_ptr? [复制]
【发布时间】:2012-03-22 17:14:51
【问题描述】:

可能重复:
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++ version 4.6.1 20110908 (Red Hat 4.6.1-9)

【问题讨论】:

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


【解决方案1】:

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

  return std::move(p);

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

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

【讨论】:

  • 不,子对象不会自动移动。
  • 12.8/31 有我的问题中的确切示例。你和纳瓦兹都是对的
  • @Xeo 你是对的。周围没有问题吗?是的,有stackoverflow.com/questions/9183087/…
  • "因此等同于:return std::move(p);" 几乎——后者不抑制 (N)RVO 吗?
  • @ildjarn 嗯,也许吧。标准措辞将其描述为“当满足复制省略的标准时,它是一个左值,它被视为重载解析的右值”。我不知道这是否会影响。反正我会改写的。
【解决方案2】:

不是 复制,它是移动

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. 

这是推荐的。 :-)

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 实际上,这是从右值的移动,而不是复制。
    猜你喜欢
    • 2018-07-11
    • 2018-05-22
    • 2018-05-28
    • 1970-01-01
    • 2018-07-19
    • 2021-10-30
    • 1970-01-01
    • 2013-07-08
    • 2019-03-28
    相关资源
    最近更新 更多