如何从捕获中准确地预测将在lambda中创建哪种类型的成员?
在C++中,我认为通过值捕获T类型的对象会创建const T类型的数据成员,并通过引用T&来创建。但在编译这段代码时:
#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;
}我遇到了以下编译错误:
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真的是通过引用捕获的,而不是像我预期的那样通过引用对象的副本捕获?
发布于 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操作。
https://stackoverflow.com/questions/38953523
复制相似问题