这是我的代码:
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。我的代码出了什么问题?
答案 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