c++c++17memory-alignmentplacement-new

C++ Declare Aligned Storage for Placement-New


I've created some templates in order to create aligned-storage capable of being used for placement-new:

template<typename T, typename... U>
constexpr size_t max_alignof()
{
    if constexpr (sizeof...(U))
        return std::max(alignof(T), max_alignof<U...>());
    else
        return alignof(T);
}

template<typename T, typename... U>
constexpr size_t max_sizeof()
{
    if constexpr (sizeof...(U))
        return std::max(sizeof(T), max_sizeof<U...>());
    else
        return sizeof(T);
}

// This isn't allowed by the standard, but illustrates my goal
template <typename... T>
using aligned_buffer_t = alignas(max_alignof<T...>()) char[max_sizeof<T...>()];

// Types A, B are classes that I want to placement-new
aligned_buffer_t<A, B> buffer;
A* = new (&buffer[0]) A();
A->~A();
B* = new (&buffer[0]) B();
B->~B();

How can I accomplish the above, without having to re-type the template parameters to aligned_buffer_t? The best solution I could come up with to accomplish this was the following macro:

#define ALIGNED_BUFFER_T(VAR, ...)\
    alignas(max_alignof<__VA_ARGS__>()) char VAR[max_sizeof<__VA_ARGS__>()]
ALIGNED_BUFFER_T(buffer, A, B);

Is the above possible without using macros, and without using the deprecated std::aligned_storage? The reason I am interested is because one of the class lists is auto-generated, so the code I tried to write was:

aligned_buffer_t<
#include "GeneratedClassList.hpp"
> buffer;

I couldn't figure out any syntax using macros that would enable such a construct.


Solution

  • As pointed out by ALX23z, my proposed approach was just a roundabout way of reimplementing std::variant. The solution therefore is simply to change the code to:

    std::variant<std::monostate, A, B> buffer;
    A *a = &buffer.emplace<A>();
    // Do stuff with a
    B *b = &buffer.emplace<B>();
    // Do stuff with b