任何想法为什么QHash和QMap返回const T而不是const T&?

时间:2009-07-14 09:21:24

标签: c++ qt hash reference performance

与std :: map和std :: hash_map不同,Qt中的相应版本无需返回引用。如果我为相当庞大的类构建哈希值,这不是很低效吗?

修改

特别是因为有一个单独的方法值(),然后可以按值返回它。

4 个答案:

答案 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::mapQMap都是基于价值的,因此是同质的。对于异构容器,您需要保持指针,指针是基本类型(当然除了智能类型)。

所有人都说,我几乎从不在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之类的内容可以减轻此设计对性能的影响。