我想将一个函数或它的引用存储在一个类中作为成员变量。我知道存储函数指针以及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;'请求
我不确定确切的问题在哪里,但我希望在编译时输入确切的函数类型。
所以我的问题是:编写一个以某种方式需要重复调用(并且只被调用)的函数信息的类,我该怎么做才能避免上述开销?
答案 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推进时,您可以在类模板中包含内联函数并使用类模板。
假设你想使用函数
double square(double in) { return in*in; }
它将被包含在类模板中:
template <typename T> struct Square
{
T operator() const (T in) { return in*in; }
};
现在您可以使用Square<double>
作为类型而不是square
作为函数指针。