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

时间:2017-11-27 03:06:27

标签: c++ multithreading compiler-errors

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

无论如何,我尝试了另一种使用中间人修复循环依赖问题的方法 - void RelayMessage()。它工作正常,直到我取消注释线程声明。我不知道它为什么会给我错误:

  

严重级代码说明项目文件行抑制状态错误   (有效)E1776功能“Device :: Device(const Device&)”(声明   隐含地)不能被引用 - 它被删除了   function testingProject c:\ Users \ osfer \ Documents \ Visual Studio   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;
}

2 个答案:

答案 0 :(得分:3)

您正在尝试复制for循环中的对象。 thread不可复制。您应该使用引用迭代:

static void RelayMessage(std::string message) {
    // relays message to all devices
    for (auto& device : Simulation::devicesInSim)
        device.incomingMessage = message;
}

(您也可以使用Device&代替auto&,但此处auto非常明确。)

这可能就是你想到的。如果没有引用,您将更改incomingMessage对象的副本而不是向量中包含的实际对象。使用基于范围的for循环时,您需要记住,这会迭代容器中元素的副本:

for (auto i : container)

要迭代实际对象,请使用:

for (auto& i : container)

要获得对元素的只读访问权限,请使用:

for (const auto& i : container)

答案 1 :(得分:1)

正如评论和其他答案中所提到的,std::thread没有复制构造函数,因此您需要通过引用传递它们。

另一个例子是处理文件时,即fstream。由于没有复制构造函数,因此无法将fstream个对象传递给函数。基本上发生的事情是,当您将对象传递给函数时,会创建一个仅对函数本地的副本(称为pass by value)。

由于threadfstream等没有复制构造函数,因此在函数调用期间无法复制。因此,您必须使用&和数据类型通过引用传递。

修改 这不是解决问题的方法,而是对它的一些见解,以便您知道下次发生的原因。