首页 文章

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

提问于
浏览
55

考虑这段代码:

#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 <_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);
}

如果我添加它,

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

然后一切都很好 . 为什么会这样?我只是把它放在内存中我们需要添加 const 但是它仍然很奇怪为什么它适用于没有 constoperator< .

2 回答

  • 24

    您会得到不同的行为,因为您实际上正在调用两个不同的(重载的)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< 将产生相同的错误,因为它不是const-correct .

  • 81

    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 成员函数 .

相关问题