Geekban极客班 C++ STL与泛型编程 第一周作业

来源:互联网 发布:美国种族歧视 知乎 编辑:程序博客网 时间:2024/05/20 16:01

特征Traits

char szNames[]="abc";std::size_t nLength=strlen(szNames);char* p=szNames;char* q=szNames+nLength;printf("Sigma(szNames)=%d\n",Siqma(p,q));

调用后结果为38,实际结果应为294
因为发生了溢出。char的最大值为255。

解决方法:为Siqma的参数类型建立关联,将其关联至另一个类型,数据返回的类型将改为关联的类型,防止数据的溢出。如char->int,short->int,int->long

Traits的实现

这里写图片描述
将char关联成int、将short关联成int、将int关联成long、将unsigned int关联成unsigned long、将float关联成double

template<typename T>inline T Sigma(const T const& start,const T const&end){   T total=T();   while(start!=end){      total+=*start++;   }   return total;}
template<typename T>inline typename SigmaTraits<T>::ReturnType Sigma(const T const& start,const T const& end){   typedef typename SigmaTraits<T>::ReturnType ReturnType;   ReturnType s=ReturnType();   while(start!=end0)      s+=*start++;   return s;}   

其中typename SigmaTraits::ReturnType为返回类型。
根据传入Sigma( , )的参数类型可以推出typename SigmaTraits::ReturnType的类型。

Trait 处理共通类型

(补充自The C++ Standard Library)

template<typename T1,typename T2>typename std::common_type<T1,T2>::type min(const T1& x,const T2& y);

当T1,T2类型不同,但是拥有共通类型,使用上述程序可以将两种参数转换为一种参数。如int和long,std::common_type会产生intstring和char,会产生std::string

迭代器

迭代器是一个“可以遍历STL容器全部或部分元素”的对象,用来表现出容器中的某一个位置。
在STL中是容器与算法之间的接口,算法通常以迭代器作为输入参数。
基本思想:

Vector

Vector是一个能够存放任意类别的动态数组
Vector指出动态空间大小调整,内部会自动扩充内存空间。
使用方法
Vector支持随机访问,提供随机访问迭代器,适用于任何STL算法。

#include<vector>int main(){   std::vector v;}
  1. vector c 产生一个空的vector,无任何元素
  2. vectorc(c2) 建立c并成为c2的一份拷贝
  3. vectorc=c2 建立一个新的vector作为c2的拷贝
  4. vectorc(rv) 建立一个新的vector,取rvalue rv的内
  5. vectorc=rv 建立一个新的vector,取rvalue rv的内容
  6. vectorc(n) 建立一个大小为n的vector
  7. vectorc(n,elem) 建立一个大小为n的vector,每个值为elem
  8. vectorc(beg,end) 建立一个vector,以区间【beg,end】作为元素初值
  9. c.~vector() 销毁所有元素,释放内存

非更易型操作

  1. c.empty()返回是否为空
  2. c.size()返回目前元素个数
  3. c.max_size()返回元素个数之最大可能量
  4. c.capacity()返回“不进行空间重新分配”条件下的元素最大容纳量
  5. c.reserve(num)如果容量不足,扩大之
  6. c.shrink_to_fit()要求降低容量,以符合元素个数

赋值操作

  1. c=c2**把c2的所有元素给c**
  2. c=rv**把rvalue rv的所有元素以move assign给c**
  3. c=initlist**将初值列initlist的所有元素给c**
  4. c=assign(n,elem)复制n个elem,赋值给c
  5. c.assign(beg,end)将区间[beg,end]中所有元素给c
  6. c.assign(initlist)将初值列initlist的所有元素赋值给c
  7. c1.swap(c2)置换c1和c2
  8. swap(c1,c2)置换c1和c2

元素访问
c[idx]返回索引idx所指的元素(不检查范围)
c.at(idx)返回索引idx所指的元素(如果idx超出范围就抛出异常)

插入与移除

  1. push_back(elem)附加一个elem的拷贝于末尾
  2. pop_back()移除最后一个元素,但是不返回
  3. insert(pos,elem)在pos位置之前插入一个elem拷贝,并返回新的位置
  4. insert(pos,n,elem)在pos位置之前插入n个elem拷贝,并返回第一个新元素的位置
  5. insert(pos,beg,end)在pos之前插入区间[beg,end)内的元素,并返回第一个新元素的位置
  6. emplace(pos,args…)在pos之前插入一个以args为初值的元素,并返回新元素的位置
  7. emplace_bakc(args…)附加一个以args为初值的元素于末尾,不返回
  8. erase(pos)移除pos位置上的元素,返回下一个元素的位置
  9. resize(num)将元素数量改为num(如果size()变大,多出来的元素以default完成初始化)
  10. resize(num,elem)将元素数量改为num(如果size()变大,多出的的元素都是elem的拷贝)
0 0