一次调用的形如f(expr);,编译器用 expr 来推导两个类型: T 和 ParamType。 这些类型经常是不一样的,因为 ParamType 一般带有限定符,如 const 或引用。 T 的类型推导不仅仅依赖于expr的类型, 还依赖于 ParamType的格式。具体需要从三个方面讨论: 如何查看模板类型参数导出的类型的方法 方式1: 见如下连接 How can I see the type deduced for a template type parameter? 方式2: 点击网址打开Compiler查看生成的代码,如下
ParamType 是个指针或引用,但不是万能引用
类型推导步骤为:
若expr具有引用类型,先将引用部分忽略
之后,对expr的类别和ParamType的类别进行匹配来决定T的类别。
情形1 f(T& a)
方式1
使用删除的模板函数
#include
#include
#include
using namespace std;
//情形1
template
void f(T& a)=delete ;
int main() {
int x = 22;
const int lx = x;
const int &rx = x;
int&& rx1 = 27;
const int*px = &x;
int*px1 = &x;
f(x);
f(lx);
f(rx);
f(rx1);
f(px);
f(px1);
f(*px);
f(*px1);
}
编译输出如下:
: In function 'int main()':
:17:6: error: use of deleted function 'void f(T&) [with T = int]'
17 | f(x);
| ~^~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:18:6: error: use of deleted function 'void f(T&) [with T = const int]'
18 | f(lx);
| ~^~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:19:6: error: use of deleted function 'void f(T&) [with T = const int]'
19 | f(rx);
| ~^~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:20:6: error: use of deleted function 'void f(T&) [with T = int]'
20 | f(rx1);
| ~^~~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:21:6: error: use of deleted function 'void f(T&) [with T = const int*]'
21 | f(px);
| ~^~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:22:6: error: use of deleted function 'void f(T&) [with T = int*]'
22 | f(px1);
| ~^~~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:23:6: error: use of deleted function 'void f(T&) [with T = const int]'
23 | f(*px);
| ~^~~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
:24:6: error: use of deleted function 'void f(T&) [with T = int]'
24 | f(*px1);
| ~^~~~~~
:8:6: note: declared here
8 | void f(T& a)=delete ;
| ^
// Compile with /W4
#include
#include
#include
using namespace std;
template
void f4(T&& a)=delete ;
int main() {
int x = 22;
const int lx = x;
const int &rx = x;
const int && yy = 27;
f4(x); // 左值 :T int&; ParamType int &
f4(lx);// 左值 :T const int&; ParamType const int&
f4(rx);// 左值 :T const int&; ParamType const int*
f4(26);// 右值 :T int; ParamType int &&
f4(yy);// 左值 :T const int&; ParamType const int&
}
编译结果如下
: In function 'int main()':
:18:7: error: use of deleted function 'void f4(T&&) [with T = int&]'
...
:19:7: error: use of deleted function 'void f4(T&&) [with T = const int&]'
...
:20:7: error: use of deleted function 'void f4(T&&) [with T = const int&]'
...
:21:7: error: use of deleted function 'void f4(T&&) [with T = int]'
...
:22:7: error: use of deleted function 'void f4(T&&) [with T = const int&]'
...
// Compile with /W4
#include
#include
#include
using namespace std;
template
void f(T a)=delete ;
int main() {
int x = 22;
const int lx = x;
const int &rx = x;
const int && yy = 27;
const char*const ptr = "xi_men_chui_xue";
f(x);
f(lx);
f(rx);
f(26);
f(yy);
f(ptr); //T 为const char *
}
:20:6: error: use of deleted function 'void f(T) [with T = int]'
...
:21:6: error: use of deleted function 'void f(T) [with T = int]'
...
:22:6: error: use of deleted function 'void f(T) [with T = int]'
...
:23:6: error: use of deleted function 'void f(T) [with T = int]'
...
:24:6: error: use of deleted function 'void f(T) [with T = int]'
...
:25:6: error: use of deleted function 'void f(T) [with T = const char*]'
...
注: 在推导过程中,ptr所指内容的常量性会得到保留,但是其自身的常量性被忽略
数组实参
#include
#include
#include
using namespace std;
template
void f(T a){} ;
template
void f1(T& a){} ;
template
constexpr std::size_t arraySize(T (&)[N])noexcept{
return N;
}
int main() {
const char name[]= "xi men chui da xue";
f(name);
f1(name);
arraySize(name);
}