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

Boost.Tuple

在标准C++中有Pairs(类模板 std::pair), 但它不支持n-tuples。用Tuple.不象用structs 或 classes 来定义n-tuples, 这个类模板支持直接声明和使用,如函数返回类型或参数,并提供一个泛型的方法来访问tuple的元素。Tuple已经被即将发布的Library Technical Report所接受。

Tuple 库如何改进你的程序?
  • 从函数返回多个返回值
  • 相关类型的组合
  • 将数值组合起来

与许多其它的编程语言一样,C++允许函数返回一个数值。但是,这一个数值可以是任意的类型,你可以用一个 struct 或 class 把多个数值组合起来作为结果。虽然可以,但是用这样的结构来组合相关的返回值通常都是很不方便的,因为这意味着要为对一种返回类型进行定义。为了避免在返回值中拷贝大量的对象,同时也为了避免创建一个特殊的类型用于从函数返回多个数值,我们常常使用非 const 引用参数或者指针参数,从而允许函数通过这些参数设置调用者的变量。在多数情况下这样做都工作良好,但也有人不愿意使用输出参数。还有,输出参数不能明确指出返回值就是返回值。有些时候,std::pair 可以满足要求,但在需要返回两个以上数值时,它就不能满足要求了。

为了提供多个返回值,我们需要一个 tuple 结构。一个 tuple 是一个固定大小的、多个指定类型的数值的聚集。相应的例子包括有:pairs, triples, quadruples, 等等。有些语言本身就内建有这样的 tuple 类型,但C++没有。借助C++本身的强大功能,这一缺点可以通过库来弥补,如你所想, Boost.Tuple 正是这样的一个库。

Tuple 库提供了 tuple 结构,它可以方便地用于返回多个数值,也可以组合任意的类型并以泛型代码来操作它们。

Tuple 库如何适用于标准库?

标准库提供了一个 tuple 的特例,一个 2-tuple, 名为 std::pair. 这个结构被用于标准库的容器,你可能在操作 std::map 的元素时已经留意到了。你也可以在容器类中存储 pair。当然,std::pair 不仅是为了给容器类使用的,它还有它自己的用途,它附带有一个方便的函数 std::make_pair, 可以自动地进行类型推断,还有一组操作符用于 pair 的比较。一个 tuple 的通常解决方案,而不仅仅是 2-tuples,会更加有用。Tuple 库所提供的还不是完全通用的,它最多可以允许10个元素的 tuple (如果需要更多的,看起来不常见但也不是没有可能的,这个限制可以放松)。还有,这些 tuples 的效率与使用 struct 的手工解决方案同样高!


Tuple

头文件: "boost/tuple/tuple.hpp"

它包含了 tuple 类模板及库的核心部分。

Header: "boost/tuple/tuple_io.hpp"
包含了对 tuple 的输入输出操作符。

Header: "boost/tuple/tuple_comparison.hpp"
包含了 tuple 的关系操作符。

Tuple 库位于 boost 里的嵌套名字空间 boost::tuples 中。要使用 tuples, 需要包含 "boost/tuple/tuple.hpp", 它包含了核心库。要进行输入输出操作,就包含 "boost/tuple/tuple_io.hpp", 要支持 tuple 的比较,就包含 "boost/tuple/tuple_comparison.hpp". 有些 Boost 库提供一个包含了所有相关库的头文件以方便使用;但 Boost.Tuple 没有。原因是把库分到各个不同的头文件中可以减少编译时间;如果你不使用关系操作符,你就无须为此付出时间和依赖性的代价。为了方便使用,Tuple 库中有些名字位于名字空间 boost:如 tuple, make_tuple, tie, 和 get. 以下是 Boost.Tuple 的部分摘要,列出并简要讨论了最主要的一些函数。

namespace boost {

  template <class T1,class T2,...,class TM> class tuple {
  public:
    tuple();
 
    template <class P1,class P2...,class PM> 
      tuple(class P1,class P2,...,PN); 
    
    template <class U1,class U2,...,class UN>
    tuple(const tuple<U1,U2,...,UN>&);
    
    tuple& operator=(const tuple&);
  };

  template<class T1,class T2,...,class TN> tuple<V1,V2,...,VN> 
    make_tuple(const T1& t1,const T2& t2,...,const TN& tn);

  template<class T1,class T2,...,class TN> tuple<T1&,T2&,...,TN> 
    tie(T1& t1,T2& t2,...,TN& tn);

  template <int I,class T1,class T2,...,class TN> 
    RI get(tuple<T1,T2,...,TN>& t);

