使用lambda在if语句中返回一个布尔值

Car*_*nta 2 c++ lambda

这是我的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

它很简单,我有一个if else语句和一个lambda函数来检查条件.我不知道它是代码还是编译器,但即使我将false更改为true,反之亦然,我得到相同的结果.我正在使用Dev CPP.我的代码出了什么问题?

AnT*_*AnT 6

5.1.2 Lambda表达式

6没有lambda-capture的lambda表达式的闭包类型有一个公共的非虚拟非显式const转换函数,用于指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数.此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果.

这正是你的情况.你忘了调用你的闭包对象的()运算符.相反,你使用闭包对象本身作为条件if.

由于您的闭包对象没有捕获任何内容,因此根据5.1.2/6,它可以隐式转换为普通函数指针类型bool (*)().因此,您的对象被隐式转换为函数指针.由于该指针不为空,它作为trueif.

换句话说,编译器以下列方式解释您的代码

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

bool (*f)() = lf;
if (f) {
  ...
Run Code Online (Sandbox Code Playgroud)

如果你使lambda函数实际捕获了某些东西(例如替换return false;return gg;),原始代码将立即无法编译.

PS正如你可以在下面的评论中看到的那样,[&]你的lambda显然应该禁用5.1.2/6.但显然你的编译器更松散地处理5.1.2/6并寻找实际的捕获而不是简单地检查是否存在非[]捕获子句.


Tho*_*ard 5

您不评估lambda,只需检查对象:

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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:Ideone代码https://ideone.com/yxloQf