6868
6969 </ head >
7070 < body >
71- < header data-kunai-mdinfo ="{"meta": {"cpp": ["cpp20"]}, "sources": [{"id": "de6681b74fc48ef06158b091d3afe2be040eed6e", "source": "#include <iostream>\n#include <string_view>\n#include <string>\n#include <new>\n#include <memory>\n#include <cstring>\n\nclass inlined_fixed_string {\n size_t length;\n\n inlined_fixed_string(size_t size, const char *data)\n : length(size)\n {\n // \u81ea\u8eab\u306e\u5f8c\u308d\u306b\u3042\u308b\u9818\u57df\u306b\u6587\u5b57\u5217\u3092\u30b3\u30d4\u30fc\u3059\u308b\n // P0593R6\u306e\u52b9\u679c\u306b\u3088\u3063\u3066\u3001char\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u751f\u5b58\u671f\u9593\u304c\u81ea\u52d5\u958b\u59cb\u3055\u308c\u308b\uff08C++20\u4ee5\u964d\uff09\n std::memcpy(this + 1, data, size);\n }\n\npublic:\n inlined_fixed_string() = delete;\n\n auto size() const -> std::size_t {\n return length;\n }\n\n auto view() const -> std::string_view {\n // this\u306e\u5f8c\u308d\u306b\u306flength\u500b\u306echar\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u751f\u5b58\u671f\u9593\u5185\u306b\u3042\u308b\u305f\u3081\u3001\u3053\u306ereinterpret_cast\u306f\u554f\u984c\u306a\u3044\n return { reinterpret_cast<const char*>(this + 1), this->size() };\n }\n\n // std::string\u304b\u3089\u69cb\u7bc9\u3059\u308b\u30d5\u30a1\u30af\u30c8\u30ea\u95a2\u6570\n static auto Make(const std::string& str) -> inlined_fixed_string* {\n // \u81ea\u8eab\u306e\u672b\u5c3e\u306b\u56fa\u5b9a\u9577\uff08\u5b9f\u884c\u6642\u53ef\u5909\u9577\uff09\u306e\u6587\u5b57\u5217\u7528\u9818\u57df\u3092\u78ba\u4fdd\u3059\u308b\n const std::size_t full_size = sizeof(inlined_fixed_string) + str.length() + 1;\n\n // \u30d1\u30c7\u30a3\u30f3\u30b0\u3057\u305f\u30b5\u30a4\u30ba\u3067\u30e1\u30e2\u30ea\u306e\u78ba\u4fdd\n // new\u5f0f\u3067\u306f\u306a\u304f\u30b0\u30ed\u30fc\u30d0\u30ebnew\u6f14\u7b97\u5b50\u306e\u547c\u51fa\n auto* p = ::operator new(full_size);\n\n // \u30ed\u30b0\u51fa\u529b\n std::cout << \"inlined_fixed_string::Make() : \" << full_size <<\" byte allocate.\\n\";\n\n // \u78ba\u4fdd\u3057\u305f\u30e1\u30e2\u30ea\u9818\u57df\u306bplacement new\u3057\u3066\u69cb\u7bc9\n // \u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u5185\u3067\u6587\u5b57\u5217\u3092\u30b3\u30d4\u30fc\n return ::new(p) inlined_fixed_string(str.length() + 1, str.c_str());\n }\n\n // \u78ba\u4fdd\u3057\u305f\u9818\u57df\u3092\u542b\u3081\u3066delete\n void operator delete(inlined_fixed_string* p, std::destroying_delete_t) {\n // \u672b\u5c3e\u9818\u57df\u306e\u9577\u3055\u3092\u53d6\u5f97\n const std::size_t full_size = sizeof(inlined_fixed_string) + p->length;\n\n // \u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u547c\u3073\u51fa\u3057\n std::destroy_at(p);\n\n // char\uff08\u30c8\u30ea\u30d3\u30a2\u30eb\u306b\u7834\u68c4\u53ef\u80fd\u306a\uff09\u578b\u306f\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u547c\u3073\u51fa\u3057\u3092\u7701\u7565\u53ef\u80fd\n std::ranges::destroy(p + 1, p + 1 + p->length + 1);\n\n // \u30e1\u30e2\u30ea\u89e3\u653e\n ::operator delete(p, full_size);\n\n // \u30ed\u30b0\u51fa\u529b\n std::cout << \"inlined_fixed_string::operator delete() : \" << full_size <<\" byte deallocate.\\n\";\n }\n};\n\nint main() {\n std::string str = \"C++20 destroying operator delete test.\";\n auto* p = inlined_fixed_string::Make(str);\n\n std::cout << p->view() << \"\\n\";\n\n delete p;\n}\n"}, {"id": "b1b899f1ce84cd2f71d578dc5c7fc96db4946932", "source": "#include <iostream>\n#include <new>\n\n// \u4eee\u60f3\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u3092\u5b9a\u7fa9\u3057\u306a\u3044\u57fa\u5e95\u30af\u30e9\u30b9\nstruct base {\n int kind = 0;\n\n // destroying operator delete\u5ba3\u8a00 #1\n void operator delete(base* p, std::destroying_delete_t);\n};\n\nstruct derived1 : base {\n derived1() : base{1} {}\n};\n\nstruct derived2 : base {\n derived2() : base{2} {}\n};\n\n// #1\u306b\u5bfe\u5fdc\u3059\u308b\u5b9a\u7fa9\nvoid base::operator delete(base* p, std::destroying_delete_t) {\n\n switch(p->kind) {\n case 1:\n {\n auto* dp = static_cast<derived1*>(p);\n std::destroy_at(dp);\n ::operator delete(dp);\n std::cout << \"destruct derived1\\n\";\n break;\n }\n case 2:\n {\n auto* dp = static_cast<derived2*>(p);\n std::destroy_at(dp);\n ::operator delete(dp);\n std::cout << \"destruct derived2\\n\";\n break;\n }\n default:\n std::destroy_at(p);\n ::operator delete(p);\n std::cout << \"destruct base\\n\";\n }\n}\n\nint main() {\n {\n base* p = new derived1{};\n // #1\u306b\u3088\u3063\u3066derived1\u306e\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u304c\u547c\u3070\u308c\u3001\u30e1\u30e2\u30ea\u304c\u89e3\u653e\u3055\u308c\u308b\n delete p;\n }\n {\n base* p = new derived2{};\n // #1\u306b\u3088\u3063\u3066derived2\u306e\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u304c\u547c\u3070\u308c\u3001\u30e1\u30e2\u30ea\u304c\u89e3\u653e\u3055\u308c\u308b\n delete p;\n }\n}\n"}], "page_id": ["lang", "cpp20", "efficient_sized_delete_for_variable_sized_classes"]} ">
71+ < header data-kunai-mdinfo ="{"meta": {"cpp": ["cpp20"]}, "sources": [{"id": "f4096cfab9fe5483a7e93c46af6c3801abb36160", "source": "#include <iostream>\n#include <string_view>\n#include <string>\n#include <new>\n#include <memory>\n#include <cstring>\n\nclass inlined_fixed_string {\n size_t length;\n\n inlined_fixed_string(size_t size, const char *data)\n : length(size)\n {\n // \u81ea\u8eab\u306e\u5f8c\u308d\u306b\u3042\u308b\u9818\u57df\u306b\u6587\u5b57\u5217\u3092\u30b3\u30d4\u30fc\u3059\u308b\n // P0593R6\u306e\u52b9\u679c\u306b\u3088\u3063\u3066\u3001char\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u751f\u5b58\u671f\u9593\u304c\u81ea\u52d5\u958b\u59cb\u3055\u308c\u308b\uff08C++20\u4ee5\u964d\uff09\n std::memcpy(this + 1, data, size);\n }\n\npublic:\n inlined_fixed_string() = delete;\n\n auto size() const -> std::size_t {\n return length - 1;\n }\n\n auto view() const -> std::string_view {\n // this\u306e\u5f8c\u308d\u306b\u306flength\u500b\u306echar\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u751f\u5b58\u671f\u9593\u5185\u306b\u3042\u308b\u305f\u3081\u3001\u3053\u306ereinterpret_cast\u306f\u554f\u984c\u306a\u3044\n return { reinterpret_cast<const char*>(this + 1), this->size() };\n }\n\n // std::string\u304b\u3089\u69cb\u7bc9\u3059\u308b\u30d5\u30a1\u30af\u30c8\u30ea\u95a2\u6570\n static auto Make(const std::string& str) -> inlined_fixed_string* {\n // \u81ea\u8eab\u306e\u672b\u5c3e\u306b\u56fa\u5b9a\u9577\uff08\u5b9f\u884c\u6642\u53ef\u5909\u9577\uff09\u306e\u6587\u5b57\u5217\u7528\u9818\u57df\u3092\u78ba\u4fdd\u3059\u308b\n const std::size_t full_size = sizeof(inlined_fixed_string) + str.length() + 1;\n\n // \u30d1\u30c7\u30a3\u30f3\u30b0\u3057\u305f\u30b5\u30a4\u30ba\u3067\u30e1\u30e2\u30ea\u306e\u78ba\u4fdd\n // new\u5f0f\u3067\u306f\u306a\u304f\u30b0\u30ed\u30fc\u30d0\u30ebnew\u6f14\u7b97\u5b50\u306e\u547c\u51fa\n auto* p = ::operator new(full_size);\n\n // \u30ed\u30b0\u51fa\u529b\n std::cout << \"inlined_fixed_string::Make() : \" << full_size <<\" byte allocate.\\n\";\n\n // \u78ba\u4fdd\u3057\u305f\u30e1\u30e2\u30ea\u9818\u57df\u306bplacement new\u3057\u3066\u69cb\u7bc9\n // \u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u5185\u3067\u6587\u5b57\u5217\u3092\u30b3\u30d4\u30fc\n return ::new(p) inlined_fixed_string(str.length() + 1, str.c_str());\n }\n\n // \u78ba\u4fdd\u3057\u305f\u9818\u57df\u3092\u542b\u3081\u3066delete\n void operator delete(inlined_fixed_string* p, std::destroying_delete_t) {\n // \u672b\u5c3e\u9818\u57df\u306e\u9577\u3055\u3092\u53d6\u5f97\n const std::size_t full_size = sizeof(inlined_fixed_string) + p->length;\n\n // char\uff08\u30c8\u30ea\u30d3\u30a2\u30eb\u306b\u7834\u68c4\u53ef\u80fd\u306a\uff09\u578b\u306f\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u547c\u3073\u51fa\u3057\u3092\u7701\u7565\u53ef\u80fd\n std::ranges::destroy(reinterpret_cast<char*>(p + 1), reinterpret_cast<char*>(p + 1) + p->length);\n\n // \u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u547c\u3073\u51fa\u3057\n std::destroy_at(p);\n\n // \u30e1\u30e2\u30ea\u89e3\u653e\n ::operator delete(p, full_size);\n\n // \u30ed\u30b0\u51fa\u529b\n std::cout << \"inlined_fixed_string::operator delete() : \" << full_size <<\" byte deallocate.\\n\";\n }\n};\n\nint main() {\n std::string str = \"C++20 destroying operator delete test.\";\n auto* p = inlined_fixed_string::Make(str);\n\n std::cout << p->view() << \"\\n\";\n\n delete p;\n}\n"}, {"id": "b1b899f1ce84cd2f71d578dc5c7fc96db4946932", "source": "#include <iostream>\n#include <new>\n\n// \u4eee\u60f3\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u3092\u5b9a\u7fa9\u3057\u306a\u3044\u57fa\u5e95\u30af\u30e9\u30b9\nstruct base {\n int kind = 0;\n\n // destroying operator delete\u5ba3\u8a00 #1\n void operator delete(base* p, std::destroying_delete_t);\n};\n\nstruct derived1 : base {\n derived1() : base{1} {}\n};\n\nstruct derived2 : base {\n derived2() : base{2} {}\n};\n\n// #1\u306b\u5bfe\u5fdc\u3059\u308b\u5b9a\u7fa9\nvoid base::operator delete(base* p, std::destroying_delete_t) {\n\n switch(p->kind) {\n case 1:\n {\n auto* dp = static_cast<derived1*>(p);\n std::destroy_at(dp);\n ::operator delete(dp);\n std::cout << \"destruct derived1\\n\";\n break;\n }\n case 2:\n {\n auto* dp = static_cast<derived2*>(p);\n std::destroy_at(dp);\n ::operator delete(dp);\n std::cout << \"destruct derived2\\n\";\n break;\n }\n default:\n std::destroy_at(p);\n ::operator delete(p);\n std::cout << \"destruct base\\n\";\n }\n}\n\nint main() {\n {\n base* p = new derived1{};\n // #1\u306b\u3088\u3063\u3066derived1\u306e\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u304c\u547c\u3070\u308c\u3001\u30e1\u30e2\u30ea\u304c\u89e3\u653e\u3055\u308c\u308b\n delete p;\n }\n {\n base* p = new derived2{};\n // #1\u306b\u3088\u3063\u3066derived2\u306e\u30c7\u30b9\u30c8\u30e9\u30af\u30bf\u304c\u547c\u3070\u308c\u3001\u30e1\u30e2\u30ea\u304c\u89e3\u653e\u3055\u308c\u308b\n delete p;\n }\n}\n"}], "page_id": ["lang", "cpp20", "efficient_sized_delete_for_variable_sized_classes"]} ">
7272 < nav class ="navbar navbar-default " role ="navigation ">
7373 < div class ="container-fluid ">
7474 < div class ="navbar-header ">
188188
189189 < p class ="text-right "> < small >
190190 最終更新日時(UTC):
191- < span itemprop ="datePublished " content ="2024-09-03T06:17:49 ">
192- 2024年09月03日 06時17分49秒
191+ < span itemprop ="datePublished " content ="2025-10-14T10:29:40 ">
192+ 2025年10月14日 10時29分40秒
193193 </ span >
194194 < br />
195195 < span itemprop ="author " itemscope itemtype ="http://schema.org/Person ">
196- < span itemprop ="name "> Akira Takahashi </ span >
196+ < span itemprop ="name "> Raclamusi </ span >
197197 </ span >
198198 が更新
199199 </ small > </ p >
@@ -362,7 +362,7 @@ <h2>仕様</h2>
362362< code > #2</ code > において、< code > E</ code > のオブジェクトの破棄とそのメモリ領域の解放は< code > E::operator delete</ code > (< em > destroying operator delete</ em > )によって行われる。</ p >
363363< h2 > 例</ h2 >
364364< h3 > 可変サイズクラスの< code > delete</ code > </ h3 >
365- < p > < div class ="yata " id ="de6681b74fc48ef06158b091d3afe2be040eed6e "> < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include</ span > < span class ="cpf "> < a href ="../../reference/iostream.html "> <iostream></ a > </ span > < span class ="cp "> </ span >
365+ < p > < div class ="yata " id ="f4096cfab9fe5483a7e93c46af6c3801abb36160 "> < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="cp "> #include</ span > < span class ="cpf "> < a href ="../../reference/iostream.html "> <iostream></ a > </ span > < span class ="cp "> </ span >
366366< span class ="cp "> #include</ span > < span class ="cpf "> < a href ="../../reference/string_view.html "> <string_view></ a > </ span > < span class ="cp "> </ span >
367367< span class ="cp "> #include</ span > < span class ="cpf "> < a href ="../../reference/string.html "> <string></ a > </ span > < span class ="cp "> </ span >
368368< span class ="cp "> #include</ span > < span class ="cpf "> < a href ="../../reference/new.html "> <new></ a > </ span > < span class ="cp "> </ span >
@@ -384,7 +384,7 @@ <h3>可変サイズクラスの<code>delete</code></h3>
384384 < span class ="n "> inlined_fixed_string</ span > < span class ="p "> ()</ span > < span class ="o "> =</ span > < span class ="k "> delete</ span > < span class ="p "> ;</ span >
385385
386386 < span class ="k "> auto</ span > < span class ="nf "> size</ span > < span class ="p "> ()</ span > < span class ="k "> const</ span > < span class ="o "> -></ span > < span class ="n "> < a href ="../../reference/cstddef/size_t.html "> std::size_t</ a > </ span > < span class ="p "> {</ span >
387- < span class ="k "> return</ span > < span class ="n "> length</ span > < span class ="p "> ;</ span >
387+ < span class ="k "> return</ span > < span class ="n "> length</ span > < span class =" o " > - </ span > < span class =" mi " > 1 </ span > < span class ="p "> ;</ span >
388388 < span class ="p "> }</ span >
389389
390390 < span class ="k "> auto</ span > < span class ="nf "> < a href ="../../reference/ranges/view.html "> view</ a > </ span > < span class ="p "> ()</ span > < span class ="k "> const</ span > < span class ="o "> -></ span > < span class ="n "> < a href ="../../reference/string_view/basic_string_view.html "> std::string_view</ a > </ span > < span class ="p "> {</ span >
@@ -414,12 +414,12 @@ <h3>可変サイズクラスの<code>delete</code></h3>
414414 < span class ="c1 "> // 末尾領域の長さを取得</ span >
415415 < span class ="k "> const</ span > < span class ="n "> < a href ="../../reference/cstddef/size_t.html "> std::size_t</ a > </ span > < span class ="n "> full_size</ span > < span class ="o "> =</ span > < span class ="k "> sizeof</ span > < span class ="p "> (</ span > < span class ="n "> inlined_fixed_string</ span > < span class ="p "> )</ span > < span class ="o "> +</ span > < span class ="n "> p</ span > < span class ="o "> -></ span > < span class ="n "> length</ span > < span class ="p "> ;</ span >
416416
417+ < span class ="c1 "> // char(トリビアルに破棄可能な)型はデストラクタ呼び出しを省略可能</ span >
418+ < span class ="n "> < a href ="../../reference/memory/ranges_destroy.html "> std::ranges::destroy</ a > </ span > < span class ="p "> (</ span > < span class ="k "> reinterpret_cast</ span > < span class ="o "> <</ span > < span class ="kt "> char</ span > < span class ="o "> *></ span > < span class ="p "> (</ span > < span class ="n "> p</ span > < span class ="o "> +</ span > < span class ="mi "> 1</ span > < span class ="p "> ),</ span > < span class ="k "> reinterpret_cast</ span > < span class ="o "> <</ span > < span class ="kt "> char</ span > < span class ="o "> *></ span > < span class ="p "> (</ span > < span class ="n "> p</ span > < span class ="o "> +</ span > < span class ="mi "> 1</ span > < span class ="p "> )</ span > < span class ="o "> +</ span > < span class ="n "> p</ span > < span class ="o "> -></ span > < span class ="n "> length</ span > < span class ="p "> );</ span >
419+
417420 < span class ="c1 "> // デストラクタ呼び出し</ span >
418421 < span class ="n "> < a href ="../../reference/memory/destroy_at.html "> std::destroy_at</ a > </ span > < span class ="p "> (</ span > < span class ="n "> p</ span > < span class ="p "> );</ span >
419422
420- < span class ="c1 "> // char(トリビアルに破棄可能な)型はデストラクタ呼び出しを省略可能</ span >
421- < span class ="n "> < a href ="../../reference/memory/ranges_destroy.html "> std::ranges::destroy</ a > </ span > < span class ="p "> (</ span > < span class ="n "> p</ span > < span class ="o "> +</ span > < span class ="mi "> 1</ span > < span class ="p "> ,</ span > < span class ="n "> p</ span > < span class ="o "> +</ span > < span class ="mi "> 1</ span > < span class ="o "> +</ span > < span class ="n "> p</ span > < span class ="o "> -></ span > < span class ="n "> length</ span > < span class ="o "> +</ span > < span class ="mi "> 1</ span > < span class ="p "> );</ span >
422-
423423 < span class ="c1 "> // メモリ解放</ span >
424424 < span class ="o "> ::</ span > < span class ="k "> operator</ span > < span class ="k "> delete</ span > < span class ="p "> (</ span > < span class ="n "> p</ span > < span class ="p "> ,</ span > < span class ="n "> full_size</ span > < span class ="p "> );</ span >
425425
0 commit comments