C++模板带<>与不带<>调用的区别及重载匹配结果异常求助
拆解你的C++模板调用匹配逻辑
我来逐个分析你代码里的每个copy调用,帮你搞懂为什么输出是这样的:
1. copy<int>(1, 2);
你显式指定了模板参数<int>,这相当于直接告诉编译器:“我要调用那个模板版本的copy,并且把T设为int”。哪怕存在一个非模板的copy(int, int),编译器也会优先使用你明确指定的模板实例,所以输出template copy。
2. copy<string>("ha", "ha");
同样,你显式指定了<string>,编译器会直接实例化模板版本的copy<string>(string, string)。虽然你传入的是const char*类型的字符串字面量,但编译器会自动把它们隐式转换成std::string来匹配模板实例的参数类型——因为你已经明确要求用模板版本了,所以不会去匹配非模板的copy(string, string),输出还是template copy。
3. copy("ab", "bc");
这里你没有指定模板参数,传入的是const char*类型的字符串字面量。现在看可用的函数:
- 非模板的
copy(int, int)和copy(string, string)都不直接匹配const char*类型(要匹配string版本需要做隐式转换); - 模板版本可以直接推导出
T为const char*,实现完全匹配,不需要任何转换。
根据C++的重载规则,完全匹配的模板实例比需要隐式转换的非模板函数优先级更高,所以编译器会选择模板版本,输出template copy。
4. copy(1, 2);
这里传入的是int类型参数,现在有两个完全匹配的选项:
- 非模板的
copy(int, int); - 模板推导出来的
copy<int>(int, int)。
C++的重载规则里,非模板函数的优先级高于模板实例化的函数,所以编译器会选非模板的版本,输出int copy。
总结一下核心规则
- 如果你显式指定了模板参数(带
<>),编译器会直接使用对应的模板实例,不会考虑非模板函数; - 没有指定模板参数时,编译器优先选完全匹配的非模板函数;如果没有,再选完全匹配的模板推导实例;最后才会考虑需要隐式转换的函数。
内容的提问来源于stack exchange,提问作者sourcerful
相关产品推荐
相关产品推荐

