For example:
struct Foo {
MyPoolAlloc<char> pool;
std::vector<int , MyPoolAlloc<char>> vec_int; // The wrapper allocator would replace MyPoolAlloc<> here.
std::vector<std::function<void()> , MyPoolAlloc<char>> vec_funcs; // The wrapper allocator would replace MyPoolAlloc<> here.
Foo() : vec_int(pool) , vec_funcs(pool) {}
// I want to store lambdas with captured variables using the custom allocator as well:
template<typename Func>
void emplace_back(const Func& func) {
vec_funcs.emplace_back(std::allocator_arg , pool , func);
}
};
In the above code, I want ALL allocations (besides the pool itself) to pull from the same pool
object. Is the best way to do this writing a wrapper allocator that stores a reference to an actual stateful allocator object? And then pass the following into the constructors (example):
: vec_int ((MyWrapperAlloc<char>(pool)));
Is there a cleaner way to do this than writing a whole extra wrapper class for MyPoolAlloc<>
?
The standard "Allocator" concept would have been better named "AllocatorReference." Each object either refers to a global instance (stateless) or to an external object (stateful).
Either way, the allocator instance within an allocator-aware container does not own a memory pool by itself. It's only a proxy. Note that allocator objects are often copied as they are rebound and returned by value. You don't want
vector::get_allocator
to copy a whole memory pool.So, yes, you need two classes.
The "wrapper," "proxy," or "reference" which satisfies the standard Allocator requirements and takes a template parameter for the allocated type.
The memory pool which has nothing to do with the Allocator interface but does know how to perform allocations.