Boost.Variant
Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象。这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题。
Variant 库如何改进你的程序?
Variant 库关注的是对一组限定类型的类型安全存储及取回,即非无类的联合。Boost.Variant 库与 Boost.Any 有许多共同之外,但在功能上也有不同的考虑。在每天的编程中通常都会需要用到非无类的联合(不同的类型)。保持类型安全的一个典型方法是使用抽象基类,但这不总是可以做到的;即使可以做得,堆分配和虚拟函数的代价也可能太高。你也可以尝试用不安全的无类类型,如 void* (它会导致不幸),或者是类型安全得无限制的可变类型,如 Boost.Any. 这里我们将看到 Boost.Variant,它支持限定的可变类型,即元素来自于一组支持的类型。
许多其它的编程语言支持可变类型,它们也再次被证实是值得的。在C++内建的对可变类型的支持非常有限,只有某种形式的联合(union),而且主要是为了与C兼容而保留。Boost.Variant 通过一个类型模板 variant 补救了这种情形,并附随有安全的存储及取回值的工具。一个可变数据类型提供一个与当前值的类型无关的接口。如果你曾经用过别的可变类型,可能是仅能支持固定的一组类型。这个库不是这样的;你在使用 variant 时自己定义一组允许使用的类型,而一个程序中可以包含任意个不同的 variant 实例。为了取回保存在 variant 中的值,你要么知道当前值的真实类型,要么使用已提供的类型安全的访问者(visitor)机制。访问者机制使得 Variant 非常不同于其它可变类型的库,包括 Boost.Any (它可以持有任意类型的值),从而为处理这些类型提供了一个安全而健壮的环境。C++ 的联合只对内建类型以及 POD 类型有用,但这个库提供的非无类联合可以支持所有类型。最后,效率方面也被考虑到了,这个库基于栈存储来保存它的值,从而避免了昂贵的堆分配。
Variant 如何适用于标准库?
成员函数
这个构造函数对 variant 的类型组中的第一个类型进行缺省构造。这意味着在声明 variant 类型时,第一个类型必须是可以被缺省构造的,或者 variant 类型本身不能被缺省构造。该构造函数传播任何从第一个类型的构造函数抛出的异常。
这个复制构造函数复制 other 的当前值,并传播任何从 other 的当前类型的复制构造函数抛出的异常。
这个构造函数从 operand 构造一个新的 variant 。operand 的类型 T, 必须可以转换为限定类型组中的某个类型。复制或转换 operand 时抛出的异常将被传播。
这个构造函数允许从另一个 variant 类型进行构造,后者的类型组为 U1, U2…UN, 它们必须可以转换为 T1,T2…TN (被构造的 variant 的类型组)。复制或转换 operand 时抛出的异常将被传播。
Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象。这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题。
Variant 库如何改进你的程序?
- 对用户指定的多种类型的进行类型安全的存储和取回
- 在标准库容器中存储不同类型的方法
- 变量访问的编译期检查
- 高效的、基于栈的变量存储
Variant 库关注的是对一组限定类型的类型安全存储及取回,即非无类的联合。Boost.Variant 库与 Boost.Any 有许多共同之外,但在功能上也有不同的考虑。在每天的编程中通常都会需要用到非无类的联合(不同的类型)。保持类型安全的一个典型方法是使用抽象基类,但这不总是可以做到的;即使可以做得,堆分配和虚拟函数的代价也可能太高。你也可以尝试用不安全的无类类型,如 void* (它会导致不幸),或者是类型安全得无限制的可变类型,如 Boost.Any. 这里我们将看到 Boost.Variant,它支持限定的可变类型,即元素来自于一组支持的类型。
许多其它的编程语言支持可变类型,它们也再次被证实是值得的。在C++内建的对可变类型的支持非常有限,只有某种形式的联合(union),而且主要是为了与C兼容而保留。Boost.Variant 通过一个类型模板 variant 补救了这种情形,并附随有安全的存储及取回值的工具。一个可变数据类型提供一个与当前值的类型无关的接口。如果你曾经用过别的可变类型,可能是仅能支持固定的一组类型。这个库不是这样的;你在使用 variant 时自己定义一组允许使用的类型,而一个程序中可以包含任意个不同的 variant 实例。为了取回保存在 variant 中的值,你要么知道当前值的真实类型,要么使用已提供的类型安全的访问者(visitor)机制。访问者机制使得 Variant 非常不同于其它可变类型的库,包括 Boost.Any (它可以持有任意类型的值),从而为处理这些类型提供了一个安全而健壮的环境。C++ 的联合只对内建类型以及 POD 类型有用,但这个库提供的非无类联合可以支持所有类型。最后,效率方面也被考虑到了,这个库基于栈存储来保存它的值,从而避免了昂贵的堆分配。
Variant 如何适用于标准库?
Boost.Variant 允许在标准库容器中存储不同的类型。由于在C++或C++标准库中都没有对可变类型的真正支持,这使得 Variant 成为了标准库的一个杰出且有用的扩充。
Variant
头文件: "boost/variant.hpp"
通过单个头文件就包含了所有 Variant 库。
"boost/variant/variant_fwd.hpp"
包含了 variant 类模板的前向声明。
"boost/variant/variant.hpp"
包含了 variant 类模板的定义。
"boost/variant/apply_visitor.hpp"
包含了对 variant 应用访问者机制的功能。
"boost/variant/get.hpp"
包含了模板函数 get.
"boost/variant/bad_visit.hpp"
包含了异常类 bad_visit 的定义。
"boost/variant/static_visitor.hpp"
包含了 visitor 类模板的定义。
以下部分摘要包含了 variant 类模板中最重要的成员。其它功能,如访问者机制,类型安全的直接取回,还有更先进的特性,如通过类型列表创建类型组等等,在 用法部分 讨论。
namespace boost {
template <typename T1,typename T2=unspecified, ...,
typename TN=unspecified>
class variant {
public:
variant();
variant(const variant& other);
template <typename T> variant(const T& operand);
template <typename U1, typename U2, ..., typename UN>
variant(const variant<U1, U2, ..., UN>& operand);
~variant();
template <typename T> variant& operator=(const T& rhs);
int which() const;
bool empty() const;
const std::type_info& type() const;
bool operator==(const variant& rhs) const;
bool operator<(const variant& rhs) const;
};
}
成员函数
- variant();
- variant(const variant& other);
- template <typename T> variant(const T& operand);
- template <typename U1,typename U2,...,typename UN>
- variant(const variant<U1,U2,...,UN>& operand);