By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,215 Members | 1,952 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,215 IT Pros & Developers. It's quick & easy.

Iterating and printing

P: n/a
Ok,
Imagine I have a class

class C
{

};

ostream& operator<<(ostream& o, const C& c) { ...}

I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of

stringstream s;
for( collection<C>::iterator it = Collection.begin(); it !=
Collection.end(); it++)
{
cout << *it;
s << *it;
}
string res = s.str();
So I tried a couple of options:

void printC(ostream& o, const C& c) { o << c;}
for_each( Collection.begin(), Collection.end(),
bind1st( fun_ptr( printC), cout) );

which wouldn't work because of a problem of refs to refs,
so i started on the second problem and created a class

class P
{
public:
P() { //Setup code }
stringstream s;
string getString(){ return s.str();}
void operator()(const C& c) { s << c; }
};

and tried to pass this:
P p;
for_each( Collection.begin(), Collection.end(), p );

which fails because we can't copy P, because it contains a
stringstream which can't be copied.

So i currently have

class Q
{
string s;
void operator()(const C& c) { stringstream ss; ss << c; s+=
ss.str(); }
};

Q q;
for_each( Collection.begin(), Collection.end(), q );

which, correct me if i'm wrong, seems like a very crude way of doing
it!

This seems like a fairly common task!
Any thoughts on the matter would be greatly appreiciated!
Michael

Apr 6 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
mi********@googlemail.com wrote:
Ok,
Imagine I have a class

class C
{

};

ostream& operator<<(ostream& o, const C& c) { ...}

I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of
[..]
Any thoughts on the matter would be greatly appreiciated!
Have you tried using 'ostream_iterator'? It should work well with
both 'cout' and any stringstream you can create.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 6 '07 #2

P: n/a
On 2007-04-06 14:17, mi********@googlemail.com wrote:
Ok,
Imagine I have a class

class C
{

};

ostream& operator<<(ostream& o, const C& c) { ...}

I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of
Don't know about for_each but std::copy can be quite useful together
with ostream_iterator mentioned by Victor:

int main()
{
std::vector<intvec;
for (int i = 0; i < 10; ++i)
vec.push_back(i);

std::stringstream ss;
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(ss, " "));
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n" << ss.str() << "\n";
return 0;
}

--
Erik Wikström
Apr 6 '07 #3

P: n/a
On 6 Apr, 14:58, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
mikehul...@googlemail.com wrote:
Ok,
Imagine I have a class
class C
{
};
ostream& operator<<(ostream& o, const C& c) { ...}
I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of

[..]
Any thoughts on the matter would be greatly appreiciated!

Have you tried using 'ostream_iterator'? It should work well with
both 'cout' and any stringstream you can create.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Thanks Victor, I will give that a go!

Apr 6 '07 #4

P: n/a
On 6 Apr, 15:30, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-04-06 14:17, mikehul...@googlemail.com wrote:
Ok,
Imagine I have a class
class C
{
};
ostream& operator<<(ostream& o, const C& c) { ...}
I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of

Don't know about for_each but std::copy can be quite useful together
with ostream_iterator mentioned by Victor:

int main()
{
std::vector<intvec;
for (int i = 0; i < 10; ++i)
vec.push_back(i);

std::stringstream ss;
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(ss, " "));
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n" << ss.str() << "\n";
return 0;

}

--
Erik Wikström
Thanks Erik, I'll give it a try!

Apr 6 '07 #5

P: n/a
On Apr 6, 2:17 pm, "mikehul...@googlemail.com"
<mikehul...@googlemail.comwrote:
Imagine I have a class
class C
{

};
ostream& operator<<(ostream& o, const C& c) { ...}
I have a collection of these objects, in an STL list or vector and
want to do 2 things:
1/ Print all these objects to cout
2/ Write all these objects to a long string
Now, I wanted to try and use for_each and avoid my usual code of
Forget for_each. It doesn't buy you anything here. (You can
use it, but you end up writing more code than if you wrote the
loop manually.)
stringstream s;
for( collection<C>::iterator it = Collection.begin(); it !=
Collection.end(); it++)
{
cout << *it;
s << *it;}
You don't really want to output to both streams in the same
loop, do you? And doubtlessly, you'll need a separator or some
other formatting structure as well.

Typically, I'd encapsulate the container in a class of my own
anyway, and then add something like:

std::ostream&
operator<<( std::ostream& dest, ContainerC const& source )
{
dest << '[' ;
for ( ContainerC::iterator it = source.begin() ;
it != source.end() ;
++ it ) {
if ( it != source.begin() ) {
dest << ", " ;
}
dest << *it ;
}
dest << ']' ;
return dest ;
}

As you can see, there's a bit more to it than just iterating
over the values; handling the separator is particularly
bothersome; the std::ostream_iterator got it wrong, and for that
reason are practically useless.
This seems like a fairly common task!
It is, but since formatting is so specific, it tends to be
written out explicitly each time it's needed.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 6 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.