Skip to content

Commit 2dae610

Browse files
committed
docs(cpp11): add STL real-world case and exercise mapping for 16-generalized-unions
- add section 二 真实案例 — include std::variant _Variant_storage_ and std::any _Storage_t examples, both cited from vendored msvc-stl/ - fill in 四 练习代码 — exercise descriptions, file links and d2x checker command - fix empty Code link in header table Case selection notes: Picked _Variant_storage_ over std::optional _Optional_destruct_base because the variant recursive union demonstrates both key C++11 generalized-union capabilities — non-trivial members and manual destructor management — while the optional pattern is effectively a special case of variant. std::any adds a second typical use: union as type-erased storage. Both are directly traceable in the vendored msvc-stl/, consistent with how ch00 cites xutility.
1 parent 307dc8a commit 2dae610

1 file changed

Lines changed: 62 additions & 5 deletions

File tree

book/src/cpp11/16-generalized-unions.md

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
| Book | Video | Code | X |
1616
| --- | --- | --- | --- |
17-
| [cppreference-union](https://cppreference.com/w/cpp/language/union.html) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp11/16-generalized-unions.md) | [视频解读]() | [练习代码]() | |
17+
| [cppreference-union](https://cppreference.com/w/cpp/language/union.html) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp11/16-generalized-unions.md) | [视频解读]() | [练习代码](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/16-generalized-unions-0.cpp) | |
1818

1919
**为什么引入**
2020

@@ -126,7 +126,55 @@ int main() {
126126
}
127127
```
128128

129-
## 二、注意事项
129+
## 二、真实案例 - STL 中的广义联合体
130+
131+
**std::variant 的内部存储 - 递归广义联合体**
132+
> 以仓库内置的 [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) 中的 `std::variant` 实现为例 (源码: [`msvc-stl/stl/inc/variant`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/variant#L343-L399)), `_CONSTEXPR20` / `_STD` 是库内部宏, 阅读时可忽略
133+
134+
```cpp
135+
// MSVC STL · msvc-stl/stl/inc/variant (有删节)
136+
template <class _First, class... _Rest>
137+
class _Variant_storage_<false, _First, _Rest...> {
138+
public:
139+
union {
140+
remove_cv_t<_First> _Head;
141+
_Variant_storage<_Rest...> _Tail;
142+
};
143+
144+
_CONSTEXPR20 ~_Variant_storage_() noexcept {
145+
// 联合体不知道哪个成员活跃, 析构由外层 variant 控制
146+
}
147+
// ...
148+
};
149+
```
150+
151+
`std::variant` 通过递归联合体在一块内存里容纳多个不同类型, 非平凡析构版本必须显式定义析构函数 — 这正是 C++11 广义联合体的核心能力: 联合体可以包含有非平凡特殊成员函数的成员, 但需要手动管理生命周期
152+
153+
**std::any 的小对象优化 - 联合体做类型擦除存储**
154+
> `std::any` 使用联合体将小对象、大对象指针和原始缓冲区合并到同一块内存 (源码: [`msvc-stl/stl/inc/any`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/any#L362-L376))
155+
156+
```cpp
157+
// MSVC STL · msvc-stl/stl/inc/any (有删节)
158+
class any {
159+
struct _Storage_t {
160+
union {
161+
unsigned char _TrivialData[_Any_trivial_space_size];
162+
_Small_storage_t _SmallStorage;
163+
_Big_storage_t _BigStorage;
164+
};
165+
uintptr_t _TypeData;
166+
};
167+
168+
union {
169+
_Storage_t _Storage{};
170+
max_align_t _Dummy;
171+
};
172+
};
173+
```
174+
175+
> 小结: `std::variant`、`std::any` 的核心存储都依赖广义联合体。C++11 之前联合体只能容纳 POD 类型, 标准库不得不用原始字节缓冲区 + placement new 的迂回方案; 广义联合体让代码可以直接表达"多选一"的语义, 类型安全且更易维护
176+
177+
## 三、注意事项
130178
131179
**可访问性**
132180
@@ -170,11 +218,20 @@ m.a = 1;
170218
double c = m.b; // 错误:未定义行为
171219
```
172220

173-
## 三、练习代码
221+
## 四、练习代码
222+
223+
### 练习代码主题
174224

175-
TODO
225+
- 0 - [联合体默认成员初始化](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/16-generalized-unions-0.cpp) — C++11 规则: 最多一个变体成员可带默认初始化器
226+
- 1 - [联合体包含非平凡类型及生命周期管理](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/16-generalized-unions-1.cpp) — placement new 构造 / 显式析构 / 非平凡成员的正确访问
227+
228+
### 练习代码自动检测命令
229+
230+
```
231+
d2x checker generalized-unions
232+
```
176233

177-
## 、其他
234+
## 、其他
178235

179236
- [交流讨论](https://forum.d2learn.org/category/20)
180237
- [d2mcpp教程仓库](https://github.com/mcpp-community/d2mcpp)

0 commit comments

Comments
 (0)