  template <int I,class T1,class T2,...,class TN> 
    PI get(const tuple<T1,T2,...,TN>& t);

  template <class T1,class T2,...,class TM,
           class U1,class U2,...,class UM>
    bool operator==(const tuple<T1,T2,...,TM>& t,
                    const tuple<U1,U2,...,UM>& u);

  template <class T1,class T2,...,class TM,
           class U1,class U2,...,class UM>
    bool operator!=(const tuple<T1,T2,...,TM>& t,
                   const tuple<U1,U2,...,UM>& u);

  template <class T1,class T2,...,class TN,
           class U1,class U2,...,class UN>
    bool operator<(const tuple<T1,T2,...,TN>&, 
                  const tuple<U1,U2,...,UN>&);
}


成员函数

  1. tuple();
tuple 的缺省构造函数初始化所有元素,这意味着这些元素必须是可以缺省构造的,它们必须有一个公有的缺省构造函数。任何从这些所含元素的构造函数抛出的异常都会被传播。
  1. template <class P1,class P2...,class PM>
  2.   tuple(class P1,class P2,...,PN);
这个构造函数接受一些参数,用于初始化 tuple 相应元素。对于一些带有非缺省构造类型的 tuple ,就需要用这种构造方式;不能缺省构造一个 tuple 而不构造它的所有元素。例如,引用类型的元素必须在构造时初始化。注意,参数的数量不必与 tuple 类型中的元素数量一致。可以仅给出部分元素的值,而让剩余元素初始化为缺省值。任何从元素的构造函数抛出的异常都会被传播。
  1. template <class U1,class U2,...,class UN>
  2.   tuple(const tuple<U1,U2,...,UN>&);
这个构造函数用来自另一个 tuple 的元素来进行初始化,要求被构造的 tuple (T1, T2,…,TM) 的每一个元素都必须可以从 (U1,U2,…,UN) 构造。任何从元素的构造函数抛出的异常都会被传播。
  1. TIndex & get<int Index>();
  2. const TIndex & get<int Index>() const;
返回位于给定的 Index 处的元素的引用。Index 必须是一个常量整型表达式;如果索引大于或等于 tuple 中的元素数量,将产生一个编译期错误。结果的类型通过相应的模板参数 TIndex 给出。
  1. tuple& operator=(const tuple& other);
tuple 的赋值要求两个 tuples 具有相同的长度和元素类型。*this 中的每一个元素被赋值为 other 的对应元素。元素赋值中的任何异常都会被传播。

普通函数
  1. template<class T1,class T2,...,class TN> tuple<V1,V2,...,VN>
  2.   make_tuple(const T1& t1,const T2& t2,...,const TN& tn);
函数模板 make_tuple 是 tuple 版本的 std::make_pair. 它使用函数模板参数推断来决定一个包含这些参数的 tuple 的元素类型。创建这个 tuple 的元素类型时不使用这些参数的高级 cv-限定符。要控制对引用类型的类型推断,可以使用 Boost.Ref 的工具 ref 和 cref 来包装这些参数,从而影响返回的 tuple 结果类型。(稍后我们将看到关于 ref 和 cref 的更多内容)
  1. template<class T1,class T2,...,class TN> tuple<T1&,T2&,...,TN>
  2.   tie(T1& t1,T2& t2,...,TN& tn);
函数模板 tie 类似于 make_tuple. 调用 tie(t1,t2,...,tn) 等同于调用 make_tuple(ref(t1),ref(t2)... ref(tn)),即它创建一个由函数参数的引用组成的 tuple 。实际结果是把一个 tuple 赋值为由 tie 创建的对象,拷贝源 tuple 的元素到 tie 的参数。这样,tie 可以很容易地从一个由函数返回的 tuple 拷贝值到一个已有变量中。你也可以让 tie 从一个 std::pair 创建一个 2-tuple 。
  1. template <int I,class T1,class T2,...,class TN>
  2.   RI get(tuple<T1,T2,...,TN>& t);
这个函数 get 的重载版本用于取出 tuple t 的一个元素。索引 I 必须位于范围 [0..N), N 为 tuple 中的元素数量。如果 TI 是一个引用类型,则RI 为 TI; 否则, RI 为 TI&.
  1. template <int I,class T1,class T2,...,class TN>
  2.   RI get(const tuple<T1,T2,...,TN>& t);
这个函数 get 用于取出 tuple t 的一个元素。索引 I 必须位于范围 [0..N), N 为 tuple
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值