Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-03-08 13:12:46


On Friday, March 8, 2002, at 12:51 PM, Peter Dimov wrote:

> From: "Howard Hinnant" <hinnant_at_[hidden]>
>> On Friday, March 8, 2002, at 12:29 PM, Peter Dimov wrote:
>>
>>> From: "Howard Hinnant" <hinnant_at_[hidden]>
>>>> Meanwhile vector<double> v(10, uninitialized_flag) breaks no vector
>>>> invariants. The vector is destructible. The vector elements can be
>>>> assigned into. If your hardware doesn't mind (mine doesn't), you can
>>>> even assign from this uninitialized vector. I can't think of a
>>>> reason
>>>> why you would want to do that though.
>>>
>>> You can't v.insert(v.begin(), 5.0) because copying the uninitialized
>>> doubles
>>> is undefined behavior. The insert() preconditions do not say that you
>>> can't.
>>> Something is wrong. :-)
>>
>> Does passing the vector a chunk of uninitialized memory solve this
>> problem?
>
> 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.

I'm not following completely how this would solve the numerics problem
that zero initializing the vector is too expensive, and also solve your
v.insert problem.

On Friday, March 8, 2002, at 01:03 PM, David Abrahams wrote:

> That wasn't my suggestion:
>
> Suppose we could hand vector<T> a chunk of memory and tell it "this
> contains memory for N instances of T, the first M of which have been
> constructed", and have it use that memory?
>
> So, in a typical vector
>
> template <class T, class A>
> vector<T,A>::adopt(void* elements, size_type length, size_type
> initialized = length)
> {
> if (this->__start != 0) this->clear();
> this->__start = static_cast<T*>(elements);
> this->__end = this->__start + initialized;
> this->__end_of_storage = this->__start + length;
> }
>
> Does this clarify?

Oh, I think I get it now! <slapping forehead>. The client initializes
the memory at his leisure before asking vector to take ownership of it.

Doesn't that make vector overkill? Why not just give the memory to a
smart pointer that will use delete[]? Then you wouldn't have to worry
about exception safety while you're still in the initialization phase.

Essentially you've got a chunk of memory that's going to change types
(well, change owners) mid way through its life. From raw pointer (or
smart pointer) to vector. Is there sufficient motivation for this
mid-life ownership transfer? Would that really help solve more problems
than it creates? It may be simpler to just create your own container
that tolerates indeterminant scalars.

-Howard


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