整数类型的模板函数会导致多个编译实例
Do template functions of integer types lead to multiple compiled instances?
在下面的代码中,模板函数的每个实例化是否会导致单独的编译目标代码?换句话说,如果我有很多像foo<398>()
这样的函数调用,这会使二进制文件的大小爆炸吗?或者编译器在这种情况下可以做一些"聪明的事情"吗?
很抱歉我的问题有点模糊。欢迎指向相应的文档。
template <int N>
int foo()
{
return N;
}
int main()
{
int a = foo<1>();
int b = foo<2>();
std::cout << a << ", " << b << std::endl;
}
在每个翻译单元中,对于每个模板专门化都有一个神奇的实例化点,并且每个翻译单元中每个模板专门化最多一次。
仍然存在一个非常有趣的问题,即不同的翻译单元如何链接在一起(实际上链接器需要知道c++的工作原理和重复数据删除),但至少在tu内部只有一个版本的函数。
(实例化点是两阶段查找的第二阶段发生的时间。因此,您只获得一次错误(在实例化时),而不是每次使用专门化时都得到错误。
是的,每次实例化一个不同的数字将生成新的二进制代码。这是你的例子的修改版本,证明两个函数有不同的地址。
int main()
{
int (*p1)() = &foo<1>;
int (*p2)() = &foo<3>;
std::cout << (void*)(p1) << ", " << (void*)(p2) << std::endl;
}
下面是一个实例:http://ideone.com/w5peQV
编辑:更好的例子是@xaxxon http://godbolt.org/g/DYXtHs
免责声明:你的原始示例和其他类似的琐碎示例是编译器可优化的,函数可能会被优化掉。
但是,如果您使用函数的地址,有更复杂的代码或只是禁用优化,则不能保证它将被优化掉,并且您的编译器将为每次实例化生成代码。
相关文章:
- 针对过时的模板显式实例化进行编译
- 从函数中全局删除并重新实例化数组结构,而无需在编译时知道数组的大小
- 如何构建模板的显式实例化以提高编译速度?
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- C++ 为什么在定义的编译和链接之前引用外部实例的程序
- DLLexport 类模板实例(专用化),减少了仅标头模板库的编译时间
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- 返回实例变量的c++方法可以访问变量中的数据,但不能更改它,但在编译时不会生成错误
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- 在编译时检查未实例化的类模板是否继承自其第一个模板参数
- make_unique 不会为创建单一实例进行编译
- 有没有办法在类实例中存储编译时常量?
- 在预编译标头中实例化模板会缩短编译时间吗?
- Google App Engine 会在实例休眠后缓存编译的 go 代码吗?
- 无法编译包含"if constexpr"的函数模板实例化
- 与模板实例化相关的编译错误
- 编译时检查是否有两个具有相同模板参数的模板实例化
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 为什么可以在编译时访问非常量、非静态成员而无需类的实例
- 整数类型的模板函数会导致多个编译实例