C++11新特性——容器相关(三)tuple

来源:互联网 发布:node forever 重启 编辑:程序博客网 时间:2024/05/16 05:36

         tuple是类似pair的模板。每个pair的成员类型都不相同,但每个pair都恰好有两个成员。不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的,但一个tuple类型的成员数目可以与另一个tuple类型不同。

        当我们希望将一些数据组合成单一对象,但又不想麻烦地定义一个新数据结构来表示些数据时,tuple是非常有用的。下面列出了tuple支持的操作。tuple类型及其相关类型和函数都定义在tuple头文件中。

        tuple<T1, T2, …, Tn> t; t是一个tuple,成员数为n,第i个成员的类型为Ti。所有成员都进行值初始化。

        tuple<T1, T2, …, Tn> t(vl, V2, …, Vn)  t是一个tuple,成员类型为Tl..Tn,每个成员用对应的初始值vi进行初始化。此构造函数是explicit的。

        make_tuple (v1, v2, …, vn)返回一个用给定初始值初始化的tupletuple的类型从初始值的类型推断。

        t1 == t2 t1 != t2   当两个tuple具有相同数量的成员且成员对应相等时,两个tuple相等。这两个操作使用成员的==运算符来完成。一旦发现某对成员不等,接下来的成员就不用比较了。

        t1 relop t2 tuple的关系运算使用字典序两个tuple必须具有相同数量的成员。使用<运算符比较t1的成员和t2中的对应成员

        get<i>(t)  返回t的第i个数据成员的引用:如果七是一个左值,结果是一个左值引用:否则,结果是一个右值引用。tuple的所有成员都是public的。

        tuple_size<tupleType>::value 一个类模板,可以通过一个tuple类型来初始化。它有一个名为valuepublicconstexpr static数据成员,类型为size_t,表示给定tuple类型中成员的数量。

        tuple_element<i, tupleType>::type 一个类模板,可以通过一个整型常量和一个tuple类型   来初始化。它有一个名为typepublic成员,表示给定tuple类型中指定成员的类型。

 

        当我们定义一个tuple时,需要指出每个成员的类型:

            tuple<size_t, size_t, size_t> threeD; //三个成员都设置为0

            tuple<string, vector<double>, int, list<int>> someVal("constants", {3.14, 2.718}, 42, { 0,1,2,3,4,5});

        当我们创建一个tuple对象时,可以使用tuple的默认构造函数,它会对每个成员进行值初始化;也可以像本例中初始化someVal -样,为每个成员提供一个初始值。tuple的这个构造函数是explicit的,因此我们必须使用直接初始化语法:

        tuple<size_t, size_t, size_t> threeD = {1, 2, 3}; //错误

        tuple<size_t, size_t, size_t> threeD{1, 2, 3}; //正确

        类似make_pair函数,标准库定义了make_tuple函数,我们可以用它来生成tuple对象:

        //表示书店交易记录的tuple,包含:ISBN、数量和每册书的价格

        auto item = make_tuple(¨0-999-78345-X¨, 3, 20. 00);

        类似make_pairmake_tuple函数使用初始值的类型来推断tuple的类型。在本例中,item是一个tuple,类型为tuple<const char*, int, double>

         一个pair总是有两个成员,标准库就可以为它们命名(如,firstsecond)。但这种命名方式对tuple是不可能的,因为一个tuple类型的成员数目是没有限制的。因此,tuple的成员都是未命名的。要访问一个tuple的成员,就要使用一个名为get的标准库函数模板。为了使用get,我们必须指定一个显式模板实参,它指出我们想要访问第几个成员。我们传递给get一个tuple对象,它返回指定成员的引用:

        auto book = get<0>(item); //返回item的第一个成员

        auto cnt = get<1>(item); //返回item的第二个成员

        auto price = get<2> (item); //返回item的最后一个成员

        get<2>(item) *= 0.8;  //打折20%

        尖括号中的值必须是一个整型常量表达式,从0开始。

        如果不知道一个tuple准确的类型细节信息,可以用两个辅助类模板来查询tuple成员的数量和类型:

        typedefdecltype(item) trans; // transitem的类型

        // 返回trans类型对象中成员的数量

        size_t sz = tuple_size<trans>::value; //返回3

        // cnt的类型与item中第二个成员相同

        tuple_element(1,trans>::type cnt = get<1>(item);  // cnt是一个int

        为了使用tuple_sizetuple_element,我们需要知道一个tuple对象的类型。与往常一样,确定一个对象的类型的最简单方法就是使用decltype。在本例中,我们使用decltype来为item类型定义一个类型别名,用它来实例化两个模板。tuple_size有一个名为valuepublicstatic数据成员,它表示给定tuple中成员的数量。tuple_element模板除了一个tuple类型外,还接受一个索引值。它有一个名为typepublic类型成员,表示给定tuple类型中指定成员的类型。类似gettuple_element所使用的索引也是从0开始计数的。

 

关系和相等运算符

        tuple的关系和相等运算符的行为类似容器的对应操作。这些运算符逐对比较左侧tuple和右侧tuple的成员。只有两个tuple具有相同数量的成员时,我们才可以比较它们。而且,为了使用tuple的相等或不等运算符,对每对成员使用==运算符必须都是合法的;为了使用关系运算符,对每对成员使用<必须都是合法的。

        由于tuple定义了<==运算符,我们可以将tuple序列传递给算法,并且可以在无序容器中将tuple作为关键字类型。

         tuple的一个常见用途是从一个函数返回多个值。

0 0
原创粉丝点击