在 lambda 中,引用的按值捕获是不是会复制底层对象?
Posted
技术标签:
【中文标题】在 lambda 中,引用的按值捕获是不是会复制底层对象?【英文标题】:In a lambda, does a by-value capture of a reference copy the underlying object?在 lambda 中,引用的按值捕获是否会复制底层对象? 【发布时间】:2013-11-09 16:27:00 【问题描述】:如果在 lambda 中按值捕获引用类型的变量,是复制引用的对象还是通过引用捕获?
有问题的小样本:
#include <iostream>
struct Test
int a;
;
void testFunc(const Test &test)
auto a = [=]
// is 'test' passed to closure object as a copy
// or as a reference?
return test.a;
();
std::cout << a;
int main()
Test test1;
testFunc(test);
【问题讨论】:
那么,测试一下怎么样? (您需要为此修改对象,这可以通过尝试使用非常量引用或通过创建变量mutable
来实现。)
似乎是value。
@JanHudec 是的,测试很好,但是查看相关标准的部分和基于理论的答案总是有用的(有很多这样的专家)。
知道引用不是对象有帮助吗? Lambda 总是捕获对象,它们可以通过值或引用来实现。
【参考方案1】:
按价值。可编译示例:
class C
public:
C()
i = 0;
C(const C & source)
std::cout << "Copy ctor called\n";
i = source.i;
int i;
;
void test(C & c)
c.i = 20;
auto lambda = [=]() mutable
c.i = 55;
;
lambda();
std::cout << c.i << "\n";
int main(int argc, char * argv[])
C c;
test(c);
getchar();
结果:
复制 ctor 调用 20
我猜,这一段 C++ 标准适用:
5.1.2 Lambda 表达式
(...) 14. 如果实体被隐式捕获且capture-default 为= 或显式捕获,则copy 捕获实体 使用不包含 & 的捕获捕获。对于通过副本捕获的每个实体,一个未命名的非静态 数据成员在闭包类型中声明。这些成员的声明顺序是未指定的。 如果实体不是 引用一个对象,或引用的类型,否则。 [ 注意:如果捕获的实体是对 函数,对应的数据成员也是对函数的引用。 —尾注]
这实际上是有道理的——如果局部变量是通过值传递的,而通过引用传递的参数“充当”函数中的局部变量,为什么它会通过引用而不是值传递?
【讨论】:
索赔的任何参考资料(如规范中的章节和段落编号)? 我认为重要的原因是存在按值捕获,因此只要闭包存在,变量就有效。如果没有剥离引用,这将不起作用。以上是关于在 lambda 中,引用的按值捕获是不是会复制底层对象?的主要内容,如果未能解决你的问题,请参考以下文章