在 C++中, decltype作为 操作符,用于查询 表达式的数据类型。decltype在 C++11标准制定时引入,主要是为 泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以(甚至不可能)表示之的问题。
泛型编程在整个1990年代越发流行,对实现类型推导机制的需求也应运而生。为此,许多编译器厂商都基于程序语言现有的功能,自行实现了这类操作符,其实现如typeof,以及一些功能有限,但更易移植的实现。2002年间, 比雅尼·斯特劳斯特鲁普提议在C++内标准化这类操作符,并将之加入C++;且建议命之为“decltype”,以反映其具有获取表达式的“声明类型”(Declared Type)的功能。

从语义上说,decltype的设计适合于通用库编写者与编程新手。总体上说,对于目标对象或函数,由decltype推导出的类型与源码中的定义可精确匹配。而正如sizeof操作符一样,decltype亦不需对操作数求值。

类似于sizeof 操作符,decltype也不需对其 操作数求值。粗略来说,decltype(e)返回类型前,进行了如下推导:
  1. 若表达式e指向一个 局部变量、 命名空间作用域变量、 静态成员变量或函数参数,那么返回类型即为该变量(或参数)的“声明类型”;
  2. 若e是一个 左值(lvalue,即“可寻址值”),则decltype(e)将返回T&,其中T为e的类型;
  3. 若e是一个x值(xvalue),则 返回值为T&&;
  4. 若e是一个纯 右值(prvalue),则返回值为T。
这些语义是为满足通用库编写者的需求而设计,但由于decltype的返回类型总与对象(或函数)的定义类型相匹配,这对编程新手来说也更为直观。更正式地说,规则1适用于不带括号的标识符表达式(id-expression)与类成员访问表达式。示例如下:
const int&& foo();const int bar();int i;struct A { double x; };
const A* a = new A();
decltype(foo()) x1; // 类型为const int&&
decltype(bar()) x2; // 类型为int
decltype(i) x3; // 类型为int
decltype(a->x) x4; // 类型为double
decltype((a->x)) x5; // 类型为const double&
由上可见,最后两个对decltype的调用,返回结果有所不同。这是因为,带括号的表达式(a->x)既非“标识符表达式”,亦非类访问表达式,因而未指向一个命名对象,而是一个 左值,于是推导类型便为“指向表达式类型的引用”,亦即const double&。
在2008年12月,雅克·雅尔维(Jaakko Järvi)向标准委员会指出一个问题:在C++中,“带限定标识符”(qualified-id)无法由decltype作成,而这正与“decltype(e)可作‘类型定义名’(typedef-name)看待”的设计初衷不一致。在评论标准委员会为 C++0x( C++11前名)制定的正式草案时,日本ISO会员成员提到,“一个定义域 操作符(::)不适用于decltype,但本应适用才对。(若能解决这一问题,则)这在需要从实例中获取成员类型( 嵌套类型)很有用,如下所示”:
vector<int> v;decltype(v)::value_type i = 0; // int i = 0;
这一问题,以及其他相似问题(关于decltype无法在 派生类声明和 析构函数调用中使用),都交由大卫·范德沃德(David Vandevoorde)处理,并在2010年3月投票纳入工作日程表。
#include <algorithm>#include <iostream>#include <iterator>#include <ostream>#include <string>#include <utility>#include <vector>using namespace std;struct Plus {template <typename T, typename U>auto operator()(T&& t, U&& u) const-> decltype(forward<T>(t) + forward<U>(u)) {return forward<T>(t) + forward<U>(u);}};int main() {vector<int> i;i.push_back(1);i.push_back(2);i.push_back(3);vector<int> j;j.push_back(40);j.push_back(50);j.push_back(60);vector<int> k;vector<string> s;s.push_back("cut");s.push_back("flu");s.push_back("kit");vector<string> t;t.push_back("e");t.push_back("ffy");t.push_back("tens");vector<string> u;transform(i.begin(), i.end(), j.begin(), back_inserter(k), Plus());transform(s.begin(), s.end(), t.begin(), back_inserter(u), Plus());for_each(k.begin(), k.end(), [](int n) { cout << n << " "; });cout << endl;for_each(u.begin(), u.end(), [](const string& r) { cout << r << " "; });cout << endl;}

