Call member function on each element in a container

独自空忆成欢 提交于 2020-01-01 04:54:06

问题


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?


回答1:


 #include <algorithm>  // for_each
 #include <functional> // bind

 // ...

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

See std::for_each and std::bind 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::bind(&Foo::func, std::placeholders::_1));



回答2:


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.




回答3:


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));
}



回答4:


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




回答5:


Since C++11 standard the BOOST approach is standardized with different syntax as the "range-based-loop":

class Foo {
    Foo(int x);
    void foo();
}
vector<int> list = {Foo(1),Foo(2),Foo(3)};
for(auto &item: list) item.foo();


来源:https://stackoverflow.com/questions/719043/call-member-function-on-each-element-in-a-container

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!