我有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;
答案 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++
标记的-O3
,std::foreach
版本的1000次迭代将持续4967ms,而for
的1000次迭代将持续3861ms。对于1000次迭代,这大约是1秒,例如如果你只运行一次这段代码,则为1毫秒..