#include <stdexcept>#include <typeinfo>// Implementation details, the user should not import this:namespace impl {template<int N, typename... Ts> // 模版声明struct storage_ops;template<typename X, typename... Ts>struct position;template<typename... Ts>struct type_info;template<int N, typename T, typename... Ts> // 模版实现 用于在指定位置对对象的析构 , 传 visitor 对对象进行访问struct storage_ops<N, T&, Ts...> { static void del(int n, void *data) {} template<typename visitor> static typename visitor::result_type apply(int n, void *data, visitor& v) {}};template<int N, typename T, typename... Ts>struct storage_ops<N, T, Ts...> { static void del(int n, void *data) { if(n == N) reinterpret_cast<T*>(data)->~T(); else storage_ops<N + 1, Ts...>::del(n, data); } template<typename visitor> static typename visitor::result_type apply(int n, void *data, visitor& v) { if(n == N) return v(*reinterpret_cast<T*>(data)); else return storage_ops<N + 1, Ts...>::apply(n, data, v); }};template<int N>struct storage_ops<N> { static void del(int n, void *data) { throw std::runtime_error( "Internal error: variant tag is invalid." ); } template<typename visitor> static typename visitor::result_type apply(int n, void *data, visitor& v) { throw std::runtime_error( "Internal error: variant tag is invalid." ); }};template<typename X> // 查找指定类型的位置struct position<X> { static const int pos = -1;};template<typename X, typename... Ts> struct position<X, X, Ts...> { // 两个一样的类型 static const int pos = 0;};template<typename X, typename T, typename... Ts> // 如果 X 不在 Ts 中 就是 -1 ,否则就是 X 在Ts 的位置struct position<X, T, Ts...> { // 接着推导 static const int pos = position<X, Ts...>::pos != -1 ? position<X, Ts...>::pos + 1 : -1;};template<typename T, typename... Ts>struct type_info<T&, Ts...> { static const bool no_reference_types = false; // 没有引用 static const bool no_duplicates = position<T, Ts...>::pos == -1 && type_info<Ts...>::no_duplicates; // 没有重复类型 1 检查 T 在Ts的重复 2 递归检查Ts1 在Ts中的重复 static const size_t size = type_info<Ts...>::size > sizeof(T&) ? type_info<Ts...>::size : sizeof(T&); // 取最大的类型};template<typename T, typename... Ts>struct type_info<T, Ts...> { static const bool no_reference_types = type_info<Ts...>::no_reference_types; // static const bool no_duplicates = position<T, Ts...>::pos == -1 && type_info<Ts...>::no_duplicates; // static const size_t size = type_info<Ts...>::size > sizeof(T) ? type_info<Ts...>::size : sizeof(T&); // };template<>struct type_info<> { static const bool no_reference_types = true; static const bool no_duplicates = true; static const size_t size = 0;};} // namespace impl// variant<int, bool, double, string> v(4);template<typename... Types> //通用变量 可以存储不同的类型class variant { static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in variant."); // 推导没有引用类型 static_assert(impl::type_info<Types...>::no_duplicates, "variant type arguments contain duplicate types."); // 推导没有重复类型 int tag; char storage[impl::type_info<Types...>::size]; // 最大类型存储支持 variant() = delete; template<typename X> void init(const X& x) { tag = impl::position<X, Types...>::pos; // 指定类型在 模版中的位置 new(storage) X(x); // 在指定地址构造 string 的长度是 std::string= 32 }public: template<typename X> // 构造类型 X的变量 variant(const X& v) { static_assert( impl::position<X, Types...>::pos != -1, // 指定类型不在模版类型中 报错 "Type not in variant." ); init(v); } ~variant() { impl::storage_ops<0, Types...>::del(tag, storage); // 第一个模版参数是0, 所以 storage_ops<N + 1, Ts...>::del(n, data) 展开 } template<typename X> void operator=(const X& v) { static_assert( impl::position<X, Types...>::pos != -1, "Type not in variant." ); this->~variant(); //析构后重新构造 init(v); } template<typename X> //返回指定类型的对象 X& get() { static_assert( impl::position<X, Types...>::pos != -1, "Type not in variant." ); if(tag == impl::position<X, Types...>::pos) { return *reinterpret_cast<X*>(storage); } else { throw std::runtime_error( std::string("variant does not contain value of type ") + typeid(X).name() ); } } template<typename X> const X& get() const { static_assert( impl::position<X, Types...>::pos != -1, "Type not in variant." ); if(tag == impl::position<X, Types...>::pos) { return *reinterpret_cast<const X*>(storage); } else { throw std::runtime_error( std::string("variant does not contain value of type ") + typeid(X).name() ); } } template<typename visitor> // visitor 通过 重载 类型,来对不同的类型选择不同的函数 typename visitor::result_type visit(visitor& v) { return impl::storage_ops<0, Types...>::apply(tag, storage, v); // 从 0 开始 的递归 apply } int which() const {return tag;} // };template<typename Result>struct visitor { typedef Result result_type; // visitor 的返回类型 };