干什么成员函数指针模板不克如函数指针模板一样产生大概的扬言方式也

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语言的指针相当之灵巧方便,但也相当好失误。许多C语言初家,甚至C语言老鸟都怪易摔倒在C语言的指针下。但不可否认的是,指针在C语言中之岗位极其重要,也许可以偏激一点的来说:没有指针的C程序不是确实的C程序。
  然而C++的指针也不时吃我平种植束手束脚的感觉。C++比C语言有双重严峻的静态类型,更加强调类型安全,强调编译时检查。因此,对于C语言中尽爱错
用的指针,更是不克放过:C++的指针被分为数据指针,数据成员指针,函数指针,成员函数指针,而且不可知任相互转换。而且这些指针的宣示格式都非雷同:

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

再有一个又要的分是,指针所占用的空间吧非同等了。即使以32位系统面临,所占据的上空啊发出或是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_TIMER消息来点定时器,而是经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中足足用了,但是你只要想用在跨越一个参数的场子,那无非
有一致句子话:不容许的职责。

  是的,在规范C++中,这是勿可能的职责。但业务并无连续悲观的,至少发生过多老三方库提供了逾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