Update item3.md

This commit is contained in:
猫耳堀川雷鼓 2021-03-31 23:05:40 +08:00 committed by GitHub
parent 5886d338fd
commit c8844c50f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -118,7 +118,7 @@ auto s = authAndAccess(makeStringDeque(), 5);
template<typename Containter, typename Index> //现在c是通用引用
decltype(auto) authAndAccess(Container&& c, Index i);
````
在这个模板中我们不知道我们操纵的容器的类型是什么那意味着我们同样不知道它使用的索引对象index objects的类型对一个未知类型的对象使用传值通常会造成不必要的拷贝对程序的性能有极大的影响还会造成对象切片行为参见[item41](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/8.Tweaks/item41.md)),以及给同事落下笑柄。但是就容器索引来说,我们遵照标准模板库对于对于索引的处理是有理由的(比如`std::string``std::vector`和`std::deque`的`operator[]`),所以我们坚持传值调用。
在这个模板中我们不知道我们操纵的容器的类型是什么那意味着我们同样不知道它使用的索引对象index objects的类型对一个未知类型的对象使用传值通常会造成不必要的拷贝对程序的性能有极大的影响还会造成对象切片行为参见[item41](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/8.Tweaks/item41.md)),以及给同事落下笑柄。但是就容器索引来说,我们遵照标准模板库对于索引的处理是有理由的(比如`std::string``std::vector`和`std::deque`的`operator[]`),所以我们坚持传值调用。
然而,我们还需要更新一下模板的实现,让它能听从[Item25](https://github.com/kelthuzadx/EffectiveModernCppChinese/blob/master/5.RRefMovSemPerfForw/item25.md)的告诫应用`std::forward`实现通用引用:
````cpp
@ -146,7 +146,7 @@ authAndAccess(Container&& c, Index i)
为了**完全**理解`decltype`的行为,你需要熟悉一些特殊情况。它们大多数都太过晦涩以至于几乎没有书进行有过权威的讨论,这本书也不例外,但是其中的一个会让我们更加理解`decltype`的使用。
将`decltype`应用于变量名会产生该变量名的声明类型。虽然变量名都是左值表达式,但这不会影响`decltype`的行为。(译者注:这里是说对于单纯的变量名,`decltype`只会返回变量的声明类型)然而,对于比单纯的变量名更复杂的左值表达式,`decltype`可以确保报告的类型始终是左值引用。也就是说,如果一个不是单纯变量名的左值表达式的类型是`T`,那么`decltype`会把这个表达式的类型报告为`T&`。这几乎没有什么太大影响,因为大多数左值表达式的类型天具备一个左值引用修饰符。例如,返回左值的函数总是返回左值引用。
将`decltype`应用于变量名会产生该变量名的声明类型。虽然变量名都是左值表达式,但这不会影响`decltype`的行为。(译者注:这里是说对于单纯的变量名,`decltype`只会返回变量的声明类型)然而,对于比单纯的变量名更复杂的左值表达式,`decltype`可以确保报告的类型始终是左值引用。也就是说,如果一个不是单纯变量名的左值表达式的类型是`T`,那么`decltype`会把这个表达式的类型报告为`T&`。这几乎没有什么太大影响,因为大多数左值表达式的类型天具备一个左值引用修饰符。例如,返回左值的函数总是返回左值引用。
这个行为暗含的意义值得我们注意,在:
````cpp