devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻

Как передать велосипедный смарт поинтер в функцию?

Имеется такой велосипед:
template <typename T>
class UniquePtr {
public:
    UniquePtr(T* obj)
        : obj(obj)
    {
    }
    UniquePtr(const UniquePtr& ptr) = delete;
    UniquePtr(UniquePtr&& ptr)
    {
        std::cout << "!! use of move !!" << std::endl;
        obj = std::move(ptr.obj);
        ptr.obj = nullptr;
    }

    UniquePtr& operator=(const UniquePtr& ptr) = delete;
    UniquePtr& operator=(const UniquePtr&& ptr) = delete;

    ~UniquePtr()
    {
        if (obj)
            delete obj;
    }

private:
    T* obj;
};

Класс для теста:
class Test {
public:
    Test()
    {
        std::cout << "Test is created" << std::endl;
    }
    Test(const Test& obj) = delete;
    Test(const Test&& obj) = delete;
    Test& operator=(const Test& obj) = delete;
    Test& operator=(const Test&& obj) = delete;
    virtual ~Test()
    {
        std::cout << "Test is destructed" << std::endl;
    }
};

и функция
void function(UniquePtr<Test>&& ptr)
{
    std::vector<UniquePtr<Test>> v;
    v.push_back(std::move(ptr));
}

Если передавать его, то всё ок
UniquePtr<Test> ptr(new Test);
    function(std::move(ptr));

Но если передавать наследованный от него класс, то не компилируется:
class TestChild : public Test {
public:
    TestChild()
    {
        std::cout << "Test child is created" << std::endl;
    }
    TestChild(const TestChild& obj) = delete;
    TestChild(const TestChild&& obj) = delete;
    TestChild& operator=(const TestChild& obj) = delete;
    TestChild& operator=(const TestChild&& obj) = delete;
    virtual ~TestChild()
    {
        std::cout << "Test child is destructed" << std::endl;
    }
};

UniquePtr<TestChild> ptr(new TestChild);
function(std::move(ptr));


error: invalid initialization of reference of type ‘UniquePtr&&’ from expression of type ‘std::remove_reference&>::type {aka UniquePtr}’
function(std::move(ptr));
~~~~~~~~~^~~~~

Как сделать, чтоб он мог привести UniquePtr<TestChild> к типу UniquePtr<Test>&&?
С std::unique_ptr такое работает
  • Вопрос задан
  • 164 просмотра
Решения вопроса 1
devalone
@devalone Автор вопроса
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
В общем, решил это, добавив следующий конструктор:
template <typename U>
UniquePtr(UniquePtr<U>&& ptr)
{
    obj = ptr.get();
    ptr.reset();
}

Если тип возможно привести к базовому, всё компилится и работает отлично.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы