Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++创建线程会导致错误吗?_C++_Multithreading_Compiler Errors - Fatal编程技术网

C++创建线程会导致错误吗?

C++创建线程会导致错误吗?,c++,multithreading,compiler-errors,C++,Multithreading,Compiler Errors,我在做一个项目,遇到了循环依赖的问题。我最初希望Device类使用Simulation类彼此发送消息,为了做到这一点,Simulation类必须具有所有已创建设备的记录列表,以便向它们发送中继消息 无论如何,我尝试了另一种方法来解决循环依赖性问题,使用了一个中间人-void RelayMessage。在我取消对线程声明的注释之前,它工作正常。我不知道为什么会出现这样的错误: 严重性代码说明项目文件行抑制状态错误 激活的E1776功能设备::Deviceconst设备&已声明 无法隐式引用-它是已

我在做一个项目,遇到了循环依赖的问题。我最初希望Device类使用Simulation类彼此发送消息,为了做到这一点,Simulation类必须具有所有已创建设备的记录列表,以便向它们发送中继消息

无论如何,我尝试了另一种方法来解决循环依赖性问题,使用了一个中间人-void RelayMessage。在我取消对线程声明的注释之前,它工作正常。我不知道为什么会出现这样的错误:

严重性代码说明项目文件行抑制状态错误 激活的E1776功能设备::Deviceconst设备&已声明 无法隐式引用-它是已删除的 功能测试项目c:\Users\osfer\Documents\visualstudio 2017\Projects\testingProject\testingProject\main.cpp 37

代码如下:

#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类型的对象不能被复制,只能被移动。噢,天哪,谢谢你们。我已经试着解决这个问题好几天了!