理解 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.访问静态变量和实例变量的两种方 ...
最新文章
- 2022-2028年中国环保服务业投资分析及前景预测报告
- 数据库实时转移之Confluent介绍(一)
- mysql having实例_Mysql必读mysql group by having 实例代码
- python聚类分析sklearn_如何使用sklearn k-mean对数据进行聚类分析?
- html获取鼠标按键数,鼠标在IE、Firefox和Opera点击键所对应的数字代码
- linux 从命令行自动识别文件并将其打开的命令
- spss 22 0统计分析从入门到精通_「转需」20+统计分析软件使用工具包,一次全搞定...
- shopxo首页右侧的登录注册板块:如何隐藏或删除?
- T-SQL 操作文件 具体解释
- javascript简单拖拽效果
- 在word表格里打勾和打叉
- 计算机信息管理的检索步骤,信息检索策略与步骤
- 轻量级c语言开发环境,几款轻量级的C/C++编写软件
- 公差基本偏差代号_基本偏差代号怎么确定
- html滤镜菜鸟教程,如何成为风光摄影菜鸟基础拍摄篇
- 基于tiny4412的u-boot移植(二)_ git clone
- 用python实现自动化办公------定时发送微信消息
- 推荐几个浪尖收藏的大数据学习平台
- python抓取微博热搜列表
- JDK Collections.shuffle(List? list, Random rnd)源码分析
热门文章
- 集成算法-随机森林与案例实战-泰坦尼克获救预测
- 网络工程师成长日记402-乌审旗某采气厂项目
- MySQL修改表字段名
- python,基于http协议,最常用的是GET和POST两种方法
- 2018年计算机网络原理自考答案,揭秘:小小的人工耳蜗为何值20万?丢失后需要重新开颅植入?...
- python速度提高了吗_这一行代码,能让你的 Python运行速度提高100倍
- maven工程中tomcat版本不匹配的问题的解决和匹配优化
- 使用 F12 开发人员工具
- 【老物转载】如何学习制作卡拉OK特效
- 艺考生文化课分数线丨各个省份去年的艺考生文化分数线最低分是多少?