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 >
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 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();
}
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