1、问题描述
入参:vector num, bool dir
如果dir==1,正向遍历num;否则反向遍历num。
常规遍历需要写两次循环,若循环体中代码量较大时,会产生严重重复代码问题,如何通过一个循环来实现呢?
2、常规迭代器正向遍历和反向遍历
if(0 == pos.dir){
for(auto it = num.begin(); it != num.end(); ++it)
{
cout << (*it) << endl;
}
}else{
for(auto it = num.rbegin(); it != num.rend(); ++it)
{
cout << (*it) << endl;
}
}
3、进阶版遍历
vector<int> num = {1, 2, 3, 4, 5, 6};
int dir = 1;
typedef vector<int>::iterator IT;
//开始迭代器
IT iStart = dir ? num.begin() : num.rbegin().base() - 1;
//结束迭代器
IT iEnd = dir ? num.end() : (num.rend() + 1).base();
int step = dir ? 1 : -1;
while(iStart != iEnd){
cout << ": " << (*iStart) << endl;
iStart += step;
}
dir = 1输出:
dir = 0输出:
从正向反向的开始迭代器来看,都对应容器中正向反向的第一个值,但是结束迭代器输出是一个奇奇怪怪值,这是因为容器自身的属性原因,需要将其指针再向后(相对而言)一个才可以正常输出容器中的最后一个值。
4、模板实现
可以通过引入模板,就不必每次循环时都将初始化迭代器代码编写一遍。
模板部分:
template< class A, class B, class T, class I>
T ForIter(A a, B b){return {b ? begin(a) : end(a) - 1, b ? end(a) : begin(a) - 1, b ? 1 : -1};}
实现部分:
vector<int> num = {1, 2, 3, 4, 5, 6};
int dir = 0;
typedef vector<int>::iterator IT;
typedef tuple<IT, IT, int> RE;
RE result;
result = ForIter<vector<int>, bool, RE, IT>(num, dir);
IT iStart = get<0>(result);
IT iEnd = get<1>(result);
int step = get<2>(result);
/*IT iStart = dir ? num.begin() : num.rbegin().base() - 1;
IT iEnd = dir ? num.end() : (num.rend() + 1).base();
int step = dir ? 1 : -1;*/
cout << "iStart: " << (*iStart) << endl;
cout << "iEnd: " << (*iEnd) << endl;
while(iStart != iEnd){
cout << ": " << (*iStart) << endl;
iStart += step;
}
博主这里将开始和结束迭代器以及step值返回到了一个tuple,这里可以灵活更改。