views:

257

answers:

4

Hello,

This question is a matter of style, since you can always write a for loop or something similar; however, is there a less obtrusive STL or BOOST equivalent to writing:

for (container<type>::iterator iter = cointainer.begin();
     iter != cointainer.end();
     iter++)
 iter->func();

?

Something like (imagined) this:

call_for_each(container.begin(), container.end(), &Type::func);

I think it would be 1) less typing, 2) easier to read, 3) less changes if you decided to change base type/container type.

EDIT: Thanks for your help, now, what if I wanted to pass some arguments to the member function?

+18  A: 
 #include <algorithm> // for_each
 #include <functional> // mem_fun

 // ...

 std::for_each(container.begin(), container.end(), 
                   std::mem_fun(&Type::func));

See for_each and mem_fun documentation for details.

Missed your edit: Anyway here is another way of achieving what you want without using Boost, if ever need be:

std::for_each(foo_vector.begin(), foo_vector.end(),
    std::bind2nd(std::mem_fun_ref(&Foo::func), 1));
dirkgently
Beat me by 8 seconds
JaredPar
@JaredPar/bb: ROFLMAO!
dirkgently
my 2 cents for your speed :)
aJ
+1. or alternatively mem_fun_ref if the container contains the objects instead of pointers to them
Johannes Schaub - litb
@litb: Thanks, I hesitated about both BOOST_FOREACH and mem_fun_ref(). I can never decide when I am writing too much or too little :P
dirkgently
+4  A: 

You can use std::for_each or boost's foreach constructs.

Use boost's BOOST_FOREACH or BOOST_REVERSE_FOREACH when you don't want to move the logic into another function.

Brian R. Bondy
+1. BOOST_FOREACH(type does look quite neat
Johannes Schaub - litb
A: 

If you actually want to improve performance rather than just pretty up your code, what you really need is a map function. Eric Sink wrote a .net implementation

Chris Upchurch
Thanks, I'm looking for a generic C++ (platform independent) solution.
kyku
+4  A: 

I found out that boost bind seems to be well suited for the task, plus you can pass additional arguments to the method:

#include <iostream>
#include <functional>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>

struct Foo {
    Foo(int value) : value_(value) {
    }

    void func(int value) {
        std::cout << "member = " << value_ << " argument = " << value << std::endl;
    }

private:
    int value_;
};

int main() {
    std::vector<Foo> foo_vector;

    for (int i = 0; i < 5; i++)
        foo_vector.push_back(Foo(i));

    std::for_each(foo_vector.begin(), foo_vector.end(),
        boost::bind(&Foo::func, _1, 1));
}
kyku
+1 because you beat me by 5minutes with that bind answer :p (oh, std::mem_fun_ref is crap when using with bound arguments!)
Johannes Schaub - litb
+1, for figuring this out without all by yourself and for using Boost. Cheers!
dirkgently
what i mean is when you have reference-to-references when you have the member function has a reference parameter. boost::bind solves it so nicely :)
Johannes Schaub - litb