2013-07-19 6 views
2

Я пытаюсь хранить информацию в std::map. Но у меня есть проблемы с find:std :: map :: find не работает

typedef map<string, string, equal_to<string>> MAP_STRING2STRING; 
.... 
MAP_STRING2STRING map; 
MAP_STRING2STRING::const_iterator iter; 

Когда я пытаюсь найти key, я получаю следующее сообщение об ошибке:

iter = map.find(key); 

Error from Visual C++
Что я делаю неправильно?
Эта ошибка появляется только тогда, когда у меня есть что-то в map.

+11

'equal_to' не правильный вид сравнения. Вам нужен строгий слабый порядок (сравнение меньше или больше, чем тип). – juanchopanza

+1

Когда ключ является 'std :: string', вам обычно не нужно передавать третий аргумент шаблона в' std :: map'; по умолчанию будет 'std :: less ', что прекрасно, если вам не нужен специальный заказ. –

+0

DONT_USE_ALL_UPPERCASE - кроме MACROS. Благодарю. :-) –

ответ

9

В вашей карте есть неправильный функтор сравнения. Вам нужно strict weak ordering (сравнение меньше или больше, чем сравнение), а не равенство. Вы можете просто опустить параметр функтора сравнения и использовать меньше, чем сравнение для std::string. Это реализует строгий слабый порядок с помощью лексикографического сравнения строк:

typedef map<string, string> MAP_STRING2STRING; 

Это эквивалентно

typedef map<string, string, less<string> > MAP_STRING2STRING; 

Внутренне, карта использует строгое слабое сравнение заказов на самого как порядок, и определить, является ли два ключа равны.

Третий параметр шаблона позволяет вам создать экземпляр карты с помощью пользовательского порядка. Например, это может создать карту с обратной упорядоченностью выше одного:

typedef map<string, string, greater<string> > MAP_STRING2STRING; 
+0

Вы гений :) Большое спасибо –

1

Если вы хотите простую карту от std::string к std::string, просто используйте map<string, string> (падение, что equal_to<string> поддельных «компаратора»).

Кроме того, поскольку у вас есть переменная с именем «map», это может привести к конфликту с классом STL map. Либо измените имя переменного (например, называют его myMap), или использовать префикс std:: пространства имен для std::map класса:

typedef map<string, string> MAP_STRING2STRING; 
.... 
MAP_STRING2STRING myMap; 

Кроме того, так как с сообщения об ошибке, которую вы используете VS2010, вы можете использовать удобный auto C++ 11 ключевых слов, чтобы избежать "беспорядок" в MAP_STRING2STRING::const_iterator, и просто использовать:

auto iter = myMap.find(someKey); 
+0

WRT ваш последний комментарий, вы _can_ используете auto, но вы можете использовать фактическое имя типа, чтобы сделать код более четким. (Это немного зависит от объема 'iter'. В небольшой функции, где все действия в переменной сразу становятся ясными, я буду использовать' auto'. Я бы никогда не использовал его для переменной в области пространства имен, однако.) –

+0

@JamesKanze: Я согласен с вами в том, что вы не используете 'auto' для переменных в области namesapce. –

Смежные вопросы