decltype的使用相关推荐

  1. C++关键字decltype

    decltype 关键字用于检查实体的声明类型或表达式的类型及值分类. 语法 decltype ( expression ) 使用 // 尾置返回允许我们在参数列表之后声明返回类型 template ...

  2. C++——auto、decltype、返回类型后置、模板别名:using =、nullptr

    1.3.声明 1.3.1.auto 以前版本关键字auto是一个存储类型说明符,表示动态存储还是静态存储,与static关键字对应,第九章也写了,C++11将其用实现自动类型推断(第三章).必须显示初 ...

  3. C++11 类型推导decltype

    我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行.RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通 ...

  4. C++ decltype类型指示符

    decltype 说明符作用是选择并返回操作数的数据类型: const int ci=0,&pi=ci; decltype(ci) x = 0; //x的类型为 const int declt ...

  5. C++11 新增关键字decltype学习

    decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导. decltype 是"declare type"的缩写,译为&q ...

  6. decltype判断变量或表达式类型

    文章目录 1 decltype判断变量或表达式类型 1 decltype判断变量或表达式类型 在C++11中增加了判断变量或表达式类型的供能,decltype (expr是变量或表达式expr的已声明 ...

  7. c++ decltype

    decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导.不了解 auto 用法的读者请转到<C++ auto>. decltype ...

  8. C++ Primer 5th笔记(2)chapter 2变量和基本类型:constexpr 、auto、类型别名、decltype

    1.constexpr和常量表达式 1.1 常量表达式 定义:变量的值在编译器的时候就可以得到是一个常量 eg. const int i = 0; 1.2 constexpr变量 让编译器来验证变量的 ...

  9. decltype 遇到计算结果为左值的表达式会得到引用类型

    c++11支持用decltype推断变量/表达式的类型,与auto推断不同,decltype并不会计算表达式的值. decltype会准确的返回变量/表达式的类型,即使是数组这种比较复杂的类型也不例外 ...

  10. C++11 auto和decltype关键字

    auto 可以用 auto 关键字定义变量,编译器会自动判断变量的类型.例如: auto i =100; // i 是 int auto p = new A(); // p 是 A* auto k = ...

最新文章

  1. 复习java基础第二天(异常处理)
  2. python待遇如何-Python薪资待遇到底是多少?老男孩python学习
  3. 海量数据处理分析_BI
  4. Spring-boot配置JedisShardInfo
  5. matlab中循环读入文件内容,[转载]Matlab利用load循环读入数据文件
  6. 报名已近500人丨基于AWR/ASH故障分析案例分享
  7. mysql 单表多级查询_mysql单表与多表查询
  8. [leetcode] 140. 单词拆分 II
  9. jquery on()绑定的点击事件在js动态新添加的元素上无效
  10. (六)授权(下):自定义permission
  11. AI Image Enlarger黑科技-人工智能无损放大图片素材不失真
  12. c# .net对接企业微信小助手 接口请求时长预警
  13. matlab动画制作详解
  14. 计算机视频DVI接口,HDMI、DVI 电脑为什么会有这么多种视频接口?
  15. MFC入门(三)-- MFC图片/文字控件(循环显示文字和图片的小程序)
  16. 【服务器数据恢复】存储raid5磁盘阵列数据恢复案例
  17. c语言用指针分离字符串数字与字符,c语言实验报告,指针的应用分别输出字符串中的数字和其他字符(共10篇).docx...
  18. 计算机院校都看重保研er的哪些能力?
  19. NLP:词典加载及切分算法
  20. 虚拟网站禁用php,虚拟主机配置,建议禁止php函数列表,禁用不安全的PHP函数

热门文章

  1. 启明医疗完成对一家脑保护装置生产商的收购
  2. C语言结构体——位段概念的讲解
  3. RXD and functions HDU-6061 NTT
  4. python凯撒加密图片
  5. 目睹鸿蒙开创四大至高位面,第二十三章 鸿蒙四大至高规则
  6. HDF Energy超大规模绿色氢气发电项目破土动工
  7. leetcode算法练习 JavaScript实现
  8. 在linux上用SDKMan对Java进行多版本管理
  9. Python 决策树预测 分类算法
  10. Python:测试代码