STL自定義排序函式 需要注意的問題
阿新 • • 發佈:2019-01-07
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了
先舉個例子:分析一下程式的執行結果:看看在三種情況下程式的輸出分別是什麼,有可能出現異常
////////////////////////////////////////////////////
#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了