c++typesc++17allocator

If C++17 and above guarantee that allocators must support overaligned types, does that mean we can avoid creating manually-aligned types?


Given a custom vector and using std::allocator for allocating, under C++17 and above do we still need to create an internal overaligned type OT using alignas, then allocate for OT, and reinterpret_cast OT* to T* before dereferencing the pointer on iterator operator*, in order to support overalignment of the type?

Or will std::allocator align correctly, and dereferencing T* be perfectly functional for returning a correctly overaligned reference to an element?

Thanks for any clarifications.


Solution

  • Before C++17 it was implementation-defined whether std::allocator supports over-aligned types.

    With P0035 for C++17 this was changed and now all types need to be supported. Which alignments an implementation supports for types in general is still implementation-defined, but you wouldn't be able to define a type with an unsupported alignment in the first place.

    So, a std::vector<T> will correctly align its elements for type T even if it is over-aligned in C++17. I don't follow your explanation of the "old" way to achieve alignment, but before C++17 there was, absent the mentioned implementation-definedness, no way to get an over-aligned type into a std::vector with the standard Allocator. You had to write your own Allocator to support over-aligned types. You also always needed and still do need alignas to actually make your type T over-aligned.

    However, the Allocator requirements in general to do not require that all over-alignments are supported and unfortunately allow alignment to be silently ignored. Therefore, if you use a different allocator than std::allocator, you must individually verify that it supports the alignment of your over-aligned type.