c++ decltype关键字的用法
1. decltype关键字的用途是什么

给定变量的名称或者表达式,decltype返回变量或者表达式的类型。如下所示:
const int i = 0; // decltype(i) is const int
bool f(const Widget& w); // decltype(w) is const Widget&,decltype(f) is bool(const Widget&)
struct Point {
int x, y; // decltype(Point::x) is int, decltype(Point::y) is int
};
Widget w; // decltype(w) is Widget
if (f(w)) ... // decltype(f(w)) is bool
template<typename T>class vector {
public:
...
T& operator[](std::size_t index);...
};
vector<int> v; // decltype(v) is vector<int>
if (v[0] == 0) ... // decltype(v[0]) is int&
2.decltype主要应用场景是模板函数
decltype在实际的开发中主要用于模板函数中,函数的返回值依赖于模板参数类型的情况。如下authAndAccess函数的返回值类型依赖于Container的元素类型。
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) -> decltype(c[i]) {
authenticateUser();
return c[i];
}
此处的返回值auto并非类型推导的意思,而是C++ 11中的函数返回类型后置的表达方式,表明函数的返回类型在参数列表之后。函数返回类型后置的优势在于我们可以用函数的参数来指定返回值。
在c++ 14中auto关键字可以独立用于对函数的返回值进行类型推导,而不必采用c++ 11中的返回返回类型后置的声明方式:
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) {
authenticateUser();
return c[i]; // return type deduced from c[i]
}
但上述写法在实际应用针对具体case可能存在问题,比如如果operator[]返回T&,auto的推导机制会返回T,下面的就会编译失败:
std::deque<int> d; ... authAndAccess(d, 5) = 10; //return d[5], then assign 10 to it; this won't compile!
因为根据auto的推导机制,authAndAccess返回的是右值,所以编译不通过。authAndAccess函数需要声明为如下方式才可以保证该示例编译通过。
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i){
authenticateUser();
return c[i];
}
decltype(auto)不仅仅可以用于函数,也可以用于变量,可以完美推导变量的类型。
Widget w; const Widget& cw = w; auto myWidget1 = cw; // auto type deduction: myWidget1's type is Widget decltype(auto) myWidget2 = cw; // decltype type deduction: myWidget2's type is const Widget&
再回到authAndAccess函数
template<typename Container, typename Index> decltype(auto) authAndAccess(Container& c, Index i);
注意到Container是一个非const的左值引用,这意味着用户可以修改Container内元素的值,同时也意味不能传递右值引用给它。
另外右值容器一般是一个临时对象,会在函数调用结束后不久被销毁,所以当用户传入一个右值引用的时候,一般我们要把返回元素拷贝它的一个副本。如何能够在不重载authAndAccess函数的情况下使它同时支持左值和右值呢?答案是通用引用。
template<typename Container, typename Index> decltype(auto) authAndAccess(Container&& c,Index i);
为了保证推导结果的正确性,需要在实现中增加完美转发(std::forward)功能。
template<typename Container, typename Index>
decltype(auto)authAndAccess(Container&& c, Index i){
authenticateUser();
return std::forward<Container>(c)[i];
} // c++ 14版本
template<typename Container, typename Index>
auto authAndAccess(Container&& c, Index i)
-> decltype(std::forward<Container>(c)[i])
{
authenticateUser();
return std::forward<Container>(c)[i];
} // c++ 11版本
3. decltype使用的极端case
decltype(auto) f1() { // decltype(x) is int, so f1 returns int
int x = 0;
...
return x;
}
decltype(auto) f2() { // decltype((x)) is int&, so f2 returns int&
int x = 0;
...
return (x);
}
返回了一个局部变量的引用。
4. 需要记住的:
1) decltype总是返回与变量或者表达式完全相同的类型;
2) 对于类型T的非名称的左值表达式,decltype总是返回T&;
以上就是c++ decltype关键字的用法的详细内容,更多关于c++ decltype关键字的资料请关注其它相关文章!
代码知识SEO上一篇 : Java中LinkedList真的是查找慢增删快
下一篇 : 如何让 vim 成为我们的神器(小结)
-
SEO外包最佳选择国内专业的白帽SEO机构,熟知搜索算法,各行业企业站优化策略!
SEO公司
-
可定制SEO优化套餐基于整站优化与品牌搜索展现,定制个性化营销推广方案!
SEO套餐
-
SEO入门教程多年积累SEO实战案例,从新手到专家,从入门到精通,海量的SEO学习资料!
SEO教程
-
SEO项目资源高质量SEO项目资源,稀缺性外链,优质文案代写,老域名提权,云主机相关配置折扣!
SEO资源
-
SEO快速建站快速搭建符合搜索引擎友好的企业网站,协助备案,域名选择,服务器配置等相关服务!
SEO建站
-
快速搜索引擎优化建议没有任何SEO机构,可以承诺搜索引擎排名的具体位置,如果有,那么请您多注意!专业的SEO机构,一般情况下只能确保目标关键词进入到首页或者前几页,如果您有相关问题,欢迎咨询!