C++ Primer 5th学习笔记16 标准库特殊设施

标准库特殊设施

1 tuple类型

  tuple是类似pair的模板,不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员

tuple支持的操作
操作 描述
tuple<T1, T2, ..., Tn> t; t是一个tuple,成员数为n,第i个成员的类型为Ti
tuple<T1, T2, ..., Tn> t(v1, v2, ..., vn); t是一个tuple,成员类型为T1...Tn,每个成员用对应的初始化vi进行初始化
make_tuple(v1,v2, ...,vn) 返回一个用给定初始值初始化的tuple。tuple的类型从初始值的类型推断
t1 == t2 当两个tuple具有相同数量的成员且成员对应相等时,两者相等
t1 != t2 只要有一个成员不等,就停止比较
t1 relop t2 tuple的关系运算使用字典序,两个tuple必须具有相同数量的成员。使用<运算符比较t1的成员和t2中的成员
get<i> (t) 返回t的第i个数据成员的引用,tuple的所有成员都是public
tuple_size<tupleType>::value 一个类模板,可以通过一个tuple类型来初始化。其有一个名为value的public constexpr static数据成员,类型为size_t,表示给定tuple类型中成员的数量
tuple_element<i, tupleType>::type 一个类模板,可以通过一个整型常量和一个tuple类型来初始化。其有一个名为type的public成员,表示给定tuple类型中指定成员的类型
1.1 定义和初始化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的这个构造函数是explicit的,因此必须使用直接初始化语法:

tuple<size_t, size_t, size_t> threeD{
   1,2,3};    //三个成员都设置为0

访问tuple的成员
  要访问tuple的成员,使用一个名为get的标准库函数模板,同时传递给get一个tuple对象,其返回指定成员的引用:

auto book = get<0>(item);    //返回item的第一个成员
auto book = get<1>(item);    //返回item的第二个成员
auto book = get<2>(item)/cnt;    //返回item的最后一个成员
get<2>(item) *= 0.8;    //打折20%

注意:尖括号中的值必须是一个整型常量表达式,从0开始计数,意味着get<0>是第一个成员。

2 bitset类型

2.1 定义和初始化bitset

  标准库定义bitset类,使得位运算的使用更为容易,其定义在头文件bitset中。
bitset类是一个类模板,类似array类,具有固定的大小,因此当定义一个bitset时,需要声明其包含多少个二进制位:

bitset<32> bitvec(1U);   //32位;低位为1,其他位为0

大小必须是一个常量表达式。其中编号从0开始的二进制位被称为低位,编号到31结束的二进制位被称为高位

初始化bitset的方法
操作 说明
bitset<n> b; b有n位;每位均为0,此构造函数是一个constexpr
bitset<n> b(u); b是unsigned long long值u的低n位的拷贝,若n超出类型范围,则b中超出类型的高位被置0
bitset<n> b(s, pos, m, zero, one); b是string从位置pos开始m个字符的拷贝。s只能包含字符zero或one;如果s包含任何其他字符,构造函数会抛出invalid——argument异常。
bitset<n> b(cp, pos, zero, one); 与是一个函数相同,但从cp指向的字符数组中拷贝字符。若未提供m,则cp必须指向一个C风格字符串。若提供了m,则从cp开始必须至少有m个zero或one字符

接受一个string或一个字符指针的构造函数是explicit

用unsigned值初始化bitset
  当使用一个整型值来初始化bitset时,此值将被转换为unsigned long long类型并被当作位模式来处理。若bitset的大小大于一个unsigned long long中的二进制位数,则剩余的高位被置为0。若bitset的大小小于一个unsigned long long中的二进制位数,则只使用给定值中的低位,超出bitset大小的高位被丢弃:

//bitvecl比初始值小;初始值中的高位被丢弃
bitset<13> bitvecl1(0xbeef);    //二进制位序列为1 1110 1110 1111
//bitvec2比初始值大;它的高位被置为0
bitset<20> bitvecl1(0xbeef);    //二进制位序列为0000 1011 1110 1110 1111
//在64位机器中,long long 0ULL是个64个0比特,故~0ULL是64个1
bitset<128> bitvecl1(~0ULL);    //0~63位为1;63~127位为0

从一个string初始化bitset
  可以从一个string或一个字符数组指针来初始化bitset。两种情况下,字符都直接表示位模式。其中字符串中下标最小的字符对应高位。

bitset<32> bitvec("1100");    //2、3两位为1,剩余两位为0

如果string包含的字符数比bitset少,则bitset的高位被置为0
tip:string的下标编号与bitset恰好相反:string中下标最大的字符(最右字符)用来初始化bitset中的低位(下标为0的二进制位)

其它初始化方式:

string str("111111100000011001101");
bitset<32> bitvec5(str, 5, 4);    //从str[5]开始的四个二进制位,1100
bitset<32> bitvec6(str, str.size() - 4);    //使用最后四个字符

下图说明了上述拷贝过程:
bitset拷贝

2.2 bitset操作

  bitset操作定义了多种检测或设置一个或多个二进制位的方法,其操作如下表:

bitset操作
操作 描述
b.any() b中是否存在置为的二进制位
b.all() b中所有位是否都置位了
b.none() b中不存在置位的二进制吗
b.count() b中置位的位数
b.size() 一个constexpr,返回b中的位数
b.test(pos) pos位置的位是置位的,则返回true,否则返回false
b.set(pos, v) b.set() 将位置pos处的位设置为bool值v。v默认为true,若未传递参数,则将b中所有位置位
b.reset(pos) b.reset() 将位置pos处的位复位或将b中的所有位复位
b.flip(pos) b.flip() 改变位置pos处的位的状态或改变b中每一位的状态
b[pos] 访问b中位置pos处的位;若b是const的,则该位置位时b[pos]返回一个bool值true,否则返回false
b.to_ulong() b.to_ullong() 返回一个unsigned long或一个unsigned long long值,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值