簡體   English   中英

將類成員函數存儲在模板中

[英]Store class member function in a template

我需要將這樣的成員函數指針存儲在某個地方:

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

struct parameters
{
   int a;
   int b;
}

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

然后可以像下面這樣調用它:

myStoreClass.call();

以便使用適當的參數調用該函數。

由於它是成員函數,我想我也應該存儲Class1對象指針,但是如何將成員函數指針和模板一起存儲呢?

您需要參數化成員函數所在的對象的類型,並將指針傳遞給該函數。 為了調用成員函數,您還需要傳遞一個指向該對象的指針以及該調用的參數。 這是一個示例:

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

如果您使用的是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所做的事情。)

這只是一個例子。 您顯然需要確保在執行調用時(在上面的示例中為class1Obj )上正在調用Class1 :: function1()的Class1實例仍然存在。

如果您不在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是僅標頭的庫。 這意味着它們易於使用,根本不需要您鏈接到任何庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM