【问题标题】:Variadically templated struct / How boost::variant is implemented可变模板结构 / boost::variant 是如何实现的
【发布时间】:2016-03-24 23:29:48
【问题描述】:

是否可以实现如下效果

DifferentTypesInOne<string, int, double> variant_obj;

variant_obj 的变量类型为 string、int 和 double。

我知道这类似于boost::variant。而且我之前搜索过有关它的问题,但我无法偶然发现可以解释该类如何使用可变参数模板来存储所有类型的元素的解释。特别是我在问如何定义一个struct,它具有所有给定类型的变量和一个表示当前重要的成员变量。

谢谢!

【问题讨论】:

  • 对于一个变体,要么使用联合递归,要么你有一块存储空间并使用新的放置。
  • 我只是很难理解如何在结构内的可变参数模板列表中包含许多类型的元素
  • 这个评论有意义吗?

标签: c++ templates c++11 boost c++14


【解决方案1】:

大概,

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;
};

这是草图;详情thesearticles 是一本好书。

如果不需要constexpr-ness,可以存储一个std::aligned_union_t&lt;0, Ts...&gt;作为存储,使用placement new,比较简单。

【讨论】:

  • 哇,这太棒了。你能解释一下这里到底发生了什么吗?
  • @Curious:它是递归,模板元编程(和一般编程)的基本工具。
  • 等等这不是递归。这是编译时递归,不是真正的递归吗?
  • @Curious 这里的“真实”是什么?
  • @Orient Stack over stack?
【解决方案2】:

C++11 提供了一个模板类型std::aligned_union,它接受一个类型列表。 aligned_union::type 是一种具有足够存储空间和对齐方式的类型,可以作为任何给定类型的存储空间。

这就是您为数据创建存储的方式。除此之外,您需要的只是一个整数,它告诉您存储了哪个值。

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

您使用放置new 将各个元素分配给特定类型,在storage 提供的存储空间内。

【讨论】:

  • 如何将类型与索引匹配?
  • 等等,你将如何将类型与索引匹配?
猜你喜欢
  • 2012-11-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 2011-04-06
  • 2022-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多