重複の可能性:
関数から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.120110908(Red Hat 4.6.1-9)
Returnステートメントでローカル変数を返すと、式は右辺値として扱われるため、自動的にmovedになります。したがって、次のようになります。
_ return std::move(p);
_
unique_ptr(unique_ptr&&)
コンストラクターを呼び出します。
メイン関数では、bar()
は一時値を生成します。これは右辺値であり、p
のmain
にも適切に移動されます。
notコピー、移動。
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.
つまりnot推奨されます。 :-)
左辺値からのコピーは無効になっていると思いますが、「bar()」は右辺値なので大丈夫です。あなたは間違いなく右辺値からコピーできる必要があります。