I'm extremely new to C++ memory management, but want to make my hands dirty building a simple allocator that would preallocate in advance enough memory for some container.
I've looked at Alexandrescu Loki library and tried to read some blogs, but all this was just to diffucult for me to grasp. I want to start from some primitive and working starting point, expand it and see how it evolves. This is what I have now and what I do understand (my starting point):
template <class T>
struct Allocator {
Allocator(){};
template <class U>
Allocator(Allocator<U> const&);
T* allocate(size_t s) {
return static_cast<T*>(::operator new(s * sizeof(T)));
}
void deallocate(T* p, size_t s) {
::operator delete(p);
}
void construct(T* p, T const& val) {
::new((void *)p) T(val);
}
void destroy(T* p) {
return ((T *) p)->~T();
}
using value_type = T;
};
So, I can now use it like so:
std::vector<int, Allocator<int> > vec;
This allocator is very simple and I understand what it does. I now want to expand it a little bit, so that my client code would look like:
std::vector<int, Allocator<int, 8> > vec;
I would now expect my code to allocate enough memory for 8 elements. I tried to expand my starting code with these lines:
template <class T, size_t T_num_els>
struct Allocator {
template <class U, size_t U_num_els>
Allocator(Allocator<U, U_num_els> const&);
... I keep all the rest without changes just for testing reason
but when I compile it, I get a crazy list of error messages, some messages tell about required substitution, rebind_alloc and no type named "type". So, how can I fix it. What correction should I make to my stepping stone code to allow my allocator have two template parameters?
I think the problem is that you have a non-type template parameter. The allocator_traits
adaptor does not seem to support that.
Some containers, like std::list<int>
, will not allocate int
s but some internal_node<int>
. So it has to be able to transform an Allocator<int>
into an Allocator<internal_node<int>>
.
To create an allocator for such a type T, allocator_traits
expects to either be able to do Alloc::rebind<T>::other
from the original (C++98) allocator interface, or to use Alloc<T, Args...>
when your allocator is Alloc<U, Args...>
.
Neither of these two options match what can be done with your Allocator
. The last one fails because the value 8
isn't a type that can match Args
.
Possibly you can fix this by adding
template<class U>
struct rebind
{
using other = Allocator<U, T_num_els>;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With