简体   繁体   English

带有模板的upcast unique_ptr

[英]Upcast unique_ptr with template

Consider the following simple code: 考虑以下简单代码:

#include <memory>

template<typename T>
struct Foo
{
    virtual T & foo() = 0;
};

struct Bar : public Foo<int>
{
    int x;
    virtual int & foo() override
    {
        return x;
    }
};

void baz(std::unique_ptr<Foo<int>>)
{
}

int main()
{
    auto up = std::make_unique<Bar>();
    baz(up);
    return 0;
}

It won't compile reporting this error: 它不会编译报告此错误:

prog.cc:27:9: error: could not convert 'up' from 'unique_ptr<Bar,default_delete<Bar>>' to 'unique_ptr<Foo<int>,default_delete<Foo<int>>>'
   27 |     baz(up);
      |         ^~
      |         |
      |         unique_ptr<Bar,default_delete<Bar>>

I wonder how I can solve this problem. 我不知道如何解决这个问题。 share_ptr seems to have proper casting methods to solve this issue , while it seems that for unique_ptr there no alternatives. share_ptr似乎具有适当的转换方法来解决此问题 ,而对于unique_ptr似乎没有其他选择。

First of all, you are taking the argument in baz by value , which would imply copying a std::unique_ptr and... that's impossible (or std::move ing it, but I doubt that's what you want here). 首先,您将value用作baz 的参数 ,这将意味着复制 std::unique_ptr并且...是不可能的(或std::move ,但我怀疑这就是您想要的)。

Second of all, std::unique_ptr doesn't convert because that would require copying. 第二, std::unique_ptr不会转换,因为这将需要复制。

What's the workaround? 解决方法是什么?

You can do: 你可以做:

std::unique_ptr<Foo<int>> up = std::make_unique<Bar>();

instead of: 代替:

auto up = std::make_unique<Bar>();

and take the argument in baz by reference : 通过引用接受baz 的参数

void baz(std::unique_ptr<Foo<int>>&) { ... }

First thing is to save a unique_ptr to derived in a unique_ptr to base. 第一件事情就是保存unique_ptr在派生unique_ptr基地。 auto cannot do that, unless you use a cast. 除非您使用强制转换,否则auto不能做到这一点。

Second thing is, as aforementioned, to not copy the unique_ptr . 如前所述,第二件事是不复制 unique_ptr

What's more, you code exhibits undefined behaviour , because you delete the derived class object with a base class pointer. 此外,您的代码表现出未定义的行为 ,因为您使用基类指针删除了派生类对象。 That requires a virtual destructor in the base class. 这需要在基类中使用virtual析构函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM