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 的规则。
今天的文章理解的英文_decltype读法分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/53398.html