Re: smart pointer clarifications
On Aug 20, 12:57 pm, "Phil Bouchard" <p...@fornux.com> wrote:
"mlimber" <mlim...@gmail.com> wrote in message
news:b5141071-8a0d-45ae-a4ba-da6bcb1c8ca3@e53g2000hsa.googlegroups.com...
On Aug 20, 4:26 am, "Phil Bouchard" <p...@fornux.com> wrote:
[...]
I still don't get it. Let's say you're designing std::vector, which
has an allocator template parameter. It doesn't matter if the user-
defined class or a smart pointer (as long as it has value semantics).
Given this code:
class C { */...*/ };
// ...
std::vector<C> v1( 10 );
std::vector< std::tr1::shared_ptr<C> > v2( 10 );
Under the hood, each of the latter two lines will use vector's
(default) allocator to grab memory for the 10 instances of the
contained type and then placement-new to construct the instances in
that memory. (Note that all the shared_ptr's pointees are null at this
point.) Why does the allocator care if it's making a C or a
shared_ptr<C>?
Cheers! --M
Indeed in that case it won't matter because the pools used to allocate no=
des
from the container and to deallocate objects from the smart pointer are n=
ot
shared. Sometimes it is in our favor to share to same pool used by the
container and the smart pointer. For example shifted_ptr<> uses this t=
o
prevent cyclicism (still requires STL modifications).
Either we do it this way or we share the allocator across the container a=
nd
smart pointer so that the smart pointer uses deallocate(void *):
1)
std::vector<shifted_ptr<int>, shifted_allocator<shifted_ptr<int> > > c1;
2)
std::vector<shifted_ptr<int, shifted_allocator<int> >,
shifted_allocator<shifted_ptr<int, shifted_allocator<int> > > > c2;
I don't even think option 2) is implementable.
I may just be dense, but I still don't see what you're getting at.
Can't you just use the deleter parameter to indicate special deletion?
Something like this (untested):
class C { /*...*/ };
template<class Alloc>
class MyDeleter
{
Alloc& m_alloc;
typedef typename Alloc::value_type T;
public:
MyDeleter( Alloc& alloc ) : m_alloc( alloc ) {}
// Might want a const T* version also
void operator()( T* const ptr )
{
m_alloc.destroy( ptr );
m_alloc.deallocate( ptr, sizeof(T) );
}
};
void Foo( MyAllocator<C>& alloc, const C& initVal )
{
typedef std::vector< std::tr1::shared_ptr<C> > VSPC;
VSPC v( 10 );
for( VSPC::iterator it=v.begin(); it != v.end(); ++it )
{
// Could hide these next lines in a factory function
C* const c = alloc.allocate( sizeof(C) );
alloc.construct( c, initVal );
it->reset( c, MyDeleter( m_alloc ) );
}
// ...
}
Now, when the vector "v" goes out of scope, the shared_ptrs use the
"alloc" object to deallocate their pointees.
Cheers! --M