当我可以将对象的实际类型指定为模板参数时,内联虚函数

时间:2015-05-31 15:02:26

标签: c++ templates inlining

我有一个虚拟课程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内部进行内联。

我的假设是真的吗?

2 个答案:

答案 0 :(得分:5)

您可以在C ++ 11中将虚拟函数标记为final,这意味着您无法在更多派生类中覆盖它。然后编译器可以内联此函数。否则,编译器无法确保您没有使用具有不同覆盖的更多派生类型调用它,因此它无法内联。

答案 1 :(得分:0)

您可以启用LTO,

https://gcc.gnu.org/wiki/LinkTimeOptimization

从我读过的内容(但我自己尚未测试过)如果链接器可以检测到实际的预期实现,LTO可以引导虚拟调用,因此在此时链接器也可以决定内联函数