【发布时间】:2010-11-15 06:50:29
【问题描述】:
我想知道人们如何在编码风格方面使用 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 显然更安全,因为没有生命周期问题,因此有人可能会争辩说,只要不需要改变捕获的值(或从其他地方查看对其所做的更改),就应该默认使用它,并捕获 -在这种情况下,引用应被视为(可能为时过早的)优化,仅在明显产生影响的情况下应用。
另一方面,按引用捕获几乎总是更快(特别是因为它通常可以优化到一个副本,如果后者实际上更快,对于小类型和可内联模板函数,例如大多数 STL 算法) ,并且如果 lambda 永远不会超出其范围(这也是所有 STL 算法的情况),那么它是安全的,因此在这种情况下默认为按引用捕获是一种微不足道且无害的优化,不会造成伤害。
你有什么想法?
【问题讨论】:
-
我对那些已经在生产代码中使用过 lambdas 的人的反馈特别感兴趣,因此有一些经验来支持他们的观点;但欢迎所有反馈。
-
Lambda 还没有真正在许多编译器中实现 - 我怀疑在 G++ 或 MSVC++ 至少支持它们之前你会找到很多生产代码
-
我实际上正在编写大量使用 VC10 lambdas 的生产代码(尤其是在较新的部分),但后来我是 VS2010 团队的开发人员,所以我猜我的情况有点特别。 .. 但是,我的印象是较新的
g++版本(不是测试版!)具有生产质量的 lambda 实现 - 我弄错了吗? -
据我所知,G++ 还没有 lambdas。一堆其他 0x 功能,但不是 lambdas。
-
GCC 在当前的 4.4 版本和开发中的 4.5 版本中都没有 lambda。有关 GCC 的 C++0x 功能支持的详细信息,请参阅gcc.gnu.org/projects/cxx0x.html
标签: c++ coding-style lambda c++11