Вставка виртуальной функции, когда я могу указать фактический тип объекта в качестве параметра шаблона

У меня есть виртуальный класс 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(),

Мое предположение верно?

1

Решение

Вы можете пометить виртуальную функцию как final в C ++ 11, что означает, что вы не можете переопределить его в более производном классе. Тогда компилятор может встроить эту функцию. В противном случае компилятор не может быть уверен, что вы не вызываете его с более производным типом с другим переопределением, поэтому он не может быть встроенным.

5

Другие решения

Вы можете включить LTO,

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

из того, что я прочитал (но еще не тестировал сам), LTO может перенаправлять виртуальные вызовы, если компоновщик может обнаружить фактическую предполагаемую реализацию, и, следовательно, в то время компоновщик может также решить встроить функцию

0

По вопросам рекламы [email protected]