如何使用std :: for_each?

时间:2012-03-15 01:17:31

标签: c++ algorithm foreach

是否可以使用std :: for_each或其他类似的东西?

#include <list>
#include <algorithm>

// Class declaration
//
struct Interface
{
   virtual void run() = 0;
};

struct A : public Interface
{
   void run() { std::cout << "I run class A" << std::endl; }
};

struct B : public Interface
{
   void run() { std::cout << "I run class B" << std::endl; }
};

// Main
//
int main()
{
   // Create A and B
   A a;
   B b;

   // Insert it inside a list
   std::list<Interface *> list;
   list.push_back(&a);
   list.push_back(&b);

   // Then execute a func with for_each without recreate a func which call Interface::run() 
   std::for_each(list.begin(), list.end(), run);

   return 0;
}

编辑: 我的问题是:如何在不使用迭代器的情况下使用算法或更简单的C ++方式在循环内调用每个run()成员函数...

4 个答案:

答案 0 :(得分:8)

您可以使用std::mem_fun

执行此操作
std::for_each(list.begin(), list.end(), std::mem_fun(&Interface::run));

答案 1 :(得分:3)

最简单的方法可能是使用lambda函数:

boost::for_each(list, [](Interface* i){ i->run(); });

其他选项包括:

boost::for_each(list | boost::adaptors::indirected, std::mem_fn(&Interface::run));

boost::for_each(
    list | boost::adaptors::indirected,
    std::bind(&Interface::run, std::placeholders::_1));

答案 2 :(得分:1)

不,你必须创建一个包装器函数,它会在传递给它的任何对象上调用run()。 C ++没有那种允许你使用字符串来引用函数并在运行时查找它的动态调度 - for_each中调用的函数必须是一个且只有一个函数在一个地址,而不是多态函数。

您不必为每个对象创建一个包装器函数:您只有一个,它会被重复调用并传入对象。然后在传入的对象上调用run(),其余的就是多态:

void wrapper(Interface* obj)
{
    obj->run();
}

std::for_each(list.begin(), list.end(), wrapper);

答案 3 :(得分:1)

以Matt为例,但将其变为通用:

class wrapper : public std::unary_function(Interface*, void) {
  void (Interface::*pmf)();
public:
  wrapper(void (Interface::*pmf)()) : pmf(pmf) { }
  operator()(Interface* intf) { intf->*pmf(); }
};

std::for_each(ist.begin(), list.end(), custom_wrapper(&Interface::run));

如果您需要支持参数,请从std::binary_function(Interface*, T, void)派生并将Tpmf一起存储