在容器中的每个元素上调用成员函数

时间:2009-04-05 14:52:24

标签: c++ stl boost coding-style

这个问题是一个风格问题,因为你总是可以写一个for循环或类似的东西;然而,是否有一个不那么突兀的STL或BOOST等同于写作:

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

像(想象)这样的东西:

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

我认为这将是1)减少打字,2)更容易阅读,3)如果您决定更改基本类型/容器类型,则更少的更改。

编辑: 感谢您的帮助,现在,如果我想将一些参数传递给成员函数怎么办?

5 个答案:

答案 0 :(得分:23)

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

 // ...

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

有关详细信息,请参阅std::for_eachstd::bind文档。

错过了您的编辑:无论如何,这里是另一种在不使用Boost的情况下实现您想要的方式,如果需要的话:

std::for_each(foo_vector.begin(), foo_vector.end(),
    std::bind(&Foo::func, std::placeholders::_1));

答案 1 :(得分:5)

您可以使用std::for_eachboost's foreach constructs

当您不想将逻辑移动到另一个函数时,请使用boost的BOOST_FOREACH或BOOST_REVERSE_FOREACH。

答案 2 :(得分:4)

我发现boost绑定似乎非常适合该任务,另外你可以向该方法传递额外的参数:

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

答案 3 :(得分:0)

如果你真的想提高性能而不仅仅是提高你的代码,那么你真正需要的是一个map函数。 Eric Sink写了.net implementation

答案 4 :(得分:0)

自C ++ 11标准以来,BOOST方法已通过不同的语法标准化为“基于范围的循环”:

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