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);