特征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会产生int,string和char,会产生std::string。
迭代器
迭代器是一个“可以遍历STL容器全部或部分元素”的对象,用来表现出容器中的某一个位置。
在STL中是容器与算法之间的接口,算法通常以迭代器作为输入参数。
基本思想:
Vector
Vector是一个能够存放任意类别的动态数组
Vector指出动态空间大小调整,内部会自动扩充内存空间。
使用方法
Vector支持随机访问,提供随机访问迭代器,适用于任何STL算法。
#include<vector>
int main(){
std::vector v;
}
- vector c 产生一个空的vector,无任何元素
- vectorc(c2) 建立c并成为c2的一份拷贝
- vectorc=c2 建立一个新的vector作为c2的拷贝
- vectorc(rv) 建立一个新的vector,取rvalue rv的内容
- vectorc=rv 建立一个新的vector,取rvalue rv的内容
- vectorc(n) 建立一个大小为n的vector
- vectorc(n,elem) 建立一个大小为n的vector,每个值为elem
- vectorc(beg,end) 建立一个vector,以区间【beg,end】作为元素初值
- c.~vector() 销毁所有元素,释放内存
非更易型操作
- c.empty()返回是否为空
- c.size()返回目前元素个数
- c.max_size()返回元素个数之最大可能量
- c.capacity()返回“不进行空间重新分配”条件下的元素最大容纳量
- c.reserve(num)如果容量不足,扩大之
- c.shrink_to_fit()要求降低容量,以符合元素个数
赋值操作
- c=c2**把c2的所有元素给c**
- c=rv**把rvalue rv的所有元素以move assign给c**
- c=initlist**将初值列initlist的所有元素给c**
- c=assign(n,elem)复制n个elem,赋值给c
- c.assign(beg,end)将区间[beg,end]中所有元素给c
- c.assign(initlist)将初值列initlist的所有元素赋值给c
- c1.swap(c2)置换c1和c2
- swap(c1,c2)置换c1和c2
元素访问
c[idx]返回索引idx所指的元素(不检查范围)
c.at(idx)返回索引idx所指的元素(如果idx超出范围就抛出异常)
插入与移除
- push_back(elem)附加一个elem的拷贝于末尾
- pop_back()移除最后一个元素,但是不返回
- insert(pos,elem)在pos位置之前插入一个elem拷贝,并返回新的位置
- insert(pos,n,elem)在pos位置之前插入n个elem拷贝,并返回第一个新元素的位置
- insert(pos,beg,end)在pos之前插入区间[beg,end)内的元素,并返回第一个新元素的位置
- emplace(pos,args…)在pos之前插入一个以args为初值的元素,并返回新元素的位置
- emplace_bakc(args…)附加一个以args为初值的元素于末尾,不返回
- erase(pos)移除pos位置上的元素,返回下一个元素的位置
- resize(num)将元素数量改为num(如果size()变大,多出来的元素以default完成初始化)
- resize(num,elem)将元素数量改为num(如果size()变大,多出的的元素都是elem的拷贝)