Цель состоит в том, чтобы получить доступ к «n-му» элементу вектора строк вместо оператора [] или метода «at». Насколько я понимаю, итераторы можно использовать для навигации по контейнерам, но я никогда раньше не использовал итераторы, и то, что я читаю, сбивает с толку.
Если бы кто-нибудь мог дать мне информацию о том, как этого добиться, я был бы признателен. Спасибо.
Ответы:
Вам нужно сделать использование
begin
иend
методы вvector
классе, которые возвращают итератор со ссылкой на первый и последний элемент соответственно.источник
std::vector
есть итераторы произвольного доступа.std::advance(it, n)
. Он определен так, чтобы делать именно то, что вы хотите, и он будет автоматически использовать,it + n
если итератор помечен как произвольный доступ, или выполнить цикл, если это необходимо.Обычно итераторы используются для линейного доступа к элементам контейнера; однако с помощью «итераторов произвольного доступа» можно получить доступ к любому элементу таким же образом, как и
operator[]
.Для доступа к произвольным элементам вектора
vec
вы можете использовать следующее:Ниже приведен пример типичного шаблона доступа (более ранние версии C ++):
Преимущество использования итератора в том, что вы можете применить тот же шаблон к другим контейнерам :
По этой причине очень легко создать код шаблона, который будет работать одинаково независимо от типа контейнера . Еще одно преимущество итераторов состоит в том, что они не предполагают, что данные находятся в памяти; например, можно создать прямой итератор, который может считывать данные из входного потока или просто генерирует данные на лету (например, генератор диапазона или случайных чисел).
Другой вариант использования
std::for_each
и лямбды:Начиная с C ++ 11 вы можете использовать,
auto
чтобы не указывать очень длинное и сложное имя типа итератора, как было показано ранее (или даже более сложное):И, кроме того, для каждого варианта есть более простой вариант:
И, наконец,
std::accumulate
нужно быть осторожным при добавлении целых чисел или чисел с плавающей запятой.источник
В C ++ - 11 вы можете:
Смотрите здесь варианты: https://en.cppreference.com/w/cpp/language/range-for
источник
7.5.0
на Ubuntu 18.04 и работает с массивом точно так же.Итераторы вектора являются итераторами произвольного доступа, что означает, что они выглядят и выглядят как простые указатели.
Вы можете получить доступ к n-му элементу, добавив n к итератору, возвращаемому из
begin()
метода контейнера , или вы можете использовать оператор[]
.В качестве альтернативы вы можете использовать функцию продвижения, которая работает со всеми видами итераторов. (Вам нужно будет подумать, действительно ли вы хотите выполнять «произвольный доступ» с итераторами, не являющимися произвольными, поскольку это может оказаться дорогостоящим делом.)
источник
advance
итераторы с произвольным доступом или итераторы неизвестной категории, поскольку в этом случае гарантируется, что он будет работать в постоянное время. Вот почему пользовательские итераторы должны быть правильно помечены.advance
это действительно раздражает (из-за использования параметра out), если вы знаете, что имеете дело с итераторами произвольного доступа. Рекомендовал бы только в общем коде, и если бы он не использовался часто (если алгоритм не поддерживает итераторы без произвольного доступа, пусть так и будет - например,std::sort
может сортировать,std::list
но это не так, потому что это было бы смехотворно неэффективным ).operator+
. Но вопрос был явно о векторе, поэтому в первой части вашего ответа нет ничего плохого. Я просто подумал, что вторая часть может подразумевать «вы не можете использовать advance с итераторами произвольного доступа, даже если хотите» для кого-то, кто никогдаadvance
раньше не видел .Vector
должна быть в нижнем регистреВот пример доступа к
ith
индексу astd::vector
с использованиемstd::iterator
внутри цикла, который не требует увеличения двух итераторов.Без цикла
и используя
at
метод:источник