当然,当在该范围(ref)中直接知道内部函数调用时,C++编译器可以内联函数模板中的函数调用.
#include <iostream>
void holyheck()
{
std::cout << "!\n";
}
template <typename F>
void bar(F foo)
{
foo();
}
int main()
{
bar(holyheck);
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我传入holyheck一个类,它存储函数指针(或等效的),然后调用它?我有希望得到内联吗?怎么样?
template <typename F>
struct Foo
{
Foo(F f) : f(f) {};
void calledLater() { f(); }
private:
F f;
};
void sendMonkeys();
void sendTissues();
int main()
{
Foo<void(*)()> f(sendMonkeys);
Foo<void(*)()> g(sendTissues);
// lots of interaction with f and g, not shown here
f.calledLater();
g.calledLater();
}
Run Code Online (Sandbox Code Playgroud)
我的类型Foo旨在隔离大量的逻辑; 它将被实例化几次.调用的特定函数calledLater是实例化之间唯一不同的东西(尽管它在a的生命周期中永远不会改变Foo),因此一半的目的Foo是遵守DRY.(其余的目的是保持这个机制与其他代码隔离.)
但是我不想在这样做时引入实际附加函数调用的开销,因为这都是在程序瓶颈中发生的.
我不会说ASM所以分析编译后的代码对我来说没什么用处.
我的直觉是我没有机会在这里内嵌.
小智 5
如果你真的不需要使用函数指针,那么仿函数应该使优化变得微不足道:
struct CallSendMonkeys {
void operator()() {
sendMonkeys();
}
};
struct CallSendTissues {
void operator()() {
sendTissues();
}
};
Run Code Online (Sandbox Code Playgroud)
(当然,C++ 11有lambdas,但你标记了你的问题C++ 03.)
通过对Foo这些类进行不同的实例化,并且在这些类中没有内部状态,f()不依赖于如何f构造,因此如果编译器无法判断它是否仍未修改,则不会出现问题.