std::for_each

P

Philip Potter

Hello there,

I'm reading about the std::for_each() function in TC++PL, 3rd Ed. It seems
like a good idea, but in practice I can never see a way to bend it to my
wishes without writing huge function objects. The same goes for most things
in <algorithm>, though I don't know if I'm just not used to it or if it
really is ugly.

Specific question:
I have a vector of objects and I'd like to send them all to std::cout. Is
there a way of doing this using standard binders and adapters? I have tried
the following:
std::for_each(myvector.begin(), myvector.end(), std::cout.operator<<);
std::for_each(myvector.begin(), myvector.end(),
bind1st(mem_fun_ref(&ostream::eek:perator<<),std::cout));
...but that didn't work. Would it have worked if operator<<(ostream &, myobj)
was a regular function? Is there a clean, readable, terse way of writing
what I want to write?

General questions:
When do you prefer to use std::for_each(), when do you prefer to use a for
loop over iterators, and when do you prefer to use a for loop over indices?
Is there a textbook which covers good (moral) usage of the members of
<algorithm> and <functional>?

Philip
 
J

Jon Clements

Philip Potter wrote:
[snip]
Specific question:
I have a vector of objects and I'd like to send them all to std::cout. Is
there a way of doing this using standard binders and adapters? I have tried
the following:
std::for_each(myvector.begin(), myvector.end(), std::cout.operator<<);
std::for_each(myvector.begin(), myvector.end(),
bind1st(mem_fun_ref(&ostream::eek:perator<<),std::cout));
..but that didn't work. Would it have worked if operator<<(ostream &, myobj)
was a regular function? Is there a clean, readable, terse way of writing
what I want to write?
[snip]

I'll probably be shot down by others in the NG but I use the Boost
Lambda library at http://www.boost.org/doc/html/lambda.html. In fact,
what you're trying to achieve here is its first example.

Jon.
 
M

mlimber

Philip said:
Hello there,

I'm reading about the std::for_each() function in TC++PL, 3rd Ed. It seems
like a good idea, but in practice I can never see a way to bend it to my
wishes without writing huge function objects. The same goes for most things
in <algorithm>, though I don't know if I'm just not used to it or if it
really is ugly.

Specific question:
I have a vector of objects and I'd like to send them all to std::cout. Is
there a way of doing this using standard binders and adapters? I have tried
the following:
std::for_each(myvector.begin(), myvector.end(), std::cout.operator<<);
std::for_each(myvector.begin(), myvector.end(),
bind1st(mem_fun_ref(&ostream::eek:perator<<),std::cout));
..but that didn't work. Would it have worked if operator<<(ostream &, myobj)
was a regular function? Is there a clean, readable, terse way of writing
what I want to write?

// For some T with operator<<(ostream&, const T&) defined...
std::vector<T> v;
// ...
std::copy( v.begin(), v.end(), std::eek:utput_iterator<T>( cout ) );

Alternately, you could use boost::lambda and boost::bind (aka
std::tr1::bind) to make things more readable. In general, I avoid
General questions:
When do you prefer to use std::for_each(), when do you prefer to use a for
loop over iterators, and when do you prefer to use a for loop over indices?
Is there a textbook which covers good (moral) usage of the members of
<algorithm> and <functional>?

Scott Meyers' _Effective STL_ is one.

Cheers! --M
 
M

mlimber

mlimber said:
// For some T with operator<<(ostream&, const T&) defined...
std::vector<T> v;
// ...
std::copy( v.begin(), v.end(), std::eek:utput_iterator<T>( cout ) );

That should be std::eek:stream_iterator<T>.

Cheers! --M
 
M

Marcus Kwok

Philip Potter said:
I'm reading about the std::for_each() function in TC++PL, 3rd Ed. It seems
like a good idea, but in practice I can never see a way to bend it to my
wishes without writing huge function objects. The same goes for most things
in <algorithm>, though I don't know if I'm just not used to it or if it
really is ugly.

Specific question:
I have a vector of objects and I'd like to send them all to std::cout. Is
there a way of doing this using standard binders and adapters? I have tried
the following:
std::for_each(myvector.begin(), myvector.end(), std::cout.operator<<);
std::for_each(myvector.begin(), myvector.end(),
bind1st(mem_fun_ref(&ostream::eek:perator<<),std::cout));
..but that didn't work. Would it have worked if operator<<(ostream &, myobj)
was a regular function? Is there a clean, readable, terse way of writing
what I want to write?

If you have defined

std::eek:stream& operator<<(std::eek:stream&, const YourObj&);

then for a std::vector<YourObj> you can do:

#include <algorithm>
#include <iterator>

std::vector<YourObj> obj_vect;
// ...
std::copy(obj_vect.begin(),
obj_vect.end(),
std::eek:stream_iterator<YourObj>(std::cout, "\n"));

where "\n" specifies the delimiter to place between vector entries.
General questions:
When do you prefer to use std::for_each(), when do you prefer to use a for
loop over iterators, and when do you prefer to use a for loop over indices?

Honestly, I almost never use std::for_each(). I use iterators when I
can, unless there is a situation in which I have to deal with parallel
data structures for some reason. With parallel data structures, I mean
something like:

std::vector<int> i_vect;
std::vector<double> d_vect;

for (std::vector<int>::size_type i = 0; i != i_vect.size(); ++i) {
something = i_vect * d_vect;
}

where i_vect and d_vect both store some property about the same
logical entity, but for some design reason a
std::vector said:
Is there a textbook which covers good (moral) usage of the members of
<algorithm> and <functional>?

Not sure on specific book recommendations. Maybe check out the reviews
on http://accu.org/ .
 
G

Gernot Frisch

I'll probably be shot down by others in the NG but I use the Boost
Lambda library at http://www.boost.org/doc/html/lambda.html. In
fact,
what you're trying to achieve here is its first example.

taking a look at lambda: it looks rather easy for such purposes to do.
but... uhm... Can someone explain to me how they did it?
Is _1 a class that has all the +-*/ operators?
And how do they de-reference _1?
<blink blink>
 
S

Shooting

Yeah, but _1 is not a class, It's an object that has all the
+-*/...ect. operators. For those function can not specified by
operators, they also have their way to deal with such as new , delete
ect...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top