C 11 では、非論理的に見えるかもしれないアクションである const オブジェクトに対して std::move を呼び出すことが許可されています。そのようなオブジェクトの不変性を考えると。この動作は、微妙なプログラミング エラーを引き起こす可能性があるという懸念を引き起こしています。
ただし、std::move(const) は実際のオブジェクトを変更しないことに注意することが重要です。代わりに、コンパイラに移動操作を試行するように指示するだけです。オブジェクトが移動セマンティクスをサポートしていない場合 (互換性のあるコンストラクターがないなど)、コンパイラーは代わりにコピー コンストラクターを自動的に呼び出します。
この動作により、開発者は、次のようなオブジェクトに対して std::move を安全に使用できます。または、移動セマンティクスをサポートしていない可能性があります。移動操作が可能な場合、コンパイラは所有権を効率的に転送し、パフォーマンスを最適化します。ただし、移動がサポートされていない場合でも、コピーに関連するパフォーマンスの低下はありますが、コードは引き続き正しく機能します。
提供された例では、
struct Cat { Cat(){} }; const Cat cat; std::move(cat); //this is valid in C++11
std::move( cat) は移動コンストラクターを定義していないため、コピー コンストラクターを効果的に呼び出します。したがって、オブジェクトの const の性質は維持され、エラーや予期せぬ動作は発生しません。
Scott Meyers の例の Annotation クラスの場合:
class Annotation { public: explicit Annotation(const std::string text) : value(std::move(text)) };
コンパイラstd::string(std::string&&) コンストラクターを呼び出そうとしますが、text が const であるため、std::move(text) の実際の型は const std::string&& となり、必要な std と一致しません。 :弦&&。その結果、代わりに std::string(const std::string&) コンストラクターが呼び出され、パフォーマンスは低下しますが、エラーにはなりません。
したがって、std:: を呼び出すのは直観に反するように思えるかもしれませんが、 const オブジェクト上で移動する場合、本質的にエラーや不安定性が生じることはありません。代わりに、コンパイラーが特定のオブジェクトの移動セマンティクスの利用可能性に基づいて適切なアクションを決定できるようにすることで、柔軟で効率的なコードを実現します。
以上がC 11 では const オブジェクトで `std::move` が許可されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。