为了账号安全,请及时绑定邮箱和手机立即绑定

关于decltype获取表达式类型的问题以及decltype和引用

关于decltype获取表达式类型的问题以及decltype和引用

PIPIONE 2019-04-07 11:18:33
1.inta=3;decltype(f())b=a;书上说编译器分析表达式的值,却不实际计算表达式的值,编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为b的类型。那如果代码中没有调用f,decltype是如何获取类型的呢?比如代码:#includeusingnamespacestd;intf(){return1;}intmain(){inta=3;decltype(f())b=a;//这里的decltype是如何获取表达式类型的?return0;}2.decltype(*p)c;//错误,c是int&,必须被初始化书上说“如果表达式的内容是解引用操作,则decltype将得到引用类型。解引用指针可以得到指针所指的对象,而且还能给这个对象赋值。因此,decltype(*p)的结果类型就是int&,而非int”但是这个解释好像也没说明白为什么“c是int&”,int&声明的c可以被赋值,int声明的c也是可以赋值的啊,为什么非要强调是int&呢?ps.参考的书籍是c++primer第五版(中文版)以上问题在中文版page63,英文版page71附近。恳求各位给予答疑,非常感谢!
查看完整描述

2 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

1)你说为什么编译器是如何获取到类型的,首先你要了解声明的本质是什么?
A declaration is a statement in a program that communicates this 
information to the compiler.
摘自Stanford语义分析-Types and Declarations
直白的说,你的f()在声明的那一刻,编译器就已经记住了你所声明的类型。你用decltype的时候,仅仅是直接用了这个结果而已。
这个问题,超出了C++Primer的范畴,你需要学习编译原理。
2)显然,你没搞清楚int与int&的差别。请回到2.3.1References这一节。
Areferencedefinesanalternativenameforanobject.
Areferencemustbeinitialized.
简单说,int&是引用,引用是什么?别名。别名是什么?另一个名字。你必须先有一个对象,才能有另一个名字。所以,你可以写:
inti;
但是你不可以写:
int&ri;//error!!!areferencemustbeinitialized.
回到你的问题。如果是int,decltype(*p)c;不会报错;如果是int&,会报错。
所以强调。
@王子亭提醒我题主可能是不清楚为何返回的是int&,这个可能看过书就比较清楚了,为了更清楚的描述题主的疑问,我将书上这部分代码在此补全:
cppinti=42,*p=&i,&r=i;
decltype(r+0)b;//ok
decltype(*p)c;//error:cisint&andmustbeinitialized.
书上的解释:(抱歉,我只有英文版)
Aswe'veseen,whenwedereferenceapointer,wegettheobjecttowhichthepointerpoints.Moreover,wecanassigntothatobject.Thus,thetypededucedbydecltype(*p)isint&,notplainint.
故,decltype(*p)<==>decltype(&i),你明白这个即可。
据我所知,如果你只看到此书的这个地方,应该还不了解左值和右值的。所以,尽量不要想太多。
若你非要打破沙锅问到底,如@王子亭所言,C++11标准(draftN3690)中是规定这个了的:
7.1.6.2/4
Thetypedenotedbydecltype(e)isdefinedasfollows:
ifeisanunparenthesizedid-expressionoranunparenthesizedclassmemberaccess(5.2.5),decltype(e)isthetypeoftheentitynamedbye.Ifthereisnosuchentity,orifenamesasetofoverloadedfunctions,theprogramisill-formed;
otherwise,ifeisanxvalue,decltype(e)isT&&,whereTisthetypeofe;
otherwise,ifeisanlvalue,decltype(e)isT&,whereTisthetypeofe;
otherwise,decltype(e)isthetypeofe.
Theoperandofthedecltypespecifierisanunevaluatedoperand(Clause5).
                            
查看完整回答
反对 回复 2019-04-07
  • 2 回答
  • 0 关注
  • 455 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信