因為習慣了 qsort 的函數指針參數,以前用 std::sort 的時候一般也是傳函數指針而不是仿函數(functor)。從很多示例程序來看,貌似沒有什麼大的不同。但是直到今天我才醒悟,原來是示例太簡單了啊!
具體來說,我今天遇到了一個問題:要對一個表進行排序,每個字段可能是升序,可能是降序,也有不同的類型,所以排序的時候需要根據這些信息進行比較。比較函數不能是類成員函數,但我又的確要用到類成員的信息,函數接口又不能變,著實發愁。愁了就只能 Google,發現原來仿函數可以輕松地搞定這件事情。
// 來自 http://stackoverflow.com/a/1902360
class MyClass{// ...
struct doCompare
{
doCompare( const MyClass& info ) : m_info(info) { } // only if you really need the object state
const MyClass& m_info;bool operator()( const int & i1, const int & i2 )
{
// comparison code using m_info
}
};doSort()
{ std::sort( arr, arr+someSize, doCompare(*this) ); }
};
簡單點兒說,因為仿函數是個類,也可以有成員變量,構造的時候可以傳參進去初始化,這樣就能實現更靈活的比較方法。這麼簡單的道理,為什麼之前我就是想不到呢?
此外值得一提的是,std::sort 要求比較的結果是 strict weak order,就是說要嚴格小於才返回 true。這就意味著,僅僅對比較結果取反,是無法實現逆序的。因為小於的取反不是大於,而是大於等於。
我們有過經驗,如果相等的時候也返回 true,可能會導致某些標准庫實現的 sort 函數指針越界,導致程序出錯。所以要千萬避免犯這個錯誤。