Вы запросили диапазон, состоящий из всех элементов вашего unordered_map
, ключ которого - 'a'
. Ваша неупорядоченная карта не содержит таких элементов. Итак, диапазон пуст.
То же самое относится и к делу map
. Однако способ обозначения этого условия различается в зависимости от контейнера (хотя на самом деле это не так; продолжайте читать). Контейнеры std::map
и std::unordered_map
- это не одно и то же (следовательно, они имеют разные имена). Первый упорядочен, а второй нет, поэтому по причинам логической реализации он работает немного по-другому:
unordered_map
Возвращаемое значение
std::pair
содержит пару итераторов, определяющих требуемый диапазон. Если таких элементов нет, итераторы конца конца (см. end()
) возвращаются как оба элемента пары.
map
Возвращаемое значение
std::pair
содержит пару итераторов, определяющих требуемый диапазон: первый указывает на первый элемент, который не меньше key
, а второй указывает на первый элемент, который больше key
.
Если нет элементов, не меньших, чем ключ, итератор конца-в-конце (см. end()
) возвращается в качестве первого элемента. Точно так же, если нет элементов больше key
, итератор конца конца возвращается как второй элемент.)
Эта разница не имеет значения. В любом случае вам просто нужно выполнить итерацию (first
, second
] , чтобы проверить элементы (если они существуют) в вашем диапазоне, как и в любом диапазоне итераторов.
В вашем коде вы не исследовали обе части пары, возвращенной в вашем map
случае. Если вы сделаете это, то вы обнаружите, что first == second
(опять же, обозначение пустого диапазона).
Ваш код map
эффективно разыменовывает итератор "конца конца" возвращаемого диапазона.
#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;
int main ()
{
{
std::map<char,int> mymap;
mymap['c'] = 60;
std::map<char, int>::iterator itlo = mymap.equal_range('a').first;
std::map<char, int>::iterator itup = mymap.equal_range('a').second;
// This compares each range extent to the map's end, which is not really useful
cout << "map::itup " << (itup == mymap.end() ? "END" : "NOT END") << '\n';
cout << "map::itlo " << (itlo == mymap.end() ? "END" : "NOT END") << '\n';
// This examines the range itself
cout << "map range empty: " << (itlo == itup ? "YES" : "NO") << '\n';
cout << "map range size: " << std::distance(itlo, itup) << '\n';
}
{
std::unordered_map<char, int> mymap;
mymap['c'] = 60;
mymap['d'] = 70;
std::unordered_map<char, int>::iterator itlo = mymap.equal_range('a').first;
std::unordered_map<char, int>::iterator itup = mymap.equal_range('a').second;
// This compares each range extent to the map's end, which is not really useful
cout << "unordered_map::itup " << (itup == mymap.end() ? "END" : "NOT END") << std::endl;
cout << "unordered_map::itlo " << (itlo == mymap.end() ? "END" : "NOT END") << std::endl;
// This examines the range itself
cout << "unordered_map range empty: " << (itlo == itup ? "YES" : "NO") << '\n';
cout << "unordered_map range size: " << std::distance(itlo, itup) << '\n';
}
}
// Output:
//
// map::itup NOT END
// map::itlo NOT END
// map range empty: YES
// map range size: 0
// unordered_map::itup END
// unordered_map::itlo END
// unordered_map range empty: YES
// unordered_map range size: 0