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

时间:2017-04-13 19:54:43

标签: c++

印象中我想要实现的目标:

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检查。

2 个答案:

答案 0 :(得分:1)

要使用指针调用类的不同方法,它将如下所示:

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

答案 1 :(得分:1)

我想你想要一个小助手,它会根据你以前的参数进行检查和行动。

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

ctypes