Подтвердить что ты не робот

Переместите unique_ptr с пользовательским удалением в shared_ptr

У меня есть функция, которая создает unique_ptr с пользовательским удалением и возвращает его:

auto give_unique_ptr() {
    auto deleter = [](int* pi) {
        delete pi;
    };
    int* i = new int{1234};
    return std::unique_ptr<int, decltype(deleter)>(i, deleter);
}

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

Я думаю, он должен выглядеть примерно так:

auto uniquePtr = give_unique_ptr();
auto sharedPtr = std::shared_ptr<..??..>(std::move(uniquePtr));

Что мне нужно написать вместо..??.., чтобы получить правильный тип?

Если это возможно, будет ли стиль shared_ptr вести себя красиво и вызвать мой пользовательский отладчик, созданный внутри функции give_unique_ptr(), когда счетчик использования достигнет нуля?

4b9b3361

Ответ 1

Если вы знаете (или хотите явно ввести) тип объекта, вы можете сделать это:

std::shared_ptr<int> sharedPtr(std::move(uniquePtr));

Конструктор std::shared_ptr позаботится об удалении.


Если вы, однако, хотите, чтобы тип был выведен, тогда:

auto sharedPtr = make_shared_from(std::move(uniquePtr));

где make_shared_from:

template<typename T, typename D>
std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p)
{
   //D is deduced but it is of no use here!
   //We need only `T` here, the rest will be taken 
   //care by the constructor of shared_ptr
   return std::shared_ptr<T>(std::move(p));
};

Надеюсь, что это поможет.

Ответ 2

auto uniquePtr = give_unique_ptr();
auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr));

И да, shared_ptr будет хранить - и позже использовать - пользовательский делектор.