|
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:
> AMDG
>
> 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;
public:
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)
{
p.reset();
}
};
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
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.
-Phil
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk