Using lambda to return a boolean inside if else st

2019-07-21 03:11发布

问题:

Here is my code:

int main(int argc, char** argv) {
    bool gg;
    if( [&]()->decltype(gg){

    return false;  //try changing this to true or false and you'll get the same result.

    } ){

    std::cout<<"all even"<<std::endl;   
    }else {
    std::cout<<"all odd"<<std::endl;
    }


    return 0;
}

It's just simple, i have an if else statement and a lambda function inside it that checks the condition. I don't know if it's the code or compiler but even if i change false to true and vice versa, i get the same result. I am using Dev CPP. What's wrong with my code?

回答1:

5.1.2 Lambda expressions

6 The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

That is exactly what happens in your case. You forgot to invoke your closure object's () operator. Instead you used the closure object itself as a condition in if.

Since your closure object does not capture anything, per 5.1.2/6 it is implicitly convertible to plain function pointer type bool (*)(). And so your object got implicitly converted to a function pointer. Since the pointer is not null, it acts as true under if.

On other words, your code is interpreted by the compiler in the following way

bool gg;
auto lf = [&]() -> decltype(gg) { return false; };

bool (*f)() = lf;
if (f) {
  ...

If you make your lambda function actually capture something (e.g. replace return false; with return gg;), your original code will immediately fail to compile.

P.S. As you can read in the comments below, the very presence of [&] apparently should have disabled 5.1.2/6 for your lambda. But apparently your compiler treats 5.1.2/6 more loosely and looks for actual captures instead of simply checking for presence of non-[] capture clause.



回答2:

You don't evaluate the lambda, you just check the object:

int main(int argc, char** argv) {
    bool gg;
    if( [&]()->decltype(gg){

    return false;  //try changing this to true or false and you'll get the same result.

    }() == true){

    std::cout<<"all even"<<std::endl;   
    }else {
    std::cout<<"all odd"<<std::endl;
    }


    return 0;
}

edit: Ideone code https://ideone.com/yxloQf



标签: c++ lambda