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 thisinformation 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;//okdecltype(*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/4Thetypedenotedbydecltype(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).
添加回答
举报
0/150
提交
取消