|
Boost : |
Subject: Re: [boost] [Container] Inner Smart Pointers
From: Phil Bouchard (phil_at_[hidden])
Date: 2016-02-20 09:58:20
On 2016-02-20 1:11 AM, Steven Watanabe wrote:
> AMDG
>
> On 02/19/2016 07:48 PM, Phil Bouchard wrote:
>> 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():
>>
>> <snip>
>> 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);
>> }
>>
>
> That isn't specific to MSVC:
> [allocator.requirements]:
>
> Table 27: "p a value of type XX::pointer,
> obtained by calling a1.allocate, where a1 == a
>
> Table 28: "a.deallocate(p,n)"
>
> p is not required to be an lvalue, here.
>
> [allocator.members]: "void deallocate(pointer p, size_type n);"
>
> (C++11)
>
>>
>> 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
>> public:
>> [...]
>> void _Freeheadnode(_Nodeptr _Pnode)
>> { // free head node using current allocator
>> _Getal().destroy(
>> _STD addressof(_Nextnode(_Pnode)));
>> _Getal().destroy(
>> _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.
>>
>
> You can't deallocate anything, anyway, because there
> may be other copies of the pointer. The whole point
> of using smart pointers in the first place, is that
> the deallocate is run automatically. Just leave allocator.deallocate
> as a no-op and let the memory be freed when the pointer
> is destroyed or assigned.
I think you're right, thanks for the hint!
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk