I have setup, similar to this:
There is class similar to vector (it is implemented using std::vector).
It contains pointers to int's.
I am using my own custom allocator.
The vector does not create elements, but it can destroy elements.
In order to destroy it needs to call non static method Allocator::deallocate(int *p).
If I do it with manual livetime management, I can call Allocator::deallocate(int *p) manually. This works, but is not RAII.
Alternatively, I can use std::unique_ptr with custom deleter. However if I do so, the size of array became double, because each std::unique_ptr must contain pointer to the allocator.
Is there any way I can do it without doubling the size of the vector?
Note i do not want to templatize the class.
Here is best RAII code I come up.
#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));
}
Aucun commentaire:
Enregistrer un commentaire