Execute a function in each element of the list conditionally

T

Teddy.Gammell

Hi,

I would like to write a function which does this:

for each element in the list
call f1() of each element.
if f1() return false, break the loop
else continue

I try to use the for_each() algorithm, but it does not let me stop the
loop conditionally (in my case, the return value of the functor I pass
in).
I check transform() also, but that does not work out.

Is there any STL algorithm that i can use? If yes, please advice.

Thank you.
 
M

Mike Wahler

Hi,

I would like to write a function which does this:

for each element in the list
call f1() of each element.
if f1() return false, break the loop
else continue

I try to use the for_each() algorithm, but it does not let me stop the
loop conditionally (in my case, the return value of the functor I pass
in).
I check transform() also, but that does not work out.

Is there any STL algorithm that i can use? If yes, please advice.

Thank you.

You can use 'find' to locate the element which should
cause termination of the 'loop'. Save an iterator to
that element (let's call it 'found_it') Then use e.g.
'for_each()' with iterator arguments begin() and 'found_it'.
This does require two passes through those elements, but
it's all I can think of at the moment. (If performance
is not impacted, then I'd call it 'good enough').

-Mike
 
W

wdmanegold

Hi,

I would like to write a function which does this:

for each element in the list
call f1() of each element.
if f1() return false, break the loop
else continue

I try to use the for_each() algorithm, but it does not let me stop the
loop conditionally (in my case, the return value of the functor I pass
in).
I check transform() also, but that does not work out.

Is there any STL algorithm that i can use? If yes, please advice.

Thank you.

Its not exactly STL, but I would think this could just be solved with a
single for() loop; something along the lines of:
//assuming vector of ints:
for(vector<int>::iterator i = j.begin(); (*i).f1() && i < j.end(); i =
i.next()) ;
 
H

Howard

wdmanegold said:
Its not exactly STL, but I would think this could just be solved with a
single for() loop; something along the lines of:
//assuming vector of ints:
for(vector<int>::iterator i = j.begin(); (*i).f1() && i < j.end(); i =
i.next()) ;

A few items of note:

1) an int doesn't have any member functions, so you can't call f1() for it.
Since we don't know the class, we can't tell what to put there, but maybe
something like vector<myClass> would illustrate the point better than int.

2) From what I've seen, using "!=" instead of "<" is the usual method for
the comparison. Since a vector is a random-access container, I guess that
"<" is perfectly legal, but I wonder if it's as efficient, since I would
suspect it has to do some kind of "distance" calculation to be sure it's not
really ">".

3) What's ".next()"? I don't see that in my book anywhere. Iterators are
generally incremented via "++i" (assuming i as the iterator, naturally).

So, the example I'd give would be:

for (vector<int>::iterator i = j.begin(); (*i).f1() && i != j.end(); ++i);

But personally, I'd probably just put a break condition in the body of my
for loop, because I find that easier to read than stuffing multiple
conditions and other such work into my loop control statement.

-Howard
 
A

Alf P. Steinbach

* (e-mail address removed):
Hi,

I would like to write a function which does this:

for each element in the list
call f1() of each element.
if f1() return false, break the loop
else continue

I try to use the for_each() algorithm, but it does not let me stop the
loop conditionally (in my case, the return value of the functor I pass
in).
I check transform() also, but that does not work out.

Is there any STL algorithm that i can use? If yes, please advice.

'std::find_if' is probably what you're looking for; just negate your
continuation condition.
 
R

roberts.noah

Howard said:
2) From what I've seen, using "!=" instead of "<" is the usual method for
the comparison. Since a vector is a random-access container, I guess that
"<" is perfectly legal, but I wonder if it's as efficient, since I would
suspect it has to do some kind of "distance" calculation to be sure it's not
really ">".

I don't think there is any performance problem but there can be a
maintenence issue. If later you change the type of container to
something other than a vector < does not work anymore. The compiler
error is this monsterous template malfunction that is very hard to
decipher. Once you run into the problem of course you can easily read
it, but the first time it happens is a bit of a bummer.
 
W

William Manegold

Howard said:
A few items of note:

1) an int doesn't have any member functions, so you can't call f1() for it.
Since we don't know the class, we can't tell what to put there, but maybe
something like vector<myClass> would illustrate the point better than int.

2) From what I've seen, using "!=" instead of "<" is the usual method for
the comparison. Since a vector is a random-access container, I guess that
"<" is perfectly legal, but I wonder if it's as efficient, since I would
suspect it has to do some kind of "distance" calculation to be sure it's not
really ">".

3) What's ".next()"? I don't see that in my book anywhere. Iterators are
generally incremented via "++i" (assuming i as the iterator, naturally).

So, the example I'd give would be:

for (vector<int>::iterator i = j.begin(); (*i).f1() && i != j.end(); ++i);

But personally, I'd probably just put a break condition in the body of my
for loop, because I find that easier to read than stuffing multiple
conditions and other such work into my loop control statement.

-Howard
Eep; thanks for catching that. Guess I didn't think it through properly.
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top