首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >给定一个lambda捕获,什么规则决定了结果闭包成员的类型?

给定一个lambda捕获,什么规则决定了结果闭包成员的类型?
EN

Stack Overflow用户
提问于 2016-08-15 18:38:05
回答 1查看 191关注 0票数 1

如何从捕获中准确地预测将在lambda中创建哪种类型的成员?

在C++中,我认为通过值捕获T类型的对象会创建const T类型的数据成员,并通过引用T&来创建。但在编译这段代码时:

代码语言:javascript
复制
#include <iostream>

struct A{
    A(){std::cout<<"A\n";}
    A(const A&){std::cout<<"A&\n";}
    void cf()const{}
    void f(){}
};


int main(){
    A a;
    A& ra=a;
    const A& cra=a;
    auto f00 = [ra, cra, &a]()-> void{
        //Fixed:
        //ra is A, cra is const A, a is A&
        //lambda is void operator()()const
        a.cf(); a.f();//pass
        //ra.cf(); ra.f();//ra.f compilation err. 
        //cra.cf(); cra.f();//cra.f compilation err
    };
    //f00(); //A&,A&

    auto f01 = [ra, cra, &a]()mutable-> void{
        //Fixed:
        //ra is A, cra is const A, a is A&
        //lambda is void operator()()mutalbe
        a.cf(); a.f();//pass
        ra.cf(); ra.f();//pass
        cra.cf(); cra.f();//cra.cf pass, but cra.f error, why?
    };
    //f01(); //A&,A&

    auto f02 = [&ra, &cra, &a]()mutable-> void{
        //Fixed:
        //ra is A&, cra is const A&, a is A&
        //lambda is void operator()()mutable
        a.cf(); a.f();//pass
        ra.cf(); ra.f();//pass
        //cra.cf(); cra.f();//cra.cf pass, but cra.f error, why?
    };
    f02(); //
    return 0;
}

我遇到了以下编译错误:

代码语言:javascript
复制
test_lambda.cpp:26:25: error: passing 'const A' as 'this' argument discards qualifiers [-fpermissive]
         cra.cf(); cra.f();//pass, cra.f error
                         ^
test_lambda.cpp:8:10: note:   in call to 'void A::f()'
     void f(){}
          ^

这是否意味着cra真的是通过引用捕获的,而不是像我预期的那样通过引用对象的副本捕获?

EN

回答 1

Stack Overflow用户

发布于 2016-08-15 18:47:35

捕获的实体的类型保持不变,只是对对象的引用被捕获为被引用对象的副本。来自CPP Reference on Lambda Closure Types

每个数据成员的类型是相应捕获的实体的类型,除非实体具有引用类型(在这种情况下,对函数的引用被捕获为对被引用函数的左值引用,而对对象的引用被捕获为被引用对象的副本)。

在所有lambda中,闭包成员cra的类型都是A。他们本身并不是const。但是,lambda的默认函数调用operator()是。第17行中关于f00的错误是由于您在调用ra.f()时尝试修改由copy创建的闭包成员,但由于它具有operator() const,所以它只能对其成员执行const操作。

这就是为什么在所有三个函数中,在cra上调用非const A::f都会导致编译错误。您应该在lambda参数列表之后添加mutable,以允许对by-copy闭包成员执行非const操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38953523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档