Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between iterator and back_insert_iterator?

Tags:

c++

stl

If random access iterators can be used to access elements at an arbitrary offset position relative to element they point to (somehow like pointers), why can't they be used in generic algorithms like std::copy() instead of using back_insert_iterator, and what's the difference between both?

like image 862
Algo Avatar asked Dec 05 '22 08:12

Algo


1 Answers

std::back_insert_iterator is a specific kind of output iterator which supports push_back operation. When you write to it using operator=, it push_backs the value into the underlying container — so, in that sense it acts as an adaptor for containers which has push_back member function.

An example would be easy to understand:

std::vector<int> v;

std::back_insert_iterator<std::vector<int>>  it(v);

*it = 10; // it is equivalent to v.push_back(10);
 it = 99; // it is ALSO equivalent to v.push_back(99);

for (auto const & i : v)
    std::cout << i << " " ; //10 99

It outputs :

10 99

Online Demo.

The usual iterator operations ++ and * on it has no effect.

But you rarely use them directly (I've never used it directly untill now). You use them with algorithms, such as std::copy in which case you also use std::back_inserter function which returns an object of type std::back_insert_iterator.

//assuming dest is a container which supports push_back!
std::copy(src.begin(), src.end(), std::back_inserter(dest));

You would also like to see the following (adaptor) iterators:

  • std::front_insert_iteratorn supports push_front operation
  • std::insert_iterator supports insert operation.

So depending on the container, you choose adaptor iterator.

Note that all of them are output iterator.

why can't they be used in generic algorithms like std::copy() instead of using back_insert_iterator.

Of course, you can use the random access iterators (or any output iterator) in algorithms like std::copy, as third argument, but that assumes the iterator is referencing to existing range — *it and ++it are well-defined for the value you passed. You pass them to overwrite the existing elements of the range, whereas std::back_insert_iterator adds new elements to the container.

Hope that helps.

like image 58
Nawaz Avatar answered Dec 09 '22 14:12

Nawaz