可变 lambda 是不是有自己的捕获值副本?

Posted

技术标签:

【中文标题】可变 lambda 是不是有自己的捕获值副本?【英文标题】:Do mutable lambdas have their own copies of captured values?可变 lambda 是否有自己的捕获值副本? 【发布时间】:2019-04-22 14:56:34 【问题描述】:
std::function<void()> create_function (args...)

    int x = initial_value (args...);

    return [x] () mutable
    
        std::cout << x++ << std::endl;
    ;

我发现我需要 lambda 上的 mutable 关键字,否则 x 是 const。

如果我多次调用create_function,返回的函数对象会各自拥有自己的x 副本还是共享?

澄清一下,如果我想要 C++11 之前的这种功能,我必须编写一个类来封装捕获,在这种情况下,我可以选择将 x 设为成员变量或全局/静止的。如果 x 是 const 也没关系。语言如何针对不同的 lambda 实例指定 x 的存储?

【问题讨论】:

简而言之:是的。 Lambda 没有静态捕获。无法使用 lambda 模拟您的静态成员。这很好,因为他们应该被排除在任何代码审查之外,有偏见。 实际上并不清楚您的静态/全局捕获将如何发挥作用以及它在什么情况下有用。 @n.m.谢谢你。你能引用标准吗? 没有一个短语说“lambdas 中没有静态/全局捕获”。它根本没有在任何地方提及。要验证它,您需要阅读整个标准。 【参考方案1】:

mutable 在捕获的值是值或引用时不会改变。它只会改变 constness。

您指定是否需要 lambda 捕获中的值(副本)或引用:

return [x] () mutable  // copies

    std::cout << x++ << std::endl;
;

return [&x] () mutable  // references

    std::cout << x++ << std::endl;
;

Lambda 捕获始终被建模为非静态数据成员,如果您对此感到困惑的话。

【讨论】:

那是一个单独的问题。常量、值/引用和共享/实例都是正交的。 @spraff lambda 捕获是 C++ 中的每个实例。就是这样。这很好。

以上是关于可变 lambda 是不是有自己的捕获值副本?的主要内容,如果未能解决你的问题,请参考以下文章

Lambda 按值捕获和“可变”关键字

如何告诉 lambda 函数捕获副本而不是 C# 中的引用?

在 lambda 中,引用的按值捕获是不是会复制底层对象?

是编译器还是我自己:继承自 lambdas 组成的可变参数模板

c ++ lambdas如何从上层范围捕获可变参数包

将 lambda 中捕获的 const 值用作模板参数是不是合法?