2
2
<feed xmlns =" http://www.w3.org/2005/Atom" >
3
3
<title >cpprefjp - C++日本語リファレンス</title >
4
4
<link href =" https://cpprefjp.github.io" />
5
- <updated >2025-02-18T06:56:57.566280 </updated >
6
- <id >a30d530b-a708-4f61-b1db-49a90155a35e </id >
5
+ <updated >2025-02-18T11:14:41.416160 </updated >
6
+ <id >6228392d-ee9e-43b1-a9da-4d1c0e94deb8 </id >
7
7
8
8
9
+ <entry >
10
+ <title >contains -- fix sample in flat_multiset</title >
11
+ <link href =" https://cpprefjp.github.io/reference/flat_set/flat_multiset/contains.html" />
12
+ <id >816853121ff41b05699b3edb3ec38c95cce82db5:reference/flat_set/flat_multiset/contains.md</id >
13
+ <updated >2025-02-18T20:11:13+09:00</updated >
14
+
15
+ <summary type =" html" >< pre>< code> diff --git a/reference/flat_set/flat_multiset/contains.md b/reference/flat_set/flat_multiset/contains.md
16
+ index 48e2daa1a..3bc429600 100644
17
+ --- a/reference/flat_set/flat_multiset/contains.md
18
+ +++ b/reference/flat_set/flat_multiset/contains.md
19
+ @@ -51,7 +51,7 @@ return find(x) != end();
20
+
21
+ int main()
22
+ {
23
+ - std::flat_set& lt;int& gt; fs = {3, 1, 4, 1};
24
+ + std::flat_multiset& lt;int& gt; fs = {3, 1, 4, 1};
25
+
26
+ // キー3の要素が含まれているか
27
+ if (fs.contains(3)) {
28
+ < /code>< /pre> </summary >
29
+
30
+ <author >
31
+ <name >suomesta</name >
32
+ <email >shawn316michaels@gmail.com</email >
33
+ </author >
34
+ </entry >
35
+
9
36
<entry >
10
37
<title >[[nodiscard]]をコンストラクタのオーバーロードごとに付加できるようにする [P1771R1] -- C++20 / C++23 : ページタイトルに提案文書の番号を追加</title >
11
38
<link href =" https://cpprefjp.github.io/lang/cpp20/nodiscard_for_constructors.html" />
@@ -1294,250 +1321,4 @@ index f935a13e9..1276d700c 100644
1294
1321
</author >
1295
1322
</entry >
1296
1323
1297
- <entry >
1298
- <title >条件付きで特殊メンバ関数をトリビアルに定義するように -- 例を追加 #1106</title >
1299
- <link href =" https://cpprefjp.github.io/lang/cpp20/conditionally_trivial_special_member_functions.html" />
1300
- <id >e25e0cdc98c39398b391c59c8dfd3368f5ee436c:lang/cpp20/conditionally_trivial_special_member_functions.md</id >
1301
- <updated >2025-02-15T18:40:43+09:00</updated >
1302
-
1303
- <summary type =" html" >< pre>< code> diff --git a/lang/cpp20/conditionally_trivial_special_member_functions.md b/lang/cpp20/conditionally_trivial_special_member_functions.md
1304
- index 6820cc28b..7a305b64c 100644
1305
- --- a/lang/cpp20/conditionally_trivial_special_member_functions.md
1306
- +++ b/lang/cpp20/conditionally_trivial_special_member_functions.md
1307
- @@ -64,25 +64,217 @@ struct wrap {
1308
-
1309
- ## 例
1310
-
1311
- -(執筆中)
1312
- +`std::optional& lt;T& gt;`の簡易実装を考える。デストラクタについて、要素型`T`が[`trivially_destructible`](/reference/type_traits/is_trivially_destructible.md)であるかどうかに応じて`optional& lt;T& gt;`のデストラクタのトリビアル性も切り替えたい場合、次のような実装になる
1313
- +
1314
- +```cpp
1315
- +// デストラクタがトリビアルでない場合のストレージ型
1316
- +template& lt;typename T, bool = std::is_trivially_destructible_v& lt;T& gt;& gt;
1317
- +struct optional_storage {
1318
- + union {
1319
- + char dummy;
1320
- + T data;
1321
- + };
1322
- + bool has_value = false;
1323
- +
1324
- + // デストラクタは常に非トリビアルでdeleteされているので定義する
1325
- + ~optional_storage() {
1326
- + if (has_value) {
1327
- + this-& gt;data.~T();
1328
- + }
1329
- + }
1330
- +};
1331
- +
1332
- +// デストラクタがトリビアルである場合のストレージ型
1333
- +template& lt;typename T& gt;
1334
- +struct optional_storage& lt;T, true& gt; {
1335
- + union {
1336
- + char dummy;
1337
- + T data;
1338
- + };
1339
- + bool has_value = false;
1340
- +
1341
- + // デストラクタはトリビアルであり常にdeleteされないので、宣言も不要
1342
- +};
1343
- +
1344
- +template& lt;typename T& gt;
1345
- +class my_optional : private optional_storage& lt;T& gt; {
1346
- +public:
1347
- +
1348
- + // 略
1349
- + ...
1350
- +
1351
- + // デストラクタ、この宣言も実はいらない
1352
- + ~my_optional() = default;
1353
- +};
1354
- +```
1355
- +
1356
- +無効値と有効値でストレージを共有し、なおかつ遅延初期化等を行いながら動的確保や追加のストレージ消費を抑えるためには共用体を使用する。共用体の特殊メンバ関数はそのメンバ型のもつ特殊メンバ関数が1つでも非トリビアルであるならば対応する特殊メンバ関数が`delete`されるため、その場合はユーザーが定義しなければならない。しかしそれを一つの型の中で行うことができなかったため、このようにデストラクタの実装を行うレイヤにおいて型を分割する必要があった。
1357
- +
1358
- +これをこの機能を用いて書き直すと、次のような実装になる
1359
- +
1360
- +```cpp
1361
- +template& lt;typename T& gt;
1362
- +class my_optional {
1363
- + bool has_value = false;
1364
- + union {
1365
- + char dummy;
1366
- + T data;
1367
- + };
1368
- +
1369
- +public:
1370
- +
1371
- + // 略
1372
- + ...
1373
- +
1374
- + // Tのデストラクタがトリビアルならばこちらが有効化
1375
- + ~my_optional() requires std::is_trivially_destructible_v& lt;T& gt; = default;
1376
- +
1377
- + // そうでないならばこちらが有効化
1378
- + ~my_optional() {
1379
- + this-& gt;reset();
1380
- + }
1381
- +
1382
- + // reset()の定義も同様の記法で分岐できる
1383
- +
1384
- + void reset() requires std::is_trivially_destructible_v& lt;T& gt; {
1385
- + this-& gt;has_value = false;
1386
- + }
1387
- +
1388
- + void reset() {
1389
- + if (this-& gt;has_value) {
1390
- + this-& gt;data.~T();
1391
- + }
1392
- + this-& gt;has_value = false;
1393
- + }
1394
- +};
1395
- +```
1396
- +
1397
- +コンセプトによって`T`の(デストラクタの)トリビアル性に応じてデストラクタを選択できるようになるため、先ほどのような定義を分けるためのレイヤが不要になり、コード量を大きく削減することができる。
1398
- +
1399
- +元の(この機能を使わない)実装に戻って、さらにコピーコンストラクタとムーブコンストラクタ、そしてコピー/ムーブ代入演算子についても同様に`T`のトリビアル性に応じて`default`とするかを切り替えることを考える。実装としてはデストラクタの時と同様に基底クラスにその判定と分岐を行うレイヤを追加して、そこで`T`の性質に応じた宣言(ユーザー定義/`default`定義)を記述していくことになるが、その総数はデストラクタのためのレイヤも含めて全5層に達し、実装はかなり複雑になる(このためここでは省略するが、この実装に興味がある場合、MSVC STLの[`xsmf_control.h`](https://github.com/microsoft/STL/blob/main/stl/inc/xsmf_control.h)およびこれを利用した`std::optional`/`std::variant`の実装が参考になると思われる)。
1400
- +
1401
- +しかし、この機能を使用すると先ほどのデストラクタの場合と同様にそのような不要なレイヤを必要とすることなくシンプルに記述できる
1402
-
1403
- ```cpp example
1404
- -// (ここには、言語機能の使い方を解説するための、サンプルコードを記述します。)
1405
- -// (インクルードとmain()関数を含む、実行可能なサンプルコードを記述してください。そのようなコードブロックにはexampleタグを付けます。)
1406
- +#include & lt;type_traits& gt;
1407
- +#include & lt;string& gt;
1408
- +
1409
- +template& lt;typename T& gt;
1410
- +class my_optional {
1411
- + bool has_value = false;
1412
- + union {
1413
- + char dummy;
1414
- + T data;
1415
- + };
1416
- +
1417
- +public:
1418
- +
1419
- + // デフォルトコンストラクタ
1420
- + constexpr my_optional()
1421
- + : has_value(false)
1422
- + , dummy{}
1423
- + {}
1424
- +
1425
- + // 値を受け取るコンストラクタ
1426
- + template& lt;typename U=T& gt;
1427
- + constexpr my_optional(U& amp;& amp; v)
1428
- + : has_value(true)
1429
- + , data(std::forward& lt;U& gt;(v))
1430
- + {}
1431
- +
1432
- + // トリビアルに定義できるならそうする
1433
- + my_optional(const my_optional& amp; that) requires std::is_trivially_copy_constructible_v& lt;T& gt; = default;
1434
- + my_optional(my_optional& amp;& amp; that) requires std::is_trivially_move_constructible_v& lt;T& gt; = default;
1435
- + my_optional& amp; operator=(const my_optional& amp; that) requires std::is_trivially_copy_assignable_v& lt;T& gt; = default;
1436
- + my_optional& amp; operator=(my_optional& amp;& amp; that) requires std::is_trivially_move_assignable_v& lt;T& gt; = default;
1437
- + ~my_optional() requires std::is_trivially_destructible_v& lt;T& gt; = default;
1438
- +
1439
- +
1440
- + // そうでない場合はユーザー定義する
1441
- +
1442
- + my_optional(const my_optional& amp; that)
1443
- + : has_value(that.has_value)
1444
- + , dummy{}
1445
- + {
1446
- + if (that.has_value) {
1447
- + new (& amp;this-& gt;data) T(that.data);
1448
- + }
1449
- + }
1450
-
1451
- -#include & lt;iostream& gt;
1452
- + my_optional(my_optional& amp;& amp; that)
1453
- + : has_value(that.has_value)
1454
- + , dummy{}
1455
- + {
1456
- + if (that.has_value) {
1457
- + new (& amp;this-& gt;data) T(std::move(that.data));
1458
- + }
1459
- + }
1460
-
1461
- -int main()
1462
- -{
1463
- - int variable = 0;
1464
- - std::cout & lt;& lt; variable & lt;& lt; std::endl;
1465
- + my_optional& amp; operator=(const my_optional& amp; that) {
1466
- + auto copy = that;
1467
- + *this = std::move(copy);
1468
- +
1469
- + return *this;
1470
- + }
1471
- +
1472
- + my_optional& amp; operator=(my_optional& amp;& amp; that) {
1473
- + if (that.has_value) {
1474
- + if (this-& gt;has_value) {
1475
- + this-& gt;data = std::move(that.data);
1476
- + } else {
1477
- + new (& amp;this-& gt;data) T(std::move(that.data));
1478
- + }
1479
- + } else {
1480
- + this-& gt;reset();
1481
- + }
1482
- +
1483
- + return *this;
1484
- + }
1485
- +
1486
- + ~my_optional() {
1487
- + this-& gt;reset();
1488
- + }
1489
- +
1490
- + // reset()の定義も同様の記法で分岐できる
1491
- +
1492
- + void reset() requires std::is_trivially_destructible_v& lt;T& gt; {
1493
- + this-& gt;has_value = false;
1494
- + }
1495
- +
1496
- + void reset() {
1497
- + if (this-& gt;has_value) {
1498
- + this-& gt;data.~T();
1499
- + }
1500
- + this-& gt;has_value = false;
1501
- + }
1502
- +};
1503
- +
1504
- +int main() {
1505
- + // int(全てのメンバ関数はトリビアル)の場合、my_optional& lt;int& gt;も同様になる
1506
- + static_assert(std::is_trivially_destructible_v& lt;my_optional& lt;int& gt;& gt;);
1507
- + static_assert(std::is_trivially_copy_constructible_v& lt;my_optional& lt;int& gt;& gt;);
1508
- + static_assert(std::is_trivially_move_constructible_v& lt;my_optional& lt;int& gt;& gt;);
1509
- + static_assert(std::is_trivially_copy_assignable_v& lt;my_optional& lt;int& gt;& gt;);
1510
- + static_assert(std::is_trivially_move_assignable_v& lt;my_optional& lt;int& gt;& gt;);
1511
- +
1512
- + // std::string(全てのメンバ関数は非トリビアル)の場合、my_optional& lt;std::string& gt;も同様になる
1513
- + static_assert(std::is_trivially_destructible_v& lt;my_optional& lt;std::string& gt;& gt; == false);
1514
- + static_assert(std::is_trivially_copy_constructible_v& lt;my_optional& lt;std::string& gt;& gt; == false);
1515
- + static_assert(std::is_trivially_move_constructible_v& lt;my_optional& lt;std::string& gt;& gt; == false);
1516
- + static_assert(std::is_trivially_copy_assignable_v& lt;my_optional& lt;std::string& gt;& gt; == false);
1517
- + static_assert(std::is_trivially_move_assignable_v& lt;my_optional& lt;std::string& gt;& gt; == false);
1518
- +
1519
- + // しかし、全ての特殊メンバ関数は利用可能(トリビアルでないだけ)
1520
- + static_assert(std::is_destructible_v& lt;my_optional& lt;std::string& gt;& gt;);
1521
- + static_assert(std::is_copy_constructible_v& lt;my_optional& lt;std::string& gt;& gt;);
1522
- + static_assert(std::is_move_constructible_v& lt;my_optional& lt;std::string& gt;& gt;);
1523
- + static_assert(std::is_copy_assignable_v& lt;my_optional& lt;std::string& gt;& gt;);
1524
- + static_assert(std::is_move_assignable_v& lt;my_optional& lt;std::string& gt;& gt;);
1525
- }
1526
- ```
1527
- -* variable[color ff0000]
1528
-
1529
- ### 出力
1530
- ```
1531
- -0
1532
- ```
1533
-
1534
- ## この機能が必要になった背景・経緯
1535
- < /code>< /pre> </summary >
1536
-
1537
- <author >
1538
- <name >onihusube</name >
1539
- <email >mona-@live.jp</email >
1540
- </author >
1541
- </entry >
1542
-
1543
1324
</feed >
0 commit comments