Использование char* в качестве ключа в std:: map, как это работает
Этот вопрос напрямую связан с использованием char в качестве ключа в stdmap.
Я понимаю, что делает переданная функция сравнения и почему она требуется для типов char * в качестве ключа. Однако я не уверен, как обновление на самом деле работает.
Мне любопытно, в каком случае вы обновляете ключ. Откуда std::map знает, как сравнить равенство между const char *, cmp_str Только сообщает map порядок, в котором вставляются ключи в дерево.
Я сделал немного копаясь в коде stl_tree.h (вытащил отсюда), но не смог найти много. Моя единственная догадка заключается в том, что он делает прямое сравнение памяти.
Меня интересует, как подчиненный stl_tree класс справляется с этой ситуацией, или если он не справляется с ней правильно все время, какой крайний случай ломается?
Код
#include <map>
#include <iostream>
#include <cstring>
struct cmp_str
{
bool operator()(char const *a, char const *b)
{
return std::strcmp(a, b) < 0;
}
};
int main ( int argc, char ** argv )
{
std::map<const char*, int, cmp_str> map;
map["aa"] = 1;
map["ca"] = 2;
map["ea"] = 3;
map["ba"] = 4;
map["ba"] = 5;
map["bb"] = 6;
map["ba"] = 7;
std::map<const char*, int, cmp_str>::iterator it = map.begin();
for (; it != map.end(); it++ )
{
std::cout << (*it).first << ": " << (*it).second << std::endl;
}
return 0;
}
Вывод
aa: 1
ba: 7
bb: 6
ca: 2
ea: 3
2 ответов:
Все упорядоченные контейнеры используют классы эквивалентности: два значения
aиbсчитаются эквивалентными, если ни одно из них не меньше другого:!(a < b) && !(b < a)или, если вы настаиваете на нотации с использованием двоичного предиката!pred(a, b) && !pred(b, a).Обратите внимание, что вам нужно, чтобы указатели жили на вашей карте: если указатели выйдут из области видимости, вы получите странные результаты. Конечно, строковые литералы остаются действительными в течение всего срока службы программы.
Ну,
cmp_strможно использовать для поиска идентичных ключей. Если обаcmp_str::operator(x,y)иcmp_str::operator(y,x)возвращаютfalse, вы нашли дубликат ключа. На самом деле это не так уж много.
Comments