Почему С++ позволяет компилировать следующий код?
std::unordered_map<std::string, int> m;
// ...
for (const std::pair<std::string, int>& p: m)
{
// ...
}
Согласно Эффективный современный С++ Скотта Мейерса (стр. 40-41):
[...] ключевая часть
std::unordered_map
равнаconst
, поэтому типstd::pair
в хеш-таблице (что и естьstd::unordered_map
) isntstd::pair<std::string, int>
, itstd::pair <const std::string, int>
. Но это не тип, объявленный для переменнойp
в цикле выше. В результате компиляторы будут стремиться найти способ преобразования объектовstd::pair<const std::string, int>
(т.е. В хэш-таблице) в объектыstd::pair<std::string, int>
(объявленный тип дляp
). Theyll удалось создать временный объект типа, которыйp
хочет связать, копируя каждый объект вm
, а затем привязывая ссылку p к этому временному объекту. В конце каждой итерации цикла временный объект будет уничтожен. Если вы написали этот цикл, вы, вероятно, будете удивлены этим поведением, потому что вы почти наверняка намерены просто привязать ссылкуp
к каждому элементу вm
.
В чем преимущество разрешения этого неявного преобразования? Есть ли какой-то общий вариант использования, когда разработчик ожидает/предпочитает это неявное преобразование (а не получение ошибки компилятора)?