メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

移動操作によってスローされる可能性があります

移動操作をスローすると、対応するコピー操作が STL コンテナーで使用される場合がある

説明

この欠陥は、noexcept 指定子が欠落している、または、引数が false に評価される noexcept 指定子が含まれている移動コンストラクターをクラスで明示的に宣言した場合に発生します。また、この欠陥は、明示的に宣言されたコンストラクターに throw(type) 例外指定が含まれている場合にも発生します (C++11 で非推奨、C++17 で削除)。

チェッカーは、移動コンストラクターが暗黙的に宣言されるか、=default として明示的に宣言された場合はフラグを設定しません。

リスク

移動操作で例外がスローされる可能性がある場合は、一部の STL コンテナーで代わりにコピー操作が使用され、移動操作のパフォーマンスの向上は見られません。たとえば、std::vector::resize メソッドの実装では、std::move_if_noexcept が使用され、移動操作が noexcept と宣言されている場合にのみ、ベクトルのサイズを変更するために移動操作が実行されます。

修正方法

noexcept 指定子を移動コンストラクターの宣言に追加します。

移動コンストラクターにスローする可能性のある式が含まれている場合は、そのような式を修正します。noexcept 例外指定の違反を検出するには、チェッカー [関数 noexcept が例外で終了] を使用します。

パフォーマンスの改善の程度は、使用しているコンパイラ、ライブラリ実装、環境によって異なる可能性があります。

すべて展開する

#include <string>

class Database {
  private:
      std::string* initEntry;
      int size;
  public:
      //Copy constructor
      Database (const Database& other);
      //Move constructor
      Database (Database&& other): initEntry{other.initEntry}, size{other.size} {
      other.initEntry = nullptr;
      other.size = 0;
    }
};

この例では、Database 移動コンストラクターに noexcept 指定が含まれていません。

修正 – noexcept 指定子を追加

noexcept 指定子を移動コンストラクターに追加します。

#include <string>

class Database {
   private:
       std::string* initEntry;
       int size;
   public:
       //Copy constructor
       Database (const Database& other);
       //Move constructor
       Database (Database&& other) noexcept: initEntry{other.initEntry}, size{other.size} {
       other.initEntry = nullptr;
       other.size = 0;
       }
};

結果情報

グループ: パフォーマンス
言語: C++
既定値: オフ
コマンド ライン構文: MOVE_OPERATION_MAY_THROW
影響度: Low

バージョン履歴

R2020b で導入