Почему 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 ответа:
вы получаете разное поведение, потому что вы на самом деле вызываете два разных (перегруженных) вроде функции.
в первом случае вы вызываете два параметра
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-правильно.