7

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);
}
4
  • 2
    @EvanTeran A has copy and move constructors. It's the assignment operators that are the problem for std::swap. Commented Nov 15, 2017 at 21:47
  • @aschepler thanks for the correction. I made sure to get it right when converting my comment to an answer :-) Commented Nov 15, 2017 at 21:48
  • 1
    A(int id) : id(id) {} this is not a good idea Commented Nov 15, 2017 at 21:51
  • @Slava Why not? Commented Nov 16, 2017 at 8:49

1 Answer 1

5

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_;
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.