我的意思是,当您实例化一个不是的模板变量时,究竟会生成什么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生成的(优化的)程序集,看看是否有任何区别:
令我惊讶的是,有!模板版本的组装行数大约是手写版本的两倍。GCC 似乎为每个实例化生成一个额外的“保护变量”。Clang 也这样做。
现在,考虑到零开销原则,这些变量应该做一些重要的事情。具体来说,我在编写“展开”版本时错过了一些东西。我想念的这个“东西”是什么?
PS:为了进一步伤害我的大脑,MSVC 采用了相反的方式,为模板版本生成的程序集实际上比没有模板的版本小 3 倍。不过,我无法从生成的程序集中理解很多,所以我把它排除在主要问题之外。