c++ decltype关键字的用法
1.decltype关键字的用途是什么
给定变量的名称或者表达式,decltype返回变量或者表达式的类型。如下所示:
constinti=0;//decltype(i)isconstint boolf(constWidget&w);//decltype(w)isconstWidget&,decltype(f)isbool(constWidget&) structPoint{ intx,y;//decltype(Point::x)isint,decltype(Point::y)isint }; Widgetw;//decltype(w)isWidget if(f(w))...//decltype(f(w))isbool templateclassvector{ public: ... T&operator[](std::size_tindex);... }; vector v;//decltype(v)isvector if(v[0]==0)...//decltype(v[0])isint&
2.decltype主要应用场景是模板函数
decltype在实际的开发中主要用于模板函数中,函数的返回值依赖于模板参数类型的情况。如下authAndAccess函数的返回值类型依赖于Container的元素类型。
templateautoauthAndAccess(Container&c,Indexi)->decltype(c[i]){ authenticateUser(); returnc[i]; }
此处的返回值auto并非类型推导的意思,而是C++11中的函数返回类型后置的表达方式,表明函数的返回类型在参数列表之后。函数返回类型后置的优势在于我们可以用函数的参数来指定返回值。
在c++14中auto关键字可以独立用于对函数的返回值进行类型推导,而不必采用c++11中的返回返回类型后置的声明方式:
templateautoauthAndAccess(Container&c,Indexi){ authenticateUser(); returnc[i];//returntypededucedfromc[i] }
但上述写法在实际应用针对具体case可能存在问题,比如如果operator[]返回T&,auto的推导机制会返回T,下面的就会编译失败:
std::dequed; ... authAndAccess(d,5)=10;//returnd[5],thenassign10toit;thiswon'tcompile!
因为根据auto的推导机制,authAndAccess返回的是右值,所以编译不通过。authAndAccess函数需要声明为如下方式才可以保证该示例编译通过。
templatedecltype(auto)authAndAccess(Container&c,Indexi){ authenticateUser(); returnc[i]; }
decltype(auto)不仅仅可以用于函数,也可以用于变量,可以完美推导变量的类型。
Widgetw; constWidget&cw=w; automyWidget1=cw;//autotypededuction:myWidget1'stypeisWidget decltype(auto)myWidget2=cw;//decltypetypededuction:myWidget2'stypeisconstWidget&
再回到authAndAccess函数
templatedecltype(auto)authAndAccess(Container&c,Indexi);
注意到Container是一个非const的左值引用,这意味着用户可以修改Container内元素的值,同时也意味不能传递右值引用给它。
另外右值容器一般是一个临时对象,会在函数调用结束后不久被销毁,所以当用户传入一个右值引用的时候,一般我们要把返回元素拷贝它的一个副本。如何能够在不重载authAndAccess函数的情况下使它同时支持左值和右值呢?答案是通用引用。
templatedecltype(auto)authAndAccess(Container&&c,Indexi);
为了保证推导结果的正确性,需要在实现中增加完美转发(std::forward)功能。
templatedecltype(auto)authAndAccess(Container&&c,Indexi){ authenticateUser(); returnstd::forward (c)[i]; }//c++14版本
templateautoauthAndAccess(Container&&c,Indexi) ->decltype(std::forward (c)[i]) { authenticateUser(); returnstd::forward (c)[i]; }//c++11版本
3.decltype使用的极端case
decltype(auto)f1(){//decltype(x)isint,sof1returnsint intx=0; ... returnx; } decltype(auto)f2(){//decltype((x))isint&,sof2returnsint& intx=0; ... return(x); }
返回了一个局部变量的引用。
4.需要记住的:
1)decltype总是返回与变量或者表达式完全相同的类型;
2)对于类型T的非名称的左值表达式,decltype总是返回T&;
以上就是c++decltype关键字的用法的详细内容,更多关于c++decltype关键字的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。