为什么“操作员”需要const但不是为“运营商<”

Why is const required for 'operator>' but not for 'operator<'?

本文关键字:运营商 操作员 lt 需要 const 为什么      更新时间:2023-10-16

考虑此代码:

#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.h:在实例化'constexpr bool std :: greem&lt; _tp> :: operator((((_tp = mystruct]':
/USR/include/c /7.2.0/bits/stl_function.h:376:20:错误:'operand类型>'无匹配(操作数类型是'const myStruct''和'const myStruct'(
(
{返回__x> __y;}

似乎是因为此功能在这里没有const预选赛:

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

如果我添加,

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

那么一切都很好。为什么这样?我不太熟悉操作员的过载,所以我只是把它放在内存中,我们需要添加const,但是它仍然很奇怪,为什么它适用于operator<,没有const

您会得到不同的行为,因为实际上您正在调用两个不同的(超载(排序功能。

在第一种情况下,您调用两个参数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<会产生相同的错误,因为它不正确。

使用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成员函数。