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

What's the advantage of using for_each loop?

P: n/a
What's the advantage of using for_each than the normal iteration using
for loop?

Is there any 'tweak' to use stream objects as 'Function' parameter of
for_each loop. Seems copy function can do the same.

May 30 '07 #1
Share this Question
Share on Google+
13 Replies


P: n/a
What's the advantage of using for_each than the normal iteration using
for loop?
In general for_each is supposed to be less verbose than for-loop.
The cool thing about for_each is:

1) you can pass the function objects by reference
2) you can apply side-effects on the function object
3) you can use the return value of the for_each() algorithm
Is there any 'tweak' to use stream objects as 'Function' parameter of
for_each loop. Seems copy function can do the same.
How about the boost library?
http://www.boost.org/

With std::copy you can do something like:

copy(a.begin(), a.end(), ostream_iterator<string>(cout, " ");
and with boost::lambda you can do the same thing:

for_each(a.begin(), a.end(), std::cout << _1 << ' ');

May 30 '07 #2

P: n/a
Sarath <CS*****@gmail.comwrote:
What's the advantage of using for_each than the normal iteration using
for loop?
I'm beginning to think this should be an FAQ. :-)

A key benefit of the standard library algorithms is that they save
the programmer from writing explicit loops. Loops can be tedious and
error-prone. The for_each() algorithm is the simplest algorithm in
the sense that it does nothing but eliminate an explicit loop... One
common use of for_each() is to extract information from elements of a
sequence. -- Stroustrup
Is there any 'tweak' to use stream objects as 'Function' parameter of
for_each loop. Seems copy function can do the same.
Obviously, if a more specialized algorithm works, then use it instead.
May 30 '07 #3

P: n/a
On May 30, 10:33 am, v.r.mari...@gmail.com wrote:
What's the advantage of using for_each than the normal iteration using
for loop?

In general for_each is supposed to be less verbose than for-loop.
The cool thing about for_each is:

1) you can pass the function objects by reference
2) you can apply side-effects on the function object
3) you can use the return value of the for_each() algorithm
Is there any 'tweak' to use stream objects as 'Function' parameter of
for_each loop. Seems copy function can do the same.

How about the boost library?http://www.boost.org/

With std::copy you can do something like:

copy(a.begin(), a.end(), ostream_iterator<string>(cout, " ");

and with boost::lambda you can do the same thing:

for_each(a.begin(), a.end(), std::cout << _1 << ' ');
Yea I used boost::lambda to do the same. But it's not possible to do
with ISO C++ STL implementation

May 30 '07 #4

P: n/a
On May 30, 2:16 am, Sarath <CSar...@gmail.comwrote:
What's the advantage of using for_each than the normal iteration using
for loop?
Obfuscation?

Seriously, the advantage of using for_each is that the reader
knows that the loop doesn't terminate prematurely. This has to
be weighed against the fact the code you execute each pass must
be separate---if the code is more or less general, and has a
good name, this is an advantage; if the code is specialized to
the place making the call, and has no good name, then it is bad.

Note too that any good coding guideline will forbid using break
or return in a loop anyway, which sort of negates the first
advantage.
Is there any 'tweak' to use stream objects as 'Function' parameter of
for_each loop. Seems copy function can do the same.
There is a standard class which converts streams to iterators.
Functions which need iterators can use them. Thus, they work
for the first two arguments of for_each, but not for the third.

--
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
May 30 '07 #5

P: n/a
Sarath wrote:
What's the advantage of using for_each than the normal iteration using
for loop?
Brevity. The "for_each" function is a rudimentary form of higher-order
function from functional programming.

For example, the pedagogical C++ example:

copy(a.begin(), a.end(), ostream_iterator<string>(cout, " ");

May be written:

iter print a

in a functional language, where "iter" is a higher-order function equivalent
to "for_each" or "copy". However, functional programming languages like
Haskell, OCaml, F# and Standard ML are all much better at finding and
explaining errors at compile time.

--
Dr Jon D Harrop, Flying Frog Consultancy
OCaml for Scientists
http://www.ffconsultancy.com/product...ntists/?usenet
May 30 '07 #6

P: n/a

<v.*********@gmail.comwrote:
The cool thing about for_each is:
1) you can pass the function objects by reference
I don't see how that could work. I thought the function
object is always passed by value? I tried passing a function
object to a for_each loop once, where the function object was
collecting data about operations. But that didn't work,
because for_each used a *copy* of the object, rather than the
object itself.

I was writing a spelling-checker, just for programming
practice. The for_each loop looked something like:

Append FuncObj = Append(Dictionary);
for_each(Dicts.begin(), Dicts.end(), FuncObj);

("Dicts" is a list of file paths, and "Dictionary" is a list
of words.)

But the the counts of files and lines went into the unnamed
*copy* of FuncObj, not FuncObj itself.
2) you can apply side-effects on the function object
?
3) you can use the return value of the for_each() algorithm
Hmmm.... Interesting. Perhaps, then, something like the following
would work in my spelling checker (could be used to count files --
or lines -- appended to a list of strings):

