2014-11-05 80 views
2

我一直在努力使小代表模板練習1)更好的自己,2)更好地瞭解模板元編程,以及3)甚至可能使用委託對一些事件驅動編程(如我無法訪問標準庫)。據this答案,像下面這樣可以爲功能實現:C++委託行使

template <typename T, typename R, typename ...Args> 
R proxycall(T & obj, R (T::*mf)(Args...), Args &&... args) 
{ 
    return (obj.*mf)(args...); 
} 

proxycall(myobj, &MyObj::func); 

看來,如果編譯器可以計算出返回類型,類類型和參數類型只是路過myobj&MyObj::func到模板。可以在上面相同的方法被用來創建一個委託類(其存儲既一個對象和一個指針到成員函數引用類)?

Delegate d(myobj, &MyObj::func); /* Preferred */ 

Delegate<myobj, &MyObj::func> d; /* Ok */ 

下面的類是我的Delegate類,它有具有指定ReturnType的不幸的副作用,並在相應的成員函數的類型Parameters的。正如我上面看到的那樣,編譯器可以將這些東西計算出來。那麼,我如何讓編譯器幫助我?

template <class Class, typename ReturnType, typename ... Parameters> 
class Delegate { 
    public: 
     typedef ReturnType (Class::*Method)(Parameters ... params); 

     Delegate(Class& ref, Method m) : obj(ref), method(m) {} 
     ReturnType operator()(Parameters ... params) { return (obj.*method)(params...); } 
     ReturnType Invoke(Parameters ... params) { return operator()(params...); } 
    private: 
     Class& obj; 
     Method method; 
}; 

/* Usage */ 
Delegate<MyObj, void> d(myobj, &MyObj::func); 
     ^^^^^^^^^^^ 
      ick 
+0

如果我沒有記錯的話,在'proxycall'你應該有'的std ::向前(參數)...',而不是'ARGS ...'。 – cdhowie 2014-11-05 18:13:14

回答

2
Delegate d(myobj, &MyObj::func); 

基本上,這會使得Delegate獨立於成員函數和它的類的類型。 只有構造函數模板纔會知道返回類型和參數類型。班級沒有。您將需要類型擦除,使委託獨立的內部函數對象的類型的類型 - 基本上你會實現一個std::function其實現解釋here(注意:function不固定在返回或參數類型而言)。

如果你想要的是更好的語法和代碼較少的冗餘,使用工廠模板:

template <typename T, typename R, typename ...Args> 
Delegate<T, R, Args...> make_delegate(T& obj, R (T::*mf)(Args...)) 
{ 
    return {obj, mf}; 
} 

,當與適當的參數調用,返回與正確初始化相應類型的委託。

auto deleg = make_delegate(myobj, &MyObj::func); 
+0

我不認爲你想在'委託'T' '。這違背了你才當即表示一切:) – Barry 2014-11-05 18:37:21

+0

@Barry我確實想在那裏'T',我只是提供了* *了類工廠。這是錯誤的立場,謝謝你的提示。 – Columbo 2014-11-05 18:41:27

+0

約'代表什麼 D';這甚至有可能嗎?我可以將對類的引用和指向成員的指針作爲模板參數傳遞嗎? – thndrwrks 2014-11-05 18:45:31