题目
编写程序,设计支持任意数据类型的通用数学比较与交换函数模板 myMax 与 mySwap。深入掌握 C++ 模板参数的自动类型推导(Type Deduction)机制;演示当两个实参类型不完全一致时(如 int 与 double)编译器推导冲突报错的成因;并展示显式模板实参指定(myMax<double>(a, b))与 C++14 引入的尾置返回类型结合 decltype 的多类型模板推导。
输入格式:无需外部输入。
输出格式:输出多种原生类型与自定义类型调用函数模板的执行结果。
数据范围与约定:函数模板具现化(Instantiation)、模板参数推导与类型折叠。
思路与算法
1. 模板具现化的编译期本质
函数模板本身并不是可执行代码,而是一张代码生成蓝图。当代码中调用 myMax(3, 5) 时,编译器在编译期自动生成一份名为 myMax<int>(int, int) 的实体机器码函数。
2. 自动推导的严格无隐式转换性
对于 template<typename T> T myMax(T a, T b),如果调用 myMax(3, 4.5),推导规则不允许为 T 进行隐式类型转换,直接报错 no matching function (deduced conflicting types for T)。
3. 多模板参数与 decltype
使用 template<typename T1, typename T2> auto add(T1 a, T2 b) -> decltype(a + b) 能够让编译器推导出两类型相加后的公共宽类型(如 int + double 返回 double)。
完整程序
#include <iostream>
#include <string>
// 1. 基础单参数函数模板
template <typename T>
const T& myMax(const T& a, const T& b) {
return (a < b) ? b : a;
}
// 2. 双参数泛型模板,返回类型由原表达式自动推导
template <typename T, typename U>
auto mixedAdd(T a, U b) -> decltype(a + b) {
return a + b;
}
int main() {
// 1. 自动推导类型
int i1 = 15, i2 = 42;
std::cout << "整型比较 myMax(15, 42): " << myMax(i1, i2) << "\n";
std::string s1 = "Apple", s2 = "Orange";
std::cout << "字符串字典序 myMax(\"Apple\", \"Orange\"): " << myMax(s1, s2) << "\n\n";
// 2. 混合类型显式指定模板参数,解决推导冲突
int x = 10;
double y = 20.5;
// 显式指定 <double>,强制将 x 隐式转换为 double
double maxVal = myMax<double>(x, y);
std::cout << "显式指定模板实参 myMax<double>(10, 20.5): " << maxVal << "\n\n";
// 3. 混合类型泛型计算
auto sumRes = mixedAdd(100, 3.14159); // 推导为 double
std::cout << "混合计算 mixedAdd(100, 3.14159): " << sumRes << "\n";
return 0;
}运行示例
输出:
整型比较 myMax(15, 42): 42
字符串字典序 myMax("Apple", "Orange"): Orange
显式指定模板实参 myMax<double>(10, 20.5): 20.5
混合计算 mixedAdd(100, 3.14159): 103.142