1. ホーム
  2. c++

[解決済み] なぜデフォルトのmove-assignment/move-constructorがないのですか?

2023-03-20 06:41:34

疑問点

私は単純なプログラマです。 私のクラスのメンバー変数は、ほとんどの場合、POD-typesとSTL-containersで構成されています。このため、代入演算子やコピーコンストラクタはデフォルトで実装されているので、めったに書く必要はありません。

これに加えて、もし私が std::move を使うと、assign-operator を使うことになります。 std::move は完全に安全であることを意味します。

私は単純なプログラマなので、私が書くすべてのクラスに移動コンストラクタ/代入演算子を追加することなく、移動機能を利用したいと思います。 this->member1_ = std::move(other.member1_);... というように実装することができます。

しかし、(少なくともVisual 2010では)そうならないのですが、何か特別な理由があるのでしょうか?

もっと重要なのは はこれを回避する方法はありますか?

更新しました。 GManNickGの回答を見ると、彼はこのための素晴らしいマクロを提供しています。そして、もしあなたが知らなかったのなら、move-semanticsを実装すれば、swapメンバ関数を削除することができます。

どのように解決するのですか?

移動コンストラクターと代入演算子の暗黙の生成は議論の的になっており、C++ 標準の最近のドラフトで大きな改訂があったため、現在利用可能なコンパイラーは暗黙の生成に関して異なる動作をする可能性があります。

この問題の歴史について詳しくは 2010 年 WG21 論文リスト を参照し、"mov" で検索してください。

現在の仕様書(N3225、11月~)には、(N3225 12.8/8)と記載されています。

もし、クラスの定義が X の定義が移動コンストラクタを明示的に宣言していない場合、以下の場合に限り、暗黙のうちにデフォルトとして宣言されます。

  • X は、ユーザが宣言したコピーコンストラクタを持たず、かつ

  • X は、ユーザが宣言したコピー代入演算子を持ちません。

  • X は、ユーザが宣言した移動代入演算子を持ちません。

  • X は、ユーザが宣言したデストラクタを持たず

  • 移動コンストラクタは暗黙のうちに削除されたと定義されることはないでしょう。

12.8/22 には、移動代入演算子が暗黙のうちに defaulted として宣言される場合を指定する同様の文言があります。 暗黙的な移動生成の現在の仕様をサポートするために行われた変更の完全なリストは、以下を参照してください。 N3203: 暗黙の着手の生成条件の厳格化 これは、Bjarne Stroustrup の論文で提案された解決策の1つに大きく基づいています。 N3201: 正しい方向に進む .