Я пытаюсь написать функцию, которая принимает unique_ptr к классам, полученным из Base
в качестве параметров (для указания передачи права собственности). Я придумал следующий код:
#include <memory>
#include <type_traits>
class Base
{
public:
Base() {}
};
class Derived : public Base
{
public:
Derived() {}
};
void foo(std::unique_ptr<Derived> _data) {}
template <class T>
void boo(std::unique_ptr<T> _data) {
static_assert(std::is_convertible<T*, Base*>::value,
"Only classes derived from Base can be used as "
"parameter for boo");
}
int main() { foo(new Derived); }
, но когда я пытаюсь скомпилировать его, я получаю сообщение об ошибке, сообщающее мне, что could not convert ‘(operator new(1ul), (<statement>, ((Derived*)<anonymous>)))’ from ‘Derived*’ to ‘std::unique_ptr<Derived>’
, если я использую foo
и то же самое (плюс некоторые детали шаблона), когда я использую boo
. Если я все правильно понял, то мне говорят, что для std::unique_ptr<Derived>
нет конструктора, который мог бы принять указатель на Derived
. Но когда я посмотрел на cppreference page конструктор unqiue_ptr, я увидел, что такой конструктор есть (номер 3-4).
Вопрос в том, как сделать функцию, которая принимает unique_ptr
в качестве параметра, и вызывать ее с необработанным указателем.
P.S. Я пытаюсь написать функцию, которая принимает unique_ptr
, потому что я хочу указать, что право собственности на параметр будет передано. Если вы знаете, как написать функцию с подписью, которая может ясно и однозначно показать, что право собственности передается, я бы также принял это как ответ. Эта функция может использовать шаблон static_assert
или указатель Base
в качестве параметра.
P.S. Основная проблема в том, как сделать foo(new Derived)
. Я знаю, что могу использовать boo(std::make_unique<Derived>())
(в этом случае все работает), но я также действительно хочу знать, почему не работает пример с необработанным указателем, потому что я не знаю, как указать, что я ' m «крадет» владение для необработанного указателя.
P.S Пример использования (с необработанными указателями) ( НЕ РАБОТАЕТ )
Derived* derived_1 = new Derived;
// Do something with derived_1
boo(derived_1); // Pass to function and don't worry about `delete`
// because you know that ownership has been
// transferred and no longer is your concern
И с умными указателями
void foo_2(std::unique_ptr<Derived>& _data) {
boo(std::move(_data));
}
std::unique_ptr<Derived> derived_2 = std::make_unique<Derived>();
// Do something with derived_2
foo(std::move(derived_2)); // Have to use `std::move`
// or
foo_2(derived_2);
Второй (исключая необходимость в новой функции) не так прост, как первый (хотя я должен признать, что разница не так уж велика (возможно, 2-кратный ввод))