У меня есть виртуальный класс 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()
из MyCalculator
должен войти внутрь calculate()
,
Мое предположение верно?
Вы можете пометить виртуальную функцию как final
в C ++ 11, что означает, что вы не можете переопределить его в более производном классе. Тогда компилятор может встроить эту функцию. В противном случае компилятор не может быть уверен, что вы не вызываете его с более производным типом с другим переопределением, поэтому он не может быть встроенным.
Вы можете включить LTO,
https://gcc.gnu.org/wiki/LinkTimeOptimization,
из того, что я прочитал (но еще не тестировал сам), LTO может перенаправлять виртуальные вызовы, если компоновщик может обнаружить фактическую предполагаемую реализацию, и, следовательно, в то время компоновщик может также решить встроить функцию