简体   繁体   English

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

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

Consider this piece of code: 考虑一下这段代码:

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

It compiles fine and gives the output one would expect. 它编译得很好并且给出了预期的输出。 But if I try to sort the structures in descending order: 但是,如果我尝试按降序排序结构:

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

This gives me an error. 这给了我一个错误。 Here is the full message : 这是完整的信息

/usr/include/c++/7.2.0/bits/stl_function.h: In instantiation of 'constexpr bool std::greater<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = MyStruct]': /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: error: no match for 'operator>' (operand types are 'const MyStruct' and 'const MyStruct') /usr/include/c++/7.2.0/bits/stl_function.h:376:20:错误:'operator>'不匹配(操作数类型是'const MyStruct'和'const MyStruct')
{ return __x > __y; {return __x> __y; } }

It seems to be because this function right here doesn't have a const qualifier: 这似乎是因为这里的函数没有const限定符:

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

If I add it, 如果我添加它,

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

Then everything is fine again. 然后一切都很好。 Why is this so? 为什么会这样? I'm not too familiar with operator overloading, so I've just put it in memory that we need to add the const but it's still weird why it works for operator< without the const . 我不太熟悉运算符重载,所以我只是把它放在内存中我们需要添加const但是它仍然很奇怪为什么它适用于operator<没有const

You get different behaviors because you are in fact calling two different (overloaded) sort functions. 您会得到不同的行为,因为您实际上正在调用两个不同的(重载) 排序函数。

In the first case you call the two parameter std::sort , which uses operator< directly. 在第一种情况下,您调用两个参数std::sort ,它使用operator< direct。 Since the iterators to your vector elements produce non-const references, it can apply operator< just fine. 由于向量元素的迭代器产生非const引用,因此它可以应用operator< just fine。

In the second case, you are using the three parameter version of std::sort . 在第二种情况下,您使用的是std::sort的三个参数版本。 The one that accepts a functor. 接受仿函数的那个​​。 You pass std::greater . 你传递std::greater And that functor has an operator() declared as follows: 该仿函数有一个operator()声明如下:

constexpr bool operator()( const T& lhs, const T& rhs ) const;

Note the const references. 请注意const引用。 It binds the elements it needs to compare to const references. 它绑定了与const引用进行比较所需的元素。 So your own operator> must be const correct as well. 所以你自己的operator>必须是const正确的。

If you were to call std::sort with std::less , your operator< will produce the same error, because it's not const-correct. 如果你用std::less调用std::sort ,你的operator<将产生相同的错误,因为它不是const-correct。

Use of std::sort(vec.begin(), vec.end()) depends only on the operator< function. 使用std::sort(vec.begin(), vec.end())仅取决于operator< function。 It does not require that the function be able to work with const objects. 它不要求该函数能够使用const对象。

std::greater , on the other hand, requires the function be able to work with const objects. 另一方面, std::greater要求函数能够使用const对象。

You will see a similar problem if you use std::less , such as std::sort(vec.begin(), vec.end(), std::less<MyStruct>()) . 如果使用std::less ,例如std::sort(vec.begin(), vec.end(), std::less<MyStruct>())您将看到类似的问题。


Having said that, there is no reason for the operator< function and the operator> function to be non- const member functions. 话虽如此, operator< function和operator>函数没有理由是非const成员函数。 Any member function that does not modify member data should be made a const member function. 任何不修改成员数据的成员函数都应该成为const成员函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM