我可以坚持GCC通过存储的函数指针内联延迟调用吗?

Lig*_*ica 3 c++ c++03

当然,当在该范围(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构造,因此如果编译器无法判断它是否仍未修改,则不会出现问题.