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

返回值 decltype(表达式)

[返回值的类型是表达式参数的类型]

 

这个可也用来决定表达式的类型,就像Bjarne暗示的一样,如果我们需要去初始化某种类型的变量,auto是最简单的选择,但是如果我们所需的类型不是一个变量,例如返回值这时我们可也试一下decltype。

 

现在我们回看一些例子我们先前做过的,

  1. template <class U, class V>
  2. void Somefunction(U u, V v)
  3. {
  4. result = u*v;//now what type would be the result???
  5. decltype(u*v) result = u*v;//Hmm .... we got what we want
  6. }

在下面的一个段落我将会让你熟悉这个观念用 auto 和 decltype 来声明模板函数的返回值,其类型依靠模板参数。

 

 

1. 如果这个表达式是个函数,decltype 给出的类型为函数返回值的类型。

  1. int add(int i, int j){ return i+j; }
  2. decltype(add(5,6)) var = 5;//Here the type of var is return of add() -> which is int

2.如果表达式是一个左值类型,那么 decltype 给出的类型为表达式左值引用类型。

  1. struct M { double x; };
  2. double pi = 3.14;
  3. const M* m = new M();
  4. decltype( (m->x) ) piRef = pi;
  5. // Note: Due to the inner bracets the inner statement is evaluated as expression,
  6. // rather than member 'x' and as type of x is double and as this is lvale
  7. // the return of declspec is double& and as 'm' is a const pointer
  8. // the return is actually const double&.
  9. // So the type of piRef is const double&

3.非常重要的标记一下,decltype 不会执行表达式而auto会,他仅仅推论一下表达式的类型。

  1. int foo(){}
  2. decltype( foo() ) x; // x is an int and note that
  3. // foo() is not actually called at runtime

跟踪返回类型:

这对 C++ 开发者来说是一个全新的特性,直到现在函数的返回类型必须放在函数名的前面。到了 C++11,我们也可以将函数返回值的类型放在函数声明后,当然仅需要用 auto 替代返回类型。现在我们想知道怎么做,让我们来寻找答案:

  1. template<class U, class V>
  2. ??? Multiply(U u, V v)    // how to specifiy the type of the return value
  3. {
  4. return u*v;
  5. }

我们明显的不能像这样:

  1. template<class U, class V>
  2. decltype(u*v) Multiply(U u, V v)    // Because u & v are not defined before Multiply.
  3. //  What to do...what to do !!!
  4. {
  5. return u*v;
  6. }


这种情况我们可也使用 auto 然后当我们使用 decltype(u*v) 作为返回值这个类型便知晓了.

这是不是很酷?

  1. template<class U, class V>
  2. auto Multiply(U u, V v) -> decltype(u*v)    // Note -> after the function bracet.
  3. {
  4. return u*v;
  5. }

decltype的更多相关文章

  1. C++11特性:decltype关键字

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

  2. C++11 auto and decltype

    1.auto关键字 C++新标准引入auto关键词,此auto与之前C语言的auto意义已经不一样了. 这里的auto是修饰未知变量的类型,编译器会通过此变量的初始化自动推导变量的类型. 例如:aut ...

  3. C++ 11 Template ... 与Decltype 测试

    #include <iostream> #include "string" using namespace std; template<typename T> ...

  4. 不支持C++11 decltype的噩耗

    前言:因为公司现在使用vs2008,所以很多c++11的新特性还未能使用,导致写了很多冤枉代码. 最初引擎的数学库非常简单,使用起来也不方便,例如: float FastLerp(const floa ...

  5. auto与decltype

    今天搜狗笔试的一道选择题,原题给忘了,但记得所考的知识点.知识点很基础,但很容易忽视. 具体内容可参考C++ Primer. auto :变量取auto后,其所对应的类型        auto一般会 ...

  6. Effective Modern C++翻译(4)-条款3:了解decltype

    条款3 了解decltype decltype是一个有趣的东西,给它一个变量名或是一个表达式,decltype会告诉你这个变量名或是这个表达式的类型,通常,告诉你的结果和你预测的是一样的,但是偶尔的结 ...

  7. auto和decltype

    auto 1.编译器通过分析表达式的类型来确定变量的类型,所以auto定义的变量必须有初始值. auto i=; //ok,i为整型 auto j; //error,定义时必须初始化. j=;     ...

  8. C++ Prime:decltype类型指示符

    decltype作用是选择并返回操作数的数据类型. decltype(f()) sum = x; // sum的类型就是函数f的返回类型 如果decltype使用的表达式是一个变量,则decltype ...

  9. 关于auto和decltype

    auto会忽略顶层const,保留底层const ; const int* const p = &i; auto p2 = p; //p2是const int*,不是const int* co ...

随机推荐

  1. IOS基础之 (三) 类的声明和对象的创建

    一 OC类的声明和实现语法 1.接口的声明 @interface NewClassName: ParentClassName { 实例变量 ... } 方法的声明 ... @end //...表示省略 ...

  2. 如何使用MASM来编译、连接、调试汇编语言

    先声明下,本人绝非大虾,也只是菜鸟一个,写此文的目的只是为了加深我对知识的理解罢了.好,进入正题.我是把masm解压后发在D盘中的一个叫masm的文件里,在masm文件里新建个记事本(记事本功能是很强 ...

  3. Android 获取本地图片

    MainActivity.java public class RegisterActivity extends AppCompatActivity { private ImageView iv; @O ...

  4. Android 实现卫星菜单

    步骤:一:自定义ViewGroup 1.自定义属性 a.attr.xml b.在布局文件中使用activity_main.xml c.在自定义控件中进行读取 2.onMeasure 3.onLayou ...

  5. linux学习之用户管理

    用户管理是在root用户下进行相关操作的 1.配置文件路径:         保存用户信息的文件:/etc/passwd         保存密码的文件:/etc/shadow         保存用 ...

  6. html表单验证程序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. CentOS 6.6编译安装Nginx1.6.2+MySQL5.6.21+PHP5.6.3(转)

    vi /etc/sysconfig/iptables #编辑防火墙配置文件 # Firewall configuration written by system-config-firewall # M ...

  8. 安装TFS2008最终版(转载)

    一.安装操作系统:windows server 2003 + Sp2具体步骤: 1.安装windows server 2003时选用工作组(默认为workgroup).由于在工作组环境中部署,因此使用 ...

  9. 关于设置SQLPLUS提示符样式的方法----登陆配置文件,动态加载提示符

    工作中用到 sqlplus mdsoss/mdsoss, 所以来了解一下sqlplus (C shell .cshrc文件里中alisa) 关于设置SQLPLUS提示符样式的方法 12638阅读 1评 ...

  10. poj1013.Counterfeit Dollar(枚举)

    Counterfeit Dollar Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 415  Solved: 237 Description Sally ...