c ++ Передача шаблонного unique_ptr по значению - PullRequest
1 голос
/ 11 октября 2019

У меня есть производный класс, для которого я хочу создать 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;
}

Но когда я хочу сделать это с шаблоном Derived, это больше не компилируется:

#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;
}

Я могу обойти это, определив базууникальный ptr и инициализация его производным пустым указателем.

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

Однако это кажется немного неправильным.

Есть ли причина, по которой мне не хватает, почему это не компилируется?
ТакжеЕсть ли другие способы, которые мне не хватает, как я могу использовать шаблонный класс и не нужно использовать голые указатели?

compile mcve1
compile mcve2

1 Ответ

5 голосов
/ 11 октября 2019

Компилятор, в данном случае, просто не может определить тип. Вы можете помочь, передав тип:

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>()));
...