Effective Modern C++》Item 3总结

decltype 总结

第一个值得说明的问题是,operator[] on a container of objects of type T typically returns a T&.[]操作符用于储存T类型对象的容器时通常返回T&,具体问题需要具体分析,decltype一个[]操作符,返回类型依赖存储它的容器。vector<bool>就比较特殊。

template<typename Container, typename Index> // works, but
auto authAndAccess(Container& c, Index i) // requires
-> decltype(c[i]) // refinement
{
authenticateUser();
return c[i];
}

这段C++11代码有效,但是存在一下问题,我们使用位置返回类型,并且使用c和i,对于其他函数如果无法获取c和i,那么无法使用decltype。这个方法可以完善。

template<typename Container, typename Index> // C++14;
auto authAndAccess(Container& c, Index i) // not quite
{ // correct
 authenticateUser();
 return c[i]; // return type deduced from c[i]
}


这段C++14代码不正确,从条款一,二可知,auto会把左值引用识别为去掉引用的部分,这里其实我们需要返回左值引用。

template<typename Container, typename Index> // C++14; works,
decltype(auto) // but still
authAndAccess(Container& c, Index i) // requires
{ // refinement
authenticateUser();
return c[i];
}

decltype(auto)终于搞定了,我们不在需要尾置返回类型,并且类型识别为左值引用。但是这个方法仍然需要完善。

因为我们仍然需要面临一个问题,这个模板无法使用右值。所以无法传入一个临时的容器对象。我们需要支持类似下面的操作

std::deque<std::string> makeStringDeque(); // factory function
// make copy of 5th element of deque returned
// from makeStringDeque
auto s = authAndAccess(makeStringDeque(), 5);


那么需要引入新词语,全球通引用和完美转发,今年C++标准委员会开大会,决定把universal references正式更名为forwarding references(转发引用),转发引用一般用与完美转发,需要深入了解一下std::forward和std::move两个函数,以及右值引用和左值引用区别,这个后续条款有讲,并且我也打算专门为右值引用写一片文章。

template<typename Container, typename Index> // final
decltype(auto) // C++14
authAndAccess(Container&& c, Index i) // version
{
 authenticateUser();
 return std::forward<Container>(c)[i];
}


这样一切都搞定了。

最后需要注意一些小问题,比如

int x;

decltype((x)) //type is int&

更详细的细节:

1) If the argument is either the unparenthesised name of an object/function,sion (object.member or pointer-> or is a member access expres member), then the decltype specifies the declared type of the entity specified by this expression.
2) If the argument is any other expression of type T, then
a) if the value category of expression is xvalue, then the decltype specifies T&&
b) if the value category of expression is lvalue, then the decltype specifies T&
c) otherwise, decltype specifies T

除了括号非常特殊以外,decltype((变量,只有名字的表达式))的类型总会是个引用。如果是一个简单的表达式(只有名字这种objec.member也算简单),那么decltype就是返回它的类型。

对于其他任何比较复杂的表达式,遵循2),

这里给出一个英文的连接,供参考什么是左值,右值,x值

http://en.cppreference.com/w/cpp/language/value_category

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值