Ostream_Iterator Question

Hey Forum,

Sorry for the general question but I'm still very new to C++ (and programming in general). I am trying to teach myself about the STL and its uses. My question is, why do you need to use the ostream_iterator / istream_iterator.

1
2
  ...
  ostream_iterator<string, char> out(cout, " ");


Is it's main use as an argument to a STL method or general function? For example

1
2
  ...
  set_union(someSetA.begin(), someSetA.end(), someSetB.begin(), someSetB.end(), out)


Could you just use a standard istream/ostream object like cout for most purposes or does the ostream_iterator add some other benefit for STL use? Thanks.
The C++ algorithms expect iterators (and functors, where appropriate) as arguments, and a stream object is not one of those. There's simply no other way: set_union, in your example, will push its result sequence into the output iterator you supply using output iterator interface, not into some arbitrary object by some arbitrary means.

(the output iterator could be a begin iterator in some vector, or a back_inserter(), a plain pointer, or, in this case, an ostream_iterator. The algorithm doesn't care)
Last edited on
for example you have file containing unknown number of integers, one char 'D' and unknown amount of double. You need to store all integers in vector,sum all doubles and output it on screen.
Also you need to output all numbers in vector squared.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
    std::vector<int> val;
    std::ifstream str("1.txt");
    std::copy(std::istream_iterator<int>(str),
              std::istream_iterator<int>(),
              std::back_inserter<std::vector<int>>(val));
    str.clear();
    str.ignore();
    std::cout << std::accumulate(std::istream_iterator<double>(str),
                                 std::istream_iterator<double>(), 0.0);
    std::cout << "\n";
    std::transform(val.begin(), val.end(),
                   std::ostream_iterator<int>(std::cout, "\n"),
                   [](int x){return x*x;});
}
//1.txt:
1 2 3 5 6 8 4 5 6 7 D 
65.6 34.4 0.5 0.5
//Output:
101
1
4
9
25
36
64
16
25
36
49
Last edited on

The C++ algorithms expect iterators (and functors, where appropriate) as arguments, and a stream object is not one of those.


Thanks, Cubbi. That makes a lot of since. I haven't even touched on functors yet, but looking forward to it. I'm going to have to do a bit more research on iterators. They certainly seem like an important (if not critical) part of the STL and perhaps generic programming in general.

MiiniPaa. Great example. So the back_insert_iterator is, in effect, turning copy() algorithm into an insert() algorithm (of some sort)? Interesting.

> So the back_insert_iterator is, in effect, turning copy() algorithm into an insert() algorithm (of some sort)

Yes. Inserters are very useful for non-trivial algorithms like std::set_union(). Not so much with std::copy().

1
2
3
// std::vector<int> vec ;
// std::copy( begin, end, std::back_inserter(vec) ) ;
std::vector<int> vec { begin, end } ;


1
2
3
std::vector<int> vec { 0, 1, 2, 3, 4 } ;
// std::copy( begin, end, std::back_inserter(vec) ) ;
vec.insert( vec.end(), begin, end ) ;

With the advent of range based for loop, I hardly ever use output iterators in conjunction with with std::copy(), std::transform() and the like. For instance, I would tend to write the above code this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
#include <numeric>

int main()
{
    std::ifstream stm("1.txt");
    std::vector<int> val { std::istream_iterator<int>(stm),
                           std::istream_iterator<int>() } ;
    stm.clear();
    stm.ignore();

    std::cout << std::accumulate( std::istream_iterator<double>(stm),
                                  std::istream_iterator<double>(), 0.0 ) << '\n' ;
    for( int x : val ) std::cout << x*x << '\n' ;
}
Topic archived. No new replies allowed.