面试题答案
一键面试在C++中,当同时存在函数重载和模板编程时,编译器确定调用哪个函数的过程如下:
- 非模板函数优先:如果有一个普通的非模板函数与调用的参数完全匹配(包括通过隐式类型转换可以匹配),则优先调用非模板函数。
- 模板函数匹配:如果没有找到完全匹配的非模板函数,则寻找模板函数实例化后的版本。编译器会尝试根据实参推导模板参数,找到最佳匹配的模板函数实例化。
- 函数重载解析:如果有多个模板函数或非模板函数都可以匹配调用,则使用函数重载解析规则来决定调用哪个函数。这些规则包括实参匹配的精确程度、类型转换的优先级等。
函数模板、显式实例化、函数重载之间的参数匹配过程示例
// 普通函数
void print(int num) {
std::cout << "普通函数:int " << num << std::endl;
}
// 函数模板
template <typename T>
void print(T value) {
std::cout << "函数模板:" << value << std::endl;
}
// 函数模板的显式实例化
template void print<double>(double value);
// 函数重载
void print(const char* str) {
std::cout << "函数重载:const char* " << str << std::endl;
}
int main() {
print(10); // 调用普通函数,因为有完全匹配的非模板函数
print(3.14); // 调用函数模板的显式实例化版本
print("Hello"); // 调用函数重载版本
print<>(15); // 调用函数模板,<>表示显式指定使用模板函数
return 0;
}
在上述代码中:
print(10)
调用普通函数print(int num)
,因为普通函数与参数完全匹配。print(3.14)
调用函数模板print(T value)
的显式实例化版本template void print<double>(double value);
。print("Hello")
调用函数重载print(const char* str)
。print<>(15)
显式指定调用函数模板print(T value)
,因为<>
表示强制使用模板函数。