c ++ 11中的for_each函数

时间:2016-02-28 18:33:27

标签: c++ c++11 vector foreach

我有5个数字的整数向量,我很好奇[&idx]做了什么:

int idx = 0;
for_each ( x . begin (), x . end (), [&idx] ( const int & a ) { cout << idx ++ << " " << a << endl; } );`

为什么它不能像这样工作? :

int idx = 0;
  for_each ( x . begin (), x . end (), ( const int & a, int & idx ) { cout << idx ++ << " " << a << endl; } );

从性能的角度来看,它是否更好? :

for ( vector<int>::size_type i = 0; i < x . size (); i ++ )
    cout << x[i] << endl;

2 个答案:

答案 0 :(得分:3)

  

我很好奇[&idx]做了什么

这是lambda捕获。它将lambda设置为引用idx。它不能用作参数,因为for_each只将一个参数传递给谓词。如果您改为使用idx参数,则无法编译。

  

从性能的角度来看,它也更好吗?

可能。如果您真的想知道,请测试每种方式。

答案 1 :(得分:3)

  

<&amp; idx]究竟在

中做了什么

[](){}

结构,从C ++ 11开始,是一个lambda函数 - 也就是说,一个匿名函数,在这个上下文中,将使用作为参数传递的向量元素进行回调。 [&idx]表示变量idx,它通常不属于lambda的环境,而后者通常是不可接受的,应该通过引用在其中访问(捕获)。这意味着您可以在lambda的主体中使用idx,并且只要您这样做,就会使用对原始变量的引用。因此,代码的idx++部分会增加原始idx变量,而不是某些本地副本。

  

为什么它不能像这样工作?

因为() {}结构不是有效的C ++表达式或语句。

  

从性能的角度来看,它是否更好? :

可能,但不一定,你应该测量以确定。但是,使用迭代器和算法而不是C风格的循环是明智的和惯用的。鉴于标准的“避免过早优化”指南,我建议您默认使用第一个版本,当您完成所有开发后,您可以决定是否要花一些时间来尝试和测量替代方案,例如第二个。如果这不是程序的某些关键部分(例如在某些回调函数中),我认为它不值得大惊小怪,无论如何差异都会非常小。

仅供参考,在我的系统中,使用带有clang++标记的-O3std::foreach版本的1000次迭代将持续4967ms,而for的1000次迭代将持续3861ms。对于1000次迭代,这大约是1秒,例如如果你只运行一次这段代码,则为1毫秒..