Boost C++ 库

……在世界上最受推崇、设计最精湛的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ Coding Standards

类模板 variant - Boost C++ 函数库
PrevUpHomeNext

类模板 variant

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_visitorvariant 支持编译时检查、类型安全的访问;通过 getvariant 支持运行时检查、类型安全的值检索。

注意:

  • 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 公有构造/复制/析构

  1. variant();

    要求

    variant 的第一个有界类型(即 T1)必须满足 DefaultConstructible [20.1.4] 概念的要求。

    后置条件

    *this 的内容是第一个有界类型(即 T1)的默认值。

    抛出

    可能因 T1 的默认构造函数产生的任何异常而失败。
  2. variant(const variant & other);

    后置条件

    *this 的内容是 other 内容的副本。

    抛出

    可能因 other 所包含类型的复制构造函数产生的任何异常而失败。
  3. variant(variant && other);

    要求

    C++11 兼容编译器。

    后置条件

    *this 的内容是从 other 的内容移动构造而来的。

    抛出

    可能因 other 所包含类型的移动构造函数产生的任何异常而失败。
  4. template<typename T> variant(T & operand);

    要求

    T 必须能够无歧义地转换为其中一个有界类型(即 T1T2 等)。

    后置条件

    *this 的内容是 operand 到其中一个有界类型的最佳转换,由标准重载解析规则确定。

    抛出

    可能因 operand 到其中一个有界类型的转换产生的任何异常而失败。
  5. template<typename T> variant(const T & operand);

    注意

    与前一个构造函数语义相同,但允许从临时对象构造。
  6. template<typename T> variant(T && operand);

    要求

    C++11 兼容编译器。

    注意

    与前一个构造函数语义相同,但如果 operand 是右值,则允许移动构造。
  7. template<typename U1, typename U2, ..., typename UN> 
      variant(variant<U1, U2, ..., UN> & operand);

    要求

    U1U2、...、UN 每一个 都必须能够无歧义地转换为其中一个有界类型(即 T1T2、...、TN)。

    后置条件

    如果 variant<U1, U2, ..., UN> 本身是其中一个有界类型,则 *this 的内容是 operand 的副本。否则,*this 的内容是 operand 的内容到其中一个有界类型的最佳转换,由标准重载解析规则确定。

    抛出

    如果 variant<U1, U2, ..., UN> 本身是其中一个有界类型,则可能因 variant<U1, U2, ..., UN> 的复制构造函数而失败。否则,可能因 operand 的内容到其中一个有界类型的转换而失败。
  8. template<typename U1, typename U2, ..., typename UN> 
      variant(const variant<U1, U2, ..., UN> & operand);

    注意

    与前一个构造函数语义相同,但允许从临时对象构造。
  9. template<typename U1, typename U2, ..., typename UN> 
      variant(variant<U1, U2, ..., UN> && operand);

    要求

    C++11 兼容编译器。

    注意

    与前一个构造函数语义相同,但允许移动构造。
  10. ~variant();

    效果

    销毁 *this 的内容。

    抛出

    不会抛出异常。

variant 修改器

  1. void swap(variant & other);

    要求

    每个有界类型都必须满足 MoveAssignable 概念的要求。

    效果

    交换 *thisother 的内容。

    抛出

    如果 other 的包含类型与 *this 的包含类型相同,则可能因 *thisother 内容的 swap 而失败。否则,可能因任一包含类型的移动构造函数或复制构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。
  2. variant & operator=(const variant & rhs);

    要求

    每个有界类型都必须满足 Assignable 概念的要求。

    效果

    如果 rhs 的包含类型与 *this 的包含类型相同,则将 rhs 的内容赋给 *this 的内容。否则,将 rhs 的内容复制到 *this 的内容,销毁 *this 的先前内容。

    抛出

    如果 rhs 的包含类型与 *this 的包含类型相同,则可能因 rhs 的内容赋值给 *this 的内容而失败。否则,可能因 rhs 所包含类型的复制构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。
  3. variant & operator=(variant && rhs);

    要求

    • C++11 兼容编译器。
    • 每个有界类型都必须满足 MoveAssignable 概念的要求。

    效果

    如果 rhs 的包含类型与 *this 的包含类型相同,则将 rhs 的内容移动赋值给 *this 的内容。否则,使用 rhs 的内容移动构造 *this,销毁 *this 的先前内容。

    抛出

    如果 rhs 的包含类型与 *this 的包含类型相同,则可能因 rhs 的内容移动赋值给 *this 的内容而失败。否则,可能因 rhs 所包含类型的移动构造函数而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。
  4. template<typename T> variant & operator=(const T & rhs);

    要求

    • T 必须能够无歧义地转换为其中一个有界类型(即 T1T2 等)。
    • 每个有界类型都必须满足 Assignable 概念的要求。

    效果

    如果 *this 的包含类型是 T,则将 rhs 赋值给 *this 的内容。否则,将 rhs 的内容转换为 *this 的有界类型中的最佳类型,由标准重载解析规则确定,并销毁 *this 的先前内容。

    抛出

    如果 *this 的包含类型是 T,则可能因 rhs 赋值给 *this 的内容而失败。否则,可能因 rhs 到其中一个有界类型的转换而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。
  5. template<typename T> variant & operator=(T && rhs);

    要求

    • C++11 兼容编译器。
    • rhs 是右值。否则将使用之前的运算符。
    • T 必须能够无歧义地转换为其中一个有界类型(即 T1T2 等)。
    • 每个有界类型都必须满足 MoveAssignable 概念的要求。

    效果

    如果 *this 的包含类型是 T,则将 rhs 移动赋值给 *this 的内容。否则,将 rhs 的内容转换为 *this 的有界类型中的最佳类型,由标准重载解析规则确定,并销毁 *this 的先前内容(转换通常通过移动构造完成)。

    抛出

    如果 *this 的包含类型是 T,则可能因 rhs 移动赋值给 *this 的内容而失败。否则,可能因 rhs 到其中一个有界类型的转换而失败。此外,在内存不足的情况下,可能因 std::bad_alloc 而失败(原因?)。

variant 查询

  1. int which() const;

    返回

    *this 所包含类型的有界类型集合的零基索引。(例如,如果在一个包含 std::stringvariant<int, std::string> 对象上调用,which() 将返回 1。)

    抛出

    不会抛出异常。
  2. bool empty() const;

    返回

    falsevariant 始终包含其有界类型中的一个。(有关更多信息,请参阅 ““永不为空”保证”。)

    基本原理

    便于与 boost::any 进行通用兼容。

    抛出

    不会抛出异常。
  3. const std::type_info & type() const;

    注意

    boost::variant 使用 Boost.TypeIndex 库,因此实际上返回的是 const boost::typeindex::type_info &。即使 RTTI 关闭,此方法也可用。

    返回

    typeid(x),其中 x*this 的内容。

    抛出

    不会抛出异常。

variant 关系运算

  1. 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_rhsrhs 的内容。

    抛出

    如果 which() == rhs.which(),则可能因 operator==(T,T)(其中 T*this 的包含类型)而失败。
  2. 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 的包含类型)而失败。
  3. 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_rhsrhs 的内容。否则:which() < rhs.which()

    抛出

    如果 which() == rhs.which(),则可能因 operator<(T,T)(其中 T*this 的包含类型)而失败。
  4. 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 的包含类型)而失败。
  5. 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 的包含类型)而失败。
  6. 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 的包含类型)而失败。

PrevUpHomeNext