A move operation may throw

Бросок операций пересылки может привести к контейнерам STL с помощью соответствующих операций копии

Описание

Этот дефект происходит, когда класс явным образом объявляет конструктора перемещения, который пропускает noexcept спецификатор или имеет noexcept спецификатор, аргумент которого оценивает к false. Дефект также происходит, если у явным образом заявленного конструктора перемещения есть бросок (type) спецификация исключения (удержанный от использования на C++ 11 и удаленный на C++ 17).

Средство проверки не повышает флаг, если конструктор перемещения неявно объявляется или явным образом объявляется как =default.

Риск

Если операция пересылки может выдать исключения, некоторые контейнеры STL будут использовать операции копии вместо этого и не получать выигрыши в производительности операции пересылки. Например, реализация std::vector::resize метод использует std::move_if_noexcept и выполняет операцию пересылки для изменения размеров вектора, только если операция пересылки объявляется noexcept.

Фиксация

Добавьте noexcept спецификатор к объявлению конструктора перемещения.

Если конструктор перемещения содержит выражения, которые могут выдать, зафиксировать те выражения. Обнаружить нарушения noexcept спецификация исключения, используйте средство проверки Noexcept function exits with exception.

Повышения производительности могут варьироваться на основе компилятора, реализации библиотеки и среды, которую вы используете.

Примеры

развернуть все

#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++
Значение по умолчанию: Off
Синтаксис командной строки: MOVE_OPERATION_MAY_THROW
Удар: низко
Введенный в R2020b