将函数模板定义为类模板的回调

Defining a function template as a callback for a class template

本文关键字:回调 函数模板 定义      更新时间:2023-10-16

我想定义一个接受相同类型的回调函数的类模板。像这样:

    typedef template<class T> bool CallbackFn( T x );
    template<class T> class MyClass
    {
    public:
        MyClass() {}
        ~MyClass() {}
        void addCallbackFn( CallbackFn* fn ) { callbackFn = fn; }
    private:
        CallbackFn* callbackFn;
    };

它将像这样使用:

    bool testFunctionInt(int x) { return true; }
    bool testFunctionString(std::string x) { return true; }
    MyClass<int> a;
    a.addCallbackFn( testFunctionInt );
    MyClass<std::string> b;
    b.addCallbackFn( testFunctionString );

不幸的是,回调函数无法通过typedef定义为函数模板。

有没有其他方法可以做到这一点?

#include <string>
template <typename T>
class MyClass {
  public:
    typedef bool CallbackFn(T x);
    MyClass() : cb_(NULL) {}
    ~MyClass() {}
    void addCallbackFn(CallbackFn *fn) { cb_ = fn; }
  private:
    CallbackFn *cb_;
};
static bool testFunctionInt(int x) { return true; }
static bool testFunctionString(std::string x) { return true; }
int main()
{
    MyClass<int> a;
    a.addCallbackFn( testFunctionInt );
    MyClass<std::string> b;
    b.addCallbackFn( testFunctionString );
}

像这样在类内移动 typedef:

template<class T> class MyClass
{
public:
    MyClass() {}
    ~MyClass() {}
    typedef bool CallbackFn( typename T x );
    void addCallbackFn( CallbackFn* fn ) { callbackFn = fn; }
    //you could also do this
    typedef bool (*CallbackFnPtr)(typename T x);
    void addCallbackFnPtr(CallbackFnPtr fn ) { callbackFn = fn; }
private:
    CallbackFn* callbackFn;  //or CallbackFnPtr callbackFn;
};

我假设你的意思是MyClass<std::string> b;在你的例子中。

我做了一些更改。

template<class T>
class MyClass
{
public:
    typedef bool (*CallbackFn)( T x );
    MyClass() {}
    ~MyClass() {}
    void addCallbackFn( CallbackFn fn ) { callbackFn = fn; }
private:
    CallbackFn callbackFn;
};
bool testFunctionInt(int x) 
{
    return true; 
}
int main(int argc, char * argv[])
{
    MyClass<int> c;
    c.addCallbackFn(testFunctionInt);
    return 0;
}