Nicolas Holthaus Nicolas Holthaus - 2 months ago 38
C++ Question

Why are are std::allocator's construct and destroy functions deprecated in c++17?

The c++17 specification deprecates the

construct
and
destroy
members of the
std::allocator
object. The working group provided rationale for deprecating other member functions here, under the heading "Deprecate the redundant members of std::allocator".

However they don't mention specifically why those two members are deprecated or what the recommendation is for replacing that functionality. I'm assuming the implication is to use
std::allocator_traits::construct
instead.

I'm a bit confused about whether implementing
construct
may actually still be necessary in some cases though because of this comment about
std::allocator_traits::construct



Because this function provides the automatic fall back to placement new, the member function construct() is an optional Allocator requirement since C++11.


For custom allocators (e.g. for page-aligned memory using
memalign
), will falling back to placement
new
always produce the correct behavior?

Answer

The mandated behavior of member construct is (between C++11 - C++17):

Effect: Constructs an object of type C at c

This means that the function is effectively required to invoke placement new with forwarded arguments at some point; the only permitted divergence in behavior for a user-supplied allocator is to perform some other action before and/or after, such as instrumentation; it is not permitted to alter the arguments to placement new in any way.

As such and since allocator_traits::construct performs the requisite placement new anyway, user code e.g. in containers is likely to just perform placement new directly, so the whole machinery of construct is redundant.

In a custom allocator (e.g. for page-aligned memory using memalign), falling back to placement new probably would not be the correct behavior.

In such an allocator the address c should already be aligned correctly, since it was obtained from the allocator. The allocator has no choice but to perform placement new.