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/