1. #include <stdexcept>
    2. #include <typeinfo>
    3. // Implementation details, the user should not import this:
    4. namespace impl {
    5. template<int N, typename... Ts> // 模版声明
    6. struct storage_ops;
    7. template<typename X, typename... Ts>
    8. struct position;
    9. template<typename... Ts>
    10. struct type_info;
    11. template<int N, typename T, typename... Ts> // 模版实现 用于在指定位置对对象的析构 , 传 visitor 对对象进行访问
    12. struct storage_ops<N, T&, Ts...> {
    13. static void del(int n, void *data) {}
    14. template<typename visitor>
    15. static typename visitor::result_type apply(int n, void *data, visitor& v) {}
    16. };
    17. template<int N, typename T, typename... Ts>
    18. struct storage_ops<N, T, Ts...> {
    19. static void del(int n, void *data) {
    20. if(n == N) reinterpret_cast<T*>(data)->~T();
    21. else storage_ops<N + 1, Ts...>::del(n, data);
    22. }
    23. template<typename visitor>
    24. static typename visitor::result_type apply(int n, void *data, visitor& v) {
    25. if(n == N) return v(*reinterpret_cast<T*>(data));
    26. else return storage_ops<N + 1, Ts...>::apply(n, data, v);
    27. }
    28. };
    29. template<int N>
    30. struct storage_ops<N> {
    31. static void del(int n, void *data) {
    32. throw std::runtime_error(
    33. "Internal error: variant tag is invalid."
    34. );
    35. }
    36. template<typename visitor>
    37. static typename visitor::result_type apply(int n, void *data, visitor& v) {
    38. throw std::runtime_error(
    39. "Internal error: variant tag is invalid."
    40. );
    41. }
    42. };
    43. template<typename X> // 查找指定类型的位置
    44. struct position<X> {
    45. static const int pos = -1;
    46. };
    47. template<typename X, typename... Ts>
    48. struct position<X, X, Ts...> { // 两个一样的类型
    49. static const int pos = 0;
    50. };
    51. template<typename X, typename T, typename... Ts> // 如果 X 不在 Ts 中 就是 -1 ,否则就是 X 在Ts 的位置
    52. struct position<X, T, Ts...> { // 接着推导
    53. static const int pos = position<X, Ts...>::pos != -1 ? position<X, Ts...>::pos + 1 : -1;
    54. };
    55. template<typename T, typename... Ts>
    56. struct type_info<T&, Ts...> {
    57. static const bool no_reference_types = false; // 没有引用
    58. static const bool no_duplicates = position<T, Ts...>::pos == -1 && type_info<Ts...>::no_duplicates; // 没有重复类型 1 检查 T 在Ts的重复 2 递归检查Ts1 在Ts中的重复
    59. static const size_t size = type_info<Ts...>::size > sizeof(T&) ? type_info<Ts...>::size : sizeof(T&); // 取最大的类型
    60. };
    61. template<typename T, typename... Ts>
    62. struct type_info<T, Ts...> {
    63. static const bool no_reference_types = type_info<Ts...>::no_reference_types; //
    64. static const bool no_duplicates = position<T, Ts...>::pos == -1 && type_info<Ts...>::no_duplicates; //
    65. static const size_t size = type_info<Ts...>::size > sizeof(T) ? type_info<Ts...>::size : sizeof(T&); //
    66. };
    67. template<>
    68. struct type_info<> {
    69. static const bool no_reference_types = true;
    70. static const bool no_duplicates = true;
    71. static const size_t size = 0;
    72. };
    73. } // namespace impl
    74. // variant<int, bool, double, string> v(4);
    75. template<typename... Types> //通用变量 可以存储不同的类型
    76. class variant {
    77. static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in variant."); // 推导没有引用类型
    78. static_assert(impl::type_info<Types...>::no_duplicates, "variant type arguments contain duplicate types."); // 推导没有重复类型
    79. int tag;
    80. char storage[impl::type_info<Types...>::size]; // 最大类型存储支持
    81. variant() = delete;
    82. template<typename X>
    83. void init(const X& x) {
    84. tag = impl::position<X, Types...>::pos; // 指定类型在 模版中的位置
    85. new(storage) X(x); // 在指定地址构造 string 的长度是 std::string= 32
    86. }
    87. public:
    88. template<typename X> // 构造类型 X的变量
    89. variant(const X& v) {
    90. static_assert(
    91. impl::position<X, Types...>::pos != -1, // 指定类型不在模版类型中 报错
    92. "Type not in variant."
    93. );
    94. init(v);
    95. }
    96. ~variant() {
    97. impl::storage_ops<0, Types...>::del(tag, storage); // 第一个模版参数是0, 所以 storage_ops<N + 1, Ts...>::del(n, data) 展开
    98. }
    99. template<typename X>
    100. void operator=(const X& v) {
    101. static_assert(
    102. impl::position<X, Types...>::pos != -1,
    103. "Type not in variant."
    104. );
    105. this->~variant(); //析构后重新构造
    106. init(v);
    107. }
    108. template<typename X> //返回指定类型的对象
    109. X& get() {
    110. static_assert(
    111. impl::position<X, Types...>::pos != -1,
    112. "Type not in variant."
    113. );
    114. if(tag == impl::position<X, Types...>::pos) {
    115. return *reinterpret_cast<X*>(storage);
    116. } else {
    117. throw std::runtime_error(
    118. std::string("variant does not contain value of type ") + typeid(X).name()
    119. );
    120. }
    121. }
    122. template<typename X>
    123. const X& get() const {
    124. static_assert(
    125. impl::position<X, Types...>::pos != -1,
    126. "Type not in variant."
    127. );
    128. if(tag == impl::position<X, Types...>::pos) {
    129. return *reinterpret_cast<const X*>(storage);
    130. } else {
    131. throw std::runtime_error(
    132. std::string("variant does not contain value of type ") + typeid(X).name()
    133. );
    134. }
    135. }
    136. template<typename visitor> // visitor 通过 重载 类型,来对不同的类型选择不同的函数
    137. typename visitor::result_type visit(visitor& v) {
    138. return impl::storage_ops<0, Types...>::apply(tag, storage, v); // 从 0 开始 的递归 apply
    139. }
    140. int which() const {return tag;} //
    141. };
    142. template<typename Result>
    143. struct visitor {
    144. typedef Result result_type; // visitor 的返回类型
    145. };