std::move called on an unmovable type

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

Описание

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

Риск

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

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

Если класс является дорогим, чтобы скопировать, непреднамеренная операция копии может вызвать потерю эффективности.

Фиксация

Сделать объект типа T подвижный, добавьте конструктора перемещения:

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