From 822f92ef1b5e1fa080eea8a8987ef4778f1ea015 Mon Sep 17 00:00:00 2001 From: light-city <455954986@qq.com> Date: Thu, 8 Aug 2019 11:09:30 +0800 Subject: [PATCH] update dir --- README.md | 1 + decltype/README.md | 137 ++++++++++++++++++++++++++++++++++++++++++ decltype/decltype | Bin 0 -> 22080 bytes decltype/decltype.cpp | 60 ++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 decltype/README.md create mode 100755 decltype/decltype create mode 100644 decltype/decltype.cpp diff --git a/README.md b/README.md index 7c1a8c4..f741628 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ - [x] [using那些事](./using) - [x] [::那些事](./::) - [x] [enum那些事](./enum) +- [x] [decltype那些事](./decltype) 代码运行: 全部在linux下用vim编写,使用gcc/g++调试!全部可正常运行! diff --git a/decltype/README.md b/decltype/README.md new file mode 100644 index 0000000..07f9c37 --- /dev/null +++ b/decltype/README.md @@ -0,0 +1,137 @@ +# decltype那些事 + +## 关于作者: + +个人公众号: + +![](../img/wechat.jpg) + +## 1.基本使用 +decltype的语法是: + +``` +decltype (expression) +``` + +这里的括号是必不可少的,decltype的作用是“查询表达式的类型”,因此,上面语句的效果是,返回 expression 表达式的类型。注意,decltype 仅仅“查询”表达式的类型,并不会对表达式进行“求值”。 + + +### 1.1 推导出表达式类型 + +``` +int i = 4; +decltype(i) a; //推导结果为int。a的类型为int。 +``` + +### 1.2 与using/typedef合用,用于定义类型。 + +```c++ +using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型 +using ptrdiff_t = decltype((int*)0 - (int*)0); +using nullptr_t = decltype(nullptr); +vectorvec; +typedef decltype(vec.begin()) vectype; +for (vectype i = vec.begin; i != vec.end(); i++) +{ +//... +} +``` + +这样和auto一样,也提高了代码的可读性。 + +### 1.3 重用匿名类型 + +在C++中,我们有时候会遇上一些匿名类型,如: + +```c++ +struct +{ + int d ; + doubel b; +}anon_s; +``` + +而借助decltype,我们可以重新使用这个匿名的结构体: + +```c++ +decltype(anon_s) as ;//定义了一个上面匿名的结构体 +``` + +### 1.4 泛型编程中结合auto,用于追踪函数的返回值类型 + +这也是decltype最大的用途了。 + +```c++ +template +auto multiply(T x, T y)->decltype(x*y) +{ + return x*y; +} +``` + +完整代码见:[decltype.cpp](decltype.cpp) + +## 2.判别规则 + +对于decltype(e)而言,其判别结果受以下条件的影响: + +如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么的decltype(e)就是e所命名的实体的类型。此外,如果e是一个被重载的函数,则会导致编译错误。 +否则 ,假设e的类型是T,如果e是一个将亡值,那么decltype(e)为T&& +否则,假设e的类型是T,如果e是一个左值,那么decltype(e)为T&。 +否则,假设e的类型是T,则decltype(e)为T。 + +标记符指的是除去关键字、字面量等编译器需要使用的标记之外的程序员自己定义的标记,而单个标记符对应的表达式即为标记符表达式。例如: +```c++ +int arr[4] +``` +则arr为一个标记符表达式,而arr[3]+0不是。 + +举例如下: + +```c++ +int i = 4; +int arr[5] = { 0 }; +int *ptr = arr; +struct S{ double d; }s ; +void Overloaded(int); +void Overloaded(char);//重载的函数 +int && RvalRef(); +const bool Func(int); + +//规则一:推导为其类型 +decltype (arr) var1; //int 标记符表达式 + +decltype (ptr) var2;//int * 标记符表达式 + +decltype(s.d) var3;//doubel 成员访问表达式 + +//decltype(Overloaded) var4;//重载函数。编译错误。 + +//规则二:将亡值。推导为类型的右值引用。 + +decltype (RvalRef()) var5 = 1; + +//规则三:左值,推导为类型的引用。 + +decltype ((i))var6 = i; //int& + +decltype (true ? i : i) var7 = i; //int& 条件表达式返回左值。 + +decltype (++i) var8 = i; //int& ++i返回i的左值。 + +decltype(arr[5]) var9 = i;//int&. []操作返回左值 + +decltype(*ptr)var10 = i;//int& *操作返回左值 + +decltype("hello")var11 = "hello"; //const char(&)[9] 字符串字面常量为左值,且为const左值。 + + +//规则四:以上都不是,则推导为本类型 + +decltype(1) var12;//const int + +decltype(Func(1)) var13=true;//const bool + +decltype(i++) var14 = i;//int i++返回右值 +``` + diff --git a/decltype/decltype b/decltype/decltype new file mode 100755 index 0000000000000000000000000000000000000000..fb9f578a277115e8c34da59ea4f0120b5dd4f17e GIT binary patch literal 22080 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 +#include +using namespace std; +/** + * 泛型编程中结合auto,用于追踪函数的返回值类型 + */ +template + +auto multiply(T x, T y)->decltype(x*y) +{ + return x*y; +} + +int main() +{ + int nums[] = {1,2,3,4}; + vector vec(nums,nums+4); + vector::iterator it; + + for(it=vec.begin();it!=vec.end();it++) + cout<<*it<<" "; + cout<