Ошибка: выбрано разрешение перегрузки, удален оператор '=' для unique_ptr, но только если не в MRE - PullRequest
0 голосов
/ 09 июля 2020

У меня проблема, которая возникает только в моем полном коде. Как вы можете видеть ниже, я изолировал его до минимально воспроизводимого примера:

#include <iostream>
#include <string>
#include <memory>

class GenericObjectHolder
    {
    public:
        GenericObjectHolder()
        {
        }

        virtual ~GenericObjectHolder() = 0;
    };

template <class T, class Holder = GenericObjectHolder>
    //Final because we shouldn't allow destructor to be overriden
    //because we absolutely must delete the holder
    //TODO: can child class call parent class's destructor????
    class Buffer final
    {
    public:
        //Ownership WILL be passed to this object
        static Buffer fromOwned(T buffer, size_t size)
        {
            return Buffer(std::make_unique<T>(buffer), size);
        }

        //Creates a buffer from an object that holds the buffer
        //ownership and saves the object too so it's only destructed
        //when this buffer itself is destructed
        static Buffer fromObject(T buffer, size_t size, Holder *holder)
        {
            return Buffer(std::make_unique<T>(buffer), size, holder);
        }

        //Allocates a new buffer with a size
        static Buffer allocate(size_t size)
        {
            return Buffer(std::make_unique<T>(new T[size]), size);
        }

        /*
        Buffer &operator=(const Buffer & buffer) 
        {
            _size = buffer._size;
            _holder = buffer._holder;
            _buffer = std::move(buffer._buffer);
        }
        */

        ~Buffer()
        {
            if (_holder)
                delete _holder;
        }
        //TODO: read this and think
        virtual void consumed(size_t amountConsumed)
        {
            //_buffer += amountConsumed;
            _size -= amountConsumed;
        }

        virtual T *data()
        {
            return _buffer.get();
        }

        virtual size_t size() const
        {
            return _size;
        }

        Buffer(std::unique_ptr<T> buffer, size_t size)
        {
            _buffer = std::move(buffer);
            _size = size;
        }

        Buffer(std::unique_ptr<T> buffer, size_t size, Holder *holder)
        {
            _buffer = std::move(buffer);
            _size = size;
            _holder = holder;
        }

        
        Buffer(const Buffer &buffer) : _size(buffer._size),
                                       _holder(buffer._holder)
        {
            _buffer = std::move(buffer._buffer);
        }
        

    private:
        Holder *_holder;
        std::unique_ptr<T> _buffer;
        size_t _size = 0;
    };

int main()
{
  auto b = Buffer<uint8_t*, GenericObjectHolder>::fromOwned(new uint8_t[1], 1);
}

, но он прекрасно компилируется .

В моей библиотеке я получаю:

/workspaces/libopenvpnclient/src/AsioAsyncChannel.h:98:21: error: overload resolution selected deleted operator '='
            _buffer = std::move(buffer._buffer);
            ~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:415:19: note: candidate function has been explicitly deleted
      unique_ptr& operator=(const unique_ptr&) = delete;
                  ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:305:7: note: candidate function not viable: 1st argument ('typename std::remove_reference<const unique_ptr<unsigned char *, default_delete<unsigned char *> > &>::type' (aka 'const std::unique_ptr<unsigned char *, std::default_delete<unsigned char *> >')) would lose const qualifier
      operator=(unique_ptr&& __u) noexcept
      ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:325:2: note: candidate template ignored: deduced type 'unique_ptr<...>' of 1st parameter does not match adjusted type 'unique_ptr<...>' of argument [with _Up = unsigned char *, _Ep = std::default_delete<unsigned char *>]
        operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
        ^
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unique_ptr.h:334:7: note: candidate function not viable: no known conversion from 'typename std::remove_reference<const unique_ptr<unsigned char *, default_delete<unsigned char *> > &>::type' (aka 'const std::unique_ptr<unsigned char *, std::default_delete<unsigned char *> >') to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
      operator=(nullptr_t) noexcept
      ^

и в обоих случаях я использую Clang 10.

Кто-нибудь знает, почему это происходит?

Я не понимаю, почему он жалуется на то, что я назначаю a unique_ptr в буфер, так как я его перемещаю. Вы также можете видеть, что я прокомментировал оператор присваивания. Я попытался использовать его, но он пожаловался на то, что у меня нет оператора копирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...