I have a supposed thread safe blocking queue implementation which is supposed to be a wrapper around std::queue Below is its implementation:
template <typename _Tp>
class SharedQueue
{
public:
explicit SharedQueue(bool isBlocking = true) : isBlocking_(isBlocking) {}
virtual ~SharedQueue() {}
virtual const _Tp& front()
{
std::unique_lock<std::mutex> mlock(mtx_);
// if this is a blocking queue, wait to be notified when when a new object is added
if (isBlocking_)
{
while (queue_.empty())
{
cv_.wait(mlock);
}
}
return queue_.front();
}
virtual bool empty() const
{
std::unique_lock<std::mutex> mlock(mtx_);
return queue_.empty();
}
virtual size_t size() const
{
std::unique_lock<std::mutex> mlock(mtx_);
return queue_.size();
}
virtual void push(const _Tp& value)
{
std::unique_lock<std::mutex> mlock(mtx_);
queue_.push(value);
if (isBlocking_)
{
if (queue_.size() == 1)
{
cv_.notify_all();
}
}
}
virtual void push(_Tp&& value)
{
{
std::unique_lock<std::mutex> mlock(mtx_);
queue_.push(std::move(value));
if (isBlocking_)
{
if (queue_.size() == 1)
{
cv_.notify_all();
}
}
}
}
template <typename... _Args>
void emplace(_Args&&... __args)
{
{
std::unique_lock<std::mutex> mlock(mtx_);
queue_.emplace(std::forward<_Args>(__args)...);
if (isBlocking_)
{
if (queue_.size() == 1)
{
cv_.notify_all();
}
}
}
}
virtual void pop()
{
std::unique_lock<std::mutex> mlock(mtx_);
if (!queue_.empty())
{
queue_.pop();
}
}
private:
bool isBlocking_;
mutable std::mutex mtx_;
mutable std::condition_variable cv_;
std::queue<_Tp> queue_;
};
I want to be be able to place unique_ptr's on this queue and I understand that I'd have to call std::move on the unique_ptr when pushing it on the queue from a client application. Here's my problem... In my main, when I create a std::queue as follows, my program compiles just fine
std::queue<std::unique_ptr<int32_t>> q1;
However, when I create an instance of my SharedQueue as below, the program does not compile.
SharedQueue<std::unique_ptr<int32_t>> q2;
I get an error telling me the copy constructor was deleted in the unique_ptr class, which is understandable. I guess I'm just wondering what std::queue does that the code can compile while my code 'appears' to be a wrapper around the std::queue and implements the operations similarly.
Aucun commentaire:
Enregistrer un commentaire