c++alignas

How to replace aligned_storage<T[]> with std::byte[]?


The use of aligned_storage is deprecated in C++23 and suggested to be replaced with an aligned std::byte[] (see here). I have two questions about this:

1. How to align this?

The document suggests to replace

std::aligned_storage_t<sizeof(T), alignof(T)> t_buff; with

alignas(T) std::byte t_buff[sizeof(T)].

However, I am actually storing an array of T (or T is an array of something). Can I simply replace std::aligned_storage_t<sizeof(T), alignof(T)> data_[SIZE]; with

alignas(alignof(T)*SIZE) std::byte data_[sizeof(T) * SIZE]; ?

I think this is a wrong usage of alignas or not?

2. How to read/write?

I think access has not changed much, so is it correct to read with:

reference data(size_t index) noexcept {
    return *std::launder(reinterpret_cast<T*>(&data_[index*sizeof(T)]));
}

and write with

new (reinterpret_cast<void*>(&data_[size_*sizeof(T)])) T{std::forward<Args>(args)...}; ?

Why am I asking?

My use of alignas seems really wrong, how should I align it? Can I really just multiply access index with sizeof(T), or do I need take padding into account? How?

Also, the code somehow seems worse than before because I have to insert sizeof() everywhere.

It seems to work when I run it but I am not sure whether this is really save.

I looked at other examples (e.g. here, here and others) but they always have T instead of T[] as an example.


Solution

  • You do not need to do anything different. Per [expr.alignof]/3 the alignement of T[N] is the alignment of T so you can just use

    alignas(T) std::byte data_[sizeof(T) * SIZE];
    

    You could also just use the alignment and size of the array iteself like

    alignas(T[SIZE]) std::byte t_buff[sizeof(T[SIZE])]