以下代码编译时没有错误:
std::string lastName, chldName;
while([&]()
{
return true;
})
{
//codes...
}
但是当我尝试这种方式时:
std::string lastName, chldName;
while([&]()
{
std::cin >>lastName;
return true;
})
{
//codes...
}
编译器抱怨说:
错误:无法转换'main():: {(* &安培; lastName)}'从'main()::'到'bool'
如何理解这个错误?是否可以这样使用lambda?
答案 0 :(得分:10)
你的第一个例子不是你想要的,它等同于while (true)
,因为lambda将被转换为函数指针,它将被转换为bool(true) - 它应该是
while([&]()
{
return true;
}())
注意调用lambda
你的第二个例子不会在没有lambda调用的情况下进行编译,因为你试图访问catched-variables,那个禁止从lambda转换为function-pointer,可以转换为bool,但它不会编译为{{ 1}},
如果 lambda-expression不包含trailing-return-type,就好像trailing-return-type表示 以下类型:
- 如果复合语句是表格 {attribute-specifier-seqopt返回表达式; } lvalue-to-rvalue转换(4.1)后返回表达式的类型,数组到指针的转换 sion(4.2)和函数到指针的转换(4.3);
- 否则,无效。
在您的情况下,返回类型将推断为()
,但由于您返回bool,您应该使用void
trailing-return-type
答案 1 :(得分:5)
没有必要明确表达返回类型,问题是你要求while循环判断lambda函数的self是否为true,而不是它返回的值。
你实际上需要在循环条件中调用lambda函数。
while([] {
return true;
}()) {
///....
}
第一次编译的原因与第二次编译的原因不是因为第一次编译没有捕获任何内容。该标准允许将其转换为普通函数指针,可以将其计算为bool(nullptr为false)。
第二次捕获,它阻止编译器将其转换为函数指针,因此无法编译。
答案 2 :(得分:1)
请注意,在您的代码中,您 NOT CALLING lambda。
while([&]()
{
return true;
})
没有调用,这不是lambda的返回值有问题。
不捕获任何内容的lambda可以隐式转换为函数指针,而函数指针又可以转换为bool
。
以下用g ++ 4.7.2编译,但不用Visual C ++ 12.0编译:
int main()
{
if( [](){} ) {}
}
lambda捕获(因此无法转换)的以下内容不能使用任何编译器进行编译:
int main()
{
int x;
if( [&](){(void)x;} ) {}
}