将类成员函数存储在模板中

时间:2013-07-31 15:55:56

标签: c++ templates

我需要在某处存储一个成员函数指针:

void Class1::function1(int a, int b)
{
  ...
}

struct parameters
{
   int a;
   int b;
}

myStoreClass.store(&Class1::function1, parameters);

然后可以像这样调用它:

myStoreClass.call();

以便使用适当的参数调用函数。

因为它是一个成员函数,我想我也应该存储一个Class1对象指针,但是如何用模板存储一个成员函数指针?

2 个答案:

答案 0 :(得分:0)

您需要参数化成员函数所在的对象类型,并将指针传递给该函数。为了调用成员函数,您还需要传递指向对象的指针以及调用的参数。这是一个示例:

class Foo 
{
public:
    void DoIt (int a, int b)
    {   
    }   
};

class Bar 
{
public:
    void DoItAgain (int x, int y)
    {   
    }   
};

template <typename Obj>
void DoSomething (Obj* that, void (Obj::*fnThat)(int,int), int i, int j)
{
    (that->*fnThat)(i, j); 
}

int main()
{
    Foo foo;
    Bar bar;

    void (Foo::*fnFoo)(int,int) = &Foo::DoIt;

    (foo.*fnFoo)(42,43);

    DoSomething (&foo, fnFoo, 99, 100);
    DoSomething (&bar, &Bar::DoItAgain, 200, 300);
}

答案 1 :(得分:0)

如果您使用的是C ++ 11编译器,那么它非常简单。鉴于此课程:

class Class1 {
public:
    void function1(int a, int b);
};

您可以使用std::bind准备一个电话:

#include <functional>
// ...

Class1 class1Obj;
auto myStore = std::bind(&Class1::function1, &class1Obj, 10, 20);

您可以稍后通过以下方式调用它:

myStore();
// The above has the same effect as:
// class1Obj.function1(10, 20);

你根本不需要StoreClass(它几乎就是std::bind所做的。)

这只是一个例子。您显然需要确保在执行调用时,您在上面示例中调用Class1 :: function1()的Class1实例(class1Obj)仍然存在。

如果您不使用C ++ 11,则可以使用Boost代替:

#include <boost/function.hpp>
#include <boost/bind.hpp>
// ...

boost::function<void()> myStore = boost::bind(&Class1::function1,
                                              &class1Obj, 10, 20);

电话是一样的:

myStore();

在这两种情况下,bind返回的函数类型为void ()。这意味着函数返回void并且不带参数(因为它们已经被bind吞噬了)。所以如果你仍然需要创建一个模板来参数化你可以存储的成员函数调用的类型,你只需要对成员函数的返回类型,而不是它们的参数。例如:

template <typename T>
// ...
std::function<T ()> storedCall;
// or with Boost:
// boost::function<T ()> storedCall;

请注意,Boost.Bind和Boost.Function是仅限标头的库。这意味着它们易于使用,并且根本不需要您链接任何库。