Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2000-10-02 16:16:48


Greg Colvin wrote on 10/2/2000 4:26 PM
>I just tried that, but discovered in testing that it would incorrectly
>convert from Derived[] to Base[].

Not that there's anything wrong with auto_array_ptr, but you can still do
it with parametrization on the deleter function. Just consider the
deleter function to be an allocator, and then mess around with the rebind
member template such that the one for delete[] doesn't work right.

#include <iostream>
#include <memory>

using std::auto_ptr;
using std::_Array;

struct A
{
        A() {std::cout << "construct A\n";}
        virtual ~A() {std::cout << "destruct A\n";}
};

struct B
        : A
{
        B() {std::cout << "construct B\n";}
        virtual ~B() {std::cout << "destruct B\n";}
};

auto_ptr<B>
source()
{
        return auto_ptr<B>(new B);
}

void
sink_b(auto_ptr<B>)
{
}
 
void
sink_a(auto_ptr<A>)
{
}

auto_ptr<B, _Array<B> >
array_source()
{
        return auto_ptr<B, _Array<B> >(new B [2]);
}

void
array_sink(auto_ptr<B, _Array<B> >)
{
}

int main()
{
        {
                auto_ptr<B> b(new B);
                auto_ptr<B> b2(b);
                b = b2;
                auto_ptr<B> b3(source());
                auto_ptr<A> a(b);
                a = b3;
                b3 = source();
                sink_b(source());
                auto_ptr<A> a2(source());
                a2 = source();
                sink_a(source());
        }
        {
                auto_ptr<B, _Array<B> > b(new B [2]);
                auto_ptr<B, _Array<B> > b2(b);
                b = b2;
                auto_ptr<B, _Array<B> > b3(array_source());
                b3 = array_source();
                array_sink(array_source());
// auto_ptr<A, _Array<A> > a(b3); // Does not compile
// a = b3; // Does not compile
        }
}

Don't try this at home though. You risk getting publicly called an idiot
by Francis Glassborow. ;-)

William Kempf wrote on 10/2/2000 4:45 PM
>Again, I'm not sure how appropriate such a class is. It has very
>little benefit over std::vector (the only benefit that comes to mind
>being the availability of release(), which can be worked around using
>std::auto_ptr<std::vector<T> > if it's that important for
>optimization). I'm not a comittee member, but I don't see such a
>class being added to the standard for this reason. So I don't see
>much reason to spend effort on such a class for Boost either.
>
>Am I failing to see some compelling reason to include it?

I recently had reason to use something very similar to auto_array_ptr. I
was creating a hash container and I originally had as a member a
vector<node*>. This was essentially my vector of buckets. But I then
noted that the size/capacity dance that vector does was wasted in my
application. I needed to specify exactly the number of buckets, and then
grow them exactly how I wanted. Of course I can do this with
vector::reserve, but the capacity data member of vector then became
superfluous. By using something more like auto_array_ptr I was able to
decrease the overhead of my hash container by 4 bytes (1 word). And yes,
a 1 word reduction in overhead for a heavily used container is
significant.

Admittedly, I was not actually using auto_array_ptr, because I needed to
traffic in uninitialized memory. But it was a very close relative. I
can easily see that vector is not always a drop-in replacement for
auto_array_ptr (but admit that it often can be).

-Howard


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