Переместите 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()
, когда счетчик использования достигнет нуля?
Ответы
Ответ 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
будет хранить - и позже использовать - пользовательский делектор.