Функция принимает std :: auto_ptr & lt; Base & gt; который может принять std :: auto_ptr & lt; Derived & gt;

Я пытаюсь создать функцию, которая принимает auto_ptr в Base класс, и я хотел бы назвать это с auto_ptr в Derived учебный класс. Однако я не могу сделать это.

Я пытался использовать его без ссылки:

void function(std::auto_ptr<Base> ptr);

std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); // error:  #348: more than one user-defined conversion from
// "std::auto_ptr<Derived>" to "std::auto_ptr<Base>" applies

И со ссылкой:

void function(std::auto_ptr<Base>& ptr);

std::auto_ptr<Derived> derivedPtr( new ... )
function(derivedPtr); //error:  #304: no instance of overloaded function "function"// matches the argument list

РЕДАКТИРОВАТЬ:
Я знаю, что auto_ptr устарела, но у меня есть доступ только к C++03 и не могу получить доступ boost, Поэтому я был бы признателен, если бы ответы были сосредоточены на самом вопросе 🙂 Я также понимаю разницу между функцией, принимающей ссылку и auto_ptr по значению. В моем фактическом коде функция становится владельцем auto_ptr так что оба хорошо, если я могу получить преобразование из Derived в Base за работой.

2

Решение

Вы можете сыграть без двусмысленности:

function(static_cast<std::auto_ptr<Base> >(derivedPtr));

Помните, что для этого нужно работать, Base должен иметь виртуальный деструктор. В противном случае код имеет неопределенное поведение.

Причина двусмысленности в том, что Арне говорит в своем ответе — для звонящего не очевидно, function принимает значение или ссылку, и поэтому для вызывающего абонента не очевидно, auto_ptr будет выпущен или нет при выполнении вызова, и если он будет выпущен, будет ли он преобразован в тип, который может правильно delete указатель Неоднозначное преобразование AFAIK поможет вам написать такой сложный код. Делая это, вы делаете это явно в вызывающем коде, который derivedPtr выпущен.

4

Другие решения

Вы пытаетесь auto_ptr по значению и по ссылке, которые совершенно разные вещи. Вызов по значению означает, что вы передаете право собственности на функцию, так как auto_ptr делает это на копии. Звоните по ссылке значит есть только auto_ptr вне функции, которая сохраняет право собственности.

Так как это различие очень неинтуитивно, auto_ptr устарел в стандарте 2011 года, и авторы препятствуют использованию auto_ptr намного длиннее. Короче:

Не использовать auto_ptr совсем.

Использовать unique_ptr если вы хотите передать владение в функцию, или ссылку или простой указатель, если вы хотите оставить его вне функции. Это зависит от конкретного случая, который у вас есть.

Обновить: так как вы упоминаете, что вы должны использовать C ++ 03 без наддува, для C ++ 03 существует реализация unique_ptr: http://howardhinnant.github.io/unique_ptr03.html
Он использует несколько функций буста, которые можно легко написать от руки, поэтому его можно перенести на платформу без использования буста.

5

Лучше управлять памятью вручную, чем использовать auto_ptrкак его использование так чревато ошибками.

Лучше всего использовать замену промышленной силы: в худшем случае, изучите либеральную boost изучите и определите, можете ли вы написать свой собственный клон.

Failimg что, напишите свою собственную замену owning_ptr, Создать ownomg_ptr_transfer учебный класс template также. Блочное копирование конструкции на owning_ptr, бит включить неявное преобразование из owning_ptr_transfer который принимает основной указатель. Имейте свободную функцию или метод, который перемещает основной указатель на объект передачи.

По сути, если нужно, напишите свой unique_ptr используя C ++ 03.

Если вы не будете использовать чужое решение и не будете писать свое собственное, просто запишите память вручную. auto_ptr это того не стоит: это не просто неоптимальный по сравнению с unique_ptrНа самом деле это вредно: его цель — упростить управление памятью, а вместо этого сделать его более подверженным ошибкам. Это был эксперимент, и он не удался.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector