Страницы

Поиск по вопросам

суббота, 29 декабря 2018 г.

Разименование итератора в std::set

Доброго времени суток! Я недавно начал заниматься программированием и сейчас возникла потребность в рассмотрении контейнера std::set(далее именуемый контейнер). И у меня возникло несколько вопросов, поискав в интернете не нашел подходящих ответов, решил спросить у знающих людей, которые могли бы помочь мне. И так суть вопроса, имеется контейнер типа const char* в который мы добавляем 2 элемента. typedef std::tr1::unordered_set unordered_set; unordered_set myUnorderedSet; myUnorderedSet.insert("testAction"); myUnorderedSet.insert("testActionTwo"); далее если пробежаться по контейнеру for ( unordered_set::iterator it = myUnorderedSet.begin(); it != myUnorderedSet.end(); ++it ) { std::cout << " " << *it; std::cout << std::endl; } можно вывести значения хранящиеся в данном контейнере. Затем я пытаюсь найти нужное мне значение используя метод find(). unordered_set::iterator = myUnorderedSet.find("testAction"); Как получить значение данного итератора, для того чтобы можно было сравнить его со значение которое я добавлял в контейнер*? И почему при такой записи *iter я получаю ошибку компиляции: list iterator is not dereferencable. Не совсем понимаю, ведь for ( unordered_set::iterator it = myUnorderedSet.begin(); it != myUnorderedSet.end(); ++it ) { std::cout << " " << *it; std::cout << std::endl; } мы можем применить операцию разыменования. Заранее благодарен за ответы!


Ответ

смотрим описание метода find() тут(ru) или тут(en) и видим что если find ничего не находит то возвращает итератор на end(), то есть на элемент следующий за последним и он (итератор end()) действительно не разыменуемый (is not dereferencable) то есть имея массив из 5 элементов [0,1,2,3,4] find ненайдя ничего вернёт [5] то есть end() соответственно для проверки "а нашлось ли чего нибудь" сравниваем if(iterator==myUnorderedSet.end()) почему так происходит? в set'e вы храните не строку testAction а указатель на неё и в функции find() сравниваются указатели! когда вы пишите строку в хардкоде то она помещается в специально отведённое место в программе, а вместо неё используется указатель на это место, написав два раза одинаковую строку testAction получаем две строки в специально отведённом месте (НО компиляторы могут с оптимизировать такие строки, в итоге имеем UB) как сравнивать строки? в STL есть тип данных(class) для строк string пихаем строки в стринг и при сравнении будет происходить преобразование string str="hello world";// или string str("hello world"); if(str=="hello world")//TRUE

Комментариев нет:

Отправить комментарий