在标准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>&);
}
成员函数
- 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>&);
- TIndex & get<int Index>();
- const TIndex & get<int Index>() const;
- tuple& operator=(const tuple& other);
普通函数
- 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>
- RI get(const tuple<T1,T2,...,TN>& t);