模板是 C++ 泛型编程的基石,就像模具一样,填入不同的类型就能得到不同的代码。一个典型的用途是写一个通用的 Swap 函数,避免为 int、double 等分别重载:
template<typename T>
void Swap(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
这里的 typename 也可以用 class,大部分情况下没区别。函数模板本身不是函数,只是蓝图,编译器在调用时根据实参推演类型并生成具体函数,这个过程叫实例化。可以隐式由编译器自动推导,也可以显式通过 Swap<int>(a, b) 指定类型。
在使用模板时,有几点经验值得留意:
- 如果存在同名的非模板函数,并且参数匹配,编译器会优先选择非模板版本。
- 模板函数不允许隐式类型转换,而普通函数可以。比如
Swap(1, 2.0)会编译失败,因为T无法从 int 和 double 同时推演。 - 如果有多个模板可以匹配,选择特化程度最高的。
类模板也类似,定义时用 template<class T1, class T2, ...>,使用时必须带上 < > 显式指定参数,比如 Stack<int> st。类模板名字本身不是真正的类,实例化后的才是。
接下来我们聚焦 std::string。它本质上是 std::basic_string<char> 的别名,掌握它的接口和内部行为对日常开发很有帮助。
构造与赋值
常用的构造函数有几种:
string s1; // 空字符串
string s2(s1); // 拷贝构造
string s3("hello"); // C字符串构造
string s4(s1, pos, len); // 从pos开始取len个字符
string s5(10, 'a'); // 10个'a'
赋值操作符支持直接赋值对象或 const char*,这些都很好理解。
迭代器
string 提供了迭代器,行为类似指针,支持正向和反向遍历。
iterator begin;
;
;
;