Append FuncObjCopy =
for_each(Dicts.begin(), Dicts.end(), Append(Dictionary););
cout << "Files processed = " << FuncObjCopy.files << endl;
cout << "Lines processed = " << FuncObjCopy.lines << endl;

Not quite as nice as getting for_each to use the original function
object, but almost.
--
Cheers,
Robbie Hatley
lonewolf aatt well dott com
triple-dubya dott tustinfreezone dott org
May 30 '07 #7

P: n/a
On Wed, 30 May 2007 15:30:36 +0100, Jon Harrop wrote:
>
The "for_each" function is a rudimentary form of higher-order
function from functional programming.
The amazing thing is that in the course of its evolution C++ changed
the underlying paradigm from object-oriented to value-oriented,
functional. This 'paradigm shift' happened approximately in 1995 with
the inauguration of STL and caused a lot of confusion ever since.
--
Roland Pibinger
"I often think that the sole purpose of the STL is to see how many
lines one can use to obfuscate a simple loop." - John Potter
May 30 '07 #8

P: n/a
On May 30, 5:02 pm, "Robbie Hatley" <bogus.addr...@no.spamwrote:
<v.r.mari...@gmail.comwrote:
The cool thing about for_each is:
1) you can pass the function objects by reference
I don't see how that could work. I thought the function
object is always passed by value?
They are.
I tried passing a function object to a for_each loop once,
where the function object was collecting data about
operations. But that didn't work, because for_each used a
*copy* of the object, rather than the object itself.
I was writing a spelling-checker, just for programming
practice. The for_each loop looked something like:
Append FuncObj = Append(Dictionary);
for_each(Dicts.begin(), Dicts.end(), FuncObj);
("Dicts" is a list of file paths, and "Dictionary" is a list
of words.)
But the the counts of files and lines went into the unnamed
*copy* of FuncObj, not FuncObj itself.
The STL requires functional objects to have value semantics, so
you would (generally) write something like:

Append FuncObj( for_each( Dicts.begin(),
Dicts.end(),
Append( Dictionary ) ) ) ;

The problem becomes more difficult if you are trying to use a
polymorphic object; you have to give it value semantics which do
not loose the polymorphic behavior, by means of the
letter/envelope idiom, or something similar. (Often, just a
small wrapper around a pointer will do the trick.)
2) you can apply side-effects on the function object
?
The function object can do just about anything which won't
invalidate the iterators. Including modifying program state.
3) you can use the return value of the for_each() algorithm
Hmmm.... Interesting. Perhaps, then, something like the following
would work in my spelling checker (could be used to count files --
or lines -- appended to a list of strings):
Append FuncObjCopy =
for_each(Dicts.begin(), Dicts.end(), Append(Dictionary););
cout << "Files processed = " << FuncObjCopy.files << endl;
cout << "Lines processed = " << FuncObjCopy.lines << endl;
Not quite as nice as getting for_each to use the original function
object, but almost.
In some contexts (including this one, IMHO), it's even nicer.
In others (i.e. polymorphic agents), it's a real pain you know
where.

