итераторы вставки в stl - PullRequest
       20

итераторы вставки в stl

1 голос
/ 08 февраля 2010

Может быть, я упускаю что-то совершенно очевидное, но я не могу понять, почему можно использовать back_inserter / front_inserter / insertter, вместо того, чтобы просто предоставить соответствующий итератор из интерфейса контейнера. И это мой вопрос.

Ответы [ 4 ]

4 голосов
/ 08 февраля 2010

Потому что те вызывают push_back, push_front и insert, что "нормальные" итераторы контейнера не могут (или, по крайней мере, не делают).

Пример:

int main() {
  using namespace std;
  vector<int> a (3, 42), b;

  copy(a.begin(), a.end(), back_inserter(b));

  copy(b.rbegin(), b.rend(), ostream_iterator<int>(cout, ", "));
  return 0;
}
2 голосов
/ 08 февраля 2010

Основная причина в том, что обычные итераторы перебирают существующие элементы в контейнере, в то время как семейство итераторов * insertter фактически вставляет новые элементы в контейнер.

std::vector<int> v(3);  // { 0, 0, 0 }
int array[] = { 1, 2, 3 };
std::copy( array, array+3, std::back_inserter(v) ); // adds 3 elements
   // v = { 0, 0, 0, 1, 2, 3 }
std::copy( array, array+3, v.begin() ); // overwrites 3 elements
   // v = { 1, 2, 3, 1, 2, 3 } 
int array2[] = { 4, 5, 6 };
std::copy( array2, array2+3, std::inserter(v, v.begin()) );
   // v = { 4, 5, 6, 1, 2, 3, 1, 2, 3 }
0 голосов
/ 08 февраля 2010

Все зависит от того, что вам действительно нужно. В зависимости от ваших намерений могут использоваться оба типа итераторов.

Когда вы используете «обычный» итератор, он не создает новые элементы в контейнере. Он просто записывает данные в существующие последовательные элементы контейнера, один за другим. Он перезаписывает любые данные, которые уже находятся в контейнере. И если разрешено достигать конца последовательности, любые дальнейшие записи приводят к тому, что она «падает с конца» и вызывает неопределенное поведение. То есть это падает.

Итераторы вставки, с другой стороны, создают новый элемент и вставляют его в текущую позицию (спереди, сзади, где-то в середине) каждый раз, когда что-то записывается через них. Они никогда не перезаписывают существующие элементы, они добавляют новые.

0 голосов
/ 08 февраля 2010

Итератор указывает на элемент и вообще не знает, к какому контейнеру он прикреплен. (Итераторы основывались на указателях, и по указателю нельзя определить, с какой структурой данных он связан.)

Добавление элемента в контейнер STL изменяет описание контейнера. Например, контейнеры STL имеют функцию .size(), которая должна быть изменена. Так как некоторые метаданные должны измениться, любой новый элемент должен знать, к какому контейнеру он добавляется.

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