2011-02-07 90 views
5

我遇到了這個問題,其中保存了C++函數指針以及一組參數,以便在稍後調用它。調用代碼不知道函數的類型和參數。在我的應用程序中保存和調用函數指針和參數是非常關鍵的性能指標。接口應該是這個樣子:保存函數指針+參數供以後使用

void func(int a, char * b); 
call_this_later(func, 5, "abc"); 

一個簡單的解決辦法是把所有的信息在一個仿函數,要求每個調用的函數不同的typedef。 C++ 11允許我使用可變參數模板來做到這一點,所以這沒問題。

由於調用函數的類型在調用點是未知的,因此似乎有必要爲這些函子創建一個虛擬基類,並使用虛函數調用調用函子。虛函數調用+堆分配的性能開銷太高(我正在儘可能少地使用匯編指令來實現這個習慣用法的邊界)。所以我需要不同的解決方案。

任何想法?

回答

0

您將需要一個自定義分配器來匹配您的分配模式。或者,使用編譯時多態將函子的類型傳遞到調用站點。

3

怎麼樣使用boost::function/boost::bind的解決方案:

void func(int a, char * b); 

boost::function<void()> my_proc = 
    boost::bind(&func, 5, "abc"); 

// then later... 

my_proc(); // calls func(5, "abc"); 
+1

我相信`:: boost :: function`和`:: std :: tr1 :: function`完全符合@Hans不想做的事情。我認爲他們使用虛擬功能和動態分配。 – Omnifarious 2011-02-07 21:36:16

2

你可以用它捕捉類型lambda表達式做到這一點。

template <typename Func, typename Arg1, typename Arg2> 
std::function<void(void)> call_this_later(Func f, Arg1 a1, Arg2 a2) { 
    return [=]() { f(a1, a2); }; // Capture arguments by value 
} 

有幾件事情需要注意:

  1. 我不認爲你可以在這裏使用完美轉發,因爲你必須捕捉到由於未收集垃圾
  2. C++的參數,如果該參數是指針,他們可能指向以後沒有活動的東西。例如,如果您的參數是const char*,那麼可以使用字符串文字,但如果您通過someStdString.c_str()並且該字符串很快就會死亡,則不會。
  3. 我給出了兩個參數的例子,如果你的編譯器支持variadic模板,你可以使用它們,否則只需爲每個參數數量創建一個重載。