我正在尝试从我的thead安全双端队列中移入和移出
template <typename T>
class ThreadSafeDeque
{
//..
T pop_front(void) noexcept
{
std::unique_lock<std::mutex> lock{_mutex};
while (_collection.empty())
{
_condNewData.wait(lock);
}
auto elem = std::move(_collection.front());
_collection.pop_front();
return elem;
}
private:
std::deque<T> _collection; // Concrete, not thread safe, storage.
//...
}
我创建了要插入双端队列的此类:
class DecodedFrame
{
public:
DecodedFrame(){}
DecodedFrame(const DecodedFrame &decodedFrame) = delete;
DecodedFrame &operator=(const DecodedFrame &) = delete;
std::unique_ptr<AVFrame, AVFrameDeleter> avFrame;
现在我正在尝试
std::shared_ptr<ThreadSafeDeque<DecodedFrame>> decodedFramesFifo;
//add some `DecodedFrame`s to decodedFramesFifo
DecodedFrame decodedFrame = std::move(decodedFramesFifo->pop_front());
但是编译器抱怨我删除了复制分配构造函数,即使我试图使用移动分配构造函数也是如此。我的猜测是,发生这种情况是因为pop_front
返回了T
,而不是T&
。但是,返回引用毫无意义,因为该对象应该永远离开双端队列,因此对它的引用将死亡。
我如何在这里搬东西?
ps :当DecodedFrame
持有unique_ptr
时,编译器如何复制内容?无法复制!
答案 0 :(得分:4)
问题是您声明了复制控制器和赋值运算符。声明删除它们并不重要,它仍然是用户提供的声明。这抑制了移动操作的隐式声明。您的选择是
答案 1 :(得分:3)
copy-ctor / assign操作被删除(这些也是声明),但是不会隐式声明/定义move-ctor / assign操作。
参见https://fr.slideshare.net/ripplelabs/howard-hinnant-accu2014的p30
您必须声明(默认)它们。
DecodedFrame(DecodedFrame &&) = default;
DecodedFrame &operator=(DecodedFrame &&) = default;
为了避免这种令人沮丧的行为,您应该考虑五个规则。
(https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_five)
答案 2 :(得分:2)
您没有得到move构造函数和move赋值运算符,因为您的副本构造函数和copy赋值运算符是由用户指定/定义的(已删除)。您可以通过“ = default”强制使用默认的move构造函数并移动赋值(就像使用delete一样)。
但是,由于类具有作为成员的唯一指针,该指针本身只能进行构造和移动分配,因此您将免费删除复制构造函数和复制分配。只需删除delete语句就可以了,因为您随后又可以进行移动操作。