Как я могу использовать std:: sort с объектами, у которых нет конструктора копирования?

Я пытаюсь отсортировать вектор, содержащий объекты, которые не являются конструктивными или конструктивными по умолчанию (но являются конструктивными), но я получаю ошибки в том, что компилятор не может найти допустимую функцию для swap. Я думал, что достаточно иметь конструктор движений. Что мне здесь не хватает?

class MyType {
public:
    MyType(bool a) {}
    MyType(const MyType& that) = delete;
    MyType(MyType&& that) = default;
};

int main(void) {
    vector<MyType> v;
    v.emplace_back(true);
    sort(v.begin(), v.end(), [](MyType const& l, MyType const& r) {
        return true;
    });
}

Ответ 1

Вам нужно явно указать оператор назначения переноса, так как это std::sort также пытается (не просто переместить конструкцию). Обратите внимание, что генерация компилятора оператора присваивания перемещения запрещена наличием созданного пользователем конструктора копий, а также наличием конструктора перемещения пользователя (даже если они delete -ed). Пример:

#include <vector>
#include <algorithm>

class MyType {
public:
    MyType(bool a) {}
    MyType(const MyType& that) = delete;
    MyType(MyType&& that) = default;
    MyType& operator=(MyType&&) = default; // need this, adapt to your own need
};

int main(void) {
    std::vector<MyType> v;
    v.emplace_back(true);
    std::sort(v.begin(), v.end(), [](MyType const& l, MyType const& r) {
        return true;
    });
}

Live on Coliru

slides Говард Хиннант (главный вкладчик в движение семантика в С++ 11) являются супер полезными, а также пунктом 17: Понимание специальной генерации функции-члена из Эффективный современный С++ Скотта Мейерса.