#include <memory> #include <vector> template <class T> struct allocator98 : std::allocator<T> { template <class U> struct rebind { typedef allocator98<U> other; }; allocator98() { } template <class U> allocator98(const allocator98<U>&) { }; void construct(T* p, const T& val) { std::allocator<T>::construct(p, val); } }; int main() { std::vector< int, allocator98<int> > v(1); } This fails in c++0x mode because std::__uninitialized_default_n_a() incorrectly assumes it's OK to call Alloc::construct with a single argument. That is true for std::allocator in C++0x mode, but not true for most user-defined allocators written to the C++98 requirements. This is the cause of https://svn.boost.org/trac/boost/ticket/5538 The bug is fixed in 4.7 because std::allocator_traits provides a default implementation of construct, ensuring backwards-compatibility with C++98-style allocators. A workaround for user-defined allocators is to add: void construct(pointer p) { return construct(p, value_type()); } The fix for libstdc++ would be to avoid calling construct with a single argument, or to backport a minimal version of allocator_traits from 4.7
Bah, in my opinion it's late to attempt sophisticated things in 4.6, either we can do something minimal or we should just tell people that in 4.6 a C++0x container wants a C++0x allocator.
I agree with the sentiment, but unfortunately a C++11 allocator isn't required to provide a construct member at all. 17.6.3.5 p5 shows a minimal C++11 allocator, and that won't work either, so 4.6 doesn't correctly support user-defined C++98 allocators or user-defined C++11 allocators! I think the minimal fix is for __uninitialized_default_n_a and __uninitialized_default_a to default construct an object of the iterator's value_type and pass that to __alloc.construct(addressof(*cur)) A less-minimal fix would be to change all the containers to use __uninitialized_fill_a instead of __uninitialized_default_a
Unfortunately either of those would cause a regression for PR 32618
suggested patch posted to http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01421.html
Author: redi Date: Wed Dec 21 18:35:40 2011 New Revision: 182600 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182600 Log: PR libstdc++/51626 * include/bits/stl_uninitialized.h (_Construct_default_a_impl): Define overloaded functions to conditionally use allocator::construct. (_Construct_default_a): Define to dispatch to appropriate _Construct_default_a_impl overload. (__uninitialized_default_a, __uninitialized_default_n_a): Use _Construct_default_a. * testsuite/20_util/allocator/51626.cc: New. Added: branches/gcc-4_6-branch/libstdc++-v3/testsuite/20_util/allocator/51626.cc Modified: branches/gcc-4_6-branch/libstdc++-v3/ChangeLog branches/gcc-4_6-branch/libstdc++-v3/include/bits/stl_uninitialized.h
fixed for 4.6.3