У меня есть функция, которая создает 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
, но я не знаю, как это сделать, учитывая, что я не знаю decltype моего пользовательского средства удаления вне функции.
Я думаю, это должно выглядеть примерно так:
auto uniquePtr = give_unique_ptr();
auto sharedPtr = std::shared_ptr<..??..>(std::move(uniquePtr));
Что я должен написать вместо ..??.. получить правильный тип?
Если это возможно, будет ли shared_ptr
вести себя хорошо и вызвать мой пользовательский удалитель, созданный внутри give_unique_ptr()
функция, когда счетчик использования достигает нуля?
Если вы знаете (или хотите явно набрать) тип объекта, то вы можете сделать это:
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));
};
Надеюсь, это поможет.
auto uniquePtr = give_unique_ptr();
auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr));
И да, shared_ptr
будет хранить — и позже использовать — пользовательский удалитель.