A move operation may throw

Операции выдачи перемещения могут привести к тому, что контейнеры STL будут использовать соответствующие операции копирования

Описание

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

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

Риск

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

Зафиксировать

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

Если конструктор перемещения содержит выражения, которые могут выдать, исправьте эти выражения. Обнаружение нарушений noexcept спецификация исключения, используйте checker 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