1.2 模板参数推导
Posted rileyye
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.2 模板参数推导相关的知识,希望对你有一定的参考价值。
当我们传入参数调用函数模板时,比如调用 max(),模板参数就被我们传进去的参数类型所决定。如果我们传进去两个 int , C++ 编译器就能推导出 T 是 int 类型的。
然而,T 有可能只是类型的一部分。比如,如果我们把 max() 定义成参数为常引用的函数:
template <typename T> T max(const T& a, const T& b) { return b < a ? a : b; }
如果这时候我们传进 int ,T 也会被推导成 int,因为函数参数和 const int& 匹配。
类型推导期间的类型转化
请注意,在类型推导期间,自动类型转换被限制。
- 当参数是引用类型时,即使是简单的类型转换也不会被推导。模板参数 T 声明的两个参数必须完全匹配。
- 当参数是值类型时,只支持退化的转换。这时候 const 和 volatile 限定被忽略,而 C 风格数组和函数会退化成相应的指针。 对于用相同模板参数 T 声明的两个参数,退化成的类型必须匹配。
例如:
template <typename T> T max(T a, T b); ... int i = 17; const int c = 42; max(i ,c); // 正确 : T 被推导成了 int max(c, c); // 正确 : T 被推导成了 int int& ir = i; max(i, ir); // 正确 : T 被推导成了 int int arr[4]; max(&i, arr); // 正确 : T 被推导成了 int*
然而,下面这些是错误的。
max(4, 7.2); // 错误: T 能被推导成 int 或者 double std::string s; max("hello", s); // 错误:T 能被推导成 const char[6] 或 std::string
有三种方式能解决此类错误:
1. 对参数进行类型转换,让所有参数的类型都与模板匹配。
max( static_cast<double>(4), 7.2); // 正确
2. 指定 T 的类型,以此来防止编译器进行类型推导。
max<double>(4, 7.2); // 正确
3. 给类型可能不同的参数指定不同的模板参数。1.3 节会对此详细说明。 15 章 第7.2 节会详细讨论在类型推导时,类型转换的规则。
默认参数的类型推导
请注意,类型推导并不对默认参数起作用。比如:
template <typename T> void f(T = ""); f(1); // 正确:T 被推导成 int,因此它调用的是 f<int>(1) f(); // 错误:不能推导 T
为了解决此问题,你得为模板参数声明一个默认类型。这在 1.4 节里会讨论到。
template<typename T = std::string> void f(T = ""); ... f(); // 正确
以上是关于1.2 模板参数推导的主要内容,如果未能解决你的问题,请参考以下文章