У меня есть настройка, похожая на эту:
Существует класс, аналогичный vector (он реализован с использованием std :: vector).
Содержит указатели на int.
Я использую свой собственный распределитель.
Вектор не создает элементов, но он может уничтожать элементы.
Чтобы уничтожить его, необходимо вызвать нестатический метод Allocator::deallocate(int *p)
.
Если я делаю это с ручным управлением в реальном времени, я могу позвонить Allocator::deallocate(int *p)
вручную. Это работает, но не RAII.
В качестве альтернативы, я могу использовать std::unique_ptr
с пользовательским удалением. Однако, если я это сделаю, размер массива станет двойным, потому что каждый std::unique_ptr
должен содержать указатель на распределитель.
Есть ли способ сделать это без удвоения размера вектора?
Заметьте, я не хочу шаблонизировать класс.
Вот лучший код RAII, который я приду.
#include <functional>
#include <cstdlib>
#include <memory>
struct MallocAllocator{
template<class T>
static T *allocate(size_t size = sizeof(T) ) noexcept{
return reinterpret_cast<T *>( malloc(size) );
}
// this is deliberately not static method
void deallocate(void *p) noexcept{
return ::free(p);
}
// this is deliberately not static method
auto getDeallocate() noexcept{
return [this](void *p){
deallocate(p);
};
}
};
struct S{
std::function<void(void *)> fn;
S(std::function<void(void *)> fn) : fn(fn){}
auto operator()() const{
auto f = [this](void *p){
fn(p);
};
return std::unique_ptr<int, decltype(f)>{ (int *) malloc(sizeof(int)), f };
}
};
int main(){
MallocAllocator m;
S s{ m.getDeallocate() };
auto x = s();
printf("%zu\n", sizeof(x));
}