首页 > 解决方案 > 即使我正在移动,编译器也会尝试使用复制构造函数

问题描述

我正在尝试将东西从我的安全双端队列中移入和移出:

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&。然而,返回引用是没有意义的,因为对象应该永远离开双端队列,因此对它的引用将会消失。

我怎样才能把东西搬到这里?

psDecodedFrame :当持有一个时,编译器怎么可能复制东西unique_ptr?不能复制!

标签: c++

解决方案


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


推荐阅读