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

1.
inta=3;
decltype(f())b=a;
书上说编译器分析表达式的值,却不实际计算表达式的值,编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为b的类型。那如果代码中没有调用f,decltype是如何获取类型的呢?
比如代码:
#include
usingnamespacestd;
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附近。
恳求各位给予答疑,非常感谢!
PIPIONE
浏览 456回答 2
2回答

慕标5832272

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;//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).
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript