在operator<
中为自定义键重载map
时,为什么参数和函数类型都需要const
?
答案 0 :(得分:1)
运营商的原型&lt;是
bool operator<(const Element& b) const { ..... }
const Element& b
表示在调用operator<
时不会创建元素b的额外副本,并且不会在方法内修改参数。第二个const
表示在此调用调用时不会修改调用operator<
的对象。
答案 1 :(得分:1)
据我所知,参数类型const reference
有两个目的:
key
类型的复制。会员功能为const
,因此您仍然可以执行find
(或任何其他 纯读取 (除非修改{ {1}}成员)操作)调用mutable
地图对象。没有那个const,在尝试在const映射对象上调用这些成员函数时,会导致编译错误。
当您尝试创建自定义比较函数时,不需要const
用于全局或非成员函数。
const
函数的 bool operator<(const Key& a, const Key& b) /* no const required here*/ {....}
仅适用于成员函数,因为它使const
指针或实例成为this
,而不是全局或非成员比较运算符的情况{ p>
答案 2 :(得分:1)
您可能认为std::map<K, V>
的value_type不是std::pair<K, V>
,而是实际std::pair<const K, V>
。 因此,在键上调用的任何比较都会处理const对象。
现在编译器看到了
a < b
且a
或b
中至少有一个是用户定义的类型,编译器调用
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概念。