1
votes

I want to create a thread object in my class/struct but don't want to initialie immediately during declaration. Intead want to do it later. Hence, I did as in below code snippet, I'm getting this compilation error. How do I fix this ?

error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function

I observed the line causing this error is :

  std::thread t2;

Does it mean that we can't just declare a std::thread without initializing ? This contradicts the answer in this 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();
    }
};

Error Details:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(611): error C2280: 'std::thread::thread(const std::thread &)' : attempting to reference a deleted function 1>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\thread(70) : see declaration of 'std::thread::thread' 1> This diagnostic occurred in the compiler generated function 'Abc::Abc(const Abc &)

2
This code is ok. It works here: ideone.com/xRjkcv. I thik the problem is somewhere else. Please post the rest of your program or try cleaning/rebuilding the whole thing...K. Kirsz

2 Answers

4
votes

The compiler error is telling you that you are trying to copy a struct Abc which has a member std::thread. This is not possible because std::thread cannot be copied.

If you would have posted the entire error message including the code that it first points to (i.e. the line of code actually invoking Abc's copy constructor), I could provide you with a more complete solution.


The old answer is kept below but I believe it is incorrect in defining the cause of your specific issue. The ramble about compiler-generated move constructors is still valid in its own right.

Your code is fine. The compiler is failing to compile the call to swap, which in the case of move-only types relies on the move constructor of the types involved. Your std::thread won't have it explicitly defined, so a conformant compiler will generate it in this case.

Visual Studio 2013 does not automatically generate move constructors. This seems like a bug they could have worked around (by explicitly defining it for their std::thread implementation, and probably every other std class (template)). Make sure you update your compiler to VS 2013.5 (update 5) and see if that helps.

If that does not work, get a newer version of Visual Studio. The problem of not generating move constructors is fixed in VS 2015. Also VS 2017 is out. The latter is a lot better and a lot stricter when it comes to standard c++, even though it still fails to compile lots of "basic" SFINAE.

-6
votes

Call a different constructor. That line calls the default constructor, which is defaulting to the move constructor, which is deleted or something lol. The answer in this question is pretty illuminating:

enter link description here