与std :: map和std :: hash_map不同,Qt中的相应版本无需返回引用。如果我为相当庞大的类构建哈希值,这不是很低效吗?
修改
特别是因为有一个单独的方法值(),然后可以按值返回它。
答案 0 :(得分:29)
STL
容器的 const下标运算符可以返回引用到const,因为它们使用容器中不存在的索引来拒绝对它的调用。在这种情况下的行为是不确定的。因此,作为明智的设计选择,std::map
甚至不提供const下标运算符重载。
QMap试图更容易调整,提供const下标运算符重载作为语法糖,遇到问题与不存在的键,再次尝试更容易,并返回默认构造的值。
如果你想保留STL的const-by-const引用约定,你需要分配一个静态值并返回那个的引用。然而,这与QMap
提供的重入保证完全不一致,因此唯一的选择是按价值返回。 const
只有糖涂层,以防止编译constmap["foo"]++
等一些愚蠢的错误。
那就是说,通过引用返回并不总是最有效的方式。如果你返回一个基本类型,或者通过更积极的优化,当sizeof(T)<=sizeof(void*)
时,返回值通常会使编译器直接在寄存器中返回结果而不是间接地(地址导致寄存器)或者天堂禁止在堆栈上。
另一个原因(除了过早的悲观化)更喜欢传递const-reference-slic,切片,这里不适用,因为std::map
和QMap
都是基于价值的,因此是同质的。对于异构容器,您需要保持指针,指针是基本类型(当然除了智能类型)。
所有人都说,我几乎从不在Qt中使用const下标运算符。是的,它的语法比find()
+ *it
更好,但总是会在const下标运算符前面调用count()
/ contains()
调用,意味着您正在进行二次搜索两次。而然后你不会注意到回报价值表现的微小差异:)
对于value() const
,我同意它应该返回引用到const,默认为作为第二个参数传入的引用到默认值,但我想Qt开发人员认为这是太多魔法了。
答案 1 :(得分:4)
由于Martin B所说的原因,QMap和QHash的文档特别指出要避免operator[]
查找。
如果您想要const引用,请使用const_iterator find ( const Key & key ) const
,然后您可以使用以下任何一个:
const Key & key () const
const T & value () const
const T & operator* () const
const T * operator-> () const
答案 2 :(得分:3)
实际上,某些方法做会返回一个引用...例如,operator[]
的非const版本会返回T &
。
但是,operator[]
的const版本会返回const T
。为什么?正如“放松”已经指出的那样,原因与地图中不存在密钥时发生的情况有关。在非const operator[]
中,我们可以将键添加到地图中,然后返回对新添加的条目的引用。但是,const operator[]
无法执行此操作,因为它无法修改地图。那么它应该返回什么引用呢?解决方案是使const operator[]
返回const T
,然后在地图中不存在键的情况下返回默认构造的T
。
答案 3 :(得分:1)
很奇怪,是的。
也许这是因为所需的语义,例如value()
在未指定的键上,返回正确类型的默认构造值。使用引用是不可能的,至少不是那么干净。
此外,name return value optimization之类的内容可以减轻此设计对性能的影响。