ホームページ >バックエンド開発 >C++ >`std::move` を使用せずに `std::unique_ptr` を返すにはどうすればよいですか?

`std::move` を使用せずに `std::unique_ptr` を返すにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-22 05:01:09992ブラウズ

How Can I Return a `std::unique_ptr` Without Using `std::move`?

std::move を使用せずに std::unique_ptr を返す: どのようにして可能ですか?

std:: でのコピー構築の禁止にもかかわらずunique_ptr を返すことができます。 std::unique_ptr std::move を使用せずに関数から。この明らかな矛盾は、C 言語仕様で許可されている特定の例外に根ざしています。

例外: コピー省略

C では、次で定義されているように、特定の状況下でコピー省略が許可されます。 12.8 §34 および §35。そのようなケースの 1 つは、関数の戻り値の型と同じ cv 非修飾型を持つ不揮発性自動オブジェクトが返される場合です。このシナリオでは、コンパイラはコピー構築プロセスを省略することができます。この省略は、コピーと移動の両方に適用されます。

コピー省略の実装

コピー省略が return ステートメントで使用される場合、コンパイラは最初にオブジェクトを次のようにみなします。オーバーロード解決の目的で、左辺値であっても右辺値を使用します。したがって、移動コンストラクターが使用可能な場合はそれが選択されますが、実際の移動操作は実行されません。これにより、プレースホルダーとして機能し、一意のポインターの所有権セマンティクスを維持する空の移動コンストラクター呼び出しが行われます。

次のコードは、この現象を示しています。

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

  return p; // Line 1, copy elision applied
}

int main()
{
  unique_ptr<int> p = foo();

  cout << *p << endl;
  return 0;
}

1 行目では、返された unique_ptrオーバーロードの解決中に右辺値として扱われます。移動コンストラクタが利用可能なので、それを選択します。ただし、実際の戻り値は、移動された値ではなく、不揮発性の自動オブジェクト p です。コンパイラはコピー/移動構造を省略し、unique_ptr を返すことを許可します。 std::move.

結論

コピー コンストラクターの禁止に対するこの例外は、効率的で簡潔な return ステートメントを容易にするために、C 言語仕様によって特別に許可されています。ただし、コピー省略は、コンパイラーが実行する場合と実行しない場合がある最適化であることに注意することが重要です。そのため、意図した動作を保証するために、return ステートメントで std::move を明示的に使用することが一般的に推奨されます。

以上が`std::move` を使用せずに `std::unique_ptr` を返すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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