Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use std::sort with objects that have no copy constructor?

I'm trying to sort a vector containing objects that are not copy constructible or default constructible (but are move constructible), but I get errors about the compiler not being able to find a valid function for swap. I thought that having a move constructor would be enough. What am I missing here?

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;
    });
}
like image 986
Drew Avatar asked Dec 31 '15 21:12

Drew


1 Answers

You need to explicitly define a move assignment operator, as this is what std::sort also tries (not just move construction). Note that the compiler-generation of a move assignment operator is prohibited by the existence of a user-provided copy constructor, as well as by the existence of a user-provided move constructor (even if they are delete-ed). Example:

#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

The slides by Howard Hinnant (the main contributor to move semantics in C++11) are super useful, as well as Item 17: Understand special member function generation from Effective Modern C++ by Scott Meyers.

like image 168
vsoftco Avatar answered Sep 22 '22 22:09

vsoftco