Any ideas why QHash and QMap return const T instead of const T&?

c++, hash, performance, qt, reference

Solution

const subscript operators of `STL` containers can return a reference-to-const because they flat out deny calls to it with indexes that do not exist in the container. Behaviour in this case is undefined. Consequently, as a wise design choice, `std::map` doesn't even provide a const subscript operator overload.

QMap tries to be a bit more accommodating, provides a const subscript operator overload as syntactic sugar, runs into the problem with non-existing keys, again tries to be more accomodating, and returns a default-constructed value instead.

If you wanted to keep STL's return-by-const-reference convention, you'd need to allocate a static value and return a reference to that. That, however, would be quite at odds with the reentrancy guarantees that `QMap` provides, so the only option is to return by value. The `const` there is just sugar coating to prevent some stupid mistakes like `constmap["foo"]++` from compiling.

That said, returning by reference is not always the most efficient way. If you return a fundamental type, or, with more aggressive optimisation, when `sizeof(T)<=sizeof(void*)`, return-by-value often makes the compiler return the result in a register directly instead of indirectly (address to result in register) or—heaven forbid—on the stack.

The other reason (besides premature pessimisation) to prefer pass-by-const-reference, slicing, doesn't apply here, since both `std::map` and `QMap` are value-based, and therefore homogeneous. For a heterogeneous container, you'd need to hold pointers, and pointers are fundamental types (except smart ones, of course).

That all said, I almost never use the const subscript operator in Qt. Yes, it has nicer syntax than `find()`+`*it`, but invariably, you'll end up with `count()`/`contains()` calls right in front of the const subscript operator, which means you're doing the binary search twice. And then you won't notice the miniscule differences in return value performance anyway :)

For `value() const`, though, I agree that it should return reference-to-const, defaulting to the reference-to-default-value being passed in as second argument, but I guess the Qt developers felt that was too much magic.

Problem

Unlike std::map and std::hash_map, corresponding versions in Qt do not bother to return a reference. Isn't it quite inefficient, if I build a hash for quite bulky class? EDIT especially since there is a separate method value(), which could then return it by value.

Original source

Related problems