大家好,欢迎来到IT知识分享网。
C++ 11 中,的主要用途大概是声明那些返回值型别依赖于形参型别的函数模板。
举个例子,如果我们想实现一个函数,其形参中包含一个容器(支持方括号下标语法),该函数会在返回下标操作前进行用户验证,同时要求函数的返回值型别必须与下标操作结果的返回值型别相同。
通常含有型别 T 的容器,其 operator[] 会返回 T&。例如:std::deque,std::vector 等,当然对于:std::vector<bool>,对应的 operator[] 会返回一个全新的对象,而不是 bool&。
对于 C++ 11(允许对单表达式的 lambda 式的返回值型别进行推导),可以有下面的写法:(这里使用了返回值型别尾序语法,函数返回值的型别由 decltype(c[i]) 决定,可以使用形参 c,i)
template<typename Container, typename Index> auto authAndAccess(Container& c, Index i) -> decltype(c[i]) // 返回值型别是根据 decltype(c[i]) 推导出来的 { authenticateUser(); return c[i]; }
对于 C++ 14(相比于 C++ 11 扩大了适用范围,对一切 lambda 式,一切函数,多表达式都可以进行返回值型别推导),这意味着可以去掉返回值型别尾序语法,而只保留前导 auto,如下:
template<typename Container, typename Index> auto authAndAccess(Container& c, Index i) -> decltype(c[i]) { authenticateUser(); return c[i]; // 返回值型别是根据 c[i] 推导出来的
}
std::deque<int> d;
...
aurhAndAccess(d, 5) = 10; // 编译不通过,因为 d[5] 本身型别是 int&,但是 aurhAndAccess 的返回值型别是 int(是一个右值),即给右值赋值 10.
事实上,这种返回值型别推导存在问题,因为这里的 auto 型别推导(本质上是模板型别推导)会忽略初始化表达式的引用性(即 c[i] 的引用性)。
因此在 C++14 中,有另一种写法,如下:
template<typename Container, typename Index> decltype(auto) authAndAccess(Container& c, Index i) { authenticateUser(); return c[i]; }
现在,authAndAccess 的返回值型别与 c[i] 的型别保持一致,因为返回值型别推导使用的是 decltype 型别推导规则。
decltype(auto) 是 C++14中的新用法,其中 auto 指定了要实施推导的型别,而推导过程采用的是 decltype的 型别推导规则。
此外,decltype(auto) 并不局限于函数返回值处使用,在变量声明也可使用,如下:
Widget w; const Widget& cw = w; auto myWidget1 = cw; // auto 型别推导:myWidget1 的型别是 Widget decltype(auto) myWidget2 = cw // decltype(auto) 型别推导:myWidget2 的型别是 const Widget&
上述 C++14 的写法还存问题:一个是只能用于左值容器;
为了使函数对右值容器也有作用,可以将函数的形参类型替换为万能应用,当然对万能引用需要使用完美转发来保持型别一致。代码如下:
template<typename Container, typename Index> // C++14 最终写法 decltype(auto) authAndAccess(Container&& c, Index i) { authenticateUser(); return std::forward<Container>(c)[i]; }
template<typename Container, typename Index> // C++11 最终写法
auto authAndAccess(Container&& c, Index i) -> decltype(std::forward<Container>(c)[i]) { authenticateUser(); return std::forward<Container>(c)[i]; }
C++14 支持 decltype(auto),和 auto 一样,它会从其初始化表达式出发来推导型别,但是它的型别推导使用的是 decltype 的规则。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/31197.html