我对C ++内存管理非常陌生,但是想要自己动手构建一个简单的分配器,它可以预先为某个容器预先分配足够的内存。
我看过Alexandrescu Loki图书馆并尝试阅读一些博客,但这一切只是为了让我难以理解。我想从一些原始和工作的起点开始,扩展它并看看它是如何演变的。这就是我现在所拥有的以及我所理解的(我的出发点):
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;
};
所以,我现在可以像这样使用它:
std::vector<int, Allocator<int> > vec;
这个分配器非常简单,我理解它的作用。我现在想稍微扩展它,以便我的客户端代码看起来像:
std::vector<int, Allocator<int, 8> > vec;
我现在希望我的代码为8个元素分配足够的内存。我尝试用这些行扩展我的起始代码:
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
但是当我编译它时,我得到一个疯狂的错误消息列表,一些消息告诉所需的替换,rebind_alloc和没有名为&#34的类型;键入&#34;。那么,我该如何解决呢。我应该对我的踩踏代码进行哪些更正以允许我的分配器有两个模板参数?
答案 0 :(得分:1)
我认为问题在于你有一个非类型模板参数。 allocator_traits
adaptor似乎不支持。
某些容器(例如std::list<int>
)不会分配int
,而是分配internal_node<int>
。因此,它必须能够将Allocator<int>
转换为Allocator<internal_node<int>>
。
要为这种类型T创建分配器,allocator_traits
期望能够从原始(C ++ 98)分配器接口执行Alloc::rebind<T>::other
,或者使用Alloc<T, Args...>
当您的分配器为Alloc<U, Args...>
时。
这两个选项都不符合Allocator
的要求。最后一个失败,因为值8
不是可以匹配Args
的类型。
可能你可以通过添加
来解决这个问题template<class U>
struct rebind
{
using other = Allocator<U, T_num_els>;
};