为什么重载'运算符< '应该是班级的常量?

时间:2014-05-29 06:22:15

标签: c++ stl operator-overloading

任何人都可以在STL sort算法的上下文中解释这种行为吗? 如果operator <未定义const则会出错,

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

sort algo lhs 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());
  ...
}

2 个答案:

答案 0 :(得分:6)

将函数标记为const承诺不会更改对象。所以它可以用在const对象上。

STL几乎肯定将参数作为const,因为这是明智之举。

operator<定义为const不应该让你受伤,因为我无法想象有一个改变对象的less-than运算符。那只是愚蠢的。

如果你想确切地知道在Fedora 20机器上从libstdc ++ bits / stl_algo.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,就在那里。

答案 1 :(得分:3)

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

  

...假设comp不会通过解除引用的迭代器应用任何非常量函数。

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

  

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

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