为什么我不能叫拉姆达递归,如果我把它写成:
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
版本不能编译的原因。
我认为这个问题与你最终隐式捕获'a'有关,因为'a'本身最终会成为'a'的成员,因此会无限递归。 – Flexo
@awoodland:这是什么意思?请详细说明。 – Nawaz
lambda的类型也取决于捕获,我怀疑这是问题。如果你不使用'a',那么编译器不关心,但是当你这样做的时候它不知道要使用什么类型的对象。 –