boost::variant — 安全、通用、基于栈的区分联合体容器。
// In header: <boost/variant/variant.hpp> template<typename T1, typename T2 = unspecified, ..., typename TN = unspecified> class variant { public: // types typedef unspecified types; // construct/copy/destruct variant(); variant(const variant &); variant(variant &&); template<typename T> variant(T &); template<typename T> variant(const T &); template<typename T> variant(T &&); template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> &); template<typename U1, typename U2, ..., typename UN> variant(const variant<U1, U2, ..., UN> &); template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> &&); ~variant(); // modifiers void swap(variant &); variant & operator=(const variant &); variant & operator=(variant &&); template<typename T> variant & operator=(const T &); template<typename T> variant & operator=(T &&); // queries int which() const; bool empty() const; const std::type_info & type() const; // relational bool operator==(const variant &) const; template<typename U> void operator==(const U &) const; bool operator!=(const variant &) const; template<typename U> void operator!=(const U &) const; bool operator<(const variant &) const; template<typename U> void operator<(const U &) const; bool operator>(const variant &) const; template<typename U> void operator>(const U &) const; bool operator<=(const variant &) const; template<typename U> void operator<=(const U &) const; bool operator>=(const variant &) const; template<typename U> void operator>=(const U &) const; };
variant
类模板(灵感来自 Andrei Alexandrescu 同名类 [Ale01A])是一种高效、支持递归、有界区分联合体值类型,能够容纳任何值类型(POD 或非 POD)。它支持从任何可转换为其有界类型之一的类型进行构造,或者从一个源 variant
进行构造,该源 variant
的有界类型都可转换为目标 variant
的有界类型之一。此外,通过 apply_visitor
,variant
支持编译时检查、类型安全的访问;通过 get
,variant
支持运行时检查、类型安全的值检索。
注意:
variant
的有界类型通过嵌套的 typedef types
暴露,这是一个 MPL 兼容的 Sequence,包含任何访问 variant
的 访问器 必须处理的类型集合。variant
的所有成员至少满足异常安全性基本保证。也就是说,即使之前的操作失败,对 variant
的所有操作仍然是定义良好的。variant
的每种类型都必须满足 BoundedType 概念的要求。variant
的每种类型在去除限定符后必须是唯一的。因此,例如,variant<int, int>
和 variant<int, const int>
都具有未定义的行为。variant
的符合规范的实现必须允许至少十种类型的模板参数。允许的参数的确切数量通过预处理器宏 BOOST_VARIANT_LIMIT_TYPES
暴露。(请参阅 make_variant_over
,了解通过 MPL 或兼容 Sequence 的元素指定 variant
的有界类型的方法,从而克服此限制。)variant
公有构造/复制/析构variant();
要求 |
variant 的第一个有界类型(即 T1 )必须满足 DefaultConstructible [20.1.4] 概念的要求。 |
后置条件 |
*this 的内容是第一个有界类型(即 T1 )的默认值。 |
抛出 |
可能因 T1 的默认构造函数产生的任何异常而失败。 |
variant(const variant & other);
后置条件 |
*this 的内容是 other 内容的副本。 |
抛出 |
可能因 other 所包含类型的复制构造函数产生的任何异常而失败。 |
variant(variant && other);
要求 |
C++11 兼容编译器。 |
后置条件 |
*this 的内容是从 other 的内容移动构造而来的。 |
抛出 |
可能因 other 所包含类型的移动构造函数产生的任何异常而失败。 |
template<typename T> variant(T & operand);
要求 |
T 必须能够无歧义地转换为其中一个有界类型(即 T1 、T2 等)。 |
后置条件 |
*this 的内容是 operand 到其中一个有界类型的最佳转换,由标准重载解析规则确定。 |
抛出 |
可能因 operand 到其中一个有界类型的转换产生的任何异常而失败。 |
template<typename T> variant(const T & operand);
注意 |
与前一个构造函数语义相同,但允许从临时对象构造。 |
template<typename T> variant(T && operand);
要求 |
C++11 兼容编译器。 |
注意 |
与前一个构造函数语义相同,但如果 operand 是右值,则允许移动构造。 |
template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> & operand);
要求 |
U1 、U2 、...、UN 每一个 都必须能够无歧义地转换为其中一个有界类型(即 T1 、T2 、...、TN )。 |
后置条件 |
如果 variant<U1, U2, ..., UN> 本身是其中一个有界类型,则 *this 的内容是 operand 的副本。否则,*this 的内容是 operand 的内容到其中一个有界类型的最佳转换,由标准重载解析规则确定。 |
抛出 |
如果 variant<U1, U2, ..., UN> 本身是其中一个有界类型,则可能因 variant<U1, U2, ..., UN> 的复制构造函数而失败。否则,可能因 operand 的内容到其中一个有界类型的转换而失败。 |
template<typename U1, typename U2, ..., typename UN> variant(const variant<U1, U2, ..., UN> & operand);
注意 |
与前一个构造函数语义相同,但允许从临时对象构造。 |
template<typename U1, typename U2, ..., typename UN> variant(variant<U1, U2, ..., UN> && operand);
要求 |
C++11 兼容编译器。 |
注意 |
与前一个构造函数语义相同,但允许移动构造。 |
~variant();
效果 |
销毁 *this 的内容。 |
抛出 |
不会抛出异常。 |
variant
修改器void swap(variant & other);
要求 |
每个有界类型都必须满足 MoveAssignable 概念的要求。 |
效果 |
交换 *this 和 other 的内容。 |
抛出 |
如果 other 的包含类型与 *this 的包含类型相同,则可能因 *this 和 other 内容的 swap 而失败。否则,可能因任一包含类型的移动构造函数或复制构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。 |
variant & operator=(const variant & rhs);
要求 |
每个有界类型都必须满足 Assignable 概念的要求。 |
效果 |
如果 rhs 的包含类型与 *this 的包含类型相同,则将 rhs 的内容赋给 *this 的内容。否则,将 rhs 的内容复制到 *this 的内容,销毁 *this 的先前内容。 |
抛出 |
如果 rhs 的包含类型与 *this 的包含类型相同,则可能因 rhs 的内容赋值给 *this 的内容而失败。否则,可能因 rhs 所包含类型的复制构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。 |
variant & operator=(variant && rhs);
要求 |
|
效果 |
如果 rhs 的包含类型与 *this 的包含类型相同,则将 rhs 的内容移动赋值给 *this 的内容。否则,使用 rhs 的内容移动构造 *this ,销毁 *this 的先前内容。 |
抛出 |
如果 rhs 的包含类型与 *this 的包含类型相同,则可能因 rhs 的内容移动赋值给 *this 的内容而失败。否则,可能因 rhs 所包含类型的移动构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。 |
template<typename T> variant & operator=(const T & rhs);
要求 |
|
效果 |
如果 *this 的包含类型是 T ,则将 rhs 赋值给 *this 的内容。否则,将 rhs 的内容转换为 *this 的有界类型中的最佳类型,由标准重载解析规则确定,并销毁 *this 的先前内容。 |
抛出 |
如果 *this 的包含类型是 T ,则可能因 rhs 赋值给 *this 的内容而失败。否则,可能因 rhs 到其中一个有界类型的转换而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。 |
template<typename T> variant & operator=(T && rhs);
要求 |
|
效果 |
如果 *this 的包含类型是 T ,则将 rhs 移动赋值给 *this 的内容。否则,将 rhs 的内容转换为 *this 的有界类型中的最佳类型,由标准重载解析规则确定,并销毁 *this 的先前内容(转换通常通过移动构造完成)。 |
抛出 |
如果 *this 的包含类型是 T ,则可能因 rhs 移动赋值给 *this 的内容而失败。否则,可能因 rhs 到其中一个有界类型的转换而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。 |
variant
查询int which() const;
返回 |
*this 所包含类型的有界类型集合的零基索引。(例如,如果在一个包含 std::string 的 variant<int, std::string> 对象上调用,which() 将返回 1 。) |
抛出 |
不会抛出异常。 |
bool empty() const;
返回 |
false :variant 始终包含其有界类型中的一个。(有关更多信息,请参阅 ““永不为空”保证”。) |
基本原理 |
便于与 boost::any 进行通用兼容。 |
抛出 |
不会抛出异常。 |
const std::type_info & type() const;
注意 |
boost::variant 使用 Boost.TypeIndex 库,因此实际上返回的是 const boost::typeindex::type_info & 。即使 RTTI 关闭,此方法也可用。 |
返回 |
typeid(x) ,其中 x 是 *this 的内容。 |
抛出 |
不会抛出异常。 |
variant
关系运算bool operator==(const variant & rhs) const; template<typename U> void operator==(const U &) const;相等比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 EqualityComparable 概念的要求。 |
返回 |
如果 which() == rhs.which() 并且 content_this == content_rhs ,则返回 true ,其中 content_this 是 *this 的内容,content_rhs 是 rhs 的内容。 |
抛出 |
如果 which() == rhs.which() ,则可能因 operator==(T,T) (其中 T 是 *this 的包含类型)而失败。 |
bool operator!=(const variant & rhs) const; template<typename U> void operator!=(const U &) const;不等比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 EqualityComparable 概念的要求。 |
返回 |
如果 !(*this == rhs) ,则返回 true 。 |
抛出 |
如果 which() == rhs.which() ,则可能因 operator==(T,T) (其中 T 是 *this 的包含类型)而失败。 |
bool operator<(const variant & rhs) const; template<typename U> void operator<(const U &) const;小于比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 LessThanComparable 概念的要求。 |
返回 |
如果 which() == rhs.which() ,则:content_this < content_rhs ,其中 content_this 是 *this 的内容,content_rhs 是 rhs 的内容。否则:which() < rhs.which() 。 |
抛出 |
如果 which() == rhs.which() ,则可能因 operator<(T,T) (其中 T 是 *this 的包含类型)而失败。 |
bool operator>(const variant & rhs) const; template<typename U> void operator>(const U &) const;大于比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 LessThanComparable 概念的要求。 |
返回 |
如果 rhs < *this ,则返回 true 。 |
抛出 |
可能因 operator<(T,T) (其中 T 是 *this 的包含类型)而失败。 |
bool operator<=(const variant & rhs) const; template<typename U> void operator<=(const U &) const;小于或等于比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 LessThanComparable 概念的要求。 |
返回 |
如果 !(*this > rhs) ,则返回 true 。 |
抛出 |
可能因 operator<(T,T) (其中 T 是 *this 的包含类型)而失败。 |
bool operator>=(const variant & rhs) const; template<typename U> void operator>=(const U &) const;大于或等于比较。
注意 |
返回 void 的重载仅用于禁止将运算符的右侧隐式转换为 variant ;因此,使用它将(有意地)导致编译时错误。 |
要求 |
variant 的每个有界类型都必须满足 LessThanComparable 概念的要求。 |
返回 |
如果 !(*this < lhs) ,则返回 true 。 |
抛出 |
可能因 operator<(T,T) (其中 T 是 *this 的包含类型)而失败。 |