Страницы

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

вторник, 31 декабря 2019 г.

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

#cpp


Доброго времени суток! 
Я недавно начал заниматься программированием и сейчас возникла потребность в рассмотрении
контейнера 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;        
                }

мы можем применить операцию разыменования. Заранее благодарен за ответы!    


Ответы

Ответ 1



смотрим описание метода 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

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

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