template<typename T>
T max(T a, T b) {
return b < a ? a : b;
}
由于历史原因,除了 typename 之外你还可以使用 class 来定义类型参数。应该优先使用 typename。
在编译阶段,模板并不是被编译成一个可以支持多种类型的实体。而是对每一个用于该模板的类型都会产生一个独立的实体。这个过程叫做实例化。
模板分两步编译:
模板参数由被传递的调用参数决定。
类型推断不适用于默认调用参数:
template<typename T>
void f(T = "");
f(1); // OK: T 推断为 int
f(); // ERROR: 无法推断 T 的类型
// 需要同时给模板参数默认值
template<typename T = std::string>
void f(T = "");
f(); // OK
C++14 起可以使用 auto 推导返回类型:
template<typename T1, typename T2>
auto max(T1 a, T2 b) {
return b < a ? a : b;
}
C++11 中可以使用尾置返回类型:
template<typename T1, typename T2>
auto max(T1 a, T2 b) -> decltype(b<a?a:b) {
return b < a ? a : b;
}
C++11 提供 std::common_type 来指定"更一般类型":
#include <type_traits>
template<typename T1, typename T2>
std::common_type_t<T1,T2> max(T1 a, T2 b) {
return b < a ? a : b;
}