编译器尝试使用复制构造函数,即使我正在移动
Compiler tries to use copy constructor even though I'm moving
我正在尝试将东西从我的头安全装置中移入和移出:
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.
//...
}
我创建了这个类来插入到 Deque 中:
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
时,编译器怎么可能复制东西?无法复制!
问题是你声明了你的复制 c'tor 和赋值运算符。声明删除它们并不重要,它仍然是用户提供的声明。这将禁止移动操作的隐式声明。您的选择是
- 显式默认移动操作。 删除复制
- 操作声明,由于不可复制的成员,它们仍将被隐式删除。
copy-ctor/assign 操作被删除(这些也是声明(,但这不会隐式声明/定义 move-ctor/assign 操作。
见 https://fr.slideshare.net/ripplelabs/howard-hinnant-accu2014 第30页
您必须声明(默认(它们。
DecodedFrame(DecodedFrame &&) = default;
DecodedFrame &operator=(DecodedFrame &&) = default;
为了避免这种令人沮丧的行为,您应该考虑五法则。
(https://en.cppreference.com/w/cpp/language/rule_of_three#Rule_of_five(
您不会获得移动构造函数和移动赋值运算符,因为您的复制构造函数和复制赋值运算符是用户删除/定义的(您删除了它们(。 您可以通过"=default"强制使用默认移动构造函数和移动赋值(就像删除一样(。
但是由于该类具有唯一的指针作为成员,该指针本身只能移动可构造且可移动可分配,因此您将免费删除复制构造函数和复制赋值。 只需删除删除语句,就会没事的,因为然后您再次获得移动操作。
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?