C++0x新特性:decltype类型指示符与返回类型后置语法

http://blog.csdn.net/zwvista/article/details/5472096

 

C++0x新特性:decltype类型指示符与返回类型后置语法

分类: C++   1805人阅读  评论(0)  收藏  举报

目录(?)[+]

 

关于decltype关键字

 
decltype是C++0x所引入的用于提取表达式类型的新关键字,其语法形式为:decltype(expression) 。这种语法形式在C++0x草案中被称为decltype类型指示符。
 
根据C++0x最终草案,decltype(e)所提取的类型由以下规则决定:
  1. 如果e是一个没有外层括弧的标识符表达式或者类成员访问表达式,那么decltype(e)就是e所命名的实体的类型。
  2. 如果e是一个函数调用或者一个重载操作符调用(忽略e的外层括弧),那么decltype(e)就是该函数的返回类型。
  3. 否则,假设e的类型是T:若e是一个左值,则decltype(e)就是T&;若e是一个右值,则decltype(e)就是T。
比如,
int a;
int f(void);
decltype(a) x1 = a;   //相当于 int x1 = a;(规则1,e是标识符)
decltype(f()) x2 = a;   //相当于 int x2 = a;(规则2,e是函数调用)
decltype((a)) x3 = a;  //相当于 int& x3 = a;(规则3,e是左值)
decltype(a+1) x4 = a; //相当于 int x4 = a;(规则3,e是右值)
 
注意:decltype(e)中的操作数e仅用于推导类型,编译器不会计算e的值。
 

关于“返回类型后置语法”

 
返回类型后置语法是C++0x所引入的新型函数语法。与传统的C系列函数语法不同,在这一语法中,函数返回类型处于函数声明的末端而不是前端(类似于BASIC或PASCAL)。
其语法形式为:auto 函数名(函数签名) -> 返回类型
 
比如,若使用返回类型后置语法,以下函数声明
void f(int);
就将被改写为:
auto f(int) -> void;
 
C++0x中的lambda表达式也将采用类似的返回类型后置语法,比如:
[](int) -> void{};
 
在后置返回类型(trailing-return-type)这一点上,普通函数与lambda表达式的区别在于:
  1. 前导符不同,lambda表达式使用[] 符号,而普通函数则使用auto关键字。
    注:为达成一致性,曾经有提案建议普通函数也应使用[] 符号作为前导符。(出于美学考虑,该提案未被标准委员会采纳)
  2. lambda表达式的后置返回类型在某些情况下可省略,而普通函数的后置返回类型在任何情况下都不能省略。
    注:为达成一致性,曾经有提案建议普通函数的后置返回类型在同等情况下也应可省略。(出于复杂性考虑,该提案未被标准委员会采纳)
 

联合使用decltype类型指示符与返回类型后置语法

 
在实现泛型算法的函数模板中,decltype类型指示符与返回类型后置语法常被搭配使用,以达到使用函数的形参自动推导返回值类型的目的。比如:
[cpp]  view plain copy
  1. #include <iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. //C++03 version  
  6. template<class R, class T, class U>  
  7. R mul1(T x, U y)  
  8. {  
  9.     return x*y;  
  10. }  
  11.   
  12. //C++0x version  
  13. template<class T, class U>  
  14. auto mul2(T x, U y) -> decltype(x*y)  
  15. {  
  16.     return x*y;  
  17. }  
  18.   
  19.   
  20. int main()  
  21. {  
  22.     cout << mul1<double>(1, 3.0) << endl;  
  23.     cout << mul2(1, 3.0) << endl;  
  24.     return 0;  
  25. }  
试比较上述示例代码所实现的两个泛型乘法函数mul1(C++03版本)和mul2(C++0x版本):
  1. 在C++03版本中,由于缺乏相应的语言设施,mul1函数无从推导返回值的类型,被迫引入了返回值类型R作为模板参数。客户端调用mul1时必须提供返回值类型。
  2. 而在C++0x版本中,通过结合使用decltype类型指示符与返回类型后置语法,mul2函数成功地推导出了返回值的类型。客户端调用mul2时也就无需再提供返回值类型。
    这里使用返回类型后置语法的理由是:用于推导返回类型的形参x与y在函数签名中才得以声明,在auto关键字所处的位置上因尚未进入作用域而无法使用。
 

补记

 
只用decltype而不用返回类型后置语法的解决方案:
[cpp]  view plain copy
  1. template<class T, class U>  
  2. decltype(*(T*)0**(U*)0) mul3(T x, U y)  
  3. {  
  4.     return x*y;  
  5. }  
  6.   
  7. template<class T, class U>  
  8. decltype(std::declval<T>()*std::declval<U>()) mul4(T x, U y)  
  9. {  
  10.     return x*y;  
  11. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值