在没有调用开销的类中存储函数

时间:2018-02-26 06:41:04

标签: c++ templates

我想将一个函数或它的引用存储在一个类中作为成员变量。我知道存储函数指针以及std :: function或boosts等价物。但是,我最近read使用指针会导致与模板参数相比的调用开销。在那次搜索中,我偶然发现了this帖子,但是我无法从答案中重现工作代码。以下是我尝试过的一些答案:

template<typename ftype>
class MyClass
{
private:
    ftype func;

public:
    MyClass(ftype func_)
    :func(func_)
    {}
};

double dosth(double x)
{
    return x*x;
}

int main()
{
    MyClass<decltype(dosth)> entity(dosth);
}

然而,它会导致错误:

  

错误:数据成员使用函数类型'double(double)'实例化

     

注意:在模板类'MyClass&lt;的实例化中双(双)&gt;'请求

我不确定确切的问题在哪里,但我希望在编译时输入确切的函数类型。

所以我的问题是:编写一个以某种方式需要重复调​​用(并且只被调用)的函数信息的类,我该怎么做才能避免上述开销?

2 个答案:

答案 0 :(得分:1)

其他评论已经解释了如何编译,但请放心,这不能解决您的性能问题。

首先,你的包装器中仍然有一个函数指针,它与std::function中的函数指针没有多大区别。恭喜重新发明轮子。

模板只会改进事物,如果不仅仅是函数签名,而是实际的函数是模板参数。只有这样,编译器才能在编译时解析函数调用并应用优化,例如内联或静态评估。

缺少这些使得函数指针如此昂贵的优化。实际调用函数指针没有实际影响,即处理器具有分支预测。

答案 1 :(得分:0)

我认为你正在研究一个不存在的问题。从您链接到的问题的accepted answer开始:

+-------------------+--------------+---------------+----------------+
|                   | function ptr | std::function | template param |
+===================+==============+===============+================+
| can capture       |    no(1)     |      yes      |       yes      |
| context variables |              |               |                |
+-------------------+--------------+---------------+----------------+
| no call overhead  |     yes      |       no      |       yes      |
| (see comments)    |              |               |                |
+-------------------+--------------+---------------+----------------+
| can be inlined    |      no      |       no      |       yes      |
| (see comments)    |              |               |                |
+-------------------+--------------+---------------+----------------+
  ...

如果不能支持内联是你唯一的问题,我会说,你没什么可担心的。

当push推进时,您可以在类模板中包含内联函数并使用类模板。

更新,以回应OP的提交。

假设你想使用函数

double square(double in) { return in*in; }

它将被包含在类模板中:

template <typename T> struct Square
{
    T operator() const (T in) { return in*in; }
};

现在您可以使用Square<double>作为类型而不是square作为函数指针。