Есть ли причина, по которой STL не предоставляет функции для возврата итератора через индекс? - PullRequest
3 голосов
/ 14 января 2010

Есть ли причина, по которой STL не предоставляет функции для возврата итератора в контейнер через индекс?

Например, допустим, я хотел вставить элемент в std::list, но в n-й позиции. Похоже, что мне нужно извлечь итератор через что-то вроде begin() и добавить n к этому итератору. Я думаю, было бы проще, если бы я мог просто получить итератор в n-й позиции с чем-то вроде std::list::get_nth_iterator(n).

Я подозреваю, что неправильно понял принципы STL. Может кто-нибудь помочь объяснить?

Спасибо BeeBand

Ответы [ 4 ]

12 голосов
/ 14 января 2010

Вы можете использовать advance() из заголовка <iterator>:

list<foo>::iterator iter = advance(someFooList.begin(), n);

list<foo>::iterator iter = someFooList.begin();

std::advance( iter, n);

Если итератор поддерживает произвольный доступ (например, vector), он будет работать достаточно эффективно, если он поддерживает только увеличение (или уменьшение) итератора, например list, он будет работать, но только так, как может .

5 голосов
/ 14 января 2010

std::list - это связанный список. Так что он не поддерживает произвольный доступ. Чтобы добраться до n-й позиции в списке, вы должны начать с начала и двигаться по всем узлам, пока не достигнете n. Это довольно дорого (O (n)), и поэтому плохо иметь метод, который не предполагает такие расходы. get_nth_iterator(n) подразумевает получение итератора, указывающего на n-й узел, дешево.

std::vector, конечно, поддерживает это напрямую с оператором [], потому что структура данных поддерживает произвольный доступ, и это очень дешево для него.

2 голосов
/ 14 января 2010

std :: list не является контейнером произвольного доступа, поэтому нет причин для доступа к n-му элементу. если вам это нужно, попробуйте вместо этого использовать std :: vector ..

1 голос
/ 15 января 2010

Как правило, все, что может быть дорогостоящим, делается немного неуклюжим, поэтому вы не будете делать это случайно. Используя ваш пример, с контейнером, который предоставляет итераторы произвольного доступа, это будет просто container.begin()+n, но для std::list (который обеспечивает прямой итератор) вам нужно будет использовать list.begin(), за которым следует advance().

Если вы хотите получить итератор N th , скорее всего, вам просто не следует использовать std::list. С другой стороны, если вы начнете это предложение с "шансов", оно останется почти как истина ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...