我有一个虚拟课程Calculator
和该课程的示例实施MyCalculator
。
template <class T>
class Calculator{
virtual void op1() = 0;
};
template <class T>
class MyCalculator : public Calculator{
void op1(){ do_something(); }
};
当我使用op1()
时,如下面的函数所示,编译器当然不能内联op1()
,因为它是虚拟的:
void calculate(Calculator* calc){
calc->op1();
}
但是,在某些情况下,我知道calc
的实际类型,并且出于性能原因我想内联它。所以我想到了以下想法:
template <class C>
void calculate(C* calc){
calc->op1();
}
我会按如下方式调用此函数:
Calculator c1 = new Calculator();
calculate(c1); // no inling possible in calculate(...)
MyCalculator c2 = new MyCalculator();
calculate(c2); // inlining possible in calculate(...) ?
在第一个示例中,内联是不可能的,但我认为在第二个示例中,op1()
的{{1}}应该在MyCalculator
内部进行内联。
我的假设是真的吗?
答案 0 :(得分:5)
您可以在C ++ 11中将虚拟函数标记为final
,这意味着您无法在更多派生类中覆盖它。然后编译器可以内联此函数。否则,编译器无法确保您没有使用具有不同覆盖的更多派生类型调用它,因此它无法内联。
答案 1 :(得分:0)
您可以启用LTO,
https://gcc.gnu.org/wiki/LinkTimeOptimization,
从我读过的内容(但我自己尚未测试过)如果链接器可以检测到实际的预期实现,LTO可以引导虚拟调用,因此在此时链接器也可以决定内联函数