Skip to content

Commit b8992ad

Browse files
committed
feat(cpp14): add 03-return-type-deduction
Book chapter (zh + en): - section 一/I: Basic usage — auto return in plain and template functions - section 二/II: Real-world case — _To_unsigned_like from vendored msvc-stl/stl/inc/xutility, demonstrating auto-return simplifying template function signatures - section 三/III: Notes — consistent return types, recursion limitation, reference stripping - section 四/IV: Exercise topics and d2x checker command - section 五/V: External resources Exercise: 0. auto return type deduction — plain function, string concatenation, template max_of. 4 D2X_YOUR_ANSWER. Build wiring: - register 03 target in dslings/cpp14, dslings/en/cpp14, solutions/cpp14 - add 03 entry to zh/en SUMMARY.md
1 parent 1c37ddd commit b8992ad

10 files changed

Lines changed: 355 additions & 0 deletions

File tree

book/en/src/SUMMARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232

3333
- [Generic Lambdas](./cpp14/00-generic-lambdas.md)
3434

35+
36+
- [Return Type Deduction](./cpp14/03-return-type-deduction.md)
37+
3538
# Additional Resources
3639

3740
- [Changelog](changelog.md)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<div align=right>
2+
3+
🌎 [中文] | [English]
4+
</div>
5+
6+
[中文]: ../../cpp14/03-return-type-deduction.html
7+
[English]: ./03-return-type-deduction.html
8+
9+
# Return Type Deduction
10+
11+
C++14 allows functions to use `auto` as a return type without trailing `-> decltype(...)`
12+
13+
| Book | Video | Code | X |
14+
| --- | --- | --- | --- |
15+
| [cppreference-auto](https://en.cppreference.com/w/cpp/language/auto) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/en/src/cpp14/03-return-type-deduction.md) | [Video Explanation]() | [Exercise Code](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/en/cpp14/03-return-type-deduction-0.cpp) | |
16+
17+
18+
**Why introduced?**
19+
20+
- C++11 required `-> decltype(...)` trailing return for `auto` functions
21+
- Many simple functions don't need an explicit return type
22+
23+
## I. Basic Usage and Scenarios
24+
25+
### auto return — plain functions
26+
27+
```cpp
28+
auto add(int a, int b) { // deduced as int
29+
return a + b;
30+
}
31+
```
32+
33+
### auto return — template functions
34+
35+
```cpp
36+
template <typename T1, typename T2>
37+
auto multiply(T1 a, T2 b) { // C++14: no -> decltype needed
38+
return a * b;
39+
}
40+
```
41+
42+
## II. Real-World Case — auto Return Deduction in the STL
43+
44+
> The MSVC STL uses `auto` return types extensively to simplify template function signatures. The examples below cite the vendored [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) (source: [`msvc-stl/stl/inc/xutility`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/xutility#L1129-L1132)); `_NODISCARD` / `constexpr` are library-internal annotations
45+
46+
### _To_unsigned_like — auto Return Simplifies Template Functions
47+
48+
```cpp
49+
// MSVC STL · msvc-stl/stl/inc/xutility (abridged)
50+
template <_Integer_like _Ty>
51+
_NODISCARD constexpr auto _To_unsigned_like(const _Ty _Value) noexcept {
52+
return static_cast<_Make_unsigned_like_t<_Ty>>(_Value);
53+
}
54+
```
55+
56+
The return type is `_Make_unsigned_like_t<_Ty>` — without `auto`, the signature would be `_Make_unsigned_like_t<_Ty> _To_unsigned_like(...)`, with the return type longer than the function name. `auto` keeps the signature clean while the return statement naturally expresses the type
57+
58+
## III. Notes
59+
60+
### auto return requires consistent types
61+
62+
```cpp
63+
auto bad(int x) {
64+
if (x > 0) return 1; // int
65+
else return 2.0; // double → error!
66+
}
67+
```
68+
69+
### Recursion requires explicit return type
70+
71+
```cpp
72+
auto factorial(int n) { // error: recursive
73+
return n <= 1 ? 1 : n * factorial(n - 1);
74+
}
75+
```
76+
77+
### auto return strips references
78+
79+
Use `decltype(auto)` when you need to preserve references (see next chapter)
80+
81+
## IV. Exercise Code
82+
83+
### Exercise Topics
84+
85+
- 0 - [auto Return Type Deduction](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/en/cpp14/03-return-type-deduction-0.cpp)
86+
87+
### Auto-Checker Command
88+
89+
```
90+
d2x checker return-type-deduction
91+
```
92+
93+
## V. Other
94+
95+
- [Discussion Forum](https://forum.d2learn.org/category/20)
96+
- [d2mcpp Tutorial Repository](https://github.com/mcpp-community/d2mcpp)
97+
- [Tutorial Video List](https://space.bilibili.com/65858958/lists/5208246)
98+
- [Tutorial Support Tool - xlings](https://github.com/openxlings/xlings)

book/src/SUMMARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232

3333
- [泛型 lambda - generic lambdas](./cpp14/00-generic-lambdas.md)
3434

35+
36+
- [返回类型推导 - return type deduction](./cpp14/03-return-type-deduction.md)
37+
3538
# 其他
3639

3740
- [更新日志](changelog.md)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<div align=right>
2+
3+
🌎 [中文] | [English]
4+
</div>
5+
6+
[中文]: ./03-return-type-deduction.html
7+
[English]: ../en/cpp14/03-return-type-deduction.html
8+
9+
# 返回类型推导 - return type deduction
10+
11+
C++14 允许函数使用 `auto` 作为返回类型而无需后置 `-> decltype(...)`, 编译器从 return 语句自动推导
12+
13+
| Book | Video | Code | X |
14+
| --- | --- | --- | --- |
15+
| [cppreference-auto](https://en.cppreference.com/w/cpp/language/auto) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp14/03-return-type-deduction.md) | [视频解读]() | [练习代码](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp14/03-return-type-deduction-0.cpp) | |
16+
17+
18+
**为什么引入?**
19+
20+
- C++11 的 `auto` 返回类型必须配合 `-> decltype(...)` 后置语法
21+
- 很多简单函数不需要显式声明返回类型, 编译器可以从 return 语句推导出来
22+
23+
## 一、基础用法和场景
24+
25+
### auto 返回 — 普通函数
26+
27+
```cpp
28+
auto add(int a, int b) { // 返回类型推导为 int
29+
return a + b;
30+
}
31+
```
32+
33+
### auto 返回 — 模板函数
34+
35+
```cpp
36+
template <typename T1, typename T2>
37+
auto multiply(T1 a, T2 b) { // C++14 不需要 -> decltype(a * b)
38+
return a * b;
39+
}
40+
```
41+
42+
## 二、真实案例 - STL 中的 auto 返回推导
43+
44+
> MSVC STL 内部大量使用 `auto` 返回类型推导来简化模板函数签名。下面以仓库内置的 [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) 为例 (源码: [`msvc-stl/stl/inc/xutility`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/xutility#L1129-L1132)), `_NODISCARD` / `constexpr` 是库内部标注, 阅读时可忽略
45+
46+
### _To_unsigned_like — auto 返回简化模板函数
47+
48+
```cpp
49+
// MSVC STL · msvc-stl/stl/inc/xutility (有删节)
50+
template <_Integer_like _Ty>
51+
_NODISCARD constexpr auto _To_unsigned_like(const _Ty _Value) noexcept {
52+
return static_cast<_Make_unsigned_like_t<_Ty>>(_Value);
53+
}
54+
```
55+
56+
返回类型是 `_Make_unsigned_like_t<_Ty>`, 如果不写成 `auto`, 函数签名会变成 `_Make_unsigned_like_t<_Ty> _To_unsigned_like(...)`, 返回类型比函数名还长。`auto` 让签名简洁, 返回类型由 return 语句自然表达
57+
58+
## 三、注意事项
59+
60+
### auto 返回必须统一类型
61+
62+
```cpp
63+
auto bad(int x) {
64+
if (x > 0) return 1; // int
65+
else return 2.0; // double → 错误!
66+
}
67+
```
68+
69+
### 递归需要显式返回类型
70+
71+
```cpp
72+
auto factorial(int n) { // 错误: 递归, 无法推导
73+
return n <= 1 ? 1 : n * factorial(n - 1);
74+
}
75+
```
76+
77+
### auto 返回会剥离引用
78+
79+
需要保留引用时用 `decltype(auto)` (见下一章)
80+
81+
## 四、练习代码
82+
83+
### 练习代码主题
84+
85+
- 0 - [auto 返回类型推导 — 普通函数和模板函数](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp14/03-return-type-deduction-0.cpp)
86+
87+
### 练习代码自动检测命令
88+
89+
```
90+
d2x checker return-type-deduction
91+
```
92+
93+
## 五、其他
94+
95+
- [交流讨论](https://forum.d2learn.org/category/20)
96+
- [d2mcpp教程仓库](https://github.com/mcpp-community/d2mcpp)
97+
- [教程视频列表](https://space.bilibili.com/65858958/lists/5208246)
98+
- [教程支持工具-xlings](https://github.com/openxlings/xlings)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// d2mcpp: https://github.com/mcpp-community/d2mcpp
2+
// license: Apache-2.0
3+
// file: dslings/cpp14/03-return-type-deduction-0.cpp
4+
//
5+
// Exercise/练习: cpp14 | 03 - return type deduction | auto 返回类型推导
6+
//
7+
// Tips/提示:
8+
// - C++14 允许 auto 作为返回类型, 无需后置 -> decltype(...)
9+
// - 编译器从 return 语句推导返回类型
10+
//
11+
// Docs/文档:
12+
// - https://en.cppreference.com/w/cpp/language/auto
13+
// - https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp14/03-return-type-deduction.md
14+
//
15+
// 练习交流讨论: http://forum.d2learn.org/category/20
16+
//
17+
// Auto-Checker/自动检测命令:
18+
//
19+
// d2x checker return-type-deduction
20+
//
21+
22+
#include <d2x/cpp/common.hpp>
23+
#include <string>
24+
25+
auto get_forty_two() {
26+
return D2X_YOUR_ANSWER;
27+
}
28+
29+
auto greet(D2X_YOUR_ANSWER name) {
30+
return "hello " + D2X_YOUR_ANSWER;
31+
}
32+
33+
template <typename T1, typename T2>
34+
D2X_YOUR_ANSWER max_of(T1 a, T2 b) {
35+
return a > b ? a : b;
36+
}
37+
38+
int main() {
39+
40+
d2x_assert_eq(get_forty_two(), 42);
41+
42+
d2x_assert(greet(std::string("world")) == "hello world");
43+
44+
d2x_assert_eq(max_of(10, 20), 20);
45+
d2x_assert_eq(max_of(2.5, D2X_YOUR_ANSWER), 3.5);
46+
47+
D2X_WAIT
48+
49+
return 0;
50+
}

dslings/cpp14/xmake.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ target("cpp14-00-generic-lambdas-0")
99
target("cpp14-00-generic-lambdas-1")
1010
set_kind("binary")
1111
add_files("00-generic-lambdas-1.cpp")
12+
13+
-- target: cpp14-03-return-type-deduction
14+
15+
target("cpp14-03-return-type-deduction-0")
16+
set_kind("binary")
17+
add_files("03-return-type-deduction-0.cpp")
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// d2mcpp: https://github.com/mcpp-community/d2mcpp
2+
// license: Apache-2.0
3+
// file: dslings/en/cpp14/03-return-type-deduction-0.cpp
4+
//
5+
// Exercise: cpp14 | 03 - return type deduction | auto return type deduction
6+
//
7+
// Tips:
8+
// - C++14 allows auto as a return type without trailing -> decltype(...)
9+
// - The compiler deduces the return type from the return statement
10+
//
11+
// Docs:
12+
// - https://en.cppreference.com/w/cpp/language/auto
13+
// - https://github.com/mcpp-community/d2mcpp/blob/main/book/en/src/cpp14/03-return-type-deduction.md
14+
//
15+
// Discussion Forum: http://forum.d2learn.org/category/20
16+
//
17+
// Auto-Checker:
18+
//
19+
// d2x checker return-type-deduction
20+
//
21+
22+
#include <d2x/cpp/common.hpp>
23+
#include <string>
24+
25+
auto get_forty_two() {
26+
return D2X_YOUR_ANSWER;
27+
}
28+
29+
auto greet(D2X_YOUR_ANSWER name) {
30+
return "hello " + D2X_YOUR_ANSWER;
31+
}
32+
33+
template <typename T1, typename T2>
34+
D2X_YOUR_ANSWER max_of(T1 a, T2 b) {
35+
return a > b ? a : b;
36+
}
37+
38+
int main() {
39+
40+
d2x_assert_eq(get_forty_two(), 42);
41+
42+
d2x_assert(greet(std::string("world")) == "hello world");
43+
44+
d2x_assert_eq(max_of(10, 20), 20);
45+
d2x_assert_eq(max_of(2.5, D2X_YOUR_ANSWER), 3.5);
46+
47+
D2X_WAIT
48+
49+
return 0;
50+
}

dslings/en/cpp14/xmake.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ target("cpp14-00-generic-lambdas-0")
99
target("cpp14-00-generic-lambdas-1")
1010
set_kind("binary")
1111
add_files("00-generic-lambdas-1.cpp")
12+
13+
-- target: cpp14-03-return-type-deduction
14+
15+
target("cpp14-03-return-type-deduction-0")
16+
set_kind("binary")
17+
add_files("03-return-type-deduction-0.cpp")
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// d2mcpp: https://github.com/mcpp-community/d2mcpp
2+
// license: Apache-2.0
3+
// reference solution for: dslings/cpp14/03-return-type-deduction-0.cpp
4+
//
5+
// 用途: 仅给 CI 与维护者参考使用,不是教程入口。
6+
// 教程练习入口: dslings/cpp14/03-return-type-deduction-0.cpp
7+
//
8+
9+
#include <d2x/cpp/common.hpp>
10+
#include <string>
11+
12+
auto get_forty_two() {
13+
return 42;
14+
}
15+
16+
auto greet(const std::string& name) {
17+
return "hello " + name;
18+
}
19+
20+
template <typename T1, typename T2>
21+
auto max_of(T1 a, T2 b) {
22+
return a > b ? a : b;
23+
}
24+
25+
int main() {
26+
27+
d2x_assert_eq(get_forty_two(), 42);
28+
29+
d2x_assert(greet(std::string("world")) == "hello world");
30+
31+
d2x_assert_eq(max_of(10, 20), 20);
32+
d2x_assert_eq(max_of(2.5, 3.5), 3.5);
33+
34+
return 0;
35+
}

solutions/cpp14/xmake.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ target("cpp14-00-generic-lambdas-0-ref")
99
target("cpp14-00-generic-lambdas-1-ref")
1010
set_kind("binary")
1111
add_files("00-generic-lambdas-1.cpp")
12+
13+
-- target: cpp14-03-return-type-deduction
14+
15+
target("cpp14-03-return-type-deduction-0-ref")
16+
set_kind("binary")
17+
add_files("03-return-type-deduction-0.cpp")

0 commit comments

Comments
 (0)