Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-03-09 11:09:45


On Friday, March 8, 2002, at 05:07 PM, Howard Hinnant wrote:

> On Friday, March 8, 2002, at 12:51 PM, Peter Dimov wrote:
>
>> No. One way to solve it (that I see) is
>>
>> template<class F> vector::vector(size_type n, F f);
>>
>> that will allocate memory and use f(this->_Ptr, n) to initialize it.
>
> The more I think about this, the more I'm beginning to like it.
>
> Official Requirements on F(T* p, size_type n):
>
> 1. It must construct and initialize all elements in the range [p, p+n).
>
> 2. It must have strong exception safety. vector will not be able to
> recover from an exception when the range is partially constructed. It
> is all or nothing.
>
> Notes:
>
> 1. This could probably find all kinds of uses other than the one were
> aiming at.
>
> 2. There's nothing to stop somebody from ducking initialization rules
> if that's what he really wants to do:
>
> struct uninitialized
> {
> void operator()(double*, size_t) {}
> };
>
> std::vector<double> v(10000, uninitialized());
> // use v at your own risk here
>
> As Peter said, could provide an excellent interface to legacy C code.
> Though it may require some gymnastics to map to the C interface,
> especially when there are multiple arrays.
>
> 3. This doesn't have the allocator compatibility problems of passing
> ownership of an array.
>
> 4. The standard would not officially sanction something like
> uninitialized_flag, and yet people can still easily manage it if they
> want to.

5. This needs a do-the-right-thing clause <sigh>. Consider:

std::vector<double> v(10000UL, 0);

This will match:

template<class F> vector::vector(size_type n, F f);

instead of:

vector(size_type, const value_type&);

While implementing the "do-the-right-thing clause" is certainly doable.
It is also certainly a pain in the rear. This would be another elegant
use for restricted templates:

vector(size_type n, const value_type& x = T(), const Allocator& =
Allocator());

template <class It
    : !(is_convertible<It, size_type>::value &&
        is_convertible<It, value_type>::value)>
vector(It first, It last, const Allocator& = Allocator());

template <class F : !is_convertible<F, value_type>::value>
vector(size_type n, F init, const Allocator& = Allocator());

...

-Howard


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