2011-02-07 96 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模板,你可以使用它们,否则只需为每个参数数量创建一个重载。