繁体   English   中英

std :: map中的自定义键,重载<运算符

[英]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有两个目的:

  1. 从签名中可以看出,该参数在函数体内是不可修改的,任何这样的冒险都会产生编译器错误。
  2. 没有额外的不必要的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

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM