Почему const требуется для ' operator>', но не для ' operator


рассмотрим этот фрагмент кода:

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

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

    bool operator < (const MyStruct& other) {
        return (key < other.key);
    }
};

int main() {
    std::vector < MyStruct > vec;

    vec.push_back(MyStruct(2, "is"));
    vec.push_back(MyStruct(1, "this"));
    vec.push_back(MyStruct(4, "test"));
    vec.push_back(MyStruct(3, "a"));

    std::sort(vec.begin(), vec.end());

    for (const MyStruct& a : vec) {
        cout << a.key << ": " << a.stringValue << endl;
    }
}

он прекрасно компилируется и дает результат, который можно было бы ожидать. Но если я попытаюсь отсортировать структуры в порядке убывания:

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

struct MyStruct
{
    int key;
    std::string stringValue;

    MyStruct(int k, const std::string& s) : key(k), stringValue(s) {}

    bool operator > (const MyStruct& other) {
        return (key > other.key);
    }
};


int main() {
    std::vector < MyStruct > vec;

    vec.push_back(MyStruct(2, "is"));
    vec.push_back(MyStruct(1, "this"));
    vec.push_back(MyStruct(4, "test"));
    vec.push_back(MyStruct(3, "a"));

    std::sort(vec.begin(), vec.end(), greater<MyStruct>());

    for (const MyStruct& a : vec) {
        cout << a.key << ": " << a.stringValue << endl;
    }
}

это дает мне ошибку. вот полное сообщение:

/usr / include/c++/7.2.0/bits / stl_function.ч: в экземпляр 'боол СТД помощью constexpr::большой::оператор()(константный _Tp&, const и _Tp&) const и [с _Tp = MyStruct]':
/usr / include/c++/7.2.0/bits / stl_function.h: 376: 20: ошибка: нет соответствия для ' operator> '(типы операндов 'const MyStruct' и 'const MyStruct')
{ return _ _ x > _ _ y;}

кажется, что эта функция здесь не было!--4--> классификатор:

bool operator > (const MyStruct& other) {
        return (key > other.key);
}

если я добавлю его,

bool operator > (const MyStruct& other) const {
        return (key > other.key);
}

тогда все снова в порядке. Почему это так? Я не слишком знаком с перегрузкой оператора, поэтому я просто положил его в память, что нам нужно чтобы добавить const но все равно странно, почему это работает для operator< без const.

2 55

2 ответа:

вы получаете разное поведение, потому что вы на самом деле вызываете два разных (перегруженных) вроде функции.

в первом случае вы вызываете два параметра std::sort, который использует operator< напрямую. Поскольку итераторы для ваших векторных элементов создают неконстантные ссылки, он может применяться operator< просто отлично.

во втором случае вы используете версию с тремя параметрами std::sort. Тот, который принимает функтор. Вы проходите std::greater. И что функтор имеет operator() объявляется следующим образом:

constexpr bool operator()( const T& lhs, const T& rhs ) const;

обратите внимание на ссылки const. Он связывает элементы, необходимые для сравнения с ссылками const. Так что ваш собственный operator> должно быть const правильно, а также.

если вы std::sort С std::less ваш operator< будет производить ту же ошибку, потому что это не const-правильно.

использование std::sort(vec.begin(), vec.end()) зависит только от неconst функции-члены. Любая функция-член, которая не изменяет данные члена, должна быть сделана const функции-члена.