函数模板

内容简介

函数模板用于编写类型无关的函数。函数逻辑相同、只是参数类型不同的时候,可以把类型抽象成模板参数。

核心意义

没有模板时,交换 intdouble 需要写两份几乎一样的函数:

void swap_int(int& a, int& b)
{
    int temp = a;
    a = b;
    b = temp;
}
 
void swap_double(double& a, double& b)
{
    double temp = a;
    a = b;
    b = temp;
}

模板把“类型不同”变成编译器处理的问题。

用法

函数模板基本语法:

template <typename T>
void swap_value(T& a, T& b)
{
    T temp = a;
    a = b;
    b = temp;
}

调用方式:

int x = 10;
int y = 20;
swap_value(x, y);       // 自动推导 T 为 int
swap_value<int>(x, y);  // 显式指定 T 为 int

typenameclass 在模板参数中通常等价:

template <class T>
T max_value(T a, T b)
{
    return a > b ? a : b;
}

最佳代码实践

  • 简单模板参数常用 T,多个参数用 KeyValueInputIt 等表达含义。
  • 参数只读时优先传 const T&,避免不必要拷贝。
  • 需要修改实参时传 T&
  • 函数模板适合“逻辑相同,类型不同”的场景。

错误用法

template <typename T>
void swap_value(T& a, T& b)
{
    T temp = a;
    a = b;
    b = temp;
}
 
int n = 10;
char c = 'c';
swap_value(n, c);  // 错误:T 不能同时推导成 int 和 char
template <typename T>
void print_type()
{
    std::cout << "type\n";
}
 
print_type();  // 错误:没有参数,T 无法自动推导
print_type<int>();  // 正确

注意事项

  • 函数模板自动推导时通常不会为了匹配模板参数而做普通函数那样的隐式类型转换。
  • 模板函数只有在被使用时才会实例化。
  • 标准库中的 std::swapstd::maxstd::sort 都大量依赖模板思想。