2012-04-14 49 views
2

我如何實例化成員函數指針類爲模板ARG

template <void (*T)(Entity *), typename Caller> 
class Updater 
{ 
public: 
    Updater(Caller c):m_caller(c){} 
    void process(Entity * e) 
    { 
     (m_caller->*T)(e);    //Is this right? 
    } 
private: 
    Caller m_caller; 
}; 

我明白我可以實例像

Foo f; 
Updater<&Foo::Bar> updater(&f); 

假設Foo具有

void Foo::Bar(Entity *e); 

但如果它有想要的方法,怎麼辦?像這樣

template <typename T> 
void Bar(T t); 

我該怎麼辦呢?喜歡這個:?

Foo f; 
Updater<&Foo::Bar<Entity *>> updater(&f); 

當我這樣做是我真正的代碼,我得到

invalid template argument for ..., expected compile-time constant expression

所以2個問題:

1,是(m_caller->*T)(e);正確的?如果不是,我叫它怎麼叫?

2,我該如何實例化它?

+0

確定你在Updater <&Foo :: Bar中沒有空格>>更新器(&f);? – Steed 2012-04-14 13:14:20

+0

@它被稱爲「直角括號」 www2.research.att.c om /〜bs/C++ 0xFAQ.html#括號 – relaxxx 2012-04-14 13:18:15

+0

我不認爲'Updater <&Foo::Bar>'是正確的,&Foo :: Bar是指向成員函數的指針,但是你的模板參數是指向函數的指針,它們不是相同的類型。 – Cosyn 2012-04-14 13:42:14

回答

1
template <typename Caller, void (Caller::*Func)(Entity *)> 
class Updater 
{ 
public: 
    Updater(Caller *c):m_caller(c){} 
    void process(Entity * e) 
    { 
     (m_caller->*Func)(e); // use pointer to member operator ->* 
    } 
private: 
    Caller *m_caller; 
}; 

// call like this 
Foo f; 
Updater<Foo, &Foo::Bar> updater(&f); 
+0

謝謝你,但很少有評論。 1,這調用了非模板版本,我發現,對於模板版本,我必須使用它,如'&Foo2 :: template bar ',和2,'template '不適用於我,我必須切換參數並傳遞它們,你使用哪種編譯器? – relaxxx 2012-04-14 13:43:33

+0

我修復了錯字「Celler」 - >「Caller」。 我想現在應該沒事了...... 我還沒有測試過,但是我之前寫過類似的代碼。 – user2k5 2012-04-14 13:54:53

+0

用msvc2010編譯並得到'錯誤C2653:'調用者':不是類或名稱空間名稱' – relaxxx 2012-04-14 13:59:51

0

編輯:

user2k5編輯他的答案,所以我接受了。

我以前的消息:

感謝user2k5我想通了正確的工作代碼,

工作示例如下:(foo2的可富代替)

#include <iostream> 

struct Entity { int i; }; 

template < typename Caller, void (Caller::*Func)(Entity *)> 
class Updater 
{ 
public: 
    Updater(Caller *c):m_caller(c){} 
    void process(Entity * e) 
    { 
     (m_caller->*Func)(e); 
    } 
private: 
    Caller *m_caller; 
}; 

struct Foo 
{ 
    void bar(Entity * e) 
    { 
     std::cout << e->i << std::endl; 
    } 
}; 

struct Foo2 
{ 
    template <typename T> 
    void bar(T t) 
    { 
     std::cout << t->i << std::endl; 
    } 
}; 

int main() 
{ 
    Foo2 f; 
    Updater<Foo2, &Foo2::template bar<Entity *>> updater(&f); 
    Entity e; 
    e.i = 5; 
    updater.process(&e); 


    return 0; 
}