我正在尝试在 C++ 中将 lambda 与线程一起使用,并使用捕获作为将数据传递给线程的一种方式。以下代码在创建线程时打印了三次“ConnectionInfo(copy)”。有没有办法将它减少到一个拷贝?我不确定为什么要多复制两次。
#include <iostream>
#include <functional>
#include <memory>
#include <thread>
using namespace std;
class ConnectionInfo
{
public:
ConnectionInfo():port(0) {}
ConnectionInfo(int p):port(p) {}
ConnectionInfo(const ConnectionInfo &other)
{
std::cout << "ConnectionInfo(copy)" << std::endl;
port = other.port;
}
int port;
void Connect() {};
};
int main() {
std::cout << "Create" << std::endl;
ConnectionInfo c(2);
std::cout << "Thread" << std::endl;
std::thread t(
[a = c]() mutable
{
a.Connect();
std::cout << "Done" << std::endl;
}
);
std::cout << "Joining" << std::endl;
t.join();
std::cout << "Joined" << std::endl;
return 0;
}
输出是:
Create
Thread
ConnectionInfo(copy)
ConnectionInfo(copy)
ConnectionInfo(copy)
Joining
Done
Joined
最佳答案
std::thread 的定义要求将参数按值传递给新线程,因为 lambda 在您的情况下是临时的,这正是您想要的。但是,这些额外的拷贝很可能实际上是降级为拷贝的移动,因为您的类没有移动构造函数。
因此,向您的类添加一个移动构造函数,应该将序列减少到一个拷贝(捕获)和两个移动。
当然,这只会在移动比复制便宜的情况下有所帮助,但是如果与线程的创建相比复制的开销很重要,则您的对象很可能在堆上管理一些数据或者必须执行其他操作在移动构造函数中通常可以省略的拷贝上的昂贵操作。
关于c++ - 在线程中运行 lambda 时如何减少拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51368321/