Why does C++ allow the following code to compile?
std::unordered_map<std::string, int> m;
// ...
for (const std::pair<std::string, int>& p: m)
{
// ...
}
According to Scott Meyers' Effective Modern C++ (p. 40-41):
[...] the key part of a
std::unordered_map
isconst
, so the type ofstd::pair
in the hash table (which is what astd::unordered_map
is) isn’tstd::pair<std::string, int>
, it'sstd::pair <const std::string, int>
. But that's not the type declared for the variablep
in the loop above. As a result, compilers will strive to find a way to convertstd::pair<const std::string, int>
objects (i.e., what’s in the hash table) tostd::pair<std::string, int>
objects (the declared type forp
). They’ll succeed by creating a temporary object of the type thatp
wants to bind to by copying each object inm
, then binding the reference p to that temporary object. At the end of each loop iteration, the temporary object will be destroyed. If you wrote this loop, you'd likely be surprised by this behavior, because you'd almost certainly intend to simply bind the referencep
to each element inm
.
What is the benefit of allowing this implicit conversion? Is there some common use case where the developer would expect / prefer this implicit conversion (rather than getting a compiler error)?
Aucun commentaire:
Enregistrer un commentaire