C ++ пользовательский компаратор между std :: string и потенциально недопустимым символьным массивом для unordered_map :: find - PullRequest
0 голосов
/ 20 января 2012

Я знаю, что вопрос может звучать странно, но есть некоторый устаревший код, где есть unordered_map, где ключ std :: string имеет максимальный размер 8 + 1 (1 для нулевого завершения).

Я получаю строку в переменной char [8], которую я не хочу strcpy для temp std :: string только для вызова find ().

Есть ли способкаким-то образом реализовать некоторый компаратор, чтобы я мог использовать char [8] непосредственно в вызове find ()?

Имейте в виду, что char [8] может содержать что-то вроде «12345678» (без нулевого завершения)поэтому strcmp по умолчанию, вероятно, не будет работать, хотя, возможно, strncmp будет работать?

Ответы [ 2 ]

2 голосов
/ 20 января 2012

Если ваш тип карты использует тип ключа std::string, вы не сможете избежать создания std::string, независимо от того, используете ли вы std::map<std::string, T> (см. Подпись в параграфе 2 пункта 23.4.4.1) или std::unordered_map<std::string, T> (см. Подпись в пункте 3 пункта 23.5.4.1): аргумент find() равен key_type const&.Попытка передать C-строку с ненулевым символом в конце приведет к смешному поведению.Лично я, вероятно, создал бы вспомогательную функцию, которая создает std::string из массива char и полагается на используемую оптимизацию небольших строк (т.е. символы копируются только вместо выделения памяти).

Если профилирование показывает, что это действительно проблема с производительностью, я, вероятно, создал бы простой класс константных строк фиксированного размера и использовал бы его в качестве ключа для моего ассоциативного контейнера: те немногие операции, которые на самом деле нужны, не очень сложны для реализации.

1 голос
/ 20 января 2012

Создайте класс компаратора, который имеет несколько перегрузок для operator==, принимая каждую комбинацию параметров char* и const string&. Используйте метод c_str() для строк и сравните с strncmp.

...