领先的中文IT技术网站    IT技术从现在起飞

飞诺旗下: 技术社区 | 在线电子书 | 在线试题 | 资源下载 | 飞诺搜索 | 技术博客
用户名: 密   码:
   飞诺网 加入收藏
飞诺网 C++ 新闻频道 开发频道 系统频道 服务器 网络频道 网络安全 Java频道 C/C++ PHP开发 电子书 资源下载 社 区 博 客 在线试题
软件编程 C C++ Java VB Delphi Foxpro 汇编语言 游戏开发 移动开发 软件工程师 软工与管理 VC shell编程 C#
编程开发 JAVA C/C++ C++ VC C语言 VB C# Delphi Foxpro 汇编 shell编程 游戏开发 软件工程师 WEB开发 PHP ASP Asp.net JSP AJAX CGI JavaScript HTML CSS 数据库 MSSQL Mysql Oracle Access Sybase DB2 sql2005 Office Word Excel Powerpoint Wps 认证考试 二级C语言 三级网络 程序员 网络工程师 思科认证

您当前的位置:飞诺网 >> c/c++ >> C++技术文章

C++ 0x 之 decltype 和 auto 受 VS 2010 支持

www.firnow.com    时间 : 2009-09-04  作者:匿名   编辑:小张 点击:   [ 评论 ]

文 / 李博(光宇广贞)

       本篇实验平台信息请见《这篇文章》


       在《C++ 0x 新标准全部革新提案文档列表》中,N1478 N1527 N1607 N1705 N1978 N2115 N2343 等文件提案向新标准语言内核中添加 decltype 算符和 auto 关键字(旧体新义)。该提案由 BS 参与设计。decltype 算符用于查询表达式类型;auto 关键字修饰变量声明,指示编译器根据变量的初始化表达式推导变量应有的类型。


       Auto

       关于 auto 关键字的用法定义很明确,也没什么花样。首先是定义变量,这里 auto 其需求、其存在价值、其意义、其用法,和 C# 下的 var 关键字一模儿一样。和 var 一样,auto 声明的变量必须“在声明处完成初始化”,编译器才可根据初始化表达式推导变量的类型。无论 auto 还是 var,都算是强类型与易用性之间的妥协罢。

       不过 C++ 下的 auto 比 C# 下的 var 要麻烦一些。因为 C++ 把“指针、引用、值”在语义上分得太清楚了。所以在使用上,会带来一些困惑,或者用当下流行的词儿,叫“纠结”……比如如下用法:

diyblPic

       在此,var1 和 var2 都会被推导为 int* 型。不过“引用”就另说了,比如如下用法:

diyblPic

       在此,refInt 是 int& 型,而 var3 是 int 型,var4 是 int& 型。我对此的解释是,尽管编译器对“引用”与“指针”的处理方式相同,但是语义上二者相差甚远。“指针”是表示地址的“值”,而“引用”是“值”的别号。不管 refInt 是否引用,处在等号右边,待之以右值,得到的便是其实体(entity type)——若是值,则是值本身;若是引用,则为引用所引之值。所以,auto 只会推导出等号右边的“右值”的实体类型,若需声明为引用,则须显式声明为 auto&。而对 var1 和 var2 来说,都会正确推导出“指针值”类型,var 2 的 auto 后面的 * 就被编译器忽略了。

       噢,对了,还有一个 const,比如如下用法:

diyblPic

       在此,intConst 是 const int 型。var5 为 int 型,var6 为 const int& 型,var7 为 const int 型。很奇怪呵。同理,编译器将只会推导出“右值”的实体类型,也就是 int,那么 var5 和 var7 都好解释了。而 var6 声明为引用,引用的是等号右边的“右值”,既是引用,编译器就会确认引用的是 const int 类型,因故 var6 为 const int& 型。显然 var6 做为引用与要引用的“右值”有关,而 var5 和 var7 和“右值”没有关系。

       注意一:auto 不能做为模板参数。因为这违背了 auto 需要由初始化表达式来推导类型的原则。尽管 BS 一开始设计的时候认为这种用法应该被允许,但是 VS 2010 给以了拒绝。话又说回来了,如下所示,与其写成第一个句子,为何不直接写成第二个的样子呢?

diyblPic

       显然,第二个句子才能体现 auto 的意义和存在价值。

       注意二:auto 不能做为函数的参数类型和返回类型。同样是因为违背了 auto 推导类型的原则。函数在编译时要实例化,此时便需要确定参数的类型,以方便安排内存。声明为 auto 的话如何确定其类型呢?没法确定,所以这样用是不允许的。再说了,如果参数表可以 auto 的话,那倒是比重载函数还要强大了……返回类型更不可以 auto,函数返回值是“右值”,“右值”要提供类型说明的,不可以 auto。

       除了在变量声明处用以声明变量之外,auto 还可以引导一种函数定义式,名为 forwarding function。由于网络翻译混乱,本文对此干脆提出一个自定义的比较“给劲”的叫法——“前导函数”。这个放到 decltype 的介绍中说。

       好像还有件事儿没有交待,auto 关键字原来就有,也用来声明变量,但原先是用来声明“可变局部变量”的,和 static const 关键字相对。问题是,哪个非 static const 的变量不是 auto 的呢?我声明个整型局部变量用 int i 就可以了,几乎没有人写成“规范”的 auto int i 吧。于是,做为 C / C++ 语言中最废的关键字,auto 旧词在新标准中被赋予新义,获得了新生——当然旧生就死了,VS 2010 中再这么写 auto int i 的话会编译报错(注:但是 IDE 不做提示,不能不说 BETA1 版的 VS 2010 挺让人别扭的,同样存在问题的还有右值引用 &&)。


       Decltype

       decltype 就是 declared type 的缩写。先摆出 decltype 的语义三规则(N2343):

       The type denoted by decltype ( e ) is defined as follows:

  1. If e is an id-expression or a class member access, decltype ( e ) is defined as the type of the entity named by e. If there is no such entity, or e names a set of overloaded functions, the program is ill-formed.
  2. If e is a function call or an invocation of an overloaded operator ( parentheses around e are ignored ), decltype ( e ) is defined as the return type of that funcion.
  3. Otherwise, where T is the type of e, if e is an lvalue, decltype ( e ) is defined as T&, otherwise  1 2 3
如果图片或页面不能正常显示请点击这里
C++技术文章推荐文章

文章评论