11
std::unique_ptr<int> ptr() {
    std::unique_ptr<int> p(new int(3));
    return p;  //  Why doesn't this require explicit move using std::move?
}  // Why didn't the data pointed to by 'p' is not destroyed here though p is not moved?

int main() {
    std::unique_ptr<int> a = ptr();  // Why doesn't this require std::move? 
    std::cout << *a; // Prints 3.
}

上記のコードでは、関数ptr()は のコピーを返しますp。範囲外にpなると、データ「3」が削除されます。しかし、コードはアクセス違反なしでどのように機能するのでしょうか?

4

2 に答える 2

15

これは、C++11 標準の§ 12.8/32で規定されています。

コピー操作の省略の基準が満たされているか、ソース オブジェクトが関数パラメーターであり、コピーされるオブジェクトが左辺値によって指定されているという事実を除いて満たされる場合、コピーのコンストラクターを選択するためのオーバーロードの解決は次のとおりです。オブジェクトが右辺値によって指定されたかのように最初に実行されます ....

(強調鉱山)。簡単に言えば、オーバーロードの解決に関しては、 lvalueはcopy elisionの候補であるため、pとして扱うことができることを意味します。これは、ムーブ コンストラクターがオーバーロードの解決時に取得されることを意味します (実際には、いずれにせよムーブ コピーは省略される可能性があります)。rvalue

于 2014-09-17T07:58:16.453 に答える
6

移動演算子が使用可能な場合、ローカル自動変数returnなどの特定の式は、移動したオブジェクトを返すように明示的に定義されているためです。

そう:

return p;

多かれ少なかれ似ています:

return std::move(p);

ただし、これはたとえばグローバル変数では機能しないことに注意してください。

std::unique_ptr<int> g(new int(3));
std::unique_ptr<int> ptr() {
    return g;  //  error!!!
}
于 2014-09-17T07:56:25.970 に答える