干什么成员函数指针模板不能够像函数指针模板一样有简要的扬言方式呢

http://topic.csdn.net/u/20101021/10/af09d7fb-5ab3-403d-a364-a6f06f472968.html

诸如成员函数模板必须是:

template<typename T, typename RT, typename P1>
void test(T t1, RT (T::*mem_fun)(P1) , P1 p);

而函数指针即能能是:
template<typename RT, typename P>
void test(RT (*func)(P) , P p);

又能是:
template<typename F, typename P>
void test (F fun, P p)

依据使用情形,能够接纳简单的定义。


http://blog.sina.com.cn/s/blog\_4a50d85b0100umqe.html

C语言的指针10分的灵活方便,但也极度不难出错。许多C语言初学者,甚至C语言老鸟都很不难跌倒在C语言的指针下。但不可以还是不可以认的是,指针在C语言中的地点极其首要,恐怕能够偏激一点的来说:没有指针的C程序不是确实的C程序。
  然则C++的指针却时常给自个儿一种束手束脚的痛感。C++比C语言有更严刻的静态类型,更加强调类型安全,强调编写翻译时检查。因而,对于C语言中最简单错
用的指针,更是不能放过:C++的指针被分为数据指针,数据成员指针,函数指针,成员函数指针,而且不能够随便相互转换。而且这么些指针的证明格式都不均等:

数据指针 T *
成员数据指针 T::*
函数指针 R (*)(…)
成员函数指针 R (T::*)(…)

再有二个更首要的区分是,指针所占的长空也不相同了。尽管在叁十几位系统中,所占的空中也有也许是4字节、8字节、12字节甚至16字节,那些依照平台及编写翻译器,有十分的大的更动。
  即便C++中照旧有万能指针void*,但它却属于被批判并斗争的对象,而且再也不能“万能”了。它不可能转换成成员指针。

  那样一来,C++的指针就变得很为难:大家须要一种指针能够针对同一档次的多寡,不管这些数量是司空见惯数据,还是成员数量;大家更须求一种指针能够针对同一档次的函数,不管那一个函数是静态函数,依然成员函数。可是尚未,至少从明天的C++标准中,还平素不观望。
 
沐枫网志 C++指针讨论(三)成员函数指针

  自从有了类,大家起始按部就班 数据+操作 的章程来集团数据结构;自从有了模版,我们又先河把
数据 和 算法
分离,以便重用,实在够折腾人的。但不管怎么折腾,今后大多数函数都不再单独,都嫁给了类,进了包围。但是我们照样需求能够随意调用那个分子函数。
  考虑一下windows下的定时调用。SetTimer函数的原型是这么的:

图片 1UINT_PTR SetTimer(
图片 2    HWND hWnd,
图片 3    UINT_PTR nIDEvent,
图片 4    UINT uElapse,
图片 5    TIMERPROC lpTimerFunc
图片 6);
图片 7

个中,参数就不解释了,这些函数测度大部分windows开发人士都精通。lpTimerFunc是个会被定时调用的函数指针。借使咱们不通过
WM_TIME奥迪Q7新闻来触发定时器,而是经过lpTimerFunc来定时工作,那么我们就只好使用普通函数或静态函数,而不顾都无法动用成员函数,
哪怕通过静态函数转调也十二分。

  再考虑一下线程的创始:

图片 8uintptr_t _beginthread( 
图片 9   void( *start_address )( void * ),
图片 10   unsigned stack_size,
图片 11   void *arglist 
图片 12);图片 13

start_address依然只帮忙一般函数。可是那回好了,它同意回调函数贰个void*参数,它将会arglist作为参数来调用
start_address。于是,聪明的C++程序员,就采取arglist传递this指针,从而选拔静态函数成功的调用到了成员函数了:

图片 14class mythread
图片 15{
图片 16  public:
图片 17    static void doit(void* pThis)
图片 18    {
图片 19    ((mythread*)pThis)->doit();
图片 20    }
图片 21    void doit(){图片 22}
图片 23};
图片 24
图片 25main()
图片 26{
图片 27  图片 28
图片 29  mythread* pmt = new mythread;
图片 30  _beginthread(&mythread::doit, 0, (void*)pmt);
图片 31  图片 32
图片 33}

  可是明显,C++程序员肯定不会因而而满意。这里头有好多被C++批判的不平静因素。它使用了C++中被认为不安全的类型转换,不安全的void*指
针,等等等等。但那是系统为C语言留下的调用接口,那也就认了。那么一旦,大家就在C++程序中如何来调用成员函数指针呢?
  如下例,我们打算对vector中的全部类调用其钦命的分子函数:

图片 34#include <vector>
图片 35#include <algorithm>
图片 36#include <functional>
图片 37#include <iostream>
图片 38using namespace std;
图片 39
图片 40class A
图片 41{
图片 42    int value;
图片 43public:
图片 44    A(int v){value = v;}
图片 45    void doit(){ cout << value << endl;};
图片 46    static void call_doit(A& rThis)
图片 47    {
图片 48        rThis.doit();
图片 49    }
图片 50};
图片 51
图片 52
图片 53int main()
图片 54{
图片 55    vector<A> va;
图片 56    va.push_back(A(1));
图片 57    va.push_back(A(2));
图片 58    va.push_back(A(3));
图片 59    va.push_back(A(4));
图片 60    //方法1:
图片 61    //for_each(va.begin(), va.end(), &A::doit); //error
图片 62    //方法2:
图片 63    for_each(va.begin(), va.end(), &A::call_doit);
图片 64    //方法3:
图片 65    for_each(va.begin(), va.end(), mem_fun_ref<void, A>(&A::doit));
图片 66
图片 67    system(“Pause”);
图片 68
图片 69    return 0;
图片 70}
图片 71

  方法1,编写翻译不可能经过。for_each只允许具备二个参数的函数指针或函数对象,哪怕A::doit默许有三个this指针参数也非常。不是for_each没考虑到那一点,而是根本做不到!
  方法2,鲜明是备受了beginthread的开导,使用多少个静态函数来转调用,哈哈打响了。然则不爽!这不是C++。
  方法3,呼,好不不难啊,终于用mem_fun_ref包装成功了成员函数指针。
  就好像方法3毋庸置疑,又是类别安全的,又足以通用--慢着,首先,它非常丑,哪有调用普通C函数指针那么精良啊(见方法2),用了一大串包装,又是尖括号又
是圆括号,还少不了&号!其次,它不得不包装不超越八个参数的函数!即便它在for_each中够用了,不过你假如想用在跨越1个参数的场子,那唯有一句话:不容许的职务。

  是的,在正规C++中,那是不容许的职务。但工作并不三番五次悲观的,至少有广大第3方库提供了当先mem_fun的包裹。如
boost::function等等。然则它也有限量:它所支撑的参数如故是有限的,唯有二十一个,固然够你用的了;同样,它也是丑陋的,永远不要想它能够不难的用&来化解。

  恐怕,以失去美观的代价,来换取品质上的保证,那也是C++对于函数指针的一种无奈啊……

  期待C++0x版本。它经过可变模板参数,能够让mem_fun的参数达到最好个……

--------
   BTW: C++Builder扩张了三个重庆大学字 closure
,允许成员函数指针就好像普通函数指针一样采纳。可能C++0x能考虑一下……


http://www.cnblogs.com/jans2002/archive/2006/10/13/528160.html

http://www.codeproject.com/KB/cpp/FastDelegate.aspx