xdavidliu
xdavidliu

Reputation: 3042

incrementing back_inserter is optional?

I'm confused as to whether I should increment an OutputIterator when I set it. See the following code in which I'm trying to split a string. My problem is with the third line of the while loop, the code seems to work fine whether I have *oit = ... or *oit++ = ... Can someone explain to me why?

template<class O> void split(string& s, O oit){

        string::iterator jt, it = s.begin();

   while(1){
        jt = find(it, s.end(), ' ');
        if(it == s.end() && jt == s.end()) return;
        *oit++ = string(it, jt);
        it = jt;
        if(it != s.end() ) it++;
   }
}

...

int main(){

        string s;
        getline(cin, s);

        vector<string> v;

        split(s, back_inserter(v));
        copy(v.begin(), v.end(), ostream_iterator<string>(cout, "\n"));        

}

Upvotes: 2

Views: 557

Answers (3)

David G
David G

Reputation: 96800

Both parts work because standard iterators are designed to be functionally equivalent to raw pointers when used with generic programming. When raw pointers are used, they must be incremented to reach the subsequent address.

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

The concept requires that you increment an output iterator for each write you do. Although the std::back_insert_iterator<T> may call push_back() on the corresponding object on each assignment to *it, the concept still demands that the increment operator is called. In principle, output iterators could be function calls but to fit into the same interface used also by pointers, they need to support the same operations.

The specification of std::back_insert_iterator<Cont> states that each assignment of a typename Cont::value_type calls cont.push_back(value) on the underlying type, operator*() just returns the iterator itself, as does operator++().

Upvotes: 4

Jerry Coffin
Jerry Coffin

Reputation: 490108

std::back_inserter creates an iterator that inserts by calling push_back on the underlying collection. That means the increment isn't necessary for it to work correctly.

The same is not necessarily true of other output iterators though, so for your code to be correct, it should perform the increment, event though in this particular case it's basically ignored.

Just for what it's worth, in this particular case you can get the same basic effect with a lot less/simpler code:

string s;
getline(cin, s);

replace(s, ' ', '\n');
cout << s;

Upvotes: 4

Related Questions