There is one mistake

Error 3 error C2280: 'std::mutex::mutex(const std::mutex &)' : attempting to reference a deleted function

It must be repaired. How does it come about? There is one class that implements a queue. In the end. I read the documentation that mutex cannot be copied. Good. I pass to the function a link to this object. But unfortunately I catch this error.


main() function

 int main() { Queue<MyStruct> tasks; //создаем объект std::thread t1(buildQueue, tasks); //кидаем ссылку return 0; } void buildQueue(Queue<MyStruct> &taskQueue) { ; //ничего не делает. } 

Class queue

 template <typename T> class Queue{ private: const unsigned int MAX = 5; std::deque<T> newQueue; std::mutex d_mutex; std::condition_variable d_condition; public: void push(T const& value) { { std::unique_lock<std::mutex> lock(this->d_mutex); newQueue.push_front(value); } this->d_condition.notify_one(); } T pop() { std::unique_lock<std::mutex> lock(this->d_mutex); this->d_condition.wait(lock, [=]{ return !this->newQueue.empty(); }); T rc(std::move(this->newQueue.back())); this->newQueue.pop_back(); return rc; } }; 

I read somewhere that such a problem arises in the case of a constructor that is trying to copy mutex. Although I do not seem to copy anything.

  • And what is MyStruct ? It is important. And yet, give the line in which the error. - VladD
  • Yes, just for the test. struct MyStruct { int test; }; There the data will be placed, and the structure itself will fall into the list. - Ascelhem
  • Okay, that’s good. And which line is wrong? - VladD
  • So it goes - Ascelhem
  • Yyy? .. Then give the full error message. - VladD

2 answers 2

 std::thread t1(buildQueue, std::ref(tasks)); t1.join(); 
  • Changed. Anyway, the same mistake. - Ascelhem
  • Try so std::thread t1(buildQueue, std::ref(tasks)); t1.join(); std::thread t1(buildQueue, std::ref(tasks)); t1.join(); - zenden2k
  • No clue where you found it, but it worked. What is going on here? Is this some kind of crutch? - Ascelhem
  • Since the buildQueue function will run in a new thread, the std :: thread constructor copies the tasks object. To copy a link, not an object, use std :: ref (or std :: cref for constant objects). It is written here cplusplus.com/reference/thread/thread/thread after the description of the parameters - zenden2k

The problem is this line:

 std::thread t1(buildQueue, tasks); 

Here you pass tasks by value, hence it attempts to copy it to the t1 object. But it is impossible to do, because std::mutex could not be copied (it has the copy constructor removed).

The easiest way is to wrap tasks into std::shared_ptr and already transfer it to the stream. In principle, the following code should work too:

 std::thread t1(buildQueue, std::move(tasks)); 

But a cursory inspection of various compilers showed that they refuse to do it. The reason, personally, is not clear. Most likely everywhere bugs.

  • Below in the post suggested using std :: ref (tasks) - works. std :: move throws the same error. - Ascelhem pm
  • one
    @Ascelhem, sending a link to a local variable to another thread is not a good idea. - ixSci 4:02 pm
  • What are some ideas for the implementation of the queue? I have one queue in which objects are placed, and another function is already in use. Therefore, I created a Queue class that stores and allows you to manipulate the queue. - Ascelhem
  • Well, you have the right idea, I would just pass the queue wrapped in a smart pointer to different threads. This allows you to forget about her life time. From what I see, you are trying to portray the concurrent queue. But this is a long-solved problem and, depending on the required compiler, can be solved using ready-made tools. Somehow boost.lockfree - for cross platform or concurrent_queue from MS, if the studio is enough. - ixSci