Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to code this way:while(lambda){}

Tags:

c++

c++11

lambda

The code below was compiled without error:

std::string lastName, chldName;
while([&]()
{
      return true;
})
{
  //codes...
}   

But when I tried this way:

std::string lastName, chldName;
while([&]()
{
      std::cin >>lastName;
      return true;
})
{
  //codes...
}   

The compiler complained that :

error: could not convert 'main()::{(* & lastName)}' from 'main()::' to 'bool'

How to understand this error?Is it possible to use lambda this way?

like image 214
Yue Wang Avatar asked Dec 16 '13 10:12

Yue Wang


3 Answers

Your first example works not how you want, it's equivalent to while (true), since lambda will be converted to function-pointer, that will be converted to bool (true) - it should be

while([&]()
{
   return true;
}())

Note to call of lambda

Your second example will not compile without call of lambda, since you are trying to access to catched-variables, thats forbids conversion from lambda to function-pointer, that can be converted to bool, but it will neither compiled with (),

If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:

— if the compound-statement is of the form { attribute-specifier-seqopt return expression ; } the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conver- sion (4.2), and function-to-pointer conversion (4.3);

— otherwise, void.

In your case, return type will be deduced to void, but since you return bool, you should use trailing-return-type

while([&]() -> bool
{
      std::cin >>lastName;
      return true;
}())
like image 172
ForEveR Avatar answered Oct 11 '22 13:10

ForEveR


There is no need to explicitly express the return type,the issue is that you are asking the while loops condition whether the lambda function its self is true, rather than the value it returns.

You actually need to the call lambda function in the loop condition.

while([] {
    return true;
 }()) {
 ///....
 }

EDIT

The reason the first compiles and the second doesn't is because the first doesn't capture anything. The standard allows this to then be converted to a normal function pointer which can be evaluated as a bool (nullptr being false).

The second captures, which stops the compiler from converting it to a function pointer and thus doesn't compile.

like image 33
111111 Avatar answered Oct 11 '22 14:10

111111


Note that in your code you're NOT CALLING the lambda.

while([&]()
{
      return true;
})

With no call it's not the lambda's return value that is problematic.

A lambda that doesn't capture anything can be implicitly converted to function pointer, which in turn can convert to bool.

The following compiles with g++ 4.7.2, but not with Visual C++ 12.0:

int main()
{
    if( [](){} ) {}
}

The following, where the lambda does capture (and thus cannot be converted), doesn't compile with either compiler:

int main()
{
    int x;
    if( [&](){(void)x;} ) {}
}
like image 41
Cheers and hth. - Alf Avatar answered Oct 11 '22 14:10

Cheers and hth. - Alf