![](/img/trans.png)
[英]std::map: overloading the operator< with a parameter other than the key's class
[英]Custom key in std::map, overloading < operator
在map
重载operator<
for custom key时,为什么参数和函数类型都需要const
?
运营商的原型<是
bool operator<(const Element& b) const { ..... }
const Element& b
意味着在调用operator<
时不会创建元素b的额外副本operator<
以及在方法内部不修改参数。 第二个const
表示在此调用调用时不会修改调用operator<
的对象。
据我所知,参数类型的const reference
有两个目的:
key
类型复制。 成员函数是const
因此您仍然可以在const
映射对象上执行find
(或任何其他纯读取 (除非修改mutable
成员)操作)。 如果没有该const,在尝试在const映射对象上调用这些成员函数时,会导致编译错误。
当您尝试创建自定义比较函数时,不需要全局或非成员函数的const
。
bool operator<(const Key& a, const Key& b) /* no const required here*/ {....}
const
仅适用于成员函数,因为它使this
指针或实例成为const
,而不是全局或非成员比较运算符的情况
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引用(推荐)或值来获取这两个参数。
参数中的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)
}
通过强制转换constness,可以打破这些承诺(这是我们正在谈论的C ++),但无论如何这都是意图。
总是尽可能少地询问你是个好主意。 如果方法不更改对象 - 将其声明为const,则可以在该类的const实例上调用此方法(例如,当它作为const引用传递到其他地方时)。
在自定义operator <
on std :: map的情况下,你不能在参数中使用非const引用的原因是因为std :: map将在一个或多个自己的方法中调用你的运算符,并且它们可能被声明为const他们自己。 编译器不允许它将const对象传递给不承诺不修改它的函数。
你不能声明operator <
本身非const的原因(假设它不是一个独立的函数,而是一个用作键的自定义类的方法)是相同的 - std :: map已经承诺不会修改键(这会对一个排序顺序造成严重破坏),所以它不能调用任何不承诺相同的方法。
自定义operator <
当用于在容器内进行排序时,还有其他要求 - 它必须满足LessThanComparable概念。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.