我想知道人们如何在编码风格方面使用 C++0x lambda。最有趣的问题是在编写捕获列表时要做到多彻底。一方面,该语言允许显式列出捕获的变量,并且通过“显式优于隐式规则”,因此进行详尽的列表以清楚地说明意图是有意义的。例如:
int sum;
std::for_each(xs.begin(), xs.end(), [&sum](int x) { sum += x });
另一个论点是,由于 ref-captured locals 的生命周期不会仅仅因为它们被捕获而改变(因此 lambda 很容易最终引用一个生命周期早已结束的局部变量),因此显式捕获有助于减少此类错误并追踪他们。
另一方面,该语言还特意提供了一种快捷方式来自动捕获所有引用的本地变量,因此很明显它是打算使用的。并且可以声称,对于上述示例,即使使用自动捕获也会发生什么,并且 lambda 的生命周期不会超过周围的范围,因此没有理由不使用它:
int sum;
std::for_each(xs.begin(), xs.end(), [&](int x) { sum += x });
显然,这不必是全有或全无,但必须有一些基本原理来决定何时自动捕获以及何时明确地进行捕获。有什么想法吗?
同样的另一个问题是何时使用 capture-by-copy - [=]
,何时使用 capture-by-reference - [&]
。Capture-by-copy 显然更安全,因为没有生命周期问题,因此有人可能会争辩说,只要不需要改变捕获的值(或从其他地方查看对其所做的更改),就应该默认使用它,并捕获 -在这种情况下,引用应该被视为(可能为时过早的)优化,仅在明显产生影响的情况下应用。
另一方面,按引用捕获几乎总是更快(特别是因为它通常可以优化到一个副本,如果后者实际上更快,对于小类型和内联模板函数,如大多数 STL 算法),并且是如果 lambda 永远不会超出其范围(这也是所有 STL 算法的情况),则安全,因此在这种情况下默认为按引用捕获是一种微不足道且无害的优化,不会造成伤害。
你觉得呢?你有没有什么想法?