【问题标题】:“Downcasting” unique_ptr<Base> to unique_ptr<Derived> with unique_ptr<Data> in Derived“向下转换” unique_ptr<Base> 到 unique_ptr<Derived> 并在 Derived 中使用 unique_ptr<Data>
【发布时间】:2019-05-24 10:13:21
【问题描述】:

“Downcasting” unique_ptr< Base > to unique_ptr< Derived > 为向下转换 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;
}

有没有更好的方法来解决这个问题?

开斋节:

修正错别字和

@Igor Tandetnik 给出解决方案

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;

【问题讨论】:

  • 除了拼写错误(Derived 构造函数没有正确定义,缺少; 等),问题是因为std::unique_ptr 有一个明确的deleted 复制构造函数,并且有问题的错误是因为试图复制构造 std::unique_ptr&lt;Data&gt;。在不知道为什么您希望复制构造 std::unique_ptr 工作的情况下 - 因为按照设计它不能 - 没有人能真正帮助你。
  • 您的程序归结为std::unique_ptr&lt;Data&gt; data; auto derived = data; 失败与static_unique_ptr_cast 无关。在修正了许多明显的错别字后,this code compiles
  • @Igor Tandetnik 谢谢。我明白了。

标签: c++ c++11 smart-pointers unique-ptr


【解决方案1】:

在线文档对unique_ptr 进行了说明:

该类满足 MoveConstructible 和 MoveAssignable 的要求,但不满足 CopyConstructible 或 CopyAssignable 的要求。

因此,您不能像尝试在行中那样复制构造或复制分配 unique_ptr

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

【讨论】:

    猜你喜欢
    • 2018-12-15
    • 2016-07-23
    • 2014-03-27
    • 2014-07-21
    • 2020-01-30
    • 2021-10-09
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    相关资源
    最近更新 更多