std :: map中的自定义键,重载<操作者

时间:2016-06-28 17:27:41

标签: c++ dictionary operator-overloading

operator<中为自定义键重载map时,为什么参数和函数类型都需要const

4 个答案:

答案 0 :(得分:1)

运营商的原型&lt;是

bool operator<(const Element& b) const { ..... }

const Element& b表示在调用operator<时不会创建元素b的额外副本,并且不会在方法内修改参数。第二个const表示在此调用调用时不会修改调用operator<的对象。

答案 1 :(得分:1)

据我所知,参数类型const reference有两个目的:

  1. 从签名中可以看出,该参数在函数体内是不可修改的,任何此类冒险都会导致编译错误。
  2. 没有额外不必要的key类型的复制。
  3. 会员功能为const,因此您仍然可以执行find(或任何其他 纯读取 (除非修改{ {1}}成员)操作)调用mutable地图对象。没有那个const,在尝试在const映射对象上调用这些成员函数时,会导致编译错误。

    当您尝试创建自定义比较函数时,不需要const用于全局或非成员函数。

    const
    函数的

    bool operator<(const Key& a, const Key& b) /* no const required here*/ {....} 仅适用于成员函数,因为它使const指针或实例成为this,而不是全局或非成员比较运算符的情况

答案 2 :(得分:1)

您可能认为std::map<K, V>的value_type不是std::pair<K, V>,而是实际std::pair<const K, V>因此,在键上调用的任何比较都会处理const对象。

现在编译器看到了

a < b

ab中至少有一个是用户定义的类型,编译器调用

operator < (a, b); //(1)

a.operator < (b); //(2)

(如果这两个都可用,则会发出错误。)

非常量成员函数(包括任何运算符)只能在非常量对象上调用 。因此,因为a是常量,所以在//2的情况下需要将该函数声明为const。由于b也是常量,因此参数必须是const引用,因为非const引用不能绑定到常量对象。因此要求两个都有。

除了const之外,该参数还有另一种选择。它可以通过值获取参数,但这意味着不必要的复制。同样,如果您选择声明非成员operator <,则应该通过const引用(推荐)或值来获取这两个参数。

答案 3 :(得分:0)

参数中的Const是函数,它允许调用者不修改传入的参数。当参数通过引用传递以避免额外的副本但不会被修改时,通常需要它,例如:

void function(const Type& var) 
{
    // can't modify var here, but can read and call its const methods (see below)
}

方法声明中的Const是承诺不修改调用它的对象的内部状态的方法。例如

void Class::function(const Type& var) const 
{
   // can't modify var here
   // can't modify "this" here (call other non const methods or change member variables)
}

这些承诺可以被破坏(这毕竟是我们所说的C ++)通过强制转换constness,但无论如何这都是意图。

总是尽可能少地要求你。如果方法不更改对象 - 将其声明为const,则可以在该类的const实例上调用此方法(例如,当它作为const引用传递给其他地方时)。

对于std :: map上的自定义operator <,你不能在参数中使用非const引用的原因是因为std :: map将在一个或多个自己的方法中调用你的运算符,他们可能会被自己声明为const。编译器不允许它将const对象传递给不承诺不修改它的函数。

你不能声明operator <本身非const的原因(假设它不是一个独立的函数,而是一个用作键的自定义类的方法)是相同的 - std :: map已经承诺不会修改密钥(这会对一个密钥排序造成严重破坏),所以它不能调用任何不承诺相同的方法。

自定义operator <用于在容器内进行排序时还有其他要求 - 它必须满足LessThanComparable概念。