简体   繁体   English

可变模板化的结构/如何实现boost :: variant

[英]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. 您的variant_obj具有字符串,整数和双variant_obj类型的变量。

I know this is similar to boost::variant . 我知道这类似于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. 特别是我在问我如何定义一个struct ,该struct具有所有给定类型的变量和一个成员变量,该变量表示当前哪个是重要的。

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. 如果不需要constexpr -ness,则可以存储std::aligned_union_t<0, Ts...>作为存储,并使用new放置,这更简单。

C++11 provided a template type, std::aligned_union , which takes a list of types. C ++ 11提供了一个模板类型std::aligned_union ,它接受类型列表。 aligned_union::type is a type which has sufficient storage space and alignment to be the storage for any of those given types. aligned_union::type是一种类型,具有足够的存储空间和对齐方式,可以作为任何给定类型的存储。

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 . 在storage提供的storage ,可以使用new放置将各个元素分配给特定类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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