【问题标题】:inline virtual method in template class模板类中的内联虚方法
【发布时间】: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
};  

问题是,我知道对于虚函数,大多数时候它们不能被内联,除非编译器具有对象的特定实例,而不是指向它的指针/引用。然而,由于basechild 是模板函数,它们位于一个头文件中,该头文件包含在每个使用这些类的翻译单元中。这意味着编译器应该知道支持内联所需的一切(据我所知,因为它不需要单独编译)。我已经尝试过了,基本上该函数没有内联,并且它不会带来任何真正的性能优势(除了函数调用开销之外,我认为流水线也被破坏了)。有没有办法支持这种情况的内联?或者有什么建议可以实现这种东西?

【问题讨论】:

  • 是否内联的最终决定是由编译器完成的。你用的是哪个编译器?
  • gcc 4.8.2。我可以将foo() 实现为虚拟并手动为派生类重写展开的get_p_pow() 以确保它被内联,但这会导致foo() 的一堆重复代码。

标签: c++ templates inline virtual-functions


【解决方案1】:

如果虚方法内联没有实际意义(因为您需要运行时信息来决定使用哪些代码进行内联),因此编译器会从这些代码中生成“正常”方法,并“定期”调用它们。

【讨论】:

    猜你喜欢
    • 2014-02-08
    • 2011-02-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2019-01-01
    相关资源
    最近更新 更多