gpt4 book ai didi

c++ - 从具有按值捕获的 lambda move 构造 std::function 时调用两次 move 构造函数

转载 作者:行者123 更新时间:2023-12-01 12:16:40 24 4
gpt4 key购买 nike

move 构建 std::function 时来自 lambda 的对象,其中该 lambda 具有按值捕获,似乎被值捕获的对象的 move 构造函数被调用了两次。考虑

#include <functional>#include <iostream>struct Foo{    int value = 1;    Foo() = default;    Foo(const Foo &) {}    Foo(Foo &&)    {        std::cout << "move ctor" << std::endl;    }};int main(){    Foo foo;    auto lambda = [=]() { return foo.value; };    std::cout << "---------" <<  std::endl;    std::function<int()> func(std::move(lambda));    std::cout << "---------" <<  std::endl;    return 0;}

The output is

---------
move ctor
move ctor
---------
我在 Mac OS X Catalina 上工作,我的编译器是
g++-9 (Homebrew GCC 9.3.0) 9.3.0
我用 g++ -std=c++17 编译.
我想这种行为可能有点依赖于编译器实现,但我仍然对这种机制感到好奇。
有人可以解释为什么 move 构造函数被调用两次以及那里到底发生了什么?

最佳答案

这是由 std::function 造成的被执行。考虑以下更简单的示例:

struct Lambda
{
Lambda() = default;
Lambda(const Lambda&) { std::cout << "C"; }
Lambda(Lambda&&) { std::cout << "M"; }
void operator()() const { }
};

int main()
{
auto lambda = Lambda();
std::function<void()> func(std::move(lambda));
}
它打印出 MM ,因此, move Lambda 的构造函数将其实例存储到 std::function 时被调用两次.
现场演示: https://godbolt.org/z/XihNdC
在您的情况下, Foo 以来,该 lambda 的成员变量(由值捕获) move 了两次整个 lambda move 了两次 .请注意 捕获本身不会调用任何 move 构造函数 ,它改为调用复制构造函数。

为什么 std::function的构造函数两次 move 论证?注意这个 构造函数按值传递参数 ,然后,它 内部需要存储该对象 .它可以通过以下函数进行模拟:
template< class F >
void function( F f )
{
F* ptr = new F(std::move(f));
delete ptr;
}
这段代码:
  auto lambda = Lambda();
function(std::move(lambda));
然后执行 两招 .
现场演示: https://godbolt.org/z/qZvVWA

关于c++ - 从具有按值捕获的 lambda move 构造 std::function 时调用两次 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62591304/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com