--
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

May 31 '07 #9

P: n/a
Robbie Hatley wrote:
<v.*********@gmail.comwrote:
>The cool thing about for_each is:
1) you can pass the function objects by reference

I don't see how that could work. I thought the function
object is always passed by value? I tried passing a function
object to a for_each loop once, where the function object was
collecting data about operations. But that didn't work,
because for_each used a *copy* of the object, rather than the
object itself.
There are things coming in the new C++ that will make this easier I
think. Would be something like so maybe:

std::for_each(itera, iterb, ref(f));

I think the committee is *trying* to get the std locked some time this year?
May 31 '07 #10

P: n/a
In article <f3**********@aioe.org>, us**@example.net says...

[ ... ]
I think the committee is *trying* to get the std locked some time this year?
Sort of. The deadline for addition of new features is in October, IIRC.
I don't know the exact schedule after that, but my guess would be that
for roughly a year after that the standard will still be open to
modification, but only to fix the definition(s) of existing features,
not to add new ones.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 2 '07 #11

P: n/a

James Kanze wrote:
Append FuncObj( for_each( Dicts.begin(),
Dicts.end(),
Append( Dictionary ) ) ) ;
Coool! That looks like a work of art. I like it. No assignment,
minimum copying; just uses constructors. Thanks for the tip.
I re-wrote my "build dictionary" function along those lines:

// Build "Dictionary" from dictionary files:
void
ns_Spell::
BuildDictionary
(
std::list<std::string& Dictionary
)
{
std::list<std::stringDicts;
rhdir::LoadFileList
(
Dicts, // List of dictionary paths.
"C:/bin/*.dic", // Wildcard.
1, // Files only (no dirs).
2 // Append to list without clearing.
);

// Define "Append" to mean "class rhdir::AppendFileToListFunctor",
// for purposes of brevity:
typedef class rhdir::AppendFileToListFunctor Append;

// For each dictionary file, append its contents to Dictionary:
Append
FuncObj
(
for_each
(
Dicts.begin(),
Dicts.end(),
Append(Dictionary)
)
);

BLAT("In ns_Spell::BuildDictionary().")
BLAT(" Number of files processed = " << FuncObj.applications)

rhutil::SortDup(Dictionary);

return;
} // end BuildDictionary()

--
Cheers,
Robbie Hatley
East Tustin, CA, USA
lonewolf aatt well dott com
triple-dubya dott tustinfreezone dott org
Jun 4 '07 #12

P: n/a
Robbie Hatley wrote:
James Kanze wrote:

Append FuncObj( for_each( Dicts.begin(),
Dicts.end(),
Append( Dictionary ) ) ) ;
Coool! That looks like a work of art.
Indeed, this is an idiom from functional programming where the above would
typically be written:

iter add dicts

and "iter" is referred to as a higher-order function because it accepts the
function "add" as an argument.

--
Dr Jon D Harrop, Flying Frog Consultancy
OCaml for Scientists
http://www.ffconsultancy.com/product...ntists/?usenet
Jun 5 '07 #13

P: n/a
On May 30, 6:02 pm, "Robbie Hatley" <bogus.addr...@no.spamwrote:
<v.r.mari...@gmail.comwrote:
The cool thing about for_each is:
1) you can pass the function objects by reference

I don't see how that could work. I thought the function
object is always passed by value? I tried passing a function
object to a for_each loop once, where the function object was
collecting data about operations. But that didn't work,
because for_each used a *copy* of the object, rather than the
object itself.
My fault. It should be:

1) you can pass the argument to the function object by reference.
BTW it looks like i cant change my username, now that's cool.

Jun 5 '07 #14

This discussion thread is closed

Replies have been disabled for this discussion.