保存函数指针+参数供以后使用

时间:2011-02-07 20:53:05

标签: c++ c++11

我遇到这个问题,其中保存了C ++函数指针,以及一组用于调用它的参数,以便稍后可以调用它。调用代码不知道函数的类型和参数。保存和调用函数指针和参数在我的应用程序中非常重要。界面应如下所示:

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

一个简单的解决方案是将所有这些信息放在仿函数中,每个被调用的函数需要不同的typedef。 C ++ 11允许我使用可变参数模板来做到这一点,所以没关系。

由于函数的类型在调用时是未知的,因此似乎有必要为这些函子创建一个虚拟基类,并使用虚函数调用来调用函子。虚函数调用+堆分配的性能开销太高(我用尽可能少的汇编指令来推动实现这个习惯用法的界限)。所以我需要一个不同的解决方案。

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

您可以使用捕获类型的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. 我给出了两个参数的示例,如果你的编译器支持可变参数模板,你可以使用它们,否则只为每个参数创建一个重载。

答案 1 :(得分: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");

答案 2 :(得分:2)

您将需要一个自定义分配器来匹配您的分配模式。或者,使用编译时多态性将函子的类型传递给调用站点。