当我可以将对象的实际类型指定为模板参数时内联虚函数
Inlining of virtual function when I can specify the actual type of the object as a template parameter
我有一个虚拟 class Calculator
和一个 class 的示例实现 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(...) ?
在第一个示例中,内联是不可能的,但我认为在第二个示例中,MyCalculator
的 op1()
应该内联在 calculate()
.
中
我的假设是真的吗?
您可以在 C++11 中将虚函数标记为 final
,这意味着您不能在更派生的 class 中覆盖它。然后编译器可以内联这个函数。否则,编译器无法确保您不会使用具有不同覆盖的更派生类型调用它,因此它无法内联。
您可以启用 LTO,
https://gcc.gnu.org/wiki/LinkTimeOptimization,
根据我的阅读(但我自己尚未测试),如果链接器可以检测到实际预期的实现,LTO 可以取消引用虚拟调用,因此那时链接器也可以决定内联函数
我有一个虚拟 class Calculator
和一个 class 的示例实现 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(...) ?
在第一个示例中,内联是不可能的,但我认为在第二个示例中,MyCalculator
的 op1()
应该内联在 calculate()
.
我的假设是真的吗?
您可以在 C++11 中将虚函数标记为 final
,这意味着您不能在更派生的 class 中覆盖它。然后编译器可以内联这个函数。否则,编译器无法确保您不会使用具有不同覆盖的更派生类型调用它,因此它无法内联。
您可以启用 LTO,
https://gcc.gnu.org/wiki/LinkTimeOptimization,
根据我的阅读(但我自己尚未测试),如果链接器可以检测到实际预期的实现,LTO 可以取消引用虚拟调用,因此那时链接器也可以决定内联函数