ホームページ >バックエンド開発 >C++ >`std::unique_ptr` を返すのに `std::move()` が必要ないのはなぜですか?

`std::unique_ptr` を返すのに `std::move()` が必要ないのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-22 18:03:10414ブラウズ

Why Does Returning a `std::unique_ptr` Not Require `std::move()`?

std::move() を使用せずに std::unique_ptr を返す理由

std::unique_ptrコピー構築を防止し、代わりに移動セマンティクスを採用します。ただし、 unique_ptr を返すことは可能です。

次のコード スニペットを考えてみましょう。

unique_ptr<int> foo()
{
  unique_ptr<int> p(new int(10));

  return p; // Line 1
}

int main()
{
  unique_ptr<int> p = foo();
  cout << *p << endl;
}

行 1 は、std::move() を使用せずに unique_ptr を返します。驚くべきことに、コードは意図したとおりにコンパイルされ、動作します。では、コピー コンストラクターを呼び出さずに、どのようにしてこれが可能になるのでしょうか?

言語仕様の悪用

この動作を理解する鍵は、C 言語仕様にあります。具体的には、セクション 12.8 §34 および §35 でコピー省略について説明します。

特定の基準が満たされる場合、実装はクラス オブジェクトのコピー/移動構築を省略することができます [...].

この場合、次の理由からコピー省略が許可されます:

  • 戻り値は一時的なものであるobject.
  • 一時オブジェクトは関数の戻り値の型と同じ型を持ちます。
コピー操作の省略基準が満たされ、コピーされるオブジェクトが次のように指定されている場合左辺値、コピーのコンストラクターを選択するオーバーロード解決は、オブジェクトが右辺値で指定されているかのように最初に実行されます。

これは、戻り値が名前付きオブジェクト (左辺値) であっても、オーバーロード解決では依然としてそれが右辺値と見なされます。したがって、move コンストラクターは呼び出されず、返された unique_ptr は正常に構築されます。

結論

std::move() を使用せずに unique_ptr を返す機能は、C 言語の微妙な機能です。言語仕様。コピー省略の条件が満たされている限り、関数から unique_ptr を返すときに std::move() を明示的に使用する必要はありません。これにより、コードの明瞭さが向上し、不必要な移動操作が削減されます。

以上が`std::unique_ptr` を返すのに `std::move()` が必要ないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。