Item3:Understand decltype

Things to Remember:

  • decltype几乎总是生成变量或者表达式的类型不需要任何的修改。
  • 对于类型T的lvalue表达式(除了名称),decltype总是报告出T&
  • C++14支持decltype(auto),看上去像是类似于auto,能从初始化器推导出类型,但是其遵循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;//decltype(Point::x) is int
    int y;//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& 

 

    在C++11,decltype的主要用途是声明函数模板,函数的返回类型取决于其参数类型。


template<typename Container,typename Index>
auto authAndAccess(Container& c,Index i)
    ->decltype(c[i])
    {
        authenticateUser();
        return c[i];
    }
    //Tips:使用auto和decltype推导类型这个适用于C++11,在C++14标准中已经取消
    //C++14可以直接使用auto

在上述例子中,auto不是用来进行type deduction,而是C++11的新特性trailing return type(尾置返回类型)在作用。

trailing return type 跟在形参列表之后,并且用一个->符号开头。任何函数都可以使用trailing return type,但是返回类型比较复杂的函数使用它最有效。

标准改变:C++11只允许single-statement lambdas被类型推导,C++14则扩展了 所有的lambdas和所有的functions都可以被推导。当然也就包括我们上面例子中的authAndAccess,这就意味着 C++14中我们可以省略 trailing return type类型,只留下auto。实际上,这就意味着编译器可以通过function‘s implement 去推导出function’s return type

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

}

operator[] 对于多数 containers-T 返回一个T&,但是在Item 1中得知,对于template 类型推导,一个初始化表达式的reference-ness是被忽略的。

std::deque<int> d;
authAndAccess(d,5) = 10;//return d[5]
//then assign 10 to it;but this won't compile!

 

d[5]返回是int&,由于auto类型推导,退步为返回int类型。此时作为一个function的返回类型,返回值是一个rvalue,不能被赋值。

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

authAndAccess(d, 5) = 10;//Ok!

 

现在authAndAccess将会真正的c[i]返回的类型。

 

authAndAccess的改进:

上述的例子,都是passed by lvalue-reference-to-non-const,因此返回一个这个容器中元素的引用,允许修改。同时也意味着当前不能传入一个rvalue。Rvalue不能绑定到lvalue引用。(除非是 lvalue-references-to-const)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值