Allocator_traits :: construct () vs allocator_traits :: allocate ()

C ++ 11 provides the class std::allocator_traits as a standard way to use distributors. The static function std::allocator_traits::construct() takes a pointer to where the object should be built. The static function std::allocator_traits::allocate() , however, returns a value of allocator::pointer , which should behave like a pointer, but it is not necessarily one (in the general case, although std::allocator::pointer requires that the pointer )

How are you supposed to use static distribution and construction methods if, in general, they work with incompatible types? Can they be used only if the pointer type is actually converted to a regular regular pointer?

+10
source share
2 answers

There are two ways to do this, depending on what you have at the moment.

If you have an lvalue expression, say the value field in node, you can use std :: addressof like this:

 allocator_traits<allocator_type>::construct(alloc, std::addressof(ptr->value), ...); 

where ptr is allocator_type::pointer .

However, if you do not have a dereferencing field and want to convert allocator_type::pointer to T* , you need to do the trick first:

 template <class T> inline T* to_raw_pointer(T* p) noexcept { return p; } template <class Pointer> inline typename std::pointer_traits<Pointer>::element_type* to_raw_pointer(Pointer p) noexcept { return p != nullptr ? ::to_raw_pointer(p.operator->()) : nullptr; } 

And now you can say:

 allocator_traits<allocator_type>::construct(alloc, to_raw_pointer(ptr), ...); 
+7
source

Starting with C ++ 20, there is std::to_address proposed in P0653 .

+2
source

Source: https://habr.com/ru/post/950289/


All Articles