我试图找出在C ++中使用lambda表达式是否存在实际的计算好处,即“此代码编译/运行更快/更慢因为我们使用lambda表达式”< / em>或者它只是一个整洁的开发特权,可供那些试图看起来很酷的可怜的程序员滥用?
我理解这个问题可能看似主观,但我非常感谢社群对此事的看法。
答案 0 :(得分:43)
好处是编写计算机程序最重要的好处: 更容易理解代码 。我不知道任何性能方面的考虑。
C ++允许在某种程度上进行功能编程。考虑一下:
std::for_each( begin, end, doer );
这个问题是函数(对象)doer
operator()
的实现)std::for_each
调用Lambdas在所有这些方面都有了很大改进(也许还有一些我忘了)。
答案 1 :(得分:41)
我认为计算性能几乎与提高语言的表达能力差不多。
答案 2 :(得分:13)
本身没有性能优势,但由于STL及其设计理念的广泛采用,对lambda的需求也随之而来。
具体来说,STL算法经常使用仿函数。如果没有lambda,则需要先声明这些函子被使用。 Lambdas可以拥有“匿名”的就地仿函数。
这很重要,因为在很多情况下你只需要使用一个仿函数,并且你不想为它命名,原因有两个:你不想污染名称空间,并且在这些特定情况下,您提供的名称要么模糊,要么非常长。
例如,我使用STL很多,但没有C ++ 0x我使用的for()循环比for_each()算法及其表兄弟多得多。那是因为如果我使用for_each()代替,我需要从循环内部获取代码并为它声明一个仿函数。此外,循环之前的所有局部变量都不可访问,因此我需要编写其他代码以将它们作为参数传递给仿函数构造函数,或者其他等价物。因此,除非有强烈的动机,否则我倾向于不使用for_each(),否则代码会更长,更难以阅读。这很糟糕,因为众所周知,使用for_each()和类似的算法为编译器提供了更多的空间。用于优化的库,包括自动并行。因此,间接地,lambda将支持更高效的代码。
答案 3 :(得分:9)
IMO,关于lambda的最重要的事情是它将相关代码保持在一起。如果你有这个代码:
std::for_each(begin, end, unknown_function);
您需要导航到unknown_function
以了解代码的作用。但是使用lambda,逻辑可以保持在一起。
答案 4 :(得分:8)
Lambdas是函子类的语法糖,所以不,没有计算上的好处。至于动机,可能是其他十几种流行语言中的任何一种都有lambdas吗?
有人可能会说它有助于代码的可读性(让你的函子在内联函数中声明它被使用)。
答案 5 :(得分:5)
虽然我认为C ++ 0x的其他部分是more important,但lambdas不仅仅是C ++ 98样式函数对象的“语法糖”,因为它们可以捕获上下文,并且它们会这样做按名称,然后他们可以将这些上下文带到其他地方并执行。这是新的东西,而不是“编译更快/更慢”的东西。
#include <iostream>
#include <vector>
#include <functional>
void something_else(std::function<void()> f)
{
f(); // A closure! I wonder if we can write in CPS now...
}
int main()
{
std::vector<int> v(10,0);
std::function<void ()> f = [&](){ std::cout << v.size() << std::endl; };
something_else(f);
}
答案 6 :(得分:2)
好吧,比较一下:
int main () {
std::vector<int> x = {2, 3, 5, 7, 11, 13, 17, 19};
int center = 10;
std::sort(x.begin(), x.end(), [=](int x, int y) {
return abs(x - center) < abs(y - center);
});
std::for_each(x.begin(), x.end(), [](int v) {
printf("%d\n", v);
});
return 0;
}
用这个:
// why enforce this to be defined nonlocally?
void printer(int v) {
printf("%d\n", v);
}
int main () {
std::vector<int> x = {2, 3, 5, 7, 11, 13, 17, 19};
// why enforce we to define a whole struct just need to maintain a state?
struct {
int center;
bool operator()(int x, int y) const {
return abs(x - center) < abs(y - center);
}
} comp = {10};
std::sort(x.begin(), x.end(), comp);
std::for_each(x.begin(), x.end(), printer);
return 0;
}
答案 7 :(得分:2)
“一个整洁的开发特权,让那些试图看起来很酷的可怜的程序员滥用?”......无论你怎么称呼它,它都会让代码变得更强大更具可读性维护。它不会提高性能。
大多数情况下,程序员会迭代一系列元素(搜索元素,累积元素,排序元素等)。使用函数式,您可以立即看到程序员打算做什么,与使用for循环不同,其中所有内容都“看起来”相同。
比较算法+ lambda:
iterator longest_tree = std::max_element(forest.begin(), forest.end(), [height]{arg0.height>arg1.height});
iterator first_leaf_tree = std::find_if(forest.begin(), forest.end(), []{is_leaf(arg0)});
std::transform(forest.begin(), forest.end(), firewood.begin(), []{arg0.trans(...));
std::for_each(forest.begin(), forest.end(), {arg0.make_plywood()});
使用oldschool for-loops;
Forest::iterator longest_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (*it.height() > *longest_tree.height()) {
longest_tree = it;
}
}
Forest::iterator leaf_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (it->type() == LEAF_TREE) {
leaf_tree = it;
break;
}
}
for (Forest::const_iterator it = forest.begin(), jt = firewood.begin();
it != forest.end();
it++, jt++) {
*jt = boost::transformtowood(*it);
}
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
std::makeplywood(*it);
}
(我知道这段代码包含语法错误。)