
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