因为习惯了 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 函数指针越界,导致程序出错。所以要千万避免犯这个错误。
用 Functor 的还有一个好处是可以 inline,效率更高。
PS.
评论只靠图标提示填写不太有好,名字那一栏想了一会儿才想到是啥。