给一个名字或者表达式,decltype告诉你名字或者表达式的类型,decltype十分诚实,它不会擅自增加或者删除cv标识符、引用标识符等,换句话说,通过decltype得到的类型就是名字或者表达式的类型。(不像模板类型推导和auto推导那样,需要几个因素一起决定被推导类型)可以把decltype也看作一种类型推导法则。
c++11标准中,decltype的作用主要是配合尾置返回类型声明函数模板的返回类型:

template<typename Container,typename Index>
auto authAndAccess(Container& c,Index i) ->decltype(c[i]) {
    autoenticateUser();
    return c[i];
}

c++14标准允许推导函数返回类型,即保留auto,去掉->decltype(c[i])。注:c++14中通过将函数返回类型声明为auto表明这里要进行类型推导,但是反直觉的是,这里的类型推导规则并不是auto类型推导规则,而是采用模板类型推导规则。
authAndAccess函数能够写成如下:

template<typename Container,typename Index>
auto authAndAccess(Container& c,Index i) {
    autoenticateUser();
    return c[i];
}

这个函数其实是有问题的,根据模板类型推导规则,auto这里会被推导为非引用类型,而c[i]返回的是引用类型。如下函数并不能达成目的:

std::deque<int> d;
autoAndAccess(d,5) = 10; //对一个rvalue赋值是不行的。

为了解决这个问题,c++14扩展了新的标识符:decltype(auto),当函数改为以下形式时:

template<typename Container,typename Index>
decltype(auto) authAndAccess(Container& c,Index i) {
    autoenticateUser();
    return c[i];
}

相当于说明函数的返回类型使用decltype类型推导法则,而不是模板类型推导法则,即返回类型是decltype(c[i])。


p__n
491 声望10 粉丝

科学告诉你什么是不可能的;工程则告诉你,付出一些代价,可以把它变成可行,这就是科学和工程不同的魅力。