考虑这段代码:
#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;
}
}
这给了我一个错误。 Here is the full message:
/ usr / include / c ++ / 7.2.0 / bits / stl_function.h:实例化'constexpr bool std :: greater&lt; _Tp&gt; :: operator()(const _Tp&amp;,const _Tp&amp;)const [with _Tp = MyStruct]':
/usr/include/c++/7.2.0/bits/stl_function.h:376:20:错误:'运营商&gt;'不匹配(操作数类型是'const MyStruct'和'const MyStruct')
{return __x&gt; __y; }
似乎是因为这里的这个功能没有const
限定符:
bool operator > (const MyStruct& other) {
return (key > other.key);
}
如果我添加它,
bool operator > (const MyStruct& other) const {
return (key > other.key);
}
然后一切都很好。为什么会这样?我不太熟悉运算符重载,所以我只是把它放在内存中我们需要添加const
但是它仍然很奇怪为什么它适用于没有operator<
的{{1}}
答案 0 :(得分:81)
您会遇到不同的行为,因为您实际上正在调用两个不同的(重载)sort函数。
在第一种情况下,您调用两个参数std::sort
,它直接使用operator<
。由于向量元素的迭代器产生非const引用,因此它可以很好地应用operator<
。
在第二种情况下,您使用的是std::sort
的三参数版本。接受仿函数的那个。你通过了std::greater
。该仿函数的operator()
声明如下:
constexpr bool operator()( const T& lhs, const T& rhs ) const;
注意const引用。它绑定了与const引用进行比较所需的元素。所以你自己的operator>
也必须是正确的。
如果您使用std::less
致电std::sort
,则operator<
会产生相同的错误,因为它不是常规错误。
答案 1 :(得分:24)
std::sort(vec.begin(), vec.end())
的使用仅取决于operator<
功能。它不要求该函数能够使用const
个对象。
std::greater
要求该函数能够使用const
个对象。
如果您使用std::less
,则会发现类似的问题,例如std::sort(vec.begin(), vec.end(), std::less<MyStruct>())
。
话虽如此,operator<
函数和operator>
函数没有理由成为非const
成员函数。任何不修改成员数据的成员函数都应该成为const
成员函数。