Boost logo

Boost :

Subject: Re: [boost] [shared_array] Why not in C++11 ?
From: Jonathan Wakely (jwakely.boost_at_[hidden])
Date: 2013-07-08 06:34:53


On 8 July 2013 09:22, Sid Sacek wrote:
>
>
>> If you want a container, use one. Containers with shared storage would be a nice addition
>> to Boost, IMHO, but these should not abuse shared_ptr interface.
>
> According to what you just wrote 'shared_ptr<T[]>' has already abused 'shared_ptr<>' and
> all of the array features should be rolled back, or be put into another class altogether.

I disagree with your implication that shared_ptr<T[]> abuses anything,
maybe your view is skewed by thinking it's trying to be something it
isn't. shared_ptr<T> and shared_ptr<T[]> are similar to T* pointing
to a single object, and a T* pointing to an array, with the same
limitation that the size is not part of the pointer but with the
advantage that you don't have to remember whether to use delete or
delete[].

Now you could argue that using pointers to refer to arrays abuses
pointers, but that's how C++ works, and it does have many advantages.

> In all seriousness, I'm not trying to be a thorn in anybody's side here. All I'm saying
> is that 'shared_ptr<T[]>' looks to me like it has come 99% of the way to being a full-blown
> object-oriented shared-buffer. I'm saying, adding the capacity will simply bring that
> concept closer to completion.

Oh dear, you used the object-oriented shibboleth and now I hate the
idea on principle ;-)

unique_ptr<T[]> doesn't store the size either, which is good as it
means sizeof(unique_ptr<T[]>) == sizeof(T*). When I've wanted to
store the size I've either wrapped the unique_ptr<T[]> (e.g.
pair<unique_ptr<T[]>, size_t>) or added the size to the deleter,
depending on where and when the size is needed.

With shared_ptr<T[]> that's even more convenient because the deleter
isn't part of the type.

struct wipeout
{
    size_t m_buflen;

    void operator()(char* buffer) const
    {
        std::memset(buffer, 0, m_buflen);
        delete [] buffer;
    }
};

typedef boost::shared_ptr<char[]> WipedBuf;

WipedBuf make_WipedBuf(size_t len)
{ return WipedBuf{ new char[len], wipeout{ len } }; }

The size can be retrieved from the deleter if needed:

size_t get_array_len(WipedBuf const& p)
{
    auto d = boost::get_deleter<wipeout>(p);
    return d ? d->m_buflen : 0;
}

So it's easy enough to add the size yourself if you want it.


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