/*NOTE
請使用g++ 2.95 or higher, Intel C++ 5.0 or higher (6.0 has been released)
編譯,其他主流編譯器無法正確通過, VC 居然出現 26 處錯誤 */
#include < iostream >
#include < utility > //
含 pair 和 make_pairusing namespace std;
template <typename T>
strUCt MemFuncTraits { };
//partial specialization 1
template < typename R, typename O >
struct MemFuncTraits< R (O::*)() /*
指向成員函數指針 */ > { typedef R ReturnType;
typedef O ObjectType;
};
//partial specialization 2
template < typename R, typename O >
struct MemFuncTraits< R (O::*)() const /*
指向成員函數 const 的指針 */ > { typedef R ReturnType;
typedef O ObjectType;
};
//partial specialization 3
template < typename R, typename O, typename P1 >
struct MemFuncTraits< R (O::*)(P1) /*
指向具有參數類型的成員函數指針 */ > { typedef R ReturnType;
typedef O ObjectType;
};
//partial specialization 4
template < typename R, typename O, typename P1 >
struct MemFuncTraits< R (O::*)(P1) const /*
指向具有參數類型的 const 成員函數指針 */ > { typedef R ReturnType;
typedef O ObjectType;
};
template < typename MemFuncPtrType >
class PMFC {
public:
typedef typename MemFuncTraits<MemFuncPtrType>::ObjectType ObjectType;
typedef typename MemFuncTraits<MemFuncPtrType>::ReturnType ReturnType;
typedef std::pair<ObjectType*, MemFuncPtrType> CallInfo;
PMFC(const CallInfo& info) : _callinfo(info) { } //init
//
支持無參數類型,ReturnType = MemFuncPreType ReturnType operator()() const
{ return (_callinfo.first->*_callinfo.second)(); }
// 支持具有參數類型
template <typename Param1Type>
ReturnType operator()(Param1Type p1) const
{ return (_callinfo.first->*_callinfo.second)(p1); }
private:
CallInfo _callinfo;
};
template <typename T>
class SmartPtrBase {
public:
SmartPtrBase(T *p) : ptr(p) { } //init
//partial specialization PMFC
並 重載 operator->*. template <typename MemFuncPtrType>
const PMFC<MemFuncPtrType> operator->*(MemFuncPtrType pmf) const
{ return std::make_pair(ptr, pmf); }
private:
T* ptr;
};
template <typename T>
class SP : private SmartPtrBase<T> { // g++ 3.04
都有錯誤,改為 public,估計是一個 bug。Intel C++沒有錯誤。public:
SP(T *p) : SmartPtrBase<T>(p) { }
using SmartPtrBase<T>::operator->*;
};
class Wombat {
public:
int dig() { cout << "Digging..." << endl; return 1; }
int sleep() { cout << "Sleeping..." << endl; return 5; }
int eat() const { cout << "Eatting..." << endl; return 7; }
int move(int op) { cout << "Moving..." << endl; return 9; }
};
typedef int (Wombat::*PWMF)();
typedef int (Wombat::*PWMFC)() const;
typedef int (Wombat::*PWMF1)(int);
main()
{
SP<Wombat> pw = new Wombat;
PWMF pmf = &Wombat::dig;
(pw->*pmf)(); // Digging...
pmf = &Wombat::sleep;
(pw->*pmf)(); // Sleeping...
PWMFC pmfc = &Wombat::eat;
(pw->*pmfc)(); // Eatting...
PWMF1 pmf1 = &Wombat::move;
(pw->*pmf1)(2); // Eatting...
return 0;
}
return 0;
}