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

时间:2015-07-24 05:40:56

标签: 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;
}

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

2 个答案:

答案 0 :(得分:6)

  

5.1.2 Lambda表达式

     

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

这正是你案件中发生的事情。你忘了调用你的闭包对象()运算符。相反,您使用闭包对象本身作为if中的条件。

由于闭包对象没有捕获任何内容,因此根据5.1.2 / 6,它可以隐式转换为普通函数指针类型bool (*)()。因此,您的对象被隐式转换为函数指针。由于指针不为null,因此它在true下充当if

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

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

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

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

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

答案 1 :(得分: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;
}

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