Oz Harary
Oz Harary

Reputation: 15

Using vector of generic queues

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

Answers (1)

rustyx
rustyx

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

Related Questions