6868
6969 </ head >
7070 < body >
71- < header data-kunai-mdinfo ="{"meta": {"cpp": ["cpp26"]}, "sources": [{"id": "ebad28136dd0620bfc92fd3b73979cc8635d6d09 ", "source": "#include <cassert>\n#include <memory> // std::construct_at()\n\nconstexpr int f() {\n union { int s[4]; };\n // s\u306f\u6697\u9ed9\u7684\ u5bff\u547d\u578b\u306e\u914d\u5217\u306a\u306e\u3067\u3001\u5bff\u547d\u304c\ u958b\u59cb\u3055\u308c \u30a2\u30af\u30c6\u30a3\u30d6\u30e1\u30f3\u30d0\u3068\u306a \u308b\n std::construct_at(&s[0], 1);\n std::construct_at(&s[1], 2);\n std::construct_at(&s[2], 3);\n return s[0] + s[1] + s[2];\n}\n\nint main() {\n static_assert(f() == 6);\n}\n"}], "page_id": ["lang", "cpp26", "trivial_unions"]} ">
71+ < header data-kunai-mdinfo ="{"meta": {"cpp": ["cpp26"]}, "sources": [{"id": "f59aa2bfdbc23ba555e7d8997d53f68ed0573d1a ", "source": "#include <cassert>\n#include <memory> // std::construct_at(), std::start_lifetime() \n\nconstexpr int f() {\n union { int s[4]; };\n // \u914d\u5217s\u81ea\u4f53\u306e\ u5bff\u547d\u3092\u660e\u793a\u7684\u306b\ u958b\u59cb\u3057\u3001 \u30a2\u30af\u30c6\u30a3\u30d6\u30e1\u30f3\u30d0\u306b\u3059 \u308b\n std::start_lifetime(s); \n std::construct_at(&s[0], 1);\n std::construct_at(&s[1], 2);\n std::construct_at(&s[2], 3);\n return s[0] + s[1] + s[2];\n}\n\nint main() {\n static_assert(f() == 6);\n}\n"}], "page_id": ["lang", "cpp26", "trivial_unions"]} ">
7272 < nav class ="navbar navbar-default " role ="navigation ">
7373 < div class ="container-fluid ">
7474 < div class ="navbar-header ">
189189 < p class ="text-right "> < small >
190190 最終更新日時:
191191 < time itemprop ="datePublished " class ="js-local-time "
192- datetime ="2026-08-08T21:05:00 +09:00 ">
193- 2026年08月08日 21時05分00秒 (JST)
192+ datetime ="2026-09-07T12:00:37 +09:00 ">
193+ 2026年09月07日 12時00分37秒 (JST)
194194 </ time >
195195 < br />
196196 < span itemprop ="author " itemscope itemtype ="http://schema.org/Person ">
197- < span itemprop ="name "> rotarymars </ span >
197+ < span itemprop ="name "> Akira Takahashi </ span >
198198 </ span >
199199 が更新
200200 </ small > </ p >
@@ -253,7 +253,10 @@ <h2>概要</h2>
253253
254254< span class ="w "> </ span > < span class ="c1 "> // C++23まで: unionのコンストラクタ/デストラクタが削除されるためコンパイルエラー</ span >
255255< span class ="w "> </ span > < span class ="c1 "> // C++26: OK。unionのコンストラクタ/デストラクタはトリビアル</ span >
256- < span class ="w "> </ span > < span class ="k "> constexpr</ span > < span class ="w "> </ span > < span class ="n "> FixedVector</ span > < span class ="p "> ()</ span > < span class ="w "> </ span > < span class ="o "> =</ span > < span class ="w "> </ span > < span class ="k "> default</ span > < span class ="p "> ;</ span >
256+ < span class ="w "> </ span > < span class ="k "> constexpr</ span > < span class ="w "> </ span > < span class ="n "> FixedVector</ span > < span class ="p "> ()</ span > < span class ="w "> </ span > < span class ="p "> {</ span >
257+ < span class ="w "> </ span > < span class ="c1 "> // 配列storage自体の生存期間を明示的に開始する(要素の生存期間は開始されない)</ span >
258+ < span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/start_lifetime.html "> std::start_lifetime</ a > </ span > < span class ="p "> (</ span > < span class ="n "> storage</ span > < span class ="p "> );</ span >
259+ < span class ="w "> </ span > < span class ="p "> }</ span >
257260
258261< span class ="w "> </ span > < span class ="k "> constexpr</ span > < span class ="w "> </ span > < span class ="o "> ~</ span > < span class ="n "> FixedVector</ span > < span class ="p "> ()</ span > < span class ="w "> </ span > < span class ="p "> {</ span >
259262< span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/destroy.html "> std::destroy</ a > </ span > < span class ="p "> (</ span > < span class ="n "> storage</ span > < span class ="p "> ,</ span > < span class ="w "> </ span > < span class ="n "> storage</ span > < span class ="w "> </ span > < span class ="o "> +</ span > < span class ="w "> </ span > < span class ="n "> size</ span > < span class ="p "> );</ span >
@@ -272,7 +275,10 @@ <h3>デフォルトコンストラクタの規則</h3>
272275< ul >
273276< li > デフォルトメンバ初期化子をもつメンバがない</ li >
274277</ ul >
275- < p > トリビアルなデフォルトコンストラクタは、いかなる初期化も実行しない。ただし、共用体の最初の選択肢 (variant member) が暗黙的寿命型 (implicit-lifetime type) の場合は、そのオブジェクトの寿命が開始され、アクティブメンバとなる。</ p >
278+ < p > トリビアルなデフォルトコンストラクタは、いかなる初期化も実行せず、どのメンバの寿命も開始しない。メンバの寿命は< code > < a href ="../../reference/memory/start_lifetime.html "> std::start_lifetime()</ a > </ code > などで明示的に開始する。</ p >
279+ < ul >
280+ < li > 本提案の当初の仕様では「共用体の最初の選択肢 (variant member) が暗黙的寿命型 (implicit-lifetime type) の場合、トリビアルなデフォルトコンストラクタがそのメンバの寿命を暗黙に開始する」とされていたが、この規則はABI破壊などの問題があったため、< a href ="adjustments_to_union_lifetime_rules.html "> P3726R2で撤回された</ a > </ li >
281+ </ ul >
276282< p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="c1 "> // トリビアルデフォルトコンストラクタ、トリビアルデストラクタ</ span >
277283< span class ="c1 "> // sの寿命は開始されない</ span >
278284< span class ="k "> union</ span > < span class ="w "> </ span > < span class ="nc "> U1</ span > < span class ="w "> </ span > < span class ="p "> {</ span > < span class ="w "> </ span > < span class ="n "> < a href ="../../reference/string/basic_string.html "> std::string</ a > </ span > < span class ="w "> </ span > < span class ="n "> s</ span > < span class ="p "> ;</ span > < span class ="w "> </ span > < span class ="p "> };</ span >
@@ -282,7 +288,7 @@ <h3>デフォルトコンストラクタの規則</h3>
282288< span class ="k "> union</ span > < span class ="w "> </ span > < span class ="nc "> U2</ span > < span class ="w "> </ span > < span class ="p "> {</ span > < span class ="w "> </ span > < span class ="n "> < a href ="../../reference/string/basic_string.html "> std::string</ a > </ span > < span class ="w "> </ span > < span class ="n "> s</ span > < span class ="w "> </ span > < span class ="o "> =</ span > < span class ="w "> </ span > < span class ="s "> "hello"</ span > < span class ="p "> ;</ span > < span class ="w "> </ span > < span class ="p "> };</ span >
283289
284290< span class ="c1 "> // トリビアルデフォルトコンストラクタ、トリビアルデストラクタ</ span >
285- < span class ="c1 "> // s (配列は暗黙的寿命型) の寿命が開始され、アクティブメンバとなる </ span >
291+ < span class ="c1 "> // sの寿命は開始されない(P3726R2により、配列でも暗黙開始はされない) </ span >
286292< span class ="k "> union</ span > < span class ="w "> </ span > < span class ="nc "> U3</ span > < span class ="w "> </ span > < span class ="p "> {</ span > < span class ="w "> </ span > < span class ="n "> < a href ="../../reference/string/basic_string.html "> std::string</ a > </ span > < span class ="w "> </ span > < span class ="n "> s</ span > < span class ="p "> [</ span > < span class ="mi "> 10</ span > < span class ="p "> ];</ span > < span class ="w "> </ span > < span class ="p "> };</ span >
287293</ code > </ pre > </ div >
288294</ p >
@@ -300,12 +306,13 @@ <h3>デストラクタの規則</h3>
300306</ p >
301307< h3 > constexprでの使用</ h3 >
302308< p > この変更により、共用体を未初期化ストレージとして< code > constexpr</ code > の文脈で使用できるようになる。</ p >
303- < p > < div class ="yata " id ="ebad28136dd0620bfc92fd3b73979cc8635d6d09 "> < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include < a href ="../../reference/cassert.html "> <cassert></ a > </ span >
304- < span class ="cp "> #include < a href ="../../reference/memory.html "> <memory></ a > </ span > < span class ="c1 "> // < a href ="../../reference/memory/construct_at.html "> std::construct_at</ a > ()</ span >
309+ < p > < div class ="yata " id ="f59aa2bfdbc23ba555e7d8997d53f68ed0573d1a "> < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include < a href ="../../reference/cassert.html "> <cassert></ a > </ span >
310+ < span class ="cp "> #include < a href ="../../reference/memory.html "> <memory></ a > </ span > < span class ="c1 "> // < a href ="../../reference/memory/construct_at.html "> std::construct_at</ a > (), < a href =" ../../reference/memory/start_lifetime.html " > std::start_lifetime </ a > () </ span >
305311
306312< span class ="k "> constexpr</ span > < span class ="w "> </ span > < span class ="kt "> int</ span > < span class ="w "> </ span > < span class ="nf "> f</ span > < span class ="p "> ()</ span > < span class ="w "> </ span > < span class ="p "> {</ span >
307313< span class ="w "> </ span > < span class ="k "> union</ span > < span class ="w "> </ span > < span class ="p "> {</ span > < span class ="w "> </ span > < span class ="kt "> int</ span > < span class ="w "> </ span > < span class ="n "> s</ span > < span class ="p "> [</ span > < span class ="mi "> 4</ span > < span class ="p "> ];</ span > < span class ="w "> </ span > < span class ="p "> };</ span >
308- < span class ="w "> </ span > < span class ="c1 "> // sは暗黙的寿命型の配列なので、寿命が開始されアクティブメンバとなる</ span >
314+ < span class ="w "> </ span > < span class ="c1 "> // 配列s自体の寿命を明示的に開始し、アクティブメンバにする</ span >
315+ < span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/start_lifetime.html "> std::start_lifetime</ a > </ span > < span class ="p "> (</ span > < span class ="n "> s</ span > < span class ="p "> );</ span >
309316< span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/construct_at.html "> std::construct_at</ a > </ span > < span class ="p "> (</ span > < span class ="o "> &</ span > < span class ="n "> s</ span > < span class ="p "> [</ span > < span class ="mi "> 0</ span > < span class ="p "> ],</ span > < span class ="w "> </ span > < span class ="mi "> 1</ span > < span class ="p "> );</ span >
310317< span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/construct_at.html "> std::construct_at</ a > </ span > < span class ="p "> (</ span > < span class ="o "> &</ span > < span class ="n "> s</ span > < span class ="p "> [</ span > < span class ="mi "> 1</ span > < span class ="p "> ],</ span > < span class ="w "> </ span > < span class ="mi "> 2</ span > < span class ="p "> );</ span >
311318< span class ="w "> </ span > < span class ="n "> < a href ="../../reference/memory/construct_at.html "> std::construct_at</ a > </ span > < span class ="p "> (</ span > < span class ="o "> &</ span > < span class ="n "> s</ span > < span class ="p "> [</ span > < span class ="mi "> 2</ span > < span class ="p "> ],</ span > < span class ="w "> </ span > < span class ="mi "> 3</ span > < span class ="p "> );</ span >
@@ -338,10 +345,16 @@ <h2><a href="#relative-page" id="relative-page">関連項目</a></h2>
338345< li > < a href ="constexpr_placement_new.html "> C++26 < code > constexpr</ code > 配置< code > new</ code > </ a > </ li >
339346< li > < a href ="allowing_exception_throwing_in_constant-evaluation.html "> C++26 定数評価での例外送出を許可</ a > </ li >
340347< li > < code > < a href ="../../reference/inplace_vector/inplace_vector.html "> std::inplace_vector</ a > </ code > </ li >
348+ < li > < a href ="adjustments_to_union_lifetime_rules.html "> C++26 共用体メンバの生存期間規則の調整</ a > </ li >
349+ < li > < code > < a href ="../../reference/memory/start_lifetime.html "> std::start_lifetime()</ a > </ code > </ li >
341350</ ul >
342351< h2 > 参照</ h2 >
343352< ul >
344353< li > < a href ="https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3074r7.html " target ="_blank "> P3074R7 trivial unions (was std::uninitialized)</ a > </ li >
354+ < li > < a href ="https://open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3726r2.html " target ="_blank "> P3726R2 Adjustments to Union Lifetime Rules</ a > < ul >
355+ < li > 先頭メンバの寿命の暗黙開始を撤回し、< code > < a href ="../../reference/memory/start_lifetime.html "> std::start_lifetime()</ a > </ code > による明示的な開始へ変更した</ li >
356+ </ ul >
357+ </ li >
345358</ ul > </ div >
346359
347360 </ div >
0 commit comments