Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a vector of custom objects with const member

Tags:

c++

sorting

stl

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);
}
like image 323
Koach Avatar asked Nov 15 '17 21:11

Koach


People also ask

Can you sort a const vector?

Yes, you can sort a const vector in C++. Let a const vector is v. const vector<int> v={5,4,3,2,1}; If you want to sort this vector using sort(v.

How do I sort custom vectors?

You can sort a vector of custom objects using the C++ STL function std::sort. The sort function has an overloaded form that takes as arguments first, last, comparator. The first and last are iterators to first and last elements of the container.

How do you sort the elements of a vector?

A vector in C++ can be easily sorted in ascending order using the sort() function defined in the algorithm header file. The sort() function sorts a given data structure and does not return anything. The sorting takes place between the two passed iterators or positions.

How do you sort a vector without sorting?

The vector can use the array notation to access the elements. If you don't want to use the default std::sort , or std::sort with custom comparator, you can use qsort or write your own.


1 Answers

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_;
};
like image 55
Evan Teran Avatar answered Oct 14 '22 22:10

Evan Teran