In the preceding section, we introduced std::allocator_traits<A>::construct(a, ptr, args...) and described it as a preferable alternative to the placement-new syntax ::new ((void*)ptr) T(args...). Now we'll see why the author of a particular allocator might want to give it different semantics.
One perhaps obvious way to change the semantics of construct for our own allocator type would be to make it trivially default-initialize primitive types instead of zero-initializing them. That code would look like this:
template<class T>
struct my_allocator : std::allocator<T>
{
my_allocator() = default;
template<class U>
my_allocator(const my_allocator<U>&) {}
template<class... Args>
void construct(T *p, Args&&... args) {
if (sizeof...(Args...