c++ 按值传递模板化unique_ptr

c++ Passing templated unique_ptr by value

本文关键字:unique ptr 按值传递 c++      更新时间:2023-10-16

我有一个派生类,我想创建一个unique_ptr并将其传递给函数。 我可以按如下方式执行此操作:

#include <memory>
struct Base{};
struct Derived : public Base
{};
void foo(std::unique_ptr<Base> sink)
{    
}
int main(){
foo(std::make_unique<Derived>());    
return 0;
}

但是当我想对派生进行模板化时,它不再编译:

#include <memory>
struct Dummy
{};
template<class D>
struct Base{};
template<class D>
struct Derived : public Base<D>
{};
template<class D>
void foo(std::unique_ptr<Base<D>> sink)
{    
}
int main(){
foo(std::make_unique<Derived<Dummy>>()); //does not compile    
//foo(std::unique_ptr<Base<Dummy>>(new Derived<Dummy>())); // compiles
return 0;
}

我可以通过定义一个 Base 唯一 ptr 并使用派生的裸指针对其进行初始化来解决这个问题。

foo(std::unique_ptr<Base<Dummy>>(new Derived<Dummy>()));

然而,这似乎有点不对劲。

我错过了为什么不编译的原因吗?
还有我缺少其他方法如何使用模板化类并且不需要使用裸指针吗?

编译MCVE1 编译 MCVE2

在这种情况下,编译器只是无法推断类型。您可以通过传递以下类型来帮助它:

foo<Dummy>(std::make_unique<Derived<Dummy>>());

但是如果你这样声明foo

template <template<class, class> class X, class Y, class Z>
void foo(X<Y,Z> sink) {}

或者像这样:

template<class D, class S>
void foo(std::unique_ptr<D, S> sink){}

它适用于以下两种情况:

foo(std::make_unique<Derived<Dummy>>());
foo(std::unique_ptr<Base<Dummy>>(new Derived<Dummy>()));