【发布时间】:2015-03-22 19:50:55
【问题描述】:
我有一个模板基类,它有一个 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
};
问题是,我知道对于虚函数,大多数时候它们不能被内联,除非编译器具有对象的特定实例,而不是指向它的指针/引用。然而,由于base 和child 是模板函数,它们位于一个头文件中,该头文件包含在每个使用这些类的翻译单元中。这意味着编译器应该知道支持内联所需的一切(据我所知,因为它不需要单独编译)。我已经尝试过了,基本上该函数没有内联,并且它不会带来任何真正的性能优势(除了函数调用开销之外,我认为流水线也被破坏了)。有没有办法支持这种情况的内联?或者有什么建议可以实现这种东西?
【问题讨论】:
-
是否内联的最终决定是由编译器完成的。你用的是哪个编译器?
-
gcc 4.8.2。我可以将
foo()实现为虚拟并手动为派生类重写展开的get_p_pow()以确保它被内联,但这会导致foo()的一堆重复代码。
标签: c++ templates inline virtual-functions