book: add text about auto as func args

Fixes #180
This commit is contained in:
Changkun Ou
2021-08-11 11:20:57 +02:00
parent 7eeaa7ae4e
commit d472ff1421
3 changed files with 40 additions and 35 deletions

View File

@@ -411,19 +411,20 @@ auto i = 5; // i as int
auto arr = new auto(10); // arr as int * auto arr = new auto(10); // arr as int *
``` ```
> **Note**: `auto` cannot be used for function arguments, so the following Since C++ 20, `auto` can even be used as function arguments. Consider
> is not possible to compile (considering overloading, the following example:
> we should use templates):
> ```cpp
> ```cpp int add(auto x, auto y) {
> int add(auto x, auto y); return x+y;
> }
> 2.6.auto.cpp:16:9: error: 'auto' not allowed in function prototype
> int add(auto x, auto y) { auto i = 5; // type int
> ^~~~ auto j = 6; // type int
> ``` std::cout << add(i, j) << std::endl;
> ```
> In addition, `auto` cannot be used to derive array types:
> **Note**: `auto` cannot be used to derive array types yet:
> >
> ```cpp > ```cpp
> auto auto_arr2[10] = {arr}; // illegal, can't infer array type > auto auto_arr2[10] = {arr}; // illegal, can't infer array type

View File

@@ -348,17 +348,21 @@ auto i = 5; // i 被推导为 int
auto arr = new auto(10); // arr 被推导为 int * auto arr = new auto(10); // arr 被推导为 int *
``` ```
> **注意**`auto`能用于函数传参,因此下面的做法是无法通过编译的(考虑重载的问题,我们应该使用模板) 从 C++ 20 起,`auto` 甚至能用于函数传参,考虑下面的例子
```cpp
int add(auto x, auto y) {
return x+y;
}
auto i = 5; // 被推导为 int
auto j = 6; // 被推导为 int
std::cout << add(i, j) << std::endl;
```
> >
> ```cpp > **注意**`auto` 还不能用于推导数组类型:
> int add(auto x, auto y);
>
> 2.6.auto.cpp:16:9: error: 'auto' not allowed in function prototype
> int add(auto x, auto y) {
> ^~~~
> ```
>
> 此外,`auto` 还不能用于推导数组类型:
> >
> ```cpp > ```cpp
> auto auto_arr2[10] = {arr}; // 错误, 无法推导数组元素类型 > auto auto_arr2[10] = {arr}; // 错误, 无法推导数组元素类型
@@ -415,7 +419,7 @@ R add(T x, U y) {
> 注意typename 和 class 在模板参数列表中没有区别,在 typename 这个关键字出现之前,都是使用 class 来定义模板参数的。但在模板中定义有[嵌套依赖类型](http://en.cppreference.com/w/cpp/language/dependent_name#The_typename_disambiguator_for_dependent_names)的变量时,需要用 typename 消除歧义 > 注意typename 和 class 在模板参数列表中没有区别,在 typename 这个关键字出现之前,都是使用 class 来定义模板参数的。但在模板中定义有[嵌套依赖类型](http://en.cppreference.com/w/cpp/language/dependent_name#The_typename_disambiguator_for_dependent_names)的变量时,需要用 typename 消除歧义
这样的代码其实变得很丑陋,因为程序员在使用这个模板函数的时候,必须明确指出返回类型。但事实上我们并不知道 `add()` 这个函数会做什么样的操作,获得一个什么样的返回类型。 这样的代码其实变得很丑陋,因为程序员在使用这个模板函数的时候,必须明确指出返回类型。但事实上我们并不知道 `add()` 这个函数会做什么样的操作,以及获得一个什么样的返回类型。
在 C++11 中这个问题得到解决。虽然你可能马上会反应出来使用 `decltype` 推导 `x+y` 的类型,写出这样的代码: 在 C++11 中这个问题得到解决。虽然你可能马上会反应出来使用 `decltype` 推导 `x+y` 的类型,写出这样的代码:

View File

@@ -21,10 +21,9 @@ public:
} }
}; };
// wrong int add(auto x, auto y) { // Supported in C++20
// int add(auto x, auto y) { return x+y;
// return x+y; }
// }
int main() { int main() {
MagicFoo magicFoo = {1, 2, 3, 4, 5}; MagicFoo magicFoo = {1, 2, 3, 4, 5};
@@ -36,8 +35,9 @@ int main() {
auto i = 5; // type int auto i = 5; // type int
auto j = 6; // type int auto j = 6; // type int
std::cout << add(i, j) << std::endl;
auto arr = new auto(10); // type int* auto arr = new auto(10); // type int*
// auto auto_arr2[10] = {arr}; // auto auto_arr2[10] = {arr}; // invalid
// std::cout << add(i, j) << std::endl;
return 0; return 0;
} }