为什么将捕获 lambda 分配给 std::function 会导致更多副本 [duplicate]

Why does assigning a capturing lambda to std::function result in more copies [duplicate]

提问人:Gonen I 提问时间:3/2/2023 最后编辑:Gonen I 更新时间:3/3/2023 访问量:195

问:

这个问题在这里已经有答案了:
9个月前关闭。

社区在 9 个月前审查了是否重新讨论这个问题,并将其关闭:

原始关闭原因未解决

在下面的代码中,分配给 std 函数会导致比分配给自动变量更多的复制构造函数调用。 (实际初始化,不分配;))

我得到必须复制本地捕获的值。

每次我将其分配给新的 std::function 时,我都会得到一个额外的副本。

但是为什么初始化 auto var 和函数 var 之间有区别呢?

#include <iostream>
#include <functional>
using namespace std;
struct A { A()=default; A(const A&) {cout << "CC\n";} };
int main()
{
    A a1;
    //auto f = [a1] (){}; // just 1 CC
    //[a1] (){}; // just 1 CC
    function<void()> f=[a1] (){}; // 2 CC 

    return 0;
}
C++ Lambda 复制构造函数 std-function

评论

0赞 user12002570 3/2/2023
在 std::function 中捕获 lambda 会导致额外的副本
0赞 kouta-kun 3/2/2023
我非常没有受过教育的猜测是,这是因为 Lambda 是一个特定的不可命名类型,而 std::function 是围绕该类型的模板化包装器,所以您需要将 Lambda 类型复制到函数类型中?并不能完全解释为什么它不只是移动,但我想这至少是其中的一部分。
0赞 Some programmer dude 3/2/2023
所有 lambda 实际上都作为编译器生成类的对象进行处理,其中捕获基本上是该类的成员。通过创建 lambda 对象的副本,还将复制所有捕获(lambda 对象的成员)。
0赞 doctorlove 3/2/2023
有人提议改变这一点:open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0792r10.html
3赞 molbdnilo 3/2/2023
从概念上讲,这种情况也有两个副本,但初始化的复制部分被省略了。由于第二个是转换,因此没有机会避免第二个副本。auto

答: 暂无答案