C++“准”标准库Boost学习指南(7):Boost.Variant

Boost.Variant提供了一种类型安全的方式在标准库容器中存储不同类型的数据,它弥补了C++标准库的不足。该库包含多个头文件,如"boost/variant.hpp",并支持variant对象的构造、拷贝、赋值等操作。通过`which()`和`get<>`函数,可以检查和获取存储的值。Boost.Variant使用基于栈的存储,保证了高效性,并且支持访问者模式,增加了灵活性和安全性。它是C++程序员的实用工具,与Boost.Any一起,是C++工具箱的重要组成部分。
摘要由CSDN通过智能技术生成
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 如何适用于标准库?

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


成员函数

  1. variant();
这个构造函数对 variant 的类型组中的第一个类型进行缺省构造。这意味着在声明 variant 类型时,第一个类型必须是可以被缺省构造的,或者 variant 类型本身不能被缺省构造。该构造函数传播任何从第一个类型的构造函数抛出的异常。
  1. variant(const variant& other);
这个复制构造函数复制 other 的当前值,并传播任何从 other 的当前类型的复制构造函数抛出的异常。
  1. template <typename T> variant(const T& operand);
这个构造函数从 operand 构造一个新的 variant 。operand 的类型 T, 必须可以转换为限定类型组中的某个类型。复制或转换 operand 时抛出的异常将被传播。
  1. template <typename U1,typename U2,...,typename UN>
  2.   variant(const variant<U1,U2,...,UN>& operand);
这个构造函数允许从另一个 variant 类型进行构造,后者的类型组为 U1, U2…UN, 它们必须可以转换为 T1,T2…TN (被构造的 variant 的类型组)。复制或转换 operand 时抛出的异常将被传播。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值