«Даункинг» unique_ptr <Base>до unique_ptr <Derived>с unique_ptr <Data>в производном - PullRequest
0 голосов
/ 26 декабря 2018

«Downcasting» unique_ptr to unique_ptr предлагает гибкое решение для downcasting unique_ptr.Это работает в большинстве случаев.Но когда в Derived содержится unique_ptr, что-то идет не так:

template<typename Derived, typename Base, typename Del>
std::unique_ptr<Derived, Del> 
static_unique_ptr_cast( std::unique_ptr<Base, Del>&& p )
{
    auto d = static_cast<Derived *>(p.release());
    return std::unique_ptr<Derived, Del>(d, std::move(p.get_deleter()));
} 

struct Data
{
   int data;
};

struct Base
{
};

struct Derived : public Base
{
    Derived() 
        : data(std::make_unique<Data>())

    std::unique_ptr<Data> data;
};

int main()
{
    std::unique_ptr<Base> base = std::make_unique<Derived>();

    auto data = static_unique_ptr_case<Derived>(std::move(base))->data; // compile error

    return 0;
}

Есть ли лучший способ решить проблему?

Eidt:

исправить опечатки и

@ Игорь Тандетник дать решение

std::unique_ptr<Base> base = std::make_unique<Derived>();

//auto& data = static_unique_ptr_case<Derived>(std::move(base))->data; // compile error

auto derived = static_unique_ptr_case<Derived>(std::move(base));

auto& data = derived->data;

return 0;

1 Ответ

0 голосов
/ 26 декабря 2018

В онлайн-документации говорится об этом unique_ptr:

Класс удовлетворяет требованиям MoveConstructible и MoveAssignable, но не требованиям ни CopyConstructible, ни CopyAssignable.

Таким образом, вы не можете скопировать конструкцию или скопировать присвоить unique_ptr, как вы пытаетесь сделать в строке:

auto derived = static_unique_ptr_cast<Derived>(std::move(base))->data; // compile error
...