在C ++中创建没有初始化的std :: thread时出错C2280

时间:2017-07-07 05:25:54

标签: c++ multithreading c++11 stdthread

我想在我的类/ struct中创建一个线程对象,但是在声明期间不想立即初始化。 Intead希望以后再做。因此,我在下面的代码片段中做了,我得到了这个编译错误。我该如何解决这个问题?

  

错误C2280:'std :: thread :: thread(const std :: thread&)':尝试   引用已删除的功能

我发现导致此错误的行是:

  std::thread t2;

这是否意味着我们不能在没有初始化的情况下声明std :: thread?这与此帖Is it possible to define an std::thread and initialize it later?

中的答案相矛盾
struct Abc
{
    int a;
    std::thread t2;
    void mem1()
    {
        printf("mem1\n");
    }

    void mem2()
    {
        printf("mem2\n");
        std::thread t1(&Abc::mem1, Abc());
        t2.swap(t1);
        printf("after spawning t1\n");
        t2.join();
    }
};

错误详细信息:

  
    

C:\ Program Files(x86)\ Microsoft Visual Studio 12.0 \ VC \ include \ xmemory0(611):错误C2280:'std :: thread :: thread(const std :: thread&)':尝试参考删除的功能1>
    C:\ Program Files(x86)\ Microsoft Visual Studio     12.0 \ VC \ include \ thread(70):参见'std :: thread :: thread'的声明1>此诊断发生在编译器生成中     函数'Abc :: Abc(const Abc&)

  

2 个答案:

答案 0 :(得分:4)

编译器错误告诉您正在尝试复制具有成员Abc的结构std::thread。这是不可能的,因为std::thread无法复制。

如果您要发布包含它首先指向的代码的整个错误消息(即实际调用Abc的复制构造函数的代码行),我可以为您提供更完整的溶液

旧的答案保留在下面,但我认为在定义您的具体问题的原因时不正确。关于编译器生成的移动构造函数的漫游本身仍然有效。

你的代码很好。编译器无法编译对swap的调用,在仅移动类型的情况下,它依赖于所涉及类型的移动构造函数。您的std::thread未明确定义,因此在这种情况下,符合条件的编译器将生成它。

Visual Studio 2013不会自动生成移动构造函数。这似乎是他们可以解决的错误(通过为他们的std::thread实现明确定义它,可能还有其他std类(模板))。确保将编译器更新到VS 2013.5(更新5)并查看是否有帮助。

如果这不起作用,请获取较新版本的Visual Studio。在VS 2015中修复了不生成移动构造函数的问题。另外VS 2017已经出局。后者在标准c ++方面要好得多,而且要严格得多,尽管它仍然无法编译很多" basic" SFINAE。

答案 1 :(得分:-6)

调用另一个构造函数。该行调用默认构造函数,该构造函数默认为移动构造函数,该构造函数被删除或者是lol。这个问题的答案很有启发性:

enter link description here