Update item24.md

This commit is contained in:
猫耳堀川雷鼓 2021-02-28 15:02:21 +08:00 committed by GitHub
parent 7d191847ec
commit 65fc362037
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -90,7 +90,7 @@ public:
}
```
`push_back`函数的形参当然有一个通用引用的正确形式,然而,在这里并没有发生类型推导。因为`push_back`在有一个特定的`vector`实例之前不可能存在,而实例化`vector`时的类型已经决定了`push_back`的声明。也就是说,
`push_back`函数的形参当然有一个通用引用的正确形式,然而,在这里并没有发生类型推导。因为`push_back`在有一个特定的`vector`实例之前不可能存在,而实例化`vector`时的类型已经决定了`push_back`的声明。也就是说,
```cpp
std::vector<Widget> v;
@ -120,23 +120,23 @@ public:
};
```
这儿,类型形参`Args`是独立于`vector`的类型参`T`之外的,所以`Args`会在每次`emplace_back`被调用的时候被推导。(好吧,`Args`实际上是一个参数包,而不是一个类型形参,但是为了讨论之利,我们可以把它当作是一个类型形参。)
这儿,类型形参`Args`是独立于`vector`的类型参`T`之外的,所以`Args`会在每次`emplace_back`被调用的时候被推导。(好吧,`Args`实际上是一个参数包,而不是一个类型形参,但是为了讨论之利,我们可以把它当作是一个类型形参。)
虽然函数`emplace_back`的类型参被命名为`Args`,但是它仍然是一个通用引用,这补充了我之前所说的,通用引用的格式必须是“`T&&`”。 没有任何规定必须使用名字`T`。举个例子,如下模板接受一个通用引用,因为格式(“`type&&`”)是正确的,并且`param`的类型将会被推导(重复一次,不考虑边缘情况,也即当调用者明确给定参数类型的时候)。
虽然函数`emplace_back`的类型参被命名为`Args`,但是它仍然是一个通用引用,这补充了我之前所说的,通用引用的格式必须是“`T&&`”。 没有任何规定必须使用名字`T`。举个例子,如下模板接受一个通用引用,因为格式(“`type&&`”)是正确的,并且`param`的类型将会被推导(重复一次,不考虑边缘情况,也即当调用者明确给定类型的时候)。
```cpp
template<typename MyTemplateType> //param是通用引用
void someFunc(MyTemplateType&& param);
```
我之前提到,类型为`auto`的变量可以是通用引用。更准确地说,类型声明为`auto&&`的变量是通用引用,因为会发生类型推导,并且它们满足正确的格式要求(`T&&`)。`auto`类型的通用引用不如模板函数参数中的通用引用常见但是它们在C++11中常常突然出现。而它们在C++14中出现地更多因为C++14的*lambda*表达式可以声明`auto&&`类型的参。举个例子如果你想写一个C++14标准的*lambda*表达式,来记录任意函数调用花费的时间,你可以这样:
我之前提到,类型为`auto`的变量可以是通用引用。更准确地说,类型声明为`auto&&`的变量是通用引用,因为会发生类型推导,并且它们满足正确的格式要求(`T&&`)。`auto`类型的通用引用不如函数模板形参中的通用引用常见但是它们在C++11中常常突然出现。而它们在C++14中出现得更多因为C++14的*lambda*表达式可以声明`auto&&`类型的参。举个例子如果你想写一个C++14标准的*lambda*表达式,来记录任意函数调用花费的时间,你可以这样:
```cpp
auto timeFuncInvocation =
[](auto&& func, auto&&... params) //C++14
{
start timer;
std::forward<decltype(func)>(func)( //对参数params调用func
std::forward<decltype(func)>(func)( //对params调用func
std::forward<delctype(params)>(params)...
);
stop timer and record elapsed time;