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.110110908(Red Hat 4.6.1-9)

4

3 に答える 3

47

returnステートメントでローカル変数を返すと、式は右辺値として扱われるため、自動的に移動されます。したがって、次のようになります。

  return std::move(p);

unique_ptr(unique_ptr&&)コンストラクターを呼び出します。

main関数で、bar()は一時値を生成します。これは右辺値であり、inに適切に移動さpmainます。

于 2012-03-22T17:18:27.807 に答える
17

コピーせず移動します。

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. 

それはお勧めできません。:-)

于 2012-03-22T17:18:47.447 に答える
1

左辺値からのコピーは無効になっていると思いますが、「bar()」は右辺値なので大丈夫です。あなたは間違いなく右辺値からコピーできる必要があります。

于 2012-03-22T17:17:08.943 に答える