Этот вопрос напрямую связан с используя char в качестве ключа в stdmap.
Я понимаю, что делает переданная функция сравнения и почему она требуется для char *
Типы в качестве ключа. Тем не менее, я не уверен, как на самом деле работает обновление.
Мне любопытно, что касается случая, когда вы обновляете ключ. Как std::map
знать, как сравнить равенство между const char *
, cmp_str
только указывает на карту, в каком порядке вставляются ключи в дерево.
Я немного покопался в stl_tree.h
код (вытащил отсюда) но не смог найти много. Мое единственное предположение, что это делает прямое сравнение памяти.
Я заинтересован в том, как подчиненный stl_tree
class обрабатывает эту ситуацию, или если он не обрабатывает это все время правильно, какой крайний случай ломается?
Код
#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
Все упорядоченные контейнеры используют классы эквивалентности: два значения 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
Вы нашли дубликат ключа. Там действительно не так много всего.