Инициализация итератора
vector<int> m={1,2,3};
m.begin()++;
cout<<m[0];}
Вопрос, почему не изменяется значение итератора на 0-й элемент?
Ответы (2 шт):
Рассмотрим код
int a = 5;
int * p = &a;
Ds ощущаете разницу между
(*p)++;
и
p++;
? В первом случае это инкремент того, на что указатель указывает, во втором — просто инкремент указателя.
Вот примерно то же самое и с итераторами: итератор по сути аналог указателя.
Что делает m.begin() - возвращает итератор (т.е. экземпляр типа iterator для специфического типа вектора). Этот итератор представляет собой новый безымянный объект, значение которого указывает на начало вектора m.
Далее ++ выполняет постинкремент этого безымянного объекта. После ; этот объект перестаёт существовать.
m.begin()++;
^--- безымянный объект, для которого был выполнен инкремент, умирает
Дальнейший вывод m[0] представляет собой вызов operator[] для вектора, который перегружен для предоставления доступа к элементам по индексу. В данном случае там (по индексу 0) расположена 1, которой проинициализирован в первой строке начальный элемент массива. Этот вывод вообще никак не связан с выполненным ранее инкрементом безымянного объекта итератора, который был получен строкой выше.
Если хочется вывести значение через итератор, и при этом, чтобы был выведен следующий элемент массива, можно написать так:
auto it = m.begin() + 1;
cout << *it; // выведет 2 (т.е. элемент m[1])
Или однострочник:
cout << *(m.begin() + 1);
Если нужно изменить непосредственно сам элемент m[0], то надо выполнить инкремент после разыменования итератора:
(*m.begin())++;
cout << m[0]; // выведет 2 (т.е. увеличенный элемент m[0])
Для однострочного варианта, чтобы значение сразу стало наблюдаемым, постинкремент следует заменить преинкрементом:
cout << ++*m.begin();