考虑一个模板函数(带有原始模板变量,即非类、非结构模板变量):
#include <iostream>
template <int m, int n>
int f() {
return m+n;
}
int main() {
for (int i=0; i<2; ++i)
for (int j=0; j<2; ++j)
std::cout << f<i,j>() << endl;
}
编译器会生成 4 个 f()
拷贝吗?或者只是 1 个拷贝,其中 m、n 作为“内部”参数?
更新
这段代码似乎无法编译。看来模板变量必须是常量。 (我对此不确定:有人吗?) 如果是这样,很抱歉提出了一个荒谬的问题。
最佳答案
如果你的编译器足够聪明,能够推断出循环是constexpr
,它很可能会展开你的循环并内联函数体。
但是,当您使用 gcc 尝试此操作时,您会收到几个错误,例如
test.cc:230:21: error: the value of 'i' is not usable in a constant expression
std::cout << f < i, j > () << endl;
非 constexpr 模板参数是一个问题,因为模板需要在编译时解析,但编译器将如何解析
std::cin >> a;
f< a, 2 >();
编译器无法做出这个编译时决定并提示。
除了这些明显的问题之外,我认为您的问题是编译器是否会为具有不同参数的模板实例化生成多个代码拷贝。一般来说,答案是是。然而,现代编译器有聪明的方法来
- 检查模板参数是否等效并生成相同的代码
- 通过识别相同部分并删除所有拷贝来折叠二进制代码。
此博客来自Honza Hubička一位 gcc 开发人员对 gcc5 的功能进行了很好的总结。
关于C++ 模板变量代码效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30051633/