为什么重载的"运算符<"应该是类的常量?

Why overloaded ' operator < ' should be const for class?

本文关键字:常量 lt 重载 运算符 为什么      更新时间:2023-10-16

有谁能在STL sort算法的背景下解释这种行为吗?如果operator <未定义const,则给出错误,

error: passing ‘const B’ as ‘this’ argument of ‘bool B::operator<(const B&)’ discards qualifiers [-fpermissive] while (__pivot < *__last)

sort算法是const对象还是sortconst方法?

class B
{
 public:
    ...
    bool operator < (const B& b) const       // why const required here?
    {
        return (m_i < b.m_i);
    } 
    ...
 private:
    int m_i;
    int m_j;
};
int main()
{
  vector<B> Bvec2 {B(5), B(3), B(30), B(20), B(8)};
  std::sort(Bvec2.begin(), Bvec2.end());
  ...
}

将函数标记为const保证它不会改变对象。因此,它可以用于const对象。

STL几乎肯定将实参作为const,因为这样做是明智的。

operator<定义为const应该没有什么害处,因为我无法想象有一个小于操作符来改变对象。那就太傻了。

如果您想知道在Fedora 20机器上从libstdc++ bits/stl_algorithm .h中复制的代码的确切位置:

  /// This is a helper function...
  template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
    _RandomAccessIterator
    __unguarded_partition(_RandomAccessIterator __first,
                          _RandomAccessIterator __last,
                          const _Tp& __pivot, _Compare __comp)

const _Tp& __pivot,就在这里

标准对此有一点不清楚,但是[alg.sorting]给出了两个提示,说明为什么编译失败可能是符合标准的行为。第一个是[alg.sorting]/2:

…假定comp不会通过解引用迭代器应用任何非常数函数。

接下来,我们被告知当没有提供比较器时,[alg.sorting]/3:

comp(*i, *j) != false默认为*i < *j != false

,因为在您的例子中,comp默认为*i < *j != false,这将非const函数应用于解引用迭代器。这使[alg.sorting]/2中给出的假设无效,因此您的代码具有未定义的行为。具有未定义行为的代码不编译是合法的。