C++Primer_Chap17_标准库特殊设施_List01_tuple类型_笔记

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

  当我们希望将一些数据组合成单一对象,但又不想麻烦地定义一个新数据结构来表示这些数据时,tuple是非常有用的:

#include <tuple>
tuple支持的操作
tuple<T1, T2, ..., Tn> t;t是一个tuple,成员数为n,第i个成员的类型是Ti。所有成员都进行值初始化
tuple<T1, T2, ..., Tn> t(v1, v2, ..., vn);使用初始值vi进行初始化。此构造函数是explicit的(只能直接初始化
make_tuple(v1, v2, ..., vn)返回一个用给定初始值初始化的tuple。tuple的类型从初始值的类型推断

t1 == t2

t1 != t2

当两个tuple具有相同数量的成员且成员对应相等时,两个tuple相等。一旦发现某对成员不等,接下来成员不再比较
t1 relop t2tuple的关系运算使用字典序。两个tuple必须具有相同数量的成员。使用<运算符比较成员
get<i>(t)

返回t的第i个数据成员的引用:如果t是一个左值,返回左值引用;否则返回右值引用。

tuple的所有成员都是public的

tuple_size<tupleType>::value一个类模板,可以通过一个tuple类型来初始化。它有一个名为value的public constexpr static数据成员,类型为size_t,表示给定tuple类型中的成员数目
tuple_element<i, tupleType>::type一个类模板,可以通过一个整型常量和一个tuple类型来初始化。它有一个名为type的public成员,表示给定tuple类型中知道成员的类型

定义和初始化tuple

    由于构造函数是explicit的,所以定义时不能拷贝构造。

#include <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});

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

auto item = make_tuple{"0-999-78345-X", 3, 20.00};
decltype(item) = tuple<const char*, int ,double>

auto book = get<0>(item);
auto cnt = get<1>(item);
auto price = get<2>(item) / cnt;
get<2>(item) *= 0.8;

typedef decltype(item) trans;
size_t sz = tuple_size<trans>::value;
tuple_element<1, trans>::type cnt = get<1>(item);

  tuple的关系和相等运算符的行为类似容器的对应操作。这些运算符逐对比较成员。为了支持关系和相等比较,每对元素使用运算符必须是合法的。

使用tuple返回多个值

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

typedef tuple< vector<Sales_data>::size_type,
                vector<Sales_data>::const_iterator,
                vector<Sales_data>::const_iterator> matcher;

vector<matcher>
findBook( const vector<vector<Sales_data>> &files,
            const string &book)
{
    vector<matches> ret;
    for(auto it = files.cbegin(); it != files.cend(); ++it)
    {
        auto found = equal_range(it->cbegin(), it->cend(),
                                    book, compareIsbn);
        if( found.first != found.second)
            ret.push_back(make_tuple(it - files.cbegin(),
                                        found.first, found.second));
    }
    return ret;
}

void reportResults(istream &in, ostream &os, 
                    const vector<vector<Sales_data>> &files)
{
    string s;
    while( in >> s)
    {
        auto trans = findBook(files, s);
        if( trans.empty())
        {
            cout << s << " not found in any stores" << endl;
            continue;
        }
        for(const auto &store : trans)
            os << "store" << get<0>(store) << " sales:"
                << accumulate(get<1>(store), get<2>(store), Sales_data(s));
                << endl;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值