Skip to content

Commit 53741bc

Browse files
committed
book: add Chapter 11 (C++23)
Add a new bilingual Chapter 11 introducing C++23: - Language: deducing this, if consteval, multidimensional subscript, auto(x), static operator(), [[assume]] - Library: std::expected, std::print/println, std::mdspan, std::flat_map/flat_set, ranges additions (zip etc.), string::contains, std::byteswap; documents features not yet in libc++ (std::generator, std::move_only_function, <stacktrace>, import std) with a caveat. Includes nine runnable examples under code/11 (verified to compile and run with clang++ -std=c++2b). Register the chapter in website/filter.py, update both toc.md, fix the stale Chapter 10 outline, bump the appendix order/nav, and wire the prev/next links. Resolves #317
1 parent 2d73270 commit 53741bc

21 files changed

Lines changed: 661 additions & 17 deletions

book/en-us/10-cpp20.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ This chapter therefore no longer presents them as C++20 features.
196196
In general, I finally saw the exciting features of Concepts/Ranges/Modules in C++20.
197197
This is still full of charm for a programming language that is already in its thirties.
198198
199-
[Table of Content](./toc.md) | [Previous Chapter](./09-others.md) | [Next Chapter](./appendix1.md)
199+
[Table of Content](./toc.md) | [Previous Chapter](./09-others.md) | [Next Chapter: Introduction of C++23](./11-cpp23.md)
200200
201201
## Further Readings
202202

