Boost logo

Boost :

Subject: Re: [boost] [Container] Inner Smart Pointers
From: Phil Bouchard (phil_at_[hidden])
Date: 2016-02-19 21:48:43

On 2016-02-19 9:30 PM, Steven Watanabe wrote:
> On 02/19/2016 05:53 PM, Phil Bouchard wrote:
>> On 2016-02-18 11:53 PM, Phil Bouchard wrote:
>>> I have to admit MSVC 2015 got a clean STL...
>> Their STL is good but unfortunately they pass their pointer arguments by
>> value and not by reference so it makes it impossible to use smart
>> pointers for internal node pointers.
> I don't understand how pass-by-value would
> break smart pointers. I can see that it might
> be inefficient, but it shouldn't actually fail.

Because the only way to deallocate the content of a smart pointer is by
deallocating and resetting its pointer to 0, which modifies the pointer.

For example:

1) The allocator's deallocate function will call p.reset():

template <typename T, typename UserPool = system_pool<system_pool_tag,
sizeof(char)> >
     class block_allocator
         typedef T element_type;

         typedef element_type value_type;
         typedef size_t size_type;
         typedef ptrdiff_t difference_type;
         typedef block_ptr<element_type> pointer;
         typedef block_ptr<const element_type> const_pointer;
         typedef element_type & reference;
         typedef const element_type & const_reference;


         pointer allocate(size_type s, const void * = 0)
             return new block<value_type, UserPool>();

         void construct(pointer & p, const T & x)

         void destroy(pointer & p)

         void deallocate(pointer & p, size_type)

2) In MSVC 2015 the deallocate function is called by this one which has
a pointer passed by value:

template<class _Alloc>
        struct _Wrap_alloc
                : public _Alloc
        { // defines traits for allocators
        void deallocate(pointer _Ptr, size_type _Count)
                { // deallocate object at _Ptr, ignore size
                _Mybase::deallocate(_Ptr, _Count);

3) Which in turn is called by another one using a parameter passed by value:

template<class _Alloc_types>
        class _List_alloc
        { // base class for list to hold allocator
        void _Freeheadnode(_Nodeptr _Pnode)
                { // free head node using current allocator
                        _STD addressof(_Nextnode(_Pnode)));
                        _STD addressof(_Prevnode(_Pnode)));
                _Getal().deallocate(_Pnode, 1);

4) ...

The bottom line is resetting a copy of a smart pointer won't do
anything. This is why it needs to be passed by reference.


Boost list run by bdawes at, gregod at, cpdaniel at, john at