Boost logo

Boost :

From: Joaquín Mª López Muñoz (joaquin_at_[hidden])
Date: 2004-05-20 07:54:37


Hi Andreas

Andreas Huber ha escrito:

> Dear Boosters
>
> Some old implementations of std::allocator don't provide the rebind member
> template (e.g. MSVC6.0 stdlib). This keeps code as the following from
> compiling:
>
> typedef std::map<
> const state_base_type *, event_queue_type,
> std::less< const state_base_type * >,
> typename allocator_type::template rebind< // *** here ***
> std::pair< const state_base_type * const, event_queue_type >
> >::other
> > deferred_map_type;
>
> However, this map will internally not allocate objects of the type
> std::pair< const state_base_type * const, event_queue_type > anyway but
> rather of some implementation-defined tree node type. So, the above typedef
> could also be written as follows, ...
>
> typedef std::map<
> const state_base_type *, event_queue_type,
> std::less< const state_base_type * >,
> allocator_type
> > deferred_map_type;
>
> which should work with just about any implementation of the std library, as
> long as the used container is a list, (multi)set or (multi)map.

Well, this is not generally true. In most cases the thing will work, but
consider for example the following:

#include <list>

typedef std::list<
  int,
  std::allocator<double>
> my_list;

int main()
{
  my_list l;
  my_list::reference e=*l.begin(); //error here
}

This actually fails to compile in CW 9.3 (it works for some other
environments). Strictly speaking, CW 9.3 is right to not compile the
snippet, as my_list::reference is double& instead of int&. The
fact that it compiles for other stdlibs is sheer luck.

>
>
> Now, the questions are:
>
> - Does the standard allow the second variant (I haven't found anything pro
> or contra)?

The std does not allow it. See 23.1.8: "[...] All other constructors for these
container types take an Allocator& argument (lib.allocator.requirements), an
allocator
whose value type is the same as the container's value type.[...]"

>
> - Even if the standard does not allow it or is silent on it, would anyone
> bother to write the technically more correct first variant? If yes, even at
> the expense of making the code compileable on fewer compilers (or having to
> clutter the code with more #ifdefs)?

The non-std variant can lead to actual errors (admittedly, the demo snippet
is not so likely to occur in practice, but it is not unrealistic, think for
example about a generic routine.)
An alternative is to write an allocator adaption layer that takes care
of the differences in rebinding support among different stdlibs. See for
instance

http://www.boost-consulting.com/boost/boost/multi_index/detail/allocator.hpp

(rebind_to utility) for an example of what can be done to overcome
the problem.

Hope this helps,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk