简体   繁体   中英

Variadically templated struct / How boost::variant is implemented

Is it possible to achieve an effect like the following

DifferentTypesInOne<string, int, double> variant_obj;

Where you variant_obj has variables of types string, int and double in it.

I know this is similar to boost::variant . And I searched up questions about it before but I was not able to stumble upon an explanation which could explain how the class uses variadic templates to store elements of all the types. In particular I am asking how I can go about defining a struct which has variables of all the given types and a member variable denoting which one is important currently.

Thanks!

Roughly,

template<class... Ts> 
struct variant_storage {};

template<class T, class... Ts>
struct variant_storage<T, Ts...>{
    union {
        T head;
        variant_storage<Ts...> tail;
    };
};

template<class... Ts>
struct variant {
    int index;
    variant_storage<Ts...> storage;
};

This is a sketch; for details these articles are a good read.

If you don't need constexpr -ness, you can store a std::aligned_union_t<0, Ts...> as storage, and use placement new, which is simpler.

C++11 provided a template type, std::aligned_union , which takes a list of types. aligned_union::type is a type which has sufficient storage space and alignment to be the storage for any of those given types.

So that's how you create the storage for the data. All you need beyond that is an integer that tells which value is stored there.

template<typename ...Types>
struct variant
{
private:
  uint8_t index;
  typename std::aligned_union<Types...>::type storage;
};

You use placement new to allocate the individual elements to a particular type, within the storage provided by storage .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM