函数 1:
template<class_RanIt> inline
voidsort(_RanIt _First, _RanIt _Last)
{ //order [_First, _Last), using operator<
_DEBUG_RANGE(_First,_Last);
_Sort(_CHECKED_BASE(_First),_CHECKED_BASE(_Last), _Last - _First);
}
默认是用"<"来判定顺序的。
函数 2:
template<class_RanIt,
class_Pr> inline
voidsort(_RanIt _First, _RanIt _Last, _Pr _Pred)
{ //order [_First, _Last), using _Pred
_DEBUG_RANGE(_First,_Last);
_DEBUG_POINTER(_Pred);
_Sort(_CHECKED_BASE(_First),_CHECKED_BASE(_Last), _Last - _First, _Pred);
}
_Pred,用户自定义的判定函数对象。
函数1算是函数2的一个特例,所以这里只分析函数2即可。
sort函数最终是调用 如下函数来比较两个参数的大小的:
template<class_Pr, class _Ty1, class _Ty2> inline
bool__CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, _Ty1& _Left, _Ty2& _Right,
constwchar_t *_Where, unsigned int _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weakordering
if(!_Pred(_Left, _Right))
return(false);
elseif (_Pred(_Right, _Left))
_DEBUG_ERROR2(,_Where, _Line);
return(true);
}
代码中标注的蓝色注释说明,判定函数_Pred必须是严格的弱序化(strict weak ordering),什么是严格的弱序化呢?参考Microsoft给的支持:http://support.microsoft.com/kb/949171>
The STL algorithmsfor stable_sort() and sort() require the binary predicate to be strict weakordering.
For example:
· Strict: pred(X, X)is always false.
· Weak: If !pred(X,Y) && !pred(Y, X), X==Y.
· Ordering: Ifpred(X, Y) && pred(Y, Z), then pred(X, Z).
理解Strict,两个相同的参数比较,必须返回false。如果不返回false,通过源代码我们可以看到,程序将会抛出异常提示"invalid operator<"。在《Effective STL》中的第21条也提到,Item 21. Always have comparison functions return false for equal values.
理解Weak,如果!Pred(X, Y)和!_Pred(X, Y)同时满足的话,即说明X和Y是相等的。相等默认不改变。
理解Ordering,先比较完X,Y和Y,Z,再来比较X,Z。
如果是比较结构体,即可以使用重载操作符<,>来完成,也可以直接自定义比较函数来完成。
typedef structST_ZONE_BLK
{
ST_ZONE_BLK(int a, intb):nFirst(a),nSecond(b){}
int nFirst;
int nSecond;
bool operator < (const ST_ZONE_BLK&_other) const
{
return nFirst > _other.nFirst;
}
}ZONE_BLK;
bool MySort(constST_ZONE_BLK &_first, const ST_ZONE_BLK &_second)
{
return _first.nFirst > _second.nFirst;
}
main()
{
// Test
vector<ZONE_BLK>vZoneBlk;
vZoneBlk.push_back(ZONE_BLK(1,2));
vZoneBlk.push_back(ZONE_BLK(3,2));
vZoneBlk.push_back(ZONE_BLK(1,3));
vZoneBlk.push_back(ZONE_BLK(4,2));
sort(vZoneBlk.begin(),vZoneBlk.end(), MySort);
sort(vZoneBlk.begin(),vZoneBlk.end());
}
P.S.