Patch: stl_vector.h

Matt Austern austern@apple.com
Sat Oct 16 18:55:00 GMT 2004


On Oct 16, 2004, at 1:47 AM, Paolo Carlini wrote:

> Dhruv Matani wrote:
>
>> http://groups.google.co.in/groups?q=vector+constructor+author: 
>> gabriel...
>>
> Ok. We should thank Gaby for this explanation.
>
> Anyway, the basic example, not involving user allocators, still works.
>
> On the other hand:
>
> /usr/local/gcc-exp/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../ 
> include/c++/4.0.0/bits/stl_uninitialized.h:294: error: no matching  
> function for call to '__gnu_cxx::__mt_alloc<dvector_t,  
> __gnu_cxx::__common_pool_policy<true> >::construct(dvector_t*, const  
> int&)'
> /usr/local/gcc-exp/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../ 
> include/c++/4.0.0/ext/mt_allocator.h:613: note: candidates are: void  
> __gnu_cxx::__mt_alloc_base<_Tp>::construct(_Tp*, const _Tp&) [with _Tp  
> = dvector_t]
>
> This is, actually, *another* issue and indeed happens because now  
> (after Matt's changes
> this summer) the user-provided allocator is used throughout.
>
> I'm not at all convinced that in _M_initialize_dispatch(__true_type)  
> we should always
> cast __value (an integer) to value_type (that is, in the example, a  
> dvector_t). Honestly,
> I'm under the impression that we are slightly abusing those  
> overloads...
>
> I think we should ask Matt, in the first place: he is """guilty""" of  
> this """regression"""...
>
> Matt, should this testcase compile:
>
> #include <vector>
> #include <ext/pool_allocator.h>
>
> using __gnu_cxx::__pool_alloc;
>
> typedef std::vector<double, __pool_alloc<double> > dvector_t;
> typedef std::vector<dvector_t, __pool_alloc<dvector_t> > matrix_t;
>
> matrix_t m = matrix_t(1, 1);

This is slightly ambiguous, but my interpretation of the standard   
(23.1.1/9) is
that this is required to work.  We're selecting the constructor
template <class InputIterator> X(InputIterator f, InputIterator l,  
const Allocator& a = Allocator())
and the standard says it has the same effect as
X(static_cast<typename X::size_type>(f), static_cast<typename  
X::value_type>(l), a)

The latter constructor is well-formed.  Static cast of 1 to dvector_t  
is well formed:
it's the same as dvector_t(1), which invokes the single-element  
constructor that
creates a length-1 vector of default-constructed elements.

The reason there's any ambiguity at all is that the standard has a  
non-normative
note describing possible implementation techniques, and, using one of  
those
techniques, this example would fail to compile.  I think the standard  
is clear and
that just means this note is wrong, but some people disagree.  Finally:  
some
people think that, irrespective of what the standard currently says,  
this example
shouldn't compile.  I think that in a future version of the standard it  
will be
explicitly illegal.  Pointer to the committee discussion:
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#438

So I would say: yes, the fact that we don't accept this is a bug.  We  
should be
prepared to think about this again in a few years, after C++0x comes  
out.

Obviously I missed something with the allocator work.  Sounds like I'm  
still
missing it, though; I don't see an obvious reason why this dispatching
should have anything to do with allocators.

			--Matt



More information about the Libstdc++ mailing list