Использование 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
625   2  

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

    Ничего не найдено.