Re: do allocators have to be stateless?
i want to pass a class to the allocator such that all STL allocators
draw from the same pool. BUT i do not want to use a global pool as we're
going multi-threaded and each thread will have it's own pool. so i'm
trying to pass the pool to the STL allocator as such:
class STLBlockAllocator {
public:
typedef T value_type;
... the rest of the typedef T stuff
inline BlockAllocator& getBlockAllocator(void) const
{
return(m_blockAllocator);
}
// constructor
STLBlockAllocator(BlockAllocator& blockAlloc) throw() :
m_blockAllocator(blockAlloc) {}
// copy constructor
STLBlockAllocator(const STLBlockAllocator & blockAlloc) throw() :
m_blockAllocator(blockAlloc.getBlockAllocator()) {}
template <class U> STLBlockAllocator
(const STLBlockAllocator<U>& t(STLBlockAllocator & blockAlloc))
throw() : m_blockAlloc(blockAlloc.getBlockAlloc()) {}
//destructor
~STLBlockAllocator() throw() {};
// space for n Ts
inline pointer allocate (size_t n, const void* hint = 0)
{
return (static_cast<pointer> (m_blockAllocator.allocate(n)));
}
// deallocate n Ts, do not destroy
inline void deallocate (pointer p, size_type n)
{
m_blockAllocator.free((void*)p, n);
return;
}
// initialize *p by val
inline void construct(pointer p, const T& val)
{
new(p) T(val);
}
// destroy *p but do not deallocate
void destroy (pointer p) { p->~T(); }
inline size_type max_size() const throw()
{ return(size_type(0x1<<28)); }
template<class U>
//in effect: typedef STLBloclAllocator<U> other
struct rebind { typedef STLBlockAllocator<U> other; };
private:
//*****************************************************************
// Implementation
//
BlockAllocator& m_blockAllocator;
};
i'm using visual .net 2003 C++ v7.1
this compiles and works fine for vectors but for list the compiler fails
with the following error:
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\list(64)
: error C2664:
'RDM::STLBlockAllocator<T>::STLBlockAllocator(RDM::BlockAllocator &)
throw()' : cannot convert parameter 1 from 'RDM::STLBlockAllocator<T>'
to 'RDM::BlockAllocator &'
with
[
T=std::_List_ptr<int,RDM::STLBlockAllocator<int>>::_Nodeptr
]
and
[
T=int
]
A reference that is not to 'const' cannot be bound to a non-lvalue
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(62) : while compiling class-template member
function 'std::_List_ptr<_Ty,_Alloc>::_List_ptr(_Alloc)'
with
[
_Ty=int,
_Alloc=RDM::STLBlockAllocator<int>
]
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(76) : see reference to class template
instantiation 'std::_List_ptr<_Ty,_Alloc>' being compiled
with
[
_Ty=int,
_Alloc=RDM::STLBlockAllocator<int>
]
c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(93) : see reference to class template
instantiation 'std::_List_val<_Ty,_Alloc>' being compiled
with
[
_Ty=int,
_Alloc=RDM::STLBlockAllocator<int>
]
w:\ccs\program\rdm_unittest\src\teststlblockallocator.cxx(54) :
see reference to class template instantiation 'std::list<_Ty,_Ax>' being
compiled
with
[
_Ty=int,
_Ax=RDM::STLBlockAllocator<int>
]
====================================================================
the file c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\list(64) looks like this around line 64:
typedef typename _List_nod<_Ty, _Alloc>::_Node _Node;
typedef typename _Alloc::template
rebind<_Node>::other::pointer _Nodeptr;
_List_ptr(_Alloc _Al)
: _List_nod<_Ty, _Alloc>(_Al), _Alptr(_Al)
==> l64 { // construct base, and allocator from _Al
}
typename _Alloc::template rebind<_Nodeptr>::other
_Alptr; // allocator object for pointers to nodes
};
it appears that the rebind stuff is getting confused. for whatever
reason, the compiler appears to be trying to use the regular construtor
(blockalloc) constructor when it should be using the copy constructor (i
think). or do i need some type of templated construtor that takes an
STLBlockAllocator<U> template as a parameter (and if so, what would that
look like??) anybody got any ideas how to fix this one??
thanks,
bill