【问题标题】:Saving function pointer+arguments for later use保存函数指针+参数供以后使用
【发布时间】:2011-12-19 10:11:52
【问题描述】:

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

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

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

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

有什么想法吗?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      使用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");
      

      【讨论】:

      • 我相信::boost::function::std::tr1::function 做的正是@Hans 不想做的事情。我认为他们使用虚函数和动态分配。
      • @Omnifarious:取决于使用的函数/函子是否有任何动态分配。对于具有少量 POD 类型的函数,它会使用内部存储,但是,是的,它确实利用(非常深)隐藏的各种虚拟表来实际执行函数调用。
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-23
        • 1970-01-01
        • 1970-01-01
        • 2016-07-15
        • 1970-01-01
        • 1970-01-01
        • 2019-08-22
        相关资源
        最近更新 更多