c++ - 当需要稍后再次实例化相同类型时,模板函数的过程是什么

标签 c++ templates

template<typename T>
int fun(T){
  return 0;
}
int main(){
  fun(0); //#1
  fun(1);  //#2 
}

首先,在#1的调用点,编译器需要实例化“int”类型的模板函数(隐式实例化),然后使用“fun(0)”的实例化结果,这个过程是没有的问题,但是在调用#2 时,编译器是否直接使用上述实例化的结果用于#2 或进行任何其他处理(例如编译器将为#2 实例化但找到上面类型“int”的实例化然后停止实例化并使用上面的结果)?换句话说,#1的实例化是否在调用#2时参与重载决议?

更新:
我的另一个问题是,当遇到相同的调用(这里是#2)时,已经实例化(#1 的隐式实例化)是否参与重载决策?

最佳答案

在不属于未评估操作数的表达式中调用函数构成对该函数的 ODR 使用 [basic.def.odr]/3 .一个 odr-use 需要函数的定义才能存在 [basic.def.odr]/4 .由于您的示例未显式专门化或显式实例化函数模板,因此由于在需要定义存在的上下文中被引用,它将被隐式实例化 [temp.inst]/4 .据我所知,这几乎是 C++ 标准对此事的全部规定。

因此,您的编译器如何准确处理这取决于编译器的实现。实际上,我非常怀疑每当源代码中的某些内容需要隐式实例化时,任何理智的实现都会经历完整的模板实例化过程。我不是 clang 也不是 GCC 开发人员,而是基于 quick look在每个源代码中,在我看来,clang 和 GCC 都会简单地记住需要哪些隐式模板实例化,并在翻译单元的末尾实际执行它们,或者检查实例化是否已经存在并只执行实例化一次……

关于c++ - 当需要稍后再次实例化相同类型时,模板函数的过程是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59402327/

相关文章:

c++ - 将 1's and 0' 的数组值转换为二进制

c++ - 表达式后预期为 ';'

c++ - 我可以在不查看每个元素的情况下将 std::vector<Animal*> 转换为 std::vector<Dog*> 吗?

c++ - 需要帮助来理解以下类(class)的目的

C++模板函数指针

c++ - 根据 sizeof 类型的模板特化

c++ - 可以确定使用什么 gcc 版本编译了一个库(.so)?

c++ - 字符串下标超出范围错误

c++ - 为什么从 const 方法返回的 string& 无法编译?

java - 使用 t :pagelink and context 在 Java Tapestry 中创建 anchor 链接