2016-02-28 51 views
1

我有一个整数的矢量充满了5个号码,我很好奇究竟是什么[&idx]做:的for_each函数C++ 11

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

此外,你的第二个代码块有错误的语法。即使没有捕获列表,Lambdas仍然需要'[]'。 –

回答

3

我很好奇,究竟是什么[&idx]

这就是拉姆达捕获。它将lambda设置为参考idx。它不会用作参数,因为for_each仅将一个参数传递给谓词。如果您制作idx参数,它将不会编译。

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

可能。如果你真的想知道,测试每种做法。

3

究竟是什么[& IDX]在

[](){} 

结构做,作为C++ 11,是λ函数 - 也就是,一个匿名函数,其,在这种情况下,将作为参数传递的向量元素进行回调。 [&idx]表示变量idx不是通常情况下属于拉姆达的环境,而是后者通常不可访问的,应该通过引用来访问(捕获)它。这意味着您可以在lambda体内使用idx,并且每当您这样做时,您都使用对原始变量的引用。因此,idx++部分代码将增加原始idx变量而不是某些本地副本。

为什么它不能这样工作?

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

从perfomance的角度来看比它更好吗? :

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

仅供参考,在我的系统中,采用clang++-O3标志,你std::foreach版本的1000次迭代将持续4967ms而for一个3861ms的1000。对于1000次迭代,这大约为1秒,例如1ms如果你只运行一次这个代码..