为何调用func(1)与func<int>(1)会得到不同结果?
为什么
func(1)和func<int>(1)会调用不同的模板函数? 先看你定义的两个C++模板函数:
template <typename T> void func(T a) { std::cout << "func(T a)" << std::endl; } template <typename T> void func(int a) { std::cout << "func(int a)" << std::endl; }
调用结果确实不同:
func(1); // 调用func(T a) func<int>(1); // 调用func(int a)
核心原因在于编译器的模板参数推导和重载决议规则:
- 对于
func(1)的调用
编译器会尝试为每个模板推导模板参数:
- 第一个模板
template <typename T> void func(T a):实参1是int类型,因此可以直接推导出T=int,生成实例void func(int)。 - 第二个模板
template <typename T> void func(int a):函数参数是固定的int,模板参数T没有出现在函数参数列表中,编译器无法通过实参推导出T的类型,因此这个模板无法参与本次重载决议。
最终只有第一个模板的实例匹配,所以调用func(T a)版本。
- 对于
func<int>(1)的调用
这里显式指定了模板参数T=int,编译器会直接实例化所有符合条件的模板:
- 第一个模板实例化为
void func(int); - 第二个模板实例化为
void func(int);
此时两个模板实例的函数签名完全相同,编译器会通过模板特化优先级来选择:第二个模板的函数参数是固定的int,相比第一个接受任意类型T的通用模板,它属于更特化的版本。在重载决议中,更特化的模板会被优先选择,因此最终调用func(int a)版本。
内容的提问来源于stack exchange,提问作者Chun-Ye Lu
相关产品推荐
相关产品推荐

