-
类型推导
-
类型推导
-
T&
-
说明
argtype
中包含&
,即左值右值和const,volatile,*,none
之类的修饰进行分析.- 这里仅仅部分的案例.
-
分析
- 引用就是指针,指针则会关注指针指向的类型.
- 即对于指针指向内容的约束,只能扩大,不能缩小.
-
概括
- 引用取对象的完整类型.
T = valuetype - argtype
-
案例一分析
template<typename T> void show(const T& a) { // error code a.nice(); } int main() { show(1); }
T = valuetype - argtype = int&& - const &
,利用集合运算. 则T = int
.- 最终的
argtype = const int&
- 因为有
const
所以&&
等价于&
.
-
案例二分析
template<typename T> void show(const T& a) { // error code a.nice(); } int main() { int a = 1; show(a); }
T = valuetype - argtype = int & - const & = int
.则T = int
.- 最终的是
valuetype = const int &
-
案例三分析
template<typename T> void show(T& a) { // error code a.nice(); } int main() { int a = 1; show(a); }
T = valuetype - argtype = int & - & = int
,则T = int
.- 最终的
valuetype = int &
.
-
案例三分析
template<typename T> void show(T& a) { // error code a.nice(); } int main() { const int a = 1; show(a); }
T = valutype - argtype = const int & - & = const int
, 则T = const int
- 最终
valuetype = const int &
-
案例四
template<typename T> void show(T&& a) { // error code a.nice(); } int main() { const int a = 1; show(&a); }
- 这里加入了指针类型,因为指针类型和变量类型是两个独立的存在。
T = valuetype - argtype = const int * && - && = const int *
.
-
总结
- 引用,不论是
&,&&
都可以按照这个表达式进行计算. 但是需要区分右值&&
和万能引用的场景. T&&
是万能,其他格式都是右值引用.
- 引用,不论是
-
-
T*
-
说明
argtype
中的值传递是指针类型。
-
指针类型和指向类型
- 指针类型: 是指针这个变量本身的类型.有对应的修饰。
- 指向类型: 是地址对应的变量是某个类型.
-
概括
- 指针取指向类型,而不是变量本身.
T = valtype - argtype
.- 注意: 变量的引用和指向类型可能会有歧义.
-
案例分析
- 比较好理解的就是
typedef int *int_ptr;
- 即
*int_ptr = int
. - 同理
typedef const int *c_intptr;
,*c_intptr = const int
. - 变量本身的所有的类型修饰一般在对应
*
之后. typedef
的可阅读性变差,C++11
之后就变成使用using
了.
- 比较好理解的就是
-
核心
T&
实际就是*
类型.
-
案例一
template<typename T> void show(T* a) { // error code a.nice(); } int main() { const int a = 1; show(&a); }
&a
是const int * &&
类型.但是argtype
中没有引用所以忽略&&
.- 则
T = valtype - argtype = const int* - * = const int
-
案例二
template<typename T> void show(T* &a) { // error code a.nice(); } int main() { const int a = 1; show(&a); }
- 编译错误,因为
&a
是右值,对变量本身有限制。 - 将
T*&a
改成T*&&a
即可.
- 编译错误,因为
-
案例三
template<typename T> void show(const T* a) { // error code a.nice(); } int main() { const int a = 1; show(&a); }
&a
是const int * &&
类型.但是argtype
中没有引用所以忽略&&
.- 则
T = valtype - argtype = const int* - const* = int
.
-
-
T&&
-
说明
- 万能引用,可以匹配任意类型.
-
核心
- 唯一可以推导出
T
是引用类型的机制.前面的T
都是基本类型。 - 即
T =
里面不存在&
类型. - 比如上面的都是
int,const int
之类,没有&
,万能引用可以.
- 唯一可以推导出
-
简要
- 右值引用仅仅用来匹配右值,太大材小用了,毕竟右值的描述性字段很少,就基础的。
- 用来扩展功能挺好的。
-
概括
- 万能引用形式像右值引用,但是也有右值匹配的功能.
- T = valuetype - argtype.,注意,这里的
& - && = &
-
注意
- 因为右值一般是消亡值,所以可以回收利用资源.
-
案例一
template<typename T> void show(T&& a) { // error code a.nice(); } int main() { const int a = 1; show(&a); }
&a
是const int *&&
.T = valuetype - argtype = const int *&& - && = const int *
.
-
案例二
template<typename T> void show(T&& a) { // error code a.nice(); } int main() { const int a = 1; show(a); }
a
是一个const int &
类型。T = valuetype - argtype = const int & - && = const int &
.
-
案例三
template<typename T> void show(T&& a) { // error code a.nice(); } int main() { show(7); }
7
是int &&
类型.即普通右值.最终有int&&
.T = valuetype - argtype = int && - && = int.
-
-
T
-
说明
- 就是一个值传递,形参.
-
核心
- 形参就是和原本的参数无关,拷贝值,可以随意操作.
-
概要
- 值传递,
valuetype
仅仅保留基础类型. - 不将
const,volatile
之类的修饰用于推测. T = valuetype - valuetype - const volatile XXX
- 值传递,
-
案例一
template<typename T> void show(T a) { // error code a.nice(); } int main() { show(7); }
T = valuetype - argtype = int.
-
案例二
template<typename T> void show(T a) { // error code a.nice(); } int main() { const int a = 1; show(a); }
T = valuetype - argtype = int.
- 去掉了
const
之列的.
-
案例三
template<typename T> void show(T a) { // error code a.nice(); } int main() { const int *a = nullptr; show(a); }
a
是指针,指向的类型是const int *
.T = argtype - valuetype = const int *
- 本身无任何修饰.
-
案例四
template<typename T> void show(const T a) { // error code a.nice(); } int main() { const int *a = nullptr; show(a); }
- 同案例三.只是对入参加了修饰.
-
案例五
template<typename T> void show(T a) { // error code a.nice(); } int main() { const int *const a = nullptr; show(a); }
- 同上,这里加了
a
变量的类型修饰.
- 同上,这里加了
-
案例六
template<typename T> void show(T& a) { // error code a.nice(); } int main() { const int *const a = nullptr; show(a); }
a
是const int *const
类型.const int *
是指向的类型,后面的是const
类型是自身的类型.- 因为这里加了
T&
. T = valuetype - argtype = const int * const& - & = const int * const
.
-
案例七
template<typename T> void show(T& a) { // error code a.nice(); } int main() { const int *volatile a = nullptr; show(a); }
- 和上面略有差异.
a
指向类型还是const int *
,但是本身是一个volatile
修饰的.- 所以
T = valutype - argtype = const int * volatile & - & = const int * volatile
.
-
-
总结
模板类型推导 T
猜你喜欢
转载自blog.csdn.net/rubikchen/article/details/121594635
今日推荐
周排行