为什么'operator>'需要const,而'operator <'不需要const?

Roc*_*645 56 c++ sorting operator-overloading

考虑一下这段代码:

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它编译得很好并且给出了预期的输出.但是,如果我尝试按降序排序结构:

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误.这是完整的信息:

/usr/include/c++/7.2.0/bits/stl_function.h:实例化'constexpr bool std :: greater <_Tp> :: operator()(const _Tp&,const _Tp&)const [with _Tp = MyStruct]' :/
usr/include/c++/7.2.0/bits/stl_function.h:376 :20 :错误:'operator>'不匹配(操作数类型是'const MyStruct'和'const MyStruct')
{return __x> __y ; }

这似乎是因为这里的函数没有const限定符:

bool operator > (const MyStruct& other) {
        return (key > other.key);
}
Run Code Online (Sandbox Code Playgroud)

如果我添加它,

bool operator > (const MyStruct& other) const {
        return (key > other.key);
}
Run Code Online (Sandbox Code Playgroud)

然后一切都很好.为什么会这样?我不太熟悉运算符重载,所以我只是把它放在我们需要添加的内存中,const但它仍然很奇怪,为什么它operator<没有const.

Sto*_*ica 84

您会得到不同的行为,因为您实际上正在调用两个不同的(重载)排序函数.

在第一种情况下,您调用直接std::sort使用的两个参数operator<.由于向量元素的迭代器产生非const引用,因此它可以应用operator<得很好.

在第二种情况下,您使用的是三参数版本std::sort.接受仿函数的那个​​.你过去了std::greater.该仿函数operator()声明如下:

constexpr bool operator()( const T& lhs, const T& rhs ) const;
Run Code Online (Sandbox Code Playgroud)

请注意const引用.它绑定了与const引用进行比较所需的元素.所以你自己也operator>必须是正确的.

如果你要打电话std::sortstd::less,你operator<会产生同样的错误,因为它不是常量,正确的.


R S*_*ahu 25

使用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成员函数都应该成为成员函数.