代码之家  ›  专栏  ›  技术社区  ›  Not a real meerkat

非constexpr变量模板的开销是否为零?

  •  1
  • Not a real meerkat  · 技术社区  · 6 年前

    constexpr ?

    template<int N>
    int fat = N*(fat<N-1>);
    
    template<>
    int fat<0> = 1;
    
    int main() {
        return fat<5>;
    }
    

    我的直觉是它会产生这样的东西:

    int fat0 = 1;
    int fat1 = 1*fat0;
    int fat2 = 2*fat1;
    int fat3 = 3*fat2;
    int fat4 = 4*fat3;
    int fat5 = 5*fat4;
    
    int main() {
        return fat5;
    }
    

    我试着去看看 C++ Insights

    template<int N>
    const int fat = N*(fat<N-1>);
    
    template<>
    const int fat<0> = 1;
    
    int main()
    {
      return fat<5>;
    }
    

    ... 一点用都没有。

    我的下一个尝试是使用 godbolt.org ,并查看是否存在任何差异:

    令我惊讶的是, ! 模板版本大致有 双重的

    现在,考虑到零开销原则,这些变量应该做些什么 重要的

    P、 S.:为了进一步伤害我的大脑,MSVC采取了相反的方式,为模板版本生成的程序集实际上是 小3倍 而不是没有模板的版本。不过,我无法从生成的程序集中理解很多内容,所以我把它排除在了主要问题之外。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Oliv    6 年前

    编译器完全按照您的要求执行。变量fat作为外部链接,因此每个实例化都必须可以被任何其他程序访问,这些程序将动态链接到此程序。所以编译器必须生成代码。

    但是如果你申报的话 static remove 额外的实例:

    template<int N>
    static int fat = N*(fat<N-1>);
    
    template<>
    int fat<0> = 1;
    
    int main() {
        return fat<5>;
    }
    

    2016年以来报告的叮当声: bug 29033