Topic: Using myAllocator<> with std::map<>
Author: "Eric Gravel" <Eric_Gravel@Syntell.cpp (remplacez/replace .cpp par/by .com)>
Date: 2000/05/10 Raw View
Here is the situation:
I use a std::map<> (but want to use a std::set<> and the "multi" variants as
well)
to which I've provided my own memory allocator which is not stateless.
(
therefore, I have the following typedef:
typdef std::map<long, TCHAR*, std::less<long>, MyAllocator<long> > Map;
and I instanciate my map like this:
Map myMap(std::less<long>(), MyAllocator<long>(hint);
)
My allocator does have an explicit constructor (thus a ctor with one
argument) and, on the way to the
intialization phase of my object (which contains a map) of my std::map<>,
the "hint" argument isn't
known yet. It could only be obtained after that the initialization part is
completed. Therefore, I attempt
to swap my map with another initialized with the now know "hint" argument.
I wrote something like this: (where "Map" is the typedef above)
ctor() :
m_map(std::less<long>, MyAllocator<long>(0))
{
unsigned hint = /* compute the hint value */
m_map.swap(Map(std::less<long>, MyAllocator<long>(hint));
}
Since my allocator isn't stateless and because I know that 2 allocators will
never be equivalent,
I also defined the logical operators:
template<class T_dataType1, class T_dataType2>
bool operator==(MyAllocator<T_dataType1> const& lhs,
MyAllocator<T_dataType2> const& rhs) { return false; }
template<class T_dataType1, class T_dataType2>
bool operator!=(MyAllocator<T_dataType1> const& lhs,
MyAllocator<T_dataType2> const& rhs) { return true; }
When the m_map.swap( /* ... */ ); is called, it utimately performs some
copying and ends up into that
method taken from Plauger's implementation (for VC++ 6.0) of the
std::_Tree<...>
_Myt& operator=(const _Myt& _X)
{if (this != &_X)
{erase(begin(), end());
key_compare = _X.key_compare;
_Copy(_X); }
return (*this); }
My question is:
Shouldn't be also copying the allocator (therefore doing: allocator =
_X.allocator;) or
is the standard saying that copying the allocator is prohibited?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Gillmer J. Derge" <gderge1@nycap.rr.com>
Date: 2000/05/10 Raw View
Eric Gravel wrote:
> My question is:
>
> Shouldn't be also copying the allocator (therefore doing: allocator =
> _X.allocator;) or
> is the standard saying that copying the allocator is prohibited?
It's permitted. In fact, it's required that it be possible to copy an
allocator. However, a container is "permitted to assume that ... all instances
of a given allocator type are required to be interchangeable and always compare
equal to each other." Therefore, although there's nothing strictly wrong with
your allocator in terms of its meeting the general requirements for an
allocator, you can't count on it working as you intend when used with the
standard container classes.
-----
Gillmer J. Derge
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Richard Parkin" <rparkin@msi-eu.com>
Date: 2000/05/10 Raw View
Gillmer J. Derge <gderge1@nycap.rr.com> wrote in message
news:39186D4A.73B81A47@nycap.rr.com...
> Eric Gravel wrote:
>
> > My question is:
> >
> > Shouldn't be also copying the allocator (therefore doing: allocator =
> > _X.allocator;) or
> > is the standard saying that copying the allocator is prohibited?
>
> It's permitted. In fact, it's required that it be possible to copy an
> allocator. However, a container is "permitted to assume that ... all
instances
> of a given allocator type are required to be interchangeable and always
compare
> equal to each other." Therefore, although there's nothing strictly wrong
with
> your allocator in terms of its meeting the general requirements for an
> allocator, you can't count on it working as you intend when used with the
> standard container classes.
This is also similar to Predicates - a copy of one must be equivalent (not
just now, but forever). ie they are stateless.
But most allocators need some state.
The way to achieve this is to use a letter/envelope pattern, aka
handle/body.
ie all the state that you currently put into the allocator, put into an
allocator_impl, then make your allocator just a handle to that
implementation. Then two copies of a handle still refer to the same 'real'
allocator.
Ric
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]