We thought make_unique could do the work (?) Can it? |
Mostly.
When I wrote the above program, I forgot about C++17's support for over-aligned new:
make_unique can be coerced into working by
- over-aligning the type being constructed (i.e., by applying
alignas) and using C++17's alignment-aware
operator new; or
- writing class-specific overloads for
operator new/new[]/delete/delete[].
The first option is ideal, if it is acceptable.
For example:
1 2 3
|
// all objects of type A are (over-)aligned on a 32-byte boundary.
struct alignas(32) A { double x[4]; };
auto result = std::make_unique<A[]>(4);
|
result will be properly aligned, but only since C++17. This is because
make_unique evaluates a
new-expression which calls the alignment-aware allocation function
void* operator new( std::size_t count, std::align_val_t al). Before C++17, there is no such allocation function, and
new will not respect over-alignment.
Unlike adjusting a type's alignment requirement,
make_unique_aligned() offers the ability to control alignment on a per-object basis at run-time.
Further, the presence of alignment-aware operator new obviates the need for a special deleter.