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, butauto 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 stillauthAndAccess(Container& c, Index i) // requires{ // refinementauthenticateUser();return c[i];}

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

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

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

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

template<typename Container, typename Index> // finaldecltype(auto) // C++14authAndAccess(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 orpointer-> or is a member access expresmember), then the decltype specifies the declared type of theentity specified by this expression.

2) If the argument is any other expression of typeT, then

a) if the value category of expression is xvalue, then the decltype specifiesT&&

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值

人,也总是很难发现自己的错误,

Effective Modern C++》Item 3总结

相关文章:

你感兴趣的文章:

标签云: