Search code examples
c++templatesstd-variant

What does this variant storage use the buffer array for?


I see this piece of code for implementing a C++ std::variant-like type. This class is used as the variant storage.

What does the buffer array stores?

alignas(Types...) unsigned char buffer[sizeof(LargestT)];

I'm still learning, but for my understanding, maybe wrong, it stores the current largest type of the template pack list.

#include <new> // for std::launder()
template<typename... Types>
class VariantStorage {
    using LargestT = LargestType<Typelist<Types...>>;
    // What stores the following buffer array?
    alignas(Types...) unsigned char buffer[sizeof(LargestT)];
    unsigned char discriminator = 0;
public:
    unsigned char getDiscriminator() const {
        return discriminator;
    }
    void setDiscriminator(unsigned char d) {
        discriminator = d;
    }
    void* getRawBuffer() {
        return buffer;
    }
    const void* getRawBuffer() const {
        return buffer;
    }
    template<typename T>
    T* getBufferAs() {
        return std::launder(reinterpret_cast<T*>(buffer));
    }
    template<typename T>
    T const* getBufferAs() const {
        return std::launder(reinterpret_cast<T const*>(buffer));
    }
};

Can please anybody explain me what is the purpose of that line of code?


Solution

  • The idea is that the variant has a buffer that can potentially store an instance of any of the alternative types.

    To do that, the buffer must be as large as the largest of the types (in terms of size), and it also has to have an alignment that is compatible with all the types.

    The sizeof(Largest) and alignas(Types...) operators do precisely that.