#c #stl #constants #std-pair
#c #stl #константы #std-pair
Вопрос:
Рассмотрим std::map
класс в 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;
Итераторы для std::map
возврата объектов типа
std::pair<const key_type, T>
Здесь важно отметить, что первым членом пары является const
. Это означает, что следующее назначение ссылки недопустимо.
std::pair<key_type, T>amp; reference = *map_iterator; // Incorrect, key_type is not const
std::pair<const key_type, T>amp; reference = *map_iterator; // Correct
Однако, следующее выражение является допустимым :
const std::pair<key_type, T>amp; reference = *map_iterator; // Correct, const reference is okay
Итак, с помощью некоторого механизма на объекты типа std::pair<const key_type, T>
можно ссылаться по ссылке типа const std::pair<key_type, T>
. Это логически желательно (поскольку const
наличие std::pair
подразумевается const
наличие обоих членов first
и second
, что совместимо с std::pair<const key_type, T>
).
Однако мне интересно узнать, какой механизм реализации C делает такую совместимость возможной. Я уверен, что существуют способы реализации std:: pair, где два приведенных выше ссылочных типа были бы несовместимы.
Ответ №1:
Когда вы делаете
const std::pair<key_type, T>amp; reference = *map_iterator;
*map_iterator
возвращает std::pair<const key_type, T>amp;
. Затем вы копируете инициализируете std::pair<key_type, T>
из этого, а затем привязываете reference
к этой временной переменной. Поскольку у вас есть ссылка на const
, это продлит срок службы этого временного элемента до срока службы ссылки, и теперь у вас есть элемент, который является копией элемента из map. В основном вы сделали
std::pair<key_type, T> copy = *map_iterator;
Приведенная выше последовательность преобразований работает, потому что вам разрешено до одного пользовательского преобразования при инициализации, и компилятор попытается сделать это, чтобы предоставить вам действительную инициализацию.
Комментарии:
1. Спасибо! Можете ли вы предоставить какую-либо ссылку для утверждения «вам разрешено до одного пользовательского преобразования при инициализации»?
2. @johngreen Конечно. Проверьте: en.cppreference.com/w/cpp/language/implicit_conversion