Reputation: 15
I made a generic safe thread queue- QueueTS And I have a class named PackagedEvent. I want to make a vector of queues. Each queue stores PackagedEvent. But its not possible to push a new queue to the vector and I dont understand why. The compiler says:
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\xmemory(671,82): error C2280: 'ds::QueueTS<smartH::PackagedEvent>::QueueTS(const ds::QueueTS<smartH::PackagedEvent> &)': attempting to reference a deleted function
1>C:\me\studies\CPP\my_code\debug1\debug1\queueTS.hpp(30): message : compiler has generated 'ds::QueueTS<smartH::PackagedEvent>::QueueTS' here
1>C:\me\studies\CPP\my_code\debug1\debug1\queueTS.hpp(30,1): message : 'ds::QueueTS<smartH::PackagedEvent>::QueueTS(const ds::QueueTS<smartH::PackagedEvent> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::mutex::mutex(const std::mutex &)'
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\mutex(92,5): message : 'std::mutex::mutex(const std::mutex &)': function was explicitly deleted
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\vector(682): message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty>(_Alloc &,_Objty *const ,_Ty &&)' being compiled
1> with
1> [
1> _Alloc=std::allocator<ds::QueueTS<smartH::PackagedEvent>>,
1> _Ty=ds::QueueTS<smartH::PackagedEvent>,
1> _Objty=ds::QueueTS<smartH::PackagedEvent>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\vector(687): message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty>(_Alloc &,_Objty *const ,_Ty &&)' being compiled
1> with
1> [
1> _Alloc=std::allocator<ds::QueueTS<smartH::PackagedEvent>>,
1> _Ty=ds::QueueTS<smartH::PackagedEvent>,
1> _Objty=ds::QueueTS<smartH::PackagedEvent>
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include\vector(700): message : see reference to function template instantiation 'void std::vector<ds::QueueTS<smartH::PackagedEvent>,std::allocator<ds::QueueTS<smartH::PackagedEvent>>>::_Emplace_back_with_unused_capacity<_Ty>(_Ty &&)' being compiled
1> with
1> [
1> _Ty=ds::QueueTS<smartH::PackagedEvent>
1> ]
int main()
{
vector<QueueTS< PackagedEvent>> vec;
vec.push_back(QueueTS< PackagedEvent>());
return 1;
}
class PackagedEvent
{
private:
shared_ptr<Event> m_eventPtr;
size_t m_destination;
public:
PackagedEvent();
PackagedEvent(const shared_ptr<Event>& _event, const size_t& _destination);
shared_ptr<Event> getEventPtr() const;
size_t getDestination() const;
void setEventPtr(const shared_ptr<Event>& _event);
void setDestination(const size_t& _destination);
};
template <typename T>
class QueueTS
{
public:
QueueTS();
~QueueTS() = default;
int enqueue(const T& _t);
int dequeue(T& _ptrT);
void stop();
int size();
private:
queue<T> m_mainQueue;
mutex m_mutex;
condition_variable m_cv;
bool m_power;
}; //QueueTS
Upvotes: 1
Views: 81
Reputation: 85286
push_back
makes a copy when pushing into a vector
, but your QueueTS
isn't copyable (it's default copy-c'tor is automatically deleted because std::mutex
isn't copyable).
One solution is to make QueueTS
copyable by adding a copy constructor and a copy assignment operator. For example:
class QueueTS
{
public:
// . . .
QueueTS(QueueTS const& q) {
(*this) = q;
}
QueueTS& operator=(QueueTS const& q) {
std::lock_guard lock(q.m_mutex);
m_mainQueue = q.m_mainQueue;
m_power = q.m_power;
return *this;
}
// . . .
private:
// . . .
mutable mutex m_mutex; // make the mutex mutable so it can be accessed via const-ref's
Another (better) solution is to make it movable, but an even better solution is to avoid copying in the first place by using e.g. a vector
of pointers to QueueTS
(vector<unique_ptr<QueueTS>>
) or an std::list
with in-place construction.
Upvotes: 1