Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用lambda在if-else语句中返回布尔值_C++_Lambda - Fatal编程技术网

C++ 使用lambda在if-else语句中返回布尔值

C++ 使用lambda在if-else语句中返回布尔值,c++,lambda,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; }e

这是我的密码:

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;
}
int main(int argc,char**argv){
布尔gg;
if([&]()->decltype(gg){
return false;//尝试将其更改为true或false,您将得到相同的结果。
} ){

std::cout您不计算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;
}
int main(int argc,char**argv){
布尔gg;
if([&]()->decltype(gg){
return false;//尝试将其更改为true或false,您将得到相同的结果。
}()==真){
标准::cout
5.1.2 Lambda表达式

6没有lambda捕获的lambda表达式的闭包类型具有公共非虚拟非显式常量转换 函数到指针,指向具有相同参数和返回的函数 类型作为闭包类型的函数调用运算符。返回的值 通过该转换函数,应为函数的地址, 调用时,与调用闭包类型的 函数调用操作符

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

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

换句话说,编译器将按照以下方式解释代码

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

bool (*f)() = lf;
if (f) {
  ...
如果使lambda函数实际捕获某些内容(例如,将
return false;
替换为
return gg;
),则原始代码将立即无法编译


注意:正如您在下面的评论中所读到的,
[&]
的存在显然应该为您的lambda禁用5.1.2/6。但显然,您的编译器对5.1.2/6的处理更为宽松,并查找实际捕获,而不是简单地检查非
[]
capture子句。

如果使用命名函数编写相同的代码:
if(returnFalse){…}
你会期望什么?如果你不调用函数,你怎么期望它返回值?…我不太明白为什么会编译它。一定是另一个gcc扩展。我投票结束这个问题,因为它显示出缺乏研究和对语言基础的理解。@dyp不一定,你对函数指针也可以做同样的事情…它从函数指针隐式转换到bool,这是非常危险的。VS实际上拒绝编译该代码。它不是已经得到了评估,因为它返回了true或false吗?@CarloBrew评估函数与调用函数不同。它的错误与:
bool f();if(f){
而不是
if(f()){
哦,好吧,我忘了lambda不会自动调用,除非它类似于std transform。我添加了==true,因为我觉得这更清楚,但真正缺少的是括号。这会计算lambda并询问“返回值为真吗?”如果没有它,则表示“此lambda对象是否可转换为布尔值?此布尔值是否为真?”这是不同的,并且不会计算lambda。@CarloBrew它们永远不会“自动调用”。高阶函数(例如
std::transform()
)也显式调用提供的回调/转换函数。OOoo好的。难怪它得到了计算,我没有得到任何错误。@dyp这一段并不排除捕获lambda进行转换;它只定义了不捕获lambda的行为。好的,再次检查:我是对的,这个lambda不能转换为有趣的Action指针。它确实有一个捕获,clang++对此表示不满。g++接受它,这是一个扩展。也就是说,捕获默认语法上是lambda捕获。因此,此lambda确实有lambda捕获,并且不能转换为函数指针。@mattmcnab请参见p3。不允许实现添加此类转换。您可以通过SFINAE反射观察转换是否存在。