如何在成员函数上使用std::for_each

3

我正在尝试学习更为“功能型”的STL编程风格,以下是一个简化的案例:

class Widget;

class Zot
{
public:
  std::vector<Widget> Widgets;

  void ProcessAWidget(int x, Widget w) { ... }

  void Process()
  {
      int ctx=123;

      std::for_each(Widgets.begin(), Widgets.end(), 
           std::bind(&Zot::ProcessAWidget, this, ctx, _1));
   }
};

有没有更好的方法来编写for_each调用的最后一个参数?

特别是需要显式地提及this感觉很“不正确”,去掉类限定符也是很好的选择。


有人愿意添加一个非C++11的替代答案吗?不幸的是,我们中的许多人受限于在“落后于潮流”的环境中工作。 - Component 10
boost函数库可能会有用--我不记得它是否与foreach算法兼容。http://www.boost.org/doc/libs/1_51_0/doc/html/function/tutorial.html#id1545718 - Steve Guidi
@Component10:没有非C++11的替代方案。当使用指向成员的指针时,类必须是显式的,并且要应用成员指针的对象也必须存在。这在lambda中被小心地隐藏了...但在C++03中必须是显式的[顺便说一句,如果没有C++11,就没有std::bind]。 - David Rodríguez - dribeas
@DavidRodríguez-dribeas:谢谢。这就是为什么我从不使用std::for_each的原因 - 太多的std::mem_fun泡沫了 - 迎接C++11的到来。 - Component 10
4个回答

8
如果编译器支持C++11 lambda表达式:
std::for_each(Widgets.begin(),
              Widgets.end(),
              [&](Widget& a_w) { ProcessAWidget(ctx, a_w); });

7

利用Lambda表达式解决问题:

std::for_each(Widgets.begin(), Widgets.end(),
              [=](Widget & w) { ProcessAWidget(ctx, w); });

你如何从lambda中调用ProcessAWidgetthis没有被捕获。 - Nawaz
Lambda比绑定更明显。尽管在我现实世界的例子中,由于涉及类型名称的长度,它的字符数比绑定多。不幸的是,在lambda签名中用'auto'替换'Widget'是行不通的。 - Rob Walker
[=] 按值捕获 - 这是你的意思吗? - Lubo Antonov

2
在C++11中,您可以使用lambda函数与std::for_each一起使用,这通常使得代码比您必须使用std::bind玩的游戏更易读。

0
你的解决方案:
直到 c++11。
    std::for_each( container.cbegin(), container.cend(), std::bind1st(std::mem_fun(&MyClass::method), this) );

之后:

    std::for_each( container.cbegin(), container.cend(),std::bind(&MyClass::method, this,  std::placeholders::_1));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接