调用作为模板参数给出的另一个类的成员函数

Calling another class's member function that is given as template parameter

本文关键字:另一个 成员 函数 参数 调用      更新时间:2023-10-16

想要实现的目标的印象:

class Foo
{
    void func1(int parameter);
    Bar<func1>  bar1;
    void some_member(int parameter)
    {
        bar1(parameter);  //should call func1 trough template function object bar1.
    }
};

这可能吗?如果是这样,我想看看 Bar 的示例实现。

至于为什么;我有很多这样的成员函数,比如 func1,都带有相同的签名。当要传递的参数为 0 时,前一个非 0应使用参数。我想自动化这个,函数对象可以记住参数并进行 0 检查。

要使用指针调用类的不同方法,它看起来像这样:

class Foo
{
    void (Foo::*bar1)(int);
    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...
    Foo()
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }
    void some_member(int parameter)
    {
        (this->*bar1)(parameter);
    }
};

将其包装在模板中将如下所示(您不能将实际的方法函数指针作为模板参数传递,因为它在编译时不是常量值(:

template<typename T>
struct Bar
{
    typedef void (T::*MethodType)(int);
    T *m_obj;
    MethodType m_method;
    Bar(T *obj)
        : m_obj(obj), m_meth(0)
    {
    }
    Bar& operator=(MethodType rhs)
    {
        m_method = rhs;
        return *this;
    }
    void operator()(int parameter)
    {
        if ((m_obj) && (m_method))
            (m_obj->*m_method)(parameter);
    }
}
class Foo
{
    Bar<Foo> bar1;
    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...
    Foo()
        : bar1(this)
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }
    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

或者,如果希望调用方指定方法类型:

template<typename T, typename MethodType>
struct Bar
{
    T *m_obj;
    MethodType m_method;
    Bar(T *obj)
        : m_obj(obj), m_meth(0)
    {
    }
    Bar& operator=(MethodType rhs)
    {
        m_method = rhs;
        return *this;
    }
    void operator()(int parameter)
    {
        if ((m_obj) && (m_method))
            (m_obj->*m_method)(parameter);
    }
}
class Foo
{
    Bar<Foo, void (Foo::*)(int)> bar1;
    // or:
    // Bar<Foo, decltype(Foo::func1)> bar1;
    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...
    Foo()
        : bar1(this)
    {
        if (condition)
            bar1 = &Foo::func1;
        else if (condition)
            bar1 = &Foo::func2;
        else if (condition)
            bar1 = &Foo::func3;
        ...
    }
    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

话虽如此,在 C++11 及更高版本中,请考虑使用 std::bind()std::function 而不是手动模板,例如:

#include <functional>
using std::placeholders::_1;
class Foo
{
    std::function<void(int)> bar1;
    void func1(int parameter);
    void func2(int parameter);
    void func3(int parameter);
    ...
    Foo()
    {
        if (condition)
            bar1 = std::bind(&Foo::func1, this, _1);
        else if (condition)
            bar1 = std::bind(&Foo::func2, this, _1);
        else if (condition)
            bar1 = std::bind(&Foo::func3, this, _1);
        ...
    }
    void some_member(int parameter)
    {
        bar1(parameter);
    }
};

我认为您想要一个小助手,它将根据您之前的参数进行检查和操作。

下面只是一个想法,你可能需要扩展它。因为在这种情况下您无法将值恢复为零。

struct sample
{
   void func1(int data)
   {
      std::cout << "Func 1 , data = " << data << std::endl;
   }
   void func2(int data)
   {
      std::cout << "Func 2 , data = " << data << std::endl;
   }
};

void invoker(std::function<void(int)> call, int param)
{
   static int _param;
   if (param) _param = param;
   call(_param);
}
int main()
{
   sample s;
   using namespace std::placeholders;
   invoker(std::bind(&sample::func1, &s, _1),1);
   invoker(std::bind(&sample::func2, &s, _1),0);
}
相关文章: