如何使用Member函数指针作为模板arg实例化类

时间:2012-04-14 12:57:50

标签: c++ templates

我有

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,我该如何实例化它?

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

修改

user2k5编辑了他的答案,所以我接受了。

我之前的消息:

感谢user2k5,我找到了正确的工作代码,

工作样本如下:( Foo2可以被Foo取代)

#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;
}