Koach
Koach

Reputation: 63

Sorting a vector of custom objects with const member

I would like to sort a vector holding objects of a class with a const member variable.
Unfortunately, I get an error stating that there is "no matching function for call to "swap"".

When I remove the const keyword for id, then std::sort() works with both the overloaded operator<() and the custom compare function.

Why is this the case? Can I in general not sort objects belonging to a class with a const member variable?

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct A
{
    const int id;
    A(int id) : id(id) {}
    bool operator<(const A &other) const
    {
        return id < other.id;
    }
};

bool cmp(const A &lhs, const A &rhs)
{
    return lhs.id < rhs.id;
}

int main()
{
    vector<A> vec;
    vec.emplace_back(3);
    vec.emplace_back(0);
    vec.emplace_back(2);
    vec.emplace_back(1);
    std::sort(vec.begin(), vec.end());
    std::sort(vec.begin(), vec.end(), cmp);
}

Upvotes: 6

Views: 1304

Answers (1)

Evan Teran
Evan Teran

Reputation: 90452

Well, the way that sort is going to be implemented is that it will swap objects as needed. A class with a const member and no copy or move assignment operators is not going to be "swappable".

I would probably make the id member private and non-const. Then I'd have it accessed via a getter (but not providing a setter). Making it logically const, but the class would be copyable.

Something like this:

class A {
public:
    A(int id) : id_(id) {}

    bool operator<(const A &other) const {
        return id_ < other.id_;
    }

    int id() const { return id_; }

private:
    int id_;
};

Upvotes: 5

Related Questions