C++创建线程会导致错误吗?
我在做一个项目,遇到了循环依赖的问题。我最初希望Device类使用Simulation类彼此发送消息,为了做到这一点,Simulation类必须具有所有已创建设备的记录列表,以便向它们发送中继消息 无论如何,我尝试了另一种方法来解决循环依赖性问题,使用了一个中间人-void RelayMessage。在我取消对线程声明的注释之前,它工作正常。我不知道为什么会出现这样的错误: 严重性代码说明项目文件行抑制状态错误 激活的E1776功能设备::Deviceconst设备&已声明 无法隐式引用-它是已删除的 功能测试项目c:\Users\osfer\Documents\visualstudio 2017\Projects\testingProject\testingProject\main.cpp 37 代码如下:C++创建线程会导致错误吗?,c++,multithreading,compiler-errors,C++,Multithreading,Compiler Errors,我在做一个项目,遇到了循环依赖的问题。我最初希望Device类使用Simulation类彼此发送消息,为了做到这一点,Simulation类必须具有所有已创建设备的记录列表,以便向它们发送中继消息 无论如何,我尝试了另一种方法来解决循环依赖性问题,使用了一个中间人-void RelayMessage。在我取消对线程声明的注释之前,它工作正常。我不知道为什么会出现这样的错误: 严重性代码说明项目文件行抑制状态错误 激活的E1776功能设备::Deviceconst设备&已声明 无法隐式引用-它是已
#include <vector>
#include <string>
#include <thread>
static void RelayMessage(std::string message);
class Device {
public:
std::string incomingMessage = "";
std::string composedMessage;
//std::thread inputStream; // uncommenting this creates an error in class Simulation @ line 36
void relayMessage() {
RelayMessage(composedMessage);
}
void InputStream() {
while (true) {
if (incomingMessage != "")
printf("Message recieved!\n");
incomingMessage = "";
}
}
};
class Simulation {
public:
// record devices in simluation
static std::vector<Device> devicesInSim;
Simulation() {
// create 2 devices
devicesInSim.push_back(Device());
devicesInSim.push_back(Device());
}
};
static void RelayMessage(std::string message) {
// relays message to all devices
for (Device device : Simulation::devicesInSim) // error
device.incomingMessage = message;
}
int main() {
return 0;
}
您正在尝试复制for循环中的对象。线程不可复制。您应该使用引用进行迭代:
static void RelayMessage(std::string message) {
// relays message to all devices
for (auto& device : Simulation::devicesInSim)
device.incomingMessage = message;
}
您也可以使用设备&而不是auto&但是auto在这里非常清楚
这可能就是你的想法。如果没有引用,您将更改对象副本上的incomingMessage,而不是向量中包含的实际对象上的incomingMessage。使用基于范围的for循环时,您需要记住,这会迭代容器中元素的副本:
for (auto i : container)
要迭代实际对象,请使用:
for (auto& i : container)
对于元素的只读访问,请使用:
for (const auto& i : container)
您正在尝试复制for循环中的对象。线程不可复制。您应该使用引用进行迭代:
static void RelayMessage(std::string message) {
// relays message to all devices
for (auto& device : Simulation::devicesInSim)
device.incomingMessage = message;
}
您也可以使用设备&而不是auto&但是auto在这里非常清楚
这可能就是你的想法。如果没有引用,您将更改对象副本上的incomingMessage,而不是向量中包含的实际对象上的incomingMessage。使用基于范围的for循环时,您需要记住,这会迭代容器中元素的副本:
for (auto i : container)
要迭代实际对象,请使用:
for (auto& i : container)
对于元素的只读访问,请使用:
for (const auto& i : container)
正如在注释和其他答案中提到的,std::thread没有复制构造函数,因此您需要通过引用来使用它们 另一个例子是处理文件时,即fstream。无法将fstream对象传递到函数中,因为没有复制构造函数。本质上,当您将对象传递到函数中时,会生成一个仅称为“按值传递”的函数本地副本 由于thread、fstream等没有复制构造函数,因此在函数调用期间无法进行复制。因此,必须使用&和数据类型通过引用传递 编辑:
这并不完全是您问题的解决方案,但需要深入了解它,以便您知道下次发生的原因。如评论和其他答案中所述,std::thread没有副本构造函数,因此您需要通过引用传递来使用它们 另一个例子是处理文件时,即fstream。无法将fstream对象传递到函数中,因为没有复制构造函数。本质上,当您将对象传递到函数中时,会生成一个仅称为“按值传递”的函数本地副本 由于thread、fstream等没有复制构造函数,因此在函数调用期间无法进行复制。因此,必须使用&和数据类型通过引用传递 编辑:
这不完全是解决问题的方法,但要深入了解问题,以便在下次发生时知道原因。这是因为std::thread没有。std::thread类型的对象不能复制,只能移动。哦,天哪,谢谢你们。我已经试着解决这个问题好几天了!这是因为std::thread没有。std::thread类型的对象不能被复制,只能被移动。噢,天哪,谢谢你们。我已经试着解决这个问题好几天了!