Рассмотрим некоторую функцию:Как я могу использовать unique_ptr с более общим делетером?
template<typename F>
void foo(F f) {
std::unique_ptr<int> p = f();
// do some stuff with p
}
Поскольку unique_ptr
указы шаблона по умолчанию аргумент а, default_delete
, для D
, любой функциональный объект, передаваемый foo
, который возвращает unique_ptr
с непостоянным по умолчанию Deleter не удается скомпилировать. Например,
int x = 3;
foo([&x](){
// use empty deleter
return std::unique_ptr<int>(&x, [](int*){});
});
Однако я мог видеть это быть потенциально полезным, и я не вижу прямой причины, почему это не должно быть возможно. Существует ли общий подход к решению этой проблемы?
Редактировать
Простое исправление было бы определить foo
вместо того, чтобы использовать следующее:
std::unique_ptr<int, std::function<void(int*)>> p = f();
Но я задаюсь вопросом, почему это не могло быть включено в интерфейс для unique_ptr
? Есть ли причина, по которой интерфейс класса не может предоставить этот общий атрибут? Существуют ли подходы для «обертывания» такого рода вещей в новое определение?
Например,
template<typename T>
using Generic_unique_ptr =
std::unique_ptr<
T,
std::function< void(typename std::unique_ptr<T>::element_type*) >
>;
Но это кажется опасным, потому что он предоставляет возможность сделать что-то вроде follwing,
Generic_unique_ptr<int> p(new int());
, который оставил бы Deleter неинициализированным и демонстрируют неопределенное поведение. Возможно, каким-то образом предоставить экземплярstd::default_delete<T>
как дефолт по умолчанию?
@TemplateRex Я не уверен, что они одинаковы. Как можно вывести тип делеции из аргумента шаблона 'F'? – jwalk