2015-03-22 2 views
0

У меня есть шаблон базовый класс с методом get_p_pow, который вызывается с помощью foo функции:встроенный виртуальный метод в шаблоне класса

template <typename T_container> 
class base {  
    public: 
    int foo() { 
     ... 
     get_p_pow(p_pow, delta_p); 
     ... 
    } 

    ... 

    protected:    
     virtual T_container& get_p_pow(T_container &p_pow, double delta_p) const { 
      p_pow(0) = 1.0; 
      p_pow(1) = delta_p; 
      for (difference_type i = 2; i <= order; ++i) { 
       p_pow(i) *= p_pow(i-1)*delta_p; 
      } 

      return p_pow; 
     } 

    int order; 
}; 

Для некоторых производных классов, значение order устанавливается на определенный номер, так что я могу раскатать петлю, с надеждой, что foo звонки и встраивает развернутую версию:

template <typename T_container> 
class child : public base<T_container> { 
    ... 
    protected:    
     T_container& get_p_pow(T_container &p_pow, double delta_p) const { 
      p_pow(0) = 1.0; 
      p_pow(1) = delta_p; 
      p_pow(2) = p_pow(1)*delta_p; 
      p_pow(3) = p_pow(2)*delta_p; 
      p_pow(4) = p_pow(3)*delta_p; 
      p_pow(5) = p_pow(4)*delta_p; 

      return p_pow; 
     } 
    // order set to 5 in constructor 
}; 

проблема заключается в том, что я знаю, для виртуальных функций, большую часть времени они не могут быть встраиваемыми, unle ss компилятор имеет конкретный экземпляр объекта, а не указатель/ссылку на него. Однако, поскольку base и child являются функциями шаблона, они находятся в файле заголовка, который входит в каждую единицу перевода, которая использует эти классы. Это означает, что компилятор должен знать все, что ему нужно, чтобы поддержать inlining (насколько мне известно, поскольку он не требует отдельной компиляции). Я пробовал это, и в основном функция не встроена, и это не приводит к какой-либо реальной производительности (в дополнение к служебным вызовам функций, я думаю, что конвейерная обработка также разрушается). Есть ли способ поддержать inlining для этой ситуации? Или есть ли какие-либо советы по реализации такого рода вещей?

+0

Окончательное решение о том, что-то встраивается, выполняется компилятором. Какой компилятор вы используете? – Oswald

+0

gcc 4.8.2. Я могу реализовать 'foo()' как виртуальную и вручную переписать разворачиваемый 'get_p_pow()' для скрытых классов только для того, чтобы убедиться, что он встраивается, но это приводит к кучке дублированного кода для 'foo()'. – Justin

ответ

1

В случае виртуальных методов inlining не имеет никакого реального смысла (так как вам потребуется информация о времени выполнения, решить, какой код использовать для inline), поэтому компиляторы генерируют «обычные» методы из такого кода и называет их «регулярно».