函数指针和函数对象不是同一类型,为何可替换用作同一函数的参数?
看下面STL std::sort()使用函数指针和函数对象的情形?
// sort algorithm example
include // std::cout
include // std::sort
include // std::vector
bool myfunction (int i,int j) { return (i<j); }
struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobject;
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector myvector (myints, myints+8); // 32 71 12 45 26 80 53 33
// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33
// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)
// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)
// print out content:
std::cout << "myvector contains:";
for(std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
如果自定义sort()函数呢?
include
bool lesser (int a,int b){return ab;}
void mysort(int arr[],int n,bool (comp)(int a,int b))
{
for(int i=0;ib;}
bool operator()(int a,int b){return a>b;}
};
main()
{
int arr[] = {2,7,5,9,3};
int n = sizeof arr / sizeof arr;
mysort(arr,n,Lesser());
for(int i=0;i<n;i++)
printf("%d ",arr[i]);
printf("\n");
getchar();
}
/
提示错误:
cannot convert parameter 3 from 'class Lesser' to 'bool (__cdecl )(int,int)'
*/
原因在于函数模板调用时,不需显式声明具体类型,编译器可以自动匹配。
std::sort()是一函数模板:
template
void sort (RandomAccessIterator first, RandomAccessIterator last);
template
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
以下是使用了模板技术的sort函数:
include
bool lesser (int a,int b){return ab;}
template
class Lesser{
public:
bool operator()(T a,T b){return a<b;} // 函数对象
};
class Greater{
public:
bool funcObj(int a,int b){return a>b;} // 演示与下面重载()相同功能
bool operator()(int a,int b){return a>b;}// 函数对象
// 以上两个成员功能一致,无疑后者更简洁,使用方式与函数相同
};
//代码效果参考:http://www.zidongmutanji.com/bxxx/232146.html
template // 需要模板才能传递函数指针或函数对象
void mysort(T arr[],T n,Comp comp)
{
for(T i=0;i<n;i++)
for(T j=0;j<n-i-1;j++)
if(comp(arr[j],arr[j+1]))
{
T t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
void printArr(int arr[],int n)
{
for(int i=0;i<n;i++)
printf("%d ",arr[i]);
printf("\n");
}
main()
{
Greater gt;
bool a = gt.funcObj(3,4);
bool b = gt(3,4);
// 以上两种函数对象的本质都是方法调用,但后者更简洁,接口统一,形似函数
int arr[] = {2,7,5,9,3};
int n = sizeof arr / sizeof *arr;
printArr(arr,n);
mysort(arr,n,greater); // 函数指针
printArr(arr,n);
mysort(arr,n,lesser); // // 函数指针
printArr(arr,n);
mysort(arr,n,Greater()); // 匿名对象
printArr(arr,n);
mysort(arr,n,Lesser<int>()); // 匿名对象
printArr(arr,n);
getchar();
}
/
2 7 5 9 3
2 3 5 7 9
9 7 5 3 2
2 3 5 7 9
9 7 5 3 2 /