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?
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.
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