STL反向迭代器,其指向的值是正确的,但是其在调试时,该迭代器总是指向下一个(右侧)。
这是由于STL容器半闭半开区间(左闭右开)造成的。
rpos总是指向pos的前一个值,为什么呢?候捷先生译的《C++标准模板库》里是这么解释的:“注意,这不是bug,这是特性!导致这个行为的原因是区间的半开性。为了能够指定容器内所有元素,我们必须运用‘最后一个元素的下一位置’。”“逆向迭代器的设计者运用了一个小技巧:他们实际上倒置了‘半开原则’”
这两句话非常重要,首先容器的区间是左闭右开的,区间是以一个空位置作为区间的结束。对于逆向迭代器言,这个空位置就成了开始rbegin()的位置。但是这个位置上是没有值的,因此rbegin的值就取的是该位置前的一个值。--这正是“运用的小技巧”。这个小技巧保持了“以一个空位置作为区间结束”的原则。
(以上文字摘自: http://www.cnblogs.com/onlyan/articles/2657803.html)
void main()
{
vector<int> iV;
iV.push_back(9);
iV.push_back(4);
iV.push_back(5);
iV.push_back(11);
iV.push_back(0);
sort(iV.begin(), iV.end());
sort(iV.begin(), iV.end(), greater<int>()); //函数对象,需要functional支持
vector<int>::iterator it = iV.begin();
++it;
--it;
it += 3;
//itr本身的值是同iV.end()相等的(从其本身的值来看,该itr不指向任何值)。
//但实际上其指向的值是0
vector<int>::reverse_iterator itr = iV.rbegin();
//itr2本身的值同iv.begin()相等(从其本身的值来看,该itr2指向index为0的元素,即11)。
//但实际上其指向的值不存在
vector<int>::reverse_iterator itr2 = iV.rend();
++itr;
--itr2;
}
以下是各种排序
// testAlgorithm.cpp : 定义控制台应用程序的入口点。
//
// testBitset.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <list>
#include <set>
#include <map>
using namespace std;
bool greater_than(const int& i1, const int& i2)
{
return i1 >= i2;
}
//
struct stru
{
int iID;
string strName;
bool operator >= (const stru& ob)
{
return iID >= ob.iID;
}
bool operator <= (const stru& ob)
{
return iID <= ob.iID;
}
bool operator > (const stru& ob)
{
return iID > ob.iID;
}
bool operator < (const stru& ob)
{
return iID < ob.iID;
}
bool operator == (const stru& ob)
{
return iID == ob.iID;
}
};
bool less_than_ID(const stru& ob1, const stru& ob2)
{
return ob1.iID < ob2.iID;
}
bool greater_than_ID(const stru& ob1, const stru& ob2)
{
return ob1.iID >= ob2.iID;
}
bool less_than_Name(const stru& ob1, const stru& ob2)
{
return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) <= 0; // ob1.strName <= ob2.strName
}
bool greater_than_Name(const stru& ob1, const stru& ob2)
{
return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) >= 0;// ob1.strName >= ob2.strName
}
/*
//
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> iV;
iV.push_back(9);
iV.push_back(4);
iV.push_back(5);
iV.push_back(11);
iV.push_back(0);
sort(iV.begin(), iV.end());
sort(iV.begin(), iV.end(), greater_than);
//
vector<stru> sV;
stru ob1 = {5, "abcd"};
sV.push_back(ob1);
stru ob2 = {4, "fcba"};
sV.push_back(ob2);
stru ob3 = {7, "eeee"};
sV.push_back(ob3);
stru ob4 = {0, "张先生"};
sV.push_back(ob4);
// sort(sV.begin(), sV.end()); //需要重载 >= <= > < == 共5个操作运行符。
// sort(sV.begin(), sV.end(), greater_than_ID); //按ID降序
// sort(sV.begin(), sV.end(), less_than_ID); //按ID升序
// sort(sV.rbegin(), sV.rend(), less_than_ID); //从后向前 按ID升序
sort(sV.begin(), sV.end(), less_than_Name); //按Name升序
sort(sV.begin(), sV.end(), greater_than_Name); //按Name降序
return 0;
}
*/
//以上方式效率较低,由于 less_than_*, greater_than_* 函数,需要多次调用(需要多次初始化和清理栈),
//而这些函数又不是内联函数,因此效率较低.
//替代方案如下,是采用类重载操作符,内联函数形式
//
class LessThanID
{
public:
inline bool operator () (const stru& ob1, const stru& ob2)
{
return ob1.iID <= ob2.iID;
}
};
class GreaterThanID
{
public:
inline bool operator () (const stru& ob1, const stru& ob2)
{
return ob1.iID >= ob2.iID;
}
};
class LessThanName
{
public:
inline bool operator () (const stru& ob1, const stru& ob2)
{
return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) <= 0; // ob1.strName <= ob2.strName
}
};
class GreaterThanName
{
public:
inline bool operator () (const stru& ob1, const stru& ob2)
{
return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) >= 0; // ob1.strName >= ob2.strName
}
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> iV;
iV.push_back(9);
iV.push_back(4);
iV.push_back(5);
iV.push_back(11);
iV.push_back(0);
sort(iV.begin(), iV.end());
sort(iV.begin(), iV.end(), greater<int>()); //函数对象,需要functional支持
vector<int>::iterator it = iV.begin();
++it;
--it;
it += 3;
//itr本身的值是同iV.end()相等的(从其本身的值来看,该itr不指向任何值)。
//但实际上其指向的值是0
vector<int>::reverse_iterator itr = iV.rbegin();
//itr2本身的值同iv.begin()相等(从其本身的值来看,该itr2指向index为0的元素,即11)。
//但实际上其指向的值不存在
vector<int>::reverse_iterator itr2 = iV.rend();
++itr;
--itr2;
list<int> iLst;
iLst.insert(iLst.end(), 9);
iLst.insert(iLst.end(), 4);
iLst.insert(iLst.end(), 5);
iLst.insert(iLst.end(), 11);
list<int>::iterator itL = iLst.begin();
++itL;
--itL;
list<int>::reverse_iterator itLr = iLst.rbegin();
list<int>::reverse_iterator itLr2 = iLst.rend();
set<int> iS;
iS.insert(9);
iS.insert(4);
iS.insert(5);
iS.insert(11);
set<int>::iterator itS = iS.begin();
++itS;
--itS;
advance(itS, 2);
advance(itS, -2);
map<int, string> mp;
mp[9] = "abc";
mp[4] = "def";
mp[5] = "厅厅";
mp[11] = "44123";
map<int, string>::iterator itM = mp.begin();
++itM;
--itM;
itM = --mp.end();
map<int, string>::reverse_iterator itMr = mp.rbegin();
std::cout<<itMr->first<<endl;
advance(itMr, 2); std::cout<<itMr->first<<endl;
advance(itMr, -1);
std::cout<<mp.rbegin()->first<<endl;
//
vector<stru> sV;
stru ob1 = {5, "abcd"};
sV.push_back(ob1);
stru ob2 = {4, "fcba"};
sV.push_back(ob2);
stru ob3 = {7, "eeee"};
sV.push_back(ob3);
stru ob4 = {0, "张先生"};
sV.push_back(ob4);
// 以下使用自定义的函数对象进行排序
// sort(sV.begin(), sV.end(), LessThanID());
// sort(sV.begin(), sV.end(), GreaterThanID());
GreaterThanName gtN;
sort(sV.begin(), sV.end(), gtN);
sort(sV.begin(), sV.end(), LessThanName());
return 0;
}