book/en-us/11-cpp23.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
---
2+
title: "Chapter 11: Introduction of C++23"
3+
type: book-en-us
4+
order: 11
5+
---
6+
7+
# Chapter 11: Introduction of C++23
8+
9+
[TOC]
10+
11+
If C++20 was another "major" release in the spirit of C++11, C++23 is more of an incremental update focused on **consolidation and polish**: it completes some features that were rushed into C++20 and adds many long-requested library facilities. This chapter introduces a selection of its more important and practical features.
12+
13+
> The examples in this chapter use C++23 features and must be compiled with `-std=c++2b` (or `-std=c++23`). In addition, depending on the progress of each standard-library implementation, some library features (such as `std::generator`, `std::move_only_function`, `<stacktrace>`, and `import std;`) may not yet be available on your toolchain; this is noted where relevant.
14+
15+
## 11.1 Language features
16+
17+
### Deducing `this` (explicit object parameter)
18+
19+
Before C++23, making a member function serve `const`/non-`const` and lvalue/rvalue cases at once usually meant writing several nearly identical overloads. C++23 introduces an **explicit object parameter**, allowing `this` to be written as the function's first parameter and its cv-/ref-qualification to be deduced via a template, so a single function template covers every case:
20+
21+
```cpp
22+
struct Counter {
23+
int value = 0;
24+
template <typename Self>
25+
auto&& get(this Self&& self) { // self is the former *this
26+
return self.value;
27+
}
28+
};
29+
```
30+
31+
This also makes previously awkward patterns, such as recursive lambdas, natural to write.
32+
33+
### `if consteval`
34+
35+
C++23 introduces `if consteval`, which distinguishes within a function body whether the current context is **constant evaluation**, letting you choose different implementations for compile time and run time:
36+
37+
```cpp
38+
constexpr int compute(int x) {
39+
if consteval {
40+
return x * 2; // taken during constant evaluation
41+
} else {
42+
return x * 3; // taken at run time
43+
}
44+
}
45+
```
46+
47+
### Multidimensional subscript operator
48+
49+
C++23 lets `operator[]` take multiple subscript arguments, so multidimensional containers can use the intuitive `m[i, j]` syntax instead of falling back to `operator()`:
50+
51+
```cpp
52+
struct Matrix2x3 {
53+
int data[6] = {};
54+
int& operator[](std::size_t r, std::size_t c) { return data[r * 3 + c]; }
55+
};
56+
57+
Matrix2x3 m;
58+
m[1, 2] = 7;
59+
```
60+
61+
### `auto(x)` and static `operator()`
62+
63+
C++23 provides the `auto(x)` / `auto{x}` syntax to explicitly produce a **decay-copy** — a prvalue copy of the same type as `x` — which is handy when you specifically want a copy:
64+
65+
```cpp
66+
std::vector<int> v{1, 2, 3};
67+
auto copy = auto(v); // explicit copy, a prvalue
68+
```
69+
70+
In addition, the call operator of a function object (including a lambda) can now be declared `static`, dropping the implicit object parameter, which can improve performance in some scenarios:
71+
72+
```cpp
73+
struct Add {
74+
static int operator()(int a, int b) { return a + b; }
75+
};
76+
```
77+
78+
### `[[assume]]`
79+
80+
`[[assume(expr)]]` is a C++23 standardized attribute that tells the compiler an expression is guaranteed to be true at that point, allowing the optimizer to take advantage of it. Note that if the assumption does not actually hold at run time, the behavior is undefined, so use it with care:
81+
82+
```cpp
83+
int divide_by(int x) {
84+
[[assume(x > 0)]]; // promise the optimizer x is positive
85+
return 100 / x;
86+
}
87+
```
88+
89+
## 11.2 The standard library
90+
91+
### `std::expected`
92+
93+
`std::expected<T, E>` represents a result that is "either a value `T` or an error `E`", providing a type-safe, expressive way to handle errors without exceptions, similar to the `Result` type in other languages:
94+
95+
```cpp
96+
#include <expected>
97+
98+
std::expected<int, std::string> parse_positive(int x) {
99+
if (x > 0) return x;
100+
return std::unexpected("not positive");
101+
}
102+
103+
auto r = parse_positive(42);
104+
if (r) {
105+
// use *r
106+
} else {
107+
// use r.error()
108+
}
109+
```
110+
111+
### `std::print` and `std::println`
112+
113+
C++23's `<print>` provides `std::print` and `std::println`, which build on C++20's `std::format` to produce output via a type-safe format string — more concise and more efficient than the traditional chained `iostream` `<<`:
114+
115+
```cpp
116+
#include <print>
117+
118+
std::println("Hello, {}!", "C++23");
119+
std::println("{} + {} = {}", 1, 2, 1 + 2);
120+
```
121+
122+
### `std::mdspan`
123+
124+
`std::mdspan` is a **non-owning multidimensional view** over contiguous storage. It does not allocate; it merely reinterprets the layout of an underlying one-dimensional array according to the given extents, and is widely used in scientific and high-performance computing:
125+
126+
```cpp
127+
#include <mdspan>
128+
129+
std::array<int, 6> storage{1, 2, 3, 4, 5, 6};
130+
std::mdspan m(storage.data(), 2, 3); // view it as 2 x 3
131+
int x = m[1, 2]; // together with the multidimensional subscript
132+
```
133+
134+
### `std::flat_map` and `std::flat_set`
135+
136+
`std::flat_map` / `std::flat_set` are associative containers backed by **sorted contiguous storage** (by default two `vector`s). Compared with the red-black-tree-based `std::map`, insertion is slower, but lookup and iteration are more cache-friendly and the memory overhead is smaller:
137+
138+
```cpp
139+
#include <flat_map>
140+
141+
std::flat_map<int, const char*> m;
142+
m.insert({3, "three"});
143+
m.insert({1, "one"});
144+
// iterated in sorted key order: 1, 3
145+
```
146+
147+
### Ranges additions
148+
149+
C++23 added many useful range adaptors, such as `views::zip` (iterates several ranges in lockstep, element by element), `views::enumerate` (attaches an index to each element), `views::chunk`, `views::slide`, and `views::join_with`, as well as the general-purpose `std::ranges::to` (materializes a range into a concrete container):
150+
151+
```cpp
152+
#include <ranges>
153+
154+
std::vector<std::string> names{"a", "b", "c"};
155+
std::vector<int> scores{90, 80, 70};
156+
for (auto&& [name, score] : std::views::zip(names, scores)) {
157+
// name and score correspond one to one
158+
}
159+
```
160+
161+
### Other improvements
162+
163+
C++23 also includes many small but practical improvements, for example:
164+
165+
- `std::string` / `std::string_view` gained a `contains` member to directly test for a substring or character;
166+
- `<bit>` added `std::byteswap`, which reverses the byte order of an integer;
167+
- `std::optional` gained monadic operations such as `and_then`, `transform`, and `or_else`.
168+
169+
## 11.3 A note on library support
170+
171+
Most C++23 language features are already well supported by mainstream compilers, but **the availability of some library features varies by implementation**. For instance, `std::generator` (coroutine ranges), `std::move_only_function`, `<stacktrace>`, and the standard-library module `import std;` may not yet be implemented, or may still be experimental, in some standard libraries (especially libc++). Before using these features, check the [cppreference compiler support page](https://en.cppreference.com/w/cpp/compiler_support) to confirm the support status of your toolchain.
172+
173+
## Conclusion
174+
175+
Although C++23 does not bring the disruptive changes of C++11 or C++20, features such as `std::expected`, `std::print`, `std::mdspan`, and the explicit object parameter genuinely improve the day-to-day experience of writing C++. Together with the upcoming C++26, modern C++ continues to evolve.
176+
177+
[Table of Content](./toc.md) | [Previous Chapter](./10-cpp20.md) | [Next Chapter: Further Study Materials](./appendix1.md)
178+
179+
## Further Readings
180+
181+
- [C++23 - cppreference](https://en.cppreference.com/w/cpp/23)
182+
- [C++ compiler support](https://en.cppreference.com/w/cpp/compiler_support)
183+
184+
## Licenses
185+
186+
<a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work was written by [Ou Changkun](https://changkun.de) and licensed under a <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>. The code of this repository is open sourced under the [MIT license](../../LICENSE).

book/en-us/appendix1.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Appendix 1: Further Study Materials"
33
type: book-en-us
4-
order: 11
4+
order: 12
55
---
66

77
# Appendix 1: Further Study Materials
@@ -15,7 +15,7 @@ As mentioned in the introduction to this book, this book is just a book that tak
1515
- [Ulrich Drepper. What Every Programmer Should Know About Memory. 2007](https://people.freebsd.org/~lstewart/articles/cpumemory.pdf)
1616
- to be added
1717

18-
[Table of Content](./toc.md) | [Previous Chapter](./10-cpp20.md) | [Next Chapter](./appendix2.md)
18+
[Table of Content](./toc.md) | [Previous Chapter](./11-cpp23.md) | [Next Chapter](./appendix2.md)
1919

2020
## Licenses
2121

book/en-us/appendix2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Appendix 2: Modern C++ Best Practices"
33
type: book-en-us
4-
order: 12
4+
order: 13
55
---
66

77
# Appendix 2: Modern C++ Best Practices

book/en-us/toc.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,22 @@
9898
+ 9.4 Memory Alignment
9999
- [**Chapter 10 Outlook: Introduction of C++20**](./10-cpp20.md)
100100
+ 10.1 Concept
101-
+ 10.2 Range
102-
+ 10.3 Module
101+
+ 10.2 Module
102+
+ 10.3 Range
103103
+ 10.4 Coroutine
104-
+ 10.5 Transaction Memory
104+
- [**Chapter 11 Introduction of C++23**](./11-cpp23.md)
105+
+ 11.1 Language features
106+
- Deducing this (explicit object parameter)
107+
- if consteval
108+
- Multidimensional subscript operator
109+
- auto(x) and static operator()
110+
- [[assume]]
111+
+ 11.2 The standard library
112+
- std::expected
113+
- std::print and std::println
114+
- std::mdspan
115+
- std::flat_map and std::flat_set
116+
- Ranges additions
105117
- [**Appendix 1: Further Study Materials**](./appendix1.md)
106118
- [**Appendix 2: Modern C++ Best Practices**](./appendix2.md)
107119

book/zh-cn/10-cpp20.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ int main() {
185185
总的来说,终于在 C++20 中看到 Concepts/Ranges/Modules 这些令人兴奋的特性,
186186
这对于一门已经三十多岁『高龄』的编程语言,依然是充满魅力的。
187187
188-
[返回目录](./toc.md) | [上一章](./09-others.md) | [下一章 进一步阅读的学习材料](./appendix1.md)
188+
[返回目录](./toc.md) | [上一章](./09-others.md) | [下一章 C++23 简介](./11-cpp23.md)
189189
190190
191191
## 进一步阅读的参考资料

0 commit comments

Comments
 (0)