
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