C++11 中的递归 lambda 函数

2021-12-12 00:00:00 lambda c++ c++11

我是 C++11 的新手.我正在编写以下递归 lambda 函数,但它无法编译.

I am new to C++11. I am writing the following recursive lambda function, but it doesn't compile.

#include <iostream>
#include <functional>

auto term = [](int a)->int {
  return a*a;
};

auto next = [](int a)->int {
  return ++a;
};

auto sum = [term,next,&sum](int a, int b)mutable ->int {
  if(a>b)
    return 0;
  else
    return term(a) + sum(next(a),b);
};

int main(){
  std::cout<<sum(1,10)<<std::endl;
  return 0;
}

编译错误:

vimal@linux-718q:~/Study/09C++/c++0x/lambda> g++ -std=c++0x sum.cpp

compilation error:

vimal@linux-718q:~/Study/09C++/c++0x/lambda> g++ -std=c++0x sum.cpp

sum.cpp:在 lambda 函数中:sum.cpp:18:36: 错误:'((*)this)->::sum' 不能用作函数

sum.cpp: In lambda function: sum.cpp:18:36: error: ‘((<lambda(int, int)>*)this)-><lambda(int, int)>::sum’ cannot be used as a function

gcc 版本 4.5.0 20091231(实验性)(GCC)

gcc version 4.5.0 20091231 (experimental) (GCC)

但是,如果我将 sum() 的声明更改为如下所示,它会起作用:

But if I change the declaration of sum() as below, it works:

std::function<int(int,int)> sum = [term,next,&sum](int a, int b)->int {
   if(a>b)
     return 0;
   else
     return term(a) + sum(next(a),b);
};

有人可以解释一下吗?

推荐答案

想想 auto 版本和完全指定类型版本之间的区别.auto 关键字从它初始化的任何东西中推断出它的类型,但是你用什么来初始化它需要知道它的类型是什么(在这种情况下,lambda 闭包需要知道它正在捕获的类型).鸡和蛋的问题.

Think about the difference between the auto version and the fully specified type version. The auto keyword infers its type from whatever it's initialized with, but what you're initializing it with needs to know what its type is (in this case, the lambda closure needs to know the types it's capturing). Something of a chicken-and-egg problem.

另一方面,完全指定的函数对象的类型不需要知道"任何关于分配给它的内容,因此 lambda 的闭包同样可以完全了解其捕获的类型.

On the other hand, a fully specified function object's type doesn't need to "know" anything about what is being assigned to it, and so the lambda's closure can likewise be fully informed about the types its capturing.

考虑对您的代码稍作修改,它可能更有意义:

Consider this slight modification of your code and it may make more sense:

std::function<int(int,int)> sum;
sum = [term,next,&sum](int a, int b)->int {
if(a>b)
    return 0;
else
    return term(a) + sum(next(a),b);
};

显然,这不适用于自动.递归 lambda 函数工作得非常好(至少在 MSVC 中是这样,我有使用它们的经验),只是它们与类型推断并不真正兼容.

Obviously, this wouldn't work with auto. Recursive lambda functions work perfectly well (at least they do in MSVC, where I have experience with them), it's just that they aren't really compatible with type inference.

相关文章