【问题标题】:Why overloaded ' operator < ' should be const for class?为什么重载的'operator <'应该是类的常量?
【发布时间】:2014-07-18 14:02:03
【问题描述】:

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

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

sort 算法 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());
  ...
}

【问题讨论】:

  • 因为比较两个对象不应该改变其中任何一个。
  • @juanchopanza 同意,但我的问题是 sort 在内部做了什么来强制执行此操作?
  • 它可以像调用一个函数一样简单,该函数采用const 对向量元素的引用。我不认为这是标准规定的,但这是有道理的。
  • 虽然很容易想象一个排序实现允许比较运算符不被声明 const,但如果不是,任何基于比较的排序操作怎么能提供任何保证逻辑上的常量?我认为这在技术上可能是实现中的一个错误,因为我在 C++ 标准中看到很多地方他们谈论操作在逻辑上是 const(而不是在语法上)

标签: c++ stl operator-overloading


【解决方案1】:

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

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

operator&lt; 定义为 const 应该不会对您造成伤害,因为我无法想象会有一个小于运算符来更改对象。那太傻了。

如果您想知道从 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&amp; __pivot,就在那儿。

【讨论】:

    【解决方案2】:

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

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

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

    ...comp(*i, *j) != false 默认为*i &lt; *j != false

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 2021-08-23
      • 2011-08-30
      • 1970-01-01
      • 2012-05-03
      • 2013-06-12
      相关资源
      最近更新 更多