1. 程式人生 > >STL自定義排序函式 需要注意的問題

STL自定義排序函式 需要注意的問題

1.例子

    先舉個例子:分析一下程式的執行結果:看看在三種情況下程式的輸出分別是什麼,有可能出現異常
////////////////////////////////////////////////////
#pragma once
#include 
#include 

///////////////////////////////////////////////////
///下面是三個自定義的謂詞函式,排序演算法將分別使用這三個函式
//////////////////////////////////////////////////
bool compare(int a,int b)
{
    return a - b;
}

bool compare1(int a,int b)
{
    return a < b;
}

bool compare2(int a,int b)
{
    return a <= b;
}
/////////////////////////////////////////////////////
///Main函式
////////////////////////////////////////////////////
int main(int arg,char * argv[])
{
    std::vector vec;
    vec.push_back(7);
    vec.push_back(5);
    vec.push_back(8);
    vec.push_back(10);
    vec.push_back(48);
    vec.push_back(32);
    vec.push_back(7);
    vec.push_back(5);
    vec.push_back(3);
    vec.push_back(3);
    //第一種情況
    std::sort(vec.begin(),vec.end(),compare);
    
//第二種情況
    std::sort(vec.begin(),vec.end(),compare1);
//第三種情況
    std::sort(vec.begin(),vec.end(),compare2);
    getchar();
    return 0;
}
//////////////////////////////////////////////////
2.結果
    三種情況在程式中分別使用後(這裡為了節省空間寫在了一起)的結果是:
    (1)第一種情況(
compare函式)和第三種情況(compare2函式)出現錯誤(assert):     (2)第二種情況(compare1函式)下程式執行正常,結果正確。
3.分析

    第一種情況和第三種情況出錯的原因是:跟蹤到出現異常的stl的原始碼的一個函式中,就是下面這個函式:
template inline
    bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, _Ty1& _Left, _Ty2& _Right,
        const wchar_t *_Where, unsigned int _Line)
    {    // test if _Pred(_Left, _Right)  and _Pred is strict weak ordering
    if (!_Pred (_Left, _Right))

        return (false);
    else if (_Pred(_Right, _Left))
        _DEBUG_ERROR2("invalid operator<", _Where, _Line);
    return (true);
    }
    這個函式要求對於呼叫的兩個引數交換位置時不能得到相同的true的結果。也就是為什麼第一種和第三種不行的原因了:A當待比較的兩個值相等的時候,
第三種情況B比較的兩個值不相等的時候,第一種情況。
    但是對於呼叫的兩個引數交換位置時允許得到相同的false的結果,因為這時根本不進行兩個引數交換位置操作!!(具體看程式:在第一個if的時候就返回false了) 在自定義比較函式中如果是相等的情況 返回false就OK了