exponenta event banner

std::move вызывается для неподвижного типа

std::move используется для типа класса без конструктора перемещения или оператора назначения перемещения

Описание

Этот дефект возникает при использовании std::move для перемещения объекта типа класса, не имеющего конструктора перемещения или оператора назначения перемещения.

Риск

Использование std::move в таких заявлениях, как:

Obj objTo {std::move(objFrom)};
objTo = std::move(objFrom);
указывает, что вы хотите извлечь выгоду из повышения производительности операции перемещения. Однако из-за отсутствия конструктора перемещения или оператора назначения перемещения вместо этого выполняется операция копирования.

Если класс является дорогим для копирования, непреднамеренная операция копирования может привести к потере производительности.

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

Создание объекта типа T movable, добавьте конструктор перемещения:

T (T&&);
и оператор назначения перемещения:
T& operator=(T&&);
в класс T. Если класс не должен непосредственно управлять ресурсом, можно использовать созданные компилятором операторы перемещения с помощью =default синтаксис, например:
T (T&&) = default;

В противном случае, если операция перемещения не требуется, удалите std::move вызовите и непосредственно скопируйте объект.

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

Примеры

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

#include <utility>
#include <string>

class stringPair {
    std::string str1;
    std::string str2;

    public:
        stringPair(const stringPair & aPair); //Copy constructor
        stringPair& operator=(const stringPair & aPair);  //Copy assignment operator
};

void exchangePairs (stringPair& first, stringPair& second) {
    stringPair tempPair {std::move(first)};
    first = std::move(second);
    second = std::move(tempPair);
}

В этом примере тип stringPair не имеет конструктора перемещения или оператора назначения перемещения. Использование std::move для объектов этого типа вместо этого выполняются операции копирования.

Исправление - добавление конструктора перемещения и оператора назначения перемещения

Сделайте тип stringPair может быть добавлен конструктор перемещения или оператор назначения перемещения.

#include <utility>
#include <string>

class stringPair {
    std::string str1;
    std::string str2;
    
    public: 
        stringPair(const stringPair & aPair); //Copy constructor
        stringPair(stringPair && aPair) noexcept; //Move constructor
        stringPair& operator=(const stringPair & aPair);  //Copy assignment operator
        stringPair& operator=(stringPair && aPair) noexcept; //Move assignment operator
};

void exchangePairs (stringPair& first, stringPair& second) {
    stringPair tempPair {std::move(first)};
    first = std::move(second);
    second = std::move(tempPair);
}
Исправление -- Удалить std::move звонить

Если тип не требуется stringPair подвижный, опустить std::move вызовы.

#include <utility>
#include <string>

class stringPair {
    std::string str1;
    std::string str2;
    
    public: 
        stringPair(const stringPair & aPair); //Copy constructor
        stringPair& operator=(const stringPair & aPair);  //Copy assignment operator
};

void exchangePairs (stringPair& first, stringPair& second) {
    stringPair tempPair {first};
    first = second;
    second = tempPair;
}

Информация о результатах

Группа: Производительность
Язык: C++
По умолчанию: Откл.
Синтаксис командной строки: STD_MOVE_UNMOVABLE_TYPE
Воздействие: среднее
Представлен в R2020b