带重载函数的模板实参推导:编译器为何优先选择模板?
为什么第一次调用
fun()时编译器选择模板函数而非void fun(const int*)重载? 先看你的代码:
#include <iostream> struct test { void fun(const int*) { std::cout<<"const int * overload\n"; } template<typename T> void fun(const T&) { std::cout<<"template"<<'\n'; } }; int main(){ test t{}; int * int_ptr; t.fun(int_ptr); const int * const_int_ptr; t.fun(const_int_ptr); }
核心原因:函数重载的匹配优先级与类型转换要求
编译器选择重载函数时,遵循「匹配程度优先,匹配程度相同时非模板优先于模板」的规则:
第一次调用
t.fun(int_ptr):- 非模板函数
void fun(const int*):实参是int*,需要做限定转换——把int*转换成const int*(给指针指向的内容加const属性),这属于一次隐式转换。 - 模板函数:编译器推导模板参数
T为int*,此时函数参数变为int* const &(对int*的const引用),实参int*可以直接绑定到这个参数上,不需要任何类型转换,属于精确匹配。
因为模板函数的匹配程度更高,所以编译器选择它。
- 非模板函数
第二次调用
t.fun(const_int_ptr):- 非模板函数
void fun(const int*)的参数和实参const int*完全匹配,无任何转换。 - 模板函数推导
T为const int*,参数变为const int* const &,也能匹配,但此时两者匹配程度相同,编译器会优先选非模板函数,所以调用的是非模板重载。
- 非模板函数
内容的提问来源于stack exchange,提问作者geniculata
相关产品推荐
相关产品推荐

