理解 decltype关键字
1. decltype关键字
decltype被称作类型说明符,它的作用是选择并返回操作数的数据类型。
例如
Test2函数的返回值是std::initializer_list类型
std::initializer_list<int> Test2()
{return { 1,2,3 };
}
我们使用一致化初始列表
decltype(Test2()) Arr1 = { 1,2,3 };
可以运行,所以decltype关键字得到了Test2返回值的类型
2.更多的常规例子
const int i = 0; // decltype(i) is const intbool f(const Widget& w); // decltype(w) is const Widget&// decltype(f) is bool(const Widget&)struct Point
{int x, y; // decltype(Point::x) is int
}; // decltype(Point::y) is intWidget w; // decltype(w) is Widgetif (f(w)) … // decltype(f(w)) is booltemplate<typename T> // simplified version of std::vector
class vector
{public:…T& operator[](std::size_t index);…
};vector<int> v; // decltype(v) is vector<int>
…
if (v[0] == 0) … // decltype(v[0]) is int&
3.C11
在C++11中,这个关键字的主要用途是你声明了一个函数模板,该函数模板的返回值依赖于形参类型。
template<typename Container, typename Index> // works, but
auto authAndAccess(Container& c, Index i) // requires-> decltype(c[i]) // refinement
{return c[i];
}
注意
①上述代码中的auto并不代表自动类型推导,他仅代表一种语法
表示正在使用C++11尾置返回类型的语法特性
②尾部返回类型的优点是,函数的参数可以用于指定返回类型
4. C14
C++11允许对单语句的lambda表达式进行类型推导。在C++14中,拓展为所有lambda和所有函数,包括多个语句(甚至多个返回,提供所有产出相同的推导类型)。这就意味着,在C++14中我们可以忽略尾置返回类型,单单只留下auto
template<typename Container, typename Index> // C++14;
auto authAndAccess(Container& c, Index i) // not quite
{ // correctreturn c[i]; // return type deduced from c[i]
}
①使用这种形式,那么auto确实会发生类型推导了
②这就表明 编译器将从函数的实现中推断出函数的返回类型
问题来了 编译器根据auto来进行推断
根据前面的条款,那么会推断成什么呢?
只会返回它的value, 也就是说是一个右值
std::deque<int> d;
…
authAndAccess(d, 5) = 10; // authenticate user, return d[5],// then assign 10 to it;// this won't compile!
那么如何改变这种呢?
template<typename Container, typename Index> // C++14; works,
decltype(auto) // but still
authAndAccess(Container& c, Index i) // requires
{ // refinementauthenticateUser();return c[i];
}
5. decltype(auto)
decltype(auto)的使用不仅仅局限于函数的返回值,也可以用于声明变量
Widget w;
const Widget& cw = w;
auto myWidget1 = cw; // auto type deduction:
// myWidget1's type is Widget
decltype(auto) myWidget2 = cw; // decltype type deduction:// myWidget2's type is// const Widget&
6.再次分析
authAndAccess(Container& c, Index i)
客户可能仅仅想得到一份拷贝
std::deque<std::string> makeStringDeque(); // factory function
// make copy of 5th element of deque returned
// from makeStringDeque
auto s = authAndAccess(makeStringDeque(), 5);
该模板无法为c传入一个右值,因为c是一个引用,所以上述模板仍需要改进
template<typename Container, typename Index> // c is now a
decltype(auto) authAndAccess(Container&& c, // universalIndex i); // reference
现在c是一个通用引用了,可以为c传入右值或者左值
c现在是一个通用引用。在这个模板中,我们不知道正在操作的容器的类型,这也意味着我们对它使用的索引对象的类型同样无知。为了使得它满足各种各样的情况,我们需要再次修改代码:
template<typename Container, typename Index> // final
decltype(auto) // C++14
authAndAccess(Container&& c, Index i) // version
{authenticateUser();return std::forward<Container>(c)[i];
}
C++11可以这么写
template<typename Container, typename Index> // final
auto // C++11
authAndAccess(Container&& c, Index i) // version
-> decltype(std::forward<Container>(c)[i])
{authenticateUser();return std::forward<Container>(c)[i];
}
7.decltype(x) 和 decltype((x))
左值会被decltype推导成引用
int x = 0;
(x);
(x)会被当做成一个左值
decltype(auto) f1()
{int x = 0;…return x; // decltype(x) is int, so f1 returns int
}
decltype(auto) f2()
{int x = 0;…return (x); // decltype((x)) is int&, so f2 returns int&}
f2返回了一个对局部变量的引用,这对C系程序员可谓是灾难了QAQ
8.注意
第二点
int nNum1 = 10;decltype(auto)d = nNum1 = 20;
左值表达式 所以d被推导成int &
nNum1不是表达式 ,而是一个变量名称
decltype(auto)d = nNum1;
d是int
理解 decltype关键字相关推荐
- 【C++】五分钟快速理解decltype与auto
首先来看下这样一段简单的代码: #include <iostream>template <class s1,class s2> typename sum(s1 x, s2 y) ...
- decltype关键字详解
学习目标: 掌握c++ decltype关键字 学习内容: decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导. 既然已经有了 auto ...
- synchronized()_这篇文章带你彻底理解synchronized关键字
Synchronized关键字一直是工作和面试中的重点.这篇文章准备彻彻底底的从基础使用到原理缺陷等各个方面来一个分析,这篇文章由于篇幅比较长,但是如果你有时间和耐心,相信会有一个比较大的收获,所以, ...
- C++11 auto和decltype关键字
auto 可以用 auto 关键字定义变量,编译器会自动判断变量的类型.例如: auto i =100; // i 是 int auto p = new A(); // p 是 A* auto k = ...
- C++decltype关键字
decltype decltype 关键字用于检查实体的声明类型或表达式的类型及值分类. 语法: decltype ( expression ) decltype 使用 // 尾置返回允许我们在参数列 ...
- C++ decltype关键字
C++ decltype关键字 希望根据表达式判定变量类型,但不用表达式的值初始化变量 如果表达式的结果对象能作为一条赋值语句的左值,则表达式将向decltype返回一个引用类型 变量加上括号后会被编 ...
- 对精致码农大佬的 [理解 volatile 关键字] 文章结论的思考和寻找真相
一:背景 1. 讲故事 昨天在园里的编辑头条看到 精致码农大佬 写的一篇题为:[C#.NET 拾遗补漏]10:理解 volatile 关键字 (https://www.cnblogs.com/will ...
- 程序员你真的理解final关键字吗?
文章目录 1.修饰类 2.修饰方法 3.修饰变量 4.final变量修饰变量(成员变量.局部变量) 4.1 final修饰成员变量: 4.2 final修饰局部变量: 5.final变量和普通变量的区 ...
- 深入理解static关键字
文章目录 1.static存在的主要意义 2.static的独特之处 3.static应用场景 4.静态变量和实例变量的概念 5.静态变量和实例变量区别[重点常用] 6.访问静态变量和实例变量的两种方 ...
最新文章
- 程序员必备的20个软件
- 修改默认的pip安装源
- java自学语法_Java自学笔记(一):基础知识
- Struts2学习8--文件上传(多个文件上传)
- SQL中通配符、转义符与[号的使用
- 从手机App通过WebSocket向浏览器推送数据
- IBASE save error
- ivx中字体显示_iVX云服务费用优化 · 上篇
- sharepoint 特别信息 --- 自个乐去吧~~
- 【一天一个C++小知识】009.C++面向对象
- html不建议翻译,[译] 可用但最不常见的 HTML5 标签
- 初识STM32之选型
- c++ 三点求外接圆圆心 3维实现
- 操作系统原理(哈工大-李治军老师)实验三系统调用
- IE11主页被篡改解决方法
- 11.3 leetcode打卡
- 全国第17届计算机辅助设计与图形学(cad/cg)学术会议论文集,征稿资讯-CCF第24届全国计算机辅助设计与图形学学术会议 (CCF CAD/CG 2021)...
- 使用Python读取网易邮箱大师客户端的所有邮件
- 新书推荐:iOS Swift 游戏开发指南
- linux新下载的源码或者官方提供的内核查看具体的内核版本