0

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?

2
  • It doesn't store the current largest type because sizeof(LargestT) is worked out a compile time before anything has been stored in the variant. Instead it creates an array largest to store any type that the variant can hold. Commented Oct 5, 2024 at 6:43
  • 1
    it stores the current largest type of the template pack list No, it doesn't any type of the template pack list. It's an unsigned char array. That buffer is used as the backing storage of whichever type is currently being stored in the variant. (Which can be any of the types. I'm not sure what you mean by "current largest", there is only the current type, which has its own sizeof.) Commented Oct 5, 2024 at 12:29

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

With a variant<char, int, double>. Does the buffer stores one type at a time (the largest one, in this case double)? Or stores each type on it (like [char, int, double])?
One at a time, even if that wastes space circumstantially.
@user11611653 - You have tuple<char, int, double> that stores them all at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.