2009-12-10 94 views
21

我有一些100%適用於我的用例的代碼。我只是想知道如果有人能解釋如何和爲什麼它的作品。將指向成員函數的指針作爲模板參數傳遞。爲什麼這個工作?

我有一個模板類,它位於一些處理線程和網絡通信的代碼和庫用戶之間,以便將從服務器接收的數據傳遞給用戶。

template <class Bar, 
      class Baz, 
      class BazReturnType, 
      void (Bar::*BarSetterFunction)(const BazReturnType &), 
      BazReturnType (Baz::*BazGetterFunction)(void) const> 
class Foo 
{ 
    Foo(Bar *bar) 
     : m_bar(bar) 
    { 
    } 

    void FooMemberFunction(const Baz *baz) 
    { 
     boost::bind(BarSetterFunction, m_bar, 
        boost::bind(BazGetterFunction, baz)())(); 
    } 

    Bar *m_bar; 
}; 

這個模板實例化,並在圖書館根據使用的類型欄和巴茲的,像這樣:

typedef Foo<MyBar, 
      MyBaz, 
      ReturnTypeFromBazGetterFunction, 
      &MyBar::ActualSetterFunction, 
      &MyBaz::ActualGetterFunction > 
    MyFoo; 

MyBar *bar = new MyBar; 
MyBaz *baz = new MyBaz; 
MyFoo *f = new MyFoo(bar); 
f->FooMemberFunction(baz); 

這一切工作和boost ::綁定調用的getter/setter函數傳遞需要去哪裏的數據。 如何以及爲什麼傳遞指向成員函數的指針作爲模板參數,如在這種情況下工作?


在迴應的意見,我沒有意識到,指向成員函數是有效的模板參數。這不是我以前在「野外」看到的。我試了一下,它工作,但我並沒有期待它。

+1

我不確定我完全理解你在問什麼。指向成員的指針是非類型模板參數的允許類型之一。你只是在標準中尋找這個參考嗎? 14.1/4 [templ.param] – 2009-12-10 17:55:16

回答

34

我認爲這是一個更好的解釋了爲什麼有可能這樣做比「因爲標準是這樣說的」:

它的工作原理的原因是因爲指針到成員是在編譯時已知的常量值(指向成員的指針實際上是類的開始的偏移量)。因此,它們可以用作模板的參數,就像任何其他整數常量一樣。

另一方面,普通指針不是編譯時間常量,因爲它們依賴於只存在於運行時的內存佈局。他們不能成爲模板參數。

+9

+1我爲你的第一句話致敬。 – Mehrdad 2012-08-13 08:42:14

2

當你問「爲什麼東西有效?」的問題時,它意味着它的工作原理對你來說有點令人驚訝。除非你解釋爲什麼你覺得它令人驚訝,否則回答這個問題是不可能的。

爲什麼它有效?因爲語言規範明確地說它應該起作用。除非您更詳細地解釋您的擔憂,否則沒有其他答案。

+0

我想「因爲語言規範這麼說」就是答案。根據標準,我沒有意識到成員函數的指針是有效的模板參數。 – 2009-12-10 18:13:57

相關問題