You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
video(cpp11/00): manim animation for auto/decltype (#53)
* video(cpp11/00): add manim animation for auto/decltype
Manim Community v0.18.1 scene mirroring the existing videos/cpp11/*
framework (MovingCameraScene + d2x mcpp_video_start/end, DHighlight,
create_code_helper). Six scenes following the chapter:
declaration, expression deduction, complex types (iterator),
trailing-return + decltype, const/reference stripping, and the
decltype parentheses pitfall.
Run: uv run --with "manim==0.18.1" manim -pql videos/cpp11/00-auto-and-decltype.py
* docs(cpp11/00): sync bilingual docs + add animation video link
- Sync en doc to zh: iterator example (v.insert) and const/reference
stripping example now match the zh version's code
- Add Bilibili animation link (BV1EzJs6HEf7) alongside the existing
explanation video in both book docs and videos/README.md
- Add render.sh launcher and refine the manim animation script
* docs(cpp11/00): correct video labels — 视频解读=BV1EzJs6HEf7, 练习讲解=BV1xkdYYUEyH
auto it = v.begin(); // Automatically deduce iterator type
65
66
// decltype(v.begin()) it = v.begin();
66
67
for (; it != v.end(); ++it) {
67
-
std::cout << *it << " ";
68
+
if (*it == 2) {
69
+
v.insert(it, 0);
70
+
break;
71
+
}
68
72
}
69
73
```
70
74
@@ -137,41 +141,42 @@ int main() {
137
141
138
142
## II. Real-World Case - auto/decltype in the STL
139
143
140
-
> The examples above illustrate syntax; the real value of auto/decltype shows up most directly in the standard library's own implementation. Below we use the in-repo [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl)as the source ([`msvc-stl/stl/inc/xutility`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/xutility#L2200-L2235)); `_EXPORT_STD` / `_NODISCARD` / `_CONSTEXPR17` / `_STD`are internal library macros — ignore them when reading.
144
+
> The examples above illustrate syntax; the practical value of auto/decltype is demonstrated most directly in the standard library's own implementation. The following picks two common pieces of code from the in-repo [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl)to demonstrate `auto` and `decltype` respectively; `_STD` and the like are internal library macros and qualifiers — focus on the `auto` / `decltype` when reading.
141
145
142
-
### Trailing return type + decltype: std::begin / std::end
146
+
### auto deduces iterator and element types: traversing a container
143
147
144
-
`std::begin` / `std::end` (added in C++11) must adapt to any container; their return type depends entirely on `_Cont.begin()` and cannot be written ahead of time, so they "borrow" it via `auto ... -> decltype(...)`
148
+
Traversing a container is the most common scenario for `auto`. Below is a traversal from path normalization in `<filesystem>`: `auto _Pos` deduces the iterator type, and `const auto _Elem` deduces the element type obtained by dereferencing — the very same form as `auto it = v.begin()` from "Complex type deduction - iterators" in `## I`.
_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) {
155
-
return _Cont.end();
156
-
}
151
+
// MSVC STL · msvc-stl/stl/inc/filesystem (abridged, original indentation kept)
152
+
auto _New_end = _Vec.begin();
153
+
for (auto _Pos = _Vec.begin(); _Pos != _Vec.end();) {
154
+
const auto _Elem = *_Pos++;
155
+
// ...(decide whether to write _Elem back to _New_end; omitted)
156
+
}
157
157
```
158
158
159
-
This is exactly the trailing-return form from the "Function Return Type Deduction" section, living inside the standard library itself: `auto` as the placeholder + `decltype(_Cont.begin())` precisely deducing the differing iterator types of `vector<int>`, `list<T>`, and so on.
159
+
`_Vec` is the container of path components; both its iterator type and its element type are left to `auto`, with no need to spell out the concrete types.
160
160
161
-
### Reusing another function's return type with decltype: std::cbegin / std::cend
161
+
### decltype takes the type of a variable: the binary search in std::lower_bound
162
162
163
-
Going further, `std::cbegin` simply reuses `begin`'s return type via `decltype(_STD begin(_Cont))` — it doesn't care what that type is, only that it "matches what begin returns"
163
+
The most direct use of `decltype` is "take the type of a variable or expression". In the standard library's binary search `std::lower_bound`, `auto` first deduces the range length `_Count`, then `decltype(_Count)` denotes "the same type as `_Count`" to convert `_Count / 2` back to that type:
auto _Count = _STD distance(_UFirst, _STD _Get_unwrapped(_Last));
169
+
170
+
while (0 < _Count) { // divide and conquer, find half that contains answer
171
+
const auto _Count2 = static_cast<decltype(_Count)>(_Count / 2);
172
+
const auto _UMid = _STD next(_UFirst, _Count2);
173
+
// ...(compare at _UMid, narrow the range; omitted)
174
+
}
172
175
```
173
176
174
-
> Takeaway: when a type "is decided by template parameters and simply cannot be written by hand", the standard library reaches for exactly the auto + decltype toolkit taught in this chapter — one of the core motivations for introducing them in C++11.
177
+
This is the same use as `decltype(b) b2` from "Declaration and definition" in `## I`: `decltype(_Count)` is simply "the type of `_Count`". `auto` deduces the type, and `decltype` reuses that same type elsewhere.
178
+
179
+
> Takeaway: traversing a container, reusing the type of some variable — these everyday forms are, inside the standard library, exactly the auto + decltype toolkit taught in this chapter. This is one of the core motivations for introducing them in C++11.
> auto deduction **strips top-level const and references**; to keep them you must write `const auto&` / `auto&` explicitly, whereas decltype preserves the declared type exactly
181
186
182
187
```cpp
183
-
constint ci = 1;
184
-
int n = 2;
185
-
int& ri = n;
188
+
int a = 1;
189
+
int &b = a;
190
+
constint c = 1;
191
+
constint &d = c;
186
192
187
-
auto a = ci; // int — top-level const stripped
188
-
auto b = ri; // int — reference stripped (b is an independent copy of n)
0 commit comments