C++ 你知道为什么QHash和QMap返回const T而不是const T&;吗;?
与std::map和std::hash_map不同,Qt中的相应版本不需要返回引用。如果我为相当庞大的类构建一个哈希,不是效率很低吗 编辑 特别是因为有一个单独的方法value(),它可以通过值返回它。奇怪,是的 这可能是因为所需的语义,例如对未指定的键执行C++ 你知道为什么QHash和QMap返回const T而不是const T&;吗;?,c++,qt,hash,reference,performance,C++,Qt,Hash,Reference,Performance,与std::map和std::hash_map不同,Qt中的相应版本不需要返回引用。如果我为相当庞大的类构建一个哈希,不是效率很低吗 编辑 特别是因为有一个单独的方法value(),它可以通过值返回它。奇怪,是的 这可能是因为所需的语义,例如对未指定的键执行,将返回正确类型的默认构造值。使用引用是不可能的,至少没有那么干净 此外,类似这样的方法可以减少这种设计对性能的影响。实际上,有些方法确实会返回一个引用。。。例如,非常量版本的运算符[]返回一个T& 但是,运算符[]的常量版本返回一个常量T。
,将返回正确类型的默认构造值。使用引用是不可能的,至少没有那么干净
此外,类似这样的方法可以减少这种设计对性能的影响。实际上,有些方法确实会返回一个引用。。。例如,非常量版本的
运算符[]
返回一个T&
但是,
运算符[]
的常量版本返回一个常量T
。为什么?正如“放松”已经指出的,原因与地图中不存在键时发生的情况有关。在非常量操作符[]
中,我们可以将键添加到映射中,然后返回对新添加项的引用。但是,常量操作符[]
无法执行此操作,因为它无法修改映射。那么它应该返回什么引用呢?解决方案是使常量运算符[]
返回常量T
,然后在映射中不存在键的情况下返回默认构造的T
。STL容器的const subscript操作符可以返回对const的引用,因为它们完全拒绝使用容器中不存在的索引调用它。这种情况下的行为是未定义的。因此,作为明智的设计选择,std::map
甚至不提供常量下标操作符重载
QMap试图更为适应,提供了一个const subscript操作符重载作为语法糖,遇到了不存在键的问题,再次尝试更为适应,并返回一个默认构造值
如果希望保持STL按常量引用返回的约定,则需要分配一个静态值并返回对该值的引用。然而,这与QMap
提供的可重入性保证非常不一致,因此唯一的选择是按值返回。const
只有糖衣可以防止编译过程中出现一些愚蠢的错误,比如constmap[“foo”]+
也就是说,通过引用返回并不总是最有效的方式。如果您返回一个基本类型,或者在进行更积极的优化时,
sizeof(T)QMap和QHash的文档特别指出,由于Martin B所述的原因,避免使用运算符[]
进行查找
如果需要常量引用,请使用const\u迭代器find(const-Key&Key)const
,然后可以使用以下任意一种:
const Key & key () const
const T & value () const
const T & operator* () const
const T * operator-> () const
我希望运算符[]的行为与std::and value()方法的行为相同,以便通过值返回它……好的,但是为什么const t QHash::value(const Key&Key,const t&defaultValue)const
不返回引用?“std::map的const subscript运算符…”但是std::map
没有const
subscript操作符?“它们使用容器中不存在的索引断然拒绝对它的调用”,但您可以在std::map上执行此操作,这是插入新值的一种方法。但是,即使你的意思是在一般情况下,他们怎么会不提供常量下标操作符呢?STL的设计准则之一就是不提供高效的操作。这就是为什么std::map
没有常量下标运算符,std::list
根本没有下标运算符的原因。进行两次二进制搜索的好处。但是如果我知道元素在那里呢?我只需要知道它们映射到什么…仅对于防御性编程而言,您将添加“assert(map.count(X)”,而且我已经看到过太多与assert一起提供的软件能够将任何断言不是性能关键的说法视为一厢情愿。可能是@ThomasKlier sure的重复,5年前刚刚询问过