Skip to content

Commit 4da96d3

Browse files
committed
Merge branch 'main' of github.com:parallel101/cppguidebook
2 parents ff3ee98 + 79cca33 commit 4da96d3

File tree

2 files changed

+100
-5
lines changed

2 files changed

+100
-5
lines changed

docs/functions.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ TODO: println 参数演示
1212

1313
## 函数的返回值
1414

15-
函数可以没有返回值,只需要返回类型写 `void` 即可,这样的函数调用的目的只是为了他的副作用(如修改全局变量,输出文本到控制台,修改引用参数等)。
15+
函数可以没有返回值,只需要声明函数时返回类型声明为 `void` 即可,调用这样的函数只是为了他的副作用(如修改全局变量,输出文本到控制台,修改引用参数等)。
1616

1717
```cpp
1818
void compute()
@@ -22,19 +22,62 @@ void compute()
2222
```
2323

2424
> {{ icon.tip }} 对于没有返回值(返回类型为 `void`)的函数,可以省略 `return` 不写。
25+
2526
```cpp
2627
void compute()
2728
{
2829
// 没问题
2930
}
3031
```
3132

32-
> {{ icon.warn }} 对于有返回值的函数,必须写 return 语句,如果漏写,会出现可怕的未定义行为 (undefined behaviour)。编译器不会报错,而是到运行时才出现崩溃等现象,建议 GCC 用户开启 `-Werror=return-type` 让编译器检测此类错误。更多未定义行为可以看我们的[未定义行为列表](undef.md)章节。
33+
> {{ icon.warn }} 对于返回类型不为 `void` 的函数,必须写 `return` 语句,如果漏写,会出现可怕的未定义行为 (undefined behaviour)。编译器不一定会报错,而是到运行时才出现崩溃等现象。建议 GCC 用户开启 `-Werror=return-type` 让编译器在编译时就检测此类错误,MSVC 则是开启 `/we4716`。更多未定义行为可以看我们的[未定义行为列表](undef.md)章节。
34+
> {{ icon.detail }} 但有两个例外:1. main 函数是特殊的可以不写 return 语句,默认会自动帮你 `return 0;`。2. 具有 co_return 或 co_await 的协程函数可以不写 return 语句。
3335
3436
### 接住返回值
3537

3638
### 返回类型 `auto`
3739

40+
C++11 `auto` 可以用作函数的返回类型,但它只是一个**占位**,让我们得以后置返回类型。
41+
42+
```cpp
43+
auto f() -> int;
44+
// 等价于:
45+
int f();
46+
```
47+
48+
C++14 引入了函数**返回类型推导**`auto` 才算真正意义上的用做了函数返回类型,它会根据函数中的 `return` 表达式推导出函数的返回类型。
49+
50+
```cpp
51+
int x = 1;
52+
auto f() {
53+
return x;
54+
}
55+
// 等价于:
56+
int f() {
57+
return x;
58+
}
59+
60+
// 如果函数中没有return语句,那么 `auto` 会被自动推导为 `void`
61+
auto f() {
62+
std::println("hello");
63+
}
64+
// 等价于:
65+
void f() {
66+
std::println("hello");
67+
}
68+
69+
// 值得注意的是,返回类型用 `auto` 来推导的函数,如果有多条 `return` 语句,那么他们必须是相同的类型;否则报错
70+
auto f(int x) {
71+
if (x > 0) {
72+
return 1; // int
73+
} else {
74+
return 3.14; // double
75+
}
76+
} // 错误:有歧义,无法确定 auto 应该推导为 int 还是 double
77+
```
78+
79+
<!-- decltype(auto)... -->
80+
3881
## 函数的参数
3982
4083
### 形参 vs 实参

examples/error_code.cpp

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ int checkStdError(int ret) {
117117
// return {};
118118
// }
119119

120-
template <class T>
121-
using expected = tl::expected<T, std::error_code>;
120+
// template <class T>
121+
// using expected = tl::expected<T, std::error_code>;
122122

123123
struct RAIIFile {
124124
int fd;
@@ -133,8 +133,60 @@ struct RAIIFile {
133133
// }
134134

135135
int main() {
136-
RAIIFile file{expectedStdError(open("/tmp/test.log", O_WRONLY)).value()};
136+
RAIIFile file{expectedStdError(::open("/tmp/test.log", O_WRONLY)).value()};
137137
std::string s = "asasasas";
138138
file.write(s).value();
139139
return 0;
140140
}
141+
142+
namespace screenshot1 {
143+
144+
namespace std {
145+
using namespace ::tl;
146+
using namespace ::std;
147+
}
148+
149+
std::expected<int, std::error_code> expectedStdError(int ret) {
150+
if (ret == -1) {
151+
return std::unexpected{std::error_code(errno, std::generic_category())};
152+
}
153+
return ret;
154+
}
155+
156+
struct File {
157+
int fd;
158+
159+
explicit File(const char *path, int flags) {
160+
fd = expectedStdError(::open(path, flags)).value();
161+
}
162+
163+
tl::expected<size_t, std::error_code> write(std::span<const char> buf) {
164+
return expectedStdError(::write(fd, buf.data(), buf.size()));
165+
}
166+
};
167+
168+
std::expected<int, std::error_code> sqrt(int x) {
169+
if (x < 0)
170+
return std::unexpected{make_error_code(std::errc::argument_out_of_domain)};
171+
172+
for (int i = 0;; i++)
173+
if (i * i >= x)
174+
return i;
175+
}
176+
177+
}
178+
179+
namespace screenshot2 {
180+
181+
int sqrt(int x) {
182+
if (x < 0) {
183+
errno = EDOM;
184+
return -1;
185+
}
186+
187+
for (int i = 0;; i++)
188+
if (i * i >= x)
189+
return i;
190+
}
191+
192+
}

0 commit comments

Comments
 (0)