lambda(C++11)中的递归调用
Recursive call in lambda (C++11)
可能重复:
c++0x 中的递归lambda函数
如果我把lambda写成:,为什么我不能递归地调用它
auto a = [&]
{
static int i = 0; i++;
std::cout << i << std::endl;
if (i<10)
a(); //recursive call
};
它给出编译错误(ideone(:
prog.cpp:8:18: error: '((const main()::<lambda()>*)this)->main()::<lambda()>::a' cannot be used as a function
prog.cpp: In function 'int main()':
prog.cpp:9:9: error: variable 'auto a' with 'auto' type used in its own initializer
这个错误是什么意思?
我理解我不能写这个的原因:
auto i=i+1; //error: unable to deduce 'auto' from '<expression error>'
我们不能写这个,因为i
的类型必须从它的初始化中推导出来,这意味着如果i
本身出现在初始化中(ideone(,就不能推导出类型。但是,在lambda的情况下,这有什么关系呢?如果我没有错的话,lambda的类型是由它的参数和返回类型决定的;如果它什么都不返回,它就不依赖于主体(在这种情况下,返回类型被推导为void
,而与lambda主体中的其他语句无关(。
无论如何,我有一个变通方法,我可以使用std::function
作为:
std::function<void()> a = [&]
{
static int i = 0; i++;
std::cout << i << std::endl;
if (i<10)
a();
};
其编译罚款(ideone(。但我仍然很想知道auto
版本没有编译的原因。
原因是auto
变量的lambda表达式初始化器没有特殊情况。
这种特殊情况很容易出现错误和误用。当您建议像a()
这样的东西应该起作用时,您需要定义规则。operator()
是如何查找的?a
类型的精确状态是什么?类型是否完整?(这意味着您已经知道lambda的捕获列表(。一旦你用一种合理的格式来制定规范,就可以更容易地对其进行陈述
允许您的用例将意味着您需要在代码中提前扫描的另一种情况,因为要确定a()
中a
的类型,您必须确保初始值设定项以任何可以"解锁"类型的内容结尾
struct y { void operator()() { } };
template<typename T> y operator+(T, y) { return y(); }
auto x = [] { x(); } + y();
在这种情况下,x()
将调用y::operator()
,而不是lambda。
现在,a
被简单地禁止在其整个初始化器中被提及。因为在C++中,auto
是而不是类型。它只是一个类型说明符,代表要推导的类型。因此,表达式的类型永远不能是auto。
在我看来,auto a
情况和std::function<void()> a
情况之间的重要区别在于类型std::function<void()>
不知道/关心它所指的实际函数的类型
std::function<void()> a;
非常好,其中为:
auto a;
毫无意义。因此,当合成捕获的时候,如果你使用std::function<void()>
,所有需要知道的类型都已经知道了,而使用auto
还不知道。
在递归函数中,f
由f
定义,而在auto
的情况下,f
的返回类型也由f
确定,因此它导致无限递归。
当CCD_ 26尝试导出类型时。decltype(f(((将进一步推导为另一个decltype`,因为f派生为f。例如,对任何递归的调用也是递归的。当应用于递归函数时,返回类型确定将变为递归。在递归函数中,递归的结束可以在运行时完成。但测定是静态的,只有
- 返回递归调用和仅递归调用的区别
- 使用静态变量的递归调用的不同输出
- 复制构造函数中的递归调用
- 为什么编译器将其解析为函数指针而不是递归调用?
- 如何在 c++ 的类中递归调用函数方法?
- 了解使用堆栈实现队列的递归调用机制
- 如何通过函数指针递归调用类成员函数?
- 条件加倍时的递归调用
- 对可变参数函数的递归调用的链接器错误
- 将多个非原始递归调用转换为迭代解决方案
- 分段错误(核心转储)错误C++递归调用
- 无全局变量或功能参数的递归调用
- 在递归DP中,通过存储变量来分解递归调用:效率低下
- C - 为什么合并函数在递归调用后会逆转数组
- 递归调用中出现错误"[Error] expression list treated as compound expression in initializer [-fpermissive]"
- C / SFML:使用两个递归调用在屏幕上打印凸形形状仅显示第一个递归调用中的形状,而不是第二个
- C++中具有 100000 个递归调用的运行时错误
- 递归调用可变参数模板函数重载时的不明确调用
- 如何在 c++ 中递归调用类
- 带有两个递归调用的递归算法的时间复杂性