Reputation: 2744
Consider std::map
class in STL:
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > // map::allocator_type
> class map;
Iterators to std::map
return objects of type
std::pair<const key_type, T>
The important thing to note here is that the first member of the pair is const
. This means that, the following reference assignment is invalid.
std::pair<key_type, T>& reference = *map_iterator; // Incorrect, key_type is not const
std::pair<const key_type, T>& reference = *map_iterator; // Correct
However, the following expression is valid :
const std::pair<key_type, T>& reference = *map_iterator; // Correct, const reference is okay
So, by some mechanism, objects of type std::pair<const key_type, T>
can be referred by reference of type const std::pair<key_type, T>
. This is logically desirable (since const
ness of std::pair
implied const
ness of both the members first
and second
, which is compatible with std::pair<const key_type, T>
).
However, I am interested in knowing what C++ implementation mechanism makes this compatibility possible. I'm sure there ways of implementing std::pair where the two reference types above would not be compatible.
Upvotes: 2
Views: 1740
Reputation: 180424
When you do
const std::pair<key_type, T>& reference = *map_iterator;
*map_iterator
returns a std::pair<const key_type, T>&
. You then copy initialize a std::pair<key_type, T>
from that, and then you bind reference
to that temporary variable. Because you have a reference to const
, this will extend the lifetime of that temporary to be the lifetime of the reference and you now have an element that is a copy of the one from the map. Basically you've done
std::pair<key_type, T> copy = *map_iterator;
The above conversion sequence works because you are allowed up to one user defined conversion in initialization and the compiler will try to do that to give you a valid initialization.
Upvotes: 6