gpt4 book ai didi

c++ - 为什么这个 lambda [=] 捕获会创建多个拷贝?

转载 作者:行者123 更新时间:2023-12-04 11:53:34 25 4
gpt4 key购买 nike

在以下代码中:

#include <iostream>
#include <thread>

using namespace std;

class tester {
public:
tester() {
cout << "constructor\t" << this << "\n";
}
tester(const tester& other) {
cout << "copy cons.\t" << this << "\n";
}
~tester() {
cout << "destructor\t" << this << "\n";
}

void print() const {
cout << "print\t\t" << this << "\n";
}
};

int main() {
tester t;

cout << " before lambda\n";
thread t2([=] {
cout << " thread start\n";
t.print();
cout << " thread end\n";
});

t2.join();
cout << " after join" << endl;

return 0;
}
使用 cl.exe 编译时(在 Windows 上)我得到以下信息:
constructor 012FFA93
before lambda
copy cons. 012FFA92
copy cons. 014F6318
destructor 012FFA92
thread start
print 014F6318
thread end
destructor 014F6318
after join
destructor 012FFA93
并与 g++ (在 WSL 上)我得到:
constructor     0x7ffff5b2155e
before lambda
copy cons. 0x7ffff5b2155f
copy cons. 0x7ffff5b21517
copy cons. 0x7fffedc630c8
destructor 0x7ffff5b21517
destructor 0x7ffff5b2155f
thread start
print 0x7fffedc630c8
thread end
destructor 0x7fffedc630c8
after join
destructor 0x7ffff5b2155e
  • 我希望 [=]捕获将正好创建 tester 的 1 个拷贝.为什么有几个拷贝会立即销毁?
  • 为什么 MSVC 和 GCC 之间存在分歧?这是未定义的行为还是什么?
  • 最佳答案

    该标准要求可调用对象传递给 std::thread 的构造函数。可有效复制构造 ( [thread.thread.constr] )

    Mandates: The following are all true:

    • is_­constructible_­v<decay_­t<F>, F>
    • [...]
    is_­constructible_­v<decay_­t<F>, F>is_copy_constructible 相同(或者更确切地说,它是相反的)。
    这是为了允许实现自由地传递可调用对象,直到它到达被调用的点。 (事实上​​,标准本身建议可调用对象至少被复制一次。)
    由于 lambda 被编译成一个重载函数调用运算符(仿函数)的小类,每次你的 lambda 被复制时,它都会创建一个捕获的拷贝 tester实例。
    如果您不希望发生复制,您可以在捕获列表中引用您的实例:
    thread t2([&ref = t] {
    cout << " thread start\n";
    ref.print();
    cout << " thread end\n";
    });
    Live Demo
    输出:
    constructor 0x7ffdfdf9d1e8
    before lambda
    thread start
    print 0x7ffdfdf9d1e8
    thread end
    after join
    destructor 0x7ffdfdf9d1e8

    关于c++ - 为什么这个 lambda [=] 捕获会创建多个拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69256940/

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