diff --git a/cpp_tricks/index.html b/cpp_tricks/index.html index 6217dda..9d4ddf6 100644 --- a/cpp_tricks/index.html +++ b/cpp_tricks/index.html @@ -613,7 +613,7 @@

地板除与天花板除

等价于

int c = floor((float)a / b);  // c = floor(2.8) = 2
 
-

如果 a 除以 b 除不尽,那么会找到比他大的第一个整数作为结果,这就是地板除 (floor div)

+

如果 a 除以 b 除不尽,那么会找到比他小的第一个整数作为结果,这就是地板除 (floor div)

C 语言默认的就是地板除。

如果我想要的是向上取整,该怎么写?

最原始的写法是先转成浮点数来除,然后ceil函数向上取整:

diff --git a/index.html b/index.html index e616745..1db3dfe 100644 --- a/index.html +++ b/index.html @@ -292,7 +292,7 @@

前言

本书还在持续更新中……要追番的话,可以在 GitHub 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一封电子邮件,提醒你小彭老师更新了。

-

更新时间:2024年11月09日 11:37:54 (UTC+08:00)

+

更新时间:2024年11月09日 11:39:40 (UTC+08:00)

在 GitHub Pages 浏览本书 | 在小彭老师自己维护的镜像上浏览本书

格式约定

diff --git a/print_page/index.html b/print_page/index.html index ca2b960..e666656 100644 --- a/print_page/index.html +++ b/print_page/index.html @@ -421,7 +421,7 @@

前言

本书还在持续更新中……要追番的话,可以在 GitHub 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一封电子邮件,提醒你小彭老师更新了。

-

更新时间:2024年11月09日 11:37:54 (UTC+08:00)

+

更新时间:2024年11月09日 11:39:40 (UTC+08:00)

在 GitHub Pages 浏览本书 | 在小彭老师自己维护的镜像上浏览本书

格式约定

@@ -1241,7 +1241,7 @@

地板除与天花板除

等价于

int c = floor((float)a / b);  // c = floor(2.8) = 2
 
-

如果 a 除以 b 除不尽,那么会找到比他大的第一个整数作为结果,这就是地板除 (floor div)

+

如果 a 除以 b 除不尽,那么会找到比他小的第一个整数作为结果,这就是地板除 (floor div)

C 语言默认的就是地板除。

如果我想要的是向上取整,该怎么写?

最原始的写法是先转成浮点数来除,然后ceil函数向上取整:

diff --git a/search/search_index.json b/search/search_index.json index c656134..90c873f 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"\u5c0f\u5f6d\u8001\u5e08\u73b0\u4ee3 C++ \u5927\u5178 \u5c0f\u5f6d\u5927\u5178\u662f\u4e00\u672c\u5173\u4e8e\u73b0\u4ee3 C++ \u7f16\u7a0b\u7684\u6743\u5a01\u6307\u5357\uff0c\u5b83\u6db5\u76d6\u4e86\u4ece\u57fa\u7840\u77e5\u8bc6\u5230\u9ad8\u7ea7\u6280\u5de7\u7684\u5185\u5bb9\uff0c\u9002\u5408\u521d\u5b66\u8005\u548c\u6709\u7ecf\u9a8c\u7684\u7a0b\u5e8f\u5458\u9605\u8bfb\u3002\u672c\u4e66\u7531\u5c0f\u5f6d\u8001\u5e08\u4eb2\u81ea\u7f16\u5199\uff0c\u901a\u8fc7\u7b80\u5355\u6613\u61c2\u7684\u8bed\u8a00\u548c\u4e30\u5bcc\u7684\u793a\u4f8b\uff0c\u5e2e\u52a9\u8bfb\u8005\u5feb\u901f\u638c\u63e1 C++ \u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8fd0\u7528\u5b83\u4eec\u6765\u89e3\u51b3\u5b9e\u9645\u95ee\u9898\u3002 \u6562\u627f\u8bfa\uff1a\u571f\u6728\u8001\u54e5\u4e5f\u80fd\u770b\u61c2\uff01 \u524d\u8a00 \u63a8\u8350\u7528\u624b\u673a\u6216\u5e73\u677f \u7ad6\u5c4f \u89c2\u770b\uff0c\u53ef\u4ee5\u5728\u5e8a\u6216\u6c99\u53d1\u4e0a\u8eba\u7740\u3002 \u7528\u7535\u8111\u770b\u7684\u8bdd\uff0c\u53ef\u4ee5\u6309 WIN + \u2190 \uff0c\u628a\u672c\u4e66\u7684\u6d4f\u89c8\u5668\u7a97\u53e3\u653e\u5728\u5c4f\u5e55\u5de6\u4fa7\uff0c\u53f3\u4fa7\u662f\u4f60\u7684 IDE\u3002\u4e00\u8fb9\u770b\u4e00\u8fb9\u81ea\u5df1\u52a8\u624b\u505a\u5b9e\u9a8c\u3002 \u8bf7\u5750\u548c\u653e\u5bbd\u3002 \u53ef\u4ee5\u6309\u987a\u5e8f\u9605\u8bfb\uff0c\u4e5f\u53ef\u4ee5\u5728\u672c\u9875\u9762\u4e0a\u65b9\u5bfc\u822a\u680f\u7684\u201c\u7ae0\u8282\u5217\u8868\u201d\u4e2d\uff0c\u9009\u62e9\u611f\u5174\u8da3\u7684\u7ae0\u8282\u9605\u8bfb\u3002 \u672c\u4e66\u5b8c\u5168\u5f00\u6e90\u548c\u514d\u8d39\uff0cGitHub \u4ed3\u5e93\uff1a https://github.com/parallel101/cppguidebook \u5982\u679c\u4f60\u662f\u5728\u4ed8\u8d39\u7fa4\u4e2d\u201c\u4e70\u201d\u5230\u672c\u4e66\uff0c\u6216\u8005\u6253\u7740\u5c0f\u5f6d\u8001\u5e08\u540d\u53f7\u5356\u8bfe\uff0c\u8bf4\u660e\u4f60\u53ef\u80fd\u662f\u79c1\u6709\u5236\u7684\u53d7\u5bb3\u8005\u3002\u56e0\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4ece\u6765\u6ca1\u6709\u4ed8\u8d39\u624d\u80fd\u770b\u7684\u8bfe\u7a0b\uff0c\u6240\u6709\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b\u90fd\u5bf9\u5168\u7403\u4e92\u8054\u7f51\u5f00\u653e\u3002 \u5982\u9700\u79bb\u7ebf\u67e5\u770b\uff0c\u53ef\u4ee5\u524d\u5f80 GitHub Release \u9875\u9762 \u4e0b\u8f7d PDF \u6587\u4ef6\u3002 \u5982\u679c\u4f60\u5728\u9605\u8bfb\u8fc7\u7a0b\u4e2d\u9047\u5230\u4efb\u4f55\u95ee\u9898\uff0c\u53ef\u4ee5\u5728 GitHub Issues \u4e2d\u63d0\u51fa\uff0c\u5c0f\u5f6d\u8001\u5e08\u4f1a\u5c3d\u529b\u89e3\u7b54\u3002 \u4e5f\u53ef\u4ee5\u5728 B \u7ad9 \u53d1\u79c1\u4fe1\u7ed9\u5c0f\u5f6d\u8001\u5e08\u54e6\u3002 \u672c\u4e66\u8fd8\u5728\u6301\u7eed\u66f4\u65b0\u4e2d\u2026\u2026\u8981\u8ffd\u756a\u7684\u8bdd\uff0c\u53ef\u4ee5\u5728 GitHub \u70b9\u4e00\u4e0b\u53f3\u4e0a\u89d2\u7684 \u201cWatch\u201d \u6309\u94ae\uff0c\u6bcf\u5f53\u5c0f\u5f6d\u8001\u5e08\u63d0\u4ea4\u65b0 commit\uff0cGitHub \u4f1a\u5411\u4f60\u53d1\u9001\u4e00\u5c01\u7535\u5b50\u90ae\u4ef6\uff0c\u63d0\u9192\u4f60\u5c0f\u5f6d\u8001\u5e08\u66f4\u65b0\u4e86\u3002 \u66f4\u65b0\u65f6\u95f4\uff1a2024\u5e7411\u670809\u65e5 11:37:54 (UTC+08:00) \u5728 GitHub Pages \u6d4f\u89c8\u672c\u4e66 | \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u5df1\u7ef4\u62a4\u7684\u955c\u50cf\u4e0a\u6d4f\u89c8\u672c\u4e66 \u683c\u5f0f\u7ea6\u5b9a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u6e29\u99a8\u63d0\u793a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u53ef\u80fd\u72af\u9519\u7684\u8b66\u544a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u7b11\u8bdd\u6216\u8da3\u5473\u5bd3\u8a00\u6545\u4e8b \u7528\u8fd9\u79cd\u989c\u8272\u4e66\u5199\u7684\u662f\u8865\u5145\u8bf4\u660e\u7684\u8bfe\u5916\u9605\u8bfb\uff0c\u770b\u4e0d\u61c2\u4e5f\u6ca1\u5173\u7cfb \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u662f\u521d\u5b66\u8005\u53ef\u6682\u65f6\u4e0d\u7528\u7406\u89e3\u7684\u7ec6\u8282 \u672f\u8bed\u540d\u79f0: \u8fd9\u91cc\u662f\u672f\u8bed\u7684\u5b9a\u4e49\u3002 \u89c2\u524d\u987b\u77e5 \u4e0e\u5927\u591a\u6570\u73b0\u6709\u6559\u6750\u4e0d\u540c\u7684\u662f\uff0c\u672c\u8bfe\u7a0b\u5c06\u4f1a\u91c7\u7528\u201c\u5012\u53d9\u201d\u7684\u5f62\u5f0f\uff0c\u4ece\u6700\u65b0\u7684 C++23 \u8bb2\u8d77\uff01\u7136\u540e\u8bb2 C++20\u3001C++17\u3001C++14\u3001C++11\uff0c\u6162\u6162\u8bb2\u5230\u6700\u539f\u59cb\u7684 C++98\u3002 \u4e0d\u7528\u62c5\u5fc3\uff0c\u8d8a\u662f\u73b0\u4ee3\u7684 C++\uff0c\u5b66\u8d77\u6765\u53cd\u800c\u66f4\u5bb9\u6613\uff01\u53cd\u800c\u53e4\u4ee3 C++ \u624d \u53c8\u81ed\u53c8\u957f \u3002 \u5f88\u591a\u540c\u5b66\u60f3\u5f53\u7136\u5730\u8bef\u4ee5\u4e3a C++98 \u6700\u7b80\u5355\uff0c\u54fc\u54e7\u54fc\u54e7\u8d39\u8001\u5927\u52b2\u4ece C++98 \u5f00\u59cb\u5b66\uff0c\u624d\u662f\u9519\u8bef\u7684\u3002 \u4e3a\u4e86\u5e94\u4ed8\u7f3a\u80f3\u818a\u5c11\u817f\u7684 C++98\uff0c\u4eba\u4eec\u53d1\u660e\u4e86\u5404\u79cd \u7e41\u7410\u65e0\u8c13 \u7684\u5199\u6cd5\uff0c\u5728\u73b0\u4ee3 C++ \u4e2d\uff0c\u65e9\u5c31\u5df2\u7ecf\u88ab\u66f4 \u7b80\u6d01\u76f4\u89c2 \u7684\u5199\u6cd5\u66ff\u4ee3\u4e86\u3002 \u4f8b\u5982\u6240\u8c13\u7684 safe-bool idiom\uff0c\u5199\u8d77\u6765\u53c8\u81ed\u53c8\u957f\uff0cC++11 \u5f15\u5165\u4e00\u4e2a explicit \u5173\u952e\u5b57\u76f4\u63a5\u5c31\u79d2\u4e86\u3002\u7ed3\u679c\u8fd8\u6709\u4e00\u6279\u52b3\u4fdd\u6559\u6750\u5927\u5439\u7279\u5439 safe-bool idiom\uff0c\u5439\u5f97\u597d\u50cf\u662f\u4e2a\u4ec0\u4e48\u9ad8\u5927\u4e0a\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e00\u6837\uff0c\u4e0d\u8fc7\u662f\u4e2a\u5e94\u4ed8 C++98 \u8bed\u8a00\u7f3a\u9677\u7684\u8e69\u811a\u73a9\u610f\u3002 \u5c31\u597d\u6bd4\u4e00\u4e2a \u8001\u5916 \u60f3\u8981\u5b66\u4e60\u6c49\u8bed\uff0c\u4ed6\u9996\u5148\u80af\u5b9a\u662f\u4ece \u73b0\u4ee3\u6c49\u8bed \u5b66\u8d77\uff01\u800c\u4e0d\u662f\u4e0a\u6765\u5c31\u6559\u4ed6 \u6587\u8a00\u6587 \u3002 \u5373\u4f7f\u8fd9\u4e2a\u8001\u5916\u7684\u804c\u4e1a\u5c31\u662f\u201c\u8003\u53e4\u201d\uff0c\u6216\u8005\u4ed6\u5bf9\u201c\u53e4\u4ee3\u6587\u5b66\u201d\u611f\u5174\u8da3\uff0c\u4e5f\u4e0d\u53ef\u80fd\u81ea\u5b66\u6587\u8a00\u6587\u7684\u540c\u65f6\u5b8c\u5168\u8df3\u8fc7\u73b0\u4ee3\u6c49\u8bed\u3002 \u5f53\u6211\u4eec\u5b66\u4e60\u4e2d\u6587\u65f6\uff0c\u4f60\u80af\u5b9a\u5e0c\u671b\u5148\u5b66\u73b0\u4ee3\u6c49\u8bed\uff0c\u518d\u5b66\u6587\u8a00\u6587\uff0c\u518d\u5b66\u7532\u9aa8\u6587\uff0c\u518d\u5b66 brainf* * k\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u5bf9\u4e8e C++ \u521d\u5b66\u8005\u4e5f\u662f\u5982\u6b64\uff1a\u6211\u4eec\u9996\u5148\u5b66\u4f1a\u7b80\u5355\u660e\u4e86\u7684\uff0c\u7b26\u5408\u73b0\u4ee3\u4eba\u601d\u7ef4\u7684 C++23\uff0c\u518d\u9010\u6e10\u56de\u5230\u4e13\u4e3a\u4f3a\u5019\u201c\u53e4\u4ee3\u5f00\u53d1\u73af\u5883\u201d\u7684 C++98\u3002 \u4f60\u7684\u751f\u4ea7\u73af\u5883\u53ef\u80fd\u4e0d\u5141\u8bb8\u7528\u4e0a C++20 \u751a\u81f3 C++23 \u7684\u65b0\u6807\u51c6\u3002 \u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u6559\u4f1a\u4f60 C++23 \u7684\u6b63\u5e38\u5199\u6cd5\u540e\uff0c\u4f1a\u8bb2\u89e3\u5982\u4f55\u5728 C++14\u3001C++98 \u4e2d\u5199\u51fa\u540c\u6837\u7684\u6548\u679c\u3002 \u8fd9\u6837\u4f60\u5b66\u4e60\u7684\u65f6\u5019\u601d\u8def\u6e05\u6670\uff0c\u4e0d\u7528\u88ab\u7e41\u7410\u7684 C++98 \u201c\u5947\u6280\u6deb\u5de7\u201d\u5e72\u6270\uff0c\u5b66\u8d77\u6765\u4e8b\u534a\u529f\u500d\uff1b\u4f46\u4e5f\u201c\u5403\u8fc7\u89c1\u8fc7\u201d\uff0c\u77e5\u9053\u53e4\u4ee3 C++98 \u7684\u5e94\u5bf9\u7b56\u7565\u3002 \u76ee\u524d\u4f01\u4e1a\u91cc\u4e3b\u6d41\u4f7f\u7528\u7684\u662f C++14 \u548c C++17\u3002\u4f8b\u5982\u8c37\u6b4c\u5c31\u660e\u786e\u89c4\u5b9a\u8981\u6c42 C++17\u3002 \u4e3e\u4e2a\u4f8b\u5b50 \u63a5\u4e0b\u6765\u7684\u4f8b\u5b50\u4f60\u53ef\u80fd\u770b\u4e0d\u61c2\uff0c\u4f46\u53ea\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e2a\u4f8b\u5b50\u662f\u5411\u4f60\u8bf4\u660e\uff1a\u8d8a\u662f\u65b0\u7684 C++ \u6807\u51c6\uff0c\u53cd\u800c\u8d8a\u5bb9\u6613\u5b66\uff01 \u4f8b\u5982\uff0c\u5728\u6a21\u677f\u5143\u7f16\u7a0b\u4e2d\uff0c\u8981\u68c0\u6d4b\u4e00\u4e2a\u7c7b\u578b T \u662f\u5426\u62e5\u6709 foo() \u8fd9\u4e00\u6210\u5458\u51fd\u6570\u3002\u5982\u679c\u5b58\u5728\uff0c\u624d\u4f1a\u8c03\u7528\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528\u5f88\u65b9\u4fbf\u7684 requires \u8bed\u6cd5\uff0c\u8f7b\u677e\u68c0\u6d4b\u4e00\u4e2a\u8868\u8fbe\u5f0f\u662f\u5426\u80fd\u5408\u6cd5\u901a\u8fc7\u7f16\u8bd1\u3002\u5982\u679c\u80fd\uff0c requires \u8bed\u53e5\u4f1a\u8fd4\u56de true \u3002\u7136\u540e\u7528\u4e00\u4e2a if constexpr \u8fdb\u884c\u7f16\u8bd1\u671f\u5206\u652f\u5224\u65ad\uff0c\u5373\u53ef\u5b9e\u73b0\u68c0\u6d4b\u5230\u5b58\u5728\u5219\u8c03\u7528\u3002 template void try_call_foo(T &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } \u4f46\u4ec5\u4ec5\u662f\u56de\u5230 C++17\uff0c\u6ca1\u6709 requires \u8bed\u6cd5\uff0c\u6211\u4eec\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a trait \u7c7b\uff0c\u5e76\u8fd0\u7528\u70e6\u4eba\u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u68c0\u6d4b\u8868\u8fbe\u5f0f\u662f\u5426\u7684\u5408\u6cd5\uff0c\u53c8\u81ed\u53c8\u957f\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template void try_call_foo(T &t) { if constexpr (has_foo::value) { t.foo(); } } \u5982\u679c\u56de\u5230 C++14\uff0c\u60c5\u51b5\u5c31\u66f4\u7cdf\u7cd5\u4e86\uff01 if constexpr \u662f C++17 \u7684\u7279\u6027\uff0c\u6ca1\u6709\u4ed6\uff0c\u8981\u5b9e\u73b0\u7f16\u8bd1\u671f\u5206\u652f\uff0c\u6211\u4eec\u5c31\u5f97\u7528 enable_if_t \u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u9700\u8981\u5b9a\u4e49\u4e24\u4e2a try_call_foo \u51fd\u6570\uff0c\u4e92\u76f8\u91cd\u8f7d\uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template ::value, int> = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int> = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++11\uff0c\u60c5\u51b5\u8fdb\u4e00\u6b65\u6076\u5316\uff01 enable_if_t \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5c0f\u52a9\u624b\u5df2\u7ecf\u4e0d\u5b58\u5728\uff0c\u9700\u8981\u4f7f\u7528\u6bd4\u4ed6\u66f4\u5e95\u5c42\u7684 enable_if \u6a21\u677f\u7c7b\uff0c\u624b\u52a8\u53d6\u51fa ::type \uff0c\u5e76\u4e14\u9700\u8981 typename \u4fee\u9970\uff0c\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff01\u5e76\u4e14 void_t \u4e5f\u4e0d\u80fd\u7528\u4e86\uff0c\u8981\u7528\u9017\u53f7\u8868\u8fbe\u5f0f\u5c0f\u6280\u5de7\u624d\u80fd\u8ba9 decltype \u56fa\u5b9a\u8fd4\u56de void\u2026\u2026 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo(), (void)0)> { static constexpr bool value = true; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++98\uff0c\u90a3\u53c8\u8981\u7f6a\u52a0\u4e00\u7b49\uff01 enable_if \u548c declval \u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u7684\u5e2e\u624b\u7c7b\u548c\u5e2e\u624b\u51fd\u6570\uff0c\u5728 C++98 \u4e2d\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5b9e\u73b0 enable_if \u2026\u2026 declval \u4e5f\u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u4e2d\u7684\u5e2e\u624b\u51fd\u6570\u2026\u2026\u5047\u8bbe\u4f60\u81ea\u5df1\u597d\u4e0d\u5bb9\u6613\u5b9e\u73b0\u51fa\u6765\u4e86 enable_if \u548c declval \uff0c\u8fd8\u6ca1\u5b8c\uff1a\u56e0\u4e3a constexpr \u5728 C++98 \u4e2d\u4e5f\u4e0d\u5b58\u5728\u4e86\uff01\u4f60\u65e0\u6cd5\u5b9a\u4e49 value \u6210\u5458\u53d8\u91cf\u4e3a\u7f16\u8bd1\u671f\u5e38\u91cf\uff0c\u6211\u4eec\u53ea\u597d\u53c8\u7528\u4e00\u4e2a\u62bd\u8c61\u7684\u679a\u4e3e\u5c0f\u6280\u5de7\u6765\u5b9e\u73b0\u5b9a\u4e49\u7c7b\u6210\u5458\u5e38\u91cf\u7684\u6548\u679c\u3002 template struct has_foo { enum { value = 0 }; }; template struct has_foo().foo(), (void)0)> { enum { value = 1 }; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u6b64\u5197\u957f\u96be\u61c2\u7684\u62bd\u8c61 C++98 \u4ee3\u7801\uff0c\u4eff\u4f5b\u662f\u201c\u52a0\u5bc6\u201d\u8fc7\u7684\u4ee3\u7801\u4e00\u6837\uff0c\u4ec5\u4ec5\u662f\u4e3a\u4e86\u5b9e\u73b0\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6210\u5458\u51fd\u6570 foo\u2026\u2026 \u5982\u679c\u56de\u5230 C \u8bed\u8a00\uff0c\u90a3\u4e48\u4f60\u751a\u81f3\u90fd\u4e0d\u7528\u68c0\u6d4b\u4e86\u3002\u56e0\u4e3a\u4f1f\u5927\u7684 C \u8bed\u8a00\u8fde\u6210\u5458\u51fd\u6570\u90fd\u6ca1\u6709\uff0c\u4f55\u8c08\u201c\u68c0\u6d4b\u6210\u5458\u51fd\u6570\u662f\u5426\u5b58\u5728\u201d\uff1f \u53cd\u89c2 C++20 \u7684\u5199\u6cd5\uff0c\u4e00\u773c\u5c31\u770b\u660e\u767d\u4ee3\u7801\u7684\u903b\u8f91\u662f\u4ec0\u4e48\uff0c\u8868\u8fbe\u4f60\u8be5\u8868\u8fbe\u7684\uff0c\u800c\u4e0d\u662f\u8ff7\u5931\u4e8e\u4f3a\u5019\u5404\u79cd\u8bed\u8a00\u7f3a\u9677\uff0c\u5e72\u6270\u6211\u4eec\u5b66\u4e60\u3002 void try_call_foo(auto &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } // \u4ece\u6b8b\u5e9f\u7684 C++98 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u5c31\u88ab\u8fd9\u4e9b\u65e0\u8c13\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u626d\u66f2\u4e86\uff0c\u800c\u4f7f\u5f97\u771f\u6b63\u5e94\u8be5\u8868\u8fbe\u7684\u4ee3\u7801\u903b\u8f91\uff0c\u6df9\u6ca1\u5728\u53c8\u81ed\u53c8\u957f\u7684\u53e4\u4ee3\u6280\u5de7\u4e2d\u3002 // \u4ece\u73b0\u4ee3\u7684 C++23 \u5b66\u8d77\uff0c\u5148\u77e5\u9053\u6b63\u5e38\u7684\u5199\u6cd5\u201c\u7406\u5e94\u201d\u662f\u4ec0\u4e48\u6837\u3002\u5de5\u4f5c\u4e2d\u7528\u4e0d\u4e0a C++23\uff1f\u6211\u4f1a\u5411\u4f60\u4ecb\u7ecd\uff0c\u5982\u679c\u8981\u5012\u9000\u56de C++14\uff0c\u53e4\u4ee3\u4eba\u90fd\u662f\u7528\u4ec0\u4e48\u201c\u5947\u6280\u6deb\u5de7\u201d\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 // \u8fd9\u6837\u4f60\u6700\u540e\u540c\u6837\u53ef\u4ee5\u9002\u5e94\u516c\u53f8\u8981\u6c42\u7684 C++14 \u73af\u5883\u3002\u4f46\u662f\u4ece C++23 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u53c8\u4e0d\u4f1a\u88ab\u5e94\u4ed8\u53e4\u4ee3\u8bed\u8a00\u7f3a\u9677\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u6270\u4e71\uff0c\u5b66\u8d77\u6765\u5c31\u4e8b\u534a\u529f\u500d\u3002 \u65e2\u7136\u73b0\u4ee3 C++ \u8fd9\u4e48\u597d\uff0c\u4e3a\u4ec0\u4e48\u5b66\u6821\u4e0d\u4ece\u73b0\u4ee3 C++ \u6559\u8d77\uff0c\u6559\u8d77\u6765\u8fd8\u8f7b\u677e\uff1f\u56e0\u4e3a\u52b3\u4fdd\u8001\u5e08\u4fdd\uff0c\u61d2\u5f97\u63a5\u89e6\u65b0\u77e5\u8bc6\uff0c\u8ba4\u4e3a\u201c\u7956\u5b97\u4e4b\u6cd5\u4e0d\u53ef\u53d8\u201d\uff0c\u201c\u7248\u53f7\u7a33\u5b9a\u538b\u5012\u4e00\u5207\u201d\u3002","title":"\u524d\u8a00"},{"location":"#c","text":"\u5c0f\u5f6d\u5927\u5178\u662f\u4e00\u672c\u5173\u4e8e\u73b0\u4ee3 C++ \u7f16\u7a0b\u7684\u6743\u5a01\u6307\u5357\uff0c\u5b83\u6db5\u76d6\u4e86\u4ece\u57fa\u7840\u77e5\u8bc6\u5230\u9ad8\u7ea7\u6280\u5de7\u7684\u5185\u5bb9\uff0c\u9002\u5408\u521d\u5b66\u8005\u548c\u6709\u7ecf\u9a8c\u7684\u7a0b\u5e8f\u5458\u9605\u8bfb\u3002\u672c\u4e66\u7531\u5c0f\u5f6d\u8001\u5e08\u4eb2\u81ea\u7f16\u5199\uff0c\u901a\u8fc7\u7b80\u5355\u6613\u61c2\u7684\u8bed\u8a00\u548c\u4e30\u5bcc\u7684\u793a\u4f8b\uff0c\u5e2e\u52a9\u8bfb\u8005\u5feb\u901f\u638c\u63e1 C++ \u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8fd0\u7528\u5b83\u4eec\u6765\u89e3\u51b3\u5b9e\u9645\u95ee\u9898\u3002 \u6562\u627f\u8bfa\uff1a\u571f\u6728\u8001\u54e5\u4e5f\u80fd\u770b\u61c2\uff01","title":"\u5c0f\u5f6d\u8001\u5e08\u73b0\u4ee3 C++ \u5927\u5178"},{"location":"#_1","text":"\u63a8\u8350\u7528\u624b\u673a\u6216\u5e73\u677f \u7ad6\u5c4f \u89c2\u770b\uff0c\u53ef\u4ee5\u5728\u5e8a\u6216\u6c99\u53d1\u4e0a\u8eba\u7740\u3002 \u7528\u7535\u8111\u770b\u7684\u8bdd\uff0c\u53ef\u4ee5\u6309 WIN + \u2190 \uff0c\u628a\u672c\u4e66\u7684\u6d4f\u89c8\u5668\u7a97\u53e3\u653e\u5728\u5c4f\u5e55\u5de6\u4fa7\uff0c\u53f3\u4fa7\u662f\u4f60\u7684 IDE\u3002\u4e00\u8fb9\u770b\u4e00\u8fb9\u81ea\u5df1\u52a8\u624b\u505a\u5b9e\u9a8c\u3002 \u8bf7\u5750\u548c\u653e\u5bbd\u3002 \u53ef\u4ee5\u6309\u987a\u5e8f\u9605\u8bfb\uff0c\u4e5f\u53ef\u4ee5\u5728\u672c\u9875\u9762\u4e0a\u65b9\u5bfc\u822a\u680f\u7684\u201c\u7ae0\u8282\u5217\u8868\u201d\u4e2d\uff0c\u9009\u62e9\u611f\u5174\u8da3\u7684\u7ae0\u8282\u9605\u8bfb\u3002 \u672c\u4e66\u5b8c\u5168\u5f00\u6e90\u548c\u514d\u8d39\uff0cGitHub \u4ed3\u5e93\uff1a https://github.com/parallel101/cppguidebook \u5982\u679c\u4f60\u662f\u5728\u4ed8\u8d39\u7fa4\u4e2d\u201c\u4e70\u201d\u5230\u672c\u4e66\uff0c\u6216\u8005\u6253\u7740\u5c0f\u5f6d\u8001\u5e08\u540d\u53f7\u5356\u8bfe\uff0c\u8bf4\u660e\u4f60\u53ef\u80fd\u662f\u79c1\u6709\u5236\u7684\u53d7\u5bb3\u8005\u3002\u56e0\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4ece\u6765\u6ca1\u6709\u4ed8\u8d39\u624d\u80fd\u770b\u7684\u8bfe\u7a0b\uff0c\u6240\u6709\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b\u90fd\u5bf9\u5168\u7403\u4e92\u8054\u7f51\u5f00\u653e\u3002 \u5982\u9700\u79bb\u7ebf\u67e5\u770b\uff0c\u53ef\u4ee5\u524d\u5f80 GitHub Release \u9875\u9762 \u4e0b\u8f7d PDF \u6587\u4ef6\u3002 \u5982\u679c\u4f60\u5728\u9605\u8bfb\u8fc7\u7a0b\u4e2d\u9047\u5230\u4efb\u4f55\u95ee\u9898\uff0c\u53ef\u4ee5\u5728 GitHub Issues \u4e2d\u63d0\u51fa\uff0c\u5c0f\u5f6d\u8001\u5e08\u4f1a\u5c3d\u529b\u89e3\u7b54\u3002 \u4e5f\u53ef\u4ee5\u5728 B \u7ad9 \u53d1\u79c1\u4fe1\u7ed9\u5c0f\u5f6d\u8001\u5e08\u54e6\u3002 \u672c\u4e66\u8fd8\u5728\u6301\u7eed\u66f4\u65b0\u4e2d\u2026\u2026\u8981\u8ffd\u756a\u7684\u8bdd\uff0c\u53ef\u4ee5\u5728 GitHub \u70b9\u4e00\u4e0b\u53f3\u4e0a\u89d2\u7684 \u201cWatch\u201d \u6309\u94ae\uff0c\u6bcf\u5f53\u5c0f\u5f6d\u8001\u5e08\u63d0\u4ea4\u65b0 commit\uff0cGitHub \u4f1a\u5411\u4f60\u53d1\u9001\u4e00\u5c01\u7535\u5b50\u90ae\u4ef6\uff0c\u63d0\u9192\u4f60\u5c0f\u5f6d\u8001\u5e08\u66f4\u65b0\u4e86\u3002 \u66f4\u65b0\u65f6\u95f4\uff1a2024\u5e7411\u670809\u65e5 11:37:54 (UTC+08:00) \u5728 GitHub Pages \u6d4f\u89c8\u672c\u4e66 | \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u5df1\u7ef4\u62a4\u7684\u955c\u50cf\u4e0a\u6d4f\u89c8\u672c\u4e66","title":"\u524d\u8a00"},{"location":"#_2","text":"\u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u6e29\u99a8\u63d0\u793a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u53ef\u80fd\u72af\u9519\u7684\u8b66\u544a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u7b11\u8bdd\u6216\u8da3\u5473\u5bd3\u8a00\u6545\u4e8b \u7528\u8fd9\u79cd\u989c\u8272\u4e66\u5199\u7684\u662f\u8865\u5145\u8bf4\u660e\u7684\u8bfe\u5916\u9605\u8bfb\uff0c\u770b\u4e0d\u61c2\u4e5f\u6ca1\u5173\u7cfb \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u662f\u521d\u5b66\u8005\u53ef\u6682\u65f6\u4e0d\u7528\u7406\u89e3\u7684\u7ec6\u8282 \u672f\u8bed\u540d\u79f0: \u8fd9\u91cc\u662f\u672f\u8bed\u7684\u5b9a\u4e49\u3002","title":"\u683c\u5f0f\u7ea6\u5b9a"},{"location":"#_3","text":"\u4e0e\u5927\u591a\u6570\u73b0\u6709\u6559\u6750\u4e0d\u540c\u7684\u662f\uff0c\u672c\u8bfe\u7a0b\u5c06\u4f1a\u91c7\u7528\u201c\u5012\u53d9\u201d\u7684\u5f62\u5f0f\uff0c\u4ece\u6700\u65b0\u7684 C++23 \u8bb2\u8d77\uff01\u7136\u540e\u8bb2 C++20\u3001C++17\u3001C++14\u3001C++11\uff0c\u6162\u6162\u8bb2\u5230\u6700\u539f\u59cb\u7684 C++98\u3002 \u4e0d\u7528\u62c5\u5fc3\uff0c\u8d8a\u662f\u73b0\u4ee3\u7684 C++\uff0c\u5b66\u8d77\u6765\u53cd\u800c\u66f4\u5bb9\u6613\uff01\u53cd\u800c\u53e4\u4ee3 C++ \u624d \u53c8\u81ed\u53c8\u957f \u3002 \u5f88\u591a\u540c\u5b66\u60f3\u5f53\u7136\u5730\u8bef\u4ee5\u4e3a C++98 \u6700\u7b80\u5355\uff0c\u54fc\u54e7\u54fc\u54e7\u8d39\u8001\u5927\u52b2\u4ece C++98 \u5f00\u59cb\u5b66\uff0c\u624d\u662f\u9519\u8bef\u7684\u3002 \u4e3a\u4e86\u5e94\u4ed8\u7f3a\u80f3\u818a\u5c11\u817f\u7684 C++98\uff0c\u4eba\u4eec\u53d1\u660e\u4e86\u5404\u79cd \u7e41\u7410\u65e0\u8c13 \u7684\u5199\u6cd5\uff0c\u5728\u73b0\u4ee3 C++ \u4e2d\uff0c\u65e9\u5c31\u5df2\u7ecf\u88ab\u66f4 \u7b80\u6d01\u76f4\u89c2 \u7684\u5199\u6cd5\u66ff\u4ee3\u4e86\u3002 \u4f8b\u5982\u6240\u8c13\u7684 safe-bool idiom\uff0c\u5199\u8d77\u6765\u53c8\u81ed\u53c8\u957f\uff0cC++11 \u5f15\u5165\u4e00\u4e2a explicit \u5173\u952e\u5b57\u76f4\u63a5\u5c31\u79d2\u4e86\u3002\u7ed3\u679c\u8fd8\u6709\u4e00\u6279\u52b3\u4fdd\u6559\u6750\u5927\u5439\u7279\u5439 safe-bool idiom\uff0c\u5439\u5f97\u597d\u50cf\u662f\u4e2a\u4ec0\u4e48\u9ad8\u5927\u4e0a\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e00\u6837\uff0c\u4e0d\u8fc7\u662f\u4e2a\u5e94\u4ed8 C++98 \u8bed\u8a00\u7f3a\u9677\u7684\u8e69\u811a\u73a9\u610f\u3002 \u5c31\u597d\u6bd4\u4e00\u4e2a \u8001\u5916 \u60f3\u8981\u5b66\u4e60\u6c49\u8bed\uff0c\u4ed6\u9996\u5148\u80af\u5b9a\u662f\u4ece \u73b0\u4ee3\u6c49\u8bed \u5b66\u8d77\uff01\u800c\u4e0d\u662f\u4e0a\u6765\u5c31\u6559\u4ed6 \u6587\u8a00\u6587 \u3002 \u5373\u4f7f\u8fd9\u4e2a\u8001\u5916\u7684\u804c\u4e1a\u5c31\u662f\u201c\u8003\u53e4\u201d\uff0c\u6216\u8005\u4ed6\u5bf9\u201c\u53e4\u4ee3\u6587\u5b66\u201d\u611f\u5174\u8da3\uff0c\u4e5f\u4e0d\u53ef\u80fd\u81ea\u5b66\u6587\u8a00\u6587\u7684\u540c\u65f6\u5b8c\u5168\u8df3\u8fc7\u73b0\u4ee3\u6c49\u8bed\u3002 \u5f53\u6211\u4eec\u5b66\u4e60\u4e2d\u6587\u65f6\uff0c\u4f60\u80af\u5b9a\u5e0c\u671b\u5148\u5b66\u73b0\u4ee3\u6c49\u8bed\uff0c\u518d\u5b66\u6587\u8a00\u6587\uff0c\u518d\u5b66\u7532\u9aa8\u6587\uff0c\u518d\u5b66 brainf* * k\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u5bf9\u4e8e C++ \u521d\u5b66\u8005\u4e5f\u662f\u5982\u6b64\uff1a\u6211\u4eec\u9996\u5148\u5b66\u4f1a\u7b80\u5355\u660e\u4e86\u7684\uff0c\u7b26\u5408\u73b0\u4ee3\u4eba\u601d\u7ef4\u7684 C++23\uff0c\u518d\u9010\u6e10\u56de\u5230\u4e13\u4e3a\u4f3a\u5019\u201c\u53e4\u4ee3\u5f00\u53d1\u73af\u5883\u201d\u7684 C++98\u3002 \u4f60\u7684\u751f\u4ea7\u73af\u5883\u53ef\u80fd\u4e0d\u5141\u8bb8\u7528\u4e0a C++20 \u751a\u81f3 C++23 \u7684\u65b0\u6807\u51c6\u3002 \u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u6559\u4f1a\u4f60 C++23 \u7684\u6b63\u5e38\u5199\u6cd5\u540e\uff0c\u4f1a\u8bb2\u89e3\u5982\u4f55\u5728 C++14\u3001C++98 \u4e2d\u5199\u51fa\u540c\u6837\u7684\u6548\u679c\u3002 \u8fd9\u6837\u4f60\u5b66\u4e60\u7684\u65f6\u5019\u601d\u8def\u6e05\u6670\uff0c\u4e0d\u7528\u88ab\u7e41\u7410\u7684 C++98 \u201c\u5947\u6280\u6deb\u5de7\u201d\u5e72\u6270\uff0c\u5b66\u8d77\u6765\u4e8b\u534a\u529f\u500d\uff1b\u4f46\u4e5f\u201c\u5403\u8fc7\u89c1\u8fc7\u201d\uff0c\u77e5\u9053\u53e4\u4ee3 C++98 \u7684\u5e94\u5bf9\u7b56\u7565\u3002 \u76ee\u524d\u4f01\u4e1a\u91cc\u4e3b\u6d41\u4f7f\u7528\u7684\u662f C++14 \u548c C++17\u3002\u4f8b\u5982\u8c37\u6b4c\u5c31\u660e\u786e\u89c4\u5b9a\u8981\u6c42 C++17\u3002","title":"\u89c2\u524d\u987b\u77e5"},{"location":"#_4","text":"\u63a5\u4e0b\u6765\u7684\u4f8b\u5b50\u4f60\u53ef\u80fd\u770b\u4e0d\u61c2\uff0c\u4f46\u53ea\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e2a\u4f8b\u5b50\u662f\u5411\u4f60\u8bf4\u660e\uff1a\u8d8a\u662f\u65b0\u7684 C++ \u6807\u51c6\uff0c\u53cd\u800c\u8d8a\u5bb9\u6613\u5b66\uff01 \u4f8b\u5982\uff0c\u5728\u6a21\u677f\u5143\u7f16\u7a0b\u4e2d\uff0c\u8981\u68c0\u6d4b\u4e00\u4e2a\u7c7b\u578b T \u662f\u5426\u62e5\u6709 foo() \u8fd9\u4e00\u6210\u5458\u51fd\u6570\u3002\u5982\u679c\u5b58\u5728\uff0c\u624d\u4f1a\u8c03\u7528\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528\u5f88\u65b9\u4fbf\u7684 requires \u8bed\u6cd5\uff0c\u8f7b\u677e\u68c0\u6d4b\u4e00\u4e2a\u8868\u8fbe\u5f0f\u662f\u5426\u80fd\u5408\u6cd5\u901a\u8fc7\u7f16\u8bd1\u3002\u5982\u679c\u80fd\uff0c requires \u8bed\u53e5\u4f1a\u8fd4\u56de true \u3002\u7136\u540e\u7528\u4e00\u4e2a if constexpr \u8fdb\u884c\u7f16\u8bd1\u671f\u5206\u652f\u5224\u65ad\uff0c\u5373\u53ef\u5b9e\u73b0\u68c0\u6d4b\u5230\u5b58\u5728\u5219\u8c03\u7528\u3002 template void try_call_foo(T &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } \u4f46\u4ec5\u4ec5\u662f\u56de\u5230 C++17\uff0c\u6ca1\u6709 requires \u8bed\u6cd5\uff0c\u6211\u4eec\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a trait \u7c7b\uff0c\u5e76\u8fd0\u7528\u70e6\u4eba\u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u68c0\u6d4b\u8868\u8fbe\u5f0f\u662f\u5426\u7684\u5408\u6cd5\uff0c\u53c8\u81ed\u53c8\u957f\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template void try_call_foo(T &t) { if constexpr (has_foo::value) { t.foo(); } } \u5982\u679c\u56de\u5230 C++14\uff0c\u60c5\u51b5\u5c31\u66f4\u7cdf\u7cd5\u4e86\uff01 if constexpr \u662f C++17 \u7684\u7279\u6027\uff0c\u6ca1\u6709\u4ed6\uff0c\u8981\u5b9e\u73b0\u7f16\u8bd1\u671f\u5206\u652f\uff0c\u6211\u4eec\u5c31\u5f97\u7528 enable_if_t \u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u9700\u8981\u5b9a\u4e49\u4e24\u4e2a try_call_foo \u51fd\u6570\uff0c\u4e92\u76f8\u91cd\u8f7d\uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template ::value, int> = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int> = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++11\uff0c\u60c5\u51b5\u8fdb\u4e00\u6b65\u6076\u5316\uff01 enable_if_t \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5c0f\u52a9\u624b\u5df2\u7ecf\u4e0d\u5b58\u5728\uff0c\u9700\u8981\u4f7f\u7528\u6bd4\u4ed6\u66f4\u5e95\u5c42\u7684 enable_if \u6a21\u677f\u7c7b\uff0c\u624b\u52a8\u53d6\u51fa ::type \uff0c\u5e76\u4e14\u9700\u8981 typename \u4fee\u9970\uff0c\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff01\u5e76\u4e14 void_t \u4e5f\u4e0d\u80fd\u7528\u4e86\uff0c\u8981\u7528\u9017\u53f7\u8868\u8fbe\u5f0f\u5c0f\u6280\u5de7\u624d\u80fd\u8ba9 decltype \u56fa\u5b9a\u8fd4\u56de void\u2026\u2026 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo(), (void)0)> { static constexpr bool value = true; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++98\uff0c\u90a3\u53c8\u8981\u7f6a\u52a0\u4e00\u7b49\uff01 enable_if \u548c declval \u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u7684\u5e2e\u624b\u7c7b\u548c\u5e2e\u624b\u51fd\u6570\uff0c\u5728 C++98 \u4e2d\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5b9e\u73b0 enable_if \u2026\u2026 declval \u4e5f\u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u4e2d\u7684\u5e2e\u624b\u51fd\u6570\u2026\u2026\u5047\u8bbe\u4f60\u81ea\u5df1\u597d\u4e0d\u5bb9\u6613\u5b9e\u73b0\u51fa\u6765\u4e86 enable_if \u548c declval \uff0c\u8fd8\u6ca1\u5b8c\uff1a\u56e0\u4e3a constexpr \u5728 C++98 \u4e2d\u4e5f\u4e0d\u5b58\u5728\u4e86\uff01\u4f60\u65e0\u6cd5\u5b9a\u4e49 value \u6210\u5458\u53d8\u91cf\u4e3a\u7f16\u8bd1\u671f\u5e38\u91cf\uff0c\u6211\u4eec\u53ea\u597d\u53c8\u7528\u4e00\u4e2a\u62bd\u8c61\u7684\u679a\u4e3e\u5c0f\u6280\u5de7\u6765\u5b9e\u73b0\u5b9a\u4e49\u7c7b\u6210\u5458\u5e38\u91cf\u7684\u6548\u679c\u3002 template struct has_foo { enum { value = 0 }; }; template struct has_foo().foo(), (void)0)> { enum { value = 1 }; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u6b64\u5197\u957f\u96be\u61c2\u7684\u62bd\u8c61 C++98 \u4ee3\u7801\uff0c\u4eff\u4f5b\u662f\u201c\u52a0\u5bc6\u201d\u8fc7\u7684\u4ee3\u7801\u4e00\u6837\uff0c\u4ec5\u4ec5\u662f\u4e3a\u4e86\u5b9e\u73b0\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6210\u5458\u51fd\u6570 foo\u2026\u2026 \u5982\u679c\u56de\u5230 C \u8bed\u8a00\uff0c\u90a3\u4e48\u4f60\u751a\u81f3\u90fd\u4e0d\u7528\u68c0\u6d4b\u4e86\u3002\u56e0\u4e3a\u4f1f\u5927\u7684 C \u8bed\u8a00\u8fde\u6210\u5458\u51fd\u6570\u90fd\u6ca1\u6709\uff0c\u4f55\u8c08\u201c\u68c0\u6d4b\u6210\u5458\u51fd\u6570\u662f\u5426\u5b58\u5728\u201d\uff1f \u53cd\u89c2 C++20 \u7684\u5199\u6cd5\uff0c\u4e00\u773c\u5c31\u770b\u660e\u767d\u4ee3\u7801\u7684\u903b\u8f91\u662f\u4ec0\u4e48\uff0c\u8868\u8fbe\u4f60\u8be5\u8868\u8fbe\u7684\uff0c\u800c\u4e0d\u662f\u8ff7\u5931\u4e8e\u4f3a\u5019\u5404\u79cd\u8bed\u8a00\u7f3a\u9677\uff0c\u5e72\u6270\u6211\u4eec\u5b66\u4e60\u3002 void try_call_foo(auto &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } // \u4ece\u6b8b\u5e9f\u7684 C++98 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u5c31\u88ab\u8fd9\u4e9b\u65e0\u8c13\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u626d\u66f2\u4e86\uff0c\u800c\u4f7f\u5f97\u771f\u6b63\u5e94\u8be5\u8868\u8fbe\u7684\u4ee3\u7801\u903b\u8f91\uff0c\u6df9\u6ca1\u5728\u53c8\u81ed\u53c8\u957f\u7684\u53e4\u4ee3\u6280\u5de7\u4e2d\u3002 // \u4ece\u73b0\u4ee3\u7684 C++23 \u5b66\u8d77\uff0c\u5148\u77e5\u9053\u6b63\u5e38\u7684\u5199\u6cd5\u201c\u7406\u5e94\u201d\u662f\u4ec0\u4e48\u6837\u3002\u5de5\u4f5c\u4e2d\u7528\u4e0d\u4e0a C++23\uff1f\u6211\u4f1a\u5411\u4f60\u4ecb\u7ecd\uff0c\u5982\u679c\u8981\u5012\u9000\u56de C++14\uff0c\u53e4\u4ee3\u4eba\u90fd\u662f\u7528\u4ec0\u4e48\u201c\u5947\u6280\u6deb\u5de7\u201d\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 // \u8fd9\u6837\u4f60\u6700\u540e\u540c\u6837\u53ef\u4ee5\u9002\u5e94\u516c\u53f8\u8981\u6c42\u7684 C++14 \u73af\u5883\u3002\u4f46\u662f\u4ece C++23 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u53c8\u4e0d\u4f1a\u88ab\u5e94\u4ed8\u53e4\u4ee3\u8bed\u8a00\u7f3a\u9677\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u6270\u4e71\uff0c\u5b66\u8d77\u6765\u5c31\u4e8b\u534a\u529f\u500d\u3002 \u65e2\u7136\u73b0\u4ee3 C++ \u8fd9\u4e48\u597d\uff0c\u4e3a\u4ec0\u4e48\u5b66\u6821\u4e0d\u4ece\u73b0\u4ee3 C++ \u6559\u8d77\uff0c\u6559\u8d77\u6765\u8fd8\u8f7b\u677e\uff1f\u56e0\u4e3a\u52b3\u4fdd\u8001\u5e08\u4fdd\uff0c\u61d2\u5f97\u63a5\u89e6\u65b0\u77e5\u8bc6\uff0c\u8ba4\u4e3a\u201c\u7956\u5b97\u4e4b\u6cd5\u4e0d\u53ef\u53d8\u201d\uff0c\u201c\u7248\u53f7\u7a33\u5b9a\u538b\u5012\u4e00\u5207\u201d\u3002","title":"\u4e3e\u4e2a\u4f8b\u5b50"},{"location":"about/","text":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08 \u5c0f\u5f6d\u8001\u5e08\u662f\u4e00\u4f4d\u64c5\u957f\u9ad8\u6027\u80fd C++ \u7684\u7a0b\u5e8f\u5458\uff0c\u76ee\u524d\u4e3b\u8981\u4ece\u4e8b\u56fe\u5f62\u5b66\u9886\u57df\u7684\u5f15\u64ce\u5f00\u53d1\uff0c\u62e5\u6709\u591a\u5e74\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u4e30\u5bcc\u7684\u77e5\u8bc6\u50a8\u5907\uff0c\u7cbe\u901a\u7ebf\u6027\u4ee3\u6570\u3001\u5fae\u79ef\u5206\u3001\u6982\u7387\u8bba\u3001\u5fae\u5206\u51e0\u4f55\u3001\u56fe\u5f62\u5b66\u3001\u6e38\u620f\u5f15\u64ce\u3001\u4e92\u8054\u7f51\u3001\u7f16\u8bd1\u539f\u7406\u3001\u8bbe\u8ba1\u6a21\u5f0f\u3001\u79bb\u7ebf\u6e32\u67d3\u3001\u73b0\u4ee3 C++\u3001\u73b0\u4ee3 CMake\u3001\u73b0\u4ee3 CUDA\u3001\u73b0\u4ee3 OpenGL\u3001\u591a\u7ebf\u7a0b\u5e76\u53d1\u3001\u534f\u7a0b\u3001\u5f02\u6b65 I/O\u3001SIMD\u3001\u5e76\u884c\u7f16\u7a0b\u3001\u6027\u80fd\u8c03\u4f18\u7b49\u591a\u4e2a\u9886\u57df\uff0c\u90fd\u80fd\u5bf9\u7b54\u5982\u6d41\u3002 \u4ed6\u64c5\u957f\u5e76\u884c\u7f16\u7a0b\u548c\u4f18\u5316\u6280\u672f\uff0c\u5bf9\u4e8e\u73b0\u4ee3 C++ \u548c\u8bbe\u8ba1\u6a21\u5f0f\u4e5f\u6709\u81ea\u5df1\u72ec\u5230\u7684\u89c1\u89e3\uff0c\u6df1\u53d7\u201c\u7ae5\u978b\u201d\u559c\u7231\u548c\u5c0a\u656c\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 B \u7ad9 \u64ad\u51fa\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u7f16\u7a0b\u4e0e\u4f18\u5316\u300b\u7cfb\u5217\u516c\u5f00\u8bfe\uff0c\u4e00\u7ecf\u63a8\u51fa\uff0c\u7acb\u523b\u597d\u8bc4\u5982\u6f6e\uff01 \u5c0f\u5f6d\u8001\u5e08\u5c06\u81ea\u5df1\u4e30\u5bcc\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u77e5\u8bc6\u50a8\u5907\u8f6c\u5316\u4e3a\u7ae5\u978b\u4eec\u7684\u751f\u4ea7\u529b\uff0c\u642d\u4e0a\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u589e\u957f\u7684\u9ad8\u901f\u730e\u8f66\uff0c\u5f15\u9886\u7ae5\u978b\u9ad8\u5c31\u7684\u4f1f\u5927\u822a\u8def\u3002 \u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\u3002","title":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08"},{"location":"about/#_1","text":"\u5c0f\u5f6d\u8001\u5e08\u662f\u4e00\u4f4d\u64c5\u957f\u9ad8\u6027\u80fd C++ \u7684\u7a0b\u5e8f\u5458\uff0c\u76ee\u524d\u4e3b\u8981\u4ece\u4e8b\u56fe\u5f62\u5b66\u9886\u57df\u7684\u5f15\u64ce\u5f00\u53d1\uff0c\u62e5\u6709\u591a\u5e74\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u4e30\u5bcc\u7684\u77e5\u8bc6\u50a8\u5907\uff0c\u7cbe\u901a\u7ebf\u6027\u4ee3\u6570\u3001\u5fae\u79ef\u5206\u3001\u6982\u7387\u8bba\u3001\u5fae\u5206\u51e0\u4f55\u3001\u56fe\u5f62\u5b66\u3001\u6e38\u620f\u5f15\u64ce\u3001\u4e92\u8054\u7f51\u3001\u7f16\u8bd1\u539f\u7406\u3001\u8bbe\u8ba1\u6a21\u5f0f\u3001\u79bb\u7ebf\u6e32\u67d3\u3001\u73b0\u4ee3 C++\u3001\u73b0\u4ee3 CMake\u3001\u73b0\u4ee3 CUDA\u3001\u73b0\u4ee3 OpenGL\u3001\u591a\u7ebf\u7a0b\u5e76\u53d1\u3001\u534f\u7a0b\u3001\u5f02\u6b65 I/O\u3001SIMD\u3001\u5e76\u884c\u7f16\u7a0b\u3001\u6027\u80fd\u8c03\u4f18\u7b49\u591a\u4e2a\u9886\u57df\uff0c\u90fd\u80fd\u5bf9\u7b54\u5982\u6d41\u3002 \u4ed6\u64c5\u957f\u5e76\u884c\u7f16\u7a0b\u548c\u4f18\u5316\u6280\u672f\uff0c\u5bf9\u4e8e\u73b0\u4ee3 C++ \u548c\u8bbe\u8ba1\u6a21\u5f0f\u4e5f\u6709\u81ea\u5df1\u72ec\u5230\u7684\u89c1\u89e3\uff0c\u6df1\u53d7\u201c\u7ae5\u978b\u201d\u559c\u7231\u548c\u5c0a\u656c\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 B \u7ad9 \u64ad\u51fa\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u7f16\u7a0b\u4e0e\u4f18\u5316\u300b\u7cfb\u5217\u516c\u5f00\u8bfe\uff0c\u4e00\u7ecf\u63a8\u51fa\uff0c\u7acb\u523b\u597d\u8bc4\u5982\u6f6e\uff01 \u5c0f\u5f6d\u8001\u5e08\u5c06\u81ea\u5df1\u4e30\u5bcc\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u77e5\u8bc6\u50a8\u5907\u8f6c\u5316\u4e3a\u7ae5\u978b\u4eec\u7684\u751f\u4ea7\u529b\uff0c\u642d\u4e0a\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u589e\u957f\u7684\u9ad8\u901f\u730e\u8f66\uff0c\u5f15\u9886\u7ae5\u978b\u9ad8\u5c31\u7684\u4f1f\u5927\u822a\u8def\u3002 \u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\u3002","title":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08"},{"location":"auto/","text":"auto \u795e\u6559 (\u672a\u5b8c\u5de5) \u53d8\u91cf auto \u8fd4\u56de\u7c7b\u578b auto C++11 \u5f15\u5165\u7684 auto \u5173\u952e\u5b57\u53ef\u4ee5\u7528\u4f5c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4f46\u5b83\u53ea\u662f\u4e00\u4e2a\u201c\u5360\u4f4d\u201d\uff0c\u8ba9\u6211\u4eec\u5f97\u4ee5\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\uff0c\u5e76\u6ca1\u6709\u591a\u5927\u4f5c\u7528\uff0c\u975e\u5e38\u6b8b\u5e9f\u3002 auto f() -> int; // \u7b49\u4ef7\u4e8e\uff1a int f(); \u95f9\u4e86\u534a\u5929\uff0c\u8fd8\u662f\u8981\u5199\u8fd4\u56de\u7c7b\u578b\uff0c\u5c31\u53ea\u662f\u632a\u5230\u540e\u9762\u53bb\u597d\u770b\u4e00\u70b9\u2026\u2026 \u5f53\u521d\u5f15\u5165\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\u5b9e\u9645\u7684\u7528\u9014\u662f auto f(int x) -> decltype(x * x) { return x * x; } \u8fd9\u79cd\u60c5\u51b5\uff0c\u4f46\u5f88\u5bb9\u6613\u88ab\u63a5\u4e0b\u6765 C++14 \u5f15\u5165\u7684\u771f\u6b63 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u5e73\u66ff\u4e86\u3002 \u4f46\u662f C++14 \u5f15\u5165\u4e86\u51fd\u6570 \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc \uff0c auto \u624d\u7b97\u771f\u6b63\u610f\u4e49\u4e0a\u80fd\u7528\u505a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff0c\u5b83\u4f1a\u81ea\u52a8\u6839\u636e\u51fd\u6570\u4e2d\u7684 return \u8868\u8fbe\u5f0f\u63a8\u5bfc\u51fa\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u3002 auto f(int x) { return x * x; // \u8868\u8fbe\u5f0f `x * x` \u7684\u7c7b\u578b\u4e3a int\uff0c\u6240\u4ee5 auto \u7c7b\u578b\u63a8\u5bfc\u4e3a int } // \u7b49\u4ef7\u4e8e\uff1a int f() { return x * x; } \u5982\u679c\u51fd\u6570\u4e2d\u6ca1\u6709 return \u8bed\u53e5\uff0c\u90a3\u4e48 auto \u4f1a\u88ab\u81ea\u52a8\u63a8\u5bfc\u4e3a void \uff0c\u975e\u5e38\u65b9\u4fbf\u3002 auto f() { std::println(\"hello\"); } // \u7b49\u4ef7\u4e8e\uff1a void f() { std::println(\"hello\"); } \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8fd4\u56de\u7c7b\u578b\u7528 auto \u6765\u63a8\u5bfc\u7684\u51fd\u6570\uff0c\u5982\u679c\u6709\u591a\u6761 return \u8bed\u53e5\uff0c\u90a3\u4e48\u4ed6\u4eec\u5fc5\u987b\u90fd\u8fd4\u56de\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u62a5\u9519\u3002 auto f(int x) { if (x > 0) { return 1; // int } else { return 3.14; // double } } // \u9519\u8bef\uff1a\u6709\u6b67\u4e49\uff0c\u65e0\u6cd5\u786e\u5b9a auto \u5e94\u8be5\u63a8\u5bfc\u4e3a int \u8fd8\u662f double auto \u8fd8\u6709\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u65e0\u6cd5\u7528\u4e8e\u201c\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u201d\u7684\u60c5\u51b5\u3002\u56e0\u4e3a\u63a8\u5bfc auto \u7c7b\u578b\u9700\u8981\u77e5\u9053\u51fd\u6570\u4f53\uff0c\u624d\u80fd\u770b\u5230\u91cc\u9762\u7684 return \u8868\u8fbe\u5f0f\u662f\u4ec0\u4e48\u7c7b\u578b\u3002\u6240\u4ee5\u5f53 auto \u8fd4\u56de\u7c7b\u578b\u88ab\u7528\u4e8e\u51fd\u6570\u7684\u975e\u5b9a\u4e49\u58f0\u660e\u65f6\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519\u3002 auto f(); // \u9519\u8bef\uff1a\u770b\u4e0d\u5230\u51fd\u6570\u4f53\uff0c\u65e0\u6cd5\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto f() { // \u7f16\u8bd1\u901a\u8fc7\uff1aauto \u63a8\u5bfc\u4e3a int return 1; // 1 \u662f int \u7c7b\u578b\u7684\u8868\u8fbe\u5f0f } \u56e0\u6b64\uff0c auto \u901a\u5e38\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u201c\u5c31\u5730\u5b9a\u4e49\u201d\u7684 inline \u51fd\u6570\uff0c\u4e0d\u9002\u5408\u9700\u8981\u201c\u5206\u79bb .cpp \u6587\u4ef6\u201d\u7684\u51fd\u6570\u3002 \u53c2\u6570\u7c7b\u578b auto C++20 \u5f15\u5165\u4e86 \u6a21\u677f\u53c2\u6570\u63a8\u5bfc \uff0c\u53ef\u4ee5\u8ba9\u6211\u4eec\u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u3002 \u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5c06\u8be5\u53c2\u6570\u58f0\u660e\u4e3a\u6a21\u677f\u53c2\u6570\uff0c\u4ec5\u4ec5\u662f\u4e00\u79cd\u66f4\u4fbf\u6377\u7684\u5199\u6cd5\u3002 void func(auto x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T x) { std::cout << x; } func(1); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(1) func(3.14); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(3.14) \u5982\u679c\u53c2\u6570\u7c7b\u578b\u7684 auto \u5e26\u6709\u5982 auto & \u8fd9\u6837\u7684\u4fee\u9970\uff0c\u5219\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u76f8\u5e94\u6a21\u677f\u51fd\u6570\u7684 T & \u3002 // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u5e38\u5f15\u7528 void func(auto const &x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T const &x) { std::cout << x; } // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u4e07\u80fd\u5f15\u7528 void func(auto &&x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T &&x) { std::cout << x; } auto \u5728\u591a\u6001\u4e2d\u7684\u5999\u7528 \u4f20\u7edf\u7684\uff0c\u57fa\u4e8e\u7c7b\u578b\u91cd\u8f7d\u7684\uff1a int square(int x) { return x * x; } double square(double x) { return x * x; } int main() { square(2); // 4\uff08\u8c03\u7528 int \u7248\u91cd\u8f7d\uff09 square(3.14); // 9.8596\uff08\u8c03\u7528 double \u7248\u91cd\u8f7d\uff09 // \u5982\u679c\u73b0\u5728\u53c8\u9700\u8981 float \u7248\u5462\uff1f\u53c8\u5f97\u5199\u4e00\u7248\u91cd\u8f7d\uff0c\u5185\u5bb9\u8fd8\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff0c\u6d6a\u8d39\u65f6\u95f4 } \u57fa\u4e8e auto \u6a21\u677f\u53c2\u6570\u63a8\u5bfc\u7684\uff1a auto square(auto x) { return x * x; } int main() { square(2); // 4\uff08auto \u63a8\u5bfc\u4e3a int\uff09 square(3.14); // 9.8596\uff08auto \u63a8\u5bfc\u4e3a double\uff09 // \u5373\u4f7f\u672a\u6765\u4ea7\u751f\u4e86 float \u7248\u7684\u9700\u6c42\uff0c\u4e5f\u4e0d\u7528\u6dfb\u52a0\u4efb\u4f55\u4ee3\u7801\uff0c\u56e0\u4e3a\u662f square \u662f\u5f88\u65b9\u4fbf\u7684\u6a21\u677f\u51fd\u6570 } auto \u63a8\u5bfc\u4e3a\u5f15\u7528 TODO: \u7ee7\u7eed\u4ecb\u7ecd auto , auto const , auto & , auto const & , auto && , decltype(auto) , auto * , auto const *","title":"auto \u795e\u6559 (\u672a\u5b8c\u5de5)"},{"location":"auto/#auto","text":"","title":"auto \u795e\u6559 (\u672a\u5b8c\u5de5)"},{"location":"auto/#auto_1","text":"","title":"\u53d8\u91cf auto"},{"location":"auto/#auto_2","text":"C++11 \u5f15\u5165\u7684 auto \u5173\u952e\u5b57\u53ef\u4ee5\u7528\u4f5c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4f46\u5b83\u53ea\u662f\u4e00\u4e2a\u201c\u5360\u4f4d\u201d\uff0c\u8ba9\u6211\u4eec\u5f97\u4ee5\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\uff0c\u5e76\u6ca1\u6709\u591a\u5927\u4f5c\u7528\uff0c\u975e\u5e38\u6b8b\u5e9f\u3002 auto f() -> int; // \u7b49\u4ef7\u4e8e\uff1a int f(); \u95f9\u4e86\u534a\u5929\uff0c\u8fd8\u662f\u8981\u5199\u8fd4\u56de\u7c7b\u578b\uff0c\u5c31\u53ea\u662f\u632a\u5230\u540e\u9762\u53bb\u597d\u770b\u4e00\u70b9\u2026\u2026 \u5f53\u521d\u5f15\u5165\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\u5b9e\u9645\u7684\u7528\u9014\u662f auto f(int x) -> decltype(x * x) { return x * x; } \u8fd9\u79cd\u60c5\u51b5\uff0c\u4f46\u5f88\u5bb9\u6613\u88ab\u63a5\u4e0b\u6765 C++14 \u5f15\u5165\u7684\u771f\u6b63 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u5e73\u66ff\u4e86\u3002 \u4f46\u662f C++14 \u5f15\u5165\u4e86\u51fd\u6570 \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc \uff0c auto \u624d\u7b97\u771f\u6b63\u610f\u4e49\u4e0a\u80fd\u7528\u505a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff0c\u5b83\u4f1a\u81ea\u52a8\u6839\u636e\u51fd\u6570\u4e2d\u7684 return \u8868\u8fbe\u5f0f\u63a8\u5bfc\u51fa\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u3002 auto f(int x) { return x * x; // \u8868\u8fbe\u5f0f `x * x` \u7684\u7c7b\u578b\u4e3a int\uff0c\u6240\u4ee5 auto \u7c7b\u578b\u63a8\u5bfc\u4e3a int } // \u7b49\u4ef7\u4e8e\uff1a int f() { return x * x; } \u5982\u679c\u51fd\u6570\u4e2d\u6ca1\u6709 return \u8bed\u53e5\uff0c\u90a3\u4e48 auto \u4f1a\u88ab\u81ea\u52a8\u63a8\u5bfc\u4e3a void \uff0c\u975e\u5e38\u65b9\u4fbf\u3002 auto f() { std::println(\"hello\"); } // \u7b49\u4ef7\u4e8e\uff1a void f() { std::println(\"hello\"); } \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8fd4\u56de\u7c7b\u578b\u7528 auto \u6765\u63a8\u5bfc\u7684\u51fd\u6570\uff0c\u5982\u679c\u6709\u591a\u6761 return \u8bed\u53e5\uff0c\u90a3\u4e48\u4ed6\u4eec\u5fc5\u987b\u90fd\u8fd4\u56de\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u62a5\u9519\u3002 auto f(int x) { if (x > 0) { return 1; // int } else { return 3.14; // double } } // \u9519\u8bef\uff1a\u6709\u6b67\u4e49\uff0c\u65e0\u6cd5\u786e\u5b9a auto \u5e94\u8be5\u63a8\u5bfc\u4e3a int \u8fd8\u662f double auto \u8fd8\u6709\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u65e0\u6cd5\u7528\u4e8e\u201c\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u201d\u7684\u60c5\u51b5\u3002\u56e0\u4e3a\u63a8\u5bfc auto \u7c7b\u578b\u9700\u8981\u77e5\u9053\u51fd\u6570\u4f53\uff0c\u624d\u80fd\u770b\u5230\u91cc\u9762\u7684 return \u8868\u8fbe\u5f0f\u662f\u4ec0\u4e48\u7c7b\u578b\u3002\u6240\u4ee5\u5f53 auto \u8fd4\u56de\u7c7b\u578b\u88ab\u7528\u4e8e\u51fd\u6570\u7684\u975e\u5b9a\u4e49\u58f0\u660e\u65f6\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519\u3002 auto f(); // \u9519\u8bef\uff1a\u770b\u4e0d\u5230\u51fd\u6570\u4f53\uff0c\u65e0\u6cd5\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto f() { // \u7f16\u8bd1\u901a\u8fc7\uff1aauto \u63a8\u5bfc\u4e3a int return 1; // 1 \u662f int \u7c7b\u578b\u7684\u8868\u8fbe\u5f0f } \u56e0\u6b64\uff0c auto \u901a\u5e38\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u201c\u5c31\u5730\u5b9a\u4e49\u201d\u7684 inline \u51fd\u6570\uff0c\u4e0d\u9002\u5408\u9700\u8981\u201c\u5206\u79bb .cpp \u6587\u4ef6\u201d\u7684\u51fd\u6570\u3002","title":"\u8fd4\u56de\u7c7b\u578b auto"},{"location":"auto/#auto_3","text":"C++20 \u5f15\u5165\u4e86 \u6a21\u677f\u53c2\u6570\u63a8\u5bfc \uff0c\u53ef\u4ee5\u8ba9\u6211\u4eec\u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u3002 \u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5c06\u8be5\u53c2\u6570\u58f0\u660e\u4e3a\u6a21\u677f\u53c2\u6570\uff0c\u4ec5\u4ec5\u662f\u4e00\u79cd\u66f4\u4fbf\u6377\u7684\u5199\u6cd5\u3002 void func(auto x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T x) { std::cout << x; } func(1); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(1) func(3.14); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(3.14) \u5982\u679c\u53c2\u6570\u7c7b\u578b\u7684 auto \u5e26\u6709\u5982 auto & \u8fd9\u6837\u7684\u4fee\u9970\uff0c\u5219\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u76f8\u5e94\u6a21\u677f\u51fd\u6570\u7684 T & \u3002 // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u5e38\u5f15\u7528 void func(auto const &x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T const &x) { std::cout << x; } // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u4e07\u80fd\u5f15\u7528 void func(auto &&x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T &&x) { std::cout << x; }","title":"\u53c2\u6570\u7c7b\u578b auto"},{"location":"auto/#auto_4","text":"\u4f20\u7edf\u7684\uff0c\u57fa\u4e8e\u7c7b\u578b\u91cd\u8f7d\u7684\uff1a int square(int x) { return x * x; } double square(double x) { return x * x; } int main() { square(2); // 4\uff08\u8c03\u7528 int \u7248\u91cd\u8f7d\uff09 square(3.14); // 9.8596\uff08\u8c03\u7528 double \u7248\u91cd\u8f7d\uff09 // \u5982\u679c\u73b0\u5728\u53c8\u9700\u8981 float \u7248\u5462\uff1f\u53c8\u5f97\u5199\u4e00\u7248\u91cd\u8f7d\uff0c\u5185\u5bb9\u8fd8\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff0c\u6d6a\u8d39\u65f6\u95f4 } \u57fa\u4e8e auto \u6a21\u677f\u53c2\u6570\u63a8\u5bfc\u7684\uff1a auto square(auto x) { return x * x; } int main() { square(2); // 4\uff08auto \u63a8\u5bfc\u4e3a int\uff09 square(3.14); // 9.8596\uff08auto \u63a8\u5bfc\u4e3a double\uff09 // \u5373\u4f7f\u672a\u6765\u4ea7\u751f\u4e86 float \u7248\u7684\u9700\u6c42\uff0c\u4e5f\u4e0d\u7528\u6dfb\u52a0\u4efb\u4f55\u4ee3\u7801\uff0c\u56e0\u4e3a\u662f square \u662f\u5f88\u65b9\u4fbf\u7684\u6a21\u677f\u51fd\u6570 }","title":"auto \u5728\u591a\u6001\u4e2d\u7684\u5999\u7528"},{"location":"auto/#auto_5","text":"TODO: \u7ee7\u7eed\u4ecb\u7ecd auto , auto const , auto & , auto const & , auto && , decltype(auto) , auto * , auto const *","title":"auto \u63a8\u5bfc\u4e3a\u5f15\u7528"},{"location":"cmake_tutor/","text":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09 TODO","title":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"cmake_tutor/#c-cmake","text":"TODO","title":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"cpp_lifetime/","text":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f \u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f \u4e09\u5927\u5b58\u50a8\u5468\u671f \u603b\u7ed3 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u4e2d\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5177\u6709\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u3002 \u6784\u9020\u51fd\u6570\u56fa\u5b9a\u4e3a \u7c7b\u540d(\u6784\u9020\u51fd\u6570\u53c2\u6570\u5217\u8868) \u3002 \u6790\u6784\u51fd\u6570\u56fa\u5b9a\u4e3a ~\u7c7b\u540d() \u3002 \u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u90fd\u6ca1\u6709\u8fd4\u56de\u503c\u7c7b\u578b\u3002 \u6790\u6784\u51fd\u6570\u4e0d\u5f97\u62e5\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u4f46\u6784\u9020\u51fd\u6570\u53ef\u4ee5\u6709\u3002 struct Class { Class() { puts(\"\u6784\u9020\u51fd\u6570\"); } ~Class() { puts(\"\u6790\u6784\u51fd\u6570\"); } }; int main() { puts(\"\u8fdb\u5165 main\"); Class c; puts(\"\u79bb\u5f00 main\"); } \u8fd0\u884c\u7ed3\u679c\uff1a \u8fdb\u5165 main \u6784\u9020\u51fd\u6570 \u79bb\u5f00 main \u6790\u6784\u51fd\u6570 \u8fd9\u662f C++ \u4e2d\u6700\u57fa\u672c\u7684\u73b0\u8c61\u3002\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\uff0c\u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570\uff0c\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u79bb\u5f00\u5b9a\u4e49\u4e86\u4ed6\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u4f1a\u8c03\u7528\u6790\u6784\u51fd\u6570\u3002 \u51fd\u6570\u4f53\u6307\u7684\u662f\u4ece { \u5230 } \u4e4b\u95f4\u7684\u4ee3\u7801\u5757\u3002 \u5176\u4e2d\u6784\u9020\u51fd\u6570\u4e2d\u901a\u5e38\u8d1f\u8d23\u521b\u5efa\u8d44\u6e90\uff0c\u6790\u6784\u51fd\u6570\u4e2d\u901a\u5e38\u9500\u6bc1\u8d44\u6e90\u3002\u5bf9\u4e8e\u667a\u80fd\u6307\u9488\u548c vector \u800c\u8a00\uff0c\u8fd9\u4e2a\u8d44\u6e90\u5c31\u662f\u5185\u5b58\u3002 \u4e3a\u4ec0\u4e48\u8981\u53ca\u65f6\u9500\u6bc1\u4e0d\u7528\u7684\u8d44\u6e90\uff1f\u53ea\u5206\u914d\u4e0d\u91ca\u653e\uff0c\u4e00\u4e2a\u7a0b\u5e8f\u5360\u7528\u7684\u5185\u5b58\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u5c31\u4f1a\u8d8a\u6765\u8d8a\u591a\uff0c\u8fd9\u79cd\u7a0b\u5e8f\u5982\u679c\u957f\u671f\u8fd0\u884c\uff0c\u4f1a\u5403\u5149\u6574\u4e2a\u7cfb\u7edf\u7684\u6240\u6709\u8d44\u6e90\u7136\u540e\u88ab Linux \u5185\u6838\u89c6\u4e3a\u5371\u9669\u8fdb\u7a0b\u800c\u6740\u6b7b\u3002\u9664\u975e\u4f60\u7684\u7a0b\u5e8f\u53ea\u4f1a\u8fd0\u884c\u4e00\u4f1a\u4f1a\uff0c\u5982\u679c\u662f\u957f\u671f\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u4f8b\u5982\u670d\u52a1\u5668\uff0c\u5fc5\u987b\u4e25\u683c\u7ba1\u7406\u6240\u6709\u81ea\u5df1\u66fe\u7ecf\u5206\u914d\u8fc7\u7684\u5185\u5b58\uff0c\u4e0d\u7528\u65f6\u5c31\u7acb\u5373\u91ca\u653e\uff0c\u4e0d\u8981\u5360\u7740\u8305\u5751\u4e0d\u62c9\u53f2\u3002 } \u88ab\u8a89\u4e3a \u6700\u4f1f\u5927\u7684\u8fd0\u7b97\u7b26 \uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u53ef\u4ee5\u89e6\u53d1\u6790\u6784\u51fd\u6570\uff0c\u5e2e\u4f60\u81ea\u52a8\u91ca\u653e\u6389\u8d44\u6e90\uff0c\u4f60\u5c31\u4e0d\u7528\u81ea\u5df1\u8d39\u5fc3\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff0c\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u4e86\u3002 \u4e09\u5927\u5b58\u50a8\u5468\u671f \u5728\u8fdb\u4e00\u6b65\u6df1\u5165\u4e4b\u524d\uff0c\u6211\u4eec\u5fc5\u987b\u660e\u786e\u4ee5\u4e0b\u672f\u8bed\uff1a\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u3001\u52a8\u6001\u5b58\u50a8\u5468\u671f\u3001\u9759\u6001\u5b58\u50a8\u5468\u671f\u3002 \u53d8\u91cf\u5b9a\u4e49\u5728\u4e0d\u540c\u7684\u4f4d\u7f6e\uff0c\u5176\u751f\u547d\u5468\u671f\uff08\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\uff09\u4f1a\u6709\u6240\u4e0d\u540c\u3002 \u6bd4\u5982\u4e00\u4e2a\u53d8\u91cf\u5b9a\u4e49\u5728\u51fd\u6570\u4f53\u5185\u3001\u7c7b\u4f53\u5185\u3001\u901a\u8fc7 new \u521b\u5efa\uff0c\u4e4b\u7c7b\u7684\u3002 \u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u76f4\u63a5\u5b9a\u4e49\u5728 \u51fd\u6570\u4f53 \u5185\u3002\u4fd7\u79f0\u201c\u6808\u4e0a\u201d\u6216\u201c\u5c40\u90e8\u53d8\u91cf\u201d void func() { Class a; // a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u5b9a\u4e49\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u6240\u5728\u7684 {} \u4ee3\u7801\u5757\u6267\u884c\u5230 } \u5904\u65f6\u8c03\u7528\u3002 \u52a8\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u901a\u8fc7 new \u6765\u521b\u5efa\u3002\u4fd7\u79f0\u201c\u5806\u4e0a\u201d\u6216\u201c\u5806\u5bf9\u8c61\u201d void func() { Class *p = new Class; // *p \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f delete p; // \u91ca\u653e\u52a8\u6001\u5206\u914d\u7684\u5185\u5b58 } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u901a\u8fc7 new \u521b\u5efa\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 delete \u88ab\u8c03\u7528\u65f6\u88ab\u8c03\u7528\u3002 \u7279\u522b\u6ce8\u610f\uff0c p \u4f9d\u7136\u662f\u201c\u6808\u4e0a\u53d8\u91cf\u201d\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u201c\u5806\u4e0a\u53d8\u91cf\u201d\uff01 \u7528\u5f8b\u5e08\u8bed\u518d\u8bf4\u4e00\u904d\uff1a p \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f\uff01\uff08\u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\uff09 \u6307\u9488\u672c\u8eab\uff0c\u548c\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\uff0c\u662f\u4e24\u4e2a\u4e1c\u897f\uff0c\u4e0d\u8981\u6df7\u6dc6\u3002 p \u672c\u8eab\u4f1a\u968f\u7740 func \u7684 } \u800c\u6790\u6784\uff0c\u4f46\u662f *p \u7684\u7c7b\u578b\u662f Class * \uff0c\u662f\u4e00\u4e2a C \u8bed\u8a00\u539f\u59cb\u6307\u9488\uff0c\u539f\u59cb\u6307\u9488\u5c5e\u4e8e C \u8bed\u8a00\u539f\u59cb\u7c7b\u578b\uff0c\u6ca1\u6709\u6790\u6784\u51fd\u6570\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u62b5\u8fbe } \u65f6\uff0c p \u540d\u4e49\u4e0a\u4f1a\u6790\u6784\uff0c\u4f46\u662f\u4ed6\u6ca1\u6709\u6790\u6784\u51fd\u6570\uff0c\u5e76\u4e0d\u4f1a\u4ea7\u751f\u4efb\u4f55\u4f5c\u7528\u3002\u8fd9\u4e00\u5207\u548c p \u6307\u5411\u7684\u5bf9\u8c61 *p \u6ca1\u6709\u4efb\u4f55\u5173\u7cfb\uff0c\u4f60\u9700\u8981\u624b\u52a8 delete \u624d\u4f1a\u8c03\u7528\u5230 *p \u7684\u6790\u6784\u51fd\u6570\uff0c\u5e76\u91ca\u653e\u5206\u914d\u7684\u5185\u5b58\u3002 new \u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u5185\u5b58\u5206\u914d + \u5bf9\u8c61\u6784\u9020 delete \u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u5bf9\u8c61\u6790\u6784 + \u5185\u5b58\u91ca\u653e \u667a\u80fd\u6307\u9488\u7684\u4f18\u52bf\u5728\u4e8e\uff0c\u667a\u80fd\u6307\u9488\u662f\u4e2a C++ \u7c7b\uff0c\u5177\u6709\u5b9a\u5236\u7684\u6790\u6784\u51fd\u6570\u3002\u5f53 } \u62b5\u8fbe\uff0c \u667a\u80fd\u6307\u9488\u672c\u8eab \u7531\u4e8e\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\u6790\u6784\u65f6\uff0c\u5176\u4f1a delete p \uff0c\u5229\u7528\u52a8\u6001\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\uff0c\u89e6\u53d1 \u667a\u80fd\u6307\u9488\u6307\u5411\u5bf9\u8c61 \u7684\u6790\u6784\u51fd\u6570\uff0c\u4e5f\u5c31\u662f\u4ece\u800c\u8c03\u7528 *p \u7684\u6790\u6784\u51fd\u6570\u3002 \u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u53c8\u8981\u5177\u4f53\u5206\u4e09\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u6216\u201c\u9759\u6001\u53d8\u91cf\u201d (1) \u5b9a\u4e49\u5728 \u540d\u5b57\u7a7a\u95f4 \u5185\uff0c\u4e0d\u8bba\u662f\u4e0d\u662f static \u6216 inline\uff08\u5728\u540d\u5b57\u7a7a\u95f4\u4e2d\uff0cstatic \u548c inline \u5f71\u54cd\u7684\u53ea\u662f\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff0c\u800c\u4e0d\u662f\u5b58\u50a8\u5468\u671f\uff09 namespace hello { Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u542f\u52a8\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u524d\uff09\uff1b\u5bf9 DLL \u6765\u8bf4\u5219\u662f DLL \u9996\u6b21\u52a0\u8f7d\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u9000\u51fa\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u540e\uff09\u3002 (2) \u6ce8\u610f\uff0c \u5168\u5c40\u540d\u5b57\u7a7a\u95f4 \u662f\u4e00\u4e2a\u7279\u6b8a\u7684 \u540d\u5b57\u7a7a\u95f4 \uff0c\u5916\u9762\u6ca1\u6709\u5305\u88f9\u4efb\u4f55 namespace \u65f6\u5c31\u5c5e\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u3002\u6240\u4ee5\u4e0b\u9762\u8fd9\u79cd\u4e5f\u5c5e\u4e8e\u201c\u5728 (\u5168\u5c40) \u540d\u5b57\u7a7a\u95f4\u5185\u201d\uff1a Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f (3) \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u9759\u6001\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u5c31\u662f\u901a\u8fc7 static \u4fee\u9970\u8fc7\u7684\u6210\u5458\u53d8\u91cf\uff08\u5728\u7c7b\u5185\uff0cstatic \u5c31\u5f71\u54cd\u5b58\u50a8\u5468\u671f\u4e86\uff0cinline \u7ee7\u7eed\u53ea\u5f71\u54cd\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff09 struct Other { static Class s; }; Class Other::s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f struct Other { inline static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f }; struct Other { Class a; // a \u4e0d\u662f\u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u800c\u662f\u8ddf\u968f\u5176\u6240\u5c5e\u7684 Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u6210\u5458\u53d8\u91cf\uff08\u6ca1\u6709 static \u7684\uff09\uff0c\u8ddf\u968f\u6240\u5c5e\u7c7b\u7684\u5b58\u50a8\u5468\u671f struct Other { Class a; // a \u8ddf\u968f Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; Other o; // o.a \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f int main() { Other o; // o.a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f Other *p; // p->a \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6784\u9020\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6790\u6784\u65f6\u8c03\u7528\u3002 \u603b\u7ed3 \u81ea\u52a8\u5b58\u50a8\u5468\u671f - \u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u81ea\u52a8\u6790\u6784 \u52a8\u6001\u5b58\u50a8\u5468\u671f - \u901a\u8fc7 new \u521b\u5efa\u7684\uff0cdelete \u65f6\u6790\u6784 \u9759\u6001\u5b58\u50a8\u5468\u671f - \u5168\u5c40\u53d8\u91cf\uff0c\u7a0b\u5e8f\u7ed3\u675f\u65f6\u6790\u6784 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u539f\u56e0\u5f88\u590d\u6742\uff0c\u6574\u4e2a\u6545\u4e8b\u8981\u4ece boost \u5f53\u5e74\u5982\u4f55\u8bbe\u8ba1\u51fa\u53f3\u503c\u5f15\u7528\u5230\u56fe\u7075\u7684\u505c\u673a\u95ee\u9898\u8bb2\u8d77\uff0c\u8bb2\u4e86\u4f60\u4e5f\u8bb0\u4e0d\u4f4f\uff0c\u53ea\u9700\u8981\u8bb0\u4f4f\u7ed3\u8bba\uff1a \u5982\u679c\u4f60\u8981\u5b9a\u4e49\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 -Wnon-virtual-dtor -Wdelete-non-virtual-dtor TODO: \u4ecb\u7ecd \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c TODO int main() { std::string const &s = std::string(\"hello\"); std::cout << s; // OK } std::string const &identity(std::string const &s) { return s; } int main() { std::string const &s = identity(std::string(\"hello\")); std::cout << s; // BOOM! }","title":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#_1","text":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f \u4e09\u5927\u5b58\u50a8\u5468\u671f \u603b\u7ed3 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c","title":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#c","text":"C++ \u4e2d\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5177\u6709\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u3002 \u6784\u9020\u51fd\u6570\u56fa\u5b9a\u4e3a \u7c7b\u540d(\u6784\u9020\u51fd\u6570\u53c2\u6570\u5217\u8868) \u3002 \u6790\u6784\u51fd\u6570\u56fa\u5b9a\u4e3a ~\u7c7b\u540d() \u3002 \u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u90fd\u6ca1\u6709\u8fd4\u56de\u503c\u7c7b\u578b\u3002 \u6790\u6784\u51fd\u6570\u4e0d\u5f97\u62e5\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u4f46\u6784\u9020\u51fd\u6570\u53ef\u4ee5\u6709\u3002 struct Class { Class() { puts(\"\u6784\u9020\u51fd\u6570\"); } ~Class() { puts(\"\u6790\u6784\u51fd\u6570\"); } }; int main() { puts(\"\u8fdb\u5165 main\"); Class c; puts(\"\u79bb\u5f00 main\"); } \u8fd0\u884c\u7ed3\u679c\uff1a \u8fdb\u5165 main \u6784\u9020\u51fd\u6570 \u79bb\u5f00 main \u6790\u6784\u51fd\u6570 \u8fd9\u662f C++ \u4e2d\u6700\u57fa\u672c\u7684\u73b0\u8c61\u3002\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\uff0c\u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570\uff0c\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u79bb\u5f00\u5b9a\u4e49\u4e86\u4ed6\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u4f1a\u8c03\u7528\u6790\u6784\u51fd\u6570\u3002 \u51fd\u6570\u4f53\u6307\u7684\u662f\u4ece { \u5230 } \u4e4b\u95f4\u7684\u4ee3\u7801\u5757\u3002 \u5176\u4e2d\u6784\u9020\u51fd\u6570\u4e2d\u901a\u5e38\u8d1f\u8d23\u521b\u5efa\u8d44\u6e90\uff0c\u6790\u6784\u51fd\u6570\u4e2d\u901a\u5e38\u9500\u6bc1\u8d44\u6e90\u3002\u5bf9\u4e8e\u667a\u80fd\u6307\u9488\u548c vector \u800c\u8a00\uff0c\u8fd9\u4e2a\u8d44\u6e90\u5c31\u662f\u5185\u5b58\u3002 \u4e3a\u4ec0\u4e48\u8981\u53ca\u65f6\u9500\u6bc1\u4e0d\u7528\u7684\u8d44\u6e90\uff1f\u53ea\u5206\u914d\u4e0d\u91ca\u653e\uff0c\u4e00\u4e2a\u7a0b\u5e8f\u5360\u7528\u7684\u5185\u5b58\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u5c31\u4f1a\u8d8a\u6765\u8d8a\u591a\uff0c\u8fd9\u79cd\u7a0b\u5e8f\u5982\u679c\u957f\u671f\u8fd0\u884c\uff0c\u4f1a\u5403\u5149\u6574\u4e2a\u7cfb\u7edf\u7684\u6240\u6709\u8d44\u6e90\u7136\u540e\u88ab Linux \u5185\u6838\u89c6\u4e3a\u5371\u9669\u8fdb\u7a0b\u800c\u6740\u6b7b\u3002\u9664\u975e\u4f60\u7684\u7a0b\u5e8f\u53ea\u4f1a\u8fd0\u884c\u4e00\u4f1a\u4f1a\uff0c\u5982\u679c\u662f\u957f\u671f\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u4f8b\u5982\u670d\u52a1\u5668\uff0c\u5fc5\u987b\u4e25\u683c\u7ba1\u7406\u6240\u6709\u81ea\u5df1\u66fe\u7ecf\u5206\u914d\u8fc7\u7684\u5185\u5b58\uff0c\u4e0d\u7528\u65f6\u5c31\u7acb\u5373\u91ca\u653e\uff0c\u4e0d\u8981\u5360\u7740\u8305\u5751\u4e0d\u62c9\u53f2\u3002 } \u88ab\u8a89\u4e3a \u6700\u4f1f\u5927\u7684\u8fd0\u7b97\u7b26 \uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u53ef\u4ee5\u89e6\u53d1\u6790\u6784\u51fd\u6570\uff0c\u5e2e\u4f60\u81ea\u52a8\u91ca\u653e\u6389\u8d44\u6e90\uff0c\u4f60\u5c31\u4e0d\u7528\u81ea\u5df1\u8d39\u5fc3\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff0c\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u4e86\u3002","title":"C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#_2","text":"\u5728\u8fdb\u4e00\u6b65\u6df1\u5165\u4e4b\u524d\uff0c\u6211\u4eec\u5fc5\u987b\u660e\u786e\u4ee5\u4e0b\u672f\u8bed\uff1a\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u3001\u52a8\u6001\u5b58\u50a8\u5468\u671f\u3001\u9759\u6001\u5b58\u50a8\u5468\u671f\u3002 \u53d8\u91cf\u5b9a\u4e49\u5728\u4e0d\u540c\u7684\u4f4d\u7f6e\uff0c\u5176\u751f\u547d\u5468\u671f\uff08\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\uff09\u4f1a\u6709\u6240\u4e0d\u540c\u3002 \u6bd4\u5982\u4e00\u4e2a\u53d8\u91cf\u5b9a\u4e49\u5728\u51fd\u6570\u4f53\u5185\u3001\u7c7b\u4f53\u5185\u3001\u901a\u8fc7 new \u521b\u5efa\uff0c\u4e4b\u7c7b\u7684\u3002 \u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u76f4\u63a5\u5b9a\u4e49\u5728 \u51fd\u6570\u4f53 \u5185\u3002\u4fd7\u79f0\u201c\u6808\u4e0a\u201d\u6216\u201c\u5c40\u90e8\u53d8\u91cf\u201d void func() { Class a; // a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u5b9a\u4e49\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u6240\u5728\u7684 {} \u4ee3\u7801\u5757\u6267\u884c\u5230 } \u5904\u65f6\u8c03\u7528\u3002 \u52a8\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u901a\u8fc7 new \u6765\u521b\u5efa\u3002\u4fd7\u79f0\u201c\u5806\u4e0a\u201d\u6216\u201c\u5806\u5bf9\u8c61\u201d void func() { Class *p = new Class; // *p \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f delete p; // \u91ca\u653e\u52a8\u6001\u5206\u914d\u7684\u5185\u5b58 } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u901a\u8fc7 new \u521b\u5efa\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 delete \u88ab\u8c03\u7528\u65f6\u88ab\u8c03\u7528\u3002 \u7279\u522b\u6ce8\u610f\uff0c p \u4f9d\u7136\u662f\u201c\u6808\u4e0a\u53d8\u91cf\u201d\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u201c\u5806\u4e0a\u53d8\u91cf\u201d\uff01 \u7528\u5f8b\u5e08\u8bed\u518d\u8bf4\u4e00\u904d\uff1a p \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f\uff01\uff08\u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\uff09 \u6307\u9488\u672c\u8eab\uff0c\u548c\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\uff0c\u662f\u4e24\u4e2a\u4e1c\u897f\uff0c\u4e0d\u8981\u6df7\u6dc6\u3002 p \u672c\u8eab\u4f1a\u968f\u7740 func \u7684 } \u800c\u6790\u6784\uff0c\u4f46\u662f *p \u7684\u7c7b\u578b\u662f Class * \uff0c\u662f\u4e00\u4e2a C \u8bed\u8a00\u539f\u59cb\u6307\u9488\uff0c\u539f\u59cb\u6307\u9488\u5c5e\u4e8e C \u8bed\u8a00\u539f\u59cb\u7c7b\u578b\uff0c\u6ca1\u6709\u6790\u6784\u51fd\u6570\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u62b5\u8fbe } \u65f6\uff0c p \u540d\u4e49\u4e0a\u4f1a\u6790\u6784\uff0c\u4f46\u662f\u4ed6\u6ca1\u6709\u6790\u6784\u51fd\u6570\uff0c\u5e76\u4e0d\u4f1a\u4ea7\u751f\u4efb\u4f55\u4f5c\u7528\u3002\u8fd9\u4e00\u5207\u548c p \u6307\u5411\u7684\u5bf9\u8c61 *p \u6ca1\u6709\u4efb\u4f55\u5173\u7cfb\uff0c\u4f60\u9700\u8981\u624b\u52a8 delete \u624d\u4f1a\u8c03\u7528\u5230 *p \u7684\u6790\u6784\u51fd\u6570\uff0c\u5e76\u91ca\u653e\u5206\u914d\u7684\u5185\u5b58\u3002 new \u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u5185\u5b58\u5206\u914d + \u5bf9\u8c61\u6784\u9020 delete \u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u5bf9\u8c61\u6790\u6784 + \u5185\u5b58\u91ca\u653e \u667a\u80fd\u6307\u9488\u7684\u4f18\u52bf\u5728\u4e8e\uff0c\u667a\u80fd\u6307\u9488\u662f\u4e2a C++ \u7c7b\uff0c\u5177\u6709\u5b9a\u5236\u7684\u6790\u6784\u51fd\u6570\u3002\u5f53 } \u62b5\u8fbe\uff0c \u667a\u80fd\u6307\u9488\u672c\u8eab \u7531\u4e8e\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\u6790\u6784\u65f6\uff0c\u5176\u4f1a delete p \uff0c\u5229\u7528\u52a8\u6001\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\uff0c\u89e6\u53d1 \u667a\u80fd\u6307\u9488\u6307\u5411\u5bf9\u8c61 \u7684\u6790\u6784\u51fd\u6570\uff0c\u4e5f\u5c31\u662f\u4ece\u800c\u8c03\u7528 *p \u7684\u6790\u6784\u51fd\u6570\u3002 \u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u53c8\u8981\u5177\u4f53\u5206\u4e09\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u6216\u201c\u9759\u6001\u53d8\u91cf\u201d (1) \u5b9a\u4e49\u5728 \u540d\u5b57\u7a7a\u95f4 \u5185\uff0c\u4e0d\u8bba\u662f\u4e0d\u662f static \u6216 inline\uff08\u5728\u540d\u5b57\u7a7a\u95f4\u4e2d\uff0cstatic \u548c inline \u5f71\u54cd\u7684\u53ea\u662f\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff0c\u800c\u4e0d\u662f\u5b58\u50a8\u5468\u671f\uff09 namespace hello { Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u542f\u52a8\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u524d\uff09\uff1b\u5bf9 DLL \u6765\u8bf4\u5219\u662f DLL \u9996\u6b21\u52a0\u8f7d\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u9000\u51fa\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u540e\uff09\u3002 (2) \u6ce8\u610f\uff0c \u5168\u5c40\u540d\u5b57\u7a7a\u95f4 \u662f\u4e00\u4e2a\u7279\u6b8a\u7684 \u540d\u5b57\u7a7a\u95f4 \uff0c\u5916\u9762\u6ca1\u6709\u5305\u88f9\u4efb\u4f55 namespace \u65f6\u5c31\u5c5e\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u3002\u6240\u4ee5\u4e0b\u9762\u8fd9\u79cd\u4e5f\u5c5e\u4e8e\u201c\u5728 (\u5168\u5c40) \u540d\u5b57\u7a7a\u95f4\u5185\u201d\uff1a Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f (3) \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u9759\u6001\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u5c31\u662f\u901a\u8fc7 static \u4fee\u9970\u8fc7\u7684\u6210\u5458\u53d8\u91cf\uff08\u5728\u7c7b\u5185\uff0cstatic \u5c31\u5f71\u54cd\u5b58\u50a8\u5468\u671f\u4e86\uff0cinline \u7ee7\u7eed\u53ea\u5f71\u54cd\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff09 struct Other { static Class s; }; Class Other::s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f struct Other { inline static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f }; struct Other { Class a; // a \u4e0d\u662f\u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u800c\u662f\u8ddf\u968f\u5176\u6240\u5c5e\u7684 Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u6210\u5458\u53d8\u91cf\uff08\u6ca1\u6709 static \u7684\uff09\uff0c\u8ddf\u968f\u6240\u5c5e\u7c7b\u7684\u5b58\u50a8\u5468\u671f struct Other { Class a; // a \u8ddf\u968f Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; Other o; // o.a \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f int main() { Other o; // o.a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f Other *p; // p->a \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6784\u9020\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6790\u6784\u65f6\u8c03\u7528\u3002","title":"\u4e09\u5927\u5b58\u50a8\u5468\u671f"},{"location":"cpp_lifetime/#_3","text":"\u81ea\u52a8\u5b58\u50a8\u5468\u671f - \u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u81ea\u52a8\u6790\u6784 \u52a8\u6001\u5b58\u50a8\u5468\u671f - \u901a\u8fc7 new \u521b\u5efa\u7684\uff0cdelete \u65f6\u6790\u6784 \u9759\u6001\u5b58\u50a8\u5468\u671f - \u5168\u5c40\u53d8\u91cf\uff0c\u7a0b\u5e8f\u7ed3\u675f\u65f6\u6790\u6784","title":"\u603b\u7ed3"},{"location":"cpp_lifetime/#_4","text":"\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u539f\u56e0\u5f88\u590d\u6742\uff0c\u6574\u4e2a\u6545\u4e8b\u8981\u4ece boost \u5f53\u5e74\u5982\u4f55\u8bbe\u8ba1\u51fa\u53f3\u503c\u5f15\u7528\u5230\u56fe\u7075\u7684\u505c\u673a\u95ee\u9898\u8bb2\u8d77\uff0c\u8bb2\u4e86\u4f60\u4e5f\u8bb0\u4e0d\u4f4f\uff0c\u53ea\u9700\u8981\u8bb0\u4f4f\u7ed3\u8bba\uff1a \u5982\u679c\u4f60\u8981\u5b9a\u4e49\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01","title":"\u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751"},{"location":"cpp_lifetime/#_5","text":"-Wnon-virtual-dtor -Wdelete-non-virtual-dtor TODO: \u4ecb\u7ecd","title":"\u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684"},{"location":"cpp_lifetime/#_6","text":"TODO int main() { std::string const &s = std::string(\"hello\"); std::cout << s; // OK } std::string const &identity(std::string const &s) { return s; } int main() { std::string const &s = identity(std::string(\"hello\")); std::cout << s; // BOOM! }","title":"\u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c"},{"location":"cpp_memory/","text":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5) void modify(int *pa) { int *pb = pa + 1; *pb = 9; } int func() { int a = 4; int b = 5; modify(&a); return b; // 5 \u8fd8\u662f 9\uff1f }","title":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5)"},{"location":"cpp_memory/#c","text":"void modify(int *pa) { int *pb = pa + 1; *pb = 9; } int func() { int a = 4; int b = 5; modify(&a); return b; // 5 \u8fd8\u662f 9\uff1f }","title":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5)"},{"location":"cpp_tricks/","text":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u522b\u518d [] \u5566\uff01 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u7ee7\u627f\u6784\u9020\u51fd\u6570 \u63d0\u524d\u8fd4\u56de \u7acb\u5373\u8c03\u7528\u7684 Lambda Lambda \u590d\u7528\u4ee3\u7801 \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u522b\u518d make_pair \u5566\uff01 insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 \u5b57\u7b26\u4e32\u5207\u7247 cout \u4e0d\u9700\u8981 endl \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f cerr \u4e0e cout \u7684\u6289\u62e9 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 if-auto \u4e0e while-auto bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f map + any \u5916\u6302\u5c5e\u6027 \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf int a = 42; int b = 58; \u73b0\u5728\u4f60\u60f3\u4ea4\u6362\u8fd9\u4e24\u4e2a\u53d8\u91cf\u3002 int tmp = a; a = b; b = tmp; \u4f46\u662f\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u65b9\u6cd5\uff1a std::swap(a, b); \u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4ea4\u6362\u4efb\u610f\u4e24\u4e2a\u540c\u7c7b\u578b\u7684\u503c\uff0c\u5305\u62ec\u7ed3\u6784\u4f53\u3001\u6570\u7ec4\u3001\u5bb9\u5668\u7b49\u3002 \u53ea\u9700\u8981 #include \u5c31\u53ef\u4ee5\u4f7f\u7528\uff01 \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5c0f\u5f6d\u8001\u5e08\uff1a\u4e0d\u8981\u51fa\u73b0 new \u548c delete\uff0c\u4e0d\u5b89\u5168\u3002 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; } \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u4f17\u6240\u5468\u77e5\uff0cC\u8bed\u8a00\u4e2d int \u76f8\u9664 / \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u4e5f\u662f int \uff0c\u5982\u679c\u9664\u6cd5\u4ea7\u751f\u4e86\u4f59\u6570\uff0c\u90a3\u4e48\u53ea\u4f1a\u4fdd\u7559\u6574\u6570\u90e8\u5206\u3002 \u4f8b\u5982 14 / 5 \uff0c\u672c\u6765\u5e94\u8be5\u5f97\u5230 2.8\u3002\u4f46\u662f\u56e0\u4e3a C \u8bed\u8a00\u7684\u9664\u6cd5\u8fd4\u56de int \uff0c\u7ed3\u679c\u4f1a\u81ea\u52a8\u5411\u4e0b\u53d6\u6574\uff0c\u5bfc\u81f4\u5f97\u5230 2\u3002 int a = 14, b = 5; int c = a / b; // c = 14 / 5 = 2 \u7b49\u4ef7\u4e8e int c = floor((float)a / b); // c = floor(2.8) = 2 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5730\u677f\u9664 (floor div) \u3002 C \u8bed\u8a00\u9ed8\u8ba4\u7684\u5c31\u662f\u5730\u677f\u9664\u3002 \u5982\u679c\u6211\u60f3\u8981\u7684\u662f\u5411\u4e0a\u53d6\u6574\uff0c\u8be5\u600e\u4e48\u5199\uff1f \u6700\u539f\u59cb\u7684\u5199\u6cd5\u662f\u5148\u8f6c\u6210\u6d6e\u70b9\u6570\u6765\u9664\uff0c\u7136\u540eceil\u51fd\u6570\u5411\u4e0a\u53d6\u6574\uff1a int c = ceil((float)a / b); \u4f46\u662f\u6d6e\u70b9\u6570\u4e0d\u4ec5\u4f4e\u6548\uff0c\u8fd8\u6709\u7cdf\u7cd5\u7684\u6d6e\u70b9\u6570\u7cbe\u5ea6\u8bef\u5dee\uff01\u5bf9\u4e8e\u5f88\u5927\u7684\u6574\u6570\uff08\u5927\u4e8e 2^{23} 2^{23} \uff09\u4f1a\u4ea7\u751f\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u66f4\u5408\u7406\u7684\u5199\u6cd5\u662f\u5148\u628a a \u52a0\u4e0a b - 1 \uff0c\u7136\u540e\u518d\u4e0b\u53d6\u6574\u5730\u9664\u4ee5 b \uff1a int c = (a + b - 1) / b; \u8fd9\u6837\u5c31\u80fd\u4ea7\u751f\u4e00\u4e2a\u5411\u4e0a\u53d6\u6574\u7684\u9664\u6cd5\u4e86\u3002 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5929\u82b1\u677f\u9664 (ceil div) \u3002 \u8bd5\u8bd5\u770b\uff1a14 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2.8\uff1b\u5982\u679c\u7528\u5730\u677f\u9664\uff0c\u4f1a\u5f97\u5230 2\uff1b\u5982\u679c\u7528\u5929\u82b1\u677f\u9664\uff0c\u4f1a\u5f97\u5230 3\u3002 14 / 5 = 2 (14 + 5 - 1) / 5 = (14 + 4) / 5 = 18 / 5 = 3 \u8bd5\u8bd5\u770b\uff1a10 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2\uff1b\u90a3\u4e48\u65e0\u8bba\u662f\u5730\u677f\u9664\u8fd8\u662f\u5929\u82b1\u677f\u9664\uff0c\u90fd\u5e94\u8be5\u5f97\u5230 2\u3002 10 / 5 = 2 (10 + 5 - 1) / 5 = (10 + 4) / 5 = 14 / 5 = 2 \u8fd9\u5c31\u662f C \u8bed\u8a00\u4e2d\u5b9e\u73b0\u5929\u82b1\u677f\u9664\u7684\u4e1a\u754c\u516c\u8ba4\u65b9\u5f0f\u3002 \u522b\u518d [] \u5566\uff01 \u4f60\u77e5\u9053\u5417\uff1f\u5728 map \u4e2d\u4f7f\u7528 [] \u67e5\u627e\u5143\u7d20\uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\u3002\u8fd9\u4e2a\u7279\u6027\u6709\u65f6\u5f88\u65b9\u4fbf\uff0c\u4f46\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u5199\u9519\u4e86\uff0c\u5c31\u4f1a\u5728 map \u4e2d\u521b\u5efa\u4e00\u4e2a\u591a\u4f59\u7684\u9ed8\u8ba4\u5143\u7d20\u3002 map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; cout << table[\"\u4faf\u6377\u8001\u5e08\"]; table \u4e2d\u660e\u660e\u6ca1\u6709 \u201c\u4faf\u6377\u8001\u5e08\u201d \u8fd9\u4e2a\u5143\u7d20\uff0c\u4f46\u7531\u4e8e [] \u7684\u7279\u6027\uff0c\u4ed6\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u4e00\u4e2a 0\uff0c\u4e0d\u4f1a\u7206\u4efb\u4f55\u9519\u8bef\uff01 \u6539\u7528\u66f4\u5b89\u5168\u7684 at() \u51fd\u6570\uff0c\u5f53\u67e5\u8be2\u7684\u5143\u7d20\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u4f60\u8c03\u8bd5\uff1a map table; table.at(\"\u5c0f\u5f6d\u8001\u5e08\") = 24; cout << table.at(\"\u4faf\u6377\u8001\u5e08\"); // \u629b\u51fa\u5f02\u5e38 [] \u771f\u6b63\u7684\u7528\u9014\u662f\u201c\u5199\u5165\u65b0\u5143\u7d20\u201d\u65f6\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u4ed6\u53ef\u4ee5\u81ea\u52a8\u5e2e\u4f60\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\uff0c\u4f9b\u4f60\u4ee5\u5f15\u7528\u7684\u65b9\u5f0f\u8d4b\u503c\u8fdb\u53bb\u3002 \u68c0\u6d4b\u5143\u7d20\u662f\u5426\u5b58\u5728\u53ef\u4ee5\u7528 count \uff1a if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } \u5373\u4f7f\u4f60\u60f3\u8981\u9ed8\u8ba4\u503c 0 \u8fd9\u4e00\u7279\u6027\uff0c count + at \u4e5f\u6bd4 [] \u66f4\u597d\uff0c\u56e0\u4e3a [] \u7684\u9ed8\u8ba4\u503c\u662f\u4f1a\u5bf9 table \u505a\u7834\u574f\u6027\u4fee\u6539\u7684\uff0c\u8fd9\u5bfc\u81f4 [] \u9700\u8981 map \u7684\u58f0\u660e\u4e0d\u4e3a const \uff1a map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u5982\u679c\"\u5c0f\u5f6d\u8001\u5e08\"\u8fd9\u4e00\u952e\u4e0d\u5b58\u5728\uff0c\u4f1a\u521b\u5efa\"\u5c0f\u5f6d\u8001\u5e08\"\u5e76\u8bbe\u4e3a\u9ed8\u8ba4\u503c 0 const map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u7f16\u8bd1\u5931\u8d25\uff01[] \u9700\u8981\u975e const \u7684 map \u5bf9\u8c61\uff0c\u56e0\u4e3a\u4ed6\u4f1a\u7834\u574f\u6027\u4fee\u6539 \u66f4\u591a map \u77e5\u8bc6\u8bf7\u770b\u6211\u4eec\u7684 map \u4e13\u9898\u8bfe \u3002 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 // C++98 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} }; Student stu(\"\u4faf\u6377\u8001\u5e08\", 42, 123); C++98 \u9700\u8981\u624b\u52a8\u4e66\u5199\u6784\u9020\u51fd\u6570\uff0c\u975e\u5e38\u9ebb\u70e6\uff01\u800c\u4e14\u51e0\u4e4e\u90fd\u662f\u91cd\u590d\u7684\u3002 C++11 \u4e2d\uff0c\u5e73\u51e1\u7684\u7ed3\u6784\u4f53\u7c7b\u578b\u4e0d\u9700\u8981\u518d\u5199\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u7528 {} \u5c31\u80fd\u5bf9\u6210\u5458\u4f9d\u6b21\u521d\u59cb\u5316\uff1a // C++11 struct Student { string name; int age; int id; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123}; \u8fd9\u88ab\u79f0\u4e3a \u805a\u5408\u521d\u59cb\u5316 (aggregate initialize)\u3002\u53ea\u8981\u4f60\u7684\u7c7b\u6ca1\u6709\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709 private \u6210\u5458\uff0c\u90fd\u53ef\u4ee5\u7528 {} \u805a\u5408\u521d\u59cb\u5316\u3002 \u597d\u6d88\u606f\uff1aC++20 \u4e2d\uff0c\u805a\u5408\u521d\u59cb\u5316\u4e5f\u652f\u6301 () \u4e86\uff0c\u7528\u8d77\u6765\u5c31\u548c\u4f20\u7edf\u7684 C++98 \u6784\u9020\u51fd\u6570\u4e00\u6837\uff01 // C++20 Student stu(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123); \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6307\u5b9a\u9ed8\u8ba4\u503c\uff1a // C++11 struct Student { string name; int age; int id = 9999; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; C++20 \u5f00\u59cb\uff0c {} \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6839\u636e\u6bcf\u4e2a\u6210\u5458\u7684\u540d\u5b57\u6765\u6307\u5b9a\u503c\uff1a Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; \u597d\u5904\u662f\uff0c\u5373\u4f7f\u4e0d\u614e\u5199\u9519\u53c2\u6570\u987a\u5e8f\u4e5f\u4e0d\u7528\u62c5\u5fc3\u3002 Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .id = 9999, .age = 24}; \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u53ea\u6709\u5f53\u4f60\u9700\u8981\u6709\u201c\u81ea\u5b9a\u4e49\u94a9\u5b50\u903b\u8f91\u201d\u7684\u65f6\u5019\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\u3002 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} Student(Student const &other) : name(other.name), age(other.age), id(other.id) { std::cout << \"\u62f7\u8d1d\u6784\u9020\\n\"; } Student &operator=(Student const &other) { name = other.name; age = other.age; id = other.id; std::cout << \"\u62f7\u8d1d\u8d4b\u503c\\n\"; return *this; } }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c \u5982\u679c\u4f60\u4e0d\u9700\u8981\u8fd9\u4e2a std::cout \uff0c\u53ea\u662f\u5e73\u51e1\u5730\u62f7\u8d1d\u6240\u6709\u6210\u5458\uff0c\u5b8c\u5168\u53ef\u4ee5\u4e0d\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\u3001\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff1a struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student(Student const &other) // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student &operator=(Student const &other) }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c assert(stu2.name == \"\u4faf\u6377\u8001\u5e08\"); \u603b\u4e4b\uff0c\u5f88\u591a C++ \u6559\u6750\u628a\u62f7\u8d1d/\u79fb\u52a8\u6784\u9020\u51fd\u6570\u8fc7\u4e8e\u5938\u5927\uff0c\u641e\u5f97\u597d\u50cf\u6bcf\u4e2a\u7c7b\u90fd\u9700\u8981\u81ea\u5df1\u5b9a\u4e49\u4e00\u6837\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u6709\u5728\u201c\u81ea\u5df1\u5b9e\u73b0\u5bb9\u5668\u201d\u7684\u60c5\u51b5\u4e0b\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3002\u53ef\u662f\u8c01\u4f1a\u6574\u5929\u624b\u6413\u5bb9\u5668\uff1f \u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u7c7b\u91cc\u9762\u5b58 vector\u3001string \u7b49\u5c01\u88c5\u597d\u7684\u5bb9\u5668\uff0c\u7f16\u8bd1\u5668\u9ed8\u8ba4\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4f1a\u81ea\u52a8\u8c03\u7528\u4ed6\u4eec\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u7528\u6237\u53ea\u9700\u4e13\u6ce8\u4e8e\u4e1a\u52a1\u903b\u8f91\u5373\u53ef\uff0c\u4e0d\u9700\u8981\u64cd\u5fc3\u5e95\u5c42\u7ec6\u8282\u3002 \u5bf9\u4e8e\u6301\u6709\u8d44\u6e90\u7684 RAII \u7c7b\uff0c\u6211\u4eec\u90fd\u4f1a\u76f4\u63a5\u5220\u9664\u5176\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff1a struct RAIIHandle { int handle; RAIIHandle() { handle = CreateObject(); } RAIIHandle(RAIIHandle const &) = delete; RAIIHandle &operator=(RAIIHandle const &) = delete; RAIIHandle() { DeleteObject(handle); } }; \u7ee7\u627f\u6784\u9020\u51fd\u6570 C++ \u7279\u8272\uff1a\u5b50\u7c7b\u4e0d\u4f1a\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff01\uff08\u9664\u975e\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\u662f\u6ca1\u6709\u53c2\u6570\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff09 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { void child_func() { ... } }; Child child(23, \"peng\"); // \u9519\u8bef\uff01Child \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff01 C++11 \u4e2d\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u9762\u5199 using \u7236\u7c7b::\u7236\u7c7b \uff0c\u5c31\u80fd\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u6240\u6709\u7684\u6784\u9020\u51fd\u6570\u4e86\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { using Parent::Parent; // \u52a0\u4e0a\u8fd9\u4e00\u884c\uff01 void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u81ea\u52a8\u8c03\u7528\u5230\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570 Parent(int, const char *) \u5728 C++98 \u4e2d\uff0c\u6ca1\u6709 using \u7684\u8fd9\u4e2a\u8bed\u6cd5\uff0c\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a\u6784\u9020\u51fd\u6570\uff0c\u7136\u540e\u4f7f\u7528\u201c\u59d4\u4efb\u6784\u9020\u201d\u7684\u8bed\u6cd5\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9\u7236\u7c7b\uff0c\u975e\u5e38\u7e41\u7410\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { Child(int age, const char *name) : Parent(age, name) { ... } void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6784\u9020\u51fd\u6570\u540e\u8f6c\u53d1\u5230\u7236\u7c7b \u63d0\u524d\u8fd4\u56de void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); } else { puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); } else { puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } } } \u8fd9\u4e2a\u51fd\u6570\u6709\u5f88\u591a\u5c42\u5d4c\u5957\uff0c\u5f88\u4e0d\u7f8e\u89c2\u3002\u7528 \u63d0\u524d\u8fd4\u56de \u7684\u5199\u6cd5\u6765\u4f18\u5316\uff1a void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); return; } puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); return; } puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } \u7acb\u5373\u8c03\u7528\u7684 Lambda \u6709\u65f6\uff0c\u9700\u8981\u5728\u4e00\u4e2a\u5217\u8868\u91cc\u5faa\u73af\u67e5\u627e\u67d0\u6837\u4e1c\u897f\uff0c\u4e5f\u53ef\u4ee5\u7528\u63d0\u524d\u8fd4\u56de\u7684\u5199\u6cd5\u4f18\u5316\uff1a bool find(const vector &v, int target) { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } \u53ef\u4ee5\u5305\u88f9\u4e00\u4e2a\u7acb\u5373\u8c03\u7528\u7684 Lambda \u5757 [&] { ... } () \uff0c\u9650\u5236\u63d0\u524d\u8fd4\u56de\u7684\u8303\u56f4\uff1a void find(const vector &v, int target) { bool found = [&] { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } (); if (found) { ... } } Lambda \u590d\u7528\u4ee3\u7801 vector spilt(string str) { vector list; string last; for (char c: str) { if (c == ' ') { list.push_back(last); last.clear(); } else { last.push_back(c); } } list.push_back(last); return list; } \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u7528 Lambda \u590d\u7528\uff1a vector spilt(string str) { vector list; string last; auto push = [&] { list.push_back(last); last.clear(); }; for (char c: str) { if (c == ' ') { push(); } else { last.push_back(c); } } push(); return list; } \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u5728\u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7ed3\u6784\u4f53\u7684 static \u6210\u5458\u65f6\uff1a struct Class { static int member; }; \u4f1a\u62a5\u9519 undefined reference to 'Class::member' \u3002\u8fd9\u662f\u8bf4\u7684\u4f60\u9700\u8981\u627e\u4e2a .cpp \u6587\u4ef6\uff0c\u5199\u51fa int Class::member \u624d\u80fd\u6d88\u9664\u8be5\u9519\u8bef\u3002 C++17 \u4e2d\uff0c\u53ea\u9700\u52a0\u4e2a inline \u5c31\u80fd\u89e3\u51b3\uff01 struct Class { inline static int member; }; \u522b\u518d make_pair \u5566\uff01 map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u4e3a\u907f\u514d\u5199\u51fa\u7c7b\u578b\u540d\u7684\u9ebb\u70e6\uff0c\u5f88\u591a\u8001\u5e08\u90fd\u4f1a\u8ba9\u4f60\u5199 make_pair\uff1a map table; table.insert(make_pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u7136\u800c C++11 \u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u5199\u6cd5\uff0c\u90a3\u5c31\u662f\u901a\u8fc7 {} \u9690\u5f0f\u6784\u9020\uff0c\u4e0d\u7528\u5199\u51fa\u7c7b\u578b\u540d\u6216 make_pair\uff1a map table; table.insert({\"\u4faf\u6377\u8001\u5e08\", 42}); \u5373\u4f7f\u4f60\u51fa\u4e8e\u67d0\u79cd\u201c\u6296m\u201d\u60c5\u8282\uff0c\u8fd8\u60f3\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u4e5f\u53ef\u4ee5\u7528 C++17 \u7684 CTAD \u8bed\u6cd5\uff0c\u514d\u53bb\u6a21\u677f\u53c2\u6570\uff1a map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); // tuple \u4e5f\u652f\u6301 CTAD\uff1a auto t = tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); // \u7b49\u4ef7\u4e8e\uff1a auto t = make_tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); println(\"{}\", typeid(t).name()); // tuple insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 map table; table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 24}); table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 42}); \u8fd9\u65f6\uff0c table[\"\u5c0f\u5f6d\u8001\u5e08\"] \u4ecd\u7136\u4f1a\u662f 24\uff0c\u800c\u4e0d\u662f 42\u3002\u56e0\u4e3a insert \u4e0d\u4f1a\u66ff\u6362 map \u91cc\u5df2\u7ecf\u5b58\u5728\u7684\u503c\u3002 \u5982\u679c\u5e0c\u671b\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u65f6\uff0c\u66ff\u6362\u73b0\u6709\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 [] \u8fd0\u7b97\u7b26\uff1a map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 42; C++17 \u63d0\u4f9b\u4e86\u6bd4 [] \u8fd0\u7b97\u7b26\u66f4\u9002\u5408\u8986\u76d6\u6027\u63d2\u5165\u7684 insert_or_assign \u51fd\u6570\uff1a map table; table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 24); table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 42); \u597d\u5904\uff1a insert_or_assign \u4e0d\u9700\u8981\u503c\u7c7b\u578b\u652f\u6301\u9ed8\u8ba4\u6784\u9020\uff0c\u53ef\u4ee5\u907f\u514d\u4e00\u6b21\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 + \u4e00\u6b21\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u7684\u5f00\u9500\u3002 \u5efa\u8bae\u628a insert_or_assign \u6539\u540d\u6210 set \uff0c at \u6539\u540d\u6210 get \uff1b\u53ea\u662f\u7531\u4e8e\u5386\u53f2\u539f\u56e0\u540d\u5b57\u8ff7\u60d1\u4e86\u3002 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f map table; for (auto it = table.begin(); it != table.end(); ++it) { if (it->second < 0) { table.erase(it); } } \u4f1a\u53d1\u751f\u5d29\u6e83\uff01\u770b\u6765 map \u4f3c\u4e4e\u4e0d\u5141\u8bb8\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u5220\u9664\uff1f\u4e0d\uff0c\u53ea\u662f\u4f60\u7684\u5199\u6cd5\u6709\u9519\u8bef\uff1a map table; for (auto it = table.begin(); it != table.end(); ) { if (it->second < 0) { it = table.erase(it); } else { ++it; } } C++20 \u5f15\u5165\u4e86\u66f4\u597d\u7684 erase_if \u5168\u5c40\u51fd\u6570\uff0c\u4e0d\u7528\u624b\u5199\u4e0a\u9762\u8fd9\u4e48\u9ebb\u70e6\u7684\u4ee3\u7801\uff1a map table; erase_if(table, [](pair it) { return it.second < 0; }); \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 vector v = {48, 23, 76, 11, 88, 63, 45, 28, 59}; \u4f17\u6240\u5468\u77e5\uff0c\u5728 vector \u4e2d\u5220\u9664\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u5341\u5206\u4f4e\u6548\u3002\u590d\u6742\u5ea6\uff1a O(n) O(n) // \u76f4\u63a5\u5220\u9664 v[3] v.erase(v.begin() + 3); \u5982\u679c\u4e0d\u5728\u4e4e\u5143\u7d20\u7684\u987a\u5e8f\uff0c\u53ef\u4ee5\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20 swap\uff0c\u7136\u540e pop_back\u3002\u590d\u6742\u5ea6\uff1a O(1) O(1) // \u628a v[3] \u548c v[v.size() - 1] \u4f4d\u7f6e\u5bf9\u8c03 swap(v[3], v[v.size() - 1]); // \u7136\u540e\u5220\u9664 v[v.size() - 1] v.pop_back(); \u8fd9\u6837\u5c31\u4e0d\u7528\u79fb\u52a8\u4e00\u5927\u5806\u5143\u7d20\u4e86\u3002\u8fd9\u88ab\u79f0\u4e3a back-swap-erase\u3002 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 vector \u4e2d\u53ea\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u9700\u8981 O(n) O(n) \u3002\u5982\u679c\u4e00\u8fb9\u904d\u5386\uff0c\u4e00\u8fb9\u5220\u9664\u591a\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u590d\u6742\u5ea6 O(n^2) O(n^2) \u4e86\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 remove \u548c remove_if \u51fd\u6570\uff0c\u5176\u5185\u90e8\u91c7\u7528\u7c7b\u4f3c back-swap-erase \u7684\u65b9\u6cd5\uff0c\u5148\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u79fb\u52a8\u5230\u672b\u5c3e\u3002\u7136\u540e\u4e00\u6b21\u6027 erase \u6389\u672b\u5c3e\u540c\u6837\u6570\u91cf\u7684\u5143\u7d20\u3002 \u4e14\u4ed6\u4eec\u90fd\u80fd\u4fdd\u6301\u987a\u5e8f\u4e0d\u53d8\u3002 \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove(v.begin(), v.end(), 42), v.end()); \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove_if(v.begin(), v.end(), [](int x) { return x > 0; }), v.end()); \u73b0\u5728 C++20 \u4e5f\u5f15\u5165\u4e86\u5168\u5c40\u51fd\u6570 erase \u548c erase_if\uff0c\u4f7f\u7528\u8d77\u6765\u66f4\u52a0\u76f4\u89c2\uff1a vector v; erase(v, 42); // \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20 erase_if(v, [](int x) { return x > 0; // \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20 }); \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 \u5982\u679c\u4f60\u60f3\u8981\u7ef4\u62a4\u4e00\u4e2a\u6709\u5e8f\u7684\u6570\u7ec4\uff0c\u7528 lower_bound \u6216 upper_bound \u6765\u63d2\u5165\u5143\u7d20\uff0c\u4fdd\u8bc1\u63d2\u5165\u540e\u4ecd\u4fdd\u6301\u6709\u5e8f\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 3), 3); // s = { 1, 2, 3, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 5), 5); // s = { 1, 2, 3, 4, 5, 6 } \u6709\u5e8f\u6570\u7ec4\u4e2d\uff0c\u53ef\u4ee5\u5229\u7528 lower_bound \u6216 upper_bound \u5feb\u901f\u4e8c\u5206\u67e5\u627e\u5230\u60f3\u8981\u7684\u503c\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } lower_bound(s.begin(), s.end(), 3); // s.begin() + 2; lower_bound(s.begin(), s.end(), 5); // s.begin() + 3; \u6709\u5e8f vector \u5e94\u7528\u6848\u4f8b\uff1a\u5229\u7528 CDF \u79ef\u5206 + \u4e8c\u5206\u6cd5\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u4efb\u610f\u6307\u5b9a\u5206\u5e03\u7684\u968f\u673a\u6570\u3002 \u4f8b\u5982\u6570\u503c\u7b56\u5212\u8981\u6c42\u7684\u62bd\u5361\u6982\u7387\u5206\u5e03\u662f\uff1a 2% \u51fa\u91d1\u5361 10% \u51fa\u84dd\u5361 80% \u51fa\u767d\u5361 8% \u51fa\u7b54\u8fa9 \u90a3\u4e48\u4f60\u8f6c\u6362\u4e00\u4e0b\u4efb\u52a1\u3002\u53d8\u6210\u968f\u673a\u751f\u6210\u4e00\u4e2a 0 \u5230 1 \u7684\u6d6e\u70b9\u6570\uff0c\u7136\u540e\u5224\u65ad\uff1a \u5c0f\u4e8e 0.02 \u65f6\uff0c\u51fa\u91d1\u5361 \u5c0f\u4e8e 0.12 \u65f6\uff0c\u51fa\u84dd\u5361 \u5c0f\u4e8e 0.92 \u65f6\uff0c\u51fa\u767d\u5361 \u5c0f\u4e8e 1.00 \u65f6\uff0c\u51fa\u7b54\u8fa9 \u8fd9\u4e2a\u8f6c\u6362\u8fc7\u7a0b\u5c31\u662f CDF \u79ef\u5206\u3002\u5982\u679c\u4f60\u628a\u8fd9 4 \u4e2a\u6570\u6309\u7167\u987a\u5e8f\u6392\u5217\uff0c\u5c31\u662f\u4e00\u4e2a\u6709\u5e8f vector\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::partial_sum \uff08\u4e0d\u7cbe\u51c6\uff09\u6216 std::inclusive_scan \uff08\u66f4\u7cbe\u51c6\uff0cC++17 \u5f15\u5165\uff09\u90fd\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684 CDF \u79bb\u6563\u79ef\u5206\u3002 vector probs = {0.02, 0.1, 0.8, 0.08}; vector cdf; // \u8ba1\u7b97 probs \u7684 CDF \u79ef\u5206\uff0c\u5b58\u5165 cdf \u6570\u7ec4 std::inclusive_scan(probs.begin(), probs.end(), std::back_inserter(cdf)); // cdf = {0.02, 0.12, 0.92, 1.00} \u662f\u4e00\u4e2a\u6709\u5e8f vector\uff0c\u53ef\u4ee5\u8fd0\u7528\u4e8c\u5206\u6cd5\u5b9a\u4f4d vector result = {\"\u91d1\u5361\", \"\u84dd\u5361\", \"\u767d\u5361\", \"\u7b54\u8fa9\"}; // \u751f\u6210 100 \u4e2a\u968f\u673a\u6570\uff1a for (int i = 0; i < 100; ++i) { double r = rand() / (RAND_MAX + 1.0); int index = lower_bound(cdf.begin(), cdf.end(), r) - cdf.begin(); cout << \"\u4f60\u62bd\u5230\u4e86\" << result[index] << endl; } \u987a\u4fbf\u4e00\u63d0\uff0cCDF \u79ef\u5206\u7684\u9006\u8fd0\u7b97\u662f\u79bb\u6563\u5fae\u5206\uff1a std::adjacent_difference \uff0c\u53ef\u4ee5\u4ece cdf \u6570\u7ec4\u590d\u539f\u51fa probs \u6570\u7ec4\u3002 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f // \u9519\u8bef\u7684\u5199\u6cd5\uff1a int r = rand() % 10; // \u8fd9\u6837\u5199\u662f\u9519\u8bef\u7684\uff01 rand() \u7684\u8fd4\u56de\u503c\u8303\u56f4\u662f [0, RAND_MAX]\uff0cRAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0b\u4e0d\u540c\uff0c\u5728 Windows \u5e73\u53f0\u7684\u662f 32767\uff0c\u5373 rand() \u53ea\u80fd\u751f\u6210 0\uff5e32767 \u4e4b\u95f4\u7684\u968f\u673a\u6570\u3002 \u5982\u679c\u60f3\u8981\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\uff1a int r = rand() % 10; \u7136\u800c\u8fd9\u79cd\u65b9\u6cd5\u6709\u4e2a\u81f4\u547d\u7684\u95ee\u9898\uff1a\u4e0d\u540c\u7684\u968f\u673a\u6570\u751f\u6210\u6982\u7387\u4e0d\u4e00\u6837\u3002 \u4f8b\u5982\u628a [0, RAND_MAX] \u5747\u5300\u5730\u5206\u6210 10 \u4efd\uff0c\u6bcf\u4efd 3276.7\u3002\u90a3\u4e48 0\uff5e6 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 10.0003%\uff0c\u800c 7\uff5e9 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 9.997%\u3002 \u8fd9\u6837\u5c31\u4e0d\u662f\u771f\u6b63\u7684\u5747\u5300\u5206\u5e03\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u786e\u6027\u3002 \u5f53\u6a21\u6570\u5927\u7684\u65f6\u5019\u4e0d\u5747\u5300\u6027\u4f1a\u53d8\u5f97\u7279\u522b\u660e\u663e\uff0c\u4f8b\u5982 rand() % 10000 \u3002 RAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0d\u540c\u7684\u7279\u6027\u4e5f\u8ba9\u8de8\u5e73\u53f0\u5f00\u53d1\u8005\u5f88\u5934\u5927\u3002 rand \u4f7f\u7528\u5168\u5c40\u53d8\u91cf\u5b58\u50a8\u79cd\u5b50\uff0c\u5bf9\u591a\u7ebf\u7a0b\u4e0d\u53cb\u597d\u3002 \u65e0\u6cd5\u72ec\u7acb\u7684\u4e3a\u591a\u4e2a\u751f\u6210\u5e8f\u5217\u8bbe\u5b9a\u72ec\u7acb\u7684\u79cd\u5b50\uff0c\u4e00\u4e9b\u6e38\u620f\u53ef\u80fd\u9700\u8981\u7528\u5230\u591a\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u5404\u81ea\u6709\u72ec\u7acb\u7684\u79cd\u5b50\u3002 \u53ea\u80fd\u751f\u6210\u5747\u5300\u5206\u5e03\u7684\u6574\u6570\uff0c\u4e0d\u80fd\u751f\u6210\u5e42\u7387\u5206\u5e03\u3001\u6b63\u592a\u5206\u5e03\u7b49\uff0c\u751f\u6210\u6d6e\u70b9\u6570\u4e5f\u6bd4\u8f83\u9ebb\u70e6\u3002 \u4f7f\u7528 srand(time(NULL)) \u65e0\u6cd5\u5b89\u5168\u5730\u751f\u6210\u968f\u673a\u6570\u7684\u521d\u59cb\u79cd\u5b50\uff0c\u5bb9\u6613\u88ab\u9ed1\u5ba2\u9884\u6d4b\u5e76\u653b\u51fb\u3002 rand \u7684\u7b97\u6cd5\u5b9e\u73b0\u6ca1\u6709\u5b98\u65b9\u89c4\u5b9a\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u5404\u6709\u4e0d\u540c\uff0c\u4ea7\u751f\u7684\u968f\u673a\u6570\u5e8f\u5217\u53ef\u80fd\u4e0d\u540c\u3002 \u4e3a\u6b64\uff0cC++ \u63d0\u51fa\u4e86\u66f4\u52a0\u4e13\u4e1a\u7684\u968f\u673a\u6570\u751f\u6210\u5668\uff1a \u5e93\u3002 // \u4f7f\u7528 \u5e93\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff1a #include #include int main() { uint64_t seed = std::random_device()(); std::mt19937 gen(seed); std::uniform_int_distribution dis(0, 9); for (int i = 0; i < 100; ++i) { int r = dis(gen); std::cout << r << \" \"; } } \u8fd9\u6837\u5c31\u53ef\u4ee5\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u4e86\u3002 std::random_device \u662f\u4e00\u4e2a\u968f\u673a\u6570\u79cd\u5b50\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u7cfb\u7edf\u7684\u968f\u673a\u8bbe\u5907\uff08\u5982\u679c\u6709\u7684\u8bdd\uff0c\u5426\u5219\u4f1a\u629b\u51fa\u5f02\u5e38\uff09\u751f\u6210\u4e00\u4e2a\u5b89\u5168\u7684\u968f\u673a\u6570\u79cd\u5b50\uff0c\u9ed1\u5ba2\u65e0\u6cd5\u9884\u6d4b\u3002 std::mt19937 \u662f\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u521d\u59cb\u79cd\u5b50\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u5e8f\u5217\u3002\u5e76\u4e14\u5fc5\u5b9a\u662f MT19937 \u8fd9\u4e2a\u9ad8\u5f3a\u5ea6\u7684\u968f\u673a\u7b97\u6cd5\uff0c\u6240\u6709\u5e73\u53f0\u90fd\u4e00\u6837\u3002 std::uniform_int_distribution \u662f\u4e00\u4e2a\u5206\u5e03\u5668\uff0c\u5b83\u53ef\u4ee5\u628a\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u6620\u5c04\u5230\u6211\u4eec\u60f3\u8981\u7684\u4e0a\u4e0b\u754c\u4e2d\u3002\u91cc\u9762\u7684\u5b9e\u73b0\u7c7b\u4f3c\u4e8e gen() % 10 \uff0c\u4f46\u901a\u8fc7\u6570\u5b66\u673a\u5236\u4fdd\u8bc1\u4e86\u7edd\u5bf9\u5747\u5300\u6027\u3002 \u7c7b\u4f3c\u7684\u8fd8\u6709 std::uniform_real_distribution \u7528\u4e8e\u751f\u6210\u6d6e\u70b9\u6570\uff0c std::normal_distribution \u7528\u4e8e\u751f\u6210\u6b63\u592a\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c std::poisson_distribution \u7528\u4e8e\u751f\u6210\u6cca\u677e\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u7b49\u7b49\u3002 \u5982\u679c\u559c\u6b22\u8001\u5f0f\u7684\u51fd\u6570\u8c03\u7528\u98ce\u683c\u63a5\u53e3\uff0c\u53ef\u4ee5\u5c01\u88c5\u4e00\u4e2a\u65b0\u7684 C++ \u91cd\u7f6e\u7248\u5b89\u5168 rand \uff1a thread_local std::mt19937 gen(std::random_device{}()); // \u6bcf\u7ebf\u7a0b\u4e00\u4e2a\uff0c\u4e92\u4e0d\u51b2\u7a81 int randint(int min, int max) { return std::uniform_int_distribution(min, max)(gen); } float randfloat(float min, float max) { return std::uniform_real_distribution(min, max)(gen); } const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u4f17\u6240\u5468\u77e5\uff0c const \u5728\u6307\u9488\u7b26\u53f7 * \u7684\u524d\u540e\uff0c\u6548\u679c\u662f\u4e0d\u540c\u7684\u3002 const int *p; int *const p; \u4f60\u80fd\u770b\u51fa\u6765\u4e0a\u9762\u8fd9\u4e2a const \u5206\u522b\u4fee\u9970\u7684\u662f\u8c01\u5417\uff1f const int *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u4e3a\u4e86\u770b\u8d77\u6765\u66f4\u52a0\u660e\u786e\uff0c\u6211\u901a\u5e38\u90fd\u4f1a\u540e\u7f6e\u6240\u6709\u7684 const \u4fee\u9970\u3002 int const *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\uff0cconst \u603b\u662f\u5728\u4fee\u9970\u4ed6\u524d\u9762\u7684\u4e1c\u897f\uff0c\u800c\u4e0d\u662f\u540e\u9762\u3002 \u4e3a\u4ec0\u4e48 int *const \u4fee\u9970\u7684\u662f int * \u4e5f\u5c31\u5f88\u5bb9\u6613\u7406\u89e3\u4e86\u3002 int const i; int const *p; int *const q; int const &r; \u4e3e\u4e2a\u4f8b\u5b50\uff1a int i, j; int *const p = &i; *p = 1; // OK\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int i, j; int const *p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // OK\uff1ap \u672c\u8eab\u53ef\u53d8\uff0c\u53ef\u4ee5\u6539\u53d8\u6307\u5411 int i, j; int const *const p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e5f\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int const * \u548c const int * \u7b49\u4ef7\uff01\u53ea\u6709 int *const \u662f\u4e0d\u540c\u7684\u3002 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u5927\u5bb6\u90fd\u77e5\u9053\uff0c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u58f0\u660e\u4e3a auto \uff0c\u8ba9\u5176\u81ea\u52a8\u63a8\u5bfc\u3002 auto square() { // int square(); return 1; } \u4f46\u4f60\u77e5\u9053\u4ece C++20 \u5f00\u59cb\uff0c\u53c2\u6570\u4e5f\u53ef\u4ee5\u58f0\u660e\u4e3a auto \u4e86\u5417\uff1f auto square(auto x) { // T square(T x); return x * x; } square(1); // square(int) square(3.14); // square(double) \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u201c\u6a21\u677f\u51fd\u6570\u201d\u7684\u4f20\u7edf\u5199\u6cd5\uff1a template T square(T x) { return x * x; } square(1); // square(int) square(3.14); // square(double) \u56e0\u4e3a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6240\u4ee5\u4e5f\u5f88\u96be\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u7684\u60c5\u51b5\u3002 auto \u53c2\u6570\u8fd8\u53ef\u4ee5\u5e26\u6709\u5f15\u7528\uff1a auto square(auto const &x) { // T square(T const &x); return x * x; } square(1); // square(int const &) square(3.14); // square(double const &) \u7b49\u4ef7\u4e8e\uff1a template T square(T const &x) { return x * x; } auto \u53c2\u6570\u6700\u597d\u7684\u914d\u5408\u83ab\u8fc7\u4e8e\u662f\u4e0e\u540c\u6837 C++20 \u5f15\u5165\u7684 concept\uff1a auto square(std::integral auto x) { // T square(T x) requires std::integral return x * x; } square(1); // square(int) square(3.14); // \u9519\u8bef\uff1adouble \u4e0d\u662f\u6574\u6570\u7c7b\u578b \u7b49\u4ef7\u4e8e\uff1a template requires std::integral T square(T x) { return x * x; } \u6216\u8005\uff1a template T square(T x) { return x * x; } \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 std::string file_get_content(std::string const &filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); std::istreambuf_iterator iit(ifs), iite; std::string content(iit, iite); return content; } void file_put_content(std::string const &filename, std::string const &content) { std::ofstream ofs(filename, std::ios::out | std::ios::binary); ofs << content; } \u8fd9\u6837\u5c31\u53ef\u4ee5\u628a\u6574\u4e2a\u6587\u4ef6\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u5f88\u65b9\u4fbf\u5730\u8fdb\u884c\u5904\u7406\u540e\u518d\u5199\u56de\u6587\u4ef6\u3002 \u63a8\u8350\u7528 std::ios::binary \u9009\u9879\u6253\u5f00\u4e8c\u8fdb\u5236\u6587\u4ef6\uff0c\u5426\u5219\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0 '\\n' \u65f6\uff0c\u4f1a\u88ab MSVC \u6807\u51c6\u5e93\u81ea\u52a8\u8f6c\u6362\u6210 '\\r\\n' \u6765\u5199\u5165\uff0c\u59a8\u788d\u6211\u4eec\u8de8\u5e73\u53f0\u3002 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 std::ifstream fin(\"test.txt\"); std::string line; while (std::getline(fin, line)) { std::cout << \"\u8bfb\u53d6\u5230\u4e00\u884c\uff1a\" << line << '\\n'; } \u5b57\u7b26\u4e32\u5207\u7247 #include #include #include std::vector split_str(std::string const &str, char ch) { std::stringstream ss(str); std::string line; std::vector res; while (std::getline(ss, line, ch)) { res.push_back(std::move(line)); } return res; } auto res = split_str(\"hello world\", ' '); // res = {\"hello\", \"world\"} cout \u4e0d\u9700\u8981 endl int a = 42; printf(\"%d\\n\", a); \u4e07\u4e00\u4f60\u5199\u9519\u4e86 % \u540e\u9762\u7684\u7c7b\u578b\uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u7559\u4e0b\u9690\u60a3\u3002 int a = 42; printf(\"%s\\n\", a); // \u7f16\u8bd1\u5668\u4e0d\u62a5\u9519\uff0c\u4f46\u662f\u8fd0\u884c\u65f6\u4f1a\u5d29\u6e83\uff01 C++ \u4e2d\u6709\u66f4\u5b89\u5168\u7684\u8f93\u51fa\u65b9\u5f0f cout \uff0c\u901a\u8fc7 C++ \u7684\u91cd\u8f7d\u673a\u5236\uff0c\u65e0\u9700\u624b\u52a8\u6307\u5b9a % \uff0c\u81ea\u52a8\u5c31\u80fd\u63a8\u5bfc\u7c7b\u578b\u3002 int a = 42; cout << a << endl; double d = 3.14; cout << d << endl; cout << \"Hello, World!\" << endl; endl \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6d41\u64cd\u4f5c\u7b26\uff0c\u4f5c\u7528\u7b49\u4ef7\u4e8e\u5148\u8f93\u51fa\u4e00\u4e2a '\\n' \u7136\u540e flush \u3002 cout << \"Hello, World!\" << '\\n'; cout.flush(); \u4f46\u5b9e\u9645\u4e0a\uff0c\u8f93\u51fa\u6d41 cout \u9ed8\u8ba4\u7684\u8bbe\u7f6e\u5c31\u662f\u201c\u884c\u5237\u65b0\u7f13\u5b58\u201d\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u68c0\u6d4b\u5230 '\\n' \u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u5237\u65b0\u4e00\u6b21\uff0c\u6839\u672c\u4e0d\u9700\u8981\u6211\u4eec\u624b\u52a8\u5237\u65b0\uff01 \u5982\u679c\u8fd8\u7528 endl \u7684\u8bdd\uff0c\u5c31\u76f8\u5f53\u4e8e\u5237\u65b0\u4e86\u4e24\u6b21\uff0c\u6d6a\u8d39\u6027\u80fd\u3002 \u53ef\u89c1\uff0cendl \u662f\u4e00\u4e2a\u88ab\u5f88\u591a\u65e0\u8111\u6559\u6750\u9519\u8bef\u5ba3\u4f20\uff0c\u5b9e\u9645\u4e0a\u6839\u672c\u591a\u6b64\u4e00\u4e3e\u7684\u4e1c\u897f\u3002 \u6211\u4eec\u53ea\u9700\u8981\u8f93\u51fa '\\n' \u5c31\u53ef\u4ee5\u4e86\uff0c\u6bcf\u6b21\u6362\u884c\u65f6 cout \u90fd\u4f1a\u81ea\u52a8\u5237\u65b0\u3002 cout << \"Hello, World!\" << '\\n'; endl \u662f\u4e00\u4e2a\u5178\u578b\u7684\u4ee5\u8bb9\u4f20\u8bb9\u9519\u8bef\u5199\u6cd5\uff0c\u53ea\u6709\u5f53\u4f60\u7684\u8f93\u51fa\u662f\u6307\u5411\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u7ba1\u9053\u65f6\uff0c\u5176\u9644\u5e26\u7684\u5237\u65b0\u529f\u80fd\u624d\u6709\u4f5c\u7528\u3002 \u5f53\u8f93\u51fa\u662f\u7ba1\u9053\u6216\u6587\u4ef6\u65f6\uff0c cout \u9700\u8981 endl \u624d\u80fd\u5237\u65b0\u3002 \u5f53\u8f93\u51fa\u662f\u666e\u901a\u63a7\u5236\u53f0\u65f6\uff0c cout \u53ea\u9700 '\\n' \u5c31\u80fd\u5237\u65b0\u4e86\uff0c\u6839\u672c\u7528\u4e0d\u7740 endl \u3002 \u800c\u4e14\uff0c\u7ba1\u9053\u6216\u6587\u4ef6\u5b9e\u9645\u4e0a\u4e5f\u4e0d\u5b58\u5728\u9891\u7e41\u5237\u65b0\u7684\u9700\u6c42\uff0c\u53cd\u6b63 ifstream \u6790\u6784\u65f6\u603b\u662f\u4f1a\u81ea\u52a8\u5237\u65b0\u5199\u5165\u78c1\u76d8\u3002 \u56e0\u6b64\uff0c endl \u64cd\u7eb5\u7b26\u5927\u591a\u65f6\u5019\u90fd\u662f\u5197\u4f59\u7684\uff1a\u63a7\u5236\u53f0\u8f93\u51fa\u7684 cout \u53ea\u9700\u8981\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u4e2d\u542b\u6709 '\\n' \u5c31\u5237\u65b0\u4e86\uff0c\u5373\u4f7f\u662f\u6587\u4ef6\u8bfb\u5199\u4e5f\u5f88\u5c11\u4f1a\u4f7f\u7528 endl \u3002 \u5982\u679c\u786e\u5b9e\u9700\u8981\u5f3a\u5236\u5237\u65b0\uff0c\u4e5f\u53ef\u4ee5\u7528 flush \u8fd9\u79cd\u66f4\u52a0\u53ef\u8bfb\u7684\u5199\u6cd5\uff1a int num; cout << \"please input the number: \" << flush; cin >> num; ofstream fout(\"log.txt\"); fout << \"immediate write 1\\n\" << flush; sleep(1); fout << \"immediate write 2\\n\" << flush; fout.close(); // \u5173\u95ed\u6587\u4ef6\u65f6\u603b\u662f\u81ea\u52a8 flush\uff0c\u4e0d\u4f1a\u6709\u6b8b\u7559\u672a\u5199\u5165\u7684\u5b57\u7b26 \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f \u540c\u5b66\uff1a\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u4f7f\u7528\uff1a cout << \"the answer is \" << 42 << '\\n'; \u53d1\u73b0\u8f93\u51fa\u4e71\u5957\u4e86\uff01\u8fd9\u662f\u4e0d\u662f\u8bf4\u660e cout \u4e0d\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\u5462\uff1f \u5c0f\u5f6d\u8001\u5e08\uff1acout \u662f\u4e00\u4e2a\u201c\u540c\u6b65\u6d41\u201d\uff0c\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\uff0c\u9519\u8bef\u7684\u662f\u4f60\u7684\u4f7f\u7528\u65b9\u5f0f\u3002 \u5982\u679c\u4ed6\u4e0d\u591a\u7ebf\u7a0b\u5b89\u5168\uff0c\u90a3\u591a\u7ebf\u7a0b\u5730\u8c03\u7528\u4ed6\u5c31\u4e0d\u662f\u8f93\u51fa\u4e71\u5e8f\uff0c\u800c\u662f\u7a0b\u5e8f\u5d29\u6e83\u4e86\u3002 \u4f46\u662f\uff0ccout \u7684\u7ebf\u7a0b\u5b89\u5168\uff0c\u53ea\u80fd\u4fdd\u8bc1\u6bcf\u4e00\u6b21 operator<< \u90fd\u662f\u539f\u5b50\u7684\uff0c\u6bcf\u4e00\u6b21\u5355\u72ec\u7684 operator<< \u4e0d\u4f1a\u88ab\u5176\u4ed6\u4eba\u6253\u65ad\u3002 \u4f46\u4f17\u6240\u5468\u77e5\uff0ccout \u4e3a\u4e86\u652f\u6301\u7ea7\u8054\u8c03\u7528\uff0c\u4ed6\u7684 operator<< \u90fd\u662f\u8fd4\u56de\u81ea\u5df1\u7684\uff0c\u4e0a\u9762\u7684\u4ee3\u7801\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5206\u522b\u4e09\u6b21\u8c03\u7528 cout \u7684 operator<< \u3002 cout << \"the answer is \" << 42 << '\\n'; // \u7b49\u4ef7\u4e8e\uff1a cout << \"the answer is \"; cout << 42; cout << '\\n'; \u53d8\u6210\u4e86\u4e09\u6b21 operator<< \uff0c\u6bcf\u4e00\u6b21\u90fd\u662f\u201c\u5404\u81ea\u201d\u539f\u5b50\u7684\uff0c\u4f46\u4e09\u4e2a\u539f\u5b50\u52a0\u5728\u4e00\u8d77\u5c31\u4e0d\u662f\u539f\u5b50\u4e86\u3002 \u800c\u662f\u5206\u5b50\u4e86 :) \u4ed6\u4eec\u4e2d\u95f4\u53ef\u80fd\u7a7f\u63d2\u4e86\u5176\u4ed6\u7ebf\u7a0b\u7684 cout\uff0c\u4ece\u800c\u5bfc\u81f4\u4f60 \"the answer is\" \u6253\u5370\u5b8c\u540e\uff0c\u88ab\u5176\u4ed6\u7ebf\u7a0b\u7684 '\\n' \u63d2\u5165\u8fdb\u6765\uff0c\u5bfc\u81f4\u6362\u884c\u6df7\u4e71\u3002 std::cout \u7684 operator<< \u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u4e0d\u4f1a\u88ab\u6253\u65ad\uff0c\u4f46\u591a\u4e2a operator<< \u7684\u8c03\u7528\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u53ef\u80fd\u4f1a \u4ea4\u9519 \uff0c\u5bfc\u81f4\u8f93\u51fa\u7ed3\u679c\u6df7\u4e71\u3002 \u66f4\u591a\u7ec6\u8282\u8bf7\u770b\u6211\u4eec\u7684 \u591a\u7ebf\u7a0b\u4e13\u9898 \u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\uff0c\u5148\u521b\u5efa\u4e00\u4e2a\u53ea\u5c5e\u4e8e\u5f53\u524d\u7ebf\u7a0b\u7684 ostringstream \uff0c\u6700\u540e\u4e00\u6b21\u6027\u8c03\u7528\u4e00\u6b21 cout \u7684 operator<< \uff0c\u8ba9\u201c\u539f\u5b50\u201d\u7684\u5355\u4f4d\u53d8\u6210\u201c\u4e00\u884c\u201d\u800c\u4e0d\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 ostringstream oss; oss << \"the answer is \" << 42 << '\\n'; cout << oss.str(); \u6216\u8005\uff0c\u4f7f\u7528 std::format \uff1a cout << std::format(\"the answer is {}\\n\", 42); \u603b\u4e4b\uff0c\u5c31\u662f\u8981\u8ba9 operator<< \u53ea\u6709\u4e00\u6b21\uff0c\u81ea\u7136\u5c31\u662f\u6ca1\u6709\u4ea4\u9519\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u6539\u7528 std::osyncstream(std::cout) \u4ee3\u66ff std::cout : std::osyncstream(std::cout) << \"the answer is \" << 42 << '\\n'; std::osyncstream \u53ef\u4ee5\u4fdd\u8bc1\uff1a1. \u4e0d\u4f1a\u4ea7\u751f\u6570\u636e\u7ade\u4e89\uff1b2. \u4e0d\u4f1a\u53d1\u751f\u7a7f\u63d2\u548c\u622a\u65ad\u3002\u53ef\u4ee5\u7406\u89e3\u4e3a std::osyncstream \u5728\u6784\u9020\u65f6\u5bf9\u7f13\u51b2\u533a\u4e0a\u9501\uff0c\u5728\u6790\u6784\u65f6\u89e3\u9501\u3002 \u5982\u679c\u4f60\u7684\u6807\u51c6\u5e93\u652f\u6301 C++23\uff0c\u8fd8\u53ef\u4ee5\u7528 std::println \uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8f93\u51fa\u4e5f\u662f\u539f\u5b50\u7684\uff08\u7b2c\u4e09\u65b9\u5e93\u5982 fmt::println \u4ea6\u53ef\uff09\uff1a std::println(\"the answer is {}\", 42); cerr \u4e0e cout \u7684\u6289\u62e9 \u5982\u679c\u4f60\u7684\u76ee\u7684\u662f\u8c03\u8bd5\u548c\u62a5\u9519\uff0c\u53ef\u4ee5\u8003\u8651\u7528 cerr \uff01 \u4ed6\u4f1a\u5728\u6bcf\u6b21 << \u65f6\u5237\u65b0\uff0c cerr \u624d\u662f\u6700\u9002\u5408\u6253\u5370\u9519\u8bef\u548c\u8c03\u8bd5\u4fe1\u606f\u7684\u6d41\u3002 cout \u7684\u4f18\u70b9\u662f\u4e0d\u9700\u8981\u65f6\u523b\u5237\u65b0\uff0c\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 cout << \"hello\\n\"; cout << \"the answer is \"; cout << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cout << \"!\\n\"; // \u56e0\u4e3a\u8fd8\u6ca1\u6709\u62b5\u8fbe \\n \u4ea7\u751f\u5237\u65b0\u5c31\u5d29\u6e83\uff0c\u5bfc\u81f4\u4e4b\u524d\u5c1a\u672a\u5237\u65b0\u7684 the answer is 42 \u4e22\u5931 \u53ef\u80fd\u7684\u8f93\u51fa\uff1a hello[\u6362\u884c] cerr << \"hello\\n\"; cerr << \"the answer is \"; cerr << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cerr << \"!\\n\"; \u8f93\u51fa\uff1a hello[\u6362\u884c] the answer is 42 \u8fd8\u6709\u4e00\u4e2a\u7279\u70b9\uff1a cout \u8f93\u51fa\u5230\u201c\u6807\u51c6\u8f93\u51fa\u6d41\u201d\uff0c\u53ef\u4ee5\u88ab\u8f93\u51fa\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u7ba1\u9053\u3002\u800c cerr \u8f93\u51fa\u5230\u201c\u6807\u51c6\u9519\u8bef\u6d41\u201d\uff0c\u901a\u5e38\u4e0d\u4f1a\u88ab\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u6216\u7ba1\u9053\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u628a\u7a0b\u5e8f\u9884\u8ba2\u7684\u8ba1\u7b97\u7ed3\u679c\u5199\u5230 cout \uff0c\u628a\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5199\u5230 cerr \uff0c\u8fd9\u6837\u7528\u6237\u5c31\u53ef\u4ee5\u901a\u8fc7 > \u91cd\u5b9a\u5411\u8ba1\u7b97\u7ed3\u679c\uff0c\u800c\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5219\u6b63\u5e38\u8f93\u51fa\u5230\u5c4f\u5e55\u4e0a\uff0c\u4e0d\u53d7\u91cd\u5b9a\u5411\u5f71\u54cd\u3002 cout << \"1 3 5 7\\n\"; cerr << \"ERROR: this is an error message!\\n\"; cout << \"11 13 17 19\\n\"; $ g++ prime.cpp -o prime $ ./prime 1 3 5 7 ERROR: this is an error message! 11 13 17 19 $ ./prime > output.txt ERROR: this is an error message! $ cat output.txt 1 3 5 7 11 13 17 19 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 \u6211\u4eec\u8bf4\u4e00\u4e2a\u7c7b\u578b\u5927\uff0c\u6709\u4e24\u79cd\u60c5\u51b5\u3002 \u7c7b\u672c\u8eab\u5f88\u5927\uff1a\u4f8b\u5982 array \u7c7b\u672c\u8eab\u4e0d\u5927\uff0c\u4f46\u5176\u6307\u5411\u7684\u5bf9\u8c61\u5927\uff0c\u4e14\u8be5\u7c7b\u662f\u6df1\u62f7\u8d1d\uff0c\u5bf9\u8be5\u7c7b\u7684\u62f7\u8d1d\u4f1a\u5f15\u8d77\u5176\u6307\u5411\u5bf9\u8c61\u7684\u62f7\u8d1d\uff1a\u4f8b\u5982 vector sizeof(array); // \u672c\u8eab 4000 \u5b57\u8282 sizeof(vector); // \u672c\u8eab 24 \u5b57\u8282\uff08\u6210\u5458\u662f 3 \u4e2a\u6307\u9488\uff09\uff0c\u6307\u5411\u7684\u6570\u7ec4\u53ef\u4ee5\u65e0\u9650\u589e\u5927 sizeof(vector) \u4e3a 24 \u5b57\u8282\u4ec5\u4e3a x86_64-pc-linux-gnu \u5e73\u53f0 libstdc++ \u5e93\u7684\u5b9e\u6d4b\u7ed3\u679c\uff0c\u5728 32 \u4f4d\u7cfb\u7edf\u4ee5\u53ca MSVC \u7684 Debug \u6a21\u5f0f STL \u4e0b\u53ef\u80fd\u5f97\u51fa\u4e0d\u540c\u7684\u7ed3\u679c\uff0c\u4e0d\u53ef\u4ee5\u4f9d\u8d56\u8fd9\u4e2a\u5e73\u53f0\u76f8\u5173\u7684\u7ed3\u679c\u6765\u7f16\u7a0b\u3002 \u5bf9\u4e8e vector\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 std::move \u79fb\u52a8\u8bed\u4e49\uff0c\u53ea\u62f7\u8d1d\u8be5\u7c7b\u672c\u8eab\u7684\u4e09\u4e2a\u6307\u9488\u6210\u5458\uff0c\u800c\u4e0d\u5bf9\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u6570\u7ec4\u8fdb\u884c\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e array\uff0c\u5219 std::move \u79fb\u52a8\u8bed\u4e49\u4e0e\u666e\u901a\u7684\u62f7\u8d1d\u6ca1\u6709\u533a\u522b\uff1aarray \u4f5c\u4e3a\u9759\u6001\u6570\u7ec4\u5bb9\u5668\uff0c\u4e0d\u662f\u901a\u8fc7\u201c\u6307\u9488\u6210\u5458\u201d\u6765\u4fdd\u5b58\u6570\u7ec4\u7684\uff0c\u800c\u662f\u76f4\u63a5\u628a\u6570\u7ec4\u5b58\u5728\u4ed6\u7684\u4f53\u5185\uff0c\u5bf9 array \u7684\u79fb\u52a8\u548c\u62f7\u8d1d\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff01 \u603b\u4e4b\uff0c\u79fb\u52a8\u8bed\u4e49\u7684\u52a0\u901f\u6548\u679c\uff0c\u53ea\u5bf9\u91c7\u7528\u4e86\u201c\u6307\u9488\u95f4\u63a5\u5b58\u50a8\u52a8\u6001\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08\u5982 vector\u3001map\u3001set\u3001string\uff09\u6709\u6548\u3002\u5bf9\u201c\u76f4\u63a5\u5b58\u50a8\u9759\u6001\u5927\u5c0f\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08array\u3001tuple\u3001variant\u3001\u6210\u529f\u201c\u5c0f\u5b57\u7b26\u4e32\u4f18\u5316\u201d\u7684 string\uff09\u65e0\u6548\u3002 \u6240\u4ee5\uff0c\u8ba9\u5f88\u591a\u201c\u79fb\u52a8\u8bed\u4e49\u201d\u5b5d\u5b50\u5931\u671b\u4e86\uff1a\u201c\u672c\u8eab\u5f88\u5927\u201d\u7684\u7c7b\uff0c\u79fb\u52a8\u548c\u62f7\u8d1d\u4e00\u6837\u6162\uff01 \u90a3\u4e48\u73b0\u5728\u6211\u4eec\u6709\u4e2a\u8d85\u5927\u7684\u7c7b\uff1a using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b vector arr; void func(BigType x) { arr.push_back(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } int main() { BigType x; func(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } \u5982\u4f55\u52a0\u901f\u8fd9\u79cd\u672c\u8eab\u8d85\u5927\u7684\u53d8\u91cf\u8f6c\u79fb\uff1f\u4f7f\u7528 const \u5f15\u7528\uff1a void func(BigType const &x) \u4f3c\u4e4e\u53ef\u4ee5\u907f\u514d\u4f20\u53c2\u65f6\u7684\u62f7\u8d1d\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u80fd\u907f\u514d push_back \u63a8\u5165 vector \u65f6\u6240\u4e0d\u5f97\u5df2\u7684\u62f7\u8d1d\u3002 \u5c0f\u6280\u5de7\uff1a\u6539\u7528 unique_ptr using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b using BigTypePtr = unique_ptr; vector arr; void func(BigTypePtr x) { arr.push_back(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488\uff0c\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u4e0d\u7528\u6df1\u62f7\u8d1d\u4e86\uff0c\u76f4\u63a5\u79fb\u52a8\u6240\u6709\u6743\u7ed9 vector \u91cc\u7684 BigTypePtr \u667a\u80fd\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } int main() { BigTypePtr x = make_unique(); // \u6ce8\u610f\uff1a\u7528\u667a\u80fd\u6307\u9488\u7684\u8bdd\uff0c\u9700\u8981\u7528 make_unique \u624d\u80fd\u521b\u5efa\u5bf9\u8c61\u4e86 func(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } \u4e0a\u9762\u6574\u4e2a\u7a0b\u5e8f\u4e2d\uff0c\u4e00\u5f00\u59cb\u901a\u8fc7 make_unique \u521b\u5efa\u7684\u8d85\u5927\u5bf9\u8c61\uff0c\u5168\u7a0b\u6ca1\u6709\u53d1\u751f\u4efb\u4f55\u79fb\u52a8\uff0c\u907f\u514d\u4e86\u65e0\u8c13\u7684\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u6765\u8bf4\uff0c\u4e5f\u53ef\u4ee5\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u5c31\u80fd\u5728\u51fd\u6570\u4e4b\u95f4\u7a7f\u68ad\u81ea\u5982\u4e86\u3002 // \u70ed\u77e5\u8bc6\uff1astd::mutex \u4e0d\u652f\u6301\u79fb\u52a8 void func(std::mutex lock); int main() { std::mutex lock; func(std::move(lock)); // \u9519\u8bef\uff1amutex(mutex &&) = delete } void func(std::unique_ptr lock); int main() { std::unique_ptr lock = std::make_unique(); func(std::move(lock)); // OK\uff1a\u8c03\u7528\u7684\u662f unique_ptr(unique_ptr &&)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b } \u66f4\u597d\u7684\u662f shared_ptr \uff0c\u8fde std::move \u90fd\u4e0d\u7528\u5199\uff0c\u66f4\u7701\u5fc3\u3002 void func(std::shared_ptr lock); int main() { std::shared_ptr lock = std::make_shared(); func(lock); // OK\uff1a\u8c03\u7528\u7684\u662f shared_ptr(shared_ptr const &)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b func(lock); // OK\uff1ashared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\uff0c\u5373\u4f7f\u6d45\u62f7\u8d1d\u53d1\u751f\u591a\u6b21\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4e5f\u4e0d\u4f1a\u88ab\u62f7\u8d1d\u6216\u79fb\u52a8 } optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u7c7b\uff0c\u5177\u6709\u81ea\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\uff0c\u4e14\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a struct SomeClass { int m_i; int m_j; SomeClass(int i, int j) : m_i(i), m_j(j) {} }; \u5f53\u6211\u4eec\u9700\u8981\u201c\u5ef6\u8fdf\u521d\u59cb\u5316\u201d\u65f6\u600e\u4e48\u529e\uff1f SomeClass c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c); \u53ef\u4ee5\u5229\u7528 optional \u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u201c\u7a7a\u201d\u7684\u7279\u6027\uff0c\u5b9e\u73b0\u5ef6\u8fdf\u8d4b\u503c\uff1a std::optional c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c.value()); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u5c31\u4f1a\u62a5\u9519\uff0c\u4ece\u800c\u628a\u7f16\u8bd1\u671f\u7684\u672a\u521d\u59cb\u5316\u8f6c\u6362\u4e3a\u8fd0\u884c\u65f6\u5f02\u5e38 \u5c31\u7c7b\u4f3c\u4e8e Python \u4e2d\u5148\u7ed9\u53d8\u91cf\u8d4b\u503c\u4e3a None\uff0c\u7136\u540e\u5728\u5faa\u73af\u6216 if \u91cc\u6761\u4ef6\u6027\u5730\u8d4b\u503c\u4e00\u6837\u3002 \u5982\u679c\u8981\u8fdb\u4e00\u6b65\u907f\u514d c = \u65f6\uff0c\u79fb\u52a8\u6784\u9020\u7684\u5f00\u9500\uff0c\u4e5f\u53ef\u4ee5\u7528 unique_ptr \u6216 shared_ptr \uff1a std::shared_ptr c; if (test()) { c = std::make_shared(1, 2); } else { c = std::make_shared(2, 3); } do_something(c); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u90a3\u4e48\u4f20\u5165\u7684\u5c31\u662f\u4e00\u4e2a nullptr\uff0cdo_something \u5185\u90e8\u9700\u8981\u8d1f\u8d23\u68c0\u6d4b\u6307\u9488\u662f\u5426\u4e3a nullptr \u5982\u679c do_something \u53c2\u6570\u9700\u8981\u7684\u662f\u539f\u59cb\u6307\u9488\uff0c\u53ef\u4ee5\u7528 .get() \u83b7\u53d6\u51fa\u6765\uff1a do_something(c.get()); // .get() \u53ef\u4ee5\u628a\u667a\u80fd\u6307\u9488\u8f6c\u6362\u56de\u539f\u59cb\u6307\u9488\uff0c\u4f46\u8bf7\u6ce8\u610f\u539f\u59cb\u6307\u9488\u4e0d\u6301\u6709\u5f15\u7528\uff0c\u4e0d\u4f1a\u5ef6\u4f38\u6307\u5411\u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5b9e\u9645\u4e0a\uff0cJava\u3001Python \u4e2d\u7684\u4e00\u5207\u5bf9\u8c61\uff08\u9664 int\u3001str \u7b49\u201c\u94a6\u5b9a\u201d\u7684\u57fa\u7840\u7c7b\u578b\u5916\uff09\u90fd\u662f\u5f15\u7528\u8ba1\u6570\u7684\u667a\u80fd\u6307\u9488 shared_ptr \uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u4e00\u5207\u7686\u6307\u9488\u4e86\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u597d\u50cf\u6ca1\u6709\u6307\u9488\u4e86\u3002 if-auto \u4e0e while-auto \u9700\u8981\u5148\u5b9a\u4e49\u4e00\u4e2a\u53d8\u91cf\uff0c\u7136\u540e\u5224\u65ad\u67d0\u4e9b\u6761\u4ef6\u7684\u60c5\u51b5\uff0c\u975e\u5e38\u5e38\u89c1\uff1a extern std::optional some_func(); auto opt = some_func(); if (opt.has_value()) { std::cout << opt.value(); } C++17 \u5f15\u5165\u7684 if-auto \u8bed\u6cd5\uff0c\u53ef\u4ee5\u5c31\u5730\u4e66\u5199\u53d8\u91cf\u5b9a\u4e49\u548c\u5224\u65ad\u6761\u4ef6\uff1a extern std::optional some_func(); if (auto opt = some_func(); opt.has_value()) { std::cout << opt.value(); } \u5bf9\u4e8e\u652f\u6301 (bool)opt \u7684 optional \u7c7b\u578b\u6765\u8bf4\uff0c\u540e\u9762\u7684\u6761\u4ef6\u4e5f\u53ef\u4ee5\u7701\u7565\uff1a extern std::optional some_func(); if (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a auto opt = some_func(); if (opt) { std::cout << opt.value(); } \u7c7b\u4f3c\u7684\u8fd8\u6709 while-auto\uff1a extern std::optional some_func(); while (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a while (true) { auto opt = some_func(); if (!opt) break; std::cout << opt.value(); } if-auto \u6700\u5e38\u89c1\u7684\u914d\u5408\u83ab\u8fc7\u4e8e map.find\uff1a std::map table; int key = 42; if (auto it = table.find(key); it != table.end()) { std::cout << it->second << '\\n'; } else { std::cout << \"not found\\n\"; } bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 \u4f17\u6240\u5468\u77e5\uff0c std::bind \u53ef\u4ee5\u4e3a\u51fd\u6570\u7ed1\u5b9a\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\uff08\u5bf9\u8c61\uff09\u3002 int func(int x, int y) { printf(\"func(%d, %d)\\n\", x, y); return x + y; } auto new_func = std::bind(func, 1, std::placeholders::_1); new_func(2); // \u8c03\u7528 new_func(2) \u65f6\uff0c\u5b9e\u9645\u4e0a\u8c03\u7528\u7684\u662f func(1, 2) } \u8f93\u51fa\uff1a func(1, 2) \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; }; bind \u7684\u5386\u53f2 \u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002 thread \u819d\u76d6\u4e2d\u7bad \u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42 \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand(); forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f \u4f17\u6240\u5468\u77e5\uff0c\u5f53\u4f60\u5728\u8f6c\u53d1\u4e00\u4e2a\u201c\u4e07\u80fd\u5f15\u7528\u201d\u53c2\u6570\u65f6\uff1a template void some_func(Arg &&arg) { other_func(arg); } \u5982\u679c\u6b64\u5904 arg \u4f20\u5165\u7684\u662f\u53f3\u503c\u5f15\u7528\uff0c\u90a3\u4e48\u4f20\u5165 other_func \u5c31\u4f1a\u53d8\u56de\u5de6\u503c\u5f15\u7528\u4e86\uff0c\u4e0d\u7b26\u5408\u5b8c\u7f8e\u8f6c\u53d1\u7684\u8981\u6c42\u3002 \u56e0\u6b64\u5f15\u5165\u4e86 forward \uff0c\u4ed6\u4f1a\u68c0\u6d4b arg \u662f\u5426\u4e3a\u201c\u53f3\u503c\u201d\uff1a\u5982\u679c\u662f\uff0c\u5219 forward \u7b49\u4ef7\u4e8e move \uff1b\u5982\u679c\u4e0d\u662f\uff0c\u5219 forward \u4ec0\u4e48\u90fd\u4e0d\u505a\uff08\u9ed8\u8ba4\u5c31\u662f\u5de6\u503c\u5f15\u7528\uff09\u3002 \u8fd9\u5f04\u5f97 forward \u7684\u5916\u89c2\u975e\u5e38\u5177\u6709\u8ff7\u60d1\u6027\uff0c\u53c8\u662f\u5c16\u62ec\u53f7\u53c8\u662f\u5706\u62ec\u53f7\u7684\u3002 template void some_func(Arg &&arg) { other_func(std::forward(arg)); } \u5b9e\u9645\u4e0a\uff0cforward \u7684\u7528\u6cd5\u975e\u5e38\u5355\u4e00\uff1a\u6c38\u8fdc\u662f forward(t) \u7684\u5f62\u5f0f\uff0c\u5176\u4e2d T \u662f t \u53d8\u91cf\u7684\u7c7b\u578b\u3002 \u53c8\u662f\u52b3\u4fdd\u7684\u9b45\u529b\uff0c\u5229\u7528\u540c\u6837\u662f C++11 \u7684 decltype \u5c31\u80fd\u83b7\u5f97 t \u5b9a\u4e49\u65f6\u7684 T \u3002 void some_func(auto &&arg) { other_func(std::forward(arg)); } \u6240\u4ee5 std::forward(arg) \u5b9e\u9645\u624d\u662f forward \u7684\u6b63\u786e\u7528\u6cd5\uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u5927\u591a\u6570\u65f6\u5019\u4f60\u662f\u6a21\u677f\u53c2\u6570 Arg && \uff0c\u6709\u7684\u4eba\u5077\u61d2\uff0c\u5c31\u628a decltype(arg) \u66ff\u6362\u6210\u5df2\u7ecf\u5339\u914d\u597d\u7684\u6a21\u677f\u53c2\u6570 Arg \u4e86\uff0c\u5b9e\u9645\u4e0a\u662f\u7b49\u4ef7\u7684\u3002 \u8fd9\u91cc\u9700\u8981\u590d\u8bfb arg \u592a\u7eb1\u5e01\u4e86\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5b8f\uff1a #define FWD(arg) std::forward(arg) \u8fd9\u6837\u5c31\u53ef\u4ee5\u7b80\u5316\u4e3a\uff1a void some_func(auto &&arg) { other_func(FWD(arg)); } \u5c11\u4e86\u70e6\u4eba\u7684\u5c16\u62ec\u53f7\uff0c\u770b\u8d77\u6765\u5bb9\u6613\u61c2\u591a\u4e86\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u540c\u5b66\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u4e3a\u4ec0\u4e48 std::forward \u8981\u5199\u6210 std::forward \u7684\u5f62\u5f0f\u5462\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u662f std::forward(t) \u5462\uff1f\u56e0\u4e3a\u8fd9\u6837\u5199\u7684\u8bdd\uff0c forward \u4e5f\u6ca1\u6cd5\u77e5\u9053\u4f60\u7684 t \u662f\u5de6\u662f\u53f3\u4e86\uff08\u51fd\u6570\u53c2\u6570\u59cb\u7ec8\u4f1a\u9ed8\u8ba4\u63a8\u5bfc\u4e3a\u5de6\uff0c\u5373\u4f7f\u5b9a\u4e49\u7684 t \u662f\u53f3\uff09\u56e0\u6b64\u5fc5\u987b\u544a\u8bc9 forward \uff0c t \u7684\u5b9a\u4e49\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f T \uff0c\u6216\u8005\u901a\u8fc7 decltype(t) \u6765\u83b7\u5f97 T \u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7528\u7684\u662f auto && \u53c2\u6570\uff0c\u90a3\u4e48 FWD \u4f1a\u5f88\u65b9\u4fbf\uff08\u81ea\u52a8\u5e2e\u4f60 decltype \uff09\u3002\u4f46\u662f\u5982\u679c\u4f60\u7528\u7684\u662f\u6a21\u677f\u53c2\u6570 T && \uff0c\u90a3\u4e48 FWD \u4e5f\u53ef\u4ee5\u7528\uff0c\u56e0\u4e3a decltype(t) \u603b\u662f\u5f97\u5230 T \u3002 bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408\u4e0a\u6587\u63d0\u5230\u7684 FWD \u5b8f\u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(FWD(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u540c\u6837\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u79f0\u624b\u7684\u5b8f\uff1a #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } \u8fd9\u91cc\u4f7f\u7528\u4e86\u5b8f\u53c2\u6570\u5305\uff0c\u6b64\u5904 __VA_ARGS__ \u5c31\u662f\u5b8f\u7684 ... \u4e2d\u7684\u5185\u5bb9\u3002\u6ce8\u610f\u533a\u5206\u5b8f\u7684 ... \u548c C++ \u53d8\u957f\u6a21\u677f\u7684 ... \u662f\u4e92\u76f8\u72ec\u7acb\u7684\u3002 struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = BIND(world, this); int x = 1; memfn(x, 2); memfn(3.14); } } int main() { // \u6355\u83b7\u975e this \u7684\u6210\u5458\u51fd\u6570\u4e5f OK\uff1a Class c; auto memfn = BIND(c.world, &c); // [&c] \u6309\u5f15\u7528\u6355\u83b7 c \u53d8\u91cf // \u5c55\u5f00\u4e3a\uff1a auto memfn = [&c] (auto &&..._args) { c.world(std::forward(_args)...); } memfn(3.14); } BIND \u8fd9\u4e2a\u540d\u5b57\u662f\u968f\u4fbf\u53d6\u7684\uff0c\u53d6\u8fd9\u4e2a\u540d\u5b57\u662f\u4e3a\u4e86\u8fb1 std::bind \u3002 \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u8fd8\u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f \u5f53\u4f60\u7684\u5168\u5c40\u51fd\u6570\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6216\u5e26\u6709\u91cd\u8f7d\u7684\u51fd\u6570\u65f6\uff1a template T square(T const t) { return t * t; } template void do_something(Fn &&fn) { fn(2); fn(3.14); } int main() { do_something(square); // \u7f16\u8bd1\u9519\u8bef\uff1a\u6709\u6b67\u4e49\u7684\u91cd\u8f7d } \u5c31\u4f1a\u51fa\u73b0\u8fd9\u6837\u607c\u4eba\u7684\u7f16\u8bd1\u9519\u8bef\uff1a test.cpp: In instantiation of 'void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]': test.cpp:18:21: required from here test.cpp:14:9: error: no matching function for call to 'do_something()' do_something(square); ^~~~~~~~~~~~~ test.cpp:7:3: note: candidate: 'template void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]' void do_something(Fn &&fn) { ^~~~~~~~~~~~~ test.cpp:7:3: note: template argument deduction/substitution failed: test.cpp:14:21: note: couldn't deduce template parameter 'Fn' do_something(square); ~~~~~~~~~~~~~^~~~~~ \u8fd9\u662f\u56e0\u4e3a\uff0c\u6a21\u677f\u51fd\u6570\u548c\u6709\u91cd\u8f7d\u7684\u51fd\u6570\uff0c\u662f\u201c\u591a\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u201c\u5e7b\u60f3\u8054\u5408\u4f53\u201d\uff0c\u800c do_something \u7684 Fn \u9700\u8981\u201c\u5355\u4e2a\u201d\u5177\u4f53\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u4e00\u822c\u6765\u8bf4\u662f\u9700\u8981 square \u548c square \u624d\u80fd\u53d8\u6210\u201c\u5177\u4f53\u201d\u7684\u201c\u5355\u4e2a\u201d\u51fd\u6570\u5bf9\u8c61\uff0c\u4f20\u5165 do_something \u7684 Fn \u6a21\u677f\u53c2\u6570\u3002 \u4f46\u662f\u5728\u201c\u51fd\u6570\u8c03\u7528\u201d\u7684\u8bed\u5883\u4e0b\uff0c\u56e0\u4e3a\u5df2\u77e5\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u5f97\u76ca\u4e8e C++ \u7684\u201c\u91cd\u8f7d\u201d\u673a\u5236\uff0c\u5e26\u6709\u6a21\u677f\u53c2\u6570\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u81ea\u52a8\u5339\u914d\u90a3\u4e2a\u6a21\u677f\u53c2\u6570\u4e3a\u4f60\u53c2\u6570\u7684\u7c7b\u578b\u3002 \u4f46\u73b0\u5728\u4f60\u5e76\u6ca1\u6709\u6307\u5b9a\u8c03\u7528\u53c2\u6570\uff0c\u800c\u53ea\u662f\u6307\u5b9a\u4e86\u4e00\u4e2a\u51fd\u6570\u540d square \uff0c\u90a3 C++ \u201c\u91cd\u8f7d\u201d\u673a\u5236\u65e0\u6cd5\u786e\u5b9a\u4f60\u9700\u8981\u7684\u662f square \u8fd8\u662f square \u4e2d\u7684\u54ea\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u4ed6\u4eec\u7684\u7c7b\u578b\u90fd\u4e0d\u540c\uff0c\u5c31\u65e0\u6cd5\u5177\u8c61\u82b1\u51fa\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b Fn \u6765\uff0c\u5bfc\u81f4 \u9519\u8bef\u3002 \u6709\u8da3\u7684\u662f\uff0c\u53ea\u9700\u8981\u5957\u4e00\u5c42 lambda \u5c31\u80fd\u89e3\u51b3\uff1a do_something([] (auto x) { return square(x); }); // \u7f16\u8bd1\u901a\u8fc7 \u6216\u8005\u7528\u6211\u4eec\u4e0a\u9762\u63a8\u8350\u7684 BIND \u5b8f\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } do_something(BIND(square)); // \u7f16\u8bd1\u901a\u8fc7 \u6709\u65f6\u5019\uff0c\u5982\u679c\u4f60\u60f3\u4f20\u9012 this \u7684\u6210\u5458\u51fd\u6570\u4e3a\u51fd\u6570\u5bf9\u8c61\uff0c\u4e5f\u4f1a\u51fa\u73b0\u8fd9\u79cd\u607c\u4eba\u7684\u9519\u8bef\uff1a struct Class { int func(int x) { return x + 1; } void test() { do_something(this->func); // \u8fd9\u91cc\u53c8\u4f1a\u4ea7\u751f\u70e6\u4eba\u7684 unresolved overload \u9519\u8bef\uff01 } }; \u540c\u6837\u53ef\u4ee5\u5305\u4e00\u5c42 lambda\uff0c\u6216\u8005\u7528\u5c0f\u5f6d\u8001\u5e08\u63d0\u4f9b\u7684 BIND \u5b8f\uff0c\u9ebb\u75f9\u7684\u7f16\u8bd1\u5668\u5c31\u4e0d\u72d7\u53eb\u4e86\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } void test() { do_something(BIND(func, this)); // \u641e\u5b9a } \u5efa\u8bae\u4fee\u6539\u6807\u51c6\u5e93\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u8fd9\u4e24\u4e2a\u771f\u6b63\u597d\u7528\u7684\u5b8f\u585e\u5230 \u548c \u91cc\uff0c\u4f5c\u4e3a C++26 \u6807\u51c6\u7684\u4e00\u90e8\u5206\u3002 map + any \u5916\u6302\u5c5e\u6027 TODO \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c C++ \u6709\u4e2a\u7279\u6027\uff1a\u652f\u6301\u7eaf\u53f3\u503c(prvalue)\u9690\u5f0f\u8f6c\u6362\u6210 const \u7684\u5de6\u503c\u5f15\u7528\u3002 \u7ffb\u8bd1\uff1a int && \u53ef\u4ee5\u81ea\u52a8\u8f6c\u6362\u6210 int const & \u3002 void func(int const &i); func(1); // OK\uff1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u53d8\u91cf\u4fdd\u5b58 1\uff0c\u7136\u540e\u4f5c\u4e3a int const & \u53c2\u6570\u4f20\u5165 \u5b9e\u9645\u4e0a\u5c31\u7b49\u4ef7\u4e8e\uff1a const int tmp = 1; func(tmp); \u4f46\u662f\uff0c int && \u5374\u4e0d\u80fd\u81ea\u52a8\u8f6c\u6362\u6210 int & \u3002 void func(int &i); func(1); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece int && \u81ea\u52a8\u8f6c\u6362\u6210 int & C++ \u5b98\u65b9\u8bbe\u7f6e\u8fd9\u4e2a\u9650\u5236\uff0c\u662f\u51fa\u4e8e\u8bed\u4e49\u5b89\u5168\u6027\u8003\u8651\uff0c\u56e0\u4e3a\u53c2\u6570\u63a5\u53d7 int & \u7684\uff0c\u4e00\u822c\u90fd\u610f\u5473\u7740\u8fd9\u4e2a\u662f\u7528\u4f5c\u8fd4\u56de\u503c\uff0c\u800c\u5982\u679c func \u7684\u53c2\u6570\u662f\uff0c func(1) \u3002 \u4e3a\u4e86\u7ed5\u5f00\u8fd9\u4e2a\u89c4\u5219\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5e2e\u624b\u51fd\u6570\uff1a T &temporary(T const &t) { return const_cast(t); } // \u6216\u8005\uff1a T &temporary(T &&t) { return const_cast(t); } \u7136\u540e\uff0c\u5c31\u53ef\u4ee5\u5feb\u4e50\u5730\u8f6c\u6362\u7eaf\u53f3\u503c\u4e3a\u975e const \u5de6\u503c\u4e86\uff1a void func(int &i); func(temporary(1)); \u5728 Libreoffice \u6e90\u7801\u4e2d\u5c31\u6709\u5e94\u7528\u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\u3002 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 std::string name = \"\u4f60\u597d\"; int answer = 42; auto str = std::format(\"\u4f60\u597d\uff0c{}\uff01\u7b54\u6848\u662f {}\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x{:02x}\\n\", name, answer, answer); \u6ca1\u6709 C++20 \u4e4b\u524d\uff0c\u8981\u4e48\u4f7f\u7528\u7b2c\u4e09\u65b9\u7684 fmt::format \uff0c\u8981\u4e48\u53ea\u80fd\u4f7f\u7528\u5b57\u7b26\u4e32\u7684 + \u8fd0\u7b97\u7b26\u62d9\u52a3\u5730\u62fc\u63a5\uff1a auto str = std::string(\"\u4f60\u597d\uff0c\") + name + \"\uff01\u7b54\u6848\u662f \" + std::to_string(answer) + \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" + std::to_string(answer) + \"\\n\"; \u8fd9\u6837\u505a\u6548\u7387\u4f4e\u4e0b\uff0c\u4e14\u4e0d\u6613\u9605\u8bfb\u3002\u800c\u4e14\u4e5f\u65e0\u6cd5\u5b9e\u73b0\u6570\u5b57\u6309\u201c\u5341\u516d\u8fdb\u5236\u201d\u8f6c\u5b57\u7b26\u4e32\u3002 \u53ef\u4ee5\u7528 std::ostringstream \uff0c\u5176\u7528\u6cd5\u4e0e std::cout \u76f8\u540c\u3002\u53ea\u4e0d\u8fc7\u4f1a\u628a\u7ed3\u679c\u5199\u5165\u4e00\u4e2a\u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f\u76f4\u63a5\u8f93\u51fa\uff09\uff0c\u53ef\u4ee5\u7528 .str() \u53d6\u51fa\u90a3\u4e2a\u5b57\u7b26\u4e32\u3002 #include std::ostringstream oss; oss << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\"; auto str = oss.str(); \u5229\u7528\u4e34\u65f6\u53d8\u91cf\u8bed\u6cd5\uff0c\u53ef\u4ee5\u6d53\u7f29\u5199\u5728\u4e00\u884c\u91cc\uff0c\u505a\u4e2a format \u62d9\u52a3\u7684\u6a21\u4eff\u8005\uff1a auto str = (std::ostringstream() << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\").str(); ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 TODO shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 system(\"chcp 65001\"); setlocale(\"LC_ALL\", \".utf-8\"); \u8be6\u89c1 Unicode \u4e13\u9898\u7ae0\u8282 \u3002 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 \u5728\u4e92\u8054\u7f51\u7f16\u7a0b\u548c\u5404\u79cd\u4e0e\u786c\u76d8\u3001\u5e8f\u5217\u5316\u6253\u4ea4\u9053\u7684\u573a\u666f\u4e2d\uff0c\u5e38\u5e38\u9700\u8981\u6309\u4f4d\u62c6\u5206\u5355\u4e2a\u5b57\u8282\u3002 C \u8bed\u8a00\u6709\u4e13\u95e8\u7167\u987e\u6b64\u7c7b\u5de5\u4f5c\u7684\u8bed\u6cd5\u7cd6\uff1a\u4f4d\u57df\u3002 \u4f4d\u57df\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u7ed3\u6784\u4f53\u6210\u5458\uff0c\u53ef\u4ee5\u5bf9\u4f4d\u8fdb\u884c\u5206\u7ec4\uff0c\u65b9\u4fbf\u8bfb\u53d6\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u4ece\u4e00\u4e2a\u5b57\u8282\u4e2d\u8bfb\u53d6\u4e09\u4e2a\u72b6\u6001\u4f4d\uff1a struct Flag { uint8_t a : 4; // \u4f4e 4 \u4f4d uint8_t b : 4; // \u9ad8 4 \u4f4d }; sizeof(Flag); // 1 \u5b57\u8282\u5927\u5c0f\uff08\u5171 8 \u4f4d\uff09 Flag f = std::bit_cast(0x21); f.a; // 0x1 f.b; // 0x2 \u4ee5\u4e0a\u7684\u4ee3\u7801\u7b49\u4ef7\u4e8e\uff1a uint8_t f = 0x21; int a = f & 0xF; // 0x1 int b = f >> 4; // 0x2 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d \u6709\u4e9b\u5d4c\u5957\u5f88\u6df1\u7684\u540d\u5b57\u7a7a\u95f4\u6bcf\u6b21\u90fd\u8981\u590d\u8bfb\u975e\u5e38\u5570\u55e6\u3002 #include int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u5982\u679c using namespace \u7684\u8bdd\uff0c\u53c8\u89c9\u5f97\u6c61\u67d3\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\u4e86\u3002 #include using namespace std::filesystem; int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u53ef\u4ee5\u7528 C++11 \u7684 namespace = \u8bed\u6cd5\uff0c\u7ed9\u540d\u5b57\u7a7a\u95f4\u53d6\u4e2a\u522b\u540d\u3002 #include namespace fs = std::filesystem; int main() { fs::path p = \"/var/www/html\"; ... } \u8fd9\u6837\u4ee5\u540e\u5c31\u53ef\u4ee5 fs \u8fd9\u4e2a\u7b80\u79f0\u8bbf\u95ee\u4e86\u3002","title":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7"},{"location":"cpp_tricks/#c","text":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u522b\u518d [] \u5566\uff01 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u7ee7\u627f\u6784\u9020\u51fd\u6570 \u63d0\u524d\u8fd4\u56de \u7acb\u5373\u8c03\u7528\u7684 Lambda Lambda \u590d\u7528\u4ee3\u7801 \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u522b\u518d make_pair \u5566\uff01 insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 \u5b57\u7b26\u4e32\u5207\u7247 cout \u4e0d\u9700\u8981 endl \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f cerr \u4e0e cout \u7684\u6289\u62e9 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 if-auto \u4e0e while-auto bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f map + any \u5916\u6302\u5c5e\u6027 \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d","title":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7"},{"location":"cpp_tricks/#_1","text":"int a = 42; int b = 58; \u73b0\u5728\u4f60\u60f3\u4ea4\u6362\u8fd9\u4e24\u4e2a\u53d8\u91cf\u3002 int tmp = a; a = b; b = tmp; \u4f46\u662f\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u65b9\u6cd5\uff1a std::swap(a, b); \u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4ea4\u6362\u4efb\u610f\u4e24\u4e2a\u540c\u7c7b\u578b\u7684\u503c\uff0c\u5305\u62ec\u7ed3\u6784\u4f53\u3001\u6570\u7ec4\u3001\u5bb9\u5668\u7b49\u3002 \u53ea\u9700\u8981 #include \u5c31\u53ef\u4ee5\u4f7f\u7528\uff01","title":"\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf"},{"location":"cpp_tricks/#_2","text":"\u5c0f\u5f6d\u8001\u5e08\uff1a\u4e0d\u8981\u51fa\u73b0 new \u548c delete\uff0c\u4e0d\u5b89\u5168\u3002 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; }","title":"\u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4"},{"location":"cpp_tricks/#_3","text":"\u4f17\u6240\u5468\u77e5\uff0cC\u8bed\u8a00\u4e2d int \u76f8\u9664 / \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u4e5f\u662f int \uff0c\u5982\u679c\u9664\u6cd5\u4ea7\u751f\u4e86\u4f59\u6570\uff0c\u90a3\u4e48\u53ea\u4f1a\u4fdd\u7559\u6574\u6570\u90e8\u5206\u3002 \u4f8b\u5982 14 / 5 \uff0c\u672c\u6765\u5e94\u8be5\u5f97\u5230 2.8\u3002\u4f46\u662f\u56e0\u4e3a C \u8bed\u8a00\u7684\u9664\u6cd5\u8fd4\u56de int \uff0c\u7ed3\u679c\u4f1a\u81ea\u52a8\u5411\u4e0b\u53d6\u6574\uff0c\u5bfc\u81f4\u5f97\u5230 2\u3002 int a = 14, b = 5; int c = a / b; // c = 14 / 5 = 2 \u7b49\u4ef7\u4e8e int c = floor((float)a / b); // c = floor(2.8) = 2 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5730\u677f\u9664 (floor div) \u3002 C \u8bed\u8a00\u9ed8\u8ba4\u7684\u5c31\u662f\u5730\u677f\u9664\u3002 \u5982\u679c\u6211\u60f3\u8981\u7684\u662f\u5411\u4e0a\u53d6\u6574\uff0c\u8be5\u600e\u4e48\u5199\uff1f \u6700\u539f\u59cb\u7684\u5199\u6cd5\u662f\u5148\u8f6c\u6210\u6d6e\u70b9\u6570\u6765\u9664\uff0c\u7136\u540eceil\u51fd\u6570\u5411\u4e0a\u53d6\u6574\uff1a int c = ceil((float)a / b); \u4f46\u662f\u6d6e\u70b9\u6570\u4e0d\u4ec5\u4f4e\u6548\uff0c\u8fd8\u6709\u7cdf\u7cd5\u7684\u6d6e\u70b9\u6570\u7cbe\u5ea6\u8bef\u5dee\uff01\u5bf9\u4e8e\u5f88\u5927\u7684\u6574\u6570\uff08\u5927\u4e8e 2^{23} 2^{23} \uff09\u4f1a\u4ea7\u751f\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u66f4\u5408\u7406\u7684\u5199\u6cd5\u662f\u5148\u628a a \u52a0\u4e0a b - 1 \uff0c\u7136\u540e\u518d\u4e0b\u53d6\u6574\u5730\u9664\u4ee5 b \uff1a int c = (a + b - 1) / b; \u8fd9\u6837\u5c31\u80fd\u4ea7\u751f\u4e00\u4e2a\u5411\u4e0a\u53d6\u6574\u7684\u9664\u6cd5\u4e86\u3002 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5929\u82b1\u677f\u9664 (ceil div) \u3002 \u8bd5\u8bd5\u770b\uff1a14 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2.8\uff1b\u5982\u679c\u7528\u5730\u677f\u9664\uff0c\u4f1a\u5f97\u5230 2\uff1b\u5982\u679c\u7528\u5929\u82b1\u677f\u9664\uff0c\u4f1a\u5f97\u5230 3\u3002 14 / 5 = 2 (14 + 5 - 1) / 5 = (14 + 4) / 5 = 18 / 5 = 3 \u8bd5\u8bd5\u770b\uff1a10 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2\uff1b\u90a3\u4e48\u65e0\u8bba\u662f\u5730\u677f\u9664\u8fd8\u662f\u5929\u82b1\u677f\u9664\uff0c\u90fd\u5e94\u8be5\u5f97\u5230 2\u3002 10 / 5 = 2 (10 + 5 - 1) / 5 = (10 + 4) / 5 = 14 / 5 = 2 \u8fd9\u5c31\u662f C \u8bed\u8a00\u4e2d\u5b9e\u73b0\u5929\u82b1\u677f\u9664\u7684\u4e1a\u754c\u516c\u8ba4\u65b9\u5f0f\u3002","title":"\u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664"},{"location":"cpp_tricks/#_4","text":"\u4f60\u77e5\u9053\u5417\uff1f\u5728 map \u4e2d\u4f7f\u7528 [] \u67e5\u627e\u5143\u7d20\uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\u3002\u8fd9\u4e2a\u7279\u6027\u6709\u65f6\u5f88\u65b9\u4fbf\uff0c\u4f46\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u5199\u9519\u4e86\uff0c\u5c31\u4f1a\u5728 map \u4e2d\u521b\u5efa\u4e00\u4e2a\u591a\u4f59\u7684\u9ed8\u8ba4\u5143\u7d20\u3002 map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; cout << table[\"\u4faf\u6377\u8001\u5e08\"]; table \u4e2d\u660e\u660e\u6ca1\u6709 \u201c\u4faf\u6377\u8001\u5e08\u201d \u8fd9\u4e2a\u5143\u7d20\uff0c\u4f46\u7531\u4e8e [] \u7684\u7279\u6027\uff0c\u4ed6\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u4e00\u4e2a 0\uff0c\u4e0d\u4f1a\u7206\u4efb\u4f55\u9519\u8bef\uff01 \u6539\u7528\u66f4\u5b89\u5168\u7684 at() \u51fd\u6570\uff0c\u5f53\u67e5\u8be2\u7684\u5143\u7d20\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u4f60\u8c03\u8bd5\uff1a map table; table.at(\"\u5c0f\u5f6d\u8001\u5e08\") = 24; cout << table.at(\"\u4faf\u6377\u8001\u5e08\"); // \u629b\u51fa\u5f02\u5e38 [] \u771f\u6b63\u7684\u7528\u9014\u662f\u201c\u5199\u5165\u65b0\u5143\u7d20\u201d\u65f6\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u4ed6\u53ef\u4ee5\u81ea\u52a8\u5e2e\u4f60\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\uff0c\u4f9b\u4f60\u4ee5\u5f15\u7528\u7684\u65b9\u5f0f\u8d4b\u503c\u8fdb\u53bb\u3002 \u68c0\u6d4b\u5143\u7d20\u662f\u5426\u5b58\u5728\u53ef\u4ee5\u7528 count \uff1a if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } \u5373\u4f7f\u4f60\u60f3\u8981\u9ed8\u8ba4\u503c 0 \u8fd9\u4e00\u7279\u6027\uff0c count + at \u4e5f\u6bd4 [] \u66f4\u597d\uff0c\u56e0\u4e3a [] \u7684\u9ed8\u8ba4\u503c\u662f\u4f1a\u5bf9 table \u505a\u7834\u574f\u6027\u4fee\u6539\u7684\uff0c\u8fd9\u5bfc\u81f4 [] \u9700\u8981 map \u7684\u58f0\u660e\u4e0d\u4e3a const \uff1a map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u5982\u679c\"\u5c0f\u5f6d\u8001\u5e08\"\u8fd9\u4e00\u952e\u4e0d\u5b58\u5728\uff0c\u4f1a\u521b\u5efa\"\u5c0f\u5f6d\u8001\u5e08\"\u5e76\u8bbe\u4e3a\u9ed8\u8ba4\u503c 0 const map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u7f16\u8bd1\u5931\u8d25\uff01[] \u9700\u8981\u975e const \u7684 map \u5bf9\u8c61\uff0c\u56e0\u4e3a\u4ed6\u4f1a\u7834\u574f\u6027\u4fee\u6539 \u66f4\u591a map \u77e5\u8bc6\u8bf7\u770b\u6211\u4eec\u7684 map \u4e13\u9898\u8bfe \u3002","title":"\u522b\u518d [] \u5566\uff01"},{"location":"cpp_tricks/#_5","text":"// C++98 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} }; Student stu(\"\u4faf\u6377\u8001\u5e08\", 42, 123); C++98 \u9700\u8981\u624b\u52a8\u4e66\u5199\u6784\u9020\u51fd\u6570\uff0c\u975e\u5e38\u9ebb\u70e6\uff01\u800c\u4e14\u51e0\u4e4e\u90fd\u662f\u91cd\u590d\u7684\u3002 C++11 \u4e2d\uff0c\u5e73\u51e1\u7684\u7ed3\u6784\u4f53\u7c7b\u578b\u4e0d\u9700\u8981\u518d\u5199\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u7528 {} \u5c31\u80fd\u5bf9\u6210\u5458\u4f9d\u6b21\u521d\u59cb\u5316\uff1a // C++11 struct Student { string name; int age; int id; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123}; \u8fd9\u88ab\u79f0\u4e3a \u805a\u5408\u521d\u59cb\u5316 (aggregate initialize)\u3002\u53ea\u8981\u4f60\u7684\u7c7b\u6ca1\u6709\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709 private \u6210\u5458\uff0c\u90fd\u53ef\u4ee5\u7528 {} \u805a\u5408\u521d\u59cb\u5316\u3002 \u597d\u6d88\u606f\uff1aC++20 \u4e2d\uff0c\u805a\u5408\u521d\u59cb\u5316\u4e5f\u652f\u6301 () \u4e86\uff0c\u7528\u8d77\u6765\u5c31\u548c\u4f20\u7edf\u7684 C++98 \u6784\u9020\u51fd\u6570\u4e00\u6837\uff01 // C++20 Student stu(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123); \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6307\u5b9a\u9ed8\u8ba4\u503c\uff1a // C++11 struct Student { string name; int age; int id = 9999; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; C++20 \u5f00\u59cb\uff0c {} \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6839\u636e\u6bcf\u4e2a\u6210\u5458\u7684\u540d\u5b57\u6765\u6307\u5b9a\u503c\uff1a Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; \u597d\u5904\u662f\uff0c\u5373\u4f7f\u4e0d\u614e\u5199\u9519\u53c2\u6570\u987a\u5e8f\u4e5f\u4e0d\u7528\u62c5\u5fc3\u3002 Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .id = 9999, .age = 24};","title":"\u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01"},{"location":"cpp_tricks/#_6","text":"\u53ea\u6709\u5f53\u4f60\u9700\u8981\u6709\u201c\u81ea\u5b9a\u4e49\u94a9\u5b50\u903b\u8f91\u201d\u7684\u65f6\u5019\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\u3002 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} Student(Student const &other) : name(other.name), age(other.age), id(other.id) { std::cout << \"\u62f7\u8d1d\u6784\u9020\\n\"; } Student &operator=(Student const &other) { name = other.name; age = other.age; id = other.id; std::cout << \"\u62f7\u8d1d\u8d4b\u503c\\n\"; return *this; } }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c \u5982\u679c\u4f60\u4e0d\u9700\u8981\u8fd9\u4e2a std::cout \uff0c\u53ea\u662f\u5e73\u51e1\u5730\u62f7\u8d1d\u6240\u6709\u6210\u5458\uff0c\u5b8c\u5168\u53ef\u4ee5\u4e0d\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\u3001\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff1a struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student(Student const &other) // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student &operator=(Student const &other) }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c assert(stu2.name == \"\u4faf\u6377\u8001\u5e08\"); \u603b\u4e4b\uff0c\u5f88\u591a C++ \u6559\u6750\u628a\u62f7\u8d1d/\u79fb\u52a8\u6784\u9020\u51fd\u6570\u8fc7\u4e8e\u5938\u5927\uff0c\u641e\u5f97\u597d\u50cf\u6bcf\u4e2a\u7c7b\u90fd\u9700\u8981\u81ea\u5df1\u5b9a\u4e49\u4e00\u6837\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u6709\u5728\u201c\u81ea\u5df1\u5b9e\u73b0\u5bb9\u5668\u201d\u7684\u60c5\u51b5\u4e0b\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3002\u53ef\u662f\u8c01\u4f1a\u6574\u5929\u624b\u6413\u5bb9\u5668\uff1f \u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u7c7b\u91cc\u9762\u5b58 vector\u3001string \u7b49\u5c01\u88c5\u597d\u7684\u5bb9\u5668\uff0c\u7f16\u8bd1\u5668\u9ed8\u8ba4\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4f1a\u81ea\u52a8\u8c03\u7528\u4ed6\u4eec\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u7528\u6237\u53ea\u9700\u4e13\u6ce8\u4e8e\u4e1a\u52a1\u903b\u8f91\u5373\u53ef\uff0c\u4e0d\u9700\u8981\u64cd\u5fc3\u5e95\u5c42\u7ec6\u8282\u3002 \u5bf9\u4e8e\u6301\u6709\u8d44\u6e90\u7684 RAII \u7c7b\uff0c\u6211\u4eec\u90fd\u4f1a\u76f4\u63a5\u5220\u9664\u5176\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff1a struct RAIIHandle { int handle; RAIIHandle() { handle = CreateObject(); } RAIIHandle(RAIIHandle const &) = delete; RAIIHandle &operator=(RAIIHandle const &) = delete; RAIIHandle() { DeleteObject(handle); } };","title":"\u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01"},{"location":"cpp_tricks/#_7","text":"C++ \u7279\u8272\uff1a\u5b50\u7c7b\u4e0d\u4f1a\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff01\uff08\u9664\u975e\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\u662f\u6ca1\u6709\u53c2\u6570\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff09 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { void child_func() { ... } }; Child child(23, \"peng\"); // \u9519\u8bef\uff01Child \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff01 C++11 \u4e2d\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u9762\u5199 using \u7236\u7c7b::\u7236\u7c7b \uff0c\u5c31\u80fd\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u6240\u6709\u7684\u6784\u9020\u51fd\u6570\u4e86\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { using Parent::Parent; // \u52a0\u4e0a\u8fd9\u4e00\u884c\uff01 void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u81ea\u52a8\u8c03\u7528\u5230\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570 Parent(int, const char *) \u5728 C++98 \u4e2d\uff0c\u6ca1\u6709 using \u7684\u8fd9\u4e2a\u8bed\u6cd5\uff0c\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a\u6784\u9020\u51fd\u6570\uff0c\u7136\u540e\u4f7f\u7528\u201c\u59d4\u4efb\u6784\u9020\u201d\u7684\u8bed\u6cd5\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9\u7236\u7c7b\uff0c\u975e\u5e38\u7e41\u7410\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { Child(int age, const char *name) : Parent(age, name) { ... } void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6784\u9020\u51fd\u6570\u540e\u8f6c\u53d1\u5230\u7236\u7c7b","title":"\u7ee7\u627f\u6784\u9020\u51fd\u6570"},{"location":"cpp_tricks/#_8","text":"void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); } else { puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); } else { puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } } } \u8fd9\u4e2a\u51fd\u6570\u6709\u5f88\u591a\u5c42\u5d4c\u5957\uff0c\u5f88\u4e0d\u7f8e\u89c2\u3002\u7528 \u63d0\u524d\u8fd4\u56de \u7684\u5199\u6cd5\u6765\u4f18\u5316\uff1a void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); return; } puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); return; } puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); }","title":"\u63d0\u524d\u8fd4\u56de"},{"location":"cpp_tricks/#lambda","text":"\u6709\u65f6\uff0c\u9700\u8981\u5728\u4e00\u4e2a\u5217\u8868\u91cc\u5faa\u73af\u67e5\u627e\u67d0\u6837\u4e1c\u897f\uff0c\u4e5f\u53ef\u4ee5\u7528\u63d0\u524d\u8fd4\u56de\u7684\u5199\u6cd5\u4f18\u5316\uff1a bool find(const vector &v, int target) { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } \u53ef\u4ee5\u5305\u88f9\u4e00\u4e2a\u7acb\u5373\u8c03\u7528\u7684 Lambda \u5757 [&] { ... } () \uff0c\u9650\u5236\u63d0\u524d\u8fd4\u56de\u7684\u8303\u56f4\uff1a void find(const vector &v, int target) { bool found = [&] { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } (); if (found) { ... } }","title":"\u7acb\u5373\u8c03\u7528\u7684 Lambda"},{"location":"cpp_tricks/#lambda_1","text":"vector spilt(string str) { vector list; string last; for (char c: str) { if (c == ' ') { list.push_back(last); last.clear(); } else { last.push_back(c); } } list.push_back(last); return list; } \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u7528 Lambda \u590d\u7528\uff1a vector spilt(string str) { vector list; string last; auto push = [&] { list.push_back(last); last.clear(); }; for (char c: str) { if (c == ' ') { push(); } else { last.push_back(c); } } push(); return list; }","title":"Lambda \u590d\u7528\u4ee3\u7801"},{"location":"cpp_tricks/#inline","text":"\u5728\u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7ed3\u6784\u4f53\u7684 static \u6210\u5458\u65f6\uff1a struct Class { static int member; }; \u4f1a\u62a5\u9519 undefined reference to 'Class::member' \u3002\u8fd9\u662f\u8bf4\u7684\u4f60\u9700\u8981\u627e\u4e2a .cpp \u6587\u4ef6\uff0c\u5199\u51fa int Class::member \u624d\u80fd\u6d88\u9664\u8be5\u9519\u8bef\u3002 C++17 \u4e2d\uff0c\u53ea\u9700\u52a0\u4e2a inline \u5c31\u80fd\u89e3\u51b3\uff01 struct Class { inline static int member; };","title":"\u7c7b\u5185\u9759\u6001\u6210\u5458 inline"},{"location":"cpp_tricks/#make_pair","text":"map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u4e3a\u907f\u514d\u5199\u51fa\u7c7b\u578b\u540d\u7684\u9ebb\u70e6\uff0c\u5f88\u591a\u8001\u5e08\u90fd\u4f1a\u8ba9\u4f60\u5199 make_pair\uff1a map table; table.insert(make_pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u7136\u800c C++11 \u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u5199\u6cd5\uff0c\u90a3\u5c31\u662f\u901a\u8fc7 {} \u9690\u5f0f\u6784\u9020\uff0c\u4e0d\u7528\u5199\u51fa\u7c7b\u578b\u540d\u6216 make_pair\uff1a map table; table.insert({\"\u4faf\u6377\u8001\u5e08\", 42}); \u5373\u4f7f\u4f60\u51fa\u4e8e\u67d0\u79cd\u201c\u6296m\u201d\u60c5\u8282\uff0c\u8fd8\u60f3\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u4e5f\u53ef\u4ee5\u7528 C++17 \u7684 CTAD \u8bed\u6cd5\uff0c\u514d\u53bb\u6a21\u677f\u53c2\u6570\uff1a map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); // tuple \u4e5f\u652f\u6301 CTAD\uff1a auto t = tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); // \u7b49\u4ef7\u4e8e\uff1a auto t = make_tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); println(\"{}\", typeid(t).name()); // tuple","title":"\u522b\u518d make_pair \u5566\uff01"},{"location":"cpp_tricks/#insert","text":"map table; table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 24}); table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 42}); \u8fd9\u65f6\uff0c table[\"\u5c0f\u5f6d\u8001\u5e08\"] \u4ecd\u7136\u4f1a\u662f 24\uff0c\u800c\u4e0d\u662f 42\u3002\u56e0\u4e3a insert \u4e0d\u4f1a\u66ff\u6362 map \u91cc\u5df2\u7ecf\u5b58\u5728\u7684\u503c\u3002 \u5982\u679c\u5e0c\u671b\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u65f6\uff0c\u66ff\u6362\u73b0\u6709\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 [] \u8fd0\u7b97\u7b26\uff1a map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 42; C++17 \u63d0\u4f9b\u4e86\u6bd4 [] \u8fd0\u7b97\u7b26\u66f4\u9002\u5408\u8986\u76d6\u6027\u63d2\u5165\u7684 insert_or_assign \u51fd\u6570\uff1a map table; table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 24); table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 42); \u597d\u5904\uff1a insert_or_assign \u4e0d\u9700\u8981\u503c\u7c7b\u578b\u652f\u6301\u9ed8\u8ba4\u6784\u9020\uff0c\u53ef\u4ee5\u907f\u514d\u4e00\u6b21\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 + \u4e00\u6b21\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u7684\u5f00\u9500\u3002 \u5efa\u8bae\u628a insert_or_assign \u6539\u540d\u6210 set \uff0c at \u6539\u540d\u6210 get \uff1b\u53ea\u662f\u7531\u4e8e\u5386\u53f2\u539f\u56e0\u540d\u5b57\u8ff7\u60d1\u4e86\u3002","title":"insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6"},{"location":"cpp_tricks/#map","text":"map table; for (auto it = table.begin(); it != table.end(); ++it) { if (it->second < 0) { table.erase(it); } } \u4f1a\u53d1\u751f\u5d29\u6e83\uff01\u770b\u6765 map \u4f3c\u4e4e\u4e0d\u5141\u8bb8\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u5220\u9664\uff1f\u4e0d\uff0c\u53ea\u662f\u4f60\u7684\u5199\u6cd5\u6709\u9519\u8bef\uff1a map table; for (auto it = table.begin(); it != table.end(); ) { if (it->second < 0) { it = table.erase(it); } else { ++it; } } C++20 \u5f15\u5165\u4e86\u66f4\u597d\u7684 erase_if \u5168\u5c40\u51fd\u6570\uff0c\u4e0d\u7528\u624b\u5199\u4e0a\u9762\u8fd9\u4e48\u9ebb\u70e6\u7684\u4ee3\u7801\uff1a map table; erase_if(table, [](pair it) { return it.second < 0; });","title":"\u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f"},{"location":"cpp_tricks/#vector","text":"vector v = {48, 23, 76, 11, 88, 63, 45, 28, 59}; \u4f17\u6240\u5468\u77e5\uff0c\u5728 vector \u4e2d\u5220\u9664\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u5341\u5206\u4f4e\u6548\u3002\u590d\u6742\u5ea6\uff1a O(n) O(n) // \u76f4\u63a5\u5220\u9664 v[3] v.erase(v.begin() + 3); \u5982\u679c\u4e0d\u5728\u4e4e\u5143\u7d20\u7684\u987a\u5e8f\uff0c\u53ef\u4ee5\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20 swap\uff0c\u7136\u540e pop_back\u3002\u590d\u6742\u5ea6\uff1a O(1) O(1) // \u628a v[3] \u548c v[v.size() - 1] \u4f4d\u7f6e\u5bf9\u8c03 swap(v[3], v[v.size() - 1]); // \u7136\u540e\u5220\u9664 v[v.size() - 1] v.pop_back(); \u8fd9\u6837\u5c31\u4e0d\u7528\u79fb\u52a8\u4e00\u5927\u5806\u5143\u7d20\u4e86\u3002\u8fd9\u88ab\u79f0\u4e3a back-swap-erase\u3002","title":"\u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20"},{"location":"cpp_tricks/#vector_1","text":"vector \u4e2d\u53ea\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u9700\u8981 O(n) O(n) \u3002\u5982\u679c\u4e00\u8fb9\u904d\u5386\uff0c\u4e00\u8fb9\u5220\u9664\u591a\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u590d\u6742\u5ea6 O(n^2) O(n^2) \u4e86\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 remove \u548c remove_if \u51fd\u6570\uff0c\u5176\u5185\u90e8\u91c7\u7528\u7c7b\u4f3c back-swap-erase \u7684\u65b9\u6cd5\uff0c\u5148\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u79fb\u52a8\u5230\u672b\u5c3e\u3002\u7136\u540e\u4e00\u6b21\u6027 erase \u6389\u672b\u5c3e\u540c\u6837\u6570\u91cf\u7684\u5143\u7d20\u3002 \u4e14\u4ed6\u4eec\u90fd\u80fd\u4fdd\u6301\u987a\u5e8f\u4e0d\u53d8\u3002 \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove(v.begin(), v.end(), 42), v.end()); \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove_if(v.begin(), v.end(), [](int x) { return x > 0; }), v.end()); \u73b0\u5728 C++20 \u4e5f\u5f15\u5165\u4e86\u5168\u5c40\u51fd\u6570 erase \u548c erase_if\uff0c\u4f7f\u7528\u8d77\u6765\u66f4\u52a0\u76f4\u89c2\uff1a vector v; erase(v, 42); // \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20 erase_if(v, [](int x) { return x > 0; // \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20 });","title":"\u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20"},{"location":"cpp_tricks/#vector_2","text":"\u5982\u679c\u4f60\u60f3\u8981\u7ef4\u62a4\u4e00\u4e2a\u6709\u5e8f\u7684\u6570\u7ec4\uff0c\u7528 lower_bound \u6216 upper_bound \u6765\u63d2\u5165\u5143\u7d20\uff0c\u4fdd\u8bc1\u63d2\u5165\u540e\u4ecd\u4fdd\u6301\u6709\u5e8f\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 3), 3); // s = { 1, 2, 3, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 5), 5); // s = { 1, 2, 3, 4, 5, 6 } \u6709\u5e8f\u6570\u7ec4\u4e2d\uff0c\u53ef\u4ee5\u5229\u7528 lower_bound \u6216 upper_bound \u5feb\u901f\u4e8c\u5206\u67e5\u627e\u5230\u60f3\u8981\u7684\u503c\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } lower_bound(s.begin(), s.end(), 3); // s.begin() + 2; lower_bound(s.begin(), s.end(), 5); // s.begin() + 3; \u6709\u5e8f vector \u5e94\u7528\u6848\u4f8b\uff1a\u5229\u7528 CDF \u79ef\u5206 + \u4e8c\u5206\u6cd5\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u4efb\u610f\u6307\u5b9a\u5206\u5e03\u7684\u968f\u673a\u6570\u3002 \u4f8b\u5982\u6570\u503c\u7b56\u5212\u8981\u6c42\u7684\u62bd\u5361\u6982\u7387\u5206\u5e03\u662f\uff1a 2% \u51fa\u91d1\u5361 10% \u51fa\u84dd\u5361 80% \u51fa\u767d\u5361 8% \u51fa\u7b54\u8fa9 \u90a3\u4e48\u4f60\u8f6c\u6362\u4e00\u4e0b\u4efb\u52a1\u3002\u53d8\u6210\u968f\u673a\u751f\u6210\u4e00\u4e2a 0 \u5230 1 \u7684\u6d6e\u70b9\u6570\uff0c\u7136\u540e\u5224\u65ad\uff1a \u5c0f\u4e8e 0.02 \u65f6\uff0c\u51fa\u91d1\u5361 \u5c0f\u4e8e 0.12 \u65f6\uff0c\u51fa\u84dd\u5361 \u5c0f\u4e8e 0.92 \u65f6\uff0c\u51fa\u767d\u5361 \u5c0f\u4e8e 1.00 \u65f6\uff0c\u51fa\u7b54\u8fa9 \u8fd9\u4e2a\u8f6c\u6362\u8fc7\u7a0b\u5c31\u662f CDF \u79ef\u5206\u3002\u5982\u679c\u4f60\u628a\u8fd9 4 \u4e2a\u6570\u6309\u7167\u987a\u5e8f\u6392\u5217\uff0c\u5c31\u662f\u4e00\u4e2a\u6709\u5e8f vector\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::partial_sum \uff08\u4e0d\u7cbe\u51c6\uff09\u6216 std::inclusive_scan \uff08\u66f4\u7cbe\u51c6\uff0cC++17 \u5f15\u5165\uff09\u90fd\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684 CDF \u79bb\u6563\u79ef\u5206\u3002 vector probs = {0.02, 0.1, 0.8, 0.08}; vector cdf; // \u8ba1\u7b97 probs \u7684 CDF \u79ef\u5206\uff0c\u5b58\u5165 cdf \u6570\u7ec4 std::inclusive_scan(probs.begin(), probs.end(), std::back_inserter(cdf)); // cdf = {0.02, 0.12, 0.92, 1.00} \u662f\u4e00\u4e2a\u6709\u5e8f vector\uff0c\u53ef\u4ee5\u8fd0\u7528\u4e8c\u5206\u6cd5\u5b9a\u4f4d vector result = {\"\u91d1\u5361\", \"\u84dd\u5361\", \"\u767d\u5361\", \"\u7b54\u8fa9\"}; // \u751f\u6210 100 \u4e2a\u968f\u673a\u6570\uff1a for (int i = 0; i < 100; ++i) { double r = rand() / (RAND_MAX + 1.0); int index = lower_bound(cdf.begin(), cdf.end(), r) - cdf.begin(); cout << \"\u4f60\u62bd\u5230\u4e86\" << result[index] << endl; } \u987a\u4fbf\u4e00\u63d0\uff0cCDF \u79ef\u5206\u7684\u9006\u8fd0\u7b97\u662f\u79bb\u6563\u5fae\u5206\uff1a std::adjacent_difference \uff0c\u53ef\u4ee5\u4ece cdf \u6570\u7ec4\u590d\u539f\u51fa probs \u6570\u7ec4\u3002","title":"\u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5"},{"location":"cpp_tricks/#c_1","text":"// \u9519\u8bef\u7684\u5199\u6cd5\uff1a int r = rand() % 10; // \u8fd9\u6837\u5199\u662f\u9519\u8bef\u7684\uff01 rand() \u7684\u8fd4\u56de\u503c\u8303\u56f4\u662f [0, RAND_MAX]\uff0cRAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0b\u4e0d\u540c\uff0c\u5728 Windows \u5e73\u53f0\u7684\u662f 32767\uff0c\u5373 rand() \u53ea\u80fd\u751f\u6210 0\uff5e32767 \u4e4b\u95f4\u7684\u968f\u673a\u6570\u3002 \u5982\u679c\u60f3\u8981\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\uff1a int r = rand() % 10; \u7136\u800c\u8fd9\u79cd\u65b9\u6cd5\u6709\u4e2a\u81f4\u547d\u7684\u95ee\u9898\uff1a\u4e0d\u540c\u7684\u968f\u673a\u6570\u751f\u6210\u6982\u7387\u4e0d\u4e00\u6837\u3002 \u4f8b\u5982\u628a [0, RAND_MAX] \u5747\u5300\u5730\u5206\u6210 10 \u4efd\uff0c\u6bcf\u4efd 3276.7\u3002\u90a3\u4e48 0\uff5e6 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 10.0003%\uff0c\u800c 7\uff5e9 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 9.997%\u3002 \u8fd9\u6837\u5c31\u4e0d\u662f\u771f\u6b63\u7684\u5747\u5300\u5206\u5e03\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u786e\u6027\u3002 \u5f53\u6a21\u6570\u5927\u7684\u65f6\u5019\u4e0d\u5747\u5300\u6027\u4f1a\u53d8\u5f97\u7279\u522b\u660e\u663e\uff0c\u4f8b\u5982 rand() % 10000 \u3002 RAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0d\u540c\u7684\u7279\u6027\u4e5f\u8ba9\u8de8\u5e73\u53f0\u5f00\u53d1\u8005\u5f88\u5934\u5927\u3002 rand \u4f7f\u7528\u5168\u5c40\u53d8\u91cf\u5b58\u50a8\u79cd\u5b50\uff0c\u5bf9\u591a\u7ebf\u7a0b\u4e0d\u53cb\u597d\u3002 \u65e0\u6cd5\u72ec\u7acb\u7684\u4e3a\u591a\u4e2a\u751f\u6210\u5e8f\u5217\u8bbe\u5b9a\u72ec\u7acb\u7684\u79cd\u5b50\uff0c\u4e00\u4e9b\u6e38\u620f\u53ef\u80fd\u9700\u8981\u7528\u5230\u591a\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u5404\u81ea\u6709\u72ec\u7acb\u7684\u79cd\u5b50\u3002 \u53ea\u80fd\u751f\u6210\u5747\u5300\u5206\u5e03\u7684\u6574\u6570\uff0c\u4e0d\u80fd\u751f\u6210\u5e42\u7387\u5206\u5e03\u3001\u6b63\u592a\u5206\u5e03\u7b49\uff0c\u751f\u6210\u6d6e\u70b9\u6570\u4e5f\u6bd4\u8f83\u9ebb\u70e6\u3002 \u4f7f\u7528 srand(time(NULL)) \u65e0\u6cd5\u5b89\u5168\u5730\u751f\u6210\u968f\u673a\u6570\u7684\u521d\u59cb\u79cd\u5b50\uff0c\u5bb9\u6613\u88ab\u9ed1\u5ba2\u9884\u6d4b\u5e76\u653b\u51fb\u3002 rand \u7684\u7b97\u6cd5\u5b9e\u73b0\u6ca1\u6709\u5b98\u65b9\u89c4\u5b9a\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u5404\u6709\u4e0d\u540c\uff0c\u4ea7\u751f\u7684\u968f\u673a\u6570\u5e8f\u5217\u53ef\u80fd\u4e0d\u540c\u3002 \u4e3a\u6b64\uff0cC++ \u63d0\u51fa\u4e86\u66f4\u52a0\u4e13\u4e1a\u7684\u968f\u673a\u6570\u751f\u6210\u5668\uff1a \u5e93\u3002 // \u4f7f\u7528 \u5e93\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff1a #include #include int main() { uint64_t seed = std::random_device()(); std::mt19937 gen(seed); std::uniform_int_distribution dis(0, 9); for (int i = 0; i < 100; ++i) { int r = dis(gen); std::cout << r << \" \"; } } \u8fd9\u6837\u5c31\u53ef\u4ee5\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u4e86\u3002 std::random_device \u662f\u4e00\u4e2a\u968f\u673a\u6570\u79cd\u5b50\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u7cfb\u7edf\u7684\u968f\u673a\u8bbe\u5907\uff08\u5982\u679c\u6709\u7684\u8bdd\uff0c\u5426\u5219\u4f1a\u629b\u51fa\u5f02\u5e38\uff09\u751f\u6210\u4e00\u4e2a\u5b89\u5168\u7684\u968f\u673a\u6570\u79cd\u5b50\uff0c\u9ed1\u5ba2\u65e0\u6cd5\u9884\u6d4b\u3002 std::mt19937 \u662f\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u521d\u59cb\u79cd\u5b50\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u5e8f\u5217\u3002\u5e76\u4e14\u5fc5\u5b9a\u662f MT19937 \u8fd9\u4e2a\u9ad8\u5f3a\u5ea6\u7684\u968f\u673a\u7b97\u6cd5\uff0c\u6240\u6709\u5e73\u53f0\u90fd\u4e00\u6837\u3002 std::uniform_int_distribution \u662f\u4e00\u4e2a\u5206\u5e03\u5668\uff0c\u5b83\u53ef\u4ee5\u628a\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u6620\u5c04\u5230\u6211\u4eec\u60f3\u8981\u7684\u4e0a\u4e0b\u754c\u4e2d\u3002\u91cc\u9762\u7684\u5b9e\u73b0\u7c7b\u4f3c\u4e8e gen() % 10 \uff0c\u4f46\u901a\u8fc7\u6570\u5b66\u673a\u5236\u4fdd\u8bc1\u4e86\u7edd\u5bf9\u5747\u5300\u6027\u3002 \u7c7b\u4f3c\u7684\u8fd8\u6709 std::uniform_real_distribution \u7528\u4e8e\u751f\u6210\u6d6e\u70b9\u6570\uff0c std::normal_distribution \u7528\u4e8e\u751f\u6210\u6b63\u592a\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c std::poisson_distribution \u7528\u4e8e\u751f\u6210\u6cca\u677e\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u7b49\u7b49\u3002 \u5982\u679c\u559c\u6b22\u8001\u5f0f\u7684\u51fd\u6570\u8c03\u7528\u98ce\u683c\u63a5\u53e3\uff0c\u53ef\u4ee5\u5c01\u88c5\u4e00\u4e2a\u65b0\u7684 C++ \u91cd\u7f6e\u7248\u5b89\u5168 rand \uff1a thread_local std::mt19937 gen(std::random_device{}()); // \u6bcf\u7ebf\u7a0b\u4e00\u4e2a\uff0c\u4e92\u4e0d\u51b2\u7a81 int randint(int min, int max) { return std::uniform_int_distribution(min, max)(gen); } float randfloat(float min, float max) { return std::uniform_real_distribution(min, max)(gen); }","title":"C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f"},{"location":"cpp_tricks/#const","text":"\u4f17\u6240\u5468\u77e5\uff0c const \u5728\u6307\u9488\u7b26\u53f7 * \u7684\u524d\u540e\uff0c\u6548\u679c\u662f\u4e0d\u540c\u7684\u3002 const int *p; int *const p; \u4f60\u80fd\u770b\u51fa\u6765\u4e0a\u9762\u8fd9\u4e2a const \u5206\u522b\u4fee\u9970\u7684\u662f\u8c01\u5417\uff1f const int *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u4e3a\u4e86\u770b\u8d77\u6765\u66f4\u52a0\u660e\u786e\uff0c\u6211\u901a\u5e38\u90fd\u4f1a\u540e\u7f6e\u6240\u6709\u7684 const \u4fee\u9970\u3002 int const *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\uff0cconst \u603b\u662f\u5728\u4fee\u9970\u4ed6\u524d\u9762\u7684\u4e1c\u897f\uff0c\u800c\u4e0d\u662f\u540e\u9762\u3002 \u4e3a\u4ec0\u4e48 int *const \u4fee\u9970\u7684\u662f int * \u4e5f\u5c31\u5f88\u5bb9\u6613\u7406\u89e3\u4e86\u3002 int const i; int const *p; int *const q; int const &r; \u4e3e\u4e2a\u4f8b\u5b50\uff1a int i, j; int *const p = &i; *p = 1; // OK\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int i, j; int const *p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // OK\uff1ap \u672c\u8eab\u53ef\u53d8\uff0c\u53ef\u4ee5\u6539\u53d8\u6307\u5411 int i, j; int const *const p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e5f\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int const * \u548c const int * \u7b49\u4ef7\uff01\u53ea\u6709 int *const \u662f\u4e0d\u540c\u7684\u3002","title":"const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e…"},{"location":"cpp_tricks/#auto","text":"\u5927\u5bb6\u90fd\u77e5\u9053\uff0c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u58f0\u660e\u4e3a auto \uff0c\u8ba9\u5176\u81ea\u52a8\u63a8\u5bfc\u3002 auto square() { // int square(); return 1; } \u4f46\u4f60\u77e5\u9053\u4ece C++20 \u5f00\u59cb\uff0c\u53c2\u6570\u4e5f\u53ef\u4ee5\u58f0\u660e\u4e3a auto \u4e86\u5417\uff1f auto square(auto x) { // T square(T x); return x * x; } square(1); // square(int) square(3.14); // square(double) \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u201c\u6a21\u677f\u51fd\u6570\u201d\u7684\u4f20\u7edf\u5199\u6cd5\uff1a template T square(T x) { return x * x; } square(1); // square(int) square(3.14); // square(double) \u56e0\u4e3a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6240\u4ee5\u4e5f\u5f88\u96be\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u7684\u60c5\u51b5\u3002 auto \u53c2\u6570\u8fd8\u53ef\u4ee5\u5e26\u6709\u5f15\u7528\uff1a auto square(auto const &x) { // T square(T const &x); return x * x; } square(1); // square(int const &) square(3.14); // square(double const &) \u7b49\u4ef7\u4e8e\uff1a template T square(T const &x) { return x * x; } auto \u53c2\u6570\u6700\u597d\u7684\u914d\u5408\u83ab\u8fc7\u4e8e\u662f\u4e0e\u540c\u6837 C++20 \u5f15\u5165\u7684 concept\uff1a auto square(std::integral auto x) { // T square(T x) requires std::integral return x * x; } square(1); // square(int) square(3.14); // \u9519\u8bef\uff1adouble \u4e0d\u662f\u6574\u6570\u7c7b\u578b \u7b49\u4ef7\u4e8e\uff1a template requires std::integral T square(T x) { return x * x; } \u6216\u8005\uff1a template T square(T x) { return x * x; }","title":"\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto"},{"location":"cpp_tricks/#_9","text":"std::string file_get_content(std::string const &filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); std::istreambuf_iterator iit(ifs), iite; std::string content(iit, iite); return content; } void file_put_content(std::string const &filename, std::string const &content) { std::ofstream ofs(filename, std::ios::out | std::ios::binary); ofs << content; } \u8fd9\u6837\u5c31\u53ef\u4ee5\u628a\u6574\u4e2a\u6587\u4ef6\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u5f88\u65b9\u4fbf\u5730\u8fdb\u884c\u5904\u7406\u540e\u518d\u5199\u56de\u6587\u4ef6\u3002 \u63a8\u8350\u7528 std::ios::binary \u9009\u9879\u6253\u5f00\u4e8c\u8fdb\u5236\u6587\u4ef6\uff0c\u5426\u5219\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0 '\\n' \u65f6\uff0c\u4f1a\u88ab MSVC \u6807\u51c6\u5e93\u81ea\u52a8\u8f6c\u6362\u6210 '\\r\\n' \u6765\u5199\u5165\uff0c\u59a8\u788d\u6211\u4eec\u8de8\u5e73\u53f0\u3002","title":"\u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32"},{"location":"cpp_tricks/#_10","text":"std::ifstream fin(\"test.txt\"); std::string line; while (std::getline(fin, line)) { std::cout << \"\u8bfb\u53d6\u5230\u4e00\u884c\uff1a\" << line << '\\n'; }","title":"\u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6"},{"location":"cpp_tricks/#_11","text":"#include #include #include std::vector split_str(std::string const &str, char ch) { std::stringstream ss(str); std::string line; std::vector res; while (std::getline(ss, line, ch)) { res.push_back(std::move(line)); } return res; } auto res = split_str(\"hello world\", ' '); // res = {\"hello\", \"world\"}","title":"\u5b57\u7b26\u4e32\u5207\u7247"},{"location":"cpp_tricks/#cout-endl","text":"int a = 42; printf(\"%d\\n\", a); \u4e07\u4e00\u4f60\u5199\u9519\u4e86 % \u540e\u9762\u7684\u7c7b\u578b\uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u7559\u4e0b\u9690\u60a3\u3002 int a = 42; printf(\"%s\\n\", a); // \u7f16\u8bd1\u5668\u4e0d\u62a5\u9519\uff0c\u4f46\u662f\u8fd0\u884c\u65f6\u4f1a\u5d29\u6e83\uff01 C++ \u4e2d\u6709\u66f4\u5b89\u5168\u7684\u8f93\u51fa\u65b9\u5f0f cout \uff0c\u901a\u8fc7 C++ \u7684\u91cd\u8f7d\u673a\u5236\uff0c\u65e0\u9700\u624b\u52a8\u6307\u5b9a % \uff0c\u81ea\u52a8\u5c31\u80fd\u63a8\u5bfc\u7c7b\u578b\u3002 int a = 42; cout << a << endl; double d = 3.14; cout << d << endl; cout << \"Hello, World!\" << endl; endl \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6d41\u64cd\u4f5c\u7b26\uff0c\u4f5c\u7528\u7b49\u4ef7\u4e8e\u5148\u8f93\u51fa\u4e00\u4e2a '\\n' \u7136\u540e flush \u3002 cout << \"Hello, World!\" << '\\n'; cout.flush(); \u4f46\u5b9e\u9645\u4e0a\uff0c\u8f93\u51fa\u6d41 cout \u9ed8\u8ba4\u7684\u8bbe\u7f6e\u5c31\u662f\u201c\u884c\u5237\u65b0\u7f13\u5b58\u201d\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u68c0\u6d4b\u5230 '\\n' \u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u5237\u65b0\u4e00\u6b21\uff0c\u6839\u672c\u4e0d\u9700\u8981\u6211\u4eec\u624b\u52a8\u5237\u65b0\uff01 \u5982\u679c\u8fd8\u7528 endl \u7684\u8bdd\uff0c\u5c31\u76f8\u5f53\u4e8e\u5237\u65b0\u4e86\u4e24\u6b21\uff0c\u6d6a\u8d39\u6027\u80fd\u3002 \u53ef\u89c1\uff0cendl \u662f\u4e00\u4e2a\u88ab\u5f88\u591a\u65e0\u8111\u6559\u6750\u9519\u8bef\u5ba3\u4f20\uff0c\u5b9e\u9645\u4e0a\u6839\u672c\u591a\u6b64\u4e00\u4e3e\u7684\u4e1c\u897f\u3002 \u6211\u4eec\u53ea\u9700\u8981\u8f93\u51fa '\\n' \u5c31\u53ef\u4ee5\u4e86\uff0c\u6bcf\u6b21\u6362\u884c\u65f6 cout \u90fd\u4f1a\u81ea\u52a8\u5237\u65b0\u3002 cout << \"Hello, World!\" << '\\n'; endl \u662f\u4e00\u4e2a\u5178\u578b\u7684\u4ee5\u8bb9\u4f20\u8bb9\u9519\u8bef\u5199\u6cd5\uff0c\u53ea\u6709\u5f53\u4f60\u7684\u8f93\u51fa\u662f\u6307\u5411\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u7ba1\u9053\u65f6\uff0c\u5176\u9644\u5e26\u7684\u5237\u65b0\u529f\u80fd\u624d\u6709\u4f5c\u7528\u3002 \u5f53\u8f93\u51fa\u662f\u7ba1\u9053\u6216\u6587\u4ef6\u65f6\uff0c cout \u9700\u8981 endl \u624d\u80fd\u5237\u65b0\u3002 \u5f53\u8f93\u51fa\u662f\u666e\u901a\u63a7\u5236\u53f0\u65f6\uff0c cout \u53ea\u9700 '\\n' \u5c31\u80fd\u5237\u65b0\u4e86\uff0c\u6839\u672c\u7528\u4e0d\u7740 endl \u3002 \u800c\u4e14\uff0c\u7ba1\u9053\u6216\u6587\u4ef6\u5b9e\u9645\u4e0a\u4e5f\u4e0d\u5b58\u5728\u9891\u7e41\u5237\u65b0\u7684\u9700\u6c42\uff0c\u53cd\u6b63 ifstream \u6790\u6784\u65f6\u603b\u662f\u4f1a\u81ea\u52a8\u5237\u65b0\u5199\u5165\u78c1\u76d8\u3002 \u56e0\u6b64\uff0c endl \u64cd\u7eb5\u7b26\u5927\u591a\u65f6\u5019\u90fd\u662f\u5197\u4f59\u7684\uff1a\u63a7\u5236\u53f0\u8f93\u51fa\u7684 cout \u53ea\u9700\u8981\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u4e2d\u542b\u6709 '\\n' \u5c31\u5237\u65b0\u4e86\uff0c\u5373\u4f7f\u662f\u6587\u4ef6\u8bfb\u5199\u4e5f\u5f88\u5c11\u4f1a\u4f7f\u7528 endl \u3002 \u5982\u679c\u786e\u5b9e\u9700\u8981\u5f3a\u5236\u5237\u65b0\uff0c\u4e5f\u53ef\u4ee5\u7528 flush \u8fd9\u79cd\u66f4\u52a0\u53ef\u8bfb\u7684\u5199\u6cd5\uff1a int num; cout << \"please input the number: \" << flush; cin >> num; ofstream fout(\"log.txt\"); fout << \"immediate write 1\\n\" << flush; sleep(1); fout << \"immediate write 2\\n\" << flush; fout.close(); // \u5173\u95ed\u6587\u4ef6\u65f6\u603b\u662f\u81ea\u52a8 flush\uff0c\u4e0d\u4f1a\u6709\u6b8b\u7559\u672a\u5199\u5165\u7684\u5b57\u7b26","title":"cout \u4e0d\u9700\u8981 endl"},{"location":"cpp_tricks/#cout","text":"\u540c\u5b66\uff1a\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u4f7f\u7528\uff1a cout << \"the answer is \" << 42 << '\\n'; \u53d1\u73b0\u8f93\u51fa\u4e71\u5957\u4e86\uff01\u8fd9\u662f\u4e0d\u662f\u8bf4\u660e cout \u4e0d\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\u5462\uff1f \u5c0f\u5f6d\u8001\u5e08\uff1acout \u662f\u4e00\u4e2a\u201c\u540c\u6b65\u6d41\u201d\uff0c\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\uff0c\u9519\u8bef\u7684\u662f\u4f60\u7684\u4f7f\u7528\u65b9\u5f0f\u3002 \u5982\u679c\u4ed6\u4e0d\u591a\u7ebf\u7a0b\u5b89\u5168\uff0c\u90a3\u591a\u7ebf\u7a0b\u5730\u8c03\u7528\u4ed6\u5c31\u4e0d\u662f\u8f93\u51fa\u4e71\u5e8f\uff0c\u800c\u662f\u7a0b\u5e8f\u5d29\u6e83\u4e86\u3002 \u4f46\u662f\uff0ccout \u7684\u7ebf\u7a0b\u5b89\u5168\uff0c\u53ea\u80fd\u4fdd\u8bc1\u6bcf\u4e00\u6b21 operator<< \u90fd\u662f\u539f\u5b50\u7684\uff0c\u6bcf\u4e00\u6b21\u5355\u72ec\u7684 operator<< \u4e0d\u4f1a\u88ab\u5176\u4ed6\u4eba\u6253\u65ad\u3002 \u4f46\u4f17\u6240\u5468\u77e5\uff0ccout \u4e3a\u4e86\u652f\u6301\u7ea7\u8054\u8c03\u7528\uff0c\u4ed6\u7684 operator<< \u90fd\u662f\u8fd4\u56de\u81ea\u5df1\u7684\uff0c\u4e0a\u9762\u7684\u4ee3\u7801\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5206\u522b\u4e09\u6b21\u8c03\u7528 cout \u7684 operator<< \u3002 cout << \"the answer is \" << 42 << '\\n'; // \u7b49\u4ef7\u4e8e\uff1a cout << \"the answer is \"; cout << 42; cout << '\\n'; \u53d8\u6210\u4e86\u4e09\u6b21 operator<< \uff0c\u6bcf\u4e00\u6b21\u90fd\u662f\u201c\u5404\u81ea\u201d\u539f\u5b50\u7684\uff0c\u4f46\u4e09\u4e2a\u539f\u5b50\u52a0\u5728\u4e00\u8d77\u5c31\u4e0d\u662f\u539f\u5b50\u4e86\u3002 \u800c\u662f\u5206\u5b50\u4e86 :) \u4ed6\u4eec\u4e2d\u95f4\u53ef\u80fd\u7a7f\u63d2\u4e86\u5176\u4ed6\u7ebf\u7a0b\u7684 cout\uff0c\u4ece\u800c\u5bfc\u81f4\u4f60 \"the answer is\" \u6253\u5370\u5b8c\u540e\uff0c\u88ab\u5176\u4ed6\u7ebf\u7a0b\u7684 '\\n' \u63d2\u5165\u8fdb\u6765\uff0c\u5bfc\u81f4\u6362\u884c\u6df7\u4e71\u3002 std::cout \u7684 operator<< \u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u4e0d\u4f1a\u88ab\u6253\u65ad\uff0c\u4f46\u591a\u4e2a operator<< \u7684\u8c03\u7528\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u53ef\u80fd\u4f1a \u4ea4\u9519 \uff0c\u5bfc\u81f4\u8f93\u51fa\u7ed3\u679c\u6df7\u4e71\u3002 \u66f4\u591a\u7ec6\u8282\u8bf7\u770b\u6211\u4eec\u7684 \u591a\u7ebf\u7a0b\u4e13\u9898 \u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\uff0c\u5148\u521b\u5efa\u4e00\u4e2a\u53ea\u5c5e\u4e8e\u5f53\u524d\u7ebf\u7a0b\u7684 ostringstream \uff0c\u6700\u540e\u4e00\u6b21\u6027\u8c03\u7528\u4e00\u6b21 cout \u7684 operator<< \uff0c\u8ba9\u201c\u539f\u5b50\u201d\u7684\u5355\u4f4d\u53d8\u6210\u201c\u4e00\u884c\u201d\u800c\u4e0d\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 ostringstream oss; oss << \"the answer is \" << 42 << '\\n'; cout << oss.str(); \u6216\u8005\uff0c\u4f7f\u7528 std::format \uff1a cout << std::format(\"the answer is {}\\n\", 42); \u603b\u4e4b\uff0c\u5c31\u662f\u8981\u8ba9 operator<< \u53ea\u6709\u4e00\u6b21\uff0c\u81ea\u7136\u5c31\u662f\u6ca1\u6709\u4ea4\u9519\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u6539\u7528 std::osyncstream(std::cout) \u4ee3\u66ff std::cout : std::osyncstream(std::cout) << \"the answer is \" << 42 << '\\n'; std::osyncstream \u53ef\u4ee5\u4fdd\u8bc1\uff1a1. \u4e0d\u4f1a\u4ea7\u751f\u6570\u636e\u7ade\u4e89\uff1b2. \u4e0d\u4f1a\u53d1\u751f\u7a7f\u63d2\u548c\u622a\u65ad\u3002\u53ef\u4ee5\u7406\u89e3\u4e3a std::osyncstream \u5728\u6784\u9020\u65f6\u5bf9\u7f13\u51b2\u533a\u4e0a\u9501\uff0c\u5728\u6790\u6784\u65f6\u89e3\u9501\u3002 \u5982\u679c\u4f60\u7684\u6807\u51c6\u5e93\u652f\u6301 C++23\uff0c\u8fd8\u53ef\u4ee5\u7528 std::println \uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8f93\u51fa\u4e5f\u662f\u539f\u5b50\u7684\uff08\u7b2c\u4e09\u65b9\u5e93\u5982 fmt::println \u4ea6\u53ef\uff09\uff1a std::println(\"the answer is {}\", 42);","title":"\u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f"},{"location":"cpp_tricks/#cerr-cout","text":"\u5982\u679c\u4f60\u7684\u76ee\u7684\u662f\u8c03\u8bd5\u548c\u62a5\u9519\uff0c\u53ef\u4ee5\u8003\u8651\u7528 cerr \uff01 \u4ed6\u4f1a\u5728\u6bcf\u6b21 << \u65f6\u5237\u65b0\uff0c cerr \u624d\u662f\u6700\u9002\u5408\u6253\u5370\u9519\u8bef\u548c\u8c03\u8bd5\u4fe1\u606f\u7684\u6d41\u3002 cout \u7684\u4f18\u70b9\u662f\u4e0d\u9700\u8981\u65f6\u523b\u5237\u65b0\uff0c\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 cout << \"hello\\n\"; cout << \"the answer is \"; cout << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cout << \"!\\n\"; // \u56e0\u4e3a\u8fd8\u6ca1\u6709\u62b5\u8fbe \\n \u4ea7\u751f\u5237\u65b0\u5c31\u5d29\u6e83\uff0c\u5bfc\u81f4\u4e4b\u524d\u5c1a\u672a\u5237\u65b0\u7684 the answer is 42 \u4e22\u5931 \u53ef\u80fd\u7684\u8f93\u51fa\uff1a hello[\u6362\u884c] cerr << \"hello\\n\"; cerr << \"the answer is \"; cerr << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cerr << \"!\\n\"; \u8f93\u51fa\uff1a hello[\u6362\u884c] the answer is 42 \u8fd8\u6709\u4e00\u4e2a\u7279\u70b9\uff1a cout \u8f93\u51fa\u5230\u201c\u6807\u51c6\u8f93\u51fa\u6d41\u201d\uff0c\u53ef\u4ee5\u88ab\u8f93\u51fa\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u7ba1\u9053\u3002\u800c cerr \u8f93\u51fa\u5230\u201c\u6807\u51c6\u9519\u8bef\u6d41\u201d\uff0c\u901a\u5e38\u4e0d\u4f1a\u88ab\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u6216\u7ba1\u9053\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u628a\u7a0b\u5e8f\u9884\u8ba2\u7684\u8ba1\u7b97\u7ed3\u679c\u5199\u5230 cout \uff0c\u628a\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5199\u5230 cerr \uff0c\u8fd9\u6837\u7528\u6237\u5c31\u53ef\u4ee5\u901a\u8fc7 > \u91cd\u5b9a\u5411\u8ba1\u7b97\u7ed3\u679c\uff0c\u800c\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5219\u6b63\u5e38\u8f93\u51fa\u5230\u5c4f\u5e55\u4e0a\uff0c\u4e0d\u53d7\u91cd\u5b9a\u5411\u5f71\u54cd\u3002 cout << \"1 3 5 7\\n\"; cerr << \"ERROR: this is an error message!\\n\"; cout << \"11 13 17 19\\n\"; $ g++ prime.cpp -o prime $ ./prime 1 3 5 7 ERROR: this is an error message! 11 13 17 19 $ ./prime > output.txt ERROR: this is an error message! $ cat output.txt 1 3 5 7 11 13 17 19","title":"cerr \u4e0e cout \u7684\u6289\u62e9"},{"location":"cpp_tricks/#_12","text":"\u6211\u4eec\u8bf4\u4e00\u4e2a\u7c7b\u578b\u5927\uff0c\u6709\u4e24\u79cd\u60c5\u51b5\u3002 \u7c7b\u672c\u8eab\u5f88\u5927\uff1a\u4f8b\u5982 array \u7c7b\u672c\u8eab\u4e0d\u5927\uff0c\u4f46\u5176\u6307\u5411\u7684\u5bf9\u8c61\u5927\uff0c\u4e14\u8be5\u7c7b\u662f\u6df1\u62f7\u8d1d\uff0c\u5bf9\u8be5\u7c7b\u7684\u62f7\u8d1d\u4f1a\u5f15\u8d77\u5176\u6307\u5411\u5bf9\u8c61\u7684\u62f7\u8d1d\uff1a\u4f8b\u5982 vector sizeof(array); // \u672c\u8eab 4000 \u5b57\u8282 sizeof(vector); // \u672c\u8eab 24 \u5b57\u8282\uff08\u6210\u5458\u662f 3 \u4e2a\u6307\u9488\uff09\uff0c\u6307\u5411\u7684\u6570\u7ec4\u53ef\u4ee5\u65e0\u9650\u589e\u5927 sizeof(vector) \u4e3a 24 \u5b57\u8282\u4ec5\u4e3a x86_64-pc-linux-gnu \u5e73\u53f0 libstdc++ \u5e93\u7684\u5b9e\u6d4b\u7ed3\u679c\uff0c\u5728 32 \u4f4d\u7cfb\u7edf\u4ee5\u53ca MSVC \u7684 Debug \u6a21\u5f0f STL \u4e0b\u53ef\u80fd\u5f97\u51fa\u4e0d\u540c\u7684\u7ed3\u679c\uff0c\u4e0d\u53ef\u4ee5\u4f9d\u8d56\u8fd9\u4e2a\u5e73\u53f0\u76f8\u5173\u7684\u7ed3\u679c\u6765\u7f16\u7a0b\u3002 \u5bf9\u4e8e vector\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 std::move \u79fb\u52a8\u8bed\u4e49\uff0c\u53ea\u62f7\u8d1d\u8be5\u7c7b\u672c\u8eab\u7684\u4e09\u4e2a\u6307\u9488\u6210\u5458\uff0c\u800c\u4e0d\u5bf9\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u6570\u7ec4\u8fdb\u884c\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e array\uff0c\u5219 std::move \u79fb\u52a8\u8bed\u4e49\u4e0e\u666e\u901a\u7684\u62f7\u8d1d\u6ca1\u6709\u533a\u522b\uff1aarray \u4f5c\u4e3a\u9759\u6001\u6570\u7ec4\u5bb9\u5668\uff0c\u4e0d\u662f\u901a\u8fc7\u201c\u6307\u9488\u6210\u5458\u201d\u6765\u4fdd\u5b58\u6570\u7ec4\u7684\uff0c\u800c\u662f\u76f4\u63a5\u628a\u6570\u7ec4\u5b58\u5728\u4ed6\u7684\u4f53\u5185\uff0c\u5bf9 array \u7684\u79fb\u52a8\u548c\u62f7\u8d1d\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff01 \u603b\u4e4b\uff0c\u79fb\u52a8\u8bed\u4e49\u7684\u52a0\u901f\u6548\u679c\uff0c\u53ea\u5bf9\u91c7\u7528\u4e86\u201c\u6307\u9488\u95f4\u63a5\u5b58\u50a8\u52a8\u6001\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08\u5982 vector\u3001map\u3001set\u3001string\uff09\u6709\u6548\u3002\u5bf9\u201c\u76f4\u63a5\u5b58\u50a8\u9759\u6001\u5927\u5c0f\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08array\u3001tuple\u3001variant\u3001\u6210\u529f\u201c\u5c0f\u5b57\u7b26\u4e32\u4f18\u5316\u201d\u7684 string\uff09\u65e0\u6548\u3002 \u6240\u4ee5\uff0c\u8ba9\u5f88\u591a\u201c\u79fb\u52a8\u8bed\u4e49\u201d\u5b5d\u5b50\u5931\u671b\u4e86\uff1a\u201c\u672c\u8eab\u5f88\u5927\u201d\u7684\u7c7b\uff0c\u79fb\u52a8\u548c\u62f7\u8d1d\u4e00\u6837\u6162\uff01 \u90a3\u4e48\u73b0\u5728\u6211\u4eec\u6709\u4e2a\u8d85\u5927\u7684\u7c7b\uff1a using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b vector arr; void func(BigType x) { arr.push_back(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } int main() { BigType x; func(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } \u5982\u4f55\u52a0\u901f\u8fd9\u79cd\u672c\u8eab\u8d85\u5927\u7684\u53d8\u91cf\u8f6c\u79fb\uff1f\u4f7f\u7528 const \u5f15\u7528\uff1a void func(BigType const &x) \u4f3c\u4e4e\u53ef\u4ee5\u907f\u514d\u4f20\u53c2\u65f6\u7684\u62f7\u8d1d\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u80fd\u907f\u514d push_back \u63a8\u5165 vector \u65f6\u6240\u4e0d\u5f97\u5df2\u7684\u62f7\u8d1d\u3002 \u5c0f\u6280\u5de7\uff1a\u6539\u7528 unique_ptr using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b using BigTypePtr = unique_ptr; vector arr; void func(BigTypePtr x) { arr.push_back(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488\uff0c\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u4e0d\u7528\u6df1\u62f7\u8d1d\u4e86\uff0c\u76f4\u63a5\u79fb\u52a8\u6240\u6709\u6743\u7ed9 vector \u91cc\u7684 BigTypePtr \u667a\u80fd\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } int main() { BigTypePtr x = make_unique(); // \u6ce8\u610f\uff1a\u7528\u667a\u80fd\u6307\u9488\u7684\u8bdd\uff0c\u9700\u8981\u7528 make_unique \u624d\u80fd\u521b\u5efa\u5bf9\u8c61\u4e86 func(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } \u4e0a\u9762\u6574\u4e2a\u7a0b\u5e8f\u4e2d\uff0c\u4e00\u5f00\u59cb\u901a\u8fc7 make_unique \u521b\u5efa\u7684\u8d85\u5927\u5bf9\u8c61\uff0c\u5168\u7a0b\u6ca1\u6709\u53d1\u751f\u4efb\u4f55\u79fb\u52a8\uff0c\u907f\u514d\u4e86\u65e0\u8c13\u7684\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u6765\u8bf4\uff0c\u4e5f\u53ef\u4ee5\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u5c31\u80fd\u5728\u51fd\u6570\u4e4b\u95f4\u7a7f\u68ad\u81ea\u5982\u4e86\u3002 // \u70ed\u77e5\u8bc6\uff1astd::mutex \u4e0d\u652f\u6301\u79fb\u52a8 void func(std::mutex lock); int main() { std::mutex lock; func(std::move(lock)); // \u9519\u8bef\uff1amutex(mutex &&) = delete } void func(std::unique_ptr lock); int main() { std::unique_ptr lock = std::make_unique(); func(std::move(lock)); // OK\uff1a\u8c03\u7528\u7684\u662f unique_ptr(unique_ptr &&)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b } \u66f4\u597d\u7684\u662f shared_ptr \uff0c\u8fde std::move \u90fd\u4e0d\u7528\u5199\uff0c\u66f4\u7701\u5fc3\u3002 void func(std::shared_ptr lock); int main() { std::shared_ptr lock = std::make_shared(); func(lock); // OK\uff1a\u8c03\u7528\u7684\u662f shared_ptr(shared_ptr const &)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b func(lock); // OK\uff1ashared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\uff0c\u5373\u4f7f\u6d45\u62f7\u8d1d\u53d1\u751f\u591a\u6b21\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4e5f\u4e0d\u4f1a\u88ab\u62f7\u8d1d\u6216\u79fb\u52a8 }","title":"\u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8"},{"location":"cpp_tricks/#optional","text":"\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u7c7b\uff0c\u5177\u6709\u81ea\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\uff0c\u4e14\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a struct SomeClass { int m_i; int m_j; SomeClass(int i, int j) : m_i(i), m_j(j) {} }; \u5f53\u6211\u4eec\u9700\u8981\u201c\u5ef6\u8fdf\u521d\u59cb\u5316\u201d\u65f6\u600e\u4e48\u529e\uff1f SomeClass c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c); \u53ef\u4ee5\u5229\u7528 optional \u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u201c\u7a7a\u201d\u7684\u7279\u6027\uff0c\u5b9e\u73b0\u5ef6\u8fdf\u8d4b\u503c\uff1a std::optional c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c.value()); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u5c31\u4f1a\u62a5\u9519\uff0c\u4ece\u800c\u628a\u7f16\u8bd1\u671f\u7684\u672a\u521d\u59cb\u5316\u8f6c\u6362\u4e3a\u8fd0\u884c\u65f6\u5f02\u5e38 \u5c31\u7c7b\u4f3c\u4e8e Python \u4e2d\u5148\u7ed9\u53d8\u91cf\u8d4b\u503c\u4e3a None\uff0c\u7136\u540e\u5728\u5faa\u73af\u6216 if \u91cc\u6761\u4ef6\u6027\u5730\u8d4b\u503c\u4e00\u6837\u3002 \u5982\u679c\u8981\u8fdb\u4e00\u6b65\u907f\u514d c = \u65f6\uff0c\u79fb\u52a8\u6784\u9020\u7684\u5f00\u9500\uff0c\u4e5f\u53ef\u4ee5\u7528 unique_ptr \u6216 shared_ptr \uff1a std::shared_ptr c; if (test()) { c = std::make_shared(1, 2); } else { c = std::make_shared(2, 3); } do_something(c); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u90a3\u4e48\u4f20\u5165\u7684\u5c31\u662f\u4e00\u4e2a nullptr\uff0cdo_something \u5185\u90e8\u9700\u8981\u8d1f\u8d23\u68c0\u6d4b\u6307\u9488\u662f\u5426\u4e3a nullptr \u5982\u679c do_something \u53c2\u6570\u9700\u8981\u7684\u662f\u539f\u59cb\u6307\u9488\uff0c\u53ef\u4ee5\u7528 .get() \u83b7\u53d6\u51fa\u6765\uff1a do_something(c.get()); // .get() \u53ef\u4ee5\u628a\u667a\u80fd\u6307\u9488\u8f6c\u6362\u56de\u539f\u59cb\u6307\u9488\uff0c\u4f46\u8bf7\u6ce8\u610f\u539f\u59cb\u6307\u9488\u4e0d\u6301\u6709\u5f15\u7528\uff0c\u4e0d\u4f1a\u5ef6\u4f38\u6307\u5411\u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5b9e\u9645\u4e0a\uff0cJava\u3001Python \u4e2d\u7684\u4e00\u5207\u5bf9\u8c61\uff08\u9664 int\u3001str \u7b49\u201c\u94a6\u5b9a\u201d\u7684\u57fa\u7840\u7c7b\u578b\u5916\uff09\u90fd\u662f\u5f15\u7528\u8ba1\u6570\u7684\u667a\u80fd\u6307\u9488 shared_ptr \uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u4e00\u5207\u7686\u6307\u9488\u4e86\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u597d\u50cf\u6ca1\u6709\u6307\u9488\u4e86\u3002","title":"optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316"},{"location":"cpp_tricks/#if-auto-while-auto","text":"\u9700\u8981\u5148\u5b9a\u4e49\u4e00\u4e2a\u53d8\u91cf\uff0c\u7136\u540e\u5224\u65ad\u67d0\u4e9b\u6761\u4ef6\u7684\u60c5\u51b5\uff0c\u975e\u5e38\u5e38\u89c1\uff1a extern std::optional some_func(); auto opt = some_func(); if (opt.has_value()) { std::cout << opt.value(); } C++17 \u5f15\u5165\u7684 if-auto \u8bed\u6cd5\uff0c\u53ef\u4ee5\u5c31\u5730\u4e66\u5199\u53d8\u91cf\u5b9a\u4e49\u548c\u5224\u65ad\u6761\u4ef6\uff1a extern std::optional some_func(); if (auto opt = some_func(); opt.has_value()) { std::cout << opt.value(); } \u5bf9\u4e8e\u652f\u6301 (bool)opt \u7684 optional \u7c7b\u578b\u6765\u8bf4\uff0c\u540e\u9762\u7684\u6761\u4ef6\u4e5f\u53ef\u4ee5\u7701\u7565\uff1a extern std::optional some_func(); if (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a auto opt = some_func(); if (opt) { std::cout << opt.value(); } \u7c7b\u4f3c\u7684\u8fd8\u6709 while-auto\uff1a extern std::optional some_func(); while (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a while (true) { auto opt = some_func(); if (!opt) break; std::cout << opt.value(); } if-auto \u6700\u5e38\u89c1\u7684\u914d\u5408\u83ab\u8fc7\u4e8e map.find\uff1a std::map table; int key = 42; if (auto it = table.find(key); it != table.end()) { std::cout << it->second << '\\n'; } else { std::cout << \"not found\\n\"; }","title":"if-auto \u4e0e while-auto"},{"location":"cpp_tricks/#bind-lambda","text":"\u4f17\u6240\u5468\u77e5\uff0c std::bind \u53ef\u4ee5\u4e3a\u51fd\u6570\u7ed1\u5b9a\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\uff08\u5bf9\u8c61\uff09\u3002 int func(int x, int y) { printf(\"func(%d, %d)\\n\", x, y); return x + y; } auto new_func = std::bind(func, 1, std::placeholders::_1); new_func(2); // \u8c03\u7528 new_func(2) \u65f6\uff0c\u5b9e\u9645\u4e0a\u8c03\u7528\u7684\u662f func(1, 2) } \u8f93\u51fa\uff1a func(1, 2) \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; };","title":"bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3"},{"location":"cpp_tricks/#bind","text":"\u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002","title":"bind \u7684\u5386\u53f2"},{"location":"cpp_tricks/#thread","text":"\u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42","title":"thread \u819d\u76d6\u4e2d\u7bad"},{"location":"cpp_tricks/#_13","text":"bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand();","title":"\u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50"},{"location":"cpp_tricks/#forward-fwd","text":"\u4f17\u6240\u5468\u77e5\uff0c\u5f53\u4f60\u5728\u8f6c\u53d1\u4e00\u4e2a\u201c\u4e07\u80fd\u5f15\u7528\u201d\u53c2\u6570\u65f6\uff1a template void some_func(Arg &&arg) { other_func(arg); } \u5982\u679c\u6b64\u5904 arg \u4f20\u5165\u7684\u662f\u53f3\u503c\u5f15\u7528\uff0c\u90a3\u4e48\u4f20\u5165 other_func \u5c31\u4f1a\u53d8\u56de\u5de6\u503c\u5f15\u7528\u4e86\uff0c\u4e0d\u7b26\u5408\u5b8c\u7f8e\u8f6c\u53d1\u7684\u8981\u6c42\u3002 \u56e0\u6b64\u5f15\u5165\u4e86 forward \uff0c\u4ed6\u4f1a\u68c0\u6d4b arg \u662f\u5426\u4e3a\u201c\u53f3\u503c\u201d\uff1a\u5982\u679c\u662f\uff0c\u5219 forward \u7b49\u4ef7\u4e8e move \uff1b\u5982\u679c\u4e0d\u662f\uff0c\u5219 forward \u4ec0\u4e48\u90fd\u4e0d\u505a\uff08\u9ed8\u8ba4\u5c31\u662f\u5de6\u503c\u5f15\u7528\uff09\u3002 \u8fd9\u5f04\u5f97 forward \u7684\u5916\u89c2\u975e\u5e38\u5177\u6709\u8ff7\u60d1\u6027\uff0c\u53c8\u662f\u5c16\u62ec\u53f7\u53c8\u662f\u5706\u62ec\u53f7\u7684\u3002 template void some_func(Arg &&arg) { other_func(std::forward(arg)); } \u5b9e\u9645\u4e0a\uff0cforward \u7684\u7528\u6cd5\u975e\u5e38\u5355\u4e00\uff1a\u6c38\u8fdc\u662f forward(t) \u7684\u5f62\u5f0f\uff0c\u5176\u4e2d T \u662f t \u53d8\u91cf\u7684\u7c7b\u578b\u3002 \u53c8\u662f\u52b3\u4fdd\u7684\u9b45\u529b\uff0c\u5229\u7528\u540c\u6837\u662f C++11 \u7684 decltype \u5c31\u80fd\u83b7\u5f97 t \u5b9a\u4e49\u65f6\u7684 T \u3002 void some_func(auto &&arg) { other_func(std::forward(arg)); } \u6240\u4ee5 std::forward(arg) \u5b9e\u9645\u624d\u662f forward \u7684\u6b63\u786e\u7528\u6cd5\uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u5927\u591a\u6570\u65f6\u5019\u4f60\u662f\u6a21\u677f\u53c2\u6570 Arg && \uff0c\u6709\u7684\u4eba\u5077\u61d2\uff0c\u5c31\u628a decltype(arg) \u66ff\u6362\u6210\u5df2\u7ecf\u5339\u914d\u597d\u7684\u6a21\u677f\u53c2\u6570 Arg \u4e86\uff0c\u5b9e\u9645\u4e0a\u662f\u7b49\u4ef7\u7684\u3002 \u8fd9\u91cc\u9700\u8981\u590d\u8bfb arg \u592a\u7eb1\u5e01\u4e86\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5b8f\uff1a #define FWD(arg) std::forward(arg) \u8fd9\u6837\u5c31\u53ef\u4ee5\u7b80\u5316\u4e3a\uff1a void some_func(auto &&arg) { other_func(FWD(arg)); } \u5c11\u4e86\u70e6\u4eba\u7684\u5c16\u62ec\u53f7\uff0c\u770b\u8d77\u6765\u5bb9\u6613\u61c2\u591a\u4e86\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u540c\u5b66\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u4e3a\u4ec0\u4e48 std::forward \u8981\u5199\u6210 std::forward \u7684\u5f62\u5f0f\u5462\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u662f std::forward(t) \u5462\uff1f\u56e0\u4e3a\u8fd9\u6837\u5199\u7684\u8bdd\uff0c forward \u4e5f\u6ca1\u6cd5\u77e5\u9053\u4f60\u7684 t \u662f\u5de6\u662f\u53f3\u4e86\uff08\u51fd\u6570\u53c2\u6570\u59cb\u7ec8\u4f1a\u9ed8\u8ba4\u63a8\u5bfc\u4e3a\u5de6\uff0c\u5373\u4f7f\u5b9a\u4e49\u7684 t \u662f\u53f3\uff09\u56e0\u6b64\u5fc5\u987b\u544a\u8bc9 forward \uff0c t \u7684\u5b9a\u4e49\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f T \uff0c\u6216\u8005\u901a\u8fc7 decltype(t) \u6765\u83b7\u5f97 T \u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7528\u7684\u662f auto && \u53c2\u6570\uff0c\u90a3\u4e48 FWD \u4f1a\u5f88\u65b9\u4fbf\uff08\u81ea\u52a8\u5e2e\u4f60 decltype \uff09\u3002\u4f46\u662f\u5982\u679c\u4f60\u7528\u7684\u662f\u6a21\u677f\u53c2\u6570 T && \uff0c\u90a3\u4e48 FWD \u4e5f\u53ef\u4ee5\u7528\uff0c\u56e0\u4e3a decltype(t) \u603b\u662f\u5f97\u5230 T \u3002","title":"forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f"},{"location":"cpp_tricks/#bind-lambda-bind_front","text":"\u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408\u4e0a\u6587\u63d0\u5230\u7684 FWD \u5b8f\u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(FWD(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u540c\u6837\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u79f0\u624b\u7684\u5b8f\uff1a #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } \u8fd9\u91cc\u4f7f\u7528\u4e86\u5b8f\u53c2\u6570\u5305\uff0c\u6b64\u5904 __VA_ARGS__ \u5c31\u662f\u5b8f\u7684 ... \u4e2d\u7684\u5185\u5bb9\u3002\u6ce8\u610f\u533a\u5206\u5b8f\u7684 ... \u548c C++ \u53d8\u957f\u6a21\u677f\u7684 ... \u662f\u4e92\u76f8\u72ec\u7acb\u7684\u3002 struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = BIND(world, this); int x = 1; memfn(x, 2); memfn(3.14); } } int main() { // \u6355\u83b7\u975e this \u7684\u6210\u5458\u51fd\u6570\u4e5f OK\uff1a Class c; auto memfn = BIND(c.world, &c); // [&c] \u6309\u5f15\u7528\u6355\u83b7 c \u53d8\u91cf // \u5c55\u5f00\u4e3a\uff1a auto memfn = [&c] (auto &&..._args) { c.world(std::forward(_args)...); } memfn(3.14); } BIND \u8fd9\u4e2a\u540d\u5b57\u662f\u968f\u4fbf\u53d6\u7684\uff0c\u53d6\u8fd9\u4e2a\u540d\u5b57\u662f\u4e3a\u4e86\u8fb1 std::bind \u3002 \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u8fd8\u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f","title":"bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front"},{"location":"cpp_tricks/#_14","text":"\u5f53\u4f60\u7684\u5168\u5c40\u51fd\u6570\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6216\u5e26\u6709\u91cd\u8f7d\u7684\u51fd\u6570\u65f6\uff1a template T square(T const t) { return t * t; } template void do_something(Fn &&fn) { fn(2); fn(3.14); } int main() { do_something(square); // \u7f16\u8bd1\u9519\u8bef\uff1a\u6709\u6b67\u4e49\u7684\u91cd\u8f7d } \u5c31\u4f1a\u51fa\u73b0\u8fd9\u6837\u607c\u4eba\u7684\u7f16\u8bd1\u9519\u8bef\uff1a test.cpp: In instantiation of 'void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]': test.cpp:18:21: required from here test.cpp:14:9: error: no matching function for call to 'do_something()' do_something(square); ^~~~~~~~~~~~~ test.cpp:7:3: note: candidate: 'template void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]' void do_something(Fn &&fn) { ^~~~~~~~~~~~~ test.cpp:7:3: note: template argument deduction/substitution failed: test.cpp:14:21: note: couldn't deduce template parameter 'Fn' do_something(square); ~~~~~~~~~~~~~^~~~~~ \u8fd9\u662f\u56e0\u4e3a\uff0c\u6a21\u677f\u51fd\u6570\u548c\u6709\u91cd\u8f7d\u7684\u51fd\u6570\uff0c\u662f\u201c\u591a\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u201c\u5e7b\u60f3\u8054\u5408\u4f53\u201d\uff0c\u800c do_something \u7684 Fn \u9700\u8981\u201c\u5355\u4e2a\u201d\u5177\u4f53\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u4e00\u822c\u6765\u8bf4\u662f\u9700\u8981 square \u548c square \u624d\u80fd\u53d8\u6210\u201c\u5177\u4f53\u201d\u7684\u201c\u5355\u4e2a\u201d\u51fd\u6570\u5bf9\u8c61\uff0c\u4f20\u5165 do_something \u7684 Fn \u6a21\u677f\u53c2\u6570\u3002 \u4f46\u662f\u5728\u201c\u51fd\u6570\u8c03\u7528\u201d\u7684\u8bed\u5883\u4e0b\uff0c\u56e0\u4e3a\u5df2\u77e5\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u5f97\u76ca\u4e8e C++ \u7684\u201c\u91cd\u8f7d\u201d\u673a\u5236\uff0c\u5e26\u6709\u6a21\u677f\u53c2\u6570\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u81ea\u52a8\u5339\u914d\u90a3\u4e2a\u6a21\u677f\u53c2\u6570\u4e3a\u4f60\u53c2\u6570\u7684\u7c7b\u578b\u3002 \u4f46\u73b0\u5728\u4f60\u5e76\u6ca1\u6709\u6307\u5b9a\u8c03\u7528\u53c2\u6570\uff0c\u800c\u53ea\u662f\u6307\u5b9a\u4e86\u4e00\u4e2a\u51fd\u6570\u540d square \uff0c\u90a3 C++ \u201c\u91cd\u8f7d\u201d\u673a\u5236\u65e0\u6cd5\u786e\u5b9a\u4f60\u9700\u8981\u7684\u662f square \u8fd8\u662f square \u4e2d\u7684\u54ea\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u4ed6\u4eec\u7684\u7c7b\u578b\u90fd\u4e0d\u540c\uff0c\u5c31\u65e0\u6cd5\u5177\u8c61\u82b1\u51fa\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b Fn \u6765\uff0c\u5bfc\u81f4 \u9519\u8bef\u3002 \u6709\u8da3\u7684\u662f\uff0c\u53ea\u9700\u8981\u5957\u4e00\u5c42 lambda \u5c31\u80fd\u89e3\u51b3\uff1a do_something([] (auto x) { return square(x); }); // \u7f16\u8bd1\u901a\u8fc7 \u6216\u8005\u7528\u6211\u4eec\u4e0a\u9762\u63a8\u8350\u7684 BIND \u5b8f\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } do_something(BIND(square)); // \u7f16\u8bd1\u901a\u8fc7 \u6709\u65f6\u5019\uff0c\u5982\u679c\u4f60\u60f3\u4f20\u9012 this \u7684\u6210\u5458\u51fd\u6570\u4e3a\u51fd\u6570\u5bf9\u8c61\uff0c\u4e5f\u4f1a\u51fa\u73b0\u8fd9\u79cd\u607c\u4eba\u7684\u9519\u8bef\uff1a struct Class { int func(int x) { return x + 1; } void test() { do_something(this->func); // \u8fd9\u91cc\u53c8\u4f1a\u4ea7\u751f\u70e6\u4eba\u7684 unresolved overload \u9519\u8bef\uff01 } }; \u540c\u6837\u53ef\u4ee5\u5305\u4e00\u5c42 lambda\uff0c\u6216\u8005\u7528\u5c0f\u5f6d\u8001\u5e08\u63d0\u4f9b\u7684 BIND \u5b8f\uff0c\u9ebb\u75f9\u7684\u7f16\u8bd1\u5668\u5c31\u4e0d\u72d7\u53eb\u4e86\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } void test() { do_something(BIND(func, this)); // \u641e\u5b9a } \u5efa\u8bae\u4fee\u6539\u6807\u51c6\u5e93\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u8fd9\u4e24\u4e2a\u771f\u6b63\u597d\u7528\u7684\u5b8f\u585e\u5230 \u548c \u91cc\uff0c\u4f5c\u4e3a C++26 \u6807\u51c6\u7684\u4e00\u90e8\u5206\u3002","title":"\u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f"},{"location":"cpp_tricks/#map-any","text":"TODO","title":"map + any \u5916\u6302\u5c5e\u6027"},{"location":"cpp_tricks/#shared_ptr-deleter","text":"","title":"\u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter"},{"location":"cpp_tricks/#check_cuda","text":"","title":"CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f"},{"location":"cpp_tricks/#_15","text":"","title":"\u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005"},{"location":"cpp_tricks/#locale-utf8","text":"","title":"\u8bbe\u7f6e locale \u4e3a .utf8"},{"location":"cpp_tricks/#_16","text":"","title":"\u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5"},{"location":"cpp_tricks/#this","text":"","title":"\u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d"},{"location":"cpp_tricks/#check_cuda_1","text":"","title":"CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f"},{"location":"cpp_tricks/#_17","text":"","title":"\u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005"},{"location":"cpp_tricks/#_18","text":"","title":"\u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5"},{"location":"cpp_tricks/#_19","text":"C++ \u6709\u4e2a\u7279\u6027\uff1a\u652f\u6301\u7eaf\u53f3\u503c(prvalue)\u9690\u5f0f\u8f6c\u6362\u6210 const \u7684\u5de6\u503c\u5f15\u7528\u3002 \u7ffb\u8bd1\uff1a int && \u53ef\u4ee5\u81ea\u52a8\u8f6c\u6362\u6210 int const & \u3002 void func(int const &i); func(1); // OK\uff1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u53d8\u91cf\u4fdd\u5b58 1\uff0c\u7136\u540e\u4f5c\u4e3a int const & \u53c2\u6570\u4f20\u5165 \u5b9e\u9645\u4e0a\u5c31\u7b49\u4ef7\u4e8e\uff1a const int tmp = 1; func(tmp); \u4f46\u662f\uff0c int && \u5374\u4e0d\u80fd\u81ea\u52a8\u8f6c\u6362\u6210 int & \u3002 void func(int &i); func(1); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece int && \u81ea\u52a8\u8f6c\u6362\u6210 int & C++ \u5b98\u65b9\u8bbe\u7f6e\u8fd9\u4e2a\u9650\u5236\uff0c\u662f\u51fa\u4e8e\u8bed\u4e49\u5b89\u5168\u6027\u8003\u8651\uff0c\u56e0\u4e3a\u53c2\u6570\u63a5\u53d7 int & \u7684\uff0c\u4e00\u822c\u90fd\u610f\u5473\u7740\u8fd9\u4e2a\u662f\u7528\u4f5c\u8fd4\u56de\u503c\uff0c\u800c\u5982\u679c func \u7684\u53c2\u6570\u662f\uff0c func(1) \u3002 \u4e3a\u4e86\u7ed5\u5f00\u8fd9\u4e2a\u89c4\u5219\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5e2e\u624b\u51fd\u6570\uff1a T &temporary(T const &t) { return const_cast(t); } // \u6216\u8005\uff1a T &temporary(T &&t) { return const_cast(t); } \u7136\u540e\uff0c\u5c31\u53ef\u4ee5\u5feb\u4e50\u5730\u8f6c\u6362\u7eaf\u53f3\u503c\u4e3a\u975e const \u5de6\u503c\u4e86\uff1a void func(int &i); func(temporary(1)); \u5728 Libreoffice \u6e90\u7801\u4e2d\u5c31\u6709\u5e94\u7528\u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\u3002 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c","title":"\u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c"},{"location":"cpp_tricks/#ostringstream","text":"std::string name = \"\u4f60\u597d\"; int answer = 42; auto str = std::format(\"\u4f60\u597d\uff0c{}\uff01\u7b54\u6848\u662f {}\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x{:02x}\\n\", name, answer, answer); \u6ca1\u6709 C++20 \u4e4b\u524d\uff0c\u8981\u4e48\u4f7f\u7528\u7b2c\u4e09\u65b9\u7684 fmt::format \uff0c\u8981\u4e48\u53ea\u80fd\u4f7f\u7528\u5b57\u7b26\u4e32\u7684 + \u8fd0\u7b97\u7b26\u62d9\u52a3\u5730\u62fc\u63a5\uff1a auto str = std::string(\"\u4f60\u597d\uff0c\") + name + \"\uff01\u7b54\u6848\u662f \" + std::to_string(answer) + \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" + std::to_string(answer) + \"\\n\"; \u8fd9\u6837\u505a\u6548\u7387\u4f4e\u4e0b\uff0c\u4e14\u4e0d\u6613\u9605\u8bfb\u3002\u800c\u4e14\u4e5f\u65e0\u6cd5\u5b9e\u73b0\u6570\u5b57\u6309\u201c\u5341\u516d\u8fdb\u5236\u201d\u8f6c\u5b57\u7b26\u4e32\u3002 \u53ef\u4ee5\u7528 std::ostringstream \uff0c\u5176\u7528\u6cd5\u4e0e std::cout \u76f8\u540c\u3002\u53ea\u4e0d\u8fc7\u4f1a\u628a\u7ed3\u679c\u5199\u5165\u4e00\u4e2a\u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f\u76f4\u63a5\u8f93\u51fa\uff09\uff0c\u53ef\u4ee5\u7528 .str() \u53d6\u51fa\u90a3\u4e2a\u5b57\u7b26\u4e32\u3002 #include std::ostringstream oss; oss << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\"; auto str = oss.str(); \u5229\u7528\u4e34\u65f6\u53d8\u91cf\u8bed\u6cd5\uff0c\u53ef\u4ee5\u6d53\u7f29\u5199\u5728\u4e00\u884c\u91cc\uff0c\u505a\u4e2a format \u62d9\u52a3\u7684\u6a21\u4eff\u8005\uff1a auto str = (std::ostringstream() << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\").str();","title":"ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32"},{"location":"cpp_tricks/#adl","text":"TODO","title":"ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001"},{"location":"cpp_tricks/#shared_from_this","text":"","title":"shared_from_this"},{"location":"cpp_tricks/#requires","text":"","title":"requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570"},{"location":"cpp_tricks/#locale-utf8-windows","text":"system(\"chcp 65001\"); setlocale(\"LC_ALL\", \".utf-8\"); \u8be6\u89c1 Unicode \u4e13\u9898\u7ae0\u8282 \u3002","title":"\u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898"},{"location":"cpp_tricks/#this_1","text":"","title":"\u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d"},{"location":"cpp_tricks/#bit-field","text":"\u5728\u4e92\u8054\u7f51\u7f16\u7a0b\u548c\u5404\u79cd\u4e0e\u786c\u76d8\u3001\u5e8f\u5217\u5316\u6253\u4ea4\u9053\u7684\u573a\u666f\u4e2d\uff0c\u5e38\u5e38\u9700\u8981\u6309\u4f4d\u62c6\u5206\u5355\u4e2a\u5b57\u8282\u3002 C \u8bed\u8a00\u6709\u4e13\u95e8\u7167\u987e\u6b64\u7c7b\u5de5\u4f5c\u7684\u8bed\u6cd5\u7cd6\uff1a\u4f4d\u57df\u3002 \u4f4d\u57df\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u7ed3\u6784\u4f53\u6210\u5458\uff0c\u53ef\u4ee5\u5bf9\u4f4d\u8fdb\u884c\u5206\u7ec4\uff0c\u65b9\u4fbf\u8bfb\u53d6\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u4ece\u4e00\u4e2a\u5b57\u8282\u4e2d\u8bfb\u53d6\u4e09\u4e2a\u72b6\u6001\u4f4d\uff1a struct Flag { uint8_t a : 4; // \u4f4e 4 \u4f4d uint8_t b : 4; // \u9ad8 4 \u4f4d }; sizeof(Flag); // 1 \u5b57\u8282\u5927\u5c0f\uff08\u5171 8 \u4f4d\uff09 Flag f = std::bit_cast(0x21); f.a; // 0x1 f.b; // 0x2 \u4ee5\u4e0a\u7684\u4ee3\u7801\u7b49\u4ef7\u4e8e\uff1a uint8_t f = 0x21; int a = f & 0xF; // 0x1 int b = f >> 4; // 0x2","title":"\u4f4d\u57df\uff08bit-field\uff09"},{"location":"cpp_tricks/#vector-unordered_map-lru-cache","text":"","title":"vector + unordered_map = LRU cache"},{"location":"cpp_tricks/#lambda-unique_ptr-function","text":"","title":"Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e"},{"location":"cpp_tricks/#_20","text":"","title":"\u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf"},{"location":"cpp_tricks/#raii-finally","text":"","title":"RAII \u7684 finally \u5e2e\u624b\u7c7b"},{"location":"cpp_tricks/#swap-mutex","text":"","title":"swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7"},{"location":"cpp_tricks/#namespace","text":"\u6709\u4e9b\u5d4c\u5957\u5f88\u6df1\u7684\u540d\u5b57\u7a7a\u95f4\u6bcf\u6b21\u90fd\u8981\u590d\u8bfb\u975e\u5e38\u5570\u55e6\u3002 #include int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u5982\u679c using namespace \u7684\u8bdd\uff0c\u53c8\u89c9\u5f97\u6c61\u67d3\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\u4e86\u3002 #include using namespace std::filesystem; int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u53ef\u4ee5\u7528 C++11 \u7684 namespace = \u8bed\u6cd5\uff0c\u7ed9\u540d\u5b57\u7a7a\u95f4\u53d6\u4e2a\u522b\u540d\u3002 #include namespace fs = std::filesystem; int main() { fs::path p = \"/var/www/html\"; ... } \u8fd9\u6837\u4ee5\u540e\u5c31\u53ef\u4ee5 fs \u8fd9\u4e2a\u7b80\u79f0\u8bbf\u95ee\u4e86\u3002","title":"namespace \u522b\u540d"},{"location":"cuda_intro/","text":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u5b89\u88c5 CUDA \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 CUDA C++ \u7248\u672c \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u521b\u5efa CUDA \u9879\u76ee CMake \u914d\u7f6e\u603b\u7ed3 \u5f00\u59cb\u7f16\u5199 CUDA \u53c2\u8003\u8d44\u6599\uff1a https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html https://www.cs.sfu.ca/~ashriram/Courses/CS431/assets/lectures/Part8/GPU1.pdf \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u786c\u4ef6\u65b9\u9762\u5efa\u8bae\u4f7f\u7528\u81f3\u5c11 GTX 1060 \u4ee5\u4e0a\u663e\u5361\uff0c\u4f46\u662f\u66f4\u8001\u7684\u663e\u5361\u4e5f\u53ef\u4ee5\u8fd0\u884c\u3002 \u8f6f\u4ef6\u65b9\u9762\u5219\u53ef\u4ee5\u5c3d\u53ef\u80fd\u6700\u65b0\uff0c\u4ee5\u83b7\u5f97 CUDA C++20 \u652f\u6301\uff0c\u6211\u5b89\u88c5\u7684\u7248\u672c\u662f CUDA 12.5\u3002 \u4ee5\u4e0b\u4ec5\u6f14\u793a Arch Linux \u4e2d\u5b89\u88c5 CUDA \u7684\u65b9\u6cd5\uff0c\u56e0\u4e3a Arch Linux \u5b98\u65b9\u6e90\u4e2d\u5c31\u81ea\u5e26 nvidia \u9a71\u52a8\u548c cuda \u5305\uff0c\u800c\u4e14\u5f00\u7bb1\u5373\u7528\uff0c\u5176\u4ed6\u53d1\u884c\u7248\u8bf7\u81ea\u884c\u5982\u6cd5\u70ae\u5236\u3002 Wendous \u7528\u6237\u53ef\u80fd\u5728\u5b89\u88c5\u5b8c\u540e\u9047\u5230\u201c\u627e\u4e0d\u5230 cuxxx.dll\u201d\u62a5\u9519\uff0c\u8bf4\u660e\u4f60\u9700\u8981\u62f7\u8d1d CUDA \u5b89\u88c5\u76ee\u5f55\u4e0b\u7684\u6240\u6709 DLL \u5230 C:\\\\Windows\\\\System32 \u3002 WSL \u7528\u6237\u8981\u6ce8\u610f\uff0cWSL \u73af\u5883\u548c\u771f\u6b63\u7684 Linux \u76f8\u5dee\u751a\u8fdc\u3002\u5f88\u591a Linux \u4e0b\u7684\u6559\u7a0b\uff0c\u4f60\u4f1a\u53d1\u73b0\u5728 WSL \u91cc\u590d\u523b\u4e0d\u51fa\u6765\u3002\u8fd9\u662f WSL \u7684 bug\uff0c\u5e94\u8be5\u6c47\u62a5\u53bb\u8ba9\u5fae\u8f6f\u7edf\u4e00\u4fee\u590d\uff0c\u800c\u4e0d\u662f\u8ba9\u6559\u7a0b\u7684\u4f5c\u8005\u96f6\u96f6\u6563\u6563\u4e00\u4e2a\u4e2a\u4ee3\u5b83\u64e6\u5c41\u80a1\u3002\u5efa\u8bae\u76f4\u63a5\u5728 Wendous \u672c\u5730\u5b89\u88c5 CUDA \u53cd\u800c\u6bd4\u4f3a\u5019 WSL \u968f\u673a\u62c9\u7684 bug \u7701\u529b\u3002 Ubuntu \u7528\u6237\u53ef\u80fd\u8003\u8651\u5378\u8f7d Ubuntu\uff0c\u56e0\u4e3a Ubuntu \u6e90\u4e2d\u7684\u7248\u672c\u6c38\u4e0d\u66f4\u65b0\u3002\u60f3\u8981\u5b89\u88c5\u65b0\u51fa\u7684\u8f6f\u4ef6\u90fd\u975e\u5e38\u56f0\u96be\uff0c\u57fa\u672c\u53ea\u80fd\u5b89\u88c5\u5230\u4e94\u516d\u5e74\u524d\u7684\u53e4\u8463\u8f6f\u4ef6\uff0c\u8981\u4e48\u53ea\u80fd\u4ece\u7f51\u4e0a\u4e0b deb \u5305\uff0c\u548c Wendous \u4e00\u4e2a\u8f6f\u8038\u6837\u3002\u6240\u6709\u5b98\u65b9 apt \u6e90\u4e2d\u5305\u7684\u7248\u672c\u4ece Ubuntu \u53d1\u5e03\u90a3\u4e00\u5929\u5c31\u5b9a\u6b7b\u4e86\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u66f4\u65b0\u4e86\u3002\u8fd9\u662f\u4e3a\u4e86\u8d77\u591c\u7ea7\u670d\u52a1\u5668\u5b89\u5168\u7a33\u5b9a\u7684\u9700\u8981\uff0c\u5bf9\u4e8e\u4e2a\u4eba\u7535\u8111\u800c\u8a00\u5374\u53ea\u662f\u767d\u767d\u963b\u788d\u6211\u4eec\u5b66\u4e60\uff0cArch Linux \u8fd9\u6837\u7684\u6eda\u52a8\u66f4\u65b0\u7684\u53d1\u884c\u7248\u624d\u66f4\u9002\u5408\u4e2a\u4eba\u684c\u9762\u7528\u6237\u3002 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u9996\u5148\u786e\u4fdd\u4f60\u5b89\u88c5\u4e86 NVIDIA \u6700\u65b0\u9a71\u52a8\uff1a pacman -S nvidia \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u786e\u8ba4\u663e\u5361\u9a71\u52a8\u6b63\u5e38\u5de5\u4f5c\uff1a nvidia-smi \u5e94\u8be5\u80fd\u5f97\u5230\uff1a Mon Aug 26 14:09:15 2024 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 555.58.02 Driver Version: 555.58.02 CUDA Version: 12.5 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4070 ... Off | 00000000:01:00.0 On | N/A | | 0% 30C P8 17W / 285W | 576MiB / 16376MiB | 41% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 583 G /usr/lib/Xorg 370MiB | | 0 N/A N/A 740 G xfwm4 4MiB | | 0 N/A N/A 783 G /usr/lib/firefox/firefox 133MiB | | 0 N/A N/A 4435 G obs 37MiB | +-----------------------------------------------------------------------------------------+ \u5982\u679c\u4e0d\u884c\uff0c\u90a3\u5c31\u91cd\u542f\u3002 \u5b89\u88c5 CUDA \u7136\u540e\u5b89\u88c5 CUDA Toolkit\uff08\u5373 nvcc \u7f16\u8bd1\u5668\uff09\uff1a pacman -S cuda \u6253\u5f00 .bashrc \uff08\u5982\u679c\u4f60\u662f zsh \u7528\u6237\u5c31\u6253\u5f00 .zshrc \uff09\uff0c\u5728\u672b\u5c3e\u6dfb\u52a0\u4e24\u884c\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u662f\u9ed8\u8ba4\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # Arch Linux \u7528\u6237\u624d\u9700\u8981\u8fd9\u4e00\u884c \u7136\u540e\u91cd\u542f bash \uff0c\u6216\u8005\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u91cd\u8f7d\u73af\u5883\u53d8\u91cf\uff1a source .bashrc \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\u6d4b\u8bd5 CUDA \u7f16\u8bd1\u5668\u662f\u5426\u53ef\u7528\uff1a nvcc --version \u5e94\u8be5\u80fd\u5f97\u5230\uff1a nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2024 NVIDIA Corporation Built on Thu_Jun__6_02:18:23_PDT_2024 Cuda compilation tools, release 12.5, V12.5.82 Build cuda_12.5.r12.5/compiler.34385749_0 \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 CMake \u62a5\u9519\u627e\u4e0d\u5230 CUDA\uff1f\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # \u53ea\u6709 Arch Linux \u9700\u8981\u8fd9\u4e00\u884c IDE \u4f7f\u7528\u4e86 Clangd \u9759\u6001\u68c0\u67e5\u63d2\u4ef6\uff0c\u62a5\u9519\u4e0d\u8ba4\u8bc6 -forward-unknown-to-host-compiler \u9009\u9879\uff1f \u521b\u5efa\u6587\u4ef6 ~/.config/clangd/config.yaml \uff1a CompileFlags: Add: # \u8981\u989d\u5916\u6dfb\u52a0\u5230 Clang \u7684 NVCC \u6ca1\u6709\u7684\u53c2\u6570 - --no-cuda-version-check Remove: # \u79fb\u9664 Clang \u4e0d\u8ba4\u8bc6\u7684 NVCC \u53c2\u6570 - -forward-unknown-to-host-compiler - --expt-* - --generate-code=* - -arch=* - -rdc=* \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 \u5982\u679c\u4f60\u65e0\u6cd5\u641e\u5b9a\u73af\u5883\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 CMAKE_CUDA_COMPILER \u76f4\u63a5\u8bbe\u7f6e nvcc \u7f16\u8bd1\u5668\u7684\u8def\u5f84\uff1a set(CMAKE_CUDA_COMPILER \"/opt/cuda/bin/nvcc\") # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e \u4e0d\u5efa\u8bae\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a\u4f1a\u8ba9\u4f7f\u7528\u4f60\u9879\u76ee\u7684\u4eba\u4e5f\u88ab\u8feb\u628a CUDA \u5b89\u88c5\u5230\u8fd9\u4e2a\u8def\u5f84\u53bb\u3002 \u5efa\u8bae\u662f\u628a\u4f60\u7684 nvcc \u5b89\u88c5\u597d\u540e\uff0c\u901a\u8fc7 PATH \u73af\u5883\u53d8\u91cf\uff0c cmake \u5c31\u80fd\u627e\u5230\u4e86\uff0c\u4e0d\u9700\u8981\u8bbe\u7f6e\u8fd9\u4e2a\u53d8\u91cf\u3002 CUDA C++ \u7248\u672c CUDA \u662f\u4e00\u79cd\u57fa\u4e8e C++ \u7684\u9886\u57df\u7279\u5b9a\u8bed\u8a00\uff0cCUDA C++ \u7684\u7248\u672c\u548c\u6b63\u89c4 C++ \u4e00\u4e00\u5bf9\u5e94\u3002 \u76ee\u524d\u6700\u65b0\u7684\u662f CUDA C++20\uff0c\u53ef\u4ee5\u5b8c\u5168\u4f7f\u7528 C++20 \u7279\u6027\u7684\u540c\u65f6\u4e66\u5199 CUDA \u4ee3\u7801\u3002 \u5728 __host__ \u51fd\u6570\uff08\u672a\u7ecf\u7279\u6b8a\u4fee\u9970\u7684\u51fd\u6570\u9ed8\u8ba4\u5c31\u662f\u6b64\u7c7b\uff0c\u5728 CPU \u7aef\u6267\u884c\uff09\u4e2d\uff0cCUDA \u548c\u666e\u901a C++ \u6ca1\u6709\u533a\u522b\uff0c\u4efb\u4f55\u666e\u901a C++ \u4ee3\u7801\uff0c\u90fd\u53ef\u4ee5\u7528 CUDA \u7f16\u8bd1\u5668\u7f16\u8bd1\u3002 \u5728 __device__ \u51fd\u6570\uff08CUDA kernel\uff0c\u5728 GPU \u7aef\u6267\u884c\uff09\u4e2d\uff0c\u80fd\u4f7f\u7528\u7684\u51fd\u6570\u548c\u7c7b\u5c31\u6709\u4e00\u5b9a\u9650\u5236\u4e86\uff1a \u4f8b\u5982\u4f60\u4e0d\u80fd\u5728 __device__ \u51fd\u6570\u91cc\u4f7f\u7528\u4ec5\u9650 __host__ \u7528\u7684 std::cout \uff08\u4f46 printf \u53ef\u4ee5\uff0c\u56e0\u4e3a CUDA \u56e2\u961f\u4e3a\u4e86\u65b9\u4fbf\u7528\u6237\u8c03\u8bd5\uff0c\u4e3a\u4f60\u505a\u4e86 printf \u7684 __device__ \u7248\u7279\u5316\uff09\u3002 __device__ \u4e2d\u4e0d\u80fd\u4f7f\u7528\u7edd\u5927\u591a\u6570\u975e constexpr \u7684 STL \u5bb9\u5668\uff0c\u4f8b\u5982 std::map \u7b49\uff0c\u4f46\u662f\u5728 __host__ \u4fa7\u8fd8\u662f\u53ef\u4ee5\u7528\u7684\uff01 \u6240\u6709\u7684 constexpr \u51fd\u6570\u4e5f\u662f\u53ef\u4ee5\u4f7f\u7528\u7684\uff0c\u4f8b\u5982\u5404\u79cd C++ \u98ce\u683c\u7684\u6570\u5b66\u51fd\u6570\u5982 std::max \uff0c std::sin \uff0c\u8fd9\u4e9b\u51fd\u6570\u90fd\u662f constexpr \u7684\uff0c\u5728 __host__ \u548c __device__ \u90fd\u80fd\u7528\u3002 \u5982\u679c\u4e00\u4e2a\u5bb9\u5668\u7684\u6210\u5458\u5168\u662f constexpr \u7684\uff0c\u90a3\u4e48\u4ed6\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u3002\u4f8b\u5982 std::tuple \u3001 std::array \u7b49\u7b49\uff0c\u56e0\u4e3a\u4e0d\u6d89\u53ca I/O \u548c\u5185\u5b58\u5206\u914d\uff0c\u90fd\u662f\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528\u7684\u3002 \u4f8b\u5982 C++20 \u589e\u52a0\u4e86 constexpr-new \u7684\u652f\u6301\uff0c\u8ba9 std::vector \u548c std::string \u53d8\u6210\u4e86 constexpr \u7684\u5bb9\u5668\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528 std::vector \uff08\u4f1a\u7528\u5230 __device__ \u7248\u672c\u7684 malloc \u51fd\u6570\uff0c\u8fd9\u662f CUDA \u7684\u4e00\u5927\u7279\u8272\uff1a\u4f60\u53ef\u4ee5\u5728 kernel \u5185\u90e8\u7528 malloc \u52a8\u6001\u5206\u914d\u8bbe\u5907\u5185\u5b58\uff0c\u5e76\u4e14\u4ece CUDA C++20 \u5f00\u59cb new \u4e5f\u53ef\u4ee5\u4e86\uff09\u3002 std::variant \u73b0\u5728\u4e5f\u662f constexpr \u7684\u5bb9\u5668\uff0c\u4e5f\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u4e86\u3002 \u5f02\u5e38\u76ee\u524d\u8fd8\u4e0d\u662f constexpr \u7684\uff0c\u56e0\u6b64\u65e0\u6cd5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528 try/catch/throw \u7cfb\u5217\u5173\u952e\u5b57\u3002 \u603b\u4e4b\uff0c\u968f\u7740\uff0c\u6211\u4eec\u53ef\u4ee5\u671f\u5f85\u8d8a\u6765\u8d8a\u591a\u7eaf\u8ba1\u7b97\u7684\u51fd\u6570\u548c\u5bb9\u5668\u80fd\u5728 CUDA kernel\uff08 __device__ \u73af\u5883\uff09\u4e2d\u4f7f\u7528\u3002 \u6b63\u5982 CMAKE_CXX_STANDARD \u8bbe\u7f6e\u4e86 .cpp \u6587\u4ef6\u6240\u7528\u7684 C++ \u7248\u672c\uff0c\u4e5f\u53ef\u4ee5\u7528 CMAKE_CUDA_STANDARD \u8bbe\u7f6e .cu \u6587\u4ef6\u6240\u7528\u7684 CUDA C++ \u7248\u672c\u3002 set(CMAKE_CXX_STANDARD 20) # .cpp \u6587\u4ef6\u91c7\u7528\u7684 C++ \u7248\u672c\u662f C++20 set(CMAKE_CUDA_STANDARD 20) # .cu \u6587\u4ef6\u91c7\u7528\u7684 CUDA C++ \u7248\u672c\u662f C++20 \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") --expt-relaxed-constexpr : \u8ba9\u6240\u6709 constexpr \u51fd\u6570\u9ed8\u8ba4\u81ea\u52a8\u5e26\u6709 __host__ __device__ --expt-extended-lambda : \u5141\u8bb8\u4e3a lambda \u8868\u8fbe\u5f0f\u6307\u5b9a __host__ \u6216 __device__ \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u4e0d\u540c\u7684\u663e\u5361\u6709\u4e0d\u540c\u7684\u201c\u67b6\u6784\u7248\u672c\u53f7\u201d\uff0c\u67b6\u6784\u7248\u672c\u53f7\u5fc5\u987b\u4e0e\u4f60\u7684\u786c\u4ef6\u5339\u914d\u624d\u80fd\u6700\u4f73\u72b6\u6001\u8fd0\u884c\uff0c\u53ef\u4ee5\u7565\u4f4e\uff0c\u4f46\u5c06\u4e0d\u80fd\u53d1\u6325\u5b8c\u6574\u6027\u80fd\u3002 set(CMAKE_CUDA_ARCHITECTURES 86) # \u8868\u793a\u9488\u5bf9 RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\u751f\u6210 set(CMAKE_CUDA_ARCHITECTURES native) # \u5982\u679c CMake \u7248\u672c\u9ad8\u4e8e 3.24\uff0c\u8be5\u53d8\u91cf\u53ef\u4ee5\u8bbe\u4e3a \"native\"\uff0c\u8ba9 CMake \u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7 \u67b6\u6784\u7248\u672c\u53f7\uff1a\u4f8b\u5982 75 \u8868\u793a RTX 20xx \u7cfb\u5217\uff08Turing \u67b6\u6784\uff09\uff1b86 \u8868\u793a RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\uff1b89 \u8868\u793a RTX 40xx \u7cfb\u5217\uff08Ada \u67b6\u6784\uff09\u7b49\u3002 \u5b8c\u6574\u7684\u67b6\u6784\u7248\u672c\u53f7\u5217\u8868\u53ef\u4ee5\u5728 CUDA \u6587\u6863 \u4e2d\u627e\u5230\u3002 \u4e5f\u53ef\u4ee5\u8fd0\u884c\u5982\u4e0b\u547d\u4ee4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u67e5\u8be2\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7\uff1a __nvcc_device_query \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u9ed8\u8ba4\u53ea\u6709 __host__ \u51fd\u6570\u53ef\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002\u5982\u679c\u4f60\u9700\u8981\u5206\u79bb __device__ \u51fd\u6570\u7684\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u5c31\u8981\u5f00\u542f\u8fd9\u4e2a\u9009\u9879\uff1a set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) # \u53ef\u9009 \u521b\u5efa CUDA \u9879\u76ee \u5b8c\u6210\u4ee5\u4e0a\u9009\u9879\u7684\u8bbe\u5b9a\u540e\uff0c\u4f7f\u7528 project \u547d\u4ee4\u6b63\u5f0f\u521b\u5efa CUDA C++ \u9879\u76ee\u3002 project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) \u6211\u89c1\u8fc7\u6709\u4eba\u7167\u6284\u4ee3\u7801\u628a\u201c\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d\u201d\u6284\u8fdb\u53bb\u7684\u3002 \u5982\u9700\u5728\u7279\u5b9a\u6761\u4ef6\u4e0b\u624d\u5f00\u542f CUDA\uff0c\u53ef\u4ee5\u7528 enable_language() \u547d\u4ee4\u5ef6\u8fdf CUDA \u73af\u5883\u5728 CMake \u4e2d\u7684\u521d\u59cb\u5316\uff1a project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX) ... option(ENABLE_CUDA \"Enable CUDA\" ON) if (ENABLE_CUDA) enable_language(CUDA) endif() CMake \u914d\u7f6e\u603b\u7ed3 \u6ce8\u610f\uff01\u4ee5\u4e0a\u8fd9\u4e9b\u9009\u9879\u8bbe\u5b9a\u90fd\u5fc5\u987b\u5728 project() \u547d\u4ee4\u4e4b\u524d\uff01\u5426\u5219\u8bbe\u5b9a\u4e86\u4e5f\u65e0\u6548\u3002 \u56e0\u4e3a\u5b9e\u9645\u4e0a\u662f project() \u547d\u4ee4\u4f1a\u68c0\u6d4b\u8fd9\u4e9b\u9009\u9879\uff0c\u7528\u8fd9\u4e9b\u9009\u9879\u6765\u627e\u5230\u7f16\u8bd1\u5668\u548c CUDA \u7248\u672c\u7b49\u4fe1\u606f\u3002 \u603b\u4e4b\uff0c\u6211\u7684\u9009\u9879\u662f\uff1a cmake_minimum_required(VERSION 3.12) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CUDA_STANDARD 20) set(CMAKE_CUDA_SEPARABLE_COMPILATION OFF) set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) set(CMAKE_CUDA_ARCHITECTURES native) endif() project(\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) file(GLOB sources \"*.cpp\" \"*.cu\") add_executable(${PROJECT_NAME} ${sources}) target_link_libraries(${PROJECT_NAME} PRIVATE cusparse cublas) \u5f00\u59cb\u7f16\u5199 CUDA CUDA \u6709\u4e24\u5957 API\uff1a CUDA runtime API \uff1a\u66f4\u52a0\u7b80\u5355\uff0c\u517c\u987e\u6027\u80fd\uff0c\u65e0\u9700\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u90fd\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff0c\u4f46\u4e0d\u591f\u7075\u6d3b\u3002 CUDA driver API \uff1a\u66f4\u52a0\u7075\u6d3b\u591a\u53d8\uff0c\u4f46\u64cd\u4f5c\u7e41\u7410\uff0c\u9700\u8981\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u9002\u5408\u6709\u7279\u6b8a\u9700\u6c42\u7684\u7528\u6237\u3002 \u4ed6\u4eec\u90fd\u63d0\u4f9b\u4e86\u5927\u91cf\u7528\u4e8e\u7ba1\u7406 CUDA \u8d44\u6e90\u548c\u5185\u5b58\u7684\u51fd\u6570\u3002 \u6211\u4eec\u8981\u5b66\u4e60\u7684\u662f\u6bd4\u8f83\u6613\u61c2\u3001\u7528\u7684\u4e5f\u6700\u591a\u7684 CUDA runtime API\u3002 \u4f7f\u7528 \u5934\u6587\u4ef6\u5373\u53ef\u5bfc\u5165\u6240\u6709 CUDA runtime API \u7684\u51fd\u6570\u548c\u7c7b\u578b\uff1a #include \u867d\u7136 CUDA \u57fa\u4e8e C++\uff08\u800c\u4e0d\u662f C \u8bed\u8a00\uff09\uff0c\u652f\u6301\u6240\u6709 C++ \u8bed\u8a00\u7279\u6027\u3002\u4f46\u5176 CUDA runtime API \u4f9d\u7136\u662f\u4eff C \u98ce\u683c\u7684\u63a5\u53e3\uff0c\u53ef\u80fd\u662f\u7167\u987e\u4e86\u90e8\u5206\u4ece C \u8bed\u8a00\u8f6c\u8fc7\u6765\u7684\u571f\u6728\u8001\u54e5\uff0c\u4e5f\u53ef\u80fd\u662f\u4e3a\u4e86\u65b9\u4fbf\u88ab\u7b2c\u4e09\u65b9\u4e8c\u6b21\u5c01\u88c5\u3002 TODO: \u66f4\u591a\u8bdd\u9898","title":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b"},{"location":"cuda_intro/#c-cuda","text":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u5b89\u88c5 CUDA \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 CUDA C++ \u7248\u672c \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u521b\u5efa CUDA \u9879\u76ee CMake \u914d\u7f6e\u603b\u7ed3 \u5f00\u59cb\u7f16\u5199 CUDA \u53c2\u8003\u8d44\u6599\uff1a https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html https://www.cs.sfu.ca/~ashriram/Courses/CS431/assets/lectures/Part8/GPU1.pdf","title":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b"},{"location":"cuda_intro/#cuda","text":"\u786c\u4ef6\u65b9\u9762\u5efa\u8bae\u4f7f\u7528\u81f3\u5c11 GTX 1060 \u4ee5\u4e0a\u663e\u5361\uff0c\u4f46\u662f\u66f4\u8001\u7684\u663e\u5361\u4e5f\u53ef\u4ee5\u8fd0\u884c\u3002 \u8f6f\u4ef6\u65b9\u9762\u5219\u53ef\u4ee5\u5c3d\u53ef\u80fd\u6700\u65b0\uff0c\u4ee5\u83b7\u5f97 CUDA C++20 \u652f\u6301\uff0c\u6211\u5b89\u88c5\u7684\u7248\u672c\u662f CUDA 12.5\u3002 \u4ee5\u4e0b\u4ec5\u6f14\u793a Arch Linux \u4e2d\u5b89\u88c5 CUDA \u7684\u65b9\u6cd5\uff0c\u56e0\u4e3a Arch Linux \u5b98\u65b9\u6e90\u4e2d\u5c31\u81ea\u5e26 nvidia \u9a71\u52a8\u548c cuda \u5305\uff0c\u800c\u4e14\u5f00\u7bb1\u5373\u7528\uff0c\u5176\u4ed6\u53d1\u884c\u7248\u8bf7\u81ea\u884c\u5982\u6cd5\u70ae\u5236\u3002 Wendous \u7528\u6237\u53ef\u80fd\u5728\u5b89\u88c5\u5b8c\u540e\u9047\u5230\u201c\u627e\u4e0d\u5230 cuxxx.dll\u201d\u62a5\u9519\uff0c\u8bf4\u660e\u4f60\u9700\u8981\u62f7\u8d1d CUDA \u5b89\u88c5\u76ee\u5f55\u4e0b\u7684\u6240\u6709 DLL \u5230 C:\\\\Windows\\\\System32 \u3002 WSL \u7528\u6237\u8981\u6ce8\u610f\uff0cWSL \u73af\u5883\u548c\u771f\u6b63\u7684 Linux \u76f8\u5dee\u751a\u8fdc\u3002\u5f88\u591a Linux \u4e0b\u7684\u6559\u7a0b\uff0c\u4f60\u4f1a\u53d1\u73b0\u5728 WSL \u91cc\u590d\u523b\u4e0d\u51fa\u6765\u3002\u8fd9\u662f WSL \u7684 bug\uff0c\u5e94\u8be5\u6c47\u62a5\u53bb\u8ba9\u5fae\u8f6f\u7edf\u4e00\u4fee\u590d\uff0c\u800c\u4e0d\u662f\u8ba9\u6559\u7a0b\u7684\u4f5c\u8005\u96f6\u96f6\u6563\u6563\u4e00\u4e2a\u4e2a\u4ee3\u5b83\u64e6\u5c41\u80a1\u3002\u5efa\u8bae\u76f4\u63a5\u5728 Wendous \u672c\u5730\u5b89\u88c5 CUDA \u53cd\u800c\u6bd4\u4f3a\u5019 WSL \u968f\u673a\u62c9\u7684 bug \u7701\u529b\u3002 Ubuntu \u7528\u6237\u53ef\u80fd\u8003\u8651\u5378\u8f7d Ubuntu\uff0c\u56e0\u4e3a Ubuntu \u6e90\u4e2d\u7684\u7248\u672c\u6c38\u4e0d\u66f4\u65b0\u3002\u60f3\u8981\u5b89\u88c5\u65b0\u51fa\u7684\u8f6f\u4ef6\u90fd\u975e\u5e38\u56f0\u96be\uff0c\u57fa\u672c\u53ea\u80fd\u5b89\u88c5\u5230\u4e94\u516d\u5e74\u524d\u7684\u53e4\u8463\u8f6f\u4ef6\uff0c\u8981\u4e48\u53ea\u80fd\u4ece\u7f51\u4e0a\u4e0b deb \u5305\uff0c\u548c Wendous \u4e00\u4e2a\u8f6f\u8038\u6837\u3002\u6240\u6709\u5b98\u65b9 apt \u6e90\u4e2d\u5305\u7684\u7248\u672c\u4ece Ubuntu \u53d1\u5e03\u90a3\u4e00\u5929\u5c31\u5b9a\u6b7b\u4e86\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u66f4\u65b0\u4e86\u3002\u8fd9\u662f\u4e3a\u4e86\u8d77\u591c\u7ea7\u670d\u52a1\u5668\u5b89\u5168\u7a33\u5b9a\u7684\u9700\u8981\uff0c\u5bf9\u4e8e\u4e2a\u4eba\u7535\u8111\u800c\u8a00\u5374\u53ea\u662f\u767d\u767d\u963b\u788d\u6211\u4eec\u5b66\u4e60\uff0cArch Linux \u8fd9\u6837\u7684\u6eda\u52a8\u66f4\u65b0\u7684\u53d1\u884c\u7248\u624d\u66f4\u9002\u5408\u4e2a\u4eba\u684c\u9762\u7528\u6237\u3002","title":"\u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883"},{"location":"cuda_intro/#nvidia","text":"\u9996\u5148\u786e\u4fdd\u4f60\u5b89\u88c5\u4e86 NVIDIA \u6700\u65b0\u9a71\u52a8\uff1a pacman -S nvidia \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u786e\u8ba4\u663e\u5361\u9a71\u52a8\u6b63\u5e38\u5de5\u4f5c\uff1a nvidia-smi \u5e94\u8be5\u80fd\u5f97\u5230\uff1a Mon Aug 26 14:09:15 2024 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 555.58.02 Driver Version: 555.58.02 CUDA Version: 12.5 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4070 ... Off | 00000000:01:00.0 On | N/A | | 0% 30C P8 17W / 285W | 576MiB / 16376MiB | 41% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 583 G /usr/lib/Xorg 370MiB | | 0 N/A N/A 740 G xfwm4 4MiB | | 0 N/A N/A 783 G /usr/lib/firefox/firefox 133MiB | | 0 N/A N/A 4435 G obs 37MiB | +-----------------------------------------------------------------------------------------+ \u5982\u679c\u4e0d\u884c\uff0c\u90a3\u5c31\u91cd\u542f\u3002","title":"\u5b89\u88c5 NVIDIA \u9a71\u52a8"},{"location":"cuda_intro/#cuda_1","text":"\u7136\u540e\u5b89\u88c5 CUDA Toolkit\uff08\u5373 nvcc \u7f16\u8bd1\u5668\uff09\uff1a pacman -S cuda \u6253\u5f00 .bashrc \uff08\u5982\u679c\u4f60\u662f zsh \u7528\u6237\u5c31\u6253\u5f00 .zshrc \uff09\uff0c\u5728\u672b\u5c3e\u6dfb\u52a0\u4e24\u884c\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u662f\u9ed8\u8ba4\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # Arch Linux \u7528\u6237\u624d\u9700\u8981\u8fd9\u4e00\u884c \u7136\u540e\u91cd\u542f bash \uff0c\u6216\u8005\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u91cd\u8f7d\u73af\u5883\u53d8\u91cf\uff1a source .bashrc \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\u6d4b\u8bd5 CUDA \u7f16\u8bd1\u5668\u662f\u5426\u53ef\u7528\uff1a nvcc --version \u5e94\u8be5\u80fd\u5f97\u5230\uff1a nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2024 NVIDIA Corporation Built on Thu_Jun__6_02:18:23_PDT_2024 Cuda compilation tools, release 12.5, V12.5.82 Build cuda_12.5.r12.5/compiler.34385749_0","title":"\u5b89\u88c5 CUDA"},{"location":"cuda_intro/#_1","text":"CMake \u62a5\u9519\u627e\u4e0d\u5230 CUDA\uff1f\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # \u53ea\u6709 Arch Linux \u9700\u8981\u8fd9\u4e00\u884c IDE \u4f7f\u7528\u4e86 Clangd \u9759\u6001\u68c0\u67e5\u63d2\u4ef6\uff0c\u62a5\u9519\u4e0d\u8ba4\u8bc6 -forward-unknown-to-host-compiler \u9009\u9879\uff1f \u521b\u5efa\u6587\u4ef6 ~/.config/clangd/config.yaml \uff1a CompileFlags: Add: # \u8981\u989d\u5916\u6dfb\u52a0\u5230 Clang \u7684 NVCC \u6ca1\u6709\u7684\u53c2\u6570 - --no-cuda-version-check Remove: # \u79fb\u9664 Clang \u4e0d\u8ba4\u8bc6\u7684 NVCC \u53c2\u6570 - -forward-unknown-to-host-compiler - --expt-* - --generate-code=* - -arch=* - -rdc=*","title":"\u5e38\u89c1\u95ee\u9898\u89e3\u7b54"},{"location":"cuda_intro/#cmake","text":"","title":"\u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879"},{"location":"cuda_intro/#cuda_2","text":"\u5982\u679c\u4f60\u65e0\u6cd5\u641e\u5b9a\u73af\u5883\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 CMAKE_CUDA_COMPILER \u76f4\u63a5\u8bbe\u7f6e nvcc \u7f16\u8bd1\u5668\u7684\u8def\u5f84\uff1a set(CMAKE_CUDA_COMPILER \"/opt/cuda/bin/nvcc\") # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e \u4e0d\u5efa\u8bae\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a\u4f1a\u8ba9\u4f7f\u7528\u4f60\u9879\u76ee\u7684\u4eba\u4e5f\u88ab\u8feb\u628a CUDA \u5b89\u88c5\u5230\u8fd9\u4e2a\u8def\u5f84\u53bb\u3002 \u5efa\u8bae\u662f\u628a\u4f60\u7684 nvcc \u5b89\u88c5\u597d\u540e\uff0c\u901a\u8fc7 PATH \u73af\u5883\u53d8\u91cf\uff0c cmake \u5c31\u80fd\u627e\u5230\u4e86\uff0c\u4e0d\u9700\u8981\u8bbe\u7f6e\u8fd9\u4e2a\u53d8\u91cf\u3002","title":"CUDA \u7f16\u8bd1\u5668\u8def\u5f84"},{"location":"cuda_intro/#cuda-c","text":"CUDA \u662f\u4e00\u79cd\u57fa\u4e8e C++ \u7684\u9886\u57df\u7279\u5b9a\u8bed\u8a00\uff0cCUDA C++ \u7684\u7248\u672c\u548c\u6b63\u89c4 C++ \u4e00\u4e00\u5bf9\u5e94\u3002 \u76ee\u524d\u6700\u65b0\u7684\u662f CUDA C++20\uff0c\u53ef\u4ee5\u5b8c\u5168\u4f7f\u7528 C++20 \u7279\u6027\u7684\u540c\u65f6\u4e66\u5199 CUDA \u4ee3\u7801\u3002 \u5728 __host__ \u51fd\u6570\uff08\u672a\u7ecf\u7279\u6b8a\u4fee\u9970\u7684\u51fd\u6570\u9ed8\u8ba4\u5c31\u662f\u6b64\u7c7b\uff0c\u5728 CPU \u7aef\u6267\u884c\uff09\u4e2d\uff0cCUDA \u548c\u666e\u901a C++ \u6ca1\u6709\u533a\u522b\uff0c\u4efb\u4f55\u666e\u901a C++ \u4ee3\u7801\uff0c\u90fd\u53ef\u4ee5\u7528 CUDA \u7f16\u8bd1\u5668\u7f16\u8bd1\u3002 \u5728 __device__ \u51fd\u6570\uff08CUDA kernel\uff0c\u5728 GPU \u7aef\u6267\u884c\uff09\u4e2d\uff0c\u80fd\u4f7f\u7528\u7684\u51fd\u6570\u548c\u7c7b\u5c31\u6709\u4e00\u5b9a\u9650\u5236\u4e86\uff1a \u4f8b\u5982\u4f60\u4e0d\u80fd\u5728 __device__ \u51fd\u6570\u91cc\u4f7f\u7528\u4ec5\u9650 __host__ \u7528\u7684 std::cout \uff08\u4f46 printf \u53ef\u4ee5\uff0c\u56e0\u4e3a CUDA \u56e2\u961f\u4e3a\u4e86\u65b9\u4fbf\u7528\u6237\u8c03\u8bd5\uff0c\u4e3a\u4f60\u505a\u4e86 printf \u7684 __device__ \u7248\u7279\u5316\uff09\u3002 __device__ \u4e2d\u4e0d\u80fd\u4f7f\u7528\u7edd\u5927\u591a\u6570\u975e constexpr \u7684 STL \u5bb9\u5668\uff0c\u4f8b\u5982 std::map \u7b49\uff0c\u4f46\u662f\u5728 __host__ \u4fa7\u8fd8\u662f\u53ef\u4ee5\u7528\u7684\uff01 \u6240\u6709\u7684 constexpr \u51fd\u6570\u4e5f\u662f\u53ef\u4ee5\u4f7f\u7528\u7684\uff0c\u4f8b\u5982\u5404\u79cd C++ \u98ce\u683c\u7684\u6570\u5b66\u51fd\u6570\u5982 std::max \uff0c std::sin \uff0c\u8fd9\u4e9b\u51fd\u6570\u90fd\u662f constexpr \u7684\uff0c\u5728 __host__ \u548c __device__ \u90fd\u80fd\u7528\u3002 \u5982\u679c\u4e00\u4e2a\u5bb9\u5668\u7684\u6210\u5458\u5168\u662f constexpr \u7684\uff0c\u90a3\u4e48\u4ed6\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u3002\u4f8b\u5982 std::tuple \u3001 std::array \u7b49\u7b49\uff0c\u56e0\u4e3a\u4e0d\u6d89\u53ca I/O \u548c\u5185\u5b58\u5206\u914d\uff0c\u90fd\u662f\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528\u7684\u3002 \u4f8b\u5982 C++20 \u589e\u52a0\u4e86 constexpr-new \u7684\u652f\u6301\uff0c\u8ba9 std::vector \u548c std::string \u53d8\u6210\u4e86 constexpr \u7684\u5bb9\u5668\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528 std::vector \uff08\u4f1a\u7528\u5230 __device__ \u7248\u672c\u7684 malloc \u51fd\u6570\uff0c\u8fd9\u662f CUDA \u7684\u4e00\u5927\u7279\u8272\uff1a\u4f60\u53ef\u4ee5\u5728 kernel \u5185\u90e8\u7528 malloc \u52a8\u6001\u5206\u914d\u8bbe\u5907\u5185\u5b58\uff0c\u5e76\u4e14\u4ece CUDA C++20 \u5f00\u59cb new \u4e5f\u53ef\u4ee5\u4e86\uff09\u3002 std::variant \u73b0\u5728\u4e5f\u662f constexpr \u7684\u5bb9\u5668\uff0c\u4e5f\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u4e86\u3002 \u5f02\u5e38\u76ee\u524d\u8fd8\u4e0d\u662f constexpr \u7684\uff0c\u56e0\u6b64\u65e0\u6cd5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528 try/catch/throw \u7cfb\u5217\u5173\u952e\u5b57\u3002 \u603b\u4e4b\uff0c\u968f\u7740\uff0c\u6211\u4eec\u53ef\u4ee5\u671f\u5f85\u8d8a\u6765\u8d8a\u591a\u7eaf\u8ba1\u7b97\u7684\u51fd\u6570\u548c\u5bb9\u5668\u80fd\u5728 CUDA kernel\uff08 __device__ \u73af\u5883\uff09\u4e2d\u4f7f\u7528\u3002 \u6b63\u5982 CMAKE_CXX_STANDARD \u8bbe\u7f6e\u4e86 .cpp \u6587\u4ef6\u6240\u7528\u7684 C++ \u7248\u672c\uff0c\u4e5f\u53ef\u4ee5\u7528 CMAKE_CUDA_STANDARD \u8bbe\u7f6e .cu \u6587\u4ef6\u6240\u7528\u7684 CUDA C++ \u7248\u672c\u3002 set(CMAKE_CXX_STANDARD 20) # .cpp \u6587\u4ef6\u91c7\u7528\u7684 C++ \u7248\u672c\u662f C++20 set(CMAKE_CUDA_STANDARD 20) # .cu \u6587\u4ef6\u91c7\u7528\u7684 CUDA C++ \u7248\u672c\u662f C++20","title":"CUDA C++ \u7248\u672c"},{"location":"cuda_intro/#c","text":"set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") --expt-relaxed-constexpr : \u8ba9\u6240\u6709 constexpr \u51fd\u6570\u9ed8\u8ba4\u81ea\u52a8\u5e26\u6709 __host__ __device__ --expt-extended-lambda : \u5141\u8bb8\u4e3a lambda \u8868\u8fbe\u5f0f\u6307\u5b9a __host__ \u6216 __device__","title":"\u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6"},{"location":"cuda_intro/#_2","text":"\u4e0d\u540c\u7684\u663e\u5361\u6709\u4e0d\u540c\u7684\u201c\u67b6\u6784\u7248\u672c\u53f7\u201d\uff0c\u67b6\u6784\u7248\u672c\u53f7\u5fc5\u987b\u4e0e\u4f60\u7684\u786c\u4ef6\u5339\u914d\u624d\u80fd\u6700\u4f73\u72b6\u6001\u8fd0\u884c\uff0c\u53ef\u4ee5\u7565\u4f4e\uff0c\u4f46\u5c06\u4e0d\u80fd\u53d1\u6325\u5b8c\u6574\u6027\u80fd\u3002 set(CMAKE_CUDA_ARCHITECTURES 86) # \u8868\u793a\u9488\u5bf9 RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\u751f\u6210 set(CMAKE_CUDA_ARCHITECTURES native) # \u5982\u679c CMake \u7248\u672c\u9ad8\u4e8e 3.24\uff0c\u8be5\u53d8\u91cf\u53ef\u4ee5\u8bbe\u4e3a \"native\"\uff0c\u8ba9 CMake \u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7 \u67b6\u6784\u7248\u672c\u53f7\uff1a\u4f8b\u5982 75 \u8868\u793a RTX 20xx \u7cfb\u5217\uff08Turing \u67b6\u6784\uff09\uff1b86 \u8868\u793a RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\uff1b89 \u8868\u793a RTX 40xx \u7cfb\u5217\uff08Ada \u67b6\u6784\uff09\u7b49\u3002 \u5b8c\u6574\u7684\u67b6\u6784\u7248\u672c\u53f7\u5217\u8868\u53ef\u4ee5\u5728 CUDA \u6587\u6863 \u4e2d\u627e\u5230\u3002 \u4e5f\u53ef\u4ee5\u8fd0\u884c\u5982\u4e0b\u547d\u4ee4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u67e5\u8be2\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7\uff1a __nvcc_device_query","title":"\u663e\u5361\u67b6\u6784\u7248\u672c\u53f7"},{"location":"cuda_intro/#_3","text":"\u9ed8\u8ba4\u53ea\u6709 __host__ \u51fd\u6570\u53ef\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002\u5982\u679c\u4f60\u9700\u8981\u5206\u79bb __device__ \u51fd\u6570\u7684\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u5c31\u8981\u5f00\u542f\u8fd9\u4e2a\u9009\u9879\uff1a set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) # \u53ef\u9009","title":"\u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49"},{"location":"cuda_intro/#cuda_3","text":"\u5b8c\u6210\u4ee5\u4e0a\u9009\u9879\u7684\u8bbe\u5b9a\u540e\uff0c\u4f7f\u7528 project \u547d\u4ee4\u6b63\u5f0f\u521b\u5efa CUDA C++ \u9879\u76ee\u3002 project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) \u6211\u89c1\u8fc7\u6709\u4eba\u7167\u6284\u4ee3\u7801\u628a\u201c\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d\u201d\u6284\u8fdb\u53bb\u7684\u3002 \u5982\u9700\u5728\u7279\u5b9a\u6761\u4ef6\u4e0b\u624d\u5f00\u542f CUDA\uff0c\u53ef\u4ee5\u7528 enable_language() \u547d\u4ee4\u5ef6\u8fdf CUDA \u73af\u5883\u5728 CMake \u4e2d\u7684\u521d\u59cb\u5316\uff1a project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX) ... option(ENABLE_CUDA \"Enable CUDA\" ON) if (ENABLE_CUDA) enable_language(CUDA) endif()","title":"\u521b\u5efa CUDA \u9879\u76ee"},{"location":"cuda_intro/#cmake_1","text":"\u6ce8\u610f\uff01\u4ee5\u4e0a\u8fd9\u4e9b\u9009\u9879\u8bbe\u5b9a\u90fd\u5fc5\u987b\u5728 project() \u547d\u4ee4\u4e4b\u524d\uff01\u5426\u5219\u8bbe\u5b9a\u4e86\u4e5f\u65e0\u6548\u3002 \u56e0\u4e3a\u5b9e\u9645\u4e0a\u662f project() \u547d\u4ee4\u4f1a\u68c0\u6d4b\u8fd9\u4e9b\u9009\u9879\uff0c\u7528\u8fd9\u4e9b\u9009\u9879\u6765\u627e\u5230\u7f16\u8bd1\u5668\u548c CUDA \u7248\u672c\u7b49\u4fe1\u606f\u3002 \u603b\u4e4b\uff0c\u6211\u7684\u9009\u9879\u662f\uff1a cmake_minimum_required(VERSION 3.12) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CUDA_STANDARD 20) set(CMAKE_CUDA_SEPARABLE_COMPILATION OFF) set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) set(CMAKE_CUDA_ARCHITECTURES native) endif() project(\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) file(GLOB sources \"*.cpp\" \"*.cu\") add_executable(${PROJECT_NAME} ${sources}) target_link_libraries(${PROJECT_NAME} PRIVATE cusparse cublas)","title":"CMake \u914d\u7f6e\u603b\u7ed3"},{"location":"cuda_intro/#cuda_4","text":"CUDA \u6709\u4e24\u5957 API\uff1a CUDA runtime API \uff1a\u66f4\u52a0\u7b80\u5355\uff0c\u517c\u987e\u6027\u80fd\uff0c\u65e0\u9700\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u90fd\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff0c\u4f46\u4e0d\u591f\u7075\u6d3b\u3002 CUDA driver API \uff1a\u66f4\u52a0\u7075\u6d3b\u591a\u53d8\uff0c\u4f46\u64cd\u4f5c\u7e41\u7410\uff0c\u9700\u8981\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u9002\u5408\u6709\u7279\u6b8a\u9700\u6c42\u7684\u7528\u6237\u3002 \u4ed6\u4eec\u90fd\u63d0\u4f9b\u4e86\u5927\u91cf\u7528\u4e8e\u7ba1\u7406 CUDA \u8d44\u6e90\u548c\u5185\u5b58\u7684\u51fd\u6570\u3002 \u6211\u4eec\u8981\u5b66\u4e60\u7684\u662f\u6bd4\u8f83\u6613\u61c2\u3001\u7528\u7684\u4e5f\u6700\u591a\u7684 CUDA runtime API\u3002 \u4f7f\u7528 \u5934\u6587\u4ef6\u5373\u53ef\u5bfc\u5165\u6240\u6709 CUDA runtime API \u7684\u51fd\u6570\u548c\u7c7b\u578b\uff1a #include \u867d\u7136 CUDA \u57fa\u4e8e C++\uff08\u800c\u4e0d\u662f C \u8bed\u8a00\uff09\uff0c\u652f\u6301\u6240\u6709 C++ \u8bed\u8a00\u7279\u6027\u3002\u4f46\u5176 CUDA runtime API \u4f9d\u7136\u662f\u4eff C \u98ce\u683c\u7684\u63a5\u53e3\uff0c\u53ef\u80fd\u662f\u7167\u987e\u4e86\u90e8\u5206\u4ece C \u8bed\u8a00\u8f6c\u8fc7\u6765\u7684\u571f\u6728\u8001\u54e5\uff0c\u4e5f\u53ef\u80fd\u662f\u4e3a\u4e86\u65b9\u4fbf\u88ab\u7b2c\u4e09\u65b9\u4e8c\u6b21\u5c01\u88c5\u3002 TODO: \u66f4\u591a\u8bdd\u9898","title":"\u5f00\u59cb\u7f16\u5199 CUDA"},{"location":"design_concept/","text":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u5982\u679c\u4e00\u4e2a\u4e1c\u897f\u53eb\u8d77\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u8d70\u8d77\u8def\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u90a3\u4e48\u4e0d\u59a8\u8ba4\u4e3a\u4ed6\u5c31\u662f\u4e00\u53ea\u9e2d\u3002 \u6211\u4eec\u6709\u4e09\u79cd\u7c7b\u578b\u7684\u72d7\uff1a\u62c9\u5e03\u62c9\u591a\u72ac\uff0c\u85cf\u7352\uff0c\u5f20\u5fc3\u6b23\u3002 \u8bf7\u52ff\u4fae\u8fb1\u62c9\u5e03\u62c9\u591a\u548c\u85cf\u7352\uff01 \u4ed6\u4eec\u6709\u4e00\u4e2a\u5171\u540c\u70b9\uff0c\u90a3\u5c31\u662f\u5b83\u4eec\u90fd\u4f1a\u72d7\u53eb\uff08bark\uff09\u4ee5\u53ca\u81ea\u6211\u4ecb\u7ecd\uff08intro\uff09\u3002 struct Labrador { void intro() { puts(\"\u6211\u80fd\u5e2e\u4f60\u6361\u56de\u68cd\u68cd\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Mastiff { void intro() { puts(\"\u6211\u80fd\u4fdd\u536b\u56fd\u738b\u8363\u8000\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Xinxin { void intro() { puts(\"\u6211\u80fd\u795d\u60a8\u88c1\u5458\u6eda\u6eda\uff01\"); } void bark() { puts(\"\u4ece\u672a\u8d21\u732e\u4efb\u4f55\u6838\u5fc3\u529f\u80fd\uff01\"); } }; \u73b0\u5728\uff0c\u6211\u4eec\u9700\u8981\u8bbe\u8ba1\u4e00\u4e2a\u201c\u9972\u517b\u5458\u201d\u51fd\u6570\uff0c\u4ed6\u4f1a\u8ba9\u72d7\u72d7\u5148\u81ea\u6211\u4ecb\u7ecd\uff0c\u7136\u540e\u53eb\u4e24\u58f0\u3002 \u4f20\u7edf\u7684\u57fa\u4e8e\u91cd\u8f7d\u7684\u5199\u6cd5\uff0c\u9700\u8981\u8fde\u7eed\u5199\u4e09\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u51fd\u6570\u4f53\uff0c\u975e\u5e38\u9ebb\u70e6\uff0c\u8fdd\u53cd\u201c\u907f\u514d\u91cd\u590d\u201d\u539f\u5219\uff0c\u4e0d\u5229\u4e8e\u4ee3\u7801\u672a\u6765\u7684\u7ef4\u62a4\u3002 void feeder(Labrador dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Mastiff dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Xinxin dog) { dog.intro(); dog.bark(); dog.bark(); } \u65b9\u68481\uff1a\u6a21\u677f\u51fd\u6570 template void feeder(Dog dog) { dog.intro(); dog.bark(); dog.bark(); } \u6b64\u5904\u628a Dog \u5b9a\u4e49\u4e3a\u6a21\u677f\u51fd\u6570 TODO","title":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5)"},{"location":"design_concept/#c20-concept","text":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u5982\u679c\u4e00\u4e2a\u4e1c\u897f\u53eb\u8d77\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u8d70\u8d77\u8def\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u90a3\u4e48\u4e0d\u59a8\u8ba4\u4e3a\u4ed6\u5c31\u662f\u4e00\u53ea\u9e2d\u3002 \u6211\u4eec\u6709\u4e09\u79cd\u7c7b\u578b\u7684\u72d7\uff1a\u62c9\u5e03\u62c9\u591a\u72ac\uff0c\u85cf\u7352\uff0c\u5f20\u5fc3\u6b23\u3002 \u8bf7\u52ff\u4fae\u8fb1\u62c9\u5e03\u62c9\u591a\u548c\u85cf\u7352\uff01 \u4ed6\u4eec\u6709\u4e00\u4e2a\u5171\u540c\u70b9\uff0c\u90a3\u5c31\u662f\u5b83\u4eec\u90fd\u4f1a\u72d7\u53eb\uff08bark\uff09\u4ee5\u53ca\u81ea\u6211\u4ecb\u7ecd\uff08intro\uff09\u3002 struct Labrador { void intro() { puts(\"\u6211\u80fd\u5e2e\u4f60\u6361\u56de\u68cd\u68cd\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Mastiff { void intro() { puts(\"\u6211\u80fd\u4fdd\u536b\u56fd\u738b\u8363\u8000\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Xinxin { void intro() { puts(\"\u6211\u80fd\u795d\u60a8\u88c1\u5458\u6eda\u6eda\uff01\"); } void bark() { puts(\"\u4ece\u672a\u8d21\u732e\u4efb\u4f55\u6838\u5fc3\u529f\u80fd\uff01\"); } }; \u73b0\u5728\uff0c\u6211\u4eec\u9700\u8981\u8bbe\u8ba1\u4e00\u4e2a\u201c\u9972\u517b\u5458\u201d\u51fd\u6570\uff0c\u4ed6\u4f1a\u8ba9\u72d7\u72d7\u5148\u81ea\u6211\u4ecb\u7ecd\uff0c\u7136\u540e\u53eb\u4e24\u58f0\u3002 \u4f20\u7edf\u7684\u57fa\u4e8e\u91cd\u8f7d\u7684\u5199\u6cd5\uff0c\u9700\u8981\u8fde\u7eed\u5199\u4e09\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u51fd\u6570\u4f53\uff0c\u975e\u5e38\u9ebb\u70e6\uff0c\u8fdd\u53cd\u201c\u907f\u514d\u91cd\u590d\u201d\u539f\u5219\uff0c\u4e0d\u5229\u4e8e\u4ee3\u7801\u672a\u6765\u7684\u7ef4\u62a4\u3002 void feeder(Labrador dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Mastiff dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Xinxin dog) { dog.intro(); dog.bark(); dog.bark(); } \u65b9\u68481\uff1a\u6a21\u677f\u51fd\u6570 template void feeder(Dog dog) { dog.intro(); dog.bark(); dog.bark(); } \u6b64\u5904\u628a Dog \u5b9a\u4e49\u4e3a\u6a21\u677f\u51fd\u6570 TODO","title":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/","text":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u865a\u51fd\u6570\u7684\u7f3a\u70b9 \u865a\u51fd\u6570\u7684\u7f3a\u70b9 TODO","title":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/#_1","text":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u865a\u51fd\u6570\u7684\u7f3a\u70b9","title":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/#_2","text":"TODO","title":"\u865a\u51fd\u6570\u7684\u7f3a\u70b9"},{"location":"design_functor/","text":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f \u51fd\u6570\u6307\u9488 \u9996\u5148\u9700\u8981\u5b9a\u4e49\u51fd\u6570\u6307\u9488\u7c7b\u578b\uff1a using func_t = int (*)(int i); // \u7b49\u4ef7\u4e8e typedef int (*func_t)(int i); \u51fd\u6570\u6307\u9488\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u7b56\u7565\u6a21\u5f0f\uff1a void test(func_t func) { cout << func(2); cout << func(3); } int twice(int i) { return i * 2; } int main() { test(twice); // 4 6 } \u51fd\u6570\u6307\u9488\u5b9e\u73b0\u591a\u6001 int twice(int i) { return i * 2; } int triple(int i) { return i * 3; } int main() { test(twice); // 4 6 test(triple); // 6 9 } \u51fd\u6570\u6307\u9488\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u51fd\u6570\u6307\u9488\u53ea\u80fd\u6307\u5411\u5168\u5c40\u51fd\u6570\uff0c\u65e0\u6cd5\u4fdd\u5b58\u72b6\u6001\u3002 int ntimes(int scale, int i) { return i * scale; } int main() { test(ntimes(2)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 test(ntimes(3)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 } \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 struct myclass { void run(string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc.run(\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc. operator() (\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc(\"\u5c0f\u5207\"); \u91cd\u8f7d\u4e86 operator() \u540e\u7684 myclass \u5bf9\u8c61\uff0c\u8c03\u7528\u8d77\u6765\u5c31\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\u3002 \u4eff\u51fd\u6570 \u4eff\u51fd\u6570\u662f\u4e00\u79cd\u91cd\u8f7d\u4e86 \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 \u7684\u7c7b\uff0c\u53ef\u4ee5\u50cf\u51fd\u6570\u4e00\u6837\u4f7f\u7528\uff1a struct twice_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; int main() { test(twice); // 4 6 } \u4eff\u51fd\u6570\u7684\u4f18\u52bf\u662f\u53ef\u4ee5\u4fdd\u5b58 \u72b6\u6001 \uff1a struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; void test(ntimes_t func) { cout << func(2); cout << func(3); } int main() { ntimes_t twice(2); ntimes_t triple(3); ntimes_t quadric(4); test(twice); // 4 6 test(triple); // 6 9 test(quadric); // 8 12 } \u4eff\u51fd\u6570\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u9700\u8981\u5728 test \u4e2d\u5199\u660e\u4eff\u51fd\u6570\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u65e0\u6cd5\u5b9e\u73b0\u591a\u6001\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; struct triple_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // \u9519\u8bef\uff1atest \u53ea\u517c\u5bb9\u4e86 twice_t \u505a\u53c2\u6570 } \u5982\u4f55\u89e3\u51b3\uff1f \u5229\u7528\u6a21\u677f template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // 6 9 } \u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86 \u7f16\u8bd1\u671f\u591a\u6001 \uff0c\u56e0\u4e3a test \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u53ef\u4ee5\u6839\u636e\u4f20\u5165\u7684\u5177\u4f53\u51fd\u6570\u7c7b\u578b\u8fdb\u884c\u63a8\u5bfc\u3002 \u6a21\u677f\u4f20\u4eff\u51fd\u6570\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u5fc5\u987b\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u65e0\u6cd5\u52a8\u6001\u51b3\u5b9a\u7c7b\u578b\u3002 template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { bool ok; cin >> ok; test(ok ? twice : triple); // \u9519\u8bef\uff1a\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u4e4b\u95f4\u4e0d\u80fd\u4e09\u76ee } \u4e07\u80fd\u7684 function \u5bb9\u5668 std::function \u91c7\u7528\u4e86 \u7c7b\u578b\u64e6\u9664\u6280\u672f \uff0c\u65e0\u9700\u5199\u660e\u4eff\u51fd\u6570\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u80fd\u5bb9\u7eb3\u4efb\u4f55\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u3002 \u53ea\u9700\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u5199\u660e\u51fd\u6570\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u5373\u53ef\uff0c\u6240\u6709\u5177\u6709\u540c\u6837\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u7684\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u90fd\u53ef\u4ee5\u4f20\u5165\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; function twice = twice_t(); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u4eff\u51fd\u6570 int triple(int i) { return i * 3; } function function_triple = triple; // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u51fd\u6570\u6307\u9488 struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; function quadric = ntimes_t(4); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u5e26\u72b6\u6001\u7684\u4eff\u51fd\u6570 \u53ef\u4ee5\u7528 function \u5bb9\u5668\u4f5c\u4e3a\u53c2\u6570\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u4f7f\u7528\u6a21\u677f\u3002 // \u6a21\u677f\uff1a\u6027\u80fd\u4f18\u5148 template void test(Func func) { cout << func(2); cout << func(3); } // \u5bb9\u5668\uff1a\u7075\u6d3b\u6027\u4f18\u5148 void test(function func) { cout << func(2); cout << func(3); } \u51fd\u6570\u5f0f\u4e3a\u4ec0\u4e48\u597d\uff1f \u6709\u4eba\u8bf4\uff0cfunction \u5e95\u5c42\u4f9d\u7136\u662f\u57fa\u4e8e\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u7684\uff0c\u4e0d\u662f\u548c\u865a\u51fd\u6570\u4e00\u6837\u4f4e\u6548\u5417\uff1f\u51fd\u6570\u5f0f\u76f8\u6bd4\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u597d\u5728\u54ea\u91cc\u5462\uff1f \u6027\u80fd\u4e0e\u7075\u6d3b\u6027\u7684\u9009\u62e9\u6743 \u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u5f80\u5f80\u662f 20% \u7684\u4ee3\u7801\u8017\u8d39\u4e86 80% \u7684\u8ba1\u7b97\u673a\u65f6\u95f4\u3002\u6211\u4eec\u53ea\u8981\u4f18\u5316\u8fd9 20% \u7684\u74f6\u9888\u4ee3\u7801\u5c31\u53ef\u4ee5\u3002 \u865a\u51fd\u6570\u5b9e\u73b0\u7684\u591a\u6001\uff0c\u662f\u5f3a\u5236\u7684\uff0c\u4e00\u65e6\u7528\u4e86\u865a\u51fd\u6570\uff0c\u5c31\u6ca1\u6cd5\u628a\u865a\u8868\u53bb\u6389\u4e86\uff0c\u6c38\u8fdc\u5361\u5728\u4f60\u7684\u5bf9\u8c61\u7c7b\u578b\u91cc\u5360 8 \u5b57\u8282\u7a7a\u95f4\uff0c\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u6001\u4f7f\u7528\u3002 \u5982\u679c\u9009\u62e9\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\uff0c\u4f60\u53ef\u4ee5\u5728\u6b21\u8981\u7684\u4e1a\u52a1\u903b\u8f91\u4ee3\u7801\u4e2d\u9009\u62e9\u66f4\u7075\u6d3b\u7684 function \u5bb9\u5668\u3002 \u800c\u5728\u9700\u8981\u6027\u80fd\u7684\u74f6\u9888\u4ee3\u7801\u5904\uff0c\u53ef\u4ee5\u968f\u65f6\u5207\u6362\u5230\u57fa\u4e8e\u6a21\u677f\u7684\uff0c\u66f4\u9ad8\u6027\u80fd\u7684\u7f16\u8bd1\u671f\u591a\u6001\u3002\u51fd\u6570\u5f0f\u7ed9\u4e86\u4f60\u6839\u636e\u60c5\u51b5\u9009\u62e9\u7684\u81ea\u7531\u5ea6\u3002 function \u6709\u5c0f\u5bf9\u8c61\u4f18\u5316 \u800c\u4e14 function \u5185\u90e8\u5177\u6709\u7c7b\u4f3c\u4e8e string \u5c0f\u5bf9\u8c61\u4f18\u5316\u673a\u5236\uff0c\u5bf9\u4e8e\u8f83\u5c0f\u7684\u72b6\u6001\u6216\u6ca1\u6709\u72b6\u6001\u7684\u4eff\u51fd\u6570\uff0c\u5c31\u65e0\u9700\u6307\u9488\uff01\u65e0\u9700\u5806\u5185\u5b58\u5206\u914d\uff01 \u800c\u865a\u51fd\u6570\u54ea\u6015\u6ca1\u6709\u72b6\u6001\uff0c\u7531\u4e8e\u865a\u8868\u6307\u9488\u7684\u5b58\u5728\uff0c\u4e5f\u603b\u662f\u9700\u8981\u7528 new \u521b\u5efa\uff0c\u603b\u662f\u4f1a\u9020\u6210\u5927\u91cf\u7684\u788e\u7247\u5316\u5185\u5b58\uff0c\u56e0\u6b64\u5373\u4f7f\u540c\u6837\u9009\u62e9\u4e86\u7075\u6d3b\u6027\uff0cfunction \u4f9d\u7136\u6bd4\u865a\u51fd\u6570\u9ad8\u6548\u4e00\u70b9\u3002 \u800c\u4e14\u5373\u4f7f\u4f60\u7684\u72b6\u6001\u975e\u5e38\u591a\uff0c\u5bfc\u81f4 function \u4e0d\u5f97\u4e0d\u9700\u8981\u5806\u5185\u5b58\u5206\u914d\u4e86\uff0c\u8fd9\u4e00\u5206\u914d\u4e5f\u4e0d\u7528\u4f60\u81ea\u5df1\u64cd\u5fc3\uff0c\u4e0d\u7528\u624b\u52a8 new\uff0c\u4e5f\u4e0d\u7528\u624b\u52a8 make_shared\uff0cfunction \u5185\u90e8\u81ea\u52a8\u5e2e\u4f60\u5b8c\u6210\u4e00\u5207\u3002 lambda \u8868\u8fbe\u5f0f\u5f88\u65b9\u4fbf \u6700\u91cd\u8981\u7684\u662f\uff0c\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u53ef\u4ee5\u4fbf\u6377\u5730\u5229\u7528 lambda \u8868\u8fbe\u5f0f\u5c31\u5730\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u800c\u9762\u5411\u5bf9\u8c61\u9700\u8981\u5927\u8d39\u5468\u7ae0\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u63a5\u53e3\uff0c\u7136\u540e\u518d\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u865a\u51fd\u6570\uff0c\u6709\u65f6\u8fd8\u9700\u8981\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u7ed5\u4e86\u4e2a\u5927\u5708\u5b50\uff0c\u4e0d\u4ec5\u5199\u8d77\u6765\u75db\u82e6\uff0c\u9700\u8981\u8d77\u540d\u5f3a\u8feb\u75c7\uff0c\u800c\u4e14\u770b\u5f97\u4eba\u4e5f\u5934\u75bc\u3002lambda \u8868\u8fbe\u5f0f\uff0c\u5c31\u5730\u521b\u5efa\uff0c\u65e0\u9700\u540d\u5b57\uff0c\u66f4\u9002\u5408\u654f\u6377\u5f00\u53d1\u3002","title":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_functor/#_1","text":"","title":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_functor/#_2","text":"\u9996\u5148\u9700\u8981\u5b9a\u4e49\u51fd\u6570\u6307\u9488\u7c7b\u578b\uff1a using func_t = int (*)(int i); // \u7b49\u4ef7\u4e8e typedef int (*func_t)(int i); \u51fd\u6570\u6307\u9488\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u7b56\u7565\u6a21\u5f0f\uff1a void test(func_t func) { cout << func(2); cout << func(3); } int twice(int i) { return i * 2; } int main() { test(twice); // 4 6 }","title":"\u51fd\u6570\u6307\u9488"},{"location":"design_functor/#_3","text":"int twice(int i) { return i * 2; } int triple(int i) { return i * 3; } int main() { test(twice); // 4 6 test(triple); // 6 9 }","title":"\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u591a\u6001"},{"location":"design_functor/#_4","text":"\u7f3a\u70b9\uff1a\u51fd\u6570\u6307\u9488\u53ea\u80fd\u6307\u5411\u5168\u5c40\u51fd\u6570\uff0c\u65e0\u6cd5\u4fdd\u5b58\u72b6\u6001\u3002 int ntimes(int scale, int i) { return i * scale; } int main() { test(ntimes(2)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 test(ntimes(3)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 }","title":"\u51fd\u6570\u6307\u9488\u7684\u7f3a\u9677"},{"location":"design_functor/#_5","text":"struct myclass { void run(string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc.run(\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc. operator() (\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc(\"\u5c0f\u5207\"); \u91cd\u8f7d\u4e86 operator() \u540e\u7684 myclass \u5bf9\u8c61\uff0c\u8c03\u7528\u8d77\u6765\u5c31\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\u3002","title":"\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26"},{"location":"design_functor/#_6","text":"\u4eff\u51fd\u6570\u662f\u4e00\u79cd\u91cd\u8f7d\u4e86 \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 \u7684\u7c7b\uff0c\u53ef\u4ee5\u50cf\u51fd\u6570\u4e00\u6837\u4f7f\u7528\uff1a struct twice_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; int main() { test(twice); // 4 6 } \u4eff\u51fd\u6570\u7684\u4f18\u52bf\u662f\u53ef\u4ee5\u4fdd\u5b58 \u72b6\u6001 \uff1a struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; void test(ntimes_t func) { cout << func(2); cout << func(3); } int main() { ntimes_t twice(2); ntimes_t triple(3); ntimes_t quadric(4); test(twice); // 4 6 test(triple); // 6 9 test(quadric); // 8 12 }","title":"\u4eff\u51fd\u6570"},{"location":"design_functor/#_7","text":"\u7f3a\u70b9\uff1a\u9700\u8981\u5728 test \u4e2d\u5199\u660e\u4eff\u51fd\u6570\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u65e0\u6cd5\u5b9e\u73b0\u591a\u6001\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; struct triple_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // \u9519\u8bef\uff1atest \u53ea\u517c\u5bb9\u4e86 twice_t \u505a\u53c2\u6570 } \u5982\u4f55\u89e3\u51b3\uff1f","title":"\u4eff\u51fd\u6570\u7684\u7f3a\u9677"},{"location":"design_functor/#_8","text":"template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // 6 9 } \u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86 \u7f16\u8bd1\u671f\u591a\u6001 \uff0c\u56e0\u4e3a test \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u53ef\u4ee5\u6839\u636e\u4f20\u5165\u7684\u5177\u4f53\u51fd\u6570\u7c7b\u578b\u8fdb\u884c\u63a8\u5bfc\u3002","title":"\u5229\u7528\u6a21\u677f"},{"location":"design_functor/#_9","text":"\u7f3a\u70b9\uff1a\u5fc5\u987b\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u65e0\u6cd5\u52a8\u6001\u51b3\u5b9a\u7c7b\u578b\u3002 template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { bool ok; cin >> ok; test(ok ? twice : triple); // \u9519\u8bef\uff1a\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u4e4b\u95f4\u4e0d\u80fd\u4e09\u76ee }","title":"\u6a21\u677f\u4f20\u4eff\u51fd\u6570\u7684\u7f3a\u9677"},{"location":"design_functor/#function","text":"std::function \u91c7\u7528\u4e86 \u7c7b\u578b\u64e6\u9664\u6280\u672f \uff0c\u65e0\u9700\u5199\u660e\u4eff\u51fd\u6570\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u80fd\u5bb9\u7eb3\u4efb\u4f55\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u3002 \u53ea\u9700\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u5199\u660e\u51fd\u6570\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u5373\u53ef\uff0c\u6240\u6709\u5177\u6709\u540c\u6837\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u7684\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u90fd\u53ef\u4ee5\u4f20\u5165\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; function twice = twice_t(); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u4eff\u51fd\u6570 int triple(int i) { return i * 3; } function function_triple = triple; // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u51fd\u6570\u6307\u9488 struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; function quadric = ntimes_t(4); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u5e26\u72b6\u6001\u7684\u4eff\u51fd\u6570 \u53ef\u4ee5\u7528 function \u5bb9\u5668\u4f5c\u4e3a\u53c2\u6570\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u4f7f\u7528\u6a21\u677f\u3002 // \u6a21\u677f\uff1a\u6027\u80fd\u4f18\u5148 template void test(Func func) { cout << func(2); cout << func(3); } // \u5bb9\u5668\uff1a\u7075\u6d3b\u6027\u4f18\u5148 void test(function func) { cout << func(2); cout << func(3); }","title":"\u4e07\u80fd\u7684 function \u5bb9\u5668"},{"location":"design_functor/#_10","text":"\u6709\u4eba\u8bf4\uff0cfunction \u5e95\u5c42\u4f9d\u7136\u662f\u57fa\u4e8e\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u7684\uff0c\u4e0d\u662f\u548c\u865a\u51fd\u6570\u4e00\u6837\u4f4e\u6548\u5417\uff1f\u51fd\u6570\u5f0f\u76f8\u6bd4\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u597d\u5728\u54ea\u91cc\u5462\uff1f \u6027\u80fd\u4e0e\u7075\u6d3b\u6027\u7684\u9009\u62e9\u6743 \u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u5f80\u5f80\u662f 20% \u7684\u4ee3\u7801\u8017\u8d39\u4e86 80% \u7684\u8ba1\u7b97\u673a\u65f6\u95f4\u3002\u6211\u4eec\u53ea\u8981\u4f18\u5316\u8fd9 20% \u7684\u74f6\u9888\u4ee3\u7801\u5c31\u53ef\u4ee5\u3002 \u865a\u51fd\u6570\u5b9e\u73b0\u7684\u591a\u6001\uff0c\u662f\u5f3a\u5236\u7684\uff0c\u4e00\u65e6\u7528\u4e86\u865a\u51fd\u6570\uff0c\u5c31\u6ca1\u6cd5\u628a\u865a\u8868\u53bb\u6389\u4e86\uff0c\u6c38\u8fdc\u5361\u5728\u4f60\u7684\u5bf9\u8c61\u7c7b\u578b\u91cc\u5360 8 \u5b57\u8282\u7a7a\u95f4\uff0c\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u6001\u4f7f\u7528\u3002 \u5982\u679c\u9009\u62e9\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\uff0c\u4f60\u53ef\u4ee5\u5728\u6b21\u8981\u7684\u4e1a\u52a1\u903b\u8f91\u4ee3\u7801\u4e2d\u9009\u62e9\u66f4\u7075\u6d3b\u7684 function \u5bb9\u5668\u3002 \u800c\u5728\u9700\u8981\u6027\u80fd\u7684\u74f6\u9888\u4ee3\u7801\u5904\uff0c\u53ef\u4ee5\u968f\u65f6\u5207\u6362\u5230\u57fa\u4e8e\u6a21\u677f\u7684\uff0c\u66f4\u9ad8\u6027\u80fd\u7684\u7f16\u8bd1\u671f\u591a\u6001\u3002\u51fd\u6570\u5f0f\u7ed9\u4e86\u4f60\u6839\u636e\u60c5\u51b5\u9009\u62e9\u7684\u81ea\u7531\u5ea6\u3002 function \u6709\u5c0f\u5bf9\u8c61\u4f18\u5316 \u800c\u4e14 function \u5185\u90e8\u5177\u6709\u7c7b\u4f3c\u4e8e string \u5c0f\u5bf9\u8c61\u4f18\u5316\u673a\u5236\uff0c\u5bf9\u4e8e\u8f83\u5c0f\u7684\u72b6\u6001\u6216\u6ca1\u6709\u72b6\u6001\u7684\u4eff\u51fd\u6570\uff0c\u5c31\u65e0\u9700\u6307\u9488\uff01\u65e0\u9700\u5806\u5185\u5b58\u5206\u914d\uff01 \u800c\u865a\u51fd\u6570\u54ea\u6015\u6ca1\u6709\u72b6\u6001\uff0c\u7531\u4e8e\u865a\u8868\u6307\u9488\u7684\u5b58\u5728\uff0c\u4e5f\u603b\u662f\u9700\u8981\u7528 new \u521b\u5efa\uff0c\u603b\u662f\u4f1a\u9020\u6210\u5927\u91cf\u7684\u788e\u7247\u5316\u5185\u5b58\uff0c\u56e0\u6b64\u5373\u4f7f\u540c\u6837\u9009\u62e9\u4e86\u7075\u6d3b\u6027\uff0cfunction \u4f9d\u7136\u6bd4\u865a\u51fd\u6570\u9ad8\u6548\u4e00\u70b9\u3002 \u800c\u4e14\u5373\u4f7f\u4f60\u7684\u72b6\u6001\u975e\u5e38\u591a\uff0c\u5bfc\u81f4 function \u4e0d\u5f97\u4e0d\u9700\u8981\u5806\u5185\u5b58\u5206\u914d\u4e86\uff0c\u8fd9\u4e00\u5206\u914d\u4e5f\u4e0d\u7528\u4f60\u81ea\u5df1\u64cd\u5fc3\uff0c\u4e0d\u7528\u624b\u52a8 new\uff0c\u4e5f\u4e0d\u7528\u624b\u52a8 make_shared\uff0cfunction \u5185\u90e8\u81ea\u52a8\u5e2e\u4f60\u5b8c\u6210\u4e00\u5207\u3002 lambda \u8868\u8fbe\u5f0f\u5f88\u65b9\u4fbf \u6700\u91cd\u8981\u7684\u662f\uff0c\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u53ef\u4ee5\u4fbf\u6377\u5730\u5229\u7528 lambda \u8868\u8fbe\u5f0f\u5c31\u5730\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u800c\u9762\u5411\u5bf9\u8c61\u9700\u8981\u5927\u8d39\u5468\u7ae0\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u63a5\u53e3\uff0c\u7136\u540e\u518d\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u865a\u51fd\u6570\uff0c\u6709\u65f6\u8fd8\u9700\u8981\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u7ed5\u4e86\u4e2a\u5927\u5708\u5b50\uff0c\u4e0d\u4ec5\u5199\u8d77\u6765\u75db\u82e6\uff0c\u9700\u8981\u8d77\u540d\u5f3a\u8feb\u75c7\uff0c\u800c\u4e14\u770b\u5f97\u4eba\u4e5f\u5934\u75bc\u3002lambda \u8868\u8fbe\u5f0f\uff0c\u5c31\u5730\u521b\u5efa\uff0c\u65e0\u9700\u540d\u5b57\uff0c\u66f4\u9002\u5408\u654f\u6377\u5f00\u53d1\u3002","title":"\u51fd\u6570\u5f0f\u4e3a\u4ec0\u4e48\u597d\uff1f"},{"location":"design_gamedev/","text":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f \u5355\u4f8b\u6a21\u5f0f \u6a21\u677f\u6a21\u5f0f \u72b6\u6001\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f CRTP \u6a21\u5f0f \u7ec4\u4ef6\u6a21\u5f0f \u89c2\u5bdf\u8005\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u8bbf\u95ee\u8005\u6a21\u5f0f \u5355\u4f8b\u6a21\u5f0f \u901a\u5e38\u7528\u4e8e\u6e38\u620f\u4e2d\u7684\u5168\u5c40\u7ba1\u7406\u7c7b\uff0c\u4fdd\u8bc1\u6574\u4e2a\u7a0b\u5e8f\uff08\u8fdb\u7a0b\uff09\u4e2d\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u5bf9\u8c61\u5b58\u5728\u3002\u6709\u5f88\u591a\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\uff1a \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 Game game; \u6548\u679c\uff1a\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u5c31\u4f1a\u521b\u5efa game \u5bf9\u8c61\uff0c\u4e4b\u540e\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 Game &getGame() { static Game game; return game; } getGame().updatePlayers(); \u6548\u679c\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 getGame() \u65f6\u4f1a\u521d\u59cb\u5316\uff0c\u4e4b\u540e\u7684\u8c03\u7528\u4f1a\u76f4\u63a5\u8fd4\u56de\u4e0a\u6b21\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 \u6839\u636e\u4f60\u7684\u9700\u8981\uff0c\u5982\u679c\u4f60\u9700\u8981\u5728\u7a0b\u5e8f\u4e00\u542f\u52a8\u65f6 game \u5bf9\u8c61\u5c31\u53ef\u7528\uff0c\u5c31\u7528\u997f\u6c57\u6a21\u5f0f\u3002 \u5982\u679c game \u7684\u521d\u59cb\u5316\u9700\u8981\u67d0\u4e9b\u6761\u4ef6\uff0c\u4f8b\u5982\u521b\u5efa Game \u7c7b\u524d\u9700\u8981 OpenGL \u521d\u59cb\u5316\uff0c\u90a3\u4e48\u53ef\u7528\u61d2\u6c57\u6a21\u5f0f\uff1a int main() { glfwInit(); // \u521d\u59cb\u5316 OpenGL getGame().initialize(); // \u7b2c\u4e00\u6b21\u8c03\u7528 getGame \u4f1a\u521d\u59cb\u5316 game \u5355\u4f8b getGame().updatePlayers(); // \u4e4b\u540e\u7684\u8c03\u7528\u603b\u662f\u8fd4\u56de\u5bf9\u540c\u4e00\u4e2a game \u5355\u4f8b\u7684\u5f15\u7528 } \u63d0\u793a\uff1a\u5982\u679c\u8981\u628a\u5355\u4f8b\u5bf9\u8c61\u7684\u5b9a\u4e49\u653e\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u52a1\u5fc5\u6dfb\u52a0 inline \u4fee\u9970\u7b26\uff0c\u800c\u4e0d\u662f static\uff0c\u5426\u5219\u4f1a\u5bfc\u81f4\u591a\u4e2a cpp \u6587\u4ef6\u5404\u81ea\u6709\u4e00\u4e2a Game \u5bf9\u8c61\u3002 // Game.hpp inline Game game; inline Game &getGame() { static Game game; return game; } \u5c01\u88c5\u5728\u7c7b\u5185\u90e8 \u7531\u4e8e\u6240\u6709\u5355\u4f8b\u5168\u90e8\u66b4\u9732\u5728\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\uff0c\u5bb9\u6613\u4ea7\u751f\u6df7\u4e71\u3002 \u4e00\u822c\u4f1a\u628a\u5355\u4f8b\u5bf9\u8c61\u6216\u51fd\u6570\u5c01\u88c5\u5728\u7c7b\u5185\u90e8\uff0c\u5e76\u4e14\u628a Game \u7684\u6784\u9020\u51fd\u6570\u8bbe\u4e3a private\uff0c\u907f\u514d\u7528\u6237\u4e0d\u614e\u76f4\u63a5\u521b\u5efa\u51fa\u672c\u5e94\u53ea\u6709\u5355\u4e2a\u5b9e\u4f8b\u7684 Game \u7c7b\u3002 \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: // inline static Game instance; // \u867d\u7136\u5f88\u723d\uff0c\u4f46\u4e0d\u80fd\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a Game \u5728\u4ed6\u7684 }; \u7ed3\u675f\u524d\u90fd\u662f\u4e0d\u5b8c\u6574\u7c7b\u578b static Game instance; // \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u5c31\u597d\u6bd4\u5168\u5c40\u53d8\u91cf\u7684 extern Game instance \u4e00\u6837\uff0c\u4e0d\u9700\u8981\u662f\u5b8c\u6574\u7c7b\u578b }; inline Game Game::instance; // \u5982\u679c\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u9700\u8981 inline\uff01 Game::instance.updatePlayers(); \u8b66\u544a\uff1a\u53ea\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\u5e76\u4f7f\u7528 inline \u8fd9\u79cd\u5199\u6cd5\uff0c\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u8fd9\u4f1a\u4f7f DLL \u548c EXE \u5404\u81ea\u6301\u6709\u4e00\u4efd\u4e92\u4e0d\u5171\u901a\u7684 instance \u3002\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\u8fd9\u79cd\u997f\u6c57\u6a21\u5f0f\u5355\u4f8b\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \uff0c\u522b\u7528 inline \u4e86\u3002 \u8fd9\u662f\u56e0\u4e3a Windows \u4e2d\u7684\u6bcf\u4e2a DLL \u548c EXE \u90fd\u662f\u4e00\u5ea7\u5b64\u5c9b\uff0c\u4e92\u76f8\u4e0d\u77e5\u9053\u5bf9\u65b9\u6709\u6ca1\u6709\u8fd9\u4e2a\u7b26\u53f7\uff0c\u6240\u4ee5 inline \u7684\u6548\u679c\u4ece\u201c\u5168\u5c40\u53ea\u4fdd\u7559\u4e00\u4efd\u5b9a\u4e49\u201d\u53d8\u6210\u5728\u6bcf\u4e2a\u201c\u5b64\u5c9b\u201d\u5185\u5404\u81ea\u5728\u5185\u90e8\u53ea\u4fdd\u7559\u4e00\u4efd\uff0c\u4ece\u800c DLL \u548c EXE \u5404\u81ea\u4e00\u4efd\uff0c\u603b\u5171\u6709\u4e24\u4efd\u4e86\uff0c\u4e92\u76f8\u5185\u5bb9\u4e0d\u4e92\u901a\uff0c\u4ece\u800c\u4e0d\u662f\u5355\u4f8b\u6a21\u5f0f\u3002\u800c Linux \u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a SO \u52a8\u6001\u5e93\u662f\u8fd0\u884c\u65f6\u624d\u7531 ld-linux.so \u5b8c\u6210\u94fe\u63a5\u7684\uff0cSO \u5185\u90e8\u4ecd\u4fdd\u6709\u7f16\u8bd1\u65f6\u4ea7\u751f\u7684\u51fd\u6570\u7b26\u53f7\u4fe1\u606f\uff0c\u4e3a\u7684\u662f\u88ab\u53ef\u6267\u884c ELF \u52a0\u8f7d\u8fdb\u6765\u4ee5\u540e\uff0c ld-linux.so \u53ef\u4ee5\u81ea\u52a8\u6839\u636e\u628a\u53ef\u6267\u884c ELF \u548c SO \u5185\u90e8\u7684 call \u6307\u4ee4\u540e\u7684\u5730\u5740\u66f4\u65b0\u4e3a\u52a0\u8f7d\u540e\u7684\u7b26\u53f7\u7684\u52a8\u6001\u5730\u5740\u3002\u800c Windows \u7684 DLL \u4e2d\u6240\u6709\u7b26\u53f7\u5728\u7f16\u8bd1\u65f6\u5c31\u5df2\u7ecf\u88ab ld \u5df2\u7ecf\u710a\u6b7b\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 Windows \u7684\u6bcf\u4e2a DLL \u90fd\u4f1a\u81ea\u52a8\u989d\u5916\u751f\u6210\u4e00\u4e2a\u540c\u540d LIB \u6587\u4ef6\uff0c\u8fd9\u4e2a LIB \u91cc\u9762\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e2a\u201c\u63d2\u6869\u201d\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u5b57\u548c DLL \u4e2d\u7684\u76f8\u540c\uff0c\u4f46\u662f\u51fd\u6570\u7684\u5185\u5bb9\uff0c\u662f\u4f1a\u52a8\u6001 LoadLibrary \u52a0\u8f7d\u540c\u540d DLL\uff0c\u5e76\u901a\u8fc7 GetProcAddress \u52a8\u6001\u83b7\u53d6\u6240\u6709 dllexport \u7684\u51fd\u6570\uff0c\u800c\u94fe\u63a5\u65f6\u5019\u6307\u5b9a\u7684\u5b9e\u9645\u4e0a\u662f\u539f DLL \u5bf9\u5e94\u7684\u8fd9\u4e2a\u63d2\u6869 LIB\uff0cDLL \u672c\u8eab\u662f\u65e0\u6cd5\u88ab\u94fe\u63a5\u5668\u94fe\u63a5\u7684\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: inline static Game &instance() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9e\u73b0\u7684\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c static Game game; return game; } }; Game::instance().updatePlayers(); \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \u3002 \u901a\u7528\u7684\u5355\u4f8b\u6a21\u5f0f\u6a21\u677f template inline T &singleton() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u5c31\u5730\u5b9e\u73b0\u7684\u6a21\u677f\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c // \u53ea\u6709\u7b2c\u4e00\u6b21\u8fdb\u5165\u65f6\u4f1a\u6784\u9020\u4e00\u904d T\uff0c\u4e4b\u540e\u4e0d\u4f1a\u518d\u6784\u9020 // \u4e0d\u540c\u7684 T \u4f1a\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684 singleton \u5b9e\u4f8b\uff0c\u5404\u81ea\u4f53\u5185\u7684 static \u53d8\u91cf\u72ec\u7acb\u8ba1\u7b97\uff0c\u4e92\u4e0d\u5e72\u6270 static T inst; return inst; } singleton().updatePlayers(); singleton().someMethod(); \u4efb\u4f55\u7c7b\u578b T\uff0c\u53ea\u8981\u4ee5 singleton() \u5f62\u5f0f\u83b7\u53d6\uff0c\u90fd\u80fd\u4fdd\u8bc1\u6bcf\u4e2a T \u90fd\u53ea\u6709\u4e00\u4efd\u5bf9\u8c61\u3002\uff08\u524d\u63d0\u662f\u4f60\u4e0d\u8981\u518d T() \u521b\u5efa\u5bf9\u8c61\uff09 \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u6a21\u677f\u7684\u58f0\u660e\u548c\u5b9a\u4e49 \u3002 \u6a21\u677f\u6a21\u5f0f \u6ce8\u610f\uff1a\u6a21\u677f\u6a21\u5f0f\u548c C++ \u7684\u6a21\u677f\u5e76\u6ca1\u6709\u5fc5\u7136\u5173\u7cfb\uff01\u6a21\u677f\u6a21\u5f0f\u53ea\u662f\u4e00\u79cd\u601d\u60f3\uff0c\u53ef\u4ee5\u7528\u6a21\u677f\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u7528\u865a\u51fd\u6570\u5b9e\u73b0\uff08\u5927\u591a\u53cd\u800c\u662f\u7528\u865a\u51fd\u6570\u5b9e\u73b0\u7684\uff09 \u6a21\u677f\u6a21\u5f0f\u7528\u4e8e\u5c01\u88c5\u6e38\u620f\u4e2d\u4e00\u4e9b\u76f8\u4f3c\u7684\u5904\u7406\u903b\u8f91\uff0c\u628a\u5171\u540c\u7684\u90e8\u5206\u96c6\u4e2d\u5230\u4e00\u4e2a\u57fa\u7c7b\uff0c\u628a\u4e0d\u540c\u7684\u7ec6\u8282\u90e8\u5206\u7559\u7ed9\u5b50\u7c7b\u5b9e\u73b0\u3002 \u548c\u7b56\u7565\u6a21\u5f0f\u5f88\u50cf\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u63a5\u6536\u7b56\u7565\u7684\u76f4\u63a5\u5c31\u662f\u57fa\u7c7b\u81ea\u5df1\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u56fa\u5b9a\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21\uff0c\u7136\u540e\u7ed8\u5236 1 \u6b21\u3002\u663e\u7136\u9700\u8981\u628a\u201c\u79fb\u52a8\u201d\u548c\u201c\u7ed8\u5236\u201d\u4f5c\u4e3a\u4e24\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u6765\u5b9e\u73b0\u3002 struct Character { virtual void draw() = 0; virtual void move() = 0; }; struct Player : Character { void draw() override { drawPlayer(); } void move() override { movePlayer(); } }; struct Enemy : Character { void draw() override { drawEnemy(); } void move() override { moveEnemy(); } }; \u5982\u679c\u8ba9\u8d1f\u8d23\u8c03\u7528 Character \u7684\u4eba\u6765\u5b9e\u73b0\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u7684\u8bdd\uff0c\u5c31\u7834\u574f\u4e86\u5f00\u95ed\u539f\u5219\u3002 struct Game { vector chars; void update() { for (auto &&c: chars) { c->move(); c->move(); c->move(); c->draw(); } } } \u6539\u4e3a\u628a\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u5c01\u88c5\u4e3a\u4e00\u4e2a Character \u7684\u666e\u901a\u51fd\u6570 update\u3002 struct Character { protected: virtual void draw() = 0; virtual void move() = 0; public: void update() { move(); move(); move(); draw(); } }; struct Game { vector chars; void update() { for (auto &&c: chars) { c->update(); } } } \u8fd9\u6837\u8c03\u7528\u8005\u5c31\u5f88\u8f7b\u677e\u4e86\uff0c\u4e0d\u5fc5\u5173\u5fc3\u5e95\u5c42\u7ec6\u8282\uff0c\u800c update \u4e5f\u53ea\u901a\u8fc7\u63a5\u53e3\u548c\u5b50\u7c7b\u901a\u4fe1\uff0c\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u548c\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\u3002 \u6a21\u677f\u6a21\u5f0f\u8fd8\u662f\u7b56\u7565\u6a21\u5f0f\uff1a\u5982\u4f55\u9009\u62e9\uff1f \u5f53\u4e00\u4e2a\u5bf9\u8c61\u6d89\u53ca\u5f88\u591a\u7b56\u7565\u65f6\uff0c\u7528\u7b56\u7565\u6a21\u5f0f\uff1b\u5f53\u53ea\u9700\u8981\u4e00\u4e2a\u7b56\u7565\uff0c\u4e14\u9700\u8981\u7528\u5230\u57fa\u7c7b\u7684\u6210\u5458\u65f6\uff0c\u7528\u6a21\u677f\u6a21\u5f0f\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u7684\u7b56\u7565\u6709\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\uff0c\u79fb\u52a8\u65b9\u5f0f\u6709\u201c\u8d70\u8def\u201d\u3001\u201c\u8dd1\u6b65\u201d\u4e24\u79cd\uff0c\u653b\u51fb\u7b56\u7565\u53c8\u6709\u201c\u5e73A\u201d\u3001\u201c\u66b4\u51fb\u201d\u4e24\u79cd\u3002 \u90a3\u4e48\u5c31\u7528\u7b56\u7565\u6a21\u5f0f\uff0c\u8ba9\u89d2\u8272\u5206\u522b\u6307\u5411\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\u7684\u6307\u9488\u3002 struct Character { MoveStrategy *moveStrategy; AttackStrategy *attackStrategy; void update() { if (isKeyPressed(GLFW_KEY_S) { moveStrategy->move(); } else if (isKeyPressed(GLFW_KEY_W)) { moveStrategy->run(); } while (auto enemy = Game::instance().findEnemy(range)) { attackStrategy->attack(enemy); } } }; \u800c\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u7b56\u7565\uff0c\u6bd4\u5982\u6b66\u5668\u7c7b\uff0c\u53ea\u9700\u8981\u653b\u51fb\u7b56\u7565\uff0c\u5e76\u4e14\u653b\u51fb\u7b56\u7565\u9700\u8981\u77e5\u9053\u6b66\u5668\u7684\u4f24\u5bb3\u503c\u3001\u5c04\u7a0b\u3001\u9644\u9b54\u5c5e\u6027\u7b49\u4fe1\u606f\uff0c\u90a3\u5c31\u9002\u5408\u6a21\u677f\u6a21\u5f0f\u3002 struct Weapon { protected: double damage; double charge; MagicFlag magicFlags; double range; virtual void attack(Enemy *enemy); public: void update() { while (auto enemy = Game::instance().findEnemy(range)) { attack(enemy); } } }; \u6700\u5e38\u89c1\u7684\u662f do_xxx \u5c01\u88c5 \u4f8b\u5982\uff0c\u4e00\u4e2a\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u63a5\u53e3\u7c7b\uff1a struct Converter { virtual void process(const char *s, size_t len) = 0; }; \u8fd9\u4e2a\u63a5\u53e3\u662f\u8003\u8651 \u5b9e\u73b0 Converter \u5b50\u7c7b\u7684\u65b9\u4fbf \uff0c\u5bf9\u4e8e \u8c03\u7528 Converter \u7684\u7528\u6237 \u4f7f\u7528\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u65b9\u4fbf\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u8fd0\u7528\u6a21\u677f\u6a21\u5f0f\uff0c\u628a\u539f\u6765\u7684\u865a\u51fd\u6570\u63a5\u53e3\u6539\u4e3a protected \u7684\u51fd\u6570\uff0c\u4e14\u540d\u5b57\u6539\u4e3a do_process\u3002 struct Converter { protected: virtual void do_process(const char *s, size_t len) = 0; public: void process(string_view str) { return do_process(str.data(), str.size()); } void process(string str) { return do_process(str.data(), str.size()); } void process(const char *cstr) { return do_process(cstr, strlen(cstr)); } }; \u5b9e\u73b0 Converter \u7684\u5b50\u7c7b\u65f6\uff0c\u91cd\u5199\u4ed6\u7684 do_process \u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u662f protected \u7684\uff0c\u53ea\u80fd\u88ab\u7ee7\u627f\u4e86 Converter \u7684\u5b50\u7c7b\u8bbf\u95ee\u548c\u91cd\u5199\u3002 \u5916\u5c42\u7528\u6237\u53ea\u80fd\u901a\u8fc7 Converter \u57fa\u7c7b\u5c01\u88c5\u597d\u7684 process \u51fd\u6570\uff0c\u907f\u514d\u5916\u5c42\u7528\u6237\u76f4\u63a5\u5e72\u6d89\u5e95\u5c42\u7ec6\u8282\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 std::pmr::memory_resource \u3001 std::codecvt \u7b49\u90fd\u8fd0\u7528\u4e86 do_xxx \u5f0f\u7684\u6a21\u677f\u6a21\u5f0f\u5c01\u88c5\u3002 \u72b6\u6001\u6a21\u5f0f \u6e38\u620f\u4e2d\u7684\u89d2\u8272\u901a\u5e38\u6709\u591a\u79cd\u72b6\u6001\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u602a\u7269\u53ef\u80fd\u6709\u201c\u5f85\u673a\u201d\u3001\u201c\u5de1\u903b\u201d\u3001\u201c\u8ffd\u51fb\u201d\u3001\u201c\u653b\u51fb\u201d\u7b49\u591a\u79cd\u72b6\u6001\uff0c\u800c\u6bcf\u79cd\u72b6\u6001\u4e0b\u7684\u884c\u4e3a\u90fd\u4e0d\u4e00\u6837\u3002 \u5982\u679c\u7528\u4e00\u4e2a\u679a\u4e3e\u53d8\u91cf\u6765\u8868\u793a\u5f53\u524d\u72b6\u6001\uff0c\u90a3\u6bcf\u6b21\u5c31\u90fd\u9700\u8981\u7528 switch \u6765\u5904\u7406\u4e0d\u540c\u7684\u72b6\u6001\u3002 enum MonsterState { Idle, Chase, Attack, }; struct Monster { MonsterState state = Idle; void update() { switch (state) { case Idle: if (seesPlayer()) state = Chase; break; case Chase: if (canAttack()) state = Attack; else if (!seesPlayer()) state = Idle; break; case Attack: if (!seesPlayer()) state = Idle; break; } } }; \u8fd9\u6216\u8bb8\u6027\u80fd\u4e0a\u6709\u4e00\u5b9a\u4f18\u52bf\uff0c\u7f3a\u70b9\u662f\uff0c\u6240\u6709\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5806\u79ef\u5728\u540c\u4e00\u4e2a\u51fd\u6570\u4e2d\uff0c\u5982\u679c\u6709\u591a\u4e2a\u51fd\u6570\uff08\u4e0d\u53ea\u662f update\uff09\uff0c\u90a3\u4e48\u6bcf\u6dfb\u52a0\u4e00\u4e2a\u65b0\u72b6\u6001\u5c31\u9700\u8981\u4fee\u6539\u6240\u6709\u51fd\u6570\uff0c\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u800c\u4e14\u5982\u679c\u4e0d\u540c\u7684\u72b6\u6001\u542b\u6709\u4e0d\u540c\u7684\u989d\u5916\u6570\u503c\u9700\u8981\u5b58\u50a8\uff0c\u6bd4\u5982 Chase \u72b6\u6001\u9700\u8981\u5b58\u50a8\u5f53\u524d\u901f\u5ea6\uff0c\u90a3\u5c31\u9700\u8981\u5728 Monster \u7c7b\u4e2d\u6dfb\u52a0 speed \u6210\u5458\uff0c\u800c state \u4e0d\u4e3a Chase \u65f6\u53c8\u7528\u4e0d\u5230\u8fd9\u4e2a\u6210\u5458\uff0c\u975e\u5e38\u5bb9\u6613\u6270\u4e71\u601d\u7ef4\u3002 \u72b6\u6001\u4e0d\u662f\u679a\u4e3e\uff0c\u800c\u662f\u7c7b \u4e3a\u6b64\uff0c\u63d0\u51fa\u4e86\u72b6\u6001\u6a21\u5f0f\uff0c\u5c06\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5206\u79bb\u5230\u4e0d\u540c\u7684\u7c7b\u4e2d\u3002\u4ed6\u628a\u6bcf\u79cd\u72b6\u6001\u62bd\u8c61\u4e3a\u4e00\u4e2a\u7c7b\uff0c\u72b6\u6001\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u89d2\u8272\u6301\u6709\u8868\u793a\u5f53\u524d\u72b6\u6001\u7684\u5bf9\u8c61\uff0c\u7528\u72b6\u6001\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u6765\u8868\u793a\u5904\u7406\u903b\u8f91\uff0c\u800c\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u901a\u8fc7 if \u5224\u65ad\u6765\u6267\u884c\u4e0d\u540c\u7684\u884c\u4e3a\u3002 struct Monster; struct State { virtual void update(Monster *monster) = 0; }; struct Idle : State { void update(Monster *monster) override { if (monster->seesPlayer()) { monster->setState(new Chase()); } } }; struct Chase : State { void update(Monster *monster) override { if (monster->canAttack()) { monster->setState(new Attack()); } else if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Attack : State { void update(Monster *monster) override { if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Monster { State *state = new Idle(); void update() { state->update(this); } void setState(State *newState) { delete state; state = newState; } }; \u539f\u578b\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f\u7528\u4e8e\u590d\u5236\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u4e14\u65b0\u5bf9\u8c61\u7684 \u5c5e\u6027 \u548c \u7c7b\u578b \u4e0e\u539f\u6765\u76f8\u540c\u3002\u5982\u4f55\u5b9e\u73b0\uff1f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4e0d\u884c\uff1f \u62f7\u8d1d\u6784\u9020\u51fd\u6570\u53ea\u80fd\u7528\u4e8e\u7c7b\u578b\u786e\u5b9a\u7684\u60c5\u51b5\uff0c\u5bf9\u4e8e\u5177\u6709\u865a\u51fd\u6570\uff0c\u53ef\u80fd\u5177\u6709\u989d\u5916\u6210\u5458\u7684\u591a\u6001\u7c7b\u578b\uff0c\u4f1a\u53d1\u751f object-slicing\uff0c\u5bfc\u81f4\u62f7\u8d1d\u51fa\u6765\u7684\u7c7b\u578b\u53ea\u662f\u57fa\u7c7b\u7684\u90e8\u5206\uff0c\u800c\u4e0d\u662f\u5b8c\u6574\u7684\u5b50\u7c7b\u5bf9\u8c61\u3002 RedBall ball; Ball newball = ball; // \u9519\u8bef\uff1a\u53d1\u751f\u4e86 object-slicing\uff01\u73b0\u5728 newball \u7684\u7c7b\u578b\u53ea\u662f Ball \u4e86\uff0c\u4e22\u5931\u4e86 RedBall \u7684\u4fe1\u606f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6307\u9488\u4e0d\u884c\uff1f \u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff0c\u800c\u6211\u4eec\u9700\u8981\u7684\u662f\u6df1\u62f7\u8d1d\u3002 Ball *ball = new RedBall(); Ball *newball = ball; // \u9519\u8bef\uff1a\u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff01newball \u548c ball \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u5bf9\u8c61 \u9700\u8981\u8c03\u7528\u5230\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u540c\u65f6\u53c8\u57fa\u4e8e\u6307\u9488 Ball *ball = new RedBall(); Ball *newball = new RedBall(*dynamic_cast(ball)); // \u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u91cc\u663e\u5f0f\u5199\u51fa\u4e86 ball \u5185\u90e8\u7684\u771f\u6b63\u7c7b\u578b\uff0c\u8fdd\u80cc\u4e86\u5f00\u95ed\u539f\u5219 \u5c06\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5c01\u88c5\u4e3a\u865a\u51fd\u6570 \u539f\u578b\u6a21\u5f0f\u5c06\u5bf9\u8c61\u7684\u62f7\u8d1d\u65b9\u6cd5\u4f5c\u4e3a\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u4e00\u4e2a\u865a\u63a5\u53e3\u7684\u6307\u9488\uff0c\u907f\u514d\u4e86\u76f4\u63a5\u62f7\u8d1d\u7c7b\u578b\u3002\u4f46\u865a\u51fd\u6570\u5185\u90e8\u4f1a\u8c03\u7528\u5b50\u7c7b\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u5b9e\u73b0\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u719f\u6089\u5de5\u5382\u6a21\u5f0f\u7684\u540c\u5b66\uff1a\u539f\u578b\u6a21\u5f0f\u76f8\u5f53\u4e8e\u628a\u6bcf\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e86\u81ea\u5df1\u7684\u5de5\u5382\uff0c\u53ea\u9700\u8981\u6709\u4e00\u4e2a\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u5c31\u80fd\u4e0d\u65ad\u590d\u5236\u51fa\u548c\u4ed6\u76f8\u540c\u7c7b\u578b\u7684\u5bf9\u8c61\u6765\u3002 struct Ball { virtual Ball *clone() = 0; }; struct RedBall : Ball { Ball *clone() override { return new RedBall(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { Ball *clone() override { return new BlueBall(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230 }; \u597d\u5904\u662f\uff0c\u8c03\u7528\u8005\u65e0\u9700\u77e5\u9053\u5177\u4f53\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u4ed6\u662f Ball \u7684\u5b50\u7c7b\uff0c\u5c31\u53ef\u4ee5\u514b\u9686\u51fa\u4e00\u4efd\u5b8c\u5168\u4e00\u6837\u7684\u5b50\u7c7b\u5bf9\u8c61\u6765\uff0c\u4e14\u8fd4\u56de\u7684\u4e5f\u662f\u6307\u9488\uff0c\u4e0d\u4f1a\u53d1\u751f object-slicing\u3002 Ball *ball = new RedBall(); ... Ball *newball = ball->clone(); // newball \u7684\u7c7b\u578b\u4ecd\u7136\u662f RedBall clone \u8fd4\u56de\u4e3a\u667a\u80fd\u6307\u9488 struct Ball { virtual unique_ptr clone() = 0; }; struct RedBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230\u65b0\u5bf9\u8c61\u4e2d }; \u8fd9\u6837\u5c31\u4fdd\u8bc1\u4e86\u5185\u5b58\u4e0d\u4f1a\u6cc4\u6f0f\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f shared_ptr\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a shared_ptr\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f\u624b\u52a8 delete \u7684\u539f\u59cb\u6307\u9488\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u901a\u8fc7 release\uff0c\u6545\u610f\u9020\u6210\u4e00\u6b21\u5185\u5b58\u6cc4\u6f0f\uff0c\u6210\u4e3a\u9700\u8981\u624b\u52a8\u7ba1\u7406\u7684\u539f\u59cb\u6307\u9488\u3002 CRTP \u6a21\u5f0f\u81ea\u52a8\u5b9e\u73b0 clone CRTP\uff08Curiously Recurring Template Pattern\uff09\u662f\u4e00\u79cd\u6a21\u677f\u5143\u7f16\u7a0b\u6280\u672f\uff0c\u5b83\u53ef\u4ee5\u5728\u7f16\u8bd1\u671f\u95f4\u628a\u6d3e\u751f\u7c7b\u7684\u7c7b\u578b\u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u4f20\u9012\u7ed9\u57fa\u7c7b\uff0c\u4ece\u800c\u5b9e\u73b0\u4e00\u4e9b\u81ea\u52a8\u5316\u7684\u529f\u80fd\u3002 \u7279\u70b9\u662f\uff0c\u7ee7\u627f\u4e00\u4e2a CRTP \u7c7b\u65f6\uff0c\u9700\u8981\u628a\u5b50\u7c7b\u672c\u8eab\u4f5c\u4e3a\u57fa\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u3002 \u5e76\u4e0d\u4f1a\u51fa\u73b0\u5faa\u73af\u5f15\u7528\u662f\u56e0\u4e3a\uff0c\u7528\u5230\u5b50\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\u662f\u5728\u57fa\u7c7b\u7684\u6210\u5458\u51fd\u6570\u5185\u90e8\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5728\u57fa\u7c7b\u5185\u90e8\uff0c\u800c\u6a21\u677f\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\u7684\u5b9e\u4f8b\u5316\u662f\u60f0\u6027\u7684\uff0c\u7528\u5230\u4e86\u624d\u4f1a\u5b9e\u4f8b\u5316\u3002 template struct Pet { void feed() { Derived *that = static_cast(this); that->speak(); that->speak(); } }; struct CatPet : Pet { void speak() { puts(\"Meow!\"); } }; struct DogPet : Pet { void speak() { puts(\"Bark!\"); } }; \u4e00\u822c\u7684\u8c61\u7259\u5854\u7406\u8bba\u5bb6\u6559\u6750\u4e2d\u90fd\u4f1a\u544a\u8bc9\u4f60\uff0cCRTP \u662f\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u66f4\u9ad8\u6548\u5730\u5b9e\u73b0\u6a21\u677f\u6a21\u5f0f\uff0c\u597d\u50cf CRTP \u5c31\u548c\u865a\u51fd\u6570\u52bf\u4e0d\u4e24\u7acb\u3002 \u4f46\u5c0f\u5f6d\u8001\u5e08\u7684\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0cCRTP \u5e38\u5e38\u662f\u548c\u865a\u51fd\u6570\u4e00\u8d77\u51fa\u73b0\u7684\u597d\u642d\u6863\u3002 \u4f8b\u5982 CRTP \u53ef\u4ee5\u5e2e\u52a9\u539f\u578b\u6a21\u5f0f\u5b9e\u73b0\u81ea\u52a8\u5316\u5b9a\u4e49 clone \u865a\u51fd\u6570\uff0c\u7a0d\u540e\u4ecb\u7ecd\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u4e2d\u4e5f\u4f1a\u7528\u5230 CRTP\u3002 struct Ball { virtual unique_ptr clone() = 0; }; template struct BallImpl : Ball { // \u81ea\u52a8\u5b9e\u73b0 clone \u7684\u8f85\u52a9\u5de5\u5177\u7c7b unique_ptr clone() override { Derived *that = static_cast(this); return make_unique(*that); } }; struct RedBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; struct BlueBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0c\u5bf9\u8c61\u7c7b\u578b zeno::IObject \u7684\u6df1\u62f7\u8d1d\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u539f\u578b\u6a21\u5f0f\u3002 \u7ec4\u4ef6\u6a21\u5f0f \u6e38\u620f\u4e2d\u7684\u7269\u4f53\uff08\u6e38\u620f\u5bf9\u8c61\uff09\u901a\u5e38\u7531\u591a\u4e2a\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u53ef\u80fd\u7531\u201c\u89d2\u8272\u63a7\u5236\u5668\u201d\u3001\u201c\u89d2\u8272\u5916\u89c2\u201d\u3001\u201c\u89d2\u8272\u52a8\u753b\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4e00\u4e2a\u5b50\u5f39\u53ef\u80fd\u7531\u201c\u5b50\u5f39\u7269\u7406\u201d\u3001\u201c\u5b50\u5f39\u5916\u89c2\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\u3002 \u7ec4\u4ef6\u6a21\u5f0f\u662f \u6e38\u620f\u5f00\u53d1\u9886\u57df\u6700\u91cd\u8981\u7684\u8bbe\u8ba1\u6a21\u5f0f \uff0c\u5b83\u5c06\u6e38\u620f\u5bf9\u8c61\u5206\u4e3a\u591a\u4e2a\u7ec4\u4ef6\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u53ea\u5173\u5fc3\u81ea\u5df1\u7684\u903b\u8f91\uff0c\u800c\u4e0d\u5173\u5fc3\u5176\u4ed6\u7ec4\u4ef6\u7684\u903b\u8f91\u3002 \u8e69\u811a\u7684\u6e38\u620f\u5f00\u53d1\u8005\uff08\u901a\u5e38\u662f 985 \u91cf\u4ea7\u51fa\u6765\u7684\u8c61\u7259\u5854\u5de8\u5a74\uff09\u4f1a\u628a\u6bcf\u4e2a\u7ec4\u4ef6\u5199\u6210\u4e00\u4e2a\u7c7b\uff0c\u7136\u540e\u4f7f\u7528\u201c\u591a\u91cd\u7ee7\u627f\u201d\u7ee7\u627f\u51fa\u4e00\u4e2a\u73a9\u5bb6\u7c7b\u6765\uff0c\u5e76\u606c\u4e0d\u77e5\u803b\u5730\u58f0\u79f0\u201c\u6211\u4e5f\u4f1a\u7ec4\u4ef6\u6a21\u5f0f\u4e86\u201d\u3002 \u7136\u800c\uff0c\u8fd9\u6837\u7684\u7f3a\u70b9\u6709\uff1a \u6e38\u620f\u5f00\u53d1\u4e2d\u666e\u904d\u6d89\u53ca\u5230 update \u51fd\u6570\uff0c\u800c\u73a9\u5bb6\u7c7b\u7684 update \u9700\u8981\u8f6e\u6d41\u8c03\u7528\u6bcf\u4e2a\u7ec4\u4ef6\u7684 update \u51fd\u6570\u3002 \u800c\u591a\u91cd\u7ee7\u627f\u4e00\u65e6\u9047\u5230\u91cd\u540d\u7684 update \u51fd\u6570\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519 \u201c\u6709\u6b67\u4e49\u7684\u51fd\u6570\u540d\u201d \u6446\u70c2\u4e0d\u5e72\u4e86\uff0c\u9700\u8981\u4f60\u624b\u5199\u65b0\u7684 update \u51fd\u6570\u3002 struct Player : PlayerController, PlayerAppearance, PlayerAnimation { void update() { PlayerController::update(); PlayerAppearance::update(); PlayerAnimation::update(); } }; C++\uff08\u548c\u5927\u591a\u6570\u975e\u811a\u672c\u8bed\u8a00\u90fd\uff09\u4e0d\u652f\u6301\u8fd0\u884c\u65f6\u6dfb\u52a0\u6216\u5220\u9664\u57fa\u7c7b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u8981\u6dfb\u52a0\u4e00\u4e2a\u65b0\u89d2\u8272\uff0c\u6216\u662f\u4fee\u6539\u73b0\u6709\u89d2\u8272\u7684\u903b\u8f91\uff0c\u5c31\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u4e00\u904d\u6574\u4e2a\u6e38\u620f\u7684\u6e90\u7801\u3002 \u5728\u7f51\u7edc\u6e38\u620f\u4e2d\uff0c\u66f4\u65b0 DLL \u548c\u66f4\u65b0\u8d44\u4ea7\uff08\u56fe\u7247\u3001\u97f3\u9891\u3001\u6a21\u578b\u7b49\uff09\u662f\u5b8c\u5168\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u670d\u52a1\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u505c\u673a\u66f4\u65b0\uff0c\u66f4\u65b0\u8d44\u4ea7\u4e0d\u9700\u8981\uff0cDLL \u53ef\u4ee5\u88ab\u7f16\u7a0b\u5141\u8bb8\u52a8\u6001\u52a0\u8f7d\u65b0\u7684\u8d34\u56fe\u3002 \u5bf9\u4e8e\u5ba2\u6237\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u91cd\u65b0\u8d70\u4e00\u904d\u5f88\u957f\u7684 App \u5ba1\u6838\u6d41\u7a0b\uff08\u56e0\u4e3a\u76f4\u63a5\u8fd0\u884c\u4e8e\u624b\u673a\u4e0a\u7684 C++ \u53ef\u4ee5\u8f7b\u677e\u690d\u5165\u75c5\u6bd2\uff09\uff0c\u800c\u66f4\u65b0\u8d44\u4ea7\u7684\u5ba1\u6838\u6d41\u7a0b\u77ed\u5f97\u591a\uff0c\u751a\u81f3\u5e72\u8106\u65e0\u9700\u5ba1\u6838\u3002 \u56e0\u6b64\uff0c\u6e38\u620f\u5f00\u53d1\u8005\u5f88\u5c11\u4f1a\u628a\u6e38\u620f\u903b\u8f91\u76f4\u63a5\u5199\u6b7b\u5728 C++ \u4e2d\uff0c\u8fd9\u4f1a\u8ba9\u66f4\u65b0\u6e38\u620f\u903b\u8f91\uff08\u4f8b\u5982\u4fee\u590d BUG\uff09\u9700\u8981\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6bcf\u6b21\u505c\u673a\u66f4\u65b0\u90fd\u4f1a\u7ed9\u73a9\u5bb6\u53d1 200 \u5408\u6210\u7389\uff09 \u4f60\u7ecf\u5e38\u770b\u5230\u6e38\u620f\u9886\u57df\u7684 \u201cC++ \u5f00\u53d1\u5c97\u201d \u5b9e\u9645\u4e0a\u662f \u201c\u89e3\u91ca\u5668\u5f00\u53d1\u201d\u3002 \u6e38\u620f\u5f00\u53d1\u8005\u4f1a\u628a\u7ecf\u5e38\u9700\u8981\u7ef4\u62a4\u548c\u66f4\u65b0\u7684\u6e38\u620f\u903b\u8f91\u5199\u5728\u5982 Lua\u3001Python \u7b49\u811a\u672c\u8bed\u8a00\u4e2d\uff0c\u7136\u540e\u5728 C++ \u4e2d\u96c6\u6210\u4e00\u4e2a Lua\u3001Python \u89e3\u91ca\u5668\uff0c\u6839\u636e\u89e3\u91ca\u5668\u7684\u8c03\u7528\u7ed3\u679c\uff0c\u52a8\u6001\u521b\u5efa\u51fa C++ \u5bf9\u8c61\uff0c\u7136\u540e\u628a\u8fd9\u4e9b C++ \u5bf9\u8c61\u5f53\u4f5c\u7ec4\u4ef6\u6dfb\u52a0\u5230\u6e38\u620f\u5bf9\u8c61\u4e0a\u3002 \u5f53\u51fa\u73b0 BUG \u65f6\uff0c\u53ea\u9700\u8981\u4fee\u6539\u8fd9\u4e9b\u811a\u672c\u8bed\u8a00\u7684\u4ee3\u7801\uff0c\u7136\u540e\u4ee5\u201c\u8d44\u4ea7\u201d\u7684\u5f62\u5f0f\uff0c\u5feb\u901f\u8d70\u4e00\u904d\u5ba1\u6838\u6d41\u7a0b\uff0c\u5c31\u53ef\u4ee5\u4fee\u590d BUG\uff0c\u65e0\u9700\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6709\u65f6\u5019\u4f1a\u201c\u8d44\u6e90\u5df2\u8fc7\u671f\u201d\u201c\u6b63\u5728\u4e0b\u8f7d\u8d44\u6e90\u201d\uff0c\u6709\u65f6\u662f\u66f4\u65b0\u4e86\u56fe\u7247\u8d44\u6e90\uff0c\u4e5f\u53ef\u80fd\u662f\u5728\u811a\u672c\u8bed\u8a00\u91cc\u52a8\u6001\u4fee\u590d\u4e86 BUG\uff09 Java \u548c C# \u90fd\u6ca1\u6709\u591a\u91cd\u7ee7\u627f\u3002\u4f60\u8ba9\u4eba\u5bb6\u57fa\u4e8e C# \u7684 Unity \u600e\u4e48\u6d3b\uff1f \u56e0\u6b64\uff0c\u771f\u6b63\u7684\u7ec4\u4ef6\u6a21\u5f0f\u90fd\u4f1a\u5141\u8bb8\u52a8\u6001\u63d2\u5165\u7ec4\u4ef6\uff0c\u800c\u4e0d\u662f\u7f16\u8bd1\u671f\u5199\u6b7b\u3002\u9664\u975e\u4f60\u662f\u67d0\u4e9b\u8c61\u7259\u5854\u7684\u4e00\u6b21\u6027\u6c99\u96d5\u5927\u4f5c\u4e1a\u3002 \u6e38\u620f\u5bf9\u8c61\u7ec4\u4ef6\u5316\u540e\uff0c\u53ef\u4ee5\u7075\u6d3b\u5730\u7ec4\u5408\u51fa\u4e0d\u540c\u7684\u6e38\u620f\u5bf9\u8c61\uff0c\u800c\u4e0d\u5fc5\u4e3a\u6bcf\u4e00\u79cd\u7ec4\u5408\u90fd\u5199\u4e00\u4e2a\u7c7b\u3002 struct Component { virtual void update(GameObject *go) = 0; virtual ~Component() = default; // \u6ce8\u610f\uff01 }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } }; \u6ce8\u610f\uff1aComponent \u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u4e3a\u865a\u51fd\u6570\u3002\u5426\u5219\uff0c\u5f53 Component \u88ab delete \u65f6\uff0c\u53ea\u4f1a\u8c03\u7528\u5230 Component \u8fd9\u4e2a\u57fa\u7c7b\u7684\u6790\u6784\u51fd\u6570\uff0c\u800c\u4e0d\u4f1a\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6790\u6784\u51fd\u6570\u3002 \u5426\u5219\uff0c\u5982\u679c\u4f60\u7684\u5b50\u7c7b\u6709 string\u3001vector \u8fd9\u79cd\u6301\u6709\u5185\u5b58\u8d44\u6e90\u7684\u5bb9\u5668\u7c7b\uff0c\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f\uff0c\u5bfc\u81f4\u6e38\u620f\u8fd0\u884c\u8d8a\u4e45\u5185\u5b58\u5360\u7528\u8d8a\u5927\u3002 \u795e\u5947\u7684\u662f\uff0c\u5982\u679c\u4f60\u7684 Component \u5168\u90e8\u90fd\u662f\u7528 make_shared \u521b\u5efa\u7684\uff0c\u90a3\u5c31\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\u4e86\uff0c\u8fd9\u5f97\u76ca\u4e8e shared_ptr \u4f1a\u5bf9 deleter \u505a\u7c7b\u578b\u64e6\u9664\u3002 make_unique \u548c new \u521b\u5efa\u7684\u5c31\u4f1a\u6cc4\u6f0f\uff0c\u56e0\u4e3a\u4ed6\u4eec delete \u65f6\u662f\u4ee5\u57fa\u7c7b\u6307\u9488\u53bb delete \u7684\uff0c\u800c shared_ptr \u4f1a\u5728\u6784\u9020\u65f6\u5c31\u8bb0\u4f4f\u5b50\u7c7b\u7684 deleter\u3002 \u6240\u6709\u7ec4\u4ef6\uff0c\u90fd\u652f\u6301 update\uff08\u6bcf\u5e27\u66f4\u65b0\uff09\u64cd\u4f5c\uff1a struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void update(GameObject *go) override { position += velocity * dt; } }; struct LivingBeing : Component { int ageLeft; void update(GameObject *go) override { if (ageLeft < 0) go->kill(); else ageLeft -= 1; } }; \u7ec4\u4ef6\u7684\u521b\u5efa \u7ec4\u4ef6\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a \u7ec4\u4ef6\u4f5c\u4e3a\u4e00\u4e2a\u666e\u901a\u5bf9\u8c61\uff0c\u7531 GameObject \u7684\u6784\u9020\u51fd\u6570\u521b\u5efa\u3002 struct Player : GameObject { Movable *movable; LivingBeing *livingBeing; PlayerController *playerController; PlayerAppearance *playerAppearance; Player() { movable = new Movable(); livingBeing = new LivingBeing(42); playerController = new PlayerController(); playerAppearance = new PlayerAppearance(); add(movable); add(livingBeing); add(playerController); add(playerAppearance); } }; \u4e0d\u518d\u9700\u8981\u5b9a\u4e49 Player \u7c7b\u53ca\u5176\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u521b\u5efa\u5177\u6709 Player \u6240\u9700\u6240\u6709\u7ec4\u4ef6\u7684 GameObject \u5bf9\u8c61\u5373\u53ef\u3002 GameObject *makePlayer() { GameObject *go = new GameObject(); go->add(new Movable()); go->add(new LivingBeing(42)); go->add(new PlayerController()); go->add(new PlayerAppearance()); return go; } \u6b63\u7ecf\u6e38\u620f\u5f15\u64ce\u90fd\u91c7\u7528\u540e\u8005\uff0c\u4e0d\u7528\u6dfb\u52a0 C++ \u6e90\u7801\uff0c\u53ea\u662f\u4ece xml \u7b49\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u6bcf\u4e2a\u7c7b\u6240\u4f9d\u8d56\u7684\u7ec4\u4ef6\uff0c\u5c31\u80fd\u521b\u5efa\u65b0\u7684\u73a9\u5bb6\u7c7b\uff0c\u65b9\u4fbf\u52a8\u6001\u66f4\u65b0\u6e38\u620f\u903b\u8f91\u800c\u65e0\u9700\u91cd\u65b0\u53d1\u5e03 dll\u3002 \u7ec4\u4ef6\u4e4b\u95f4\u5982\u4f55\u901a\u4fe1 \u7f3a\u70b9\u662f\uff0c\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u9700\u8981\u901a\u8fc7 GameObject \u6765\u5b9e\u73b0\uff0c\u800c GameObject \u5e76\u4e0d\u77e5\u9053\u5b83\u7684\u7ec4\u4ef6\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u5c31\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u7ec4\u4ef6\u7684\u6210\u5458\u3002 \u4f8b\u5982\uff0cPlayerController \u7ec4\u4ef6\u60f3\u8981\u6539\u53d8 Movable \u7ec4\u4ef6\u7684 velocity\uff0c\u5c31\u65e0\u6cd5\u76f4\u63a5\u6539\u3002 struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { go->velocity.y += 1; // \u9519\u8bef\uff01velocity \u662f Movable \u7ec4\u4ef6\u7684\u6210\u5458\uff0c\u800c\u4e0d\u662f GameObject \u91cc\u76f4\u63a5\u6709\u7684 } if (isKeyPressed(GLFW_KEY_S)) { go->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { go->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { go->velocity.x += 1; } } }; \u5982\u4f55\u89e3\u51b3\u7ec4\u4ef6\u4e4b\u95f4\u901a\u4fe1\u96be\u7684\u95ee\u9898\uff1f \u628a\u5e38\u7528\u7684\u5b57\u6bb5\uff0c\u4f8b\u5982 position \u548c velocity \u76f4\u63a5\u653e\u5728 GameObject \u91cc\uff0c\u4f9b\u6240\u6709\u7ec4\u4ef6\u76f4\u63a5\u8bbf\u95ee\u3002 struct GameObject { glm::vec3 position; glm::vec3 velocity; ... }; \u5141\u8bb8\u7528\u6237\u6839\u636e\u5176\u4ed6\u7ec4\u4ef6\u7684\u7c7b\u578b\uff0c\u76f4\u63a5\u83b7\u53d6\u51fa\u5176\u4ed6\u7ec4\u4ef6\u7684\u6307\u9488\uff0c\u5373\u53ef\u8bbf\u95ee\u5176\u6210\u5458\u3002 struct PlayerController : Component { void update(GameObject *go) override { Movable *movable = go->getComponent(); if (!movable) { throw runtime_error(\"\u8fd9\u4e2a\u5bf9\u8c61\u4f3c\u4e4e\u4e0d\u652f\u6301\u79fb\u52a8\"); } if (isKeyPressed(GLFW_KEY_W)) { movable->velocity.y += 1; } if (isKeyPressed(GLFW_KEY_S)) { movable->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { movable->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { movable->velocity.x += 1; } } }; \u7136\u800c\uff0cgetComponent \u5982\u4f55\u5b9e\u73b0\uff1f struct GameObject { template T *getComponent() { for (auto &&c: components) { if (T *t = dynamic_cast(c)) { return t; } } return nullptr; } }; \u7528\u5230\u4e86 dynamic_cast \uff0c\u8fd9\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\u4e00\u79cd\u5b9e\u73b0\u65b9\u5f0f\uff0c\u800c\u4e14\u4e5f\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u66f4\u597d\u7684\u5b9e\u73b0\u65b9\u5f0f\u662f\u5229\u7528 typeid \u505a map \u7684\u952e\uff0c\u52a0\u901f\u67e5\u627e\u3002\u6ca1\u6709\u6027\u80fd\u95ee\u9898\uff0c\u4f46\u4f9d\u7136\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 struct GameObject { unordered_map components; template T *getComponent() { if (auto it = components.find(typeid(T)); it != components.end()) { return dynamic_cast(it->second); } else { return nullptr; } } void add(Component *component) { components[typeid(*component)] = component; } }; \u8ba9 PlayerController \u53d1\u51fa\u6307\u5b9a\u7c7b\u578b\u7684\u6d88\u606f\u5bf9\u8c61\uff0c\u7531 Movable \u68c0\u67e5\u5e76\u5904\u7406\u3002 \u6d88\u606f\u7c7b\u578b\u4e5f\u662f\u591a\u6001\u7684\uff0c\u521d\u5b66\u8005\u53ef\u4ee5\u5148\u901a\u8fc7 dynamic_cast \u5b9e\u73b0\u7c7b\u578b\u68c0\u67e5\u3002\u7a0d\u540e\u6211\u4eec\u4f1a\u4ecb\u7ecd\u66f4\u4e13\u4e1a\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u628a\u5b50\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u57fa\u7c7b\u6307\u9488\u3002 \u800c dynamic_cast \u53ef\u4ee5\u628a\u57fa\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u5b50\u7c7b\u6307\u9488\u3002 \u5982\u679c\u4ed6\u6307\u5411\u7684\u5bf9\u8c61\u786e\u5b9e\u5c31\u662f\u90a3\u4e2a\u5b50\u7c7b\u7c7b\u578b\u7684\u8bdd\uff0c\u5c31\u6b63\u5e38\u8fd4\u56de\u5b50\u7c7b\u6307\u9488\u4e86\u3002 \u5426\u5219\uff0c\u5982\u679c\u7c7b\u578b\u4e0d\u5339\u914d\uff0c dynamic_cast \u4f1a\u8fd4\u56de nullptr\u3002\u53ea\u9700\u5224\u65ad\u8fd4\u56de\u7684\u6307\u9488\u662f\u4e0d\u662f nullptr \u5c31\u77e5\u9053\u662f\u5426\u7c7b\u578b\u5339\u914d\u4e86\u3002 \u89c2\u5bdf\u8005\u6a21\u5f0f struct Message { virtual ~Message() = default; // C++ \u89c4\u5b9a\uff1a\u53ea\u6709\u591a\u6001\u7c7b\u578b\u624d\u80fd dynamic_cast\uff0c\u8fd9\u91cc\u6211\u4eec\u7528\u4e0d\u5230\u865a\u51fd\u6570\uff0c\u90a3\u5c31\u53ea\u8ba9\u6790\u6784\u51fd\u6570\u4e3a\u865a\u51fd\u6570\uff0c\u5373\u53ef\u4f7f Message \u53d8\u4e3a\u591a\u6001\u7c7b\u578b }; struct MoveMessage : Message { glm::vec3 velocityChange; }; struct Component { virtual void update(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) override { // \u6240\u6709\u4e0d\u540c\u7684\u6d88\u606f\u7c7b\u578b\u90fd\u4f1a\u8fdb\u5165\u6b64\u51fd\u6570 if (MoveMessage *mm = dynamic_cast(msg)) { // \u4f46\u53ea\u6709\u771f\u6b63\u7c7b\u578b\u4e3a MoveMessage \u7684\u6d88\u606f\u4f1a\u88ab\u5904\u7406 velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } } }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } void send(Message *msg) { for (auto &&c: components) { c->handleMessage(msg); } } }; \u8fd9\u5c31\u662f\u6240\u8c13\u7684\u89c2\u5bdf\u8005\u6a21\u5f0f\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u53ef\u4ee5\u6536\u5230\u6240\u6709\u6d88\u606f\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u3002 \u4f46\u8fd9\u6837\u505a\u7684\u7f3a\u70b9\u662f\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u9700\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u4e0d\u8bba\u662f\u5426\u662f\u81ea\u5df1\u9700\u8981\u7684\uff0c\u5982\u679c\u7ec4\u4ef6\u6570\u91cf\u591a\uff0c\u6d88\u606f\u7c7b\u578b\u53c8\u591a\uff0c\u5c31\u4f1a\u51fa\u73b0\u6027\u80fd\u95ee\u9898\u3002 \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f\u662f\u89c2\u5bdf\u8005\u6a21\u5f0f\u7684\u5347\u7ea7\u7248\uff0c\u7531\u4e00\u4e2a\u4e2d\u5fc3\u7684\u4e8b\u4ef6\u603b\u7ebf\u6765\u7ba1\u7406\u6d88\u606f\u7684\u5206\u53d1\u3002\u4e8b\u4ef6\u603b\u7ebf\u901a\u5e38\u4f5c\u4e3a GameObject \u7684\u6210\u5458\u51fa\u73b0\u3002 \u6bcf\u4e2a\u7ec4\u4ef6\u53ef\u4ee5\u8ba2\u9605\u81ea\u5df1\u611f\u5174\u8da3\u7684\u6d88\u606f\u7c7b\u578b\uff0c\u5f53\u4e8b\u4ef6\u603b\u7ebf\u6536\u5230\u6d88\u606f\u65f6\uff0c\u53ea\u628a\u6d88\u606f\u5206\u53d1\u7ed9\u8ba2\u9605\u8005\uff0c\u800c\u4e0d\u662f\u6240\u6709\u7ec4\u4ef6\u3002 struct GameObject { vector components; unordered_map> subscribers; // \u4e8b\u4ef6\u603b\u7ebf template void subscribe(Component *component) { subscribers[type_index(typeid(EventType))].push_back(component); } template void send(EventType *msg) { for (auto &&c: subscribers[type_index(typeid(EventType))]) { c->handleMessage(msg); } } void add(Component *component) { components.push_back(component); component->subscribeMessages(this); } void update() { for (auto &&c: components) { c->update(this); } } }; struct Component { virtual void update(GameObject *go) = 0; virtual void subscribeMessages(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void subscribeMessages(GameObject *go) { go->subscribe(this); } void handleMessage(Message *msg) override { if (MoveMessage *mm = dynamic_cast(msg)) { velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_SPACE)) { JumpMessage jm; go->send(&jm); } } }; \u8fd9\u6837\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u6309\u9700\u901a\u4fe1\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f struct Message { virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; }; struct JumpMessage { double jumpHeight; }; \u5982\u4f55\u5b9a\u4e49\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u7684\u5904\u7406\u65b9\u5f0f\uff1f struct MessageVisitor; // \u524d\u5411\u58f0\u660e struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(MoveMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct JumpMessage { double jumpHeight; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(JumpMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct MessageVisitor { virtual void visit(MoveMessage *mm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 virtual void visit(JumpMessage *jm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 }; struct Movable : MessageVisitor { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) { msg->accept(this); } void visit(MoveMessage *mm) override { velocity += mm->velocityChange; } void visit(JumpMessage *jm) override { velocity.y += sqrt(2 * 9.8 * jm->jumpHeight); } }; \u8fd9\u5c31\u662f\u8bbf\u95ee\u8005\u6a21\u5f0f\uff0c\u540c\u65f6\u7528\u5230\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u548c\u91cd\u8f7d\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u90fd\u80fd\u5b9a\u5236\u4e00\u4e2a\u5904\u7406\u65b9\u5f0f\uff0c\u800c\u4e0d\u7528\u901a\u8fc7\u4f4e\u6548\u7684 dynamic_cast \u5224\u65ad\u6d88\u606f\u7c7b\u578b\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u662f\u5426\u7b26\u5408\u5f00\u95ed\u539f\u5219\u5462\uff1f \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u6d88\u606f\u7c7b\u578b \u5728 MessageVisitor \u4e2d\u6dfb\u52a0\u4e00\u4e2a visit \u7684\u91cd\u8f7d \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u7ec4\u4ef6\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u7ec4\u4ef6\u7c7b\u578b \u8fd9\u4e09\u9879\u4fee\u6539\u90fd\u662f\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\uff0c\u5e76\u4e0d\u4f1a\u51fa\u73b0\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u7684\u60c5\u51b5\u3002 \u4f46\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\u8bbe\u8ba1\uff0c\u56e0\u6b64\u6211\u4eec\u8ba9\u6240\u6709\u7684 visit \u865a\u51fd\u6570\u6709\u4e00\u4e2a\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u4ec0\u4e48\u90fd\u4e0d\u505a\u3002\u8fd9\u6837\u5f53\u65b0\u589e\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u867d\u7136\u9700\u8981\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u91cd\u65b0\u7f16\u8bd1\u4e86\uff0c\u4f46\u662f\u7a0b\u5e8f\u5458\u65e0\u9700\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\uff0c\u6e90\u7801\u7ea7\u522b\u4e0a\uff0c\u662f\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u7684\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u901a\u5e38\u7528\u4e8e acceptor \u6570\u91cf\u6709\u9650\uff0c\u4f46 visitor \u7684\u7ec4\u4ef6\u7c7b\u578b\u5343\u53d8\u4e07\u5316\u7684\u60c5\u51b5\u3002 \u5982\u679c\u6d88\u606f\u7c7b\u578b\u6709\u9650\uff0c\u7ec4\u4ef6\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5982\u679c\u7ec4\u4ef6\u7c7b\u578b\u6709\u9650\uff0c\u6d88\u606f\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5e38\u4f5c\u4e3a acceptor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684 IR \u8282\u70b9\uff08\u4ee3\u7801\u4e2d\u95f4\u8868\u793a\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u6d88\u606f\u7c7b\u578b\u3002 \u5e38\u4f5c\u4e3a visitor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684\u4f18\u5316 pass\uff08\u4f1a\u4fee\u6539 IR \u8282\u70b9\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u63a5\u53d7\u6d88\u606f\u7ec4\u4ef6\u7c7b\u578b\u3002 \u4f46\u662f\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5b9e\u73b0 accept \u7684\u91cd\u8f7d\uff0c\u5185\u5bb9\u5b8c\u5168\u4e00\u6837\uff0c\u51fa\u73b0\u4e86\u4ee3\u7801\u91cd\u590d\u3002 Java \u7684\u6a21\u677f\u662f type-erasure \u7684\uff0c\u5bf9\u6b64\u675f\u624b\u65e0\u7b56\u3002\u800c C++ \u7684\u6a21\u677f\u662f refined-generic\uff0c\u53ef\u4ee5\u5229\u7528 CRTP \u81ea\u52a8\u5b9e\u73b0\u8fd9\u90e8\u5206\uff1a struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; template struct MessageImpl : Message { void accept(MessageVisitor *visitor) override { static_assert(std::is_base_of_v); visitor->visit(static_cast(this)); } }; struct MoveMessage : MessageImpl { glm::vec3 velocityChange; // \u81ea\u52a8\u5b9e\u73b0\u4e86 accept \u51fd\u6570 }; struct JumpMessage : MessageImpl { double jumpHeight; }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0cZFX \u7f16\u8bd1\u5668\u7684 IR \u4f18\u5316\u7cfb\u7edf\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 MVC \u6a21\u5f0f \u8bbe\u8ba1\u6a21\u5f0f\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u8bdd\u9898\uff0c\u672c\u671f\u5148\u8bb2\u5230\u8fd9\u91cc\uff0c\u4e0b\u96c6\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd UI \u5f00\u53d1\u4e2d\u5927\u540d\u9f0e\u9f0e\u7684 MVC \u6a21\u5f0f\u3002 MVC \u6a21\u5f0f\u662f\u4e00\u79cd\u67b6\u6784\u6a21\u5f0f\uff0c\u5b83\u5c06\u5e94\u7528\u7a0b\u5e8f\u5206\u4e3a\u4e09\u4e2a\u6838\u5fc3\u90e8\u5206\uff1a\u6a21\u578b\uff08Model\uff09\u3001\u89c6\u56fe\uff08View\uff09\u548c\u63a7\u5236\u5668\uff08Controller\uff09\uff0c\u901a\u8fc7\u5206\u79bb\u5e94\u7528\u7a0b\u5e8f\u7684\u8f93\u5165\u3001\u5904\u7406\u548c\u8f93\u51fa\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u6a21\u578b\uff08Model\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u6570\u636e\u548c\u4e1a\u52a1\u903b\u8f91\uff0c\u901a\u5e38\u7531\u6570\u636e\u7ed3\u6784\u548c\u6570\u636e\u5e93\u7ec4\u6210\u3002 \u89c6\u56fe\uff08View\uff09\uff1a\u8d1f\u8d23\u5c55\u793a\u6570\u636e\u548c\u7528\u6237\u754c\u9762\uff0c\u901a\u5e38\u7531 HTML\u3001CSS \u548c JavaScript \u7ec4\u6210\u3002 \u63a7\u5236\u5668\uff08Controller\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u7528\u6237\u4ea4\u4e92\u548c\u8c03\u5ea6\u6a21\u578b\u548c\u89c6\u56fe\uff0c\u901a\u5e38\u7531\u540e\u7aef\u8bed\u8a00\uff08\u5982 PHP\u3001Java \u7b49\uff09\u5b9e\u73b0\u3002 MVC \u6a21\u5f0f\u7684\u4f18\u70b9\uff1a \u4f4e\u8026\u5408\uff1a\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u804c\u8d23\u6e05\u6670\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u8fdb\u884c\u5355\u72ec\u7684\u4fee\u6539\u548c\u7ef4\u62a4\u3002 \u53ef\u6269\u5c55\u6027\uff1a\u7531\u4e8e\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u4f4e\u8026\u5408\u6027\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u6dfb\u52a0\u65b0\u7684\u529f\u80fd\u548c\u7ec4\u4ef6\u3002 \u53ef\u7ef4\u62a4\u6027\uff1a\u5206\u79bb\u4e86\u4e0d\u540c\u7684\u804c\u8d23\uff0c\u4f7f\u5f97\u4ee3\u7801\u66f4\u5bb9\u6613\u7406\u89e3\u548c\u7ef4\u62a4\u3002","title":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_gamedev/#_1","text":"\u5355\u4f8b\u6a21\u5f0f \u6a21\u677f\u6a21\u5f0f \u72b6\u6001\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f CRTP \u6a21\u5f0f \u7ec4\u4ef6\u6a21\u5f0f \u89c2\u5bdf\u8005\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u8bbf\u95ee\u8005\u6a21\u5f0f","title":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_gamedev/#_2","text":"\u901a\u5e38\u7528\u4e8e\u6e38\u620f\u4e2d\u7684\u5168\u5c40\u7ba1\u7406\u7c7b\uff0c\u4fdd\u8bc1\u6574\u4e2a\u7a0b\u5e8f\uff08\u8fdb\u7a0b\uff09\u4e2d\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u5bf9\u8c61\u5b58\u5728\u3002\u6709\u5f88\u591a\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\uff1a \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 Game game; \u6548\u679c\uff1a\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u5c31\u4f1a\u521b\u5efa game \u5bf9\u8c61\uff0c\u4e4b\u540e\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 Game &getGame() { static Game game; return game; } getGame().updatePlayers(); \u6548\u679c\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 getGame() \u65f6\u4f1a\u521d\u59cb\u5316\uff0c\u4e4b\u540e\u7684\u8c03\u7528\u4f1a\u76f4\u63a5\u8fd4\u56de\u4e0a\u6b21\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 \u6839\u636e\u4f60\u7684\u9700\u8981\uff0c\u5982\u679c\u4f60\u9700\u8981\u5728\u7a0b\u5e8f\u4e00\u542f\u52a8\u65f6 game \u5bf9\u8c61\u5c31\u53ef\u7528\uff0c\u5c31\u7528\u997f\u6c57\u6a21\u5f0f\u3002 \u5982\u679c game \u7684\u521d\u59cb\u5316\u9700\u8981\u67d0\u4e9b\u6761\u4ef6\uff0c\u4f8b\u5982\u521b\u5efa Game \u7c7b\u524d\u9700\u8981 OpenGL \u521d\u59cb\u5316\uff0c\u90a3\u4e48\u53ef\u7528\u61d2\u6c57\u6a21\u5f0f\uff1a int main() { glfwInit(); // \u521d\u59cb\u5316 OpenGL getGame().initialize(); // \u7b2c\u4e00\u6b21\u8c03\u7528 getGame \u4f1a\u521d\u59cb\u5316 game \u5355\u4f8b getGame().updatePlayers(); // \u4e4b\u540e\u7684\u8c03\u7528\u603b\u662f\u8fd4\u56de\u5bf9\u540c\u4e00\u4e2a game \u5355\u4f8b\u7684\u5f15\u7528 } \u63d0\u793a\uff1a\u5982\u679c\u8981\u628a\u5355\u4f8b\u5bf9\u8c61\u7684\u5b9a\u4e49\u653e\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u52a1\u5fc5\u6dfb\u52a0 inline \u4fee\u9970\u7b26\uff0c\u800c\u4e0d\u662f static\uff0c\u5426\u5219\u4f1a\u5bfc\u81f4\u591a\u4e2a cpp \u6587\u4ef6\u5404\u81ea\u6709\u4e00\u4e2a Game \u5bf9\u8c61\u3002 // Game.hpp inline Game game; inline Game &getGame() { static Game game; return game; }","title":"\u5355\u4f8b\u6a21\u5f0f"},{"location":"design_gamedev/#_3","text":"\u7531\u4e8e\u6240\u6709\u5355\u4f8b\u5168\u90e8\u66b4\u9732\u5728\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\uff0c\u5bb9\u6613\u4ea7\u751f\u6df7\u4e71\u3002 \u4e00\u822c\u4f1a\u628a\u5355\u4f8b\u5bf9\u8c61\u6216\u51fd\u6570\u5c01\u88c5\u5728\u7c7b\u5185\u90e8\uff0c\u5e76\u4e14\u628a Game \u7684\u6784\u9020\u51fd\u6570\u8bbe\u4e3a private\uff0c\u907f\u514d\u7528\u6237\u4e0d\u614e\u76f4\u63a5\u521b\u5efa\u51fa\u672c\u5e94\u53ea\u6709\u5355\u4e2a\u5b9e\u4f8b\u7684 Game \u7c7b\u3002 \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: // inline static Game instance; // \u867d\u7136\u5f88\u723d\uff0c\u4f46\u4e0d\u80fd\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a Game \u5728\u4ed6\u7684 }; \u7ed3\u675f\u524d\u90fd\u662f\u4e0d\u5b8c\u6574\u7c7b\u578b static Game instance; // \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u5c31\u597d\u6bd4\u5168\u5c40\u53d8\u91cf\u7684 extern Game instance \u4e00\u6837\uff0c\u4e0d\u9700\u8981\u662f\u5b8c\u6574\u7c7b\u578b }; inline Game Game::instance; // \u5982\u679c\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u9700\u8981 inline\uff01 Game::instance.updatePlayers(); \u8b66\u544a\uff1a\u53ea\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\u5e76\u4f7f\u7528 inline \u8fd9\u79cd\u5199\u6cd5\uff0c\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u8fd9\u4f1a\u4f7f DLL \u548c EXE \u5404\u81ea\u6301\u6709\u4e00\u4efd\u4e92\u4e0d\u5171\u901a\u7684 instance \u3002\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\u8fd9\u79cd\u997f\u6c57\u6a21\u5f0f\u5355\u4f8b\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \uff0c\u522b\u7528 inline \u4e86\u3002 \u8fd9\u662f\u56e0\u4e3a Windows \u4e2d\u7684\u6bcf\u4e2a DLL \u548c EXE \u90fd\u662f\u4e00\u5ea7\u5b64\u5c9b\uff0c\u4e92\u76f8\u4e0d\u77e5\u9053\u5bf9\u65b9\u6709\u6ca1\u6709\u8fd9\u4e2a\u7b26\u53f7\uff0c\u6240\u4ee5 inline \u7684\u6548\u679c\u4ece\u201c\u5168\u5c40\u53ea\u4fdd\u7559\u4e00\u4efd\u5b9a\u4e49\u201d\u53d8\u6210\u5728\u6bcf\u4e2a\u201c\u5b64\u5c9b\u201d\u5185\u5404\u81ea\u5728\u5185\u90e8\u53ea\u4fdd\u7559\u4e00\u4efd\uff0c\u4ece\u800c DLL \u548c EXE \u5404\u81ea\u4e00\u4efd\uff0c\u603b\u5171\u6709\u4e24\u4efd\u4e86\uff0c\u4e92\u76f8\u5185\u5bb9\u4e0d\u4e92\u901a\uff0c\u4ece\u800c\u4e0d\u662f\u5355\u4f8b\u6a21\u5f0f\u3002\u800c Linux \u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a SO \u52a8\u6001\u5e93\u662f\u8fd0\u884c\u65f6\u624d\u7531 ld-linux.so \u5b8c\u6210\u94fe\u63a5\u7684\uff0cSO \u5185\u90e8\u4ecd\u4fdd\u6709\u7f16\u8bd1\u65f6\u4ea7\u751f\u7684\u51fd\u6570\u7b26\u53f7\u4fe1\u606f\uff0c\u4e3a\u7684\u662f\u88ab\u53ef\u6267\u884c ELF \u52a0\u8f7d\u8fdb\u6765\u4ee5\u540e\uff0c ld-linux.so \u53ef\u4ee5\u81ea\u52a8\u6839\u636e\u628a\u53ef\u6267\u884c ELF \u548c SO \u5185\u90e8\u7684 call \u6307\u4ee4\u540e\u7684\u5730\u5740\u66f4\u65b0\u4e3a\u52a0\u8f7d\u540e\u7684\u7b26\u53f7\u7684\u52a8\u6001\u5730\u5740\u3002\u800c Windows \u7684 DLL \u4e2d\u6240\u6709\u7b26\u53f7\u5728\u7f16\u8bd1\u65f6\u5c31\u5df2\u7ecf\u88ab ld \u5df2\u7ecf\u710a\u6b7b\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 Windows \u7684\u6bcf\u4e2a DLL \u90fd\u4f1a\u81ea\u52a8\u989d\u5916\u751f\u6210\u4e00\u4e2a\u540c\u540d LIB \u6587\u4ef6\uff0c\u8fd9\u4e2a LIB \u91cc\u9762\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e2a\u201c\u63d2\u6869\u201d\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u5b57\u548c DLL \u4e2d\u7684\u76f8\u540c\uff0c\u4f46\u662f\u51fd\u6570\u7684\u5185\u5bb9\uff0c\u662f\u4f1a\u52a8\u6001 LoadLibrary \u52a0\u8f7d\u540c\u540d DLL\uff0c\u5e76\u901a\u8fc7 GetProcAddress \u52a8\u6001\u83b7\u53d6\u6240\u6709 dllexport \u7684\u51fd\u6570\uff0c\u800c\u94fe\u63a5\u65f6\u5019\u6307\u5b9a\u7684\u5b9e\u9645\u4e0a\u662f\u539f DLL \u5bf9\u5e94\u7684\u8fd9\u4e2a\u63d2\u6869 LIB\uff0cDLL \u672c\u8eab\u662f\u65e0\u6cd5\u88ab\u94fe\u63a5\u5668\u94fe\u63a5\u7684\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: inline static Game &instance() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9e\u73b0\u7684\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c static Game game; return game; } }; Game::instance().updatePlayers(); \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \u3002","title":"\u5c01\u88c5\u5728\u7c7b\u5185\u90e8"},{"location":"design_gamedev/#_4","text":"template inline T &singleton() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u5c31\u5730\u5b9e\u73b0\u7684\u6a21\u677f\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c // \u53ea\u6709\u7b2c\u4e00\u6b21\u8fdb\u5165\u65f6\u4f1a\u6784\u9020\u4e00\u904d T\uff0c\u4e4b\u540e\u4e0d\u4f1a\u518d\u6784\u9020 // \u4e0d\u540c\u7684 T \u4f1a\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684 singleton \u5b9e\u4f8b\uff0c\u5404\u81ea\u4f53\u5185\u7684 static \u53d8\u91cf\u72ec\u7acb\u8ba1\u7b97\uff0c\u4e92\u4e0d\u5e72\u6270 static T inst; return inst; } singleton().updatePlayers(); singleton().someMethod(); \u4efb\u4f55\u7c7b\u578b T\uff0c\u53ea\u8981\u4ee5 singleton() \u5f62\u5f0f\u83b7\u53d6\uff0c\u90fd\u80fd\u4fdd\u8bc1\u6bcf\u4e2a T \u90fd\u53ea\u6709\u4e00\u4efd\u5bf9\u8c61\u3002\uff08\u524d\u63d0\u662f\u4f60\u4e0d\u8981\u518d T() \u521b\u5efa\u5bf9\u8c61\uff09 \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u6a21\u677f\u7684\u58f0\u660e\u548c\u5b9a\u4e49 \u3002","title":"\u901a\u7528\u7684\u5355\u4f8b\u6a21\u5f0f\u6a21\u677f"},{"location":"design_gamedev/#_5","text":"\u6ce8\u610f\uff1a\u6a21\u677f\u6a21\u5f0f\u548c C++ \u7684\u6a21\u677f\u5e76\u6ca1\u6709\u5fc5\u7136\u5173\u7cfb\uff01\u6a21\u677f\u6a21\u5f0f\u53ea\u662f\u4e00\u79cd\u601d\u60f3\uff0c\u53ef\u4ee5\u7528\u6a21\u677f\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u7528\u865a\u51fd\u6570\u5b9e\u73b0\uff08\u5927\u591a\u53cd\u800c\u662f\u7528\u865a\u51fd\u6570\u5b9e\u73b0\u7684\uff09 \u6a21\u677f\u6a21\u5f0f\u7528\u4e8e\u5c01\u88c5\u6e38\u620f\u4e2d\u4e00\u4e9b\u76f8\u4f3c\u7684\u5904\u7406\u903b\u8f91\uff0c\u628a\u5171\u540c\u7684\u90e8\u5206\u96c6\u4e2d\u5230\u4e00\u4e2a\u57fa\u7c7b\uff0c\u628a\u4e0d\u540c\u7684\u7ec6\u8282\u90e8\u5206\u7559\u7ed9\u5b50\u7c7b\u5b9e\u73b0\u3002 \u548c\u7b56\u7565\u6a21\u5f0f\u5f88\u50cf\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u63a5\u6536\u7b56\u7565\u7684\u76f4\u63a5\u5c31\u662f\u57fa\u7c7b\u81ea\u5df1\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u56fa\u5b9a\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21\uff0c\u7136\u540e\u7ed8\u5236 1 \u6b21\u3002\u663e\u7136\u9700\u8981\u628a\u201c\u79fb\u52a8\u201d\u548c\u201c\u7ed8\u5236\u201d\u4f5c\u4e3a\u4e24\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u6765\u5b9e\u73b0\u3002 struct Character { virtual void draw() = 0; virtual void move() = 0; }; struct Player : Character { void draw() override { drawPlayer(); } void move() override { movePlayer(); } }; struct Enemy : Character { void draw() override { drawEnemy(); } void move() override { moveEnemy(); } }; \u5982\u679c\u8ba9\u8d1f\u8d23\u8c03\u7528 Character \u7684\u4eba\u6765\u5b9e\u73b0\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u7684\u8bdd\uff0c\u5c31\u7834\u574f\u4e86\u5f00\u95ed\u539f\u5219\u3002 struct Game { vector chars; void update() { for (auto &&c: chars) { c->move(); c->move(); c->move(); c->draw(); } } } \u6539\u4e3a\u628a\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u5c01\u88c5\u4e3a\u4e00\u4e2a Character \u7684\u666e\u901a\u51fd\u6570 update\u3002 struct Character { protected: virtual void draw() = 0; virtual void move() = 0; public: void update() { move(); move(); move(); draw(); } }; struct Game { vector chars; void update() { for (auto &&c: chars) { c->update(); } } } \u8fd9\u6837\u8c03\u7528\u8005\u5c31\u5f88\u8f7b\u677e\u4e86\uff0c\u4e0d\u5fc5\u5173\u5fc3\u5e95\u5c42\u7ec6\u8282\uff0c\u800c update \u4e5f\u53ea\u901a\u8fc7\u63a5\u53e3\u548c\u5b50\u7c7b\u901a\u4fe1\uff0c\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u548c\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\u3002","title":"\u6a21\u677f\u6a21\u5f0f"},{"location":"design_gamedev/#_6","text":"\u5f53\u4e00\u4e2a\u5bf9\u8c61\u6d89\u53ca\u5f88\u591a\u7b56\u7565\u65f6\uff0c\u7528\u7b56\u7565\u6a21\u5f0f\uff1b\u5f53\u53ea\u9700\u8981\u4e00\u4e2a\u7b56\u7565\uff0c\u4e14\u9700\u8981\u7528\u5230\u57fa\u7c7b\u7684\u6210\u5458\u65f6\uff0c\u7528\u6a21\u677f\u6a21\u5f0f\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u7684\u7b56\u7565\u6709\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\uff0c\u79fb\u52a8\u65b9\u5f0f\u6709\u201c\u8d70\u8def\u201d\u3001\u201c\u8dd1\u6b65\u201d\u4e24\u79cd\uff0c\u653b\u51fb\u7b56\u7565\u53c8\u6709\u201c\u5e73A\u201d\u3001\u201c\u66b4\u51fb\u201d\u4e24\u79cd\u3002 \u90a3\u4e48\u5c31\u7528\u7b56\u7565\u6a21\u5f0f\uff0c\u8ba9\u89d2\u8272\u5206\u522b\u6307\u5411\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\u7684\u6307\u9488\u3002 struct Character { MoveStrategy *moveStrategy; AttackStrategy *attackStrategy; void update() { if (isKeyPressed(GLFW_KEY_S) { moveStrategy->move(); } else if (isKeyPressed(GLFW_KEY_W)) { moveStrategy->run(); } while (auto enemy = Game::instance().findEnemy(range)) { attackStrategy->attack(enemy); } } }; \u800c\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u7b56\u7565\uff0c\u6bd4\u5982\u6b66\u5668\u7c7b\uff0c\u53ea\u9700\u8981\u653b\u51fb\u7b56\u7565\uff0c\u5e76\u4e14\u653b\u51fb\u7b56\u7565\u9700\u8981\u77e5\u9053\u6b66\u5668\u7684\u4f24\u5bb3\u503c\u3001\u5c04\u7a0b\u3001\u9644\u9b54\u5c5e\u6027\u7b49\u4fe1\u606f\uff0c\u90a3\u5c31\u9002\u5408\u6a21\u677f\u6a21\u5f0f\u3002 struct Weapon { protected: double damage; double charge; MagicFlag magicFlags; double range; virtual void attack(Enemy *enemy); public: void update() { while (auto enemy = Game::instance().findEnemy(range)) { attack(enemy); } } };","title":"\u6a21\u677f\u6a21\u5f0f\u8fd8\u662f\u7b56\u7565\u6a21\u5f0f\uff1a\u5982\u4f55\u9009\u62e9\uff1f"},{"location":"design_gamedev/#do_xxx","text":"\u4f8b\u5982\uff0c\u4e00\u4e2a\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u63a5\u53e3\u7c7b\uff1a struct Converter { virtual void process(const char *s, size_t len) = 0; }; \u8fd9\u4e2a\u63a5\u53e3\u662f\u8003\u8651 \u5b9e\u73b0 Converter \u5b50\u7c7b\u7684\u65b9\u4fbf \uff0c\u5bf9\u4e8e \u8c03\u7528 Converter \u7684\u7528\u6237 \u4f7f\u7528\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u65b9\u4fbf\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u8fd0\u7528\u6a21\u677f\u6a21\u5f0f\uff0c\u628a\u539f\u6765\u7684\u865a\u51fd\u6570\u63a5\u53e3\u6539\u4e3a protected \u7684\u51fd\u6570\uff0c\u4e14\u540d\u5b57\u6539\u4e3a do_process\u3002 struct Converter { protected: virtual void do_process(const char *s, size_t len) = 0; public: void process(string_view str) { return do_process(str.data(), str.size()); } void process(string str) { return do_process(str.data(), str.size()); } void process(const char *cstr) { return do_process(cstr, strlen(cstr)); } }; \u5b9e\u73b0 Converter \u7684\u5b50\u7c7b\u65f6\uff0c\u91cd\u5199\u4ed6\u7684 do_process \u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u662f protected \u7684\uff0c\u53ea\u80fd\u88ab\u7ee7\u627f\u4e86 Converter \u7684\u5b50\u7c7b\u8bbf\u95ee\u548c\u91cd\u5199\u3002 \u5916\u5c42\u7528\u6237\u53ea\u80fd\u901a\u8fc7 Converter \u57fa\u7c7b\u5c01\u88c5\u597d\u7684 process \u51fd\u6570\uff0c\u907f\u514d\u5916\u5c42\u7528\u6237\u76f4\u63a5\u5e72\u6d89\u5e95\u5c42\u7ec6\u8282\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 std::pmr::memory_resource \u3001 std::codecvt \u7b49\u90fd\u8fd0\u7528\u4e86 do_xxx \u5f0f\u7684\u6a21\u677f\u6a21\u5f0f\u5c01\u88c5\u3002","title":"\u6700\u5e38\u89c1\u7684\u662f do_xxx \u5c01\u88c5"},{"location":"design_gamedev/#_7","text":"\u6e38\u620f\u4e2d\u7684\u89d2\u8272\u901a\u5e38\u6709\u591a\u79cd\u72b6\u6001\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u602a\u7269\u53ef\u80fd\u6709\u201c\u5f85\u673a\u201d\u3001\u201c\u5de1\u903b\u201d\u3001\u201c\u8ffd\u51fb\u201d\u3001\u201c\u653b\u51fb\u201d\u7b49\u591a\u79cd\u72b6\u6001\uff0c\u800c\u6bcf\u79cd\u72b6\u6001\u4e0b\u7684\u884c\u4e3a\u90fd\u4e0d\u4e00\u6837\u3002 \u5982\u679c\u7528\u4e00\u4e2a\u679a\u4e3e\u53d8\u91cf\u6765\u8868\u793a\u5f53\u524d\u72b6\u6001\uff0c\u90a3\u6bcf\u6b21\u5c31\u90fd\u9700\u8981\u7528 switch \u6765\u5904\u7406\u4e0d\u540c\u7684\u72b6\u6001\u3002 enum MonsterState { Idle, Chase, Attack, }; struct Monster { MonsterState state = Idle; void update() { switch (state) { case Idle: if (seesPlayer()) state = Chase; break; case Chase: if (canAttack()) state = Attack; else if (!seesPlayer()) state = Idle; break; case Attack: if (!seesPlayer()) state = Idle; break; } } }; \u8fd9\u6216\u8bb8\u6027\u80fd\u4e0a\u6709\u4e00\u5b9a\u4f18\u52bf\uff0c\u7f3a\u70b9\u662f\uff0c\u6240\u6709\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5806\u79ef\u5728\u540c\u4e00\u4e2a\u51fd\u6570\u4e2d\uff0c\u5982\u679c\u6709\u591a\u4e2a\u51fd\u6570\uff08\u4e0d\u53ea\u662f update\uff09\uff0c\u90a3\u4e48\u6bcf\u6dfb\u52a0\u4e00\u4e2a\u65b0\u72b6\u6001\u5c31\u9700\u8981\u4fee\u6539\u6240\u6709\u51fd\u6570\uff0c\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u800c\u4e14\u5982\u679c\u4e0d\u540c\u7684\u72b6\u6001\u542b\u6709\u4e0d\u540c\u7684\u989d\u5916\u6570\u503c\u9700\u8981\u5b58\u50a8\uff0c\u6bd4\u5982 Chase \u72b6\u6001\u9700\u8981\u5b58\u50a8\u5f53\u524d\u901f\u5ea6\uff0c\u90a3\u5c31\u9700\u8981\u5728 Monster \u7c7b\u4e2d\u6dfb\u52a0 speed \u6210\u5458\uff0c\u800c state \u4e0d\u4e3a Chase \u65f6\u53c8\u7528\u4e0d\u5230\u8fd9\u4e2a\u6210\u5458\uff0c\u975e\u5e38\u5bb9\u6613\u6270\u4e71\u601d\u7ef4\u3002","title":"\u72b6\u6001\u6a21\u5f0f"},{"location":"design_gamedev/#_8","text":"\u4e3a\u6b64\uff0c\u63d0\u51fa\u4e86\u72b6\u6001\u6a21\u5f0f\uff0c\u5c06\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5206\u79bb\u5230\u4e0d\u540c\u7684\u7c7b\u4e2d\u3002\u4ed6\u628a\u6bcf\u79cd\u72b6\u6001\u62bd\u8c61\u4e3a\u4e00\u4e2a\u7c7b\uff0c\u72b6\u6001\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u89d2\u8272\u6301\u6709\u8868\u793a\u5f53\u524d\u72b6\u6001\u7684\u5bf9\u8c61\uff0c\u7528\u72b6\u6001\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u6765\u8868\u793a\u5904\u7406\u903b\u8f91\uff0c\u800c\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u901a\u8fc7 if \u5224\u65ad\u6765\u6267\u884c\u4e0d\u540c\u7684\u884c\u4e3a\u3002 struct Monster; struct State { virtual void update(Monster *monster) = 0; }; struct Idle : State { void update(Monster *monster) override { if (monster->seesPlayer()) { monster->setState(new Chase()); } } }; struct Chase : State { void update(Monster *monster) override { if (monster->canAttack()) { monster->setState(new Attack()); } else if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Attack : State { void update(Monster *monster) override { if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Monster { State *state = new Idle(); void update() { state->update(this); } void setState(State *newState) { delete state; state = newState; } };","title":"\u72b6\u6001\u4e0d\u662f\u679a\u4e3e\uff0c\u800c\u662f\u7c7b"},{"location":"design_gamedev/#_9","text":"\u539f\u578b\u6a21\u5f0f\u7528\u4e8e\u590d\u5236\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u4e14\u65b0\u5bf9\u8c61\u7684 \u5c5e\u6027 \u548c \u7c7b\u578b \u4e0e\u539f\u6765\u76f8\u540c\u3002\u5982\u4f55\u5b9e\u73b0\uff1f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4e0d\u884c\uff1f \u62f7\u8d1d\u6784\u9020\u51fd\u6570\u53ea\u80fd\u7528\u4e8e\u7c7b\u578b\u786e\u5b9a\u7684\u60c5\u51b5\uff0c\u5bf9\u4e8e\u5177\u6709\u865a\u51fd\u6570\uff0c\u53ef\u80fd\u5177\u6709\u989d\u5916\u6210\u5458\u7684\u591a\u6001\u7c7b\u578b\uff0c\u4f1a\u53d1\u751f object-slicing\uff0c\u5bfc\u81f4\u62f7\u8d1d\u51fa\u6765\u7684\u7c7b\u578b\u53ea\u662f\u57fa\u7c7b\u7684\u90e8\u5206\uff0c\u800c\u4e0d\u662f\u5b8c\u6574\u7684\u5b50\u7c7b\u5bf9\u8c61\u3002 RedBall ball; Ball newball = ball; // \u9519\u8bef\uff1a\u53d1\u751f\u4e86 object-slicing\uff01\u73b0\u5728 newball \u7684\u7c7b\u578b\u53ea\u662f Ball \u4e86\uff0c\u4e22\u5931\u4e86 RedBall \u7684\u4fe1\u606f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6307\u9488\u4e0d\u884c\uff1f \u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff0c\u800c\u6211\u4eec\u9700\u8981\u7684\u662f\u6df1\u62f7\u8d1d\u3002 Ball *ball = new RedBall(); Ball *newball = ball; // \u9519\u8bef\uff1a\u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff01newball \u548c ball \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u5bf9\u8c61 \u9700\u8981\u8c03\u7528\u5230\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u540c\u65f6\u53c8\u57fa\u4e8e\u6307\u9488 Ball *ball = new RedBall(); Ball *newball = new RedBall(*dynamic_cast(ball)); // \u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u91cc\u663e\u5f0f\u5199\u51fa\u4e86 ball \u5185\u90e8\u7684\u771f\u6b63\u7c7b\u578b\uff0c\u8fdd\u80cc\u4e86\u5f00\u95ed\u539f\u5219 \u5c06\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5c01\u88c5\u4e3a\u865a\u51fd\u6570 \u539f\u578b\u6a21\u5f0f\u5c06\u5bf9\u8c61\u7684\u62f7\u8d1d\u65b9\u6cd5\u4f5c\u4e3a\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u4e00\u4e2a\u865a\u63a5\u53e3\u7684\u6307\u9488\uff0c\u907f\u514d\u4e86\u76f4\u63a5\u62f7\u8d1d\u7c7b\u578b\u3002\u4f46\u865a\u51fd\u6570\u5185\u90e8\u4f1a\u8c03\u7528\u5b50\u7c7b\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u5b9e\u73b0\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u719f\u6089\u5de5\u5382\u6a21\u5f0f\u7684\u540c\u5b66\uff1a\u539f\u578b\u6a21\u5f0f\u76f8\u5f53\u4e8e\u628a\u6bcf\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e86\u81ea\u5df1\u7684\u5de5\u5382\uff0c\u53ea\u9700\u8981\u6709\u4e00\u4e2a\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u5c31\u80fd\u4e0d\u65ad\u590d\u5236\u51fa\u548c\u4ed6\u76f8\u540c\u7c7b\u578b\u7684\u5bf9\u8c61\u6765\u3002 struct Ball { virtual Ball *clone() = 0; }; struct RedBall : Ball { Ball *clone() override { return new RedBall(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { Ball *clone() override { return new BlueBall(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230 }; \u597d\u5904\u662f\uff0c\u8c03\u7528\u8005\u65e0\u9700\u77e5\u9053\u5177\u4f53\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u4ed6\u662f Ball \u7684\u5b50\u7c7b\uff0c\u5c31\u53ef\u4ee5\u514b\u9686\u51fa\u4e00\u4efd\u5b8c\u5168\u4e00\u6837\u7684\u5b50\u7c7b\u5bf9\u8c61\u6765\uff0c\u4e14\u8fd4\u56de\u7684\u4e5f\u662f\u6307\u9488\uff0c\u4e0d\u4f1a\u53d1\u751f object-slicing\u3002 Ball *ball = new RedBall(); ... Ball *newball = ball->clone(); // newball \u7684\u7c7b\u578b\u4ecd\u7136\u662f RedBall","title":"\u539f\u578b\u6a21\u5f0f"},{"location":"design_gamedev/#clone","text":"struct Ball { virtual unique_ptr clone() = 0; }; struct RedBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230\u65b0\u5bf9\u8c61\u4e2d }; \u8fd9\u6837\u5c31\u4fdd\u8bc1\u4e86\u5185\u5b58\u4e0d\u4f1a\u6cc4\u6f0f\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f shared_ptr\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a shared_ptr\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f\u624b\u52a8 delete \u7684\u539f\u59cb\u6307\u9488\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u901a\u8fc7 release\uff0c\u6545\u610f\u9020\u6210\u4e00\u6b21\u5185\u5b58\u6cc4\u6f0f\uff0c\u6210\u4e3a\u9700\u8981\u624b\u52a8\u7ba1\u7406\u7684\u539f\u59cb\u6307\u9488\u3002","title":"clone \u8fd4\u56de\u4e3a\u667a\u80fd\u6307\u9488"},{"location":"design_gamedev/#crtp-clone","text":"CRTP\uff08Curiously Recurring Template Pattern\uff09\u662f\u4e00\u79cd\u6a21\u677f\u5143\u7f16\u7a0b\u6280\u672f\uff0c\u5b83\u53ef\u4ee5\u5728\u7f16\u8bd1\u671f\u95f4\u628a\u6d3e\u751f\u7c7b\u7684\u7c7b\u578b\u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u4f20\u9012\u7ed9\u57fa\u7c7b\uff0c\u4ece\u800c\u5b9e\u73b0\u4e00\u4e9b\u81ea\u52a8\u5316\u7684\u529f\u80fd\u3002 \u7279\u70b9\u662f\uff0c\u7ee7\u627f\u4e00\u4e2a CRTP \u7c7b\u65f6\uff0c\u9700\u8981\u628a\u5b50\u7c7b\u672c\u8eab\u4f5c\u4e3a\u57fa\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u3002 \u5e76\u4e0d\u4f1a\u51fa\u73b0\u5faa\u73af\u5f15\u7528\u662f\u56e0\u4e3a\uff0c\u7528\u5230\u5b50\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\u662f\u5728\u57fa\u7c7b\u7684\u6210\u5458\u51fd\u6570\u5185\u90e8\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5728\u57fa\u7c7b\u5185\u90e8\uff0c\u800c\u6a21\u677f\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\u7684\u5b9e\u4f8b\u5316\u662f\u60f0\u6027\u7684\uff0c\u7528\u5230\u4e86\u624d\u4f1a\u5b9e\u4f8b\u5316\u3002 template struct Pet { void feed() { Derived *that = static_cast(this); that->speak(); that->speak(); } }; struct CatPet : Pet { void speak() { puts(\"Meow!\"); } }; struct DogPet : Pet { void speak() { puts(\"Bark!\"); } }; \u4e00\u822c\u7684\u8c61\u7259\u5854\u7406\u8bba\u5bb6\u6559\u6750\u4e2d\u90fd\u4f1a\u544a\u8bc9\u4f60\uff0cCRTP \u662f\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u66f4\u9ad8\u6548\u5730\u5b9e\u73b0\u6a21\u677f\u6a21\u5f0f\uff0c\u597d\u50cf CRTP \u5c31\u548c\u865a\u51fd\u6570\u52bf\u4e0d\u4e24\u7acb\u3002 \u4f46\u5c0f\u5f6d\u8001\u5e08\u7684\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0cCRTP \u5e38\u5e38\u662f\u548c\u865a\u51fd\u6570\u4e00\u8d77\u51fa\u73b0\u7684\u597d\u642d\u6863\u3002 \u4f8b\u5982 CRTP \u53ef\u4ee5\u5e2e\u52a9\u539f\u578b\u6a21\u5f0f\u5b9e\u73b0\u81ea\u52a8\u5316\u5b9a\u4e49 clone \u865a\u51fd\u6570\uff0c\u7a0d\u540e\u4ecb\u7ecd\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u4e2d\u4e5f\u4f1a\u7528\u5230 CRTP\u3002 struct Ball { virtual unique_ptr clone() = 0; }; template struct BallImpl : Ball { // \u81ea\u52a8\u5b9e\u73b0 clone \u7684\u8f85\u52a9\u5de5\u5177\u7c7b unique_ptr clone() override { Derived *that = static_cast(this); return make_unique(*that); } }; struct RedBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; struct BlueBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0c\u5bf9\u8c61\u7c7b\u578b zeno::IObject \u7684\u6df1\u62f7\u8d1d\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u539f\u578b\u6a21\u5f0f\u3002","title":"CRTP \u6a21\u5f0f\u81ea\u52a8\u5b9e\u73b0 clone"},{"location":"design_gamedev/#_10","text":"\u6e38\u620f\u4e2d\u7684\u7269\u4f53\uff08\u6e38\u620f\u5bf9\u8c61\uff09\u901a\u5e38\u7531\u591a\u4e2a\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u53ef\u80fd\u7531\u201c\u89d2\u8272\u63a7\u5236\u5668\u201d\u3001\u201c\u89d2\u8272\u5916\u89c2\u201d\u3001\u201c\u89d2\u8272\u52a8\u753b\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4e00\u4e2a\u5b50\u5f39\u53ef\u80fd\u7531\u201c\u5b50\u5f39\u7269\u7406\u201d\u3001\u201c\u5b50\u5f39\u5916\u89c2\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\u3002 \u7ec4\u4ef6\u6a21\u5f0f\u662f \u6e38\u620f\u5f00\u53d1\u9886\u57df\u6700\u91cd\u8981\u7684\u8bbe\u8ba1\u6a21\u5f0f \uff0c\u5b83\u5c06\u6e38\u620f\u5bf9\u8c61\u5206\u4e3a\u591a\u4e2a\u7ec4\u4ef6\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u53ea\u5173\u5fc3\u81ea\u5df1\u7684\u903b\u8f91\uff0c\u800c\u4e0d\u5173\u5fc3\u5176\u4ed6\u7ec4\u4ef6\u7684\u903b\u8f91\u3002 \u8e69\u811a\u7684\u6e38\u620f\u5f00\u53d1\u8005\uff08\u901a\u5e38\u662f 985 \u91cf\u4ea7\u51fa\u6765\u7684\u8c61\u7259\u5854\u5de8\u5a74\uff09\u4f1a\u628a\u6bcf\u4e2a\u7ec4\u4ef6\u5199\u6210\u4e00\u4e2a\u7c7b\uff0c\u7136\u540e\u4f7f\u7528\u201c\u591a\u91cd\u7ee7\u627f\u201d\u7ee7\u627f\u51fa\u4e00\u4e2a\u73a9\u5bb6\u7c7b\u6765\uff0c\u5e76\u606c\u4e0d\u77e5\u803b\u5730\u58f0\u79f0\u201c\u6211\u4e5f\u4f1a\u7ec4\u4ef6\u6a21\u5f0f\u4e86\u201d\u3002 \u7136\u800c\uff0c\u8fd9\u6837\u7684\u7f3a\u70b9\u6709\uff1a \u6e38\u620f\u5f00\u53d1\u4e2d\u666e\u904d\u6d89\u53ca\u5230 update \u51fd\u6570\uff0c\u800c\u73a9\u5bb6\u7c7b\u7684 update \u9700\u8981\u8f6e\u6d41\u8c03\u7528\u6bcf\u4e2a\u7ec4\u4ef6\u7684 update \u51fd\u6570\u3002 \u800c\u591a\u91cd\u7ee7\u627f\u4e00\u65e6\u9047\u5230\u91cd\u540d\u7684 update \u51fd\u6570\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519 \u201c\u6709\u6b67\u4e49\u7684\u51fd\u6570\u540d\u201d \u6446\u70c2\u4e0d\u5e72\u4e86\uff0c\u9700\u8981\u4f60\u624b\u5199\u65b0\u7684 update \u51fd\u6570\u3002 struct Player : PlayerController, PlayerAppearance, PlayerAnimation { void update() { PlayerController::update(); PlayerAppearance::update(); PlayerAnimation::update(); } }; C++\uff08\u548c\u5927\u591a\u6570\u975e\u811a\u672c\u8bed\u8a00\u90fd\uff09\u4e0d\u652f\u6301\u8fd0\u884c\u65f6\u6dfb\u52a0\u6216\u5220\u9664\u57fa\u7c7b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u8981\u6dfb\u52a0\u4e00\u4e2a\u65b0\u89d2\u8272\uff0c\u6216\u662f\u4fee\u6539\u73b0\u6709\u89d2\u8272\u7684\u903b\u8f91\uff0c\u5c31\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u4e00\u904d\u6574\u4e2a\u6e38\u620f\u7684\u6e90\u7801\u3002 \u5728\u7f51\u7edc\u6e38\u620f\u4e2d\uff0c\u66f4\u65b0 DLL \u548c\u66f4\u65b0\u8d44\u4ea7\uff08\u56fe\u7247\u3001\u97f3\u9891\u3001\u6a21\u578b\u7b49\uff09\u662f\u5b8c\u5168\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u670d\u52a1\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u505c\u673a\u66f4\u65b0\uff0c\u66f4\u65b0\u8d44\u4ea7\u4e0d\u9700\u8981\uff0cDLL \u53ef\u4ee5\u88ab\u7f16\u7a0b\u5141\u8bb8\u52a8\u6001\u52a0\u8f7d\u65b0\u7684\u8d34\u56fe\u3002 \u5bf9\u4e8e\u5ba2\u6237\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u91cd\u65b0\u8d70\u4e00\u904d\u5f88\u957f\u7684 App \u5ba1\u6838\u6d41\u7a0b\uff08\u56e0\u4e3a\u76f4\u63a5\u8fd0\u884c\u4e8e\u624b\u673a\u4e0a\u7684 C++ \u53ef\u4ee5\u8f7b\u677e\u690d\u5165\u75c5\u6bd2\uff09\uff0c\u800c\u66f4\u65b0\u8d44\u4ea7\u7684\u5ba1\u6838\u6d41\u7a0b\u77ed\u5f97\u591a\uff0c\u751a\u81f3\u5e72\u8106\u65e0\u9700\u5ba1\u6838\u3002 \u56e0\u6b64\uff0c\u6e38\u620f\u5f00\u53d1\u8005\u5f88\u5c11\u4f1a\u628a\u6e38\u620f\u903b\u8f91\u76f4\u63a5\u5199\u6b7b\u5728 C++ \u4e2d\uff0c\u8fd9\u4f1a\u8ba9\u66f4\u65b0\u6e38\u620f\u903b\u8f91\uff08\u4f8b\u5982\u4fee\u590d BUG\uff09\u9700\u8981\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6bcf\u6b21\u505c\u673a\u66f4\u65b0\u90fd\u4f1a\u7ed9\u73a9\u5bb6\u53d1 200 \u5408\u6210\u7389\uff09 \u4f60\u7ecf\u5e38\u770b\u5230\u6e38\u620f\u9886\u57df\u7684 \u201cC++ \u5f00\u53d1\u5c97\u201d \u5b9e\u9645\u4e0a\u662f \u201c\u89e3\u91ca\u5668\u5f00\u53d1\u201d\u3002 \u6e38\u620f\u5f00\u53d1\u8005\u4f1a\u628a\u7ecf\u5e38\u9700\u8981\u7ef4\u62a4\u548c\u66f4\u65b0\u7684\u6e38\u620f\u903b\u8f91\u5199\u5728\u5982 Lua\u3001Python \u7b49\u811a\u672c\u8bed\u8a00\u4e2d\uff0c\u7136\u540e\u5728 C++ \u4e2d\u96c6\u6210\u4e00\u4e2a Lua\u3001Python \u89e3\u91ca\u5668\uff0c\u6839\u636e\u89e3\u91ca\u5668\u7684\u8c03\u7528\u7ed3\u679c\uff0c\u52a8\u6001\u521b\u5efa\u51fa C++ \u5bf9\u8c61\uff0c\u7136\u540e\u628a\u8fd9\u4e9b C++ \u5bf9\u8c61\u5f53\u4f5c\u7ec4\u4ef6\u6dfb\u52a0\u5230\u6e38\u620f\u5bf9\u8c61\u4e0a\u3002 \u5f53\u51fa\u73b0 BUG \u65f6\uff0c\u53ea\u9700\u8981\u4fee\u6539\u8fd9\u4e9b\u811a\u672c\u8bed\u8a00\u7684\u4ee3\u7801\uff0c\u7136\u540e\u4ee5\u201c\u8d44\u4ea7\u201d\u7684\u5f62\u5f0f\uff0c\u5feb\u901f\u8d70\u4e00\u904d\u5ba1\u6838\u6d41\u7a0b\uff0c\u5c31\u53ef\u4ee5\u4fee\u590d BUG\uff0c\u65e0\u9700\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6709\u65f6\u5019\u4f1a\u201c\u8d44\u6e90\u5df2\u8fc7\u671f\u201d\u201c\u6b63\u5728\u4e0b\u8f7d\u8d44\u6e90\u201d\uff0c\u6709\u65f6\u662f\u66f4\u65b0\u4e86\u56fe\u7247\u8d44\u6e90\uff0c\u4e5f\u53ef\u80fd\u662f\u5728\u811a\u672c\u8bed\u8a00\u91cc\u52a8\u6001\u4fee\u590d\u4e86 BUG\uff09 Java \u548c C# \u90fd\u6ca1\u6709\u591a\u91cd\u7ee7\u627f\u3002\u4f60\u8ba9\u4eba\u5bb6\u57fa\u4e8e C# \u7684 Unity \u600e\u4e48\u6d3b\uff1f \u56e0\u6b64\uff0c\u771f\u6b63\u7684\u7ec4\u4ef6\u6a21\u5f0f\u90fd\u4f1a\u5141\u8bb8\u52a8\u6001\u63d2\u5165\u7ec4\u4ef6\uff0c\u800c\u4e0d\u662f\u7f16\u8bd1\u671f\u5199\u6b7b\u3002\u9664\u975e\u4f60\u662f\u67d0\u4e9b\u8c61\u7259\u5854\u7684\u4e00\u6b21\u6027\u6c99\u96d5\u5927\u4f5c\u4e1a\u3002 \u6e38\u620f\u5bf9\u8c61\u7ec4\u4ef6\u5316\u540e\uff0c\u53ef\u4ee5\u7075\u6d3b\u5730\u7ec4\u5408\u51fa\u4e0d\u540c\u7684\u6e38\u620f\u5bf9\u8c61\uff0c\u800c\u4e0d\u5fc5\u4e3a\u6bcf\u4e00\u79cd\u7ec4\u5408\u90fd\u5199\u4e00\u4e2a\u7c7b\u3002 struct Component { virtual void update(GameObject *go) = 0; virtual ~Component() = default; // \u6ce8\u610f\uff01 }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } }; \u6ce8\u610f\uff1aComponent \u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u4e3a\u865a\u51fd\u6570\u3002\u5426\u5219\uff0c\u5f53 Component \u88ab delete \u65f6\uff0c\u53ea\u4f1a\u8c03\u7528\u5230 Component \u8fd9\u4e2a\u57fa\u7c7b\u7684\u6790\u6784\u51fd\u6570\uff0c\u800c\u4e0d\u4f1a\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6790\u6784\u51fd\u6570\u3002 \u5426\u5219\uff0c\u5982\u679c\u4f60\u7684\u5b50\u7c7b\u6709 string\u3001vector \u8fd9\u79cd\u6301\u6709\u5185\u5b58\u8d44\u6e90\u7684\u5bb9\u5668\u7c7b\uff0c\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f\uff0c\u5bfc\u81f4\u6e38\u620f\u8fd0\u884c\u8d8a\u4e45\u5185\u5b58\u5360\u7528\u8d8a\u5927\u3002 \u795e\u5947\u7684\u662f\uff0c\u5982\u679c\u4f60\u7684 Component \u5168\u90e8\u90fd\u662f\u7528 make_shared \u521b\u5efa\u7684\uff0c\u90a3\u5c31\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\u4e86\uff0c\u8fd9\u5f97\u76ca\u4e8e shared_ptr \u4f1a\u5bf9 deleter \u505a\u7c7b\u578b\u64e6\u9664\u3002 make_unique \u548c new \u521b\u5efa\u7684\u5c31\u4f1a\u6cc4\u6f0f\uff0c\u56e0\u4e3a\u4ed6\u4eec delete \u65f6\u662f\u4ee5\u57fa\u7c7b\u6307\u9488\u53bb delete \u7684\uff0c\u800c shared_ptr \u4f1a\u5728\u6784\u9020\u65f6\u5c31\u8bb0\u4f4f\u5b50\u7c7b\u7684 deleter\u3002 \u6240\u6709\u7ec4\u4ef6\uff0c\u90fd\u652f\u6301 update\uff08\u6bcf\u5e27\u66f4\u65b0\uff09\u64cd\u4f5c\uff1a struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void update(GameObject *go) override { position += velocity * dt; } }; struct LivingBeing : Component { int ageLeft; void update(GameObject *go) override { if (ageLeft < 0) go->kill(); else ageLeft -= 1; } };","title":"\u7ec4\u4ef6\u6a21\u5f0f"},{"location":"design_gamedev/#_11","text":"\u7ec4\u4ef6\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a \u7ec4\u4ef6\u4f5c\u4e3a\u4e00\u4e2a\u666e\u901a\u5bf9\u8c61\uff0c\u7531 GameObject \u7684\u6784\u9020\u51fd\u6570\u521b\u5efa\u3002 struct Player : GameObject { Movable *movable; LivingBeing *livingBeing; PlayerController *playerController; PlayerAppearance *playerAppearance; Player() { movable = new Movable(); livingBeing = new LivingBeing(42); playerController = new PlayerController(); playerAppearance = new PlayerAppearance(); add(movable); add(livingBeing); add(playerController); add(playerAppearance); } }; \u4e0d\u518d\u9700\u8981\u5b9a\u4e49 Player \u7c7b\u53ca\u5176\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u521b\u5efa\u5177\u6709 Player \u6240\u9700\u6240\u6709\u7ec4\u4ef6\u7684 GameObject \u5bf9\u8c61\u5373\u53ef\u3002 GameObject *makePlayer() { GameObject *go = new GameObject(); go->add(new Movable()); go->add(new LivingBeing(42)); go->add(new PlayerController()); go->add(new PlayerAppearance()); return go; } \u6b63\u7ecf\u6e38\u620f\u5f15\u64ce\u90fd\u91c7\u7528\u540e\u8005\uff0c\u4e0d\u7528\u6dfb\u52a0 C++ \u6e90\u7801\uff0c\u53ea\u662f\u4ece xml \u7b49\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u6bcf\u4e2a\u7c7b\u6240\u4f9d\u8d56\u7684\u7ec4\u4ef6\uff0c\u5c31\u80fd\u521b\u5efa\u65b0\u7684\u73a9\u5bb6\u7c7b\uff0c\u65b9\u4fbf\u52a8\u6001\u66f4\u65b0\u6e38\u620f\u903b\u8f91\u800c\u65e0\u9700\u91cd\u65b0\u53d1\u5e03 dll\u3002","title":"\u7ec4\u4ef6\u7684\u521b\u5efa"},{"location":"design_gamedev/#_12","text":"\u7f3a\u70b9\u662f\uff0c\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u9700\u8981\u901a\u8fc7 GameObject \u6765\u5b9e\u73b0\uff0c\u800c GameObject \u5e76\u4e0d\u77e5\u9053\u5b83\u7684\u7ec4\u4ef6\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u5c31\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u7ec4\u4ef6\u7684\u6210\u5458\u3002 \u4f8b\u5982\uff0cPlayerController \u7ec4\u4ef6\u60f3\u8981\u6539\u53d8 Movable \u7ec4\u4ef6\u7684 velocity\uff0c\u5c31\u65e0\u6cd5\u76f4\u63a5\u6539\u3002 struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { go->velocity.y += 1; // \u9519\u8bef\uff01velocity \u662f Movable \u7ec4\u4ef6\u7684\u6210\u5458\uff0c\u800c\u4e0d\u662f GameObject \u91cc\u76f4\u63a5\u6709\u7684 } if (isKeyPressed(GLFW_KEY_S)) { go->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { go->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { go->velocity.x += 1; } } }; \u5982\u4f55\u89e3\u51b3\u7ec4\u4ef6\u4e4b\u95f4\u901a\u4fe1\u96be\u7684\u95ee\u9898\uff1f \u628a\u5e38\u7528\u7684\u5b57\u6bb5\uff0c\u4f8b\u5982 position \u548c velocity \u76f4\u63a5\u653e\u5728 GameObject \u91cc\uff0c\u4f9b\u6240\u6709\u7ec4\u4ef6\u76f4\u63a5\u8bbf\u95ee\u3002 struct GameObject { glm::vec3 position; glm::vec3 velocity; ... }; \u5141\u8bb8\u7528\u6237\u6839\u636e\u5176\u4ed6\u7ec4\u4ef6\u7684\u7c7b\u578b\uff0c\u76f4\u63a5\u83b7\u53d6\u51fa\u5176\u4ed6\u7ec4\u4ef6\u7684\u6307\u9488\uff0c\u5373\u53ef\u8bbf\u95ee\u5176\u6210\u5458\u3002 struct PlayerController : Component { void update(GameObject *go) override { Movable *movable = go->getComponent(); if (!movable) { throw runtime_error(\"\u8fd9\u4e2a\u5bf9\u8c61\u4f3c\u4e4e\u4e0d\u652f\u6301\u79fb\u52a8\"); } if (isKeyPressed(GLFW_KEY_W)) { movable->velocity.y += 1; } if (isKeyPressed(GLFW_KEY_S)) { movable->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { movable->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { movable->velocity.x += 1; } } }; \u7136\u800c\uff0cgetComponent \u5982\u4f55\u5b9e\u73b0\uff1f struct GameObject { template T *getComponent() { for (auto &&c: components) { if (T *t = dynamic_cast(c)) { return t; } } return nullptr; } }; \u7528\u5230\u4e86 dynamic_cast \uff0c\u8fd9\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\u4e00\u79cd\u5b9e\u73b0\u65b9\u5f0f\uff0c\u800c\u4e14\u4e5f\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u66f4\u597d\u7684\u5b9e\u73b0\u65b9\u5f0f\u662f\u5229\u7528 typeid \u505a map \u7684\u952e\uff0c\u52a0\u901f\u67e5\u627e\u3002\u6ca1\u6709\u6027\u80fd\u95ee\u9898\uff0c\u4f46\u4f9d\u7136\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 struct GameObject { unordered_map components; template T *getComponent() { if (auto it = components.find(typeid(T)); it != components.end()) { return dynamic_cast(it->second); } else { return nullptr; } } void add(Component *component) { components[typeid(*component)] = component; } }; \u8ba9 PlayerController \u53d1\u51fa\u6307\u5b9a\u7c7b\u578b\u7684\u6d88\u606f\u5bf9\u8c61\uff0c\u7531 Movable \u68c0\u67e5\u5e76\u5904\u7406\u3002 \u6d88\u606f\u7c7b\u578b\u4e5f\u662f\u591a\u6001\u7684\uff0c\u521d\u5b66\u8005\u53ef\u4ee5\u5148\u901a\u8fc7 dynamic_cast \u5b9e\u73b0\u7c7b\u578b\u68c0\u67e5\u3002\u7a0d\u540e\u6211\u4eec\u4f1a\u4ecb\u7ecd\u66f4\u4e13\u4e1a\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u628a\u5b50\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u57fa\u7c7b\u6307\u9488\u3002 \u800c dynamic_cast \u53ef\u4ee5\u628a\u57fa\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u5b50\u7c7b\u6307\u9488\u3002 \u5982\u679c\u4ed6\u6307\u5411\u7684\u5bf9\u8c61\u786e\u5b9e\u5c31\u662f\u90a3\u4e2a\u5b50\u7c7b\u7c7b\u578b\u7684\u8bdd\uff0c\u5c31\u6b63\u5e38\u8fd4\u56de\u5b50\u7c7b\u6307\u9488\u4e86\u3002 \u5426\u5219\uff0c\u5982\u679c\u7c7b\u578b\u4e0d\u5339\u914d\uff0c dynamic_cast \u4f1a\u8fd4\u56de nullptr\u3002\u53ea\u9700\u5224\u65ad\u8fd4\u56de\u7684\u6307\u9488\u662f\u4e0d\u662f nullptr \u5c31\u77e5\u9053\u662f\u5426\u7c7b\u578b\u5339\u914d\u4e86\u3002","title":"\u7ec4\u4ef6\u4e4b\u95f4\u5982\u4f55\u901a\u4fe1"},{"location":"design_gamedev/#_13","text":"struct Message { virtual ~Message() = default; // C++ \u89c4\u5b9a\uff1a\u53ea\u6709\u591a\u6001\u7c7b\u578b\u624d\u80fd dynamic_cast\uff0c\u8fd9\u91cc\u6211\u4eec\u7528\u4e0d\u5230\u865a\u51fd\u6570\uff0c\u90a3\u5c31\u53ea\u8ba9\u6790\u6784\u51fd\u6570\u4e3a\u865a\u51fd\u6570\uff0c\u5373\u53ef\u4f7f Message \u53d8\u4e3a\u591a\u6001\u7c7b\u578b }; struct MoveMessage : Message { glm::vec3 velocityChange; }; struct Component { virtual void update(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) override { // \u6240\u6709\u4e0d\u540c\u7684\u6d88\u606f\u7c7b\u578b\u90fd\u4f1a\u8fdb\u5165\u6b64\u51fd\u6570 if (MoveMessage *mm = dynamic_cast(msg)) { // \u4f46\u53ea\u6709\u771f\u6b63\u7c7b\u578b\u4e3a MoveMessage \u7684\u6d88\u606f\u4f1a\u88ab\u5904\u7406 velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } } }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } void send(Message *msg) { for (auto &&c: components) { c->handleMessage(msg); } } }; \u8fd9\u5c31\u662f\u6240\u8c13\u7684\u89c2\u5bdf\u8005\u6a21\u5f0f\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u53ef\u4ee5\u6536\u5230\u6240\u6709\u6d88\u606f\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u3002 \u4f46\u8fd9\u6837\u505a\u7684\u7f3a\u70b9\u662f\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u9700\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u4e0d\u8bba\u662f\u5426\u662f\u81ea\u5df1\u9700\u8981\u7684\uff0c\u5982\u679c\u7ec4\u4ef6\u6570\u91cf\u591a\uff0c\u6d88\u606f\u7c7b\u578b\u53c8\u591a\uff0c\u5c31\u4f1a\u51fa\u73b0\u6027\u80fd\u95ee\u9898\u3002","title":"\u89c2\u5bdf\u8005\u6a21\u5f0f"},{"location":"design_gamedev/#-","text":"\u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f\u662f\u89c2\u5bdf\u8005\u6a21\u5f0f\u7684\u5347\u7ea7\u7248\uff0c\u7531\u4e00\u4e2a\u4e2d\u5fc3\u7684\u4e8b\u4ef6\u603b\u7ebf\u6765\u7ba1\u7406\u6d88\u606f\u7684\u5206\u53d1\u3002\u4e8b\u4ef6\u603b\u7ebf\u901a\u5e38\u4f5c\u4e3a GameObject \u7684\u6210\u5458\u51fa\u73b0\u3002 \u6bcf\u4e2a\u7ec4\u4ef6\u53ef\u4ee5\u8ba2\u9605\u81ea\u5df1\u611f\u5174\u8da3\u7684\u6d88\u606f\u7c7b\u578b\uff0c\u5f53\u4e8b\u4ef6\u603b\u7ebf\u6536\u5230\u6d88\u606f\u65f6\uff0c\u53ea\u628a\u6d88\u606f\u5206\u53d1\u7ed9\u8ba2\u9605\u8005\uff0c\u800c\u4e0d\u662f\u6240\u6709\u7ec4\u4ef6\u3002 struct GameObject { vector components; unordered_map> subscribers; // \u4e8b\u4ef6\u603b\u7ebf template void subscribe(Component *component) { subscribers[type_index(typeid(EventType))].push_back(component); } template void send(EventType *msg) { for (auto &&c: subscribers[type_index(typeid(EventType))]) { c->handleMessage(msg); } } void add(Component *component) { components.push_back(component); component->subscribeMessages(this); } void update() { for (auto &&c: components) { c->update(this); } } }; struct Component { virtual void update(GameObject *go) = 0; virtual void subscribeMessages(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void subscribeMessages(GameObject *go) { go->subscribe(this); } void handleMessage(Message *msg) override { if (MoveMessage *mm = dynamic_cast(msg)) { velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_SPACE)) { JumpMessage jm; go->send(&jm); } } }; \u8fd9\u6837\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u6309\u9700\u901a\u4fe1\u3002","title":"\u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f"},{"location":"design_gamedev/#_14","text":"struct Message { virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; }; struct JumpMessage { double jumpHeight; }; \u5982\u4f55\u5b9a\u4e49\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u7684\u5904\u7406\u65b9\u5f0f\uff1f struct MessageVisitor; // \u524d\u5411\u58f0\u660e struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(MoveMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct JumpMessage { double jumpHeight; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(JumpMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct MessageVisitor { virtual void visit(MoveMessage *mm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 virtual void visit(JumpMessage *jm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 }; struct Movable : MessageVisitor { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) { msg->accept(this); } void visit(MoveMessage *mm) override { velocity += mm->velocityChange; } void visit(JumpMessage *jm) override { velocity.y += sqrt(2 * 9.8 * jm->jumpHeight); } }; \u8fd9\u5c31\u662f\u8bbf\u95ee\u8005\u6a21\u5f0f\uff0c\u540c\u65f6\u7528\u5230\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u548c\u91cd\u8f7d\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u90fd\u80fd\u5b9a\u5236\u4e00\u4e2a\u5904\u7406\u65b9\u5f0f\uff0c\u800c\u4e0d\u7528\u901a\u8fc7\u4f4e\u6548\u7684 dynamic_cast \u5224\u65ad\u6d88\u606f\u7c7b\u578b\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u662f\u5426\u7b26\u5408\u5f00\u95ed\u539f\u5219\u5462\uff1f \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u6d88\u606f\u7c7b\u578b \u5728 MessageVisitor \u4e2d\u6dfb\u52a0\u4e00\u4e2a visit \u7684\u91cd\u8f7d \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u7ec4\u4ef6\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u7ec4\u4ef6\u7c7b\u578b \u8fd9\u4e09\u9879\u4fee\u6539\u90fd\u662f\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\uff0c\u5e76\u4e0d\u4f1a\u51fa\u73b0\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u7684\u60c5\u51b5\u3002 \u4f46\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\u8bbe\u8ba1\uff0c\u56e0\u6b64\u6211\u4eec\u8ba9\u6240\u6709\u7684 visit \u865a\u51fd\u6570\u6709\u4e00\u4e2a\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u4ec0\u4e48\u90fd\u4e0d\u505a\u3002\u8fd9\u6837\u5f53\u65b0\u589e\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u867d\u7136\u9700\u8981\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u91cd\u65b0\u7f16\u8bd1\u4e86\uff0c\u4f46\u662f\u7a0b\u5e8f\u5458\u65e0\u9700\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\uff0c\u6e90\u7801\u7ea7\u522b\u4e0a\uff0c\u662f\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u7684\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u901a\u5e38\u7528\u4e8e acceptor \u6570\u91cf\u6709\u9650\uff0c\u4f46 visitor \u7684\u7ec4\u4ef6\u7c7b\u578b\u5343\u53d8\u4e07\u5316\u7684\u60c5\u51b5\u3002 \u5982\u679c\u6d88\u606f\u7c7b\u578b\u6709\u9650\uff0c\u7ec4\u4ef6\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5982\u679c\u7ec4\u4ef6\u7c7b\u578b\u6709\u9650\uff0c\u6d88\u606f\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5e38\u4f5c\u4e3a acceptor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684 IR \u8282\u70b9\uff08\u4ee3\u7801\u4e2d\u95f4\u8868\u793a\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u6d88\u606f\u7c7b\u578b\u3002 \u5e38\u4f5c\u4e3a visitor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684\u4f18\u5316 pass\uff08\u4f1a\u4fee\u6539 IR \u8282\u70b9\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u63a5\u53d7\u6d88\u606f\u7ec4\u4ef6\u7c7b\u578b\u3002 \u4f46\u662f\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5b9e\u73b0 accept \u7684\u91cd\u8f7d\uff0c\u5185\u5bb9\u5b8c\u5168\u4e00\u6837\uff0c\u51fa\u73b0\u4e86\u4ee3\u7801\u91cd\u590d\u3002 Java \u7684\u6a21\u677f\u662f type-erasure \u7684\uff0c\u5bf9\u6b64\u675f\u624b\u65e0\u7b56\u3002\u800c C++ \u7684\u6a21\u677f\u662f refined-generic\uff0c\u53ef\u4ee5\u5229\u7528 CRTP \u81ea\u52a8\u5b9e\u73b0\u8fd9\u90e8\u5206\uff1a struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; template struct MessageImpl : Message { void accept(MessageVisitor *visitor) override { static_assert(std::is_base_of_v); visitor->visit(static_cast(this)); } }; struct MoveMessage : MessageImpl { glm::vec3 velocityChange; // \u81ea\u52a8\u5b9e\u73b0\u4e86 accept \u51fd\u6570 }; struct JumpMessage : MessageImpl { double jumpHeight; }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0cZFX \u7f16\u8bd1\u5668\u7684 IR \u4f18\u5316\u7cfb\u7edf\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002","title":"\u8bbf\u95ee\u8005\u6a21\u5f0f"},{"location":"design_gamedev/#mvc","text":"\u8bbe\u8ba1\u6a21\u5f0f\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u8bdd\u9898\uff0c\u672c\u671f\u5148\u8bb2\u5230\u8fd9\u91cc\uff0c\u4e0b\u96c6\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd UI \u5f00\u53d1\u4e2d\u5927\u540d\u9f0e\u9f0e\u7684 MVC \u6a21\u5f0f\u3002 MVC \u6a21\u5f0f\u662f\u4e00\u79cd\u67b6\u6784\u6a21\u5f0f\uff0c\u5b83\u5c06\u5e94\u7528\u7a0b\u5e8f\u5206\u4e3a\u4e09\u4e2a\u6838\u5fc3\u90e8\u5206\uff1a\u6a21\u578b\uff08Model\uff09\u3001\u89c6\u56fe\uff08View\uff09\u548c\u63a7\u5236\u5668\uff08Controller\uff09\uff0c\u901a\u8fc7\u5206\u79bb\u5e94\u7528\u7a0b\u5e8f\u7684\u8f93\u5165\u3001\u5904\u7406\u548c\u8f93\u51fa\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u6a21\u578b\uff08Model\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u6570\u636e\u548c\u4e1a\u52a1\u903b\u8f91\uff0c\u901a\u5e38\u7531\u6570\u636e\u7ed3\u6784\u548c\u6570\u636e\u5e93\u7ec4\u6210\u3002 \u89c6\u56fe\uff08View\uff09\uff1a\u8d1f\u8d23\u5c55\u793a\u6570\u636e\u548c\u7528\u6237\u754c\u9762\uff0c\u901a\u5e38\u7531 HTML\u3001CSS \u548c JavaScript \u7ec4\u6210\u3002 \u63a7\u5236\u5668\uff08Controller\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u7528\u6237\u4ea4\u4e92\u548c\u8c03\u5ea6\u6a21\u578b\u548c\u89c6\u56fe\uff0c\u901a\u5e38\u7531\u540e\u7aef\u8bed\u8a00\uff08\u5982 PHP\u3001Java \u7b49\uff09\u5b9e\u73b0\u3002 MVC \u6a21\u5f0f\u7684\u4f18\u70b9\uff1a \u4f4e\u8026\u5408\uff1a\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u804c\u8d23\u6e05\u6670\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u8fdb\u884c\u5355\u72ec\u7684\u4fee\u6539\u548c\u7ef4\u62a4\u3002 \u53ef\u6269\u5c55\u6027\uff1a\u7531\u4e8e\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u4f4e\u8026\u5408\u6027\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u6dfb\u52a0\u65b0\u7684\u529f\u80fd\u548c\u7ec4\u4ef6\u3002 \u53ef\u7ef4\u62a4\u6027\uff1a\u5206\u79bb\u4e86\u4e0d\u540c\u7684\u804c\u8d23\uff0c\u4f7f\u5f97\u4ee3\u7801\u66f4\u5bb9\u6613\u7406\u89e3\u548c\u7ef4\u62a4\u3002","title":"MVC \u6a21\u5f0f"},{"location":"design_overview/","text":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 \u4e0d\u8981\u53bb\u6307\u6325\u4e0b\u9762\u600e\u4e48\u505a\uff01 \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. \u4f60\u597d O(N) O(N) \u554a\uff01","title":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5)"},{"location":"design_overview/#_1","text":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 \u4e0d\u8981\u53bb\u6307\u6325\u4e0b\u9762\u600e\u4e48\u505a\uff01","title":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5)"},{"location":"design_overview/#_2","text":"x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. \u4f60\u597d O(N) O(N) \u554a\uff01","title":"\u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9"},{"location":"design_variant/","text":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 visitor \u6a21\u5f0f \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 TODO visitor \u6a21\u5f0f","title":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5)"},{"location":"design_variant/#_1","text":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 visitor \u6a21\u5f0f","title":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5)"},{"location":"design_variant/#_2","text":"TODO","title":"\u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9"},{"location":"design_variant/#visitor","text":"","title":"visitor \u6a21\u5f0f"},{"location":"design_virtual/","text":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01 \u8bb8\u591a\u8bbe\u8ba1\u6a21\u5f0f\u90fd\u4e0e\u865a\u51fd\u6570\u606f\u606f\u76f8\u5173\uff0c\u4eca\u5929\u6211\u4eec\u6765\u5b66\u4e60\u4e00\u4e9b\u5e38\u7528\u7684\u3002 \u7b56\u7565\u6a21\u5f0f \u8fed\u4ee3\u5668\u6a21\u5f0f \u9002\u914d\u5668\u6a21\u5f0f \u5de5\u5382\u6a21\u5f0f \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f \u4eab\u5143\u6a21\u5f0f \u4ee3\u7406\u6a21\u5f0f \u5f88\u591a\u6559\u6750\u4e2d\u90fd\u4f1a\u4e3e\u51fa\u8fd9\u79cd\u770b\u8d77\u6765\u597d\u50cf\u5f88\u6709\u8bf4\u670d\u529b\u7684\u4f8b\u5b50\uff1a struct Pet { virtual void speak() = 0; }; struct CatPet \uff1aPet { void speak() override { puts(\"\u55b5\"); } }; struct DogPet \uff1aPet { void speak() override { puts(\"\u6c6a\"); } }; int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); cat->speak(); dog->speak(); } \u7136\u800c\uff0c\u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2d\uff0c\u865a\u51fd\u6570\u53ef\u6709\u53ef\u65e0\uff0c\u5e76\u6ca1\u6709\u53d1\u6325\u4efb\u4f55\u4ef7\u503c\uff0c\u56e0\u4e3a\u666e\u901a\u6210\u5458\u51fd\u6570\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 \u865a\u51fd\u6570\u771f\u6b63\u7684\u4ef7\u503c\u5728\u4e8e\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u5165\u5176\u4ed6\u51fd\u6570\u65f6\uff01\u53ef\u4ee5\u590d\u7528\u90a3\u4e2a\u51fd\u6570\u91cc\u7684\u4ee3\u7801\u3002 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); puts(\"\u5582\u98df\u5b8c\u6bd5\"); } int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); feed(cat); feed(dog); } \u4f18\u70b9\u5728\u4e8e\uff0cfeed \u51fd\u6570\u53ea\u7528\u5b9e\u73b0\u4e00\u904d\u4e86\u3002\u5982\u679c\u6ca1\u6709\u865a\u51fd\u6570\uff1a void feed(DogPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u6c6a\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u55b5\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u5582\u98df \u548c \u5582\u98df\u5b8c\u6bd5 \u91cd\u590d\u4e24\u904d\uff01\u5982\u679c\u6211\u4eec\u53c8\u8981\u5f15\u5165\u4e00\u79cd\u65b0\u52a8\u7269 PigPet \u5462\uff1f\u4f60\u53c8\u8981\u624b\u5fd9\u811a\u4e71\u590d\u5236\u7c98\u8d34\u4e00\u4efd\u65b0\u7684 feed \u51fd\u6570\uff01 void feed(PigPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u62f1\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u6539\u4e86\u9700\u6c42\uff0c\u4ed6\u8bf4\u52a8\u7269\u73b0\u5728\u8981\u53eb\u4e24\u6b21\u3002 \u91c7\u7528\u4e86\u865a\u51fd\u6570\u7684\u4f60\uff0c\u53ea\u9700\u8981\u5728 feed \u51fd\u6570\u5185\u589e\u52a0\u4e00\u6b21 speak \u5373\u53ef\uff0c\u8f7b\u677e\uff01 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); pet->speak(); // \u52a0\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u5982\u679c\u4e00\u5f00\u59cb\u6ca1\u7528\u865a\u51fd\u6570\uff0c\u5c31\u5f97\u8fde\u6539 3 \u4e2a\u5730\u65b9\uff01 void feed(DogPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u4e14\u4e07\u4e00\u590d\u5236\u7c98\u8d34\u7684\u65f6\u5019\u6709\u4e2a\u5730\u65b9\u5199\u9519\u4e86\uff0c\u975e\u5e38\u9690\u853d\uff0c\u5f88\u5bb9\u6613\u53d1\u73b0\u4e0d\u4e86\uff1a void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); puts(\"\u55b5\"); // \u628a\u732b\u7684\u4ee3\u7801\u590d\u5236\u8fc7\u6765\u7684\u65f6\u5019\u6f0f\u6539\u4e86 \ud83e\udd2f puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u865a\u51fd\u6570\u5b9e\u6218\u6848\u4f8b \u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8bf4\u7684\u8fd9\u4e9b\u6211\u90fd\u4f1a\uff0c\u8fd9\u6709\u4ec0\u4e48\u7a00\u5947\u7684\u3002\u90a3\u6211\u4eec\u6765\u4e3e\u4e2a\u5b9e\u9645\u5f00\u53d1\u4e2d\u4f1a\u9047\u5230\u7684\u4f8b\u5b50\u3002 \u8fd9\u91cc\u6709\u4e00\u4e2a\u6c42\u548c\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u548c\u3002 \u8fd8\u6709\u4e00\u4e2a\u6c42\u79ef\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u79ef\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u4ee3\u7801\u91cd\u590d\uff01 \u6211\u4eec\u89c2\u5bdf\u4e00\u4e0b sum \u548c product \u4e4b\u95f4\u6709\u54ea\u4e9b\u76f8\u4f3c\u7684\u90e8\u5206\uff0c\u628a\u4e24\u8005\u4ea7\u751f\u4e0d\u540c\u7684\u90e8\u5206\u7528 ??? \u4ee3\u66ff\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * } return res; } \u628a ??? \u90e8\u5206\u7528\u4e00\u4e2a\u865a\u51fd\u6570\u9876\u66ff\uff1a struct Reducer { virtual int init() = 0; virtual int add(int a, int b) = 0; }; int reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u8fd9\u6837\u4e0d\u8bba\u6211\u4eec\u60f3\u8981\u6c42\u548c\uff0c\u8fd8\u662f\u6c42\u79ef\uff0c\u53ea\u9700\u8981\u5b9e\u73b0\u5176\u4e2d\u4e0d\u540c\u7684\u90e8\u5206\u5c31\u53ef\u4ee5\u4e86\uff0c\u516c\u5171\u90e8\u5206\u5df2\u7ecf\u5728 reduce \u91cc\u5b9e\u73b0\u597d\uff0c\u5c31\u5b9e\u73b0\u4e86\u4ee3\u7801\u590d\u7528\u3002 struct SumReducer : Reducer { int init() override { return 0; } int add(int a, int b) override { return a + b; } }; struct ProductReducer : Reducer { int init() override { return 1; } int add(int a, int b) override { return a * b; } }; reduce(v, new SumReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 sum(v) reduce(v, new ProductReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 product(v) \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 \u5f88\u5bb9\u6613\u6dfb\u52a0\u65b0\u7684\u7b56\u7565\u8fdb\u6765\uff1a struct MinReducer : Reducer { int init() override { return numeric_limits::max(); } int add(int a, int b) override { return min(a, b); } }; struct MaxReducer : Reducer { int init() override { return numeric_limits::min(); } int add(int a, int b) override { return max(a, b); } }; \u591a\u91cd\u7b56\u7565 \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 sum \u548c product \u51fd\u6570\u4ece\u8f93\u5165\u6570\u636e\u76f4\u63a5\u8ba1\u7b97\uff08\u800c\u4e0d\u7528\u5148\u8bfb\u53d6\u5230\u4e00\u4e2a vector\uff09\uff01 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u62bd\u51fa\u516c\u5171\u90e8\u5206\uff0c\u73b0\u5728\u53ea\u9700\u8981\u4fee\u6539 reduce \u51fd\u6570\u672c\u8eab\u5c31\u53ef\u4ee5\u4e86\u3002 SumReducer \u548c ProductReducer \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u4f53\u73b0\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 int reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u53c8\u6539\u56de\u6765\uff0c\u4ed6\u7a81\u7136\u53c8\u60f3\u8981\u4ece vector \u91cc\u8bfb\u53d6\u6570\u636e\u4e86\u3002 \u5728\u7834\u53e3\u5927\u9a82\u8001\u677f\u51fa\u5c14\u53cd\u5c14\u7684\u540c\u65f6\uff0c\u4f60\u5f00\u59cb\u601d\u8003\uff0c\u8fd9\u4e24\u4e2a\u51fd\u6570\u4f3c\u4e4e\u8fd8\u662f\u6709\u4e00\u4e9b\u91cd\u590d\u53ef\u4ee5\u62bd\u53d6\u51fa\u6765\uff1f int cin_reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } int vector_reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u73b0\u5728\u6211\u4eec\u53ea\u6709\u8868\u793a\u5982\u4f55\u8ba1\u7b97\u7684\u7c7b Reducer \u505a\u53c2\u6570\u3002 \u4f60\u51b3\u5b9a\uff0c\u518d\u5b9a\u4e49\u4e00\u4e2a\u8868\u793a\u5982\u4f55\u8bfb\u53d6\u7684\u865a\u7c7b Inputer\u3002 struct Inputer { virtual optional fetch() = 0; }; int reduce(Inputer *inputer, Reducer *reducer) { int res = reducer->init(); while (auto tmp = inputer->fetch()) { res = reducer->add(res, tmp.value()); } return res; } \u8fd9\u6837\uff0c\u6211\u4eec\u6ee1\u8db3\u4e86 \u5355\u4e00\u804c\u8d23\u539f\u5219 \uff1a\u6bcf\u4e2a\u7c7b\u53ea\u8d1f\u8d23\u4e00\u4ef6\u4e8b\u3002 \u8fd9\u91cc\u7684 Inputer \u5b9e\u9645\u4e0a\u8fd0\u7528\u4e86 \u8fed\u4ee3\u5668\u6a21\u5f0f \uff1a\u63d0\u4f9b\u4e00\u4e2a\u62bd\u8c61\u63a5\u53e3\u6765 \u987a\u5e8f\u8bbf\u95ee \u4e00\u4e2a\u96c6\u5408\u4e2d\u5404\u4e2a\u5143\u7d20\uff0c\u800c\u53c8\u65e0\u987b\u66b4\u9732\u8be5\u96c6\u5408\u7684\u5185\u90e8\u8868\u793a\u3002 \u5e95\u5c42\u662f cin \u8fd8\u662f vector\uff1f\u6211\u4e0d\u5728\u4e4e\uff01\u6211\u53ea\u77e5\u9053\u4ed6\u53ef\u4ee5\u4f9d\u6b21\u987a\u5e8f\u53d6\u51fa\u6570\u636e\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; reduce(new CinInputer(), new SumReducer()); reduce(new VectorInputer(v), new SumReducer()); reduce(new CinInputer(), new ProductReducer()); reduce(new VectorInputer(v), new ProductReducer()); Inputer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8bfb\u53d6\u6570\u636e\uff0cReducer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8ba1\u7b97\u6570\u636e\u3002 \u8fd9\u5c31\u662f \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \uff1a\u9ad8\u5c42\u6a21\u5757\uff08reduce \u51fd\u6570\uff09\u4e0d\u8981\u76f4\u63a5\u4f9d\u8d56\u4e8e\u4f4e\u5c42\u6a21\u5757\uff0c\u4e8c\u8005\u90fd\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff08Inputer \u548c Reducer \u7c7b\uff09\u6765\u6c9f\u901a\u3002 \u4e0d\u8981\u4ec0\u4e48\u4e1c\u897f\u90fd\u585e\u4e00\u5757 \u6709\u4e9b\u7cdf\u7cd5\u7684\u5b9e\u73b0\u4f1a\u628a\u5206\u660e\u4e0d\u5c5e\u4e8e\u540c\u4e00\u5c42\u6b21\u7684\u4e1c\u897f\u5f3a\u884c\u653e\u5728\u4e00\u8d77\uff0c\u6bd4\u5982\u6ca1\u80fd\u5206\u6e05 Inputer \u548c Reducer \u7c7b\uff0c\u9519\u8bef\u5730\u628a\u4ed6\u4eec\u8bbe\u8ba1\u6210\u4e86\u4e00\u4e2a\u7c7b\uff01 int reduce(Reducer *reducer) { int res = reducer->init(); while (auto tmp = reducer->fetch()) { // fetch \u51ed\u4ec0\u4e48\u548c init\u3001add \u653e\u5728\u4e00\u8d77\uff1f res = reducer->add(res, tmp.value()); } return res; } fetch \u660e\u660e\u5c5e\u4e8e IO \u64cd\u4f5c\uff01\u4f46\u4ed6\u88ab\u9519\u8bef\u5730\u653e\u5728\u4e86\u672c\u5e94\u53ea\u8d1f\u8d23\u8ba1\u7b97\u7684 Reducer \u91cc\uff01 \u8fd9\u5bfc\u81f4\u4f60\u5fc5\u987b\u5b9e\u73b0\u56db\u4e2a\u7c7b\uff0c\u7f57\u5217\u6240\u6709\u7684\u6392\u5217\u7ec4\u5408\uff1a struct CinSumReducer : Reducer { ... }; struct VectorSumReducer : Reducer { ... }; struct CinProductReducer : Reducer { ... }; struct VectorProductReducer : Reducer { ... }; \u8fd9\u663e\u7136\u662f\u4e0d\u7b26\u5408 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u7684\u3002 \u6ee1\u8db3 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3001 \u5f00\u95ed\u539f\u5219 \u3001 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u7684\u4ee3\u7801\u66f4\u52a0\u7075\u6d3b\u3001\u6613\u4e8e\u6269\u5c55\u3001\u6613\u4e8e\u7ef4\u62a4\u3002\u8bf7\u52a1\u5fc5\u8bb0\u4f4f\u5e76\u843d\u5b9e\u8d77\u6765\uff01 \u5426\u5219\u5373\u4f60\u88c5\u6a21\u4f5c\u6837\u5730\u7528\u4e86\u865a\u51fd\u6570\uff0c\u4e5f\u4e00\u6837\u4f1a\u5bfc\u81f4\u4ee3\u7801\u91cd\u590d\u3001\u96be\u4ee5\u7ef4\u62a4\uff01 \u8001\u677f\u514b\u6263\u5de5\u8d44\u65f6\u5c31\u4e0d\u7528\u9075\u5b88\u8fd9\u4e9b\u539f\u5219 \u9002\u914d\u5668\u6a21\u5f0f \u521a\u624d\u7684\u4f8b\u5b50\u4e2d\u6211\u4eec\u7528\u5230\u4e86 Inputer \u865a\u63a5\u53e3\u7c7b\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; \u5982\u679c\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\uff1a\u8bfb\u53d6\u5230 0 \u622a\u6b62\uff0c\u800c\u4e0d\u662f -1 \u5462\uff1f\u96be\u9053\u8fd8\u5f97\u7ed9 CinInputer \u52a0\u4e2a\u53c2\u6570\uff1f \u4f46\u662f vector \u6709\u65f6\u5019\u4e5f\u53ef\u80fd\u6709\u8bfb\u5230 -1 \u5c31\u63d0\u524d\u622a\u65ad\u7684\u9700\u6c42\u5440\uff1f \u8fd9\u660e\u663e\u8fdd\u80cc\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 \u66f4\u597d\u7684\u8bbe\u8ba1\u662f\uff0c\u8ba9 CinInputer \u65e0\u9650\u8bfb\u53d6\uff0c\u6c38\u8fdc\u6210\u529f\u3002 \u7136\u540e\u53e6\u5916\u5f04\u4e00\u4e2a StopInputerAdapter\uff0c\u5176\u63a5\u53d7\u4e00\u4e2a CinInputer \u4f5c\u4e3a\u6784\u9020\u53c2\u6570\u3002 \u5f53 StopInputerAdapter \u88ab\u8bfb\u53d6\u65f6\uff0c\u4ed6\u4f1a\u68c0\u67e5\u662f\u5426\u4e3a -1\uff0c\u5982\u679c\u5df2\u7ecf\u5f97\u5230 -1\uff0c\u90a3\u4e48\u5c31\u8fd4\u56de nullopt\uff0c\u4e0d\u4f1a\u8fdb\u4e00\u6b65\u8c03\u7528 CinInputer \u4e86\u3002 StopInputerAdapter \u8d1f\u8d23\u5904\u7406\u622a\u65ad\u95ee\u9898\uff0cCinInputer \u53ea\u662f\u8d1f\u8d23\u8bfb\u53d6 cin \u8f93\u5165\u3002\u6ee1\u8db3\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 struct StopInputerAdapter : Inputer { Inputer *inputer; int stopMark; StopInputerAdapter(Inputer *inputer, int stopMark) : inputer(inputer) , stopMark(stopMark) {} optional fetch() override { auto tmp = inputer->fetch(); if (tmp == stopMark) return nullopt; return tmp; } }; \u8fd9\u91cc\u7684 StopInputerAdapter \u5c31\u662f\u4e00\u4e2a\u9002\u914d\u5668\uff0c\u4ed6\u628a CinInputer \u7684\u63a5\u53e3\uff08\u65e0\u9650\u8bfb\u53d6\uff09\u53e0\u52a0\u4e0a\u4e86\u4e00\u4e2a\u989d\u5916\u529f\u80fd\uff0c\u8bfb\u5230\u6307\u5b9a\u7684 stopMark \u503c\u5c31\u505c\u6b62\uff0c\u4ea7\u751f\u4e86\u4e00\u4e2a\u65b0\u7684 Inputer\u3002 reduce(new StopInputerAdapter(new CinInputer(), -1), new SumReducer()); // \u4ece cin \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new StopInputerAdapter(new VectorInputer(v), -1), new SumReducer()); // \u4ece vector \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new VectorInputer(), new SumReducer()); // \u4ece vector \u8bfb\uff0c\u4f46\u65e0\u9700\u622a\u65ad \u8fd9\u5c31\u662f \u9002\u914d\u5668\u6a21\u5f0f \uff1a\u5c06\u4e00\u4e2a\u7c7b\u7684\u63a5\u53e3\u6dfb\u6cb9\u52a0\u918b\uff0c\u8f6c\u6362\u6210\u5ba2\u6237\u5e0c\u671b\u7684\u53e6\u4e00\u4e2a\u63a5\u53e3\u3002 StopInputerAdapter \u8fd9\u4e2a\u9002\u914d\u5668\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a Inputer\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f5c\u4e3a reduce \u7684\u53c2\u6570\uff0c\u9002\u5e94\u4e86\u73b0\u6709\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 StopInputerAdapter \u5e76\u4e0d\u4f9d\u8d56\u4e8e\u53c2\u6570 Inputer \u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u53ef\u4ee5\u662f CinInputer\u3001\u4e5f\u53ef\u4ee5\u662f VectorInputer\uff0c\u6ee1\u8db3\u4e86 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u3002 \u672a\u6765\u5373\u4f7f\u65b0\u589e\u4e86\u4e0d\u540c\u7c7b\u578b\u7684 Inputer\uff0c\u751a\u81f3\u662f\u5176\u4ed6 InputerAdapter\uff0c\u4e00\u6837\u53ef\u4ee5\u914d\u5408 StopInputerAdapter \u4e00\u8d77\u4f7f\u7528\u800c\u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u6ee1\u8db3\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u5982\u679c\u6211\u4eec\u8fd8\u60f3\u5b9e\u73b0\uff0c\u8fc7\u6ee4\u51fa\u6240\u6709\u6b63\u6570\u548c\u96f6\uff0c\u8d1f\u6570\u76f4\u63a5\u4e22\u5f03\u5462\uff1f struct FilterInputerAdapter { Inputer *inputer; FilterInputerAdapter(Inputer *inputer) : inputer(inputer) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (tmp >= 0) { return tmp; } } } }; \u6539\u8fdb\uff1aFilter \u7684\u6761\u4ef6\u4e0d\u5e94\u4e3a\u5199\u6b7b\u7684 tmp >= 0 \uff0c\u800c\u5e94\u8be5\u662f\u4f20\u5165\u4e00\u4e2a FilterStrategy\uff0c\u5141\u8bb8\u7528\u6237\u6269\u5c55\u3002 struct FilterStrategy { virtual bool shouldPass(int value) = 0; // \u8fd4\u56de true \u8868\u793a\u8be5\u503c\u5e94\u8be5\u88ab\u4fdd\u7559 }; struct FilterStrategyAbove : FilterStrategy { // \u5927\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyAbove(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value > threshold; } }; struct FilterStrategyBelow : FilterStrategy { // \u5c0f\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyBelow(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value < threshold; } }; struct FilterInputerAdapter : Inputer { Inputer *inputer; FilterStrategy *strategy; FilterInputerAdapter(Inputer *inputer, FilterStrategy *strategy) : inputer(inputer), strategy(strategy) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (strategy->shouldPass(tmp)) { return tmp; } } } }; FilterStrategy \u53c8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u8fd0\u7528\u9002\u914d\u5668\u6a21\u5f0f\uff1a\u4f8b\u5982\u6211\u4eec\u53ef\u4ee5\u628a FilterStrategyAbove(0) \u548c FilterStrategyBelow(100) \u7ec4\u5408\u8d77\u6765\uff0c\u5b9e\u73b0\u8fc7\u6ee4\u51fa 0\uff5e100 \u8303\u56f4\u5185\u7684\u6574\u6570\u3002 struct FilterStrategyAnd : FilterStrategy { // \u8981\u6c42 a \u548c b \u4e24\u4e2a\u8fc7\u6ee4\u7b56\u7565\u90fd\u4e3a true\uff0c\u624d\u80fd\u901a\u8fc7 FilterStrategy *a; FilterStrategy *b; FilterStrategyAnd(FilterStrategy *a, FilterStrategy *b) : a(a), b(b) {} bool shouldPass(int value) override { return a->shouldPass(value) && b->shouldPass(value); } }; reduce( new FilterInputerAdapter( new StopInputerAdapter( new CinInputer(), -1 ), new FilterStrategyAnd( new FilterStrategyAbove(0), new FilterStrategyBelow(100) ) ), new SumReducer()); \u662f\u4e0d\u662f\u903b\u8f91\u975e\u5e38\u6e05\u6670\uff0c\u800c\u4e14\u5bb9\u6613\u6269\u5c55\u5462\uff1f \u5b9e\u9645\u4e0a\u51fd\u6570\u5f0f\u548c\u6a21\u677f\u5143\u7f16\u7a0b\u66f4\u64c5\u957f\u505a\u8fd9\u79cd\u5de5\u4f5c\uff0c\u4f46\u4eca\u5929\u5148\u4ecb\u7ecd\u5b8c\u539f\u6c41\u539f\u5473\u7684 Java \u98ce\u683c\u9762\u5411\u5bf9\u8c61\uff0c\u4ed6\u4eec\u590d\u7528\u4ee3\u7801\u7684\u601d\u8def\u662f\u5171\u901a\u7684\u3002 \u4f60\u5148\u5b66\u4f1a\u8d70\u8def\uff0c\u660e\u5929\u6211\u4eec\u518d\u6765\u5b66\u4e60\u8dd1\u6b65\uff0c\u597d\u5427\uff1f \u8de8\u63a5\u53e3\u7684\u9002\u914d\u5668 \u9002\u914d\u5668\u6a21\u5f0f\u8fd8\u53ef\u4ee5\u4f7f\u539f\u672c\u7531\u4e8e\u63a5\u53e3\u4e0d\u517c\u5bb9\u800c\u4e0d\u80fd\u4e00\u8d77\u5de5\u4f5c\u7684\u90a3\u4e9b\u7c7b\u53ef\u4ee5\u4e00\u8d77\u5de5\u4f5c\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u4e86\u7c7b\u4f3c\u4e8e\u6211\u4eec Inputer \u7684\u8f93\u5165\u6d41\u63a5\u53e3\uff0c\u4e5f\u662f\u57fa\u4e8e\u865a\u51fd\u6570\u7684\u3002\u4f46\u662f\u4ed6\u7684\u63a5\u53e3\u663e\u7136\u4e0d\u80fd\u76f4\u63a5\u4f20\u5165\u6211\u4eec\u7684 reduce \u51fd\u6570\uff0c\u6211\u4eec\u7684 reduce \u51fd\u6570\u53ea\u63a5\u53d7\u6211\u4eec\u81ea\u5df1\u7684 Inputer \u63a5\u53e3\u3002\u8fd9\u65f6\u5c31\u53ef\u4ee5\u7528\u9002\u914d\u5668\uff0c\u628a\u63a5\u53e3\u7ffb\u8bd1\u6210\u6211\u4eec\u7684 reducer \u80fd\u591f\u7406\u89e3\u7684\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e2a\u81ea\u79f0 \u201cPoost\u201d \u7684\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u63a5\u53e3\uff1a struct PoostInputer { virtual bool hasNext() = 0; virtual int getNext() = 0; }; \u4ed6\u4eec\u8981\u6c42\u7684\u7528\u6cd5\u662f\u5148\u5224\u65ad hasNext()\uff0c\u7136\u540e\u624d\u80fd\u8c03\u7528 getNext \u8bfb\u53d6\u51fa\u771f\u6b63\u7684\u503c\u3002\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u4e86\u4e00\u4e2a Poost \u9002\u914d\u5668\uff0c\u628a PoostInputer \u7ffb\u8bd1\u6210\u6211\u4eec\u7684 Inputer\uff1a struct PoostInputerAdapter : Inputer { PoostInputer *poostIn; PoostInputerAdapter(PoostInputer *poostIn) : poostIn(poostIn) {} optional fetch() override { if (poostIn->hasNext()) { return poostIn->getNext(); } else { return nullopt; } } }; \u5f53\u6211\u4eec\u5f97\u5230\u4e00\u4e2a PoostInputer \u65f6\uff0c\u5982\u679c\u60f3\u8981\u8c03\u7528\u6211\u4eec\u81ea\u5df1\u7684 reducer\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u4e2a PoostInputerAdapter \u5957\u4e00\u5c42\uff1a auto poostStdIn = poost::getStandardInput(); reduce(new PoostInputerAdapter(poostStdIn), new SumReducer()); \u8fd9\u6837\u5c31\u53ef\u4ee5\u65e0\u7f1d\u5730\u628a PoostInputer \u4f5c\u4e3a reduce \u7684\u53c2\u6570\u4e86\u3002 \u5de5\u5382\u6a21\u5f0f \u73b0\u5728\u4f60\u662f\u4e00\u4e2a\u6e38\u620f\u5f00\u53d1\u8005\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u88c5\u5907\u6b66\u5668\uff0c\u4e0d\u540c\u7684\u6b66\u5668\u53ef\u4ee5\u53d1\u51fa\u4e0d\u540c\u7684\u5b50\u5f39\uff01 \u4f60\u4f7f\u7528\u5c0f\u5f6d\u8001\u5e08\u6559\u7684 \u7b56\u7565\u6a21\u5f0f \uff0c\u628a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u4f5c\u4e3a\u4e0d\u540c\u7684\u7b56\u7565\u4f20\u5165 player \u51fd\u6570\uff0c\u9020\u6210\u4e0d\u540c\u7c7b\u578b\u7684\u4f24\u5bb3\u3002 struct Bullet { virtual void explode() = 0; }; struct AK47Bullet : Bullet { void explode() override { puts(\"\u7269\u7406\u4f24\u5bb3\"); } }; struct MagicBullet : Bullet { void explode() override { puts(\"\u9b54\u6cd5\u4f24\u5bb3\"); } }; void player(Bullet *bullet) { bullet->explode(); } player(new AK47Bullet()); player(new MagicBullet()); \u4f46\u662f\u8fd9\u6837\u5c31\u76f8\u5f53\u4e8e\u6bcf\u4e2a\u73a9\u5bb6\u53ea\u6709\u4e00\u53d1\u5b50\u5f39\uff0c\u542c\u4e2a\u54cd\u5c31\u6ca1\u4e86\u2026 \u5982\u4f55\u5141\u8bb8\u73a9\u5bb6\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u9020\u65b0\u5b50\u5f39\u51fa\u6765\uff1f\u6211\u4eec\u53ef\u4ee5\u628a\u201c\u521b\u5efa\u5b50\u5f39\u201d\u8fd9\u4e00\u8fc7\u7a0b\u62bd\u8c61\u51fa\u6765\uff0c\u653e\u5728\u4e00\u4e2a\u201c\u67aa\u201d\u7c7b\u91cc\u3002 struct Gun { virtual Bullet *shoot() = 0; }; struct AK47Gun : Gun { Bullet *shoot() override { return new AK47Bullet(); } }; struct MagicGun : Gun { Bullet *shoot() override { return new MagicBullet(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new AK47Gun()); player(new MagicGun()); \u73b0\u5728\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u76f4\u63a5\u9009\u62e9\u4e0d\u540c\u7684\u67aa\u4e86\uff01 \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u5de5\u5382\u6a21\u5f0f \uff1a\u201c\u67aa\u201d\u5c31\u662f\u201c\u5b50\u5f39\u201d\u5bf9\u8c61\u7684\u5de5\u5382\u3002 \u4f20\u7ed9\u73a9\u5bb6\u7684\u662f\u5b50\u5f39\u7684\u5de5\u5382\u2014\u2014\u67aa\uff0c\u800c\u4e0d\u662f\u5b50\u5f39\u672c\u8eab\u3002 \u53ea\u8981\u8c03\u7528\u5de5\u5382\u7684 shoot \u51fd\u6570\uff0c\u73a9\u5bb6\u53ef\u4ee5\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u5efa\u65b0\u5b50\u5f39\u51fa\u6765\u3002 \u6b63\u6240\u8c13\u6388\u4eba\u4ee5\u9c7c\u4e0d\u5982\u6388\u4eba\u4ee5\u6e14\uff0c\u4f60\u7684\u73a9\u5bb6\u4e0d\u518d\u662f\u88ab\u52a8\u63a5\u53d7\u5b50\u5f39\uff0c\u800c\u662f\u53ef\u4ee5\u81ea\u5df1\u521b\u9020\u5b50\u5f39\u4e86\uff01 \u5de5\u5382\u8fd8\u53ef\u4ee5\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u6570\uff0c\u4f8b\u5982\u6211\u4eec\u9700\u8981\u6a21\u62df AK47 \u53ef\u80fd\u201c\u53d7\u6f6e\u201d\uff0c\u5bfc\u81f4\u4ea7\u751f\u7684\u5b50\u5f39\u5a01\u529b\u964d\u4f4e\u3002 \u5c31\u53ef\u4ee5\u7ed9\u67aa\u52a0\u4e00\u4e2a isWet \u53c2\u6570\uff0c\u7ed9\u5b50\u5f39\u52a0\u4e00\u4e2a damage \u53c2\u6570\uff0c\u8ba9 AK47 \u751f\u6210\u5b50\u5f39\u7684\u65f6\u5019\uff0c\u6839\u636e isWet \u4e3a\u5b50\u5f39\u6784\u9020\u51fd\u6570\u8bbe\u7f6e\u4e0d\u540c\u7684 damage\u3002 struct AK47Bullet { int damage; AK47Bullet(int damage) : damage(damage) {} void explode() { printf(\"\u9020\u6210 %d \u70b9\u7269\u7406\u4f24\u5bb3\\n\", damage); } }; struct AK47Gun : Gun { bool isWet; AK47Gun(bool isWet) : isWet(isWet) {} Bullet *shoot() override { if (isWet) return new AK47Bullet(5); // \u53d7\u6f6e\u4e86\uff0c\u4f24\u5bb3\u964d\u4f4e\u4e3a 5 else return new AK47Bullet(10); // \u6b63\u5e38\u60c5\u51b5\u4e0b\u4f24\u5bb3\u4e3a 10 } }; \u6211\u4eec\u8fd8\u53ef\u4ee5\u5229\u7528\u6a21\u677f\u81ea\u52a8\u4e3a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u6279\u91cf\u5b9a\u4e49\u5de5\u5382\uff1a template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new GunWithBullet()); player(new GunWithBullet()); \u8fd9\u6837\u5c31\u4e0d\u5fc5\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5b50\u5f39\u7c7b\u578b\u65f6\uff0c\u90fd\u5f97\u65b0\u5efa\u4e00\u4e2a\u76f8\u5e94\u7684\u67aa\u7c7b\u578b\u4e86\uff0c\u8fdb\u4e00\u6b65\u907f\u514d\u4e86\u4ee3\u7801\u91cd\u590d\u3002\u53ef\u89c1\u6a21\u677f\u5143\u7f16\u7a0b\u5b8c\u5168\u53ef\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u5f3a\u5f3a\u8054\u624b\u3002 \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f Gun *getGun(string name) { if (name == \"AK47\") { return new GunWithBullet(); } else if (name == \"Magic\") { return new GunWithBullet(); } else { throw runtime_error(\"\u6ca1\u6709\u8fd9\u79cd\u67aa\"); } } player(getGun(\"AK47\")); player(getGun(\"Magic\")); RAII \u81ea\u52a8\u7ba1\u7406\u5185\u5b58 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); delete bullet; // \u521a\u624d\u6ca1\u6709 delete\uff01\u4f1a\u4ea7\u751f\u5185\u5b58\u6cc4\u6f0f\uff01 } } player(new GunWithBullet()); player(new GunWithBullet()); \u73b0\u5728\u7684\u5de5\u5382\u4e00\u822c\u90fd\u4f1a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u5177\u4f53\u6765\u8bf4\u5c31\u662f\u7528 unique_ptr \u4ee3\u66ff T * \uff0c\u7528 make_unique(xxx) \u4ee3\u66ff new T(xxx) \u3002 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); unique_ptr shoot() override { return make_unique(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { auto bullet = gun->shoot(); bullet->explode(); // unique_ptr \u5728\u9000\u51fa\u5f53\u524d {} \u65f6\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u4e0d\u7528\u4f60\u60e6\u8bb0\u7740\u4e86 } } player(make_unique>().get()); player(make_unique>().get()); \u8fd9\u91cc C++ \u6807\u51c6\u4fdd\u8bc1\u4e86 unique_ptr \u7684\u751f\u547d\u5468\u671f\u662f\u8fd9\u4e00\u6574\u884c\uff08; \u7ed3\u675f\u524d\uff09\uff0c\u6574\u4e2a player \u6267\u884c\u671f\u95f4\u90fd\u6d3b\u7740\uff0c\u4e0d\u4f1a\u63d0\u524d\u91ca\u653e \u6b63\u5982 func(string().c_str()) \u4e0d\u4f1a\u6709\u4efb\u4f55\u95ee\u9898\uff0cstring \u8981\u5230 func \u8fd4\u56de\u540e\u624d\u91ca\u653e\u5462\uff01 \u53ea\u8981\u628a\u6240\u6709 make_unique \u770b\u4f5c new T \uff0c\u628a\u6240\u6709\u7684 unique_ptr \u770b\u4f5c T * \uff0c\u7528\u6cd5\u51e0\u4e4e\u4e00\u6837\uff0c\u4f46\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\uff0c\u65e0\u9700\u624b\u52a8 delete\u3002 \u5de5\u5382\u6a21\u5f0f\u5b9e\u6218 \u56de\u5230\u6570\u7ec4\u6c42\u548c\u95ee\u9898\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } int average(vector v) { int res = 0; int count = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; count = count + 1; } return res / count; } \u6211\u4eec\u60f3\u8981\u52a0\u4e00\u4e2a\u6c42\u5e73\u5747\u503c\u7684\u51fd\u6570 average\uff0c\u8fd9\u8be5\u5982\u4f55\u4e0e sum \u5408\u8d77\u6765\uff1f \u6ce8\u610f\u56e0\u4e3a\u6211\u4eec\u8981\u652f\u6301\u4ece CinInputer \u8bfb\u5165\u6570\u636e\uff0c\u5e76\u4e0d\u4e00\u5b9a\u50cf\u4e00\u6837 VectorInputer \u80fd\u591f\u63d0\u524d\u5f97\u5230\u6570\u7ec4\u5927\u5c0f\uff0c\u4e0d\u7136\u4e5f\u4e0d\u9700\u8981 count \u4e86\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 int count? = ???; // sum \u548c product \u7528\u4e0d\u5230\u8be5\u53d8\u91cf\uff0c\u53ea\u6709 average \u9700\u8981 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * count? = count? ???; // average \u65f6\u8fd9\u91cc\u8fd8\u9700\u8981\u989d\u5916\u4fee\u6539 count \u53d8\u91cf\uff01 } return res; } \u770b\u6765\u6211\u4eec\u9700\u8981\u5141\u8bb8 Reducer \u7684 init() \u8fd4\u56de \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d\uff01 \u4ee5\u524d\u7684\u8bbe\u8ba1\u8ba9 init() \u53ea\u80fd\u8fd4\u56de\u5355\u4e2a int \u662f\u4e2a\u9519\u8bef\u7684\u51b3\u5b9a\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u628a \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d \u5c01\u88c5\u6210\u4e00\u4e2a\u65b0\u7684\u7c7b\u3002 \u7136\u540e\u6539\u4e3a\u7531\u8fd9\u4e2a\u7c7b\u8d1f\u8d23\u63d0\u4f9b\u865a\u51fd\u6570 add()\u3002 \u4e14\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u53f3\u4fa7\u53c2\u6570\u4e86\uff0c\u5de6\u4fa7\u7684 res \u53d8\u91cf\u5df2\u7ecf\u5b58\u5728 ReducerState \u4f53\u5185\u4e86\u3002 struct ReducerState { virtual void add(int val) = 0; virtual int result() = 0; }; struct Reducer { virtual unique_ptr init() = 0; }; struct SumReducerState : ReducerState { int res; SumReducerState() : res(0) {} void add(int val) override { res = res + val; } int result() override { return res; } }; struct ProductReducerState : ReducerState { int res; ProductReducerState() : res(1) {} void add(int val) override { res = res * val; } int result() override { return res; } }; struct AverageReducerState : ReducerState { int res; int count; AverageReducerState() : res(0), count(0) {} void add(int val) override { res = res + val; count = count + 1; } int result() override { return res / count; } }; struct SumReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct ProductReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct AverageReducer : Reducer { unique_ptr init() override { return make_unique(); } }; \u8fd9\u91cc Reducer \u5c31\u6210\u4e86 ReducerState \u7684\u5de5\u5382\u3002 int reduce(Inputer *inputer, Reducer *reducer) { unique_ptr state = reducer->init(); while (auto val = inputer->fetch()) { state->add(val); } return state->result(); } int main() { vector v; reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 \u5e76\u884c \u7684 sum \u548c product \u51fd\u6570\uff01 \u5e76\u884c\u7248\u9700\u8981\u521b\u5efa\u5f88\u591a\u4e2a\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u9700\u8981\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u4e2d\u95f4\u7ed3\u679c\u53d8\u91cf\uff0c\u6700\u540e\u7684\u7ed3\u679c\u8ba1\u7b97\u53c8\u9700\u8981\u4e00\u4e2a\u4e2d\u95f4\u53d8\u91cf\u3002 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u91c7\u7528\u5de5\u5382\u6a21\u5f0f\uff0c\u5141\u8bb8\u51fd\u6570\u4f53\u5185\u591a\u6b21\u521b\u5efa ReducerState \u5bf9\u8c61\u3002 int reduce(Inputer *inputer, Reducer *reducer) { tbb::task_group g; list> local_states; vector chunk; auto enqueue_chunk = [&]() { local_chunks.emplace_back(); g.run([chunk = move(chunk), &back = local_chunks.back()]() { auto local_state = reducer->init(); for (auto &&c: chunk) { local_state->add(c); } back = move(local_state); // list \u4fdd\u8bc1\u5df2\u7ecf\u63d2\u5165\u5143\u7d20\u7684\u5f15\u7528\u4e0d\u4f1a\u5931\u6548\uff0c\u6240\u4ee5\u53ef\u4ee5\u6682\u5b58 back \u5f15\u7528 }); chunk.clear(); }; while (auto tmp = inputer->fetch()) { if (chunk.size() < 64) { // \u8fd8\u6ca1\u586b\u6ee1 64 \u4e2a chunk.push_back(tmp); } else { // \u586b\u6ee1\u4e86 64 \u4e2a\uff0c\u53ef\u4ee5\u63d0\u4ea4\u6210\u4e00\u4e2a\u5355\u72ec\u4efb\u52a1\u4e86 enqueue_chunk(); } } if (chunk.size() > 0) { enqueue_chunk(); // \u63d0\u4ea4\u4e0d\u8db3 64 \u4e2a\u7684\u6b8b\u4f59\u9879 } g.wait(); auto final_state = reducer->init(); for (auto &&local_state: local_states) { res = final_state->add(local_state->result()); } return final_state->result(); } \u53ea\u9700\u8981\u628a reducer \u53c2\u6570\u66ff\u6362\u4e3a MinReducer\u3001AverageReducer\u2026\u2026\u5c31\u81ea\u52a8\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u4efb\u52a1\uff0c\u800c\u4e0d\u7528\u4e3a\u4ed6\u4eec\u6bcf\u4e2a\u5355\u72ec\u7f16\u5199\u5e76\u884c\u7248\u672c\u7684\u4ee3\u7801\u3002 \u8bfe\u540e\u4f5c\u4e1a\uff1a\u4f7f\u7528\u6a21\u677f\u6279\u91cf\u5b9a\u4e49\u6240\u6709\u7684 Reducer\uff01\u4f8b\u5982\uff1a using MinReducer = ReducerWithState; ... \u4eab\u5143\u6a21\u5f0f \u5728\u4e8c\u7ef4\u6e38\u620f\u5f00\u53d1\u4e2d\uff0c\u5e38\u5e38\u4f1a\u63d0\u5230\u4e00\u79cd\u79f0\u4e3a Sprite\uff08\u7cbe\u7075\u8d34\u56fe\uff09\u7684\u9ed1\u8bdd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6bcf\u4e2a\u5bf9\u8c61\u81ea\u5df1\u6709\u4e00\u5f20\u8d34\u56fe\uff0c\u8d34\u56fe\u8ddf\u7740\u7269\u4f53\u7684\u4f4d\u7f6e\u8d70\u3002 struct Bullet { glm::vec3 position; glm::vec3 velocity; vector texture; void draw() { glDrawPixels(position, texture); } }; texture \u91cc\u9762\u5b58\u50a8\u7740\u8d34\u56fe\u7684 RGB \u6570\u636e\uff0c\u4ed6\u76f4\u63a5\u5c31\u662f Bullet \u7684\u6210\u5458\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u6253\u51fa\u4e86 100 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 100 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u540c\u65f6\u6253\u51fa\u4e86 1000 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 1000 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5185\u5b58\u6d88\u8017\u5c06\u4f1a\u975e\u5e38\u5927\u3002\u7136\u800c\u6240\u6709\u540c\u7c7b\u578b\u7684 Bullet\uff0c\u5176\u8d34\u56fe\u6570\u7ec4\u5176\u5b9e\u662f\u5b8c\u5168\u76f8\u540c\u7684\uff0c\u5b8c\u5168\u6ca1\u5fc5\u8981\u5404\u81ea\u5b58\u90a3\u4e48\u591a\u4efd\u62f7\u8d1d\u3002 \u4e3a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 \u4eab\u5143\u6a21\u5f0f \uff1a\u5171\u4eab\u591a\u4e2a\u5bf9\u8c61\u4e4b\u95f4 \u76f8\u540c \u7684\u90e8\u5206\uff0c\u8282\u7701\u5185\u5b58\u5f00\u9500\u3002 \u8fd9\u91cc\u6bcf\u9897\u5b50\u5f39\u7684 position\u3001velocity \u663e\u7136\u90fd\u662f\u5404\u6709\u4e0d\u540c\u7684\uff0c\u4e0d\u53ef\u80fd\u6240\u6709\u5b50\u5f39\u90fd\u5728\u540c\u4e00\u4e2a\u4f4d\u7f6e\u4e0a\u3002 \u4f46\u662f\u5f88\u591a\u5b50\u5f39\u90fd\u4f1a\u6709\u7740\u76f8\u540c\u7684\u8d34\u56fe\uff0c\u53ea\u6709\u4e0d\u540c\u7c7b\u578b\u7684\u5b50\u5f39\u8d34\u56fe\u4f1a\u4e0d\u4e00\u6837\u3002 \u6bd4\u5982\u706b\u7130\u5f39\u548c\u5bd2\u51b0\u5f39\u4f1a\u6709\u4e0d\u540c\u7684\u8d34\u56fe\uff0c\u4f46\u662f\u5f53\u573a\u4e0a\u51fa\u73b0 100 \u9897\u706b\u7130\u5f39\u65f6\uff0c\u663e\u7136\u4e0d\u9700\u8981\u62f7\u8d1d 100 \u4efd\u5b8c\u5168\u76f8\u540c\u7684\u706b\u7130\u5f39\u8d34\u56fe\u3002 struct Sprite { // Sprite \u624d\u662f\u771f\u6b63\u6301\u6709\uff08\u5f88\u5927\u7684\uff09\u8d34\u56fe\u6570\u636e\u7684 vector texture; void draw(glm::vec3 position) { glDrawPixels(position, texture); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // \u5141\u8bb8\u591a\u4e2a\u5b50\u5f39\u5bf9\u8c61\u5171\u4eab\u540c\u4e00\u4e2a\u7cbe\u7075\u8d34\u56fe\u7684\u6240\u6709\u6743 void draw() { sprite->draw(position); // \u8f6c\u53d1\u7ed9 Sprite \u8ba9\u4ed6\u5e2e\u5fd9\u5728\u6211\u7684\u4f4d\u7f6e\u7ed8\u5236\u8d34\u56fe } }; \u9700\u8981\u7ed8\u5236\u5b50\u5f39\u65f6\uff0cBullet \u7684 draw \u53ea\u662f\u7b80\u5355\u5730\u8f6c\u53d1\u7ed9 Sprite \u7c7b\u7684 draw\u3002 \u53ea\u8981\u544a\u8bc9 Sprite \u5b50\u5f39\u7684\u4f4d\u7f6e\u5c31\u884c\uff0c\u8d34\u56fe\u6570\u636e\u5df2\u7ecf\u5b58\u5728 Sprite \u5185\u90e8\uff0c\u8ba9\u4ed6\u6765\u8d1f\u8d23\u771f\u6b63\u7ed8\u5236\u3002 Bullet \u7c7b\u53ea\u9700\u8981\u4e13\u6ce8\u4e8e\u4f4d\u7f6e\u3001\u901f\u5ea6\u7684\u66f4\u65b0\u5373\u53ef\uff0c\u4e0d\u5fc5\u53bb\u64cd\u5fc3\u7740\u8d34\u56fe\u7ed8\u5236\u7684\u7ec6\u8282\uff0c\u5b9e\u73b0\u4e86\u89e3\u8026\u3002 \u8fd9\u79cd\u51fd\u6570\u8c03\u7528\u7684\u8f6c\u53d1\u4e5f\u88ab\u79f0\u4e3a \u4ee3\u7406\u6a21\u5f0f \u3002 \u4ee3\u7406\u6a21\u5f0f \u8fd9\u6837\u8fd8\u6709\u4e00\u4e2a\u597d\u5904\u90a3\u5c31\u662f\uff0cSprite \u53ef\u4ee5\u8bbe\u8ba1\u6210\u4e00\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\u7c7b\uff1a struct Sprite { virtual void draw(glm::vec3 position) = 0; }; struct FireSprite : Sprite { vector fireTexture; FireSprite() : fireTexture(loadTexture(\"fire.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, fireTexture); } }; struct IceSprite : Sprite { // \u5047\u5982\u5bd2\u51b0\u5f39\u9700\u8981\u4e24\u5f20\u8d34\u56fe\uff0c\u4e5f\u6ca1\u95ee\u9898\uff01\u56e0\u4e3a\u865a\u63a5\u53e3\u7c7b\u5141\u8bb8\u5b50\u7c7b\u6709\u4e0d\u540c\u7684\u6210\u5458\uff0c\u4e0d\u540c\u7684\u7ed3\u6784\u4f53\u5927\u5c0f vector iceTexture1; vector iceTexture2; IceSprite() : iceTexture1(loadTexture(\"ice1.jpg\")) , iceTexture2(loadTexture(\"ice2.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, iceTexture1); glDrawPixels(position, iceTexture2); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // Sprite \u8d1f\u8d23\u542b\u6709\u865a\u51fd\u6570 void draw() { // Bullet \u7684 draw \u5c31\u4e0d\u7528\u662f\u865a\u51fd\u6570\u4e86\uff01 sprite->draw(position); } }; \u7ec4\u4ef6\u6a21\u5f0f \u865a\u51fd\u6570\u5e38\u89c1\u95ee\u9898\u8fa8\u6790 \u8fd4\u56de bool \u7684\u865a\u51fd\u6570 \u8bfe\u540e\u4f5c\u4e1a \u4f60\u62ff\u5230\u4e86\u4e00\u4e2a\u5927\u5b66\u751f\u8ba1\u7b97\u5668\u7684\u5927\u4f5c\u4e1a\uff1a int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; if (c == '+') { cout << a + b; } else if (c == '-') { cout << a - b; } else if (c == '*') { cout << a * b; } else if (c == '/') { cout << a / b; } else { cout << \"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"; } } \u4f60\u5f00\u59cb\u7528\u7b56\u7565\u6a21\u5f0f\u6539\u9020\u5b83\uff1a struct Calculator { virtual int calculate(int a, int b) = 0; }; struct AddCalculator : Calculator { int calculate(int a, int b) override { return a + b; } }; struct SubCalculator : Calculator { int calculate(int a, int b) override { return a - b; } }; struct MulCalculator : Calculator { int calculate(int a, int b) override { return a * b; } }; struct DivCalculator : Calculator { int calculate(int a, int b) override { return a / b; } }; Calculator *getCalculator(char c) { if (c == '+') { calculator = new AddCalculator(); } else if (c == '-') { calculator = new SubCalculator(); } else if (c == '*') { calculator = new MulCalculator(); } else if (c == '/') { calculator = new DivCalculator(); } else { throw runtime_error(\"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"); } }; int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; Calculator *calculator = getCalculator(c); cout << calculator->calculate(a, b); }","title":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01"},{"location":"design_virtual/#_1","text":"\u8bb8\u591a\u8bbe\u8ba1\u6a21\u5f0f\u90fd\u4e0e\u865a\u51fd\u6570\u606f\u606f\u76f8\u5173\uff0c\u4eca\u5929\u6211\u4eec\u6765\u5b66\u4e60\u4e00\u4e9b\u5e38\u7528\u7684\u3002 \u7b56\u7565\u6a21\u5f0f \u8fed\u4ee3\u5668\u6a21\u5f0f \u9002\u914d\u5668\u6a21\u5f0f \u5de5\u5382\u6a21\u5f0f \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f \u4eab\u5143\u6a21\u5f0f \u4ee3\u7406\u6a21\u5f0f \u5f88\u591a\u6559\u6750\u4e2d\u90fd\u4f1a\u4e3e\u51fa\u8fd9\u79cd\u770b\u8d77\u6765\u597d\u50cf\u5f88\u6709\u8bf4\u670d\u529b\u7684\u4f8b\u5b50\uff1a struct Pet { virtual void speak() = 0; }; struct CatPet \uff1aPet { void speak() override { puts(\"\u55b5\"); } }; struct DogPet \uff1aPet { void speak() override { puts(\"\u6c6a\"); } }; int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); cat->speak(); dog->speak(); } \u7136\u800c\uff0c\u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2d\uff0c\u865a\u51fd\u6570\u53ef\u6709\u53ef\u65e0\uff0c\u5e76\u6ca1\u6709\u53d1\u6325\u4efb\u4f55\u4ef7\u503c\uff0c\u56e0\u4e3a\u666e\u901a\u6210\u5458\u51fd\u6570\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 \u865a\u51fd\u6570\u771f\u6b63\u7684\u4ef7\u503c\u5728\u4e8e\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u5165\u5176\u4ed6\u51fd\u6570\u65f6\uff01\u53ef\u4ee5\u590d\u7528\u90a3\u4e2a\u51fd\u6570\u91cc\u7684\u4ee3\u7801\u3002 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); puts(\"\u5582\u98df\u5b8c\u6bd5\"); } int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); feed(cat); feed(dog); } \u4f18\u70b9\u5728\u4e8e\uff0cfeed \u51fd\u6570\u53ea\u7528\u5b9e\u73b0\u4e00\u904d\u4e86\u3002\u5982\u679c\u6ca1\u6709\u865a\u51fd\u6570\uff1a void feed(DogPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u6c6a\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u55b5\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u5582\u98df \u548c \u5582\u98df\u5b8c\u6bd5 \u91cd\u590d\u4e24\u904d\uff01\u5982\u679c\u6211\u4eec\u53c8\u8981\u5f15\u5165\u4e00\u79cd\u65b0\u52a8\u7269 PigPet \u5462\uff1f\u4f60\u53c8\u8981\u624b\u5fd9\u811a\u4e71\u590d\u5236\u7c98\u8d34\u4e00\u4efd\u65b0\u7684 feed \u51fd\u6570\uff01 void feed(PigPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u62f1\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u6539\u4e86\u9700\u6c42\uff0c\u4ed6\u8bf4\u52a8\u7269\u73b0\u5728\u8981\u53eb\u4e24\u6b21\u3002 \u91c7\u7528\u4e86\u865a\u51fd\u6570\u7684\u4f60\uff0c\u53ea\u9700\u8981\u5728 feed \u51fd\u6570\u5185\u589e\u52a0\u4e00\u6b21 speak \u5373\u53ef\uff0c\u8f7b\u677e\uff01 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); pet->speak(); // \u52a0\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u5982\u679c\u4e00\u5f00\u59cb\u6ca1\u7528\u865a\u51fd\u6570\uff0c\u5c31\u5f97\u8fde\u6539 3 \u4e2a\u5730\u65b9\uff01 void feed(DogPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u4e14\u4e07\u4e00\u590d\u5236\u7c98\u8d34\u7684\u65f6\u5019\u6709\u4e2a\u5730\u65b9\u5199\u9519\u4e86\uff0c\u975e\u5e38\u9690\u853d\uff0c\u5f88\u5bb9\u6613\u53d1\u73b0\u4e0d\u4e86\uff1a void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); puts(\"\u55b5\"); // \u628a\u732b\u7684\u4ee3\u7801\u590d\u5236\u8fc7\u6765\u7684\u65f6\u5019\u6f0f\u6539\u4e86 \ud83e\udd2f puts(\"\u5582\u98df\u5b8c\u6bd5\"); }","title":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01"},{"location":"design_virtual/#_2","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8bf4\u7684\u8fd9\u4e9b\u6211\u90fd\u4f1a\uff0c\u8fd9\u6709\u4ec0\u4e48\u7a00\u5947\u7684\u3002\u90a3\u6211\u4eec\u6765\u4e3e\u4e2a\u5b9e\u9645\u5f00\u53d1\u4e2d\u4f1a\u9047\u5230\u7684\u4f8b\u5b50\u3002 \u8fd9\u91cc\u6709\u4e00\u4e2a\u6c42\u548c\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u548c\u3002 \u8fd8\u6709\u4e00\u4e2a\u6c42\u79ef\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u79ef\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u4ee3\u7801\u91cd\u590d\uff01 \u6211\u4eec\u89c2\u5bdf\u4e00\u4e0b sum \u548c product \u4e4b\u95f4\u6709\u54ea\u4e9b\u76f8\u4f3c\u7684\u90e8\u5206\uff0c\u628a\u4e24\u8005\u4ea7\u751f\u4e0d\u540c\u7684\u90e8\u5206\u7528 ??? \u4ee3\u66ff\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * } return res; } \u628a ??? \u90e8\u5206\u7528\u4e00\u4e2a\u865a\u51fd\u6570\u9876\u66ff\uff1a struct Reducer { virtual int init() = 0; virtual int add(int a, int b) = 0; }; int reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u8fd9\u6837\u4e0d\u8bba\u6211\u4eec\u60f3\u8981\u6c42\u548c\uff0c\u8fd8\u662f\u6c42\u79ef\uff0c\u53ea\u9700\u8981\u5b9e\u73b0\u5176\u4e2d\u4e0d\u540c\u7684\u90e8\u5206\u5c31\u53ef\u4ee5\u4e86\uff0c\u516c\u5171\u90e8\u5206\u5df2\u7ecf\u5728 reduce \u91cc\u5b9e\u73b0\u597d\uff0c\u5c31\u5b9e\u73b0\u4e86\u4ee3\u7801\u590d\u7528\u3002 struct SumReducer : Reducer { int init() override { return 0; } int add(int a, int b) override { return a + b; } }; struct ProductReducer : Reducer { int init() override { return 1; } int add(int a, int b) override { return a * b; } }; reduce(v, new SumReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 sum(v) reduce(v, new ProductReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 product(v) \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 \u5f88\u5bb9\u6613\u6dfb\u52a0\u65b0\u7684\u7b56\u7565\u8fdb\u6765\uff1a struct MinReducer : Reducer { int init() override { return numeric_limits::max(); } int add(int a, int b) override { return min(a, b); } }; struct MaxReducer : Reducer { int init() override { return numeric_limits::min(); } int add(int a, int b) override { return max(a, b); } };","title":"\u865a\u51fd\u6570\u5b9e\u6218\u6848\u4f8b"},{"location":"design_virtual/#_3","text":"\u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 sum \u548c product \u51fd\u6570\u4ece\u8f93\u5165\u6570\u636e\u76f4\u63a5\u8ba1\u7b97\uff08\u800c\u4e0d\u7528\u5148\u8bfb\u53d6\u5230\u4e00\u4e2a vector\uff09\uff01 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u62bd\u51fa\u516c\u5171\u90e8\u5206\uff0c\u73b0\u5728\u53ea\u9700\u8981\u4fee\u6539 reduce \u51fd\u6570\u672c\u8eab\u5c31\u53ef\u4ee5\u4e86\u3002 SumReducer \u548c ProductReducer \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u4f53\u73b0\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 int reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u53c8\u6539\u56de\u6765\uff0c\u4ed6\u7a81\u7136\u53c8\u60f3\u8981\u4ece vector \u91cc\u8bfb\u53d6\u6570\u636e\u4e86\u3002 \u5728\u7834\u53e3\u5927\u9a82\u8001\u677f\u51fa\u5c14\u53cd\u5c14\u7684\u540c\u65f6\uff0c\u4f60\u5f00\u59cb\u601d\u8003\uff0c\u8fd9\u4e24\u4e2a\u51fd\u6570\u4f3c\u4e4e\u8fd8\u662f\u6709\u4e00\u4e9b\u91cd\u590d\u53ef\u4ee5\u62bd\u53d6\u51fa\u6765\uff1f int cin_reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } int vector_reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u73b0\u5728\u6211\u4eec\u53ea\u6709\u8868\u793a\u5982\u4f55\u8ba1\u7b97\u7684\u7c7b Reducer \u505a\u53c2\u6570\u3002 \u4f60\u51b3\u5b9a\uff0c\u518d\u5b9a\u4e49\u4e00\u4e2a\u8868\u793a\u5982\u4f55\u8bfb\u53d6\u7684\u865a\u7c7b Inputer\u3002 struct Inputer { virtual optional fetch() = 0; }; int reduce(Inputer *inputer, Reducer *reducer) { int res = reducer->init(); while (auto tmp = inputer->fetch()) { res = reducer->add(res, tmp.value()); } return res; } \u8fd9\u6837\uff0c\u6211\u4eec\u6ee1\u8db3\u4e86 \u5355\u4e00\u804c\u8d23\u539f\u5219 \uff1a\u6bcf\u4e2a\u7c7b\u53ea\u8d1f\u8d23\u4e00\u4ef6\u4e8b\u3002 \u8fd9\u91cc\u7684 Inputer \u5b9e\u9645\u4e0a\u8fd0\u7528\u4e86 \u8fed\u4ee3\u5668\u6a21\u5f0f \uff1a\u63d0\u4f9b\u4e00\u4e2a\u62bd\u8c61\u63a5\u53e3\u6765 \u987a\u5e8f\u8bbf\u95ee \u4e00\u4e2a\u96c6\u5408\u4e2d\u5404\u4e2a\u5143\u7d20\uff0c\u800c\u53c8\u65e0\u987b\u66b4\u9732\u8be5\u96c6\u5408\u7684\u5185\u90e8\u8868\u793a\u3002 \u5e95\u5c42\u662f cin \u8fd8\u662f vector\uff1f\u6211\u4e0d\u5728\u4e4e\uff01\u6211\u53ea\u77e5\u9053\u4ed6\u53ef\u4ee5\u4f9d\u6b21\u987a\u5e8f\u53d6\u51fa\u6570\u636e\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; reduce(new CinInputer(), new SumReducer()); reduce(new VectorInputer(v), new SumReducer()); reduce(new CinInputer(), new ProductReducer()); reduce(new VectorInputer(v), new ProductReducer()); Inputer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8bfb\u53d6\u6570\u636e\uff0cReducer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8ba1\u7b97\u6570\u636e\u3002 \u8fd9\u5c31\u662f \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \uff1a\u9ad8\u5c42\u6a21\u5757\uff08reduce \u51fd\u6570\uff09\u4e0d\u8981\u76f4\u63a5\u4f9d\u8d56\u4e8e\u4f4e\u5c42\u6a21\u5757\uff0c\u4e8c\u8005\u90fd\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff08Inputer \u548c Reducer \u7c7b\uff09\u6765\u6c9f\u901a\u3002","title":"\u591a\u91cd\u7b56\u7565"},{"location":"design_virtual/#_4","text":"\u6709\u4e9b\u7cdf\u7cd5\u7684\u5b9e\u73b0\u4f1a\u628a\u5206\u660e\u4e0d\u5c5e\u4e8e\u540c\u4e00\u5c42\u6b21\u7684\u4e1c\u897f\u5f3a\u884c\u653e\u5728\u4e00\u8d77\uff0c\u6bd4\u5982\u6ca1\u80fd\u5206\u6e05 Inputer \u548c Reducer \u7c7b\uff0c\u9519\u8bef\u5730\u628a\u4ed6\u4eec\u8bbe\u8ba1\u6210\u4e86\u4e00\u4e2a\u7c7b\uff01 int reduce(Reducer *reducer) { int res = reducer->init(); while (auto tmp = reducer->fetch()) { // fetch \u51ed\u4ec0\u4e48\u548c init\u3001add \u653e\u5728\u4e00\u8d77\uff1f res = reducer->add(res, tmp.value()); } return res; } fetch \u660e\u660e\u5c5e\u4e8e IO \u64cd\u4f5c\uff01\u4f46\u4ed6\u88ab\u9519\u8bef\u5730\u653e\u5728\u4e86\u672c\u5e94\u53ea\u8d1f\u8d23\u8ba1\u7b97\u7684 Reducer \u91cc\uff01 \u8fd9\u5bfc\u81f4\u4f60\u5fc5\u987b\u5b9e\u73b0\u56db\u4e2a\u7c7b\uff0c\u7f57\u5217\u6240\u6709\u7684\u6392\u5217\u7ec4\u5408\uff1a struct CinSumReducer : Reducer { ... }; struct VectorSumReducer : Reducer { ... }; struct CinProductReducer : Reducer { ... }; struct VectorProductReducer : Reducer { ... }; \u8fd9\u663e\u7136\u662f\u4e0d\u7b26\u5408 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u7684\u3002 \u6ee1\u8db3 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3001 \u5f00\u95ed\u539f\u5219 \u3001 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u7684\u4ee3\u7801\u66f4\u52a0\u7075\u6d3b\u3001\u6613\u4e8e\u6269\u5c55\u3001\u6613\u4e8e\u7ef4\u62a4\u3002\u8bf7\u52a1\u5fc5\u8bb0\u4f4f\u5e76\u843d\u5b9e\u8d77\u6765\uff01 \u5426\u5219\u5373\u4f60\u88c5\u6a21\u4f5c\u6837\u5730\u7528\u4e86\u865a\u51fd\u6570\uff0c\u4e5f\u4e00\u6837\u4f1a\u5bfc\u81f4\u4ee3\u7801\u91cd\u590d\u3001\u96be\u4ee5\u7ef4\u62a4\uff01 \u8001\u677f\u514b\u6263\u5de5\u8d44\u65f6\u5c31\u4e0d\u7528\u9075\u5b88\u8fd9\u4e9b\u539f\u5219","title":"\u4e0d\u8981\u4ec0\u4e48\u4e1c\u897f\u90fd\u585e\u4e00\u5757"},{"location":"design_virtual/#_5","text":"\u521a\u624d\u7684\u4f8b\u5b50\u4e2d\u6211\u4eec\u7528\u5230\u4e86 Inputer \u865a\u63a5\u53e3\u7c7b\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; \u5982\u679c\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\uff1a\u8bfb\u53d6\u5230 0 \u622a\u6b62\uff0c\u800c\u4e0d\u662f -1 \u5462\uff1f\u96be\u9053\u8fd8\u5f97\u7ed9 CinInputer \u52a0\u4e2a\u53c2\u6570\uff1f \u4f46\u662f vector \u6709\u65f6\u5019\u4e5f\u53ef\u80fd\u6709\u8bfb\u5230 -1 \u5c31\u63d0\u524d\u622a\u65ad\u7684\u9700\u6c42\u5440\uff1f \u8fd9\u660e\u663e\u8fdd\u80cc\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 \u66f4\u597d\u7684\u8bbe\u8ba1\u662f\uff0c\u8ba9 CinInputer \u65e0\u9650\u8bfb\u53d6\uff0c\u6c38\u8fdc\u6210\u529f\u3002 \u7136\u540e\u53e6\u5916\u5f04\u4e00\u4e2a StopInputerAdapter\uff0c\u5176\u63a5\u53d7\u4e00\u4e2a CinInputer \u4f5c\u4e3a\u6784\u9020\u53c2\u6570\u3002 \u5f53 StopInputerAdapter \u88ab\u8bfb\u53d6\u65f6\uff0c\u4ed6\u4f1a\u68c0\u67e5\u662f\u5426\u4e3a -1\uff0c\u5982\u679c\u5df2\u7ecf\u5f97\u5230 -1\uff0c\u90a3\u4e48\u5c31\u8fd4\u56de nullopt\uff0c\u4e0d\u4f1a\u8fdb\u4e00\u6b65\u8c03\u7528 CinInputer \u4e86\u3002 StopInputerAdapter \u8d1f\u8d23\u5904\u7406\u622a\u65ad\u95ee\u9898\uff0cCinInputer \u53ea\u662f\u8d1f\u8d23\u8bfb\u53d6 cin \u8f93\u5165\u3002\u6ee1\u8db3\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 struct StopInputerAdapter : Inputer { Inputer *inputer; int stopMark; StopInputerAdapter(Inputer *inputer, int stopMark) : inputer(inputer) , stopMark(stopMark) {} optional fetch() override { auto tmp = inputer->fetch(); if (tmp == stopMark) return nullopt; return tmp; } }; \u8fd9\u91cc\u7684 StopInputerAdapter \u5c31\u662f\u4e00\u4e2a\u9002\u914d\u5668\uff0c\u4ed6\u628a CinInputer \u7684\u63a5\u53e3\uff08\u65e0\u9650\u8bfb\u53d6\uff09\u53e0\u52a0\u4e0a\u4e86\u4e00\u4e2a\u989d\u5916\u529f\u80fd\uff0c\u8bfb\u5230\u6307\u5b9a\u7684 stopMark \u503c\u5c31\u505c\u6b62\uff0c\u4ea7\u751f\u4e86\u4e00\u4e2a\u65b0\u7684 Inputer\u3002 reduce(new StopInputerAdapter(new CinInputer(), -1), new SumReducer()); // \u4ece cin \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new StopInputerAdapter(new VectorInputer(v), -1), new SumReducer()); // \u4ece vector \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new VectorInputer(), new SumReducer()); // \u4ece vector \u8bfb\uff0c\u4f46\u65e0\u9700\u622a\u65ad \u8fd9\u5c31\u662f \u9002\u914d\u5668\u6a21\u5f0f \uff1a\u5c06\u4e00\u4e2a\u7c7b\u7684\u63a5\u53e3\u6dfb\u6cb9\u52a0\u918b\uff0c\u8f6c\u6362\u6210\u5ba2\u6237\u5e0c\u671b\u7684\u53e6\u4e00\u4e2a\u63a5\u53e3\u3002 StopInputerAdapter \u8fd9\u4e2a\u9002\u914d\u5668\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a Inputer\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f5c\u4e3a reduce \u7684\u53c2\u6570\uff0c\u9002\u5e94\u4e86\u73b0\u6709\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 StopInputerAdapter \u5e76\u4e0d\u4f9d\u8d56\u4e8e\u53c2\u6570 Inputer \u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u53ef\u4ee5\u662f CinInputer\u3001\u4e5f\u53ef\u4ee5\u662f VectorInputer\uff0c\u6ee1\u8db3\u4e86 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u3002 \u672a\u6765\u5373\u4f7f\u65b0\u589e\u4e86\u4e0d\u540c\u7c7b\u578b\u7684 Inputer\uff0c\u751a\u81f3\u662f\u5176\u4ed6 InputerAdapter\uff0c\u4e00\u6837\u53ef\u4ee5\u914d\u5408 StopInputerAdapter \u4e00\u8d77\u4f7f\u7528\u800c\u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u6ee1\u8db3\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u5982\u679c\u6211\u4eec\u8fd8\u60f3\u5b9e\u73b0\uff0c\u8fc7\u6ee4\u51fa\u6240\u6709\u6b63\u6570\u548c\u96f6\uff0c\u8d1f\u6570\u76f4\u63a5\u4e22\u5f03\u5462\uff1f struct FilterInputerAdapter { Inputer *inputer; FilterInputerAdapter(Inputer *inputer) : inputer(inputer) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (tmp >= 0) { return tmp; } } } }; \u6539\u8fdb\uff1aFilter \u7684\u6761\u4ef6\u4e0d\u5e94\u4e3a\u5199\u6b7b\u7684 tmp >= 0 \uff0c\u800c\u5e94\u8be5\u662f\u4f20\u5165\u4e00\u4e2a FilterStrategy\uff0c\u5141\u8bb8\u7528\u6237\u6269\u5c55\u3002 struct FilterStrategy { virtual bool shouldPass(int value) = 0; // \u8fd4\u56de true \u8868\u793a\u8be5\u503c\u5e94\u8be5\u88ab\u4fdd\u7559 }; struct FilterStrategyAbove : FilterStrategy { // \u5927\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyAbove(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value > threshold; } }; struct FilterStrategyBelow : FilterStrategy { // \u5c0f\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyBelow(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value < threshold; } }; struct FilterInputerAdapter : Inputer { Inputer *inputer; FilterStrategy *strategy; FilterInputerAdapter(Inputer *inputer, FilterStrategy *strategy) : inputer(inputer), strategy(strategy) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (strategy->shouldPass(tmp)) { return tmp; } } } }; FilterStrategy \u53c8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u8fd0\u7528\u9002\u914d\u5668\u6a21\u5f0f\uff1a\u4f8b\u5982\u6211\u4eec\u53ef\u4ee5\u628a FilterStrategyAbove(0) \u548c FilterStrategyBelow(100) \u7ec4\u5408\u8d77\u6765\uff0c\u5b9e\u73b0\u8fc7\u6ee4\u51fa 0\uff5e100 \u8303\u56f4\u5185\u7684\u6574\u6570\u3002 struct FilterStrategyAnd : FilterStrategy { // \u8981\u6c42 a \u548c b \u4e24\u4e2a\u8fc7\u6ee4\u7b56\u7565\u90fd\u4e3a true\uff0c\u624d\u80fd\u901a\u8fc7 FilterStrategy *a; FilterStrategy *b; FilterStrategyAnd(FilterStrategy *a, FilterStrategy *b) : a(a), b(b) {} bool shouldPass(int value) override { return a->shouldPass(value) && b->shouldPass(value); } }; reduce( new FilterInputerAdapter( new StopInputerAdapter( new CinInputer(), -1 ), new FilterStrategyAnd( new FilterStrategyAbove(0), new FilterStrategyBelow(100) ) ), new SumReducer()); \u662f\u4e0d\u662f\u903b\u8f91\u975e\u5e38\u6e05\u6670\uff0c\u800c\u4e14\u5bb9\u6613\u6269\u5c55\u5462\uff1f \u5b9e\u9645\u4e0a\u51fd\u6570\u5f0f\u548c\u6a21\u677f\u5143\u7f16\u7a0b\u66f4\u64c5\u957f\u505a\u8fd9\u79cd\u5de5\u4f5c\uff0c\u4f46\u4eca\u5929\u5148\u4ecb\u7ecd\u5b8c\u539f\u6c41\u539f\u5473\u7684 Java \u98ce\u683c\u9762\u5411\u5bf9\u8c61\uff0c\u4ed6\u4eec\u590d\u7528\u4ee3\u7801\u7684\u601d\u8def\u662f\u5171\u901a\u7684\u3002 \u4f60\u5148\u5b66\u4f1a\u8d70\u8def\uff0c\u660e\u5929\u6211\u4eec\u518d\u6765\u5b66\u4e60\u8dd1\u6b65\uff0c\u597d\u5427\uff1f","title":"\u9002\u914d\u5668\u6a21\u5f0f"},{"location":"design_virtual/#_6","text":"\u9002\u914d\u5668\u6a21\u5f0f\u8fd8\u53ef\u4ee5\u4f7f\u539f\u672c\u7531\u4e8e\u63a5\u53e3\u4e0d\u517c\u5bb9\u800c\u4e0d\u80fd\u4e00\u8d77\u5de5\u4f5c\u7684\u90a3\u4e9b\u7c7b\u53ef\u4ee5\u4e00\u8d77\u5de5\u4f5c\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u4e86\u7c7b\u4f3c\u4e8e\u6211\u4eec Inputer \u7684\u8f93\u5165\u6d41\u63a5\u53e3\uff0c\u4e5f\u662f\u57fa\u4e8e\u865a\u51fd\u6570\u7684\u3002\u4f46\u662f\u4ed6\u7684\u63a5\u53e3\u663e\u7136\u4e0d\u80fd\u76f4\u63a5\u4f20\u5165\u6211\u4eec\u7684 reduce \u51fd\u6570\uff0c\u6211\u4eec\u7684 reduce \u51fd\u6570\u53ea\u63a5\u53d7\u6211\u4eec\u81ea\u5df1\u7684 Inputer \u63a5\u53e3\u3002\u8fd9\u65f6\u5c31\u53ef\u4ee5\u7528\u9002\u914d\u5668\uff0c\u628a\u63a5\u53e3\u7ffb\u8bd1\u6210\u6211\u4eec\u7684 reducer \u80fd\u591f\u7406\u89e3\u7684\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e2a\u81ea\u79f0 \u201cPoost\u201d \u7684\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u63a5\u53e3\uff1a struct PoostInputer { virtual bool hasNext() = 0; virtual int getNext() = 0; }; \u4ed6\u4eec\u8981\u6c42\u7684\u7528\u6cd5\u662f\u5148\u5224\u65ad hasNext()\uff0c\u7136\u540e\u624d\u80fd\u8c03\u7528 getNext \u8bfb\u53d6\u51fa\u771f\u6b63\u7684\u503c\u3002\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u4e86\u4e00\u4e2a Poost \u9002\u914d\u5668\uff0c\u628a PoostInputer \u7ffb\u8bd1\u6210\u6211\u4eec\u7684 Inputer\uff1a struct PoostInputerAdapter : Inputer { PoostInputer *poostIn; PoostInputerAdapter(PoostInputer *poostIn) : poostIn(poostIn) {} optional fetch() override { if (poostIn->hasNext()) { return poostIn->getNext(); } else { return nullopt; } } }; \u5f53\u6211\u4eec\u5f97\u5230\u4e00\u4e2a PoostInputer \u65f6\uff0c\u5982\u679c\u60f3\u8981\u8c03\u7528\u6211\u4eec\u81ea\u5df1\u7684 reducer\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u4e2a PoostInputerAdapter \u5957\u4e00\u5c42\uff1a auto poostStdIn = poost::getStandardInput(); reduce(new PoostInputerAdapter(poostStdIn), new SumReducer()); \u8fd9\u6837\u5c31\u53ef\u4ee5\u65e0\u7f1d\u5730\u628a PoostInputer \u4f5c\u4e3a reduce \u7684\u53c2\u6570\u4e86\u3002","title":"\u8de8\u63a5\u53e3\u7684\u9002\u914d\u5668"},{"location":"design_virtual/#_7","text":"\u73b0\u5728\u4f60\u662f\u4e00\u4e2a\u6e38\u620f\u5f00\u53d1\u8005\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u88c5\u5907\u6b66\u5668\uff0c\u4e0d\u540c\u7684\u6b66\u5668\u53ef\u4ee5\u53d1\u51fa\u4e0d\u540c\u7684\u5b50\u5f39\uff01 \u4f60\u4f7f\u7528\u5c0f\u5f6d\u8001\u5e08\u6559\u7684 \u7b56\u7565\u6a21\u5f0f \uff0c\u628a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u4f5c\u4e3a\u4e0d\u540c\u7684\u7b56\u7565\u4f20\u5165 player \u51fd\u6570\uff0c\u9020\u6210\u4e0d\u540c\u7c7b\u578b\u7684\u4f24\u5bb3\u3002 struct Bullet { virtual void explode() = 0; }; struct AK47Bullet : Bullet { void explode() override { puts(\"\u7269\u7406\u4f24\u5bb3\"); } }; struct MagicBullet : Bullet { void explode() override { puts(\"\u9b54\u6cd5\u4f24\u5bb3\"); } }; void player(Bullet *bullet) { bullet->explode(); } player(new AK47Bullet()); player(new MagicBullet()); \u4f46\u662f\u8fd9\u6837\u5c31\u76f8\u5f53\u4e8e\u6bcf\u4e2a\u73a9\u5bb6\u53ea\u6709\u4e00\u53d1\u5b50\u5f39\uff0c\u542c\u4e2a\u54cd\u5c31\u6ca1\u4e86\u2026 \u5982\u4f55\u5141\u8bb8\u73a9\u5bb6\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u9020\u65b0\u5b50\u5f39\u51fa\u6765\uff1f\u6211\u4eec\u53ef\u4ee5\u628a\u201c\u521b\u5efa\u5b50\u5f39\u201d\u8fd9\u4e00\u8fc7\u7a0b\u62bd\u8c61\u51fa\u6765\uff0c\u653e\u5728\u4e00\u4e2a\u201c\u67aa\u201d\u7c7b\u91cc\u3002 struct Gun { virtual Bullet *shoot() = 0; }; struct AK47Gun : Gun { Bullet *shoot() override { return new AK47Bullet(); } }; struct MagicGun : Gun { Bullet *shoot() override { return new MagicBullet(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new AK47Gun()); player(new MagicGun()); \u73b0\u5728\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u76f4\u63a5\u9009\u62e9\u4e0d\u540c\u7684\u67aa\u4e86\uff01 \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u5de5\u5382\u6a21\u5f0f \uff1a\u201c\u67aa\u201d\u5c31\u662f\u201c\u5b50\u5f39\u201d\u5bf9\u8c61\u7684\u5de5\u5382\u3002 \u4f20\u7ed9\u73a9\u5bb6\u7684\u662f\u5b50\u5f39\u7684\u5de5\u5382\u2014\u2014\u67aa\uff0c\u800c\u4e0d\u662f\u5b50\u5f39\u672c\u8eab\u3002 \u53ea\u8981\u8c03\u7528\u5de5\u5382\u7684 shoot \u51fd\u6570\uff0c\u73a9\u5bb6\u53ef\u4ee5\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u5efa\u65b0\u5b50\u5f39\u51fa\u6765\u3002 \u6b63\u6240\u8c13\u6388\u4eba\u4ee5\u9c7c\u4e0d\u5982\u6388\u4eba\u4ee5\u6e14\uff0c\u4f60\u7684\u73a9\u5bb6\u4e0d\u518d\u662f\u88ab\u52a8\u63a5\u53d7\u5b50\u5f39\uff0c\u800c\u662f\u53ef\u4ee5\u81ea\u5df1\u521b\u9020\u5b50\u5f39\u4e86\uff01 \u5de5\u5382\u8fd8\u53ef\u4ee5\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u6570\uff0c\u4f8b\u5982\u6211\u4eec\u9700\u8981\u6a21\u62df AK47 \u53ef\u80fd\u201c\u53d7\u6f6e\u201d\uff0c\u5bfc\u81f4\u4ea7\u751f\u7684\u5b50\u5f39\u5a01\u529b\u964d\u4f4e\u3002 \u5c31\u53ef\u4ee5\u7ed9\u67aa\u52a0\u4e00\u4e2a isWet \u53c2\u6570\uff0c\u7ed9\u5b50\u5f39\u52a0\u4e00\u4e2a damage \u53c2\u6570\uff0c\u8ba9 AK47 \u751f\u6210\u5b50\u5f39\u7684\u65f6\u5019\uff0c\u6839\u636e isWet \u4e3a\u5b50\u5f39\u6784\u9020\u51fd\u6570\u8bbe\u7f6e\u4e0d\u540c\u7684 damage\u3002 struct AK47Bullet { int damage; AK47Bullet(int damage) : damage(damage) {} void explode() { printf(\"\u9020\u6210 %d \u70b9\u7269\u7406\u4f24\u5bb3\\n\", damage); } }; struct AK47Gun : Gun { bool isWet; AK47Gun(bool isWet) : isWet(isWet) {} Bullet *shoot() override { if (isWet) return new AK47Bullet(5); // \u53d7\u6f6e\u4e86\uff0c\u4f24\u5bb3\u964d\u4f4e\u4e3a 5 else return new AK47Bullet(10); // \u6b63\u5e38\u60c5\u51b5\u4e0b\u4f24\u5bb3\u4e3a 10 } }; \u6211\u4eec\u8fd8\u53ef\u4ee5\u5229\u7528\u6a21\u677f\u81ea\u52a8\u4e3a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u6279\u91cf\u5b9a\u4e49\u5de5\u5382\uff1a template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new GunWithBullet()); player(new GunWithBullet()); \u8fd9\u6837\u5c31\u4e0d\u5fc5\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5b50\u5f39\u7c7b\u578b\u65f6\uff0c\u90fd\u5f97\u65b0\u5efa\u4e00\u4e2a\u76f8\u5e94\u7684\u67aa\u7c7b\u578b\u4e86\uff0c\u8fdb\u4e00\u6b65\u907f\u514d\u4e86\u4ee3\u7801\u91cd\u590d\u3002\u53ef\u89c1\u6a21\u677f\u5143\u7f16\u7a0b\u5b8c\u5168\u53ef\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u5f3a\u5f3a\u8054\u624b\u3002","title":"\u5de5\u5382\u6a21\u5f0f"},{"location":"design_virtual/#_8","text":"Gun *getGun(string name) { if (name == \"AK47\") { return new GunWithBullet(); } else if (name == \"Magic\") { return new GunWithBullet(); } else { throw runtime_error(\"\u6ca1\u6709\u8fd9\u79cd\u67aa\"); } } player(getGun(\"AK47\")); player(getGun(\"Magic\"));","title":"\u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f"},{"location":"design_virtual/#raii","text":"template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); delete bullet; // \u521a\u624d\u6ca1\u6709 delete\uff01\u4f1a\u4ea7\u751f\u5185\u5b58\u6cc4\u6f0f\uff01 } } player(new GunWithBullet()); player(new GunWithBullet()); \u73b0\u5728\u7684\u5de5\u5382\u4e00\u822c\u90fd\u4f1a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u5177\u4f53\u6765\u8bf4\u5c31\u662f\u7528 unique_ptr \u4ee3\u66ff T * \uff0c\u7528 make_unique(xxx) \u4ee3\u66ff new T(xxx) \u3002 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); unique_ptr shoot() override { return make_unique(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { auto bullet = gun->shoot(); bullet->explode(); // unique_ptr \u5728\u9000\u51fa\u5f53\u524d {} \u65f6\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u4e0d\u7528\u4f60\u60e6\u8bb0\u7740\u4e86 } } player(make_unique>().get()); player(make_unique>().get()); \u8fd9\u91cc C++ \u6807\u51c6\u4fdd\u8bc1\u4e86 unique_ptr \u7684\u751f\u547d\u5468\u671f\u662f\u8fd9\u4e00\u6574\u884c\uff08; \u7ed3\u675f\u524d\uff09\uff0c\u6574\u4e2a player \u6267\u884c\u671f\u95f4\u90fd\u6d3b\u7740\uff0c\u4e0d\u4f1a\u63d0\u524d\u91ca\u653e \u6b63\u5982 func(string().c_str()) \u4e0d\u4f1a\u6709\u4efb\u4f55\u95ee\u9898\uff0cstring \u8981\u5230 func \u8fd4\u56de\u540e\u624d\u91ca\u653e\u5462\uff01 \u53ea\u8981\u628a\u6240\u6709 make_unique \u770b\u4f5c new T \uff0c\u628a\u6240\u6709\u7684 unique_ptr \u770b\u4f5c T * \uff0c\u7528\u6cd5\u51e0\u4e4e\u4e00\u6837\uff0c\u4f46\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\uff0c\u65e0\u9700\u624b\u52a8 delete\u3002","title":"RAII \u81ea\u52a8\u7ba1\u7406\u5185\u5b58"},{"location":"design_virtual/#_9","text":"\u56de\u5230\u6570\u7ec4\u6c42\u548c\u95ee\u9898\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } int average(vector v) { int res = 0; int count = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; count = count + 1; } return res / count; } \u6211\u4eec\u60f3\u8981\u52a0\u4e00\u4e2a\u6c42\u5e73\u5747\u503c\u7684\u51fd\u6570 average\uff0c\u8fd9\u8be5\u5982\u4f55\u4e0e sum \u5408\u8d77\u6765\uff1f \u6ce8\u610f\u56e0\u4e3a\u6211\u4eec\u8981\u652f\u6301\u4ece CinInputer \u8bfb\u5165\u6570\u636e\uff0c\u5e76\u4e0d\u4e00\u5b9a\u50cf\u4e00\u6837 VectorInputer \u80fd\u591f\u63d0\u524d\u5f97\u5230\u6570\u7ec4\u5927\u5c0f\uff0c\u4e0d\u7136\u4e5f\u4e0d\u9700\u8981 count \u4e86\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 int count? = ???; // sum \u548c product \u7528\u4e0d\u5230\u8be5\u53d8\u91cf\uff0c\u53ea\u6709 average \u9700\u8981 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * count? = count? ???; // average \u65f6\u8fd9\u91cc\u8fd8\u9700\u8981\u989d\u5916\u4fee\u6539 count \u53d8\u91cf\uff01 } return res; } \u770b\u6765\u6211\u4eec\u9700\u8981\u5141\u8bb8 Reducer \u7684 init() \u8fd4\u56de \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d\uff01 \u4ee5\u524d\u7684\u8bbe\u8ba1\u8ba9 init() \u53ea\u80fd\u8fd4\u56de\u5355\u4e2a int \u662f\u4e2a\u9519\u8bef\u7684\u51b3\u5b9a\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u628a \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d \u5c01\u88c5\u6210\u4e00\u4e2a\u65b0\u7684\u7c7b\u3002 \u7136\u540e\u6539\u4e3a\u7531\u8fd9\u4e2a\u7c7b\u8d1f\u8d23\u63d0\u4f9b\u865a\u51fd\u6570 add()\u3002 \u4e14\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u53f3\u4fa7\u53c2\u6570\u4e86\uff0c\u5de6\u4fa7\u7684 res \u53d8\u91cf\u5df2\u7ecf\u5b58\u5728 ReducerState \u4f53\u5185\u4e86\u3002 struct ReducerState { virtual void add(int val) = 0; virtual int result() = 0; }; struct Reducer { virtual unique_ptr init() = 0; }; struct SumReducerState : ReducerState { int res; SumReducerState() : res(0) {} void add(int val) override { res = res + val; } int result() override { return res; } }; struct ProductReducerState : ReducerState { int res; ProductReducerState() : res(1) {} void add(int val) override { res = res * val; } int result() override { return res; } }; struct AverageReducerState : ReducerState { int res; int count; AverageReducerState() : res(0), count(0) {} void add(int val) override { res = res + val; count = count + 1; } int result() override { return res / count; } }; struct SumReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct ProductReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct AverageReducer : Reducer { unique_ptr init() override { return make_unique(); } }; \u8fd9\u91cc Reducer \u5c31\u6210\u4e86 ReducerState \u7684\u5de5\u5382\u3002 int reduce(Inputer *inputer, Reducer *reducer) { unique_ptr state = reducer->init(); while (auto val = inputer->fetch()) { state->add(val); } return state->result(); } int main() { vector v; reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 \u5e76\u884c \u7684 sum \u548c product \u51fd\u6570\uff01 \u5e76\u884c\u7248\u9700\u8981\u521b\u5efa\u5f88\u591a\u4e2a\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u9700\u8981\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u4e2d\u95f4\u7ed3\u679c\u53d8\u91cf\uff0c\u6700\u540e\u7684\u7ed3\u679c\u8ba1\u7b97\u53c8\u9700\u8981\u4e00\u4e2a\u4e2d\u95f4\u53d8\u91cf\u3002 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u91c7\u7528\u5de5\u5382\u6a21\u5f0f\uff0c\u5141\u8bb8\u51fd\u6570\u4f53\u5185\u591a\u6b21\u521b\u5efa ReducerState \u5bf9\u8c61\u3002 int reduce(Inputer *inputer, Reducer *reducer) { tbb::task_group g; list> local_states; vector chunk; auto enqueue_chunk = [&]() { local_chunks.emplace_back(); g.run([chunk = move(chunk), &back = local_chunks.back()]() { auto local_state = reducer->init(); for (auto &&c: chunk) { local_state->add(c); } back = move(local_state); // list \u4fdd\u8bc1\u5df2\u7ecf\u63d2\u5165\u5143\u7d20\u7684\u5f15\u7528\u4e0d\u4f1a\u5931\u6548\uff0c\u6240\u4ee5\u53ef\u4ee5\u6682\u5b58 back \u5f15\u7528 }); chunk.clear(); }; while (auto tmp = inputer->fetch()) { if (chunk.size() < 64) { // \u8fd8\u6ca1\u586b\u6ee1 64 \u4e2a chunk.push_back(tmp); } else { // \u586b\u6ee1\u4e86 64 \u4e2a\uff0c\u53ef\u4ee5\u63d0\u4ea4\u6210\u4e00\u4e2a\u5355\u72ec\u4efb\u52a1\u4e86 enqueue_chunk(); } } if (chunk.size() > 0) { enqueue_chunk(); // \u63d0\u4ea4\u4e0d\u8db3 64 \u4e2a\u7684\u6b8b\u4f59\u9879 } g.wait(); auto final_state = reducer->init(); for (auto &&local_state: local_states) { res = final_state->add(local_state->result()); } return final_state->result(); } \u53ea\u9700\u8981\u628a reducer \u53c2\u6570\u66ff\u6362\u4e3a MinReducer\u3001AverageReducer\u2026\u2026\u5c31\u81ea\u52a8\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u4efb\u52a1\uff0c\u800c\u4e0d\u7528\u4e3a\u4ed6\u4eec\u6bcf\u4e2a\u5355\u72ec\u7f16\u5199\u5e76\u884c\u7248\u672c\u7684\u4ee3\u7801\u3002 \u8bfe\u540e\u4f5c\u4e1a\uff1a\u4f7f\u7528\u6a21\u677f\u6279\u91cf\u5b9a\u4e49\u6240\u6709\u7684 Reducer\uff01\u4f8b\u5982\uff1a using MinReducer = ReducerWithState; ...","title":"\u5de5\u5382\u6a21\u5f0f\u5b9e\u6218"},{"location":"design_virtual/#_10","text":"\u5728\u4e8c\u7ef4\u6e38\u620f\u5f00\u53d1\u4e2d\uff0c\u5e38\u5e38\u4f1a\u63d0\u5230\u4e00\u79cd\u79f0\u4e3a Sprite\uff08\u7cbe\u7075\u8d34\u56fe\uff09\u7684\u9ed1\u8bdd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6bcf\u4e2a\u5bf9\u8c61\u81ea\u5df1\u6709\u4e00\u5f20\u8d34\u56fe\uff0c\u8d34\u56fe\u8ddf\u7740\u7269\u4f53\u7684\u4f4d\u7f6e\u8d70\u3002 struct Bullet { glm::vec3 position; glm::vec3 velocity; vector texture; void draw() { glDrawPixels(position, texture); } }; texture \u91cc\u9762\u5b58\u50a8\u7740\u8d34\u56fe\u7684 RGB \u6570\u636e\uff0c\u4ed6\u76f4\u63a5\u5c31\u662f Bullet \u7684\u6210\u5458\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u6253\u51fa\u4e86 100 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 100 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u540c\u65f6\u6253\u51fa\u4e86 1000 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 1000 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5185\u5b58\u6d88\u8017\u5c06\u4f1a\u975e\u5e38\u5927\u3002\u7136\u800c\u6240\u6709\u540c\u7c7b\u578b\u7684 Bullet\uff0c\u5176\u8d34\u56fe\u6570\u7ec4\u5176\u5b9e\u662f\u5b8c\u5168\u76f8\u540c\u7684\uff0c\u5b8c\u5168\u6ca1\u5fc5\u8981\u5404\u81ea\u5b58\u90a3\u4e48\u591a\u4efd\u62f7\u8d1d\u3002 \u4e3a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 \u4eab\u5143\u6a21\u5f0f \uff1a\u5171\u4eab\u591a\u4e2a\u5bf9\u8c61\u4e4b\u95f4 \u76f8\u540c \u7684\u90e8\u5206\uff0c\u8282\u7701\u5185\u5b58\u5f00\u9500\u3002 \u8fd9\u91cc\u6bcf\u9897\u5b50\u5f39\u7684 position\u3001velocity \u663e\u7136\u90fd\u662f\u5404\u6709\u4e0d\u540c\u7684\uff0c\u4e0d\u53ef\u80fd\u6240\u6709\u5b50\u5f39\u90fd\u5728\u540c\u4e00\u4e2a\u4f4d\u7f6e\u4e0a\u3002 \u4f46\u662f\u5f88\u591a\u5b50\u5f39\u90fd\u4f1a\u6709\u7740\u76f8\u540c\u7684\u8d34\u56fe\uff0c\u53ea\u6709\u4e0d\u540c\u7c7b\u578b\u7684\u5b50\u5f39\u8d34\u56fe\u4f1a\u4e0d\u4e00\u6837\u3002 \u6bd4\u5982\u706b\u7130\u5f39\u548c\u5bd2\u51b0\u5f39\u4f1a\u6709\u4e0d\u540c\u7684\u8d34\u56fe\uff0c\u4f46\u662f\u5f53\u573a\u4e0a\u51fa\u73b0 100 \u9897\u706b\u7130\u5f39\u65f6\uff0c\u663e\u7136\u4e0d\u9700\u8981\u62f7\u8d1d 100 \u4efd\u5b8c\u5168\u76f8\u540c\u7684\u706b\u7130\u5f39\u8d34\u56fe\u3002 struct Sprite { // Sprite \u624d\u662f\u771f\u6b63\u6301\u6709\uff08\u5f88\u5927\u7684\uff09\u8d34\u56fe\u6570\u636e\u7684 vector texture; void draw(glm::vec3 position) { glDrawPixels(position, texture); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // \u5141\u8bb8\u591a\u4e2a\u5b50\u5f39\u5bf9\u8c61\u5171\u4eab\u540c\u4e00\u4e2a\u7cbe\u7075\u8d34\u56fe\u7684\u6240\u6709\u6743 void draw() { sprite->draw(position); // \u8f6c\u53d1\u7ed9 Sprite \u8ba9\u4ed6\u5e2e\u5fd9\u5728\u6211\u7684\u4f4d\u7f6e\u7ed8\u5236\u8d34\u56fe } }; \u9700\u8981\u7ed8\u5236\u5b50\u5f39\u65f6\uff0cBullet \u7684 draw \u53ea\u662f\u7b80\u5355\u5730\u8f6c\u53d1\u7ed9 Sprite \u7c7b\u7684 draw\u3002 \u53ea\u8981\u544a\u8bc9 Sprite \u5b50\u5f39\u7684\u4f4d\u7f6e\u5c31\u884c\uff0c\u8d34\u56fe\u6570\u636e\u5df2\u7ecf\u5b58\u5728 Sprite \u5185\u90e8\uff0c\u8ba9\u4ed6\u6765\u8d1f\u8d23\u771f\u6b63\u7ed8\u5236\u3002 Bullet \u7c7b\u53ea\u9700\u8981\u4e13\u6ce8\u4e8e\u4f4d\u7f6e\u3001\u901f\u5ea6\u7684\u66f4\u65b0\u5373\u53ef\uff0c\u4e0d\u5fc5\u53bb\u64cd\u5fc3\u7740\u8d34\u56fe\u7ed8\u5236\u7684\u7ec6\u8282\uff0c\u5b9e\u73b0\u4e86\u89e3\u8026\u3002 \u8fd9\u79cd\u51fd\u6570\u8c03\u7528\u7684\u8f6c\u53d1\u4e5f\u88ab\u79f0\u4e3a \u4ee3\u7406\u6a21\u5f0f \u3002","title":"\u4eab\u5143\u6a21\u5f0f"},{"location":"design_virtual/#_11","text":"\u8fd9\u6837\u8fd8\u6709\u4e00\u4e2a\u597d\u5904\u90a3\u5c31\u662f\uff0cSprite \u53ef\u4ee5\u8bbe\u8ba1\u6210\u4e00\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\u7c7b\uff1a struct Sprite { virtual void draw(glm::vec3 position) = 0; }; struct FireSprite : Sprite { vector fireTexture; FireSprite() : fireTexture(loadTexture(\"fire.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, fireTexture); } }; struct IceSprite : Sprite { // \u5047\u5982\u5bd2\u51b0\u5f39\u9700\u8981\u4e24\u5f20\u8d34\u56fe\uff0c\u4e5f\u6ca1\u95ee\u9898\uff01\u56e0\u4e3a\u865a\u63a5\u53e3\u7c7b\u5141\u8bb8\u5b50\u7c7b\u6709\u4e0d\u540c\u7684\u6210\u5458\uff0c\u4e0d\u540c\u7684\u7ed3\u6784\u4f53\u5927\u5c0f vector iceTexture1; vector iceTexture2; IceSprite() : iceTexture1(loadTexture(\"ice1.jpg\")) , iceTexture2(loadTexture(\"ice2.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, iceTexture1); glDrawPixels(position, iceTexture2); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // Sprite \u8d1f\u8d23\u542b\u6709\u865a\u51fd\u6570 void draw() { // Bullet \u7684 draw \u5c31\u4e0d\u7528\u662f\u865a\u51fd\u6570\u4e86\uff01 sprite->draw(position); } };","title":"\u4ee3\u7406\u6a21\u5f0f"},{"location":"design_virtual/#_12","text":"","title":"\u7ec4\u4ef6\u6a21\u5f0f"},{"location":"design_virtual/#_13","text":"","title":"\u865a\u51fd\u6570\u5e38\u89c1\u95ee\u9898\u8fa8\u6790"},{"location":"design_virtual/#bool","text":"","title":"\u8fd4\u56de bool \u7684\u865a\u51fd\u6570"},{"location":"design_virtual/#_14","text":"\u4f60\u62ff\u5230\u4e86\u4e00\u4e2a\u5927\u5b66\u751f\u8ba1\u7b97\u5668\u7684\u5927\u4f5c\u4e1a\uff1a int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; if (c == '+') { cout << a + b; } else if (c == '-') { cout << a - b; } else if (c == '*') { cout << a * b; } else if (c == '/') { cout << a / b; } else { cout << \"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"; } } \u4f60\u5f00\u59cb\u7528\u7b56\u7565\u6a21\u5f0f\u6539\u9020\u5b83\uff1a struct Calculator { virtual int calculate(int a, int b) = 0; }; struct AddCalculator : Calculator { int calculate(int a, int b) override { return a + b; } }; struct SubCalculator : Calculator { int calculate(int a, int b) override { return a - b; } }; struct MulCalculator : Calculator { int calculate(int a, int b) override { return a * b; } }; struct DivCalculator : Calculator { int calculate(int a, int b) override { return a / b; } }; Calculator *getCalculator(char c) { if (c == '+') { calculator = new AddCalculator(); } else if (c == '-') { calculator = new SubCalculator(); } else if (c == '*') { calculator = new MulCalculator(); } else if (c == '/') { calculator = new DivCalculator(); } else { throw runtime_error(\"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"); } }; int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; Calculator *calculator = getCalculator(c); cout << calculator->calculate(a, b); }","title":"\u8bfe\u540e\u4f5c\u4e1a"},{"location":"donate/","text":"\u8d5e\u52a9\u540d\u5355 \u5c0f\u5f6d\u5927\u5178\u7684\u6301\u7eed\u7f16\u5199\u79bb\u4e0d\u5f00\u4ee5\u4e0b\u5c0f\u5f6d\u53cb\u7684\u8d5e\u52a9\uff01 \u5c0f\u5f6d\u8001\u5e08\u7684\u5927\u5178\u662f\u514d\u8d39\u4e0b\u8f7d\u7684\uff0c\u4e0d\u7528\u8d5e\u52a9\u4e5f\u53ef\u4ee5\u67e5\u770b\u54e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u906d\u5230 \u201c\u767d\u773c\u72fc\u201d\u8111\u677f \u5f00\u9664\uff0c\u76ee\u524d\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\u3002\u53ea\u597d\u5bfb\u6c42\u5404\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9\uff0c\u4fdd\u969c\u5c0f\u5f6d\u8001\u5e08\u7684\u57fa\u672c\u751f\u547d\u4f53\u5f81\u8fd0\u884c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9886\u8854\u5f00\u53d1\u7684 Zeno \u8f6f\u4ef6\uff0c\u66fe\u53c2\u4e0e \u6d41\u91cf\u5730\u7403 2 \u3001\u676d\u5dde\u4e9a\u8fd0\u4f1a\u7b49\u5927\u578b\u9879\u76ee\u7684\u7279\u6548\u5236\u4f5c\uff0c\u9b45\u60d1\u65e0\u6570\u897f\u88c5\u5927\u8111\u6295\u8d44\u4eba\uff0c\u4e3a\u201c\u767d\u773c\u72fc\u201d\u535a\u5f97\u98ce\u5149\u65e0\u9650\u3002\u73b0\u5728\u5374\u5c06\u5982\u6b64\u8d21\u732e\u5de8\u5927\u7684 Zeno \u201c\u5f00\u56fd\u529f\u52cb\u201d\uff0c\u4ee5\u201c\u8d44\u91d1\u56f0\u96be\u201d\u4e3a\u7531\u201c\u5378\u8f7d\u201d\u4e86\uff0c\u8db3\u4ee5\u89c1\u8fd9\u4f4d\u201c\u767d\u773c\u72fc\u201d\u7684\u201c\u77e5\u6069\u56fe\u62a5\u201d\u3002 \u5982\u679c\u4f60\u89c9\u5f97\u672c\u4e66\u5bf9\u4f60\u6709\u6240\u5e2e\u52a9\uff0c\u53ef\u4ee5\u901a\u8fc7 \u7231\u53d1\u7535 \u8d5e\u52a9\u5c0f\u5f6d\u8001\u5e08\uff0c\u4ee5\u4fbf\u5c0f\u5f6d\u8001\u5e08\u6709\u66f4\u591a\u7684\u7cbe\u529b\u7ee7\u7eed\u7f16\u5199\u548c\u7ef4\u62a4\u672c\u4e66\u3002 \u6bcf\u6709\u4e00\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9 26.90 \uff0c\u5c0f\u5f6d\u8001\u5e08\u4e00\u5929\u7684\u98df\u54c1\u5b89\u5168\u5c31\u6709\u4e86\u7740\u843d\u3002 \u6551\u547d\u2026\u2026\u7231\u53d1\u7535\u4f3c\u4e4e\u5173\u505c\u4e86\uff01\uff1f\u5c0f\u5f6d\u8001\u5e08\u8d76\u7d27\u8d34\u51fa\u652f\u4ed8\u5b9d\u6536\u6b3e\u7801\u4f5c\u4e3a\u66ff\u4ee3\u2026\u2026 \u5982\u679c\u4f60\u4e5f\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\uff0c\u5c31\u4e0d\u7528\u52c9\u5f3a\u8d5e\u52a9\u4e86\u2026\u2026\u4e5f\u53ef\u4ee5\u5148\u7ed9\u5c0f\u5f6d\u8001\u5e08\u70b9\u4e00\u9897 \u2b50Star\u2b50 \u8868\u793a\u5fc3\u610f\u3002","title":"\u8d5e\u52a9\u540d\u5355"},{"location":"donate/#_1","text":"\u5c0f\u5f6d\u5927\u5178\u7684\u6301\u7eed\u7f16\u5199\u79bb\u4e0d\u5f00\u4ee5\u4e0b\u5c0f\u5f6d\u53cb\u7684\u8d5e\u52a9\uff01 \u5c0f\u5f6d\u8001\u5e08\u7684\u5927\u5178\u662f\u514d\u8d39\u4e0b\u8f7d\u7684\uff0c\u4e0d\u7528\u8d5e\u52a9\u4e5f\u53ef\u4ee5\u67e5\u770b\u54e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u906d\u5230 \u201c\u767d\u773c\u72fc\u201d\u8111\u677f \u5f00\u9664\uff0c\u76ee\u524d\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\u3002\u53ea\u597d\u5bfb\u6c42\u5404\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9\uff0c\u4fdd\u969c\u5c0f\u5f6d\u8001\u5e08\u7684\u57fa\u672c\u751f\u547d\u4f53\u5f81\u8fd0\u884c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9886\u8854\u5f00\u53d1\u7684 Zeno \u8f6f\u4ef6\uff0c\u66fe\u53c2\u4e0e \u6d41\u91cf\u5730\u7403 2 \u3001\u676d\u5dde\u4e9a\u8fd0\u4f1a\u7b49\u5927\u578b\u9879\u76ee\u7684\u7279\u6548\u5236\u4f5c\uff0c\u9b45\u60d1\u65e0\u6570\u897f\u88c5\u5927\u8111\u6295\u8d44\u4eba\uff0c\u4e3a\u201c\u767d\u773c\u72fc\u201d\u535a\u5f97\u98ce\u5149\u65e0\u9650\u3002\u73b0\u5728\u5374\u5c06\u5982\u6b64\u8d21\u732e\u5de8\u5927\u7684 Zeno \u201c\u5f00\u56fd\u529f\u52cb\u201d\uff0c\u4ee5\u201c\u8d44\u91d1\u56f0\u96be\u201d\u4e3a\u7531\u201c\u5378\u8f7d\u201d\u4e86\uff0c\u8db3\u4ee5\u89c1\u8fd9\u4f4d\u201c\u767d\u773c\u72fc\u201d\u7684\u201c\u77e5\u6069\u56fe\u62a5\u201d\u3002 \u5982\u679c\u4f60\u89c9\u5f97\u672c\u4e66\u5bf9\u4f60\u6709\u6240\u5e2e\u52a9\uff0c\u53ef\u4ee5\u901a\u8fc7 \u7231\u53d1\u7535 \u8d5e\u52a9\u5c0f\u5f6d\u8001\u5e08\uff0c\u4ee5\u4fbf\u5c0f\u5f6d\u8001\u5e08\u6709\u66f4\u591a\u7684\u7cbe\u529b\u7ee7\u7eed\u7f16\u5199\u548c\u7ef4\u62a4\u672c\u4e66\u3002 \u6bcf\u6709\u4e00\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9 26.90 \uff0c\u5c0f\u5f6d\u8001\u5e08\u4e00\u5929\u7684\u98df\u54c1\u5b89\u5168\u5c31\u6709\u4e86\u7740\u843d\u3002 \u6551\u547d\u2026\u2026\u7231\u53d1\u7535\u4f3c\u4e4e\u5173\u505c\u4e86\uff01\uff1f\u5c0f\u5f6d\u8001\u5e08\u8d76\u7d27\u8d34\u51fa\u652f\u4ed8\u5b9d\u6536\u6b3e\u7801\u4f5c\u4e3a\u66ff\u4ee3\u2026\u2026 \u5982\u679c\u4f60\u4e5f\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\uff0c\u5c31\u4e0d\u7528\u52c9\u5f3a\u8d5e\u52a9\u4e86\u2026\u2026\u4e5f\u53ef\u4ee5\u5148\u7ed9\u5c0f\u5f6d\u8001\u5e08\u70b9\u4e00\u9897 \u2b50Star\u2b50 \u8868\u793a\u5fc3\u610f\u3002","title":"\u8d5e\u52a9\u540d\u5355"},{"location":"error_code/","text":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u914d\u5957\u89c6\u9891\uff1a BV1QpWSekEJY \u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u9519\u8bef\u7684\u5206\u7c7b \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u53ef\u6062\u590d\u9519\u8bef \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected \u9519\u8bef\u7684\u5206\u7c7b \u5047\u8bbe\u4e00\u4e2a\u51fd\u6570 open \u7684\u529f\u80fd\u662f\u6253\u5f00\u6587\u4ef6\u3002 int open(const char *path) { if (!file_exists(path)) { // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\u600e\u4e48\u529e\uff1f } // \u6210\u529f\u627e\u5230\u6587\u4ef6\uff1a return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u51fd\u6570\u90fd\u80fd\u6210\u529f\u6267\u884c\uff0c\u90fd\u80fd\u6b63\u5e38\u8fd4\u56de\u7ed3\u679c\u2026\u2026 \u53ef\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u8bbe\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u6c38\u8fdc\u6b63\u786e\u6267\u884c\uff08\u4f8b\u5982\u6587\u4ef6\u53ef\u80fd\u88ab\u7528\u6237\u8bef\u5220\u9664\uff0c\u6216\u8005\u5185\u5b58\u4e0d\u591f\u7528\u7b49\uff09\u3002 \u66f4\u6709\u751a\u8005\uff0c\u6709\u65f6\u9519\u8bef\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff08\u4f8b\u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u4e00\u4e2a\u65b0\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5c06\u5176\u89c6\u4e3a\u4e0d\u53ef\u4fee\u590d\u7684\u9519\u8bef\uff09\u3002 \u7279\u522b\u662f\u6d89\u53ca IO \u64cd\u4f5c\u7684\u4efb\u52a1\uff0c\u51fa\u73b0\u4e00\u4e9b\u7ec6\u5c0f\u9519\u8bef\u7684\u60c5\u51b5\u662f\u5f88\u591a\u7684\u3002\u8981\u533a\u5206\u54ea\u4e9b\u662f\u53ef\u4ee5\u4fee\u590d\u7684\u9519\u8bef\uff0c\u54ea\u4e9b\u662f\u4e0d\u53ef\u633d\u56de\u7684\u9519\u8bef\u3002 \u4f8b\u5982\u5f53\u7f51\u7edc\u8fde\u63a5\u5931\u8d25\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u5c1d\u8bd5\u8fde\u63a5\u4e24\u4e09\u6b21\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u884c\uff0c\u90a3\u624d\u8ba4\u4e3a\u662f\u771f\u7684\u5931\u8d25\u4e86\u3002 \u56e0\u6b64\uff0c\u6211\u4eec\u628a\u9519\u8bef\u5206\u4e3a\u4e24\u5927\u7c7b\uff1a \u53ef\u6062\u590d\u9519\u8bef\uff1a\u4e0d\u662f\u7279\u522b\u4e25\u91cd\u7684\uff0c\u751a\u81f3\u662f\u8ba1\u5212\u4e4b\u4e2d\u7684\uff0c\u7ecf\u5e38\u53d1\u751f\u7684\u9519\u8bef\u3002\u53ef\u4ee5\u901a\u8fc7\u4e00\u5b9a\u64cd\u4f5c\u6765\u5f25\u8865\u8fd9\u7c7b\u9519\u8bef\uff0c\u6216\u5c06\u5176\u8f6c\u5316\u4e3a\u5176\u4ed6\u4e0d\u540c\u7c7b\u578b\u7684\u9519\u8bef\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef\uff1a\u975e\u5e38\u4e25\u91cd\u7684\u9519\u8bef\uff0c\u6216\u8005\u662f\u53d1\u751f\u6982\u7387\u5f88\u4f4e\u5e73\u65f6\u6ca1\u5fc5\u8981\u7279\u6b8a\u5904\u7406\u7684\u9519\u8bef\u3002\u4e00\u65e6\u53d1\u751f\uff0c\u6574\u4e2a\u7a0b\u5e8f\u90fd\u65e0\u6cd5\u7ee7\u7eed\u6267\u884c\u4e0b\u53bb\uff0c\u5fc5\u987b\u5168\u8eab\u800c\u9000\uff0c\u6574\u4e2a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u90fd\u5c06\u7ec8\u6b62\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u4e0d\u53ef\u6062\u590d\u9519\u8bef\u7684\u5904\u7406\u6700\u7b80\u5355\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u88ab\u8c03\u7528\u8005\u68c0\u6d4b\u5230\u9519\u8bef\u7684\u5206\u652f\u4e2d\uff0c\u76f4\u63a5\u8c03\u7528 exit \u51fd\u6570\u201c\u7ec8\u6b62\u7a0b\u5e8f\u201d\u5373\u53ef\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\u6211\u5c31\u81ea\u6740\uff01 exit(1); // \u7a0b\u5e8f\u4e0d\u4f1a\u6267\u884c\u5230\u6b64 } return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7f3a\u70b9\uff1a exit \u4f1a\u76f4\u63a5\u9000\u51fa\u6574\u4e2a\u8fdb\u7a0b\uff01\u6ca1\u6709\u4efb\u4f55\u7ed9\u8c03\u7528\u8005\u633d\u56de\u7684\u673a\u4f1a\uff0c\u56e0\u6b64\u53ea\u80fd\u7528\u4e8e\u201c\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u201d\u8fd9\u4e2a\u7c7b\u578b\u3002 \u4f18\u70b9\uff1a\u8c03\u7528\u8005\u65e0\u9700\u505a\u4efb\u4f55\u5224\u65ad\u5904\u7406\uff0c\u5199\u8d77\u6765\u5c31\u597d\u50cf\u88ab\u8c03\u7528\u51fd\u6570\u201c\u603b\u662f\u6210\u529f\u201d\u4e00\u6837\uff0c\u603b\u80fd\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u4e3a\u5982\u679c\u88ab\u8c03\u7528\u8005\u5931\u8d25\u7684\u8bdd\uff0c\u4ed6\u4f1a\u8c03\u7528 exit \u81ea\u6740\uff0c\u5c31\u4e0d\u4f1a\u8fd4\u56de\u5230\u8c03\u7528\u8005\u4e2d\u4e86\u3002 \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6\u53d8\u6210\u201c\u7801\u7801\u7684\u8424\u706b\u866b\u201d\u4e86\u3002 \u53ef\u6062\u590d\u9519\u8bef \u6709\u65f6\u5019\uff0c\u6211\u4eec\u5bf9\u4e8e\u90e8\u5206\u9519\u8bef\uff0c\u662f\u6709\u633d\u56de\u673a\u4f1a\u7684\uff0c\u4e0d\u5e0c\u671b\u56e0\u4e3a\u4e00\u70b9\u53ef\u4ee5\u4fee\u590d\u7684\u5c0f\u9519\u8bef\u5c31\u628a\u6574\u4e2a\u7a0b\u5e8f\u7ec8\u6b62\u6389\u3002 \u8981\u4e0d\u8981\u633d\u56de\u5e94\u8be5\u7531\u8c03\u7528\u8005\u7684\u5177\u4f53\u4e1a\u52a1\u51b3\u5b9a\uff0c\u800c\u5c01\u88c5\u826f\u597d\u7684 API\uff08 open \uff09\u5e94\u8be5\u5fe0\u5b9e\u5730\u628a\u9519\u8bef\u62a5\u544a\u7ed9\u8c03\u7528\u8005\uff08 main \uff09\u3002 \u8ba9\u8c03\u7528\u8005\u6765\u51b3\u5b9a\u8981\u6740\u4e86\u8fd8\u662f\u62a2\u6551\uff0c\u800c\u4e0d\u662f\u81ea\u4f5c\u4e3b\u5f20\u5730\u76f4\u63a5\u81ea\u6740\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c31\u8fd4\u56de -1 \u8fd9\u4e2a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d\u4ee3\u66ff return -1; } return get_handle(path); } int main() { int file = open(\"file.txt\"); if (file == -1) { // \u7f3a\u70b9\u662f main \u91cc\u9762\u5fc5\u987b\u5224\u65ad\u8fd4\u56de\u503c\u662f\u5426\u4e3a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c1d\u8bd5\u8fdb\u884c\u5904\u7406 create_empty_file(\"file.txt\"); // \u91cd\u65b0\u5c1d\u8bd5\u6253\u5f00 file = open(\"file.txt\"); if (file == -1) { // \u5982\u679c\u8fd8\u662f\u51fa\u9519\uff0c\u90a3\u5c31\u6ca1\u6551\u4e86 exit(-1); // \u76f4\u63a5\u81ea\u6740 } } char buf[64]; read(file, buf, sizeof buf); ... } \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 main \u662f\u8c03\u7528\u8005\uff0c open \u662f\u88ab\u8c03\u7528\u8005\u3002 \u88ab\u8c03\u7528\u8005\u51fd\u6570\u53ef\u80fd\u4ea7\u751f\u9519\u8bef\uff0c\u4e5f\u53ef\u80fd\u6b63\u5e38\u6267\u884c\u3002 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected \u4e5f\u53ef\u4ee5 boost::expected \u66ff\u4ee3\u3002","title":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"error_code/#c","text":"\u914d\u5957\u89c6\u9891\uff1a BV1QpWSekEJY \u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u9519\u8bef\u7684\u5206\u7c7b \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u53ef\u6062\u590d\u9519\u8bef \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected","title":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"error_code/#_1","text":"\u5047\u8bbe\u4e00\u4e2a\u51fd\u6570 open \u7684\u529f\u80fd\u662f\u6253\u5f00\u6587\u4ef6\u3002 int open(const char *path) { if (!file_exists(path)) { // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\u600e\u4e48\u529e\uff1f } // \u6210\u529f\u627e\u5230\u6587\u4ef6\uff1a return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u51fd\u6570\u90fd\u80fd\u6210\u529f\u6267\u884c\uff0c\u90fd\u80fd\u6b63\u5e38\u8fd4\u56de\u7ed3\u679c\u2026\u2026 \u53ef\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u8bbe\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u6c38\u8fdc\u6b63\u786e\u6267\u884c\uff08\u4f8b\u5982\u6587\u4ef6\u53ef\u80fd\u88ab\u7528\u6237\u8bef\u5220\u9664\uff0c\u6216\u8005\u5185\u5b58\u4e0d\u591f\u7528\u7b49\uff09\u3002 \u66f4\u6709\u751a\u8005\uff0c\u6709\u65f6\u9519\u8bef\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff08\u4f8b\u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u4e00\u4e2a\u65b0\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5c06\u5176\u89c6\u4e3a\u4e0d\u53ef\u4fee\u590d\u7684\u9519\u8bef\uff09\u3002 \u7279\u522b\u662f\u6d89\u53ca IO \u64cd\u4f5c\u7684\u4efb\u52a1\uff0c\u51fa\u73b0\u4e00\u4e9b\u7ec6\u5c0f\u9519\u8bef\u7684\u60c5\u51b5\u662f\u5f88\u591a\u7684\u3002\u8981\u533a\u5206\u54ea\u4e9b\u662f\u53ef\u4ee5\u4fee\u590d\u7684\u9519\u8bef\uff0c\u54ea\u4e9b\u662f\u4e0d\u53ef\u633d\u56de\u7684\u9519\u8bef\u3002 \u4f8b\u5982\u5f53\u7f51\u7edc\u8fde\u63a5\u5931\u8d25\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u5c1d\u8bd5\u8fde\u63a5\u4e24\u4e09\u6b21\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u884c\uff0c\u90a3\u624d\u8ba4\u4e3a\u662f\u771f\u7684\u5931\u8d25\u4e86\u3002 \u56e0\u6b64\uff0c\u6211\u4eec\u628a\u9519\u8bef\u5206\u4e3a\u4e24\u5927\u7c7b\uff1a \u53ef\u6062\u590d\u9519\u8bef\uff1a\u4e0d\u662f\u7279\u522b\u4e25\u91cd\u7684\uff0c\u751a\u81f3\u662f\u8ba1\u5212\u4e4b\u4e2d\u7684\uff0c\u7ecf\u5e38\u53d1\u751f\u7684\u9519\u8bef\u3002\u53ef\u4ee5\u901a\u8fc7\u4e00\u5b9a\u64cd\u4f5c\u6765\u5f25\u8865\u8fd9\u7c7b\u9519\u8bef\uff0c\u6216\u5c06\u5176\u8f6c\u5316\u4e3a\u5176\u4ed6\u4e0d\u540c\u7c7b\u578b\u7684\u9519\u8bef\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef\uff1a\u975e\u5e38\u4e25\u91cd\u7684\u9519\u8bef\uff0c\u6216\u8005\u662f\u53d1\u751f\u6982\u7387\u5f88\u4f4e\u5e73\u65f6\u6ca1\u5fc5\u8981\u7279\u6b8a\u5904\u7406\u7684\u9519\u8bef\u3002\u4e00\u65e6\u53d1\u751f\uff0c\u6574\u4e2a\u7a0b\u5e8f\u90fd\u65e0\u6cd5\u7ee7\u7eed\u6267\u884c\u4e0b\u53bb\uff0c\u5fc5\u987b\u5168\u8eab\u800c\u9000\uff0c\u6574\u4e2a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u90fd\u5c06\u7ec8\u6b62\u3002","title":"\u9519\u8bef\u7684\u5206\u7c7b"},{"location":"error_code/#_2","text":"\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u7684\u5904\u7406\u6700\u7b80\u5355\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u88ab\u8c03\u7528\u8005\u68c0\u6d4b\u5230\u9519\u8bef\u7684\u5206\u652f\u4e2d\uff0c\u76f4\u63a5\u8c03\u7528 exit \u51fd\u6570\u201c\u7ec8\u6b62\u7a0b\u5e8f\u201d\u5373\u53ef\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\u6211\u5c31\u81ea\u6740\uff01 exit(1); // \u7a0b\u5e8f\u4e0d\u4f1a\u6267\u884c\u5230\u6b64 } return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7f3a\u70b9\uff1a exit \u4f1a\u76f4\u63a5\u9000\u51fa\u6574\u4e2a\u8fdb\u7a0b\uff01\u6ca1\u6709\u4efb\u4f55\u7ed9\u8c03\u7528\u8005\u633d\u56de\u7684\u673a\u4f1a\uff0c\u56e0\u6b64\u53ea\u80fd\u7528\u4e8e\u201c\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u201d\u8fd9\u4e2a\u7c7b\u578b\u3002 \u4f18\u70b9\uff1a\u8c03\u7528\u8005\u65e0\u9700\u505a\u4efb\u4f55\u5224\u65ad\u5904\u7406\uff0c\u5199\u8d77\u6765\u5c31\u597d\u50cf\u88ab\u8c03\u7528\u51fd\u6570\u201c\u603b\u662f\u6210\u529f\u201d\u4e00\u6837\uff0c\u603b\u80fd\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u4e3a\u5982\u679c\u88ab\u8c03\u7528\u8005\u5931\u8d25\u7684\u8bdd\uff0c\u4ed6\u4f1a\u8c03\u7528 exit \u81ea\u6740\uff0c\u5c31\u4e0d\u4f1a\u8fd4\u56de\u5230\u8c03\u7528\u8005\u4e2d\u4e86\u3002 \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6\u53d8\u6210\u201c\u7801\u7801\u7684\u8424\u706b\u866b\u201d\u4e86\u3002","title":"\u4e0d\u53ef\u6062\u590d\u9519\u8bef"},{"location":"error_code/#_3","text":"\u6709\u65f6\u5019\uff0c\u6211\u4eec\u5bf9\u4e8e\u90e8\u5206\u9519\u8bef\uff0c\u662f\u6709\u633d\u56de\u673a\u4f1a\u7684\uff0c\u4e0d\u5e0c\u671b\u56e0\u4e3a\u4e00\u70b9\u53ef\u4ee5\u4fee\u590d\u7684\u5c0f\u9519\u8bef\u5c31\u628a\u6574\u4e2a\u7a0b\u5e8f\u7ec8\u6b62\u6389\u3002 \u8981\u4e0d\u8981\u633d\u56de\u5e94\u8be5\u7531\u8c03\u7528\u8005\u7684\u5177\u4f53\u4e1a\u52a1\u51b3\u5b9a\uff0c\u800c\u5c01\u88c5\u826f\u597d\u7684 API\uff08 open \uff09\u5e94\u8be5\u5fe0\u5b9e\u5730\u628a\u9519\u8bef\u62a5\u544a\u7ed9\u8c03\u7528\u8005\uff08 main \uff09\u3002 \u8ba9\u8c03\u7528\u8005\u6765\u51b3\u5b9a\u8981\u6740\u4e86\u8fd8\u662f\u62a2\u6551\uff0c\u800c\u4e0d\u662f\u81ea\u4f5c\u4e3b\u5f20\u5730\u76f4\u63a5\u81ea\u6740\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c31\u8fd4\u56de -1 \u8fd9\u4e2a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d\u4ee3\u66ff return -1; } return get_handle(path); } int main() { int file = open(\"file.txt\"); if (file == -1) { // \u7f3a\u70b9\u662f main \u91cc\u9762\u5fc5\u987b\u5224\u65ad\u8fd4\u56de\u503c\u662f\u5426\u4e3a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c1d\u8bd5\u8fdb\u884c\u5904\u7406 create_empty_file(\"file.txt\"); // \u91cd\u65b0\u5c1d\u8bd5\u6253\u5f00 file = open(\"file.txt\"); if (file == -1) { // \u5982\u679c\u8fd8\u662f\u51fa\u9519\uff0c\u90a3\u5c31\u6ca1\u6551\u4e86 exit(-1); // \u76f4\u63a5\u81ea\u6740 } } char buf[64]; read(file, buf, sizeof buf); ... }","title":"\u53ef\u6062\u590d\u9519\u8bef"},{"location":"error_code/#_4","text":"","title":"\u6211\u8be5\u5982\u4f55\u6289\u62e9"},{"location":"error_code/#_5","text":"main \u662f\u8c03\u7528\u8005\uff0c open \u662f\u88ab\u8c03\u7528\u8005\u3002 \u88ab\u8c03\u7528\u8005\u51fd\u6570\u53ef\u80fd\u4ea7\u751f\u9519\u8bef\uff0c\u4e5f\u53ef\u80fd\u6b63\u5e38\u6267\u884c\u3002","title":"\u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005"},{"location":"error_code/#_6","text":"","title":"\u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01"},{"location":"error_code/#_7","text":"","title":"\u5f02\u5e38"},{"location":"error_code/#_8","text":"","title":"\u9519\u8bef\u7801"},{"location":"error_code/#stderror_code","text":"","title":"std::error_code"},{"location":"error_code/#stdexpected","text":"\u4e5f\u53ef\u4ee5 boost::expected \u66ff\u4ee3\u3002","title":"std::expected"},{"location":"functions/","text":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u81ea\u5b9a\u4e49\u51fd\u6570 \u8c03\u7528\u51fd\u6570 \u51fd\u6570\u7684\u8fd4\u56de\u503c \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570 \u81ea\u5b9a\u4e49\u51fd\u6570 int square(int x) { } \u8c03\u7528\u51fd\u6570 TODO: println \u53c2\u6570\u6f14\u793a \u51fd\u6570\u7684\u8fd4\u56de\u503c \u51fd\u6570\u53ef\u4ee5\u6ca1\u6709\u8fd4\u56de\u503c\uff0c\u53ea\u9700\u8981\u58f0\u660e\u51fd\u6570\u65f6\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a void \u5373\u53ef\uff0c\u8c03\u7528\u8fd9\u6837\u7684\u51fd\u6570\u53ea\u662f\u4e3a\u4e86\u4ed6\u7684\u526f\u4f5c\u7528\uff08\u5982\u4fee\u6539\u5168\u5c40\u53d8\u91cf\uff0c\u8f93\u51fa\u6587\u672c\u5230\u63a7\u5236\u53f0\uff0c\u4fee\u6539\u5f15\u7528\u53c2\u6570\u7b49\uff09\u3002 void compute() { return; } \u5bf9\u4e8e\u6ca1\u6709\u8fd4\u56de\u503c\uff08\u8fd4\u56de\u7c7b\u578b\u4e3a void \uff09\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7701\u7565 return \u4e0d\u5199\u3002 void compute() { // \u6ca1\u95ee\u9898 } \u5bf9\u4e8e\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6f0f\u5199\uff0c\u4f1a\u51fa\u73b0\u53ef\u6015\u7684\u672a\u5b9a\u4e49\u884c\u4e3a (undefined behaviour)\u3002\u7f16\u8bd1\u5668\u4e0d\u4e00\u5b9a\u4f1a\u62a5\u9519\uff0c\u800c\u662f\u5230\u8fd0\u884c\u65f6\u624d\u51fa\u73b0\u5d29\u6e83\u7b49\u73b0\u8c61\u3002\u5efa\u8bae GCC \u7528\u6237\u5f00\u542f -Werror=return-type \u8ba9\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u65f6\u5c31\u68c0\u6d4b\u6b64\u7c7b\u9519\u8bef\uff0cMSVC \u5219\u662f\u5f00\u542f /we4716 \u3002\u66f4\u591a\u672a\u5b9a\u4e49\u884c\u4e3a\u53ef\u4ee5\u770b\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5217\u8868 \u7ae0\u8282\u3002 \u4f46\u6709\u4e24\u4e2a\u4f8b\u5916\uff1a1. main \u51fd\u6570\u662f\u7279\u6b8a\u7684\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u4f1a\u81ea\u52a8\u5e2e\u4f60 return 0; \u30022. \u5177\u6709 co_return \u6216 co_await \u7684\u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\u3002 \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 TODO\uff1a\u548c Python\u3001Java \u5bf9\u6bd4 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 TODO\uff1a\u66f4\u591a\u4ecb\u7ecd\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570 TODO","title":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5)"},{"location":"functions/#_1","text":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u81ea\u5b9a\u4e49\u51fd\u6570 \u8c03\u7528\u51fd\u6570 \u51fd\u6570\u7684\u8fd4\u56de\u503c \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570","title":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5)"},{"location":"functions/#_2","text":"int square(int x) { }","title":"\u81ea\u5b9a\u4e49\u51fd\u6570"},{"location":"functions/#_3","text":"TODO: println \u53c2\u6570\u6f14\u793a","title":"\u8c03\u7528\u51fd\u6570"},{"location":"functions/#_4","text":"\u51fd\u6570\u53ef\u4ee5\u6ca1\u6709\u8fd4\u56de\u503c\uff0c\u53ea\u9700\u8981\u58f0\u660e\u51fd\u6570\u65f6\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a void \u5373\u53ef\uff0c\u8c03\u7528\u8fd9\u6837\u7684\u51fd\u6570\u53ea\u662f\u4e3a\u4e86\u4ed6\u7684\u526f\u4f5c\u7528\uff08\u5982\u4fee\u6539\u5168\u5c40\u53d8\u91cf\uff0c\u8f93\u51fa\u6587\u672c\u5230\u63a7\u5236\u53f0\uff0c\u4fee\u6539\u5f15\u7528\u53c2\u6570\u7b49\uff09\u3002 void compute() { return; } \u5bf9\u4e8e\u6ca1\u6709\u8fd4\u56de\u503c\uff08\u8fd4\u56de\u7c7b\u578b\u4e3a void \uff09\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7701\u7565 return \u4e0d\u5199\u3002 void compute() { // \u6ca1\u95ee\u9898 } \u5bf9\u4e8e\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6f0f\u5199\uff0c\u4f1a\u51fa\u73b0\u53ef\u6015\u7684\u672a\u5b9a\u4e49\u884c\u4e3a (undefined behaviour)\u3002\u7f16\u8bd1\u5668\u4e0d\u4e00\u5b9a\u4f1a\u62a5\u9519\uff0c\u800c\u662f\u5230\u8fd0\u884c\u65f6\u624d\u51fa\u73b0\u5d29\u6e83\u7b49\u73b0\u8c61\u3002\u5efa\u8bae GCC \u7528\u6237\u5f00\u542f -Werror=return-type \u8ba9\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u65f6\u5c31\u68c0\u6d4b\u6b64\u7c7b\u9519\u8bef\uff0cMSVC \u5219\u662f\u5f00\u542f /we4716 \u3002\u66f4\u591a\u672a\u5b9a\u4e49\u884c\u4e3a\u53ef\u4ee5\u770b\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5217\u8868 \u7ae0\u8282\u3002 \u4f46\u6709\u4e24\u4e2a\u4f8b\u5916\uff1a1. main \u51fd\u6570\u662f\u7279\u6b8a\u7684\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u4f1a\u81ea\u52a8\u5e2e\u4f60 return 0; \u30022. \u5177\u6709 co_return \u6216 co_await \u7684\u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\u3002","title":"\u51fd\u6570\u7684\u8fd4\u56de\u503c"},{"location":"functions/#_5","text":"","title":"\u63a5\u4f4f\u8fd4\u56de\u503c"},{"location":"functions/#_6","text":"","title":"\u51fd\u6570\u7684\u53c2\u6570"},{"location":"functions/#vs","text":"","title":"\u5f62\u53c2 vs \u5b9e\u53c2"},{"location":"functions/#vs_1","text":"TODO\uff1a\u548c Python\u3001Java \u5bf9\u6bd4","title":"\u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2"},{"location":"functions/#c","text":"","title":"C \u98ce\u683c\u53d8\u957f\u53c2\u6570"},{"location":"functions/#_7","text":"TODO\uff1a\u66f4\u591a\u4ecb\u7ecd\u51fd\u6570","title":"\u6a21\u677f\u51fd\u6570"},{"location":"functions/#main","text":"TODO","title":"main \u51fd\u6570\u7684\u53c2\u6570"},{"location":"hello_world/","text":"\u4f60\u597d\uff0c\u4e16\u754c \u4f60\u597d\uff0c\u4e16\u754c \u4ec0\u4e48\u662f\u51fd\u6570 \u4ece main \u51fd\u6570\u8bf4\u8d77 main \u51fd\u6570\u7684\u8fd4\u56de\u503c \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f \u6253\u5370\u4e00\u4e9b\u4fe1\u606f \u6ce8\u91ca \u4ec0\u4e48\u662f\u51fd\u6570 \u51fd\u6570: \u4e00\u6bb5\u7528 {} \u5305\u88f9\u7684\u4ee3\u7801\u5757\uff0c\u6709\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u540d\u5b57\u505a\u6807\u8bc6\u3002\u51fd\u6570\u53ef\u4ee5\u88ab\u5176\u4ed6\u51fd\u6570\u8c03\u7528\u3002\u51fd\u6570\u53ef\u4ee5\u6709\u8fd4\u56de\u503c\u548c\u53c2\u6570\u3002\u51fd\u6570\u7684 {} \u4ee3\u7801\u5757\u5185\u7684\u7a0b\u5e8f\u4ee3\u7801\uff0c\u6bcf\u6b21\u8be5\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u90fd\u4f1a\u6267\u884c\u3002 int compute() { return 42; } \u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c compute \u5c31\u662f\u51fd\u6570\u7684\u540d\u5b57\uff0c int \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u2014\u2014\u6574\u6570\u3002 \u4e43\u53d6\u6574\u6570\u4e4b\u82f1\u6587\u201cinteger\u201d\u7684\u201cint\u201d\u800c\u5f97\u540d\uff08\u6a21\u4eff\u4faf\u6377\u8001\u5e08\u8bf4\u8bdd\uff09 \u800c {} \u5305\u88f9\u7684\u662f\u51fd\u6570\u4f53\uff0c\u662f\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u4f1a\u6267\u884c\u7684\u4ee3\u7801\u3002 \u6b64\u5904 return 42 \u5c31\u662f\u51fd\u6570\u4f53\u5185\u7684\u552f\u4e00\u4e00\u6761\u8bed\u53e5\uff0c\u8868\u793a\u51fd\u6570\u7acb\u5373\u6267\u884c\u5b8c\u6bd5\uff0c\u8fd4\u56de 42\u3002 \u8fd4\u56de\u503c: \u5f53\u4e00\u4e2a\u51fd\u6570\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f1a\u5411\u8c03\u7528\u8be5\u51fd\u6570\u7684\u8c03\u7528\u8005\u8fd4\u56de\u4e00\u4e2a\u503c\uff0c\u8fd9\u4e2a\u503c\u5c31\u662f return \u540e\u9762\u7684\u8868\u8fbe\u5f0f\u7684\u503c\u3002\u8fd4\u56de\u503c\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u7c7b\u578b\uff0c\u6b64\u5904 compute \u7684\u8fd4\u56de\u7c7b\u578b\u662f int \uff0c\u4e5f\u5c31\u662f\u8bf4 compute \u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u3002 \u5173\u4e8e\u51fd\u6570\u7684\u53c2\u6570\uff0c\u6211\u4eec\u7a0d\u540e\u518d\u505a\u8bf4\u660e\u3002 \u4ece main \u51fd\u6570\u8bf4\u8d77 C++ \u7a0b\u5e8f\u901a\u5e38\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u7ec4\u6210\uff0c\u5176\u4e2d\u5fc5\u987b\u6709\u4e00\u4e2a\u540d\u4e3a main \u7684\u51fd\u6570\u4f5c\u4e3a\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002 main \u51fd\u6570\u7684\u5b9a\u4e49\u5982\u4e0b\uff1a int main() { } \u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u8c03\u7528 main \u51fd\u6570\u3002 \u4e25\u683c\u6765\u8bf4\uff0c\u662f C++ \u8fd0\u884c\u65f6\u8c03\u7528\u4e86 main \u51fd\u6570\uff0c\u4f46\u76ee\u524d\u5148\u7406\u89e3\u4e3a\u201c\u64cd\u4f5c\u7cfb\u7edf\u8c03\u7528\u4e86 main \u51fd\u6570\u201d\u4e5f\u65e0\u59a8\u3002 \u8981\u628a\u7a0b\u5e8f\u53d1\u5c55\u58ee\u5927\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba9 main \u51fd\u6570\u7ee7\u7eed\u8c03\u7528\u5176\u4ed6\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u5728 main \u51fd\u6570\u4e2d\u7f16\u5199\u6574\u4e2a\u7a0b\u5e8f\u7684\u903b\u8f91\uff08\u4e0d\u63a8\u8350\uff09\u3002 \u56e0\u6b64\uff0c main \u53ef\u4ee5\u88ab\u770b\u4f5c\u662f\u201c\u5b87\u5b99\u5927\u7206\u70b8\u201d\u3002 main \u51fd\u6570\u7684\u8fd4\u56de\u503c int main() { return 0; } return \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\uff0cmain \u51fd\u6570\u8fd4\u56de\uff0c\u5373\u610f\u5473\u7740\u7a0b\u5e8f\u7684\u7ed3\u675f\u3002 main \u51fd\u6570\u603b\u662f\u8fd4\u56de\u4e00\u4e2a\u6574\u6570 ( int \u7c7b\u578b)\uff0c\u7528\u8fd9\u4e2a\u6574\u6570\u5411\u64cd\u4f5c\u7cfb\u7edf\u8868\u793a\u7a0b\u5e8f\u9000\u51fa\u7684\u539f\u56e0\u3002 \u5982\u679c\u7a0b\u5e8f\u6b63\u5e38\u6267\u884c\u5b8c\u6bd5\uff0c\u6b63\u5e38\u7ed3\u675f\u9000\u51fa\uff0c\u90a3\u5c31\u8bf7\u8fd4\u56de 0\u3002 \u901a\u5e38\u6765\u8bf4\u6709\u8fd4\u56de\u7c7b\u578b\u7684\u51fd\u6570\u90fd\u9700\u8981\u5728\u6240\u6709\u5206\u652f\u90fd\u6709 return \u8bed\u53e5\uff0c\u4f46\u6709\u8da3\u7684\u662f\uff0cC++ \u6807\u51c6\u5bf9 main \u51fd\u6570\u505a\u4e86\u7279\u6b8a\u7684\u201c\u5bbd\u5927\u5904\u7406\u201d\uff1a\u5728\u63a7\u5236\u6d41\u8fbe\u5230 main \u51fd\u6570\u7684\u7ed3\u5c3e\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u9047\u5230 return \u8bed\u53e5\uff0c\u5219\u7b49\u4ef7\u4e8e\u6267\u884c return 0; \u3002\u6240\u4ee5\u5bf9\u4e8e\u4f60\u672c\u6765\u5c31\u6253\u7b97\u8fd4\u56de 0 \u7684\u60c5\u51b5\uff0c\u4e5f\u53ef\u4ee5\u5077\u61d2\u4e0d\u5199 return \u8bed\u53e5\uff0c\u7f16\u8bd1\u5668\u81ea\u52a8\u4f1a\u5e2e\u4f60\u52a0\u4e0a\u3002\u4ee5\u53ca\uff0cmain \u51fd\u6570\u5fc5\u987b\u8fd4\u56de int \u7c7b\u578b\uff0c\u4e0d\u80fd\u8fd4\u56de void \u7c7b\u578b\u3002 \u8fd4\u56de\u4e00\u4e2a\u4e0d\u4e3a 0 \u7684\u6574\u6570\u53ef\u4ee5\u8868\u793a\u7a0b\u5e8f\u51fa\u73b0\u4e86\u5f02\u5e38\uff0c\u662f\u56e0\u4e3a\u51fa\u9519\u4e86\u624d\u9000\u51fa\u7684\uff0c\u503c\u7684\u591a\u5c11\u53ef\u4ee5\u7528\u4e8e\u8868\u660e\u9519\u8bef\u7684\u5177\u4f53\u539f\u56e0\u3002 \u64cd\u4f5c\u7cfb\u7edf\uff1a\u6211\u8c03\u7528\u4e86\u4f60\u8fd9\u4e2a\u7a0b\u5e8f\u7684 main \u51fd\u6570\uff0c\u6211\u597d\u5947\u7a0b\u5e8f\u662f\u5426\u6b63\u786e\u6267\u884c\u4e86\uff1f\u8ba9\u6211\u4eec\u7ea6\u5b9a\u597d\uff1a\u5982\u679c\u4f60\u8fd0\u8f6c\u6b63\u5e38\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de0\u8868\u793a\u6210\u529f\u54e6\uff01\u5982\u679c\u6709\u9519\u8bef\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de\u4e00\u4e2a\u9519\u8bef\u4ee3\u7801\uff0c\u6bd4\u5982\u8fd4\u56de1\u8868\u793a\u65e0\u6743\u9650\uff0c2\u8868\u793a\u627e\u4e0d\u5230\u6587\u4ef6\u2026\u2026\u4e4b\u7c7b\u7684\u3002\u5f53\u7136\uff0c\u9519\u8bef\u4ee3\u7801\u90fd\u662f\u4e0d\u4e3a0\u7684\u3002 \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f TODO: \u4ecb\u7ecd\u63a7\u5236\u53f0 \u6253\u5370\u4e00\u4e9b\u4fe1\u606f int main() { std::println(\"Hello, World!\"); } \u4ee5\u4e0a\u4ee3\u7801\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa Hello, World! \u3002 \u6ce8\u91ca int main() { // \u5c0f\u5f6d\u8001\u5e08\uff0c\u8bf7\u4f60\u5728\u8fd9\u91cc\u63d2\u5165\u7a0b\u5e8f\u7684\u903b\u8f91\u54e6\uff01 } \u8fd9\u91cc\u7684 // \u662f\u6ce8\u91ca\uff0c\u6ce8\u91ca\u4f1a\u88ab\u7f16\u8bd1\u5668\u5ffd\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u7a0b\u5e8f\u6e90\u7801\u4e2d\u690d\u5165\u63cf\u8ff0\u6027\u7684\u6587\u672c\u3002\u6709\u65f6\u4e5f\u4f1a\u7528\u4e8e\u591a\u4eba\u534f\u4f5c\u9879\u76ee\u4e2d\u7a0b\u5e8f\u5458\u4e4b\u95f4\u4e92\u76f8\u6c9f\u901a\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u8bf6\u563f\u4f60\u770b\u4e0d\u89c1\u6211 } \u5728\u7f16\u8bd1\u5668\u770b\u6765\u5c31\u53ea\u662f\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); } (* \u7f16\u8bd1\u5668\u8138\u7ea2\u4e2d* ) C++ \u652f\u6301\u884c\u6ce8\u91ca // xx \u548c\u5757\u6ce8\u91ca /* xx */ \u4e24\u79cd\u8bed\u6cd5\u3002 int main() { // \u6211\u662f\u884c\u6ce8\u91ca /* \u6211\u662f\u5757\u6ce8\u91ca */ /* \u5757\u6ce8\u91ca \u53ef\u4ee5 \u6709 \u5f88\u591a\u884c */ std::println(/* \u5757\u6ce8\u91ca\u4e5f\u53ef\u4ee5\u5939\u5728\u4ee3\u7801\u4e2d\u95f4 */\"\u4f60\u597d\"); std::println(\"\u4e16\u754c\"); // \u884c\u6ce8\u91ca\u53ea\u80fd\u8ffd\u52a0\u5728\u4e00\u884c\u7684\u672b\u5c3e std::println(\"\u65e9\u5b89\"); } \u5728\u6211\u4eec\u4ee5\u540e\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\uff0c\u90fd\u4f1a\u50cf\u8fd9\u6837\u6ce8\u91ca\u8bf4\u660e\uff0c\u5145\u5f53 \u5c31\u5730\u8bb2\u89e3\u5458 \u7684\u6548\u679c\u3002\u53bb\u9664\u8fd9\u4e9b\u6ce8\u91ca\u5e76\u4e0d\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u5e38\u8fd0\u884c\uff0c\u6dfb\u52a0\u6587\u5b57\u6ce8\u91ca\u53ea\u662f\u5c0f\u5f6d\u8001\u5e08\u4e3a\u4e86\u63d0\u9192\u4f60\u6bcf\u4e00\u884c\u7684\u4ee3\u7801\u4f5c\u7528\u3002","title":"\u4f60\u597d\uff0c\u4e16\u754c"},{"location":"hello_world/#_1","text":"\u4f60\u597d\uff0c\u4e16\u754c \u4ec0\u4e48\u662f\u51fd\u6570 \u4ece main \u51fd\u6570\u8bf4\u8d77 main \u51fd\u6570\u7684\u8fd4\u56de\u503c \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f \u6253\u5370\u4e00\u4e9b\u4fe1\u606f \u6ce8\u91ca","title":"\u4f60\u597d\uff0c\u4e16\u754c"},{"location":"hello_world/#_2","text":"\u51fd\u6570: \u4e00\u6bb5\u7528 {} \u5305\u88f9\u7684\u4ee3\u7801\u5757\uff0c\u6709\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u540d\u5b57\u505a\u6807\u8bc6\u3002\u51fd\u6570\u53ef\u4ee5\u88ab\u5176\u4ed6\u51fd\u6570\u8c03\u7528\u3002\u51fd\u6570\u53ef\u4ee5\u6709\u8fd4\u56de\u503c\u548c\u53c2\u6570\u3002\u51fd\u6570\u7684 {} \u4ee3\u7801\u5757\u5185\u7684\u7a0b\u5e8f\u4ee3\u7801\uff0c\u6bcf\u6b21\u8be5\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u90fd\u4f1a\u6267\u884c\u3002 int compute() { return 42; } \u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c compute \u5c31\u662f\u51fd\u6570\u7684\u540d\u5b57\uff0c int \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u2014\u2014\u6574\u6570\u3002 \u4e43\u53d6\u6574\u6570\u4e4b\u82f1\u6587\u201cinteger\u201d\u7684\u201cint\u201d\u800c\u5f97\u540d\uff08\u6a21\u4eff\u4faf\u6377\u8001\u5e08\u8bf4\u8bdd\uff09 \u800c {} \u5305\u88f9\u7684\u662f\u51fd\u6570\u4f53\uff0c\u662f\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u4f1a\u6267\u884c\u7684\u4ee3\u7801\u3002 \u6b64\u5904 return 42 \u5c31\u662f\u51fd\u6570\u4f53\u5185\u7684\u552f\u4e00\u4e00\u6761\u8bed\u53e5\uff0c\u8868\u793a\u51fd\u6570\u7acb\u5373\u6267\u884c\u5b8c\u6bd5\uff0c\u8fd4\u56de 42\u3002 \u8fd4\u56de\u503c: \u5f53\u4e00\u4e2a\u51fd\u6570\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f1a\u5411\u8c03\u7528\u8be5\u51fd\u6570\u7684\u8c03\u7528\u8005\u8fd4\u56de\u4e00\u4e2a\u503c\uff0c\u8fd9\u4e2a\u503c\u5c31\u662f return \u540e\u9762\u7684\u8868\u8fbe\u5f0f\u7684\u503c\u3002\u8fd4\u56de\u503c\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u7c7b\u578b\uff0c\u6b64\u5904 compute \u7684\u8fd4\u56de\u7c7b\u578b\u662f int \uff0c\u4e5f\u5c31\u662f\u8bf4 compute \u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u3002 \u5173\u4e8e\u51fd\u6570\u7684\u53c2\u6570\uff0c\u6211\u4eec\u7a0d\u540e\u518d\u505a\u8bf4\u660e\u3002","title":"\u4ec0\u4e48\u662f\u51fd\u6570"},{"location":"hello_world/#main","text":"C++ \u7a0b\u5e8f\u901a\u5e38\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u7ec4\u6210\uff0c\u5176\u4e2d\u5fc5\u987b\u6709\u4e00\u4e2a\u540d\u4e3a main \u7684\u51fd\u6570\u4f5c\u4e3a\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002 main \u51fd\u6570\u7684\u5b9a\u4e49\u5982\u4e0b\uff1a int main() { } \u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u8c03\u7528 main \u51fd\u6570\u3002 \u4e25\u683c\u6765\u8bf4\uff0c\u662f C++ \u8fd0\u884c\u65f6\u8c03\u7528\u4e86 main \u51fd\u6570\uff0c\u4f46\u76ee\u524d\u5148\u7406\u89e3\u4e3a\u201c\u64cd\u4f5c\u7cfb\u7edf\u8c03\u7528\u4e86 main \u51fd\u6570\u201d\u4e5f\u65e0\u59a8\u3002 \u8981\u628a\u7a0b\u5e8f\u53d1\u5c55\u58ee\u5927\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba9 main \u51fd\u6570\u7ee7\u7eed\u8c03\u7528\u5176\u4ed6\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u5728 main \u51fd\u6570\u4e2d\u7f16\u5199\u6574\u4e2a\u7a0b\u5e8f\u7684\u903b\u8f91\uff08\u4e0d\u63a8\u8350\uff09\u3002 \u56e0\u6b64\uff0c main \u53ef\u4ee5\u88ab\u770b\u4f5c\u662f\u201c\u5b87\u5b99\u5927\u7206\u70b8\u201d\u3002","title":"\u4ece main \u51fd\u6570\u8bf4\u8d77"},{"location":"hello_world/#main_1","text":"int main() { return 0; } return \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\uff0cmain \u51fd\u6570\u8fd4\u56de\uff0c\u5373\u610f\u5473\u7740\u7a0b\u5e8f\u7684\u7ed3\u675f\u3002 main \u51fd\u6570\u603b\u662f\u8fd4\u56de\u4e00\u4e2a\u6574\u6570 ( int \u7c7b\u578b)\uff0c\u7528\u8fd9\u4e2a\u6574\u6570\u5411\u64cd\u4f5c\u7cfb\u7edf\u8868\u793a\u7a0b\u5e8f\u9000\u51fa\u7684\u539f\u56e0\u3002 \u5982\u679c\u7a0b\u5e8f\u6b63\u5e38\u6267\u884c\u5b8c\u6bd5\uff0c\u6b63\u5e38\u7ed3\u675f\u9000\u51fa\uff0c\u90a3\u5c31\u8bf7\u8fd4\u56de 0\u3002 \u901a\u5e38\u6765\u8bf4\u6709\u8fd4\u56de\u7c7b\u578b\u7684\u51fd\u6570\u90fd\u9700\u8981\u5728\u6240\u6709\u5206\u652f\u90fd\u6709 return \u8bed\u53e5\uff0c\u4f46\u6709\u8da3\u7684\u662f\uff0cC++ \u6807\u51c6\u5bf9 main \u51fd\u6570\u505a\u4e86\u7279\u6b8a\u7684\u201c\u5bbd\u5927\u5904\u7406\u201d\uff1a\u5728\u63a7\u5236\u6d41\u8fbe\u5230 main \u51fd\u6570\u7684\u7ed3\u5c3e\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u9047\u5230 return \u8bed\u53e5\uff0c\u5219\u7b49\u4ef7\u4e8e\u6267\u884c return 0; \u3002\u6240\u4ee5\u5bf9\u4e8e\u4f60\u672c\u6765\u5c31\u6253\u7b97\u8fd4\u56de 0 \u7684\u60c5\u51b5\uff0c\u4e5f\u53ef\u4ee5\u5077\u61d2\u4e0d\u5199 return \u8bed\u53e5\uff0c\u7f16\u8bd1\u5668\u81ea\u52a8\u4f1a\u5e2e\u4f60\u52a0\u4e0a\u3002\u4ee5\u53ca\uff0cmain \u51fd\u6570\u5fc5\u987b\u8fd4\u56de int \u7c7b\u578b\uff0c\u4e0d\u80fd\u8fd4\u56de void \u7c7b\u578b\u3002 \u8fd4\u56de\u4e00\u4e2a\u4e0d\u4e3a 0 \u7684\u6574\u6570\u53ef\u4ee5\u8868\u793a\u7a0b\u5e8f\u51fa\u73b0\u4e86\u5f02\u5e38\uff0c\u662f\u56e0\u4e3a\u51fa\u9519\u4e86\u624d\u9000\u51fa\u7684\uff0c\u503c\u7684\u591a\u5c11\u53ef\u4ee5\u7528\u4e8e\u8868\u660e\u9519\u8bef\u7684\u5177\u4f53\u539f\u56e0\u3002 \u64cd\u4f5c\u7cfb\u7edf\uff1a\u6211\u8c03\u7528\u4e86\u4f60\u8fd9\u4e2a\u7a0b\u5e8f\u7684 main \u51fd\u6570\uff0c\u6211\u597d\u5947\u7a0b\u5e8f\u662f\u5426\u6b63\u786e\u6267\u884c\u4e86\uff1f\u8ba9\u6211\u4eec\u7ea6\u5b9a\u597d\uff1a\u5982\u679c\u4f60\u8fd0\u8f6c\u6b63\u5e38\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de0\u8868\u793a\u6210\u529f\u54e6\uff01\u5982\u679c\u6709\u9519\u8bef\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de\u4e00\u4e2a\u9519\u8bef\u4ee3\u7801\uff0c\u6bd4\u5982\u8fd4\u56de1\u8868\u793a\u65e0\u6743\u9650\uff0c2\u8868\u793a\u627e\u4e0d\u5230\u6587\u4ef6\u2026\u2026\u4e4b\u7c7b\u7684\u3002\u5f53\u7136\uff0c\u9519\u8bef\u4ee3\u7801\u90fd\u662f\u4e0d\u4e3a0\u7684\u3002","title":"main \u51fd\u6570\u7684\u8fd4\u56de\u503c"},{"location":"hello_world/#_3","text":"TODO: \u4ecb\u7ecd\u63a7\u5236\u53f0","title":"\u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f"},{"location":"hello_world/#_4","text":"int main() { std::println(\"Hello, World!\"); } \u4ee5\u4e0a\u4ee3\u7801\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa Hello, World! \u3002","title":"\u6253\u5370\u4e00\u4e9b\u4fe1\u606f"},{"location":"hello_world/#_5","text":"int main() { // \u5c0f\u5f6d\u8001\u5e08\uff0c\u8bf7\u4f60\u5728\u8fd9\u91cc\u63d2\u5165\u7a0b\u5e8f\u7684\u903b\u8f91\u54e6\uff01 } \u8fd9\u91cc\u7684 // \u662f\u6ce8\u91ca\uff0c\u6ce8\u91ca\u4f1a\u88ab\u7f16\u8bd1\u5668\u5ffd\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u7a0b\u5e8f\u6e90\u7801\u4e2d\u690d\u5165\u63cf\u8ff0\u6027\u7684\u6587\u672c\u3002\u6709\u65f6\u4e5f\u4f1a\u7528\u4e8e\u591a\u4eba\u534f\u4f5c\u9879\u76ee\u4e2d\u7a0b\u5e8f\u5458\u4e4b\u95f4\u4e92\u76f8\u6c9f\u901a\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u8bf6\u563f\u4f60\u770b\u4e0d\u89c1\u6211 } \u5728\u7f16\u8bd1\u5668\u770b\u6765\u5c31\u53ea\u662f\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); } (* \u7f16\u8bd1\u5668\u8138\u7ea2\u4e2d* ) C++ \u652f\u6301\u884c\u6ce8\u91ca // xx \u548c\u5757\u6ce8\u91ca /* xx */ \u4e24\u79cd\u8bed\u6cd5\u3002 int main() { // \u6211\u662f\u884c\u6ce8\u91ca /* \u6211\u662f\u5757\u6ce8\u91ca */ /* \u5757\u6ce8\u91ca \u53ef\u4ee5 \u6709 \u5f88\u591a\u884c */ std::println(/* \u5757\u6ce8\u91ca\u4e5f\u53ef\u4ee5\u5939\u5728\u4ee3\u7801\u4e2d\u95f4 */\"\u4f60\u597d\"); std::println(\"\u4e16\u754c\"); // \u884c\u6ce8\u91ca\u53ea\u80fd\u8ffd\u52a0\u5728\u4e00\u884c\u7684\u672b\u5c3e std::println(\"\u65e9\u5b89\"); } \u5728\u6211\u4eec\u4ee5\u540e\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\uff0c\u90fd\u4f1a\u50cf\u8fd9\u6837\u6ce8\u91ca\u8bf4\u660e\uff0c\u5145\u5f53 \u5c31\u5730\u8bb2\u89e3\u5458 \u7684\u6548\u679c\u3002\u53bb\u9664\u8fd9\u4e9b\u6ce8\u91ca\u5e76\u4e0d\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u5e38\u8fd0\u884c\uff0c\u6dfb\u52a0\u6587\u5b57\u6ce8\u91ca\u53ea\u662f\u5c0f\u5f6d\u8001\u5e08\u4e3a\u4e86\u63d0\u9192\u4f60\u6bcf\u4e00\u884c\u7684\u4ee3\u7801\u4f5c\u7528\u3002","title":"\u6ce8\u91ca"},{"location":"interview/","text":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c \u6700\u8fd1\u597d\u50cf\u5f88\u6d41\u884c\u9762\u7ecf\u2026\u2026\u5c0f\u5f6d\u8001\u5e08\u4e5f\u6765\u5199\u4e00\u4e0b\u3002 \u6cfd\u68ee\u79d1\u5de5 (2021.12.07) \u5f20\u5265\u58eb\u5728taichi\u8bba\u575b\u91cc\u4e3b\u52a8\u627e\u4e0a\u6765\u8054\u7cfb\uff0c\u8868\u793a\u6211\u4eec\u5f88\u6b23\u8d4f\u4f60\u5728\u592a\u6781\u7684\u4f1f\u5927\u8d21\u732e\uff0c\u5e0c\u671b\u548c\u6211\u4eec\u6cfd\u68ee\u4e00\u8d77\u521b\u9020\u66f4\u597d\u7684\u65b0\u4ea7\u54c1(\u4ec0\u4e48\u6316\u5899\u89d2) \u5f20\u5265\u58eb\u5728\u5fae\u4fe1\u7535\u8bdd\u91cc\u5f00\u59cb\u8bed\u97f3\u9762\u8bd5\u4e86\uff0c\u4e0a\u6765\u5c31\u8981\u6c42\u5b9e\u73b0sqrt\u51fd\u6570(\u725b\u987f\u8fed\u4ee3\u6cd5\u5373\u53ef\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e0d\u5c0f\u5fc3\u5199\u9519\uff0c\u6709\u6b7b\u5faa\u73af\uff0c\u5f20\u5265\u58eb\u8868\u793a\u4e0d\u8981\u7d27\uff0c\u8fd9\u4e2a\u4f60\u80af\u5b9a\u73b0\u5b9e\u4e2d\u5f88\u5bb9\u6613\u8c03\u8bd5\u6539\u6b63\u7684\uff0c\u4e3b\u8981\u662f\u725b\u987f\u8fed\u4ee3\u9700\u8981\u5bfc\u6570\u7684\u89e3\u6790\u5f0f\uff0c\u5bb9\u6613\u5199\u9519\uff0cnaive\u7684\u521d\u5b66\u8005\u4e5f\u53ef\u4ee5\u9009\u62e9\u5199\u4e8c\u5206\u6cd5\uff0c\u4f59\u5207\u6cd5\u7b49) \u6709\u6ca1\u6709\u4e86\u89e3\u8fc7\u96f7\u795e3\u7684\u5feb\u901fsqrt\u51fd\u6570\uff1f(\u77e5\u9053\uff0c\u4f46\u597d\u50cf\u662f\u795e\u5947\u7684\u4e8c\u8fdb\u5236\u8fd0\u7b97\uff0c\u6ca1\u6709\u6df1\u5165\u4e86\u89e3\u8fc7\u4e3a\u4ec0\u4e48\u8fd9\u6837\u505a) \u77e5\u9053float\u7684\u5e03\u5c40\u5427(23\u4f4d\u5e95\u6570mantissa\uff0c8\u4f4d\u6307\u6570exponent\uff0c1\u4f4d\u7b26\u53f7sign) \u800c\u725b\u987f\u8fed\u4ee3\u6cd5\u9700\u8981\u8fd1\u4f3c\uff0csqrt\u6700\u597d\u7684\u8fd1\u4f3c\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u628aexponent\u4f4d\u9664\u4ee52\uff0c\u5bf9\u4e0d\u5bf9\uff1f(\u5c0f\u5f6d\u8001\u5e08\u604d\u7136\u5927\u609f\uff0c\u602a\u4e0d\u5f97\u9700\u8981\u53f3\u79fb1\u4f4d\uff0c\u539f\u6765\u662f\u8ba9exponent\u96642\uff0c\u96f7\u795e\u7684sqrt\u56e0\u4e3a\u6709\u826f\u597d\u7684\u8fd1\u4f3c\u521d\u503c\uff0c\u63a5\u4e0b\u6765\u5c31\u53ea\u9700\u8981\u4e00\u4e24\u6b65\u5c31\u80fd\u6536\u655b) \u63a5\u4e0b\u6765\u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u6211\u6709\u4ece 1 \u5230 100 \u8fd9 100 \u4e2a\u6570\uff0c\u7ec4\u6210\u8d85\u957f\u7684\u6570\u7ec4\uff0c\u968f\u673a\u6392\u5217\uff0c\u73b0\u5728\u8fd9\u91cc\u9762\u7f3a\u5c11\u4e86\u4e00\u4f4d(\u6bd4\u5982 1 2 3 4 5 7 8 9 10 \u5c31\u662f\u7f3a\u5c11\u4e86 6) \u73b0\u5728\uff0c\u6211\u4e00\u8fb9\u62a5\u6570\u4f60\u4e00\u8fb9\u64cd\u4f5c\uff0c\u6211\u62a5\u5b8c\u7684\u90a3\u4e00\u523b\uff0c\u4f60\u5fc5\u987b\u7acb\u5373\u544a\u8bc9\u6211\uff0c\u7f3a\u5931\u7684\u90a3\u4e00\u4e2a\u6570\u662f\u4ec0\u4e48\uff0c\u5e76\u4e14\u4e0d\u5141\u8bb8\u4f7f\u7528\u8bb0\u4e8b\u672c(\u4e5f\u5c31\u662f\u8981\u6c42\u5e38\u6570\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5f88\u7b80\u5355\uff0c\u4f60\u62a5\u7684\u540c\u65f6\u6211\u5f80\u4e00\u4e2a\u8ba1\u6570\u5668\u91cc\u7d2f\u52a0\u6c42\u548c\uff0c\u7136\u540e\u7b97\u51fa\u6765\u7684\u603b\u6c42\u548c\u548c 5050 \u76f8\u51cf\uff0c\u5f97\u5230\u7684\u5c31\u662f\u7f3a\u5931\u7684\u90a3\u4e2a\u6570\u4e86\uff0c\u6bd4\u5982 1+2+3+4+5+7+8+9+10 - 55 = -6\uff0c\u90a3\u4e48\u5c31\u77e5\u9053\u7f3a\u7684\u662f 6) \u5982\u679c\u6211\u662f\u7f3a\u4e86\u4e24\u4e2a\u6570\u5462\uff1f(\u90a3\u6211\u5f04\u4e24\u4e2a\u8ba1\u6570\u5668\uff0c\u4e00\u4e2a\u6c42\u548c\uff0c\u4e00\u4e2a\u6c42\u79ef\uff0c\u7136\u540e\u8054\u7acb\u4e8c\u5143\u4e8c\u6b21\u65b9\u7a0b) \u6211\u63d0\u4f9b\u4e00\u4e2a\u751f\u62100\u52301\u533a\u95f4\u5747\u5300\u968f\u673a\u6570\u7684\u51fd\u6570frand\uff0c\u5982\u679c\u6211\u6307\u5b9a\u4e00\u4e2a\u5206\u5e03\uff0c\u6bd4\u5982\u8981\u6c42\u9ad8\u65af\u5206\u5e03\uff0c\u5982\u4f55\u751f\u6210\u7b26\u5408\u8fd9\u4e2a\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff1f(frand\u662f\u5747\u5300\u968f\u673a\u6570\u51fd\u6570\uff0c\u8981\u6620\u5c04\u5230\u6307\u5b9a\u5bc6\u5ea6\u5206\u5e03\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u5148\u5bf9\u8be5\u6982\u7387\u5bc6\u5ea6\u51fd\u6570pdf\u6c42\u79ef\u5206\uff0c\u5f97\u5230\u7d2f\u79ef\u6982\u7387\u51fd\u6570cdf\uff0c\u6c42\u5176\u53cd\u51fd\u6570icdf\uff0c\u7136\u540e\u4f7f\u7528icdf(frand())\u5373\u4e3a\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff0c\u4f8b\u5982\u5bf9\u4e8e\u9ad8\u65af\u5206\u5e03\u6765\u8bf4\uff0c\u4ed6\u7684cdf\u51fd\u6570\u662ferf\uff0c\u4e5f\u5c31\u662ferfinv(frand())\u53ef\u4ee5\u751f\u6210\u9ad8\u65af\u5206\u5e03\u7684\u968f\u673a\u6570\uff09 \u5199\u4e00\u4e2a\u51fd\u6570\uff0c\u751f\u6210\u4e00\u4e2a\u5706\u5f62\u5185\u5747\u5300\u5206\u5e03\u7684\u70b9(\u521d\u5b66\u8005naive\u7684\u5199\u6cd5\uff1a\u5148\u751f\u6210\u4e00\u4e2a\u6b63\u65b9\u5f62\u7684\u5747\u5300\u5206\u5e03\u70b9\uff0c\u7136\u540e\u5224\u5b9a\u662f\u5426\u5728\u534a\u5f841\u5185\uff0c\u5982\u679c\u5728\u5219\u4fdd\u7559\uff0c\u5426\u5219\u91cd\u65b0\u751f\u6210\uff0c\u76f4\u5230\u751f\u6210\u5728\u534a\u5f84\u5185\uff1b\u5c0f\u5f6d\u8001\u5e08\u7684\u5199\u6cd5\uff1a\u9996\u5148\u6c42\u5706\u5f62\u5468\u957fS=2pir\u7684icdf\uff0c\u7136\u540eblahblah\uff0c\u6700\u7ec8\u662fr=icdf(frand())\uff0c\u7136\u540e\u518d\u968f\u673a\u4e00\u4e2atheta=frand()*2pi\uff0cx=rcostheta\uff0cy=rsintheta) \u5047\u5982\u6211\u6307\u5b9a\u7684\u51fd\u6570\u4e0d\u662f\u4e00\u4e2a\u89e3\u6790\u5f0f\uff0c\u800c\u662f\u4e00\u4e2a\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u600e\u4e48\u751f\u6210\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\uff1f(\u9996\u5148\u6c42\u8be5\u5bc6\u5ea6\u6570\u7ec4\u7684\u524d\u7f00\u548cprefix sum\uff0c\u7136\u540er=frand()\uff0c\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e0b\u6807\u4f4d\u7f6e\uff0c\u8be5\u4e0b\u6807\u5373\u4e3a\u8981\u751f\u6210\u7684\u968f\u673a\u6570\uff0c\u5982\u679c\u6709\u4e00\u4e2a\u503c\u5217\u8868\uff0c\u5219\u7528\u4e0b\u6807\u8bbf\u95ee\u8fd9\u4e2a\u503c\u5217\u8868\uff0c\u5982\u679c\u9700\u8981\u8fde\u7eed\u53d8\u5316\uff0c\u53ef\u4ee5\u5728\u7b2c\u4e00\u4e2a\u5927\u4e8e\u7b49\u4e8er\u548c\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e24\u4e2a\u5143\u7d20\u4e4b\u95f4\u6309r\u591a\u51fa\u7684\u4f59\u6570\u63d2\u503c) \u53ef\u662f\u904d\u5386\u53bb\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4f4d\u7f6e\u53ef\u80fd\u4f1a\u5f88\u6162\uff0c\u600e\u4e48\u52a0\u901f\uff1f(\u4e8c\u5206\u6cd5\u641c\u7d22\u8be5\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u53ef\u4ee5\u7528\u6807\u51c6\u5e93\u7684lower_bound) \u4e8b\u540e \u540e\u6765\u5c0f\u5f6d\u8001\u5e08\u5728\u804c\u671f\u95f4\uff0c\u5f20\u5265\u58eb\u4e00\u987f\u5439\u6367\uff1a\u4f60\u662f\u6211\u4eec\u8fd9\u91cc\u552f\u4e00\u4e00\u4e2a\u901a\u8fc7\u7845\u8c37\u7ea7\u4eba\u624d\u6d4b\u8bd5\u7684\u5458\u5de5\uff0c\u4e00\u89c1\u5230\u65b0\u5458\u5de5\u5c31\u5439\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u770b\u770b\u4eba\u5bb6\u5c0f\u5f6d\u8001\u5e08\u3002 \u5f20\u5265\u58eb\u8fd8\u753b\u51fa\u4e86\u671f\u6743\u5927\u997c\uff0c\u8bb2\u4e86\u4e00\u7cfb\u5217\u6211\u542c\u4e0d\u61c2\u7684\u865a\u62df\u671f\u6743\u6982\u5ff5\u91d1\u6eb6\u672f\u8bed\u540e\uff0c\u603b\u4e4b\u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\u9f13\u52b1\u5c0f\u5f6d\u8001\u5e08\u594b\u6597\uff0c\u594b\u6597\u7684\u516c\u53f8\u80a1\u4ef7\u6da8\u4e86\u5c31\u80fd\u5206\u7ea2\uff0c\u4f46\u76f4\u5230\u6700\u540e\u90fd\u6ca1\u6709\u5151\u73b0\uff0c\u800c\u4e14\u636e\u4e86\u89e3\u4e0a\u5e02\u516c\u53f8\u624d\u6709\u671f\u6743\u2026\u2026 \u5c0f\u5f6d\u8001\u5e08\u770b\u5230\u5f20\u5265\u58eb\u8fd9\u4e48\u91cd\u7528\uff0c\u4ee5\u4e3a\u6bd5\u4e1a\u4ee5\u540e\u80af\u5b9a\u7ed9\u8f6c\u6b63\u4e86\uff0c\u6240\u4ee5\u5c31\u6ca1\u6709\u8003\u7814\uff0c\u6ca1\u6709\u53bb\u770b\u6821\u62db\uff0c\u4e5f\u6ca1\u6709\u63a5\u53d7\u5b66\u6821\u7684\u5bf9\u63a5\uff0c\u5fd8\u6211\u5730\u4f3a\u5019zeno\u5de5\u4f5c\uff0c\u6253\u7b97\u4e00\u6bd5\u4e1a\u5c31\u76f4\u63a5\u53bb\u6df1\u5733\u4f3a\u5019\u5f20\u5265\u58eb\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 zeno \u7684\u5de5\u4f5c\u57fa\u672c\u5b8c\u6210\u4e86\uff0c\u627e\u4e0d\u5230\u6709\u4ec0\u4e48\u9700\u8981\u505a\u7684\uff0c\u5f20\u5265\u58eb\u7a81\u7136\u5f00\u59cb\u53cd\u590d\u7c97\u9119\u8bed\u8a00\u7f9e\u8fb1\u5c0f\u5f6d\u8001\u5e08\uff0cpua\u5c0f\u5f6d\u8001\u5e08\uff0c\u66f0\u201c\u4f60\u662f\u7a0b\u5e8f\u5458\u9493\u4e1d\u601d\u7ef4\u201d\u201c\u6839\u672c\u4e0d\u61c2\u6211\u4eec\u7684\u5b9e\u9645\u9700\u6c42\u201d\u201c\u4f60\u4eec\u9493\u4e1d\u7a0b\u5e8f\u5458\u662f\u6700\u4e0d\u61c2\u7f8e\u672f\u7d20\u517b\u7684\u201d\uff0c\u770b\u5728\u5265\u58eb\u8fd8\u5728\u53d1\u5de5\u8d44\u7684\u4efd\u4e0a\uff0c\u5c31\u6ca1\u6709\u7406\u5b83\u3002 \u5c0f\u5f6d\u8001\u5e08\u7ec8\u4e8e\u6bd5\u4e1a\u4e86\uff0c\u8868\u793a\u53ef\u4ee5\u8f6c\u6b63\uff0c\u8fd9\u65f6\u5f20\u5265\u58eb\u5374\u51fa\u5c14\u53cd\u5c14\uff0c\u5404\u79cd\u63a8\u8131\uff0c\u66f0\u201c\u8d44\u91d1\u56f0\u96be\u201d\u201c\u8bf7\u4e0d\u52a8\u5c0f\u5f6d\u8001\u5e08\u201d\u201c\u7b49\u62119\u6708\u62c9\u5230\u6295\u8d44\u597d\u4e0d\u597d\u201d\uff0c\u7136\u800c\u81f3\u4eca\u6ca1\u6709\u53cd\u5e94\uff0c\u8f6c\u5934\u5c31\u770b\u5230\u670b\u53cb\u5708\u5728\u53d1\u5e03\u5916\u5305jd\u3002 \u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u201c\u54c0\u6c42\u201d\u5f20\u5265\u58eb\u201c\u5f00\u773c\u201d\uff0c\u5f20\u5265\u58eb\u53cd\u590d\u63a8\u8131\u540e\uff0c\u7ec8\u4e8e\u8868\u793a\uff1a\u770b\u5728\u4f60\u5bf9zeno\u4e5f\u6709\u201c\u611f\u60c5\u201d\u4e86\uff0c\u5982\u679c\u4f60\u8fd8\u60f3\u4e3a\u6211\u4eeczeno\u7ee7\u7eed\u201c\u8d21\u732e\u201d\u7684\u8bdd\uff0c\u53ef\u4ee5\u5f00\u51fa5k\u4f4e\u4ef7\u91cd\u65b0\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\uff0c\u7b49\u201c\u62c9\u5230\u6295\u8d44\u201d\u201c\u8d44\u91d1\u4e0d\u56f0\u96be\u201d\u65f6\uff0c\u518d\u7ed9\u5c0f\u5f6d\u8001\u5e08\u201c\u8865\u8d34\u201d\u56de\u539f\u6765\u768416k\u5de5\u8d44\uff0c\u540c\u65f6\u770b\u5230\u5f20\u5265\u58eb\u5728\u7fa4\u91cc\u70ab\u8000\u4ed6\u8239\u65b0\u7684\u7b49\u8eab\u624b\u529e(\u5c04)\u3002 \u5f20\u5265\u58eb\u81ea\u6211\u611f\u52a8\u6f14\u7684\u60df\u5999\u60df\u8096\uff0c\u5c0f\u5f6d\u8001\u5e08\u8003\u8651\u5230\u5f20\u5265\u58eb\u671f\u6743\u5927\u997c\u7684\u524d\u8f66\u4e4b\u9274\uff0c\u5c31\u6ca1\u6709\u76f8\u4fe1\u5265\u58eb\u7684\u201c\u597d\u610f\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\u53ea\u597d\u4ee5\u672c\u79d1\u5e94\u5c4a\u751f\u8eab\u4efd\u5f00\u59cb\u5bfb\u627e\u5de5\u4f5c\uff0c\u5176\u4e2dhr\u7ecf\u5e38\u62f7\u95ee\u201c\u6211\u770b\u4f601\u6708\u5230\u73b0\u5728\u90fd\u662f\u6ca1\u6709\u5de5\u4f5c\u7684\u72b6\u6001\uff1f\u201d\u201c\u8bf4\u4e00\u4e0b\u79bb\u804c\u539f\u56e0\u201d\u9020\u6210\u5f88\u5927\u7684\u9ebb\u70e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u5c55\u793a\u201c\u5de5\u4f5c\u7ecf\u9a8c\u201d\u65f6\uff0chr\u603b\u662f\u53cd\u590d\u5f3a\u8c03\u201c\u6211\u770b\u4f60\u624d\u521a\u6bd5\u4e1a\u5440\uff1f\u201d\uff0c\u8ba4\u4e3a\u201c\u5b9e\u4e60\u7ecf\u9a8c\u201d\u4e0d\u7b97\uff0c\u5bfc\u81f4\u5c0f\u5f6d\u8001\u5e08\u5728\u5f20\u5265\u58eb\u7684\u7ecf\u9a8c\u51e0\u4e4e\u4f5c\u5e9f\uff0c\u800c\u5e94\u5c4a\u751f\u4f18\u60e0\u53c8\u88ab\u5f20\u5265\u58eb\u8017\u6389\uff0c\u7136\u800c\uff0c\u5b83\u53ea\u8981\u770b\u4e00\u4e0bzeno\u8d21\u732e\u6392\u884c\u699c\u5c31\u77e5\u9053\uff0c\u5c0f\u5f6d\u8001\u5e08\u7684\u8d21\u732e\u662f\u7b2c\u4e00\u7684\u3002 \u6240\u6709\u6cfd\u68ee\u5458\u5de5\u90fd\u9700\u8981\u719f\u6089\u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u8fed\u4ee3\u8fc7\u7684\u8282\u70b9\u7cfb\u7edf\uff0c\u624d\u80fd\u5f00\u59cb\u4ed6\u7684zeno\u5f00\u53d1\uff0c\u66f4\u4f55\u51b5\u5c0f\u5f6d\u8001\u5e08\u8fd8\u8d21\u732e\u4e86\u5305\u62ec\u8282\u70b9\u7f16\u8f91\u5668\u3001Python bindings\u3001\u5b9e\u65f6\u4e09\u7ef4\u89c6\u7a97\u3001\u591a\u8fdb\u7a0b\u901a\u4fe1\u3001\u78c1\u76d8\u7f13\u5b58\u3001\u5bf9\u8c61\u5e8f\u5217\u5316\u3001\u5b9e\u65f6optix\u3001shader\u8282\u70b9\u3001GLSL codegen\u3001\u521a\u4f53\u4eff\u771f\u3001Prim\u5c5e\u6027\u7cfb\u7edf\u3001ZFX\u7f16\u8bd1\u5668\u3001PrimPrim \u90bb\u5c45\u67e5\u627e\u3001\u63d2\u4ef6\u7cfb\u7edf\u3001ABC \u52a0\u8f7d\u5668\u3001\u51e0\u4f55\u8282\u70b9\u3001VDB \u8282\u70b9\u3001\u6d41\u4f53\u5b50\u56fe\u3001Blender \u63d2\u4ef6\u3001OpenSubdiv \u96c6\u6210\u3001libigl \u96c6\u6210\u3001CI/CD \u5de5\u4f5c\u6d41\u7b49\u8bf8\u591a\u529f\u80fd\u3002 \u5f20\u5265\u58eb\u53d1\u77e5\u4e4e\u6587\u7ae0\u7206\u8bba\uff1a\u6211\u4eec\u4e0d\u9700\u8981\u7a0b\u5e8f\u5458\uff01\u53ea\u9700\u8981\u5076\u5c14\u62db\u4e24\u4e2a\u5389\u5bb3\u4e00\u70b9\u7684\u5b9e\u4e60\u751f\uff0c\u505a\u4e2a\u4e00\u4e24\u5e74\uff0c\u628a\u8f6f\u4ef6\u505a\u5b8c\u4ee5\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u4ed6\u4eec\u4e86\uff0c\u663e\u7136\u5c0f\u5f6d\u8001\u5e08\u5c31\u662f\u8fd9\u6837\u4e00\u4e2a\u4e00\u6b21\u6027\u53c8\u7279\u522b\u597d\u7528\u7684\u5b9e\u4e60\u751f\u3002 \u67d0 Unity \u5c0f\u5382 (2024.08.12) \u4e00\u4e2a\u770b\u8d77\u6765\u53ef\u80fd\u662f\u8001\u677f\u7684\u4eba\u7269\u51fa\u9762\u8fce\u63a5\uff0c\u8fdb\u5165\u4e00\u4e2a\u72ec\u7acb\u7684\u4f1a\u8bae\u5ba4\u5f00\u59cb\u9762\u8c08\u3002 \u4e4b\u524d\u73a9\u8fc7\u54ea\u4e9b\u6e38\u620f\uff1f(\u4e3b\u8981\u662f\u8089\u9e3d\u548c\u6a21\u62df\u7ecf\u8425\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u6740\u622e\u5c16\u5854\u548cKSP\uff0c\u56e0\u4e3a\u4ed6\u4eec\u662fUnity\u6e38\u620f\uff0c\u8fd8\u4ecb\u7ecd\u4e86\u5236\u4f5c\u4ee5\u6492\u7684\u7ed3\u5408\u6a21\u7ec4\u7684\u7ecf\u5386\uff0c\u57fa\u4e8eLua API\u7684) \u9762\u8bd5\u5b98\u8bf4\u73b0\u5728 KSP2 \u6ca1\u6709\u5361\u987f\u4e86\uff0c\u56e0\u4e3a GC \u4f18\u5316\u4e86 \u95ee\u5b66\u8fc7Unity\u5417\uff1f(\u4e86\u89e3\u4e00\u70b98\uff0c\u4e4b\u524d\u505a\u8fc7KSP\u6a21\u7ec4) \u95ee\u90a3\u4e48\u4f60\u7684Unity\u7248\u672c\uff1f(\u7cdf\u7cd5\uff0c\u53ea\u80fd\u88c5\u50bb\u4e86\uff0c\u56e0\u4e3a\u5176\u5b9e\u5f88\u4e45\u6ca1\u6253\u5f00\u8fc7\u4e86\uff0c\u800c\u4e14\u65b0\u7535\u8111\u91cc\u4e5f\u6ca1\u6709\u4e0bUnity) \u8868\u793a\u4f60\u5e94\u8be5\u591a\u770b\u770bUnity\u5b98\u65b9\u6587\u6863\uff0c\u7279\u522b\u662f\u82f1\u6587\u7684\u6587\u6863 \u95eePBR\u6d41\u7a0b\uff1f(\u5206\u4e3aLambert\u548cCook-Torrance\u4e24\u4e2a\u6a21\u578b\uff0c\u5408\u5e76\u8d77\u6765\uff0clambert\u5f88\u7b80\u5355\u7684\u5168\u65b9\u5411\u968f\u673a\u6f2b\u53cd\u5c04\uff0c\u4ecb\u7ecd\u4e86NDF, GDF, FDF\u4e09\u4e2a\u51fd\u6570\u7684\u7269\u7406\u610f\u4e49) \u95eeCg\u7740\u8272\u8bed\u8a00\uff1f(Unity\u81ea\u5df1\u7684\u7740\u8272\u5668\u8bed\u8a00\uff0c\u4e0d\u719f\u6089\uff0c\u8868\u793a\u4e4b\u524d\u5199\u7684\u90fd\u662fGLSL\uff0c\u4f46\u6211\u77e5\u9053\u6240\u6709\u5f15\u64ce\u90fd\u6709\u4e00\u4e2a\u94a6\u5b9a\u8bed\u8a00\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u4f1a\u7ffb\u8bd1\u751f\u6210\u4e0d\u540c\u7684\u76ee\u6807\u8bed\u8a00\u6bd4\u5982GLSL\uff0cUnity\u4e5f\u652f\u6301\u5199GLSL\uff0c\u4f46\u90e8\u5206\u529f\u80fd\u7279\u6027API\u6709\u6240\u7f3a\u5931\uff0c\u6240\u4ee5\u4e3b\u8981\u8fd8\u662f\u5199Cg\uff0c\u5728GL\u540e\u7aef\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u751f\u6210GLSL\u7684) \u5c0f\u5f6d\u8001\u5e08\u63d0\u8d77\u4e3a\u4e86\u652f\u6301UE\uff0c\u7279\u522b\u505a\u4e86HLSL\u540e\u7aef(\u9762\u8bd5\u5b98\u9510\u8bc4\u4e86\u715e\u7b14DX\u4e0d\u8de8\u5e73\u53f0\uff0c\u73b0\u5728\u6e38\u620f\u4e3b\u8981\u8fd8\u662f\u57fa\u4e8eOpenGL\u5728\u505a\uff0cUE\u662f\u56e0\u4e3a\u5fae\u8f6f\u7ed9\u94b1\u4e86\u624d\u94a6\u5b9aHLSL\u4e3a\u4e3b\u8bed\u8a00\uff0c\u4f46\u5b9e\u9645\u4e0a\u4e5f\u6709\u7ffb\u8bd1\u5230GLSL\u7684OpenGL\u540e\u7aef) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u8868\u793a\u6211\u4eec\u505a\u7684\u662fUnity\u7684\u5fae\u4fe1\u5c0f\u6e38\u620f\uff0c\u56e0\u4e3a\u6700\u8fd1\u63a8\u51fa\u7684WebGL\u540e\u7aef(\u5c0f\u5f6d\u8001\u5e08\uff1a\u602a\u4e0d\u5f97\u53ef\u4ee5\u770b\u5230\u6700\u8fd1\u8fd9\u4e48\u591a\u5fae\u4fe1\u5c0f\u6e38\u620f) \u95ee\u4e86 Lua(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u5199\u7684 Lua \u811a\u672c\u5b9e\u73b0\u4ee5\u6492\u6a21\u7ec4) \u6211\u4eec\u4e0d\u662f\u8981\u5199 Lua\uff0c\u800c\u662f\u8981\u8c03\u7528 Lua \u7684 C \u63a5\u53e3\u54e6\uff01(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e5f\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u53c2\u4e0e\u7684\u4e00\u4e2a\u4ee5\u6492\u6a21\u7ec4\u9879\u76ee IsaacSocket \u5c31\u662f\u57fa\u4e8e C# \u5ba2\u6237\u7aef\uff0c\u52a8\u6001\u5f80\u4ee5\u6492\u8fdb\u7a0b\u6ce8\u5165 C++ DLL\uff0c\u52ab\u6301\u4ee5\u6492\u7684\u5404\u79cd\u56de\u8c03\uff0c\u7136\u540e\u66b4\u9732\u51fa Lua \u63a5\u53e3\uff0c\u521b\u5efa\u4e86\u4e00\u7cfb\u5217\u5bf9\u6e38\u620f\u5185 Lua \u811a\u672c\u53ef\u89c1\u7684 C++ \u51fd\u6570\uff0c\u5b9e\u73b0\u4ee5\u6492 API \u7684\u6269\u5c55\uff0c\u9700\u8981 lua_tonumber \u6765\u83b7\u53d6\u53c2\u6570\uff0clua_pushnumber \u6765\u8fd4\u56de\u503c\u7b49) \u95ee\u4e86 lua_State \u662f\u4ec0\u4e48(\u5c0f\u5f6d\u8001\u5e08\uff1a\u542b\u6709 lua \u7684\u5806\u6808\u5168\u5c40\u53d8\u91cf\u7b49\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u5404\u81ea\u72ec\u7acb) \u95ee\u5982\u4f55\u521b\u5efa\u4e00\u4e2a UI \u754c\u9762\uff1f\u9009\u62e9\u4e0d\u540c\u7684\u670d\u52a1\u5668\uff0c\u767b\u5f55(\u4f7f\u7528json+http\u5b9e\u73b0rpc\uff0c\u83b7\u5f97\u4e00\u4e2a\u5217\u8868\uff0c\u7136\u540e\u8bbe\u7f6e\u5217\u8868\uff0c\u5373\u53ef\u5229\u7528MVC\u521b\u5efa\u51fa\u754c\u9762) Unity \u7684 UI \u7cfb\u7edf\u4f1a\u5199\u5417\uff1f(\u4e0d\u4f1a\uff0c\u53ea\u77e5\u9053Qt\u6709QListView\u63a7\u4ef6\uff0cUnity\u53ef\u80fd\u4e5f\u6709\u5427\uff1f) \u851a\u6765\u5c0f\u6c7d\u8f66 (2024.08.15) 1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 2\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 \u6ca1\u67093\u9762\u4e86\uff0c\u539f\u56e0\u4e0d\u660e\u3002 \u5176\u57df\u79d1\u6280 (2024.09.03) 1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 \u8981\u6c42\u81ea\u6211\u4ecb\u7ecd(\u4e3b\u8981\u4ecb\u7ecd\u4e86\u6cfd\u68ee\u5728\u6e32\u67d3\u7684\u5de5\u4f5c\uff0cshader\u8282\u70b9\u7b49\uff0c\u4e0d\u4ec5\u8d1f\u8d23\u4e86Qt+OpenGL\u5b9e\u65f6\u53ef\u89c6\u5316\uff0c\u540e\u6765\u8fd8\u52a0\u5165\u4e86OptiX\u5b9e\u65f6\u5149\u8ffd\u652f\u6301) \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecdzeno\u7684shader\u8282\u70b9\u652f\u6301\u8f93\u51fa\u4e3aGLSL\u3001HLSL\u3001CUDA\u4e09\u79cd\u540e\u7aef\u683c\u5f0f\uff0c\u90fd\u662fcodegen\uff0c\u5176\u4e2dCUDA\u540e\u7aef\u91c7\u7528NVPTX\u7f16\u8bd1\uff0c\u4f9bOptiX\u4f7f\u7528 \u4ecb\u7ecdPBR\u6d41\u7a0b(albedo, metallic, roughness \u7b49\uff0c\u8fd8\u6709\u6cd5\u7ebf\u8d34\u56fe\u7684\u70d8\u70e4\uff0cIBL \u5149\u7167\u7b49) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u4ecb\u7ecd\u4e86\u516c\u53f8\u5185\u90e8\u662f\u6709\u5d4c\u5165\u5f0f(\u4e09\u7ef4\u6355\u83b7\u8bbe\u5907)\u548c\u7535\u8111\u7aef(\u7528\u4e8e\u67e5\u770b\u4e09\u7ef4\u6355\u83b7\u7ed3\u679c\u7684App)\uff0c\u5d4c\u5165\u5f0f\u8bbe\u5907\u53ea\u9700\u8981\u505a\u521d\u6b65\u7684\u6570\u636e\u5904\u7406\uff0c\u57fa\u4e8e\u56fd\u4ea7GPU(\u4f46\u662fCUDA\u63a5\u53e3)\uff0c\u521d\u6b65\u5904\u7406\u540e\u56de\u4f20\u7528\u6237\u7535\u8111\uff0c\u7535\u8111\u7aef\u53ef\u4ee5\u5047\u5b9a\u7528\u6237\u662fNVIDIA\u663e\u5361(\u4e5f\u662fCUDA\u63a5\u53e3)\u7528\u4e8e\u66f4massive\u7684\u540e\u5904\u7406\u548c\u6e32\u67d3\u53ef\u89c6\u5316 \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecd\u5728taichi three\u4e2d\u624b\u6413\u8f6f\u5149\u6805\u6e32\u67d3\u5668\u7684\u7ecf\u5386(\u652f\u6301ssr, ssgi, taa\u7b49) 2\u9762\uff08LeetCode\u5728\u7ebf\u9762\u8bd5\uff0c\u6709\u5171\u4eab\u4ee3\u7801\u7f16\u8f91\u5668\uff09 \u8981\u6c42\u5c0f\u5f6d\u8001\u5e08\u81ea\u6211\u4ecb\u7ecd(\u7b80\u5386\u4ed6\u5df2\u7ecf\u62ff\u5230\u770b\u7740\u4e86\uff0c\u5c31\u4e0d\u590d\u8bfb\u540d\u5b57\u548c\u5b66\u5386\u4e86\uff0c\u6240\u4ee5\u4e3b\u8981\u4ecb\u7ecd\u9879\u76ee\uff0c\u5728zeno\u4e2d\uff0c\u5c0f\u5f6d\u8001\u5e08\u62c5\u4efb\u6e32\u67d3\u548c\u8282\u70b9\u7cfb\u7edf\u7684\u5f00\u53d1\uff0c\u4ecb\u7ecdQt+OpenGL\u89c6\u7a97\u53ef\u89c6\u5316\uff0c\u4ecb\u7ecd\u8282\u70b9\u7cfb\u7edf\u7c7b\u4f3c\u4e8e\u4f4e\u4ee3\u7801\u7684\u4f18\u52bf\uff0c\u7b80\u8981\u4ecb\u7ecdtaichi, nbodysolver, co_async\u2026\u2026\u70ab\u8000\u9ad8\u6548\u7684\u534f\u7a0b\uff0c\u5e76\u5b89\u5229\u5c0f\u5f6d\u8001\u5e08\u6bd4\u7ad9\u9891\u9053\uff0ccpp\u516c\u5f00\u8bfe) \u9762\u8bd5\u5b98\u8868\u793a\u4e0d\u719fcpp20\uff0c\u63d0\u51fa\u8981\u4ee5cpp17\u4e3a\u57fa\u7840(\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u5728zeno\u548ctaichi\u4e5f\u90fd\u662f\u7528cpp17) cpp\u6709\u54ea\u56db\u5927cast(static_cast, dynamic_cast, const_cast, reinterpret_cast) static_cast vs dynamic_cast\u9002\u7528\u573a\u666f(\u5b50\u7c7b\u8f6c\u57fa\u7c7b\u603b\u662fstatic_cast\uff0c\u4e00\u4e2a\u57fa\u7c7b\u6307\u9488\uff0c\u5982\u679c\u4e0d\u80fd\u786e\u5b9a\u662f\u4e0d\u662f\u5b50\u7c7b\uff0c\u90a3\u5c31\u9700\u8981dynamic_cast\uff0c\u5982\u679c\u5931\u8d25\u4f1a\u8fd4\u56denullptr\uff0c\u8bb0\u5f97\u68c0\u67e5\uff01\u5982\u679cdynamic_cast\u5f15\u7528\u5219\u5931\u8d25\u629b\u51fabad_cast\u5f02\u5e38) dynamic_cast\u80cc\u540eRTTI\u539f\u7406(\u5b9e\u9645\u4e0a\u662f\u6bd4\u8f83typeid\u662f\u5426\u517c\u5bb9\uff0ctypeid\u6307\u9488\u5b58\u5728\u865a\u51fd\u6570\u8868\u91cc\uff0c\u53ea\u6709\u5e26\u6709\u81f3\u5c111\u4e2a\u865a\u51fd\u6570\u7684\u79f0\u4e3a\u201c\u591a\u6001\u7c7b\u201d\u7684\u7c7b\u578b\u4f1a\u751f\u6210RTTI\u4fe1\u606f\uff0c\u987a\u4fbf\u63a8\u9500\u4e86\u4e3a\u4ec0\u4e48llvm\u9009\u62e9\u5f00\u542f-fno-rtti\u548c-fno-exception\uff0c\u662f\u907f\u514d\u4e8c\u8fdb\u5236\u81a8\u80c0) llvm\u5173\u95ed\u4e86RTTI\uff0c\u90a3\u4ed6\u662f\u5982\u4f55\u53d8\u76f8\u5b9e\u73b0dynamic_cast\u7684\uff1f(\u6211\u77e5\u9053\uff0c\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff01\u5b9a\u4e49\u4e86getType\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u679a\u4e3e\uff0c\u7528\u4e8e\u6bd4\u8f83) \u53ef\u662f\u5982\u679cD2\u7ee7\u627fD1\u7ee7\u627fB\uff0c\u5982\u4f55\u4fdd\u8bc1D2\u4e5f\u53ef\u4ee5cast\u4e3aD1\uff1f(\u5b8c\u4e86\uff0cllvm\u6e90\u7801\u770b\u7684\u4e0d\u4ed4\u7ec6\uff0c\u53ea\u80fd\u7528\u4ee5\u6492\u7684\u505a\u6cd5\u76f2\u731c\u4e00\u4e2a\uff1a\u662fB\u6709getD1\u548cgetD2\u4e24\u4e2a\u865a\u51fd\u6570\uff01\u4ed6\u4eec\u9ed8\u8ba4\u8fd4\u56denullptr\uff0c\u53ea\u6709D1\u4f1a\u91cd\u5199getD1\uff0cD2\u4f1a\u91cd\u5199getD2\uff0c\u5185\u90e8\u90fd\u662f\u7b80\u5355\u7684\u8fd4\u56dethis) const_cast\u672a\u5b9a\u4e49\u884c\u4e3a(\u672c\u6765\u662fconst\u7684\u4e0d\u80fd\u53bb\u6389const\u540e\u8bbf\u95ee\uff0c\u5c55\u793a\u4e86\u6210\u5458\u51fd\u6570\u590d\u7528\u4e24\u4e2adata\u7684\u7528\u6cd5) const_cast\u540e\u8fd4\u56de\u6307\u9488\u6ca1\u95ee\u9898\uff0c\u9762\u8bd5\u5b98\u6539\u6210\u8fd4\u56de\u5f15\u7528\uff0c\u6d89\u53ca\u89e3\u5f15\u7528\uff0c\u95ee\u8fd9\u6837\u8fd8\u5b89\u5168\u5417\uff1f(\u8ff7\u60d1\u6027\u5f88\u5f3a\u7684\u95ee\u9898\uff0c\u88ab\u5c0f\u5f6d\u8001\u5e08\u8bc6\u7834\uff1a\u975econst\u5730\u89e3\u5f15\u7528const\u53d8\u91cf\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u53d6\uff0c\u5c31\u548cend\u8fed\u4ee3\u5668\u4e0d\u80fd\u89e3\u5f15\u7528\u4e00\u6837\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u5199\u8bbf\u95ee) const vs constexpr\u53d8\u91cf\u533a\u522b(const\u53ef\u4ee5\u6709\u5730\u5740\uff0c\u800cconstexpr\u4e0d\u4e00\u5b9a\u6709) reinterpret_cast\u7528\u6cd5\uff0c\u4ec0\u4e48\u60c5\u51b5\u4e0b\u5b89\u5168(\u5c0f\u5f6d\u8001\u5e08\u5199\u7ecf\u5178\u4e3e\u51faint\u548cfloat\u4e4b\u95f4bit-cast\u7684\u6848\u4f8b\uff0c\u4ecb\u7ecd\u503c\u8f6c\u6362\u548c\u6309\u4f4d\u8f6c\u6362\u7684\u533a\u522b\uff0c\u52fe\u5f15\u9762\u8bd5\u5b98\u4e0a\u94a9\uff0c\u4ed6\u80af\u5b9a\u8ba4\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4e0d\u77e5\u9053reinterpret_cast\u4e0d\u80fd\u505aint\u548cfloat\u7684\u6307\u9488\u8f6c\u6362\uff0c\u4e8e\u662f\u53d1\u95ee\uff1a) \u9762\u8bd5\u5b98\u5199\u51faint\u548cfloat\u6307\u9488\u5f3a\u8f6c\u5e76\u89e3\u5f15\u7528\u7684\u4ee3\u7801\uff0c\u95ee\u8fd9\u4e2a\u5b89\u5168\u5417\uff1f(\u4e0a\u94a9\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u5373\u7b54\uff1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e0d\u80fd\u7528reinterpret_cast\u8f6cint\u548cfloat\u6307\u9488\uff0c\u662f\u56e0\u4e3astrict-aliasing\u8ba4\u4e3aint\u548cfloat\u4e0d\u517c\u5bb9\uff0c\u8f6c\u6362\u540e\u89e3\u5f15\u7528\u5373UB\uff0c\u9762\u8bd5\u5b98\u8bf4\u4f3c\u4e4e\u53ea\u6709GCC\u4f1a\u7528\u8fd9\u4e2a\uff0c\u5c0f\u5f6d\u8001\u5e08\u7b54\uff1aGCC\u9ed8\u8ba4\u5f00\u542f\uff0c\u53ef\u4ee5\u7528-fno-strict-aliasing\u5173\u95ed\uff0cMSVC\u4e0d\u5229\u7528\u6b64\u89c4\u5219\u4f18\u5316\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u4ecb\u7ecd\u6307\u9488\u522b\u540d\u4e0e\u4f18\u5316\u7684\u5173\u7cfb\uff0c\u5373\u4e3a\u4ec0\u4e48\u63d0\u51fastrict-aliasing\u89c4\u5219\u7684\u539f\u56e0) \u5c0f\u5f6d\u8001\u5e08\u5f3a\u8c03int\u548cunsigned int\u662f\u517c\u5bb9\uff0c\u9762\u8bd5\u5b98\u5c31\u95ee\u4e3a\u4ec0\u4e48char\u53ef\u4ee5\uff1f(reinterpret_cast\u6709\u7834\u683c\u5141\u8bb8\u7684\u7279\u4f8b\uff0cchar,unsigned char,std::byte\u4e0e\u6240\u6709\u7c7b\u578b\u90fd\u517c\u5bb9\uff0c\u8f6c\u4e3achar\u6307\u9488\u540e\u53ef\u4ee5\u968f\u610f\u8bbf\u95ee\u4efb\u610f\u7c7b\u578b\u7684\u5185\u5b58\uff0c\u6307\u51fa\u662fcpp\u6807\u51c6\u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u89e3\u5e8f\u5217\u5316\u7684\u65b9\u4fbf\u6027) \u5982\u4f55\u5b9e\u73b0\u771f\u6b63\u5b89\u5168\u7684int\u548cfloat\u8f6c\u6362\uff1f(\u4f7f\u7528memcpy\u6216cpp20\u7684bit_cast\u662f\u5b89\u5168\u7684\uff0c\u5e76\u63a8\u9500memcpy vs bit_cast\u533a\u522b\uff1a\u867d\u7136cppref\u4e0abit_cast\u7684\u201c\u53c2\u8003\u5b9e\u73b0\u201d\u662fmemcpy\uff0c\u4f46\u5f97\u76ca\u4e8e\u5176\u57fa\u4e8e\u7f16\u8bd1\u5668\u5f00\u6d1e__builtin_bit_cast\uff0c\u8ba9bit_cast\u662fconstexpr\u51fd\u6570\u53ef\u7f16\u8bd1\u671f\u786e\u5b9a) inline\u5173\u952e\u5b57\u4f5c\u7528(non-odr external linkage\uff0c\u5efa\u8bae\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u7684\u51fd\u6570\u90fd\u52a0inline\uff0c\u5426\u5219\u591a\u4e2a.cpp\u6587\u4ef6\u4e2d\u4ea7\u751f\u591a\u4e2a\u5b9a\u4e49\uff0c\u89e6\u53d1\u94fe\u63a5\u5668odr\u62a5\u9519\uff0c\u800cinline\u5219\u662f\u975endr\u7684\u5916\u90e8\u94fe\u63a5) \u9762\u8bd5\u5b98\u95eeinline\u51fd\u6570\u591a\u4e2a\u6587\u4ef6\u4e2d\u770b\u5230\u7684\u51fd\u6570\u4f53\u5b9a\u4e49\u4e0d\u540c\uff0c\u4f46\u51fd\u6570\u53c2\u6570\u5217\u8868\u76f8\u540c\uff0c\u4f1a\u600e\u4e48\u6837\uff1f(\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6807\u51c6\u8981\u6c42\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709.cpp\u7ffb\u8bd1\u5355\u5143\u770b\u5230\u7684inline\u51fd\u6570\u5b9a\u4e49\u4e00\u81f4\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u5f80\u5f80\u5e76\u4e0d\u62a5\u9519) \u5c0f\u5f6d\u8001\u5e08\u63a8\u9500\uff1a\u8fd9\u5bfc\u81f4\u4f60\u5728cpp\u6587\u4ef6\u4e2d\u5b9a\u4e49\u975ePOD\u7c7b\u4f1a\u88ab\u5751\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9a\u4e49\u7684\u6210\u5458\u51fd\u6570\uff0c\u9ed8\u8ba4\u662finline\u7684\uff0c\u5305\u62ec\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5f53\u65f6\u5bfc\u81f4zeno\u8c03\u8bd5\u4e86\u534a\u5929(\u9762\u8bd5\u5b98\u8868\u793a\u4ed6\u4e4b\u524d\u96c6\u6210\u4e00\u4e2a\u5f00\u6e90\u5e93\u4e5f\u9047\u5230\u8fd9\u4e2a\u5751\uff0c\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u53ef\u4ee5\u5957\u533f\u540dnamespace\u89e3\u51b3) push_back vs emplace_back(2\u91cd\u8f7dvs\u4e07\u80fd\u5f15\u7528+\u53d8\u957f\u53c2\u6570\uff0cemplace\u53ef\u4ee5\u5c31\u5730\u5e26\u4efb\u610f\u53c2\u6570\u6784\u9020\u4f60\u7684\u5143\u7d20\u7c7b\u578b\uff0cemplace\u7684\u989d\u5916\u597d\u5904\u662f\u89e6\u53d1explicit\u7684\u6784\u9020\u51fd\u6570\u800c\u65e0\u9700\u663e\u5f0f\u5199\u51fa\u7c7b\u540d\uff0c\u4e5f\u5e26\u6765\u4e86\u5371\u9669\uff0c\u6240\u4ee5\u6211\u5728\u8bfe\u7a0b\u4e2d\u90fd\u4e0d\u63a8\u8350\u4f7f\u7528\uff0c\u5982\u9700\u907f\u514d\u79fb\u52a8\u53ef\u4ee5 vector> \uff0c\u8fd9\u8fd8\u80fd\u4f7f\u6269\u5bb9\u65f6\u4e5f\u4e0d\u89e6\u53d1\u79fb\u52a8) \u4ec0\u4e48\u60c5\u51b5\u4e0b\u4e0d\u4f1a\u79fb\u52a8\uff1f\u9762\u8bd5\u5b98\u4f3c\u4e4e\u5728\u8bd5\u63a2\u6211\u662f\u5426\u4e86\u89e3 vector \u6269\u5bb9\u539f\u7406(\u53ea\u6709\u5f53size>capacity\u65f6\u624d\u4f1a\u89e6\u53d1\uff0c\u6bcf\u6b21\u89e6\u53d1\u6269\u5bb9\u65f6gcc\u589e\u52a0\u52302 x size\uff0cmsvc\u5219\u662f1.5 x size\uff0c\u603b\u51712n\u6b21\u64cd\u4f5c\uff0c\u597d\u5904\u662f\u4fdd\u8bc1\u4e86\u603b\u4f53O(n)\u590d\u6742\u5ea6\uff0c\u6211\u4eec\u5efa\u8bae\u77e5\u9053\u957f\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528reserve\u63d0\u524d\u9884\u8ba2100\u7684capacity\uff0c\u8fd9\u6837\u53ea\u6709\u63a8\u5165\u7b2c101\u4e2a\u5143\u7d20\u624d\u4f1a\u6269\u5bb9\u5230200\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u63a8\u9500\u4e86vector, deque, list\u7684\u533a\u522b\uff0c\u8fed\u4ee3\u5668\u5931\u6548\u539f\u56e0) \u8fd8\u95ee\u4e86\u4e07\u80fd\u5f15\u7528\u548c\u5b8c\u7f8e\u8f6c\u53d1\u7684\u539f\u7406(\u5f15\u7528\u6298\u53e0) \u4ec0\u4e48\u662fPOD(\u57fa\u7840\u7c7b\u578b\u3001\u6307\u9488\u3001\u65e0\u7528\u6237\u6784\u9020\u51fd\u6570\u7684\u7eaf\u57fa\u7840\u7c7b\u578b\u7ec4\u6210\u7684\u7ed3\u6784\u4f53) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1avector\u8d85\u7f13\u5b58\u5927resize\u5bfc\u81f4memset\u6027\u80fd\u5f71\u54cd\uff1f(\u62ff\u51fa\u6211\u7684tbb\u8bfe\u7a0b\u7684parallel_filter\u6848\u4f8b\uff0c\u5229\u7528pod\u6a21\u677f\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u719f\u6089\u7f13\u5b58\uff0c\u4e0d\u7528\u63d0\u95ee\u4e86) \u9762\u8bd5\u5b98\u63d0\u95eePIMPL\u6a21\u5f0f(\u5199C::Impl\u7ed9\u4ed6\u770b\uff0c\u53c8\u95eePIMPL\u7684\u76ee\u7684\u662f\u4ec0\u4e48\uff0c\u4e00\u5f00\u59cb\u7b54\uff1a\u5206\u79bb\u5b9a\u4e49\uff0c\u52a0\u901f\u7f16\u8bd1\uff0c\u95ee\u8fd8\u6709\u4ec0\u4e48\u4f5c\u7528\u5417\uff1f\u4fdd\u6301abi\u7a33\u5b9a\uff0c\u4e0d\u7528\u91cd\u65b0\u7f16\u8bd1\u4f9d\u8d56\u8005\uff0c\u53ef\u7528\u4e8e\u63d2\u4ef6\u70ed\u88c5\u8f7d) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48C\u7684\u6784\u9020\u51fd\u6570\u91cc\u4f1a\u9700\u8981unique_ptr\u7c7b\u578b\u6790\u6784\u51fd\u6570\u7684\u4fe1\u606f\u5417\uff1f(\u9762\u8bd5\u5b98\uff1a\u56e0\u4e3a\u6790\u6784\u51fd\u6570\u9700\u8981\u77e5\u9053sizeof!=0\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u4f46\u662f\uff0cC\u7684\u6790\u6784\u51fd\u6570\u88ab\u8f6c\u79fb\u5230\u4e86C.cpp\uff0c\u4e3a\u4ec0\u4e48\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521d\u59cbunique_ptr\u4e3anullptr\uff0c\u4ecd\u7136\u7f16\u8bd1\u51fa\u9519\uff1f\u9762\u8bd5\u5b98\u652f\u652f\u543e\u543e\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u56e0\u4e3a\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u5f02\u5e38\uff0c\u5bfc\u81f4\u4e4b\u524d\u521d\u59cb\u5316\u8fc7\u7684\u6210\u5458\u6790\u6784\uff0c\u518d\u6b21\u5411\u4ed6\u515c\u552ecpp\u5f02\u5e38\u9b45\u529b\u65f6\u523b) q\u6307\u9488 vs d\u6307\u9488(Qt\u5b9e\u73b0cow\u548cpimpl\u7684\u7ec6\u8282\uff0c\u56e0\u4e3a\u5e73\u65f6\u6ca1\u6ce8\u610f\u770bqt\u5934\u6587\u4ef6\u6e90\u7801\uff0c\u5c0f\u5f6d\u8001\u5e08\u552f\u4e00\u683d\u8ddf\u5934\u7684\u9898\uff0c\u8bf4\u662f\u770b\u5230\u7b80\u5386\u5199\u7684Qt\u5c31\u95ee\u4e86\uff0c\u5e76\u8868\u793a\u4e4b\u524dzeno\u91cc\u4e3b\u8981\u662f\u7528PyQt) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1ac++11 string\u4e3a\u4ec0\u4e48\u6253\u7834abi(\u56e0\u4e3ac++98 string\u91c7\u7528cow\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u6a21\u578b\u5e38\u8bc6\u201c\u5171\u4eab\u8bfb\u5b89\u5168\u201d) make_shared vs shared_ptr new\u7684\u533a\u522b(\u53ea\u9700\u4e00\u6b21\u6027\u5206\u914d\uff0c\u65e0\u9700\u518dnew SpCounter\uff0c\u539f\u7406\u662foperator new+placement new) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48shared_ptr\u7684\u6784\u9020\u51fd\u6570\u6ca1\u6709noexcept\u5417\uff1f(\u5c31\u662f\u56e0\u4e3a\u8981new SpCounter) \u662foperator new\u8fd8\u662fnew_allocator\uff1f(\u9ed8\u8ba4\u662fnew_allocator\uff0c\u53ef\u7528allocate_shared\u66ff\u6362\u6389) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053make_shared_for_overwrite\u7684\u533a\u522b\u5417(\u91c7\u7528default-init\uff0cnew\u8868\u8fbe\u5f0f\u540e\u6ca1\u6709\u4e86\u62ec\u53f7\uff0c\u53ef\u907f\u514dPOD\u7c7b\u578b0\u521d\u59cb\u5316\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u8fd9\u4e2a\u6211\u90fd\u6ca1\u4e86\u89e3\u8fc7) CRTP(\u5947\u5f02\u9012\u5f52\u6a21\u677f\u6a21\u5f0f\uff0c\u6700\u521d\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u8981\u5b9e\u73b0\u83b7\u53d6\u5b50\u7c7b\u6307\u9488self\uff0c\u63a8\u9500\u4e86cpp\u6a21\u677f\u7c7b\u5ef6\u8fdf\u5b9e\u4f8b\u5316\u6210\u5458\u51fd\u6570\u7684\u673a\u5236\uff0c\u5176\u5b9eCRTP\u8fd8\u80fd\u7528\u4e8e\u5b9e\u73b0\u539f\u578b\u6a21\u5f0f\u548cvisitor\u6a21\u5f0f\uff0c\u56e0\u4e3a\u65f6\u95f4\u5173\u7cfb\u6ca1\u6765\u5f97\u53ca\u8bf4) \u865a\u51fd\u6570\u4e3a\u4ec0\u4e48\u4f4e\u6548\uff1f\u865a\u51fd\u6570\u5982\u4f55\u4f18\u5316(\u56e0\u4e3a\u9700\u8981call\u4e00\u4e2a\u6307\u9488\uff0ccpu\u65e0\u6cd5\u9884\u77e5\uff0c\u4f7f\u7528final\uff0c\u4e0d\u7528\u8bfb\u53d6\u865a\u51fd\u6570\u6307\u9488\u8868\uff0c\u7136\u540e\u8bf4\u660e\u4e86vecB\u62c6\u6210vecD1\u548cvecD2\u66f4\u9ad8\u6548) shared_from_this\u5b9e\u73b0(\u672c\u6765\u8981\u6211\u5199\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6765\u4e0d\u53ca\u5199\uff0c\u4f46\u662f\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u51fa\u8fc7\u624b\u6413shared\u5168\u5bb6\u6876\u7684\u89c6\u9891\uff0c\u9762\u8bd5\u5b98\u53ea\u597d\u653e\u5fc3) \u4f60\u5bf9\u54ea\u4e2a\u9886\u57df\u611f\u5174\u8da3\uff1f(\u5f53\u7136\u662f\u6e32\u67d3\uff0c\u6211\u4ece\u5c0f\u505a\u5230\u5927\uff0c\u5e76\u8868\u793a\u6027\u80fd\u4f18\u5316\u8fd9\u4e00\u5757\u4e5f\u5c3d\u7ba1\u8bf7\u6559\u5c0f\u5f6d\u8001\u5e08\uff0c\u6709cuda\u548csimd\u4f18\u5316\u5ba2\u6237\u7ecf\u9a8c) \u8fd8\u6709\u4ec0\u4e48\u95ee\u9898\u5bf9\u672c\u516c\u53f8\u5417\uff1f(\u65f6\u95f4\u4e0d\u591a\u4e86\uff0c\u5c31\u95ee\u8981\u4e0d\u8981\u73b0\u5728\u5f00\u59cb\u5b66\u4e60\u4e09\u7ef4\u91cd\u5efa\uff0c\u6216\u8005\u53ef\u4ee5\u8bd5\u8bd5\u770b\u5ba2\u6237\u7aef\uff0c\u8bf4\u5c97\u4f4d\u9009\u62e9\u53ef\u4ee5\u4e4b\u540e\u548chr\u6c9f\u901a\uff0c\u5e76\u5411\u6211\u63a8\u9500\u4e863dgs\uff0c\u7403\u978b\u51fd\u6570\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u597d\u591apaper\u5440\uff1f\u770b\u4e86\u51e0\u4e2a\u6548\u679c\u56fe\uff0c\u5178\u4e2d\u5178\u4e4bOurs\u6c38\u8fdc\u662f\u6700\u597d\u7684) 3\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\uff09 \u53c8\u4ecb\u7ecd\u4e86zeno\u548ctaichi\uff0c\u95ee\u4e86\u70b9\u4e91\u76f8\u5173\u95ee\u9898\uff0c\u5f88\u5feb\u7ed3\u675f\u4e86\u3002 4\u9762\uff08\u62c9\u6295\u8d44\u7684\u5408\u4f19\u4eba\u4eb2\u81ea\u7ebf\u4e0b\u89c1\u9762\uff09 \u5546\u573a\u5168\u90e8\u5173\u95ed\u4e86\uff0c\u661f\u5df4\u514b\u8fd8\u5f00\u7740 \u4ecb\u7ecd\u4e00\u4e0b\u4f60\u81ea\u5df18\uff08\u53c8\u662f zeno\uff09 \u95ee\u4e86\u4e0a\u6b21\u7684\u9762\u8bd5\u5b98\u600e\u4e48\u6837\u5440\uff08\u6211\u770b\u4e86\u63a8\u8350\u7684 3dgs\uff0c\u53d1\u73b0\u662f\u628a\u626b\u63cf\u51fa\u6765\u7684\u70b9\u4e91\uff0c\u9010\u6b65\u8f6c\u6362\u4e3a\u692d\u5706\u7403\u6e32\u67d3\uff09 \u4f60\u77e5\u9053\uff0c\u73b0\u5728\u4e3b\u6d41\u56fe\u5f62\u5b66\u90fd\u662f\u4e09\u89d2\u5f62\u7f51\u683c\uff0c\u90a3\u4e48\u8fd9\u79cd\u70b9\u4e91\u8981\u5982\u4f55\u6e32\u67d3\u5462\uff1f\uff08\u70b9\u4e91\u7684\u8bdd\u53ef\u4ee5\u5148\u7528 marching cube \u8f6c\u4e09\u89d2\u5f62\u9762\uff0czeno \u7684\u6d41\u4f53\u5c31\u662f\u8fd9\u6837\u7684\uff09 \u4f46\u662f\u6027\u80fd\u4e0d\u591f\uff0c\u4e0d\u80fd\u4fdd\u8bc1\u5b9e\u65f6\uff08\u53ef\u4ee5\u7528\u5c4f\u5e55\u7a7a\u95f4\u6d41\u4f53\uff0c\u4f46\u662f\u6548\u679c\u4e00\u822c\uff0c\u6211\u4eec\u505a\u7535\u5f71\u7684\u9700\u8981\u9ad8\u8d28\u91cf\u7684\u79bb\u7ebf\u6e32\u67d3\uff0c\u4e0d\u592a\u6ce8\u91cd\u5b9e\u65f6\u6027\uff0c\u5b9e\u65f6\u692d\u7403\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u7528\u5149\u8ffd\uff0c\u7b97\u5c04\u7ebf\u4e0e\u692d\u7403\u8868\u9762\u6c42\u4ea4\u5373\u53ef\uff0c\u4e0d\u8fc7\u82f1\u4f1f\u8fbe\u7684\u786c\u4ef6\u52a0\u901f\u53ea\u6709\u4e09\u89d2\u5f62\u7684\uff0c\u4f46\u662f GPU Gems \u4e0a\u7684 BVH \u52a0\u901f\u6c42\u4ea4\u4ee3\u7801\u7528\u4e8e\u692d\u7403\u4e5f\u662f\u53ef\u4ee5\u62ff\u6765\u53c2\u8003\u7684\uff09 \u62ff\u51fa\u4e00\u53f0 3D \u626b\u63cf\u673a\u5668\uff0c\u8bf4\u4f60\u77e5\u9053\u6211\u4eec\u8fd9\u4e2a\u6d4b\u7ed8\u673a\u5668\u662f\u5982\u4f55\u5b9a\u4f4d\u7684\u5417\uff08\u60ef\u6027\u5236\u5bfc\uff0c\u91cc\u9762\u6709\u52a0\u901f\u5ea6\u8ba1\uff0c\u6c42\u4e8c\u9636\u79ef\u5206\u5c31\u53ef\u4ee5\u5f97\u5230\u4f4d\u7f6e\uff09 \u4f46\u662f\u8fd9\u6837\u65f6\u95f4\u957f\u4f1a\u6709\u7d2f\u8ba1\u8bef\u5dee\uff0c\u5982\u4f55\u6d88\u9664\u8bef\u5dee\uff1f\uff08\u53ef\u4ee5\u7528 GPS \u5b9a\u4f4d\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5149\u5b66\u6444\u50cf\u5934\u626b\u63cf\u7684\u7ed3\u679c\uff0c\u786e\u5b9a\u81ea\u5df1\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u5fc5\u8981\u65f6\u53ef\u4ee5\u8d34\u51e0\u4e2a\u8bc6\u522b\u7eb8\u7247\u5728\u5899\u4e0a\u65b9\u4fbf\u7a0b\u5e8f\u68c0\u6d4b\uff09 \u662f\u7684\uff0c\u5b9e\u9645\u4e0a\u6211\u4eec\u5728\u6237\u5916\u4f1a\u7528 GPS \u5b9a\u4f4d\uff0c\u77ff\u6d1e\u91cc\u5c31\u4f1a\u7528\u5149\u5b66\u7684\u5b9a\u4f4d\u65b9\u6cd5\uff0c\u6d88\u9664\u60ef\u6027\u5236\u5bfc\u7684\u7d2f\u8ba1\u8bef\u5dee\u3002 \u90a3\u4e48 GPS \u536b\u661f\u5b9a\u4f4d\u7684\u539f\u7406\u4f60\u77e5\u9053\u5417\uff1f\uff08\u4e09\u9897 GPS \u536b\u661f\u53d1\u51fa\u4e0d\u540c\u76f8\u4f4d\u7684\u7535\u78c1\u6ce2\uff0c\u56e0\u4e3a\u5149\u901f\u6709\u9650\uff0c\u79fb\u52a8\u8bbe\u5907\u901a\u8fc7\u68c0\u6d4b\u76f8\u4f4d\u5dee\uff0c\u5c31\u77e5\u9053\u81ea\u5df1\u8ddd\u79bb\u4e09\u9897\u536b\u661f\u7684\u8ddd\u79bb\uff0c\u7136\u540e\u4e09\u4e2a\u8ddd\u79bb\u5c31\u80fd\u552f\u4e00\u786e\u5b9a\u4e00\u4e2a\u70b9\uff09 \u96c5\u79d1\u8d1d\u601d (2024.09.03) \u4ecb\u7ecd\u4e00\u4e0b\u81ea\u5df1\uff08\u53c8\u4ecb\u7ecdzeno\u662f\u4e00\u6b3eCAD\u7c7b\u7684\u9879\u76ee\uff09 \u54c8\u5e0c\u8868\uff08\u4ecb\u7ecdunordered_map\u57fa\u4e8e\u94fe\u8868\u6cd5\uff0c\u6807\u51c6\u5e93\u7684hashint\u662f\u6052\u7b49\u51fd\u6570\uff0cabsl\u7684\u5b9e\u73b0\u57fa\u4e8e\u5f00\u653e\u5730\u5740\u6cd5\u66f4\u9ad8\u6548\uff0cjava\u4e5f\u662f\u94fe\u8868\u6cd5\uff0c\u4f46\u94fe\u8868\u8fc7\u957f\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u7b49\uff09 \u7ea2\u9ed1\u6811\uff08\u4e94\u5927\u89c4\u5219\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u4e94\u4e2a\u89c4\u5219\u80fd\u4fdd\u8bc1\u4e0d\u8d85\u8fc72\u500d\u6df1\u5ea6\uff0c\u540c\u65f6\u6bd4\u4e8c\u53c9\u5e73\u8861\u6811\u9ad8\u6548\uff09 \u7ea2\u9ed1\u6811\u5de6\u65cb\u53f3\u65cb\u64cd\u4f5c\uff08\u53f3\u513f\u5b50\u66ff\u6362\u7236\u4eb2\uff0c\u7236\u4eb2\u53d8\u6210\u5de6\u513f\u5b50\uff09 \u9762\u8bd5\u5b98\u900f\u9732\uff1a\u5b9e\u9645\u4e0a\u7ea2\u9ed1\u6811\u5c31\u662f\u4e00\u4e2a4\u9636\u6811\uff0c\u4f60\u60f3\u60f3\u770b\uff08\u786e\u5b9e\uff0c\u5982\u679c\u628a\u7ea2\u9ed1\u4e24\u5c42\u770b\u4f5c\u4e00\u5c42\u7684\u8bdd\uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a4\u9636\u5e73\u8861\u6811\uff09 OpenGL \u6e32\u67d3\u7ba1\u7ebf\uff083d\u9876\u70b9\u6570\u636e -> vert shader (\u77e9\u9635\u53d8\u6362) -> \u5149\u6805\u5316+\u63d2\u503c+\u6df1\u5ea6\u6d4b\u8bd5 -> frag shader (\u524d\u5411\u7740\u8272) -> G-buffer -> \u5ef6\u8fdf\u6e32\u67d3 (\u540e\u5411\u7740\u8272) -> \u540e\u5904\u7406 -> \u5c4f\u5e55\uff09 \u6765\u9762\u8bd5\u7684\u4eba\u4e2d\uff0c\u4f60\u662f\u6211\u89c1\u8fc7\u6280\u672f\u6700\u597d\u7684\u4e00\u4e2a\uff0c\u4e4b\u524d\u4e00\u4e2a\u7855\u58eb\uff0c\u4e0a\u6765\u54c8\u5e0c\u8868\u5c31\u652f\u652f\u543e\u543e\u6302\u6389\u3002 \u4e8b\u540e\uff1a\u5df2\u5f55\u53d6\uff0c\u6b63\u5728\u4e0a\u73eding\u2026\u2026\u53c8\u662f\u505a Qt + OpenGL \u7684\u9879\u76ee","title":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c"},{"location":"interview/#_1","text":"\u6700\u8fd1\u597d\u50cf\u5f88\u6d41\u884c\u9762\u7ecf\u2026\u2026\u5c0f\u5f6d\u8001\u5e08\u4e5f\u6765\u5199\u4e00\u4e0b\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c"},{"location":"interview/#20211207","text":"\u5f20\u5265\u58eb\u5728taichi\u8bba\u575b\u91cc\u4e3b\u52a8\u627e\u4e0a\u6765\u8054\u7cfb\uff0c\u8868\u793a\u6211\u4eec\u5f88\u6b23\u8d4f\u4f60\u5728\u592a\u6781\u7684\u4f1f\u5927\u8d21\u732e\uff0c\u5e0c\u671b\u548c\u6211\u4eec\u6cfd\u68ee\u4e00\u8d77\u521b\u9020\u66f4\u597d\u7684\u65b0\u4ea7\u54c1(\u4ec0\u4e48\u6316\u5899\u89d2) \u5f20\u5265\u58eb\u5728\u5fae\u4fe1\u7535\u8bdd\u91cc\u5f00\u59cb\u8bed\u97f3\u9762\u8bd5\u4e86\uff0c\u4e0a\u6765\u5c31\u8981\u6c42\u5b9e\u73b0sqrt\u51fd\u6570(\u725b\u987f\u8fed\u4ee3\u6cd5\u5373\u53ef\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e0d\u5c0f\u5fc3\u5199\u9519\uff0c\u6709\u6b7b\u5faa\u73af\uff0c\u5f20\u5265\u58eb\u8868\u793a\u4e0d\u8981\u7d27\uff0c\u8fd9\u4e2a\u4f60\u80af\u5b9a\u73b0\u5b9e\u4e2d\u5f88\u5bb9\u6613\u8c03\u8bd5\u6539\u6b63\u7684\uff0c\u4e3b\u8981\u662f\u725b\u987f\u8fed\u4ee3\u9700\u8981\u5bfc\u6570\u7684\u89e3\u6790\u5f0f\uff0c\u5bb9\u6613\u5199\u9519\uff0cnaive\u7684\u521d\u5b66\u8005\u4e5f\u53ef\u4ee5\u9009\u62e9\u5199\u4e8c\u5206\u6cd5\uff0c\u4f59\u5207\u6cd5\u7b49) \u6709\u6ca1\u6709\u4e86\u89e3\u8fc7\u96f7\u795e3\u7684\u5feb\u901fsqrt\u51fd\u6570\uff1f(\u77e5\u9053\uff0c\u4f46\u597d\u50cf\u662f\u795e\u5947\u7684\u4e8c\u8fdb\u5236\u8fd0\u7b97\uff0c\u6ca1\u6709\u6df1\u5165\u4e86\u89e3\u8fc7\u4e3a\u4ec0\u4e48\u8fd9\u6837\u505a) \u77e5\u9053float\u7684\u5e03\u5c40\u5427(23\u4f4d\u5e95\u6570mantissa\uff0c8\u4f4d\u6307\u6570exponent\uff0c1\u4f4d\u7b26\u53f7sign) \u800c\u725b\u987f\u8fed\u4ee3\u6cd5\u9700\u8981\u8fd1\u4f3c\uff0csqrt\u6700\u597d\u7684\u8fd1\u4f3c\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u628aexponent\u4f4d\u9664\u4ee52\uff0c\u5bf9\u4e0d\u5bf9\uff1f(\u5c0f\u5f6d\u8001\u5e08\u604d\u7136\u5927\u609f\uff0c\u602a\u4e0d\u5f97\u9700\u8981\u53f3\u79fb1\u4f4d\uff0c\u539f\u6765\u662f\u8ba9exponent\u96642\uff0c\u96f7\u795e\u7684sqrt\u56e0\u4e3a\u6709\u826f\u597d\u7684\u8fd1\u4f3c\u521d\u503c\uff0c\u63a5\u4e0b\u6765\u5c31\u53ea\u9700\u8981\u4e00\u4e24\u6b65\u5c31\u80fd\u6536\u655b) \u63a5\u4e0b\u6765\u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u6211\u6709\u4ece 1 \u5230 100 \u8fd9 100 \u4e2a\u6570\uff0c\u7ec4\u6210\u8d85\u957f\u7684\u6570\u7ec4\uff0c\u968f\u673a\u6392\u5217\uff0c\u73b0\u5728\u8fd9\u91cc\u9762\u7f3a\u5c11\u4e86\u4e00\u4f4d(\u6bd4\u5982 1 2 3 4 5 7 8 9 10 \u5c31\u662f\u7f3a\u5c11\u4e86 6) \u73b0\u5728\uff0c\u6211\u4e00\u8fb9\u62a5\u6570\u4f60\u4e00\u8fb9\u64cd\u4f5c\uff0c\u6211\u62a5\u5b8c\u7684\u90a3\u4e00\u523b\uff0c\u4f60\u5fc5\u987b\u7acb\u5373\u544a\u8bc9\u6211\uff0c\u7f3a\u5931\u7684\u90a3\u4e00\u4e2a\u6570\u662f\u4ec0\u4e48\uff0c\u5e76\u4e14\u4e0d\u5141\u8bb8\u4f7f\u7528\u8bb0\u4e8b\u672c(\u4e5f\u5c31\u662f\u8981\u6c42\u5e38\u6570\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5f88\u7b80\u5355\uff0c\u4f60\u62a5\u7684\u540c\u65f6\u6211\u5f80\u4e00\u4e2a\u8ba1\u6570\u5668\u91cc\u7d2f\u52a0\u6c42\u548c\uff0c\u7136\u540e\u7b97\u51fa\u6765\u7684\u603b\u6c42\u548c\u548c 5050 \u76f8\u51cf\uff0c\u5f97\u5230\u7684\u5c31\u662f\u7f3a\u5931\u7684\u90a3\u4e2a\u6570\u4e86\uff0c\u6bd4\u5982 1+2+3+4+5+7+8+9+10 - 55 = -6\uff0c\u90a3\u4e48\u5c31\u77e5\u9053\u7f3a\u7684\u662f 6) \u5982\u679c\u6211\u662f\u7f3a\u4e86\u4e24\u4e2a\u6570\u5462\uff1f(\u90a3\u6211\u5f04\u4e24\u4e2a\u8ba1\u6570\u5668\uff0c\u4e00\u4e2a\u6c42\u548c\uff0c\u4e00\u4e2a\u6c42\u79ef\uff0c\u7136\u540e\u8054\u7acb\u4e8c\u5143\u4e8c\u6b21\u65b9\u7a0b) \u6211\u63d0\u4f9b\u4e00\u4e2a\u751f\u62100\u52301\u533a\u95f4\u5747\u5300\u968f\u673a\u6570\u7684\u51fd\u6570frand\uff0c\u5982\u679c\u6211\u6307\u5b9a\u4e00\u4e2a\u5206\u5e03\uff0c\u6bd4\u5982\u8981\u6c42\u9ad8\u65af\u5206\u5e03\uff0c\u5982\u4f55\u751f\u6210\u7b26\u5408\u8fd9\u4e2a\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff1f(frand\u662f\u5747\u5300\u968f\u673a\u6570\u51fd\u6570\uff0c\u8981\u6620\u5c04\u5230\u6307\u5b9a\u5bc6\u5ea6\u5206\u5e03\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u5148\u5bf9\u8be5\u6982\u7387\u5bc6\u5ea6\u51fd\u6570pdf\u6c42\u79ef\u5206\uff0c\u5f97\u5230\u7d2f\u79ef\u6982\u7387\u51fd\u6570cdf\uff0c\u6c42\u5176\u53cd\u51fd\u6570icdf\uff0c\u7136\u540e\u4f7f\u7528icdf(frand())\u5373\u4e3a\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff0c\u4f8b\u5982\u5bf9\u4e8e\u9ad8\u65af\u5206\u5e03\u6765\u8bf4\uff0c\u4ed6\u7684cdf\u51fd\u6570\u662ferf\uff0c\u4e5f\u5c31\u662ferfinv(frand())\u53ef\u4ee5\u751f\u6210\u9ad8\u65af\u5206\u5e03\u7684\u968f\u673a\u6570\uff09 \u5199\u4e00\u4e2a\u51fd\u6570\uff0c\u751f\u6210\u4e00\u4e2a\u5706\u5f62\u5185\u5747\u5300\u5206\u5e03\u7684\u70b9(\u521d\u5b66\u8005naive\u7684\u5199\u6cd5\uff1a\u5148\u751f\u6210\u4e00\u4e2a\u6b63\u65b9\u5f62\u7684\u5747\u5300\u5206\u5e03\u70b9\uff0c\u7136\u540e\u5224\u5b9a\u662f\u5426\u5728\u534a\u5f841\u5185\uff0c\u5982\u679c\u5728\u5219\u4fdd\u7559\uff0c\u5426\u5219\u91cd\u65b0\u751f\u6210\uff0c\u76f4\u5230\u751f\u6210\u5728\u534a\u5f84\u5185\uff1b\u5c0f\u5f6d\u8001\u5e08\u7684\u5199\u6cd5\uff1a\u9996\u5148\u6c42\u5706\u5f62\u5468\u957fS=2pir\u7684icdf\uff0c\u7136\u540eblahblah\uff0c\u6700\u7ec8\u662fr=icdf(frand())\uff0c\u7136\u540e\u518d\u968f\u673a\u4e00\u4e2atheta=frand()*2pi\uff0cx=rcostheta\uff0cy=rsintheta) \u5047\u5982\u6211\u6307\u5b9a\u7684\u51fd\u6570\u4e0d\u662f\u4e00\u4e2a\u89e3\u6790\u5f0f\uff0c\u800c\u662f\u4e00\u4e2a\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u600e\u4e48\u751f\u6210\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\uff1f(\u9996\u5148\u6c42\u8be5\u5bc6\u5ea6\u6570\u7ec4\u7684\u524d\u7f00\u548cprefix sum\uff0c\u7136\u540er=frand()\uff0c\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e0b\u6807\u4f4d\u7f6e\uff0c\u8be5\u4e0b\u6807\u5373\u4e3a\u8981\u751f\u6210\u7684\u968f\u673a\u6570\uff0c\u5982\u679c\u6709\u4e00\u4e2a\u503c\u5217\u8868\uff0c\u5219\u7528\u4e0b\u6807\u8bbf\u95ee\u8fd9\u4e2a\u503c\u5217\u8868\uff0c\u5982\u679c\u9700\u8981\u8fde\u7eed\u53d8\u5316\uff0c\u53ef\u4ee5\u5728\u7b2c\u4e00\u4e2a\u5927\u4e8e\u7b49\u4e8er\u548c\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e24\u4e2a\u5143\u7d20\u4e4b\u95f4\u6309r\u591a\u51fa\u7684\u4f59\u6570\u63d2\u503c) \u53ef\u662f\u904d\u5386\u53bb\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4f4d\u7f6e\u53ef\u80fd\u4f1a\u5f88\u6162\uff0c\u600e\u4e48\u52a0\u901f\uff1f(\u4e8c\u5206\u6cd5\u641c\u7d22\u8be5\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u53ef\u4ee5\u7528\u6807\u51c6\u5e93\u7684lower_bound) \u4e8b\u540e \u540e\u6765\u5c0f\u5f6d\u8001\u5e08\u5728\u804c\u671f\u95f4\uff0c\u5f20\u5265\u58eb\u4e00\u987f\u5439\u6367\uff1a\u4f60\u662f\u6211\u4eec\u8fd9\u91cc\u552f\u4e00\u4e00\u4e2a\u901a\u8fc7\u7845\u8c37\u7ea7\u4eba\u624d\u6d4b\u8bd5\u7684\u5458\u5de5\uff0c\u4e00\u89c1\u5230\u65b0\u5458\u5de5\u5c31\u5439\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u770b\u770b\u4eba\u5bb6\u5c0f\u5f6d\u8001\u5e08\u3002 \u5f20\u5265\u58eb\u8fd8\u753b\u51fa\u4e86\u671f\u6743\u5927\u997c\uff0c\u8bb2\u4e86\u4e00\u7cfb\u5217\u6211\u542c\u4e0d\u61c2\u7684\u865a\u62df\u671f\u6743\u6982\u5ff5\u91d1\u6eb6\u672f\u8bed\u540e\uff0c\u603b\u4e4b\u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\u9f13\u52b1\u5c0f\u5f6d\u8001\u5e08\u594b\u6597\uff0c\u594b\u6597\u7684\u516c\u53f8\u80a1\u4ef7\u6da8\u4e86\u5c31\u80fd\u5206\u7ea2\uff0c\u4f46\u76f4\u5230\u6700\u540e\u90fd\u6ca1\u6709\u5151\u73b0\uff0c\u800c\u4e14\u636e\u4e86\u89e3\u4e0a\u5e02\u516c\u53f8\u624d\u6709\u671f\u6743\u2026\u2026 \u5c0f\u5f6d\u8001\u5e08\u770b\u5230\u5f20\u5265\u58eb\u8fd9\u4e48\u91cd\u7528\uff0c\u4ee5\u4e3a\u6bd5\u4e1a\u4ee5\u540e\u80af\u5b9a\u7ed9\u8f6c\u6b63\u4e86\uff0c\u6240\u4ee5\u5c31\u6ca1\u6709\u8003\u7814\uff0c\u6ca1\u6709\u53bb\u770b\u6821\u62db\uff0c\u4e5f\u6ca1\u6709\u63a5\u53d7\u5b66\u6821\u7684\u5bf9\u63a5\uff0c\u5fd8\u6211\u5730\u4f3a\u5019zeno\u5de5\u4f5c\uff0c\u6253\u7b97\u4e00\u6bd5\u4e1a\u5c31\u76f4\u63a5\u53bb\u6df1\u5733\u4f3a\u5019\u5f20\u5265\u58eb\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 zeno \u7684\u5de5\u4f5c\u57fa\u672c\u5b8c\u6210\u4e86\uff0c\u627e\u4e0d\u5230\u6709\u4ec0\u4e48\u9700\u8981\u505a\u7684\uff0c\u5f20\u5265\u58eb\u7a81\u7136\u5f00\u59cb\u53cd\u590d\u7c97\u9119\u8bed\u8a00\u7f9e\u8fb1\u5c0f\u5f6d\u8001\u5e08\uff0cpua\u5c0f\u5f6d\u8001\u5e08\uff0c\u66f0\u201c\u4f60\u662f\u7a0b\u5e8f\u5458\u9493\u4e1d\u601d\u7ef4\u201d\u201c\u6839\u672c\u4e0d\u61c2\u6211\u4eec\u7684\u5b9e\u9645\u9700\u6c42\u201d\u201c\u4f60\u4eec\u9493\u4e1d\u7a0b\u5e8f\u5458\u662f\u6700\u4e0d\u61c2\u7f8e\u672f\u7d20\u517b\u7684\u201d\uff0c\u770b\u5728\u5265\u58eb\u8fd8\u5728\u53d1\u5de5\u8d44\u7684\u4efd\u4e0a\uff0c\u5c31\u6ca1\u6709\u7406\u5b83\u3002 \u5c0f\u5f6d\u8001\u5e08\u7ec8\u4e8e\u6bd5\u4e1a\u4e86\uff0c\u8868\u793a\u53ef\u4ee5\u8f6c\u6b63\uff0c\u8fd9\u65f6\u5f20\u5265\u58eb\u5374\u51fa\u5c14\u53cd\u5c14\uff0c\u5404\u79cd\u63a8\u8131\uff0c\u66f0\u201c\u8d44\u91d1\u56f0\u96be\u201d\u201c\u8bf7\u4e0d\u52a8\u5c0f\u5f6d\u8001\u5e08\u201d\u201c\u7b49\u62119\u6708\u62c9\u5230\u6295\u8d44\u597d\u4e0d\u597d\u201d\uff0c\u7136\u800c\u81f3\u4eca\u6ca1\u6709\u53cd\u5e94\uff0c\u8f6c\u5934\u5c31\u770b\u5230\u670b\u53cb\u5708\u5728\u53d1\u5e03\u5916\u5305jd\u3002 \u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u201c\u54c0\u6c42\u201d\u5f20\u5265\u58eb\u201c\u5f00\u773c\u201d\uff0c\u5f20\u5265\u58eb\u53cd\u590d\u63a8\u8131\u540e\uff0c\u7ec8\u4e8e\u8868\u793a\uff1a\u770b\u5728\u4f60\u5bf9zeno\u4e5f\u6709\u201c\u611f\u60c5\u201d\u4e86\uff0c\u5982\u679c\u4f60\u8fd8\u60f3\u4e3a\u6211\u4eeczeno\u7ee7\u7eed\u201c\u8d21\u732e\u201d\u7684\u8bdd\uff0c\u53ef\u4ee5\u5f00\u51fa5k\u4f4e\u4ef7\u91cd\u65b0\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\uff0c\u7b49\u201c\u62c9\u5230\u6295\u8d44\u201d\u201c\u8d44\u91d1\u4e0d\u56f0\u96be\u201d\u65f6\uff0c\u518d\u7ed9\u5c0f\u5f6d\u8001\u5e08\u201c\u8865\u8d34\u201d\u56de\u539f\u6765\u768416k\u5de5\u8d44\uff0c\u540c\u65f6\u770b\u5230\u5f20\u5265\u58eb\u5728\u7fa4\u91cc\u70ab\u8000\u4ed6\u8239\u65b0\u7684\u7b49\u8eab\u624b\u529e(\u5c04)\u3002 \u5f20\u5265\u58eb\u81ea\u6211\u611f\u52a8\u6f14\u7684\u60df\u5999\u60df\u8096\uff0c\u5c0f\u5f6d\u8001\u5e08\u8003\u8651\u5230\u5f20\u5265\u58eb\u671f\u6743\u5927\u997c\u7684\u524d\u8f66\u4e4b\u9274\uff0c\u5c31\u6ca1\u6709\u76f8\u4fe1\u5265\u58eb\u7684\u201c\u597d\u610f\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\u53ea\u597d\u4ee5\u672c\u79d1\u5e94\u5c4a\u751f\u8eab\u4efd\u5f00\u59cb\u5bfb\u627e\u5de5\u4f5c\uff0c\u5176\u4e2dhr\u7ecf\u5e38\u62f7\u95ee\u201c\u6211\u770b\u4f601\u6708\u5230\u73b0\u5728\u90fd\u662f\u6ca1\u6709\u5de5\u4f5c\u7684\u72b6\u6001\uff1f\u201d\u201c\u8bf4\u4e00\u4e0b\u79bb\u804c\u539f\u56e0\u201d\u9020\u6210\u5f88\u5927\u7684\u9ebb\u70e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u5c55\u793a\u201c\u5de5\u4f5c\u7ecf\u9a8c\u201d\u65f6\uff0chr\u603b\u662f\u53cd\u590d\u5f3a\u8c03\u201c\u6211\u770b\u4f60\u624d\u521a\u6bd5\u4e1a\u5440\uff1f\u201d\uff0c\u8ba4\u4e3a\u201c\u5b9e\u4e60\u7ecf\u9a8c\u201d\u4e0d\u7b97\uff0c\u5bfc\u81f4\u5c0f\u5f6d\u8001\u5e08\u5728\u5f20\u5265\u58eb\u7684\u7ecf\u9a8c\u51e0\u4e4e\u4f5c\u5e9f\uff0c\u800c\u5e94\u5c4a\u751f\u4f18\u60e0\u53c8\u88ab\u5f20\u5265\u58eb\u8017\u6389\uff0c\u7136\u800c\uff0c\u5b83\u53ea\u8981\u770b\u4e00\u4e0bzeno\u8d21\u732e\u6392\u884c\u699c\u5c31\u77e5\u9053\uff0c\u5c0f\u5f6d\u8001\u5e08\u7684\u8d21\u732e\u662f\u7b2c\u4e00\u7684\u3002 \u6240\u6709\u6cfd\u68ee\u5458\u5de5\u90fd\u9700\u8981\u719f\u6089\u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u8fed\u4ee3\u8fc7\u7684\u8282\u70b9\u7cfb\u7edf\uff0c\u624d\u80fd\u5f00\u59cb\u4ed6\u7684zeno\u5f00\u53d1\uff0c\u66f4\u4f55\u51b5\u5c0f\u5f6d\u8001\u5e08\u8fd8\u8d21\u732e\u4e86\u5305\u62ec\u8282\u70b9\u7f16\u8f91\u5668\u3001Python bindings\u3001\u5b9e\u65f6\u4e09\u7ef4\u89c6\u7a97\u3001\u591a\u8fdb\u7a0b\u901a\u4fe1\u3001\u78c1\u76d8\u7f13\u5b58\u3001\u5bf9\u8c61\u5e8f\u5217\u5316\u3001\u5b9e\u65f6optix\u3001shader\u8282\u70b9\u3001GLSL codegen\u3001\u521a\u4f53\u4eff\u771f\u3001Prim\u5c5e\u6027\u7cfb\u7edf\u3001ZFX\u7f16\u8bd1\u5668\u3001PrimPrim \u90bb\u5c45\u67e5\u627e\u3001\u63d2\u4ef6\u7cfb\u7edf\u3001ABC \u52a0\u8f7d\u5668\u3001\u51e0\u4f55\u8282\u70b9\u3001VDB \u8282\u70b9\u3001\u6d41\u4f53\u5b50\u56fe\u3001Blender \u63d2\u4ef6\u3001OpenSubdiv \u96c6\u6210\u3001libigl \u96c6\u6210\u3001CI/CD \u5de5\u4f5c\u6d41\u7b49\u8bf8\u591a\u529f\u80fd\u3002 \u5f20\u5265\u58eb\u53d1\u77e5\u4e4e\u6587\u7ae0\u7206\u8bba\uff1a\u6211\u4eec\u4e0d\u9700\u8981\u7a0b\u5e8f\u5458\uff01\u53ea\u9700\u8981\u5076\u5c14\u62db\u4e24\u4e2a\u5389\u5bb3\u4e00\u70b9\u7684\u5b9e\u4e60\u751f\uff0c\u505a\u4e2a\u4e00\u4e24\u5e74\uff0c\u628a\u8f6f\u4ef6\u505a\u5b8c\u4ee5\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u4ed6\u4eec\u4e86\uff0c\u663e\u7136\u5c0f\u5f6d\u8001\u5e08\u5c31\u662f\u8fd9\u6837\u4e00\u4e2a\u4e00\u6b21\u6027\u53c8\u7279\u522b\u597d\u7528\u7684\u5b9e\u4e60\u751f\u3002","title":"\u6cfd\u68ee\u79d1\u5de5 (2021.12.07)"},{"location":"interview/#unity-20240812","text":"\u4e00\u4e2a\u770b\u8d77\u6765\u53ef\u80fd\u662f\u8001\u677f\u7684\u4eba\u7269\u51fa\u9762\u8fce\u63a5\uff0c\u8fdb\u5165\u4e00\u4e2a\u72ec\u7acb\u7684\u4f1a\u8bae\u5ba4\u5f00\u59cb\u9762\u8c08\u3002 \u4e4b\u524d\u73a9\u8fc7\u54ea\u4e9b\u6e38\u620f\uff1f(\u4e3b\u8981\u662f\u8089\u9e3d\u548c\u6a21\u62df\u7ecf\u8425\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u6740\u622e\u5c16\u5854\u548cKSP\uff0c\u56e0\u4e3a\u4ed6\u4eec\u662fUnity\u6e38\u620f\uff0c\u8fd8\u4ecb\u7ecd\u4e86\u5236\u4f5c\u4ee5\u6492\u7684\u7ed3\u5408\u6a21\u7ec4\u7684\u7ecf\u5386\uff0c\u57fa\u4e8eLua API\u7684) \u9762\u8bd5\u5b98\u8bf4\u73b0\u5728 KSP2 \u6ca1\u6709\u5361\u987f\u4e86\uff0c\u56e0\u4e3a GC \u4f18\u5316\u4e86 \u95ee\u5b66\u8fc7Unity\u5417\uff1f(\u4e86\u89e3\u4e00\u70b98\uff0c\u4e4b\u524d\u505a\u8fc7KSP\u6a21\u7ec4) \u95ee\u90a3\u4e48\u4f60\u7684Unity\u7248\u672c\uff1f(\u7cdf\u7cd5\uff0c\u53ea\u80fd\u88c5\u50bb\u4e86\uff0c\u56e0\u4e3a\u5176\u5b9e\u5f88\u4e45\u6ca1\u6253\u5f00\u8fc7\u4e86\uff0c\u800c\u4e14\u65b0\u7535\u8111\u91cc\u4e5f\u6ca1\u6709\u4e0bUnity) \u8868\u793a\u4f60\u5e94\u8be5\u591a\u770b\u770bUnity\u5b98\u65b9\u6587\u6863\uff0c\u7279\u522b\u662f\u82f1\u6587\u7684\u6587\u6863 \u95eePBR\u6d41\u7a0b\uff1f(\u5206\u4e3aLambert\u548cCook-Torrance\u4e24\u4e2a\u6a21\u578b\uff0c\u5408\u5e76\u8d77\u6765\uff0clambert\u5f88\u7b80\u5355\u7684\u5168\u65b9\u5411\u968f\u673a\u6f2b\u53cd\u5c04\uff0c\u4ecb\u7ecd\u4e86NDF, GDF, FDF\u4e09\u4e2a\u51fd\u6570\u7684\u7269\u7406\u610f\u4e49) \u95eeCg\u7740\u8272\u8bed\u8a00\uff1f(Unity\u81ea\u5df1\u7684\u7740\u8272\u5668\u8bed\u8a00\uff0c\u4e0d\u719f\u6089\uff0c\u8868\u793a\u4e4b\u524d\u5199\u7684\u90fd\u662fGLSL\uff0c\u4f46\u6211\u77e5\u9053\u6240\u6709\u5f15\u64ce\u90fd\u6709\u4e00\u4e2a\u94a6\u5b9a\u8bed\u8a00\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u4f1a\u7ffb\u8bd1\u751f\u6210\u4e0d\u540c\u7684\u76ee\u6807\u8bed\u8a00\u6bd4\u5982GLSL\uff0cUnity\u4e5f\u652f\u6301\u5199GLSL\uff0c\u4f46\u90e8\u5206\u529f\u80fd\u7279\u6027API\u6709\u6240\u7f3a\u5931\uff0c\u6240\u4ee5\u4e3b\u8981\u8fd8\u662f\u5199Cg\uff0c\u5728GL\u540e\u7aef\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u751f\u6210GLSL\u7684) \u5c0f\u5f6d\u8001\u5e08\u63d0\u8d77\u4e3a\u4e86\u652f\u6301UE\uff0c\u7279\u522b\u505a\u4e86HLSL\u540e\u7aef(\u9762\u8bd5\u5b98\u9510\u8bc4\u4e86\u715e\u7b14DX\u4e0d\u8de8\u5e73\u53f0\uff0c\u73b0\u5728\u6e38\u620f\u4e3b\u8981\u8fd8\u662f\u57fa\u4e8eOpenGL\u5728\u505a\uff0cUE\u662f\u56e0\u4e3a\u5fae\u8f6f\u7ed9\u94b1\u4e86\u624d\u94a6\u5b9aHLSL\u4e3a\u4e3b\u8bed\u8a00\uff0c\u4f46\u5b9e\u9645\u4e0a\u4e5f\u6709\u7ffb\u8bd1\u5230GLSL\u7684OpenGL\u540e\u7aef) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u8868\u793a\u6211\u4eec\u505a\u7684\u662fUnity\u7684\u5fae\u4fe1\u5c0f\u6e38\u620f\uff0c\u56e0\u4e3a\u6700\u8fd1\u63a8\u51fa\u7684WebGL\u540e\u7aef(\u5c0f\u5f6d\u8001\u5e08\uff1a\u602a\u4e0d\u5f97\u53ef\u4ee5\u770b\u5230\u6700\u8fd1\u8fd9\u4e48\u591a\u5fae\u4fe1\u5c0f\u6e38\u620f) \u95ee\u4e86 Lua(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u5199\u7684 Lua \u811a\u672c\u5b9e\u73b0\u4ee5\u6492\u6a21\u7ec4) \u6211\u4eec\u4e0d\u662f\u8981\u5199 Lua\uff0c\u800c\u662f\u8981\u8c03\u7528 Lua \u7684 C \u63a5\u53e3\u54e6\uff01(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e5f\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u53c2\u4e0e\u7684\u4e00\u4e2a\u4ee5\u6492\u6a21\u7ec4\u9879\u76ee IsaacSocket \u5c31\u662f\u57fa\u4e8e C# \u5ba2\u6237\u7aef\uff0c\u52a8\u6001\u5f80\u4ee5\u6492\u8fdb\u7a0b\u6ce8\u5165 C++ DLL\uff0c\u52ab\u6301\u4ee5\u6492\u7684\u5404\u79cd\u56de\u8c03\uff0c\u7136\u540e\u66b4\u9732\u51fa Lua \u63a5\u53e3\uff0c\u521b\u5efa\u4e86\u4e00\u7cfb\u5217\u5bf9\u6e38\u620f\u5185 Lua \u811a\u672c\u53ef\u89c1\u7684 C++ \u51fd\u6570\uff0c\u5b9e\u73b0\u4ee5\u6492 API \u7684\u6269\u5c55\uff0c\u9700\u8981 lua_tonumber \u6765\u83b7\u53d6\u53c2\u6570\uff0clua_pushnumber \u6765\u8fd4\u56de\u503c\u7b49) \u95ee\u4e86 lua_State \u662f\u4ec0\u4e48(\u5c0f\u5f6d\u8001\u5e08\uff1a\u542b\u6709 lua \u7684\u5806\u6808\u5168\u5c40\u53d8\u91cf\u7b49\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u5404\u81ea\u72ec\u7acb) \u95ee\u5982\u4f55\u521b\u5efa\u4e00\u4e2a UI \u754c\u9762\uff1f\u9009\u62e9\u4e0d\u540c\u7684\u670d\u52a1\u5668\uff0c\u767b\u5f55(\u4f7f\u7528json+http\u5b9e\u73b0rpc\uff0c\u83b7\u5f97\u4e00\u4e2a\u5217\u8868\uff0c\u7136\u540e\u8bbe\u7f6e\u5217\u8868\uff0c\u5373\u53ef\u5229\u7528MVC\u521b\u5efa\u51fa\u754c\u9762) Unity \u7684 UI \u7cfb\u7edf\u4f1a\u5199\u5417\uff1f(\u4e0d\u4f1a\uff0c\u53ea\u77e5\u9053Qt\u6709QListView\u63a7\u4ef6\uff0cUnity\u53ef\u80fd\u4e5f\u6709\u5427\uff1f)","title":"\u67d0 Unity \u5c0f\u5382 (2024.08.12)"},{"location":"interview/#20240815","text":"1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 2\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 \u6ca1\u67093\u9762\u4e86\uff0c\u539f\u56e0\u4e0d\u660e\u3002","title":"\u851a\u6765\u5c0f\u6c7d\u8f66 (2024.08.15)"},{"location":"interview/#20240903","text":"1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 \u8981\u6c42\u81ea\u6211\u4ecb\u7ecd(\u4e3b\u8981\u4ecb\u7ecd\u4e86\u6cfd\u68ee\u5728\u6e32\u67d3\u7684\u5de5\u4f5c\uff0cshader\u8282\u70b9\u7b49\uff0c\u4e0d\u4ec5\u8d1f\u8d23\u4e86Qt+OpenGL\u5b9e\u65f6\u53ef\u89c6\u5316\uff0c\u540e\u6765\u8fd8\u52a0\u5165\u4e86OptiX\u5b9e\u65f6\u5149\u8ffd\u652f\u6301) \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecdzeno\u7684shader\u8282\u70b9\u652f\u6301\u8f93\u51fa\u4e3aGLSL\u3001HLSL\u3001CUDA\u4e09\u79cd\u540e\u7aef\u683c\u5f0f\uff0c\u90fd\u662fcodegen\uff0c\u5176\u4e2dCUDA\u540e\u7aef\u91c7\u7528NVPTX\u7f16\u8bd1\uff0c\u4f9bOptiX\u4f7f\u7528 \u4ecb\u7ecdPBR\u6d41\u7a0b(albedo, metallic, roughness \u7b49\uff0c\u8fd8\u6709\u6cd5\u7ebf\u8d34\u56fe\u7684\u70d8\u70e4\uff0cIBL \u5149\u7167\u7b49) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u4ecb\u7ecd\u4e86\u516c\u53f8\u5185\u90e8\u662f\u6709\u5d4c\u5165\u5f0f(\u4e09\u7ef4\u6355\u83b7\u8bbe\u5907)\u548c\u7535\u8111\u7aef(\u7528\u4e8e\u67e5\u770b\u4e09\u7ef4\u6355\u83b7\u7ed3\u679c\u7684App)\uff0c\u5d4c\u5165\u5f0f\u8bbe\u5907\u53ea\u9700\u8981\u505a\u521d\u6b65\u7684\u6570\u636e\u5904\u7406\uff0c\u57fa\u4e8e\u56fd\u4ea7GPU(\u4f46\u662fCUDA\u63a5\u53e3)\uff0c\u521d\u6b65\u5904\u7406\u540e\u56de\u4f20\u7528\u6237\u7535\u8111\uff0c\u7535\u8111\u7aef\u53ef\u4ee5\u5047\u5b9a\u7528\u6237\u662fNVIDIA\u663e\u5361(\u4e5f\u662fCUDA\u63a5\u53e3)\u7528\u4e8e\u66f4massive\u7684\u540e\u5904\u7406\u548c\u6e32\u67d3\u53ef\u89c6\u5316 \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecd\u5728taichi three\u4e2d\u624b\u6413\u8f6f\u5149\u6805\u6e32\u67d3\u5668\u7684\u7ecf\u5386(\u652f\u6301ssr, ssgi, taa\u7b49) 2\u9762\uff08LeetCode\u5728\u7ebf\u9762\u8bd5\uff0c\u6709\u5171\u4eab\u4ee3\u7801\u7f16\u8f91\u5668\uff09 \u8981\u6c42\u5c0f\u5f6d\u8001\u5e08\u81ea\u6211\u4ecb\u7ecd(\u7b80\u5386\u4ed6\u5df2\u7ecf\u62ff\u5230\u770b\u7740\u4e86\uff0c\u5c31\u4e0d\u590d\u8bfb\u540d\u5b57\u548c\u5b66\u5386\u4e86\uff0c\u6240\u4ee5\u4e3b\u8981\u4ecb\u7ecd\u9879\u76ee\uff0c\u5728zeno\u4e2d\uff0c\u5c0f\u5f6d\u8001\u5e08\u62c5\u4efb\u6e32\u67d3\u548c\u8282\u70b9\u7cfb\u7edf\u7684\u5f00\u53d1\uff0c\u4ecb\u7ecdQt+OpenGL\u89c6\u7a97\u53ef\u89c6\u5316\uff0c\u4ecb\u7ecd\u8282\u70b9\u7cfb\u7edf\u7c7b\u4f3c\u4e8e\u4f4e\u4ee3\u7801\u7684\u4f18\u52bf\uff0c\u7b80\u8981\u4ecb\u7ecdtaichi, nbodysolver, co_async\u2026\u2026\u70ab\u8000\u9ad8\u6548\u7684\u534f\u7a0b\uff0c\u5e76\u5b89\u5229\u5c0f\u5f6d\u8001\u5e08\u6bd4\u7ad9\u9891\u9053\uff0ccpp\u516c\u5f00\u8bfe) \u9762\u8bd5\u5b98\u8868\u793a\u4e0d\u719fcpp20\uff0c\u63d0\u51fa\u8981\u4ee5cpp17\u4e3a\u57fa\u7840(\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u5728zeno\u548ctaichi\u4e5f\u90fd\u662f\u7528cpp17) cpp\u6709\u54ea\u56db\u5927cast(static_cast, dynamic_cast, const_cast, reinterpret_cast) static_cast vs dynamic_cast\u9002\u7528\u573a\u666f(\u5b50\u7c7b\u8f6c\u57fa\u7c7b\u603b\u662fstatic_cast\uff0c\u4e00\u4e2a\u57fa\u7c7b\u6307\u9488\uff0c\u5982\u679c\u4e0d\u80fd\u786e\u5b9a\u662f\u4e0d\u662f\u5b50\u7c7b\uff0c\u90a3\u5c31\u9700\u8981dynamic_cast\uff0c\u5982\u679c\u5931\u8d25\u4f1a\u8fd4\u56denullptr\uff0c\u8bb0\u5f97\u68c0\u67e5\uff01\u5982\u679cdynamic_cast\u5f15\u7528\u5219\u5931\u8d25\u629b\u51fabad_cast\u5f02\u5e38) dynamic_cast\u80cc\u540eRTTI\u539f\u7406(\u5b9e\u9645\u4e0a\u662f\u6bd4\u8f83typeid\u662f\u5426\u517c\u5bb9\uff0ctypeid\u6307\u9488\u5b58\u5728\u865a\u51fd\u6570\u8868\u91cc\uff0c\u53ea\u6709\u5e26\u6709\u81f3\u5c111\u4e2a\u865a\u51fd\u6570\u7684\u79f0\u4e3a\u201c\u591a\u6001\u7c7b\u201d\u7684\u7c7b\u578b\u4f1a\u751f\u6210RTTI\u4fe1\u606f\uff0c\u987a\u4fbf\u63a8\u9500\u4e86\u4e3a\u4ec0\u4e48llvm\u9009\u62e9\u5f00\u542f-fno-rtti\u548c-fno-exception\uff0c\u662f\u907f\u514d\u4e8c\u8fdb\u5236\u81a8\u80c0) llvm\u5173\u95ed\u4e86RTTI\uff0c\u90a3\u4ed6\u662f\u5982\u4f55\u53d8\u76f8\u5b9e\u73b0dynamic_cast\u7684\uff1f(\u6211\u77e5\u9053\uff0c\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff01\u5b9a\u4e49\u4e86getType\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u679a\u4e3e\uff0c\u7528\u4e8e\u6bd4\u8f83) \u53ef\u662f\u5982\u679cD2\u7ee7\u627fD1\u7ee7\u627fB\uff0c\u5982\u4f55\u4fdd\u8bc1D2\u4e5f\u53ef\u4ee5cast\u4e3aD1\uff1f(\u5b8c\u4e86\uff0cllvm\u6e90\u7801\u770b\u7684\u4e0d\u4ed4\u7ec6\uff0c\u53ea\u80fd\u7528\u4ee5\u6492\u7684\u505a\u6cd5\u76f2\u731c\u4e00\u4e2a\uff1a\u662fB\u6709getD1\u548cgetD2\u4e24\u4e2a\u865a\u51fd\u6570\uff01\u4ed6\u4eec\u9ed8\u8ba4\u8fd4\u56denullptr\uff0c\u53ea\u6709D1\u4f1a\u91cd\u5199getD1\uff0cD2\u4f1a\u91cd\u5199getD2\uff0c\u5185\u90e8\u90fd\u662f\u7b80\u5355\u7684\u8fd4\u56dethis) const_cast\u672a\u5b9a\u4e49\u884c\u4e3a(\u672c\u6765\u662fconst\u7684\u4e0d\u80fd\u53bb\u6389const\u540e\u8bbf\u95ee\uff0c\u5c55\u793a\u4e86\u6210\u5458\u51fd\u6570\u590d\u7528\u4e24\u4e2adata\u7684\u7528\u6cd5) const_cast\u540e\u8fd4\u56de\u6307\u9488\u6ca1\u95ee\u9898\uff0c\u9762\u8bd5\u5b98\u6539\u6210\u8fd4\u56de\u5f15\u7528\uff0c\u6d89\u53ca\u89e3\u5f15\u7528\uff0c\u95ee\u8fd9\u6837\u8fd8\u5b89\u5168\u5417\uff1f(\u8ff7\u60d1\u6027\u5f88\u5f3a\u7684\u95ee\u9898\uff0c\u88ab\u5c0f\u5f6d\u8001\u5e08\u8bc6\u7834\uff1a\u975econst\u5730\u89e3\u5f15\u7528const\u53d8\u91cf\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u53d6\uff0c\u5c31\u548cend\u8fed\u4ee3\u5668\u4e0d\u80fd\u89e3\u5f15\u7528\u4e00\u6837\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u5199\u8bbf\u95ee) const vs constexpr\u53d8\u91cf\u533a\u522b(const\u53ef\u4ee5\u6709\u5730\u5740\uff0c\u800cconstexpr\u4e0d\u4e00\u5b9a\u6709) reinterpret_cast\u7528\u6cd5\uff0c\u4ec0\u4e48\u60c5\u51b5\u4e0b\u5b89\u5168(\u5c0f\u5f6d\u8001\u5e08\u5199\u7ecf\u5178\u4e3e\u51faint\u548cfloat\u4e4b\u95f4bit-cast\u7684\u6848\u4f8b\uff0c\u4ecb\u7ecd\u503c\u8f6c\u6362\u548c\u6309\u4f4d\u8f6c\u6362\u7684\u533a\u522b\uff0c\u52fe\u5f15\u9762\u8bd5\u5b98\u4e0a\u94a9\uff0c\u4ed6\u80af\u5b9a\u8ba4\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4e0d\u77e5\u9053reinterpret_cast\u4e0d\u80fd\u505aint\u548cfloat\u7684\u6307\u9488\u8f6c\u6362\uff0c\u4e8e\u662f\u53d1\u95ee\uff1a) \u9762\u8bd5\u5b98\u5199\u51faint\u548cfloat\u6307\u9488\u5f3a\u8f6c\u5e76\u89e3\u5f15\u7528\u7684\u4ee3\u7801\uff0c\u95ee\u8fd9\u4e2a\u5b89\u5168\u5417\uff1f(\u4e0a\u94a9\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u5373\u7b54\uff1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e0d\u80fd\u7528reinterpret_cast\u8f6cint\u548cfloat\u6307\u9488\uff0c\u662f\u56e0\u4e3astrict-aliasing\u8ba4\u4e3aint\u548cfloat\u4e0d\u517c\u5bb9\uff0c\u8f6c\u6362\u540e\u89e3\u5f15\u7528\u5373UB\uff0c\u9762\u8bd5\u5b98\u8bf4\u4f3c\u4e4e\u53ea\u6709GCC\u4f1a\u7528\u8fd9\u4e2a\uff0c\u5c0f\u5f6d\u8001\u5e08\u7b54\uff1aGCC\u9ed8\u8ba4\u5f00\u542f\uff0c\u53ef\u4ee5\u7528-fno-strict-aliasing\u5173\u95ed\uff0cMSVC\u4e0d\u5229\u7528\u6b64\u89c4\u5219\u4f18\u5316\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u4ecb\u7ecd\u6307\u9488\u522b\u540d\u4e0e\u4f18\u5316\u7684\u5173\u7cfb\uff0c\u5373\u4e3a\u4ec0\u4e48\u63d0\u51fastrict-aliasing\u89c4\u5219\u7684\u539f\u56e0) \u5c0f\u5f6d\u8001\u5e08\u5f3a\u8c03int\u548cunsigned int\u662f\u517c\u5bb9\uff0c\u9762\u8bd5\u5b98\u5c31\u95ee\u4e3a\u4ec0\u4e48char\u53ef\u4ee5\uff1f(reinterpret_cast\u6709\u7834\u683c\u5141\u8bb8\u7684\u7279\u4f8b\uff0cchar,unsigned char,std::byte\u4e0e\u6240\u6709\u7c7b\u578b\u90fd\u517c\u5bb9\uff0c\u8f6c\u4e3achar\u6307\u9488\u540e\u53ef\u4ee5\u968f\u610f\u8bbf\u95ee\u4efb\u610f\u7c7b\u578b\u7684\u5185\u5b58\uff0c\u6307\u51fa\u662fcpp\u6807\u51c6\u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u89e3\u5e8f\u5217\u5316\u7684\u65b9\u4fbf\u6027) \u5982\u4f55\u5b9e\u73b0\u771f\u6b63\u5b89\u5168\u7684int\u548cfloat\u8f6c\u6362\uff1f(\u4f7f\u7528memcpy\u6216cpp20\u7684bit_cast\u662f\u5b89\u5168\u7684\uff0c\u5e76\u63a8\u9500memcpy vs bit_cast\u533a\u522b\uff1a\u867d\u7136cppref\u4e0abit_cast\u7684\u201c\u53c2\u8003\u5b9e\u73b0\u201d\u662fmemcpy\uff0c\u4f46\u5f97\u76ca\u4e8e\u5176\u57fa\u4e8e\u7f16\u8bd1\u5668\u5f00\u6d1e__builtin_bit_cast\uff0c\u8ba9bit_cast\u662fconstexpr\u51fd\u6570\u53ef\u7f16\u8bd1\u671f\u786e\u5b9a) inline\u5173\u952e\u5b57\u4f5c\u7528(non-odr external linkage\uff0c\u5efa\u8bae\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u7684\u51fd\u6570\u90fd\u52a0inline\uff0c\u5426\u5219\u591a\u4e2a.cpp\u6587\u4ef6\u4e2d\u4ea7\u751f\u591a\u4e2a\u5b9a\u4e49\uff0c\u89e6\u53d1\u94fe\u63a5\u5668odr\u62a5\u9519\uff0c\u800cinline\u5219\u662f\u975endr\u7684\u5916\u90e8\u94fe\u63a5) \u9762\u8bd5\u5b98\u95eeinline\u51fd\u6570\u591a\u4e2a\u6587\u4ef6\u4e2d\u770b\u5230\u7684\u51fd\u6570\u4f53\u5b9a\u4e49\u4e0d\u540c\uff0c\u4f46\u51fd\u6570\u53c2\u6570\u5217\u8868\u76f8\u540c\uff0c\u4f1a\u600e\u4e48\u6837\uff1f(\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6807\u51c6\u8981\u6c42\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709.cpp\u7ffb\u8bd1\u5355\u5143\u770b\u5230\u7684inline\u51fd\u6570\u5b9a\u4e49\u4e00\u81f4\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u5f80\u5f80\u5e76\u4e0d\u62a5\u9519) \u5c0f\u5f6d\u8001\u5e08\u63a8\u9500\uff1a\u8fd9\u5bfc\u81f4\u4f60\u5728cpp\u6587\u4ef6\u4e2d\u5b9a\u4e49\u975ePOD\u7c7b\u4f1a\u88ab\u5751\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9a\u4e49\u7684\u6210\u5458\u51fd\u6570\uff0c\u9ed8\u8ba4\u662finline\u7684\uff0c\u5305\u62ec\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5f53\u65f6\u5bfc\u81f4zeno\u8c03\u8bd5\u4e86\u534a\u5929(\u9762\u8bd5\u5b98\u8868\u793a\u4ed6\u4e4b\u524d\u96c6\u6210\u4e00\u4e2a\u5f00\u6e90\u5e93\u4e5f\u9047\u5230\u8fd9\u4e2a\u5751\uff0c\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u53ef\u4ee5\u5957\u533f\u540dnamespace\u89e3\u51b3) push_back vs emplace_back(2\u91cd\u8f7dvs\u4e07\u80fd\u5f15\u7528+\u53d8\u957f\u53c2\u6570\uff0cemplace\u53ef\u4ee5\u5c31\u5730\u5e26\u4efb\u610f\u53c2\u6570\u6784\u9020\u4f60\u7684\u5143\u7d20\u7c7b\u578b\uff0cemplace\u7684\u989d\u5916\u597d\u5904\u662f\u89e6\u53d1explicit\u7684\u6784\u9020\u51fd\u6570\u800c\u65e0\u9700\u663e\u5f0f\u5199\u51fa\u7c7b\u540d\uff0c\u4e5f\u5e26\u6765\u4e86\u5371\u9669\uff0c\u6240\u4ee5\u6211\u5728\u8bfe\u7a0b\u4e2d\u90fd\u4e0d\u63a8\u8350\u4f7f\u7528\uff0c\u5982\u9700\u907f\u514d\u79fb\u52a8\u53ef\u4ee5 vector> \uff0c\u8fd9\u8fd8\u80fd\u4f7f\u6269\u5bb9\u65f6\u4e5f\u4e0d\u89e6\u53d1\u79fb\u52a8) \u4ec0\u4e48\u60c5\u51b5\u4e0b\u4e0d\u4f1a\u79fb\u52a8\uff1f\u9762\u8bd5\u5b98\u4f3c\u4e4e\u5728\u8bd5\u63a2\u6211\u662f\u5426\u4e86\u89e3 vector \u6269\u5bb9\u539f\u7406(\u53ea\u6709\u5f53size>capacity\u65f6\u624d\u4f1a\u89e6\u53d1\uff0c\u6bcf\u6b21\u89e6\u53d1\u6269\u5bb9\u65f6gcc\u589e\u52a0\u52302 x size\uff0cmsvc\u5219\u662f1.5 x size\uff0c\u603b\u51712n\u6b21\u64cd\u4f5c\uff0c\u597d\u5904\u662f\u4fdd\u8bc1\u4e86\u603b\u4f53O(n)\u590d\u6742\u5ea6\uff0c\u6211\u4eec\u5efa\u8bae\u77e5\u9053\u957f\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528reserve\u63d0\u524d\u9884\u8ba2100\u7684capacity\uff0c\u8fd9\u6837\u53ea\u6709\u63a8\u5165\u7b2c101\u4e2a\u5143\u7d20\u624d\u4f1a\u6269\u5bb9\u5230200\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u63a8\u9500\u4e86vector, deque, list\u7684\u533a\u522b\uff0c\u8fed\u4ee3\u5668\u5931\u6548\u539f\u56e0) \u8fd8\u95ee\u4e86\u4e07\u80fd\u5f15\u7528\u548c\u5b8c\u7f8e\u8f6c\u53d1\u7684\u539f\u7406(\u5f15\u7528\u6298\u53e0) \u4ec0\u4e48\u662fPOD(\u57fa\u7840\u7c7b\u578b\u3001\u6307\u9488\u3001\u65e0\u7528\u6237\u6784\u9020\u51fd\u6570\u7684\u7eaf\u57fa\u7840\u7c7b\u578b\u7ec4\u6210\u7684\u7ed3\u6784\u4f53) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1avector\u8d85\u7f13\u5b58\u5927resize\u5bfc\u81f4memset\u6027\u80fd\u5f71\u54cd\uff1f(\u62ff\u51fa\u6211\u7684tbb\u8bfe\u7a0b\u7684parallel_filter\u6848\u4f8b\uff0c\u5229\u7528pod\u6a21\u677f\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u719f\u6089\u7f13\u5b58\uff0c\u4e0d\u7528\u63d0\u95ee\u4e86) \u9762\u8bd5\u5b98\u63d0\u95eePIMPL\u6a21\u5f0f(\u5199C::Impl\u7ed9\u4ed6\u770b\uff0c\u53c8\u95eePIMPL\u7684\u76ee\u7684\u662f\u4ec0\u4e48\uff0c\u4e00\u5f00\u59cb\u7b54\uff1a\u5206\u79bb\u5b9a\u4e49\uff0c\u52a0\u901f\u7f16\u8bd1\uff0c\u95ee\u8fd8\u6709\u4ec0\u4e48\u4f5c\u7528\u5417\uff1f\u4fdd\u6301abi\u7a33\u5b9a\uff0c\u4e0d\u7528\u91cd\u65b0\u7f16\u8bd1\u4f9d\u8d56\u8005\uff0c\u53ef\u7528\u4e8e\u63d2\u4ef6\u70ed\u88c5\u8f7d) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48C\u7684\u6784\u9020\u51fd\u6570\u91cc\u4f1a\u9700\u8981unique_ptr\u7c7b\u578b\u6790\u6784\u51fd\u6570\u7684\u4fe1\u606f\u5417\uff1f(\u9762\u8bd5\u5b98\uff1a\u56e0\u4e3a\u6790\u6784\u51fd\u6570\u9700\u8981\u77e5\u9053sizeof!=0\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u4f46\u662f\uff0cC\u7684\u6790\u6784\u51fd\u6570\u88ab\u8f6c\u79fb\u5230\u4e86C.cpp\uff0c\u4e3a\u4ec0\u4e48\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521d\u59cbunique_ptr\u4e3anullptr\uff0c\u4ecd\u7136\u7f16\u8bd1\u51fa\u9519\uff1f\u9762\u8bd5\u5b98\u652f\u652f\u543e\u543e\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u56e0\u4e3a\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u5f02\u5e38\uff0c\u5bfc\u81f4\u4e4b\u524d\u521d\u59cb\u5316\u8fc7\u7684\u6210\u5458\u6790\u6784\uff0c\u518d\u6b21\u5411\u4ed6\u515c\u552ecpp\u5f02\u5e38\u9b45\u529b\u65f6\u523b) q\u6307\u9488 vs d\u6307\u9488(Qt\u5b9e\u73b0cow\u548cpimpl\u7684\u7ec6\u8282\uff0c\u56e0\u4e3a\u5e73\u65f6\u6ca1\u6ce8\u610f\u770bqt\u5934\u6587\u4ef6\u6e90\u7801\uff0c\u5c0f\u5f6d\u8001\u5e08\u552f\u4e00\u683d\u8ddf\u5934\u7684\u9898\uff0c\u8bf4\u662f\u770b\u5230\u7b80\u5386\u5199\u7684Qt\u5c31\u95ee\u4e86\uff0c\u5e76\u8868\u793a\u4e4b\u524dzeno\u91cc\u4e3b\u8981\u662f\u7528PyQt) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1ac++11 string\u4e3a\u4ec0\u4e48\u6253\u7834abi(\u56e0\u4e3ac++98 string\u91c7\u7528cow\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u6a21\u578b\u5e38\u8bc6\u201c\u5171\u4eab\u8bfb\u5b89\u5168\u201d) make_shared vs shared_ptr new\u7684\u533a\u522b(\u53ea\u9700\u4e00\u6b21\u6027\u5206\u914d\uff0c\u65e0\u9700\u518dnew SpCounter\uff0c\u539f\u7406\u662foperator new+placement new) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48shared_ptr\u7684\u6784\u9020\u51fd\u6570\u6ca1\u6709noexcept\u5417\uff1f(\u5c31\u662f\u56e0\u4e3a\u8981new SpCounter) \u662foperator new\u8fd8\u662fnew_allocator\uff1f(\u9ed8\u8ba4\u662fnew_allocator\uff0c\u53ef\u7528allocate_shared\u66ff\u6362\u6389) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053make_shared_for_overwrite\u7684\u533a\u522b\u5417(\u91c7\u7528default-init\uff0cnew\u8868\u8fbe\u5f0f\u540e\u6ca1\u6709\u4e86\u62ec\u53f7\uff0c\u53ef\u907f\u514dPOD\u7c7b\u578b0\u521d\u59cb\u5316\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u8fd9\u4e2a\u6211\u90fd\u6ca1\u4e86\u89e3\u8fc7) CRTP(\u5947\u5f02\u9012\u5f52\u6a21\u677f\u6a21\u5f0f\uff0c\u6700\u521d\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u8981\u5b9e\u73b0\u83b7\u53d6\u5b50\u7c7b\u6307\u9488self\uff0c\u63a8\u9500\u4e86cpp\u6a21\u677f\u7c7b\u5ef6\u8fdf\u5b9e\u4f8b\u5316\u6210\u5458\u51fd\u6570\u7684\u673a\u5236\uff0c\u5176\u5b9eCRTP\u8fd8\u80fd\u7528\u4e8e\u5b9e\u73b0\u539f\u578b\u6a21\u5f0f\u548cvisitor\u6a21\u5f0f\uff0c\u56e0\u4e3a\u65f6\u95f4\u5173\u7cfb\u6ca1\u6765\u5f97\u53ca\u8bf4) \u865a\u51fd\u6570\u4e3a\u4ec0\u4e48\u4f4e\u6548\uff1f\u865a\u51fd\u6570\u5982\u4f55\u4f18\u5316(\u56e0\u4e3a\u9700\u8981call\u4e00\u4e2a\u6307\u9488\uff0ccpu\u65e0\u6cd5\u9884\u77e5\uff0c\u4f7f\u7528final\uff0c\u4e0d\u7528\u8bfb\u53d6\u865a\u51fd\u6570\u6307\u9488\u8868\uff0c\u7136\u540e\u8bf4\u660e\u4e86vecB\u62c6\u6210vecD1\u548cvecD2\u66f4\u9ad8\u6548) shared_from_this\u5b9e\u73b0(\u672c\u6765\u8981\u6211\u5199\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6765\u4e0d\u53ca\u5199\uff0c\u4f46\u662f\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u51fa\u8fc7\u624b\u6413shared\u5168\u5bb6\u6876\u7684\u89c6\u9891\uff0c\u9762\u8bd5\u5b98\u53ea\u597d\u653e\u5fc3) \u4f60\u5bf9\u54ea\u4e2a\u9886\u57df\u611f\u5174\u8da3\uff1f(\u5f53\u7136\u662f\u6e32\u67d3\uff0c\u6211\u4ece\u5c0f\u505a\u5230\u5927\uff0c\u5e76\u8868\u793a\u6027\u80fd\u4f18\u5316\u8fd9\u4e00\u5757\u4e5f\u5c3d\u7ba1\u8bf7\u6559\u5c0f\u5f6d\u8001\u5e08\uff0c\u6709cuda\u548csimd\u4f18\u5316\u5ba2\u6237\u7ecf\u9a8c) \u8fd8\u6709\u4ec0\u4e48\u95ee\u9898\u5bf9\u672c\u516c\u53f8\u5417\uff1f(\u65f6\u95f4\u4e0d\u591a\u4e86\uff0c\u5c31\u95ee\u8981\u4e0d\u8981\u73b0\u5728\u5f00\u59cb\u5b66\u4e60\u4e09\u7ef4\u91cd\u5efa\uff0c\u6216\u8005\u53ef\u4ee5\u8bd5\u8bd5\u770b\u5ba2\u6237\u7aef\uff0c\u8bf4\u5c97\u4f4d\u9009\u62e9\u53ef\u4ee5\u4e4b\u540e\u548chr\u6c9f\u901a\uff0c\u5e76\u5411\u6211\u63a8\u9500\u4e863dgs\uff0c\u7403\u978b\u51fd\u6570\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u597d\u591apaper\u5440\uff1f\u770b\u4e86\u51e0\u4e2a\u6548\u679c\u56fe\uff0c\u5178\u4e2d\u5178\u4e4bOurs\u6c38\u8fdc\u662f\u6700\u597d\u7684) 3\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\uff09 \u53c8\u4ecb\u7ecd\u4e86zeno\u548ctaichi\uff0c\u95ee\u4e86\u70b9\u4e91\u76f8\u5173\u95ee\u9898\uff0c\u5f88\u5feb\u7ed3\u675f\u4e86\u3002 4\u9762\uff08\u62c9\u6295\u8d44\u7684\u5408\u4f19\u4eba\u4eb2\u81ea\u7ebf\u4e0b\u89c1\u9762\uff09 \u5546\u573a\u5168\u90e8\u5173\u95ed\u4e86\uff0c\u661f\u5df4\u514b\u8fd8\u5f00\u7740 \u4ecb\u7ecd\u4e00\u4e0b\u4f60\u81ea\u5df18\uff08\u53c8\u662f zeno\uff09 \u95ee\u4e86\u4e0a\u6b21\u7684\u9762\u8bd5\u5b98\u600e\u4e48\u6837\u5440\uff08\u6211\u770b\u4e86\u63a8\u8350\u7684 3dgs\uff0c\u53d1\u73b0\u662f\u628a\u626b\u63cf\u51fa\u6765\u7684\u70b9\u4e91\uff0c\u9010\u6b65\u8f6c\u6362\u4e3a\u692d\u5706\u7403\u6e32\u67d3\uff09 \u4f60\u77e5\u9053\uff0c\u73b0\u5728\u4e3b\u6d41\u56fe\u5f62\u5b66\u90fd\u662f\u4e09\u89d2\u5f62\u7f51\u683c\uff0c\u90a3\u4e48\u8fd9\u79cd\u70b9\u4e91\u8981\u5982\u4f55\u6e32\u67d3\u5462\uff1f\uff08\u70b9\u4e91\u7684\u8bdd\u53ef\u4ee5\u5148\u7528 marching cube \u8f6c\u4e09\u89d2\u5f62\u9762\uff0czeno \u7684\u6d41\u4f53\u5c31\u662f\u8fd9\u6837\u7684\uff09 \u4f46\u662f\u6027\u80fd\u4e0d\u591f\uff0c\u4e0d\u80fd\u4fdd\u8bc1\u5b9e\u65f6\uff08\u53ef\u4ee5\u7528\u5c4f\u5e55\u7a7a\u95f4\u6d41\u4f53\uff0c\u4f46\u662f\u6548\u679c\u4e00\u822c\uff0c\u6211\u4eec\u505a\u7535\u5f71\u7684\u9700\u8981\u9ad8\u8d28\u91cf\u7684\u79bb\u7ebf\u6e32\u67d3\uff0c\u4e0d\u592a\u6ce8\u91cd\u5b9e\u65f6\u6027\uff0c\u5b9e\u65f6\u692d\u7403\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u7528\u5149\u8ffd\uff0c\u7b97\u5c04\u7ebf\u4e0e\u692d\u7403\u8868\u9762\u6c42\u4ea4\u5373\u53ef\uff0c\u4e0d\u8fc7\u82f1\u4f1f\u8fbe\u7684\u786c\u4ef6\u52a0\u901f\u53ea\u6709\u4e09\u89d2\u5f62\u7684\uff0c\u4f46\u662f GPU Gems \u4e0a\u7684 BVH \u52a0\u901f\u6c42\u4ea4\u4ee3\u7801\u7528\u4e8e\u692d\u7403\u4e5f\u662f\u53ef\u4ee5\u62ff\u6765\u53c2\u8003\u7684\uff09 \u62ff\u51fa\u4e00\u53f0 3D \u626b\u63cf\u673a\u5668\uff0c\u8bf4\u4f60\u77e5\u9053\u6211\u4eec\u8fd9\u4e2a\u6d4b\u7ed8\u673a\u5668\u662f\u5982\u4f55\u5b9a\u4f4d\u7684\u5417\uff08\u60ef\u6027\u5236\u5bfc\uff0c\u91cc\u9762\u6709\u52a0\u901f\u5ea6\u8ba1\uff0c\u6c42\u4e8c\u9636\u79ef\u5206\u5c31\u53ef\u4ee5\u5f97\u5230\u4f4d\u7f6e\uff09 \u4f46\u662f\u8fd9\u6837\u65f6\u95f4\u957f\u4f1a\u6709\u7d2f\u8ba1\u8bef\u5dee\uff0c\u5982\u4f55\u6d88\u9664\u8bef\u5dee\uff1f\uff08\u53ef\u4ee5\u7528 GPS \u5b9a\u4f4d\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5149\u5b66\u6444\u50cf\u5934\u626b\u63cf\u7684\u7ed3\u679c\uff0c\u786e\u5b9a\u81ea\u5df1\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u5fc5\u8981\u65f6\u53ef\u4ee5\u8d34\u51e0\u4e2a\u8bc6\u522b\u7eb8\u7247\u5728\u5899\u4e0a\u65b9\u4fbf\u7a0b\u5e8f\u68c0\u6d4b\uff09 \u662f\u7684\uff0c\u5b9e\u9645\u4e0a\u6211\u4eec\u5728\u6237\u5916\u4f1a\u7528 GPS \u5b9a\u4f4d\uff0c\u77ff\u6d1e\u91cc\u5c31\u4f1a\u7528\u5149\u5b66\u7684\u5b9a\u4f4d\u65b9\u6cd5\uff0c\u6d88\u9664\u60ef\u6027\u5236\u5bfc\u7684\u7d2f\u8ba1\u8bef\u5dee\u3002 \u90a3\u4e48 GPS \u536b\u661f\u5b9a\u4f4d\u7684\u539f\u7406\u4f60\u77e5\u9053\u5417\uff1f\uff08\u4e09\u9897 GPS \u536b\u661f\u53d1\u51fa\u4e0d\u540c\u76f8\u4f4d\u7684\u7535\u78c1\u6ce2\uff0c\u56e0\u4e3a\u5149\u901f\u6709\u9650\uff0c\u79fb\u52a8\u8bbe\u5907\u901a\u8fc7\u68c0\u6d4b\u76f8\u4f4d\u5dee\uff0c\u5c31\u77e5\u9053\u81ea\u5df1\u8ddd\u79bb\u4e09\u9897\u536b\u661f\u7684\u8ddd\u79bb\uff0c\u7136\u540e\u4e09\u4e2a\u8ddd\u79bb\u5c31\u80fd\u552f\u4e00\u786e\u5b9a\u4e00\u4e2a\u70b9\uff09","title":"\u5176\u57df\u79d1\u6280 (2024.09.03)"},{"location":"interview/#20240903_1","text":"\u4ecb\u7ecd\u4e00\u4e0b\u81ea\u5df1\uff08\u53c8\u4ecb\u7ecdzeno\u662f\u4e00\u6b3eCAD\u7c7b\u7684\u9879\u76ee\uff09 \u54c8\u5e0c\u8868\uff08\u4ecb\u7ecdunordered_map\u57fa\u4e8e\u94fe\u8868\u6cd5\uff0c\u6807\u51c6\u5e93\u7684hashint\u662f\u6052\u7b49\u51fd\u6570\uff0cabsl\u7684\u5b9e\u73b0\u57fa\u4e8e\u5f00\u653e\u5730\u5740\u6cd5\u66f4\u9ad8\u6548\uff0cjava\u4e5f\u662f\u94fe\u8868\u6cd5\uff0c\u4f46\u94fe\u8868\u8fc7\u957f\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u7b49\uff09 \u7ea2\u9ed1\u6811\uff08\u4e94\u5927\u89c4\u5219\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u4e94\u4e2a\u89c4\u5219\u80fd\u4fdd\u8bc1\u4e0d\u8d85\u8fc72\u500d\u6df1\u5ea6\uff0c\u540c\u65f6\u6bd4\u4e8c\u53c9\u5e73\u8861\u6811\u9ad8\u6548\uff09 \u7ea2\u9ed1\u6811\u5de6\u65cb\u53f3\u65cb\u64cd\u4f5c\uff08\u53f3\u513f\u5b50\u66ff\u6362\u7236\u4eb2\uff0c\u7236\u4eb2\u53d8\u6210\u5de6\u513f\u5b50\uff09 \u9762\u8bd5\u5b98\u900f\u9732\uff1a\u5b9e\u9645\u4e0a\u7ea2\u9ed1\u6811\u5c31\u662f\u4e00\u4e2a4\u9636\u6811\uff0c\u4f60\u60f3\u60f3\u770b\uff08\u786e\u5b9e\uff0c\u5982\u679c\u628a\u7ea2\u9ed1\u4e24\u5c42\u770b\u4f5c\u4e00\u5c42\u7684\u8bdd\uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a4\u9636\u5e73\u8861\u6811\uff09 OpenGL \u6e32\u67d3\u7ba1\u7ebf\uff083d\u9876\u70b9\u6570\u636e -> vert shader (\u77e9\u9635\u53d8\u6362) -> \u5149\u6805\u5316+\u63d2\u503c+\u6df1\u5ea6\u6d4b\u8bd5 -> frag shader (\u524d\u5411\u7740\u8272) -> G-buffer -> \u5ef6\u8fdf\u6e32\u67d3 (\u540e\u5411\u7740\u8272) -> \u540e\u5904\u7406 -> \u5c4f\u5e55\uff09 \u6765\u9762\u8bd5\u7684\u4eba\u4e2d\uff0c\u4f60\u662f\u6211\u89c1\u8fc7\u6280\u672f\u6700\u597d\u7684\u4e00\u4e2a\uff0c\u4e4b\u524d\u4e00\u4e2a\u7855\u58eb\uff0c\u4e0a\u6765\u54c8\u5e0c\u8868\u5c31\u652f\u652f\u543e\u543e\u6302\u6389\u3002 \u4e8b\u540e\uff1a\u5df2\u5f55\u53d6\uff0c\u6b63\u5728\u4e0a\u73eding\u2026\u2026\u53c8\u662f\u505a Qt + OpenGL \u7684\u9879\u76ee","title":"\u96c5\u79d1\u8d1d\u601d (2024.09.03)"},{"location":"lambda/","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u7528\u51fd\u6570\u5c01\u88c5 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u4e8c\u6b21\u5c01\u88c5 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 mutable \u7684\u51fd\u6570\u5bf9\u8c61 \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u6309\u5f15\u7528\u6355\u83b7 \u6309\u503c\u79fb\u52a8\u6355\u83b7 \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u7c7b lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 std::bind_front \u548c std::bind_back \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4f7f\u7528 lambda \u4ee3\u66ff bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5 \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum = {}\", s); return 0; } \u8fd9\u662f\u4e00\u4e2a\u8ba1\u7b97\u6570\u7ec4\u6c42\u548c\u7684\u7b80\u5355\u7a0b\u5e8f\u3002 \u4f46\u662f\uff0c\u4ed6\u53ea\u80fd\u8ba1\u7b97\u6570\u7ec4 a \u7684\u6c42\u548c\uff0c\u65e0\u6cd5\u590d\u7528\u3002 \u5982\u679c\u6211\u4eec\u6709\u53e6\u4e00\u4e2a\u6570\u7ec4 b \u4e5f\u9700\u8981\u6c42\u548c\u7684\u8bdd\uff0c\u5c31\u5f97\u628a\u6574\u4e2a\u6c42\u548c\u7684 for \u5faa\u73af\u91cd\u65b0\u5199\u4e00\u904d\uff1a int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum of a = {}\", s); std::vector b = {5, 6, 7, 8}; s = 0; for (int i = 0; i < a.size(); i++) { s += b[i]; } fmt::println(\"sum of b = {}\", s); return 0; } \u8fd9\u5c31\u51fa\u73b0\u4e86\u7a0b\u5e8f\u8bbe\u8ba1\u7684\u5927\u5fcc\uff1a\u4ee3\u7801\u91cd\u590d\u3002 \u4f8b\u5982\uff0c\u4f60\u6709\u5439\u7a7a\u8c03\u7684\u9700\u6c42\uff0c\u548c\u5145\u624b\u673a\u7684\u9700\u6c42\u3002\u4f60\u4e3a\u4e86\u6ee1\u8db3\u8fd9\u4e24\u4e2a\u9700\u6c42\uff0c\u8d2d\u4e70\u4e86\u4e24\u53f0\u53d1\u7535\u673a\uff0c\u5206\u522b\u4e3a\u7a7a\u8c03\u548c\u624b\u673a\u4f9b\u7535\u3002\u7b2c\u4e8c\u5929\uff0c\u4f60\u53c8\u4ea7\u751f\u4e86\u73a9\u7535\u8111\u9700\u6c42\uff0c\u4e8e\u662f\u4f60\u53c8\u8d2d\u4e70\u4e00\u53f0\u53d1\u7535\u673a\uff0c\u4e13\u4e3a\u7535\u8111\u4f9b\u7535\u2026\u2026\u771f\u662f\u6d6a\u8d39\uff01 \u91cd\u590d\u7684\u4ee3\u7801\u4e0d\u4ec5\u5f71\u54cd\u4ee3\u7801\u7684 \u53ef\u8bfb\u6027 \uff0c\u4e5f\u589e\u52a0\u4e86 \u7ef4\u62a4 \u4ee3\u7801\u7684\u6210\u672c\u3002 \u770b\u8d77\u6765\u4e71\u7cdf\u7cdf\u7684\uff0c\u4fe1\u606f\u5bc6\u5ea6\u4f4e\uff0c\u8ba9\u4eba\u4e00\u773c\u770b\u4e0d\u51fa\u4ee3\u7801\u5728\u5e72\u4ec0\u4e48\u7684\u529f\u80fd \u5f88\u5bb9\u6613\u5199\u9519\uff0c\u770b\u8d70\u773c\uff0c\u96be\u8c03\u8bd5 \u590d\u5236\u7c98\u8d34\u8fc7\u7a0b\u4e2d\uff0c\u5bb9\u6613\u6f0f\u6539\uff0c\u6bd4\u5982\u8fd9\u91cc\u7684 s += b[i] \u53ef\u80fd\u5199\u6210 s += a[i] \u800c\u81ea\u5df1\u4e0d\u53d1\u73b0 \u6539\u8d77\u6765\u4e0d\u65b9\u4fbf\uff0c\u5f53\u6211\u4eec\u7684\u9700\u6c42\u53d8\u66f4\u65f6\uff0c\u9700\u8981\u591a\u5904\u4fee\u6539\uff0c\u6bd4\u5982\u5f53\u6211\u9700\u8981\u6539\u4e3a\u8ba1\u7b97\u4e58\u79ef\u65f6\uff0c\u9700\u8981\u628a\u4e24\u4e2a\u5730\u65b9\u90fd\u6539\u6210 s *= \u6539\u4e86\u4ee5\u540e\u53ef\u80fd\u6f0f\u6539\u4e00\u90e8\u5206\uff0c\u7559\u4e0b Bug \u9690\u60a3 \u654f\u6377\u5f00\u53d1\u9700\u8981\u53cd\u590d\u4fee\u6539\u4ee3\u7801\uff0c\u6bd4\u5982\u4f60\u6b63\u5728\u8c03\u8bd5 += \u548c -= \u7684\u533a\u522b\uff0c\u770b\u7ed3\u679c\u53d8\u5316\uff0c\u5982\u679c\u4e00\u6b21\u5207\u6362\u9700\u8981\u6539\u591a\u5904\uff0c\u5c31\u5f71\u54cd\u4e86\u8c03\u8bd5\u901f\u5ea6 \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u5982\u679c\u4f60\u8fd8\u662f\u559c\u6b22\u201c\u4e00\u672c\u9053\u201d\u5199\u6cd5\u7684\u8bdd\uff0c\u4e0d\u59a8\u60f3\u60f3\u770b\uff0c\u5b8c\u5168\u4e0d\u7528\u4efb\u4f55\u6807\u51c6\u5e93\u548c\u7b2c\u4e09\u65b9\u5e93\u7684\u51fd\u6570\u548c\u7c7b\uff0c\u628a fmt::println \u548c std::vector \u8fd9\u4e9b\u51fd\u6570\u5168\u90e8\u62c6\u89e3\u6210\u4e00\u4e2a\u4e2a\u7cfb\u7edf\u8c03\u7528\u3002\u90a3\u8fd9\u6574\u4e2a\u7a0b\u5e8f\u4f1a\u6709\u591a\u96be\u5199\uff1f int main() { #ifdef _WIN32 int *a = (int *)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else int *a = (int *)mmap(NULL, 4 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); #endif a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; int s = 0; for (int i = 0; i < 4; i++) { s += a[i]; } char buffer[64]; buffer[0] = 's'; buffer[1] = 'u'; buffer[2] = 'm'; buffer[3] = ' '; buffer[4] = '='; buffer[5] = ' '; // \u4f8b\u5982\uff0c\u5982\u679c\u8981\u4fee\u6539\u6b64\u5904\u7684\u63d0\u793a\u6587\u672c\uff0c\u751a\u81f3\u9700\u8981\u4fee\u6539\u540e\u9762\u7684 len \u53d8\u91cf... int len = 6; int x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif int *b = (int *)a; b[0] = 4; b[1] = 5; b[2] = 6; b[3] = 7; int s = 0; for (int i = 0; i < 4; i++) { s += b[i]; } len = 6; x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif #ifdef _WIN32 VirtualFree(a, 0, MEM_RELEASE); #else munmap(a); #endif return 0; } \u4e0d\u4ec5\u5b8c\u5168\u6ca1\u6709\u53ef\u8bfb\u6027\u3001\u53ef\u7ef4\u62a4\u6027\uff0c\u751a\u81f3\u90fd\u6ca1\u6709\u53ef\u79fb\u690d\u6027\u3002 \u9664\u975e\u4f60\u53ea\u5199\u5e94\u4ed8\u5bfc\u5e08\u7684\u201c\u4e00\u6b21\u6027\u201d\u7a0b\u5e8f\uff0c\u4e00\u65e6\u8981\u5b9e\u73b0\u590d\u6742\u7684\u4e1a\u52a1\u9700\u6c42\uff0c\u4e0d\u53ef\u907f\u514d\u7684\u8981\u81ea\u5df1\u5c01\u88c5\u51fd\u6570\u6216\u7c7b\u3002\u7f51\u4e0a\u6240\u6709\u9f13\u5439\u201c\u4e0d\u5c01\u88c5\u201d\u201c\u8bbe\u8ba1\u6a21\u5f0f\u662f\u9762\u5b50\u5de5\u7a0b\u201d\u7684\u53cd\u667a\u8a00\u8bba\uff0c\u90fd\u662f\u6ca1\u6709\u505a\u8fc7\u5927\u578b\u9879\u76ee\u7684\u3002 \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u5f88\u591a\u8bbe\u8ba1\u6a21\u5f0f\u6559\u6750\u7247\u9762\u5f3a\u8c03 \u53ef\u8bfb\u6027 \uff0c\u4eff\u4f5b\u8bbe\u8ba1\u6a21\u5f0f\u5c31\u662f\u4e3a\u4e86\u201c\u4f18\u96c5\u201d\u201c\u9ad8\u5927\u4e0a\u201d\u201c\u7f8e\u5b66\u201d\uff1f\u4f7f\u5f97\u5f88\u591a\u4eba\u8ba4\u4e3a\uff0c\u201c\u6211\u8fd9\u4e2a\u662f\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u4e0d\u7528\u7f8e\u5316\u7ed9\u9886\u5bfc\u770b\u201d\u800c\u62d2\u7edd\u8bbe\u8ba1\u6a21\u5f0f\u3002\u5b9e\u9645\u4e0a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e \u65b9\u4fbf\u540e\u7eed\u4fee\u6539 \uff01 \u4f8b\u5982 B \u7ad9\u4ee5\u524d\u53ea\u652f\u6301\u4e0a\u4f20\u666e\u901a\u89c6\u9891\uff0c\u73b0\u5728\u53d4\u53d4\u7a81\u7136\u63d0\u51fa\uff1a\u8981\u652f\u6301\u4e92\u52a8\u89c6\u9891\uff0c\u5145\u7535\u89c6\u9891\uff0c\u89c6\u9891\u5408\u96c6\uff0c\u8fd8\u5e9f\u9664\u4e86\u89c6\u9891\u5206 p\uff0c\u8fd8\u8981\u652f\u6301\u4e0a\u4f20\u77ed\u89c6\u9891\uff0c\u7ad6\u5c4f\u5f00\u5173\u7b49\u2026\u2026\u6bcf\u4e00\u4e2a\u53d4\u53d4\u7684\u8981\u6c42\uff0c\u90fd\u9700\u8981\u5927\u91cf\u7a0b\u5e8f\u5458\u4fee\u6539\u4ee3\u7801\uff0c\u65e0\u8bba\u6d89\u53ca\u524d\u7aef\u8fd8\u662f\u540e\u7aef\u3002 \u4e0e\u5efa\u7b51\u3001\u7ed8\u753b\u7b49\u9886\u57df\u4e0d\u540c\uff0c\u4e00\u6b21\u4ea4\u4ed8\u5b8c\u6bd5\u5c31\u53ef\u4ee5\u51e0\u4e4e\u6c38\u4e45\u4f7f\u7528\u3002\u800c\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u66f4\uff0c\u90fd\u5bfc\u81f4\u4ee3\u7801\u9700\u8981\u4fee\u6539\u3002\u5f00\u53d1\u4eba\u5458\u51e0\u4e4e\u9700\u8981\u4e00\u76f4\u56f4\u7ed5\u7740\u8f6f\u4ef6\u4ee3\u7801\uff0c\u4e0d\u65ad\u7684\u4fee\u6539\u3002\u8c03\u67e5\u8868\u660e\uff0c\u7a0b\u5e8f\u5458 90% \u7684\u65f6\u95f4\u82b1\u5728 \u6539\u4ee3\u7801 \u4e0a\uff0c \u5199\u4ee3\u7801 \u53ea\u5360 10%\u3002 \u8f6f\u4ef6\u5c31\u50cf\u751f\u7269\uff0c\u8981\u4e0d\u65ad\u8fdb\u5316\uff0c\u8f6f\u4ef6\u4e0d\u66f4\u65b0\u4e0d\u7ef4\u62a4\u4e86\u7b49\u4e8e\u6b7b\u3002\u5982\u679c\u4e00\u4e2a\u8f6f\u4ef6\u9010\u6e10\u53d8\u5f97\u81c3\u80bf\u96be\u4ee5\u4fee\u6539\uff0c\u65e0\u6cd5\u9002\u5e94\u65b0\u9700\u6c42\uff0c\u90a3\u4ed6\u5c31\u50cf\u5df2\u7ecf\u5931\u53bb\u8fdb\u5316\u80fd\u529b\u7684\u751f\u7269\u79cd\u7fa4\uff0c\u5982\u300a\u4e09\u4f53\u300b\u4e16\u754c\u89c2\u4e2d\u201c\u5b89\u987f\u201d\u5230\u6fb3\u5927\u5229\u4e9a\u4fdd\u7559\u533a\u91cc\u201c\u7edd\u80b2\u201d\u7684\u4eba\u7c7b\uff0c\u88ab\u6dd8\u6c70\u53ea\u662f\u65f6\u95f4\u95ee\u9898\u3002 \u5982\u679c\u6211\u4eec\u80fd\u5728 \u5199\u4ee3\u7801 \u9636\u6bb5\uff0c\u5c31\u628a\u7a0b\u5e8f\u51c6\u5907\u5f97 \u6613\u4e8e\u540e\u7eed\u4fee\u6539 \uff0c\u90a3\u5c31\u53ef\u4ee5\u5728\u540e\u7eed 90% \u7684 \u6539\u4ee3\u7801 \u9636\u6bb5\u7701\u4e0b\u65e0\u6570\u65f6\u95f4\u3002 \u5982\u4f55\u8ba9\u4ee3\u7801\u6613\u4e8e\u4fee\u6539\uff1f\u524d\u4eba\u603b\u7ed3\u51fa\u4e00\u7cfb\u5217\u5e38\u7528\u7684\u5199\u6cd5\uff0c\u8fd9\u7c7b\u5199\u6cd5\u6709\u52a9\u4e8e\u8ba9\u540e\u7eed\u4fee\u6539\u66f4\u5bb9\u6613\uff0c\u5404\u81ea\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u5408\uff0c\u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u3002 \u63d0\u5347\u53ef\u7ef4\u62a4\u6027\u6700\u57fa\u7840\u7684\u4e00\u70b9\uff0c\u5c31\u662f\u907f\u514d\u91cd\u590d\uff01 \u5f53\u4f60\u6709\u5f88\u591a\u5730\u65b9\u51fa\u73b0\u91cd\u590d\u7684\u4ee3\u7801\u65f6\uff0c\u4e00\u65e6\u9700\u8981\u6d89\u53ca\u4fee\u6539\u8fd9\u90e8\u5206\u903b\u8f91\u65f6\uff0c\u5c31\u9700\u8981\u5230\u6bcf\u4e00\u4e2a\u51fa\u73b0\u4e86\u8fd9\u4e2a\u903b\u8f91\u7684\u4ee3\u7801\u4e2d\uff0c\u53bb\u9010\u4e00\u4fee\u6539\u3002 \u4f8b\u5982\u4f60\u7684\u540d\u5b57\uff0c\u5728\u51fa\u751f\u8bc1\uff0c\u8eab\u4efd\u8bc1\uff0c\u5b66\u751f\u8bc1\uff0c\u6bd5\u4e1a\u8bc1\uff0c\u623f\u4ea7\u8bc1\uff0c\u9a7e\u9a76\u8bc1\uff0c\u5404\u79cd\u5730\u65b9\u90fd\u51fa\u73b0\u4e86\u3002\u90a3\u4e48\u4f60\u8981\u6539\u540d\u7684\u8bdd\uff0c\u6240\u6709\u8fd9\u4e9b\u8bc1\u4ef6\u90fd\u9700\u8981\u91cd\u65b0\u5370\u5237\uff01\u5982\u679c\u80fd\u628a\u4ed6\u4eec\u5408\u5e76\u6210\u4e00\u4e2a\u201c\u7edf\u4e00\u8bc1\u201d\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4fee\u6539\u201c\u7edf\u4e00\u8bc1\u201d\u4e0a\u7684\u540d\u5b57\u5c31\u884c\u4e86\u3002 \u4e0d\u8fc7\uff0c\u73b0\u5b9e\u4e2d\u5e76\u6ca1\u6709\u9891\u7e41\u6539\u540d\u5b57\u7684\u9700\u6c42\uff0c\u8fd9\u8bf4\u660e\uff1a \u5bf9\u4e8e\u4e0d\u5e38\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u53ef\u4ee5\u5bb9\u5fcd\u4e00\u5b9a\u7684\u91cd\u590d\u3002 \u8d8a\u662f\u672a\u6765\u6709\u53ef\u80fd\u4fee\u6539\u7684\uff0c\u5c31\u8d8a\u9700\u8981\u8bbe\u8ba1\u6a21\u5f0f\u964d\u91cd\uff01 \u4f8b\u5982\u6570\u5b66\u5e38\u6570 PI = 3.1415926535897\uff0c\u8fd9\u8f88\u5b50\u90fd\u4e0d\u53ef\u80fd\u51fa\u73b0\u4fee\u6539\u7684\u9700\u6c42\uff0c\u90a3\u5199\u6b7b\u4e5f\u6ca1\u5173\u7cfb\u3002\u5982\u679c\u8981\u628a PI \u5b9a\u4e49\u6210\u5b8f\uff0c\u53ea\u662f\u51fa\u4e8e\u201c\u8bb0\u4e0d\u4f4f\u201d\u201c\u5199\u8d77\u6765\u592a\u957f\u4e86\u201d\u201c\u590d\u5236\u7c98\u8d34\u9ebb\u70e6\u201d\u3002\u6240\u4ee5\u5bf9\u4e8e PI \u8fd9\u79cd\u4e0d\u4f1a\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u964d\u91cd\u53ea\u662f\u589e\u52a0 \u53ef\u8bfb\u6027 \uff0c\u800c\u4e0d\u662f \u53ef\u4fee\u6539\u6027 \u3002 \u4f46\u662f\uff0c\u4e0d\u8981\u60f3\u5f53\u7136\uff01\u9700\u6c42\u7684\u5343\u53d8\u4e07\u5316\u603b\u662f\u8d85\u51fa\u4f60\u7684\u60f3\u8c61\u3002 \u4f8b\u5982\u4f60\u505a\u4e86\u4e00\u4e2a\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u6e38\u620f\uff0c\u9700\u8981\u7528\u5230\u91cd\u529b\u52a0\u901f\u5ea6 g = 9.8\uff0c\u4f60\u60f3\u5f53\u7136\u8ba4\u4e3a g \u4ee5\u540e\u4e0d\u53ef\u80fd\u4fee\u6539\u3002\u8001\u677f\u4e5f\u4fe1\u8a93\u65e6\u65e6\u5411\u4f60\u4fdd\u8bc1\uff1a\u201c\u6ca1\u4e8b\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u4e0d\u4f1a\u6539\u53d8\u3002\u201d\u4f60\u5c31\u5199\u6b7b\u5728\u4ee3\u7801\u91cc\u4e86\u3002 \u6ca1\u60f3\u5230\uff0c\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u8001\u677f\u7a81\u7136\u8981\u6c42\u4f60\u52a0\u5165\u201c\u6708\u7403\u7ae0\u201d\u5173\u5361\uff0c\u5728\u8fd9\u4e9b\u5173\u5361\u4e2d\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u662f g = 1.6\u3002 \u5982\u679c\u4f60\u4e00\u5f00\u59cb\u5c31\u5df2\u7ecf\u628a g \u63d0\u53d6\u51fa\u6765\uff0c\u5b9a\u4e49\u4e3a\u5e38\u91cf\uff1a struct Level { const double g = 9.8; void physics_sim() { bird.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f pig.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f } }; \u90a3\u4e48\u8981\u652f\u6301\u6708\u7403\u5173\u5361\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5c31\u53ef\u4ee5\u4e86\u3002 struct Level { double g; Level(Chapter chapter) { if (chapter == ChapterMoon) { g = 1.6; } else { g = 9.8; } } void physics_sim() { bird.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g pig.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g } }; \u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u505a zeno \u65f6\uff0c\u8be2\u95ee\u8981\u4e0d\u8981\u628a\u6e32\u67d3\u7ba1\u7ebf\u8282\u70b9\u5316\uff0c\u65b9\u4fbf\u7528\u6237\u52a8\u6001\u7f16\u7a0b\uff1f\u5f20\u7329\u7329\u5c31\u662f\u4fe1\u8a93\u65e6\u65e6\u9053\uff1a\u201c\u6e32\u67d3\u662f\u4e00\u4e2a\u9ad8\u5ea6\u6210\u719f\u9886\u57df\uff0c\u4e0d\u4f1a\u6709\u591a\u5c11\u4fee\u6539\u9700\u6c42\u7684\u3002\u201d\u5c0f\u5f6d\u8001\u5e08\u9042\u5199\u6b7b\u4e86\u6e32\u67d3\u7ba1\u7ebf\uff0c\u4e13\u4e3a\u6027\u80fd\u6781\u5ea6\u4f18\u5316\uff0c\u51e0\u4e2a\u6708\u540e\uff0c\u5f20\u7329\u7329\u7f9e\u7b54\u7b54\u627e\u5230\u5c0f\u5f6d\u8001\u5e08\uff1a\u201c\u5c0f\u5f6d\u8001\u5e08\uff0c\u90a3\u4e2a\uff0c\u6e32\u67d3\uff0c\u80fd\u4e0d\u80fd\u6539\u6210\u8282\u70b9\u554a\u2026\u2026\u201d\u3002\u8fd9\u4e2a\u6545\u4e8b\u544a\u8bc9\u6211\u4eec\uff0c\u7532\u65b9\u7684\u4fe1\u8a93\u65e6\u65e6\u653e\u7684\u4e00\u4e2a\u5c41\u90fd\u4e0d\u80fd\u4fe1\u3002 \u7528\u51fd\u6570\u5c01\u88c5 \u51fd\u6570\u5c31\u662f\u6765\u5e2e\u4f60\u89e3\u51b3\u4ee3\u7801\u91cd\u590d\u95ee\u9898\u7684\uff01\u8981\u9886\uff1a \u628a\u5171\u540c\u7684\u90e8\u5206\u63d0\u53d6\u51fa\u6765\uff0c\u628a\u4e0d\u540c\u7684\u90e8\u5206\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u3002 void sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } fmt::println(\"sum of v = {}\", s); } int main() { std::vector a = {1, 2, 3, 4}; sum(a); std::vector b = {5, 6, 7, 8}; sum(b); return 0; } \u8fd9\u6837 main \u51fd\u6570\u91cc\u5c31\u53ef\u4ee5\u53ea\u5173\u5fc3\u8981\u6c42\u548c\u7684\u6570\u7ec4\uff0c\u800c\u4e0d\u7528\u5173\u5fc3\u6c42\u548c\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\u4e86\u3002\u4e8b\u540e\u6211\u4eec\u53ef\u4ee5\u968f\u65f6\u628a sum \u7684\u5185\u5bb9\u5077\u5077\u6362\u6389\uff0c\u6362\u6210\u5e76\u884c\u7684\u7b97\u6cd5\uff0cmain \u4e5f\u4e0d\u7528\u77e5\u9053\u3002\u8fd9\u5c31\u662f \u5c01\u88c5 \uff0c\u53ef\u4ee5\u628a\u91cd\u590d\u7684\u516c\u5171\u90e8\u5206\u62bd\u53d6\u51fa\u6765\uff0c\u65b9\u4fbf\u4ee5\u540e\u4fee\u6539\u4ee3\u7801\u3002 sum \u51fd\u6570\u76f8\u5f53\u4e8e\uff0c\u5f53\u9700\u8981\u5439\u7a7a\u8c03\u65f6\uff0c\u63d2\u4e0a\u7a7a\u8c03\u63d2\u5ea7\u3002\u5f53\u9700\u8981\u7ed9\u624b\u673a\u5145\u7535\u65f6\uff0c\u63d2\u4e0a\u624b\u673a\u5145\u7535\u5668\u3002\u4f60\u4e0d\u9700\u8981\u5173\u5fc3\u63d2\u5ea7\u91cc\u7684\u7535\u54ea\u91cc\u6765\uff0c\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4f1a\u66ff\u4f60\u60f3\u529e\u6cd5\u89e3\u51b3\uff0c\u60f3\u529e\u6cd5\u4f18\u5316\uff0c\u60f3\u529e\u6cd5\u5347\u7ea7\u5230\u7eff\u8272\u80fd\u6e90\u3002\u4f60\u53ea\u9700\u8981\u5439\u7740\u7a7a\u8c03\u7ed9\u4f60\u6b63\u5728\u5f00\u53d1\u7684\u624b\u673a App \u4f18\u5316\u5c31\u884c\u4e86\uff0c\u5927\u5927\u51cf\u8f7b\u7a0b\u5e8f\u5458\u5fc3\u667a\u8d1f\u62c5\u3002 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u4f46\u662f\uff01\u8fd9\u6bb5\u4ee3\u7801\u4ecd\u7136\u6709\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u628a sum \u6c42\u548c\u7684\u7ed3\u679c\uff0c\u76f4\u63a5\u5728 sum \u91cc\u6253\u5370\u4e86\u51fa\u6765\u3002sum \u91cc\u5199\u6b7b\u4e86\uff0c\u6c42\u5b8c\u548c\u4e4b\u540e\u53ea\u80fd\u76f4\u63a5\u6253\u5370\uff0c\u8c03\u7528\u8005 main \u6839\u672c\u65e0\u6cd5\u63a7\u5236\u3002 \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u5c01\u88c5\uff0c\u6216\u8005\u8bf4\uff0c\u5c01\u88c5\u8fc7\u5934\u4e86\u3002 \u4f60\u628a\u624b\u673a\u5145\u7535\u5668 (fmt::println) \u710a\u6b7b\u5728\u4e86\u63d2\u5ea7 (sum) \u4e0a\uff0c\u73b0\u5728\u8fd9\u4e2a\u63d2\u5ea7\u53ea\u80fd\u7ed9\u624b\u673a\u5145\u7535 (\u7528\u4e8e\u76f4\u63a5\u6253\u5370) \u4e86\uff0c\u4e0d\u80fd\u7ed9\u7b14\u8bb0\u672c\u7535\u8111\u5145\u7535 (\u6c42\u548c\u7ed3\u679c\u4e0d\u76f4\u63a5\u7528\u4e8e\u6253\u5370) \u4e86\uff01\u5c3d\u7ba1\u901a\u8fc7\u66f4\u6362\u5145\u7535\u7ebf (\u53c2\u6570 v)\uff0c\u8fd8\u53ef\u4ee5\u652f\u6301\u652f\u6301\u5b89\u5353 (a) \u548c\u82f9\u679c (b) \u4e24\u79cd\u624b\u673a\u7684\u5145\u7535\uff0c\u4f46\u8fd9\u6837\u710a\u6b7b\u7684\u63d2\u5ea7\u5df2\u7ecf\u548c\u7b14\u8bb0\u672c\u7535\u8111\u65e0\u7f18\u4e86\u3002 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u5f88\u660e\u663e\uff0c\u201c\u6253\u5370\u201d\u548c\u201c\u6c42\u548c\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u64cd\u4f5c\uff0c\u4e0d\u5e94\u8be5\u710a\u6b7b\u5728\u4e00\u5757\u3002 sum \u51fd\u6570\u7684\u672c\u804c\u5de5\u4f5c\u662f\u201c\u6570\u7ec4\u6c42\u548c\u201d\uff0c\u4e0d\u5e94\u8be5\u9644\u8d60\u6253\u5370\u529f\u80fd\u3002 sum \u8ba1\u7b97\u51fa\u6c42\u548c\u7ed3\u679c\u540e\uff0c\u76f4\u63a5 return \u5373\u53ef\u3002 \u5982\u4f55\u5904\u7406\u8fd9\u4e2a\u7ed3\u679c\uff0c\u662f\u8c03\u7528\u8005 main \u7684\u4e8b\uff0c\u6b63\u5982\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4e0d\u4f1a\u7ba1\u4f60\u7528\u4ed6\u63d0\u4f9b\u7684\u7535\u6765\u5439\u7a7a\u8c03\u8fd8\u662f\u73a9\u6e38\u620f\u4e00\u6837\uff0c\u53ea\u8981\u4e0d\u59a8\u788d\u5230\u5176\u4ed6\u5c45\u6c11\u7684\u6b63\u5e38\u7528\u7535\u3002 int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum of a = {}\", sum(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"sum of b = {}\", sum(b)); return 0; } \u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8bf4\u7684 \u804c\u8d23\u5355\u4e00\u539f\u5219 \u3002 \u4e8c\u6b21\u5c01\u88c5 \u5047\u8bbe\u6211\u4eec\u8981\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff0c\u53ef\u4ee5\u518d\u5b9a\u4e49\u4e2a\u51fd\u6570 average\uff0c\u4ed6\u53ef\u4ee5\u57fa\u4e8e sum \u5b9e\u73b0\uff1a int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } double average(std::vector const &v) { return (double)sum(v) / v.size(); } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"average of a = {}\", average(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"average of b = {}\", average(b)); return 0; } \u8fdb\u4e00\u6b65\u5c01\u88c5\u4e00\u4e2a\u6253\u5370\u6570\u7ec4\u6240\u6709\u7edf\u8ba1\u5b66\u4fe1\u606f\u7684\u51fd\u6570\uff1a void print_statistics(std::vector const &v) { if (v.empty()) { fmt::println(\"this is empty...\"); } else { fmt::println(\"sum: {}\", sum(v)); fmt::println(\"average: {}\", average(v)); fmt::println(\"min: {}\", min(v)); fmt::println(\"max: {}\", max(v)); } } int main() { std::vector a = {1, 2, 3, 4}; print_statistics(a); std::vector b = {5, 6, 7, 8}; print_statistics(b); return 0; } \u66b4\u9732 API \u65f6\uff0c\u8981\u540c\u65f6\u63d0\u4f9b\u5e95\u5c42\u7684 API \u548c\u9ad8\u5c42\u5c01\u88c5\u7684 API\u3002\u7528\u6237\u5982\u679c\u60f3\u8981\u63a7\u5236\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u8c03\u7528\u5e95\u5c42 API\uff0c\u60f3\u8981\u7701\u4e8b\u7684\u7528\u6237\u53ef\u4ee5\u8c03\u7528\u9ad8\u5c42\u5c01\u88c5\u597d\u7684 API\u3002 \u9ad8\u5c42\u5c01\u88c5 API \u5e94\u5f53\u53ef\u4ee5\u5b8c\u5168\u901a\u8fc7\u8c03\u7528\u5e95\u5c42 API \u5b9e\u73b0\uff0c\u63d0\u4f9b\u9ad8\u5c42 API \u53ea\u662f\u65b9\u4fbf\u521d\u7ea7\u7528\u6237\u4f7f\u7528\u548c\u7406\u89e3\u3002 \u4f8b\u5982 libcurl \u5c31\u63d0\u4f9b\u4e86 curl_easy \u548c curl_multi \u4e24\u5957 API\u3002 - `curl_multi` \u63d0\u4f9b\u4e86\u8d85\u8be6\u7ec6\u7684\u53c2\u6570\uff0c\u628a\u6bcf\u4e2a\u64cd\u4f5c\u5206\u62c6\u6210\u591a\u6b65\uff0c\u65b9\u4fbf\u7528\u6237\u63d2\u624b\u7ec6\u8282\uff0c\u6ee1\u8db3\u9ad8\u7ea7\u7528\u6237\u7684\u5b9a\u5236\u5316\u9700\u6c42\uff0c\u4f46\u592a\u8fc7\u590d\u6742\uff0c\u96be\u4ee5\u5b66\u4e60\u3002 - `curl_easy` \u662f\u5bf9 `curl_multi` \u7684\u518d\u5c01\u88c5\uff0c\u63d0\u4f9b\u4e86\u66f4\u7b80\u5355\u7684 API\uff0c\u4f46\u662f\u5bf9\u5177\u4f53\u7ec6\u8282\u5c31\u96be\u4ee5\u64cd\u63a7\u4e86\uff0c\u9002\u5408\u521d\u5b66\u8005\u4e0a\u624b\u3002 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c Linux \u5185\u6838\u4e3a\u4ec0\u4e48\u575a\u6301\u4f7f\u7528 8 \u7f29\u8fdb\u4e3a\u4ee3\u7801\u98ce\u683c\uff1f \u56e0\u4e3a\u9ad8\u7f29\u8fdb\u53ef\u4ee5\u907f\u514d\u7a0b\u5e8f\u5458\u5199\u51fa\u5d4c\u5957\u5c42\u6570\u592a\u6df1\u7684\u4ee3\u7801\uff0c\u5f53\u4ed6\u5199\u51fa\u592a\u6df1\u5d4c\u5957\u65f6\uff0c\u5de8\u5927\u7684 8 \u7f29\u8fdb\u4f1a\u8ba9\u4ee3\u7801\u53d8\u5f97\u975e\u5e38\u504f\u53f3\uff0c\u5199\u4e0d\u4e0b\u591a\u5c11\u7a7a\u95f4\u3002\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u81ea\u5df1\u7ea2\u7740\u8138\u201c\u5bf9\u4e0d\u8d77\uff0c\u6211\u628a\u5355\u4e2a\u51fd\u6570\u5199\u592a\u6df1\u4e86\u201d\u7136\u540e\u8d76\u7d27\u62c6\u5206\u51fa\u591a\u4e2a\u51fd\u6570\u6765\u3002 \u6b64\u5916\uff0c\u4ed6\u8fd8\u89c4\u5b9a\u4e86\u5355\u4e00\u4e00\u4e2a\u51fd\u6570\u5fc5\u987b\u5728\u7ec8\u7aef\u5bbd\u5ea6 80 x 24 \u4e2d\u663e\u793a\u5f97\u4e0b\uff0c\u5426\u5219\u5c31\u9700\u8981\u62c6\u5206\u6210\u591a\u4e2a\u51fd\u6570\u91cd\u5199\uff0c\u8fd9\u914d\u5408 8 \u7f29\u8fdb\uff0c\u6709\u6548\u7684\u9650\u5236\u4e86\u5d4c\u5957\u7684\u5c42\u6570\uff0c\u8feb\u4f7f\u7a0b\u5e8f\u5458\u4e0d\u5f97\u4e0d\u91cd\u65b0\u601d\u8003\uff0c\u66f4\u89e3\u8026\u7684\u5199\u6cd5\u51fa\u6765\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u4f60\u4ea7\u751f\u4e86\u4e24\u4e2a\u9700\u6c42\uff0c\u5206\u522b\u5c01\u88c5\u4e86\u4e24\u4e2a\u51fd\u6570\uff1a sum \u6c42\u6240\u6709\u5143\u7d20\u7684\u548c product \u6c42\u6240\u6709\u5143\u7d20\u7684\u79ef int sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret += v[i]; } return ret; } int product(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret *= v[i]; } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", sum(a)); fmt::println(\"product: {}\", product(a)); return 0; } \u6ce8\u610f\u5230 sum \u548c product \u7684\u5185\u5bb9\u51e0\u4e4e\u5982\u51fa\u4e00\u8f99\uff0c\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff1a sum \u7684\u5faa\u73af\u4f53\u4e3a += \uff1b product \u7684\u5faa\u73af\u4f53\u4e3a *= \u3002 \u8fd9\u79cd\u51fd\u6570\u4f53\u5185\u6709\u90e8\u5206\u4ee3\u7801\u91cd\u590d\uff0c\u4f46\u53c8\u6709\u7279\u5b9a\u90e8\u5206\u4e0d\u540c\uff0c\u96be\u4ee5\u62bd\u79bb\u3002 \u8be5\u600e\u4e48\u590d\u7528\u8fd9\u91cd\u590d\u7684\u90e8\u5206\u4ee3\u7801\u5462\uff1f \u6211\u4eec\u8981\u628a sum \u548c product \u5408\u5e76\u6210\u4e00\u4e2a\u51fd\u6570 generic_sum \u3002\u7136\u540e\u901a\u8fc7\u51fd\u6570\u53c2\u6570\uff0c\u628a\u5dee\u5f02\u90e8\u5206\uff080\u3001 += \uff09\u201c\u6ce8\u5165\u201d\u5230\u4e24\u4e2a\u51fd\u6570\u539f\u672c\u4e0d\u540c\u5730\u65b9\u3002 \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u5982\u4f55\u8868\u793a\u6211\u8fd9\u4e2a\u51fd\u6570\u662f\u8981\u505a\u6c42\u548c += \u8fd8\u662f\u6c42\u79ef *= \uff1f \u8ba9\u6211\u4eec\u5b9a\u4e49\u679a\u4e3e\uff1a enum Mode { ADD, // \u6c42\u548c\u64cd\u4f5c MUL, // \u6c42\u79ef\u64cd\u4f5c }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { // \u51fd\u6570\u5185\u5224\u65ad\u679a\u4e3e\uff0c\u51b3\u5b9a\u8981\u505a\u4ec0\u4e48\u64cd\u4f5c ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", generic_sum(a, ADD)); // \u7528\u6237\u6307\u5b9a\u4ed6\u60f3\u8981\u7684\u64cd\u4f5c fmt::println(\"product: {}\", generic_sum(a, MUL)); return 0; } \u7136\u800c\uff0c\u5982\u679c\u7528\u6237\u73b0\u5728\u60f3\u8981\u6c42\u6570\u7ec4\u7684 \u6700\u5927\u503c \u5462\uff1f \u679a\u4e3e\u4e2d\u8fd8\u6ca1\u6709\u5b9e\u73b0\u6700\u5927\u503c\u7684\u64cd\u4f5c\u2026\u2026\u8981\u652f\u6301\uff0c\u5c31\u5f97\u624b\u5fd9\u811a\u4e71\u5730\u53bb\u4fee\u6539 generic_sum \u51fd\u6570\u548c Mode \u679a\u4e3e\u539f\u672c\u7684\u5b9a\u4e49\uff0c\u771f\u9ebb\u70e6\uff01 enum Mode { ADD, MUL, MAX, // ***\u6539*** }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } else if (mode == MAX) { // ***\u6539*** ret = std::max(ret, v[i]); // ***\u6539*** } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, MAX); // ***\u6539*** return 0; } \u6211\u7528 // ***\u6539*** \u6307\u793a\u4e86\u6240\u6709\u9700\u8981\u6539\u52a8\u7684\u5730\u65b9\u3002 \u4e3a\u4e86\u589e\u52a0\u4e00\u4e2a\u6c42\u6700\u5927\u503c\u7684\u64cd\u4f5c\uff0c\u5c31\u9700\u8981\u4e09\u5904\u5206\u6563\u5728\u5404\u5730\u7684\u6539\u52a8\uff01 \u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u5bb9\u6613\u6284\u6f0f\uff0c\u6284\u9519\uff0c\u6bd4\u5982 MAX \u4e0d\u5c0f\u5fc3\u6253\u9519\u6210 MUL \u4e86\uff0c\u81ea\u5df1\u5374\u6ca1\u53d1\u73b0\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u8fd9\u6837\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\uff0c\u5fc3\u667a\u8d1f\u62c5\u6781\u5927\uff0c\u6574\u5929\u5c31\u63d0\u5fc3\u540a\u80c6\u7740\u4e1c\u4e00\u5757\uff0c\u897f\u4e00\u5757\u7684\u6563\u88c5\u4ee3\u7801\uff0c\u62c5\u5fc3\u7740\u6709\u6ca1\u6709\u54ea\u4e2a\u5730\u65b9\u5199\u9519\u5199\u6f0f\uff0c\u4e25\u91cd\u59a8\u788d\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u5e76\u4e14\u5199\u51fa\u6765\u7684\u4ee3\u7801\u4e5f\u4e0d\u80fd\u9002\u5e94\u9700\u6c42\u7684\u53d8\u5316\uff1a\u5047\u5982\u6211\u9700\u8981\u652f\u6301 MIN \u5462\uff1f\u53c8\u5f97\u6539\u4e09\u4e2a\u5730\u65b9\uff01\u8fd9\u8fdd\u80cc\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u7684 \u5f00\u95ed\u539f\u5219 \u3002 \u5f00\u95ed\u539f\u5219: \u5bf9\u6269\u5c55\u5f00\u653e\uff0c\u5bf9\u4fee\u6539\u5c01\u95ed\u3002\u6307\u7684\u662f\u8f6f\u4ef6\u5728\u9002\u5e94\u9700\u6c42\u53d8\u5316\u65f6\uff0c\u5e94\u5c3d\u91cf\u901a\u8fc7 \u6269\u5c55\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\uff0c\u800c\u4e0d\u662f\u901a\u8fc7 \u4fee\u6539\u5df2\u6709\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\u3002 \u4f7f\u7528\u679a\u4e3e\u548c if-else \u5b9e\u73b0\u591a\u6001\uff0c\u96be\u4ee5\u6269\u5c55\uff0c\u8fd8\u8981\u4e00\u76f4\u53bb\u4fee\u6539\u539f\u51fd\u6570\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5c31\u8fdd\u80cc\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u5982\u679c\u6211\u4eec\u53ef\u4ee5\u201c\u6ce8\u5165\u201d\u4ee3\u7801\u5c31\u597d\u4e86\uff01\u80fd\u5426\u628a\u4e00\u6bb5\u201c\u4ee3\u7801\u201d\u4f5c\u4e3a generic_sum \u51fd\u6570\u7684\u53c2\u6570\u5462\uff1f \u4ee3\u7801\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\uff0c\u6ce8\u5165\u4ee3\u7801\u5c31\u662f\u6ce8\u5165\u51fd\u6570\u3002\u6211\u4eec\u5148\u5b9a\u4e49\u51fa\u4e09\u4e2a\u4e0d\u540c\u64cd\u4f5c\u5bf9\u5e94\u7684\u51fd\u6570\uff1a int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } \u7136\u540e\uff0c\u628a\u8fd9\u4e09\u4e2a\u5c0f\u51fd\u6570\uff0c\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u5927\u51fd\u6570 generic_sum \u7684\u53c2\u6570\u5c31\u884c\uff01 int generic_sum(std::vector const &v, auto op) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { // \u51fd\u6570\u4f5c\u8005\u65e0\u9700\u4e86\u89e3\u7528\u6237\u6307\u5b9a\u7684\u201c\u64cd\u4f5c\u201d\u5177\u4f53\u662f\u4ec0\u4e48 // \u53ea\u9700\u8981\u8c03\u7528\u8fd9\u4e00\u201c\u64cd\u4f5c\u201d\uff0c\u5f97\u5230\u7ed3\u679c\u5c31\u884c ret = op(ret, v[i]); } return ret; } int main() { std::vector a = {1, 2, 3, 4}; // \u7528\u6237\u65e0\u9700\u5173\u5fc3\u51fd\u6570\u7684\u5177\u4f53\u5b9e\u73b0\u662f\u4ec0\u4e48 // \u53ea\u9700\u968f\u5fc3\u6240\u6b32\u6307\u5b9a\u4ed6\u7684\u201c\u64cd\u4f5c\u201d\u4f5c\u4e3a\u53c2\u6570 generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u8d23\u4efb\u660e\u786e\u4e86\uff0c\u6211\u4eec\u6210\u529f\u628a\u4e00\u90e8\u5206\u7ec6\u8282\u4ece generic_sum \u4e2d\u8fdb\u4e00\u6b65\u62bd\u79bb\u3002 \u5e93\u4f5c\u8005 generic_sum \u4e0d\u5fc5\u4e86\u89e3 main \u7684\u64cd\u4f5c\u5177\u4f53\u662f\u4ec0\u4e48\uff0c\u4ed6\u53ea\u8d1f\u8d23\u5229\u7528\u8fd9\u4e2a\u64cd\u4f5c\u6c42\u201c\u548c\u201d\u3002 \u5e93\u7528\u6237 main \u4e0d\u5fc5\u4e86\u89e3 generic_sum \u5982\u4f55\u5b9e\u73b0\u64cd\u4f5c\u7d2f\u52a0\uff0c\u4ed6\u53ea\u7ba1\u6ce8\u5165\u201c\u5982\u4f55\u64cd\u4f5c\u201d\u7684\u4ee3\u7801\uff0c\u4ee5\u51fd\u6570\u7684\u5f62\u5f0f\u3002 \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 int generic_sum(std::vector const &v, auto op) { } \u8fd9\u91cc\u7684\u53c2\u6570 op \u7c7b\u578b\u58f0\u660e\u4e3a auto\uff0c\u6548\u679c\u5c31\u662f\uff0cop \u8fd9\u4e2a\u53c2\u6570\u73b0\u5728\u80fd\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u7684\u5bf9\u8c61\u4e86\uff08\u5305\u62ec\u51fd\u6570\uff01\uff09 int generic_sum(std::vector const &v, auto op) { ... } \u51c6\u786e\u7684\u8bf4\uff0c auto op \u53c2\u6570\u7684\u6548\u679c\u662f\u4f7f generic_sum \u53d8\u4e3a\u4e00\u4e2a \u6a21\u677f\u51fd\u6570 \uff0c\u5176\u4e2d op \u53c2\u6570\u53d8\u6210\u4e86\u6a21\u677f\u53c2\u6570\uff0c\u80fd\u591f\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u4e86\u3002\u800c\u5199\u660e\u7c7b\u578b\u7684\u53c2\u6570 std::vector const &v \u5c31\u6ca1\u6709\u4efb\u4f55\u989d\u5916\u6548\u679c\uff0c\u5c31\u53ea\u80fd\u63a5\u53d7 vector \u800c\u5df2\u3002 \u5982\u679c\u4f60\u4e0d\u652f\u6301 C++20 \u7684\u8bdd\uff0c\u9700\u8981\u663e\u5f0f\u5199\u51fa template \uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\uff1a template int generic_sum(std::vector const &v, Op op) { ... } C++11\uff1aauto \u53ea\u80fd\u7528\u4e8e\u5b9a\u4e49\u53d8\u91cf\uff1bC++14\uff1a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u662f auto\uff1bC++17\uff1a\u6a21\u677f\u53c2\u6570\u4e5f\u53ef\u4ee5 auto\uff1bC++20\uff1a\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5\u662f auto \u4e86\uff1b\uff08\u72c2\u60f3\uff09C++47\uff1aauto \u73b0\u5728\u662f C++47 \u7684\u552f\u4e00\u5173\u952e\u5b57\uff0c\u7528\u6237\u53ea\u9700\u4e0d\u65ad\u8f93\u5165 auto-auto-auto\uff0c\u7f16\u8bd1\u5668\u5185\u5efa\u4eba\u5de5\u667a\u80fd\u81ea\u52a8\u8bc6\u522b\u4f60\u7684\u610f\u56fe\u751f\u6210\u673a\u5668\u7801\u3002 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 \u5728\u8fc7\u53bb\u7684 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f \u4e2d\uff0c\u51fd\u6570\uff08\u4ee3\u7801\uff09\u548c\u5bf9\u8c61\uff08\u6570\u636e\uff09\u88ab \u5272\u88c2 \u5f00\u6765\uff0c\u4ed6\u4eec\u611a\u6627\u5730\u8ba4\u4e3a \u51fd\u6570\u4e0d\u662f\u5bf9\u8c61 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f \u5219\u8ba4\u4e3a\uff1a \u51fd\u6570\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u51fd\u6570\u53ef\u4ee5\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u51fd\u6570\u7684\u53c2\u6570\uff01 Function lives matter! \u9762\u5411\u5bf9\u8c61\u5c31\u597d\u6bd4\u8ba1\u7b97\u673a\u7684\u201c\u54c8\u4f5b\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u548c\u6570\u636e\u5272\u88c2\uff0c\u4ee3\u7801\u53ea\u80fd\u5355\u65b9\u9762\u64cd\u4f5c\u6570\u636e\u3002\u51fd\u6570\u5f0f\u5c31\u597d\u6bd4\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u4e5f\u662f\u6570\u636e\u3002\u770b\u4f3c\u4f1a\u5bfc\u81f4\u4f4e\u6548\uff0c\u5b9e\u5219\u5927\u5927\u65b9\u4fbf\u4e86\u52a8\u6001\u52a0\u8f7d\u65b0\u7a0b\u5e8f\uff0c\u56e0\u800c\u73b0\u5728\u7684\u8ba1\u7b97\u673a\u57fa\u672c\u90fd\u91c7\u7528\u4e86\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff0c\u88ab\u4eb2\u5207\u5730\u5c0a\u79f0\u4e3a \u51fd\u6570\u5bf9\u8c61 \u3002 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 C++98 \u65f6\u4ee3\uff0c\u4eba\u4eec\u8fd8\u9700\u8981\u5355\u72ec\u8dd1\u5230 main \u5916\u9762\uff0c\u4e13\u95e8\u5b9a\u4e49 add \u3001 mul \u3001 max \u51fd\u6570\u3002\u5f04\u5f97\u6574\u4e2a\u4ee3\u7801\u4e71\u54c4\u54c4\u7684\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } C++11 \u5f15\u5165\u4e86 Lambda \u8868\u8fbe\u5f0f \u8bed\u6cd5\uff0c\u5141\u8bb8\u4f60\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002 int main() { std::vector a = {1, 2, 3, 4}; auto add = [](int a, int b) { return a + b; }; auto mul = [](int a, int b) { return a * b; }; auto max = [](int a, int b) { return std::max(a, b); }; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u4e0d\u7528\u5f80 main \u5916\u9762\u585e\u5783\u573e\u4e86\uff0c\u4e00\u6e05\u723d\u3002 \u66f4\u8fdb\u4e00\u6b65\uff0c\u6211\u4eec\u751a\u81f3\u4e0d\u7528\u5b9a\u4e49\u53d8\u91cf\uff0c\u76f4\u63a5\u628a Lambda \u8868\u8fbe\u5f0f\u5199\u5728 generic_sum \u7684\u53c2\u6570\u91cc\u5c31\u884c\u4e86\uff01 int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); // ***\u6539*** return 0; } \u4ee5\u4e0a\u5199\u6cd5\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u8981\u652f\u6301\u4e00\u4e2a\u65b0\u64cd\u4f5c\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5730\u65b9\uff1a\u5728\u8c03\u7528 generic_sum \u65f6\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002\u968f\u53eb\u968f\u5230\uff0c\u4e0d\u7528\u7ea0\u7ed3\u4e8e\u201c\u8d77\u540d\u5f3a\u8feb\u75c7\u201d\uff0c\u662f\u4e0d\u662f\u5f88\u65b9\u4fbf\u5462\uff1f \u51c6\u786e\u7684\u8bf4\uff0cLambda \u521b\u5efa\u7684\u662f\u51fd\u6570\u5bf9\u8c61 (function object) \u6216\u79f0\u4eff\u51fd\u6570 (functor) \u800c\u4e0d\u662f\u4f20\u7edf\u610f\u4e49\u4e0a\u7684\u51fd\u6570\u3002 \u5176\u5b9e C++98 \u65f6\u4ee3\u4eba\u4eec\u5c31\u5df2\u7ecf\u5927\u91cf\u5728\u7528 operator()() \u6a21\u62df\u51fd\u6570\u5bf9\u8c61\u4e86\uff0c\u8457\u540d\u7684\u7b2c\u4e09\u65b9\u5e93 Boost \u4e5f\u5c01\u88c5\u4e86\u5404\u79cd\u51fd\u6570\u5f0f\u5e38\u7528\u7684\u5bb9\u5668\u548c\u5de5\u5177\u3002C++11 \u624d\u7ec8\u4e8e\u628a \u51fd\u6570\u5bf9\u8c61 \u8fd9\u4e2a\u6982\u5ff5\u8f6c\u6b63\uff0c\u5e76\u5f15\u5165\u4e86\u66f4\u65b9\u4fbf\u7684 Lambda \u8bed\u6cd5\u7cd6\u3002 \u5373\u4f7f\u662f\u9762\u5411\u5bf9\u8c61\u7684\u5934\u53f7\u5b5d\u5b50 Java\uff0c\u4e5f\u5df2\u7ecf\u5f00\u59cb\u5f15\u5165\u51fd\u6570\u5f0f\u7684 Lambda \u8bed\u6cd5\u7cd6\uff0cC# \u7684 LINQ \u66f4\u662f\u660e\u76ee\u5f20\u80c6\u7684\u81f4\u656c map-reduce \u5168\u5bb6\u6876\uff0c\u751a\u81f3 C \u8bed\u8a00\u7528\u6237\u4e5f\u5f00\u59cb\u73a9\u5404\u79cd\u51fd\u6570\u6307\u9488\u56de\u8c03\u2026\u2026\u6ca1\u529e\u6cd5\uff0c\u51fd\u6570\u5f0f\u786e\u5b9e\u65b9\u4fbf\u5440\uff01 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u51fd\u6570\u5bf9\u8c61 op \u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\uff0c\u8ba9 generic_sum \u5185\u90e8\u53bb\u8c03\u7528\uff0c\u5c31\u50cf\u5f80 generic_sum \u4f53\u5185\u201c\u6ce8\u5165\u201d\u4e86\u4e00\u6bb5\u81ea\u5b9a\u4e49\u4ee3\u7801\u4e00\u6837\u3002 \u8fd9\u53ef\u4ee5\u8ba9 generic_sum \u5728\u4e0d\u4fee\u6539\u672c\u4f53\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7\u4fee\u6539\u201c\u6ce8\u5165\u201d\u90e8\u5206\uff0c\u8f7b\u677e\u6269\u5c55\uff0c\u6ee1\u8db3 \u5f00\u95ed\u539f\u5219 \u3002 \u66f4\u51c6\u786e\u7684\u8bf4\uff0c\u8fd9\u4f53\u73b0\u7684\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8981\u6c42\u7684 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u3002 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219: \u4e00\u4e2a\u5c01\u88c5\u597d\u7684\u51fd\u6570\u6216\u7c7b\uff0c\u5e94\u8be5\u5c3d\u91cf\u4f9d\u8d56\u4e8e\u62bd\u8c61\u63a5\u53e3\uff0c\u800c\u4e0d\u662f\u4f9d\u8d56\u4e8e\u5177\u4f53\u5b9e\u73b0\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u56db\u5927\u7f16\u7a0b\u8303\u5f0f\u90fd\u5404\u81ea\u53d1\u5c55\u51fa\u4e86 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u7684\u89e3\u51b3\u65b9\u6848\uff1a \u9762\u5411\u8fc7\u7a0b\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u6307\u9488 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u865a\u51fd\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u5bf9\u8c61 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u6a21\u677f\u5143\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u6a21\u677f\u53c2\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u540c\u6837\u662f\u628a\u62bd\u8c61\u63a5\u53e3\u4f5c\u4e3a\u53c2\u6570\uff0c\u540c\u6837\u89e3\u51b3\u53ef\u6269\u5c55\u95ee\u9898\u3002 \u51fd\u6570\u6307\u9488\u8d34\u8fd1\u5e95\u5c42\u786c\u4ef6\uff0c\u865a\u51fd\u6570\u65b9\u4fbf\u6574\u5408\u591a\u4e2a\u63a5\u53e3\uff0c\u51fd\u6570\u5bf9\u8c61\u8f7b\u91cf\u7ea7\u3001\u968f\u5730\u53d6\u7528\uff0c\u6a21\u677f\u5143\u6709\u52a9\u9ad8\u6027\u80fd\u4f18\u5316\uff0c\u4e0d\u540c\u7684\u7f16\u7a0b\u8303\u5f0f\u6b8a\u9014\u540c\u5f52\u3002 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4f9d\u8d56\u6ce8\u5165\u539f\u5219\u53ef\u4ee5\u51cf\u5c11\u4ee3\u7801\u4e4b\u95f4\u7684\u8026\u5408\u5ea6\uff0c\u5927\u5927\u63d0\u9ad8\u4ee3\u7801\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u8026\u5408\u5ea6: \u6307\u7684\u662f\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u548c\u5176\u4ed6\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u8026\u5408\u5ea6\u8d8a\u4f4e\uff0c\u8d8a\u5bb9\u6613\u8fdb\u884c\u5355\u5143\u6d4b\u8bd5\u3001\u91cd\u6784\u3001\u590d\u7528\u548c\u6269\u5c55\u3002 \u9ad8\u8026\u5408\u5ea6\u7684\u5178\u578b\u662f\u201c\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u201d\u3002\u4f4e\u8026\u5408\u7684\u5178\u8303\u662f\u86af\u8693\uff0c\u56e0\u4e3a\u86af\u8693\u53ef\u4ee5\u5728\u4efb\u610f\u65ad\u9762\u5207\u5f00\uff0c\u8fd8\u80fd\u6d3b\u4e0b\u6765\uff0c\u770b\u6765\u86af\u8693\u7684\u8eab\u4f53\u8bbe\u8ba1\u975e\u5e38\u201c\u6a21\u5757\u5316\u201d\u5462\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8f6f\u4ef6\u5e94\u5f53\u8ffd\u6c42\u4f4e\u8026\u5408\u5ea6\uff0c\u9002\u5ea6\u89e3\u8026\u7684\u8f6f\u4ef6\u80fd\u66f4\u5feb\u9002\u5e94\u9700\u6c42\u53d8\u5316\u3002\u4f46\u8fc7\u5ea6\u7684\u4f4e\u8026\u5408\u4e5f\u4f1a\u5bfc\u81f4\u4ee3\u7801\u8fc7\u4e8e\u5206\u6563\uff0c\u4e0d\u6613\u9605\u8bfb\u548c\u4fee\u6539\uff0c\u751a\u81f3\u53ef\u80fd\u8d77\u5230\u53cd\u6548\u679c\u3002 \u82e5\u4f60\u89e3\u8026\u540e\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u5316\u8981\u6539\u52a8\u7684\u5730\u65b9\u53d8\u5c11\u4e86\uff0c\u90a3\u5c31\u662f\u5408\u7406\u7684\u89e3\u8026\u3002\u82e5\u4f60\u8fc7\u5206\u89e3\u8026\uff0c\u4ee3\u7801\u4e1c\u4e00\u5757\u897f\u4e00\u5757\uff0c\u4ee5\u81f3\u4e8e\u9700\u6c42\u53d8\u5316\u65f6\u9700\u8981\u5230\u5904\u6539\uff0c\u6bd4\u4e0d\u89e3\u8026\u65f6\u6d6a\u8d39\u7684\u65f6\u95f4\u8fd8\u8981\u591a\uff0c\u90a3\u5c31\u662f\u89e3\u8026\u8fc7\u5ea6\u3002 \u5b8c\u5168\u96f6\u8026\u5408\u7684\u7a0b\u5e8f\u6bcf\u4e2a\u51fd\u6570\u4e92\u4e0d\u8054\u7cfb\uff0c\u5c31\u50cf\u628a\u86af\u8693\u62c6\u6563\u6210\u4e00\u4e2a\u4e2a\u72ec\u7acb\u7684\u7ec6\u80de\u4e00\u6837\u3002\u8fde\u521d\u59cb\u9700\u6c42\u201c\u6d3b\u7740\u201d\u90fd\u5b9e\u73b0\u4e0d\u4e86\uff0c\u8c08\u4f55\u9002\u5e94\u9700\u6c42\u53d8\u5316\uff1f\u6240\u4ee5\u89e3\u8026\u4e5f\u5207\u52ff\u77eb\u6789\u8fc7\u6b63\u3002 \u4e3a\u4e86\u907f\u514d\u89e3\u8026\u77eb\u6789\u8fc7\u6b63\uff0c\u4eba\u4eec\u53c8\u63d0\u51fa\u4e86\u5185\u805a\u7684\u6982\u5ff5\uff0c\u5e76\u89c4\u5b9a\u89e3\u8026\u7684\u524d\u63d0\u662f\uff1a\u4e0d\u803d\u8bef\u5185\u805a\u3002\u803d\u8bef\u5230\u5185\u805a\u7684\u89e3\u8026\uff0c\u5c31\u53ea\u4f1a\u8d77\u5230\u964d\u4f4e\u53ef\u7ef4\u62a4\u6027\u7684\u53cd\u6548\u679c\u4e86\u3002 \u5185\u805a: \u6307\u7684\u662f\u540c\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u5185\u90e8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u5185\u805a\u5ea6\u8d8a\u9ad8\uff0c\u529f\u80fd\u8d8a\u72ec\u7acb\uff0c\u8d8a\u65b9\u4fbf\u96c6\u4e2d\u7ef4\u62a4\u3002 \u4f8b\u5982\uff0c\u4eba\u7684\u5fc3\u810f\u4e13\u95e8\u8d1f\u8d23\u6cf5\u8840\uff0c\u809d\u810f\u53ea\u8d1f\u8d23\u89e3\u6bd2\uff0c\u8fd9\u5c31\u662f\u9ad8\u5185\u805a\u7684\u4eba\u4f53\u5668\u5b98\u3002\u82e5\u4eba\u7684\u5fc3\u810f\u8fd8\u8981\u517c\u804c\u89e3\u6bd2\uff0c\u809d\u810f\u8fd8\u517c\u804c\u6cf5\u8840\uff0c\u770b\u4f3c\u597d\u50cf\u662f\u589e\u52a0\u4e86\u201c\u4e07\u4e00\u5fc3\u810f\u574f\u6389\u201d\u7684\u5197\u4f59\u6027\uff0c\u5b9e\u9645\u4e0a\u628a\u201c\u6cf5\u8840\u201d\u8fd9\u4e00\u529f\u80fd\u62c6\u6563\u5230\u5404\u5730\uff0c\u65e0\u6cd5\u201c\u96c6\u4e2d\u529b\u91cf\u6cf5\u5927\u8840\u201d\u4e86\u3002 \u4eba\u7c7b\u7684\u5927\u8111\u548c CPU \u4e00\u6837\uff0c\u4e5f\u6709\u201c\u7f13\u5b58\u5c40\u57df\u6027 (cache-locality)\u201d\u7684\u9650\u5236\uff1a\u4e0d\u80fd\u540c\u65f6\u5728\u5f88\u591a\u4e2a\u4e3b\u9898\u4e4b\u95f4\u5feb\u901f\u5207\u6362\uff0c\u65e0\u8bba\u662f\u65f6\u95f4\u4e0a\u7684\u8fd8\u662f\u7a7a\u95f4\u4e0a\u7684\u5272\u88c2 (cache-miss)\uff0c\u90fd\u4f1a\u5e72\u6270\u7a0b\u5e8f\u5458\u601d\u7ef4\u7684\u8fde\u8d2f\u6027\uff0c\u4ece\u800c\u589e\u5927\u5fc3\u667a\u8d1f\u62c5\u3002 \u597d\u7684\u8f6f\u4ef6\u8981\u4fdd\u6301\u4f4e\u8026\u5408\uff0c\u540c\u65f6\u9ad8\u5185\u805a\u3002 \u5c31\u50cf\u201c\u6c11\u4e3b\u96c6\u4e2d\u5236\u201d\u4e00\u6837\uff0c\u65e2\u8981\u76d1\u7763\u9632\u6b62\u5927\u6743\u72ec\u63fd\uff0c\u53c8\u8981\u96c6\u4e2d\u529b\u91cf\u529e\u4e00\u4e2a\u4eba\u529e\u4e0d\u6210\u7684\u5927\u4e8b\u3002 \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u4f20\u7edf\u7684\u9762\u5411\u5bf9\u8c61\u540c\u6837\u53ef\u4ee5\u7528 \u865a\u51fd\u6570\u63a5\u53e3\u7c7b \u6a21\u62df \u51fd\u6570\u5bf9\u8c61 \u4e00\u6837\u7684\u529f\u80fd\uff0c\u53ea\u4e0d\u8fc7\u6ca1\u6709 lambda \u548c\u95ed\u5305\u7684\u8bed\u6cd5\u52a0\u6301\uff0c\u5199\u8d77\u6765\u975e\u5e38\u7e41\u7410\uff0c\u5c31\u548c\u5728 C \u8bed\u8a00\u91cc\u201c\u6a21\u62df\u201d\u9762\u5411\u5bf9\u8c61\u4e00\u6837\u3002 \u4e3a\u4e86\u8fd9\u4e48\u5c0f\u7684\u4e00\u4e2a\u4ee3\u7801\u5757\uff0c\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u5c31\u50cf\u5988\u5988\u5f00\u4e00\u67b6\u201c\u7a7a\u4e2d\u6218\u8f66\u201d A380 \u53ea\u662f\u4e3a\u4e86\u63a5\u4f60\u653e\u5b66\u4e00\u6837\uff0c\u7b49\u4f60\u503c\u597d\u673a\u7684\u65f6\u95f4\u6211\u81ea\u5df1\u8d70\u90fd\u8d70\u5230\u4e86\u3002\u800c\u51fd\u6570\u5f0f\u4e2d\uff0c\u7528 lambda \u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u76f8\u5f53\u4e8e\u968f\u5730\u6293\u6765\u4e00\u53f0\u5171\u4eab\u5355\u8f66\u5f00\u8d70\u3002 struct OpBase { // \u9762\u5411\u5bf9\u8c61\uff1a\u9047\u4e8b\u4e0d\u51b3\u5148\u5b9a\u4e49\u63a5\u53e3\u2026\u2026 virtual int compute(int a, int b) = 0; virtual ~OpBase() = default; }; struct OpAdd : OpBase { int compute(int a, int b) override { return a + b; } }; struct OpMul : OpBase { int compute(int a, int b) override { return a * b; } }; struct OpMax : OpBase { int compute(int a, int b) override { return std::max(a, b); } }; int generic_sum(std::vector const &v, OpBase *op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op->compute(ret, v[i]); // \u5199\u8d77\u6765\u4e5f\u9ebb\u70e6\uff0c\u9700\u8981\u8c03\u7528\u4ed6\u7684\u6210\u5458\u51fd\u6570\uff0c\u6210\u5458\u51fd\u6570\u53c8\u8981\u8d77\u540d\u2026\u2026 } delete op; return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, new OpAdd()); generic_sum(a, new OpMul()); generic_sum(a, new OpMax()); return 0; } \u4e0d\u4ec5\u9700\u8981\u5b9a\u4e49\u4e00\u5806\u7c7b\uff0c\u63a5\u53e3\u7c7b\uff0c\u5b9e\u73b0\u7c7b\uff0c\u7ee7\u627f\u6765\u7ee7\u627f\u53bb\uff0c\u8fd8\u9700\u8981\u7ba1\u7406\u8ba8\u538c\u7684\u6307\u9488\uff0c\u4ee3\u7801\u91cf\u7ffb\u500d\uff0c\u6ca1\u4ec0\u4e48\u53ef\u8bfb\u6027\uff0c\u53c8\u5f71\u54cd\u8fd0\u884c\u6548\u7387\u3002 3 \u5e74 2 \u73ed\u5c0f\u5f6d\u540c\u5b66\uff0c\u4f60\u7684\u5988\u5988\u5f00\u7740 A380 \u6765\u63a5\u4f60\u4e86\u3002 \u800c\u73b0\u4ee3 C++ \u53ea\u9700 Lambda \u8bed\u6cd5\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u723d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u521a\u521a\uff0c\u6211\u4eec\u7684\u5b9e\u73b0\u7528\u4e86 auto op \u505a\u53c2\u6570\uff0c\u8fd9\u7b49\u4ef7\u4e8e\u8ba9 generic_sum \u53d8\u6210\u4e00\u4e2a\u6a21\u677f\u51fd\u6570\u3002 int generic_sum(std::vector const &v, auto op); // \u4e0d\u652f\u6301 C++20 \u65f6\u7684\u66ff\u4ee3\u5199\u6cd5\uff1a template int generic_sum(std::vector const &v, Op op); \u8fd9\u610f\u5473\u7740\u6bcf\u5f53\u7528\u6237\u6307\u5b9a\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff08lambda\uff09\u65f6\uff0c generic_sum \u90fd\u4f1a\u91cd\u65b0\u5b9e\u4f8b\u5316\u4e00\u904d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u7f16\u8bd1\u540e\uff0c\u4f1a\u53d8\u6210\u7c7b\u4f3c\u4e8e\u8fd9\u6837\uff1a generic_sum(a); generic_sum(a); generic_sum(a); \u4f1a\u751f\u6210\u4e09\u4efd\u51fd\u6570\uff0c\u6bcf\u4e2a\u90fd\u662f\u72ec\u7acb\u7f16\u8bd1\u7684\uff1a int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = add(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = mul(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = max(ret, v[i]); } return ret; } \u8fd9\u5141\u8bb8\u7f16\u8bd1\u5668\u4e3a\u6bcf\u4e2a\u7248\u672c\u7684 generic_sum \u5355\u72ec\u505a\u4f18\u5316\uff0c\u91cf\u8eab\u5b9a\u5236\u6700\u4f18\u7684\u4ee3\u7801\u3002 \u4f8b\u5982 add \u8fd9\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u56e0\u4e3a\u53ea\u5728 generic_sum \u4e2d\u4f7f\u7528\u4e86\uff0c\u4f1a\u88ab\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u5185\u8054\uff0c\u4e0d\u4f1a\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u548c\u8df3\u8f6c\u7684\u6307\u4ee4\uff0c\u5404\u81ea\u4f18\u5316\u6210\u5355\u72ec\u4e00\u6761\u52a0\u6cd5 / \u4e58\u6cd5 / \u6700\u5927\u503c\u6307\u4ee4\u7b49\u3002 \u6bd4\u5982\uff0c\u7f16\u8bd1\u5668\u4f1a\u68c0\u6d4b\u5230 += \u53ef\u4ee5\u77e2\u91cf\u5316\uff0c\u4e8e\u662f\u7528 _mm_add_epi32 \u66ff\u4ee3\u4e86\u3002\u540c\u7406\uff0cmul \u5219\u7528 _mm_mullo_epi32 \u66ff\u4ee3\uff0cmax \u5219\u7528 _mm_max_epi32 \u66ff\u4ee3\u7b49\uff0c\u5404\u81ea\u5206\u522b\u751f\u6210\u4e86\u5404\u81ea\u7248\u672c\u6700\u4f18\u7684\u4ee3\u7801\u3002\u800c\u5982\u679c\u662f\u666e\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u4e0d\u4f1a\u751f\u6210\u4e09\u4efd\u91cf\u8eab\u5b9a\u505a\u7684\u5b9e\u4f8b\uff0c\u65e0\u6cd5\u77e2\u91cf\u5316\uff08\u6709\u4e00\u79cd\u4f8b\u5916\uff0c\u5c31\u662f\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u4e86 generic_sum \u4f3c\u4e4e\u53ea\u6709\u8fd9\u4e09\u79cd\u53ef\u80fd\u53c2\u6570\uff0c\u7136\u540e\u505a\u4e86 IPO \u4f18\u5316\uff0c\u4f46\u5e76\u4e0d\u5982\u6a21\u677f\u5b9e\u4f8b\u5316\u4e00\u6837\u7a33\u5b9a\u5f3a\u5236\uff09\u3002 \u4e3a\u4e09\u79cd\u4e0d\u540c\u7684 op \u53c2\u6570\u5206\u522b\u5b9a\u505a\u4e09\u4efd\u3002\u867d\u7136\u589e\u52a0\u4e86\u7f16\u8bd1\u65f6\u95f4\uff0c\u81a8\u80c0\u4e86\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u4f53\u79ef\uff1b\u4f46\u751f\u6210\u7684\u673a\u5668\u7801\u662f\u5206\u522b\u9488\u5bf9\u6bcf\u79cd\u7279\u4f8b\u4e00\u5bf9\u4e00\u6df1\u5ea6\u4f18\u5316\u7684\uff0c\u66f4\u9ad8\u6548\u3002 \u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\uff08gemm\uff09\u7684\u6700\u4f18\u7b97\u6cd5\uff0c\u5bf9\u4e8e\u4e0d\u540c\u7684\u77e9\u9635\u5927\u5c0f\u548c\u5f62\u72b6\u662f\u4e0d\u540c\u7684\u3002\u8457\u540d\u7684\u7ebf\u6027\u4ee3\u6570\u5e93 CUBLAS \u548c MKL \u4e2d\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u7528\u6237\u8f93\u5165\u7684\u77e9\u9635\u5f62\u72b6\uff0c\u9009\u53d6\u6700\u4f18\u7684\u7b97\u6cd5\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cCUBLAS \u5e93\u91cc\u5176\u5b9e\u5b58\u7740\u9002\u5408\u5404\u79cd\u77e9\u9635\u5927\u5c0f\u6392\u5217\u7ec4\u5408\u7684\u7b97\u6cd5\u4ee3\u7801\uff08\u4ee5 fatbin \u683c\u5f0f\u5b58\u50a8\u5728\u4e8c\u8fdb\u5236\u4e2d\uff09\u3002\u5f53\u8c03\u7528\u77e9\u9635\u4e58\u6cd5\u65f6\uff0c\u81ea\u52a8\u67e5\u5230\u6700\u9002\u5408\u7684\u4e00\u7248\u6765\u8c03\u7528\u7ed9\u4f60\u3002\u7c7b\u4f3c gemm\uff0c\u8fd8\u6709 gemv\u3001spmv\u2026\u2026\u6240\u6709\u7684\u77e9\u9635\u8fd0\u7b97 API \u90fd\u7ecf\u5386\u4e86\u8fd9\u6837\u7684\u201c\u7f16\u8bd1\u671f\u201d\u66b4\u529b\u6392\u5217\u7ec4\u5408\uff0c\u53ea\u4e3a\u201c\u8fd0\u884c\u65f6\u201d\u91ca\u653e\u6700\u5927\u6027\u80fd\uff01\u8fd9\u4e5f\u5bfc\u81f4\u7f16\u8bd1\u597d\u7684 cublas.dll \u6587\u4ef6\u6765\u5230\u4e86\u6050\u6016\u7684 20 MB \u5de6\u53f3\uff0c\u800c\u6211\u4eec\u79f0\u4e4b\u4e3a\u9ad8\u6548\u3002 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u6bcf\u4e2a Lambda \u8868\u8fbe\u5f0f\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b\uff0c\u8fd9\u4f7f\u5f97 generic_sum \u5bf9\u4e8e\u6bcf\u4e2a\u4e0d\u540c\u7684 Lambda \u90fd\u4f1a\u5b9e\u4f8b\u5316\u4e00\u904d\u3002\u867d\u7136\u6709\u5229\u4e8e\u6027\u80fd\u4f18\u5316\uff0c\u4f46\u4e5f\u5f71\u54cd\u4e86\u7f16\u8bd1\u901f\u5ea6\u548c\u7075\u6d3b\u6027\u3002 \u901a\u5e38\uff0c\u6211\u4eec\u53ea\u80fd\u901a\u8fc7 decltype(add) \u83b7\u53d6 add \u8fd9\u4e2a Lambda \u5bf9\u8c61\u7684\u7c7b\u578b\u3002\u4e5f\u53ea\u80fd\u901a\u8fc7 auto \u6765\u6355\u83b7 Lambda \u5bf9\u8c61\u4e3a\u53d8\u91cf\u3002 \u4e3a\u6b64\uff0c\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::function \u5bb9\u5668\uff0c\u4ed6\u80fd\u5bb9\u7eb3\u4efb\u4f55\u51fd\u6570\u5bf9\u8c61\uff01\u65e0\u8bba\u662f\u533f\u540d\u7684 Lambda \u51fd\u6570\u5bf9\u8c61\uff0c\u8fd8\u662f\u666e\u666e\u901a\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u90fd\u80fd\u7eb3\u5165 std::function \u7684\u4f53\u5185\u3002 \u552f\u4e00\u7684\u4ee3\u4ef7\u662f\uff0c\u4f60\u9700\u8981\u6307\u5b9a\u51fa\u6240\u6709\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u53c2\u6570\u4e3a\u4e24\u4e2a int \uff0c\u8fd4\u56de int \u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7528 std::function \u5bb9\u5668\u5b58\u50a8\u3002 auto add_lambda = [](int a, int b) { // Lambda \u51fd\u6570\u5bf9\u8c61 return a + b; }; struct AddClass { int operator()(int a, int b) { // \u81ea\u5b9a\u4e49\u7c7b\u6a21\u62df\u51fd\u6570\u5bf9\u8c61 return a + b; } }; AddClass add_object; int add_regular_func(int a, int b) { // \u666e\u901a\u51fd\u6570 return a + b; } std::function add; // \u6240\u6709\u5e7f\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u7edf\u7edf\u63a5\u7eb3 add = add_lambda; // OK add = add_object; // OK add = add_regular_func; // OK int generic_sum(std::vector const &v, std::function op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op(ret, v[i]); // \u5199\u8d77\u6765\u548c\u6a21\u677f\u4f20\u53c2\u65f6\u4e00\u6837\u65e0\u611f } // \u65e0\u9700\u6307\u9488\uff0c\u65e0\u9700 delete\uff0cfunction \u80fd\u81ea\u52a8\u7ba1\u7406\u51fd\u6570\u5bf9\u8c61\u751f\u547d\u5468\u671f return ret; } \u5982\u679c\u8fd8\u60f3\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b std::function \u3002\u8fd9\u91cc std::any \u662f\u4e2a\u8d85\u7ea7\u4e07\u80fd\u5bb9\u5668\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u4f55\u5bf9\u8c61\uff0c\u4ed6\u548c std::function \u4e00\u6837\u90fd\u91c7\u7528\u4e86\u201c\u7c7b\u578b\u64e6\u9664 (type-erasure)\u201d\u6280\u672f\uff0c\u7f3a\u70b9\u662f\u5fc5\u987b\u914d\u5408 std::any_cast \u624d\u80fd\u53d6\u51fa\u4f7f\u7528\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u8fdb\u9636\u4e13\u9898\u4e2d\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u4ed6\u4eec\u7684\u539f\u7406\uff0c\u5e76\u5e26\u4f60\u81ea\u5df1\u505a\u4e00\u4e2a\u64e6\u52a0\u6cd5\u7684\u7c7b\u578b\u64e6\u9664\u5bb9\u5668\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\uff0c\u80fd\u5728\u9759\u6001\u4e0e\u52a8\u6001\u4e4b\u95f4\u8f7b\u677e\u5207\u6362\uff0c \u9ad8\u6027\u80fd \u4e0e \u7075\u6d3b\u6027 \u4efb\u541b\u9009\u62e9\u3002 \u5728\u9700\u8981\u6027\u80fd\u7684 \u74f6\u9888\u4ee3\u7801 \u4e2d\u7528\u6a21\u677f\u4f20\u53c2\uff0c\u7f16\u8bd1\u671f\u9759\u6001\u5206\u53d1\uff0c\u591a\u6b21\u91cf\u8eab\u5b9a\u505a\uff0c\u63d0\u9ad8\u8fd0\u884c\u65f6\u6027\u80fd\u3002 \u74f6\u9888\u4ee3\u7801: \u5f80\u5f80\u4e00\u4e2a\u7a0b\u5e8f 80% \u7684\u65f6\u95f4\u82b1\u5728 20% \u7684\u4ee3\u7801\u4e0a\u3002\u8fd9 20% \u662f\u5728\u7a0b\u5e8f\u4e2d\u9891\u7e41\u6267\u884c\u7684\u3001\u8ba1\u7b97\u91cf\u5927\u7684\u3001\u6216\u8005\u8c03\u7528\u7279\u522b\u8017\u65f6\u7684\u51fd\u6570\u3002\u9488\u5bf9\u8fd9\u90e8\u5206\u74f6\u9888\u4ee3\u7801\u4f18\u5316\u5373\u53ef\uff0c\u800c\u5269\u4f59\u7684 80% \u6253\u9171\u6cb9\u4ee3\u7801\uff0c\u5927\u53ef\u4ee5\u600e\u4e48\u65b9\u4fbf\u600e\u4e48\u5199\u3002 \u5728\u6027\u80fd\u65e0\u5173\u7d27\u8981\u7684\u9876\u5c42\u4e1a\u52a1\u903b\u8f91\u4e2d\u7528 function \u5bb9\u5668\u4f20\u53c2\uff0c\u8fd0\u884c\u65f6\u52a8\u6001\u5206\u53d1\uff0c\u8282\u7701\u7f16\u8bd1\u4f53\u79ef\uff0c\u65b9\u4fbf\u6301\u4e45\u5b58\u50a8\uff0c\u7075\u6d3b\u6613\u7528\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 generic_sum \u51fd\u6570\uff0c\u5982\u679c\u6211\u4eec\u7a81\u7136\u60f3\u8981\u9ad8\u6027\u80fd\u4e86\uff0c\u53ea\u9700\u628a std::function op \u8f7b\u8f7b\u6539\u4e3a auto op \u5c31\u8f7b\u677e\u5207\u6362\u5230\u9759\u6001\u5206\u53d1\u6a21\u5f0f\u4e86\u3002 \u800c\u865a\u51fd\u6570\u4e00\u65e6\u7528\u4e86\uff0c\u57fa\u672c\u5c31\u53ea\u80fd\u52a8\u6001\u5206\u53d1\u4e86\uff0c\u5373\u4f7f\u80fd\u88ab IPO \u4f18\u5316\u6389\uff0c\u865a\u8868\u6307\u9488\u4e5f\u6c38\u8fdc\u5360\u636e\u7740\u4e00\u4e2a 8 \u5b57\u8282\u7684\u7a7a\u95f4\uff0c\u4e14\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u5f0f\u4f20\u6765\u4f20\u53bb\u3002 \u4e00\u79cd\u9759\u6001\u5206\u53d1\u7248\u7684\u865a\u51fd\u6570\u66ff\u4ee3\u54c1\u662f CRTP\uff0c\u4ed6\u57fa\u4e8e\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u4f46\u4e0e\u865a\u51fd\u6570\u4e4b\u95f4\u5207\u6362\u56f0\u96be\uff0c\u4e0d\u50cf\u51fd\u6570\u5bf9\u8c61\u90a3\u4e48\u65e0\u611f\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u3002 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u4e3b\u7ebf\u7a0b\u4e0d\u65ad\u5730\u5411\u5de5\u4f5c\u8005\u7ebf\u7a0b\u53d1\u9001\u51fd\u6570\u5bf9\u8c61\uff0c\u4ee4\u5176\u4ee3\u4e3a\u6267\u884c\uff1a mt_queue> task_queue; void main_thread() { task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a11\"); }); task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a12\"); }); } void worker_thread() { while (true) { auto task = task_queue.pop(); task(); } } mt_queue \u662f\u5c0f\u5f6d\u8001\u5e08\u5c01\u88c5\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u7684\u6d88\u606f\u961f\u5217\uff0c\u5b9e\u73b0\u539f\u7406\u4f1a\u5728\u7a0d\u540e\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4e2d\u8be6\u7ec6\u8bb2\u89e3\u3002 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u662f\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff0c\u4ed6\u5141\u8bb8\u51fd\u6570\u5bf9\u8c61\u6355\u83b7\u5916\u90e8\u53d8\u91cf\uff0c\u5e76\u5728\u51fd\u6570\u5bf9\u8c61\u5185\u90e8\u4f7f\u7528\u8fd9\u4e9b\u53d8\u91cf\u3002 int x = 10; auto add_x = [x](int a) { return a + x; }; fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 \u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u52a0\u4e0a mutable \u4fee\u9970\uff0c\u89c1\u540e\u6587\u3002 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u95ed\u5305\u8bed\u6cd5\uff1a int x = 10; auto add_x = [x](int a) { return a + x; }; \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u4e00\u4e2a\u5e26\u6709 operator() \u6210\u5458\u51fd\u6570\u7684\u7ed3\u6784\u4f53\uff1a struct Lambda { int x; Lambda(int val) : x(val) {} int operator() (int a) const { return a + x; } }; int main() { int x = 10; Lambda add_x(x); fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 return 0; } \u76f8\u5f53\u4e8e\u6211\u4eec\u5199\u7684 lambda \u51fd\u6570\u4f53\uff0c\u5b9e\u9645\u4e0a\u88ab\u7f16\u8bd1\u5668\u79fb\u5230\u4e86 Lambda \u7c7b\u7684 operator() \u6210\u5458\u51fd\u6570\u4f53\u5185\u3002 \u800c\u4e14\u8fd9\u7ed3\u6784\u4f53\u662f\u533f\u540d\u7684\uff0c\u6ca1\u6709\u786e\u5b9a\u7684\u540d\u5b57\uff0c\u6b64\u5904\u7c7b\u540d Lambda \u53ea\u662f\u793a\u610f\uff0c\u56e0\u800c\u5e73\u65f6\u53ea\u80fd\u901a\u8fc7 auto \u4fdd\u5b58\u5373\u65f6\u521b\u5efa\u7684 lambda \u5bf9\u8c61\u3002 \u800c\u6240\u8c13\u7684\u95ed\u5305\u6355\u83b7\u53d8\u91cf\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8fd9\u4e2a\u7ed3\u6784\u4f53\u7684\u6210\u5458\uff01 \u6309\u503c\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u91cc\u62f7\u8d1d\u4e86\u4e00\u4efd\u540c\u540d\u7684\u6210\u5458\uff1b\u5982\u679c\u662f\u5f15\u7528\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u91cc\u7684\u6210\u5458\u662f\u4e2a\u5f15\u7528\u3002 \u53ef\u4ee5\u5728 https://cppinsights.io \u8fd9\u4e2a\u7f51\u7ad9\uff0c\u81ea\u52a8\u62c6\u89e3\u5305\u62ec Lambda \u5728\u5185\u7684\u6240\u6709\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6\u4e3a\u539f\u59cb\u7684\u7ed3\u6784\u4f53\u548c\u51fd\u6570\u3002\u66f4\u591a\u597d\u7528\u7684\u5de5\u5177\u7f51\u7ad9\u53ef\u4ee5\u770b\u6211\u4eec \u5de5\u5177\u548c\u9879\u76ee\u63a8\u8350 \u4e13\u9898\u7ae0\u8282\u3002 \u5bf9\u4e8e\u5f15\u7528\uff0c\u5219\u662f\u7b49\u4ef7\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u4e2d\u542b\u6709\u4e00\u4efd\u5f15\u7528\u4f5c\u4e3a\u6210\u5458\uff1a int x = 10; auto inc_x = [&x](int a) { return x++; }; struct Lambda { int &x; Lambda(int &val) : x(val) {} int operator() () const { return x++; } }; int main() { int x = 10; Lambda inc_x(x); fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 10 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 11 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 12 fmt::println(\"{}\", x); // \u8f93\u51fa 13 return 0; } operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u533f\u540d lambda \u5bf9\u8c61\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u7684\u7c7b\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); \u5f88\u591a\u540c\u5b66\u90fd\u5206\u4e0d\u6e05 operator operator() opeartor()() \uff0c\u8fd9\u4e2a\u62ec\u53f7\u786e\u5b9e\u5f88\u6709\u8ff7\u60d1\u6027\uff0c\u4eca\u5929\u6211\u6765\u89e3\u91ca\u4e00\u4e0b\u3002 \u4f60\u73b0\u5728\uff0c\u628a\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6539\u6210\u8fd9\u6837\uff1a struct Lambda { int call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.call(2); \u662f\u4e0d\u662f\u5f88\u5bb9\u6613\u770b\u61c2\uff1f\u8fd9\u5c31\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6210\u5458\u51fd\u6570 call \uff0c\u7136\u540e\u8c03\u7528\u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u73b0\u5728\uff0c\u8fdb\u4e00\u6b65\u6539\u6210\uff1a struct Lambda { int operator_call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator_call(2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f\u8fd9\u5c31\u662f\u628a\u51fd\u6570\u540d\u6539\u6210\u4e86 operator_call \uff0c\u4f9d\u7136\u662f\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u91cd\u70b9\u6765\u4e86\uff0c\u6211\u4eec\u628a\u51fd\u6570\u540d\uff0c\u6ce8\u610f\u662f\u51fd\u6570\u540d\u53eb operator() \uff0c\u8fd9\u4e2a\u7a7a\u7684\u5706\u62ec\u53f7\u662f\u51fd\u6570\u540d\u7684\u4e00\u90e8\u5206\uff01 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f operator \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u5173\u952e\u5b57\uff0c\u6548\u679c\u662f\u548c\u540e\u9762\u7684\u4e00\u4e2a\u8fd0\u7b97\u7b26\u7ed3\u5408\uff0c\u5f62\u6210\u4e00\u4e2a\u7279\u6b8a\u7684\u201c\u6807\u8bc6\u7b26\u201d\uff0c\u8fd9\u4e2a\u201c\u6807\u8bc6\u7b26\u201d\u548c\u666e\u901a\u51fd\u6570\u540d\u4e00\u6837\uff0c\u90fd\u662f\u201c\u5355\u4e2a\u5355\u8bcd\u201d\uff0c\u4e0d\u53ef\u5206\u5272\u3002 \u4f8b\u5982 operator+ \u5c31\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c operator[] \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6211\u4eec\u8fd9\u91cc\u7684 operator() \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6ca1\u6709\u4ec0\u4e48\u7a00\u5947\u7684\uff0c\u53ea\u4e0d\u8fc7\u540e\u9762\u8fde\u7684\u8fd0\u7b97\u7b26\u521a\u597d\u662f\u62ec\u53f7\u800c\u5df2\u3002 \u8fd9\u91cc\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 lambda . operator() \u6765\u8bbf\u95ee\u8fd9\u4e2a\u6210\u5458\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\uff0c operator() \u5c31\u548c\u4e00\u4e2a\u666e\u901a\u6210\u5458\u540d\u5b57\u4e00\u6837\uff0c\u6ca1\u6709\u533a\u522b\uff0c\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7 . \u8bbf\u95ee\u3002 \u4f8b\u5982\uff0c\u5bf9\u4e8e\u8fd0\u7b97\u7b26 + \u6765\u8bf4\uff0c\u5f53\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230 lambda + 2 \u8fd9\u6837\u7684\u8868\u8fbe\u5f0f\u65f6\uff0c\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u6210 lambda.operator+ (2) \uff0c\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 struct Lambda { int operator+ (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda + 2; // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator+ (2); \u540c\u6837\u7684\uff0c\u5bf9\u4e8e () \u8fd0\u7b97\u7b26\uff0c\u4e5f\u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210 operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\uff0c\u7531\u4e8e\u5bf9 operator() \u51fd\u6570\u672c\u8eab\u7684\u8c03\u7528\u4e5f\u9700\u8981\u4e00\u4e2a\u62ec\u53f7\uff08\u53c2\u6570\u5217\u8868\uff09\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u5c31\u6709\u4e24\u4e2a\u62ec\u53f7\u4e86\u3002\u5b9e\u9645\u4e0a\u6839\u672c\u4e0d\u642d\u754c\uff0c\u4e00\u4e2a\u662f\u51fd\u6570\u540d\u6807\u8bc6\u7b26\u7684\u4e00\u90e8\u5206\uff0c\u4e00\u4e2a\u662f\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u3002 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (2); \u8fd9\u65f6\u5019\uff0c\u53bb\u6389 (2) \u91cc\u7684\u53c2\u6570 2 \uff0c\u5c31\u53d8\u6210\u4e86\u8ba9\u4f60\u5f88\u56f0\u60d1\u7684\u53cc\u62ec\u53f7\u3002\u800c\u5f88\u591a\u4eba\u559c\u6b22\u7d27\u6328\u8005\u8fde\u5199\uff0c\u770b\u8d77\u6765\u5c31\u5f88\u8ff7\u60d1\u3002 \u5b9e\u9645\u4e0a\uff0c\u7b2c\u4e00\u4e2a () \u662f\u51fd\u6570\u540d\u5b57\u7684\u4e00\u90e8\u5206\uff0c\u548c operator \u662f\u8fde\u5728\u4e00\u8d77\u7684\uff0c\u4e0d\u53ef\u5206\u5272\uff0c\u4e2d\u95f4\u4e5f\u4e0d\u80fd\u6709\u5176\u4ed6\u53c2\u6570\u3002\u7b2c\u4e8c\u4e2a () \u662f\u51fd\u6570\u53c2\u6570\u5217\u8868\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u521a\u597d\u662f\u6ca1\u6709\u53c2\u6570\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u4e5f\u662f\u4e2a\u7a7a\u62ec\u53f7\uff0c\u5f88\u591a\u521d\u5b66\u8005\u770b\u5230\u5c31\u8ff7\u7cca\u4e86\uff0c\u8fd8\u770b\u4e0d\u61c2\u5efa\u8bae\u4ece\u4e0a\u9762\u6709\u4e00\u4e2a\u53c2\u6570\u7684 operator() (int a) \u770b\u3002 struct Lambda { int operator() () const { return 1; } }; Lambda lambda; int ret = lambda(); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (); \u6240\u4ee5\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u8bf4\u5b9a\u4e49\u4e86 operator() \u6210\u5458\u51fd\u6570\u7684\u7c7b\uff0c\u662f\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u6216\u8005\u8bf4\u201c\u4eff\u51fd\u6570\u201d\uff0c\u56e0\u4e3a\u5f53\u4f60\u4f7f\u7528\u51fd\u6570\u7684\u8bed\u6cd5 lambda(2) \u8c03\u7528\u4ed6\u4eec\u65f6\uff0c\u4f1a\u89e6\u53d1\u4ed6\u4eec\u7684\u6210\u5458\u51fd\u6570 operator()(2) \u4ece\u800c\u7528\u6cd5\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u5176\u5b9e\u9645\u53c8\u662f\u5bf9\u8c61\uff0c\u4e5f\u5c31\u5f97\u540d\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u548c\u201c\u4eff\u51fd\u6570\u201d\u4e86\u3002 \u6211\u5efa\u8bae\u4f60\u81ea\u5df1\u53bb https://cppinsights.io \u8fd9\u4e2a\u89e3\u6784\u8bed\u6cd5\u7cd6\u7684\u5de5\u5177\u7f51\u7ad9\u52a8\u52a8\u624b\u8bd5\u8bd5\u770b\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u800c\u6355\u83b7\u4e86\u53d8\u91cf\u7684\uff1a int x = 4; auto lambda = [&x] (int a) { return a + x; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int &x; Lambda(int &x_) : x(x_) {} int operator() (int a) const { return a + x; } }; int x = 4; Lambda lambda(x); int ret = lambda.operator() (2); \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 \u6b63\u56e0\u5982\u6b64\uff0c\u95ed\u5305\u6309\u503c\u6355\u83b7\uff08 [=] \uff09\u7684\u53d8\u91cf\uff0c\u5176\u751f\u547d\u5468\u671f\u548c Lambda \u5bf9\u8c61\u76f8\u540c\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u62f7\u8d1d\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u88ab\u91cd\u65b0\u62f7\u8d1d\u4e00\u4efd\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u79fb\u52a8\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u968f\u4e4b\u4e00\u8d77\u79fb\u52a8\u3002 struct C { C() { fmt::println(\"C \u9ed8\u8ba4\u6784\u9020\"); } C(C const &) { fmt::println(\"C \u62f7\u8d1d\u6784\u9020\"); } C(C &&) { fmt::println(\"C \u79fb\u52a8\u6784\u9020\"); } C &operator=(C const &) { fmt::println(\"C \u62f7\u8d1d\u8d4b\u503c\"); } C &operator=(C &&) { fmt::println(\"C \u79fb\u52a8\u8d4b\u503c\"); } ~C() { fmt::println(\"C \u6790\u6784\"); } }; C c; fmt::println(\"\u6784\u9020 lambda\"); auto lambda = [c] {}; fmt::println(\"\u62f7\u8d1d lambda \u5230 lambda2\"); auto lambda2 = lambda; fmt::println(\"\u79fb\u52a8 lambda \u5230 lambda3\"); auto lambda3 = lambda; \u8f93\u51fa\uff1a C \u9ed8\u8ba4\u6784\u9020 \u6784\u9020 lambda C \u62f7\u8d1d\u6784\u9020 \u62f7\u8d1d lambda \u5230 lambda2 C \u62f7\u8d1d\u6784\u9020 \u79fb\u52a8 lambda \u5230 lambda3 C \u79fb\u52a8\u6784\u9020 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 \u5982\u679c\u6309\u503c\u6355\u83b7\u4e86\u4e0d\u80fd\u62f7\u8d1d\u7684\u5bf9\u8c61\uff08\u6bd4\u5982 std::unique_ptr \uff09\uff0c\u90a3\u4e48 Lambda \u5bf9\u8c61\u4e5f\u4f1a\u65e0\u6cd5\u62f7\u8d1d\uff0c\u53ea\u80fd\u79fb\u52a8\u3002 std::unique_ptr p = std::make_unique(10); auto lambda = [p] {}; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u56e0\u4e3a\u8fd9\u91cc\u7b49\u4ef7\u4e8e [p' = p]\uff0c\u662f\u5bf9 p' \u7684\u62f7\u8d1d\u6784\u9020 auto lambda = [p = std::move(p)] {}; // \u7f16\u8bd1\u901a\u8fc7\u2705unique_ptr \u652f\u6301\u79fb\u52a8\u6784\u9020 auto lambda2 = lambda; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3std::unique_ptr \u53ea\u652f\u6301\u79fb\u52a8\uff0c\u4e0d\u652f\u6301\u62f7\u8d1d auto lambda2 = std::move(lambda); // \u7f16\u8bd1\u901a\u8fc7\u2705 \u7528\u6211\u4eec\u4e4b\u524d\u7684\u65b9\u6cd5\u89e3\u6784\u8bed\u6cd5\u7cd6\u540e\uff1a struct Lambda { std::unique_ptr p; Lambda(std::unique_ptr ptr) : p(std::move(ptr)) {} // Lambda(Lambda const &) = delete; // \u56e0\u4e3a\u6709 unique_ptr \u6210\u5458\uff0c\u5bfc\u81f4 Lambda \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u88ab\u9690\u5f0f\u5220\u9664 void operator()() const { } }; int main() { std::unique_ptr p = std::make_unique(10); Lambda lambda(p); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3 Lambda lambda(std::move(p)); // \u7f16\u8bd1\u901a\u8fc7\u2705 return 0; } mutable \u7684\u51fd\u6570\u5bf9\u8c61 int x = 10; auto lambda = [x] () { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3lambda \u6355\u83b7\u7684 x \u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684 }; int ret = lambda(); \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int x; int operator() () const { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3const \u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u6210\u5458\u53d8\u91cf } }; int x = 10; Lambda lambda{x}; int ret = lambda.operator() (); \u6ce8\u610f\u5230\uff0c\u8fd9\u91cc\u7684 operator() \u6210\u5458\u51fd\u6570\u6709\u4e00\u4e2a const \u4fee\u9970\uff0c\u610f\u5473\u7740\u8be5\u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5176\u4f53\u5185\u7684\u53d8\u91cf\u3002 \u6240\u6709 lambda \u51fd\u6570\u5bf9\u8c61\u751f\u6210\u65f6\u9ed8\u8ba4\uff0c\u5c31\u4f1a\u7ed9\u4ed6\u7684 operator() \u6210\u5458\u51fd\u6570\u52a0\u4e0a const \u4fee\u9970\u3002 \u4e5f\u5c31\u662f\u8bf4\u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u7ed9 lambda \u52a0\u4e0a mutable \u4fee\u9970\uff0c\u5c31\u52a0\u5728 () \u540e\u9762\u3002 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"lambda() = {}\", lambda()); // 10 fmt::println(\"lambda() = {}\", lambda()); // 11 fmt::println(\"lambda() = {}\", lambda()); // 12 \u7f16\u8bd1\u5668\u7ffb\u8bd1\u4ea7\u751f\u7684 Lambda \u7c7b\u7684\u6210\u5458\u51fd\u6570\uff0c\u5c31\u4e0d\u4f1a\u5e26 const \u4fee\u9970\u4e86\uff0c\u4ece\u800c\u5141\u8bb8\u6211\u4eec\u7684\u51fd\u6570\u4f53\u4fee\u6539\u6355\u83b7\u7684\u975e\u5f15\u7528\u53d8\u91cf\u3002 struct Lambda { int x; int operator() () { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 } }; int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 \u6ce8\u610f\uff1a\u7531\u4e8e\u4f7f\u7528\u4e86\u503c\u6355\u83b7\uff0clambda \u4fee\u6539\u7684\u662f\u5728\u4ed6\u521b\u5efa\u65f6\u5bf9 x \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u5916\u9762\u7684 x \u4e0d\u4f1a\u6539\u53d8\uff01 int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // 13 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"ret = {}\", lambda()); // 10 fmt::println(\"ret = {}\", lambda()); // 11 fmt::println(\"ret = {}\", lambda()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u7f16\u8bd1\u5668\u4ea7\u751f\u7684\u533f\u540d lambda \u5bf9\u8c61\u4e2d\u6355\u83b7\u4ea7\u751f\u7684 x \u6210\u5458\u53d8\u91cf\u662f\u533f\u540d\u7684\uff0c\u65e0\u6cd5\u8bbf\u95ee \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u4e00\u4e2a\u53d8\u91cf\u7684\u4e09\u79cd\u6355\u83b7\u65b9\u5f0f\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7 [x] \u6309\u5f15\u7528\u6355\u83b7 [&x] \u6309\u503c\u79fb\u52a8\u6355\u83b7 [x = std::move(x)] \u6309\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 [x = ...] \u6279\u91cf\u6355\u83b7\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [=] \u6309\u5f15\u7528\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [&] \u591a\u4e2a\u6355\u83b7 + \u9ed8\u8ba4\u6355\u83b7\u65b9\u5f0f [x, y, &] \u6216 [&x, &y, =] \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u8bed\u6cd5\uff1a [\u53d8\u91cf\u540d] \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u62f7\u8d1d\u4e00\u4efd\u6355\u83b7\u7684\u53d8\u91cf\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u5df2\u7ecf\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4e0d\u4f1a\u5f71\u54cd lambda \u6355\u83b7 x \u7684\u503c\u3002 main \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 985 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) mutable { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u7531\u4e8e lambda \u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u9ed8\u8ba4\u90fd\u662f\u4e0d\u53ef\u4fee\u6539\uff08 const \uff09\uff0c\u9700\u8981 mutable \u624d\u80fd\u4fee\u6539\u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u3002\u800c\u6309\u5f15\u7528\u6355\u83b7\u5c31\u4e0d\u9700\u8981 mutable \uff0c\u56e0\u4e3a\u867d\u7136 lambda \u672c\u8eab\u4e0d\u53ef\u4fee\u6539\uff0c\u4f46\u4ed6\u6307\u5411\u7684\u4e1c\u897f\u53ef\u4ee5\u4fee\u6539\u5440\uff01 \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 985 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u4f9d\u7136\u6709\u6548\u3002 int main() { std::function lambda; { int x = 985; lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = 985 \u6309\u5f15\u7528\u6355\u83b7 \u8bed\u6cd5\uff1a [&\u53d8\u91cf\u540d] \u6309\u5f15\u7528\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u521b\u5efa\u4e00\u4efd\u6307\u5411\u53d8\u91cf\u7684\u5f15\u7528\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf\u5f15\u7528 &x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u662f\u540c\u4e00\u4e2a\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4f1a\u76f4\u63a5\u5f71\u54cd lambda \u6355\u83b7\u4e2d x \u7684\u503c\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 \u6f14\u793a\uff1amain \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e5f\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u5c06\u6210\u4e3a\u5371\u9669\u7684\u201c\u7a7a\u60ac\u5f15\u7528\uff08dangling-reference\uff09\u201d\uff01\u6b64\u65f6\u518d\u5c1d\u8bd5\u8bbf\u95ee x\uff0c\u5c06\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int main() { std::function lambda; { int x = 985; lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = -858993460 -858993460 \u4e3a\u5185\u5b58\u4e2d\u7684\u5783\u573e\u503c\uff0c\u4f60\u8bfb\u5230\u7684\u7ed3\u679c\u53ef\u80fd\u968f\u5e73\u53f0\uff0c\u7f16\u8bd1\u5668\u7248\u672c\uff0c\u4f18\u5316\u9009\u9879\u7684\u4e0d\u540c\u800c\u4e0d\u540c\uff0c\u6b63\u5e38\u8bfb\u5230 985 \u4e5f\u662f\u6709\u53ef\u80fd\u7684\uff0c\u5f00\u53d1\u8005\u4e0d\u80fd\u4f9d\u8d56\u6b64\u7c7b\u968f\u673a\u6027\u7684\u7ed3\u679c\u3002 \u6b63\u5e38\u8bfb\u5230 985\uff08\u5927\u5b66\uff09\u4e5f\u662f\u6709\u53ef\u80fd\u7684\u3002 -858993460 \u662f\u5728 Windows \u5e73\u53f0\u7684\u8c03\u8bd5\u6a21\u5f0f\u4e0b\u53ef\u80fd\u7684\u8f93\u51fa\uff0c\u56e0\u4e3a Windows \u503e\u5411\u4e8e\u628a\u6808\u5185\u5b58\u586b\u6ee1 0xcccccccc \u4ee5\u65b9\u4fbf\u8c03\u8bd5\uff0c\u5176\u4e2d 0xcc \u521a\u597d\u4e5f\u662f int3 \u8fd9\u6761 x86 \u8c03\u8bd5\u6307\u4ee4\u7684\u4e8c\u8fdb\u5236\u7801\uff0c\u53ef\u80fd\u662f\u4e3a\u4e86\u907f\u514d\u6307\u4ee4\u6307\u9488\u6267\u884c\u5230\u5806\u6808\u91cc\u53bb\u3002 \u6309\u503c\u79fb\u52a8\u6355\u83b7 TODO \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 TODO lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b lambda \u51fd\u6570\u53ef\u4ee5\u901a\u8fc7\u5728\u53c2\u6570\u5217\u8868\u540e\u4f7f\u7528 -> \u6307\u5b9a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) -> int { return a; }; int i = lambda(); \u5982\u679c\u8fd4\u56de\u7c7b\u578b\u7701\u7565\u4e0d\u5199\uff0c\u9ed8\u8ba4\u662f -> auto \uff0c\u4e5f\u5c31\u662f\u6839\u636e\u4f60\u7684 return \u8bed\u53e5\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 auto lambda = [] (int a) { return a; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> auto { return a; }; \u548c\u666e\u901a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a auto \u4e00\u6837\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u8868\u8fbe\u5f0f\u4e3a\u4f60\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) { return a; // \u6b64\u8868\u8fbe\u5f0f\u7c7b\u578b\u4e3a int }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> int { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f int return a; }; auto lambda2 = [] (int a) { return a * 2.0; // \u6b64\u8fd4\u56de\u8868\u8fbe\u5f0f\u7684\u7c7b\u578b\u4e3a double }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda2 = [] (int a) -> double { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f double return a * 2.0; }; \u5982\u679c\u6ca1\u6709\u8fd4\u56de\u8bed\u53e5\uff0c\u90a3\u4e48\u4f1a\u63a8\u5bfc\u4e3a\u8fd4\u56de void \u7c7b\u578b\u7684 lambda\u3002 auto lambda = [] (int a) { fmt::println(\"a = {}\", a); }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { fmt::println(\"a = {}\", a); }; auto lambda = [] (int a) { return; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { return; }; \u548c\u51fd\u6570\u7684 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u4e00\u6837\uff0c\u5f53\u8fd4\u56de\u7c7b\u578b\u4e3a auto \u7684 lambda \u5177\u6709\u591a\u4e2a\u8fd4\u56de\u8bed\u53e5\u65f6\uff0c\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709\u5206\u652f\u4e0a\u7684\u8fd4\u56de\u503c\u5177\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u62a5\u9519\uff0c\u9700\u8981\u624b\u52a8\u5199\u51fa\u8fd4\u56de\u7c7b\u578b\uff0c\u6216\u8005\u628a\u6240\u6709\u5206\u652f\u7684\u8fd4\u56de\u503c\u6539\u6210\u76f8\u540c\u7684\u3002 auto lambda_error = [] (double x) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u4e24\u4e2a\u5206\u652f\u7684\u8fd4\u56de\u7c7b\u578b\u4e0d\u540c\uff0c\u65e0\u6cd5\u81ea\u52a8\u63a8\u5bfc if (x > 0) { return x; // double } else { return 0; // int } }; auto lambda_ok = [] (double x) { // \u7f16\u8bd1\u901a\u8fc7 if (x > 0) { return x; // double } else { return (double)0; // double } }; auto lambda_also_ok = [] (double x) -> double { // \u624b\u52a8\u660e\u786e\u8fd4\u56de\u7c7b\u578b\uff0c\u7f16\u8bd1\u4e5f\u80fd\u901a\u8fc7 if (x > 0) { return x; // double } else { return 0; // int\uff0c\u4f46\u4f1a\u9690\u5f0f\u8f6c\u6362\u4e3a double } }; auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b TODO auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u6211\u4eec\u603b\u662f\u7528 auto \u6765\u4fdd\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u4f5c\u4e3a\u5c40\u90e8\u53d8\u91cf\uff0c\u8fd9\u4f1a\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\u3002 \u4e3a\u4ec0\u4e48\u4e0d\u80fd\u663e\u5f0f\u5199\u51fa\u7c7b\u578b\u540d\u5b57\uff1f\u56e0\u4e3a lambda \u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f60\u65e0\u6cd5\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u53ea\u80fd\u901a\u8fc7 auto \u63a8\u5bfc\u3002 int b = 2; auto lambda = [b] (int a) { return a + b; }; \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 C++11 \u540c\u65f6\u5f15\u5165 auto \u548c lambda \u8bed\u6cd5\u7684\u539f\u56e0\u3002 \u5982\u679c\u4f60\u5b9e\u5728\u9700\u8981\u663e\u5f0f\u7684\u7c7b\u540d\uff0c\u90a3\u5c31\u9700\u8981\u4f7f\u7528 std::function \u5bb9\u5668\u3002\u867d\u7136 lambda \u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f46\u662f\u8be5\u7c7b\u578b\u7b26\u5408\u201c\u53ef\u8c03\u7528\u201d\u7684\u7ea6\u675f\uff0c\u53ef\u4ee5\u88ab std::function \u5bb9\u5668\u63a5\u7eb3\u3002 \u5373 lambda \u7c7b\u578b\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u76f8\u5e94\u53c2\u6570\u5217\u8868\u7684 std::function \u5bb9\u5668\u3002\u56e0\u4e3a std::function \u5bb9\u5668\u53ef\u4ee5\u63a5\u7eb3\u4efb\u4f55\u201c\u53ef\u63a5\u53d7 (Args...) \u53c2\u6570\u8c03\u7528\u5e76\u8fd4\u56de Ret \u7c7b\u578b\u201d\u7684\u4efb\u610f\u51fd\u6570\u5bf9\u8c61\u3002 int b = 2; std::function lambda = [b] (int a) { return a + b; }; \u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u628a lambda \u5bf9\u8c61\u63a8\u5165 vector \u7b49\u5bb9\u5668\u4e2d\u65f6\uff0c\u5c31\u9700\u8981\u663e\u5f0f\u5199\u51fa\u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\uff0c\u6b64\u65f6\u4e07\u80fd\u51fd\u6570\u5bf9\u8c61\u5bb9\u5668 std::function \u5c31\u80fd\u6d3e\u4e0a\u7528\u573a\u4e86\uff1a // vector lambda_list; // \u9519\u8bef\uff1a\u4e0d\u652f\u6301\u7684\u8bed\u6cd5 vector> lambda_list; // OK int b = 2; lambda_list.push_back([b] (int a) { return a + b; }; lambda_list.push_back([b] (int a) { return a * b; }; for (auto lambda: lambda_list) { int ret = lambda(2); fmt::println(\"{}\", ret); } \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 TODO \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom TODO \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u65b0\u624b\u7528 lambda \u5e38\u89c1\u7684\u9519\u8bef\u5c31\u662f\u641e\u4e0d\u6e05\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\uff0c\u603b\u662f\u60f3\u5f53\u7136\u5730\u65e0\u8111\u7528 [&] \uff0c\u975e\u5e38\u5371\u9669\u3002 \u5982\u679c\u4f60\u6709\u201c\u81ea\u77e5\u4e4b\u660e\u201d\uff0c\u81ea\u77e5\u4e0d\u719f\u6089\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u90a3\u5c31\u5168\u90e8 [=] \u3002 \u7b49\u6211\u4eec\u7a0d\u540e\u7684 \u751f\u547d\u5468\u671f\u4e13\u9898\u8bfe\u7a0b \u4e2d\u4ecb\u7ecd\u3002 \u5b9e\u9645\u4e0a\uff0c [=] \u5e94\u8be5\u662f\u4f60\u9ed8\u8ba4\u7684\u6355\u83b7\u65b9\u5f0f\u3002 \u53ea\u6709\u5f53\u7c7b\u578b\u65e0\u6cd5\u62f7\u8d1d\u4f1a\u6df1\u62f7\u8d1d\u6210\u672c\u8fc7\u9ad8\u65f6\uff0c\u624d\u4f1a\u9009\u62e9\u6027\u5730\u628a\u4e00\u4e9b\u53ef\u4ee5\u6539\u6210\u5f15\u7528\u6355\u83b7\u7684\u90e8\u5206 lambda\uff0c\u4f7f\u7528 [&] \u6765\u6355\u83b7\u90e8\u5206\u9700\u8981\u907f\u514d\u62f7\u8d1d\u7684\u53d8\u91cf\uff0c\u6216\u8005\u4f7f\u7528 shared_ptr \u914d\u5408 [=] \u5c06\u6df1\u62f7\u8d1d\u5316\u4e3a\u6d45\u62f7\u8d1d\u3002 \u4e00\u4e9b\u4e60\u60ef\u4e86 Python\u3001JS \u7b49\u5168\u5458 shared_ptr \u7684\u5783\u573e\u56de\u6536\u8bed\u8a00\u5de8\u5a74\uff0c\u4e00\u4e0a\u6765\u5c31\u5168\u90e8\u65e0\u8111 [&] \uff0c\u7528\u5b9e\u9645\u884c\u52a8\u8bc1\u660e\u4e86\u667a\u5546\u548c\u52c7\u6c14\u6210\u53cd\u6bd4\u5b9a\u5f8b\u3002 \u597d\u6d88\u606f\u662f\uff0c\u5bf9\u4e8e\u4ee3\u7801\u590d\u7528\u548c\u5c31\u5730\u8c03\u7528\u7684\u60c5\u51b5\uff0clambda \u5bf9\u8c61\u7684\u751f\u547d\u90fd\u4e0d\u4f1a\u51fa\u51fd\u6570\u4f53\uff0c\u53ef\u4ee5\u5b89\u5168\u5730\u6539\u6210\u6309\u5f15\u7528\u6355\u83b7 [&] \u3002 \u4f46\u662f\u5bf9\u4e8e\u4e0b\u9762\u4e24\u79cd\u60c5\u51b5\uff08\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u548c\u4f5c\u4e3a\u8fd4\u56de\u503c\uff09\uff0c\u5c31\u4e0d\u4e00\u5b9a\u6709\u8fd9\u4e48\u5e78\u8fd0\u4e86\u3002 \u603b\u4e4b\uff0c\u65e0\u8bba\u5982\u4f55\u8981\u4fdd\u8bc1 lambda \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5c0f\u4e8e\u7b49\u4e8e \u6309\u5f15\u7528\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u3002\u5982\u679c\u505a\u4e0d\u5230\uff0c\u90a3\u5c31\u5f97\u628a\u8fd9\u4e9b\u53ef\u80fd\u8d85\u51fa\u7684\u53d8\u91cf\u6539\u6210\u6309\u503c\u6355\u83b7 [=] \u3002 \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5982\u679c\u4f60\u60f3\u8ba9\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5c31\u5730\u5b9a\u4e49\uff08\u58f0\u660e\u4e0e\u5b9a\u4e49\u5408\u4f53\uff09\u7684\u51fd\u6570\uff0c\u5efa\u8bae\u586b\u5199 auto \u4e3a\u8fd4\u56de\u503c\u7c7b\u578b\uff0c\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\uff08\u56e0\u4e3a\u4f60\u65e0\u6cd5\u5199\u51fa\u5177\u4f53\u7c7b\u578b\u540d\uff09\u3002 \u7136\u540e\uff0c\u5728 return \u8bed\u53e5\u4e2d\u5c31\u5730\u5199\u51fa lambda \u8868\u8fbe\u5f0f\u5373\u53ef\uff1a auto make_adder(int x) { return [x] (int y) { return x + y; }; } \u5206\u79bb\u58f0\u660e\u4e0e\u5b9a\u4e49\u7684\u51fd\u6570\uff0c\u65e0\u6cd5\u4f7f\u7528 auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff0c\u4e0d\u5f97\u4e0d\u4f7f\u7528\u4e07\u80fd\u7684\u51fd\u6570\u5bb9\u5668 std::function \u6765\u64e6\u5c41\u80a1\uff1a // adder.h std::function make_adder(int x); // adder.cpp std::function make_adder(int x) { return [x] (int y) { return x + y; }; } \u201c\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\uff0c\u8fd9\u79cd\u7528\u6cd5\u5728\u51fd\u6570\u5f0f\u7f16\u7a0b\u975e\u5e38\u5e38\u89c1\u3002 \u5e94\u7528\u6848\u4f8b \u4f8b\u5982\u4e0a\u8ff0\u7684 make_adder \u7b49\u4e8e\u7ed1\u5b9a\u4e86\u4e00\u4e2a\u56fa\u5b9a\u53c2\u6570 x \u7684\u52a0\u6cd5\u51fd\u6570\uff0c\u4e4b\u540e\u6bcf\u6b21\u8c03\u7528\u8fd9\u4e2a\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5c31\u56fa\u5b9a\u589e\u52a0\u4e4b\u524d\u5728 make_adder \u53c2\u6570\u4e2d x \u7684\u589e\u91cf\u4e86\u3002 TODO \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u6b64\u7c7b\u201c\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u5199\u6cd5\uff0c\u5176 lambda \u6355\u83b7\u5fc5\u987b\u662f\u6309\u503c\u6355\u83b7\u7684\uff01 \u5426\u5219\uff0c\u56e0\u4e3a\u8c03\u7528\u8005\u8c03\u7528\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\u65f6\uff0c\u5c40\u90e8\u53d8\u91cf\u548c\u5b9e\u53c2\u6240\u5bf9\u5e94\u7684\u51fd\u6570\u5c40\u90e8\u6808\u7a7a\u95f4\u5df2\u7ecf\u91ca\u653e\uff0c\u76f8\u5f53\u4e8e\u5728 lambda \u4f53\u5185\u5b58\u6709\u7a7a\u60ac\u5f15\u7528\uff0c\u5bfc\u81f4\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u8981\u4e48\u76f4\u63a5\u5d29\u6e83\uff0c\u8981\u4e48\u975e\u5e38\u9690\u853d\u5730\u7559\u4e0b\u5185\u5b58\u975e\u6cd5\u8bbf\u95ee\u7684\u9690\u60a3\uff09\u3002 auto make_adder(int x) { return [x] (int y) { return x + y; }; } int main() { // \u6211\u662f\u8c03\u7528\u8005 auto adder = make_adder(2); adder(3); // 2 + 3 = 5 } \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 TODO\uff1a\u4ee3\u7801 \u5e94\u7528\u6848\u4f8b TODO\uff1a\u7b56\u7565\u6a21\u5f0f TODO\uff1a\u5ef6\u8fdf\u56de\u8c03 \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570\u7684\u751f\u547d\u5468\u671f\u95ee\u9898\uff0c\u9700\u8981\u5206\u5c31\u5730\u8c03\u7528\u548c\u5ef6\u8fdf\u8c03\u7528\u4e24\u79cd\u60c5\u51b5\u8ba8\u8bba\u3002 \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] \u5982\u679c\u4f60\u7684\u667a\u529b\u6682\u4e0d\u8db3\u4ee5\u641e\u61c2\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u6ca1\u5173\u7cfb\uff0c\u59cb\u7ec8\u4f7f\u7528 [=] \u80af\u5b9a\u6ca1\u9519\u3002 \u4e00\u4e2a\u540c\u5b66\u8be2\u95ee\uff1a\u6211\u53e3\u6e34\uff01\u5728\u4e0d\u77e5\u9053\u4ed6\u7684\u8010\u53d7\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u80af\u5b9a\u662f\u76f4\u63a5\u7ed9\u4ed6\u5403\u6c34\uff0c\u800c\u4e0d\u662f\u7ed9\u4ed6\u5403\u9152\u7cbe\u3002\u867d\u7136\u4e00\u4e9b\u5b5d\u5b50\u66f0\u201c\u9002\u91cf\u201d\u201c\u9002\u5ea6\u201d\u201c\u8ba1\u91cf\u201d\u5404\u79cd\u4e00\u8fde\u4e32\u9644\u52a0\u6761\u4ef6\u4e0b\uff0c\u5ba3\u79f0\u201c\u9152\u7cbe\u4e5f\u662f\u5b89\u5168\u7684\u201d\u3002\u4f46\u662f\u201c\u6c34\u6c38\u8fdc\u662f\u5b89\u5168\u7684\u201d\uff0c\u201c\u6c38\u8fdc\u201d\uff0c\u90a3\u6211\u76f4\u63a5\u7ed9\u4ed6\u559d\u6c34\uff0c\u662f\u80af\u5b9a\u4e0d\u4f1a\u9519\u7684\u3002\u7b49\u4f60\u957f\u5927\u6210\u5e74\u4e86\uff0c\u6709\u8fa8\u522b\u80fd\u529b\u4e86\uff0c\u518d\u53bb\u6839\u636e\u81ea\u5df1\u7684\u5c0f\u8ba1\u673a\u7619\u75d2\u7a0b\u5ea6\uff0c\u9009\u62e9\u6027\u5730\u559d\u6709\u673a\u6eb6\u5242\u3002\u6b64\u5904 [=] \u5c31\u662f\u8fd9\u4e2a\u4e07\u80fd\u7684\u6c34\uff0c\u867d\u7136\u4e0d\u4e00\u5b9a\u9ad8\u6548\uff0c\u4f46\u662f\u80af\u5b9a\u6ca1\u9519\u3002\u521d\u5b66\u8005\u603b\u662f\u4ece [=] \u7528\u8d77\uff0c\u7b49\u5b66\u660e\u767d\u4e86\uff0c\u518d\u6765\u5c1d\u8bd5\u7a81\u7834\u201c\u5c0f\u8ba1\u673a\u6027\u80fd\u7126\u8651\u4f18\u5316\u201d\u4e5f\u4e0d\u8fdf\u3002 \u5982\u679c\u4f60\u81ea\u8ba4\u4e3a\u80fd\u5206\u5f97\u6e05\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u521b\u5efa\uff0c\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u8fd4\u56de\u4e00\u4e2a lambda\uff0c\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u63a5\u53d7\u4e00\u4e2a lambda \u505a\u53c2\u6570\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u4f5c\u4e3a\u56de\u8c03\u51fd\u6570\uff0c\u5ef6\u8fdf\u8c03\u7528\uff0c\u90a3\u5c31\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u4ee5\u4e0a\u56db\u79cd\u60c5\u51b5\uff0c\u5206\u522b\u4ee3\u7801\u6f14\u793a\uff1a void func() { int i = 1; auto lambda = [&] () { return i; }; lambda(); } int main() { func(); } auto func() { int i = 1; return [=] () { return i; }; } int main() { auto lambda = func(); lambda(); } auto func(auto lambda) { lambda(); } int main() { int i = 1; func([&] () { return i; }); } vector> g_callbacks; auto func(auto lambda) { g_callbacks.push_back(lambda); } void init() { int i = 1; func([=] () { return i; }); } int main() { init(); for (auto cb: g_callbacks) { cb(); } } lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u51fd\u6570\u6bd4\u8f83\u7b80\u5355\uff0c\u76f4\u63a5\u5f80\u51fd\u6570\u53c2\u6570\u4e2d\u4f20\u5165 lambda \u5bf9\u8c61\u5373\u53ef\u3002 sort \uff1a std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::sort(a.begin(), a.end(), comp); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 shared_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::shared_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u7684\u5f15\u7528\u8ba1\u6570\u5f52\u96f6\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002 \u6a21\u677f\u7c7b \u800c\u6a21\u677f\u7c7b\u5219\u9700\u8981\u5148\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u6307\u5b9a\u7c7b\u578b\uff0c\u7136\u540e\u5728\u6784\u9020\u51fd\u6570\u4e2d\u4f20\u5165\u53c2\u6570\u3002 std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::set sorted(comp); sorted.assign(a.begin(), a.end()); a.assign(sorted.begin(), sorted.end()); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5229\u7528 set \u5bb9\u5668\u6709\u5e8f\u7684\u7279\u70b9\uff0c\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 unique_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::unique_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u6790\u6784\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002 lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b TODO: count_if, erase_if, argsort \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 \u4e8c\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b a < b std::less a > b std::greater a <= b std::less_equal a >= b std::greater_equal a == b std::equal_to a != b std::not_equal_to a <=> b std::compare_three_way (C++20) a && b std::logical_and a \\|\\| b std::logical_or a & b std::bit_and a \\| b std::bit_or a ^ b std::bit_xor a + b std::plus a - b std::minus a * b std::multiplies a / b std::divides a % b std::modulus \u4e00\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b !a std::logical_not ~a std::bit_not -a std::negate a std::identity bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 \u539f\u59cb\u51fd\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { hello(2, 3); hello(2, 4); hello(2, 5); return 0; } \u7ed1\u5b9a\u90e8\u5206\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello2 = std::bind(hello, 2, std::placeholders::_1); hello2(3); // hello(2, 3) hello2(4); // hello(2, 4) hello2(5); // hello(2, 5) return 0; } std::placeholders::_1 \u8868\u793a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\u3002 std::placeholders::_1 \u5728 bind \u8868\u8fbe\u5f0f\u4e2d\u4f4d\u4e8e hello \u7684\u7684\u7b2c\u4e8c\u53c2\u6570\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\uff1a\u628a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\uff0c\u4f20\u9012\u5230 hello \u7684\u7b2c\u4e8c\u53c2\u6570\u4e0a\u53bb\u3002 \u7ed1\u5b9a\u5168\u90e8\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello23 = std::bind(hello, 2, 3); hello23(); // hello(2, 3) return 0; } \u7ed1\u5b9a\u5f15\u7528\u53c2\u6570\uff1a int inc(int &x) { x += 1; } int main() { int x = 0; auto incx = std::bind(inc, std::ref(x)); incx(); fmt::println(\"x = {}\", x); // x = 1 incx(); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u5982\u679c\u4e0d\u4f7f\u7528 std::ref \uff0c\u90a3\u4e48 main \u91cc\u7684\u5c40\u90e8\u53d8\u91cf x \u4e0d\u4f1a\u6539\u53d8\uff01\u56e0\u4e3a std::bind \u6709\u4e00\u4e2a\u607c\u4eba\u7684\u8bbe\u8ba1\uff1a\u9ed8\u8ba4\u6309\u62f7\u8d1d\u6355\u83b7\uff0c\u4f1a\u628a\u53c2\u6570\u62f7\u8d1d\u4e00\u4efd\uff0c\u800c\u4e0d\u662f\u4fdd\u7559\u5f15\u7528\u3002 \u6709\u8da3\u7684\u662f\uff0cplaceholder \u6307\u5b9a\u7684\u53c2\u6570\uff0c\u5374\u4e0d\u9700\u8981 std::ref \u624d\u80fd\u4fdd\u6301\u5f15\u7528\uff1a int inc(int &x, int y) { x += y; } int main() { int x = 0; auto inc1 = std::bind(inc, std::placeholders::_1, 1); inc1(x); // \u6b64\u5904 x \u662f\u6309\u5f15\u7528\u4f20\u9012\u7684 fmt::println(\"x = {}\", x); // x = 1 inc1(x); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u90a3\u662f\u56e0\u4e3a\uff0c std::placeholders::_1 \u6307\u5b9a\u7684\u53c2\u6570\u4f1a\u88ab\u76f4\u63a5\u5b8c\u7f8e\u8f6c\u53d1\u7ed9 inc \u91cc\u7684 x \uff0c\u76f8\u5f53\u4e8e inc(x, 2); \u3002\u53ea\u6709\u6355\u83b7\u7684\u53c2\u6570\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e0d\u4f1a\u5b8c\u7f8e\u8f6c\u53d1\u3002 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; }; bind \u7684\u5386\u53f2 \u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002 thread \u819d\u76d6\u4e2d\u7bad \u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42 \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand(); std::bind_front \u548c std::bind_back C++17 \u5f15\u5165\u4e86\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\uff1a std::bind_front \uff1a\u7ed1\u5b9a\u6700\u524d\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u540e\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\uff1b std::bind_back \uff1a\u7ed1\u5b9a\u672b\u5c3e\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u524d\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\u3002 \u548c\u666e\u901a\u7684 std::bind \u76f8\u6bd4\u6709\u4ec0\u4e48\u597d\u5904\u5462\uff1f \u5bf9\u4e8e\u51fd\u6570\u53c2\u6570\u975e\u5e38\u591a\uff0c\u4f46\u5b9e\u9645\u53ea\u9700\u8981\u7ed1\u5b9a\u4e00\u4e24\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\uff0c\u7528 std::bind \u4f1a\u9700\u8981\u6dfb\u52a0\u975e\u5e38\u591a\u7684 placeholder\uff0c\u6570\u91cf\u548c\u51fd\u6570\u7684\u5269\u4f59\u53c2\u6570\u6570\u91cf\u4e00\u6837\u591a\u3002\u800c std::bind_front \u5219\u76f8\u5f53\u4e8e\u4e00\u4e2a\u7b80\u5199\uff0c\u540e\u9762\u7684\u5360\u4f4d\u7b26\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\u4e86\u3002 \u4f8b\u5982\u7ed1\u5b9a x = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, 42, std::placeholders::_1, std::placeholders::_2); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_front(func, 42); \u7ed1\u5b9a z = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, std::placeholders::_1, std::placeholders::_2, 42); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_back(func, 42); \u53ef\u4ee5\u770b\u5230\uff0c\u4f7f\u7528\u8fd9\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\u660e\u663e\u5199\u7684\u4ee3\u7801\u5c11\u4e86\u3002 \u5176\u4e2d\u6700\u5e38\u7528\u7684\u662f std::bind_front \uff0c\u7528\u4e8e\u7ed1\u5b9a\u7c7b\u6210\u5458\u7684 this \u6307\u9488\u3002 \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f \u4f7f\u7528 lambda \u4ee3\u66ff \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408 forward \u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(std::forward(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 TODO\uff1a std::less \u548c std::bind \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u901a\u8fc7\u6309\u503c\u79fb\u52a8\u6355\u83b7 [p = std::move(p)] \uff0clambda \u53ef\u4ee5\u6301\u6709\u4e00\u4e2a unique_ptr \u4f5c\u4e3a\u6355\u83b7\u53d8\u91cf\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u8fd9\u6837\u521b\u5efa\u51fa\u6765\u7684 lambda\uff0c\u5b58\u5165 std::function \u65f6\u4f1a\u62a5\u9519\uff1a TODO: \u4ee3\u7801 \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 TODO: \u4ee3\u7801\u6848\u4f8b \u5728\u4e4b\u540e\u7684 std::variant \u4e13\u9898\u7ae0\u8282 \u4e2d\u4f1a\u8fdb\u4e00\u6b65\u4ecb\u7ecd\u3002 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b"},{"location":"lambda/#_1","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u7528\u51fd\u6570\u5c01\u88c5 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u4e8c\u6b21\u5c01\u88c5 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 mutable \u7684\u51fd\u6570\u5bf9\u8c61 \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u6309\u5f15\u7528\u6355\u83b7 \u6309\u503c\u79fb\u52a8\u6355\u83b7 \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u7c7b lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 std::bind_front \u548c std::bind_back \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4f7f\u7528 lambda \u4ee3\u66ff bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b"},{"location":"lambda/#_2","text":"int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum = {}\", s); return 0; } \u8fd9\u662f\u4e00\u4e2a\u8ba1\u7b97\u6570\u7ec4\u6c42\u548c\u7684\u7b80\u5355\u7a0b\u5e8f\u3002 \u4f46\u662f\uff0c\u4ed6\u53ea\u80fd\u8ba1\u7b97\u6570\u7ec4 a \u7684\u6c42\u548c\uff0c\u65e0\u6cd5\u590d\u7528\u3002 \u5982\u679c\u6211\u4eec\u6709\u53e6\u4e00\u4e2a\u6570\u7ec4 b \u4e5f\u9700\u8981\u6c42\u548c\u7684\u8bdd\uff0c\u5c31\u5f97\u628a\u6574\u4e2a\u6c42\u548c\u7684 for \u5faa\u73af\u91cd\u65b0\u5199\u4e00\u904d\uff1a int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum of a = {}\", s); std::vector b = {5, 6, 7, 8}; s = 0; for (int i = 0; i < a.size(); i++) { s += b[i]; } fmt::println(\"sum of b = {}\", s); return 0; } \u8fd9\u5c31\u51fa\u73b0\u4e86\u7a0b\u5e8f\u8bbe\u8ba1\u7684\u5927\u5fcc\uff1a\u4ee3\u7801\u91cd\u590d\u3002 \u4f8b\u5982\uff0c\u4f60\u6709\u5439\u7a7a\u8c03\u7684\u9700\u6c42\uff0c\u548c\u5145\u624b\u673a\u7684\u9700\u6c42\u3002\u4f60\u4e3a\u4e86\u6ee1\u8db3\u8fd9\u4e24\u4e2a\u9700\u6c42\uff0c\u8d2d\u4e70\u4e86\u4e24\u53f0\u53d1\u7535\u673a\uff0c\u5206\u522b\u4e3a\u7a7a\u8c03\u548c\u624b\u673a\u4f9b\u7535\u3002\u7b2c\u4e8c\u5929\uff0c\u4f60\u53c8\u4ea7\u751f\u4e86\u73a9\u7535\u8111\u9700\u6c42\uff0c\u4e8e\u662f\u4f60\u53c8\u8d2d\u4e70\u4e00\u53f0\u53d1\u7535\u673a\uff0c\u4e13\u4e3a\u7535\u8111\u4f9b\u7535\u2026\u2026\u771f\u662f\u6d6a\u8d39\uff01 \u91cd\u590d\u7684\u4ee3\u7801\u4e0d\u4ec5\u5f71\u54cd\u4ee3\u7801\u7684 \u53ef\u8bfb\u6027 \uff0c\u4e5f\u589e\u52a0\u4e86 \u7ef4\u62a4 \u4ee3\u7801\u7684\u6210\u672c\u3002 \u770b\u8d77\u6765\u4e71\u7cdf\u7cdf\u7684\uff0c\u4fe1\u606f\u5bc6\u5ea6\u4f4e\uff0c\u8ba9\u4eba\u4e00\u773c\u770b\u4e0d\u51fa\u4ee3\u7801\u5728\u5e72\u4ec0\u4e48\u7684\u529f\u80fd \u5f88\u5bb9\u6613\u5199\u9519\uff0c\u770b\u8d70\u773c\uff0c\u96be\u8c03\u8bd5 \u590d\u5236\u7c98\u8d34\u8fc7\u7a0b\u4e2d\uff0c\u5bb9\u6613\u6f0f\u6539\uff0c\u6bd4\u5982\u8fd9\u91cc\u7684 s += b[i] \u53ef\u80fd\u5199\u6210 s += a[i] \u800c\u81ea\u5df1\u4e0d\u53d1\u73b0 \u6539\u8d77\u6765\u4e0d\u65b9\u4fbf\uff0c\u5f53\u6211\u4eec\u7684\u9700\u6c42\u53d8\u66f4\u65f6\uff0c\u9700\u8981\u591a\u5904\u4fee\u6539\uff0c\u6bd4\u5982\u5f53\u6211\u9700\u8981\u6539\u4e3a\u8ba1\u7b97\u4e58\u79ef\u65f6\uff0c\u9700\u8981\u628a\u4e24\u4e2a\u5730\u65b9\u90fd\u6539\u6210 s *= \u6539\u4e86\u4ee5\u540e\u53ef\u80fd\u6f0f\u6539\u4e00\u90e8\u5206\uff0c\u7559\u4e0b Bug \u9690\u60a3 \u654f\u6377\u5f00\u53d1\u9700\u8981\u53cd\u590d\u4fee\u6539\u4ee3\u7801\uff0c\u6bd4\u5982\u4f60\u6b63\u5728\u8c03\u8bd5 += \u548c -= \u7684\u533a\u522b\uff0c\u770b\u7ed3\u679c\u53d8\u5316\uff0c\u5982\u679c\u4e00\u6b21\u5207\u6362\u9700\u8981\u6539\u591a\u5904\uff0c\u5c31\u5f71\u54cd\u4e86\u8c03\u8bd5\u901f\u5ea6","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f"},{"location":"lambda/#_3","text":"\u5982\u679c\u4f60\u8fd8\u662f\u559c\u6b22\u201c\u4e00\u672c\u9053\u201d\u5199\u6cd5\u7684\u8bdd\uff0c\u4e0d\u59a8\u60f3\u60f3\u770b\uff0c\u5b8c\u5168\u4e0d\u7528\u4efb\u4f55\u6807\u51c6\u5e93\u548c\u7b2c\u4e09\u65b9\u5e93\u7684\u51fd\u6570\u548c\u7c7b\uff0c\u628a fmt::println \u548c std::vector \u8fd9\u4e9b\u51fd\u6570\u5168\u90e8\u62c6\u89e3\u6210\u4e00\u4e2a\u4e2a\u7cfb\u7edf\u8c03\u7528\u3002\u90a3\u8fd9\u6574\u4e2a\u7a0b\u5e8f\u4f1a\u6709\u591a\u96be\u5199\uff1f int main() { #ifdef _WIN32 int *a = (int *)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else int *a = (int *)mmap(NULL, 4 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); #endif a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; int s = 0; for (int i = 0; i < 4; i++) { s += a[i]; } char buffer[64]; buffer[0] = 's'; buffer[1] = 'u'; buffer[2] = 'm'; buffer[3] = ' '; buffer[4] = '='; buffer[5] = ' '; // \u4f8b\u5982\uff0c\u5982\u679c\u8981\u4fee\u6539\u6b64\u5904\u7684\u63d0\u793a\u6587\u672c\uff0c\u751a\u81f3\u9700\u8981\u4fee\u6539\u540e\u9762\u7684 len \u53d8\u91cf... int len = 6; int x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif int *b = (int *)a; b[0] = 4; b[1] = 5; b[2] = 6; b[3] = 7; int s = 0; for (int i = 0; i < 4; i++) { s += b[i]; } len = 6; x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif #ifdef _WIN32 VirtualFree(a, 0, MEM_RELEASE); #else munmap(a); #endif return 0; } \u4e0d\u4ec5\u5b8c\u5168\u6ca1\u6709\u53ef\u8bfb\u6027\u3001\u53ef\u7ef4\u62a4\u6027\uff0c\u751a\u81f3\u90fd\u6ca1\u6709\u53ef\u79fb\u690d\u6027\u3002 \u9664\u975e\u4f60\u53ea\u5199\u5e94\u4ed8\u5bfc\u5e08\u7684\u201c\u4e00\u6b21\u6027\u201d\u7a0b\u5e8f\uff0c\u4e00\u65e6\u8981\u5b9e\u73b0\u590d\u6742\u7684\u4e1a\u52a1\u9700\u6c42\uff0c\u4e0d\u53ef\u907f\u514d\u7684\u8981\u81ea\u5df1\u5c01\u88c5\u51fd\u6570\u6216\u7c7b\u3002\u7f51\u4e0a\u6240\u6709\u9f13\u5439\u201c\u4e0d\u5c01\u88c5\u201d\u201c\u8bbe\u8ba1\u6a21\u5f0f\u662f\u9762\u5b50\u5de5\u7a0b\u201d\u7684\u53cd\u667a\u8a00\u8bba\uff0c\u90fd\u662f\u6ca1\u6709\u505a\u8fc7\u5927\u578b\u9879\u76ee\u7684\u3002","title":"\u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f"},{"location":"lambda/#_4","text":"\u5f88\u591a\u8bbe\u8ba1\u6a21\u5f0f\u6559\u6750\u7247\u9762\u5f3a\u8c03 \u53ef\u8bfb\u6027 \uff0c\u4eff\u4f5b\u8bbe\u8ba1\u6a21\u5f0f\u5c31\u662f\u4e3a\u4e86\u201c\u4f18\u96c5\u201d\u201c\u9ad8\u5927\u4e0a\u201d\u201c\u7f8e\u5b66\u201d\uff1f\u4f7f\u5f97\u5f88\u591a\u4eba\u8ba4\u4e3a\uff0c\u201c\u6211\u8fd9\u4e2a\u662f\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u4e0d\u7528\u7f8e\u5316\u7ed9\u9886\u5bfc\u770b\u201d\u800c\u62d2\u7edd\u8bbe\u8ba1\u6a21\u5f0f\u3002\u5b9e\u9645\u4e0a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e \u65b9\u4fbf\u540e\u7eed\u4fee\u6539 \uff01 \u4f8b\u5982 B \u7ad9\u4ee5\u524d\u53ea\u652f\u6301\u4e0a\u4f20\u666e\u901a\u89c6\u9891\uff0c\u73b0\u5728\u53d4\u53d4\u7a81\u7136\u63d0\u51fa\uff1a\u8981\u652f\u6301\u4e92\u52a8\u89c6\u9891\uff0c\u5145\u7535\u89c6\u9891\uff0c\u89c6\u9891\u5408\u96c6\uff0c\u8fd8\u5e9f\u9664\u4e86\u89c6\u9891\u5206 p\uff0c\u8fd8\u8981\u652f\u6301\u4e0a\u4f20\u77ed\u89c6\u9891\uff0c\u7ad6\u5c4f\u5f00\u5173\u7b49\u2026\u2026\u6bcf\u4e00\u4e2a\u53d4\u53d4\u7684\u8981\u6c42\uff0c\u90fd\u9700\u8981\u5927\u91cf\u7a0b\u5e8f\u5458\u4fee\u6539\u4ee3\u7801\uff0c\u65e0\u8bba\u6d89\u53ca\u524d\u7aef\u8fd8\u662f\u540e\u7aef\u3002 \u4e0e\u5efa\u7b51\u3001\u7ed8\u753b\u7b49\u9886\u57df\u4e0d\u540c\uff0c\u4e00\u6b21\u4ea4\u4ed8\u5b8c\u6bd5\u5c31\u53ef\u4ee5\u51e0\u4e4e\u6c38\u4e45\u4f7f\u7528\u3002\u800c\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u66f4\uff0c\u90fd\u5bfc\u81f4\u4ee3\u7801\u9700\u8981\u4fee\u6539\u3002\u5f00\u53d1\u4eba\u5458\u51e0\u4e4e\u9700\u8981\u4e00\u76f4\u56f4\u7ed5\u7740\u8f6f\u4ef6\u4ee3\u7801\uff0c\u4e0d\u65ad\u7684\u4fee\u6539\u3002\u8c03\u67e5\u8868\u660e\uff0c\u7a0b\u5e8f\u5458 90% \u7684\u65f6\u95f4\u82b1\u5728 \u6539\u4ee3\u7801 \u4e0a\uff0c \u5199\u4ee3\u7801 \u53ea\u5360 10%\u3002 \u8f6f\u4ef6\u5c31\u50cf\u751f\u7269\uff0c\u8981\u4e0d\u65ad\u8fdb\u5316\uff0c\u8f6f\u4ef6\u4e0d\u66f4\u65b0\u4e0d\u7ef4\u62a4\u4e86\u7b49\u4e8e\u6b7b\u3002\u5982\u679c\u4e00\u4e2a\u8f6f\u4ef6\u9010\u6e10\u53d8\u5f97\u81c3\u80bf\u96be\u4ee5\u4fee\u6539\uff0c\u65e0\u6cd5\u9002\u5e94\u65b0\u9700\u6c42\uff0c\u90a3\u4ed6\u5c31\u50cf\u5df2\u7ecf\u5931\u53bb\u8fdb\u5316\u80fd\u529b\u7684\u751f\u7269\u79cd\u7fa4\uff0c\u5982\u300a\u4e09\u4f53\u300b\u4e16\u754c\u89c2\u4e2d\u201c\u5b89\u987f\u201d\u5230\u6fb3\u5927\u5229\u4e9a\u4fdd\u7559\u533a\u91cc\u201c\u7edd\u80b2\u201d\u7684\u4eba\u7c7b\uff0c\u88ab\u6dd8\u6c70\u53ea\u662f\u65f6\u95f4\u95ee\u9898\u3002 \u5982\u679c\u6211\u4eec\u80fd\u5728 \u5199\u4ee3\u7801 \u9636\u6bb5\uff0c\u5c31\u628a\u7a0b\u5e8f\u51c6\u5907\u5f97 \u6613\u4e8e\u540e\u7eed\u4fee\u6539 \uff0c\u90a3\u5c31\u53ef\u4ee5\u5728\u540e\u7eed 90% \u7684 \u6539\u4ee3\u7801 \u9636\u6bb5\u7701\u4e0b\u65e0\u6570\u65f6\u95f4\u3002 \u5982\u4f55\u8ba9\u4ee3\u7801\u6613\u4e8e\u4fee\u6539\uff1f\u524d\u4eba\u603b\u7ed3\u51fa\u4e00\u7cfb\u5217\u5e38\u7528\u7684\u5199\u6cd5\uff0c\u8fd9\u7c7b\u5199\u6cd5\u6709\u52a9\u4e8e\u8ba9\u540e\u7eed\u4fee\u6539\u66f4\u5bb9\u6613\uff0c\u5404\u81ea\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u5408\uff0c\u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u3002 \u63d0\u5347\u53ef\u7ef4\u62a4\u6027\u6700\u57fa\u7840\u7684\u4e00\u70b9\uff0c\u5c31\u662f\u907f\u514d\u91cd\u590d\uff01 \u5f53\u4f60\u6709\u5f88\u591a\u5730\u65b9\u51fa\u73b0\u91cd\u590d\u7684\u4ee3\u7801\u65f6\uff0c\u4e00\u65e6\u9700\u8981\u6d89\u53ca\u4fee\u6539\u8fd9\u90e8\u5206\u903b\u8f91\u65f6\uff0c\u5c31\u9700\u8981\u5230\u6bcf\u4e00\u4e2a\u51fa\u73b0\u4e86\u8fd9\u4e2a\u903b\u8f91\u7684\u4ee3\u7801\u4e2d\uff0c\u53bb\u9010\u4e00\u4fee\u6539\u3002 \u4f8b\u5982\u4f60\u7684\u540d\u5b57\uff0c\u5728\u51fa\u751f\u8bc1\uff0c\u8eab\u4efd\u8bc1\uff0c\u5b66\u751f\u8bc1\uff0c\u6bd5\u4e1a\u8bc1\uff0c\u623f\u4ea7\u8bc1\uff0c\u9a7e\u9a76\u8bc1\uff0c\u5404\u79cd\u5730\u65b9\u90fd\u51fa\u73b0\u4e86\u3002\u90a3\u4e48\u4f60\u8981\u6539\u540d\u7684\u8bdd\uff0c\u6240\u6709\u8fd9\u4e9b\u8bc1\u4ef6\u90fd\u9700\u8981\u91cd\u65b0\u5370\u5237\uff01\u5982\u679c\u80fd\u628a\u4ed6\u4eec\u5408\u5e76\u6210\u4e00\u4e2a\u201c\u7edf\u4e00\u8bc1\u201d\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4fee\u6539\u201c\u7edf\u4e00\u8bc1\u201d\u4e0a\u7684\u540d\u5b57\u5c31\u884c\u4e86\u3002 \u4e0d\u8fc7\uff0c\u73b0\u5b9e\u4e2d\u5e76\u6ca1\u6709\u9891\u7e41\u6539\u540d\u5b57\u7684\u9700\u6c42\uff0c\u8fd9\u8bf4\u660e\uff1a \u5bf9\u4e8e\u4e0d\u5e38\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u53ef\u4ee5\u5bb9\u5fcd\u4e00\u5b9a\u7684\u91cd\u590d\u3002 \u8d8a\u662f\u672a\u6765\u6709\u53ef\u80fd\u4fee\u6539\u7684\uff0c\u5c31\u8d8a\u9700\u8981\u8bbe\u8ba1\u6a21\u5f0f\u964d\u91cd\uff01 \u4f8b\u5982\u6570\u5b66\u5e38\u6570 PI = 3.1415926535897\uff0c\u8fd9\u8f88\u5b50\u90fd\u4e0d\u53ef\u80fd\u51fa\u73b0\u4fee\u6539\u7684\u9700\u6c42\uff0c\u90a3\u5199\u6b7b\u4e5f\u6ca1\u5173\u7cfb\u3002\u5982\u679c\u8981\u628a PI \u5b9a\u4e49\u6210\u5b8f\uff0c\u53ea\u662f\u51fa\u4e8e\u201c\u8bb0\u4e0d\u4f4f\u201d\u201c\u5199\u8d77\u6765\u592a\u957f\u4e86\u201d\u201c\u590d\u5236\u7c98\u8d34\u9ebb\u70e6\u201d\u3002\u6240\u4ee5\u5bf9\u4e8e PI \u8fd9\u79cd\u4e0d\u4f1a\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u964d\u91cd\u53ea\u662f\u589e\u52a0 \u53ef\u8bfb\u6027 \uff0c\u800c\u4e0d\u662f \u53ef\u4fee\u6539\u6027 \u3002 \u4f46\u662f\uff0c\u4e0d\u8981\u60f3\u5f53\u7136\uff01\u9700\u6c42\u7684\u5343\u53d8\u4e07\u5316\u603b\u662f\u8d85\u51fa\u4f60\u7684\u60f3\u8c61\u3002 \u4f8b\u5982\u4f60\u505a\u4e86\u4e00\u4e2a\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u6e38\u620f\uff0c\u9700\u8981\u7528\u5230\u91cd\u529b\u52a0\u901f\u5ea6 g = 9.8\uff0c\u4f60\u60f3\u5f53\u7136\u8ba4\u4e3a g \u4ee5\u540e\u4e0d\u53ef\u80fd\u4fee\u6539\u3002\u8001\u677f\u4e5f\u4fe1\u8a93\u65e6\u65e6\u5411\u4f60\u4fdd\u8bc1\uff1a\u201c\u6ca1\u4e8b\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u4e0d\u4f1a\u6539\u53d8\u3002\u201d\u4f60\u5c31\u5199\u6b7b\u5728\u4ee3\u7801\u91cc\u4e86\u3002 \u6ca1\u60f3\u5230\uff0c\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u8001\u677f\u7a81\u7136\u8981\u6c42\u4f60\u52a0\u5165\u201c\u6708\u7403\u7ae0\u201d\u5173\u5361\uff0c\u5728\u8fd9\u4e9b\u5173\u5361\u4e2d\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u662f g = 1.6\u3002 \u5982\u679c\u4f60\u4e00\u5f00\u59cb\u5c31\u5df2\u7ecf\u628a g \u63d0\u53d6\u51fa\u6765\uff0c\u5b9a\u4e49\u4e3a\u5e38\u91cf\uff1a struct Level { const double g = 9.8; void physics_sim() { bird.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f pig.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f } }; \u90a3\u4e48\u8981\u652f\u6301\u6708\u7403\u5173\u5361\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5c31\u53ef\u4ee5\u4e86\u3002 struct Level { double g; Level(Chapter chapter) { if (chapter == ChapterMoon) { g = 1.6; } else { g = 9.8; } } void physics_sim() { bird.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g pig.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g } }; \u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u505a zeno \u65f6\uff0c\u8be2\u95ee\u8981\u4e0d\u8981\u628a\u6e32\u67d3\u7ba1\u7ebf\u8282\u70b9\u5316\uff0c\u65b9\u4fbf\u7528\u6237\u52a8\u6001\u7f16\u7a0b\uff1f\u5f20\u7329\u7329\u5c31\u662f\u4fe1\u8a93\u65e6\u65e6\u9053\uff1a\u201c\u6e32\u67d3\u662f\u4e00\u4e2a\u9ad8\u5ea6\u6210\u719f\u9886\u57df\uff0c\u4e0d\u4f1a\u6709\u591a\u5c11\u4fee\u6539\u9700\u6c42\u7684\u3002\u201d\u5c0f\u5f6d\u8001\u5e08\u9042\u5199\u6b7b\u4e86\u6e32\u67d3\u7ba1\u7ebf\uff0c\u4e13\u4e3a\u6027\u80fd\u6781\u5ea6\u4f18\u5316\uff0c\u51e0\u4e2a\u6708\u540e\uff0c\u5f20\u7329\u7329\u7f9e\u7b54\u7b54\u627e\u5230\u5c0f\u5f6d\u8001\u5e08\uff1a\u201c\u5c0f\u5f6d\u8001\u5e08\uff0c\u90a3\u4e2a\uff0c\u6e32\u67d3\uff0c\u80fd\u4e0d\u80fd\u6539\u6210\u8282\u70b9\u554a\u2026\u2026\u201d\u3002\u8fd9\u4e2a\u6545\u4e8b\u544a\u8bc9\u6211\u4eec\uff0c\u7532\u65b9\u7684\u4fe1\u8a93\u65e6\u65e6\u653e\u7684\u4e00\u4e2a\u5c41\u90fd\u4e0d\u80fd\u4fe1\u3002","title":"\u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01"},{"location":"lambda/#_5","text":"\u51fd\u6570\u5c31\u662f\u6765\u5e2e\u4f60\u89e3\u51b3\u4ee3\u7801\u91cd\u590d\u95ee\u9898\u7684\uff01\u8981\u9886\uff1a \u628a\u5171\u540c\u7684\u90e8\u5206\u63d0\u53d6\u51fa\u6765\uff0c\u628a\u4e0d\u540c\u7684\u90e8\u5206\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u3002 void sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } fmt::println(\"sum of v = {}\", s); } int main() { std::vector a = {1, 2, 3, 4}; sum(a); std::vector b = {5, 6, 7, 8}; sum(b); return 0; } \u8fd9\u6837 main \u51fd\u6570\u91cc\u5c31\u53ef\u4ee5\u53ea\u5173\u5fc3\u8981\u6c42\u548c\u7684\u6570\u7ec4\uff0c\u800c\u4e0d\u7528\u5173\u5fc3\u6c42\u548c\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\u4e86\u3002\u4e8b\u540e\u6211\u4eec\u53ef\u4ee5\u968f\u65f6\u628a sum \u7684\u5185\u5bb9\u5077\u5077\u6362\u6389\uff0c\u6362\u6210\u5e76\u884c\u7684\u7b97\u6cd5\uff0cmain \u4e5f\u4e0d\u7528\u77e5\u9053\u3002\u8fd9\u5c31\u662f \u5c01\u88c5 \uff0c\u53ef\u4ee5\u628a\u91cd\u590d\u7684\u516c\u5171\u90e8\u5206\u62bd\u53d6\u51fa\u6765\uff0c\u65b9\u4fbf\u4ee5\u540e\u4fee\u6539\u4ee3\u7801\u3002 sum \u51fd\u6570\u76f8\u5f53\u4e8e\uff0c\u5f53\u9700\u8981\u5439\u7a7a\u8c03\u65f6\uff0c\u63d2\u4e0a\u7a7a\u8c03\u63d2\u5ea7\u3002\u5f53\u9700\u8981\u7ed9\u624b\u673a\u5145\u7535\u65f6\uff0c\u63d2\u4e0a\u624b\u673a\u5145\u7535\u5668\u3002\u4f60\u4e0d\u9700\u8981\u5173\u5fc3\u63d2\u5ea7\u91cc\u7684\u7535\u54ea\u91cc\u6765\uff0c\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4f1a\u66ff\u4f60\u60f3\u529e\u6cd5\u89e3\u51b3\uff0c\u60f3\u529e\u6cd5\u4f18\u5316\uff0c\u60f3\u529e\u6cd5\u5347\u7ea7\u5230\u7eff\u8272\u80fd\u6e90\u3002\u4f60\u53ea\u9700\u8981\u5439\u7740\u7a7a\u8c03\u7ed9\u4f60\u6b63\u5728\u5f00\u53d1\u7684\u624b\u673a App \u4f18\u5316\u5c31\u884c\u4e86\uff0c\u5927\u5927\u51cf\u8f7b\u7a0b\u5e8f\u5458\u5fc3\u667a\u8d1f\u62c5\u3002","title":"\u7528\u51fd\u6570\u5c01\u88c5"},{"location":"lambda/#_6","text":"\u4f46\u662f\uff01\u8fd9\u6bb5\u4ee3\u7801\u4ecd\u7136\u6709\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u628a sum \u6c42\u548c\u7684\u7ed3\u679c\uff0c\u76f4\u63a5\u5728 sum \u91cc\u6253\u5370\u4e86\u51fa\u6765\u3002sum \u91cc\u5199\u6b7b\u4e86\uff0c\u6c42\u5b8c\u548c\u4e4b\u540e\u53ea\u80fd\u76f4\u63a5\u6253\u5370\uff0c\u8c03\u7528\u8005 main \u6839\u672c\u65e0\u6cd5\u63a7\u5236\u3002 \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u5c01\u88c5\uff0c\u6216\u8005\u8bf4\uff0c\u5c01\u88c5\u8fc7\u5934\u4e86\u3002 \u4f60\u628a\u624b\u673a\u5145\u7535\u5668 (fmt::println) \u710a\u6b7b\u5728\u4e86\u63d2\u5ea7 (sum) \u4e0a\uff0c\u73b0\u5728\u8fd9\u4e2a\u63d2\u5ea7\u53ea\u80fd\u7ed9\u624b\u673a\u5145\u7535 (\u7528\u4e8e\u76f4\u63a5\u6253\u5370) \u4e86\uff0c\u4e0d\u80fd\u7ed9\u7b14\u8bb0\u672c\u7535\u8111\u5145\u7535 (\u6c42\u548c\u7ed3\u679c\u4e0d\u76f4\u63a5\u7528\u4e8e\u6253\u5370) \u4e86\uff01\u5c3d\u7ba1\u901a\u8fc7\u66f4\u6362\u5145\u7535\u7ebf (\u53c2\u6570 v)\uff0c\u8fd8\u53ef\u4ee5\u652f\u6301\u652f\u6301\u5b89\u5353 (a) \u548c\u82f9\u679c (b) \u4e24\u79cd\u624b\u673a\u7684\u5145\u7535\uff0c\u4f46\u8fd9\u6837\u710a\u6b7b\u7684\u63d2\u5ea7\u5df2\u7ecf\u548c\u7b14\u8bb0\u672c\u7535\u8111\u65e0\u7f18\u4e86\u3002","title":"\u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408"},{"location":"lambda/#_7","text":"\u5f88\u660e\u663e\uff0c\u201c\u6253\u5370\u201d\u548c\u201c\u6c42\u548c\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u64cd\u4f5c\uff0c\u4e0d\u5e94\u8be5\u710a\u6b7b\u5728\u4e00\u5757\u3002 sum \u51fd\u6570\u7684\u672c\u804c\u5de5\u4f5c\u662f\u201c\u6570\u7ec4\u6c42\u548c\u201d\uff0c\u4e0d\u5e94\u8be5\u9644\u8d60\u6253\u5370\u529f\u80fd\u3002 sum \u8ba1\u7b97\u51fa\u6c42\u548c\u7ed3\u679c\u540e\uff0c\u76f4\u63a5 return \u5373\u53ef\u3002 \u5982\u4f55\u5904\u7406\u8fd9\u4e2a\u7ed3\u679c\uff0c\u662f\u8c03\u7528\u8005 main \u7684\u4e8b\uff0c\u6b63\u5982\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4e0d\u4f1a\u7ba1\u4f60\u7528\u4ed6\u63d0\u4f9b\u7684\u7535\u6765\u5439\u7a7a\u8c03\u8fd8\u662f\u73a9\u6e38\u620f\u4e00\u6837\uff0c\u53ea\u8981\u4e0d\u59a8\u788d\u5230\u5176\u4ed6\u5c45\u6c11\u7684\u6b63\u5e38\u7528\u7535\u3002 int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum of a = {}\", sum(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"sum of b = {}\", sum(b)); return 0; } \u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8bf4\u7684 \u804c\u8d23\u5355\u4e00\u539f\u5219 \u3002","title":"\u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528"},{"location":"lambda/#_8","text":"\u5047\u8bbe\u6211\u4eec\u8981\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff0c\u53ef\u4ee5\u518d\u5b9a\u4e49\u4e2a\u51fd\u6570 average\uff0c\u4ed6\u53ef\u4ee5\u57fa\u4e8e sum \u5b9e\u73b0\uff1a int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } double average(std::vector const &v) { return (double)sum(v) / v.size(); } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"average of a = {}\", average(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"average of b = {}\", average(b)); return 0; } \u8fdb\u4e00\u6b65\u5c01\u88c5\u4e00\u4e2a\u6253\u5370\u6570\u7ec4\u6240\u6709\u7edf\u8ba1\u5b66\u4fe1\u606f\u7684\u51fd\u6570\uff1a void print_statistics(std::vector const &v) { if (v.empty()) { fmt::println(\"this is empty...\"); } else { fmt::println(\"sum: {}\", sum(v)); fmt::println(\"average: {}\", average(v)); fmt::println(\"min: {}\", min(v)); fmt::println(\"max: {}\", max(v)); } } int main() { std::vector a = {1, 2, 3, 4}; print_statistics(a); std::vector b = {5, 6, 7, 8}; print_statistics(b); return 0; } \u66b4\u9732 API \u65f6\uff0c\u8981\u540c\u65f6\u63d0\u4f9b\u5e95\u5c42\u7684 API \u548c\u9ad8\u5c42\u5c01\u88c5\u7684 API\u3002\u7528\u6237\u5982\u679c\u60f3\u8981\u63a7\u5236\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u8c03\u7528\u5e95\u5c42 API\uff0c\u60f3\u8981\u7701\u4e8b\u7684\u7528\u6237\u53ef\u4ee5\u8c03\u7528\u9ad8\u5c42\u5c01\u88c5\u597d\u7684 API\u3002 \u9ad8\u5c42\u5c01\u88c5 API \u5e94\u5f53\u53ef\u4ee5\u5b8c\u5168\u901a\u8fc7\u8c03\u7528\u5e95\u5c42 API \u5b9e\u73b0\uff0c\u63d0\u4f9b\u9ad8\u5c42 API \u53ea\u662f\u65b9\u4fbf\u521d\u7ea7\u7528\u6237\u4f7f\u7528\u548c\u7406\u89e3\u3002 \u4f8b\u5982 libcurl \u5c31\u63d0\u4f9b\u4e86 curl_easy \u548c curl_multi \u4e24\u5957 API\u3002 - `curl_multi` \u63d0\u4f9b\u4e86\u8d85\u8be6\u7ec6\u7684\u53c2\u6570\uff0c\u628a\u6bcf\u4e2a\u64cd\u4f5c\u5206\u62c6\u6210\u591a\u6b65\uff0c\u65b9\u4fbf\u7528\u6237\u63d2\u624b\u7ec6\u8282\uff0c\u6ee1\u8db3\u9ad8\u7ea7\u7528\u6237\u7684\u5b9a\u5236\u5316\u9700\u6c42\uff0c\u4f46\u592a\u8fc7\u590d\u6742\uff0c\u96be\u4ee5\u5b66\u4e60\u3002 - `curl_easy` \u662f\u5bf9 `curl_multi` \u7684\u518d\u5c01\u88c5\uff0c\u63d0\u4f9b\u4e86\u66f4\u7b80\u5355\u7684 API\uff0c\u4f46\u662f\u5bf9\u5177\u4f53\u7ec6\u8282\u5c31\u96be\u4ee5\u64cd\u63a7\u4e86\uff0c\u9002\u5408\u521d\u5b66\u8005\u4e0a\u624b\u3002","title":"\u4e8c\u6b21\u5c01\u88c5"},{"location":"lambda/#linus-3-80-24","text":"Linux \u5185\u6838\u4e3a\u4ec0\u4e48\u575a\u6301\u4f7f\u7528 8 \u7f29\u8fdb\u4e3a\u4ee3\u7801\u98ce\u683c\uff1f \u56e0\u4e3a\u9ad8\u7f29\u8fdb\u53ef\u4ee5\u907f\u514d\u7a0b\u5e8f\u5458\u5199\u51fa\u5d4c\u5957\u5c42\u6570\u592a\u6df1\u7684\u4ee3\u7801\uff0c\u5f53\u4ed6\u5199\u51fa\u592a\u6df1\u5d4c\u5957\u65f6\uff0c\u5de8\u5927\u7684 8 \u7f29\u8fdb\u4f1a\u8ba9\u4ee3\u7801\u53d8\u5f97\u975e\u5e38\u504f\u53f3\uff0c\u5199\u4e0d\u4e0b\u591a\u5c11\u7a7a\u95f4\u3002\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u81ea\u5df1\u7ea2\u7740\u8138\u201c\u5bf9\u4e0d\u8d77\uff0c\u6211\u628a\u5355\u4e2a\u51fd\u6570\u5199\u592a\u6df1\u4e86\u201d\u7136\u540e\u8d76\u7d27\u62c6\u5206\u51fa\u591a\u4e2a\u51fd\u6570\u6765\u3002 \u6b64\u5916\uff0c\u4ed6\u8fd8\u89c4\u5b9a\u4e86\u5355\u4e00\u4e00\u4e2a\u51fd\u6570\u5fc5\u987b\u5728\u7ec8\u7aef\u5bbd\u5ea6 80 x 24 \u4e2d\u663e\u793a\u5f97\u4e0b\uff0c\u5426\u5219\u5c31\u9700\u8981\u62c6\u5206\u6210\u591a\u4e2a\u51fd\u6570\u91cd\u5199\uff0c\u8fd9\u914d\u5408 8 \u7f29\u8fdb\uff0c\u6709\u6548\u7684\u9650\u5236\u4e86\u5d4c\u5957\u7684\u5c42\u6570\uff0c\u8feb\u4f7f\u7a0b\u5e8f\u5458\u4e0d\u5f97\u4e0d\u91cd\u65b0\u601d\u8003\uff0c\u66f4\u89e3\u8026\u7684\u5199\u6cd5\u51fa\u6765\u3002","title":"Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c"},{"location":"lambda/#_9","text":"\u4f60\u4ea7\u751f\u4e86\u4e24\u4e2a\u9700\u6c42\uff0c\u5206\u522b\u5c01\u88c5\u4e86\u4e24\u4e2a\u51fd\u6570\uff1a sum \u6c42\u6240\u6709\u5143\u7d20\u7684\u548c product \u6c42\u6240\u6709\u5143\u7d20\u7684\u79ef int sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret += v[i]; } return ret; } int product(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret *= v[i]; } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", sum(a)); fmt::println(\"product: {}\", product(a)); return 0; } \u6ce8\u610f\u5230 sum \u548c product \u7684\u5185\u5bb9\u51e0\u4e4e\u5982\u51fa\u4e00\u8f99\uff0c\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff1a sum \u7684\u5faa\u73af\u4f53\u4e3a += \uff1b product \u7684\u5faa\u73af\u4f53\u4e3a *= \u3002 \u8fd9\u79cd\u51fd\u6570\u4f53\u5185\u6709\u90e8\u5206\u4ee3\u7801\u91cd\u590d\uff0c\u4f46\u53c8\u6709\u7279\u5b9a\u90e8\u5206\u4e0d\u540c\uff0c\u96be\u4ee5\u62bd\u79bb\u3002 \u8be5\u600e\u4e48\u590d\u7528\u8fd9\u91cd\u590d\u7684\u90e8\u5206\u4ee3\u7801\u5462\uff1f \u6211\u4eec\u8981\u628a sum \u548c product \u5408\u5e76\u6210\u4e00\u4e2a\u51fd\u6570 generic_sum \u3002\u7136\u540e\u901a\u8fc7\u51fd\u6570\u53c2\u6570\uff0c\u628a\u5dee\u5f02\u90e8\u5206\uff080\u3001 += \uff09\u201c\u6ce8\u5165\u201d\u5230\u4e24\u4e2a\u51fd\u6570\u539f\u672c\u4e0d\u540c\u5730\u65b9\u3002","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f"},{"location":"lambda/#_10","text":"\u5982\u4f55\u8868\u793a\u6211\u8fd9\u4e2a\u51fd\u6570\u662f\u8981\u505a\u6c42\u548c += \u8fd8\u662f\u6c42\u79ef *= \uff1f \u8ba9\u6211\u4eec\u5b9a\u4e49\u679a\u4e3e\uff1a enum Mode { ADD, // \u6c42\u548c\u64cd\u4f5c MUL, // \u6c42\u79ef\u64cd\u4f5c }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { // \u51fd\u6570\u5185\u5224\u65ad\u679a\u4e3e\uff0c\u51b3\u5b9a\u8981\u505a\u4ec0\u4e48\u64cd\u4f5c ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", generic_sum(a, ADD)); // \u7528\u6237\u6307\u5b9a\u4ed6\u60f3\u8981\u7684\u64cd\u4f5c fmt::println(\"product: {}\", generic_sum(a, MUL)); return 0; } \u7136\u800c\uff0c\u5982\u679c\u7528\u6237\u73b0\u5728\u60f3\u8981\u6c42\u6570\u7ec4\u7684 \u6700\u5927\u503c \u5462\uff1f \u679a\u4e3e\u4e2d\u8fd8\u6ca1\u6709\u5b9e\u73b0\u6700\u5927\u503c\u7684\u64cd\u4f5c\u2026\u2026\u8981\u652f\u6301\uff0c\u5c31\u5f97\u624b\u5fd9\u811a\u4e71\u5730\u53bb\u4fee\u6539 generic_sum \u51fd\u6570\u548c Mode \u679a\u4e3e\u539f\u672c\u7684\u5b9a\u4e49\uff0c\u771f\u9ebb\u70e6\uff01 enum Mode { ADD, MUL, MAX, // ***\u6539*** }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } else if (mode == MAX) { // ***\u6539*** ret = std::max(ret, v[i]); // ***\u6539*** } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, MAX); // ***\u6539*** return 0; } \u6211\u7528 // ***\u6539*** \u6307\u793a\u4e86\u6240\u6709\u9700\u8981\u6539\u52a8\u7684\u5730\u65b9\u3002 \u4e3a\u4e86\u589e\u52a0\u4e00\u4e2a\u6c42\u6700\u5927\u503c\u7684\u64cd\u4f5c\uff0c\u5c31\u9700\u8981\u4e09\u5904\u5206\u6563\u5728\u5404\u5730\u7684\u6539\u52a8\uff01 \u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u5bb9\u6613\u6284\u6f0f\uff0c\u6284\u9519\uff0c\u6bd4\u5982 MAX \u4e0d\u5c0f\u5fc3\u6253\u9519\u6210 MUL \u4e86\uff0c\u81ea\u5df1\u5374\u6ca1\u53d1\u73b0\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u8fd9\u6837\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\uff0c\u5fc3\u667a\u8d1f\u62c5\u6781\u5927\uff0c\u6574\u5929\u5c31\u63d0\u5fc3\u540a\u80c6\u7740\u4e1c\u4e00\u5757\uff0c\u897f\u4e00\u5757\u7684\u6563\u88c5\u4ee3\u7801\uff0c\u62c5\u5fc3\u7740\u6709\u6ca1\u6709\u54ea\u4e2a\u5730\u65b9\u5199\u9519\u5199\u6f0f\uff0c\u4e25\u91cd\u59a8\u788d\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u5e76\u4e14\u5199\u51fa\u6765\u7684\u4ee3\u7801\u4e5f\u4e0d\u80fd\u9002\u5e94\u9700\u6c42\u7684\u53d8\u5316\uff1a\u5047\u5982\u6211\u9700\u8981\u652f\u6301 MIN \u5462\uff1f\u53c8\u5f97\u6539\u4e09\u4e2a\u5730\u65b9\uff01\u8fd9\u8fdd\u80cc\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u7684 \u5f00\u95ed\u539f\u5219 \u3002 \u5f00\u95ed\u539f\u5219: \u5bf9\u6269\u5c55\u5f00\u653e\uff0c\u5bf9\u4fee\u6539\u5c01\u95ed\u3002\u6307\u7684\u662f\u8f6f\u4ef6\u5728\u9002\u5e94\u9700\u6c42\u53d8\u5316\u65f6\uff0c\u5e94\u5c3d\u91cf\u901a\u8fc7 \u6269\u5c55\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\uff0c\u800c\u4e0d\u662f\u901a\u8fc7 \u4fee\u6539\u5df2\u6709\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\u3002 \u4f7f\u7528\u679a\u4e3e\u548c if-else \u5b9e\u73b0\u591a\u6001\uff0c\u96be\u4ee5\u6269\u5c55\uff0c\u8fd8\u8981\u4e00\u76f4\u53bb\u4fee\u6539\u539f\u51fd\u6570\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5c31\u8fdd\u80cc\u4e86 \u5f00\u95ed\u539f\u5219 \u3002","title":"\u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5"},{"location":"lambda/#_11","text":"\u5982\u679c\u6211\u4eec\u53ef\u4ee5\u201c\u6ce8\u5165\u201d\u4ee3\u7801\u5c31\u597d\u4e86\uff01\u80fd\u5426\u628a\u4e00\u6bb5\u201c\u4ee3\u7801\u201d\u4f5c\u4e3a generic_sum \u51fd\u6570\u7684\u53c2\u6570\u5462\uff1f \u4ee3\u7801\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\uff0c\u6ce8\u5165\u4ee3\u7801\u5c31\u662f\u6ce8\u5165\u51fd\u6570\u3002\u6211\u4eec\u5148\u5b9a\u4e49\u51fa\u4e09\u4e2a\u4e0d\u540c\u64cd\u4f5c\u5bf9\u5e94\u7684\u51fd\u6570\uff1a int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } \u7136\u540e\uff0c\u628a\u8fd9\u4e09\u4e2a\u5c0f\u51fd\u6570\uff0c\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u5927\u51fd\u6570 generic_sum \u7684\u53c2\u6570\u5c31\u884c\uff01 int generic_sum(std::vector const &v, auto op) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { // \u51fd\u6570\u4f5c\u8005\u65e0\u9700\u4e86\u89e3\u7528\u6237\u6307\u5b9a\u7684\u201c\u64cd\u4f5c\u201d\u5177\u4f53\u662f\u4ec0\u4e48 // \u53ea\u9700\u8981\u8c03\u7528\u8fd9\u4e00\u201c\u64cd\u4f5c\u201d\uff0c\u5f97\u5230\u7ed3\u679c\u5c31\u884c ret = op(ret, v[i]); } return ret; } int main() { std::vector a = {1, 2, 3, 4}; // \u7528\u6237\u65e0\u9700\u5173\u5fc3\u51fd\u6570\u7684\u5177\u4f53\u5b9e\u73b0\u662f\u4ec0\u4e48 // \u53ea\u9700\u968f\u5fc3\u6240\u6b32\u6307\u5b9a\u4ed6\u7684\u201c\u64cd\u4f5c\u201d\u4f5c\u4e3a\u53c2\u6570 generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u8d23\u4efb\u660e\u786e\u4e86\uff0c\u6211\u4eec\u6210\u529f\u628a\u4e00\u90e8\u5206\u7ec6\u8282\u4ece generic_sum \u4e2d\u8fdb\u4e00\u6b65\u62bd\u79bb\u3002 \u5e93\u4f5c\u8005 generic_sum \u4e0d\u5fc5\u4e86\u89e3 main \u7684\u64cd\u4f5c\u5177\u4f53\u662f\u4ec0\u4e48\uff0c\u4ed6\u53ea\u8d1f\u8d23\u5229\u7528\u8fd9\u4e2a\u64cd\u4f5c\u6c42\u201c\u548c\u201d\u3002 \u5e93\u7528\u6237 main \u4e0d\u5fc5\u4e86\u89e3 generic_sum \u5982\u4f55\u5b9e\u73b0\u64cd\u4f5c\u7d2f\u52a0\uff0c\u4ed6\u53ea\u7ba1\u6ce8\u5165\u201c\u5982\u4f55\u64cd\u4f5c\u201d\u7684\u4ee3\u7801\uff0c\u4ee5\u51fd\u6570\u7684\u5f62\u5f0f\u3002","title":"\u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a"},{"location":"lambda/#c20-auto","text":"int generic_sum(std::vector const &v, auto op) { } \u8fd9\u91cc\u7684\u53c2\u6570 op \u7c7b\u578b\u58f0\u660e\u4e3a auto\uff0c\u6548\u679c\u5c31\u662f\uff0cop \u8fd9\u4e2a\u53c2\u6570\u73b0\u5728\u80fd\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u7684\u5bf9\u8c61\u4e86\uff08\u5305\u62ec\u51fd\u6570\uff01\uff09 int generic_sum(std::vector const &v, auto op) { ... } \u51c6\u786e\u7684\u8bf4\uff0c auto op \u53c2\u6570\u7684\u6548\u679c\u662f\u4f7f generic_sum \u53d8\u4e3a\u4e00\u4e2a \u6a21\u677f\u51fd\u6570 \uff0c\u5176\u4e2d op \u53c2\u6570\u53d8\u6210\u4e86\u6a21\u677f\u53c2\u6570\uff0c\u80fd\u591f\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u4e86\u3002\u800c\u5199\u660e\u7c7b\u578b\u7684\u53c2\u6570 std::vector const &v \u5c31\u6ca1\u6709\u4efb\u4f55\u989d\u5916\u6548\u679c\uff0c\u5c31\u53ea\u80fd\u63a5\u53d7 vector \u800c\u5df2\u3002 \u5982\u679c\u4f60\u4e0d\u652f\u6301 C++20 \u7684\u8bdd\uff0c\u9700\u8981\u663e\u5f0f\u5199\u51fa template \uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\uff1a template int generic_sum(std::vector const &v, Op op) { ... } C++11\uff1aauto \u53ea\u80fd\u7528\u4e8e\u5b9a\u4e49\u53d8\u91cf\uff1bC++14\uff1a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u662f auto\uff1bC++17\uff1a\u6a21\u677f\u53c2\u6570\u4e5f\u53ef\u4ee5 auto\uff1bC++20\uff1a\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5\u662f auto \u4e86\uff1b\uff08\u72c2\u60f3\uff09C++47\uff1aauto \u73b0\u5728\u662f C++47 \u7684\u552f\u4e00\u5173\u952e\u5b57\uff0c\u7528\u6237\u53ea\u9700\u4e0d\u65ad\u8f93\u5165 auto-auto-auto\uff0c\u7f16\u8bd1\u5668\u5185\u5efa\u4eba\u5de5\u667a\u80fd\u81ea\u52a8\u8bc6\u522b\u4f60\u7684\u610f\u56fe\u751f\u6210\u673a\u5668\u7801\u3002","title":"\u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6"},{"location":"lambda/#_12","text":"\u5728\u8fc7\u53bb\u7684 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f \u4e2d\uff0c\u51fd\u6570\uff08\u4ee3\u7801\uff09\u548c\u5bf9\u8c61\uff08\u6570\u636e\uff09\u88ab \u5272\u88c2 \u5f00\u6765\uff0c\u4ed6\u4eec\u611a\u6627\u5730\u8ba4\u4e3a \u51fd\u6570\u4e0d\u662f\u5bf9\u8c61 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f \u5219\u8ba4\u4e3a\uff1a \u51fd\u6570\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u51fd\u6570\u53ef\u4ee5\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u51fd\u6570\u7684\u53c2\u6570\uff01 Function lives matter! \u9762\u5411\u5bf9\u8c61\u5c31\u597d\u6bd4\u8ba1\u7b97\u673a\u7684\u201c\u54c8\u4f5b\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u548c\u6570\u636e\u5272\u88c2\uff0c\u4ee3\u7801\u53ea\u80fd\u5355\u65b9\u9762\u64cd\u4f5c\u6570\u636e\u3002\u51fd\u6570\u5f0f\u5c31\u597d\u6bd4\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u4e5f\u662f\u6570\u636e\u3002\u770b\u4f3c\u4f1a\u5bfc\u81f4\u4f4e\u6548\uff0c\u5b9e\u5219\u5927\u5927\u65b9\u4fbf\u4e86\u52a8\u6001\u52a0\u8f7d\u65b0\u7a0b\u5e8f\uff0c\u56e0\u800c\u73b0\u5728\u7684\u8ba1\u7b97\u673a\u57fa\u672c\u90fd\u91c7\u7528\u4e86\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff0c\u88ab\u4eb2\u5207\u5730\u5c0a\u79f0\u4e3a \u51fd\u6570\u5bf9\u8c61 \u3002","title":"\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01"},{"location":"lambda/#c11-lambda","text":"C++98 \u65f6\u4ee3\uff0c\u4eba\u4eec\u8fd8\u9700\u8981\u5355\u72ec\u8dd1\u5230 main \u5916\u9762\uff0c\u4e13\u95e8\u5b9a\u4e49 add \u3001 mul \u3001 max \u51fd\u6570\u3002\u5f04\u5f97\u6574\u4e2a\u4ee3\u7801\u4e71\u54c4\u54c4\u7684\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } C++11 \u5f15\u5165\u4e86 Lambda \u8868\u8fbe\u5f0f \u8bed\u6cd5\uff0c\u5141\u8bb8\u4f60\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002 int main() { std::vector a = {1, 2, 3, 4}; auto add = [](int a, int b) { return a + b; }; auto mul = [](int a, int b) { return a * b; }; auto max = [](int a, int b) { return std::max(a, b); }; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u4e0d\u7528\u5f80 main \u5916\u9762\u585e\u5783\u573e\u4e86\uff0c\u4e00\u6e05\u723d\u3002 \u66f4\u8fdb\u4e00\u6b65\uff0c\u6211\u4eec\u751a\u81f3\u4e0d\u7528\u5b9a\u4e49\u53d8\u91cf\uff0c\u76f4\u63a5\u628a Lambda \u8868\u8fbe\u5f0f\u5199\u5728 generic_sum \u7684\u53c2\u6570\u91cc\u5c31\u884c\u4e86\uff01 int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); // ***\u6539*** return 0; } \u4ee5\u4e0a\u5199\u6cd5\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u8981\u652f\u6301\u4e00\u4e2a\u65b0\u64cd\u4f5c\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5730\u65b9\uff1a\u5728\u8c03\u7528 generic_sum \u65f6\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002\u968f\u53eb\u968f\u5230\uff0c\u4e0d\u7528\u7ea0\u7ed3\u4e8e\u201c\u8d77\u540d\u5f3a\u8feb\u75c7\u201d\uff0c\u662f\u4e0d\u662f\u5f88\u65b9\u4fbf\u5462\uff1f \u51c6\u786e\u7684\u8bf4\uff0cLambda \u521b\u5efa\u7684\u662f\u51fd\u6570\u5bf9\u8c61 (function object) \u6216\u79f0\u4eff\u51fd\u6570 (functor) \u800c\u4e0d\u662f\u4f20\u7edf\u610f\u4e49\u4e0a\u7684\u51fd\u6570\u3002 \u5176\u5b9e C++98 \u65f6\u4ee3\u4eba\u4eec\u5c31\u5df2\u7ecf\u5927\u91cf\u5728\u7528 operator()() \u6a21\u62df\u51fd\u6570\u5bf9\u8c61\u4e86\uff0c\u8457\u540d\u7684\u7b2c\u4e09\u65b9\u5e93 Boost \u4e5f\u5c01\u88c5\u4e86\u5404\u79cd\u51fd\u6570\u5f0f\u5e38\u7528\u7684\u5bb9\u5668\u548c\u5de5\u5177\u3002C++11 \u624d\u7ec8\u4e8e\u628a \u51fd\u6570\u5bf9\u8c61 \u8fd9\u4e2a\u6982\u5ff5\u8f6c\u6b63\uff0c\u5e76\u5f15\u5165\u4e86\u66f4\u65b9\u4fbf\u7684 Lambda \u8bed\u6cd5\u7cd6\u3002 \u5373\u4f7f\u662f\u9762\u5411\u5bf9\u8c61\u7684\u5934\u53f7\u5b5d\u5b50 Java\uff0c\u4e5f\u5df2\u7ecf\u5f00\u59cb\u5f15\u5165\u51fd\u6570\u5f0f\u7684 Lambda \u8bed\u6cd5\u7cd6\uff0cC# \u7684 LINQ \u66f4\u662f\u660e\u76ee\u5f20\u80c6\u7684\u81f4\u656c map-reduce \u5168\u5bb6\u6876\uff0c\u751a\u81f3 C \u8bed\u8a00\u7528\u6237\u4e5f\u5f00\u59cb\u73a9\u5404\u79cd\u51fd\u6570\u6307\u9488\u56de\u8c03\u2026\u2026\u6ca1\u529e\u6cd5\uff0c\u51fd\u6570\u5f0f\u786e\u5b9e\u65b9\u4fbf\u5440\uff01","title":"C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6"},{"location":"lambda/#_13","text":"\u51fd\u6570\u5bf9\u8c61 op \u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\uff0c\u8ba9 generic_sum \u5185\u90e8\u53bb\u8c03\u7528\uff0c\u5c31\u50cf\u5f80 generic_sum \u4f53\u5185\u201c\u6ce8\u5165\u201d\u4e86\u4e00\u6bb5\u81ea\u5b9a\u4e49\u4ee3\u7801\u4e00\u6837\u3002 \u8fd9\u53ef\u4ee5\u8ba9 generic_sum \u5728\u4e0d\u4fee\u6539\u672c\u4f53\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7\u4fee\u6539\u201c\u6ce8\u5165\u201d\u90e8\u5206\uff0c\u8f7b\u677e\u6269\u5c55\uff0c\u6ee1\u8db3 \u5f00\u95ed\u539f\u5219 \u3002 \u66f4\u51c6\u786e\u7684\u8bf4\uff0c\u8fd9\u4f53\u73b0\u7684\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8981\u6c42\u7684 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u3002 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219: \u4e00\u4e2a\u5c01\u88c5\u597d\u7684\u51fd\u6570\u6216\u7c7b\uff0c\u5e94\u8be5\u5c3d\u91cf\u4f9d\u8d56\u4e8e\u62bd\u8c61\u63a5\u53e3\uff0c\u800c\u4e0d\u662f\u4f9d\u8d56\u4e8e\u5177\u4f53\u5b9e\u73b0\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u56db\u5927\u7f16\u7a0b\u8303\u5f0f\u90fd\u5404\u81ea\u53d1\u5c55\u51fa\u4e86 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u7684\u89e3\u51b3\u65b9\u6848\uff1a \u9762\u5411\u8fc7\u7a0b\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u6307\u9488 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u865a\u51fd\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u5bf9\u8c61 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u6a21\u677f\u5143\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u6a21\u677f\u53c2\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u540c\u6837\u662f\u628a\u62bd\u8c61\u63a5\u53e3\u4f5c\u4e3a\u53c2\u6570\uff0c\u540c\u6837\u89e3\u51b3\u53ef\u6269\u5c55\u95ee\u9898\u3002 \u51fd\u6570\u6307\u9488\u8d34\u8fd1\u5e95\u5c42\u786c\u4ef6\uff0c\u865a\u51fd\u6570\u65b9\u4fbf\u6574\u5408\u591a\u4e2a\u63a5\u53e3\uff0c\u51fd\u6570\u5bf9\u8c61\u8f7b\u91cf\u7ea7\u3001\u968f\u5730\u53d6\u7528\uff0c\u6a21\u677f\u5143\u6709\u52a9\u9ad8\u6027\u80fd\u4f18\u5316\uff0c\u4e0d\u540c\u7684\u7f16\u7a0b\u8303\u5f0f\u6b8a\u9014\u540c\u5f52\u3002","title":"\u4f9d\u8d56\u6ce8\u5165\u539f\u5219"},{"location":"lambda/#_14","text":"\u4f9d\u8d56\u6ce8\u5165\u539f\u5219\u53ef\u4ee5\u51cf\u5c11\u4ee3\u7801\u4e4b\u95f4\u7684\u8026\u5408\u5ea6\uff0c\u5927\u5927\u63d0\u9ad8\u4ee3\u7801\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u8026\u5408\u5ea6: \u6307\u7684\u662f\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u548c\u5176\u4ed6\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u8026\u5408\u5ea6\u8d8a\u4f4e\uff0c\u8d8a\u5bb9\u6613\u8fdb\u884c\u5355\u5143\u6d4b\u8bd5\u3001\u91cd\u6784\u3001\u590d\u7528\u548c\u6269\u5c55\u3002 \u9ad8\u8026\u5408\u5ea6\u7684\u5178\u578b\u662f\u201c\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u201d\u3002\u4f4e\u8026\u5408\u7684\u5178\u8303\u662f\u86af\u8693\uff0c\u56e0\u4e3a\u86af\u8693\u53ef\u4ee5\u5728\u4efb\u610f\u65ad\u9762\u5207\u5f00\uff0c\u8fd8\u80fd\u6d3b\u4e0b\u6765\uff0c\u770b\u6765\u86af\u8693\u7684\u8eab\u4f53\u8bbe\u8ba1\u975e\u5e38\u201c\u6a21\u5757\u5316\u201d\u5462\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8f6f\u4ef6\u5e94\u5f53\u8ffd\u6c42\u4f4e\u8026\u5408\u5ea6\uff0c\u9002\u5ea6\u89e3\u8026\u7684\u8f6f\u4ef6\u80fd\u66f4\u5feb\u9002\u5e94\u9700\u6c42\u53d8\u5316\u3002\u4f46\u8fc7\u5ea6\u7684\u4f4e\u8026\u5408\u4e5f\u4f1a\u5bfc\u81f4\u4ee3\u7801\u8fc7\u4e8e\u5206\u6563\uff0c\u4e0d\u6613\u9605\u8bfb\u548c\u4fee\u6539\uff0c\u751a\u81f3\u53ef\u80fd\u8d77\u5230\u53cd\u6548\u679c\u3002 \u82e5\u4f60\u89e3\u8026\u540e\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u5316\u8981\u6539\u52a8\u7684\u5730\u65b9\u53d8\u5c11\u4e86\uff0c\u90a3\u5c31\u662f\u5408\u7406\u7684\u89e3\u8026\u3002\u82e5\u4f60\u8fc7\u5206\u89e3\u8026\uff0c\u4ee3\u7801\u4e1c\u4e00\u5757\u897f\u4e00\u5757\uff0c\u4ee5\u81f3\u4e8e\u9700\u6c42\u53d8\u5316\u65f6\u9700\u8981\u5230\u5904\u6539\uff0c\u6bd4\u4e0d\u89e3\u8026\u65f6\u6d6a\u8d39\u7684\u65f6\u95f4\u8fd8\u8981\u591a\uff0c\u90a3\u5c31\u662f\u89e3\u8026\u8fc7\u5ea6\u3002 \u5b8c\u5168\u96f6\u8026\u5408\u7684\u7a0b\u5e8f\u6bcf\u4e2a\u51fd\u6570\u4e92\u4e0d\u8054\u7cfb\uff0c\u5c31\u50cf\u628a\u86af\u8693\u62c6\u6563\u6210\u4e00\u4e2a\u4e2a\u72ec\u7acb\u7684\u7ec6\u80de\u4e00\u6837\u3002\u8fde\u521d\u59cb\u9700\u6c42\u201c\u6d3b\u7740\u201d\u90fd\u5b9e\u73b0\u4e0d\u4e86\uff0c\u8c08\u4f55\u9002\u5e94\u9700\u6c42\u53d8\u5316\uff1f\u6240\u4ee5\u89e3\u8026\u4e5f\u5207\u52ff\u77eb\u6789\u8fc7\u6b63\u3002 \u4e3a\u4e86\u907f\u514d\u89e3\u8026\u77eb\u6789\u8fc7\u6b63\uff0c\u4eba\u4eec\u53c8\u63d0\u51fa\u4e86\u5185\u805a\u7684\u6982\u5ff5\uff0c\u5e76\u89c4\u5b9a\u89e3\u8026\u7684\u524d\u63d0\u662f\uff1a\u4e0d\u803d\u8bef\u5185\u805a\u3002\u803d\u8bef\u5230\u5185\u805a\u7684\u89e3\u8026\uff0c\u5c31\u53ea\u4f1a\u8d77\u5230\u964d\u4f4e\u53ef\u7ef4\u62a4\u6027\u7684\u53cd\u6548\u679c\u4e86\u3002 \u5185\u805a: \u6307\u7684\u662f\u540c\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u5185\u90e8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u5185\u805a\u5ea6\u8d8a\u9ad8\uff0c\u529f\u80fd\u8d8a\u72ec\u7acb\uff0c\u8d8a\u65b9\u4fbf\u96c6\u4e2d\u7ef4\u62a4\u3002 \u4f8b\u5982\uff0c\u4eba\u7684\u5fc3\u810f\u4e13\u95e8\u8d1f\u8d23\u6cf5\u8840\uff0c\u809d\u810f\u53ea\u8d1f\u8d23\u89e3\u6bd2\uff0c\u8fd9\u5c31\u662f\u9ad8\u5185\u805a\u7684\u4eba\u4f53\u5668\u5b98\u3002\u82e5\u4eba\u7684\u5fc3\u810f\u8fd8\u8981\u517c\u804c\u89e3\u6bd2\uff0c\u809d\u810f\u8fd8\u517c\u804c\u6cf5\u8840\uff0c\u770b\u4f3c\u597d\u50cf\u662f\u589e\u52a0\u4e86\u201c\u4e07\u4e00\u5fc3\u810f\u574f\u6389\u201d\u7684\u5197\u4f59\u6027\uff0c\u5b9e\u9645\u4e0a\u628a\u201c\u6cf5\u8840\u201d\u8fd9\u4e00\u529f\u80fd\u62c6\u6563\u5230\u5404\u5730\uff0c\u65e0\u6cd5\u201c\u96c6\u4e2d\u529b\u91cf\u6cf5\u5927\u8840\u201d\u4e86\u3002 \u4eba\u7c7b\u7684\u5927\u8111\u548c CPU \u4e00\u6837\uff0c\u4e5f\u6709\u201c\u7f13\u5b58\u5c40\u57df\u6027 (cache-locality)\u201d\u7684\u9650\u5236\uff1a\u4e0d\u80fd\u540c\u65f6\u5728\u5f88\u591a\u4e2a\u4e3b\u9898\u4e4b\u95f4\u5feb\u901f\u5207\u6362\uff0c\u65e0\u8bba\u662f\u65f6\u95f4\u4e0a\u7684\u8fd8\u662f\u7a7a\u95f4\u4e0a\u7684\u5272\u88c2 (cache-miss)\uff0c\u90fd\u4f1a\u5e72\u6270\u7a0b\u5e8f\u5458\u601d\u7ef4\u7684\u8fde\u8d2f\u6027\uff0c\u4ece\u800c\u589e\u5927\u5fc3\u667a\u8d1f\u62c5\u3002 \u597d\u7684\u8f6f\u4ef6\u8981\u4fdd\u6301\u4f4e\u8026\u5408\uff0c\u540c\u65f6\u9ad8\u5185\u805a\u3002 \u5c31\u50cf\u201c\u6c11\u4e3b\u96c6\u4e2d\u5236\u201d\u4e00\u6837\uff0c\u65e2\u8981\u76d1\u7763\u9632\u6b62\u5927\u6743\u72ec\u63fd\uff0c\u53c8\u8981\u96c6\u4e2d\u529b\u91cf\u529e\u4e00\u4e2a\u4eba\u529e\u4e0d\u6210\u7684\u5927\u4e8b\u3002","title":"\u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a"},{"location":"lambda/#_15","text":"\u4f20\u7edf\u7684\u9762\u5411\u5bf9\u8c61\u540c\u6837\u53ef\u4ee5\u7528 \u865a\u51fd\u6570\u63a5\u53e3\u7c7b \u6a21\u62df \u51fd\u6570\u5bf9\u8c61 \u4e00\u6837\u7684\u529f\u80fd\uff0c\u53ea\u4e0d\u8fc7\u6ca1\u6709 lambda \u548c\u95ed\u5305\u7684\u8bed\u6cd5\u52a0\u6301\uff0c\u5199\u8d77\u6765\u975e\u5e38\u7e41\u7410\uff0c\u5c31\u548c\u5728 C \u8bed\u8a00\u91cc\u201c\u6a21\u62df\u201d\u9762\u5411\u5bf9\u8c61\u4e00\u6837\u3002 \u4e3a\u4e86\u8fd9\u4e48\u5c0f\u7684\u4e00\u4e2a\u4ee3\u7801\u5757\uff0c\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u5c31\u50cf\u5988\u5988\u5f00\u4e00\u67b6\u201c\u7a7a\u4e2d\u6218\u8f66\u201d A380 \u53ea\u662f\u4e3a\u4e86\u63a5\u4f60\u653e\u5b66\u4e00\u6837\uff0c\u7b49\u4f60\u503c\u597d\u673a\u7684\u65f6\u95f4\u6211\u81ea\u5df1\u8d70\u90fd\u8d70\u5230\u4e86\u3002\u800c\u51fd\u6570\u5f0f\u4e2d\uff0c\u7528 lambda \u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u76f8\u5f53\u4e8e\u968f\u5730\u6293\u6765\u4e00\u53f0\u5171\u4eab\u5355\u8f66\u5f00\u8d70\u3002 struct OpBase { // \u9762\u5411\u5bf9\u8c61\uff1a\u9047\u4e8b\u4e0d\u51b3\u5148\u5b9a\u4e49\u63a5\u53e3\u2026\u2026 virtual int compute(int a, int b) = 0; virtual ~OpBase() = default; }; struct OpAdd : OpBase { int compute(int a, int b) override { return a + b; } }; struct OpMul : OpBase { int compute(int a, int b) override { return a * b; } }; struct OpMax : OpBase { int compute(int a, int b) override { return std::max(a, b); } }; int generic_sum(std::vector const &v, OpBase *op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op->compute(ret, v[i]); // \u5199\u8d77\u6765\u4e5f\u9ebb\u70e6\uff0c\u9700\u8981\u8c03\u7528\u4ed6\u7684\u6210\u5458\u51fd\u6570\uff0c\u6210\u5458\u51fd\u6570\u53c8\u8981\u8d77\u540d\u2026\u2026 } delete op; return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, new OpAdd()); generic_sum(a, new OpMul()); generic_sum(a, new OpMax()); return 0; } \u4e0d\u4ec5\u9700\u8981\u5b9a\u4e49\u4e00\u5806\u7c7b\uff0c\u63a5\u53e3\u7c7b\uff0c\u5b9e\u73b0\u7c7b\uff0c\u7ee7\u627f\u6765\u7ee7\u627f\u53bb\uff0c\u8fd8\u9700\u8981\u7ba1\u7406\u8ba8\u538c\u7684\u6307\u9488\uff0c\u4ee3\u7801\u91cf\u7ffb\u500d\uff0c\u6ca1\u4ec0\u4e48\u53ef\u8bfb\u6027\uff0c\u53c8\u5f71\u54cd\u8fd0\u884c\u6548\u7387\u3002 3 \u5e74 2 \u73ed\u5c0f\u5f6d\u540c\u5b66\uff0c\u4f60\u7684\u5988\u5988\u5f00\u7740 A380 \u6765\u63a5\u4f60\u4e86\u3002 \u800c\u73b0\u4ee3 C++ \u53ea\u9700 Lambda \u8bed\u6cd5\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u723d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); });","title":"\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4"},{"location":"lambda/#_16","text":"\u521a\u521a\uff0c\u6211\u4eec\u7684\u5b9e\u73b0\u7528\u4e86 auto op \u505a\u53c2\u6570\uff0c\u8fd9\u7b49\u4ef7\u4e8e\u8ba9 generic_sum \u53d8\u6210\u4e00\u4e2a\u6a21\u677f\u51fd\u6570\u3002 int generic_sum(std::vector const &v, auto op); // \u4e0d\u652f\u6301 C++20 \u65f6\u7684\u66ff\u4ee3\u5199\u6cd5\uff1a template int generic_sum(std::vector const &v, Op op); \u8fd9\u610f\u5473\u7740\u6bcf\u5f53\u7528\u6237\u6307\u5b9a\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff08lambda\uff09\u65f6\uff0c generic_sum \u90fd\u4f1a\u91cd\u65b0\u5b9e\u4f8b\u5316\u4e00\u904d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u7f16\u8bd1\u540e\uff0c\u4f1a\u53d8\u6210\u7c7b\u4f3c\u4e8e\u8fd9\u6837\uff1a generic_sum(a); generic_sum(a); generic_sum(a); \u4f1a\u751f\u6210\u4e09\u4efd\u51fd\u6570\uff0c\u6bcf\u4e2a\u90fd\u662f\u72ec\u7acb\u7f16\u8bd1\u7684\uff1a int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = add(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = mul(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = max(ret, v[i]); } return ret; } \u8fd9\u5141\u8bb8\u7f16\u8bd1\u5668\u4e3a\u6bcf\u4e2a\u7248\u672c\u7684 generic_sum \u5355\u72ec\u505a\u4f18\u5316\uff0c\u91cf\u8eab\u5b9a\u5236\u6700\u4f18\u7684\u4ee3\u7801\u3002 \u4f8b\u5982 add \u8fd9\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u56e0\u4e3a\u53ea\u5728 generic_sum \u4e2d\u4f7f\u7528\u4e86\uff0c\u4f1a\u88ab\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u5185\u8054\uff0c\u4e0d\u4f1a\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u548c\u8df3\u8f6c\u7684\u6307\u4ee4\uff0c\u5404\u81ea\u4f18\u5316\u6210\u5355\u72ec\u4e00\u6761\u52a0\u6cd5 / \u4e58\u6cd5 / \u6700\u5927\u503c\u6307\u4ee4\u7b49\u3002 \u6bd4\u5982\uff0c\u7f16\u8bd1\u5668\u4f1a\u68c0\u6d4b\u5230 += \u53ef\u4ee5\u77e2\u91cf\u5316\uff0c\u4e8e\u662f\u7528 _mm_add_epi32 \u66ff\u4ee3\u4e86\u3002\u540c\u7406\uff0cmul \u5219\u7528 _mm_mullo_epi32 \u66ff\u4ee3\uff0cmax \u5219\u7528 _mm_max_epi32 \u66ff\u4ee3\u7b49\uff0c\u5404\u81ea\u5206\u522b\u751f\u6210\u4e86\u5404\u81ea\u7248\u672c\u6700\u4f18\u7684\u4ee3\u7801\u3002\u800c\u5982\u679c\u662f\u666e\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u4e0d\u4f1a\u751f\u6210\u4e09\u4efd\u91cf\u8eab\u5b9a\u505a\u7684\u5b9e\u4f8b\uff0c\u65e0\u6cd5\u77e2\u91cf\u5316\uff08\u6709\u4e00\u79cd\u4f8b\u5916\uff0c\u5c31\u662f\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u4e86 generic_sum \u4f3c\u4e4e\u53ea\u6709\u8fd9\u4e09\u79cd\u53ef\u80fd\u53c2\u6570\uff0c\u7136\u540e\u505a\u4e86 IPO \u4f18\u5316\uff0c\u4f46\u5e76\u4e0d\u5982\u6a21\u677f\u5b9e\u4f8b\u5316\u4e00\u6837\u7a33\u5b9a\u5f3a\u5236\uff09\u3002 \u4e3a\u4e09\u79cd\u4e0d\u540c\u7684 op \u53c2\u6570\u5206\u522b\u5b9a\u505a\u4e09\u4efd\u3002\u867d\u7136\u589e\u52a0\u4e86\u7f16\u8bd1\u65f6\u95f4\uff0c\u81a8\u80c0\u4e86\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u4f53\u79ef\uff1b\u4f46\u751f\u6210\u7684\u673a\u5668\u7801\u662f\u5206\u522b\u9488\u5bf9\u6bcf\u79cd\u7279\u4f8b\u4e00\u5bf9\u4e00\u6df1\u5ea6\u4f18\u5316\u7684\uff0c\u66f4\u9ad8\u6548\u3002 \u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\uff08gemm\uff09\u7684\u6700\u4f18\u7b97\u6cd5\uff0c\u5bf9\u4e8e\u4e0d\u540c\u7684\u77e9\u9635\u5927\u5c0f\u548c\u5f62\u72b6\u662f\u4e0d\u540c\u7684\u3002\u8457\u540d\u7684\u7ebf\u6027\u4ee3\u6570\u5e93 CUBLAS \u548c MKL \u4e2d\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u7528\u6237\u8f93\u5165\u7684\u77e9\u9635\u5f62\u72b6\uff0c\u9009\u53d6\u6700\u4f18\u7684\u7b97\u6cd5\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cCUBLAS \u5e93\u91cc\u5176\u5b9e\u5b58\u7740\u9002\u5408\u5404\u79cd\u77e9\u9635\u5927\u5c0f\u6392\u5217\u7ec4\u5408\u7684\u7b97\u6cd5\u4ee3\u7801\uff08\u4ee5 fatbin \u683c\u5f0f\u5b58\u50a8\u5728\u4e8c\u8fdb\u5236\u4e2d\uff09\u3002\u5f53\u8c03\u7528\u77e9\u9635\u4e58\u6cd5\u65f6\uff0c\u81ea\u52a8\u67e5\u5230\u6700\u9002\u5408\u7684\u4e00\u7248\u6765\u8c03\u7528\u7ed9\u4f60\u3002\u7c7b\u4f3c gemm\uff0c\u8fd8\u6709 gemv\u3001spmv\u2026\u2026\u6240\u6709\u7684\u77e9\u9635\u8fd0\u7b97 API \u90fd\u7ecf\u5386\u4e86\u8fd9\u6837\u7684\u201c\u7f16\u8bd1\u671f\u201d\u66b4\u529b\u6392\u5217\u7ec4\u5408\uff0c\u53ea\u4e3a\u201c\u8fd0\u884c\u65f6\u201d\u91ca\u653e\u6700\u5927\u6027\u80fd\uff01\u8fd9\u4e5f\u5bfc\u81f4\u7f16\u8bd1\u597d\u7684 cublas.dll \u6587\u4ef6\u6765\u5230\u4e86\u6050\u6016\u7684 20 MB \u5de6\u53f3\uff0c\u800c\u6211\u4eec\u79f0\u4e4b\u4e3a\u9ad8\u6548\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1"},{"location":"lambda/#function","text":"Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u6bcf\u4e2a Lambda \u8868\u8fbe\u5f0f\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b\uff0c\u8fd9\u4f7f\u5f97 generic_sum \u5bf9\u4e8e\u6bcf\u4e2a\u4e0d\u540c\u7684 Lambda \u90fd\u4f1a\u5b9e\u4f8b\u5316\u4e00\u904d\u3002\u867d\u7136\u6709\u5229\u4e8e\u6027\u80fd\u4f18\u5316\uff0c\u4f46\u4e5f\u5f71\u54cd\u4e86\u7f16\u8bd1\u901f\u5ea6\u548c\u7075\u6d3b\u6027\u3002 \u901a\u5e38\uff0c\u6211\u4eec\u53ea\u80fd\u901a\u8fc7 decltype(add) \u83b7\u53d6 add \u8fd9\u4e2a Lambda \u5bf9\u8c61\u7684\u7c7b\u578b\u3002\u4e5f\u53ea\u80fd\u901a\u8fc7 auto \u6765\u6355\u83b7 Lambda \u5bf9\u8c61\u4e3a\u53d8\u91cf\u3002 \u4e3a\u6b64\uff0c\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::function \u5bb9\u5668\uff0c\u4ed6\u80fd\u5bb9\u7eb3\u4efb\u4f55\u51fd\u6570\u5bf9\u8c61\uff01\u65e0\u8bba\u662f\u533f\u540d\u7684 Lambda \u51fd\u6570\u5bf9\u8c61\uff0c\u8fd8\u662f\u666e\u666e\u901a\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u90fd\u80fd\u7eb3\u5165 std::function \u7684\u4f53\u5185\u3002 \u552f\u4e00\u7684\u4ee3\u4ef7\u662f\uff0c\u4f60\u9700\u8981\u6307\u5b9a\u51fa\u6240\u6709\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u53c2\u6570\u4e3a\u4e24\u4e2a int \uff0c\u8fd4\u56de int \u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7528 std::function \u5bb9\u5668\u5b58\u50a8\u3002 auto add_lambda = [](int a, int b) { // Lambda \u51fd\u6570\u5bf9\u8c61 return a + b; }; struct AddClass { int operator()(int a, int b) { // \u81ea\u5b9a\u4e49\u7c7b\u6a21\u62df\u51fd\u6570\u5bf9\u8c61 return a + b; } }; AddClass add_object; int add_regular_func(int a, int b) { // \u666e\u901a\u51fd\u6570 return a + b; } std::function add; // \u6240\u6709\u5e7f\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u7edf\u7edf\u63a5\u7eb3 add = add_lambda; // OK add = add_object; // OK add = add_regular_func; // OK int generic_sum(std::vector const &v, std::function op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op(ret, v[i]); // \u5199\u8d77\u6765\u548c\u6a21\u677f\u4f20\u53c2\u65f6\u4e00\u6837\u65e0\u611f } // \u65e0\u9700\u6307\u9488\uff0c\u65e0\u9700 delete\uff0cfunction \u80fd\u81ea\u52a8\u7ba1\u7406\u51fd\u6570\u5bf9\u8c61\u751f\u547d\u5468\u671f return ret; } \u5982\u679c\u8fd8\u60f3\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b std::function \u3002\u8fd9\u91cc std::any \u662f\u4e2a\u8d85\u7ea7\u4e07\u80fd\u5bb9\u5668\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u4f55\u5bf9\u8c61\uff0c\u4ed6\u548c std::function \u4e00\u6837\u90fd\u91c7\u7528\u4e86\u201c\u7c7b\u578b\u64e6\u9664 (type-erasure)\u201d\u6280\u672f\uff0c\u7f3a\u70b9\u662f\u5fc5\u987b\u914d\u5408 std::any_cast \u624d\u80fd\u53d6\u51fa\u4f7f\u7528\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u8fdb\u9636\u4e13\u9898\u4e2d\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u4ed6\u4eec\u7684\u539f\u7406\uff0c\u5e76\u5e26\u4f60\u81ea\u5df1\u505a\u4e00\u4e2a\u64e6\u52a0\u6cd5\u7684\u7c7b\u578b\u64e6\u9664\u5bb9\u5668\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\uff0c\u80fd\u5728\u9759\u6001\u4e0e\u52a8\u6001\u4e4b\u95f4\u8f7b\u677e\u5207\u6362\uff0c \u9ad8\u6027\u80fd \u4e0e \u7075\u6d3b\u6027 \u4efb\u541b\u9009\u62e9\u3002 \u5728\u9700\u8981\u6027\u80fd\u7684 \u74f6\u9888\u4ee3\u7801 \u4e2d\u7528\u6a21\u677f\u4f20\u53c2\uff0c\u7f16\u8bd1\u671f\u9759\u6001\u5206\u53d1\uff0c\u591a\u6b21\u91cf\u8eab\u5b9a\u505a\uff0c\u63d0\u9ad8\u8fd0\u884c\u65f6\u6027\u80fd\u3002 \u74f6\u9888\u4ee3\u7801: \u5f80\u5f80\u4e00\u4e2a\u7a0b\u5e8f 80% \u7684\u65f6\u95f4\u82b1\u5728 20% \u7684\u4ee3\u7801\u4e0a\u3002\u8fd9 20% \u662f\u5728\u7a0b\u5e8f\u4e2d\u9891\u7e41\u6267\u884c\u7684\u3001\u8ba1\u7b97\u91cf\u5927\u7684\u3001\u6216\u8005\u8c03\u7528\u7279\u522b\u8017\u65f6\u7684\u51fd\u6570\u3002\u9488\u5bf9\u8fd9\u90e8\u5206\u74f6\u9888\u4ee3\u7801\u4f18\u5316\u5373\u53ef\uff0c\u800c\u5269\u4f59\u7684 80% \u6253\u9171\u6cb9\u4ee3\u7801\uff0c\u5927\u53ef\u4ee5\u600e\u4e48\u65b9\u4fbf\u600e\u4e48\u5199\u3002 \u5728\u6027\u80fd\u65e0\u5173\u7d27\u8981\u7684\u9876\u5c42\u4e1a\u52a1\u903b\u8f91\u4e2d\u7528 function \u5bb9\u5668\u4f20\u53c2\uff0c\u8fd0\u884c\u65f6\u52a8\u6001\u5206\u53d1\uff0c\u8282\u7701\u7f16\u8bd1\u4f53\u79ef\uff0c\u65b9\u4fbf\u6301\u4e45\u5b58\u50a8\uff0c\u7075\u6d3b\u6613\u7528\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 generic_sum \u51fd\u6570\uff0c\u5982\u679c\u6211\u4eec\u7a81\u7136\u60f3\u8981\u9ad8\u6027\u80fd\u4e86\uff0c\u53ea\u9700\u628a std::function op \u8f7b\u8f7b\u6539\u4e3a auto op \u5c31\u8f7b\u677e\u5207\u6362\u5230\u9759\u6001\u5206\u53d1\u6a21\u5f0f\u4e86\u3002 \u800c\u865a\u51fd\u6570\u4e00\u65e6\u7528\u4e86\uff0c\u57fa\u672c\u5c31\u53ea\u80fd\u52a8\u6001\u5206\u53d1\u4e86\uff0c\u5373\u4f7f\u80fd\u88ab IPO \u4f18\u5316\u6389\uff0c\u865a\u8868\u6307\u9488\u4e5f\u6c38\u8fdc\u5360\u636e\u7740\u4e00\u4e2a 8 \u5b57\u8282\u7684\u7a7a\u95f4\uff0c\u4e14\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u5f0f\u4f20\u6765\u4f20\u53bb\u3002 \u4e00\u79cd\u9759\u6001\u5206\u53d1\u7248\u7684\u865a\u51fd\u6570\u66ff\u4ee3\u54c1\u662f CRTP\uff0c\u4ed6\u57fa\u4e8e\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u4f46\u4e0e\u865a\u51fd\u6570\u4e4b\u95f4\u5207\u6362\u56f0\u96be\uff0c\u4e0d\u50cf\u51fd\u6570\u5bf9\u8c61\u90a3\u4e48\u65e0\u611f\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1"},{"location":"lambda/#_17","text":"\u4e3b\u7ebf\u7a0b\u4e0d\u65ad\u5730\u5411\u5de5\u4f5c\u8005\u7ebf\u7a0b\u53d1\u9001\u51fd\u6570\u5bf9\u8c61\uff0c\u4ee4\u5176\u4ee3\u4e3a\u6267\u884c\uff1a mt_queue> task_queue; void main_thread() { task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a11\"); }); task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a12\"); }); } void worker_thread() { while (true) { auto task = task_queue.pop(); task(); } } mt_queue \u662f\u5c0f\u5f6d\u8001\u5e08\u5c01\u88c5\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u7684\u6d88\u606f\u961f\u5217\uff0c\u5b9e\u73b0\u539f\u7406\u4f1a\u5728\u7a0d\u540e\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4e2d\u8be6\u7ec6\u8bb2\u89e3\u3002","title":"\u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217"},{"location":"lambda/#_18","text":"\u95ed\u5305\u662f\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff0c\u4ed6\u5141\u8bb8\u51fd\u6570\u5bf9\u8c61\u6355\u83b7\u5916\u90e8\u53d8\u91cf\uff0c\u5e76\u5728\u51fd\u6570\u5bf9\u8c61\u5185\u90e8\u4f7f\u7528\u8fd9\u4e9b\u53d8\u91cf\u3002 int x = 10; auto add_x = [x](int a) { return a + x; }; fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 \u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u52a0\u4e0a mutable \u4fee\u9970\uff0c\u89c1\u540e\u6587\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305"},{"location":"lambda/#_19","text":"Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u95ed\u5305\u8bed\u6cd5\uff1a int x = 10; auto add_x = [x](int a) { return a + x; }; \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u4e00\u4e2a\u5e26\u6709 operator() \u6210\u5458\u51fd\u6570\u7684\u7ed3\u6784\u4f53\uff1a struct Lambda { int x; Lambda(int val) : x(val) {} int operator() (int a) const { return a + x; } }; int main() { int x = 10; Lambda add_x(x); fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 return 0; } \u76f8\u5f53\u4e8e\u6211\u4eec\u5199\u7684 lambda \u51fd\u6570\u4f53\uff0c\u5b9e\u9645\u4e0a\u88ab\u7f16\u8bd1\u5668\u79fb\u5230\u4e86 Lambda \u7c7b\u7684 operator() \u6210\u5458\u51fd\u6570\u4f53\u5185\u3002 \u800c\u4e14\u8fd9\u7ed3\u6784\u4f53\u662f\u533f\u540d\u7684\uff0c\u6ca1\u6709\u786e\u5b9a\u7684\u540d\u5b57\uff0c\u6b64\u5904\u7c7b\u540d Lambda \u53ea\u662f\u793a\u610f\uff0c\u56e0\u800c\u5e73\u65f6\u53ea\u80fd\u901a\u8fc7 auto \u4fdd\u5b58\u5373\u65f6\u521b\u5efa\u7684 lambda \u5bf9\u8c61\u3002 \u800c\u6240\u8c13\u7684\u95ed\u5305\u6355\u83b7\u53d8\u91cf\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8fd9\u4e2a\u7ed3\u6784\u4f53\u7684\u6210\u5458\uff01 \u6309\u503c\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u91cc\u62f7\u8d1d\u4e86\u4e00\u4efd\u540c\u540d\u7684\u6210\u5458\uff1b\u5982\u679c\u662f\u5f15\u7528\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u91cc\u7684\u6210\u5458\u662f\u4e2a\u5f15\u7528\u3002 \u53ef\u4ee5\u5728 https://cppinsights.io \u8fd9\u4e2a\u7f51\u7ad9\uff0c\u81ea\u52a8\u62c6\u89e3\u5305\u62ec Lambda \u5728\u5185\u7684\u6240\u6709\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6\u4e3a\u539f\u59cb\u7684\u7ed3\u6784\u4f53\u548c\u51fd\u6570\u3002\u66f4\u591a\u597d\u7528\u7684\u5de5\u5177\u7f51\u7ad9\u53ef\u4ee5\u770b\u6211\u4eec \u5de5\u5177\u548c\u9879\u76ee\u63a8\u8350 \u4e13\u9898\u7ae0\u8282\u3002 \u5bf9\u4e8e\u5f15\u7528\uff0c\u5219\u662f\u7b49\u4ef7\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u4e2d\u542b\u6709\u4e00\u4efd\u5f15\u7528\u4f5c\u4e3a\u6210\u5458\uff1a int x = 10; auto inc_x = [&x](int a) { return x++; }; struct Lambda { int &x; Lambda(int &val) : x(val) {} int operator() () const { return x++; } }; int main() { int x = 10; Lambda inc_x(x); fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 10 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 11 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 12 fmt::println(\"{}\", x); // \u8f93\u51fa 13 return 0; }","title":"\u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6"},{"location":"lambda/#operator","text":"\u533f\u540d lambda \u5bf9\u8c61\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u7684\u7c7b\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); \u5f88\u591a\u540c\u5b66\u90fd\u5206\u4e0d\u6e05 operator operator() opeartor()() \uff0c\u8fd9\u4e2a\u62ec\u53f7\u786e\u5b9e\u5f88\u6709\u8ff7\u60d1\u6027\uff0c\u4eca\u5929\u6211\u6765\u89e3\u91ca\u4e00\u4e0b\u3002 \u4f60\u73b0\u5728\uff0c\u628a\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6539\u6210\u8fd9\u6837\uff1a struct Lambda { int call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.call(2); \u662f\u4e0d\u662f\u5f88\u5bb9\u6613\u770b\u61c2\uff1f\u8fd9\u5c31\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6210\u5458\u51fd\u6570 call \uff0c\u7136\u540e\u8c03\u7528\u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u73b0\u5728\uff0c\u8fdb\u4e00\u6b65\u6539\u6210\uff1a struct Lambda { int operator_call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator_call(2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f\u8fd9\u5c31\u662f\u628a\u51fd\u6570\u540d\u6539\u6210\u4e86 operator_call \uff0c\u4f9d\u7136\u662f\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u91cd\u70b9\u6765\u4e86\uff0c\u6211\u4eec\u628a\u51fd\u6570\u540d\uff0c\u6ce8\u610f\u662f\u51fd\u6570\u540d\u53eb operator() \uff0c\u8fd9\u4e2a\u7a7a\u7684\u5706\u62ec\u53f7\u662f\u51fd\u6570\u540d\u7684\u4e00\u90e8\u5206\uff01 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f operator \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u5173\u952e\u5b57\uff0c\u6548\u679c\u662f\u548c\u540e\u9762\u7684\u4e00\u4e2a\u8fd0\u7b97\u7b26\u7ed3\u5408\uff0c\u5f62\u6210\u4e00\u4e2a\u7279\u6b8a\u7684\u201c\u6807\u8bc6\u7b26\u201d\uff0c\u8fd9\u4e2a\u201c\u6807\u8bc6\u7b26\u201d\u548c\u666e\u901a\u51fd\u6570\u540d\u4e00\u6837\uff0c\u90fd\u662f\u201c\u5355\u4e2a\u5355\u8bcd\u201d\uff0c\u4e0d\u53ef\u5206\u5272\u3002 \u4f8b\u5982 operator+ \u5c31\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c operator[] \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6211\u4eec\u8fd9\u91cc\u7684 operator() \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6ca1\u6709\u4ec0\u4e48\u7a00\u5947\u7684\uff0c\u53ea\u4e0d\u8fc7\u540e\u9762\u8fde\u7684\u8fd0\u7b97\u7b26\u521a\u597d\u662f\u62ec\u53f7\u800c\u5df2\u3002 \u8fd9\u91cc\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 lambda . operator() \u6765\u8bbf\u95ee\u8fd9\u4e2a\u6210\u5458\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\uff0c operator() \u5c31\u548c\u4e00\u4e2a\u666e\u901a\u6210\u5458\u540d\u5b57\u4e00\u6837\uff0c\u6ca1\u6709\u533a\u522b\uff0c\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7 . \u8bbf\u95ee\u3002 \u4f8b\u5982\uff0c\u5bf9\u4e8e\u8fd0\u7b97\u7b26 + \u6765\u8bf4\uff0c\u5f53\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230 lambda + 2 \u8fd9\u6837\u7684\u8868\u8fbe\u5f0f\u65f6\uff0c\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u6210 lambda.operator+ (2) \uff0c\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 struct Lambda { int operator+ (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda + 2; // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator+ (2); \u540c\u6837\u7684\uff0c\u5bf9\u4e8e () \u8fd0\u7b97\u7b26\uff0c\u4e5f\u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210 operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\uff0c\u7531\u4e8e\u5bf9 operator() \u51fd\u6570\u672c\u8eab\u7684\u8c03\u7528\u4e5f\u9700\u8981\u4e00\u4e2a\u62ec\u53f7\uff08\u53c2\u6570\u5217\u8868\uff09\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u5c31\u6709\u4e24\u4e2a\u62ec\u53f7\u4e86\u3002\u5b9e\u9645\u4e0a\u6839\u672c\u4e0d\u642d\u754c\uff0c\u4e00\u4e2a\u662f\u51fd\u6570\u540d\u6807\u8bc6\u7b26\u7684\u4e00\u90e8\u5206\uff0c\u4e00\u4e2a\u662f\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u3002 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (2); \u8fd9\u65f6\u5019\uff0c\u53bb\u6389 (2) \u91cc\u7684\u53c2\u6570 2 \uff0c\u5c31\u53d8\u6210\u4e86\u8ba9\u4f60\u5f88\u56f0\u60d1\u7684\u53cc\u62ec\u53f7\u3002\u800c\u5f88\u591a\u4eba\u559c\u6b22\u7d27\u6328\u8005\u8fde\u5199\uff0c\u770b\u8d77\u6765\u5c31\u5f88\u8ff7\u60d1\u3002 \u5b9e\u9645\u4e0a\uff0c\u7b2c\u4e00\u4e2a () \u662f\u51fd\u6570\u540d\u5b57\u7684\u4e00\u90e8\u5206\uff0c\u548c operator \u662f\u8fde\u5728\u4e00\u8d77\u7684\uff0c\u4e0d\u53ef\u5206\u5272\uff0c\u4e2d\u95f4\u4e5f\u4e0d\u80fd\u6709\u5176\u4ed6\u53c2\u6570\u3002\u7b2c\u4e8c\u4e2a () \u662f\u51fd\u6570\u53c2\u6570\u5217\u8868\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u521a\u597d\u662f\u6ca1\u6709\u53c2\u6570\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u4e5f\u662f\u4e2a\u7a7a\u62ec\u53f7\uff0c\u5f88\u591a\u521d\u5b66\u8005\u770b\u5230\u5c31\u8ff7\u7cca\u4e86\uff0c\u8fd8\u770b\u4e0d\u61c2\u5efa\u8bae\u4ece\u4e0a\u9762\u6709\u4e00\u4e2a\u53c2\u6570\u7684 operator() (int a) \u770b\u3002 struct Lambda { int operator() () const { return 1; } }; Lambda lambda; int ret = lambda(); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (); \u6240\u4ee5\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u8bf4\u5b9a\u4e49\u4e86 operator() \u6210\u5458\u51fd\u6570\u7684\u7c7b\uff0c\u662f\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u6216\u8005\u8bf4\u201c\u4eff\u51fd\u6570\u201d\uff0c\u56e0\u4e3a\u5f53\u4f60\u4f7f\u7528\u51fd\u6570\u7684\u8bed\u6cd5 lambda(2) \u8c03\u7528\u4ed6\u4eec\u65f6\uff0c\u4f1a\u89e6\u53d1\u4ed6\u4eec\u7684\u6210\u5458\u51fd\u6570 operator()(2) \u4ece\u800c\u7528\u6cd5\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u5176\u5b9e\u9645\u53c8\u662f\u5bf9\u8c61\uff0c\u4e5f\u5c31\u5f97\u540d\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u548c\u201c\u4eff\u51fd\u6570\u201d\u4e86\u3002 \u6211\u5efa\u8bae\u4f60\u81ea\u5df1\u53bb https://cppinsights.io \u8fd9\u4e2a\u89e3\u6784\u8bed\u6cd5\u7cd6\u7684\u5de5\u5177\u7f51\u7ad9\u52a8\u52a8\u624b\u8bd5\u8bd5\u770b\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u800c\u6355\u83b7\u4e86\u53d8\u91cf\u7684\uff1a int x = 4; auto lambda = [&x] (int a) { return a + x; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int &x; Lambda(int &x_) : x(x_) {} int operator() (int a) const { return a + x; } }; int x = 4; Lambda lambda(x); int ret = lambda.operator() (2);","title":"operator() \u5f88\u6709\u8ff7\u60d1\u6027"},{"location":"lambda/#_20","text":"\u6b63\u56e0\u5982\u6b64\uff0c\u95ed\u5305\u6309\u503c\u6355\u83b7\uff08 [=] \uff09\u7684\u53d8\u91cf\uff0c\u5176\u751f\u547d\u5468\u671f\u548c Lambda \u5bf9\u8c61\u76f8\u540c\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u62f7\u8d1d\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u88ab\u91cd\u65b0\u62f7\u8d1d\u4e00\u4efd\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u79fb\u52a8\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u968f\u4e4b\u4e00\u8d77\u79fb\u52a8\u3002 struct C { C() { fmt::println(\"C \u9ed8\u8ba4\u6784\u9020\"); } C(C const &) { fmt::println(\"C \u62f7\u8d1d\u6784\u9020\"); } C(C &&) { fmt::println(\"C \u79fb\u52a8\u6784\u9020\"); } C &operator=(C const &) { fmt::println(\"C \u62f7\u8d1d\u8d4b\u503c\"); } C &operator=(C &&) { fmt::println(\"C \u79fb\u52a8\u8d4b\u503c\"); } ~C() { fmt::println(\"C \u6790\u6784\"); } }; C c; fmt::println(\"\u6784\u9020 lambda\"); auto lambda = [c] {}; fmt::println(\"\u62f7\u8d1d lambda \u5230 lambda2\"); auto lambda2 = lambda; fmt::println(\"\u79fb\u52a8 lambda \u5230 lambda3\"); auto lambda3 = lambda; \u8f93\u51fa\uff1a C \u9ed8\u8ba4\u6784\u9020 \u6784\u9020 lambda C \u62f7\u8d1d\u6784\u9020 \u62f7\u8d1d lambda \u5230 lambda2 C \u62f7\u8d1d\u6784\u9020 \u79fb\u52a8 lambda \u5230 lambda3 C \u79fb\u52a8\u6784\u9020 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 \u5982\u679c\u6309\u503c\u6355\u83b7\u4e86\u4e0d\u80fd\u62f7\u8d1d\u7684\u5bf9\u8c61\uff08\u6bd4\u5982 std::unique_ptr \uff09\uff0c\u90a3\u4e48 Lambda \u5bf9\u8c61\u4e5f\u4f1a\u65e0\u6cd5\u62f7\u8d1d\uff0c\u53ea\u80fd\u79fb\u52a8\u3002 std::unique_ptr p = std::make_unique(10); auto lambda = [p] {}; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u56e0\u4e3a\u8fd9\u91cc\u7b49\u4ef7\u4e8e [p' = p]\uff0c\u662f\u5bf9 p' \u7684\u62f7\u8d1d\u6784\u9020 auto lambda = [p = std::move(p)] {}; // \u7f16\u8bd1\u901a\u8fc7\u2705unique_ptr \u652f\u6301\u79fb\u52a8\u6784\u9020 auto lambda2 = lambda; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3std::unique_ptr \u53ea\u652f\u6301\u79fb\u52a8\uff0c\u4e0d\u652f\u6301\u62f7\u8d1d auto lambda2 = std::move(lambda); // \u7f16\u8bd1\u901a\u8fc7\u2705 \u7528\u6211\u4eec\u4e4b\u524d\u7684\u65b9\u6cd5\u89e3\u6784\u8bed\u6cd5\u7cd6\u540e\uff1a struct Lambda { std::unique_ptr p; Lambda(std::unique_ptr ptr) : p(std::move(ptr)) {} // Lambda(Lambda const &) = delete; // \u56e0\u4e3a\u6709 unique_ptr \u6210\u5458\uff0c\u5bfc\u81f4 Lambda \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u88ab\u9690\u5f0f\u5220\u9664 void operator()() const { } }; int main() { std::unique_ptr p = std::make_unique(10); Lambda lambda(p); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3 Lambda lambda(std::move(p)); // \u7f16\u8bd1\u901a\u8fc7\u2705 return 0; }","title":"\u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898"},{"location":"lambda/#mutable","text":"int x = 10; auto lambda = [x] () { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3lambda \u6355\u83b7\u7684 x \u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684 }; int ret = lambda(); \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int x; int operator() () const { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3const \u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u6210\u5458\u53d8\u91cf } }; int x = 10; Lambda lambda{x}; int ret = lambda.operator() (); \u6ce8\u610f\u5230\uff0c\u8fd9\u91cc\u7684 operator() \u6210\u5458\u51fd\u6570\u6709\u4e00\u4e2a const \u4fee\u9970\uff0c\u610f\u5473\u7740\u8be5\u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5176\u4f53\u5185\u7684\u53d8\u91cf\u3002 \u6240\u6709 lambda \u51fd\u6570\u5bf9\u8c61\u751f\u6210\u65f6\u9ed8\u8ba4\uff0c\u5c31\u4f1a\u7ed9\u4ed6\u7684 operator() \u6210\u5458\u51fd\u6570\u52a0\u4e0a const \u4fee\u9970\u3002 \u4e5f\u5c31\u662f\u8bf4\u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u7ed9 lambda \u52a0\u4e0a mutable \u4fee\u9970\uff0c\u5c31\u52a0\u5728 () \u540e\u9762\u3002 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"lambda() = {}\", lambda()); // 10 fmt::println(\"lambda() = {}\", lambda()); // 11 fmt::println(\"lambda() = {}\", lambda()); // 12 \u7f16\u8bd1\u5668\u7ffb\u8bd1\u4ea7\u751f\u7684 Lambda \u7c7b\u7684\u6210\u5458\u51fd\u6570\uff0c\u5c31\u4e0d\u4f1a\u5e26 const \u4fee\u9970\u4e86\uff0c\u4ece\u800c\u5141\u8bb8\u6211\u4eec\u7684\u51fd\u6570\u4f53\u4fee\u6539\u6355\u83b7\u7684\u975e\u5f15\u7528\u53d8\u91cf\u3002 struct Lambda { int x; int operator() () { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 } }; int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 \u6ce8\u610f\uff1a\u7531\u4e8e\u4f7f\u7528\u4e86\u503c\u6355\u83b7\uff0clambda \u4fee\u6539\u7684\u662f\u5728\u4ed6\u521b\u5efa\u65f6\u5bf9 x \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u5916\u9762\u7684 x \u4e0d\u4f1a\u6539\u53d8\uff01 int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // 13 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"ret = {}\", lambda()); // 10 fmt::println(\"ret = {}\", lambda()); // 11 fmt::println(\"ret = {}\", lambda()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u7f16\u8bd1\u5668\u4ea7\u751f\u7684\u533f\u540d lambda \u5bf9\u8c61\u4e2d\u6355\u83b7\u4ea7\u751f\u7684 x \u6210\u5458\u53d8\u91cf\u662f\u533f\u540d\u7684\uff0c\u65e0\u6cd5\u8bbf\u95ee","title":"mutable \u7684\u51fd\u6570\u5bf9\u8c61"},{"location":"lambda/#lambda","text":"","title":"\u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5"},{"location":"lambda/#_21","text":"\u4e00\u4e2a\u53d8\u91cf\u7684\u4e09\u79cd\u6355\u83b7\u65b9\u5f0f\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7 [x] \u6309\u5f15\u7528\u6355\u83b7 [&x] \u6309\u503c\u79fb\u52a8\u6355\u83b7 [x = std::move(x)] \u6309\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 [x = ...] \u6279\u91cf\u6355\u83b7\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [=] \u6309\u5f15\u7528\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [&] \u591a\u4e2a\u6355\u83b7 + \u9ed8\u8ba4\u6355\u83b7\u65b9\u5f0f [x, y, &] \u6216 [&x, &y, =]","title":"\u6355\u83b7\u5217\u8868\u8bed\u6cd5"},{"location":"lambda/#_22","text":"\u8bed\u6cd5\uff1a [\u53d8\u91cf\u540d] \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u62f7\u8d1d\u4e00\u4efd\u6355\u83b7\u7684\u53d8\u91cf\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u5df2\u7ecf\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4e0d\u4f1a\u5f71\u54cd lambda \u6355\u83b7 x \u7684\u503c\u3002 main \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 985 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) mutable { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u7531\u4e8e lambda \u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u9ed8\u8ba4\u90fd\u662f\u4e0d\u53ef\u4fee\u6539\uff08 const \uff09\uff0c\u9700\u8981 mutable \u624d\u80fd\u4fee\u6539\u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u3002\u800c\u6309\u5f15\u7528\u6355\u83b7\u5c31\u4e0d\u9700\u8981 mutable \uff0c\u56e0\u4e3a\u867d\u7136 lambda \u672c\u8eab\u4e0d\u53ef\u4fee\u6539\uff0c\u4f46\u4ed6\u6307\u5411\u7684\u4e1c\u897f\u53ef\u4ee5\u4fee\u6539\u5440\uff01 \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 985 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u4f9d\u7136\u6709\u6548\u3002 int main() { std::function lambda; { int x = 985; lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = 985","title":"\u6309\u503c\u62f7\u8d1d\u6355\u83b7"},{"location":"lambda/#_23","text":"\u8bed\u6cd5\uff1a [&\u53d8\u91cf\u540d] \u6309\u5f15\u7528\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u521b\u5efa\u4e00\u4efd\u6307\u5411\u53d8\u91cf\u7684\u5f15\u7528\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf\u5f15\u7528 &x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u662f\u540c\u4e00\u4e2a\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4f1a\u76f4\u63a5\u5f71\u54cd lambda \u6355\u83b7\u4e2d x \u7684\u503c\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 \u6f14\u793a\uff1amain \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e5f\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u5c06\u6210\u4e3a\u5371\u9669\u7684\u201c\u7a7a\u60ac\u5f15\u7528\uff08dangling-reference\uff09\u201d\uff01\u6b64\u65f6\u518d\u5c1d\u8bd5\u8bbf\u95ee x\uff0c\u5c06\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int main() { std::function lambda; { int x = 985; lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = -858993460 -858993460 \u4e3a\u5185\u5b58\u4e2d\u7684\u5783\u573e\u503c\uff0c\u4f60\u8bfb\u5230\u7684\u7ed3\u679c\u53ef\u80fd\u968f\u5e73\u53f0\uff0c\u7f16\u8bd1\u5668\u7248\u672c\uff0c\u4f18\u5316\u9009\u9879\u7684\u4e0d\u540c\u800c\u4e0d\u540c\uff0c\u6b63\u5e38\u8bfb\u5230 985 \u4e5f\u662f\u6709\u53ef\u80fd\u7684\uff0c\u5f00\u53d1\u8005\u4e0d\u80fd\u4f9d\u8d56\u6b64\u7c7b\u968f\u673a\u6027\u7684\u7ed3\u679c\u3002 \u6b63\u5e38\u8bfb\u5230 985\uff08\u5927\u5b66\uff09\u4e5f\u662f\u6709\u53ef\u80fd\u7684\u3002 -858993460 \u662f\u5728 Windows \u5e73\u53f0\u7684\u8c03\u8bd5\u6a21\u5f0f\u4e0b\u53ef\u80fd\u7684\u8f93\u51fa\uff0c\u56e0\u4e3a Windows \u503e\u5411\u4e8e\u628a\u6808\u5185\u5b58\u586b\u6ee1 0xcccccccc \u4ee5\u65b9\u4fbf\u8c03\u8bd5\uff0c\u5176\u4e2d 0xcc \u521a\u597d\u4e5f\u662f int3 \u8fd9\u6761 x86 \u8c03\u8bd5\u6307\u4ee4\u7684\u4e8c\u8fdb\u5236\u7801\uff0c\u53ef\u80fd\u662f\u4e3a\u4e86\u907f\u514d\u6307\u4ee4\u6307\u9488\u6267\u884c\u5230\u5806\u6808\u91cc\u53bb\u3002","title":"\u6309\u5f15\u7528\u6355\u83b7"},{"location":"lambda/#_24","text":"TODO","title":"\u6309\u503c\u79fb\u52a8\u6355\u83b7"},{"location":"lambda/#_25","text":"TODO","title":"\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7"},{"location":"lambda/#lambda-auto","text":"","title":"lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc"},{"location":"lambda/#auto","text":"lambda \u51fd\u6570\u53ef\u4ee5\u901a\u8fc7\u5728\u53c2\u6570\u5217\u8868\u540e\u4f7f\u7528 -> \u6307\u5b9a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) -> int { return a; }; int i = lambda(); \u5982\u679c\u8fd4\u56de\u7c7b\u578b\u7701\u7565\u4e0d\u5199\uff0c\u9ed8\u8ba4\u662f -> auto \uff0c\u4e5f\u5c31\u662f\u6839\u636e\u4f60\u7684 return \u8bed\u53e5\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 auto lambda = [] (int a) { return a; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> auto { return a; }; \u548c\u666e\u901a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a auto \u4e00\u6837\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u8868\u8fbe\u5f0f\u4e3a\u4f60\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) { return a; // \u6b64\u8868\u8fbe\u5f0f\u7c7b\u578b\u4e3a int }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> int { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f int return a; }; auto lambda2 = [] (int a) { return a * 2.0; // \u6b64\u8fd4\u56de\u8868\u8fbe\u5f0f\u7684\u7c7b\u578b\u4e3a double }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda2 = [] (int a) -> double { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f double return a * 2.0; }; \u5982\u679c\u6ca1\u6709\u8fd4\u56de\u8bed\u53e5\uff0c\u90a3\u4e48\u4f1a\u63a8\u5bfc\u4e3a\u8fd4\u56de void \u7c7b\u578b\u7684 lambda\u3002 auto lambda = [] (int a) { fmt::println(\"a = {}\", a); }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { fmt::println(\"a = {}\", a); }; auto lambda = [] (int a) { return; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { return; }; \u548c\u51fd\u6570\u7684 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u4e00\u6837\uff0c\u5f53\u8fd4\u56de\u7c7b\u578b\u4e3a auto \u7684 lambda \u5177\u6709\u591a\u4e2a\u8fd4\u56de\u8bed\u53e5\u65f6\uff0c\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709\u5206\u652f\u4e0a\u7684\u8fd4\u56de\u503c\u5177\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u62a5\u9519\uff0c\u9700\u8981\u624b\u52a8\u5199\u51fa\u8fd4\u56de\u7c7b\u578b\uff0c\u6216\u8005\u628a\u6240\u6709\u5206\u652f\u7684\u8fd4\u56de\u503c\u6539\u6210\u76f8\u540c\u7684\u3002 auto lambda_error = [] (double x) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u4e24\u4e2a\u5206\u652f\u7684\u8fd4\u56de\u7c7b\u578b\u4e0d\u540c\uff0c\u65e0\u6cd5\u81ea\u52a8\u63a8\u5bfc if (x > 0) { return x; // double } else { return 0; // int } }; auto lambda_ok = [] (double x) { // \u7f16\u8bd1\u901a\u8fc7 if (x > 0) { return x; // double } else { return (double)0; // double } }; auto lambda_also_ok = [] (double x) -> double { // \u624b\u52a8\u660e\u786e\u8fd4\u56de\u7c7b\u578b\uff0c\u7f16\u8bd1\u4e5f\u80fd\u901a\u8fc7 if (x > 0) { return x; // double } else { return 0; // int\uff0c\u4f46\u4f1a\u9690\u5f0f\u8f6c\u6362\u4e3a double } };","title":"auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b"},{"location":"lambda/#auto_1","text":"TODO","title":"auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b"},{"location":"lambda/#auto_2","text":"","title":"auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528"},{"location":"lambda/#auto-auto-const","text":"","title":"auto & \u4e0e auto const & \u7684\u5e94\u7528"},{"location":"lambda/#auto_3","text":"","title":"auto && \u4e07\u80fd\u5f15\u7528"},{"location":"lambda/#decltypeauto","text":"","title":"decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b"},{"location":"lambda/#lambda_1","text":"","title":"lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5"},{"location":"lambda/#_26","text":"\u6211\u4eec\u603b\u662f\u7528 auto \u6765\u4fdd\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u4f5c\u4e3a\u5c40\u90e8\u53d8\u91cf\uff0c\u8fd9\u4f1a\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\u3002 \u4e3a\u4ec0\u4e48\u4e0d\u80fd\u663e\u5f0f\u5199\u51fa\u7c7b\u578b\u540d\u5b57\uff1f\u56e0\u4e3a lambda \u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f60\u65e0\u6cd5\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u53ea\u80fd\u901a\u8fc7 auto \u63a8\u5bfc\u3002 int b = 2; auto lambda = [b] (int a) { return a + b; }; \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 C++11 \u540c\u65f6\u5f15\u5165 auto \u548c lambda \u8bed\u6cd5\u7684\u539f\u56e0\u3002 \u5982\u679c\u4f60\u5b9e\u5728\u9700\u8981\u663e\u5f0f\u7684\u7c7b\u540d\uff0c\u90a3\u5c31\u9700\u8981\u4f7f\u7528 std::function \u5bb9\u5668\u3002\u867d\u7136 lambda \u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f46\u662f\u8be5\u7c7b\u578b\u7b26\u5408\u201c\u53ef\u8c03\u7528\u201d\u7684\u7ea6\u675f\uff0c\u53ef\u4ee5\u88ab std::function \u5bb9\u5668\u63a5\u7eb3\u3002 \u5373 lambda \u7c7b\u578b\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u76f8\u5e94\u53c2\u6570\u5217\u8868\u7684 std::function \u5bb9\u5668\u3002\u56e0\u4e3a std::function \u5bb9\u5668\u53ef\u4ee5\u63a5\u7eb3\u4efb\u4f55\u201c\u53ef\u63a5\u53d7 (Args...) \u53c2\u6570\u8c03\u7528\u5e76\u8fd4\u56de Ret \u7c7b\u578b\u201d\u7684\u4efb\u610f\u51fd\u6570\u5bf9\u8c61\u3002 int b = 2; std::function lambda = [b] (int a) { return a + b; }; \u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u628a lambda \u5bf9\u8c61\u63a8\u5165 vector \u7b49\u5bb9\u5668\u4e2d\u65f6\uff0c\u5c31\u9700\u8981\u663e\u5f0f\u5199\u51fa\u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\uff0c\u6b64\u65f6\u4e07\u80fd\u51fd\u6570\u5bf9\u8c61\u5bb9\u5668 std::function \u5c31\u80fd\u6d3e\u4e0a\u7528\u573a\u4e86\uff1a // vector lambda_list; // \u9519\u8bef\uff1a\u4e0d\u652f\u6301\u7684\u8bed\u6cd5 vector> lambda_list; // OK int b = 2; lambda_list.push_back([b] (int a) { return a + b; }; lambda_list.push_back([b] (int a) { return a * b; }; for (auto lambda: lambda_list) { int ret = lambda(2); fmt::println(\"{}\", ret); }","title":"\u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf"},{"location":"lambda/#_27","text":"","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_28","text":"TODO","title":"\u4ee3\u7801\u590d\u7528"},{"location":"lambda/#lambda-idiom","text":"TODO","title":"\u5c31\u5730\u8c03\u7528\u7684 lambda-idiom"},{"location":"lambda/#_29","text":"\u65b0\u624b\u7528 lambda \u5e38\u89c1\u7684\u9519\u8bef\u5c31\u662f\u641e\u4e0d\u6e05\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\uff0c\u603b\u662f\u60f3\u5f53\u7136\u5730\u65e0\u8111\u7528 [&] \uff0c\u975e\u5e38\u5371\u9669\u3002 \u5982\u679c\u4f60\u6709\u201c\u81ea\u77e5\u4e4b\u660e\u201d\uff0c\u81ea\u77e5\u4e0d\u719f\u6089\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u90a3\u5c31\u5168\u90e8 [=] \u3002 \u7b49\u6211\u4eec\u7a0d\u540e\u7684 \u751f\u547d\u5468\u671f\u4e13\u9898\u8bfe\u7a0b \u4e2d\u4ecb\u7ecd\u3002 \u5b9e\u9645\u4e0a\uff0c [=] \u5e94\u8be5\u662f\u4f60\u9ed8\u8ba4\u7684\u6355\u83b7\u65b9\u5f0f\u3002 \u53ea\u6709\u5f53\u7c7b\u578b\u65e0\u6cd5\u62f7\u8d1d\u4f1a\u6df1\u62f7\u8d1d\u6210\u672c\u8fc7\u9ad8\u65f6\uff0c\u624d\u4f1a\u9009\u62e9\u6027\u5730\u628a\u4e00\u4e9b\u53ef\u4ee5\u6539\u6210\u5f15\u7528\u6355\u83b7\u7684\u90e8\u5206 lambda\uff0c\u4f7f\u7528 [&] \u6765\u6355\u83b7\u90e8\u5206\u9700\u8981\u907f\u514d\u62f7\u8d1d\u7684\u53d8\u91cf\uff0c\u6216\u8005\u4f7f\u7528 shared_ptr \u914d\u5408 [=] \u5c06\u6df1\u62f7\u8d1d\u5316\u4e3a\u6d45\u62f7\u8d1d\u3002 \u4e00\u4e9b\u4e60\u60ef\u4e86 Python\u3001JS \u7b49\u5168\u5458 shared_ptr \u7684\u5783\u573e\u56de\u6536\u8bed\u8a00\u5de8\u5a74\uff0c\u4e00\u4e0a\u6765\u5c31\u5168\u90e8\u65e0\u8111 [&] \uff0c\u7528\u5b9e\u9645\u884c\u52a8\u8bc1\u660e\u4e86\u667a\u5546\u548c\u52c7\u6c14\u6210\u53cd\u6bd4\u5b9a\u5f8b\u3002 \u597d\u6d88\u606f\u662f\uff0c\u5bf9\u4e8e\u4ee3\u7801\u590d\u7528\u548c\u5c31\u5730\u8c03\u7528\u7684\u60c5\u51b5\uff0clambda \u5bf9\u8c61\u7684\u751f\u547d\u90fd\u4e0d\u4f1a\u51fa\u51fd\u6570\u4f53\uff0c\u53ef\u4ee5\u5b89\u5168\u5730\u6539\u6210\u6309\u5f15\u7528\u6355\u83b7 [&] \u3002 \u4f46\u662f\u5bf9\u4e8e\u4e0b\u9762\u4e24\u79cd\u60c5\u51b5\uff08\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u548c\u4f5c\u4e3a\u8fd4\u56de\u503c\uff09\uff0c\u5c31\u4e0d\u4e00\u5b9a\u6709\u8fd9\u4e48\u5e78\u8fd0\u4e86\u3002 \u603b\u4e4b\uff0c\u65e0\u8bba\u5982\u4f55\u8981\u4fdd\u8bc1 lambda \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5c0f\u4e8e\u7b49\u4e8e \u6309\u5f15\u7528\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u3002\u5982\u679c\u505a\u4e0d\u5230\uff0c\u90a3\u5c31\u5f97\u628a\u8fd9\u4e9b\u53ef\u80fd\u8d85\u51fa\u7684\u53d8\u91cf\u6539\u6210\u6309\u503c\u6355\u83b7 [=] \u3002","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_30","text":"\u5982\u679c\u4f60\u60f3\u8ba9\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5c31\u5730\u5b9a\u4e49\uff08\u58f0\u660e\u4e0e\u5b9a\u4e49\u5408\u4f53\uff09\u7684\u51fd\u6570\uff0c\u5efa\u8bae\u586b\u5199 auto \u4e3a\u8fd4\u56de\u503c\u7c7b\u578b\uff0c\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\uff08\u56e0\u4e3a\u4f60\u65e0\u6cd5\u5199\u51fa\u5177\u4f53\u7c7b\u578b\u540d\uff09\u3002 \u7136\u540e\uff0c\u5728 return \u8bed\u53e5\u4e2d\u5c31\u5730\u5199\u51fa lambda \u8868\u8fbe\u5f0f\u5373\u53ef\uff1a auto make_adder(int x) { return [x] (int y) { return x + y; }; } \u5206\u79bb\u58f0\u660e\u4e0e\u5b9a\u4e49\u7684\u51fd\u6570\uff0c\u65e0\u6cd5\u4f7f\u7528 auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff0c\u4e0d\u5f97\u4e0d\u4f7f\u7528\u4e07\u80fd\u7684\u51fd\u6570\u5bb9\u5668 std::function \u6765\u64e6\u5c41\u80a1\uff1a // adder.h std::function make_adder(int x); // adder.cpp std::function make_adder(int x) { return [x] (int y) { return x + y; }; } \u201c\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\uff0c\u8fd9\u79cd\u7528\u6cd5\u5728\u51fd\u6570\u5f0f\u7f16\u7a0b\u975e\u5e38\u5e38\u89c1\u3002","title":"\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c"},{"location":"lambda/#_31","text":"\u4f8b\u5982\u4e0a\u8ff0\u7684 make_adder \u7b49\u4e8e\u7ed1\u5b9a\u4e86\u4e00\u4e2a\u56fa\u5b9a\u53c2\u6570 x \u7684\u52a0\u6cd5\u51fd\u6570\uff0c\u4e4b\u540e\u6bcf\u6b21\u8c03\u7528\u8fd9\u4e2a\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5c31\u56fa\u5b9a\u589e\u52a0\u4e4b\u524d\u5728 make_adder \u53c2\u6570\u4e2d x \u7684\u589e\u91cf\u4e86\u3002 TODO","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_32","text":"\u6b64\u7c7b\u201c\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u5199\u6cd5\uff0c\u5176 lambda \u6355\u83b7\u5fc5\u987b\u662f\u6309\u503c\u6355\u83b7\u7684\uff01 \u5426\u5219\uff0c\u56e0\u4e3a\u8c03\u7528\u8005\u8c03\u7528\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\u65f6\uff0c\u5c40\u90e8\u53d8\u91cf\u548c\u5b9e\u53c2\u6240\u5bf9\u5e94\u7684\u51fd\u6570\u5c40\u90e8\u6808\u7a7a\u95f4\u5df2\u7ecf\u91ca\u653e\uff0c\u76f8\u5f53\u4e8e\u5728 lambda \u4f53\u5185\u5b58\u6709\u7a7a\u60ac\u5f15\u7528\uff0c\u5bfc\u81f4\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u8981\u4e48\u76f4\u63a5\u5d29\u6e83\uff0c\u8981\u4e48\u975e\u5e38\u9690\u853d\u5730\u7559\u4e0b\u5185\u5b58\u975e\u6cd5\u8bbf\u95ee\u7684\u9690\u60a3\uff09\u3002 auto make_adder(int x) { return [x] (int y) { return x + y; }; } int main() { // \u6211\u662f\u8c03\u7528\u8005 auto adder = make_adder(2); adder(3); // 2 + 3 = 5 }","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_33","text":"TODO\uff1a\u4ee3\u7801","title":"\u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570"},{"location":"lambda/#_34","text":"TODO\uff1a\u7b56\u7565\u6a21\u5f0f TODO\uff1a\u5ef6\u8fdf\u56de\u8c03","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_35","text":"\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570\u7684\u751f\u547d\u5468\u671f\u95ee\u9898\uff0c\u9700\u8981\u5206\u5c31\u5730\u8c03\u7528\u548c\u5ef6\u8fdf\u8c03\u7528\u4e24\u79cd\u60c5\u51b5\u8ba8\u8bba\u3002","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_36","text":"\u5982\u679c\u4f60\u7684\u667a\u529b\u6682\u4e0d\u8db3\u4ee5\u641e\u61c2\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u6ca1\u5173\u7cfb\uff0c\u59cb\u7ec8\u4f7f\u7528 [=] \u80af\u5b9a\u6ca1\u9519\u3002 \u4e00\u4e2a\u540c\u5b66\u8be2\u95ee\uff1a\u6211\u53e3\u6e34\uff01\u5728\u4e0d\u77e5\u9053\u4ed6\u7684\u8010\u53d7\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u80af\u5b9a\u662f\u76f4\u63a5\u7ed9\u4ed6\u5403\u6c34\uff0c\u800c\u4e0d\u662f\u7ed9\u4ed6\u5403\u9152\u7cbe\u3002\u867d\u7136\u4e00\u4e9b\u5b5d\u5b50\u66f0\u201c\u9002\u91cf\u201d\u201c\u9002\u5ea6\u201d\u201c\u8ba1\u91cf\u201d\u5404\u79cd\u4e00\u8fde\u4e32\u9644\u52a0\u6761\u4ef6\u4e0b\uff0c\u5ba3\u79f0\u201c\u9152\u7cbe\u4e5f\u662f\u5b89\u5168\u7684\u201d\u3002\u4f46\u662f\u201c\u6c34\u6c38\u8fdc\u662f\u5b89\u5168\u7684\u201d\uff0c\u201c\u6c38\u8fdc\u201d\uff0c\u90a3\u6211\u76f4\u63a5\u7ed9\u4ed6\u559d\u6c34\uff0c\u662f\u80af\u5b9a\u4e0d\u4f1a\u9519\u7684\u3002\u7b49\u4f60\u957f\u5927\u6210\u5e74\u4e86\uff0c\u6709\u8fa8\u522b\u80fd\u529b\u4e86\uff0c\u518d\u53bb\u6839\u636e\u81ea\u5df1\u7684\u5c0f\u8ba1\u673a\u7619\u75d2\u7a0b\u5ea6\uff0c\u9009\u62e9\u6027\u5730\u559d\u6709\u673a\u6eb6\u5242\u3002\u6b64\u5904 [=] \u5c31\u662f\u8fd9\u4e2a\u4e07\u80fd\u7684\u6c34\uff0c\u867d\u7136\u4e0d\u4e00\u5b9a\u9ad8\u6548\uff0c\u4f46\u662f\u80af\u5b9a\u6ca1\u9519\u3002\u521d\u5b66\u8005\u603b\u662f\u4ece [=] \u7528\u8d77\uff0c\u7b49\u5b66\u660e\u767d\u4e86\uff0c\u518d\u6765\u5c1d\u8bd5\u7a81\u7834\u201c\u5c0f\u8ba1\u673a\u6027\u80fd\u7126\u8651\u4f18\u5316\u201d\u4e5f\u4e0d\u8fdf\u3002 \u5982\u679c\u4f60\u81ea\u8ba4\u4e3a\u80fd\u5206\u5f97\u6e05\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u521b\u5efa\uff0c\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u8fd4\u56de\u4e00\u4e2a lambda\uff0c\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u63a5\u53d7\u4e00\u4e2a lambda \u505a\u53c2\u6570\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u4f5c\u4e3a\u56de\u8c03\u51fd\u6570\uff0c\u5ef6\u8fdf\u8c03\u7528\uff0c\u90a3\u5c31\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u4ee5\u4e0a\u56db\u79cd\u60c5\u51b5\uff0c\u5206\u522b\u4ee3\u7801\u6f14\u793a\uff1a void func() { int i = 1; auto lambda = [&] () { return i; }; lambda(); } int main() { func(); } auto func() { int i = 1; return [=] () { return i; }; } int main() { auto lambda = func(); lambda(); } auto func(auto lambda) { lambda(); } int main() { int i = 1; func([&] () { return i; }); } vector> g_callbacks; auto func(auto lambda) { g_callbacks.push_back(lambda); } void init() { int i = 1; func([=] () { return i; }); } int main() { init(); for (auto cb: g_callbacks) { cb(); } }","title":"\u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&]"},{"location":"lambda/#lambda-stl","text":"\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a","title":"lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570"},{"location":"lambda/#_37","text":"\u6a21\u677f\u51fd\u6570\u6bd4\u8f83\u7b80\u5355\uff0c\u76f4\u63a5\u5f80\u51fd\u6570\u53c2\u6570\u4e2d\u4f20\u5165 lambda \u5bf9\u8c61\u5373\u53ef\u3002 sort \uff1a std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::sort(a.begin(), a.end(), comp); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 shared_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::shared_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u7684\u5f15\u7528\u8ba1\u6570\u5f52\u96f6\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002","title":"\u6a21\u677f\u51fd\u6570"},{"location":"lambda/#_38","text":"\u800c\u6a21\u677f\u7c7b\u5219\u9700\u8981\u5148\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u6307\u5b9a\u7c7b\u578b\uff0c\u7136\u540e\u5728\u6784\u9020\u51fd\u6570\u4e2d\u4f20\u5165\u53c2\u6570\u3002 std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::set sorted(comp); sorted.assign(a.begin(), a.end()); a.assign(sorted.begin(), sorted.end()); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5229\u7528 set \u5bb9\u5668\u6709\u5e8f\u7684\u7279\u70b9\uff0c\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 unique_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::unique_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u6790\u6784\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002","title":"\u6a21\u677f\u7c7b"},{"location":"lambda/#lambda-stl_1","text":"TODO: count_if, erase_if, argsort","title":"lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b"},{"location":"lambda/#_39","text":"\u4e8c\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b a < b std::less a > b std::greater a <= b std::less_equal a >= b std::greater_equal a == b std::equal_to a != b std::not_equal_to a <=> b std::compare_three_way (C++20) a && b std::logical_and a \\|\\| b std::logical_or a & b std::bit_and a \\| b std::bit_or a ^ b std::bit_xor a + b std::plus a - b std::minus a * b std::multiplies a / b std::divides a % b std::modulus \u4e00\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b !a std::logical_not ~a std::bit_not -a std::negate a std::identity","title":"\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570"},{"location":"lambda/#bind","text":"\u539f\u59cb\u51fd\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { hello(2, 3); hello(2, 4); hello(2, 5); return 0; } \u7ed1\u5b9a\u90e8\u5206\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello2 = std::bind(hello, 2, std::placeholders::_1); hello2(3); // hello(2, 3) hello2(4); // hello(2, 4) hello2(5); // hello(2, 5) return 0; } std::placeholders::_1 \u8868\u793a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\u3002 std::placeholders::_1 \u5728 bind \u8868\u8fbe\u5f0f\u4e2d\u4f4d\u4e8e hello \u7684\u7684\u7b2c\u4e8c\u53c2\u6570\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\uff1a\u628a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\uff0c\u4f20\u9012\u5230 hello \u7684\u7b2c\u4e8c\u53c2\u6570\u4e0a\u53bb\u3002 \u7ed1\u5b9a\u5168\u90e8\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello23 = std::bind(hello, 2, 3); hello23(); // hello(2, 3) return 0; } \u7ed1\u5b9a\u5f15\u7528\u53c2\u6570\uff1a int inc(int &x) { x += 1; } int main() { int x = 0; auto incx = std::bind(inc, std::ref(x)); incx(); fmt::println(\"x = {}\", x); // x = 1 incx(); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u5982\u679c\u4e0d\u4f7f\u7528 std::ref \uff0c\u90a3\u4e48 main \u91cc\u7684\u5c40\u90e8\u53d8\u91cf x \u4e0d\u4f1a\u6539\u53d8\uff01\u56e0\u4e3a std::bind \u6709\u4e00\u4e2a\u607c\u4eba\u7684\u8bbe\u8ba1\uff1a\u9ed8\u8ba4\u6309\u62f7\u8d1d\u6355\u83b7\uff0c\u4f1a\u628a\u53c2\u6570\u62f7\u8d1d\u4e00\u4efd\uff0c\u800c\u4e0d\u662f\u4fdd\u7559\u5f15\u7528\u3002 \u6709\u8da3\u7684\u662f\uff0cplaceholder \u6307\u5b9a\u7684\u53c2\u6570\uff0c\u5374\u4e0d\u9700\u8981 std::ref \u624d\u80fd\u4fdd\u6301\u5f15\u7528\uff1a int inc(int &x, int y) { x += y; } int main() { int x = 0; auto inc1 = std::bind(inc, std::placeholders::_1, 1); inc1(x); // \u6b64\u5904 x \u662f\u6309\u5f15\u7528\u4f20\u9012\u7684 fmt::println(\"x = {}\", x); // x = 1 inc1(x); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u90a3\u662f\u56e0\u4e3a\uff0c std::placeholders::_1 \u6307\u5b9a\u7684\u53c2\u6570\u4f1a\u88ab\u76f4\u63a5\u5b8c\u7f8e\u8f6c\u53d1\u7ed9 inc \u91cc\u7684 x \uff0c\u76f8\u5f53\u4e8e inc(x, 2); \u3002\u53ea\u6709\u6355\u83b7\u7684\u53c2\u6570\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e0d\u4f1a\u5b8c\u7f8e\u8f6c\u53d1\u3002","title":"bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570"},{"location":"lambda/#bind_1","text":"\u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; };","title":"bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1"},{"location":"lambda/#bind_2","text":"\u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002","title":"bind \u7684\u5386\u53f2"},{"location":"lambda/#thread","text":"\u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42","title":"thread \u819d\u76d6\u4e2d\u7bad"},{"location":"lambda/#_40","text":"bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand();","title":"\u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668"},{"location":"lambda/#stdbind_front-stdbind_back","text":"C++17 \u5f15\u5165\u4e86\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\uff1a std::bind_front \uff1a\u7ed1\u5b9a\u6700\u524d\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u540e\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\uff1b std::bind_back \uff1a\u7ed1\u5b9a\u672b\u5c3e\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u524d\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\u3002 \u548c\u666e\u901a\u7684 std::bind \u76f8\u6bd4\u6709\u4ec0\u4e48\u597d\u5904\u5462\uff1f \u5bf9\u4e8e\u51fd\u6570\u53c2\u6570\u975e\u5e38\u591a\uff0c\u4f46\u5b9e\u9645\u53ea\u9700\u8981\u7ed1\u5b9a\u4e00\u4e24\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\uff0c\u7528 std::bind \u4f1a\u9700\u8981\u6dfb\u52a0\u975e\u5e38\u591a\u7684 placeholder\uff0c\u6570\u91cf\u548c\u51fd\u6570\u7684\u5269\u4f59\u53c2\u6570\u6570\u91cf\u4e00\u6837\u591a\u3002\u800c std::bind_front \u5219\u76f8\u5f53\u4e8e\u4e00\u4e2a\u7b80\u5199\uff0c\u540e\u9762\u7684\u5360\u4f4d\u7b26\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\u4e86\u3002 \u4f8b\u5982\u7ed1\u5b9a x = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, 42, std::placeholders::_1, std::placeholders::_2); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_front(func, 42); \u7ed1\u5b9a z = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, std::placeholders::_1, std::placeholders::_2, 42); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_back(func, 42); \u53ef\u4ee5\u770b\u5230\uff0c\u4f7f\u7528\u8fd9\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\u660e\u663e\u5199\u7684\u4ee3\u7801\u5c11\u4e86\u3002 \u5176\u4e2d\u6700\u5e38\u7528\u7684\u662f std::bind_front \uff0c\u7528\u4e8e\u7ed1\u5b9a\u7c7b\u6210\u5458\u7684 this \u6307\u9488\u3002","title":"std::bind_front \u548c std::bind_back"},{"location":"lambda/#_41","text":"\u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } }","title":"\u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570"},{"location":"lambda/#stdbind_front","text":"\u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f","title":"\u4f7f\u7528 std::bind_front \u4ee3\u66ff"},{"location":"lambda/#lambda_2","text":"\u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408 forward \u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(std::forward(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } }","title":"\u4f7f\u7528 lambda \u4ee3\u66ff"},{"location":"lambda/#bind_3","text":"TODO\uff1a std::less \u548c std::bind","title":"bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408"},{"location":"lambda/#c","text":"","title":"\u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389"},{"location":"lambda/#lambda_3","text":"","title":"lambda \u8fdb\u9636\u6848\u4f8b"},{"location":"lambda/#lambda_4","text":"","title":"lambda \u5b9e\u73b0\u9012\u5f52"},{"location":"lambda/#lambda_5","text":"","title":"lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef"},{"location":"lambda/#lambda-if-constexpr","text":"","title":"lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26"},{"location":"lambda/#c23-stdmove_only_function-stdfunction","text":"\u901a\u8fc7\u6309\u503c\u79fb\u52a8\u6355\u83b7 [p = std::move(p)] \uff0clambda \u53ef\u4ee5\u6301\u6709\u4e00\u4e2a unique_ptr \u4f5c\u4e3a\u6355\u83b7\u53d8\u91cf\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u8fd9\u6837\u521b\u5efa\u51fa\u6765\u7684 lambda\uff0c\u5b58\u5165 std::function \u65f6\u4f1a\u62a5\u9519\uff1a TODO: \u4ee3\u7801","title":"\u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function"},{"location":"lambda/#lambda_6","text":"","title":"\u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488"},{"location":"lambda/#stdvariant-stdvisit","text":"TODO: \u4ee3\u7801\u6848\u4f8b \u5728\u4e4b\u540e\u7684 std::variant \u4e13\u9898\u7ae0\u8282 \u4e2d\u4f1a\u8fdb\u4e00\u6b65\u4ecb\u7ecd\u3002","title":"\u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001"},{"location":"lambda/#shared_from_this-this","text":"","title":"\u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f"},{"location":"lambda/#mutable-lambda","text":"","title":"mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668"},{"location":"lambda/#c20-lambda","text":"","title":"C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5"},{"location":"llvm_intro/","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM \u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM LLVM \u4ecb\u7ecd \u53c2\u8003\u8d44\u6599 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u4e00\u70b9\u5fe0\u544a LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 Linux/MacOS \u7528\u6237 Windows \u7528\u6237 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 \u5f00\u59cb\u6784\u5efa \u8fd0\u884c\u8bd5\u8bd5 \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u8bed\u6cd5\u6811\uff08AST\uff09 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 LLVM IR \u7684\u7279\u70b9 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u7c7b\u578b\u7cfb\u7edf \u57fa\u7840\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u6307\u9488\u7c7b\u578b \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM IR \u6848\u4f8b\u5206\u6790 target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f define \u5b9a\u4e49\u51fd\u6570 alloca \u6307\u4ee4 store \u6307\u4ee4 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 load \u6307\u4ee4 add \u6307\u4ee4 ret \u6307\u4ee4 \u4e3a\u51fd\u6570\u6307\u5b9a attributes Clang \u751f\u6210 IR \u6c47\u7f16 \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c \u4e4b\u95f4\u7684\u8f6c\u6362 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u8c03\u7528 LLVM pass \u4f18\u5316 \u6848\u4f8b \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417 LLVM \u4ecb\u7ecd LLVM \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\u57fa\u7840\u8bbe\u65bd\uff0c\u5b83\u4e0d\u662f\u4e00\u4e2a\u5355\u4e00\u7684\u7f16\u8bd1\u5668\uff0c\u800c\u662f\u4e00\u7cfb\u5217\u5de5\u5177\u548c\u5e93\u7684\u96c6\u5408\uff0c\u5176\u63d0\u4f9b\u4e30\u5bcc\u7684\u6570\u636e\u7ed3\u6784 (ADT) \u548c\u4e2d\u95f4\u8868\u793a\u5c42 (IR)\uff0c\u662f\u5b9e\u73b0\u7f16\u8bd1\u5668\u7684\u6700\u4f73\u6846\u67b6\u3002 LLVM \u662f\u7f16\u8bd1\u5668\u7684\u4e2d\u540e\u7aef\uff0c\u4e2d\u7aef\u8d1f\u8d23\u4f18\u5316\uff0c\u540e\u7aef\u8d1f\u8d23\u6700\u7ec8\u6c47\u7f16\u4ee3\u7801\u7684\u751f\u6210\uff0c\u4ed6\u5e76\u4e0d\u5728\u4e4e\u8c03\u7528\u4ed6\u7684\u4ec0\u4e48\u9ad8\u7ea7\u8bed\u8a00\uff0c\u53ea\u8d1f\u8d23\u628a\u62bd\u8c61\u7684\u4ee3\u6570\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\uff0c\u57fa\u672c\u5757\uff0c\u8f6c\u5316\u4e3a\u8ba1\u7b97\u673a\u786c\u4ef6\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u4e5f\u6709\u4e9b\u6c99\u96d5\u6559\u6750\u4f1a\u628a\u4e2d\u7aef\u548c\u540e\u7aef\u7edf\u79f0\u4e3a\u540e\u7aef\u2026\u2026 Clang \u53ea\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u524d\u7aef\uff0c\u5176\u8d1f\u8d23\u7f16\u8bd1 C/C++ \u8fd9\u7c7b\u8bed\u8a00\uff0c\u8fd8\u6709\u7528\u4e8e\u7f16\u8bd1 Fotran \u7684 Flang \u524d\u7aef\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u8bf8\u5982 Rust\u3001Swift\u3001Haskell \u4e4b\u7c7b\u7684\u8bed\u8a00\uff0c\u4e5f\u90fd\u5728\u4f7f\u7528 LLVM \u505a\u540e\u7aef\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6790\u6784\u51fd\u6570\u5728 } \u5904\u8c03\u7528\uff0c\u8fd9\u662f C++ \u7684\u8bed\u6cd5\u89c4\u5219\uff0c\u5728 Clang \u524d\u7aef\u4e2d\u5904\u7406\u3002\u5f53 Clang \u5b8c\u6210 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u8bed\u4e49\u89c4\u5219\u7684\u89e3\u6790\u540e\uff0c\u5c31\u4f1a\u521b\u5efa\u4e00\u79cd\u53eb\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff0cIntermediate Representation\uff09\u7684\u4e1c\u897f\uff0c\u585e\u7ed9 LLVM \u540e\u7aef\u3002\u5728 IR \u5c42\u9762\uff0c\u6790\u6784\u51fd\u6570\u548c\u666e\u901a C \u8bed\u8a00\u51fd\u6570\u5df2\u7ecf\u6ca1\u6709\u533a\u522b\uff0c\u90fd\u662f\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\u5728 Clang \u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u786e\u5b9a\uff08\u57fa\u4e8e C++ \u8bed\u6cd5\u89c4\u5219\u51b3\u5b9a\uff09\u3002LLVM \u5e76\u4e0d\u5173\u5fc3\u8fd9\u4e2a\u51fd\u6570\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f Rust \u51fd\u6570\uff0c\u4ed6\u53ea\u77e5\u9053\u8fd9\u662f\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u53ea\u9700\u8981\u8fd9\u4e2a\u4fe1\u606f\uff0c\u5c31\u53ef\u4ee5\u53bb\u505a\u4f18\u5316\u4e86\u3002 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u5982\u679c\u6ca1\u6709 IR \u4f1a\u600e\u6837\uff1f\u5047\u8bbe\u6709 M M \u79cd\u8bed\u8a00\uff0c N N \u79cd\u786c\u4ef6\uff0c\u5c31\u9700\u8981\u91cd\u590d\u5b9e\u73b0 M \\times N M \\times N \u4e2a\u7f16\u8bd1\u5668\uff01\u800c IR \u4f5c\u4e3a\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4ee4\u8bed\u8a00\u548c\u786c\u4ef6\u7684\u5177\u4f53\u7ec6\u8282\u89e3\u8026\u4e86\uff0c\u4ece\u800c\u53ea\u9700\u8981\u5199 M + N M + N \u4efd\u4ee3\u7801\u5c31\u53ef\u4ee5\uff1a\u8bed\u8a00\u7684\u5f00\u53d1\u8005\u53ea\u9700\u8981\u8003\u8651\u8bed\u6cd5\u5982\u4f55\u53d8\u6210\u6570\u5b66\u8fd0\u7b97\u548c\u63a7\u5236\u6d41\uff0c\u786c\u4ef6\u5382\u5546\u53ea\u9700\u8981\u8003\u8651\u5982\u4f55\u628a\u6570\u5b66\u548c\u8df3\u8f6c\u6307\u4ee4\u53d8\u6210\u81ea\u5df1\u7279\u5b9a\u7684\u673a\u5668\u7801\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u662f LLVM/Clang \u8fd8\u662f GCC \u5bb6\u65cf\uff0c\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u5185\u90e8\u90fd\u65e0\u4e00\u4f8b\u5916\u91c7\u7528\u4e86 IR \u505a\u4e2d\u95f4\u8868\u793a\u3002 \u6709\u4e86\u7edf\u4e00\u7684\u62bd\u8c61 IR \u4ee5\u540e\uff0c\u4e0d\u7ba1\u4f60\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f C \u8bed\u8a00\u666e\u901a\u51fd\u6570\uff0c\u8fdb\u4e86 IR \u4ee5\u540e\u90fd\u662f\u4e00\u6837\u7684\u51fd\u6570\u8c03\u7528\uff0c\u51cf\u8f7b\u4e86\u7f16\u8bd1\u5668\u4e2d\u540e\u7aef\u5f00\u53d1\u8005\u7684\u5fc3\u667a\u8d1f\u62c5\u3002\u8981\u5f00\u53d1\u4e00\u79cd\u65b0\u8bed\u8a00\uff0c\u53ea\u7ba1\u89e3\u6790\u5b8c\u8bed\u6cd5\u751f\u6210 IR \u8f93\u5165 LLVM\uff0c\u4ed6\u4f1a\u66ff\u4f60\u5305\u529e\u597d\u4f18\u5316\u548c\u6c47\u7f16\u7684\u4e8b\u3002 \u53c2\u8003\u8d44\u6599 LLVM \u5b98\u65b9\u4ed3\u5e93\uff1ahttps://github.com/llvm/llvm-project LLVM \u7528\u6237\u6587\u6863\uff1ahttps://llvm.org/docs/ LLVM \u6e90\u7801\u7ea7\u6587\u6863\uff1ahttps://llvm.org/doxygen/ LLVM IR \u5168\u6587\u6863\uff1ahttps://llvm.org/docs/LangRef.html \u300aLearn LLVM 17\u300b\uff1ahttps://github.com/xiaoweiChen/Learn-LLVM-17 \u300a\u5f00\u59cb\u5b66\u4e60 LLVM\u300b\uff1ahttps://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/ \u300aminiSysY \u7f16\u8bd1\u5b9e\u9a8c\u300b\uff1ahttps://buaa-se-compiling.github.io/miniSysY-tutorial/pre/llvm.html \u300aA Gentle Introduction to LLVM IR\u300b\uff1ahttps://mcyoung.xyz/2023/08/01/llvm-ir/ \u300aLLVM IR C++ API Tutorial\u300b\uff1ahttps://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/ \u4e0d\u5efa\u8bae\u6309\u987a\u5e8f\u5168\u90e8\u9010\u4e2a\u9605\u8bfb\u5b8c\uff0c\u8fd9\u4e48\u591a\u6587\u6863\u5c0f\u5f6d\u8001\u5e08\u90fd\u770b\u4e0d\u5b8c\u3002\u5efa\u8bae\u9047\u5230\u4e86\u4e0d\u719f\u6089\u7684\u6307\u4ee4\u65f6\uff0c\u518d\u53bb\u9488\u5bf9\u6027\u5730\u627e\u5230\u76f8\u5e94\u7ae0\u8282\uff0c\u5b66\u4e60\u3002 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM \u5982\u679c\u4f60\u5bf9 C++ \u8bed\u8a00\u7684\u5e95\u5c42\u5b9e\u73b0\u611f\u5174\u8da3\uff0c\u7f16\u8bd1\u5668\u662f\u7ed5\u4e0d\u8fc7\u7684\u4e00\u73af\u3002\u5fa1\u4e09\u5bb6\u4e2d\uff0cMSVC \u662f\u95ed\u6e90\u7684\u65e0\u6cd5\u5b66\u4e60\uff0cGCC \u4ee3\u7801\u9ad8\u5ea6\u8026\u5408\uff0c\u4e14\u5f88\u591a\u539f\u59cb\u7684 C \u8bed\u8a00\u201c\u53e4\u795e\u4f4e\u8bed\u201d\u6df7\u6742\u5176\u4e2d\uff0c\u53ef\u8bfb\u6027\u8f83\u5dee\u3002Clang \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 C++ \u7f16\u8bd1\u5668\u524d\u7aef\uff0c\u800c LLVM \u6b63\u662f\u4ed6\u7684\u540e\u7aef\uff0c\u9ad8\u5ea6\u6a21\u5757\u5316\u7684\u8bbe\u8ba1\uff0c\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5f88\u5bb9\u6613\u52a0\u5165\u81ea\u5df1\u7684\u65b0\u6a21\u5757\uff0c\u6700\u9002\u5408\u7f16\u8bd1\u5668\u65b0\u4eba\u4e0a\u624b\u5b66\u4e60\u3002\u9664\u53bb Clang \u8d1f\u8d23\u7684 C++ \u8bed\u6cd5\u89e3\u6790\u540e\uff0cLLVM \u540e\u7aef\u5360\u636e\u4e86\u534a\u58c1\u6c5f\u5c71\u3002\u4f60\u60f3\u4e0d\u60f3\u63a2\u7a76\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5229\u7528\u672a\u5b9a\u4e49\u884c\u4e3a\u4f18\u5316\u7684\uff1f\u60f3\u4e0d\u60f3\u77e5\u9053\u4e3a\u4ec0\u4e48\u6709\u65f6 C++ \u7f16\u8bd1\u5668\u51fa\u73b0\u5f02\u5e38\u7684\u884c\u4e3a\uff1f\u60f3\u4e0d\u60f3\u4e86\u89e3\u600e\u6837\u624d\u80fd\u5199\u51fa\u5bf9\u7f16\u8bd1\u5668\u53cb\u597d\u7684\u4ee3\u7801\uff0c\u65b9\u4fbf\u7f16\u8bd1\u5668\u81ea\u52a8\u5e2e\u4f60\u4f18\u5316\uff1f\u90a3\u5c31\u6765\u5b66\u4e60 LLVM \u5427\uff01 \u524d\u7aef\u548c\u540e\u7aef\u4f17\u591a\uff0c\u65e0\u8bba\u4f60\u662f\u6253\u7b97\u5f00\u53d1\u4e00\u79cd\u65b0\u578b\u8bed\u8a00\uff0c\u8fd8\u662f\u81ea\u7814\u4e00\u79cd\u65b0\u7684 CPU \u67b6\u6784\uff0c\u8003\u8651\u652f\u6301 LLVM \u4f5c\u4e3a\u4e2d\u7aef\u51e0\u4e4e\u662f\u4f60\u552f\u4e00\u7684\u9009\u62e9\u3002 \u5bf9\u4e8e CPU/GPU \u786c\u4ef6\u5382\u5546\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u524d\u7aef\uff0c\u652f\u6301 LLVM \u5c06\u4f7f\u4f60\u7684\u786c\u4ef6\u76f4\u63a5\u652f\u6301 C/C++/CUDA/OpenCL/SyCL/Objective-C/Fortran/Rust/Swift/Haskell \u7b49\u6240\u6709 LLVM \u6709\u524d\u7aef\u7684\u8bed\u8a00\u3002\u4f8b\u5982\u6709\u7684\u56fd\u4ea7\u663e\u5361\u57fa\u4e8e LLVM \u6dfb\u52a0\u4e86\u81ea\u5df1\u7684\u786c\u4ef6\u6307\u4ee4\u96c6\u4f5c\u4e3a\u540e\u7aef\uff0c\u7136\u540e\u518d\u5229\u7528 LLVM \u7684 CUDA \u524d\u7aef\uff0c\u5c31\u5b9e\u73b0\u4e86\u517c\u5bb9 CUDA\uff0cAMD \u5f97\u4ee5\u5b9e\u73b0 CUDA \u517c\u5bb9\u4e5f\u662f\u57fa\u4e8e\u6b64\u3002\u53cd\u4e4b\uff0c\u65b0\u8bed\u8a00\u4e5f\u53ef\u4ee5\u4f7f\u7528 LLVM \u7684 PTX \u540e\u7aef\u8f93\u51fa\uff0c\u4ece\u800c\u652f\u6301\u5728 NVIDIA \u663e\u5361\u4e0a\u6267\u884c\u3002 \u5bf9\u4e8e\u60f3\u53d1\u660e\u65b0\u8bed\u8a00\u6216\u4e3a\u73b0\u6709\u811a\u672c\u8bed\u8a00\u5b9e\u73b0 JIT \u52a0\u901f\u7684\u5f00\u53d1\u8005\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u540e\u7aef\uff0c\u65b0\u8bed\u8a00\u4f7f\u7528 LLVM \u5c31\u80fd\u76f4\u63a5\u652f\u6301 x86/ARM/MIPS/PPC/BPF/PTX/AMDGPU/SPIR-V \u7b49\u5404\u79cd\u67b6\u6784\u548c\u6307\u4ee4\u96c6\uff0c\u800c\u81ea\u5df1\u4e0d\u7528\u589e\u52a0\u4efb\u4f55\u5e95\u5c42\u7ec6\u8282\u8d1f\u62c5\u3002\u4f8b\u5982\u4e00\u4e9b Rust \u7528\u6237\u867d\u7136\u5ba3\u79f0\u53ef\u4ee5\u53d6\u4ee3 C++\uff0c\u4f46 Rust \u7f16\u8bd1\u5668\u6700\u7ec8\u4ecd\u662f\u8c03\u7528 LLVM \u5b9e\u73b0\u7f16\u8bd1\uff0c\u4ea7\u751f\u53ef\u4ee5\u6267\u884c\u7684\u4e8c\u8fdb\u5236\u7801\u3002\u81ea\u5df1\u4e00\u4e2a\u4e2a\u9002\u914d\u6240\u6709\u786c\u4ef6\u5e73\u53f0\u7684\u673a\u5668\u7801\u6210\u672c\u5b9e\u5728\u592a\u9ad8\u4e86\uff0c\u4e14\u4e0d\u8bba\u8fd8\u8981\u4e13\u95e8\u5f00\u53d1\u6240\u6709\u7684\u4f18\u5316 pass\uff0c\u800c LLVM \u4f5c\u4e3a\u4e1a\u754c\u652f\u6301\u6700\u5b8c\u5584\u7684\u73b0\u6210\u54c1\u5728\u5f88\u957f\u4e00\u6bb5\u65f6\u95f4\u5185\u90fd\u5f88\u96be\u4ee3\u66ff\u3002 \u4e2d\u7aef\u4f18\u5316\u548c\u5206\u6790\u80fd\u529b\u5f3a\u5927\uff0c\u65b0\u8bed\u8a00\u82e5\u57fa\u4e8e LLVM\uff0c\u4f18\u5316\u65b9\u9762\u7684\u5de5\u4f5c\u90fd\u6709\u73b0\u6210\u7684\u5b9e\u73b0\uff0c\u53ef\u4ee5\u5168\u90e8\u8ba9 LLVM \u4ee3\u52b3\uff0c\u81ea\u5df1\u53ea\u9700\u8981\u8d1f\u8d23\u89e3\u6790\u8bed\u6cd5\uff0c\u751f\u6210 LLVM IR \u5373\u53ef\uff0c\u5982\u4f55\u4f18\u5316\u540e\u751f\u6210\u4e8c\u8fdb\u5236\u7801\u6839\u672c\u65e0\u9700\u64cd\u5fc3\uff0cLLVM \u4f1a\u81ea\u52a8\u6839\u636e\u5f53\u524d\u7684\u76ee\u6807\u5e73\u53f0\u5224\u65ad\u3002 \u9ad8\u5ea6\u81ea\u5305\u542b\uff0c\u5b8c\u5168\u57fa\u4e8e CMake \u7684\u6a21\u5757\u5316\u6784\u5efa\uff0c\u5145\u6ee1\u73b0\u4ee3\u611f\u3002\u7528\u6237\u53ef\u81ea\u884c\u9009\u62e9\u8981\u6784\u5efa\u7684\u6a21\u5757\u3002\u4e14\u51e0\u4e4e\u5b8c\u5168\u65e0\u4f9d\u8d56\u5c31\u80fd\u6784\u5efa\uff0c\u6709 CMake \u6709\u7f16\u8bd1\u5668\u5c31\u884c\uff0c\u65e0\u9700\u5b89\u88c5\u7e41\u7410\u7684\u7b2c\u4e09\u65b9\u5e93\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u843d\u540e\u7684 Makefile + AutoConf \u6784\u5efa\u7cfb\u7edf\uff0c\u4e14\u7248\u672c\u8981\u6c42\u82db\u523b\u3002 LLVM \u91c7\u7528\u7684 MIT \u5f00\u6e90\u534f\u8bae\u5341\u5206\u5bbd\u677e\uff0c\u5bf9\u5546\u7528\u81ea\u7531\u5ea6\u8f83\u9ad8\u3002\u4e14\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5bb9\u6613\u81ea\u5df1\u63d2\u5165\u65b0\u529f\u80fd\uff0c\u53ef\u4fee\u6539\u540e\u4f9b\u81ea\u5df1\u4f7f\u7528\uff0c\u56e0\u6b64\u5e38\u7528\u4e8e\u95ed\u6e90\u9a71\u52a8\u4e2d\uff08\u4f8b\u5982 NVIDIA \u7684 OpenGL \u9a71\u52a8\u7b49\uff09\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u7684 GPL \u534f\u8bae\u5c31\u6bd4\u8f83\u4e25\u683c\uff0c\u4e0d\u5f97\u81ea\u5df1\u4fee\u6539\u540e\u95ed\u6e90\u53d1\u5e03\uff08\u5fc5\u987b\u8fde\u540c\u6e90\u4ee3\u7801\u4e00\u8d77\u53d1\u5e03\uff09\u3002 LLVM \u9644\u5e26\u4e86\u8bb8\u591a\u5b9e\u7528\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5e2e\u52a9\u6211\u4eec\u5206\u6790\u7f16\u8bd1\u5168\u8fc7\u7a0b\u7684\u4e2d\u95f4\u7ed3\u679c\uff0c\u7406\u89e3\u4f18\u5316\u662f\u5982\u4f55\u53d1\u751f\u7684\u3002\u4f8b\u5982 llvm-as\uff08LLVM IR \u8f6c\u4e3a\u538b\u7f29\u7684\u5b57\u8282\u7801\uff09\uff0cllvm-dis\uff08\u5b57\u8282\u7801\u8f6c\u4e3a IR\uff09\uff0copt\uff08\u53ef\u4ee5\u5bf9 IR \u8c03\u7528\u5355\u4e2a\u4f18\u5316 pass\uff09\uff0cllc\uff08\u5c06\u5b57\u8282\u7801\u8f6c\u6362\u4e3a\u76ee\u6807\u673a\u5668\u7684\u6c47\u7f16\u4ee3\u7801\uff09\uff0cllvm-link\uff08IR \u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u8f93\u5165\u591a\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u4ea7\u751f\u5355\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff09\uff0clld\uff08\u5bf9\u8c61\u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u7c7b\u4f3c\u4e8e GNU ld\uff09\uff0clli\uff08\u89e3\u91ca\u6267\u884c\u5b57\u8282\u7801\uff09\uff0cllvm-lit\uff08\u5355\u5143\u6d4b\u8bd5\u5de5\u5177\uff09\u3002 \u4e00\u4e9b\u82af\u7247\u76f8\u5173\u7684\u5927\u5382\u4e2d\uff0c\u7f16\u8bd1\u5668\u65b9\u9762\u7684\u5c97\u4f4d\u9700\u6c42\u91cf\u5f88\u5927\u3002\u800c\u5176\u4e2d\u4e3b\u8981\u7528\u7684\uff0c\u4f8b\u5982 NVIDIA \u7684\u7f16\u8bd1\u5668 nvcc\uff0c\u5176\u540e\u7aef\u5c31\u662f\u57fa\u4e8e LLVM \u9b54\u6539\u7684\uff0c\u56e0\u6b64\u5b66\u4e60 LLVM \u5f88\u6709\u5c31\u4e1a\u524d\u666f\u3002 \u4e3a\u4ec0\u4e48\u6709\u4e86 Clang \u8fd8\u8981 nvcc\uff1f\u867d\u7136 Clang \u4e5f\u80fd\u652f\u6301 CUDA\uff0c\u4f46 Clang \u53ea\u80fd\u628a CUDA \u7f16\u8bd1\u6210\u6240\u6709 NVIDIA \u663e\u5361\u90fd\u80fd\u901a\u7528\u7684 PTX\uff0c\u65e0\u6cd5\u751f\u6210\u4e13\u95e8\u5bf9\u4e0d\u540c\u663e\u5361\u578b\u53f7\u7279\u5316 SASS \u6c47\u7f16\uff08\u9700\u8981\u8c03\u7528 NVIDIA CUDA Toolkit \u63d0\u4f9b\u7684 ptxas \u624d\u80fd\u8f6c\u6362\uff09\u3002\u800c nvcc \u7684\u524d\u7aef\u9664\u4e86\u662f\u81ea\u5df1\u7684\uff0c\u540e\u7aef\u540c\u6837\u662f\u8c03\u7528 LLVM \u751f\u6210 PTX \u6c47\u7f16\uff0c\u53ea\u662f NVIDIA \u5bf9 LLVM \u505a\u4e86\u4e00\u4e9b\u95ed\u6e90\u7684\u9b54\u6539\uff08\u5176\u5b9e\u65e9\u671f nvcc \u7684\u540e\u7aef\u662f\u57fa\u4e8e NVIDIA \u81ea\u7814\u7684 NVVM \u540e\u7aef\uff0c\u4f46\u662f\u53d1\u73b0\u6548\u679c\u4e0d\u597d\uff0c\u6700\u8fd1\u6b63\u5728\u9010\u6b65\u5207\u6362\u5230 LLVM \u540e\u7aef\uff0c\u6bd5\u7adf\u662f\u8001\u724c\u9879\u76ee\uff09\u3002\u5982\u679c\u5bf9 C++ \u65b0\u7279\u6027\u6709\u8ffd\u6c42\uff0c\u53ef\u4ee5\u7528 Clang \u524d\u7aef + LLVM \u751f\u6210 PTX + ptxas \u6c47\u7f16\u7684\u7ec4\u5408\uff0c\u5b9e\u73b0\u81ea\u7531\u4e16\u754c\u7684 CUDA \u5de5\u4f5c\u6d41\uff08\u4e4b\u540e\u4ecb\u7ecd\uff09\u3002\u4f46\u662f\u56e0\u4e3a ptxas\uff0c\u4ee5\u53ca CUDA \u5176\u4ed6\u8fd0\u884c\u65f6\u5e93\u7684\u9700\u8981\uff0cClang CUDA \u4f9d\u7136\u9700\u8981\u5b89\u88c5 CUDA Toolkit \u624d\u80fd\u6b63\u5e38\u8fd0\u884c\uff0c\u4e14\u5bf9 CUDA \u7248\u672c\u8981\u6c42\u6bd4\u8f83\u4e25\u683c\uff0c\u53ef\u80fd\u9700\u8981\u8f83\u591a\u7684\u914d\u7f6e\u529f\u592b\u3002 Rust \u7f16\u8bd1\u5668\u6700\u8fd1\u4e5f\u6709\u63d0\u51fa\u4e86 gcc-rust\uff0c\u4f7f\u7528 GCC \u505a\u540e\u7aef\u4ee3\u66ff LLVM \u7684\u8ba1\u5212\u2026\u2026\u5c31\u4e0d\u80fd\u81ea\u7814\u4e00\u4e2a RRVM \u4e48\uff1f\u4e0d\u4ec5\u662f Rust \u7f16\u8bd1\u5668\uff0c\u4f60\u4f1a\u53d1\u73b0\u5f88\u591a Rust \u9879\u76ee\u6700\u7ec8\u6216\u591a\u6216\u5c11\u90fd\u5728\u4f9d\u8d56\u4e00\u4e9b C++ \u5e93\uff0c\u6bd4\u5982 RustDesk \u8fd9\u6b3e\u9ad8\u6027\u80fd\u7684\u8fdc\u7a0b\u63a7\u5236\u8f6f\u4ef6\uff0c\u4e0d\u77e5\u548b\u5730\u5c31\u975e\u8981\u4f9d\u8d56 libyuv \u548c libvpx\uff0c\u8fd8\u8981\u6c42\u7528\u6c99\u96d5\u7684 vcpkg \u5b89\u88c5\u2026\u2026\u662f\u81ea\u5df1\u5199\u4e0d\u6765\u8fd8\u662f\u61d2\u5f97\u5199\u4e86\uff1fRust \u4e0d\u662f\u9ad8\u6027\u80fd\u7684\u7cfb\u7edf\u7ea7\u8bed\u8a00\u4e48\uff1f\u5982\u679c Rust \u793e\u533a\u4e0d\u4f1a\u5199 YUV \u7f16\u7801\uff0c\u53ef\u4ee5\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\u5e2e\u5fd9\u7684\u3002\u603b\u4e4b\uff0c\u73b0\u5728\u641e\u5f97 Rust \u548c Python \u4e00\u6837\uff0c\u6210\u5305\u76ae\u8bed\u8a00\u4e86\u3002\u4eca\u540e\u5bf9 Rust \u7684\u5b66\u4e60\uff0c\u6050\u6015\u8fd8\u662f\u5c48\u670d\u4e8e\u5b9e\u7528\uff0c\u548c Python \u4e00\u6837\u5404\u79cd\u201cAPI bindings\u201d\u3002 LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f LLVM \u9879\u76ee\u4e0d\u4ec5\u5305\u542b\u4e86 LLVM \u672c\u4f53\uff0c\u8fd8\u6709\u4e00\u7cfb\u5217\u56f4\u7ed5 LLVM \u5f00\u53d1\u7684\u4e0a\u4e0b\u6e38\u5de5\u5177\u3002\u4f8b\u5982 Clang \u7f16\u8bd1\u5668\u5c31\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff0c\u4ed6\u662f\u4e00\u4e2a C/C++/CUDA/OpenCL/SyCL/Objective-C \u7b49 C \u7c7b\u8bed\u8a00\u7684\u524d\u7aef\uff0c\u53ea\u8d1f\u8d23\u5b8c\u6210\u8bed\u6cd5\u7684\u89e3\u6790\uff0c\u5b9e\u9645\u7f16\u8bd1\u548c\u4e8c\u8fdb\u5236\u751f\u6210\u4ea4\u7ed9 LLVM \u672c\u4f53\uff08\u4e2d\u540e\u7aef\uff09\u6765\u5904\u7406\u3002\u901a\u5e38\u8bf4\u7684 LLVM \u6307\u7684\u662f LLVM \u672c\u4f53\uff0c\u5176\u662f\u4e00\u4e2a\u901a\u7528\u7684\u7f16\u8bd1\u5668\u57fa\u5efa\uff0c\u4ec5\u5305\u542b\u4e2d\u7aef\uff08\u5404\u79cd\u4f18\u5316\uff09\u548c\u540e\u7aef\uff08\u751f\u6210 x86/ARM/MIPS \u7b49\u786c\u4ef6\u7684\u6307\u4ee4\u7801\uff09\u3002Clang \u89e3\u6790 .cpp \u6587\u4ef6\u540e\u4ea7\u751f IR\uff0c\u8c03\u7528 LLVM \u7f16\u8bd1\u751f\u6210\u7684 .o \u5bf9\u8c61\u6587\u4ef6\uff0c\u53c8\u4f1a\u88ab\u8f93\u5165\u5230\u540c\u5c5e LLVM \u9879\u76ee\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff1aLLD \u94fe\u63a5\u5668\u4e2d\uff0c\u94fe\u63a5\u5f97\u5230\u6700\u7ec8\u7684\u5355\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\uff08.exe\uff09\u6216\u52a8\u6001\u94fe\u63a5\u5e93\uff08.dll\uff09\uff0cLLD \u8fd8\u53ef\u4ee5\u5f00\u542f\u94fe\u63a5\u65f6\u4f18\u5316\uff0c\u8fd9\u53c8\u4f1a\u7528\u5230 BOLT \u8fd9\u4e2a\u94fe\u63a5\u65f6\u4f18\u5316\u5668\uff0c\u5bf9\u751f\u6210\u7684\u5355\u4e2a\u4e8c\u8fdb\u5236\u505a\u8fdb\u4e00\u6b65\u6c47\u7f16\u7ea7\u522b\u7684\u4f18\u5316\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8457\u540d\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\u4e4b\u4e00\uff0clibc++\uff0c\u4e5f\u662f LLVM \u9879\u76ee\u7684\u4e00\u90e8\u5206\uff0c\u76f8\u6bd4 GCC \u5bb6\u65cf\u7684 libstdc++ \u66f4\u7b80\u5355\uff0c\u66f4\u9002\u5408\u5b66\u4e60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5e76\u884c\u7684 STL \u5b9e\u73b0 pstl\uff0cOpenCL \u7f16\u8bd1\u5668 libclc \u7b49\u2026\u2026\u5e94\u6709\u5c3d\u6709\uff0c\u662f\u7f16\u8bd1\u5668\u5f00\u53d1\u8005\u7684\u5929\u5802\u3002 Clang \u7f16\u8bd1 C++ \u7a0b\u5e8f\u7684\u6574\u4e2a\u8fc7\u7a0b\uff1a Clang \u524d\u7aef\u89e3\u6790 C++ \u8bed\u6cd5 -> LLVM \u4e2d\u7aef\u4f18\u5316 -> LLVM \u540e\u7aef\u751f\u6210\u6307\u4ee4\u7801 -> LLD \u94fe\u63a5 -> BOLT \u94fe\u63a5\u540e\u4f18\u5316 \u800c GCC \u5c31\u6ca1\u6709\u8fd9\u4e48\u6a21\u5757\u5316\u4e86\uff0c\u867d\u7136 GCC \u5185\u90e8\u540c\u6837\u662f\u6709\u524d\u7aef\u548c\u4e2d\u7aef IR\uff0c\u4f46\u662f\u6574\u4e2a\u5c31\u662f\u7cca\u5728\u4e00\u4e2a GCC \u53ef\u6267\u884c\u6587\u4ef6\u91cc\uff0c\u96be\u4ee5\u91cd\u6784\uff0c\u79ef\u91cd\u96be\u53cd\uff0c\u4e5f\u96be\u4ee5\u8de8\u5e73\u53f0\uff08MinGW \u8fd8\u662f\u6c11\u95f4\u81ea\u5df1\u79fb\u690d\u8fc7\u53bb\u7684\uff0c\u5e76\u975e GCC \u5b98\u65b9\u9879\u76ee\uff09\u3002\u548c Clang \u80fd\u8f7b\u6613\u4f5c\u4e3a libclang \u548c libLLVM \u5e93\u53d1\u5e03\u76f8\u6bd4\uff0c\u9ad8\u4e0b\u7acb\u5224\u3002MSVC \u66f4\u662f\u4e0d\u5fc5\u591a\u8bf4\uff0c\u8fde\u6e90\u7801\u90fd\u4e0d\u5f00\u653e\uff0c\u8ba9\u4eba\u600e\u4e48\u5b66\u4e60\u548c\u9b54\u6539\u554a\uff1f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u8981\u5b66\u4e60 LLVM\uff0c\u80af\u5b9a\u4e0d\u80fd\u7eb8\u4e0a\u8c08\u5175\u3002LLVM \u662f\u5f00\u6e90\u8f6f\u4ef6\uff0c\u6700\u597d\u662f\u81ea\u5df1\u4e0b\u8f7d\u4e00\u4e2a LLVM \u5168\u5bb6\u6876\u6e90\u7801\uff0c\u7136\u540e\u81ea\u5df1\u4ece\u6e90\u7801\u6784\u5efa\u3002 \u6ce8\u610f\uff1a\u6211\u4eec\u6700\u597d\u662f\u4ece\u6e90\u7801\u6784\u5efa LLVM \u548c Clang\uff0c\u65b9\u4fbf\u6211\u4eec\u52a8\u624b\u4fee\u6539\u5176\u6e90\u7801\uff0c\u6dfb\u52a0\u6a21\u5757\uff0c\u67e5\u770b\u6548\u679c\u3002\u4e0b\u8f7d\u4e8c\u8fdb\u5236\u53d1\u5e03\u7248 LLVM \u6216 Clang \u7684\u8bdd\uff0c\u867d\u7136\u540c\u6837\u53ef\u4ee5\u4f7f\u7528\u6240\u6709\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5c31\u53ea\u80fd\u5bf9\u7740 IR \u4e00\u901a\u5206\u6790\u76f2\u731c\u4e86\u3002 \u6e90\u7801\u9762\u524d\uff0c\u4e86\u65e0\u79d8\u5bc6\u3002 \u867d\u7136 LLVM \u51e0\u4e4e\u662f\u65e0\u4f9d\u8d56\u7684\uff0c\u53ea\u9700\u8981 CMake \u548c\u7f16\u8bd1\u5668\u5c31\u80fd\u6784\u5efa\uff0c\u4f46\u4f9d\u7136\u63a8\u8350\u4f7f\u7528 Linux \u7cfb\u7edf\u8fdb\u884c\u5b9e\u9a8c\uff0c\u4ee5\u83b7\u5f97\u548c\u5c0f\u5f6d\u8001\u5e08\u540c\u6837\u7684\u5f00\u53d1\u4f53\u9a8c\u3002Windows \u7528\u6237\u5efa\u8bae\u4f7f\u7528 Visual Studio \u6216 CLion \u7b49\u5f3a\u5927 IDE \u5e2e\u52a9\u9605\u8bfb\u7406\u89e3\u6e90\u7801\uff1bLinux \u7528\u6237\u5efa\u8bae\u5b89\u88c5 \u5c0f\u5f6d\u8001\u5e08 vimrc \uff1b\u6216\u8005\u5982\u679c\u4f60\u662f\u8fdc\u7a0b Linux\uff0c\u53ef\u4ee5\u8bd5\u8bd5\u770b VSCode \u7684\u8fdc\u7a0b SSH \u8fde\u63a5\u63d2\u4ef6\uff1bCLion \u4f3c\u4e4e\u4e5f\u6709\u8fdc\u7a0b\u63d2\u4ef6\uff0c\u53ea\u4e0d\u8fc7\u9700\u8981\u5728\u8fdc\u7a0b\u5b89\u88c5\u597d\u5ba2\u6237\u7aef\u3002 \u5f3a\u5927\u7684 IDE \u548c\u7f16\u8f91\u5668\u5bf9\u5b66\u4e60\u4efb\u4f55\u5927\u578b\u9879\u76ee\u90fd\u662f\u5fc5\u4e0d\u53ef\u5c11\u7684\uff0c\u7279\u522b\u662f\u8df3\u8f6c\u5230\u5b9a\u4e49\uff0c\u4ee5\u53ca\u8fd4\u56de\u8fd9\u4e24\u4e2a\u64cd\u4f5c\uff0c\u662f\u4f7f\u7528\u9891\u7387\u6700\u9ad8\u7684\uff0c\u5728\u6e90\u7801\u4e4b\u95f4\u7684\u5feb\u901f\u8df3\u8f6c\u5c06\u5927\u5927\u6709\u52a9\u4e8e\u5feb\u901f\u7406\u89e3\u548c\u638c\u63e1\u4ee3\u7801\u7ed3\u6784\u3002 \u5982\u679c\u5b9e\u5728\u6ca1\u6709\u6761\u4ef6\u81ea\u5df1\u6784\u5efa LLVM \u6e90\u7801\uff0c\u6216\u8005 IDE \u6bd4\u8f83\u62c9\u80ef\uff1a\u53ef\u4ee5\u53bb LLVM \u7684\u5728\u7ebf\u6e90\u7801\u7ea7\u6587\u6863\uff08\u4f7f\u7528 Doxygen \u751f\u6210\uff09\u770b\u770b\u3002\u5176\u4e0d\u4ec5\u63d0\u4f9b\u4e86 LLVM \u4e2d\u6240\u6709\u7c7b\u548c\u51fd\u6570\u7684\u8be6\u5c3d\u6587\u6863\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u7528\u6cd5\u8bf4\u660e\u7b49\uff1b\u8fd8\u63d0\u4f9b\u4e86\u6bcf\u4e2a\u51fd\u6570\u7684\u6240\u5728\u6587\u4ef6\u548c\u884c\u53f7\u4fe1\u606f\uff0c\u70b9\u51fb\u7c7b\u578b\u6216\u51fd\u6570\u540d\u7684\u8d85\u94fe\u63a5\uff0c\u5c31\u53ef\u4ee5\u5728\u6e90\u7801\u548c\u6587\u6863\u4e4b\u95f4\u6765\u56de\u8df3\u8f6c\u3002\u8fd8\u80fd\u770b\u5230\u54ea\u91cc\u5f15\u7528\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u8fd8\u80fd\u663e\u793a\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb\u56fe\uff0c\u975e\u5e38\u9002\u5408\u4e0a\u73ed\u8def\u4e0a\u6ca1\u6cd5\u6253\u5f00\u7535\u8111\u65f6\u5077\u5b66 LLVM \u6e90\u7801\u7528\u3002\u4f8b\u5982\uff0c llvm::VectorType \u8fd9\u4e2a\u7c7b\u7684\u6587\u6863\uff1ahttps://llvm.org/doxygen/classllvm_1_1VectorType.html \u4e00\u70b9\u5fe0\u544a \u5bf9\u4e8e LLVM \u8fd9\u79cd\u5927\u578b\u9879\u76ee\uff0c\u7531\u4e8e\u4f60\u662f\u521d\u5b66\u8005\uff0c\u52a1\u5fc5\u505a\u5230\u201c\u4e0d\u6c42\u751a\u89e3\u201d\uff01 \u4f60\u5fc5\u7136\u4e00\u65f6\u534a\u4f1a\u4e0d\u80fd\u5b8c\u5168\u770b\u61c2\u6bcf\u4e2a\u7ec6\u8282\uff0c\u5343\u4e07\u4e0d\u8981\u6b7b\u6263\u7ec6\u8282\uff0c\u4e00\u4e2a\u7ec6\u8282\u4e0d\u7406\u89e3\u5c31\u786c\u77aa\u773c\u5e72\u770b\uff01 \u770b\u4e0d\u61c2\u7684\u5148\u8df3\u8fc7\u53bb\u5373\u53ef\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\u3002\u7535\u89c6\u8fde\u7eed\u5267\u8df3\u4e00\u4e24\u96c6\uff0c\u751a\u81f3\u4ece\u4e2d\u95f4\u5f00\u59cb\u770b\uff0c\u90fd\u80fd\u770b\u61c2\u5462\uff01\u6ca1\u6709\u90a3\u4e48\u4e25\u683c\u7684\u987a\u5e8f\u4f9d\u8d56\u3002 \u4ee5\u540e\u77e5\u8bc6\u50a8\u5907\u591f\u4e86\uff0c\u6216\u8005\u5de5\u4f5c\u4e2d\u9700\u8981\u7528\u5230\u4e86\uff0c\u518d\u56de\u8fc7\u5934\u6765\u67e5\u6f0f\u8865\u7f3a\u4e5f\u4e0d\u8fdf\u3002 \u6211\u6700\u6015\u67d0\u4e9b\u540c\u5b66\u76ef\u7740\u67d0\u4e2a\u6b21\u8981\u7684\u7ec6\u8282\u6b7b\u52b2\u60f3\uff0c\u60f3\u4e0d\u51fa\u5c31\u6b62\u6b65\u4e0d\u524d\u4e86\u3002\u6bd4\u5982\u4ed6\u9047\u5230\u4e00\u4e2a\u8001\u5916\u8bf4\uff1a My dick is bleeding, could you tell me where is the toilet? \u800c \u2018dick\u2019 \u662f\u8fd9\u4e2a\u540c\u5b66\u770b\u4e0d\u61c2\u7684\u201c\u751f\u8bcd\u201d\uff0c\u4ed6\u5c31\u6b7b\u6263\u8fd9\u4e2a\u5b57\u773c\uff0c\u8ba4\u4e3a\u770b\u4e0d\u61c2\u8fd9\u4e2a\u8bcd\uff0c\u540e\u9762\u7684\u5bf9\u8bdd\u4e5f\u4f1a\u770b\u4e0d\u61c2\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u9700\u8981\u628a\u8fd9\u4e2a\u770b\u4e0d\u61c2\u7684\u5730\u65b9\u8df3\u8fc7\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\uff0c\u5c31\u5f53\u4ed6\u662f\u4e00\u4e2a\u4e71\u7801\u585e\u5728\u90a3\u91cc\u5e72\u6270\u4f60\u9605\u8bfb\u7684\uff0c\u4f60\u53ea\u7ba1\u7ee7\u7eed\u770b\u4e0b\u53bb\uff1a My \ufffd\ufffd\ufffd is \ufffd\ufffd\ufffd\ufffd\ufffd, could you tell me where is the toilet? \u4e00\u6837\u80fd\u770b\u61c2\u8001\u5916\u60f3\u8981\u95ee\u7684\u662f\u5395\u6240\uff08toilet\uff09\uff0c\u6839\u672c\u4e0d\u9700\u8981\u77e5\u9053\u524d\u9762\u7684 \u2018dick\u2019 \u662f\u4ec0\u4e48\u610f\u601d\u3002 \u81f4\u6d82\u9ed1\u4e16\u754c\u7684\u4e66\u4fe1 LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 LLVM\uff08\u548c Clang\uff09\u7684\u6784\u5efa\u4f9d\u8d56\u9879\u51e0\u4e4e\u6ca1\u6709\uff0c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\uff0c\u975e\u5e38\u7684\u73b0\u4ee3\u3002 Linux/MacOS \u7528\u6237 \u9996\u5148\u5b89\u88c5 Git\u3001CMake\u3001Ninja\u3001GCC\uff08\u6216 Clang\uff09\u3002 \u5176\u4e2d Ninja \u53ef\u4ee5\u4e0d\u5b89\u88c5\uff0c\u53ea\u662f\u56e0\u4e3a Ninja \u6784\u5efa\u901f\u5ea6\u6bd4 Make \u5feb\uff0c\u7279\u522b\u662f\u5f53\u6587\u4ef6\u975e\u5e38\u591a\uff0c\u800c\u4f60\u6539\u52a8\u975e\u5e38\u5c11\u65f6\u3002\u800c\u4e14 Ninja \u9ed8\u8ba4\u5c31\u5f00\u542f\u591a\u6838\u5e76\u884c\u6784\u5efa\uff0c\u6240\u4ee5\u5927\u578b\u9879\u76ee\u901a\u5e38\u4f1a\u5c3d\u91cf\u7ed9 cmake \u6307\u5b9a\u4e00\u4e0b -G Ninja \u9009\u9879\uff0c\u8ba9\u5176\u4f7f\u7528\u66f4\u9ad8\u6548\u7684 Ninja \u540e\u7aef\u6784\u5efa\u3002 Arch Linux: sudo pacman -S git cmake ninja gcc Ubuntu: sudo apt-get install git cmake ninja-build g++ MacOS: brew install git cmake ninja gcc \u5f00\u59cb\u514b\u9686\u9879\u76ee\uff08\u9700\u8981\u65f6\u95f4\uff09\uff1a git clone https://github.com/llvm/llvm-project \u5982\u679c\u4f60\u7684 GitHub \u7f51\u901f\u8f83\u6162\uff0c\u53ef\u4ee5\u6539\u7528 Gitee \u56fd\u5185\u955c\u50cf\uff08\u53ea\u4e0d\u8fc7\u8fd9\u6837\u4f60\u5c31\u6ca1\u6cd5\u7ed9 LLVM \u5b98\u65b9\u6c34 PR \u4e86 \ud83e\udd23\uff09\uff1a git clone https://gitee.com/mirrors/LLVM Windows \u7528\u6237 \u5373\u4f7f\u662f LLVM \u8fd9\u6837\u6beb\u65e0\u4f9d\u8d56\u9879\u7684\u9879\u76ee\uff0c\u201c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\u201d\uff0c\u5728 Windows \u7528\u6237\u770b\u6765\u4f9d\u7136\u975e\u5e38\u79d1\u5e7b\u3002 \u597d\u5728\u5fae\u8f6f\u4e5f\u610f\u8bc6\u5230\u4e86\u81ea\u5df1\u7684\u6b8b\u5e9f\uff0c\u73b0\u5728 Virtual Studio 2022 \u5df2\u7ecf\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff08\u81ea\u5e26 Git\u3001CMake \u548c Ninja \u4e86\uff09\u3002 \u5982\u679c\u4f60\u662f\u7528 VS2022 \u81ea\u5e26\u7684 Git \u514b\u9686 llvm-project\uff0c\u8bb0\u5f97 cd \u5230 llvm \u6587\u4ef6\u5939\u91cc\u518d\u7528 cmake\uff0c\u7136\u800c\u8d35\u7269 IDE \u7684\u4e00\u4e2a cd \u90fd\u662f\u5982\u6b64\u7684\u56f0\u96be\u3002 \u6240\u4ee5\u8fd9\u8fb9\u5efa\u8bae\u4f60\u76f4\u63a5\u5148\u628a llvm-project \u4ed3\u5e93\u4f5c\u4e3a ZIP \u4e0b\u8f7d\u4e0b\u6765\uff0c\u7136\u540e\u6253\u5f00\u5176\u4e2d\u7684 llvm \u5b50\u6587\u4ef6\u5939\uff0c\u7136\u540e\u7528 VS2022 \u6253\u5f00\u5176\u4e2d\u7684 CMakeLists.txt\uff0c\u7136\u540e\u5f00\u59cb\u6784\u5efa\u3002 \u7136\u540e\uff0c\u8981\u5f00\u542f\u4e00\u4e2a CMake \u9009\u9879 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \uff0c\u624d\u80fd\u6784\u5efa Clang \u5b50\u9879\u76ee\uff08\u5426\u5219\u6784\u5efa\u7684\u662f\u8d64\u818a LLVM\uff0c\u6ca1\u6709\u4efb\u4f55\u524d\u7aef\uff0c\u8fd9\u6beb\u65e0\u610f\u4e49\uff09\u3002\u4ec5\u6b64\u662f\u6307\u5b9a\u8fd9\u4e00\u4e2a\u5c0f\u5c0f\u9009\u9879\u5bf9\u4e8e IDE \u53d7\u5bb3\u8005\u53c8\u662f\u4f55\u7b49\u7684\u56f0\u96be\u2026\u2026\u4ed6\u4eec\u9700\u8981\u5728 VS2022 \u4e2d\u6253\u5f00 CMakeSettings.json\uff0c\u4fee\u6539 x64-Debug \u7684\u914d\u7f6e\uff0c\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\uff0c\u503c\u4e3a \u201cclang;clang-tools-extra\u201d\u2026\u2026\u5982\u679c\u4ed6\u4eec\u8981\u6539\u6210 Release \u914d\u7f6e\uff0c\u53c8\u8981\u70b9\u51fb\u52a0\u53f7\u521b\u5efa x64-Release\uff08\u5343\u4e07\u522b\u70b9\u9519\u6210 x86-Release\uff01\uff09\uff0c\u7136\u540e\u518d\u6b21\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\u2026\u2026 \u56e0\u4e3a llvm-project \u662f\u8bb8\u591a\u9879\u76ee\u7684\u96c6\u5408\uff0c\u6839\u76ee\u5f55\u91cc\u5e76\u6ca1\u6709 CMakeLists.txt\uff0c\u800c VS2022 \u4f3c\u4e4e\u53ea\u80fd\u8bc6\u522b\u6839\u76ee\u5f55\u7684 CMakeLists.txt\u2026\u2026 \u6b63\u5e38\u7cfb\u7edf\u53ea\u9700\u8981\u7ed9\u4f60\u5199\u4e00\u4e32\u547d\u4ee4\uff0c\u4f60\u53ea\u7ba1\u590d\u5236\u7c98\u8d34\u5230 Shell \u91cc\u4e00\u6267\u884c\u5c31\u641e\u5b9a\u4e86\u3002\u8111\u762b\u7cfb\u7edf\u9700\u8981\u5927\u91cf\u65e0\u8c13\u7684\u6587\u5b57\u63cf\u8ff0\u548c\u622a\u56fe\u7bad\u5934\u6307\u793a\u534a\u5929\uff0c\u8fd8\u7ecf\u5e38\u6709\u4eba\u770b\u4e0d\u61c2\uff0c\u8981\u53cd\u590d\u5f3a\u8c03\uff0c\u753b\u7bad\u5934\uff0c\u52a0\u7c97\u5b57\u4f53\uff0c\u624d\u80fd\u64cd\u63a7\u4ed6\u7684\u9f20\u6807\u70b9\u51fb\u5230\u6b63\u786e\u6309\u94ae\u4e0a\u3002\u6211\u4e5f\u60f3\u628a\u9f20\u6807\u5b8f\u5f55\u4e0b\u6765\uff0c\u53ef\u662f\u4e0d\u540c\u7535\u8111\u5206\u8fa8\u7387\u4e0d\u540c\uff0c\u7a97\u53e3\u4f4d\u7f6e\u53c8\u5f88\u968f\u673a\uff0c\u7535\u8111\u54cd\u5e94\u901f\u5ea6\u53c8\u968f\u673a\uff0c\u6709\u65f6\u5019 C \u76d8\uff0c\u6709\u65f6\u5019\u53c8 D \u76d8\uff0c\u6839\u672c\u4e0d\u7ed9\u4e00\u4e2a\u7edf\u4e00\u7684\u64cd\u4f5c\u65b9\u5f0f,\u7edf\u4e00\u7684\u547d\u4ee4\u884c\u5c31\u6ca1\u6709\u8fd9\u79cd\u70e6\u607c\u3002\u6240\u4ee5\uff0c\u80fd\u5378\u8f7d\u7684\u5378\u8f7d\uff0c\u80fd\u53cc\u7cfb\u7edf\u7684\u53cc\u7cfb\u7edf\uff0c\u80fd WSL \u4e5f\u603b\u6bd4\u8171\u9798\u7c89\u788e\u5668\uff08\u9f20\u6807\uff09\u597d\uff0c\u81f3\u5c11\u80fd\u4e00\u952e\u7c98\u8d34\u5c0f\u5f6d\u8001\u5e08\u540c\u6b3e\u64cd\u4f5c\u3002 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 $ cd llvm-project $ ls bolt CONTRIBUTING.md LICENSE.TXT pstl build cross-project-tests lld pyproject.toml build.sh flang lldb README.md clang libc llvm runtimes clang-tools-extra libclc llvm-libgcc SECURITY.md cmake libcxx mlir third-party CODE_OF_CONDUCT.md libcxxabi openmp utils compiler-rt libunwind polly \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u7684\u5b50\u9879\u76ee\uff0c\u5176\u4e2d\u6211\u4eec\u4e3b\u8981\u5b66\u4e60\u7684\u5c31\u662f\u8fd9\u91cc\u9762\u7684 llvm \u6587\u4ef6\u5939\uff0c\u4ed6\u662f LLVM \u7684\u672c\u4f53\u3002\u5176\u4e2d\u4e0d\u4ec5\u5305\u542b LLVM \u5e93\uff0c\u4e5f\u5305\u542b\u4e00\u4e9b\u5904\u7406 LLVM IR \u548c\u5b57\u8282\u7801\u7684\u5b9e\u7528\u5de5\u5177\uff08\u4f8b\u5982 llvm-as\uff09\u3002 \u5176\u6b21\u5c31\u662f clang \u6587\u4ef6\u5939\uff0c\u8fd9\u4e2a\u5b50\u9879\u76ee\u5c31\u662f\u5927\u540d\u9f0e\u9f0e\u7684 Clang \u7f16\u8bd1\u5668\uff0c\u4ed6\u4e5f\u662f\u57fa\u4e8e LLVM \u672c\u4f53\u5b9e\u73b0\u7684\uff0c\u672c\u8eab\u53ea\u662f\u4e2a\u524d\u7aef\uff0c\u5e76\u4e0d\u505a\u4f18\u5316\u548c\u540e\u7aef\u6c47\u7f16\u751f\u6210\u3002 clang-tools-extra \u8fd9\u4e2a\u5b50\u9879\u76ee\u662f clangd\u3001clang-tidy\u3001clang-format \u7b49 C/C++ \u4ee3\u7801\u8d28\u91cf\u5de5\u5177\uff0c\u53ef\u4ee5\u9009\u62e9\u4e0d\u6784\u5efa\u3002 libc \u662f Clang \u5b98\u914d\u7684 C \u6807\u51c6\u5e93\uff0c\u800c libcxx \u662f Clang \u5b98\u914d\u7684 C++ \u6807\u51c6\u5e93\uff0c\u60f3\u5b66\u6807\u51c6\u5e93\u6e90\u7801\u7684\u540c\u5b66\u53ef\u4ee5\u770b\u770b\u3002 flang \u662f LLVM \u7684 Fortran \u524d\u7aef\uff0c\u7f16\u7a0b\u754c\u7684\u6d3b\u5316\u77f3\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 lldb \u662f LLVM \u5b98\u65b9\u7684\u8c03\u8bd5\u5668\uff0c\u5bf9\u6807 GCC \u7684 gdb \u8c03\u8bd5\u5668\uff0cVSCode \u4e2d\u7684\u8c03\u8bd5\u9ed8\u8ba4\u5c31\u662f\u57fa\u4e8e lldb \u7684\u3002 lld \u662f LLVM \u5b98\u65b9\u7684\u4e8c\u8fdb\u5236\u94fe\u63a5\u5668\uff0c\u5bf9\u6807 GCC \u7684 ld \u548c ld.gold\uff1b\u800c bolt \u662f\u94fe\u63a5\u540e\u4f18\u5316\u5668\uff0c\u7528\u7684\u4e0d\u591a\u3002 compiler-rt \u662f\u8bf8\u5982 AddressSantizer\uff08\u5185\u5b58\u6ea2\u51fa\u68c0\u6d4b\u5de5\u5177\uff09\u3001MSAN\uff08\u5185\u5b58\u6cc4\u6f0f\u68c0\u6d4b\uff09\u3001TSAN\uff08\u7ebf\u7a0b\u5b89\u5168\u68c0\u6d4b\uff09\u3001UBSAN\uff08\u672a\u5b9a\u4e49\u884c\u4e3a\u68c0\u6d4b\uff09\u7b49\u5de5\u5177\u7684\u5b9e\u73b0\u3002 mlir \u662f LLVM \u5bf9 MLIR \u7684\u7f16\u8bd1\u5668\u5b9e\u73b0\uff08\u4e00\u79cd\u4e3a\u673a\u5668\u5b66\u4e60\u5b9a\u5236\uff0c\u5141\u8bb8\u7528\u6237\u81ea\u5b9a\u4e49\u65b0\u7684 IR \u8282\u70b9\uff0c\u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\u7b49\u9ad8\u9636\u64cd\u4f5c\uff0c\u65b9\u4fbf\u7279\u5b9a\u786c\u4ef6\u8bc6\u522b\u5230\u5e76\u4f18\u5316\u6210\u81ea\u7814\u786c\u4ef6\u4e13\u95e8\u7684\u77e9\u9635\u4e58\u6cd5\u6307\u4ee4\uff0c\u6700\u8fd1\u4f3c\u4e4e\u5728 AI \u5b5d\u5b50\u4e2d\u5f88\u6d41\u884c\uff09\u3002 libclc \u662f LLVM \u5bf9 OpenCL \u7684\u5b9e\u73b0\uff08OpenCL \u8bed\u8a00\u89c4\u8303\u7684\u7f16\u8bd1\u5668\uff09\uff0cOpenCL \u662f\u5b64\u513f\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 openmp \u662f LLVM \u5bf9 OpenMP \u7684\u5b9e\u73b0\uff08\u4e00\u79cd\u7528\u4e8e\u50bb\u74dc\u5f0f CPU \u5355\u673a\u5e76\u884c\u7684\u6846\u67b6\uff0c\u7528\u6cd5\u5f62\u5982 #pragma omp parallel for \uff09\u3002 pstl \u662f LLVM \u5bf9 C++17 Parallel STL \u7684\u5b9e\u73b0\uff08\u540c\u6837\u662f\u5355\u673a CPU \u5e76\u884c\uff0c\u4f18\u52bf\u5728\u4e8e\u5229\u7528\u4e86 C++ \u8bed\u6cd5\u7cd6\uff0c\u4e5f\u6bd4\u8f83\u5b64\u513f\uff0c\u7528\u7684\u4e0d\u591a\uff09\u3002 cmake \u6587\u4ef6\u5939\u5e76\u4e0d\u662f\u5b50\u9879\u76ee\uff0c\u800c\u662f\u88c5\u7740\u548c LLVM \u76f8\u5173\u7684\u4e00\u4e9b CMake \u811a\u672c\u6587\u4ef6\u3002 build \u6587\u4ef6\u5939\u662f\u4f7f\u7528\u8fc7 CMake \u540e\u4f1a\u624d\u751f\u6210\u7684\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u662f cmake -B build \u547d\u4ee4\u751f\u6210\u7684\u3002\u5176\u4e2d\u5b58\u50a8\u7740\u6784\u5efa\u9879\u76ee\u8fc7\u7a0b\u4e2d\u4ea7\u751f\u7684\u4e34\u65f6\u5bf9\u8c61\u6587\u4ef6\u548c\u6700\u7ec8\u7684\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u6240\u6709\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u653e\u5728 build/bin \u5b50\u6587\u4ef6\u5939\u4e2d\uff0c\u4f8b\u5982 build/bin/llvm-as\u3002\u5982\u679c CMake \u51fa\u73b0\u4e0d\u542c\u4f7f\u5524\u7684\u95ee\u9898\uff0c\u53ef\u4ee5\u5220\u9664 build \u6587\u4ef6\u5939\u8bd5\u8bd5\uff0c\u8fd9\u4f1a\u8feb\u4f7f CMake \u91cd\u65b0\u751f\u6210\uff08\u5efa\u8bae\u6bcf\u6b21\u4fee\u6539\u8fc7 CMake \u9009\u9879\u540e\u90fd\u5220 build\uff09\u3002 \u5f00\u59cb\u6784\u5efa cd llvm-project bash build.sh build.sh \u811a\u672c\u7684\u5185\u5bb9\u7b49\u4ef7\u4e8e\uff1a cmake -Sllvm -Bbuild -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" -GNinja ninja -Cbuild \u4f60\u5728\u547d\u4ee4\u884c\u624b\u52a8\u8f93\u5165\u8fd9\u4e24\u6761\u547d\u4ee4\u4e5f\u662f\u7b49\u4ef7\u7684\uff0c build.sh \u53ea\u662f\u4e3a\u4e86\u65b9\u4fbf\u3002 \u6b64\u5904 -S llvm \u9009\u9879\u8868\u793a\u6307\u5b9a\u6e90\u7801\u8def\u5f84\u4e3a\u6839\u76ee\u5f55\u4e0b\u7684 llvm \u5b50\u9879\u76ee\u6587\u4ef6\u5939\uff0c\u548c cd llvm && cmake -B build \u7b49\u4ef7\uff0c\u4f46\u662f\u4e0d\u7528\u5207\u6362\u76ee\u5f55\u3002 -G Ninja \u8868\u793a\u4f7f\u7528 Ninja \u540e\u7aef\uff0c\u5982\u679c\u4f60\u6ca1\u6709 Ninja\uff0c\u53ef\u4ee5\u53bb\u6389\u8be5\u9009\u9879\uff0cCMake \u5c06\u4f1a\u91c7\u7528\u9ed8\u8ba4\u7684 Makefile \u540e\u7aef\uff08\u66f4\u6162\uff09\u3002 \u5982\u679c\u4f60\u662f Wendous \u53d7\u5bb3\u8005\uff0c\u8bf7\u81ea\u884c\u7528\u9f20\u6807\u70b9\u51fb\u5e8f\u5217\u5728 VS2022 \u4e2d\u6a21\u62df\u4ee5\u4e0a\u4ee3\u7801\u4e4b\u540c\u7b49\u6548\u679c\uff0c\u795d\u60a8\u8171\u9798\u6109\u5feb\uff01 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \u8868\u793a\u542f\u7528 clang \u548c clang-tools-extra \u4e24\u4e2a\u5b50\u9879\u76ee\u3002 \u8fd9\u662f\u56e0\u4e3a\u901a\u5e38\u7528\u7684\u524d\u7aef\u90fd\u662f C++\uff0c\u6240\u4ee5 LLVM \u5b98\u65b9\u5728 build.sh \u91cc\u5c31\u8fd9\u4e48\u5199\u4e86\u3002 \u5982\u679c\u4f60\u53e3\u5473\u6bd4\u8f83\u91cd\uff0c\u60f3\u7814\u7a76 Fortran \u524d\u7aef\uff0c\u4e5f\u53ef\u4ee5\u5b9a\u4e49\u8be5 CMake \u53d8\u91cf\u4e3a -DLLVM_ENABLE_PROJECTS=\"flang\" \u3002 build.sh \u540e\uff0c\u9700\u8981\u82b1\u8d39\u5927\u7ea6 10 \u5206\u949f\u65f6\u95f4\uff08\u53d6\u51b3\u4e8e\u4f60\u7684\u7535\u8111\u914d\u7f6e\uff09\uff0c\u8fd9\u6bb5\u65f6\u95f4\u4f60\u53ef\u4ee5\u5148\u770b\u4e0b\u9762\u7684\u57fa\u672c\u6982\u5ff5\u901f\u89c8\u3002\u7b49\u98ce\u6247\u505c\u4e86\u4ee5\u540e\uff0cLLVM \u548c Clang \u5c31\u6784\u5efa\u597d\u4e86\u3002 \u8fd0\u884c\u8bd5\u8bd5 ls build/bin \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u53ea\u662f\u8ba9\u4f60\u83b7\u5f97\u4e00\u4e2a\u5168\u5c40\u89c2\u5ff5\uff08overview\uff09\uff0c\u4e0d\u7528\u6df1\u7a76\u7ec6\u8282\uff0c\u4e4b\u540e\u4f1a\u518d\u8be6\u7ec6\u5c55\u5f00\u4ecb\u7ecd\u7684\u3002 \u5b66\u8fc7 C \u8bed\u8a00\u7684\u540c\u5b66\u90fd\u77e5\u9053\uff0c\u4e00\u4e2a C/C++ \u6e90\u7801\u6587\u4ef6\u5230\u8ba1\u7b97\u673a\u5b9e\u9645\u53ef\u6267\u884c\u7684 EXE \u6587\u4ef6\u4e4b\u95f4\uff0c\u4e3b\u8981\u6709\u4e24\u6b65\u64cd\u4f5c\uff1a\u7f16\u8bd1\uff08compile\uff09\u548c\u94fe\u63a5\uff08link\uff09\u3002 \u4e4b\u6240\u4ee5\u628a\u7f16\u8bd1\u548c\u94fe\u63a5\u5206\u5f00\uff0c\u662f\u56e0\u4e3a\u4e00\u4e2a\u9879\u76ee\u5e38\u5e38\u7531\u8bb8\u591a\u6e90\u7801\u6587\u4ef6\u7ec4\u6210\uff0c\u800c\u4e0d\u53ea\u662f\u5355\u4e2a\u6587\u4ef6\u3002\u7f16\u8bd1\u5668\u628a C++ \u6e90\u7801\u7f16\u8bd1\u6210\u4e2d\u95f4\u5bf9\u8c61\u6587\u4ef6\uff08.o \u6216 .obj \u683c\u5f0f\uff09\uff0c\u5982\u679c\u6709\u5f88\u591a .cpp \u6587\u4ef6\uff0c\u5c31\u4f1a\u5f97\u5230\u5f88\u591a .o \u6587\u4ef6\uff0c\u7136\u540e\u7531\u94fe\u63a5\u5668\u8d1f\u8d23\u7edf\u4e00\u94fe\u63a5\u6240\u6709 .o \u6587\u4ef6\uff0c\u5c31\u5f97\u5230\u4e86\u6700\u7ec8\u7684 .exe \u6216 .dll \u76ee\u6807\u6587\u4ef6\u3002 \u5206\u79bb\u591a .cpp \u6587\u4ef6\u7684\u597d\u5904\u662f\uff0c\u7f16\u8bd1\u901f\u5ea6\u66f4\u5feb\uff0c\u53ef\u4ee5\u5e76\u884c\u7f16\u8bd1\u3002\u800c\u4e14\u4fee\u6539\u4e86\u5176\u4e2d\u4e00\u4e2a .cpp \u6587\u4ef6\uff0c\u53ea\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u90a3\u4e2a .cpp \u5bf9\u5e94\u7684 .o \u6587\u4ef6\uff0c\u7136\u540e\u91cd\u65b0\u94fe\u63a5\u6700\u7ec8\u7684 .exe \u5373\u53ef\uff0c\u65e0\u9700\u518d\u91cd\u590d\u7f16\u8bd1\u5176\u4ed6 .cpp \u6587\u4ef6\u7684 .o \u6587\u4ef6\u4e86\u3002\u81ea\u52a8\u68c0\u6d4b\u54ea\u4e9b .cpp \u6587\u4ef6\u66f4\u65b0\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u7f16\u8bd1 .o \u6587\u4ef6\uff0c\u662f Makefile \u548c Ninja \u4e4b\u7c7b\u6784\u5efa\u7cfb\u7edf\u7684\u804c\u8d23\u3002 \u6211\u4eec\u73b0\u5728\u8981\u6765\u5b66\u4e60\u7684\u5c31\u662f\u5176\u4e2d\u7684\u7f16\u8bd1\u9636\u6bb5\uff0c\u8fd9\u4e5f\u662f\u5927\u90e8\u5206\u4eba\u60f3\u5173\u6ce8\u7684\u91cd\u70b9\u3002 \u5728\u8fd9\u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\uff0c\u53d1\u751f\u4e86\u5f88\u591a\u6709\u8da3\u7684\u4e8b\uff0c\u4f46\u5374\u88ab\u4f20\u7edf\u6559\u6750\u7684 C++ \u201c\u4e24\u6bb5\u5f0f\u201d\u7f16\u8bd1\u6a21\u578b\uff08\u7f16\u8bd1 -> \u94fe\u63a5\uff09\u4e00\u7b14\u5e26\u8fc7\u4e86\u3002 \u5c31\u62ff\u8fd9\u91cc\u9762\u7684\u201c\u7f16\u8bd1\u201d\u9636\u6bb5\u5c55\u5f00\u8bb2\u8bb2\uff0c\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5c06 .cpp \u6587\u4ef6\u8f6c\u6362\u4e3a\u5145\u65a5\u7740\u673a\u5668\u6307\u4ee4\u7801 .o \u6587\u4ef6\u7684\uff1f .o \u6587\u4ef6\u91cc\u51e0\u4e4e\u5168\u662f\u5b8c\u6210\u7684\u673a\u5668\u6307\u4ee4\u7801\uff0c\u9664\u4e86\u90e8\u5206 call \u5230\u5916\u90e8\u51fd\u6570\u7684\u4e00\u90e8\u5206\u6307\u4ee4\uff0c\u4f1a\u7559\u767d\u3002\u8fd9\u90e8\u5206\u7559\u767d\u4f1a\u7b49\u5230\u94fe\u63a5\u9636\u6bb5\u65f6\uff0c\u7531\u94fe\u63a5\u5668\u5728\u5176\u4ed6 .o \u6587\u4ef6\u4e2d\u627e\u5230\u76f8\u540c\u7684\u7b26\u53f7\u65f6\u66ff\u6362\u4e0a\u6b63\u786e\u7684\u5730\u5740\u548c\u504f\u79fb\u91cf\uff0c\u5f97\u5230\u5b8c\u6574\u7684\u53ef\u6267\u884c .exe \u6587\u4ef6\u3002 \u8fc7\u53bb\uff0c\u6211\u4eec\u628a\u7f16\u8bd1\u5668\u770b\u4f5c\u9ed1\u7bb1\uff0c\u8fdb\u53bb\u6e90\u7801\uff0c\u51fa\u6765\u673a\u5668\u7801\uff0c\u4e2d\u95f4\u6709\u54ea\u4e9b\u8fc7\u7a0b\uff1f\u53ea\u80fd\u8ba4\u4e3a\u662f\u9b54\u6cd5\u3002 \u73b0\u5728\uff0c\u6709\u4e86 LLVM \u548c Clang \u6e90\u7801\u5728\u624b\uff0c\u7ec8\u4e8e\u53ef\u4ee5\u4e00\u63a2\u7a76\u7adf\u4e86\u3002 \u5b9e\u9645\u4e0a\uff0c\u201c\u7f16\u8bd1\u201d\u8fd9\u4e00\u8fc7\u7a0b\uff0c\u8fd8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u62c6\u5206\u6210\u4e09\u4e2a\u9636\u6bb5\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u7f16\u8bd1\u5668\uff08Compiler\uff09\u7684\u5de5\u4f5c\u6d41\u7a0b\u53ef\u4ee5\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\uff1a \u524d\u7aef\uff08Front-end\uff09\uff1a\u8d1f\u8d23\u63a5\u6536\u6e90\u4ee3\u7801\uff0c\u89e3\u6790\u51fa\u62bd\u8c61\u8bed\u6cd5\u6811\uff08AST\uff09\uff0c\u5e76\u8fdb\u884c\u8bed\u6cd5\u548c\u8bed\u4e49\u5206\u6790\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\u3002 \u4e2d\u7aef\uff08Middle-end\uff09\uff1a\u8d1f\u8d23\u4f18\u5316\u4e2d\u95f4\u8868\u793a\u7801\u3002 \u540e\u7aef\uff08Back-end\uff09\uff1a\u8d1f\u8d23\u5c06\u4f18\u5316\u5b8c\u6bd5\u7684\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u4e2d\u540e\u7aef\u548c\u4e92\u8054\u7f51\u5f00\u53d1\u8005\u6240\u8bf4\u7684\u524d\u540e\u7aef\u65e0\u5173\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u662f\u524d\u7aef\u9ad8\u624b\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u96c7\u4f63\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u8ba8\u538c JS\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u4f60\u4e0d\u662f\u524d\u7aef\u9ad8\u624b\u5417\uff1f\u5c0f\u5f6d\u8001\u5e08\uff1a\u7f16\u8bd1\u5668\u524d\u7aef\u3002 \u5982\u679c\u4f60\u60f3\u8981\u7814\u7a76 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u6bd4\u5982\u505a\u4e2a C++ \u8bed\u6cd5\u9ad8\u4eae\u63d2\u4ef6\uff0c\u90a3\u5c31\u9700\u8981\u770b\u524d\u7aef\u3002libclang \u548c clangd \u53ef\u4ee5\u5e2e\u52a9\u4f60\u89e3\u6790 C++ \u7e41\u7410\u7684\u8bed\u6cd5\uff0c\u5e76\u4ee5 AST \u6811\u7684\u7ed3\u6784\u63d0\u4f9b\u7ed9\u4f60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u5982\u679c\u4f60\u8981\u8bbe\u8ba1\u4e00\u95e8\u65b0\u8bed\u8a00\uff0c\u751a\u81f3\u662f OpenGL \u9a71\u52a8\uff08\u5176\u9700\u8981\u5b9e\u73b0 GLSL \u7f16\u8bd1\u5668\uff09\uff0c\u5b9e\u9645\u4e0a\u4e5f\u5c31\u662f\u4e3a LLVM \u6dfb\u52a0\u4e00\u4e2a\u524d\u7aef\u3002 \u5982\u679c\u4f60\u5bf9\u5185\u5b58\u6a21\u578b\uff0c\u6027\u80fd\u4f18\u5316\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u7814\u7a76\u4e2d\u7aef\u3002\u8fd9\u662f\u76ee\u524d\u5b66\u672f\u7814\u7a76\u6bd4\u8f83\u6d3b\u8dc3\u7684\u9886\u57df\uff0c\u7279\u522b\u662f\u591a\u9762\u4f53\u4f18\u5316\u65b9\u5411\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6c34\u4e24\u5f20 paper \u6216 PR\u3002\u8fd9\u90e8\u5206\u90fd\u662f\u57fa\u4e8e LLVM IR \u64cd\u4f5c\u7684\uff0c\u6709\u7279\u522b\u591a\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u3002 \u5982\u679c\u4f60\u5bf9\u6c47\u7f16\u8bed\u8a00\uff0c\u673a\u5668\u6307\u4ee4\uff0c\u786c\u4ef6\u67b6\u6784\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u770b\u540e\u7aef\u3002\u8fd9\u91cc\u9762\u6709\u628a\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u771f\u6b63\u53ef\u6267\u884c\u7684\u6c47\u7f16\u6307\u4ee4\u7684\u5b8c\u6574\u8fc7\u7a0b\uff0c\u81ea\u7814\u82af\u7247\u7684\u5927\u5382\u901a\u5e38\u60f3\u8981\u4e3a LLVM \u6dfb\u52a0\u540e\u7aef\u3002 \u6ce8\u610f\u94fe\u63a5\u9636\u6bb5\uff08Link\uff09\u5c5e\u4e8e\u94fe\u63a5\u5668\u7684\u804c\u8d23\uff0c\u4e0d\u5c5e\u4e8e\u72ed\u4e49\u4e0a\u7684\u7f16\u8bd1\u5668\uff1b\u524d\u4e2d\u540e\u7aef\u53ea\u662f\u5bf9\u7f16\u8bd1\uff08Compile\uff09\u8fd9\u4e00\u9636\u6bb5\u7684\u8fdb\u4e00\u6b65\u62c6\u5206\u3002 \u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u8d70\u8fdb LLVM \u8fd9\u5ea7\u5f00\u6e90\u5de5\u5382\uff0c\u4e00\u6b65\u6b65\u89c2\u5bdf\u4e00\u6bb5 C++ \u4ee3\u7801\u88ab\u7f16\u8bd1\u6210\u6c47\u7f16\u7684\u5168\u8fc7\u7a0b\u3002 \u8bed\u6cd5\u6811\uff08AST\uff09 \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u8d1f\u8d23\u89e3\u6790 C++ \u8fd9\u7c7b\u9ad8\u7ea7\u8bed\u8a00\u7684\u6e90\u4ee3\u7801\uff0c\u751f\u6210\u62bd\u8c61\u8bed\u6cd5\u6811\uff08Abstract Syntax Tree\uff0cAST\uff09\u3002AST \u662f\u6e90\u4ee3\u7801\u7684\u4e00\u79cd\u62bd\u8c61\u8868\u793a\uff0c\u5176\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u6e90\u4ee3\u7801\u4e2d\u7684\u4e00\u4e2a\u8bed\u6cd5\u7ed3\u6784\uff0c\u4f8b\u5982 if\u3001while\u3001for\u3001\u51fd\u6570\u8c03\u7528\u3001\u8fd0\u7b97\u7b26\u3001\u53d8\u91cf\u58f0\u660e\u7b49\u3002\u6bcf\u4e2a AST \u8282\u70b9\u90fd\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982\u7c7b\u578b\u3001\u4f5c\u7528\u57df\u3001\u4fee\u9970\u7b26\u7b49\u3002 \u4e0d\u540c\u7c7b\u578b\u7684 AST \u8282\u70b9\u6709\u4e0d\u540c\u7684\u7c7b\u578b\u540d\uff0c\u4f8b\u5982 IntegerLiterial \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6574\u6570\u7c7b\u578b\u7684\u5e38\u91cf\uff0c\u800c BinaryOperator \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u4e8c\u5143\u8fd0\u7b97\u7b26\uff08\u53ef\u80fd\u662f\u52a0\u51cf\u4e58\u9664\u7b49\u4e8c\u5143\u8fd0\u7b97\uff09\u3002 AST \u8282\u70b9\u53ef\u4ee5\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u8282\u70b9\uff0c\u8bb8\u591a\u8282\u70b9\u5c31\u6784\u6210\u4e86\u4e00\u9897\u8bed\u6cd5\u6811\u3002\u6bcf\u4e2a .cpp \u6587\u4ef6\u90fd\u53ef\u4ee5\u89e3\u6790\u5f97\u5230\u4e00\u9897\u8bed\u6cd5\u6811\uff0c\u5728 C++ \u7684\u8bed\u6cd5\u4e2d\uff0c\u6bcf\u9897\u6811\u7684\u6839\u90e8\u603b\u662f\u4e00\u4e2a TranslationUnitDecl \u7c7b\u578b\u7684\u8282\u70b9\u3002\u8fd9\u662f\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\uff0c\u5176\u4e2d\u5305\u542b\u4e86\u4efb\u610f\u591a\u7684\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u7b49\uff0c\u4f5c\u4e3a TU \u7684\u5b50\u8282\u70b9\u5b58\u5728\u5176\u4e2d\u3002 \u5bf9\u6811\u505a\u4e86\u4e00\u4e9b\u8bed\u6cd5\u8bed\u4e49\u4e0a\u7684\u6b63\u786e\u6027\u68c0\u6d4b\u540e\uff0c\u5c31\u4f1a\u904d\u5386\u8fd9\u9897\u6811\uff0c\u4e3a\u6bcf\u4e2a\u8282\u70b9\u9010\u4e00\u751f\u6210\u5bf9\u5e94\u7684 LLVM IR\uff0c\u8f93\u5165\u5230\u4e2d\u540e\u7aef\u4f18\u5316\u5e76\u751f\u6210\u771f\u6b63\u7684\u6c47\u7f16\u3002 // Clang \u6e90\u7801\u4e2d\u7684 AST \u8282\u70b9\u7c7b\u578b\u5927\u81f4\u957f\u8fd9\u6837\uff08\u5df2\u7b80\u5316\uff09 struct ASTNode { std::string type; std::vector children; }; \u8fd9\u90e8\u5206\u7684\u5b9e\u73b0\u5728 clang \u5b50\u9879\u76ee\u4e2d\u3002 clang \u89e3\u6790\u6e90\u7801\u751f\u6210\u8bed\u6cd5\u6811\u7684\u6848\u4f8b\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u8fd0\u884c\u547d\u4ee4\uff1a clang -fsyntax-only -Xclang -ast-dump test.cpp -fsyntax-only \u610f\u5473\u7740\u53ea\u89e3\u6790\u8bed\u6cd5\uff0c\u4e0d\u8fdb\u884c\u7f16\u8bd1\u548c\u94fe\u63a5\uff08\u4e0d\u4f1a\u751f\u6210 a.out\uff09\uff1b -Xclang \u662f\u6307\u5411 Clang \u6838\u5fc3\u4f20\u9012\u4e00\u4e2a\u9009\u9879\uff0c\u4e5f\u5c31\u662f\u540e\u9762\u7d27\u6328\u7740\u7684 -ast-dump \uff1b -ast-dump \u662f Clang \u6838\u5fc3\u7684\u9009\u9879\uff0c\u8868\u793a\u8981\u6c42\u6253\u5370\u51fa\u8bed\u6cd5\u6811\u3002 \u8f93\u51fa\uff1a \u5df2\u7701\u7565 \u5934\u6587\u4ef6\u90e8\u5206\u7684\u5b50\u8282\u70b9\uff0c\u4ec5\u5c55\u793a\u4e86 main \u7684\u90e8\u5206\uff0c\u5426\u5219\u5c31\u592a\u957f\u4e86\u3002 \u6700\u6839\u90e8\u7684 TranslationUnitDecl \u8282\u70b9\uff0c\u662f\u6574\u4e2a\u5f53\u524d\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\u3002 \u6240\u6709\u7684 C++ \u6e90\u7801\u89e3\u6790\u540e\u5f97\u5230\u7684\uff0c\u603b\u662f\u4ee5 TranslationUnitDecl \u4e3a\u6839\u8282\u70b9\u7684\u4e00\u9897\u8bed\u6cd5\u6811\u3002 \u7ffb\u8bd1\u5355\u5143 \u6307\u7684\u5c31\u662f\u5355\u4e2a .cpp \u6587\u4ef6\uff0c\u53ca\u5176\u5bfc\u5165\u7684\u6240\u6709 .h \u5934\u6587\u4ef6\u62fc\u63a5\u5f62\u6210\u7684\u6574\u6bb5 C++ \u6e90\u7801\uff0c\u662f C++ \u7f16\u8bd1\u7684\u6700\u5c0f\u5355\u5143\u3002\u4e0d\u540c\u7ffb\u8bd1\u5355\u5143\u7f16\u8bd1\u6210\u5404\u81ea\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u540e\uff0c\u4e4b\u95f4\u518d\u901a\u8fc7\u201c\u94fe\u63a5\u5668\u201d\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e00\u4e2a\u6700\u7ec8\u7684\u76ee\u6807\u6587\u4ef6\uff08.exe \u6216 .dll\uff09\u3002 \u7ffb\u8bd1\u5355\u5143\u4e2d\u5305\u542b\u4e86\u6240\u6709\u5f53\u524d .cpp \u53ca\u5176\u5bfc\u5165\u7684\u5934\u6587\u4ef6\u4e2d\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\u8282\u70b9\u6709\u7740\u8bb8\u591a\u5b50\u8282\u70b9\uff0c\u4e00\u5927\u5806\u90fd\u662f \u5934\u6587\u4ef6\u4e2d\u5bfc\u5165\u8fdb\u6765\u7684\u51fd\u6570\u58f0\u660e\u548c\u7c7b\u578b\u5b9a\u4e49\u3002 \u4e3a\u4e86\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u6211\u7279\u610f\u4ece\u622a\u56fe\u4e2d\u6263\u6389\u4e86\u6240\u6709\u6765\u81ea \u7684\u8282\u70b9\uff0c\u5e76\u4e0d\u662f\u8bf4\u7ffb\u8bd1\u5355\u5143\u4e0d\u5305\u62ec\u5934\u6587\u4ef6\u54e6\uff01 \u6211\u4eec\u6700\u5173\u5fc3\u7684\u662f\u5176\u4e2d\u4e00\u4e2a\u5b50\u8282\u70b9\uff1a\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u8282\u70b9\uff0c\u7c7b\u578b\u4e3a FunctionDecl\u3002 \u6b64\u5904 FunctionDecl \u5c31\u8868\u660e\uff0c\u8be5\u8282\u70b9\u662f\u4e00\u4e2a\u51fd\u6570\uff08Function\uff09\u7684\u58f0\u660e\uff08Decleration\uff09\u3002\u6ce8\u610f\u5230\u540e\u9762\u8ddf\u7740\u8bb8\u591a\u548c\u8be5\u51fd\u6570\u5b9a\u4e49\u6709\u5173\u7684\u5173\u952e\u4fe1\u606f\uff0c\u8ba9\u6211\u4eec\u9010\u4e00\u5206\u6790\uff1a \u8fd9\u91cc\u7684\u5341\u516d\u8fdb\u5236\u6570 0x567bdbf246d8 \u662f AST \u8282\u70b9\u5728\u7f16\u8bd1\u5668\u5185\u5b58\u4e2d\u7684\u5730\u5740\uff0c\u6bcf\u6b21\u90fd\u4e0d\u4e00\u6837\uff0c\u65e0\u610f\u4e49\u3002 \u540e\u9762\u7684\u5c16\u62ec\u53f7 \u91cc\u8fd8\u597d\u5fc3\u63d0\u9192\u4e86\u51fd\u6570\u5b9a\u4e49\u7684\u4f4d\u7f6e\u3002 \u6700\u540e\u662f\u51fd\u6570\u540d main \u548c\u51fd\u6570\u7c7b\u578b int () \uff0c\u8bf4\u660e\u8fd9\u662f\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u3002 \u6709\u8da3\u7684\u662f\uff0c\u8be5\u8282\u70b9\u7684\u7c7b\u578b\u662f FunctionDecl\uff0c\u7ffb\u8bd1\u6210\u4e2d\u6587\u5c31\u662f\u51fd\u6570\u58f0\u660e\u3002\u4f46\u662f\u6211\u4eec\u5199\u7684\u660e\u660e\u662f\u4e00\u4e2a\u51fd\u6570\u7684 \u5b9a\u4e49 \u554a\uff01\u4e3a\u4ec0\u4e48\u88ab Clang AST \u5f53\u4f5c\u4e86 \u58f0\u660e \u5462\uff1f\u539f\u6765\uff0cC++ \u5b98\u65b9\u7684\u8bdd\u8bed\u4e2d\uff0c\u5b9a\u4e49\u4e5f\u662f\u58f0\u660e\uff01\u4f46\u58f0\u660e\u4e0d\u90fd\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u8fd9\u91cc\u7684 FunctionDecl \u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u901a\u7528\u7684\u8282\u70b9\uff0c\u65e2\u53ef\u4ee5\u662f\u58f0\u660e\uff08\u540e\u9762\u76f4\u63a5\u63a5 ; \u7684\uff09\uff0c\u4e5f\u53ef\u4ee5\u662f\u5b9a\u4e49\uff08\u540e\u9762\u63a5\u7740 {} \u7684\uff09\uff0c\u8981\u6839\u636e\u662f\u5426\u6709\u5b50\u8282\u70b9\uff08\u82b1\u62ec\u53f7\u8bed\u53e5\u5757\uff09\u6765\u5224\u65ad\u3002 \u603b\u4e4b\uff0c\u5b9a\u4e49\u548c\u58f0\u660e\u662f\u5b50\u96c6\u5173\u7cfb\u3002\u5f53\u6211\u4eec\u8981\u5f3a\u8c03\u4e00\u4e2a\u58f0\u660e\u53ea\u662f\u58f0\u660e\uff0c\u6ca1\u6709\u5b9a\u4e49\u65f6\uff0c\u4f1a\u7528 \u975e\u5b9a\u4e49\u58f0\u660e \u8fd9\u6837\u4e25\u8c28\u7684\u5f8b\u5e08\u8bf4\u6cd5\u3002\u4f46\u65e5\u5e38\u63d0\u95ee\u65f6\u4f60\u8bf4\u201c\u58f0\u660e\u201d\u6211\u4e5f\u660e\u767d\uff0c\u4f60\u6307\u7684\u5e94\u8be5\u662f\u975e\u5b9a\u4e49\u58f0\u660e\u3002\u66f4\u591a\u76f8\u5173\u6982\u5ff5\u8bf7\u770b \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49 \u7ae0\u8282\u548c \u767d\u5f8b\u5e08\u7684\u9510\u8bc4 \uff0c\u7528\u6587\u6c0f\u56fe\u6765\u753b\u5c31\u662f\uff1a \u51fd\u6570\u5b9a\u4e49\u8282\u70b9\u53c8\u5177\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f CompoundStmt\u3002\u8fd9\u4e2a\u5b9e\u9645\u4e0a\u5c31\u662f\u6211\u4eec\u6240\u8bf4\u7684\u82b1\u62ec\u53f7\u8bed\u53e5\u5757 {} \u4e86\u3002\u4ed6\u672c\u8eab\u4e5f\u662f\u4e00\u6761\u8bed\u53e5\uff0c\u4f46\u91cc\u9762\u7531\u5f88\u591a\u6761\u5b50\u8bed\u53e5\u7ec4\u6210\u3002\u89c4\u5b9a\u51fd\u6570\u58f0\u660e FunctionDecl \u5982\u679c\u662f\u5b9a\u4e49\uff0c\u5219\u5176\u552f\u4e00\u5b50\u8282\u70b9\u5fc5\u987b\u662f\u8bed\u53e5\u5757\u7c7b\u578b CompoundStmt\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u719f\u6089\u7684\u51fd\u6570\u58f0\u660e\u540e\u7d27\u63a5\u7740\u82b1\u62ec\u53f7\uff0c\u5c31\u80fd\u5b9a\u4e49\u51fd\u6570\u3002\u5982\u679c\u662f\u975e\u5b9a\u4e49\u58f0\u660e\uff08\u4ec5\u58f0\u660e\uff0c\u4e0d\u5b9a\u4e49\uff09\u90a3\u5c31\u6ca1\u6709\u8fd9\u4e2a\u5b50\u8282\u70b9\u3002 \u63a5\u4e0b\u6765\u53ef\u4ee5\u770b\u5230 CompountStmt \u5185\u90e8\uff0c\u53c8\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1aCallExpr \u548c ReturnStmt\uff0c\u5206\u522b\u662f\u6211\u4eec\u5bf9 printf \u51fd\u6570\u7684\u8c03\u7528\uff0c\u548c return 0 \u8fd9\u4e24\u6761\u5b50\u8bed\u53e5\u3002 ReturnStmt \u5f88\u597d\u7406\u89e3\uff0c\u4ed6\u53ea\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f IntegerLiterial\uff0c\u8868\u793a\u4e00\u4e2a\u6574\u5f62\u5e38\u6570\uff0c\u6574\u6570\u7684\u7c7b\u578b\u662f int\uff0c\u503c\u662f 0\u3002\u8fd9\u79cd\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\u7684 ReturnStmt \u8282\u70b9\uff0c\u5c31\u8868\u793a\u4e00\u4e2a\u6709\u8fd4\u56de\u503c\u7684 return \u8bed\u53e5\uff0c\u6574\u4f53\u6765\u770b\u4e5f\u5c31\u662f\u6211\u4eec\u4ee3\u7801\u91cc\u5199\u7684 return 0 \u3002 \u4e3e\u4e00\u53cd\u4e09\uff0c\u53ef\u4ee5\u60f3\u8c61\uff1a\u5982\u679c\u4ee3\u7801\u91cc\u5199\u7684\u662f return x + 1 \uff0c\u90a3\u4e48 ReturnStmt \u7684\u5b50\u8282\u70b9\u5c31\u4f1a\u53d8\u6210\u8fd0\u7b97\u7b26\u4e3a + \u7684 BinaryOperator\u3002\u5176\u53c8\u5177\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1a\u5de6\u4fa7\u662f DeclRefExpr \u8282\u70b9\uff0c\u6807\u8bc6\u7b26\u4e3a x \uff1b\u53f3\u4fa7\u662f IntegerLiterial \u8282\u70b9\uff0c\u503c\u4e3a 1\u3002 \u7136\u540e\u6211\u4eec\u6765\u770b printf \u51fd\u6570\u8c03\u7528\u8fd9\u6761\u8bed\u53e5\uff1a \u53ef\u4ee5\u770b\u5230\u662f\u4e00\u4e2a CallExpr\uff0c\u8868\u793a\u8fd9\u662f\u51fd\u6570\u8c03\u7528\uff0c\u800c\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\u9700\u8981\u77e5\u9053\u4e24\u4e2a\u4fe1\u606f\uff1a \u8c03\u7528\u54ea\u4e2a\u51fd\u6570\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f printf \u51fd\u6570\u3002 \u4f20\u9012\u7ed9\u51fd\u6570\u7684\u5b9e\u53c2\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f \"Hello, world!\" \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u3002 \u8fd9\u5c31\u5206\u522b\u7528\u4e24\u4e2a\u5b50\u8282\u70b9\u8868\u793a\u4e86\u3002 \u6ce8\u610f\u5230\u8fd9\u91cc printf \u53d1\u751f\u4e86\u4e00\u4e2a\u9690\u5f0f\u8f6c\u6362 ImplicitCastExpr \u540e\u624d\u4f5c\u4e3a CallExpr \u7684\u7b2c\u4e00\u4e2a\u5b50\u8282\u70b9\uff08\u56de\u7b54\u4e86\u8c03\u7528\u54ea\u4e2a\u51fd\u6570\u7684\u95ee\u9898\uff09\uff0c\u5e76\u4e14\u540e\u9762\u6ce8\u91ca\u4e86\u8bf4 FunctionToPointerDecay \u3002\u4e5f\u5c31\u662f\u8bf4\uff0c printf \u8fd9\u4e2a\u6807\u8bc6\u7b26\uff08DeclRefExpr\uff09\u672c\u6765\u662f\u4e00\u4e2a\u5bf9\u51fd\u6570\u6807\u8bc6\u7b26\u7684\u5f15\u7528\uff0c\u8fd8\u6ca1\u6709\u53d8\u6210\u51fd\u6570\u6307\u9488\uff0c\u8fd9\u65f6\u5019\u8fd8\u6ca1\u6709\u5b8c\u6210\u51fd\u6570\u7684\u91cd\u8f7d\u51b3\u8bae\u3002\u662f\u7b49\u5230\u51fd\u6570\u88ab () \u8c03\u7528\u65f6\uff0c\u624d\u4f1a\u89e6\u53d1\u91cd\u8f7d\u51b3\u8bae\uff0c\u800c\u5b9e\u73b0\u533a\u5206\u91cd\u8f7d\u7684\u65b9\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\u5f15\u7528\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u6210\u51fd\u6570\u6307\u9488\u7684\u8fc7\u7a0b\u6240\u89e6\u53d1\u7684\uff0c\u4e5f\u5c31\u662f\u8fd9\u91cc\u7684 ImplicitCastExpr \u9690\u5f0f\u8f6c\u6362\u8282\u70b9\u4e86\u3002\u8fd9\u79cd\u81ea\u52a8\u53d1\u751f\u7684\u9690\u5f0f\u8f6c\u6362\u88ab\u79f0\u4e3a\u201c\u9000\u5316\u201d\uff08decay\uff09\u3002\u6240\u4ee5\uff0c\u51fd\u6570\u5f15\u7528\u65e0\u6cd5\u76f4\u63a5\u8c03\u7528\uff0cClang \u91cc\u4e00\u76f4\u90fd\u662f\u9700\u8981\u9000\u5316\u6210\u6307\u9488\u624d\u8c03\u7528\u7684\u3002 \u7136\u540e\uff0c\u8fd9\u91cc\u7684\u51fd\u6570\u53c2\u6570\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6309\u7406\u8bf4\u4e00\u4e2a StringLiterial \u8282\u70b9\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u6709\u4e2a ImplicitCastExpr\uff1f\u8fd9\u91cc\u6709\u4e2a\u5e38\u89c1\u8bef\u533a\u9700\u8981\u7ea0\u6b63\uff1a\u5f88\u591a\u540c\u5b66\u5e38\u5e38\u60f3\u5f53\u7136\u4ee5\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char * \u3002\u5b9e\u9645\u4e0a\uff0c\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char [] \uff0c\u662f\u4e00\u4e2a\u6570\u7ec4\u7c7b\u578b\uff01\u6570\u7ec4\u4e0d\u662f\u6307\u9488\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u5b8c\u5168\u4e0d\u540c\u7684\u7c7b\u578b\u3002\u4e4b\u6240\u4ee5\u4f60\u4f1a\u6709\u6570\u7ec4\u662f\u6307\u9488\u7684\u9519\u89c9\uff0c\u662f\u56e0\u4e3a\u6570\u7ec4\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a\u5143\u7d20\u7c7b\u578b\u7684\u6307\u9488\u3002\u800c\u8fd9\u662f\u201c\u9000\u5316\u201d\u89c4\u5219\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u51fd\u6570\u53c2\u6570\u3001auto \u63a8\u5bfc\u7684\u65f6\u5019\u662f\u81ea\u52a8\u53d1\u751f\u7684\uff08\u6b63\u5982\u4e0a\u9762\u8bf4\u7684\u51fd\u6570\u5f15\u7528\u4f1a\u5728\u8c03\u7528\u65f6\u81ea\u52a8\u201c\u9000\u5316\u201d\u6210\u51fd\u6570\u6307\u9488\u4e00\u6837\uff09\u3002 \u6570\u7ec4\u80fd\u81ea\u52a8\u9000\u5316\u6210\u6307\u9488\uff0c\u4e0d\u4ee3\u8868\u6570\u7ec4\u5c31\u662f\u6307\u9488\u3002\u4f8b\u5982 int \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a double\uff0c\u96be\u9053\u5c31\u53ef\u4ee5\u8bf4\u201cint \u5c31\u662f double\u201d\u5417\uff1f\u540c\u6837\u5730\uff0c\u4e0d\u80fd\u8bf4\u201c\u6570\u7ec4\u5c31\u662f\u6307\u9488\u201d\u3002\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\uff0c\u4ece\u6765\u90fd\u662f const char [N] \uff0c\u5176\u4e2d N \u662f\u5b57\u7b26\u4e32\u4e2d\u5b57\u7b26\u7684\u4e2a\u6570\uff08\u5305\u62ec\u672b\u5c3e\u81ea\u52a8\u52a0\u4e0a\u7684 '\\0' \u7ed3\u675f\u7b26\uff09\u3002\u53ea\u4e0d\u8fc7\u662f\u5728\u4f20\u5165\u51fd\u6570\u53c2\u6570\uff08\u6b64\u5904\u662f printf \u51fd\u6570\u7684\u5b57\u7b26\u4e32\u53c2\u6570\uff09\u65f6\uff0c\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u4e3a const char * \u4e86\u800c\u5df2\u3002\u6b63\u5982\u8fd9\u4e2a ImplicitCastExpr \u540e\u9762\u5c16\u62ec\u53f7\u7684\u63d0\u793a\u4e2d\u6240\u8bf4\uff0cArrayToPointerDecay\uff0c\u662f\u6570\u7ec4\u7c7b\u578b\u5230\u6307\u9488\u7c7b\u578b\u7684\u81ea\u52a8\u9000\u5316\uff0c\u4ece const char [14] \u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u5230\u4e86 const char * \u3002 #include int main() { printf(\"Hello, world!\"); // \u7b49\u4ef7\u4e8e static_cast(printf) ( static_cast(\"Hello, world!\") ); return 0; } \u603b\u4e4b\uff0c\u901a\u8fc7\u89c2\u5bdf Clang AST \u6811\uff0c\u53ef\u4ee5\u83b7\u5f97\u5f88\u591a\u9690\u85cf\u7684\u4fe1\u606f\uff0c\u7279\u522b\u662f C++ \u7684\u5404\u79cd\u9690\u85cf\u8bed\u6cd5\u89c4\u5219\uff0c\u53ef\u4ee5\u5e2e\u4f60\u89e3\u6784\u8bed\u6cd5\u7cd6\u3002 Clang \u89e3\u6790\u51fa AST \u6811\u540e\uff0c\u4f1a\u518d\u6b21\u904d\u5386\u8be5\u6811\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\uff0c\u8f93\u5165 LLVM \u540e\u7aef\u7f16\u8bd1\uff0c\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff08 -S \uff09\u6216\u4e8c\u8fdb\u5236\u6307\u4ee4\u7801\uff08 -c \uff09\u3002 \u5982\u679c\u6307\u5b9a\u4e86 -emit-llvm \u9009\u9879\uff0c\u5219\u4e0d\u4f1a\u8f93\u5165 LLVM \u540e\u7aef\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6307\u4ee4\u7801\uff0c\u800c\u662f\u76f4\u63a5\u628a\u4ea7\u751f\u7684 IR \u4ee5 IR \u6c47\u7f16\uff08 -S -emit-llvm \uff09\u6216 IR \u5b57\u8282\u7801\uff08 -c -emit-llvm \uff09\u7684\u683c\u5f0f\u5bfc\u51fa\uff0c\u65b9\u4fbf\u6211\u4eec\u5206\u6790\u548c\u67e5\u770b\u3002 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 \u4e2d\u95f4\u8868\u793a\u7801\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u673a\u5668\u6307\u4ee4\uff0c\u5b83\u4e0d\u9488\u5bf9\u5177\u4f53\u7684\u786c\u4ef6\uff0c\u800c\u662f\u4e00\u79cd\u901a\u7528\u7684\u6307\u4ee4\u96c6\u3002\u5b83\u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u8fbe\uff0c\u53ef\u4ee5\u88ab\u8fdb\u4e00\u6b65\u7f16\u8bd1\u4e3a\u76ee\u6807\u4ee3\u7801\u3002 LLVM IR\uff08Intermediate Representation\uff09\u662f\u4e00\u79cd\u4e2d\u95f4\u8bed\u8a00\u8868\u793a\uff0c\u4f5c\u4e3a\u7f16\u8bd1\u5668\u524d\u7aef\u548c\u540e\u7aef\u7684\u5206\u6c34\u5cad\u3002LLVM \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u2014\u2014Clang \u8d1f\u8d23\u4ea7\u751f IR\uff0c\u800c\u5176 LLVM \u540e\u7aef\u8d1f\u8d23\u6d88\u8d39 IR\u3002 C++ \u6e90\u7801 -> IR -> \u76ee\u6807\u5e73\u53f0\u6c47\u7f16 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 IR \u5e76\u4e0d\u662f LLVM \u7684\u4e13\u5229\uff0c\u6240\u6709\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u90fd\u4f7f\u7528 IR\uff0c\u5305\u62ec GCC \u548c MSVC\u3002\u4e5f\u6709\u5f88\u591a\u72ec\u7acb\u4e8e\u7f16\u8bd1\u5668\u7684\u8de8\u5e73\u53f0 IR \u89c4\u8303\uff0c\u4f8b\u5982 SPIR-V\u3001MLIR\u3001MIR\uff0cLLVM IR \u53ea\u662f\u4f17\u591a IR \u4e2d\u7684\u4e00\u79cd\uff0c\u4e13\u7528\u4e8e LLVM \u7f16\u8bd1\u5668\u5168\u5bb6\u6876\u3002\u7531\u4e8e\u672c\u8bfe\u7a0b\u662f LLVM \u8bfe\u7a0b\uff0c\u4ee5\u540e\u63d0\u5230 IR\uff0c\u8bfb\u8005\u5e94\u9ed8\u8ba4\u6307\u7684\u662f LLVM IR\u3002 LLVM IR \u6709\u591a\u79cd\u8868\u73b0\u5f62\u5f0f\uff1a \u5185\u5b58\u4e2d\u7684 IR \u8282\u70b9\u5bf9\u8c61\uff0c\u4f4d\u4e8e clang \u548c libLLVM.so \u8fdb\u7a0b\u7684\u5185\u5b58\u4e2d\uff0c\u90fd\u662f\u4e00\u4e2a\u4e2a C++ \u7c7b\uff0c\u901a\u8fc7\u6307\u9488\u4e92\u76f8\u8fde\u63a5\u3002LLVM \u4f5c\u4e3a\u4e00\u4e2a C++ \u7a0b\u5e8f\uff0c\u5904\u7406 IR \u65f6\u90fd\u662f\u8981\u8bfb\u5230\u5185\u5b58\u4e2d\u5904\u7406\u7684\u3002\u4f46\u7531\u4e8e\u5185\u5b58\u4e2d\u7684 IR \u5bf9\u8c61\u5b58\u5728\u865a\u8868\u6307\u9488\u4ee5\u53ca\u590d\u6742\u7684\u6811\u72b6\u6570\u636e\u7ed3\u6784\uff0c\u65e0\u6cd5\u76f4\u63a5\u5b58\u5165\u78c1\u76d8\uff0c\u4e5f\u65e0\u6cd5\u4f9b\u4eba\u7c7b\u9605\u8bfb\uff0c\u9700\u8981\u5e8f\u5217\u5316\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u683c\u5f0f\u540e\u5b58\u50a8\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u6c47\u7f16\uff08Assembly\uff09\uff0c\u4ee5\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c\u5f62\u5f0f\uff08\u7eaf ASCII \u5b57\u7b26\uff09\u5b58\u50a8\u5728\u78c1\u76d8\u4e2d\uff0c\u65b9\u4fbf\u4eba\u7c7b\u89c2\u5bdf\u3001\u4fee\u6539\u548c\u8c03\u8bd5\u3002\u6211\u4eec\u540e\u9762\u7684\u8bfe\u7a0b\uff0c\u4e5f\u4f1a\u7ecf\u5e38\u89c2\u5bdf\u4e2d\u95f4\u4ea7\u7269\u7684 IR \u6c47\u7f16\uff0c\u5206\u6790 LLVM \u7684\u884c\u4e3a\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u5b58\u50a8\u7684 IR\uff0c\u672c\u8d28\u4e0a\u548c IR \u6c47\u7f16\u76f8\u540c\uff0c\u53ea\u662f\u4ee5\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u5b57\u8282\u5b58\u50a8\u3002\u7f3a\u70b9\u662f\u4eba\u7c7b\u770b\u4e0d\u61c2\uff0c\u4f18\u70b9\u662f\u8282\u7ea6\u78c1\u76d8\u7a7a\u95f4\uff0c\u65b9\u4fbf\u7a0b\u5e8f\u5feb\u901f\u89e3\u6790\u3002 \u5f53\u9700\u8981\u957f\u671f\u50a8\u5b58 IR \u7684\u4e2d\u95f4\u7ed3\u679c\u65f6\u4f1a\u7528\u5230 IR \u5b57\u8282\u7801\uff0c\u5f53\u9700\u8981\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\u4e2d\u95f4\u7ed3\u679c\u65f6\u5c31\u9700\u8981 IR \u6c47\u7f16\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 \u6ce8\u610f IR \u6c47\u7f16\u5e76\u4e0d\u662f\u771f\u6b63\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u8bed\u8a00\uff08Assembly\uff09\uff0c\u4ed6\u53ea\u662f\u4e00\u79cd\u4e2d\u95f4\u4ea7\u7269\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16\uff0c\u6b63\u5982 IR \u5b57\u8282\u7801\u4e0d\u662f x86 \u7684\u673a\u5668\u7801\u4e00\u6837\u3002IR \u7684\u4e1c\u897f\u90fd\u662f LLVM \u5f00\u53d1\u8005\u81ea\u62df\u7684\u4e00\u5957\u683c\u5f0f\uff0c\u548c\u786c\u4ef6\u65e0\u5173\uff0c\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u65e0\u5173\u3002\u4e0d\u8bba\u76ee\u6807\u5e73\u53f0\u662f\u4ec0\u4e48\uff0c\u6765\u81ea\u4ec0\u4e48\u6e90\u7801\u8bed\u8a00\uff0cLLVM IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u683c\u5f0f\u90fd\u662f\u4e00\u6837\u7684\u3002 \u4f46\u4e0d\u540c\u5e73\u53f0\u7684 IR \u4f1a\u9644\u52a0\u4e0d\u540c\u7684 intrinsics \u6307\u4ee4\uff0c\u9664\u6b64\u4e4b\u5916\u7684\u90e8\u5206\u90fd\u662f\u5171\u901a\u7684\u3002\u7531\u4e8e\u5f88\u591a\u7a0b\u5e8f\u4f1a\u5229\u7528\u76ee\u6807\u786c\u4ef6\u505a\u5224\u65ad\uff08\u4f8b\u5982 #ifdef __x86_64__ \uff09\uff0c\u751f\u6210\u4e0d\u540c\u7684 intrinsics\uff0c\u56e0\u6b64 IR \u5e76\u4e0d\u662f\u5b8c\u5168\u8de8\u5e73\u53f0\u7684\u3002 IR \u7684\u76ee\u7684\u662f\u628a\u5927\u90e8\u5206\u901a\u7528\u7684\u8ba1\u7b97\uff0c\u4f8b\u5982\u52a0\u51cf\u4e58\u9664\u3001\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u7edf\u4e00\u6210\u76f8\u540c\u7684 IR \u6c47\u7f16\u3002\u800c\u4e0d\u662f x86 \u6c47\u7f16\u91cc\u53eb call \uff0cARM \u6c47\u7f16\u91cc\u53eb bl \u7684\u4e11\u6001\uff0c\u8fd9\u5c31\u591f\u4e86\u3002\u5bf9\u4e8e\u5229\u7528\u786c\u4ef6\u7279\u6709\u7684\u6307\u4ee4\uff08\u4f8b\u5982 SSE\u3001NEON \u6307\u4ee4\u96c6\uff09\u6765\u4f18\u5316\uff0c\u4ee5\u53ca\u5185\u8054\u6c47\u7f16\uff08 asm \u5173\u952e\u5b57\uff09\u7b49\uff0cLLVM IR \u4e5f\u662f\u652f\u6301\u7684\u3002 \u901a\u7528\u7684\u90a3\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201ccommon IR\u201d\uff0c\u4f8b\u5982 Function\u3001Instruction \u7b49\u3002\u8fd9\u90e8\u5206\u662f\u8de8\u5e73\u53f0\u7684\uff0c\u7edf\u4e00\u4e86\u5206\u5d29\u79bb\u6790\u7684\u5404\u5927\u786c\u4ef6\u6c47\u7f16\uff0c\u4fbf\u4e8e\u7edf\u4e00\u7f16\u5199\u4f18\u5316\u5f15\u64ce\u3002 \u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201cspecific IR\u201d\uff0c\u4f8b\u5982 MachineFunction\u3001MachineInstr \u7b49\u3002\u8fd9\u90e8\u5206\u57fa\u672c\u662f\u7528\u4e8e\u6a21\u4eff\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff0c\u5c31\u662f\u8fd9\u90e8\u5206\u7684\u5b58\u5728\u5bfc\u81f4\u4e86 LLVM IR \u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 \u5728\u8fdb\u5165\u540e\u7aef\u7684\u201c\u6307\u4ee4\u9009\u62e9\u201d\u9636\u6bb5\u540e\uff0cIR \u8282\u70b9\u4e2d\u901a\u7528\u7684\u90a3\u90e8\u5206\u8282\u70b9\uff0c\u4f1a\u9010\u6b65\u88ab\u66ff\u6362\u4e3a\u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u76f8\u5e94 MachineInstr \u8282\u70b9\uff0c\u5728\u201c\u6307\u4ee4\u9009\u62e9\u201d\u540e\u7684\u9636\u6bb5\u770b\u6765\uff0c\u5c31\u597d\u50cf\u524d\u9762\u8f93\u51fa\u4e86\u4e00\u5927\u5806\u5185\u8054\u6c47\u7f16\u4e00\u6837\uff0c\u6700\u7ec8\uff0c\u9010\u6e10\u53d8\u6210\u4e86\u5b8c\u5168\u7684\u76ee\u6807\u5e73\u53f0\u6c47\u7f16\uff0c\u6700\u7ec8\u8f93\u51fa\u3002 LLVM IR \u7684\u7279\u70b9 IR \u548c\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u76f8\u6bd4\uff0c\u4e0d\u4ec5\u4ec5\u662f\u7edf\u4e00\uff0c\u597d\u5904\u6709\u5f88\u591a\u3002 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u6bcf\u4e2a C++ \u6587\u4ef6\u7f16\u8bd1\u5f97\u5230\u7684 IR \u6c47\u7f16\u5747\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u5b9a\u4e49\uff08\u548c\u5c11\u91cf\u7279\u6b8a\u6307\u4ee4\uff0c\u6bd4\u5982 target triple \uff09\u7ec4\u6210\uff0c\u6240\u6709\u7684 IR \u6307\u4ee4\u90fd\u5305\u5728\u51fd\u6570\u4e2d\u3002 \u51fd\u6570\u662f LLVM \u4f18\u5316\u7684\u57fa\u672c\u5355\u4f4d\uff0c\u7edd\u5927\u591a\u6570 LLVM pass\uff0c\u90fd\u662f\u4ee5\u5355\u4e2a\u51fd\u6570\u4e3a\u5355\u4f4d\u6765\u4f18\u5316\u7684\u3002\u53ea\u6709\u5185\u8054\u4f18\u5316\u548c IPO \u4f18\u5316\uff0c\u53ef\u4ee5\u5b9e\u73b0\u8de8\u51fd\u6570\u7684\u4f18\u5316\u3002 \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u5185\u8054\u4f18\u5316\u4e0d\u4ec5\u4ec5\u662f\u201c\u51fd\u6570\u539f\u5c01\u4e0d\u52a8\u63d2\u5165\u8c03\u7528\u4f4d\u7f6e\u201d\u3002\u628a\u51fd\u6570\u63d2\u5165\u8c03\u7528\u8005\u4f53\u5185\u540e\uff0c\u4e24\u4e2a\u51fd\u6570\u878d\u5408\u4e3a\u4e00\u4e2a\u51fd\u6570\u4e86\uff0c\u4f7f\u4f18\u5316\u5668\u7684\u201c\u89c6\u91ce\u201d\u66f4\u5927\uff08\u56e0\u4e3a\u5927\u90e8\u5206\u4f18\u5316\u4e0d\u80fd\u8de8\u8d8a\u51fd\u6570\u8fb9\u754c\uff09\uff01\u4ece\u800c\u5e2e\u52a9\u4e86\u5176\u4ed6\u4ee5\u51fd\u6570\u4e3a\u8fb9\u754c\u7684\u4f18\u5316 pass \u80fd\u591f\u66f4\u597d\u7684\u4f18\u5316\u3002\u4f8b\u5982\u5728 main \u4e2d\u4ee5\u8fed\u4ee3\u5668\u904d\u5386\u4e00\u4e2a\u5bb9\u5668\uff1a\u672c\u6765 main \u51fd\u6570\u662f\u8c03\u7528\u8fed\u4ee3\u5668\u7684 operator++ \uff0c\u800c operator++ \u4e0d\u5185\u8054\u6389\u7684\u8bdd\uff0c main \u7684\u4f18\u5316\u5668\u6c38\u8fdc\u65e0\u6cd5\u610f\u8bc6\u5230 operator++ \u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u6307\u9488\u7684\u52a0\u6cd5\uff0c\u53ea\u80fd\u8001\u8001\u5b9e\u5b9e\u5206\u914d alloca \u7136\u540e\u83b7\u53d6\u51fa this \u6307\u9488\u4f20\u5165 operator++ \u51fd\u6570\u3002\u800c\u5185\u8054\u4ee5\u540e\uff0c operator++ \u7684\u5185\u5bb9\u66b4\u9732\u5728\u4f18\u5316 pass \u773c\u524d\uff0c\u4ed6\u5c31\u77e5\u9053\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u4f18\u5316\u6210\u4e00\u4e2a\u9759\u6001\u5bc4\u5b58\u5668\u4e86\uff0c\u6839\u672c\u4e0d\u7528\u4e3a\u5176\u5206\u914d\u5185\u5b58\uff01\u6700\u7ec8\u4ea7\u751f\u7684\u6c47\u7f16\u4e00\u4e0b\u5b50\u4ece\u5fc5\u987b\u5206\u914d\u5728\u6808\u5185\u5b58\u4e0a\uff0c\u5230\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u6307\u9488\u653e\u5728\u5bc4\u5b58\u5668\u91cc\u4e86\u3002\u800c IPO (Inter-procedure Optimization) \u5219\u662f\u6839\u636e\u51fd\u6570\u53c2\u6570\u4e3a\u5e38\u6570\u7684\u60c5\u51b5\u505a\u5206\u53d1\uff0c\u5206\u53d1\u540e\u53ef\u4ee5\u9488\u5bf9\u4e0d\u540c\u5e38\u6570\u53c2\u6570\u7684\u7ed3\u679c\u505a\u7279\u5b9a\u4f18\u5316\uff0c\u4f46\u4e0d\u5408\u5e76\u51fd\u6570\uff0c\u65e0\u6cd5\u8d4b\u80fd\u5176\u4ed6\u4f18\u5316 pass\uff0c\u6548\u679c\u770b\u8d77\u6765\u5c31\u6ca1\u6709\u5185\u8054\u5f3a\u4e86\u3002\u4f46\u662f\u8981\u6ce8\u610f\u5f88\u591a\u4f18\u5316 pass \u7684\u5f00\u9500\u662f\u548c\u51fd\u6570\u7684\u5927\u5c0f\uff08IR \u6307\u4ee4\u6570\u91cf\uff09\u6210\u6b63\u6bd4\u7684\uff0c\u6240\u4ee5\u5185\u8054\u592a\u591a\u5c42\u5bfc\u81f4\u4e00\u4e2a\u51fd\u6570\u5f88\u5927\u7684\u8bdd\uff0c\u7f16\u8bd1\u4f1a\u53d8\u5f97\u6bd4\u8f83\u6162\u3002 \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u5bc4\u5b58\u5668\u65e0\u9650\u91cf\u4f9b\u5e94\uff01\u4e00\u4e2a\u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u5b9a\u4e49\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668\uff0c\u65e0\u9700\u8003\u8651\u786c\u4ef6\u5177\u4f53\u63d0\u4f9b\u4e86\u591a\u5c11\u4e2a\u5bc4\u5b58\u5668\u3002\u56e0\u4e3a\u548c\u786c\u4ef6\u5bc4\u5b58\u5668\u8131\u94a9\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u79f0\u4e4b\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u53ea\u5728 LLVM \u4e2d\u7aef\u91cc\u51fa\u73b0\uff0c\u4e3a\u4e86\u4fbf\u4e8e\u4f18\u5316\u548c\u5904\u7406\u91c7\u53d6\u7684\u7b80\u5316\u7b56\u7565\u3002 \u865a\u62df\u5bc4\u5b58\u5668\u7edf\u4e00\u4ee5 %0 %1 %2 \u547d\u540d\u3002\u5982\u679c\u6253\u7b97\u624b\u5199 IR\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5b9a\u4e49\u540d\u5b57\u5982 %x %i \uff0c\u4e0d\u8fc7 Clang \u81ea\u52a8\u751f\u6210\u7684 IR \u4e2d\u5bc4\u5b58\u5668\u90fd\u662f\u4ece 0 \u5f00\u59cb\uff0c\u81ea\u52a8\u9012\u589e\u7684\u547d\u540d\u3002 \u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u4f1a\u628a\u8fd9\u4e9b\u5bc4\u5b58\u5668\u6620\u5c04\u5230\u76f8\u5e94\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u4e0d\u7528\u62c5\u5fc3\uff01\u5982\u679c\u540e\u7aef\u53d1\u73b0 IR \u4e2d\u7684\u5bc4\u5b58\u5668\u7528\u91cf\u8d85\u51fa\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u5bc4\u5b58\u5668\u6570\u91cf\u4e0a\u9650\uff0c\u90a3\u4e48\u4f1a\u9009\u62e9\u4e00\u90e8\u5206\u201c\u6253\u7ffb\u201d\uff08spill\uff09\u5230\u5185\u5b58\u4e2d\u53bb\u3002 \u800c\u4e14\u5982\u679c\u53d1\u73b0\u5bc4\u5b58\u5668\u53ef\u4ee5\u590d\u7528\uff0c\u4e5f\u4f1a\u590d\u7528\u4e4b\u524d\u5df2\u7ecf\u6ca1\u7528\u5230\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982\u4ee5\u4e0b IR \u4e2d\uff0c\u770b\u4f3c\u7528\u5230\u4e86\u4e94\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u5b9e\u9645\u53ea\u9700\u8981\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u53ef\u4ee5\u4e86\uff0c\u56e0\u4e3a %1 \u5728\u88ab %2 \u7684 add \u6307\u4ee4\u7528\u5b8c\u4ee5\u540e\uff0c\u5c31\u6ca1\u4eba\u518d\u4f7f\u7528\u4e86\u3002\u8fd9\u65f6\u5c31\u7a7a\u51fa\u4e86\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u8d44\u6e90\uff0c\u540e\u6765\u65b0\u7684\u5bc4\u5b58\u5668\u53ef\u4ee5\u4ece\u8fd9\u91cc\u9876\u66ff\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, 1 \u5728 LLVM \u4e2d\uff0c\u662f\u5229\u7528\u7ebf\u6027\u626b\u63cf\u6cd5\uff08\u7535\u68af\u7b97\u6cd5\uff09\u6765\u786e\u5b9a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff08\u4ece\u7b2c\u4e00\u6b21\u521b\u5efa\uff0c\u5230\u6700\u540e\u4e00\u6b21\u4f7f\u7528\u4e4b\u95f4\u7684\u65f6\u95f4\u6bb5\uff09\uff0c\u5bf9\u4e8e\u751f\u547d\u5468\u671f\u6709\u91cd\u53e0\u7684\u591a\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u624d\u9700\u8981\u4e3a\u4ed6\u4eec\u5206\u914d\u72ec\u7acb\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\uff0c\u5982\u679c\u751f\u547d\u5468\u671f\u6ca1\u6709\u4ea4\u96c6\uff0c\u90a3\u4e48\u53ef\u4ee5\u8ba9\u65b0\u6765\u7684\u865a\u62df\u5bc4\u5b58\u5668\u590d\u7528\u8001\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u53ea\u9700\u8981\u7528\u5230\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u591f\u4e86\uff1a eax = 0 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 \u800c\u5982\u679c %1 \u5bc4\u5b58\u5668\u540e\u9762\u8fd8\u6709\u4f7f\u7528\uff0c\u90a3\u5c31\u4e0d\u80fd\u628a %1 \u6240\u5728\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u590d\u7528\u4e86\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, %1 ; \u6b64\u5904\u7684\u201c\u4f7f\u7528\u201d\u5ef6\u957f\u4e86 %1 \u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff01 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u81f3\u591a\u9700\u8981\u5206\u914d\u4e24\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u8d44\u6e90\uff1a eax = 0 ecx = add eax, 1 ecx = add ecx, 1 ecx = add ecx, 1 ecx = add ecx, 1 eax = add eax, ecx \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u865a\u62df\u5bc4\u5b58\u5668\u90fd\u662f\u53ea\u8bfb\u7684\uff01\u4e00\u6b21\u6027\u8d4b\u503c\u5b8c\u6bd5\u540e\uff0c\u5c31\u4e0d\u5141\u8bb8\u518d\u6b21\u4fee\u6539\uff0c\u6240\u6709\u7684\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u80fd\u5728\u5b9a\u4e49\u7684\u5730\u65b9\u8d4b\u503c\u3002 \u5982\u679c\u9700\u8981\u80fd\u4fee\u6539\u7684\u53d8\u91cf\uff0c\u9700\u8981\u7528 IR \u4e2d\u7684 alloca \u6307\u4ee4\u5728\u51fd\u6570\u6808\u4e0a\u5206\u914d\uff08\u9759\u6001\u5927\u5c0f\u7684\uff09\u7a7a\u95f4\uff0c\u5176\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\u3002 \u5728 Clang \u4e2d\uff0c\u4f1a\u5148\u628a\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u90fd\u5b9a\u4e49\u4e3a alloca \u7684\uff0c\u5f53\u521d\u59cb\u5316\u53d8\u91cf\u65f6\uff0c\u7528 IR \u4e2d\u7684\u5185\u5b58\u5199\u6307\u4ee4 store \u5199\u5165\u521d\u59cb\u503c\u3002 \u7136\u540e\uff0c\u5728\u5f00\u542f\u4e86\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0cLLVM \u4e2d\u7aef\u4e00\u4e2a\u53eb\u505a mem2reg \u7684\u4f18\u5316 pass\uff0c\u4f1a\u68c0\u6d4b\u5230\u6240\u6709\u53ea\u6709\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u5e38\u91cf\u53d8\u91cf\u7684 alloca\uff0c\u5e76\u5c1d\u8bd5\u628a\u4ed6\u4eec\u4f18\u5316\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\u3002 \u5bf9\u4e8e\u5b58\u5728 if \u6761\u4ef6\u8d4b\u503c\uff0c\u4ee5\u53ca for \u5faa\u73af\u7684\uff0c\u5219\u4f1a\u5229\u7528 Phi \u8282\u70b9\uff0c\u4f9d\u7136\u53ef\u4ee5\u4f18\u5316\u79f0\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002\uff08\u540e\u9762\u7684\u7ae0\u8282\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd Phi \u7684\u77e5\u8bc6\uff09 \u5982\u679c\u5b9e\u5728\u907f\u514d\u4e0d\u4e86 alloca\uff08\u6bd4\u5982\u5bf9\u53d8\u91cf\u7528\u5230\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26\uff0c\u800c\u865a\u62df\u5bc4\u5b58\u5668\u6ca1\u6709\u5185\u5b58\u5730\u5740\uff09\uff0c\u90a3\u5c31\u4f1a\u653e\u5f03\u4f18\u5316\u8fd9\u4e2a\u53d8\u91cf\uff0c\u4f9d\u7136\u4fdd\u6301 alloca + store \u7684\u72b6\u6001\u3002 \u6700\u7ec8\uff0c\u6240\u6709\u80fd\u4f18\u5316\u6210\u7684\uff0c\u90fd\u53d8\u6210\u65e0\u9650\u4f9b\u5e94\u4e14\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u4e86\u3002 \u8fd9\u79cd\u5bc4\u5b58\u5668\u53ea\u8bfb\u7684 IR\uff0c\u88ab\u79f0\u4e3a SSA IR\uff08Static Single Assignment IR\uff09\uff0c\u4e2d\u6587\u5c31\u662f\u662f\u201c\u9759\u6001\u5355\u8d4b\u503c IR\u201d\u3002 \u9759\u6001\uff1a\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u548c\u5e8f\u53f7\u662f\u786e\u5b9a\u7684\uff0c\u5728\u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u56fa\u5b9a\u3002 \u5355\u8d4b\u503c\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u53ea\u80fd\u8d4b\u503c\u4e00\u6b21\uff0c\u4e4b\u540e\u4e0d\u5f97\u4fee\u6539\u3002 SSA IR \u7684\u597d\u5904\u662f\u65b9\u4fbf\u4f18\u5316\uff0c\u4f8b\u5982\uff1a x = 1; x = 2; y = x; return y; \u5f88\u660e\u663e\uff0c\u6211\u4eec\u53ef\u4ee5\u628a x = 1 \u8fd9\u4e00\u884c\u4f18\u5316\u6389\uff0c\u56e0\u4e3a\u540e\u9762\u7684 x = 2 \u5df2\u7ecf\u628a\u4ed6\u8986\u76d6\u4e86\u3002\u4f46\u662f\u5982\u4f55\u786e\u5b9a\u8fd9\u4e00\u70b9\uff1f\u5f88\u56f0\u96be\u3002 \u800c\u5982\u679c\u5148\u901a\u8fc7 mem2reg \u8f6c\u6210 SSA IR \u7684\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u8fd9\u65f6\u4ed6\u4f1a\u6ce8\u610f\u5230 x = 1 \u548c x = 2 \u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u8d4b\u503c\uff0c\u751f\u547d\u5468\u671f\u4e92\u4e0d\u91cd\u53e0\uff0c\u53ef\u4ee5\u62c6\u6210\u4e24\u4e2a\u5e38\u91cf\uff0c\u5b89\u5168\u653e\u8fdb\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002 x1 = 1; // \u68c0\u6d4b\u5230\u201c\u4e0d\u53ef\u8fbe\u201d\u7684\u5bc4\u5b58\u5668 x2 = 2; y = x2; return y; \u7136\u540e\uff0c\u7531\u4e8e x1 \u6839\u672c\u6ca1\u6709\u4f7f\u7528\u8fc7\uff0c\u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u5f88\u5bb9\u6613\u5c31\u628a x1 \u8fd9\u4e2a\u672a\u4f7f\u7528\u7684\u53d8\u91cf\u5254\u9664\u6389\u3002\u5373\u4f7f\u4e0d\u662f\u540e\u7aef\uff0c\u4e2d\u7aef\u7684\u4e00\u4e9b\u5176\u4ed6\u4f18\u5316 pass \u4e5f\u5f88\u5bb9\u6613\u6e05\u9664\u8fd9\u4e9b\u672a\u4f7f\u7528\u7684\u5e38\u91cf\u5bc4\u5b58\u5668\u3002 \u603b\u4e4b\uff0c\u901a\u8fc7 SSA \u89c4\u5219\uff0c\u628a\u201c\u5bc4\u5b58\u5668\u88ab\u8986\u76d6\u201d\u8fd9\u4e2a\u6bd4\u8f83\u96be\u68c0\u6d4b\u7684\u6761\u4ef6\uff0c\u53d8\u6210\u4e86\u201c\u5bc4\u5b58\u5668\u53ea\u5b9a\u4e49\uff0c\u6ca1\u4eba\u4f7f\u7528\u201d\u8fd9\u4e2a\u5f88\u5bb9\u6613\u68c0\u6d4b\u7684\u4e8b\u5b9e\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u7531\u4e8e LLVM \u7684\u7814\u7a76\u4e3b\u8981\u96c6\u4e2d\u5728\u4e2d\u7aef\uff0c\u5728\u4e2d\u7aef\u7684\u8bed\u5883\u4e0b\u63d0\u5230\u7684\u5bc4\u5b58\u5668\uff0c\u5982\u975e\u7279\u522b\u8bf4\u660e\uff0c\u8bfb\u8005\u5e94\u5f53\u9ed8\u8ba4\u6307\u7684\u5c31\u662f LLVM \u865a\u62df\u5bc4\u5b58\u5668\uff0c\u800c\u4e0d\u662f\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u6700\u540e\uff0c\u5728\u201c\u5206\u914d\u5bc4\u5b58\u5668\u201d\u9636\u6bb5\uff0c\u628a\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u5bb9\u7eb3\u4e0d\u4e0b\u6216\u65e0\u6cd5\u53d8\u6210\u5355\u6b21\u9759\u6001\u8d4b\u503c\u7684\u90e8\u5206\u53d8\u91cf\uff0c\u518d\u9009\u62e9\u6027\u5730\u201c\u6253\u7ffb\u201d\u5230\u5185\u5b58\u4e2d\u53bb\u3002\u8fd9\u6837\u4e00\u6765\u4e00\u56de\uff0c\u5728\u4e2d\u7aef\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u540e\u7aef\u53c8\u4e00\u6837\u80fd\u6b63\u5e38\u751f\u6210\u6c47\u7f16\uff0c\u5bf9\u4e8e\u5bc4\u5b58\u5668\u7528\u91cf\u8f83\u5c11\u7684\u51fd\u6570\u5219\u5b8c\u5168\u907f\u514d\u4e86\u5185\u5b58\u8bfb\u5199\u3002\u4e3a\u4e86\u4fdd\u8bc1\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf\u90fd\u5b58\u5230\u5bc4\u5b58\u5668\u4e2d\uff0c\u4f60\u53ef\u4ee5\u81ea\u5df1\u6570\u4e00\u4e0b\uff0c\u6240\u6709\u53d8\u91cf\u751f\u547d\u5468\u671f\u91cd\u53e0\u7684\u6700\u591a\u7684\u6570\u91cf\u662f\u591a\u5c11\uff0c\u662f\u5426\u8d85\u8fc7\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u4e0a\u9650\uff1a\u5bf9 x86 \u6765\u8bf4\uff0c\u5c31\u662f\u9664 rsp \u548c rbp \u5916\u6240\u6709\u7684\u901a\u7528\u5bc4\u5b58\u5668\uff08\u6574\u6570\u53d8\u91cf\uff09\u548c\u6240\u6709 xmm \u7cfb\u5217\u5bc4\u5b58\u5668\uff08\u6d6e\u70b9\u53d8\u91cf\uff09\uff1b\u5982\u679c\u8be5\u51fd\u6570\u4e2d\u8fd8\u8c03\u7528\u4e86\u5176\u4ed6\u51fd\u6570\uff0c\u90a3\u4e48\u5c31\u53ea\u6709\u975e\u6613\u5931\u5bc4\u5b58\u5668\u53ef\u7528\u3002 \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u6211\u4eec\u719f\u6089\u7684 x86 \u6c47\u7f16\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u7531\u5176\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\uff08\u4f8b\u5982 add \uff09\u90fd\u662f\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668 + \u6e90\u5bc4\u5b58\u5668\u7684\u7279\u70b9\u5f97\u540d\u3002 add eax, ecx \u6548\u679c\uff1a eax = eax + ecx \u7c7b\u4f3c\u4e8e C \u8bed\u8a00\u4e2d\u7684 += \u8fd0\u7b97\u7b26\uff0c\u4fee\u6539\u662f\u5c31\u5730\u751f\u6548\u5728\u5176\u4e2d\u4e00\u4e2a\u5bc4\u5b58\u5668\u4e0a\u7684\uff0c\u5176\u4e2d\u5de6\u4fa7\u7684\u5bc4\u5b58\u5668\u65e2\u662f\u6e90\u5bc4\u5b58\u5668\u53c8\u662f\u76ee\u7684\u5bc4\u5b58\u5668\u3002 \u4f18\u70b9\uff1a\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u5c31\u5730\u5199\u5165\u53ef\u4ee5\u8282\u7701\u6307\u4ee4\u7801\u7684\u5927\u5c0f\uff0c\u8282\u7701\u7a7a\u95f4\uff0c\u7b26\u5408 x86 \u7684 CISC \u8bbe\u8ba1\u601d\u8def\u3002 \u7f3a\u70b9\uff1a\u5982\u679c\u9700\u8981\u628a\u7ed3\u679c\u5b58\u5728\u53e6\u4e00\u4e2a\u5bc4\u5b58\u5668\u91cc\uff0c\u5c31\u9700\u8981\u5148 mov \u6307\u4ee4\u62f7\u8d1d\u4e00\u4efd\uff0c\u4e14\u5b58\u5728\u526f\u4f5c\u7528\u4e0d\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u800c LLVM \u7684 IR \u662f\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u3002\u4f8b\u5982\uff1a %3 = add %1, %2 \u6548\u679c\uff1a %3 = %1 + %2 \u8fd9\u91cc\uff0c %3 \u662f\u76ee\u6807\u5bc4\u5b58\u5668\uff0c %1 \u548c %2 \u662f\u6e90\u5bc4\u5b58\u5668\uff0c add \u662f\u64cd\u4f5c\u6307\u4ee4\u3002 \u548c\u4e24\u64cd\u4f5c\u6570\u6307\u4ee4\u76f8\u6bd4\uff0c\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u7684\u597d\u5904\u662f\uff1a \u6e90\u5bc4\u5b58\u5668\u53ea\u8bfb\uff0c\u4e0d\u4f1a\u6539\u53d8\uff1a\u5982\u9700\u8ba1\u7b97\u4e00\u52a0\u4e00\u51cf\uff0c\u65e0\u9700\u9884\u5148\u62f7\u8d1d\u4e00\u4efd\u65e7\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u76f4\u63a5 %3 = add %1, %2 \u548c %4 = sub %1, %2 \u5373\u53ef\u3002 \u76ee\u7684\u5bc4\u5b58\u5668\u53ea\u5199\uff0c\u6ee1\u8db3\u4e86\u9759\u6001\u5355\u8d4b\u503c IR\uff08SSA IR\uff09\u7684\u8981\u6c42\uff0c\u4e0d\u9700\u8981\u8003\u8651\u526f\u4f5c\u7528\uff0c\u4f18\u5316\u8d77\u6765\u66f4\u65b9\u4fbf\uff0c\u662f\u4e2d\u95f4 IR \u7684\u7406\u60f3\u8bbe\u8ba1\u3002 \u6240\u6709\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u4e4b\u95f4\u987a\u5e8f\u65e0\u5173\uff0c\u53ef\u4ee5\u4efb\u610f\u8c03\u6362\u987a\u5e8f\uff0c\u53ef\u4ee5\u8f7b\u677e\u901a\u8fc7 DFS \u9012\u5f52\u627e\u51fa\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668\u6240\u6709\u76f4\u63a5\u548c\u95f4\u63a5\u4f9d\u8d56\u7684\u5bc4\u5b58\u5668\uff0c\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u7f3a\u70b9\uff1a\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u4f46\u662f LLVM IR \u662f\u53ea\u5728\u7f16\u8bd1\u671f\u5b58\u5728\u7684\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u5e76\u4e0d\u8fdb\u5165\u6700\u7ec8\u4e8c\u8fdb\u5236\u4ea7\u7269\uff0c\u6700\u7ec8\u7f16\u8bd1\u6210 x86 \u6c47\u7f16\u540e\u4f9d\u7136\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u6240\u4ee5\u8fd9\u4e2a\u7f3a\u70b9\u5e76\u4e0d\u5f71\u54cd\u3002 \u7c7b\u578b\u7cfb\u7edf LLVM IR \u4e2d\uff0c\u6240\u6709\u7684\u5bc4\u5b58\u5668\u5e76\u4e0d\u662f\u539f\u59cb\u7684\u4e8c\u8fdb\u5236\u5185\u5b58\uff0c\u800c\u662f\u6709\u7c7b\u578b\u7684\u3002 \u6709\u4eba\u4f1a\u8bf4\uff0c\u5df2\u7ecf\u8fdb\u5165 IR \u4e86\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u5fc5\u8981\uff1f\u628a\u6240\u6709\u7c7b\u578b\u90fd\u5f53\u6210\u4e8c\u8fdb\u5236\u5185\u5b58\u4e0d\u884c\u5417\uff1f \u5728 IR \u5c42\u9762\u533a\u5206\u7c7b\u578b\u7684\u597d\u5904\uff1a \u53ef\u4ee5\u660e\u786e\u5404\u79cd\u6570\u5b66\u8fd0\u7b97\u64cd\u4f5c\u6570\u7684\u7c7b\u578b\uff08\u4f8b\u5982\u6d6e\u70b9\u6570 f32 \u6216\u6574\u6570 i32 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bc4\u5b58\u5668\u7684\u5927\u5c0f\uff08\u4f8b\u5982 32 \u4f4d\u6574\u6570 i32 \u548c 8 \u4f4d\u6574\u6570 i8 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bf9\u9f50\u5ea6\u3002 \u53ef\u4ee5\u533a\u5206\u51fa\u6307\u9488\u548c\u666e\u901a\u7c7b\u578b\u4e24\u79cd\u4e0d\u540c\u7684\u7528\u9014\uff0c\u9632\u6b62\u6df7\u6dc6\uff08\u4f8b\u5982\u6574\u6570\u7c7b\u578b i32 \u548c\u4ed6\u7684\u6307\u9488 i32* \uff09\u3002 \u5f3a\u7c7b\u578b\u7684 IR \u53ef\u4ee5\u5927\u5927\u5e2e\u52a9\u4f18\u5316 pass \u7406\u89e3\u7a0b\u5e8f\u3002 \u7c7b\u578b\u4e3a\u4ec0\u4e48\u5e2e\u52a9\u4f18\u5316\uff1f\u4f8b\u5982\uff0c\u77e5\u9053\u7c7b\u578b\u4fe1\u606f\u540e\uff0c\u53ef\u4ee5\u914d\u5408 C++ \u7684 strict-aliasing \u89c4\u5219\u6392\u9664\u4e00\u90e8\u5206\u53ef\u80fd\u7684\u6307\u9488\u522b\u540d\uff0c\u79f0\u4e3a\u201c\u57fa\u4e8e\u7c7b\u578b\u7684\u522b\u540d\u5206\u6790\u201d\uff08TBAA, type-based-aliasing-analysis\uff09\u3002 \u522b\u540d\u6307\u7684\u662f\u4e24\u4e2a\u6307\u9488\u6709\u76f8\u4e92\u201c\u7a7f\u63d2\u201d\u7684\u90e8\u5206\uff0c\u6307\u9488\u5b58\u5728\u522b\u540d\u4f1a\u5bfc\u81f4 SIMD \u77e2\u91cf\u4f18\u5316\u5931\u8d25\u3002\u800c C++ \u7684 strict-aliasing \u53ef\u4ee5\u4fdd\u8bc1\u4e0d\u76f8\u5e72\u7c7b\u578b\u7684\u4e24\u4e2a\u6307\u9488\u4e4b\u95f4\u4e0d\u4f1a\u6709\u201c\u7a7f\u63d2\u201d\uff0c\u4ece\u800c\u5e2e\u52a9\u77e2\u91cf\u4f18\u5316\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u4ece int * \u5f3a\u8f6c\u4e3a float * \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u4e3a strict-aliasing \u8981\u6c42\u4e0d\u540c\u7c7b\u578b\u7684\u6307\u9488\u6ca1\u6709\u91cd\u53e0\u90e8\u5206\uff08\u6307\u5411\u76f8\u540c\u7684\u5730\u5740\uff09\uff0c\u5982\u679c\u4f60\u540c\u65f6\u7528\u4e86\u6307\u5411\u540c\u4e00\u4e2a\u5730\u5740\u7684 int * \u548c float * \uff0c\u90a3\u4e48\u5982\u679c LLVM \u5047\u5b9a\u4e86\u4ed6\u4eec\u4e0d\u80fd\u6307\u5411\u540c\u5730\u5740\u6765\u4f18\u5316\uff0c\u5c31\u4f1a\u5bfc\u81f4\u8fd0\u884c\u7ed3\u679c\u51fa\u9519\u3002\u4e0d\u8fc7 int * \u8f6c\u4e3a char * \u3001 unsigned char * \u5374\u662f\u5141\u8bb8\u7684\uff0c\u8fd9\u662f\u56e0\u4e3a\u7ecf\u5e38\u51fa\u73b0\u7528 char \u6765\u505a\u7f13\u51b2\u533a\uff0c\u7136\u540e\u89e3\u6790\u51fa\u7ed3\u6784\u4f53\u7684\u573a\u666f\uff0cC++ \u6807\u51c6\u4e3a\u8fd9\u79cd\u5e38\u7528\u60c5\u51b5\u5f00\u4e86\u540e\u95e8\u3002\u6240\u4ee5\u5982\u679c\u4f60\u9700\u8981\u5728 int \u548c float \u4e4b\u95f4\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 memcpy \u6765\u62f7\u8d1d\uff08 memcpy \u5185\u90e8\u88ab LLVM \u8ba4\u4e3a\u662f\u6309 unsigned char * \u8bbf\u95ee\u7684\uff09\uff0c\u4e0d\u8981\u5f3a\u8f6c\u6307\u9488\u8bbf\u95ee\u3002\u8be6\u89c1\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u3002 \u57fa\u7840\u7c7b\u578b LLVM IR \u4e2d\u7684\u57fa\u7840\u7c7b\u578b\u6709\uff1a LLVM \u7c7b\u578b C \u8bed\u8a00\u7c7b\u578b \u89e3\u91ca i1 bool 1 \u4f4d\u6574\u6570/\u5e03\u5c14\u7c7b\u578b i8 char 8 \u4f4d\u6574\u6570\u7c7b\u578b i16 short 16 \u4f4d\u6574\u6570\u7c7b\u578b i32 int 32 \u4f4d\u6574\u6570\u7c7b\u578b i64 long long 64 \u4f4d\u6574\u6570\u7c7b\u578b f16 _Float16 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b bf16 _BFloat16 \u7a84\u5e95 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b f32 float 32 \u4f4d\u6d6e\u70b9\u7c7b\u578b f64 double 64 \u4f4d\u6d6e\u70b9\u7c7b\u578b f80 long double 80 \u4f4d\u6d6e\u70b9\u7c7b\u578b f128 _Float128 128 \u4f4d\u6d6e\u70b9\u7c7b\u578b void void \u7a7a\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u5176\u4e2d i1 \u662f\u5e03\u5c14\u7c7b\u578b\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 bool \uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u6bd2\u503c\uff09\u3002 \u6307\u9488\u7c7b\u578b \u6240\u6709\u7c7b\u578b\u90fd\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u76f8\u5e94\u7684\u6307\u9488\u7c7b\u578b\uff0c\u7528\u4e00\u4e2a * \u505a\u540e\u7f00\u6765\u8868\u793a\u3002 \u4f8b\u5982\u4e00\u4e2a\u6307\u5411 i8 \u7684\u6307\u9488\uff0c\u7c7b\u578b\u5c31\u662f i8* \uff0c\u5bf9\u5e94 C \u8bed\u8a00\u4e2d\u7684 char * \u7c7b\u578b\u3002 \u6ce8\u610f LLVM IR \u4e2d\u4e0d\u533a\u5206\u7c7b\u578b\u7684 const \u4e0e\u5426\uff0c const \u53ea\u5728 C++ \u8bed\u6cd5\u5c42\u9762\u5b58\u5728\uff0c\u4f8b\u5982 const char * \u548c char * \u5728 LLVM IR \u4e2d\u5bf9\u5e94\u7684\u90fd\u662f i8* \u3002 \u53ef\u4ee5\u7528\u591a\u4e2a * \u540e\u7f00\u8868\u793a\u591a\u91cd\u6307\u9488\uff0c\u4f8b\u5982 char ** \u7c7b\u578b\u5728 LLVM IR \u4e2d\u5c31\u662f i8** \u3002 \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u6ce8\u610f\u5230\uff0cLLVM \u4e2d\u4f3c\u4e4e\u53ea\u6709 i32 \u800c\u6ca1\u6709 u32 \uff1f\u8fd9\u662f\u56e0\u4e3a LLVM IR \u7684\u7c7b\u578b\u7cfb\u7edf\u5e76\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\u3002 int \u548c unsigned int \u90fd\u7edf\u4e00\u7528 i32 \u8868\u793a\uff1b char \u548c unsigned char \u7edf\u4e00\u7528 i8 \u8868\u793a\u3002 \u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\uff1a LLVM IR \u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u4e0d\u5e94\u8be5\u5305\u542b\u592a\u591a\u8bed\u8a00\u7279\u6027\uff0c\u4fdd\u6301\u7b80\u5355\u3002 \u5927\u591a\u6570\u65f6\u5019\uff0c\u6211\u4eec\u5e76\u4e0d\u5173\u5fc3\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\uff0c\u53ea\u5173\u5fc3\u52a0\u51cf\u6cd5\u540e\u662f\u5426\u6ea2\u51fa\u3002 \u50cf\u52a0\u6cd5\uff08 add \uff09\u548c\u51cf\u6cd5\uff08 sub \uff09\u8fd9\u6837\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u7531\u4e8e\u8865\u7801\u7684\u5de7\u5999\u8bbe\u8ba1\uff0c\u65e0\u8bba\u64cd\u4f5c\u6570\u662f\u5426\u6709\u7b26\u53f7\uff0c\u5176\u7ed3\u679c\u5728\u4e8c\u8fdb\u5236\u4e0a\u90fd\u662f\u4e00\u6837\u7684\u3002 \u50cf\u6309\u4f4d\u6216\uff08 or \uff09\u548c\u6309\u4f4d\u4e0e\uff08 and \uff09\u8fd9\u6837\u7684\u903b\u8f91\u8fd0\u7b97\uff0c\u4e5f\u4e0d\u6d89\u53ca\u7b26\u53f7\u4f4d\uff0c\u90fd\u662f\u5f53\u6210\u666e\u901a\u7684\u4e8c\u8fdb\u5236\u4f4d\u6765\u8fd0\u7b97\uff0c\u7ed3\u679c\u4e5f\u6ca1\u6709\u533a\u522b\u3002 \u4fdd\u6301\u7b80\u5355\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\uff0c\u4f8b\u5982\uff0c\u4e0d\u7528\u8003\u8651 int \u7c7b\u578b\u548c unsigned int \u7c7b\u578b\u4e4b\u95f4\u7684\u6765\u56de\u8f6c\u6362\u3002 \u56e0\u6b64 i32 \u548c u32 \u7684 add \u548c sub \u6307\u4ee4\u53ef\u4ee5\u7edf\u4e00\u5f53\u4f5c i32 \u6765\u52a0\u51cf\u3002 \u800c\u5bf9\u4e8e\u4e58\u6cd5\u548c\u9664\u6cd5\u8fd9\u4e9b\u6709\u7b26\u53f7\u548c\u65e0\u7b26\u53f7\u7ed3\u679c\u4f1a\u4e0d\u540c\u7684\u6570\u5b66\u8fd0\u7b97\uff0cLLVM \u5c06\u4ed6\u4eec\u5206\u79bb\u6210\u4e24\u7ec4 IR \u6307\u4ee4\uff1a\u9488\u5bf9\u6709\u7b26\u53f7\u6570\u7684 smul \u548c sdiv \uff0c\u4ee5\u53ca\u9488\u5bf9\u65e0\u7b26\u53f7\u7684 umul \u548c udiv \u3002 \u6240\u4ee5\uff0cLLVM \u53ea\u662f\u9488\u5bf9\u4e58\u9664\u8fd9\u79cd\u6709\u65e0\u7b26\u53f7\u7ed3\u679c\u4e0d\u540c\u7684\u8fd0\u7b97\uff0c\u533a\u5206\u6210\u4e86\u4e24\u5957\u4e0d\u540c\u7684\u6307\u4ee4\uff1a\u7528 s \u548c u \u524d\u7f00\u533a\u5206\uff0c\u5176\u4f59\u50cf\u52a0\u51cf\u6cd5\u8fd9\u4e9b\u6307\u4ee4\u90fd\u662f\u5171\u7528\u7684\u3002 \u9700\u8981\u533a\u5206\u6709\u65e0\u7b26\u53f7\u7684\u6574\u6570\u8fd0\u7b97\u6307\u4ee4\uff1a\u4e58\u6cd5\u3001\u9664\u6cd5\u3001\u53d6\u6a21\u8fd0\u7b97\u3001\u6309\u4f4d\u53f3\u79fb\u3001\u6bd4\u8f83\u5927\u5c0f\u5173\u7cfb\u3002 \u4e0d\u9700\u8981\u533a\u5206\u7684\uff1a\u52a0\u6cd5\u3001\u51cf\u6cd5\u3001\u6309\u4f4d\u6216\u3001\u6309\u4f4d\u4e0e\u3001\u6309\u4f4d\u5f02\u6216\u3001\u6309\u4f4d\u5de6\u79fb\u3001\u6309\u4f4d\u53d6\u53cd\u3001\u6bd4\u8f83\u662f\u5426\u76f8\u7b49\u3002 \u4ece\u6307\u4ee4\u5c42\u9762\u4e0a\u533a\u5206\u6709\u65e0\u7b26\u53f7\u6570\uff0c\u800c\u7c7b\u578b\u5c42\u9762\u4e0a\u76f8\u540c\u3002\u8ba9\u662f\u5426\u6709\u7b26\u53f7\u53d8\u6210\u4e86\u6307\u4ee4\u7684\u7279\u6027\u800c\u4e0d\u662f\u7c7b\u578b\u7684\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u4e0d\u4ec5 LLVM IR \u4e2d\u5982\u6b64\uff0c\u5728 x86 \u6307\u4ee4\u96c6\u4e2d\u4e5f\u662f\u8fd9\u6837\u8bbe\u8ba1\u7684\u3002 \u81ea\u6b64\uff0c\u6709\u65e0\u7b26\u53f7\u7684\u4fe1\u606f\u53ea\u5728 Clang \u524d\u7aef\u4e2d\u51fa\u73b0\uff0c\u7531 Clang \u6839\u636e\u53d8\u91cf\u7c7b\u578b\u4fe1\u606f\uff0c\u9009\u62e9\u751f\u6210 smul \u6216 umul \u7b49 IR \u6307\u4ee4\uff0c\u7c7b\u578b\u90fd\u662f\u7edf\u4e00\u7684 i32 \u3002 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u8fd9\u91cc\u6211\u4eec\u6709\u5fc5\u8981\u660e\u786e\u4e00\u4e0b\u201c\u5b9a\u4e49(define)\u201d\u548c\u201c\u4f7f\u7528(use)\u201d\u3002\u8fd9\u662f\u4e24\u4e2a\u7f16\u8bd1\u5668\u9886\u57df\u7684\u672f\u8bed\uff0c\u7528\u4e8e\u63cf\u8ff0 SSA IR \u7684\u5bc4\u5b58\u5668\u53ca\u5176\u7528\u51b5\u3002 \u5b9a\u4e49\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u88ab\u8d4b\u503c\u7684\u5730\u65b9\uff0c\u5c31\u662f\u4ed6\u7684\u5b9a\u4e49\u3002 %1 = 1 ; %1 \u7684\u5b9a\u4e49 %2 = 2 ; %2 \u7684\u5b9a\u4e49 %3 = add %1, %2 ; %3 \u7684\u5b9a\u4e49 \u56e0\u4e3a LLVM IR \u662f SSA \u7684\uff0c\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c\u53ea\u80fd\u5728\u521d\u59cb\u5316\u65f6\u88ab\u8d4b\u503c\u4e00\u6b21\u3002\u6240\u4ee5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u662f\u552f\u4e00\u7684\uff0c\u4e5f\u5c31\u662f\u521d\u59cb\u5316\u7684\u90a3\u4e00\u6b21\u8d4b\u503c\u7684\u5730\u65b9\u3002 \u8868\u793a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e2d\uff0c\u5176\u521d\u59cb\u5316\uff0c\u7528\u5230\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\u505a\u53c2\u6570\u3002\u8fd9\u4e9b\u88ab\u5f15\u7528\u4e86\u7684\u201c\u53c2\u6570\u5bc4\u5b58\u5668\u201d\uff0c\u5c31\u662f\u4ed6\u7684\u201c\u4f7f\u7528\u201d\u3002 %1 = 1 %2 = 2 %3 = add %1, %2 ; %3 \u4f7f\u7528\u4e86 %1 \u548c %2 \u521d\u59cb\u5316\u4e3a\u5e38\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 %1 = 233 ; %1 \u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u4eba\uff01 \u5728 LLVM \u4e2d\u7ef4\u62a4\u6709\u201c\u5b9a\u4e49-\u4f7f\u7528(def-use)\u201d\u548c\u201c\u4f7f\u7528-\u5b9a\u4e49(use-def)\u201d\u7684\u53cc\u5411\u6620\u5c04\u5173\u7cfb\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\uff0c\u627e\u5230\u4ed6\u88ab\u54ea\u4e9b\u5bc4\u5b58\u5668\u201c\u4f7f\u7528\u201d\u4e86\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u4f7f\u7528\u201d\uff0c\u627e\u5230\u4ed6\u662f\u5728\u54ea\u91cc\u88ab\u201c\u5b9a\u4e49\u201d\u7684\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u548c\u201c\u4f7f\u7528\u5b9a\u4e49\u201d\u662f\u4e24\u4e2a\u4e92\u9006\u7684\u6620\u5c04\u3002\u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c\u4ed6\u4eec\u90fd\u4e0d\u662f\u4e00\u4e00\u6620\u5c04\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u53ef\u4ee5\u88ab\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u91cd\u590d\u4f7f\u7528\uff0c\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e5f\u53ef\u80fd\u4f7f\u7528\u5230\u4e86\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u6620\u5c04 \u7531\u4e8e\u6307\u4ee4\u5728\u4ed6\u7684\u6e90\u64cd\u4f5c\u6570\u4e2d\u6307\u5b9a\u4e86\u64cd\u4f5c\u6570\u6765\u81ea\u54ea\u4e2a\u5bc4\u5b58\u5668\uff0c\u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\u662f IR \u5929\u751f\u81ea\u5e26\u7684\uff0c\u76f4\u63a5\u901a\u8fc7 IR \u8282\u70b9\u7684 op \u6210\u5458\u51fd\u6570\uff0c\u5c31\u80fd\u67e5\u5230\u4ed6\u4f7f\u7528\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\uff08\u6216\u5e38\u6570\uff09\u3002 llvm::Instruction *pi = ...; for (llvm::Use &U: pi->operands()) { llvm::Value *v = U.get(); // v \u4f7f\u7528\u4e86 pi } \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04 \u800c\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff0c\u5c31\u9700\u8981\u6211\u4eec\u81ea\u5df1\u6784\u5efa\u4e86\u3002 \u5e78\u8fd0\u7684\u662f\uff0cLLVM \u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u4fbf\u7684\u5206\u6790\u5de5\u5177\uff0c\u6765\u81ea\u52a8\u6784\u5efa\u8fd9\u4e2a\u5173\u7cfb\uff1a def-use pass\u3002 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM \u4e2d\u7684 pass\uff0c\u662f\u6307\u4e00\u7ec4\u5bf9 IR \u8fdb\u884c\u64cd\u4f5c\u7684\u51fd\u6570\u3002pass \u5206\u4e3a\u5206\u6790\u7c7b pass \u548c\u4f18\u5316\u7c7b pass\u3002 \u5206\u6790\u7c7b pass \u53ea\u662f\u5e2e\u52a9\u6211\u4eec\u89c2\u5bdf IR\uff0c\u83b7\u5f97\u67d0\u4e9b\u6982\u62ec\u4fe1\u606f\uff0c\u5e76\u4e0d\u4fee\u6539 IR\u3002\u73b0\u5728\u6211\u4eec\u8981\u7528\u7684 def-use pass \u5c31\u5c5e\u4e8e\u5206\u6790\u7c7b pass\uff0c\u4ed6\u901a\u8fc7\u4e00\u6b21\u904d\u5386\u627e\u5230\u6240\u6709\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\u5173\u7cfb\u3002\u53ea\u8981 IR \u4e0d\u4fee\u6539\uff0c\u5c31\u53ef\u4ee5\u7f13\u5b58\u4e4b\u524d\u7684\u7ed3\u679c\uff0c\u4f9b\u540e\u6765\u8005\u91cd\u590d\u4f7f\u7528\u3002 \u4f18\u5316\u7c7b pass \u53ef\u4ee5\u4fee\u6539 IR \u7684\u8282\u70b9\uff0c\u4fee\u6539 IR \u539f\u6709\u7684\u7ed3\u6784\uff0c\u4f8b\u5982\u4e4b\u524d\u63d0\u5230\u7684 mem2reg pass \u5c31\u5c5e\u4e8e\u6b64\u7c7b\uff0c\u4ed6\u4f1a\u628a\u6240\u6709\u80fd\u4f18\u5316\u7684 alloca + store \u4fee\u6539\u6210\u9759\u6001\u5355\u8d4b\u503c\u7684\u5bc4\u5b58\u5668\u3002\u7531\u4e8e\u4f1a\u4fee\u6539 IR\uff0c\u53ef\u80fd\u5bfc\u81f4\u67d0\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u5931\u6548\uff0c\u4e0b\u6b21\u518d\u7528\u5230\u65f6\u9700\u8981\u91cd\u8dd1\u3002 \u533a\u522b\uff1a \u5206\u6790\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u5206\u6790\u7ed3\u679c\u7c7b\u578b\u3002\u4f8b\u5982\u5bf9\u4e8e def-use pass\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a Analysis \u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u4e2d\u7ef4\u62a4\u4e86\u4e00\u4e2a \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d \u7684\u53cc\u5411\u6620\u5c04\uff0c\u6211\u4eec def-use pass \u5206\u6790\u5f97\u5230\u7ed3\u679c\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u6620\u5c04\u6765\u67e5\u8be2\u3002 \u4f18\u5316\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u4e5f\u662f\u4e00\u6bb5 IR\uff0c\u88ab\u6539\u53d8\u540e\u7684 IR\u3002LLVM \u5b9e\u73b0\u4f18\u5316\uff0c\u5c31\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u4f18\u5316 pass \u7684\u7ec4\u5408\u5b8c\u6210\u7684\u3002\u6709\u65f6\uff0c\u4f18\u5316 pass \u4f1a\u9700\u8981\u4e00\u4e9b\u5206\u6790\u7684\u7ed3\u679c\uff0c\u624d\u80fd\u8fdb\u884c\uff0c\u56e0\u6b64\u4f18\u5316 pass \u6709\u65f6\u4f1a\u8bf7\u6c42\u4e00\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\uff0cLLVM \u4f1a\u68c0\u67e5\u8fd9\u4e2a\u5206\u6790\u4e4b\u524d\u6709\u6ca1\u6709\u8fdb\u884c\u8fc7\uff0c\u5982\u679c\u6709\uff0c\u5c31\u4f1a\u590d\u7528\u4e0a\u6b21\u5206\u6790\u7684\u7ed3\u679c\uff0c\u4e0d\u4f1a\u91cd\u65b0\u5206\u6790\u6d6a\u8d39\u65f6\u95f4\u3002\u4f18\u5316 pass \u5728\u4fee\u6539\u4e86 IR \u540e\uff0c\u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6807\u5fd7\u4f4d\uff0c\u8868\u793a IR \u4fee\u6539\u540e\uff0c\u54ea\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u5931\u6548\u3002\u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u5c31\u8fd4\u56de all \u5427\uff1a\u672c\u4f18\u5316 pass \u4fee\u6539\u8fc7 IR \u540e\u6240\u6709\u4e4b\u524d\u5206\u6790 pass \u7f13\u5b58\u7684\u7ed3\u679c\u90fd\u4f1a\u5931\u6548\u3002 \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\u662f\u5426\u53ef\u4ee5\u88ab\u4f18\u5316\u6389\uff1f\u68c0\u6d4b\u4ed6\u6709\u6ca1\u6709\u88ab\u522b\u4eba\u201c\u4f7f\u7528\u201d\uff1a\u4e5f\u5c31\u662f\u67e5\u8be2\u4ed6\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\uff0c\u5982\u679c\u53d1\u73b0\u201c\u4f7f\u7528\u8005\u5217\u8868\u201d\u4e3a\u7a7a\uff0c\u5c31\u8bf4\u660e\u8be5\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\u6ca1\u4eba\u4f7f\u7528\uff0c\u53ef\u4ee5\u4f18\u5316\u6389\u3002 LLVM IR \u6848\u4f8b\u5206\u6790 \u4ee5\u4e0b\u662f\u4e00\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u53ca\u5176\u6240\u5bf9\u5e94\u7684 LLVM IR \u6c47\u7f16\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u770b\u8d77\u6765\u597d\u590d\u6742\uff01\u8ba9\u6211\u4eec\u4e00\u884c\u4e00\u884c\u6765\u89e3\u8bfb\uff1a ; ModuleID = 'a.cpp' \u8fd9\u79cd\u4ee5\u5206\u53f7\u5f00\u5934\u7684\uff0c\u5c31\u662f IR \u6c47\u7f16\u8bed\u6cd5\u4e2d\u7684\u6ce8\u91ca\uff0c\u5206\u53f7\u540e\u9762\u7684\u4e1c\u897f\u4f1a\u88ab\u65e0\u89c6\uff0c\u4e0d\u5f71\u54cd\u5b9e\u9645\u7ed3\u679c\u3002\u5c31\u548c C \u8bed\u8a00\u7684 // \u4e00\u6837\uff0c\u5c5e\u4e8e\u884c\u6ce8\u91ca\u3002 Clang \u751f\u6210\u7684 IR \u6c47\u7f16\u6709\u65f6\u5e26\u6709\u6ce8\u91ca\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u7ed9\u4eba\u770b\u7684\uff0c\u5e76\u4e0d\u5f71\u54cd\u540e\u7aef\u7684\u89e3\u6790\u3002\u8fd9\u91cc\u7684\u6ce8\u91ca\u5f88\u660e\u663e\u662f\u5728\u63d0\u793a\uff0c\u8be5\u6c47\u7f16\u662f\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u7684\uff1f\u662f\u4e00\u4e2a\u53eb a.cpp \u7684\u6587\u4ef6\uff0c\u4f46\u4ed6\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u529b\uff0c\u53ea\u662f\u7ed9\u8bfb\u6c47\u7f16\u7684\u4f60\u6211\u770b\u3002 source_filename = \"a.cpp\" target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f \u8fd9\u624d\u662f\u771f\u6b63\u5bf9 LLVM \u4e2d\u7aef\u6709\u6548\u529b\u7684\u4e1c\u897f\uff0c\u4ed6\u8d4b\u503c\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u63d0\u793a\u8be5 IR \u6c47\u7f16\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u3002\u8fd9\u4e2a source_filename \u5c5e\u6027\uff0c\u662f\u7531 Clang \u5728\u751f\u6210 IR \u6c47\u7f16\u65f6\uff0c\u4e3b\u52a8\u52a0\u4e0a\u544a\u77e5 LLVM \u540e\u7aef\u7684\u3002\u4e5f\u662f\u4e3a\u4e86\u65b9\u4fbf\u8c03\u8bd5\uff0c\u4f8b\u5982\u5f53 LLVM \u4e2d\u7aef\u4e2d\u89e6\u53d1\u4e86\u62a5\u9519\uff0c\u4ed6\u53ef\u4ee5\u4ee5\u8fd9\u4e2a\u6587\u4ef6\u540d\u6765\u63d0\u793a\u7528\u6237\u3002 target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" \u8fd9\u91cc\u6307\u5b9a\u7684\u662f\u5173\u4e8e\u201c\u76ee\u6807\u5e73\u53f0\u201d\u7684\u4e00\u4e9b\u4fe1\u606f\uff0c\u5206\u4e3a\u4e24\u4e2a\u90e8\u5206\u3002 \u76ee\u6807\u5e73\u53f0\u6307\u7684\u662f\u5f53\u524d\u6e90\u7801\u8981\u7f16\u8bd1\u5230\u4ec0\u4e48\u786c\u4ef6\u4e0a\u6267\u884c\uff0c\u6bd4\u5982\u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u76ee\u6807\u5e73\u53f0\u5c31\u662f x86\u3002 \u5176\u4e2d target triple \u662f\u6307\u5b9a\u7684\u76ee\u6807\u5e73\u53f0\u7684\u540d\u5b57\uff0c\u8fd9\u91cc\u6211\u4eec\u662f x86_64-pc-linux-gnu \uff0c\u8868\u793a 64 \u4f4d x86 \u67b6\u6784\uff0c\u684c\u9762\u7aef\uff0cLinux \u7cfb\u7edf\uff0cGNU \u7f16\u8bd1\u5668\u63a5\u53e3\u3002\u4e0d\u540c\u7684 target triple \u4f1a\u5f71\u54cd\u6700\u7ec8\u751f\u6210\u7684\u6c47\u7f16\u4e2d\u51fd\u6570\u8c03\u7528\u7ea6\u5b9a\u3001C++ \u51fd\u6570\u540d\u91cd\u7ec4\u7b49\u7ec6\u8282\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a triple \u5c31\u662f\u6211\u4eec\u5e38\u8bf4\u7684 ABI\uff08\u4e8c\u8fdb\u5236\u5e94\u7528\u7a0b\u5e8f\u63a5\u53e3\uff09\u3002 \u4f8b\u5982\uff0c\u5728 Windows \u4e0a\u4f7f\u7528 clang \uff0c\u53ef\u80fd\u5f97\u5230 target triple \u662f x86_64-pc-windows-msvc \uff08\u5982\u679c\u4f60\u662f MSVC \u7f16\u8bd1\u5668\uff09\u6216\u8005 x86_64-pc-windows-gnu \uff08\u5982\u679c\u4f60\u662f MinGW \u7f16\u8bd1\u5668\uff09\uff0c\u4ea7\u751f\u7684 C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u4f1a\u6709\u4e0d\u540c\u3002\u5728 MacOS \u4e0a\u8fd8\u4f1a\u5f97\u5230 x86_64-apple-darwin \u6216 aarch64-apple-darmin \u3002 \u4e0d\u540c\u7684\u64cd\u4f5c\u7cfb\u7edf\u548c\u786c\u4ef6\uff0c\u90fd\u4f1a\u6709\u4e0d\u540c\u7684 ABI\uff0c\u4f8b\u5982 Linux \u5728 x86_64 \u4e0a\u7684 ABI \u89c4\u5b9a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7531 rdi \u4f20\u5165\uff0c\u800c Windows \u5219\u662f rcx \u3002\u8fd9\u4e9b\u7ec6\u8282\u90fd\u662f\u7531 target triple \u786e\u5b9a\u7684\u3002 target datalayout \u5219\u662f\u6307\u5b9a\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u7c7b\u578b\u5927\u5c0f\u548c\u5e03\u5c40\u7b49\u4fe1\u606f\uff0c\u4f8b\u5982\u6307\u9488\u5927\u5c0f\u3001\u5bf9\u9f50\u65b9\u5f0f\u7b49\u3002\u4f8b\u5982\u5728 x86_64-pc-linux-gnu \u8fd9\u4e2a ABI \u4e0a\uff0c long \u662f 64 \u4f4d\u3002\u800c\u5728 x86_64-pc-windows-msvc \u4e0a\uff0c long \u662f 32 \u4f4d\u3002\u8fd9\u4e9b\u4fe1\u606f\u4f1a\u5f71\u54cd\u540e\u7aef\u4ea7\u751f\u6c47\u7f16\u7684\u5185\u5b58\u5e03\u5c40\uff0c\u56e0\u6b64\uff0cIR \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 target datalayout \u662f\u4e00\u4e2a\u5f88\u957f\u7684\u5b57\u7b26\u4e32\uff0c\u91cc\u9762\u6709\u591a\u4e2a\u7531 - \u5206\u9694\u7684\u5b57\u6bb5\u3002\u6bcf\u4e2a\u5b57\u6bb5\u53ef\u4ee5\u5206\u522b\u7528\u6765\u63cf\u8ff0\u6307\u9488\u3001\u6574\u578b\u3001\u6d6e\u70b9\u578b\u3001\u77e2\u91cf\u3001\u6570\u7ec4\u3001\u7ed3\u6784\u4f53\u3001\u8054\u5408\u4f53\u7b49\u7684\u5927\u5c0f\u548c\u5185\u5b58\u5e03\u5c40\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 \uff0c\u6211\u4eec\u9996\u5148\u6309 - \u62c6\u5206\uff0c\u5f97\u5230\u6bcf\u4e00\u4e2a\u5b50\u5b57\u6bb5\u3002 e // \u8868\u793a\u76ee\u6807\u5e73\u53f0\u7684\u5b57\u8282\u5e8f\uff0ce=\u5c0f\u7aef\uff0cE=\u5927\u7aef m:e // \u8868\u793a C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u91c7\u7528\u4f55\u79cd\u673a\u5236\uff0ce=ELF\u98ce\u683c\uff0cw=Windows\u98ce\u683c\u2026\u2026\u7b49 p270:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p271:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p272:64:64 // \u6307\u9488\u5927\u5c0f 64 \u4f4d\uff0c\u5bf9\u9f50\u5230 64 \u4f4d i64:64 // __int64 \u91c7\u7528 64 \u4f4d\u6765\u5b58\u50a8 i128:128 // __int128 \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 f80:128 // long double \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 n8:16:32:64 // \u6307\u5b9a\u54ea\u4e9b\u662f\u76ee\u6807 CPU \u539f\u751f\u7684\u7c7b\u578b\u5927\u5c0f\uff0c\u5bf9\u4e8e 64 \u4f4d x86 \u6765\u8bf4\uff0c\u5206\u522b\u6709 8 \u4f4d\u300116 \u4f4d\u300132 \u4f4d\u300164 \u4f4d\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u90fd\u5199\u4e0a S128 // \u6808\u6307\u9488\uff08rsp\uff09\u5bf9\u9f50\u5230 128 \u4f4d\uff0816 \u5b57\u8282\uff09\uff0c\u8fd9\u662f 64 \u4f4d x86 ABI \u6240\u8981\u6c42\u7684 target datalayout \u7684\u8be6\u7ec6\u8bed\u6cd5\uff0c\u53ef\u4ee5\u53c2\u8003 LLVM \u5b98\u65b9\u6587\u6863 \u3002 270\u3001271\u3001272 \u662f\u4e09\u4e2a\u679a\u4e3e\u503c\uff0c\u5206\u522b\u8868\u793a PTR32_SPTR \u3001 PTR32_UPTR \u548c PTR64 \uff0c\u8868\u793a\u4e0d\u540c\u7684\u6307\u9488\u7c7b\u578b\u3002\u524d\u4e24\u4e2a\u662f\u56e0\u4e3a x86_64 \u67b6\u6784\u4f9d\u7136\u652f\u6301\u4ee5 32 \u4f4d\u5bc4\u5b58\u5668\u505a\u5730\u5740\u8bbf\u95ee\u5185\u5b58\uff08\u975e\u5e38\u611a\u8822\u7684\u8bbe\u5b9a\uff0c\u8bf7\u5ffd\u89c6\uff09\uff0c\u540e\u9762\u7684 PTR64 \u624d\u662f\u6211\u4eec\u6b63\u5e38\u4f7f\u7528\u7684 64 \u4f4d\u6307\u9488\u3002\u679a\u4e3e\u7684\u5b9a\u4e49\u8bf7\u770b llvm/lib/Target/X86/X86.h \u3002 define \u5b9a\u4e49\u51fd\u6570 \u7ee7\u7eed\u770b\u4e0b\u53bb: ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { ... } \u9996\u5148\uff0c\u4ee5\u5206\u53f7\u5f00\u5934\u7684 ; Function Attrs: ... \u662f\u6ce8\u91ca\uff0c\u53ef\u4ee5\u5ffd\u7565\u3002 \u6ce8\u91ca\u91cc\u9762\u7684 mustprogress noinline ... \u7b49\uff0c\u8868\u793a\u7684\u662f\u4e0b\u9762\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u5c5e\u6027\u201d\u3002\u4f46\u662f\u6ce8\u91ca\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u679c\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u4f5c\u7528\uff0c\u771f\u6b63\u8bbe\u7f6e\u4e86\u5c5e\u6027\u7684\u662f\u66f4\u4e0b\u9762\u7684 attributes #0 \u6307\u4ee4\uff0cClang \u751f\u6210\u4e00\u4e2a\u6ce8\u91ca\u53ea\u662f\u8ba9\u4f60\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u4e0d\u7528\u8dd1\u5230\u4e0b\u9762\u624d\u80fd\u770b\u5230\u5c5e\u6027\u3002 \u90a3\u4e48\uff0c\u53ea\u5269\u4e0b\u51fd\u6570\u7684\u5b9a\u4e49\u4e86\uff1a define dso_local noundef i32 @main() #0 { ... } define \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u51fd\u6570\u7684\u5b9a\u4e49\u3002 dso_local \u662f\u51fd\u6570 main \u7684\u4fee\u9970\u7b26\uff0c\u542b\u4e49\u76f8\u5f53\u4e8e extern \u8868\u793a\u8be5\u53d8\u91cf\u4e3a\u5bfc\u51fa\u7b26\u53f7\uff0c\u4e14\u8981\u6c42\u7b26\u5408 ODR \u89c4\u5219\u3002\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u610f\u5473\u7740\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u8bbe\u6807\u8bb0\u8be5\u51fd\u6570\u6216\u53d8\u91cf\u88ab\u89e3\u6790\u4e3a\u540c\u4e00\u94fe\u63a5\u5355\u5143\u5185\u7684\u7b26\u53f7\uff0cdso\u4ee3\u8868\u52a8\u6001\u5171\u4eab\u5bf9\u8c61\uff08dynamic shared object\uff09\uff0c\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 noundef \u662f\u8fd4\u56de\u7c7b\u578b i32 \u7684\u4fee\u9970\u7b26\uff0c\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u4f1a\u8fd4\u56de\u4e00\u4e2a\u672a\u5b9a\u4e49\u7684\u503c\uff0c\u6ce8\u610f noundef \u4fee\u9970\u7684\u662f\u53f3\u8fb9\u7684\u8fd4\u56de\u7c7b\u578b i32 \u800c\u4e0d\u662f\u51fd\u6570\u672c\u8eab\u3002\u8fd9\u4e2a\u5c5e\u6027\u53ef\u4ee5\u7528\u4e8e\u5e2e\u52a9\u7f16\u8bd1\u5668\u6392\u9664\u4e00\u4e9b\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e5f\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 i32 \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 int \u3002 @main \u662f\u51fd\u6570\u540d\u5b57\uff0c\u5176\u4e2d @ \u662f\u6240\u6709\u51fd\u6570\u540d\u7684\u56fa\u6709\u524d\u7f00\uff0c\u540e\u9762\u7684 main \u5c31\u662f\u6211\u4eec\u5f53\u524d\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u51fd\u6570\u540d\u5b57\u540e\u9762\u7d27\u63a5\u7740\u7684 () \u8868\u793a\u53c2\u6570\u5217\u8868\uff0c\u6b64\u5904\u6211\u4eec\u7684 main \u51fd\u6570\u521a\u597d\u6ca1\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u6240\u4ee5\u662f\u4e00\u4e2a\u7a7a\u7684\u62ec\u53f7\uff08\u7a0d\u540e\u6211\u4eec\u4f1a\u770b\u4e00\u4e2a\u6709\u53c2\u6570\u7684\u6848\u4f8b\uff09\u3002 #0 \u8868\u793a\u8be5\u51fd\u6570\u7684\u7f16\u53f7\uff0c\u5c31\u548c\u5bc4\u5b58\u5668\u7f16\u53f7\u4e00\u6837\uff0c\u6240\u6709\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u4ece 0 \u5f00\u59cb\u7684\u7f16\u53f7\u3002 {} \u4e2d\u7684\u5185\u5bb9\uff0c\u5c31\u662f\u51fd\u6570\u5757\u5185\u90e8\u7684 IR \u4e86\uff0c\u8fd9\u4e9b\u662f main \u51fd\u6570\u7684\u51fd\u6570\u4f53\uff0c\u6bcf\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u5c31\u4f1a\u6267\u884c\u5176\u4e2d\u7684\u6240\u6709 IR \u8282\u70b9\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7684\u5b9a\u4e49\u4e5f\u662f\u4e00\u4e2a IR \u8282\u70b9\uff0c\u540c\u6837\u6709\u4ece 0 \u5f00\u59cb\u9012\u589e\u7684\u201c\u5bc4\u5b58\u5668\u7f16\u53f7\u201d\uff0c\u4f46\u4ed6\u5e76\u4e0d\u662f\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7528 #n \u8868\u793a\uff0c\u800c\u5bc4\u5b58\u5668\u7528 %n \u8868\u793a\u3002 define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } \u8ba9\u6211\u4eec\u4e00\u6761\u4e00\u6761\u89e3\u6790\u51fd\u6570\u4f53\u5185\u7684\u8fd9\u4e9b IR \u8282\u70b9\u5427\uff01 alloca \u6307\u4ee4 %1 = alloca i32, align 4 %1 \u8868\u793a\u4e86\u5bc4\u5b58\u5668\u7684\u540d\u5b57\uff0c = \u53f3\u8fb9\u5c31\u662f\u8be5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u3002\u8fd9\u91cc\u8981\u4ecb\u7ecd LLVM IR \u7684\u4e00\u4e2a\u91cd\u8981\u89c4\u5219\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff01\u5bc4\u5b58\u5668\u4e00\u65e6\u5b9a\u4e49\uff08\u8d4b\u503c\uff09\u8fc7\u4e00\u6b21\u540e\u5c31\u4e0d\u80fd\u518d\u4fee\u6539\uff0c\u9664\u975e\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u5bc4\u5b58\u5668\u3002\u4e3a\u4e86\u4ea7\u751f\u53ef\u4ee5\u52a8\u6001\u4fee\u6539\u7684\u53d8\u91cf\uff0cClang \u5fc5\u987b\u4f7f\u7528 alloca \u6307\u4ee4\u5206\u914d\u4e00\u5757\u201c\u6808\u5185\u5b58\u201d\uff0c\u6808\u5185\u5b58\u603b\u662f\u53ef\u8bfb\u5199\u7684\u3002 alloca \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6808\u5185\u5b58\u5206\u914d\u6307\u4ee4\uff0c\u4ed6\u4f1a\u5728\u5f53\u524d\u51fd\u6570 main \u7684\u6808\u4e0a\u5206\u914d\u4e00\u4e2a\u7c7b\u578b\u4e3a i32 \u7684\u5185\u5b58\u7a7a\u95f4\u3002 i32 \u6307\u5b9a\u4e86\u6808\u5185\u5b58\u8981\u5206\u914d\u7684\u7c7b\u578b\u662f \u201c32 \u4f4d\u6574\u6570\u201d\u3002\u6ce8\u610f LLVM IR \u662f\u4e00\u4e2a\u6709\u7c7b\u578b\u7684 IR\uff0c\u6b64\u5904\u6211\u4eec\u9700\u8981\u6307\u5b9a\u53d8\u91cf\u7684\u5b9e\u9645\u7c7b\u578b i32 \u800c\u4e0d\u662f\u6307\u5b9a\u4e00\u4e2a 4 \u8868\u793a\u5927\u5c0f\u3002 align 4 \u8868\u793a\u8fd4\u56de\u5730\u5740\u6240\u8981\u6c42\u7684\u5bf9\u9f50\u5ea6\uff0c\u6839\u636e C \u8bed\u8a00\u89c4\u5219\u8981\u6c42\uff0c int \u7c7b\u578b\u5fc5\u987b\u5bf9\u9f50\u5230 4 \u5b57\u8282\uff0c\u56e0\u6b64\u6307\u5b9a align 4 \u3002\u5176\u4ed6\u8bed\u8a00\u82e5\u6ca1\u6709\u6b64\u89c4\u5b9a\uff0c\u4e5f\u53ef\u4ee5\u751f\u6210 align 1 \u5728 IR \u4e2d\u3002 alloca \u4f1a\u201c\u8fd4\u56de\u201d\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u521d\u59cb\u5316 %1 \u3002\u7c7b\u578b\u662f i32* \uff08\u8fd9\u91cc\u7684 * \u548c C \u8bed\u8a00\u7684\u6307\u9488\u4e00\u6837\uff0c\u8868\u793a\u524d\u9762\u7c7b\u578b\u7684\u6307\u9488\u7c7b\u578b\uff09\uff0c\u8be5\u6307\u9488\u6307\u5411\u6808\u4e0a\u5206\u914d\u597d\u7684 i32 \u53d8\u91cf\u3002 %1 \u5bc4\u5b58\u5668\u5c31\u8fd9\u6837\u88ab\u5b9a\u4e49\u4e3a\u5b9e\u9645\u53d8\u91cf\u7684\u5730\u5740\u503c\u3002 \u8fd9\u6761 IR \u6307\u4ee4\u6267\u884c\u5b8c\u6bd5\u540e\uff0c %1 \u5bc4\u5b58\u5668\u91cc\u7684\u503c\uff0c\u5c31\u662f\u6307\u5411\u7684\u6307\u9488\u3002\u7531\u4e8e\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c %1 \u8fd9\u4e2a\u6307\u9488\u672c\u8eab\u5728\u51fd\u6570\u9000\u51fa\u524d\uff0c\u5c06\u6c38\u8fdc\u4e0d\u53d8\u3002\u4f46\u662f\u6307\u9488\u4e0d\u80fd\u53d8\uff0c\u6307\u9488\u6307\u5411\u7684\u503c\u53ef\u4ee5\u53d8\uff0c\u6240\u4ee5\u4e4b\u540e\u53ea\u9700\u8981\u4ee5\u6307\u9488\u5f62\u5f0f\u8bfb\u5199\u5176\u6307\u5411\u7684\u5730\u5740\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u53ef\u53d8\u7684\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u53d7\u5236\u4e8e\u5bc4\u5b58\u5668\u4e0d\u53ef\u53d8\u3002 \u5728 LLVM IR \u5c42\u9762\uff0c\u4e0d\u5b58\u5728\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \u3002\u6216\u8005\u8bf4\uff0c\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u4fdd\u5b58\u7684\u672c\u6765\u5c31\u662f\u4ed6\u4eec\u7684\u5730\u5740\uff08\u901a\u8fc7 alloca \u8fd4\u56de\u7684\uff09\u3002\u6b63\u5e38\u8d4b\u503c\u548c\u8bfb\u53d6\u53d8\u91cf\u7684\u64cd\u4f5c\u90fd\u662f\u901a\u8fc7 store \u548c load \u95f4\u63a5\u901a\u8fc7\u53d8\u91cf\u7684\u6307\u9488\u6765\u4fee\u6539\u53d8\u91cf\u7684\uff0c\u5bc4\u5b58\u5668\u672c\u8eab\u4e0d\u53ef\u53d8\u3002\u5982\u679c\u4f7f\u7528\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u5c31\u662f\u539f\u5c01\u4e0d\u52a8\u628a\u5bc4\u5b58\u5668\u7684\u6307\u9488\u503c\u8d4b\u7ed9\u4f60\u800c\u5df2\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u7684\u7c7b\u578b\u672c\u8eab\u5c31\u662f\u6307\u9488\uff08\u6bd4\u5982 char * \uff09\uff0c\u90a3\u4e48\u901a\u8fc7 alloca i8* \u5b9a\u4e49\u7684\u5bc4\u5b58\u5668\u7684\u7c7b\u578b\u5c31\u4f1a\u662f\u4e00\u4e2a\u4e8c\u7ea7\u6307\u9488\uff08 i8** \uff09\u3002 C++ \u5f15\u7528\u5728 LLVM IR \u5c42\u9762\u540c\u6837\u4e5f\u4f1a\u53d8\u6210\u6307\u9488\u7c7b\u578b\u7684\u53d8\u91cf\u3002\u6ce8\u610f\uff0c\u6211\u53ea\u662f\u8bf4 C++ \u5f15\u7528\u548c\u6307\u9488\u4f1a\u5728 LLVM \u4e2d\u4f1a\u540c\u6837\u53d8\u6210\u6307\u9488\u7c7b\u578b\uff0c\u5e76\u4e0d\u662f\u8bf4\u5728 Clang \u524d\u7aef\u91cc\u5f15\u7528\u548c\u6307\u9488\u6ca1\u533a\u522b\u3002 \u6240\u4ee5\uff0c\u8fd9\u91cc\u7684 %1 \u548c %2 \u5176\u5b9e\u662f\u5bf9\u5e94\u6e90\u7801\u4e2d\u7684 a \u548c b \u53d8\u91cf\uff08\u7684\u6307\u9488\uff09\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e int * %1 = alloca(4) \u3002 store \u6307\u4ee4 \u7ee7\u7eed\u63a5\u7740\u770b\uff1a store i32 1, ptr %1, align 4 \u8fd9\u662f\u4e00\u6761 store \u6307\u4ee4\u3002 \u6307\u4ee4\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570 i32 1 \u8868\u793a\u8981\u5b58\u5165\u7684\u503c\uff0c\u8fd9\u91cc\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u5e38\u6570 1 \u3002LLVM IR \u4e2d\u6307\u4ee4\u6240\u6709\u7684\u53c2\u6570\u90fd\u9700\u8981\u5728\u524d\u9762\u6307\u5b9a\u7c7b\u578b\u540d\uff0c\u6211\u4eec\u8981\u5199\u5165\u7684 a \u53d8\u91cf\u662f int \u4e5f\u5c31\u662f i32 \u7c7b\u578b\uff0c\u6240\u4ee5\u7528 i32 \u4fee\u9970\u8981\u5199\u5165\u7684\u503c 1 \u3002 \u7b2c\u4e8c\u4e2a\u53c2\u6570 ptr %1 \u8868\u793a\u8981\u5199\u5165\u5230\u7684\u5730\u5740\uff0c\u5fc5\u987b\u662f\u6307\u9488\u7c7b\u578b\u3002\u8fd9\u91cc\u7684 ptr \u662f i32* \u7684\u7b80\u5199\uff0c\u7b49\u4ef7\u4e8e i32* %1 \u3002\u7531\u4e8e\u521a\u624d %1 \u5b9a\u4e49\u4e3a alloca \uff0c\u4e5f\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\u4e86\u4e00\u4e2a\u53d8\u91cf\uff08C++ \u6e90\u7801\u4e2d\u7684 a \uff09\u3002 %1 \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u5176\u503c\u662f a \u7684\u5730\u5740\u3002\u6240\u4ee5\u6b64\u5904 store \u7684\u6548\u679c\u662f\u5f80\u53d8\u91cf a \u4e2d\u5199\u5165\u4e86\u4e00\u4e2a\u5e38\u6570 1 \u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 alloca \u548c\u7d27\u63a5\u7740\u7684 store \u8fd9\u4e24\u6761\u6307\u4ee4\uff0c\u8fde\u8d77\u6765\uff0c\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\uff08 alloca \uff09\u4e86\u4e00\u4e2a\u53d8\u91cf a \u4e4b\u540e\uff0c\u5411\u5176\u4e2d\u8d4b\u4e86\u4e00\u4e2a\u521d\u59cb\u503c 0 \u3002 \u6ce8\u610f\u5230\uff0c store \u5e76\u6ca1\u6709\u7528\u4e8e\u5b9a\u4e49\u4e00\u4e2a\u5bc4\u5b58\u5668\uff08\u4f8b\u5982 %1 = store ... \uff09\u3002 store \u6307\u4ee4\u6ca1\u6709\u201c\u8fd4\u56de\u503c\u201d\uff0c\u56e0\u6b64\u4ed6\u4e0d\u4f1a\u5b9a\u4e49\u4efb\u4f55\u5bc4\u5b58\u5668\uff1b store \u672c\u8eab\u662f\u56e0\u4e3a\u5176\u5199\u5165\u4ea7\u751f\u7684\u526f\u4f5c\u7528\u800c\u5b58\u5728\uff0c\u4e0d\u9700\u8981\u6709\u4eba\u201c\u4f7f\u7528\u201d\u4ed6\u7684\u503c\u3002 \u56e0\u4e3a\u6709\u526f\u4f5c\u7528\uff0c store \u5c31\u4e0d\u80fd\u7b80\u5355\u5730\u88ab def-use \u5206\u6790 pass \u4f18\u5316\u6389\u4e86\uff0c\u6240\u4ee5\u9700\u8981\u5148\u8fc7\u4e00\u4e2a mem2reg pass \u628a\u80fd\u8f6c\u5316\u6389\u7684 store \u5c3d\u53ef\u80fd\u8f6c\u6210\u5bb9\u6613\u4f18\u5316\u7684\u5bc4\u5b58\u5668\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b store i32 1, ptr %1, align 4 ; a = 1 store i32 2, ptr %2, align 4 ; a = 2 \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e *%1 = 1 \u3002 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 \u5982\u679c\u4f60\u53ea\u662f alloca \uff0c\u800c\u6ca1\u6709\u5f80\u91cc\u9762 store \u8d4b\u503c\u8fc7\u7684\u8bdd\uff0c\u90a3\u4e48\u8be5\u6808\u53d8\u91cf\u7684\u503c\u662f\u201c\u672a\u5b9a\u4e49\u503c\u201d\uff0c\u5728 C++ \u6807\u51c6\u4e2d\uff0c\u8bbf\u95ee\uff08 load \uff09\u4e00\u4e2a\u201c\u672a\u5b9a\u4e49\u503c\u201d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4f8b\u5982\uff1a int a; return a; // \u9519\u8bef\uff1aa \u672a\u521d\u59cb\u5316\uff0c\u91cc\u9762\u7684\u503c\u662f\u672a\u5b9a\u4e49\u503c\uff01 \u8bfb\u53d6\u6ca1\u6709\u521d\u59cb\u5316\u8fc7\u7684\u6808\u53d8\u91cf\uff0c\u5728 x86 \u548c ARM \u7b49\u5177\u4f53\u67b6\u6784\u4e2d\uff0c\u4f60\u53ef\u80fd\u4f1a\u8bfb\u5230\u5185\u5b58\u4e2d\u7684\u968f\u673a\u53d8\u91cf\u3002 \u5728 LLVM \u4e2d\uff0c\u8fd9\u7c7b\u5904\u4e8e\u672a\u521d\u59cb\u5316\u72b6\u6001\u7684\u503c\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u540d\u5b57\uff0c\u53eb\u201c\u6bd2\u503c\u201d\uff08poison value\uff09\u3002 \u6bd2\u503c\u4e0d\u662f C++ \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f\u786c\u4ef6\u67b6\u6784\u7684\u4e00\u90e8\u5206\uff0c\u800c\u662f LLVM \u4e2d\u7aef\u4eba\u4e3a\u5b9a\u4e49\u7684\uff08\u56e0\u4e3a\u5f88\u591a\u7cfb\u7edf\u7ea7\u8bed\u8a00\u90fd\u6709\u652f\u6301\u672a\u521d\u59cb\u5316\u7684\u5185\u5b58\uff0c\u77e5\u9053\u54ea\u4e9b\u503c\u662f\u4e0d\u53ef\u80fd\u7684\u6709\u52a9\u4e8e LLVM \u4f18\u5316\uff09\u3002 \u201c\u6bd2\u503c\u201d\u5e76\u4e0d\u662f\u968f\u673a\u503c\uff0c\u4ed6\u662f i32 \u8868\u793a\u7a7a\u95f4\u4e4b\u5916\u7684\u4e00\u4e2a\u7279\u6b8a\u503c\uff0c\u4e0d\u662f\u88ab 0 \u5230 4294967295 \u8303\u56f4\u5185\u7684\u4efb\u4f55\u6574\u6570\uff0c\u800c\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u7528\u4e8e\u6807\u8bc6\u201c\u672a\u5b9a\u4e49\u884c\u4e3a\u201d\u7684\u4e00\u4e2a LLVM \u4e2d\u624d\u6709\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u610f\u601d\u662f\u201c\u8fd9\u4e2a\u503c\u73b0\u5728\u4e0d\u80fd\u4f7f\u7528\u201d\u3002\u53ea\u4e0d\u8fc7\u5728\u8f6c\u6362\u4e3a\u5177\u4f53\u67b6\u6784\u7684\u6c47\u7f16\u4ee3\u7801\u540e\u5f80\u5f80\u4f1a\u53d8\u6210\u201c\u968f\u673a\u503c\u201d\u8fd9\u4e00\u5177\u4f53\u5b9e\u73b0\uff0c\u4f9d\u8d56\u8fd9\u4e00\u70b9\u7684\u540e\u679c\u662f\u672a\u5b9a\u4e49\u7684\u3002\uff08\u4f8b\u5982\u4f60\u4e0d\u80fd\u7528\u4e00\u4e2a\u201c\u672a\u521d\u59cb\u5316\u53d8\u91cf\u201d\u751f\u6210\u968f\u673a\u6570\uff0c\u5728\u9ad8\u4f18\u5316\u4e0b\u53ef\u80fd\u4ea7\u751f\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u800c\u4e14\u4e5f\u5e76\u4e0d\u4e00\u5b9a\u591f\u968f\u673a\uff09 \u6bd2\u503c\u7684\u7279\u70b9\uff1a alloca \u540e\u6ca1\u6709 store \u8fc7\u7684\u6808\u53d8\u91cf\u521d\u59cb\u5c31\u662f\u4e3a\u6bd2\u503c\u3002\u5982\u679c\u5c1d\u8bd5\u76f4\u63a5 load \u8fd9\u4e2a\u5730\u5740\uff0c\u90a3\u4e48 load \u8fd4\u56de\u7684\u5bc4\u5b58\u5668\u5c31\u548c\u521d\u59cb\u5316\u4e3a\u201c\u6bd2\u503c\u201d\u3002 \u6bd2\u503c\u4f1a\u611f\u67d3\u6240\u6709\u201c\u4f7f\u7528\u201d\u4e86\u4ed6\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982 %1 \u662f\u6bd2\u503c\uff0c\u90a3\u4e48 %2 = add %1, 1 \u4e5f\u662f\u6bd2\u503c\uff0c\u56e0\u4e3a %2 \u201c\u4f7f\u7528\u201d\u4e86\u7684 %1 \u662f\u6bd2\u503c\u3002 \u6807\u8bb0\u4e3a noundef \u7c7b\u578b\u7684\u53d8\u91cf\uff08\u4f8b\u5982 noundef i32 \uff09\uff0c\u5fc5\u987b\u4e0d\u80fd\u662f\u6bd2\u503c\uff0c\u5426\u5219\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u8fd4\u56de\u7c7b\u578b\u6807\u8bb0\u4e3a noundef \uff08\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5e94\u8fd4\u56de\u6bd2\u503c\uff09\u7684\u51fd\u6570\u8fd4\u56de\u4e86\u6bd2\u503c\uff0c\u90a3\u4e48\u5c31\u89e6\u53d1\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 load \u6307\u4ee4 %3 = load i32, ptr %1, align 4 ; \u52a0\u8f7d a %4 = load i32, ptr %2, align 4 ; \u52a0\u8f7d b load \u6307\u4ee4\u4ece\u5185\u5b58\u7684\u6307\u5b9a\u5730\u5740\u5904\u52a0\u8f7d\u4e00\u4e2a\u6307\u5b9a\u7c7b\u578b\u7684\u6570\u636e\uff0c\u8bfb\u53d6\u5230\u5bc4\u5b58\u5668\u4e2d\u3002 \u5206\u522b\u662f\u5bf9\u5e94\u52a0\u8f7d a \u548c b \u8fd9\u4e24\u4e2a\u53d8\u91cf\uff0c\u6765\u770b\u52a0\u8f7d a \u7684\u8fd9\u6761\u6307\u4ee4\uff1a %3 = load i32, ptr %1, align 4 i32 \u8868\u793a\u52a0\u8f7d\u4e00\u4e2a 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u8fd9\u4f1a\u628a = \u524d\u9762\u7684\u5bc4\u5b58\u5668 %3 \u5b9a\u4e49\u4e3a i32 \u7c7b\u578b\u7684\u3002 ptr %1 \u8868\u793a\u8981\u52a0\u8f7d\u7684\u5185\u5b58\u5730\u5740\uff0c\u6b64\u5904\u5730\u5740\u901a\u8fc7 %1 \u5bc4\u5b58\u5668\u6307\u5b9a\uff0c\u800c %1 \u88ab\u5b9a\u4e49\u4e3a alloca i32 \uff0c\u4e5f\u5c31\u662f\u4e00\u4e2a\u6808\u53d8\u91cf\u7684\u6307\u9488\uff0c\u6240\u4ee5\u6b64\u5904 load i32, ptr %1 \u5c31\u662f\u5728\u52a0\u8f7d\u8fd9\u4e2a\u6808\u53d8\u91cf\u7684\u503c\u3002 \u6ce8\u610f\u8fd9\u91cc\u7684\u53c2\u6570\u6307\u9488 %1 \u5fc5\u987b\u662f\u4e0e\u8981\u52a0\u8f7d\u7c7b\u578b i32 \u5bf9\u5e94\u7684\u6307\u9488\u7c7b\u578b i32* \uff0c\u800c alloca i32 \u8fd4\u56de\u7684\u6070\u597d\u662f i32* \u7c7b\u578b\u7684\u6307\u9488\uff0c\u7b26\u5408\u8981\u6c42\u3002 \u6b64\u5904 ptr %1 \u5b9e\u9645\u4e0a\u662f i32* %1 \u7684\u7b80\u5199\uff0c ptr \u662f\u4e00\u4e2a\u8bed\u6cd5\u7cd6\uff0c\u56e0\u4e3a\u524d\u9762 load i32 \u5df2\u7ecf\u6307\u5b9a\u4e86\u8981\u52a0\u8f7d\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u5177\u4f53\u7684\u6307\u9488\u7c7b\u578b i32* \u53ef\u4ee5\u7701\u7565\uff0c\u7528 ptr \u4ee3\u66ff\u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 \u7531\u4e8e\u4e4b\u524d\u5df2\u7ecf\u5f80 ptr %1 \u6307\u5411\u7684\u5730\u65b9\uff08\u5c40\u90e8\u53d8\u91cf a \uff09\u91cc store \u8fc7\u6574\u6570\u503c 1 \u4e86\uff0c\u6240\u4ee5\u8fd9\u91cc load \u51fa\u6765\u4e5f\u4f1a\u662f 1 \u3002 \u8fd9\u6837\u91cd\u590d\u7684 store \u548c load \u4f1a\u88ab\u540e\u7eed\u7684 LLVM \u4f18\u5316\u6389\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u7684 clang \u6ca1\u6709\u5f00\u542f\u4f18\u5316\uff08\u9ed8\u8ba4 -O0 \uff09\uff0c\u6240\u4ee5\u4f9d\u7136\u4fdd\u6301\u539f\u59cb\u7684 store \u548c load \u91cd\u590d\u52b3\u52a8\uff0c\u5fe0\u5b9e\u590d\u523b\u539f\u672c\u7684 C++ \u4ee3\u7801\u8bed\u4e49\u3002 \u56e0\u4e3a\u5f88\u591a\u8c61\u7259\u5854\u7262\u6e7f\u8981\u4e48\u201c\u547d\u4ee4\u884c\u8c03\u7528\u7f16\u8bd1\u201d\uff0c\u8981\u4e48 IDE \u662f\u9ed8\u8ba4\u7684\u201cDebug\u201d\u6a21\u5f0f\uff0c\u5b83\u4eec\u4e0d\u77e5\u9053\u53ef\u4ee5\u901a\u8fc7 -O \u9009\u9879\u5f00\u542f\u4f18\u5316\uff0c\u751a\u81f3\u6709\u4eba\u8ba4\u4e3a\u201c\u4f18\u5316\u201d\u662f\u4e0d\u6807\u51c6\u7684\uff0c\u8ba4\u4e3a\u4e0d\u5f00\u4f18\u5316\u7684 C++ \u624d\u80fd\u6d4b\u5f97\u771f\u5b9e\u6027\u80fd\u3002\u800c\u5b83\u4eec\u5bf9\u7f16\u8bd1\u5668\u7684\u7406\u89e3\u53c8\u662f\u7c97\u7cd9\u7684\u201c\u6ca1\u6709 AST\uff0c\u6ca1\u6709 IR\uff0c\u524d\u7aef\u89e3\u6790\u7684\u8fc7\u7a0b\u4e2d\u76f4\u63a5\u751f\u6210\u6c47\u7f16\u4ee3\u7801\u201d\uff0c\u6240\u4ee5\u624d\u4f1a\u628a C++ \u51fd\u6570\u5c40\u90e8\u53d8\u91cf\u548c\u4e00\u4e9b CPU \u540e\u7aef\u5177\u4f53\u5b9e\u73b0\u4e2d\u7684\u201c\u6808\u201d\u6df7\u4e3a\u4e00\u8c08\u3002\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u4f53\u5185\u5b9a\u4e49\u7684\u5c40\u90e8\u53d8\u91cf\uff08\u5f8b\u5e08\u7684\u8bf4\u6cd5\u662f\u201c\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u53d8\u91cf\u201d\uff0c\u5f97\u540d\u4e8e\u51fd\u6570\u4f5c\u7528\u57df\u9000\u51fa\u65f6\u4f1a\u81ea\u52a8\u6790\u6784\u548c\u91ca\u653e\u5185\u5b58\uff09\uff0c\u90fd\u53ef\u4ee5\u88ab\u4f18\u5316\u5230\u5bc4\u5b58\u5668\u4e2d\u3002\u8fd8\u6709\u4e00\u4e9b GPU \u76ee\u6807\u67b6\u6784\uff0c\u4f8b\u5982\u5728 CUDA \u4e2d\uff0c\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u6781\u591a\uff0c\u5c40\u90e8\u53d8\u91cf\u51e0\u4e4e\u603b\u662f\u53ef\u4ee5\u653e\u5230\u5728\u5bc4\u5b58\u5668\u4e0a\uff0c\u751a\u81f3\u5c40\u90e8\u6570\u7ec4\u53d8\u91cf\uff08\u5982\u679c\u4e0b\u6807\u8bbf\u95ee\u90fd\u662f\u5e38\u6570\uff09\u4e5f\u53ef\u4ee5\u653e\u5230\u5bc4\u5b58\u5668\u4e0a\u3002\u8981\u662f\u4e0d\u5f00\u5bc4\u5b58\u5668\u4f18\u5316\u5c31\u5168\u90e8\u8981\u6253\u7ffb\u5230\u5168\u5c40\u5185\u5b58\u4e86\uff0c\u4f1a\u53d8\u5f97\u548c\u5168\u5c40\u5185\u5b58\u4e00\u6837\u6162\uff01\u6240\u4ee5 nvcc \u54ea\u6015\u4e0d\u5f00 -O \u7684\u60c5\u51b5\u4e0b\u4e5f\u4f1a\u5c1d\u8bd5\u628a\u5c40\u90e8\u53d8\u91cf\u4f18\u5316\u5230\u786c\u4ef6\u5bc4\u5b58\u5668\u91cc\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %3 = *%1 \u3002 add \u6307\u4ee4 %5 = add nsw i32 %3, %4 LLVM \u4e2d\u6709\u52a0\u51cf\u4e58\u9664\u7684\u6307\u4ee4\uff0c\u5176\u4e2d add \u5c31\u662f\u5176\u4e2d\u8d1f\u8d23\u6574\u6570\u52a0\u6cd5\u8fd0\u7b97\u7684\u6307\u4ee4\uff0c\u4ed6\u63a5\u53d7\u4e24\u4e2a\u64cd\u4f5c\u6570\u505a\u53c2\u6570\u3002 add \u8868\u793a\u8fd9\u662f\u4e00\u6761\u52a0\u6cd5\u8fd0\u7b97\u6307\u4ee4\u3002 nsw \u662f\u4e00\u4e2a\u4fee\u9970\u7b26\uff0c\u53ef\u4ee5\u5148\u5ffd\u7565\u4e0d\u7ba1\u3002 i32 \u8868\u793a\u52a0\u6cd5\u64cd\u4f5c\u7684\u7c7b\u578b\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5728\u8fdb\u884c\u52a0\u6cd5\u524d\uff0c\u5fc5\u987b\u5148\u628a\u4e24\u8fb9\u7684\u6574\u6570\u7c7b\u578b\u8f6c\u6362\u5230\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u65e0\u6cd5\u76f8\u52a0\u3002 %3, %4 \u8868\u793a\u4e86\u52a0\u6cd5\u7684\u4e24\u4e2a\u64cd\u4f5c\u6570\uff0c\u8fd9\u4e24\u4e2a\u6570\u4f1a\u88ab\u52a0\u8d77\u6765\uff0c\u7ed3\u679c\u5b58\u5230 %5 \u5bc4\u5b58\u5668\u4e2d\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %5 = %3 + %4 \u3002 \u5728 Clang \u524d\u7aef\u4e2d\uff0c\u5982\u679c\u53d1\u73b0\u4e24\u8fb9\u7684\u7c7b\u578b\u5927\u5c0f\u4e0d\u540c\uff1a\u4f1a\u5148\u7528 sext \uff08\u6709\u7b26\u53f7\u6269\u5c55\uff09\u6216 zext \uff08\u65e0\u7b26\u53f7\u6269\u5c55\uff09\u6307\u4ee4\uff0c\u628a\u8f83\u5c0f\u90a3\u8fb9\u7684\u7c7b\u578b\uff0c\u8f6c\u6362\u5230\u4e24\u8005\u4e4b\u95f4\u6700\u5927\u7684\u90a3\u4e2a\u7c7b\u578b\u3002\u7136\u540e\u518d\u505a\u52a0\u6cd5\u3002\u5bf9\u4e8e\u6d6e\u70b9\u6570\u548c\u6574\u6570\u76f8\u52a0\u7684\u60c5\u51b5\uff0c\u5219\u662f\u5148\u628a\u6574\u6570\u8f6c\u6362\u4e3a\u6d6e\u70b9\u6570\u540e\u518d\u8c03\u7528\u6d6e\u70b9\u6570\u52a0\u6cd5 fadd \u3002\u603b\u4e4b\uff0cLLVM IR \u91cc\u6240\u6709\u7684\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\u90fd\u53d1\u751f\u5728\u76f8\u540c\u7c7b\u578b\u4e4b\u95f4\u3002 \u5bf9\u4e8e\u597d\u5947\u5b9d\u5b9d\uff1a nsw \u8868\u793a no signed wrap\uff0c\u610f\u601d\u662f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u8fd9\u4e2a\u662f\u6709\u7b26\u53f7\u52a0\u6cd5\uff0c\u5e76\u4e14\u4fdd\u8bc1\u4e0d\u4f1a\u6ea2\u51fa\u3002\u4e3a\u4ec0\u4e48\u4e0d\u4f1a\u6ea2\u51fa\uff1f\u56e0\u4e3a C++ \u6807\u51c6\u89c4\u5b9a\u201c\u6709\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u52a0\u6cd5\u5982\u679c\u53d1\u751f\u6ea2\u51fa\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u56de\u73af\uff08wrap\uff09\u201d\uff0c\u6240\u4ee5 Clang \u628a\u8fd9\u4e2a\u4fe1\u606f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u7528\u6237\u8fd9\u4e2a\u52a0\u6cd5\u5982\u679c\u6ea2\u51fa\u4e86\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cLLVM \u53ef\u4ee5\u5229\u7528\u8fd9\u4e00\u70b9\u6765\u4f18\u5316\uff01\u6362\u53e5\u8bdd\u8bf4\uff1a nsw \u8868\u793a\u5de6\u53f3\u4e24\u4e2a i32 \u4f5c\u4e3a\u6709\u7b26\u53f7\u6570\u76f8\u52a0\u5982\u679c\u6ea2\u51fa\u4f1a\u8fd4\u56de\u201c\u6bd2\u503c\u201d\u3002\u4f46\u662f C++ \u6807\u51c6\u53c8\u89c4\u5b9a\u65e0\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u6ea2\u51fa\u662f\u5fc5\u5b9a\u56de\u73af\uff0c\u4e0d\u4f1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6240\u4ee5\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b\u628a int \u66ff\u6362\u4e3a unsigned int \uff0c\u4f60\u4f1a\u53d1\u73b0 nsw \u6ca1\u4e86\uff0c\u56e0\u4e3a Clang \u77e5\u9053 C++ \u6807\u51c6\u5141\u8bb8 unsigned int \u52a0\u6cd5\u51fa\u73b0\u56de\u73af\u3002\u53e6\u5916\uff0c\u5982\u679c\u4f7f\u7528 Rust \u7684 i32 \u52a0\u6cd5\uff0c\u4e5f\u4f1a\u6ca1\u6709 nsw \uff0c\u56e0\u4e3a Rust \u6807\u51c6\u89c4\u5b9a\u6574\u6570\u65e0\u8bba\u6709\u6ca1\u6709\u7b26\u53f7\uff0c\u5176\u52a0\u6cd5\u6ea2\u51fa\u603b\u662f\u56de\u73af\uff0c\u4e0d\u4f1a\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u90a3\u4e48 LLVM \u540e\u7aef\u6536\u5230 Rust \u7f16\u8bd1\u5668\u4ea7\u751f\u7684 IR \u540e\uff0c\u5c31\u4e0d\u4f1a\u5047\u5b9a\u52a0\u6cd5\u4e0d\u4f1a\u6ea2\u51fa\u6765\u4f18\u5316\u4e86\u3002 \u8fd9\u6761\u6307\u4ee4\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 a + b \u8868\u8fbe\u5f0f\uff0c\u7528\u4e8e\u8ba1\u7b97\u4e24\u4e2a\u53d8\u91cf\u7684\u548c\uff0c\u8ba1\u7b97\u7ed3\u679c\u5b58\u5165 %5 \u5bc4\u5b58\u5668\u3002 ret \u6307\u4ee4 ret i32 %5 ret \u8868\u793a\u51fd\u6570\u8fd4\u56de\u3002\u901a\u5e38\u51fa\u73b0\u5728\u51fd\u6570\u7684\u672b\u5c3e\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return \u8bed\u53e5\u3002 \u5982\u679c\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \uff0c\u5219\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u8fd4\u56de\u503c\uff08\u4ee5\u5e38\u6570\u6216\u5bc4\u5b58\u5668\u7684\u5f62\u5f0f\uff09\u3002\u4f8b\u5982\u8fd9\u91cc\u6307\u5b9a\u7684 ret i32 %5 \u5c31\u8868\u793a\u51fd\u6570\u4f1a\u8fd4\u56de\u5bc4\u5b58\u5668 %5 \u7684\u503c\u3002 \u800c %5 \u5c31\u662f\u521a\u624d\u6211\u4eec add \u6307\u4ee4\u7684\u8fd0\u7b97\u7ed3\u679c\uff0c\u6240\u4ee5 ret \u548c add \u8fd9\u4e24\u6761\u6307\u4ee4\u5c31\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return a + b \u3002 \u548c store \u4e00\u6837\uff0c ret \u4e5f\u662f\u4e00\u6761\u65e0\u5bc4\u5b58\u5668\u5b9a\u4e49\u7684\u6307\u4ee4\u3002 \u901a\u5e38\u6765\u8bf4\u4f1a\u662f ret i32 0 \uff0c\u8868\u793a return 0 \u3002 \u4e3a\u51fd\u6570\u6307\u5b9a attributes \u6ce8\u610f\u5230\u51fd\u6570\u5b9a\u4e49\u540e\u9762\u6709 attributes \u6307\u4ee4\uff1a define dso_local noundef i32 @main() #0 { ... } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } \u4f5c\u7528\u662f\u4e3a\u51fd\u6570\u8d4b\u4e88\u5c5e\u6027\u503c\uff0c\u5c5e\u6027\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\u540e\u8d4b\u4e88\u7684\uff0c\u7528 #0 \u6765\u5f15\u7528\u4e4b\u524d\u5b9a\u4e49\u7684\u51fd\u6570 main \u3002 \u683c\u5f0f\u4e3a attributes #\u51fd\u6570\u7f16\u53f7 = { \u5c5e\u6027\u5217\u8868... } \u5c5e\u6027\u5217\u8868\u53ef\u4ee5\u662f noinline \u8fd9\u6837\u7684\u5355\u6761\u5c5e\u6027\uff0c\u4e5f\u53ef\u4ee5\u662f\u5e26\u503c\u53c2\u6570\u7684\uff0c\u4f8b\u5982 \"target-cpu\"=\"x86-64\" \u3002 \u73b0\u5728\u6765\u89e3\u91ca\u5176\u4e2d\u91cd\u8981\u7684\u5c5e\u6027\uff1a mustprogress \u8868\u793a\u5fc5\u5b9a\u524d\u8fdb\u5047\u8bbe\uff0c\u8fd9\u662f C++ \u672a\u5b9a\u4e49\u884c\u4e3a\u89c4\u5b9a\u4e2d\u7684\u4e00\u6761\uff0c\u8981\u6c42\u7a0b\u5e8f\u4e00\u76f4\u5904\u4e8e\u201c\u8fdb\u5c55\u201d\u3002\u610f\u601d\u662f\u4e0d\u5f97\u51fa\u73b0\u65e0\u526f\u4f5c\u7528\u7684\u6b7b\u5faa\u73af\uff0c\u5426\u5219\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982 while (true) {} \u662f\u4e0d\u5141\u8bb8\u7684\uff1b\u4f46\u662f while (true) { volatile int i = 0; } \u5c31\u53ef\u4ee5\uff0c\u56e0\u4e3a volatile \u53d8\u91cf\u7684\u521d\u59cb\u5316\u88ab\u89c6\u4e3a\u526f\u4f5c\u7528\uff1b while (true) { cin >> i; } \u4e5f\u53ef\u4ee5\uff0c\u56e0\u4e3a cin \u5c5e\u4e8e IO \u64cd\u4f5c\uff0c\u662f\u6709\u5bf9\u5916\u754c\u73af\u5883\u9020\u6210\u526f\u4f5c\u7528\u7684\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 clang++ \u5f00\u7740\u4f18\u5316\u7f16\u8bd1 while (1); \u65f6\u4f1a\u4ea7\u751f\u53cd\u5e38\u7684\u6c47\u7f16\u7ed3\u679c\uff0c\u800c clang \u4e0d\u4f1a\u3002\u56e0\u4e3a\u53ea\u6709 C++ \u6807\u51c6\u8981\u6c42\u4e86\u201c\u5fc5\u5b9a\u524d\u8fdb\u201d\uff0c\u800c C \u6807\u51c6\u6ca1\u6709\u3002 C++ \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u524d\u8fdb\uff0c\u4f60\u4eec\u53ea\u80fd\u524d\u8fdb\uff0c\u4e0d\u62e9\u624b\u6bb5\u7684\u524d\u8fdb\uff08\u5b5d\u55b7\uff09 noinline \u6307\u5b9a\u4e86\u8be5\u51fd\u6570\u4e0d\u5f97\u88ab\u5185\u8054\u4f18\u5316\uff0c\u56e0\u4e3a\u6211\u4eec\u662f main \u51fd\u6570\uff0c\u662f\u6ce8\u5b9a\u4e0d\u80fd\u88ab\u5185\u8054\u7684\uff0c\u6240\u4ee5 Clang \u81ea\u52a8\u52a0\u4e0a\u4e86\u8fd9\u6761\u5c5e\u6027\u3002 optnone \u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5141\u8bb8\u4f18\u5316\u3002\u4e0d\u5f00\u542f\u4f18\u5316\uff08 -O0 \uff09\u65f6\uff0cClang \u4f1a\u81ea\u52a8\u4e3a\u6240\u6709\u51fd\u6570\u52a0\u4e0a optnone \u5c5e\u6027\u3002 LLVM \u4e2d\u7aef\u4e00\u65e6\u770b\u5230\u5e26\u6709 optnone \u5c5e\u6027\u7684\u51fd\u6570\uff0c\u4f1a\u8df3\u8fc7\u7edd\u5927\u90e8\u5206\u4f18\u5316 pass\u3002\u53ea\u4fdd\u7559\u6781\u5c11\u4e00\u90e8\u5206\u5fc5\u8981\u7684\u8f6c\u6362 pass\uff0c\u4f8b\u5982\u201c\u6307\u4ee4\u9009\u62e9\u201d\u548c\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u5c31\u4e0d\u4f1a\u88ab optnone \u5c4f\u853d\u3002\u6240\u4ee5\uff0cLLVM \u4e2d\u7aef\u4e2d\u4e00\u4e2a pass \u662f\u4f18\u5316\u6027\u8d28\u7684\u8fd8\u662f\u8f6c\u6362\u6027\u8d28\u7684\uff0c\u5c31\u53ef\u4ee5\u4ece\u4ed6\u662f\u5426\u4f1a\u88ab optnone \u5c4f\u853d\u770b\u51fa\u3002 \u53ea\u6709\u5168\u5c40\u5f00\u542f\u4e86 -O \u9009\u9879\u540e\uff0c\u6216\u662f\u4e3a\u5f53\u524d\u51fd\u6570\u6307\u5b9a\u4e86 __attribute__((optimize(\"-O\"))) \u8fd9\u4e00\u7279\u6b8a\u6269\u5c55\u8bed\u6cd5\u540e\uff0cClang \u624d\u4f1a\u53bb\u9664\u51fd\u6570\u7684 optnone \u5c5e\u6027\uff0c\u8ba9 LLVM \u4e2d\u7aef\u7684\u4f18\u5316 pass \u5f97\u4ee5\u5bf9\u8be5\u51fd\u6570\u751f\u6548\u3002 Clang \u751f\u6210 IR \u6c47\u7f16 \u6211\u4eec\u7f16\u5199\u4e00\u6bb5\u7b80\u5355\u7684 C++ \u201c\u4f60\u597d\uff0c\u4e16\u754c\u201d\u4ee3\u7801\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u6307\u5b9a -S -emit-llvm \u9009\u9879\uff0c\u5c31\u53ef\u4ee5\u8ba9 clang \u751f\u6210 IR \u6c47\u7f16\u4f9b\u4f60\u67e5\u770b\u4e86\uff08 -o \u53ef\u4ee5\u6307\u5b9a\u8f93\u51fa\u5230\u7684\u6587\u4ef6\u8def\u5f84\uff09\u3002 clang -S -emit-llvm a.cpp -o a.ll \u4ee5\u4e0b\u662f Clang \u89e3\u6790\u5f97\u5230\u7684 IR\uff08\u6c47\u7f16\u5f62\u5f0f\u6253\u5370\uff09\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 ; Function Attrs: mustprogress noinline norecurse optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } declare i32 @printf(ptr noundef, ...) #1 attributes #0 = { mustprogress noinline norecurse optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } attributes #1 = { \"frame-pointer\"=\"all\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u8fd8\u662f\u7167\u4f8b\u4ecb\u7ecd\u4e00\u4e0b\u65b0\u51fa\u73b0\u7684\u6307\u4ee4\uff1a \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u8fd9\u91cc\u7684 @.str \u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u3002 @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 \u6ce8\u610f\u5230\u4e86\u5417\uff1f\u5168\u5c40\u51fd\u6570\u548c\u53d8\u91cf\u90fd\u662f @ \u5f00\u5934\u7684\uff0c\u5c40\u90e8\u5bc4\u5b58\u5668\u90fd\u662f % \u5f00\u5934\u7684\uff0c\u51fd\u6570\u7f16\u53f7\u90fd\u662f # \u5f00\u5934\u7684\uff0c\u7f16\u8bd1\u671f\u4fe1\u606f\u90fd\u662f ! \u5f00\u5934\u7684\u3002 \u800c . \u5f00\u5934\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u533f\u540d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u4e0d\u5bf9\u5916\u53ef\u89c1\uff0c\u4f8b\u5982 @.str \u5e76\u4e0d\u4ee3\u8868\u771f\u7684\u6709\u4e00\u4e2a const char str[14] \uff0c\u53ea\u662f\u4e3a\u4e86\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u4e34\u65f6\u751f\u6210\u7684\u4e00\u4e2a\u533f\u540d\u5168\u5c40\u53d8\u91cf\u800c\u5df2\u3002 @.str \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u540d\u5b57\uff0c\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u5168\u5c40\u7684\u5b9a\u4e49\u90fd\u662f\u4ee5 @ \u5f00\u5934\u3002 private \u8868\u793a\u5bf9\u5916\u4e0d\u53ef\u89c1\uff0c\u662f\u4e00\u4e2a\u79c1\u6709\u53d8\u91cf\u3002 unnamed_addr \u8868\u793a\u8be5\u53d8\u91cf\u6ca1\u6709\u540d\u5b57\uff0c\u662f\u533f\u540d\u7684\u3002 constant \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u4e0d\u53ef\u4ee5\u88ab\u4fee\u6539\u3002 [14 x i8] \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u7c7b\u578b\uff0c [14 x i8] \u7684\u610f\u601d\u662f\u4e00\u4e2a\u957f\u5ea6\u4e3a 14 \u7684 i8 \u6570\u7ec4\uff0c\u7531 14 \u4e2a i8 \u7c7b\u578b\u7ec4\u6210\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 \u6570\u7ec4\u7c7b\u578b char [14] \u3002 c\"Hello, world!\\00\" \u8868\u793a\u8be5\u6570\u7ec4\u7684\u521d\u59cb\u5316\u503c\uff0c\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u3002 align 1 \u8868\u793a\u8be5\u5168\u5c40\u53d8\u91cf\u7684\u9996\u5730\u5740\u5bf9\u9f50\u5230 1 \u5b57\u8282\uff0c\u56e0\u4e3a\u8fd9\u662f\u4e00\u4e2a char \u6570\u7ec4\uff0c char \u53ea\u8981\u6c42\u5bf9\u9f50\u5230 1 \u5b57\u8282\u5373\u53ef\u3002 \u548c\u4e0d\u53c2\u4e0e\u7b26\u53f7\u94fe\u63a5\u7684\u5c40\u90e8\u5bc4\u5b58\u5668 % \u4e0d\u540c\uff0c\u5168\u5c40\u53d8\u91cf @ \u540e\u9762\u7684\u540d\u5b57\u5c31\u662f\u4ed6\u4eec\u5728\u94fe\u63a5\u65f6\u5bfc\u51fa\u7b26\u53f7\u7684\u540d\u5b57\u3002\u6240\u4ee5\u5168\u5c40\u53d8\u91cf\u5fc5\u987b\u662f\u6709\u540d\u5b57\u7684\uff0c\u4e0d\u80fd\u7528\u6570\u5b57\u5e8f\u53f7\u8868\u793a\u3002 \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u5982\u679c\u6211\u5b9a\u4e49\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf int i \u4f1a\u4ea7\u751f\u600e\u6837\u7684 IR\uff1f int i = 42; @i = dso_local global i32 42, align 4 align 4 \u662f\u56e0\u4e3a i \u662f int \u6216\u8005\u8bf4 i32 \u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309 C++ \u6807\u51c6\u8981\u6c42\u9700\u8981\u5bf9\u9f50\u5230 4 \u5b57\u8282\u3002 \u8fd9\u91cc global \u548c\u4e4b\u524d\u5e38\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 constant \u4e0d\u540c\uff0c\u8868\u793a\u662f\u53ef\u8bfb\u5199\u7684\u5168\u5c40\u53d8\u91cf\u3002 \u8fd9\u91cc\u7684 dso_local \u4fee\u9970\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u8868\u793a i \u4e3a\u5168\u5c40\u5bfc\u51fa\u7b26\u53f7\uff08ODR external linkage\uff09\u3002 C++ \u4ee3\u7801 LLVM IR \u4e2d\u7684\u4fee\u9970 C++ \u5f8b\u5e08\u672f\u8bed static int i @i = internal internal linkage inline int i @i = linkonce_odr dso_local non-ODR external linkage int i @i = dso_local ODR external linkage int i \uff08\u51fd\u6570\u5c40\u90e8\uff09 %1 %2 %3 \u2026 no linkage\uff0c\u4e0d\u9700\u8981\u77e5\u9053\u540d\u5b57 \u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\u3002 \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 \u6ce8\u610f\uff0c\u5168\u5c40\u53d8\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 @i \u662f\u4e00\u4e2a\u5730\u5740\uff01\u5c31\u548c alloca \u5b9a\u4e49\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u662f\u6307\u5411\u6808\u4e0a\u5185\u5b58\u7684\u5730\u5740\u4e00\u6837\u3002 \u5982\u679c\u9700\u8981\u52a0\u8f7d\u5176\u4e2d\u7684\u503c\uff0c\u8fd8\u9700\u8981\u7528 load \u547d\u4ee4\u8bfb\u53d6\u5230\u51fd\u6570\u7684\u5c40\u90e8\u5bc4\u5b58\u5668\u4e2d\uff0c\u624d\u80fd\u5c06\u5176\u4e2d\u7684\u503c\u7528\u4e8e\u8fd4\u56de\u3002 static int i = 42; int main() { return i; // \u4f1a\u4ea7\u751f load @i \u6307\u4ee4 } @i = dso_local global i32 42, align 4 ; @i \u662f i32* \u7c7b\u578b define dso_local noundef i32 @main() #0 { %1 = load i32, ptr @i, align 4 ; load \u8bfb\u53d6\u8be5\u6307\u9488\u624d\u80fd\u8bfb\u5230 i \u53d8\u91cf\u7684\u503c ret i32 %1 ; %1 \u4e2d\u662f i \u53d8\u91cf\u7684\u503c } \u5982\u679c\u76f4\u63a5 ret i32 @i \u7684\u8bdd\uff0c\u5c31\u53d8\u6210 return &i \u7684\u6548\u679c\u4e86\u3002 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } TODO \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 Clang \u7f16\u8bd1\u65f6\u662f\u4ec0\u4e48\u5e73\u53f0\u5c31\u662f\u4ec0\u4e48\u5e73\u53f0\u4e86\uff0c\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7684 IR \u4f1a\u6709\u4e9b\u5fae\u7684\u4e0d\u4e00\u6837\uff08\u7531\u4e8e\u4e00\u4e9b\u8f6f\u4ef6\u9700\u8981\u5229\u7528\u786c\u4ef6 intrinsics\uff09\u3002\u4e00\u4efd IR \u4ece\u751f\u6210\u5f00\u59cb\uff0c\u5c31\u6ce8\u5b9a\u6c38\u8fdc\u53ea\u80fd\u53d8\u6210\u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u3002 \u8fd9\u662f\u56e0\u4e3a\u867d\u7136 IR \u662f\u901a\u7528\u7684\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4f46\u7c7b\u578b\u5927\u5c0f\uff0c\u77e2\u91cf\u5bbd\u5ea6\u7b49\u4fe1\u606f\u548c\u786c\u4ef6\u9ad8\u5ea6\u7ed1\u5b9a\u3002 \u800c\u4e14\u6709\u65f6\u7528\u6237\u9700\u8981\u6839\u636e #ifdef __x86_64__ \u5224\u65ad\uff0c\u9488\u5bf9\u4e0d\u540c\u7684\u786c\u4ef6\uff0c\u4f7f\u7528\u4e0d\u540c\u7684 intrinsics\u3002 \u8fd9\u5bfc\u81f4\u5373\u4f7f\u662f\u540c\u4e00\u4efd .cpp \u6587\u4ef6\uff0c\u9488\u5bf9\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7f16\u8bd1\u7684\u4ea7\u751f\u7684 IR\uff0c\u4e5f\u5fc5\u7136\u662f\u4e0d\u540c\u7684\u3002 \u66f4\u4f55\u51b5 Windows \u548c Linux \u73af\u5883\u7684\u6807\u51c6\u5e93\u4e5f\u4e0d\u4e00\u6837\uff0c\u53ef\u80fd Windows \u7248\u7684\u7ffb\u8bd1\u5355\u5143\u5728\u4f1a\u6709\u4e00\u4e9b Windows \u7279\u6709\u51fd\u6570\u7684\u58f0\u660e\uff0c\u800c Linux \u4e0a\u7f16\u8bd1\u51fa\u6765\u5c31\u6ca1\u6709\u3002 \u603b\u4e4b\uff0c\u56e0\u4e3a\u8fd9\u6837\u90a3\u6837\u7684\u539f\u56e0\uff0cLLVM IR \u5e76\u4e0d\u652f\u6301\u8de8\u5e73\u53f0\u5171\u7528\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a Clang \u7f16\u8bd1\u51fa\u6765\u7684 IR \u6ce8\u5b9a\u662f\u4e0d\u540c\u7684\u3002 \u4e5f\u6709\u4e00\u4e9b\u652f\u6301\u8de8\u5e73\u53f0\u7684 IR\uff0c\u6bd4\u5982 SPIR-V \u548c MLIR\uff0c\u9002\u7528\u4e8e\u6e38\u620f\u5ba2\u6237\u7aef\u90e8\u7f72\u7684\u573a\u666f\u3002\u4f46\u663e\u7136 LLVM \u4f5c\u4e3a\u8ffd\u6c42\u6781\u81f4\u4f18\u5316\u7684\u88f8\u786c\u4ef6\u7f16\u8bd1\u5668\uff0c\u5176 LLVM IR \u5982\u679c\u8981\u6c42\u8de8\u5e73\u53f0\u4f1a\u5f88\u4e0d\u5229\u4e8e Clang \u524d\u7aef\u652f\u6301\u786c\u4ef6 intrinsics\uff0c\u4e5f\u4e0d\u5229\u4e8e LLVM \u4e2d\u7aef\u9488\u5bf9\u76ee\u6807\u786c\u4ef6\u7279\u6027\u505a\u4f18\u5316\uff0c\u4e5f\u4f1a\u65e0\u6cd5\u652f\u6301\u5185\u8054\u6c47\u7f16\uff0c\u6240\u4ee5\u5c31\u653e\u5f03\u4e86\u3002\u6240\u4ee5\u73b0\u5b9e\u4e2d\uff0c\u4eba\u4eec\u4f1a\u5148\u628a Vulkan \u7740\u8272\u5668\u7f16\u8bd1\u6210\u8de8\u5e73\u53f0\u7684 SPIR-V \u4e8c\u8fdb\u5236\u53d1\u5e03\uff0c\u7b49\u90e8\u7f72\u5230\u6e38\u620f\u73a9\u5bb6\u7535\u8111\u4e0a\u540e\uff0c\u7136\u540e\u518d\u8f93\u5165\u663e\u5361\u9a71\u52a8\u4e2d\u7684 LLVM \u5f97\u5230 LLVM IR \u540e\u4f18\u5316\uff0c\u7f16\u8bd1\u751f\u6210\u6700\u9002\u5408\u5f53\u524d\u73a9\u5bb6\u663e\u5361\u4f53\u8d28\u7684 GPU \u6c47\u7f16\u3002 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 \u4e0a\u9762\u4ecb\u7ecd\u7684 LLVM IR \u6c47\u7f16\uff0c\u662f\u4ee5\u6587\u672c\u5f62\u5f0f\u5b58\u50a8\u548c\u5904\u7406\uff0c\u867d\u7136\u65b9\u4fbf\u4e86\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\uff0c\u4f46\u5bf9\u7a0b\u5e8f\u800c\u8a00\u6548\u7387\u4e0d\u9ad8\u3002 \u56e0\u6b64 LLVM \u53c8\u53d1\u660e\u4e86\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u6765\u5b58\u50a8 IR\uff0c\u4e5f\u5c31\u662f\u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u53ef\u7b80\u5199\u4e3a BC\u3002 \u4ed6\u4eec\u662f \u5b8c\u5168\u7b49\u4ef7\u7684 \uff0c\u90fd\u662f IR \u7684\u4e24\u79cd\u8868\u73b0\u65b9\u5f0f\uff1a\u4e00\u4e2a\u662f\u6587\u672c\u683c\u5f0f\uff08\u9002\u5408\u4eba\u7c7b\u9605\u8bfb\uff09\uff0c\u4e00\u4e2a\u662f\u4e8c\u8fdb\u5236\u683c\u5f0f\uff08\u9002\u5408\u7a0b\u5e8f\u9605\u8bfb\uff09\u3002 IR \u5b57\u8282\u7801\u4e2d\u7684\u6bcf\u4e2a\uff08\u6216\u591a\u4e2a\uff09\u5b57\u8282\u90fd\u53ef\u4ee5\u548c IR \u6c47\u7f16\u4e2d\u7684\u4e00\u884c IR \u6307\u4ee4\u4e00\u4e00\u5bf9\u5e94\u3002 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c IR \u6c47\u7f16\uff1a .ll IR \u5b57\u8282\u7801: .bc \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c Clang \u751f\u6210 IR \u6c47\u7f16\uff1a\u4f7f\u7528 -S -emit-llvm \u9009\u9879\u3002 clang -S -emit-llvm a.cpp -o a.ll Clang \u751f\u6210 IR \u5b57\u8282\u7801\uff1a\u4f7f\u7528 -c -emit-llvm \u9009\u9879\u3002 clang -c -emit-llvm a.cpp -o a.bc \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c IR \u6c47\u7f16: \u6587\u672c\u683c\u5f0f\uff08a.ll\uff09 ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 1, ptr %2, align 4 %3 = load i32, ptr %2, align 4 %4 = add nsw i32 %3, 1 ret i32 %4 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 17.0.6\"} IR \u5b57\u8282\u7801: \u4e8c\u8fdb\u5236\u683c\u5f0f\uff08a.bc\uff09 00000000 42 43 c0 de 35 14 00 00 05 00 00 00 62 0c 30 24 |BC..5.......b.0$| 00000010 4a 59 be 66 bd fb b4 af 0b 51 80 4c 01 00 00 00 |JY.f.....Q.L....| 00000020 21 0c 00 00 e1 01 00 00 0b 02 21 00 02 00 00 00 |!.........!.....| 00000030 16 00 00 00 07 81 23 91 41 c8 04 49 06 10 32 39 |......#.A..I..29| 00000040 92 01 84 0c 25 05 08 19 1e 04 8b 62 80 0c 45 02 |....%......b..E.| ... \u4ee5\u4e0a\u4e3a\u4f7f\u7528 hexdump \u5de5\u5177\u67e5\u770b\u7684\u5341\u516d\u8fdb\u5236\u5b57\u8282\u53ef\u89c6\u5316\u7ed3\u679c\u3002 .bc \u7684\u5b9e\u9645\u5185\u5bb9\u5b8c\u5168\u662f\u4e8c\u8fdb\u5236\uff0c\u76f4\u63a5 cat \u5230\u7ec8\u7aef\u4f1a\u4e71\u7801\u3002 \u4e4b\u95f4\u7684\u8f6c\u6362 IR \u6c47\u7f16\u5230 IR \u5b57\u8282\u7801\uff1a llvm-as \uff0c\u628a\u6587\u672c IR \u7f16\u8bd1\u6210\u7d27\u51d1\u538b\u7f29\u7684\u5b57\u8282\u7801\u3002 llvm-as test.ll -o test.bc IR \u5b57\u8282\u7801\u5230 IR \u6c47\u7f16\uff1a llvm-dis \uff0c\u628a\u5b57\u8282\u7801\u91cd\u65b0\u8f6c\u56de\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c IR\u3002 llvm-dis test.bc -o test.ll \u518d\u6b21\u63d0\u9192\uff1a\u8fd9\u4e9b\u662f LLVM \u5185\u90e8\u7684 IR \u7684\u4e24\u79cd\u5f62\u5f0f\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u6c47\u7f16\u548c\u673a\u5668\u7801\u3002 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb IR \u5b57\u8282\u7801\u548c IR \u6c47\u7f16\u7684\u5173\u7cfb\uff0c\u6b63\u5982 x86 \u6c47\u7f16\u548c x86 \u673a\u5668\u7801\u7684\u5173\u7cfb\uff0c\u4e4b\u95f4\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb\u3002 IR \u5b57\u8282\u7801\u662f\u4e8c\u8fdb\u5236\u7684\uff0c\u5bf9\u8ba1\u7b97\u673a\u53cb\u597d\uff1b\u800c IR \u6c47\u7f16\u662f\u4eba\u7c7b\u53ef\u8bfb\u7684 ASCII \u5b57\u7b26\uff0c\u65b9\u4fbf\u4eba\u7c7b\u9605\u8bfb\u548c\u8c03\u8bd5\uff0c\u4ed6\u4eec\u672c\u8d28\u4e0a\u90fd\u662f IR\u3002 \u6c47\u7f16\u662f\u7ed9\u4eba\u770b\u7684\u6587\u672c\u6587\u4ef6\uff0c\u673a\u5668\u7801\u662f\u7ed9 CPU \u770b\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\uff1b\u540c\u6837\u5730\uff0cIR \u6c47\u7f16\u662f IR \u7684\u6587\u672c\u683c\u5f0f\uff0c\u662f\u6253\u5370\u7ed9\u4eba\u770b\u7684\uff1b\u800c IR \u5b57\u8282\u7801\u662f\u7ed9 LLVM \u7f16\u8bd1\u5668\u770b\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f IR\uff0c\u89e3\u6790\u8d77\u6765\u66f4\u5feb\uff0c\u4e5f\u8282\u7ea6\u5185\u5b58\u3002 \u4e0d\u8fc7\uff0c\u8981\u6ce8\u610f\u5b57\u8282\u7801\u548c\u673a\u5668\u7801\u4e0d\u540c\uff0c\u4ed6\u4f9d\u7136\u5c5e\u4e8e\u4e2d\u95f4\u8868\u793a\uff08\u53ea\u4e0d\u8fc7\u662f\u538b\u7f29\u5f97\u4eba\u7c7b\u770b\u4e0d\u61c2\u7684\u9ad8\u6548\u4e8c\u8fdb\u5236\u7248 IR\uff09\uff0c\u5e76\u4e0d\u80fd\u76f4\u63a5\u5728\u8ba1\u7b97\u673a\u4e2d\u6267\u884c\uff0cLLVM \u5b57\u8282\u7801\u53ea\u80fd\u5728 lli \u865a\u62df\u673a\u4e2d\u89e3\u91ca\u6267\u884c\uff0c\u6216\u8005\u901a\u8fc7 llc \u7f16\u8bd1\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u540e\u5728\u76ee\u6807\u5e73\u53f0\u88f8\u673a\u6267\u884c\u3002 \u4f46\u548c Java \u7684\u5b57\u8282\u7801\u53c8\u4e0d\u4e00\u6837\uff0cLLVM \u7684\u5b57\u8282\u7801\u672c\u6765\u5c31\u662f\u4e8c\u8fdb\u5236\u7684 IR\u3002\u800c IR \u5e76\u4e0d\u8de8\u5e73\u53f0\uff0c\u6240\u4ee5\u5b57\u8282\u7801\u4e5f\u4e0d\u8de8\u5e73\u53f0\u3002LLVM \u56e2\u961f\u63d0\u4f9b lli \u5de5\u5177\u4e3b\u8981\u662f\u4e3a\u4e86\u65b9\u4fbf\u4e34\u65f6\u6d4b\u8bd5 IR\uff0c\u7528\u4e8e\u751f\u4ea7\u73af\u5883\u7684\u80af\u5b9a\u8fd8\u662f llc \u7f16\u8bd1\u597d\u4ea7\u751f\u771f\u6b63\u7684\u9ad8\u6548\u673a\u5668\u7801\u3002 \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5f97\u5230\u7684 .bc \u5b57\u8282\u7801\u6587\u4ef6\u4e5f\u88ab\u79f0\u4e3a\u4e00\u4e2a\u6a21\u5757\uff08Module\uff09\uff0c\u6a21\u5757\u7531\u4e00\u7cfb\u5217 IR \u9636\u6bb5\u7684\u7ec4\u6210\uff1b\u6b63\u5982\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7531\u5927\u91cf\u6c47\u7f16\u6307\u4ee4\u7ec4\u6210\u4e00\u6837\u3002 \u8fd9\u91cc\u8bf4\u7684 LLVM \u6a21\u5757\u548c C++20 \u7684 Modules \u7279\u6027\u5173\u7cfb\u4e0d\u5927\uff0c\u6a21\u5757\u662f LLVM \u5f88\u65e9\u5c31\u6709\u7684\u6982\u5ff5\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u4e00\u4e2a .cpp \u6587\u4ef6\u7f16\u8bd1\u53ef\u4ee5\u4ea7\u751f IR \u6c47\u7f16\uff08.ll\uff09\uff0cIR \u6c47\u7f16\u53ef\u4ee5\u901a\u8fc7 llvm-as \u7f16\u8bd1\u5f97\u5230\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09\u3002\u56e0\u6b64\u53ef\u4ee5\u7c97\u7565\u7684\u8ba4\u4e3a\uff0c \u4e00\u4e2a\u6e90\u6587\u4ef6\uff08.cpp\uff09\u7f16\u8bd1\u540e\u5c31\u662f\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09 \u3002 \u800c LLVM \u6a21\u5757\uff08.bc\uff09\u53ef\u4ee5\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210\u901a\u7528\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\uff0c\u4ece\u800c\u5c31\u662f\u6211\u4eec\u770b\u5230\u7684\uff1a\u4e00\u4e2a .cpp \u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a .o \u6587\u4ef6\u4e86\u3002 \u6a21\u5757\u4e2d\u5305\u542b\u4e86\u4e4b\u524d\u4ecb\u7ecd\u7684 IR \u6c47\u7f16\u4e2d\u6240\u6709\u7684\u4fe1\u606f\uff0c\u4f8b\u5982\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u5e03\u5c40\u4fe1\u606f\uff0c\u5168\u5c40\u53d8\u91cf\uff0c\u7c7b\u578b\u58f0\u660e\uff0c\u51fd\u6570\u5b9a\u4e49\u548c\u58f0\u660e\u7b49\u3002 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b \u5b57\u8282\u7801\uff08.bc\uff09\u662f LLVM \u5185\u90e8\u7684\u6587\u4ef6\u683c\u5f0f\uff0c\u4e0d\u901a\u7528\u3002\u4f46\u7531\u4e8e\u5176\u76f4\u63a5\u5b58\u50a8 IR\uff0c\u65b9\u4fbf LLVM \u5904\u7406\u548c\u4f18\u5316\uff0c\u4e14\u53ef\u4ee5\u5f88\u5bb9\u6613\u901a\u8fc7 llvm-dis \u53cd\u6c47\u7f16\u6210\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\u6765\u67e5\u770b\uff08.ll\uff09\u3002\u901a\u5e38\u7528\u4e8e\u8c03\u8bd5 LLVM\uff0c\u4ee5\u53ca\u76ee\u6807\u5e73\u53f0\u4e0d\u662f CPU \u7684\u60c5\u51b5\uff08\u4f8b\u5982 CUDA PTX\uff09\u3002 \u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u662f\u7c7b Unix \u5e73\u53f0\u901a\u7528\u7684 ELF \u683c\u5f0f\uff08\u5728 Windows \u5e73\u53f0\u5219\u662f .obj \u6587\u4ef6\uff0cCOFF \u683c\u5f0f\uff09\uff0c\u5176\u4ed6\u652f\u6301 ELF \u7684\u7f16\u8bd1\u5668\u548c\u94fe\u63a5\u5668\u4e5f\u53ef\u4ee5\u4f7f\u7528\u3002\u4f8b\u5982 GCC \u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e5f\u53ef\u4ee5\u540c LLVM \u7f16\u8bd1\u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e00\u8d77\u94fe\u63a5\uff0c\u800c\u5982\u679c\u662f .bc \u683c\u5f0f GCC \u5c31\u8ba4\u4e0d\u51fa\u6765\u3002\u7f3a\u70b9\u662f\u4e00\u65e6\u7f16\u8bd1\u6210 .o \u6587\u4ef6\uff0c\u5c31\u65e0\u6cd5\u518d\u53cd\u63a8\u51fa IR \u4e86\uff0c\u53ea\u80fd\u901a\u8fc7 objdump \u53cd\u6c47\u7f16\u5f97\u5230\u6c47\u7f16\u4ee3\u7801\uff0c\u5c31\u4e0d\u65b9\u4fbf LLVM \u518d\u5904\u7406\u548c\u4f18\u5316\u4e86\u3002 LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u603b\u4e4b\u5728 LLVM / Clang \u5de5\u4f5c\u6d41\u4e2d\uff0c\u53ef\u4ee5\u7c97\u7565\u8ba4\u4e3a\uff0c\u4e00\u4e2a .cpp \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u4e5f\u6709\u4e00\u4e9b\u65f6\u5019\uff0c\u6211\u4eec\u7f16\u8bd1\u6a21\u5757\u7684\u76ee\u6807\u5e76\u4e0d\u662f CPU\uff0c\u4f8b\u5982 Taichi \u9879\u76ee\u4e2d\uff0c\u5c31\u662f\u901a\u8fc7 LLVM \u91cd\u65b0\u7f16\u8bd1 Python \u5b57\u8282\u7801\uff0c\u751f\u6210 .bc \u6a21\u5757\uff0c\u7136\u540e\u7f16\u8bd1\u4ea7\u751f PTX \u6c47\u7f16\uff0c\u8f6c\u5316\u4e3a CUBIN \u4e8c\u8fdb\u5236\u540e\uff0c\u63d0\u4ea4\u5230 CUDA \u9a71\u52a8\u4e2d\u6267\u884c\uff08\u5b9e\u9645\u4e0a\u6b64\u5904\u8fd8\u4f1a\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210 SASS \u6c47\u7f16\uff09\u3002 \u5728 LLVM / Clang CUDA \u5de5\u4f5c\u6d41\u4e2d\uff0c\u4e00\u4e2a .cu \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u5c0f\u5f6d\u8001\u5e08\u7ed8\u5236\u4e00\u526f\u4e16\u754c\u540d\u753b\u300aIntel \u8d4b\u80fd AI \u7f16\u8bd1\u5668\u300b\uff0c\u540c\u5b66\u95ee\uff0c\u6211\u53ea\u770b\u5230\u6309\u6469\u5e97\u548c\u6deb\u5a01\u5927\uff0c\u6a31\u7279\u5c14\u5728\u54ea\u5462\uff1f\u7b54\uff1a\u6a31\u7279\u5c14\u5728\u8d4b\u80fd\u3002 \u8fd9\u91cc\u7684 cubin \u5176\u5b9e\u5c31\u662f\u5e38\u542c\u5230\u7684 fatbin\uff0c\u4e8c\u8fdb\u5236\u7248\u7684 PTX \u6c47\u7f16\uff0cNVCC \u7684\u6d41\u7a0b\u4e5f\u548c\u8fd9\u4e2a\u5dee\u4e0d\u591a\u3002 \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\uff08.bc\uff09\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u94fe\u63a5\uff0c\u5f62\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6a21\u5757\uff0c\u5176\u4e2d\u5305\u542b\u6240\u6709\u5b50\u6a21\u5757\u7684\u5185\u5bb9\u3002 llvm-link test1.bc test2.bc -o test.bc \u901a\u8fc7\u94fe\u63a5\uff0c\u53ef\u4ee5\u628a\u591a\u4e2a\u6a21\u5757\u7684 IR \u5408\u5e76\u5230\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u65b9\u4fbf\u540e\u7eed\u4f18\u5316\u548c\u7f16\u8bd1\u3002 \u6ce8\u610f\uff01\u8fd9\u91cc\u7684 IR \u94fe\u63a5\uff08llvm-link\uff09\u53ea\u662f LLVM \u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\u7684\u4e00\u4e2a\u5c0f\u8fc7\u7a0b\uff0c\u548c\u6c47\u7f16\u9636\u6bb5\u540e\u751f\u6210\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7684\u771f\u6b63\u94fe\u63a5\uff08lld\uff09\u4e0d\u540c\u3002\u8fd9\u91cc\u53ea\u662f\u628a\u591a\u4e2a LLM \u6a21\u5757\u5408\u5e76\u6210\u4e00\u4e2a\u6a21\u5757\u800c\u5df2\uff0c\u6700\u540e\u8fd9\u4e2a\u603b\u6a21\u5757\u7f16\u8bd1\u4f9d\u7136\u662f\u5f97\u5230\u5355\u4e2a .o \u6587\u4ef6\uff0c\u8fd8\u662f\u8981\u7ecf\u8fc7\u771f\u6b63\u7684\u94fe\u63a5\u5668\uff08lld\uff09\uff0c\u4e0e\u5176\u4ed6 .o \u6587\u4ef6\u94fe\u63a5\u624d\u80fd\u5f62\u6210\u6700\u7ec8\u53ef\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 \u628a C++ \u6587\u4ef6\u7f16\u8bd1\u751f\u6210\u7684\u5b57\u8282\u7801\u6a21\u5757\u94fe\u63a5\u8d77\u6765\uff0c\u5c31\u50cf\u5f88\u591a\u4e2a C++ \u6587\u4ef6\u7a81\u7136\u56fd\u5b9d\u7279\u5de5\u5408\u4f53\u4e00\u6837\u3002 \u8c03\u7528 LLVM pass \u4f18\u5316 LLVM \u63d0\u4f9b\u4e86 opt \u8fd9\u4e2a\u65b9\u4fbf\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u53ef\u4ee5\u8c03\u7528 LLVM \u4e2d\u6307\u5b9a\u540d\u79f0\u7684\u4f18\u5316\u7c7b pass\uff0c\u7528\u6765\u4f18\u5316\u4f20\u5165\u7684 IR \u6587\u4ef6\uff08\u53ef\u4ee5\u662f IR \u6c47\u7f16\u6216 IR \u5b57\u8282\u7801\uff09\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8f93\u51fa\u7684\u662f\u4e8c\u8fdb\u5236\u7684 IR \u5b57\u8282\u7801\uff0c\u5982\u9700\u8f93\u51fa\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\uff0c\u53ef\u4ee5\u6307\u5b9a -S \u9009\u9879\uff08\u5c31\u548c\u521a\u624d\u6211\u4eec\u4f7f\u7528 clang -S \u8ba9 -emit-llvm \u751f\u6210 IR \u6c47\u7f16\u800c\u4e0d\u662f IR \u5b57\u8282\u7801\u4e00\u6837\uff09\u3002 # \u8f93\u5165 a.ll\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.ll\uff08IR \u6c47\u7f16\uff09 opt -S -p mem2reg a.ll -o a-opt.ll cat a-opt.ll # \u8f93\u5165 a.bc\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.bc\uff08IR \u5b57\u8282\u7801\uff09 opt -p mem2reg a.bc -o a-opt.bc llvm-dis a-opt.bc -o a-opt.ll # \u5982\u679c\u8f93\u51fa\u5b57\u8282\u7801\u683c\u5f0f\uff0c\u8fd8\u9700\u8981 llvm-dis \u624d\u80fd\u8ba9\u4eba\u7c7b\u770b\u61c2 \u6848\u4f8b \u8fd8\u662f\u8fd9\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u4f7f\u7528 clang \u7f16\u8bd1\uff0c\u751f\u6210 IR \u6c47\u7f16\uff1a clang -S -emit-llvm a.cpp -o a.ll \u5f97\u5230 a.ll\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 0, ptr %2, align 4 store i32 1, ptr %3, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %4, 1 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u73b0\u5728\uff0c\u6211\u4eec\u7528 opt \u5de5\u5177\u5bf9\u5176\u8fdb\u884c\u4f18\u5316\uff1a TODO \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM"},{"location":"llvm_intro/#llvm","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM LLVM \u4ecb\u7ecd \u53c2\u8003\u8d44\u6599 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u4e00\u70b9\u5fe0\u544a LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 Linux/MacOS \u7528\u6237 Windows \u7528\u6237 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 \u5f00\u59cb\u6784\u5efa \u8fd0\u884c\u8bd5\u8bd5 \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u8bed\u6cd5\u6811\uff08AST\uff09 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 LLVM IR \u7684\u7279\u70b9 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u7c7b\u578b\u7cfb\u7edf \u57fa\u7840\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u6307\u9488\u7c7b\u578b \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM IR \u6848\u4f8b\u5206\u6790 target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f define \u5b9a\u4e49\u51fd\u6570 alloca \u6307\u4ee4 store \u6307\u4ee4 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 load \u6307\u4ee4 add \u6307\u4ee4 ret \u6307\u4ee4 \u4e3a\u51fd\u6570\u6307\u5b9a attributes Clang \u751f\u6210 IR \u6c47\u7f16 \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c \u4e4b\u95f4\u7684\u8f6c\u6362 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u8c03\u7528 LLVM pass \u4f18\u5316 \u6848\u4f8b \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM"},{"location":"llvm_intro/#llvm_1","text":"LLVM \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\u57fa\u7840\u8bbe\u65bd\uff0c\u5b83\u4e0d\u662f\u4e00\u4e2a\u5355\u4e00\u7684\u7f16\u8bd1\u5668\uff0c\u800c\u662f\u4e00\u7cfb\u5217\u5de5\u5177\u548c\u5e93\u7684\u96c6\u5408\uff0c\u5176\u63d0\u4f9b\u4e30\u5bcc\u7684\u6570\u636e\u7ed3\u6784 (ADT) \u548c\u4e2d\u95f4\u8868\u793a\u5c42 (IR)\uff0c\u662f\u5b9e\u73b0\u7f16\u8bd1\u5668\u7684\u6700\u4f73\u6846\u67b6\u3002 LLVM \u662f\u7f16\u8bd1\u5668\u7684\u4e2d\u540e\u7aef\uff0c\u4e2d\u7aef\u8d1f\u8d23\u4f18\u5316\uff0c\u540e\u7aef\u8d1f\u8d23\u6700\u7ec8\u6c47\u7f16\u4ee3\u7801\u7684\u751f\u6210\uff0c\u4ed6\u5e76\u4e0d\u5728\u4e4e\u8c03\u7528\u4ed6\u7684\u4ec0\u4e48\u9ad8\u7ea7\u8bed\u8a00\uff0c\u53ea\u8d1f\u8d23\u628a\u62bd\u8c61\u7684\u4ee3\u6570\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\uff0c\u57fa\u672c\u5757\uff0c\u8f6c\u5316\u4e3a\u8ba1\u7b97\u673a\u786c\u4ef6\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u4e5f\u6709\u4e9b\u6c99\u96d5\u6559\u6750\u4f1a\u628a\u4e2d\u7aef\u548c\u540e\u7aef\u7edf\u79f0\u4e3a\u540e\u7aef\u2026\u2026 Clang \u53ea\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u524d\u7aef\uff0c\u5176\u8d1f\u8d23\u7f16\u8bd1 C/C++ \u8fd9\u7c7b\u8bed\u8a00\uff0c\u8fd8\u6709\u7528\u4e8e\u7f16\u8bd1 Fotran \u7684 Flang \u524d\u7aef\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u8bf8\u5982 Rust\u3001Swift\u3001Haskell \u4e4b\u7c7b\u7684\u8bed\u8a00\uff0c\u4e5f\u90fd\u5728\u4f7f\u7528 LLVM \u505a\u540e\u7aef\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6790\u6784\u51fd\u6570\u5728 } \u5904\u8c03\u7528\uff0c\u8fd9\u662f C++ \u7684\u8bed\u6cd5\u89c4\u5219\uff0c\u5728 Clang \u524d\u7aef\u4e2d\u5904\u7406\u3002\u5f53 Clang \u5b8c\u6210 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u8bed\u4e49\u89c4\u5219\u7684\u89e3\u6790\u540e\uff0c\u5c31\u4f1a\u521b\u5efa\u4e00\u79cd\u53eb\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff0cIntermediate Representation\uff09\u7684\u4e1c\u897f\uff0c\u585e\u7ed9 LLVM \u540e\u7aef\u3002\u5728 IR \u5c42\u9762\uff0c\u6790\u6784\u51fd\u6570\u548c\u666e\u901a C \u8bed\u8a00\u51fd\u6570\u5df2\u7ecf\u6ca1\u6709\u533a\u522b\uff0c\u90fd\u662f\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\u5728 Clang \u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u786e\u5b9a\uff08\u57fa\u4e8e C++ \u8bed\u6cd5\u89c4\u5219\u51b3\u5b9a\uff09\u3002LLVM \u5e76\u4e0d\u5173\u5fc3\u8fd9\u4e2a\u51fd\u6570\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f Rust \u51fd\u6570\uff0c\u4ed6\u53ea\u77e5\u9053\u8fd9\u662f\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u53ea\u9700\u8981\u8fd9\u4e2a\u4fe1\u606f\uff0c\u5c31\u53ef\u4ee5\u53bb\u505a\u4f18\u5316\u4e86\u3002 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u5982\u679c\u6ca1\u6709 IR \u4f1a\u600e\u6837\uff1f\u5047\u8bbe\u6709 M M \u79cd\u8bed\u8a00\uff0c N N \u79cd\u786c\u4ef6\uff0c\u5c31\u9700\u8981\u91cd\u590d\u5b9e\u73b0 M \\times N M \\times N \u4e2a\u7f16\u8bd1\u5668\uff01\u800c IR \u4f5c\u4e3a\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4ee4\u8bed\u8a00\u548c\u786c\u4ef6\u7684\u5177\u4f53\u7ec6\u8282\u89e3\u8026\u4e86\uff0c\u4ece\u800c\u53ea\u9700\u8981\u5199 M + N M + N \u4efd\u4ee3\u7801\u5c31\u53ef\u4ee5\uff1a\u8bed\u8a00\u7684\u5f00\u53d1\u8005\u53ea\u9700\u8981\u8003\u8651\u8bed\u6cd5\u5982\u4f55\u53d8\u6210\u6570\u5b66\u8fd0\u7b97\u548c\u63a7\u5236\u6d41\uff0c\u786c\u4ef6\u5382\u5546\u53ea\u9700\u8981\u8003\u8651\u5982\u4f55\u628a\u6570\u5b66\u548c\u8df3\u8f6c\u6307\u4ee4\u53d8\u6210\u81ea\u5df1\u7279\u5b9a\u7684\u673a\u5668\u7801\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u662f LLVM/Clang \u8fd8\u662f GCC \u5bb6\u65cf\uff0c\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u5185\u90e8\u90fd\u65e0\u4e00\u4f8b\u5916\u91c7\u7528\u4e86 IR \u505a\u4e2d\u95f4\u8868\u793a\u3002 \u6709\u4e86\u7edf\u4e00\u7684\u62bd\u8c61 IR \u4ee5\u540e\uff0c\u4e0d\u7ba1\u4f60\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f C \u8bed\u8a00\u666e\u901a\u51fd\u6570\uff0c\u8fdb\u4e86 IR \u4ee5\u540e\u90fd\u662f\u4e00\u6837\u7684\u51fd\u6570\u8c03\u7528\uff0c\u51cf\u8f7b\u4e86\u7f16\u8bd1\u5668\u4e2d\u540e\u7aef\u5f00\u53d1\u8005\u7684\u5fc3\u667a\u8d1f\u62c5\u3002\u8981\u5f00\u53d1\u4e00\u79cd\u65b0\u8bed\u8a00\uff0c\u53ea\u7ba1\u89e3\u6790\u5b8c\u8bed\u6cd5\u751f\u6210 IR \u8f93\u5165 LLVM\uff0c\u4ed6\u4f1a\u66ff\u4f60\u5305\u529e\u597d\u4f18\u5316\u548c\u6c47\u7f16\u7684\u4e8b\u3002","title":"LLVM \u4ecb\u7ecd"},{"location":"llvm_intro/#_1","text":"LLVM \u5b98\u65b9\u4ed3\u5e93\uff1ahttps://github.com/llvm/llvm-project LLVM \u7528\u6237\u6587\u6863\uff1ahttps://llvm.org/docs/ LLVM \u6e90\u7801\u7ea7\u6587\u6863\uff1ahttps://llvm.org/doxygen/ LLVM IR \u5168\u6587\u6863\uff1ahttps://llvm.org/docs/LangRef.html \u300aLearn LLVM 17\u300b\uff1ahttps://github.com/xiaoweiChen/Learn-LLVM-17 \u300a\u5f00\u59cb\u5b66\u4e60 LLVM\u300b\uff1ahttps://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/ \u300aminiSysY \u7f16\u8bd1\u5b9e\u9a8c\u300b\uff1ahttps://buaa-se-compiling.github.io/miniSysY-tutorial/pre/llvm.html \u300aA Gentle Introduction to LLVM IR\u300b\uff1ahttps://mcyoung.xyz/2023/08/01/llvm-ir/ \u300aLLVM IR C++ API Tutorial\u300b\uff1ahttps://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/ \u4e0d\u5efa\u8bae\u6309\u987a\u5e8f\u5168\u90e8\u9010\u4e2a\u9605\u8bfb\u5b8c\uff0c\u8fd9\u4e48\u591a\u6587\u6863\u5c0f\u5f6d\u8001\u5e08\u90fd\u770b\u4e0d\u5b8c\u3002\u5efa\u8bae\u9047\u5230\u4e86\u4e0d\u719f\u6089\u7684\u6307\u4ee4\u65f6\uff0c\u518d\u53bb\u9488\u5bf9\u6027\u5730\u627e\u5230\u76f8\u5e94\u7ae0\u8282\uff0c\u5b66\u4e60\u3002","title":"\u53c2\u8003\u8d44\u6599"},{"location":"llvm_intro/#llvm_2","text":"\u5982\u679c\u4f60\u5bf9 C++ \u8bed\u8a00\u7684\u5e95\u5c42\u5b9e\u73b0\u611f\u5174\u8da3\uff0c\u7f16\u8bd1\u5668\u662f\u7ed5\u4e0d\u8fc7\u7684\u4e00\u73af\u3002\u5fa1\u4e09\u5bb6\u4e2d\uff0cMSVC \u662f\u95ed\u6e90\u7684\u65e0\u6cd5\u5b66\u4e60\uff0cGCC \u4ee3\u7801\u9ad8\u5ea6\u8026\u5408\uff0c\u4e14\u5f88\u591a\u539f\u59cb\u7684 C \u8bed\u8a00\u201c\u53e4\u795e\u4f4e\u8bed\u201d\u6df7\u6742\u5176\u4e2d\uff0c\u53ef\u8bfb\u6027\u8f83\u5dee\u3002Clang \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 C++ \u7f16\u8bd1\u5668\u524d\u7aef\uff0c\u800c LLVM \u6b63\u662f\u4ed6\u7684\u540e\u7aef\uff0c\u9ad8\u5ea6\u6a21\u5757\u5316\u7684\u8bbe\u8ba1\uff0c\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5f88\u5bb9\u6613\u52a0\u5165\u81ea\u5df1\u7684\u65b0\u6a21\u5757\uff0c\u6700\u9002\u5408\u7f16\u8bd1\u5668\u65b0\u4eba\u4e0a\u624b\u5b66\u4e60\u3002\u9664\u53bb Clang \u8d1f\u8d23\u7684 C++ \u8bed\u6cd5\u89e3\u6790\u540e\uff0cLLVM \u540e\u7aef\u5360\u636e\u4e86\u534a\u58c1\u6c5f\u5c71\u3002\u4f60\u60f3\u4e0d\u60f3\u63a2\u7a76\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5229\u7528\u672a\u5b9a\u4e49\u884c\u4e3a\u4f18\u5316\u7684\uff1f\u60f3\u4e0d\u60f3\u77e5\u9053\u4e3a\u4ec0\u4e48\u6709\u65f6 C++ \u7f16\u8bd1\u5668\u51fa\u73b0\u5f02\u5e38\u7684\u884c\u4e3a\uff1f\u60f3\u4e0d\u60f3\u4e86\u89e3\u600e\u6837\u624d\u80fd\u5199\u51fa\u5bf9\u7f16\u8bd1\u5668\u53cb\u597d\u7684\u4ee3\u7801\uff0c\u65b9\u4fbf\u7f16\u8bd1\u5668\u81ea\u52a8\u5e2e\u4f60\u4f18\u5316\uff1f\u90a3\u5c31\u6765\u5b66\u4e60 LLVM \u5427\uff01 \u524d\u7aef\u548c\u540e\u7aef\u4f17\u591a\uff0c\u65e0\u8bba\u4f60\u662f\u6253\u7b97\u5f00\u53d1\u4e00\u79cd\u65b0\u578b\u8bed\u8a00\uff0c\u8fd8\u662f\u81ea\u7814\u4e00\u79cd\u65b0\u7684 CPU \u67b6\u6784\uff0c\u8003\u8651\u652f\u6301 LLVM \u4f5c\u4e3a\u4e2d\u7aef\u51e0\u4e4e\u662f\u4f60\u552f\u4e00\u7684\u9009\u62e9\u3002 \u5bf9\u4e8e CPU/GPU \u786c\u4ef6\u5382\u5546\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u524d\u7aef\uff0c\u652f\u6301 LLVM \u5c06\u4f7f\u4f60\u7684\u786c\u4ef6\u76f4\u63a5\u652f\u6301 C/C++/CUDA/OpenCL/SyCL/Objective-C/Fortran/Rust/Swift/Haskell \u7b49\u6240\u6709 LLVM \u6709\u524d\u7aef\u7684\u8bed\u8a00\u3002\u4f8b\u5982\u6709\u7684\u56fd\u4ea7\u663e\u5361\u57fa\u4e8e LLVM \u6dfb\u52a0\u4e86\u81ea\u5df1\u7684\u786c\u4ef6\u6307\u4ee4\u96c6\u4f5c\u4e3a\u540e\u7aef\uff0c\u7136\u540e\u518d\u5229\u7528 LLVM \u7684 CUDA \u524d\u7aef\uff0c\u5c31\u5b9e\u73b0\u4e86\u517c\u5bb9 CUDA\uff0cAMD \u5f97\u4ee5\u5b9e\u73b0 CUDA \u517c\u5bb9\u4e5f\u662f\u57fa\u4e8e\u6b64\u3002\u53cd\u4e4b\uff0c\u65b0\u8bed\u8a00\u4e5f\u53ef\u4ee5\u4f7f\u7528 LLVM \u7684 PTX \u540e\u7aef\u8f93\u51fa\uff0c\u4ece\u800c\u652f\u6301\u5728 NVIDIA \u663e\u5361\u4e0a\u6267\u884c\u3002 \u5bf9\u4e8e\u60f3\u53d1\u660e\u65b0\u8bed\u8a00\u6216\u4e3a\u73b0\u6709\u811a\u672c\u8bed\u8a00\u5b9e\u73b0 JIT \u52a0\u901f\u7684\u5f00\u53d1\u8005\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u540e\u7aef\uff0c\u65b0\u8bed\u8a00\u4f7f\u7528 LLVM \u5c31\u80fd\u76f4\u63a5\u652f\u6301 x86/ARM/MIPS/PPC/BPF/PTX/AMDGPU/SPIR-V \u7b49\u5404\u79cd\u67b6\u6784\u548c\u6307\u4ee4\u96c6\uff0c\u800c\u81ea\u5df1\u4e0d\u7528\u589e\u52a0\u4efb\u4f55\u5e95\u5c42\u7ec6\u8282\u8d1f\u62c5\u3002\u4f8b\u5982\u4e00\u4e9b Rust \u7528\u6237\u867d\u7136\u5ba3\u79f0\u53ef\u4ee5\u53d6\u4ee3 C++\uff0c\u4f46 Rust \u7f16\u8bd1\u5668\u6700\u7ec8\u4ecd\u662f\u8c03\u7528 LLVM \u5b9e\u73b0\u7f16\u8bd1\uff0c\u4ea7\u751f\u53ef\u4ee5\u6267\u884c\u7684\u4e8c\u8fdb\u5236\u7801\u3002\u81ea\u5df1\u4e00\u4e2a\u4e2a\u9002\u914d\u6240\u6709\u786c\u4ef6\u5e73\u53f0\u7684\u673a\u5668\u7801\u6210\u672c\u5b9e\u5728\u592a\u9ad8\u4e86\uff0c\u4e14\u4e0d\u8bba\u8fd8\u8981\u4e13\u95e8\u5f00\u53d1\u6240\u6709\u7684\u4f18\u5316 pass\uff0c\u800c LLVM \u4f5c\u4e3a\u4e1a\u754c\u652f\u6301\u6700\u5b8c\u5584\u7684\u73b0\u6210\u54c1\u5728\u5f88\u957f\u4e00\u6bb5\u65f6\u95f4\u5185\u90fd\u5f88\u96be\u4ee3\u66ff\u3002 \u4e2d\u7aef\u4f18\u5316\u548c\u5206\u6790\u80fd\u529b\u5f3a\u5927\uff0c\u65b0\u8bed\u8a00\u82e5\u57fa\u4e8e LLVM\uff0c\u4f18\u5316\u65b9\u9762\u7684\u5de5\u4f5c\u90fd\u6709\u73b0\u6210\u7684\u5b9e\u73b0\uff0c\u53ef\u4ee5\u5168\u90e8\u8ba9 LLVM \u4ee3\u52b3\uff0c\u81ea\u5df1\u53ea\u9700\u8981\u8d1f\u8d23\u89e3\u6790\u8bed\u6cd5\uff0c\u751f\u6210 LLVM IR \u5373\u53ef\uff0c\u5982\u4f55\u4f18\u5316\u540e\u751f\u6210\u4e8c\u8fdb\u5236\u7801\u6839\u672c\u65e0\u9700\u64cd\u5fc3\uff0cLLVM \u4f1a\u81ea\u52a8\u6839\u636e\u5f53\u524d\u7684\u76ee\u6807\u5e73\u53f0\u5224\u65ad\u3002 \u9ad8\u5ea6\u81ea\u5305\u542b\uff0c\u5b8c\u5168\u57fa\u4e8e CMake \u7684\u6a21\u5757\u5316\u6784\u5efa\uff0c\u5145\u6ee1\u73b0\u4ee3\u611f\u3002\u7528\u6237\u53ef\u81ea\u884c\u9009\u62e9\u8981\u6784\u5efa\u7684\u6a21\u5757\u3002\u4e14\u51e0\u4e4e\u5b8c\u5168\u65e0\u4f9d\u8d56\u5c31\u80fd\u6784\u5efa\uff0c\u6709 CMake \u6709\u7f16\u8bd1\u5668\u5c31\u884c\uff0c\u65e0\u9700\u5b89\u88c5\u7e41\u7410\u7684\u7b2c\u4e09\u65b9\u5e93\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u843d\u540e\u7684 Makefile + AutoConf \u6784\u5efa\u7cfb\u7edf\uff0c\u4e14\u7248\u672c\u8981\u6c42\u82db\u523b\u3002 LLVM \u91c7\u7528\u7684 MIT \u5f00\u6e90\u534f\u8bae\u5341\u5206\u5bbd\u677e\uff0c\u5bf9\u5546\u7528\u81ea\u7531\u5ea6\u8f83\u9ad8\u3002\u4e14\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5bb9\u6613\u81ea\u5df1\u63d2\u5165\u65b0\u529f\u80fd\uff0c\u53ef\u4fee\u6539\u540e\u4f9b\u81ea\u5df1\u4f7f\u7528\uff0c\u56e0\u6b64\u5e38\u7528\u4e8e\u95ed\u6e90\u9a71\u52a8\u4e2d\uff08\u4f8b\u5982 NVIDIA \u7684 OpenGL \u9a71\u52a8\u7b49\uff09\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u7684 GPL \u534f\u8bae\u5c31\u6bd4\u8f83\u4e25\u683c\uff0c\u4e0d\u5f97\u81ea\u5df1\u4fee\u6539\u540e\u95ed\u6e90\u53d1\u5e03\uff08\u5fc5\u987b\u8fde\u540c\u6e90\u4ee3\u7801\u4e00\u8d77\u53d1\u5e03\uff09\u3002 LLVM \u9644\u5e26\u4e86\u8bb8\u591a\u5b9e\u7528\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5e2e\u52a9\u6211\u4eec\u5206\u6790\u7f16\u8bd1\u5168\u8fc7\u7a0b\u7684\u4e2d\u95f4\u7ed3\u679c\uff0c\u7406\u89e3\u4f18\u5316\u662f\u5982\u4f55\u53d1\u751f\u7684\u3002\u4f8b\u5982 llvm-as\uff08LLVM IR \u8f6c\u4e3a\u538b\u7f29\u7684\u5b57\u8282\u7801\uff09\uff0cllvm-dis\uff08\u5b57\u8282\u7801\u8f6c\u4e3a IR\uff09\uff0copt\uff08\u53ef\u4ee5\u5bf9 IR \u8c03\u7528\u5355\u4e2a\u4f18\u5316 pass\uff09\uff0cllc\uff08\u5c06\u5b57\u8282\u7801\u8f6c\u6362\u4e3a\u76ee\u6807\u673a\u5668\u7684\u6c47\u7f16\u4ee3\u7801\uff09\uff0cllvm-link\uff08IR \u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u8f93\u5165\u591a\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u4ea7\u751f\u5355\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff09\uff0clld\uff08\u5bf9\u8c61\u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u7c7b\u4f3c\u4e8e GNU ld\uff09\uff0clli\uff08\u89e3\u91ca\u6267\u884c\u5b57\u8282\u7801\uff09\uff0cllvm-lit\uff08\u5355\u5143\u6d4b\u8bd5\u5de5\u5177\uff09\u3002 \u4e00\u4e9b\u82af\u7247\u76f8\u5173\u7684\u5927\u5382\u4e2d\uff0c\u7f16\u8bd1\u5668\u65b9\u9762\u7684\u5c97\u4f4d\u9700\u6c42\u91cf\u5f88\u5927\u3002\u800c\u5176\u4e2d\u4e3b\u8981\u7528\u7684\uff0c\u4f8b\u5982 NVIDIA \u7684\u7f16\u8bd1\u5668 nvcc\uff0c\u5176\u540e\u7aef\u5c31\u662f\u57fa\u4e8e LLVM \u9b54\u6539\u7684\uff0c\u56e0\u6b64\u5b66\u4e60 LLVM \u5f88\u6709\u5c31\u4e1a\u524d\u666f\u3002 \u4e3a\u4ec0\u4e48\u6709\u4e86 Clang \u8fd8\u8981 nvcc\uff1f\u867d\u7136 Clang \u4e5f\u80fd\u652f\u6301 CUDA\uff0c\u4f46 Clang \u53ea\u80fd\u628a CUDA \u7f16\u8bd1\u6210\u6240\u6709 NVIDIA \u663e\u5361\u90fd\u80fd\u901a\u7528\u7684 PTX\uff0c\u65e0\u6cd5\u751f\u6210\u4e13\u95e8\u5bf9\u4e0d\u540c\u663e\u5361\u578b\u53f7\u7279\u5316 SASS \u6c47\u7f16\uff08\u9700\u8981\u8c03\u7528 NVIDIA CUDA Toolkit \u63d0\u4f9b\u7684 ptxas \u624d\u80fd\u8f6c\u6362\uff09\u3002\u800c nvcc \u7684\u524d\u7aef\u9664\u4e86\u662f\u81ea\u5df1\u7684\uff0c\u540e\u7aef\u540c\u6837\u662f\u8c03\u7528 LLVM \u751f\u6210 PTX \u6c47\u7f16\uff0c\u53ea\u662f NVIDIA \u5bf9 LLVM \u505a\u4e86\u4e00\u4e9b\u95ed\u6e90\u7684\u9b54\u6539\uff08\u5176\u5b9e\u65e9\u671f nvcc \u7684\u540e\u7aef\u662f\u57fa\u4e8e NVIDIA \u81ea\u7814\u7684 NVVM \u540e\u7aef\uff0c\u4f46\u662f\u53d1\u73b0\u6548\u679c\u4e0d\u597d\uff0c\u6700\u8fd1\u6b63\u5728\u9010\u6b65\u5207\u6362\u5230 LLVM \u540e\u7aef\uff0c\u6bd5\u7adf\u662f\u8001\u724c\u9879\u76ee\uff09\u3002\u5982\u679c\u5bf9 C++ \u65b0\u7279\u6027\u6709\u8ffd\u6c42\uff0c\u53ef\u4ee5\u7528 Clang \u524d\u7aef + LLVM \u751f\u6210 PTX + ptxas \u6c47\u7f16\u7684\u7ec4\u5408\uff0c\u5b9e\u73b0\u81ea\u7531\u4e16\u754c\u7684 CUDA \u5de5\u4f5c\u6d41\uff08\u4e4b\u540e\u4ecb\u7ecd\uff09\u3002\u4f46\u662f\u56e0\u4e3a ptxas\uff0c\u4ee5\u53ca CUDA \u5176\u4ed6\u8fd0\u884c\u65f6\u5e93\u7684\u9700\u8981\uff0cClang CUDA \u4f9d\u7136\u9700\u8981\u5b89\u88c5 CUDA Toolkit \u624d\u80fd\u6b63\u5e38\u8fd0\u884c\uff0c\u4e14\u5bf9 CUDA \u7248\u672c\u8981\u6c42\u6bd4\u8f83\u4e25\u683c\uff0c\u53ef\u80fd\u9700\u8981\u8f83\u591a\u7684\u914d\u7f6e\u529f\u592b\u3002 Rust \u7f16\u8bd1\u5668\u6700\u8fd1\u4e5f\u6709\u63d0\u51fa\u4e86 gcc-rust\uff0c\u4f7f\u7528 GCC \u505a\u540e\u7aef\u4ee3\u66ff LLVM \u7684\u8ba1\u5212\u2026\u2026\u5c31\u4e0d\u80fd\u81ea\u7814\u4e00\u4e2a RRVM \u4e48\uff1f\u4e0d\u4ec5\u662f Rust \u7f16\u8bd1\u5668\uff0c\u4f60\u4f1a\u53d1\u73b0\u5f88\u591a Rust \u9879\u76ee\u6700\u7ec8\u6216\u591a\u6216\u5c11\u90fd\u5728\u4f9d\u8d56\u4e00\u4e9b C++ \u5e93\uff0c\u6bd4\u5982 RustDesk \u8fd9\u6b3e\u9ad8\u6027\u80fd\u7684\u8fdc\u7a0b\u63a7\u5236\u8f6f\u4ef6\uff0c\u4e0d\u77e5\u548b\u5730\u5c31\u975e\u8981\u4f9d\u8d56 libyuv \u548c libvpx\uff0c\u8fd8\u8981\u6c42\u7528\u6c99\u96d5\u7684 vcpkg \u5b89\u88c5\u2026\u2026\u662f\u81ea\u5df1\u5199\u4e0d\u6765\u8fd8\u662f\u61d2\u5f97\u5199\u4e86\uff1fRust \u4e0d\u662f\u9ad8\u6027\u80fd\u7684\u7cfb\u7edf\u7ea7\u8bed\u8a00\u4e48\uff1f\u5982\u679c Rust \u793e\u533a\u4e0d\u4f1a\u5199 YUV \u7f16\u7801\uff0c\u53ef\u4ee5\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\u5e2e\u5fd9\u7684\u3002\u603b\u4e4b\uff0c\u73b0\u5728\u641e\u5f97 Rust \u548c Python \u4e00\u6837\uff0c\u6210\u5305\u76ae\u8bed\u8a00\u4e86\u3002\u4eca\u540e\u5bf9 Rust \u7684\u5b66\u4e60\uff0c\u6050\u6015\u8fd8\u662f\u5c48\u670d\u4e8e\u5b9e\u7528\uff0c\u548c Python \u4e00\u6837\u5404\u79cd\u201cAPI bindings\u201d\u3002","title":"\u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM"},{"location":"llvm_intro/#llvm_3","text":"LLVM \u9879\u76ee\u4e0d\u4ec5\u5305\u542b\u4e86 LLVM \u672c\u4f53\uff0c\u8fd8\u6709\u4e00\u7cfb\u5217\u56f4\u7ed5 LLVM \u5f00\u53d1\u7684\u4e0a\u4e0b\u6e38\u5de5\u5177\u3002\u4f8b\u5982 Clang \u7f16\u8bd1\u5668\u5c31\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff0c\u4ed6\u662f\u4e00\u4e2a C/C++/CUDA/OpenCL/SyCL/Objective-C \u7b49 C \u7c7b\u8bed\u8a00\u7684\u524d\u7aef\uff0c\u53ea\u8d1f\u8d23\u5b8c\u6210\u8bed\u6cd5\u7684\u89e3\u6790\uff0c\u5b9e\u9645\u7f16\u8bd1\u548c\u4e8c\u8fdb\u5236\u751f\u6210\u4ea4\u7ed9 LLVM \u672c\u4f53\uff08\u4e2d\u540e\u7aef\uff09\u6765\u5904\u7406\u3002\u901a\u5e38\u8bf4\u7684 LLVM \u6307\u7684\u662f LLVM \u672c\u4f53\uff0c\u5176\u662f\u4e00\u4e2a\u901a\u7528\u7684\u7f16\u8bd1\u5668\u57fa\u5efa\uff0c\u4ec5\u5305\u542b\u4e2d\u7aef\uff08\u5404\u79cd\u4f18\u5316\uff09\u548c\u540e\u7aef\uff08\u751f\u6210 x86/ARM/MIPS \u7b49\u786c\u4ef6\u7684\u6307\u4ee4\u7801\uff09\u3002Clang \u89e3\u6790 .cpp \u6587\u4ef6\u540e\u4ea7\u751f IR\uff0c\u8c03\u7528 LLVM \u7f16\u8bd1\u751f\u6210\u7684 .o \u5bf9\u8c61\u6587\u4ef6\uff0c\u53c8\u4f1a\u88ab\u8f93\u5165\u5230\u540c\u5c5e LLVM \u9879\u76ee\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff1aLLD \u94fe\u63a5\u5668\u4e2d\uff0c\u94fe\u63a5\u5f97\u5230\u6700\u7ec8\u7684\u5355\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\uff08.exe\uff09\u6216\u52a8\u6001\u94fe\u63a5\u5e93\uff08.dll\uff09\uff0cLLD \u8fd8\u53ef\u4ee5\u5f00\u542f\u94fe\u63a5\u65f6\u4f18\u5316\uff0c\u8fd9\u53c8\u4f1a\u7528\u5230 BOLT \u8fd9\u4e2a\u94fe\u63a5\u65f6\u4f18\u5316\u5668\uff0c\u5bf9\u751f\u6210\u7684\u5355\u4e2a\u4e8c\u8fdb\u5236\u505a\u8fdb\u4e00\u6b65\u6c47\u7f16\u7ea7\u522b\u7684\u4f18\u5316\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8457\u540d\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\u4e4b\u4e00\uff0clibc++\uff0c\u4e5f\u662f LLVM \u9879\u76ee\u7684\u4e00\u90e8\u5206\uff0c\u76f8\u6bd4 GCC \u5bb6\u65cf\u7684 libstdc++ \u66f4\u7b80\u5355\uff0c\u66f4\u9002\u5408\u5b66\u4e60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5e76\u884c\u7684 STL \u5b9e\u73b0 pstl\uff0cOpenCL \u7f16\u8bd1\u5668 libclc \u7b49\u2026\u2026\u5e94\u6709\u5c3d\u6709\uff0c\u662f\u7f16\u8bd1\u5668\u5f00\u53d1\u8005\u7684\u5929\u5802\u3002 Clang \u7f16\u8bd1 C++ \u7a0b\u5e8f\u7684\u6574\u4e2a\u8fc7\u7a0b\uff1a Clang \u524d\u7aef\u89e3\u6790 C++ \u8bed\u6cd5 -> LLVM \u4e2d\u7aef\u4f18\u5316 -> LLVM \u540e\u7aef\u751f\u6210\u6307\u4ee4\u7801 -> LLD \u94fe\u63a5 -> BOLT \u94fe\u63a5\u540e\u4f18\u5316 \u800c GCC \u5c31\u6ca1\u6709\u8fd9\u4e48\u6a21\u5757\u5316\u4e86\uff0c\u867d\u7136 GCC \u5185\u90e8\u540c\u6837\u662f\u6709\u524d\u7aef\u548c\u4e2d\u7aef IR\uff0c\u4f46\u662f\u6574\u4e2a\u5c31\u662f\u7cca\u5728\u4e00\u4e2a GCC \u53ef\u6267\u884c\u6587\u4ef6\u91cc\uff0c\u96be\u4ee5\u91cd\u6784\uff0c\u79ef\u91cd\u96be\u53cd\uff0c\u4e5f\u96be\u4ee5\u8de8\u5e73\u53f0\uff08MinGW \u8fd8\u662f\u6c11\u95f4\u81ea\u5df1\u79fb\u690d\u8fc7\u53bb\u7684\uff0c\u5e76\u975e GCC \u5b98\u65b9\u9879\u76ee\uff09\u3002\u548c Clang \u80fd\u8f7b\u6613\u4f5c\u4e3a libclang \u548c libLLVM \u5e93\u53d1\u5e03\u76f8\u6bd4\uff0c\u9ad8\u4e0b\u7acb\u5224\u3002MSVC \u66f4\u662f\u4e0d\u5fc5\u591a\u8bf4\uff0c\u8fde\u6e90\u7801\u90fd\u4e0d\u5f00\u653e\uff0c\u8ba9\u4eba\u600e\u4e48\u5b66\u4e60\u548c\u9b54\u6539\u554a\uff1f","title":"LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f"},{"location":"llvm_intro/#llvm_4","text":"\u8981\u5b66\u4e60 LLVM\uff0c\u80af\u5b9a\u4e0d\u80fd\u7eb8\u4e0a\u8c08\u5175\u3002LLVM \u662f\u5f00\u6e90\u8f6f\u4ef6\uff0c\u6700\u597d\u662f\u81ea\u5df1\u4e0b\u8f7d\u4e00\u4e2a LLVM \u5168\u5bb6\u6876\u6e90\u7801\uff0c\u7136\u540e\u81ea\u5df1\u4ece\u6e90\u7801\u6784\u5efa\u3002 \u6ce8\u610f\uff1a\u6211\u4eec\u6700\u597d\u662f\u4ece\u6e90\u7801\u6784\u5efa LLVM \u548c Clang\uff0c\u65b9\u4fbf\u6211\u4eec\u52a8\u624b\u4fee\u6539\u5176\u6e90\u7801\uff0c\u6dfb\u52a0\u6a21\u5757\uff0c\u67e5\u770b\u6548\u679c\u3002\u4e0b\u8f7d\u4e8c\u8fdb\u5236\u53d1\u5e03\u7248 LLVM \u6216 Clang \u7684\u8bdd\uff0c\u867d\u7136\u540c\u6837\u53ef\u4ee5\u4f7f\u7528\u6240\u6709\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5c31\u53ea\u80fd\u5bf9\u7740 IR \u4e00\u901a\u5206\u6790\u76f2\u731c\u4e86\u3002 \u6e90\u7801\u9762\u524d\uff0c\u4e86\u65e0\u79d8\u5bc6\u3002 \u867d\u7136 LLVM \u51e0\u4e4e\u662f\u65e0\u4f9d\u8d56\u7684\uff0c\u53ea\u9700\u8981 CMake \u548c\u7f16\u8bd1\u5668\u5c31\u80fd\u6784\u5efa\uff0c\u4f46\u4f9d\u7136\u63a8\u8350\u4f7f\u7528 Linux \u7cfb\u7edf\u8fdb\u884c\u5b9e\u9a8c\uff0c\u4ee5\u83b7\u5f97\u548c\u5c0f\u5f6d\u8001\u5e08\u540c\u6837\u7684\u5f00\u53d1\u4f53\u9a8c\u3002Windows \u7528\u6237\u5efa\u8bae\u4f7f\u7528 Visual Studio \u6216 CLion \u7b49\u5f3a\u5927 IDE \u5e2e\u52a9\u9605\u8bfb\u7406\u89e3\u6e90\u7801\uff1bLinux \u7528\u6237\u5efa\u8bae\u5b89\u88c5 \u5c0f\u5f6d\u8001\u5e08 vimrc \uff1b\u6216\u8005\u5982\u679c\u4f60\u662f\u8fdc\u7a0b Linux\uff0c\u53ef\u4ee5\u8bd5\u8bd5\u770b VSCode \u7684\u8fdc\u7a0b SSH \u8fde\u63a5\u63d2\u4ef6\uff1bCLion \u4f3c\u4e4e\u4e5f\u6709\u8fdc\u7a0b\u63d2\u4ef6\uff0c\u53ea\u4e0d\u8fc7\u9700\u8981\u5728\u8fdc\u7a0b\u5b89\u88c5\u597d\u5ba2\u6237\u7aef\u3002 \u5f3a\u5927\u7684 IDE \u548c\u7f16\u8f91\u5668\u5bf9\u5b66\u4e60\u4efb\u4f55\u5927\u578b\u9879\u76ee\u90fd\u662f\u5fc5\u4e0d\u53ef\u5c11\u7684\uff0c\u7279\u522b\u662f\u8df3\u8f6c\u5230\u5b9a\u4e49\uff0c\u4ee5\u53ca\u8fd4\u56de\u8fd9\u4e24\u4e2a\u64cd\u4f5c\uff0c\u662f\u4f7f\u7528\u9891\u7387\u6700\u9ad8\u7684\uff0c\u5728\u6e90\u7801\u4e4b\u95f4\u7684\u5feb\u901f\u8df3\u8f6c\u5c06\u5927\u5927\u6709\u52a9\u4e8e\u5feb\u901f\u7406\u89e3\u548c\u638c\u63e1\u4ee3\u7801\u7ed3\u6784\u3002 \u5982\u679c\u5b9e\u5728\u6ca1\u6709\u6761\u4ef6\u81ea\u5df1\u6784\u5efa LLVM \u6e90\u7801\uff0c\u6216\u8005 IDE \u6bd4\u8f83\u62c9\u80ef\uff1a\u53ef\u4ee5\u53bb LLVM \u7684\u5728\u7ebf\u6e90\u7801\u7ea7\u6587\u6863\uff08\u4f7f\u7528 Doxygen \u751f\u6210\uff09\u770b\u770b\u3002\u5176\u4e0d\u4ec5\u63d0\u4f9b\u4e86 LLVM \u4e2d\u6240\u6709\u7c7b\u548c\u51fd\u6570\u7684\u8be6\u5c3d\u6587\u6863\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u7528\u6cd5\u8bf4\u660e\u7b49\uff1b\u8fd8\u63d0\u4f9b\u4e86\u6bcf\u4e2a\u51fd\u6570\u7684\u6240\u5728\u6587\u4ef6\u548c\u884c\u53f7\u4fe1\u606f\uff0c\u70b9\u51fb\u7c7b\u578b\u6216\u51fd\u6570\u540d\u7684\u8d85\u94fe\u63a5\uff0c\u5c31\u53ef\u4ee5\u5728\u6e90\u7801\u548c\u6587\u6863\u4e4b\u95f4\u6765\u56de\u8df3\u8f6c\u3002\u8fd8\u80fd\u770b\u5230\u54ea\u91cc\u5f15\u7528\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u8fd8\u80fd\u663e\u793a\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb\u56fe\uff0c\u975e\u5e38\u9002\u5408\u4e0a\u73ed\u8def\u4e0a\u6ca1\u6cd5\u6253\u5f00\u7535\u8111\u65f6\u5077\u5b66 LLVM \u6e90\u7801\u7528\u3002\u4f8b\u5982\uff0c llvm::VectorType \u8fd9\u4e2a\u7c7b\u7684\u6587\u6863\uff1ahttps://llvm.org/doxygen/classllvm_1_1VectorType.html","title":"\u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907"},{"location":"llvm_intro/#_2","text":"\u5bf9\u4e8e LLVM \u8fd9\u79cd\u5927\u578b\u9879\u76ee\uff0c\u7531\u4e8e\u4f60\u662f\u521d\u5b66\u8005\uff0c\u52a1\u5fc5\u505a\u5230\u201c\u4e0d\u6c42\u751a\u89e3\u201d\uff01 \u4f60\u5fc5\u7136\u4e00\u65f6\u534a\u4f1a\u4e0d\u80fd\u5b8c\u5168\u770b\u61c2\u6bcf\u4e2a\u7ec6\u8282\uff0c\u5343\u4e07\u4e0d\u8981\u6b7b\u6263\u7ec6\u8282\uff0c\u4e00\u4e2a\u7ec6\u8282\u4e0d\u7406\u89e3\u5c31\u786c\u77aa\u773c\u5e72\u770b\uff01 \u770b\u4e0d\u61c2\u7684\u5148\u8df3\u8fc7\u53bb\u5373\u53ef\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\u3002\u7535\u89c6\u8fde\u7eed\u5267\u8df3\u4e00\u4e24\u96c6\uff0c\u751a\u81f3\u4ece\u4e2d\u95f4\u5f00\u59cb\u770b\uff0c\u90fd\u80fd\u770b\u61c2\u5462\uff01\u6ca1\u6709\u90a3\u4e48\u4e25\u683c\u7684\u987a\u5e8f\u4f9d\u8d56\u3002 \u4ee5\u540e\u77e5\u8bc6\u50a8\u5907\u591f\u4e86\uff0c\u6216\u8005\u5de5\u4f5c\u4e2d\u9700\u8981\u7528\u5230\u4e86\uff0c\u518d\u56de\u8fc7\u5934\u6765\u67e5\u6f0f\u8865\u7f3a\u4e5f\u4e0d\u8fdf\u3002 \u6211\u6700\u6015\u67d0\u4e9b\u540c\u5b66\u76ef\u7740\u67d0\u4e2a\u6b21\u8981\u7684\u7ec6\u8282\u6b7b\u52b2\u60f3\uff0c\u60f3\u4e0d\u51fa\u5c31\u6b62\u6b65\u4e0d\u524d\u4e86\u3002\u6bd4\u5982\u4ed6\u9047\u5230\u4e00\u4e2a\u8001\u5916\u8bf4\uff1a My dick is bleeding, could you tell me where is the toilet? \u800c \u2018dick\u2019 \u662f\u8fd9\u4e2a\u540c\u5b66\u770b\u4e0d\u61c2\u7684\u201c\u751f\u8bcd\u201d\uff0c\u4ed6\u5c31\u6b7b\u6263\u8fd9\u4e2a\u5b57\u773c\uff0c\u8ba4\u4e3a\u770b\u4e0d\u61c2\u8fd9\u4e2a\u8bcd\uff0c\u540e\u9762\u7684\u5bf9\u8bdd\u4e5f\u4f1a\u770b\u4e0d\u61c2\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u9700\u8981\u628a\u8fd9\u4e2a\u770b\u4e0d\u61c2\u7684\u5730\u65b9\u8df3\u8fc7\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\uff0c\u5c31\u5f53\u4ed6\u662f\u4e00\u4e2a\u4e71\u7801\u585e\u5728\u90a3\u91cc\u5e72\u6270\u4f60\u9605\u8bfb\u7684\uff0c\u4f60\u53ea\u7ba1\u7ee7\u7eed\u770b\u4e0b\u53bb\uff1a My \ufffd\ufffd\ufffd is \ufffd\ufffd\ufffd\ufffd\ufffd, could you tell me where is the toilet? \u4e00\u6837\u80fd\u770b\u61c2\u8001\u5916\u60f3\u8981\u95ee\u7684\u662f\u5395\u6240\uff08toilet\uff09\uff0c\u6839\u672c\u4e0d\u9700\u8981\u77e5\u9053\u524d\u9762\u7684 \u2018dick\u2019 \u662f\u4ec0\u4e48\u610f\u601d\u3002 \u81f4\u6d82\u9ed1\u4e16\u754c\u7684\u4e66\u4fe1","title":"\u4e00\u70b9\u5fe0\u544a"},{"location":"llvm_intro/#llvm_5","text":"","title":"LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa"},{"location":"llvm_intro/#_3","text":"LLVM\uff08\u548c Clang\uff09\u7684\u6784\u5efa\u4f9d\u8d56\u9879\u51e0\u4e4e\u6ca1\u6709\uff0c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\uff0c\u975e\u5e38\u7684\u73b0\u4ee3\u3002","title":"\u73af\u5883\u51c6\u5907"},{"location":"llvm_intro/#linuxmacos","text":"\u9996\u5148\u5b89\u88c5 Git\u3001CMake\u3001Ninja\u3001GCC\uff08\u6216 Clang\uff09\u3002 \u5176\u4e2d Ninja \u53ef\u4ee5\u4e0d\u5b89\u88c5\uff0c\u53ea\u662f\u56e0\u4e3a Ninja \u6784\u5efa\u901f\u5ea6\u6bd4 Make \u5feb\uff0c\u7279\u522b\u662f\u5f53\u6587\u4ef6\u975e\u5e38\u591a\uff0c\u800c\u4f60\u6539\u52a8\u975e\u5e38\u5c11\u65f6\u3002\u800c\u4e14 Ninja \u9ed8\u8ba4\u5c31\u5f00\u542f\u591a\u6838\u5e76\u884c\u6784\u5efa\uff0c\u6240\u4ee5\u5927\u578b\u9879\u76ee\u901a\u5e38\u4f1a\u5c3d\u91cf\u7ed9 cmake \u6307\u5b9a\u4e00\u4e0b -G Ninja \u9009\u9879\uff0c\u8ba9\u5176\u4f7f\u7528\u66f4\u9ad8\u6548\u7684 Ninja \u540e\u7aef\u6784\u5efa\u3002 Arch Linux: sudo pacman -S git cmake ninja gcc Ubuntu: sudo apt-get install git cmake ninja-build g++ MacOS: brew install git cmake ninja gcc \u5f00\u59cb\u514b\u9686\u9879\u76ee\uff08\u9700\u8981\u65f6\u95f4\uff09\uff1a git clone https://github.com/llvm/llvm-project \u5982\u679c\u4f60\u7684 GitHub \u7f51\u901f\u8f83\u6162\uff0c\u53ef\u4ee5\u6539\u7528 Gitee \u56fd\u5185\u955c\u50cf\uff08\u53ea\u4e0d\u8fc7\u8fd9\u6837\u4f60\u5c31\u6ca1\u6cd5\u7ed9 LLVM \u5b98\u65b9\u6c34 PR \u4e86 \ud83e\udd23\uff09\uff1a git clone https://gitee.com/mirrors/LLVM","title":"Linux/MacOS \u7528\u6237"},{"location":"llvm_intro/#windows","text":"\u5373\u4f7f\u662f LLVM \u8fd9\u6837\u6beb\u65e0\u4f9d\u8d56\u9879\u7684\u9879\u76ee\uff0c\u201c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\u201d\uff0c\u5728 Windows \u7528\u6237\u770b\u6765\u4f9d\u7136\u975e\u5e38\u79d1\u5e7b\u3002 \u597d\u5728\u5fae\u8f6f\u4e5f\u610f\u8bc6\u5230\u4e86\u81ea\u5df1\u7684\u6b8b\u5e9f\uff0c\u73b0\u5728 Virtual Studio 2022 \u5df2\u7ecf\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff08\u81ea\u5e26 Git\u3001CMake \u548c Ninja \u4e86\uff09\u3002 \u5982\u679c\u4f60\u662f\u7528 VS2022 \u81ea\u5e26\u7684 Git \u514b\u9686 llvm-project\uff0c\u8bb0\u5f97 cd \u5230 llvm \u6587\u4ef6\u5939\u91cc\u518d\u7528 cmake\uff0c\u7136\u800c\u8d35\u7269 IDE \u7684\u4e00\u4e2a cd \u90fd\u662f\u5982\u6b64\u7684\u56f0\u96be\u3002 \u6240\u4ee5\u8fd9\u8fb9\u5efa\u8bae\u4f60\u76f4\u63a5\u5148\u628a llvm-project \u4ed3\u5e93\u4f5c\u4e3a ZIP \u4e0b\u8f7d\u4e0b\u6765\uff0c\u7136\u540e\u6253\u5f00\u5176\u4e2d\u7684 llvm \u5b50\u6587\u4ef6\u5939\uff0c\u7136\u540e\u7528 VS2022 \u6253\u5f00\u5176\u4e2d\u7684 CMakeLists.txt\uff0c\u7136\u540e\u5f00\u59cb\u6784\u5efa\u3002 \u7136\u540e\uff0c\u8981\u5f00\u542f\u4e00\u4e2a CMake \u9009\u9879 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \uff0c\u624d\u80fd\u6784\u5efa Clang \u5b50\u9879\u76ee\uff08\u5426\u5219\u6784\u5efa\u7684\u662f\u8d64\u818a LLVM\uff0c\u6ca1\u6709\u4efb\u4f55\u524d\u7aef\uff0c\u8fd9\u6beb\u65e0\u610f\u4e49\uff09\u3002\u4ec5\u6b64\u662f\u6307\u5b9a\u8fd9\u4e00\u4e2a\u5c0f\u5c0f\u9009\u9879\u5bf9\u4e8e IDE \u53d7\u5bb3\u8005\u53c8\u662f\u4f55\u7b49\u7684\u56f0\u96be\u2026\u2026\u4ed6\u4eec\u9700\u8981\u5728 VS2022 \u4e2d\u6253\u5f00 CMakeSettings.json\uff0c\u4fee\u6539 x64-Debug \u7684\u914d\u7f6e\uff0c\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\uff0c\u503c\u4e3a \u201cclang;clang-tools-extra\u201d\u2026\u2026\u5982\u679c\u4ed6\u4eec\u8981\u6539\u6210 Release \u914d\u7f6e\uff0c\u53c8\u8981\u70b9\u51fb\u52a0\u53f7\u521b\u5efa x64-Release\uff08\u5343\u4e07\u522b\u70b9\u9519\u6210 x86-Release\uff01\uff09\uff0c\u7136\u540e\u518d\u6b21\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\u2026\u2026 \u56e0\u4e3a llvm-project \u662f\u8bb8\u591a\u9879\u76ee\u7684\u96c6\u5408\uff0c\u6839\u76ee\u5f55\u91cc\u5e76\u6ca1\u6709 CMakeLists.txt\uff0c\u800c VS2022 \u4f3c\u4e4e\u53ea\u80fd\u8bc6\u522b\u6839\u76ee\u5f55\u7684 CMakeLists.txt\u2026\u2026 \u6b63\u5e38\u7cfb\u7edf\u53ea\u9700\u8981\u7ed9\u4f60\u5199\u4e00\u4e32\u547d\u4ee4\uff0c\u4f60\u53ea\u7ba1\u590d\u5236\u7c98\u8d34\u5230 Shell \u91cc\u4e00\u6267\u884c\u5c31\u641e\u5b9a\u4e86\u3002\u8111\u762b\u7cfb\u7edf\u9700\u8981\u5927\u91cf\u65e0\u8c13\u7684\u6587\u5b57\u63cf\u8ff0\u548c\u622a\u56fe\u7bad\u5934\u6307\u793a\u534a\u5929\uff0c\u8fd8\u7ecf\u5e38\u6709\u4eba\u770b\u4e0d\u61c2\uff0c\u8981\u53cd\u590d\u5f3a\u8c03\uff0c\u753b\u7bad\u5934\uff0c\u52a0\u7c97\u5b57\u4f53\uff0c\u624d\u80fd\u64cd\u63a7\u4ed6\u7684\u9f20\u6807\u70b9\u51fb\u5230\u6b63\u786e\u6309\u94ae\u4e0a\u3002\u6211\u4e5f\u60f3\u628a\u9f20\u6807\u5b8f\u5f55\u4e0b\u6765\uff0c\u53ef\u662f\u4e0d\u540c\u7535\u8111\u5206\u8fa8\u7387\u4e0d\u540c\uff0c\u7a97\u53e3\u4f4d\u7f6e\u53c8\u5f88\u968f\u673a\uff0c\u7535\u8111\u54cd\u5e94\u901f\u5ea6\u53c8\u968f\u673a\uff0c\u6709\u65f6\u5019 C \u76d8\uff0c\u6709\u65f6\u5019\u53c8 D \u76d8\uff0c\u6839\u672c\u4e0d\u7ed9\u4e00\u4e2a\u7edf\u4e00\u7684\u64cd\u4f5c\u65b9\u5f0f,\u7edf\u4e00\u7684\u547d\u4ee4\u884c\u5c31\u6ca1\u6709\u8fd9\u79cd\u70e6\u607c\u3002\u6240\u4ee5\uff0c\u80fd\u5378\u8f7d\u7684\u5378\u8f7d\uff0c\u80fd\u53cc\u7cfb\u7edf\u7684\u53cc\u7cfb\u7edf\uff0c\u80fd WSL \u4e5f\u603b\u6bd4\u8171\u9798\u7c89\u788e\u5668\uff08\u9f20\u6807\uff09\u597d\uff0c\u81f3\u5c11\u80fd\u4e00\u952e\u7c98\u8d34\u5c0f\u5f6d\u8001\u5e08\u540c\u6b3e\u64cd\u4f5c\u3002","title":"Windows \u7528\u6237"},{"location":"llvm_intro/#_4","text":"$ cd llvm-project $ ls bolt CONTRIBUTING.md LICENSE.TXT pstl build cross-project-tests lld pyproject.toml build.sh flang lldb README.md clang libc llvm runtimes clang-tools-extra libclc llvm-libgcc SECURITY.md cmake libcxx mlir third-party CODE_OF_CONDUCT.md libcxxabi openmp utils compiler-rt libunwind polly \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u7684\u5b50\u9879\u76ee\uff0c\u5176\u4e2d\u6211\u4eec\u4e3b\u8981\u5b66\u4e60\u7684\u5c31\u662f\u8fd9\u91cc\u9762\u7684 llvm \u6587\u4ef6\u5939\uff0c\u4ed6\u662f LLVM \u7684\u672c\u4f53\u3002\u5176\u4e2d\u4e0d\u4ec5\u5305\u542b LLVM \u5e93\uff0c\u4e5f\u5305\u542b\u4e00\u4e9b\u5904\u7406 LLVM IR \u548c\u5b57\u8282\u7801\u7684\u5b9e\u7528\u5de5\u5177\uff08\u4f8b\u5982 llvm-as\uff09\u3002 \u5176\u6b21\u5c31\u662f clang \u6587\u4ef6\u5939\uff0c\u8fd9\u4e2a\u5b50\u9879\u76ee\u5c31\u662f\u5927\u540d\u9f0e\u9f0e\u7684 Clang \u7f16\u8bd1\u5668\uff0c\u4ed6\u4e5f\u662f\u57fa\u4e8e LLVM \u672c\u4f53\u5b9e\u73b0\u7684\uff0c\u672c\u8eab\u53ea\u662f\u4e2a\u524d\u7aef\uff0c\u5e76\u4e0d\u505a\u4f18\u5316\u548c\u540e\u7aef\u6c47\u7f16\u751f\u6210\u3002 clang-tools-extra \u8fd9\u4e2a\u5b50\u9879\u76ee\u662f clangd\u3001clang-tidy\u3001clang-format \u7b49 C/C++ \u4ee3\u7801\u8d28\u91cf\u5de5\u5177\uff0c\u53ef\u4ee5\u9009\u62e9\u4e0d\u6784\u5efa\u3002 libc \u662f Clang \u5b98\u914d\u7684 C \u6807\u51c6\u5e93\uff0c\u800c libcxx \u662f Clang \u5b98\u914d\u7684 C++ \u6807\u51c6\u5e93\uff0c\u60f3\u5b66\u6807\u51c6\u5e93\u6e90\u7801\u7684\u540c\u5b66\u53ef\u4ee5\u770b\u770b\u3002 flang \u662f LLVM \u7684 Fortran \u524d\u7aef\uff0c\u7f16\u7a0b\u754c\u7684\u6d3b\u5316\u77f3\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 lldb \u662f LLVM \u5b98\u65b9\u7684\u8c03\u8bd5\u5668\uff0c\u5bf9\u6807 GCC \u7684 gdb \u8c03\u8bd5\u5668\uff0cVSCode \u4e2d\u7684\u8c03\u8bd5\u9ed8\u8ba4\u5c31\u662f\u57fa\u4e8e lldb \u7684\u3002 lld \u662f LLVM \u5b98\u65b9\u7684\u4e8c\u8fdb\u5236\u94fe\u63a5\u5668\uff0c\u5bf9\u6807 GCC \u7684 ld \u548c ld.gold\uff1b\u800c bolt \u662f\u94fe\u63a5\u540e\u4f18\u5316\u5668\uff0c\u7528\u7684\u4e0d\u591a\u3002 compiler-rt \u662f\u8bf8\u5982 AddressSantizer\uff08\u5185\u5b58\u6ea2\u51fa\u68c0\u6d4b\u5de5\u5177\uff09\u3001MSAN\uff08\u5185\u5b58\u6cc4\u6f0f\u68c0\u6d4b\uff09\u3001TSAN\uff08\u7ebf\u7a0b\u5b89\u5168\u68c0\u6d4b\uff09\u3001UBSAN\uff08\u672a\u5b9a\u4e49\u884c\u4e3a\u68c0\u6d4b\uff09\u7b49\u5de5\u5177\u7684\u5b9e\u73b0\u3002 mlir \u662f LLVM \u5bf9 MLIR \u7684\u7f16\u8bd1\u5668\u5b9e\u73b0\uff08\u4e00\u79cd\u4e3a\u673a\u5668\u5b66\u4e60\u5b9a\u5236\uff0c\u5141\u8bb8\u7528\u6237\u81ea\u5b9a\u4e49\u65b0\u7684 IR \u8282\u70b9\uff0c\u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\u7b49\u9ad8\u9636\u64cd\u4f5c\uff0c\u65b9\u4fbf\u7279\u5b9a\u786c\u4ef6\u8bc6\u522b\u5230\u5e76\u4f18\u5316\u6210\u81ea\u7814\u786c\u4ef6\u4e13\u95e8\u7684\u77e9\u9635\u4e58\u6cd5\u6307\u4ee4\uff0c\u6700\u8fd1\u4f3c\u4e4e\u5728 AI \u5b5d\u5b50\u4e2d\u5f88\u6d41\u884c\uff09\u3002 libclc \u662f LLVM \u5bf9 OpenCL \u7684\u5b9e\u73b0\uff08OpenCL \u8bed\u8a00\u89c4\u8303\u7684\u7f16\u8bd1\u5668\uff09\uff0cOpenCL \u662f\u5b64\u513f\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 openmp \u662f LLVM \u5bf9 OpenMP \u7684\u5b9e\u73b0\uff08\u4e00\u79cd\u7528\u4e8e\u50bb\u74dc\u5f0f CPU \u5355\u673a\u5e76\u884c\u7684\u6846\u67b6\uff0c\u7528\u6cd5\u5f62\u5982 #pragma omp parallel for \uff09\u3002 pstl \u662f LLVM \u5bf9 C++17 Parallel STL \u7684\u5b9e\u73b0\uff08\u540c\u6837\u662f\u5355\u673a CPU \u5e76\u884c\uff0c\u4f18\u52bf\u5728\u4e8e\u5229\u7528\u4e86 C++ \u8bed\u6cd5\u7cd6\uff0c\u4e5f\u6bd4\u8f83\u5b64\u513f\uff0c\u7528\u7684\u4e0d\u591a\uff09\u3002 cmake \u6587\u4ef6\u5939\u5e76\u4e0d\u662f\u5b50\u9879\u76ee\uff0c\u800c\u662f\u88c5\u7740\u548c LLVM \u76f8\u5173\u7684\u4e00\u4e9b CMake \u811a\u672c\u6587\u4ef6\u3002 build \u6587\u4ef6\u5939\u662f\u4f7f\u7528\u8fc7 CMake \u540e\u4f1a\u624d\u751f\u6210\u7684\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u662f cmake -B build \u547d\u4ee4\u751f\u6210\u7684\u3002\u5176\u4e2d\u5b58\u50a8\u7740\u6784\u5efa\u9879\u76ee\u8fc7\u7a0b\u4e2d\u4ea7\u751f\u7684\u4e34\u65f6\u5bf9\u8c61\u6587\u4ef6\u548c\u6700\u7ec8\u7684\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u6240\u6709\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u653e\u5728 build/bin \u5b50\u6587\u4ef6\u5939\u4e2d\uff0c\u4f8b\u5982 build/bin/llvm-as\u3002\u5982\u679c CMake \u51fa\u73b0\u4e0d\u542c\u4f7f\u5524\u7684\u95ee\u9898\uff0c\u53ef\u4ee5\u5220\u9664 build \u6587\u4ef6\u5939\u8bd5\u8bd5\uff0c\u8fd9\u4f1a\u8feb\u4f7f CMake \u91cd\u65b0\u751f\u6210\uff08\u5efa\u8bae\u6bcf\u6b21\u4fee\u6539\u8fc7 CMake \u9009\u9879\u540e\u90fd\u5220 build\uff09\u3002","title":"\u9879\u76ee\u76ee\u5f55\u7ed3\u6784"},{"location":"llvm_intro/#_5","text":"cd llvm-project bash build.sh build.sh \u811a\u672c\u7684\u5185\u5bb9\u7b49\u4ef7\u4e8e\uff1a cmake -Sllvm -Bbuild -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" -GNinja ninja -Cbuild \u4f60\u5728\u547d\u4ee4\u884c\u624b\u52a8\u8f93\u5165\u8fd9\u4e24\u6761\u547d\u4ee4\u4e5f\u662f\u7b49\u4ef7\u7684\uff0c build.sh \u53ea\u662f\u4e3a\u4e86\u65b9\u4fbf\u3002 \u6b64\u5904 -S llvm \u9009\u9879\u8868\u793a\u6307\u5b9a\u6e90\u7801\u8def\u5f84\u4e3a\u6839\u76ee\u5f55\u4e0b\u7684 llvm \u5b50\u9879\u76ee\u6587\u4ef6\u5939\uff0c\u548c cd llvm && cmake -B build \u7b49\u4ef7\uff0c\u4f46\u662f\u4e0d\u7528\u5207\u6362\u76ee\u5f55\u3002 -G Ninja \u8868\u793a\u4f7f\u7528 Ninja \u540e\u7aef\uff0c\u5982\u679c\u4f60\u6ca1\u6709 Ninja\uff0c\u53ef\u4ee5\u53bb\u6389\u8be5\u9009\u9879\uff0cCMake \u5c06\u4f1a\u91c7\u7528\u9ed8\u8ba4\u7684 Makefile \u540e\u7aef\uff08\u66f4\u6162\uff09\u3002 \u5982\u679c\u4f60\u662f Wendous \u53d7\u5bb3\u8005\uff0c\u8bf7\u81ea\u884c\u7528\u9f20\u6807\u70b9\u51fb\u5e8f\u5217\u5728 VS2022 \u4e2d\u6a21\u62df\u4ee5\u4e0a\u4ee3\u7801\u4e4b\u540c\u7b49\u6548\u679c\uff0c\u795d\u60a8\u8171\u9798\u6109\u5feb\uff01 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \u8868\u793a\u542f\u7528 clang \u548c clang-tools-extra \u4e24\u4e2a\u5b50\u9879\u76ee\u3002 \u8fd9\u662f\u56e0\u4e3a\u901a\u5e38\u7528\u7684\u524d\u7aef\u90fd\u662f C++\uff0c\u6240\u4ee5 LLVM \u5b98\u65b9\u5728 build.sh \u91cc\u5c31\u8fd9\u4e48\u5199\u4e86\u3002 \u5982\u679c\u4f60\u53e3\u5473\u6bd4\u8f83\u91cd\uff0c\u60f3\u7814\u7a76 Fortran \u524d\u7aef\uff0c\u4e5f\u53ef\u4ee5\u5b9a\u4e49\u8be5 CMake \u53d8\u91cf\u4e3a -DLLVM_ENABLE_PROJECTS=\"flang\" \u3002 build.sh \u540e\uff0c\u9700\u8981\u82b1\u8d39\u5927\u7ea6 10 \u5206\u949f\u65f6\u95f4\uff08\u53d6\u51b3\u4e8e\u4f60\u7684\u7535\u8111\u914d\u7f6e\uff09\uff0c\u8fd9\u6bb5\u65f6\u95f4\u4f60\u53ef\u4ee5\u5148\u770b\u4e0b\u9762\u7684\u57fa\u672c\u6982\u5ff5\u901f\u89c8\u3002\u7b49\u98ce\u6247\u505c\u4e86\u4ee5\u540e\uff0cLLVM \u548c Clang \u5c31\u6784\u5efa\u597d\u4e86\u3002","title":"\u5f00\u59cb\u6784\u5efa"},{"location":"llvm_intro/#_6","text":"ls build/bin","title":"\u8fd0\u884c\u8bd5\u8bd5"},{"location":"llvm_intro/#_7","text":"\u53ea\u662f\u8ba9\u4f60\u83b7\u5f97\u4e00\u4e2a\u5168\u5c40\u89c2\u5ff5\uff08overview\uff09\uff0c\u4e0d\u7528\u6df1\u7a76\u7ec6\u8282\uff0c\u4e4b\u540e\u4f1a\u518d\u8be6\u7ec6\u5c55\u5f00\u4ecb\u7ecd\u7684\u3002 \u5b66\u8fc7 C \u8bed\u8a00\u7684\u540c\u5b66\u90fd\u77e5\u9053\uff0c\u4e00\u4e2a C/C++ \u6e90\u7801\u6587\u4ef6\u5230\u8ba1\u7b97\u673a\u5b9e\u9645\u53ef\u6267\u884c\u7684 EXE \u6587\u4ef6\u4e4b\u95f4\uff0c\u4e3b\u8981\u6709\u4e24\u6b65\u64cd\u4f5c\uff1a\u7f16\u8bd1\uff08compile\uff09\u548c\u94fe\u63a5\uff08link\uff09\u3002 \u4e4b\u6240\u4ee5\u628a\u7f16\u8bd1\u548c\u94fe\u63a5\u5206\u5f00\uff0c\u662f\u56e0\u4e3a\u4e00\u4e2a\u9879\u76ee\u5e38\u5e38\u7531\u8bb8\u591a\u6e90\u7801\u6587\u4ef6\u7ec4\u6210\uff0c\u800c\u4e0d\u53ea\u662f\u5355\u4e2a\u6587\u4ef6\u3002\u7f16\u8bd1\u5668\u628a C++ \u6e90\u7801\u7f16\u8bd1\u6210\u4e2d\u95f4\u5bf9\u8c61\u6587\u4ef6\uff08.o \u6216 .obj \u683c\u5f0f\uff09\uff0c\u5982\u679c\u6709\u5f88\u591a .cpp \u6587\u4ef6\uff0c\u5c31\u4f1a\u5f97\u5230\u5f88\u591a .o \u6587\u4ef6\uff0c\u7136\u540e\u7531\u94fe\u63a5\u5668\u8d1f\u8d23\u7edf\u4e00\u94fe\u63a5\u6240\u6709 .o \u6587\u4ef6\uff0c\u5c31\u5f97\u5230\u4e86\u6700\u7ec8\u7684 .exe \u6216 .dll \u76ee\u6807\u6587\u4ef6\u3002 \u5206\u79bb\u591a .cpp \u6587\u4ef6\u7684\u597d\u5904\u662f\uff0c\u7f16\u8bd1\u901f\u5ea6\u66f4\u5feb\uff0c\u53ef\u4ee5\u5e76\u884c\u7f16\u8bd1\u3002\u800c\u4e14\u4fee\u6539\u4e86\u5176\u4e2d\u4e00\u4e2a .cpp \u6587\u4ef6\uff0c\u53ea\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u90a3\u4e2a .cpp \u5bf9\u5e94\u7684 .o \u6587\u4ef6\uff0c\u7136\u540e\u91cd\u65b0\u94fe\u63a5\u6700\u7ec8\u7684 .exe \u5373\u53ef\uff0c\u65e0\u9700\u518d\u91cd\u590d\u7f16\u8bd1\u5176\u4ed6 .cpp \u6587\u4ef6\u7684 .o \u6587\u4ef6\u4e86\u3002\u81ea\u52a8\u68c0\u6d4b\u54ea\u4e9b .cpp \u6587\u4ef6\u66f4\u65b0\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u7f16\u8bd1 .o \u6587\u4ef6\uff0c\u662f Makefile \u548c Ninja \u4e4b\u7c7b\u6784\u5efa\u7cfb\u7edf\u7684\u804c\u8d23\u3002 \u6211\u4eec\u73b0\u5728\u8981\u6765\u5b66\u4e60\u7684\u5c31\u662f\u5176\u4e2d\u7684\u7f16\u8bd1\u9636\u6bb5\uff0c\u8fd9\u4e5f\u662f\u5927\u90e8\u5206\u4eba\u60f3\u5173\u6ce8\u7684\u91cd\u70b9\u3002 \u5728\u8fd9\u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\uff0c\u53d1\u751f\u4e86\u5f88\u591a\u6709\u8da3\u7684\u4e8b\uff0c\u4f46\u5374\u88ab\u4f20\u7edf\u6559\u6750\u7684 C++ \u201c\u4e24\u6bb5\u5f0f\u201d\u7f16\u8bd1\u6a21\u578b\uff08\u7f16\u8bd1 -> \u94fe\u63a5\uff09\u4e00\u7b14\u5e26\u8fc7\u4e86\u3002 \u5c31\u62ff\u8fd9\u91cc\u9762\u7684\u201c\u7f16\u8bd1\u201d\u9636\u6bb5\u5c55\u5f00\u8bb2\u8bb2\uff0c\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5c06 .cpp \u6587\u4ef6\u8f6c\u6362\u4e3a\u5145\u65a5\u7740\u673a\u5668\u6307\u4ee4\u7801 .o \u6587\u4ef6\u7684\uff1f .o \u6587\u4ef6\u91cc\u51e0\u4e4e\u5168\u662f\u5b8c\u6210\u7684\u673a\u5668\u6307\u4ee4\u7801\uff0c\u9664\u4e86\u90e8\u5206 call \u5230\u5916\u90e8\u51fd\u6570\u7684\u4e00\u90e8\u5206\u6307\u4ee4\uff0c\u4f1a\u7559\u767d\u3002\u8fd9\u90e8\u5206\u7559\u767d\u4f1a\u7b49\u5230\u94fe\u63a5\u9636\u6bb5\u65f6\uff0c\u7531\u94fe\u63a5\u5668\u5728\u5176\u4ed6 .o \u6587\u4ef6\u4e2d\u627e\u5230\u76f8\u540c\u7684\u7b26\u53f7\u65f6\u66ff\u6362\u4e0a\u6b63\u786e\u7684\u5730\u5740\u548c\u504f\u79fb\u91cf\uff0c\u5f97\u5230\u5b8c\u6574\u7684\u53ef\u6267\u884c .exe \u6587\u4ef6\u3002 \u8fc7\u53bb\uff0c\u6211\u4eec\u628a\u7f16\u8bd1\u5668\u770b\u4f5c\u9ed1\u7bb1\uff0c\u8fdb\u53bb\u6e90\u7801\uff0c\u51fa\u6765\u673a\u5668\u7801\uff0c\u4e2d\u95f4\u6709\u54ea\u4e9b\u8fc7\u7a0b\uff1f\u53ea\u80fd\u8ba4\u4e3a\u662f\u9b54\u6cd5\u3002 \u73b0\u5728\uff0c\u6709\u4e86 LLVM \u548c Clang \u6e90\u7801\u5728\u624b\uff0c\u7ec8\u4e8e\u53ef\u4ee5\u4e00\u63a2\u7a76\u7adf\u4e86\u3002 \u5b9e\u9645\u4e0a\uff0c\u201c\u7f16\u8bd1\u201d\u8fd9\u4e00\u8fc7\u7a0b\uff0c\u8fd8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u62c6\u5206\u6210\u4e09\u4e2a\u9636\u6bb5\u3002","title":"\u57fa\u672c\u6982\u5ff5\u901f\u89c8"},{"location":"llvm_intro/#_8","text":"\u7f16\u8bd1\u5668\uff08Compiler\uff09\u7684\u5de5\u4f5c\u6d41\u7a0b\u53ef\u4ee5\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\uff1a \u524d\u7aef\uff08Front-end\uff09\uff1a\u8d1f\u8d23\u63a5\u6536\u6e90\u4ee3\u7801\uff0c\u89e3\u6790\u51fa\u62bd\u8c61\u8bed\u6cd5\u6811\uff08AST\uff09\uff0c\u5e76\u8fdb\u884c\u8bed\u6cd5\u548c\u8bed\u4e49\u5206\u6790\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\u3002 \u4e2d\u7aef\uff08Middle-end\uff09\uff1a\u8d1f\u8d23\u4f18\u5316\u4e2d\u95f4\u8868\u793a\u7801\u3002 \u540e\u7aef\uff08Back-end\uff09\uff1a\u8d1f\u8d23\u5c06\u4f18\u5316\u5b8c\u6bd5\u7684\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u4e2d\u540e\u7aef\u548c\u4e92\u8054\u7f51\u5f00\u53d1\u8005\u6240\u8bf4\u7684\u524d\u540e\u7aef\u65e0\u5173\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u662f\u524d\u7aef\u9ad8\u624b\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u96c7\u4f63\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u8ba8\u538c JS\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u4f60\u4e0d\u662f\u524d\u7aef\u9ad8\u624b\u5417\uff1f\u5c0f\u5f6d\u8001\u5e08\uff1a\u7f16\u8bd1\u5668\u524d\u7aef\u3002 \u5982\u679c\u4f60\u60f3\u8981\u7814\u7a76 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u6bd4\u5982\u505a\u4e2a C++ \u8bed\u6cd5\u9ad8\u4eae\u63d2\u4ef6\uff0c\u90a3\u5c31\u9700\u8981\u770b\u524d\u7aef\u3002libclang \u548c clangd \u53ef\u4ee5\u5e2e\u52a9\u4f60\u89e3\u6790 C++ \u7e41\u7410\u7684\u8bed\u6cd5\uff0c\u5e76\u4ee5 AST \u6811\u7684\u7ed3\u6784\u63d0\u4f9b\u7ed9\u4f60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u5982\u679c\u4f60\u8981\u8bbe\u8ba1\u4e00\u95e8\u65b0\u8bed\u8a00\uff0c\u751a\u81f3\u662f OpenGL \u9a71\u52a8\uff08\u5176\u9700\u8981\u5b9e\u73b0 GLSL \u7f16\u8bd1\u5668\uff09\uff0c\u5b9e\u9645\u4e0a\u4e5f\u5c31\u662f\u4e3a LLVM \u6dfb\u52a0\u4e00\u4e2a\u524d\u7aef\u3002 \u5982\u679c\u4f60\u5bf9\u5185\u5b58\u6a21\u578b\uff0c\u6027\u80fd\u4f18\u5316\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u7814\u7a76\u4e2d\u7aef\u3002\u8fd9\u662f\u76ee\u524d\u5b66\u672f\u7814\u7a76\u6bd4\u8f83\u6d3b\u8dc3\u7684\u9886\u57df\uff0c\u7279\u522b\u662f\u591a\u9762\u4f53\u4f18\u5316\u65b9\u5411\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6c34\u4e24\u5f20 paper \u6216 PR\u3002\u8fd9\u90e8\u5206\u90fd\u662f\u57fa\u4e8e LLVM IR \u64cd\u4f5c\u7684\uff0c\u6709\u7279\u522b\u591a\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u3002 \u5982\u679c\u4f60\u5bf9\u6c47\u7f16\u8bed\u8a00\uff0c\u673a\u5668\u6307\u4ee4\uff0c\u786c\u4ef6\u67b6\u6784\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u770b\u540e\u7aef\u3002\u8fd9\u91cc\u9762\u6709\u628a\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u771f\u6b63\u53ef\u6267\u884c\u7684\u6c47\u7f16\u6307\u4ee4\u7684\u5b8c\u6574\u8fc7\u7a0b\uff0c\u81ea\u7814\u82af\u7247\u7684\u5927\u5382\u901a\u5e38\u60f3\u8981\u4e3a LLVM \u6dfb\u52a0\u540e\u7aef\u3002 \u6ce8\u610f\u94fe\u63a5\u9636\u6bb5\uff08Link\uff09\u5c5e\u4e8e\u94fe\u63a5\u5668\u7684\u804c\u8d23\uff0c\u4e0d\u5c5e\u4e8e\u72ed\u4e49\u4e0a\u7684\u7f16\u8bd1\u5668\uff1b\u524d\u4e2d\u540e\u7aef\u53ea\u662f\u5bf9\u7f16\u8bd1\uff08Compile\uff09\u8fd9\u4e00\u9636\u6bb5\u7684\u8fdb\u4e00\u6b65\u62c6\u5206\u3002 \u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u8d70\u8fdb LLVM \u8fd9\u5ea7\u5f00\u6e90\u5de5\u5382\uff0c\u4e00\u6b65\u6b65\u89c2\u5bdf\u4e00\u6bb5 C++ \u4ee3\u7801\u88ab\u7f16\u8bd1\u6210\u6c47\u7f16\u7684\u5168\u8fc7\u7a0b\u3002","title":"\u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef"},{"location":"llvm_intro/#ast","text":"\u7f16\u8bd1\u5668\u7684\u524d\u7aef\u8d1f\u8d23\u89e3\u6790 C++ \u8fd9\u7c7b\u9ad8\u7ea7\u8bed\u8a00\u7684\u6e90\u4ee3\u7801\uff0c\u751f\u6210\u62bd\u8c61\u8bed\u6cd5\u6811\uff08Abstract Syntax Tree\uff0cAST\uff09\u3002AST \u662f\u6e90\u4ee3\u7801\u7684\u4e00\u79cd\u62bd\u8c61\u8868\u793a\uff0c\u5176\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u6e90\u4ee3\u7801\u4e2d\u7684\u4e00\u4e2a\u8bed\u6cd5\u7ed3\u6784\uff0c\u4f8b\u5982 if\u3001while\u3001for\u3001\u51fd\u6570\u8c03\u7528\u3001\u8fd0\u7b97\u7b26\u3001\u53d8\u91cf\u58f0\u660e\u7b49\u3002\u6bcf\u4e2a AST \u8282\u70b9\u90fd\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982\u7c7b\u578b\u3001\u4f5c\u7528\u57df\u3001\u4fee\u9970\u7b26\u7b49\u3002 \u4e0d\u540c\u7c7b\u578b\u7684 AST \u8282\u70b9\u6709\u4e0d\u540c\u7684\u7c7b\u578b\u540d\uff0c\u4f8b\u5982 IntegerLiterial \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6574\u6570\u7c7b\u578b\u7684\u5e38\u91cf\uff0c\u800c BinaryOperator \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u4e8c\u5143\u8fd0\u7b97\u7b26\uff08\u53ef\u80fd\u662f\u52a0\u51cf\u4e58\u9664\u7b49\u4e8c\u5143\u8fd0\u7b97\uff09\u3002 AST \u8282\u70b9\u53ef\u4ee5\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u8282\u70b9\uff0c\u8bb8\u591a\u8282\u70b9\u5c31\u6784\u6210\u4e86\u4e00\u9897\u8bed\u6cd5\u6811\u3002\u6bcf\u4e2a .cpp \u6587\u4ef6\u90fd\u53ef\u4ee5\u89e3\u6790\u5f97\u5230\u4e00\u9897\u8bed\u6cd5\u6811\uff0c\u5728 C++ \u7684\u8bed\u6cd5\u4e2d\uff0c\u6bcf\u9897\u6811\u7684\u6839\u90e8\u603b\u662f\u4e00\u4e2a TranslationUnitDecl \u7c7b\u578b\u7684\u8282\u70b9\u3002\u8fd9\u662f\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\uff0c\u5176\u4e2d\u5305\u542b\u4e86\u4efb\u610f\u591a\u7684\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u7b49\uff0c\u4f5c\u4e3a TU \u7684\u5b50\u8282\u70b9\u5b58\u5728\u5176\u4e2d\u3002 \u5bf9\u6811\u505a\u4e86\u4e00\u4e9b\u8bed\u6cd5\u8bed\u4e49\u4e0a\u7684\u6b63\u786e\u6027\u68c0\u6d4b\u540e\uff0c\u5c31\u4f1a\u904d\u5386\u8fd9\u9897\u6811\uff0c\u4e3a\u6bcf\u4e2a\u8282\u70b9\u9010\u4e00\u751f\u6210\u5bf9\u5e94\u7684 LLVM IR\uff0c\u8f93\u5165\u5230\u4e2d\u540e\u7aef\u4f18\u5316\u5e76\u751f\u6210\u771f\u6b63\u7684\u6c47\u7f16\u3002 // Clang \u6e90\u7801\u4e2d\u7684 AST \u8282\u70b9\u7c7b\u578b\u5927\u81f4\u957f\u8fd9\u6837\uff08\u5df2\u7b80\u5316\uff09 struct ASTNode { std::string type; std::vector children; }; \u8fd9\u90e8\u5206\u7684\u5b9e\u73b0\u5728 clang \u5b50\u9879\u76ee\u4e2d\u3002 clang \u89e3\u6790\u6e90\u7801\u751f\u6210\u8bed\u6cd5\u6811\u7684\u6848\u4f8b\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u8fd0\u884c\u547d\u4ee4\uff1a clang -fsyntax-only -Xclang -ast-dump test.cpp -fsyntax-only \u610f\u5473\u7740\u53ea\u89e3\u6790\u8bed\u6cd5\uff0c\u4e0d\u8fdb\u884c\u7f16\u8bd1\u548c\u94fe\u63a5\uff08\u4e0d\u4f1a\u751f\u6210 a.out\uff09\uff1b -Xclang \u662f\u6307\u5411 Clang \u6838\u5fc3\u4f20\u9012\u4e00\u4e2a\u9009\u9879\uff0c\u4e5f\u5c31\u662f\u540e\u9762\u7d27\u6328\u7740\u7684 -ast-dump \uff1b -ast-dump \u662f Clang \u6838\u5fc3\u7684\u9009\u9879\uff0c\u8868\u793a\u8981\u6c42\u6253\u5370\u51fa\u8bed\u6cd5\u6811\u3002 \u8f93\u51fa\uff1a \u5df2\u7701\u7565 \u5934\u6587\u4ef6\u90e8\u5206\u7684\u5b50\u8282\u70b9\uff0c\u4ec5\u5c55\u793a\u4e86 main \u7684\u90e8\u5206\uff0c\u5426\u5219\u5c31\u592a\u957f\u4e86\u3002 \u6700\u6839\u90e8\u7684 TranslationUnitDecl \u8282\u70b9\uff0c\u662f\u6574\u4e2a\u5f53\u524d\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\u3002 \u6240\u6709\u7684 C++ \u6e90\u7801\u89e3\u6790\u540e\u5f97\u5230\u7684\uff0c\u603b\u662f\u4ee5 TranslationUnitDecl \u4e3a\u6839\u8282\u70b9\u7684\u4e00\u9897\u8bed\u6cd5\u6811\u3002 \u7ffb\u8bd1\u5355\u5143 \u6307\u7684\u5c31\u662f\u5355\u4e2a .cpp \u6587\u4ef6\uff0c\u53ca\u5176\u5bfc\u5165\u7684\u6240\u6709 .h \u5934\u6587\u4ef6\u62fc\u63a5\u5f62\u6210\u7684\u6574\u6bb5 C++ \u6e90\u7801\uff0c\u662f C++ \u7f16\u8bd1\u7684\u6700\u5c0f\u5355\u5143\u3002\u4e0d\u540c\u7ffb\u8bd1\u5355\u5143\u7f16\u8bd1\u6210\u5404\u81ea\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u540e\uff0c\u4e4b\u95f4\u518d\u901a\u8fc7\u201c\u94fe\u63a5\u5668\u201d\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e00\u4e2a\u6700\u7ec8\u7684\u76ee\u6807\u6587\u4ef6\uff08.exe \u6216 .dll\uff09\u3002 \u7ffb\u8bd1\u5355\u5143\u4e2d\u5305\u542b\u4e86\u6240\u6709\u5f53\u524d .cpp \u53ca\u5176\u5bfc\u5165\u7684\u5934\u6587\u4ef6\u4e2d\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\u8282\u70b9\u6709\u7740\u8bb8\u591a\u5b50\u8282\u70b9\uff0c\u4e00\u5927\u5806\u90fd\u662f \u5934\u6587\u4ef6\u4e2d\u5bfc\u5165\u8fdb\u6765\u7684\u51fd\u6570\u58f0\u660e\u548c\u7c7b\u578b\u5b9a\u4e49\u3002 \u4e3a\u4e86\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u6211\u7279\u610f\u4ece\u622a\u56fe\u4e2d\u6263\u6389\u4e86\u6240\u6709\u6765\u81ea \u7684\u8282\u70b9\uff0c\u5e76\u4e0d\u662f\u8bf4\u7ffb\u8bd1\u5355\u5143\u4e0d\u5305\u62ec\u5934\u6587\u4ef6\u54e6\uff01 \u6211\u4eec\u6700\u5173\u5fc3\u7684\u662f\u5176\u4e2d\u4e00\u4e2a\u5b50\u8282\u70b9\uff1a\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u8282\u70b9\uff0c\u7c7b\u578b\u4e3a FunctionDecl\u3002 \u6b64\u5904 FunctionDecl \u5c31\u8868\u660e\uff0c\u8be5\u8282\u70b9\u662f\u4e00\u4e2a\u51fd\u6570\uff08Function\uff09\u7684\u58f0\u660e\uff08Decleration\uff09\u3002\u6ce8\u610f\u5230\u540e\u9762\u8ddf\u7740\u8bb8\u591a\u548c\u8be5\u51fd\u6570\u5b9a\u4e49\u6709\u5173\u7684\u5173\u952e\u4fe1\u606f\uff0c\u8ba9\u6211\u4eec\u9010\u4e00\u5206\u6790\uff1a \u8fd9\u91cc\u7684\u5341\u516d\u8fdb\u5236\u6570 0x567bdbf246d8 \u662f AST \u8282\u70b9\u5728\u7f16\u8bd1\u5668\u5185\u5b58\u4e2d\u7684\u5730\u5740\uff0c\u6bcf\u6b21\u90fd\u4e0d\u4e00\u6837\uff0c\u65e0\u610f\u4e49\u3002 \u540e\u9762\u7684\u5c16\u62ec\u53f7 \u91cc\u8fd8\u597d\u5fc3\u63d0\u9192\u4e86\u51fd\u6570\u5b9a\u4e49\u7684\u4f4d\u7f6e\u3002 \u6700\u540e\u662f\u51fd\u6570\u540d main \u548c\u51fd\u6570\u7c7b\u578b int () \uff0c\u8bf4\u660e\u8fd9\u662f\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u3002 \u6709\u8da3\u7684\u662f\uff0c\u8be5\u8282\u70b9\u7684\u7c7b\u578b\u662f FunctionDecl\uff0c\u7ffb\u8bd1\u6210\u4e2d\u6587\u5c31\u662f\u51fd\u6570\u58f0\u660e\u3002\u4f46\u662f\u6211\u4eec\u5199\u7684\u660e\u660e\u662f\u4e00\u4e2a\u51fd\u6570\u7684 \u5b9a\u4e49 \u554a\uff01\u4e3a\u4ec0\u4e48\u88ab Clang AST \u5f53\u4f5c\u4e86 \u58f0\u660e \u5462\uff1f\u539f\u6765\uff0cC++ \u5b98\u65b9\u7684\u8bdd\u8bed\u4e2d\uff0c\u5b9a\u4e49\u4e5f\u662f\u58f0\u660e\uff01\u4f46\u58f0\u660e\u4e0d\u90fd\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u8fd9\u91cc\u7684 FunctionDecl \u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u901a\u7528\u7684\u8282\u70b9\uff0c\u65e2\u53ef\u4ee5\u662f\u58f0\u660e\uff08\u540e\u9762\u76f4\u63a5\u63a5 ; \u7684\uff09\uff0c\u4e5f\u53ef\u4ee5\u662f\u5b9a\u4e49\uff08\u540e\u9762\u63a5\u7740 {} \u7684\uff09\uff0c\u8981\u6839\u636e\u662f\u5426\u6709\u5b50\u8282\u70b9\uff08\u82b1\u62ec\u53f7\u8bed\u53e5\u5757\uff09\u6765\u5224\u65ad\u3002 \u603b\u4e4b\uff0c\u5b9a\u4e49\u548c\u58f0\u660e\u662f\u5b50\u96c6\u5173\u7cfb\u3002\u5f53\u6211\u4eec\u8981\u5f3a\u8c03\u4e00\u4e2a\u58f0\u660e\u53ea\u662f\u58f0\u660e\uff0c\u6ca1\u6709\u5b9a\u4e49\u65f6\uff0c\u4f1a\u7528 \u975e\u5b9a\u4e49\u58f0\u660e \u8fd9\u6837\u4e25\u8c28\u7684\u5f8b\u5e08\u8bf4\u6cd5\u3002\u4f46\u65e5\u5e38\u63d0\u95ee\u65f6\u4f60\u8bf4\u201c\u58f0\u660e\u201d\u6211\u4e5f\u660e\u767d\uff0c\u4f60\u6307\u7684\u5e94\u8be5\u662f\u975e\u5b9a\u4e49\u58f0\u660e\u3002\u66f4\u591a\u76f8\u5173\u6982\u5ff5\u8bf7\u770b \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49 \u7ae0\u8282\u548c \u767d\u5f8b\u5e08\u7684\u9510\u8bc4 \uff0c\u7528\u6587\u6c0f\u56fe\u6765\u753b\u5c31\u662f\uff1a \u51fd\u6570\u5b9a\u4e49\u8282\u70b9\u53c8\u5177\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f CompoundStmt\u3002\u8fd9\u4e2a\u5b9e\u9645\u4e0a\u5c31\u662f\u6211\u4eec\u6240\u8bf4\u7684\u82b1\u62ec\u53f7\u8bed\u53e5\u5757 {} \u4e86\u3002\u4ed6\u672c\u8eab\u4e5f\u662f\u4e00\u6761\u8bed\u53e5\uff0c\u4f46\u91cc\u9762\u7531\u5f88\u591a\u6761\u5b50\u8bed\u53e5\u7ec4\u6210\u3002\u89c4\u5b9a\u51fd\u6570\u58f0\u660e FunctionDecl \u5982\u679c\u662f\u5b9a\u4e49\uff0c\u5219\u5176\u552f\u4e00\u5b50\u8282\u70b9\u5fc5\u987b\u662f\u8bed\u53e5\u5757\u7c7b\u578b CompoundStmt\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u719f\u6089\u7684\u51fd\u6570\u58f0\u660e\u540e\u7d27\u63a5\u7740\u82b1\u62ec\u53f7\uff0c\u5c31\u80fd\u5b9a\u4e49\u51fd\u6570\u3002\u5982\u679c\u662f\u975e\u5b9a\u4e49\u58f0\u660e\uff08\u4ec5\u58f0\u660e\uff0c\u4e0d\u5b9a\u4e49\uff09\u90a3\u5c31\u6ca1\u6709\u8fd9\u4e2a\u5b50\u8282\u70b9\u3002 \u63a5\u4e0b\u6765\u53ef\u4ee5\u770b\u5230 CompountStmt \u5185\u90e8\uff0c\u53c8\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1aCallExpr \u548c ReturnStmt\uff0c\u5206\u522b\u662f\u6211\u4eec\u5bf9 printf \u51fd\u6570\u7684\u8c03\u7528\uff0c\u548c return 0 \u8fd9\u4e24\u6761\u5b50\u8bed\u53e5\u3002 ReturnStmt \u5f88\u597d\u7406\u89e3\uff0c\u4ed6\u53ea\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f IntegerLiterial\uff0c\u8868\u793a\u4e00\u4e2a\u6574\u5f62\u5e38\u6570\uff0c\u6574\u6570\u7684\u7c7b\u578b\u662f int\uff0c\u503c\u662f 0\u3002\u8fd9\u79cd\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\u7684 ReturnStmt \u8282\u70b9\uff0c\u5c31\u8868\u793a\u4e00\u4e2a\u6709\u8fd4\u56de\u503c\u7684 return \u8bed\u53e5\uff0c\u6574\u4f53\u6765\u770b\u4e5f\u5c31\u662f\u6211\u4eec\u4ee3\u7801\u91cc\u5199\u7684 return 0 \u3002 \u4e3e\u4e00\u53cd\u4e09\uff0c\u53ef\u4ee5\u60f3\u8c61\uff1a\u5982\u679c\u4ee3\u7801\u91cc\u5199\u7684\u662f return x + 1 \uff0c\u90a3\u4e48 ReturnStmt \u7684\u5b50\u8282\u70b9\u5c31\u4f1a\u53d8\u6210\u8fd0\u7b97\u7b26\u4e3a + \u7684 BinaryOperator\u3002\u5176\u53c8\u5177\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1a\u5de6\u4fa7\u662f DeclRefExpr \u8282\u70b9\uff0c\u6807\u8bc6\u7b26\u4e3a x \uff1b\u53f3\u4fa7\u662f IntegerLiterial \u8282\u70b9\uff0c\u503c\u4e3a 1\u3002 \u7136\u540e\u6211\u4eec\u6765\u770b printf \u51fd\u6570\u8c03\u7528\u8fd9\u6761\u8bed\u53e5\uff1a \u53ef\u4ee5\u770b\u5230\u662f\u4e00\u4e2a CallExpr\uff0c\u8868\u793a\u8fd9\u662f\u51fd\u6570\u8c03\u7528\uff0c\u800c\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\u9700\u8981\u77e5\u9053\u4e24\u4e2a\u4fe1\u606f\uff1a \u8c03\u7528\u54ea\u4e2a\u51fd\u6570\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f printf \u51fd\u6570\u3002 \u4f20\u9012\u7ed9\u51fd\u6570\u7684\u5b9e\u53c2\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f \"Hello, world!\" \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u3002 \u8fd9\u5c31\u5206\u522b\u7528\u4e24\u4e2a\u5b50\u8282\u70b9\u8868\u793a\u4e86\u3002 \u6ce8\u610f\u5230\u8fd9\u91cc printf \u53d1\u751f\u4e86\u4e00\u4e2a\u9690\u5f0f\u8f6c\u6362 ImplicitCastExpr \u540e\u624d\u4f5c\u4e3a CallExpr \u7684\u7b2c\u4e00\u4e2a\u5b50\u8282\u70b9\uff08\u56de\u7b54\u4e86\u8c03\u7528\u54ea\u4e2a\u51fd\u6570\u7684\u95ee\u9898\uff09\uff0c\u5e76\u4e14\u540e\u9762\u6ce8\u91ca\u4e86\u8bf4 FunctionToPointerDecay \u3002\u4e5f\u5c31\u662f\u8bf4\uff0c printf \u8fd9\u4e2a\u6807\u8bc6\u7b26\uff08DeclRefExpr\uff09\u672c\u6765\u662f\u4e00\u4e2a\u5bf9\u51fd\u6570\u6807\u8bc6\u7b26\u7684\u5f15\u7528\uff0c\u8fd8\u6ca1\u6709\u53d8\u6210\u51fd\u6570\u6307\u9488\uff0c\u8fd9\u65f6\u5019\u8fd8\u6ca1\u6709\u5b8c\u6210\u51fd\u6570\u7684\u91cd\u8f7d\u51b3\u8bae\u3002\u662f\u7b49\u5230\u51fd\u6570\u88ab () \u8c03\u7528\u65f6\uff0c\u624d\u4f1a\u89e6\u53d1\u91cd\u8f7d\u51b3\u8bae\uff0c\u800c\u5b9e\u73b0\u533a\u5206\u91cd\u8f7d\u7684\u65b9\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\u5f15\u7528\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u6210\u51fd\u6570\u6307\u9488\u7684\u8fc7\u7a0b\u6240\u89e6\u53d1\u7684\uff0c\u4e5f\u5c31\u662f\u8fd9\u91cc\u7684 ImplicitCastExpr \u9690\u5f0f\u8f6c\u6362\u8282\u70b9\u4e86\u3002\u8fd9\u79cd\u81ea\u52a8\u53d1\u751f\u7684\u9690\u5f0f\u8f6c\u6362\u88ab\u79f0\u4e3a\u201c\u9000\u5316\u201d\uff08decay\uff09\u3002\u6240\u4ee5\uff0c\u51fd\u6570\u5f15\u7528\u65e0\u6cd5\u76f4\u63a5\u8c03\u7528\uff0cClang \u91cc\u4e00\u76f4\u90fd\u662f\u9700\u8981\u9000\u5316\u6210\u6307\u9488\u624d\u8c03\u7528\u7684\u3002 \u7136\u540e\uff0c\u8fd9\u91cc\u7684\u51fd\u6570\u53c2\u6570\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6309\u7406\u8bf4\u4e00\u4e2a StringLiterial \u8282\u70b9\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u6709\u4e2a ImplicitCastExpr\uff1f\u8fd9\u91cc\u6709\u4e2a\u5e38\u89c1\u8bef\u533a\u9700\u8981\u7ea0\u6b63\uff1a\u5f88\u591a\u540c\u5b66\u5e38\u5e38\u60f3\u5f53\u7136\u4ee5\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char * \u3002\u5b9e\u9645\u4e0a\uff0c\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char [] \uff0c\u662f\u4e00\u4e2a\u6570\u7ec4\u7c7b\u578b\uff01\u6570\u7ec4\u4e0d\u662f\u6307\u9488\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u5b8c\u5168\u4e0d\u540c\u7684\u7c7b\u578b\u3002\u4e4b\u6240\u4ee5\u4f60\u4f1a\u6709\u6570\u7ec4\u662f\u6307\u9488\u7684\u9519\u89c9\uff0c\u662f\u56e0\u4e3a\u6570\u7ec4\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a\u5143\u7d20\u7c7b\u578b\u7684\u6307\u9488\u3002\u800c\u8fd9\u662f\u201c\u9000\u5316\u201d\u89c4\u5219\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u51fd\u6570\u53c2\u6570\u3001auto \u63a8\u5bfc\u7684\u65f6\u5019\u662f\u81ea\u52a8\u53d1\u751f\u7684\uff08\u6b63\u5982\u4e0a\u9762\u8bf4\u7684\u51fd\u6570\u5f15\u7528\u4f1a\u5728\u8c03\u7528\u65f6\u81ea\u52a8\u201c\u9000\u5316\u201d\u6210\u51fd\u6570\u6307\u9488\u4e00\u6837\uff09\u3002 \u6570\u7ec4\u80fd\u81ea\u52a8\u9000\u5316\u6210\u6307\u9488\uff0c\u4e0d\u4ee3\u8868\u6570\u7ec4\u5c31\u662f\u6307\u9488\u3002\u4f8b\u5982 int \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a double\uff0c\u96be\u9053\u5c31\u53ef\u4ee5\u8bf4\u201cint \u5c31\u662f double\u201d\u5417\uff1f\u540c\u6837\u5730\uff0c\u4e0d\u80fd\u8bf4\u201c\u6570\u7ec4\u5c31\u662f\u6307\u9488\u201d\u3002\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\uff0c\u4ece\u6765\u90fd\u662f const char [N] \uff0c\u5176\u4e2d N \u662f\u5b57\u7b26\u4e32\u4e2d\u5b57\u7b26\u7684\u4e2a\u6570\uff08\u5305\u62ec\u672b\u5c3e\u81ea\u52a8\u52a0\u4e0a\u7684 '\\0' \u7ed3\u675f\u7b26\uff09\u3002\u53ea\u4e0d\u8fc7\u662f\u5728\u4f20\u5165\u51fd\u6570\u53c2\u6570\uff08\u6b64\u5904\u662f printf \u51fd\u6570\u7684\u5b57\u7b26\u4e32\u53c2\u6570\uff09\u65f6\uff0c\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u4e3a const char * \u4e86\u800c\u5df2\u3002\u6b63\u5982\u8fd9\u4e2a ImplicitCastExpr \u540e\u9762\u5c16\u62ec\u53f7\u7684\u63d0\u793a\u4e2d\u6240\u8bf4\uff0cArrayToPointerDecay\uff0c\u662f\u6570\u7ec4\u7c7b\u578b\u5230\u6307\u9488\u7c7b\u578b\u7684\u81ea\u52a8\u9000\u5316\uff0c\u4ece const char [14] \u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u5230\u4e86 const char * \u3002 #include int main() { printf(\"Hello, world!\"); // \u7b49\u4ef7\u4e8e static_cast(printf) ( static_cast(\"Hello, world!\") ); return 0; } \u603b\u4e4b\uff0c\u901a\u8fc7\u89c2\u5bdf Clang AST \u6811\uff0c\u53ef\u4ee5\u83b7\u5f97\u5f88\u591a\u9690\u85cf\u7684\u4fe1\u606f\uff0c\u7279\u522b\u662f C++ \u7684\u5404\u79cd\u9690\u85cf\u8bed\u6cd5\u89c4\u5219\uff0c\u53ef\u4ee5\u5e2e\u4f60\u89e3\u6784\u8bed\u6cd5\u7cd6\u3002 Clang \u89e3\u6790\u51fa AST \u6811\u540e\uff0c\u4f1a\u518d\u6b21\u904d\u5386\u8be5\u6811\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\uff0c\u8f93\u5165 LLVM \u540e\u7aef\u7f16\u8bd1\uff0c\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff08 -S \uff09\u6216\u4e8c\u8fdb\u5236\u6307\u4ee4\u7801\uff08 -c \uff09\u3002 \u5982\u679c\u6307\u5b9a\u4e86 -emit-llvm \u9009\u9879\uff0c\u5219\u4e0d\u4f1a\u8f93\u5165 LLVM \u540e\u7aef\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6307\u4ee4\u7801\uff0c\u800c\u662f\u76f4\u63a5\u628a\u4ea7\u751f\u7684 IR \u4ee5 IR \u6c47\u7f16\uff08 -S -emit-llvm \uff09\u6216 IR \u5b57\u8282\u7801\uff08 -c -emit-llvm \uff09\u7684\u683c\u5f0f\u5bfc\u51fa\uff0c\u65b9\u4fbf\u6211\u4eec\u5206\u6790\u548c\u67e5\u770b\u3002","title":"\u8bed\u6cd5\u6811\uff08AST\uff09"},{"location":"llvm_intro/#ir","text":"\u4e2d\u95f4\u8868\u793a\u7801\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u673a\u5668\u6307\u4ee4\uff0c\u5b83\u4e0d\u9488\u5bf9\u5177\u4f53\u7684\u786c\u4ef6\uff0c\u800c\u662f\u4e00\u79cd\u901a\u7528\u7684\u6307\u4ee4\u96c6\u3002\u5b83\u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u8fbe\uff0c\u53ef\u4ee5\u88ab\u8fdb\u4e00\u6b65\u7f16\u8bd1\u4e3a\u76ee\u6807\u4ee3\u7801\u3002 LLVM IR\uff08Intermediate Representation\uff09\u662f\u4e00\u79cd\u4e2d\u95f4\u8bed\u8a00\u8868\u793a\uff0c\u4f5c\u4e3a\u7f16\u8bd1\u5668\u524d\u7aef\u548c\u540e\u7aef\u7684\u5206\u6c34\u5cad\u3002LLVM \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u2014\u2014Clang \u8d1f\u8d23\u4ea7\u751f IR\uff0c\u800c\u5176 LLVM \u540e\u7aef\u8d1f\u8d23\u6d88\u8d39 IR\u3002 C++ \u6e90\u7801 -> IR -> \u76ee\u6807\u5e73\u53f0\u6c47\u7f16 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 IR \u5e76\u4e0d\u662f LLVM \u7684\u4e13\u5229\uff0c\u6240\u6709\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u90fd\u4f7f\u7528 IR\uff0c\u5305\u62ec GCC \u548c MSVC\u3002\u4e5f\u6709\u5f88\u591a\u72ec\u7acb\u4e8e\u7f16\u8bd1\u5668\u7684\u8de8\u5e73\u53f0 IR \u89c4\u8303\uff0c\u4f8b\u5982 SPIR-V\u3001MLIR\u3001MIR\uff0cLLVM IR \u53ea\u662f\u4f17\u591a IR \u4e2d\u7684\u4e00\u79cd\uff0c\u4e13\u7528\u4e8e LLVM \u7f16\u8bd1\u5668\u5168\u5bb6\u6876\u3002\u7531\u4e8e\u672c\u8bfe\u7a0b\u662f LLVM \u8bfe\u7a0b\uff0c\u4ee5\u540e\u63d0\u5230 IR\uff0c\u8bfb\u8005\u5e94\u9ed8\u8ba4\u6307\u7684\u662f LLVM IR\u3002 LLVM IR \u6709\u591a\u79cd\u8868\u73b0\u5f62\u5f0f\uff1a \u5185\u5b58\u4e2d\u7684 IR \u8282\u70b9\u5bf9\u8c61\uff0c\u4f4d\u4e8e clang \u548c libLLVM.so \u8fdb\u7a0b\u7684\u5185\u5b58\u4e2d\uff0c\u90fd\u662f\u4e00\u4e2a\u4e2a C++ \u7c7b\uff0c\u901a\u8fc7\u6307\u9488\u4e92\u76f8\u8fde\u63a5\u3002LLVM \u4f5c\u4e3a\u4e00\u4e2a C++ \u7a0b\u5e8f\uff0c\u5904\u7406 IR \u65f6\u90fd\u662f\u8981\u8bfb\u5230\u5185\u5b58\u4e2d\u5904\u7406\u7684\u3002\u4f46\u7531\u4e8e\u5185\u5b58\u4e2d\u7684 IR \u5bf9\u8c61\u5b58\u5728\u865a\u8868\u6307\u9488\u4ee5\u53ca\u590d\u6742\u7684\u6811\u72b6\u6570\u636e\u7ed3\u6784\uff0c\u65e0\u6cd5\u76f4\u63a5\u5b58\u5165\u78c1\u76d8\uff0c\u4e5f\u65e0\u6cd5\u4f9b\u4eba\u7c7b\u9605\u8bfb\uff0c\u9700\u8981\u5e8f\u5217\u5316\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u683c\u5f0f\u540e\u5b58\u50a8\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u6c47\u7f16\uff08Assembly\uff09\uff0c\u4ee5\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c\u5f62\u5f0f\uff08\u7eaf ASCII \u5b57\u7b26\uff09\u5b58\u50a8\u5728\u78c1\u76d8\u4e2d\uff0c\u65b9\u4fbf\u4eba\u7c7b\u89c2\u5bdf\u3001\u4fee\u6539\u548c\u8c03\u8bd5\u3002\u6211\u4eec\u540e\u9762\u7684\u8bfe\u7a0b\uff0c\u4e5f\u4f1a\u7ecf\u5e38\u89c2\u5bdf\u4e2d\u95f4\u4ea7\u7269\u7684 IR \u6c47\u7f16\uff0c\u5206\u6790 LLVM \u7684\u884c\u4e3a\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u5b58\u50a8\u7684 IR\uff0c\u672c\u8d28\u4e0a\u548c IR \u6c47\u7f16\u76f8\u540c\uff0c\u53ea\u662f\u4ee5\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u5b57\u8282\u5b58\u50a8\u3002\u7f3a\u70b9\u662f\u4eba\u7c7b\u770b\u4e0d\u61c2\uff0c\u4f18\u70b9\u662f\u8282\u7ea6\u78c1\u76d8\u7a7a\u95f4\uff0c\u65b9\u4fbf\u7a0b\u5e8f\u5feb\u901f\u89e3\u6790\u3002 \u5f53\u9700\u8981\u957f\u671f\u50a8\u5b58 IR \u7684\u4e2d\u95f4\u7ed3\u679c\u65f6\u4f1a\u7528\u5230 IR \u5b57\u8282\u7801\uff0c\u5f53\u9700\u8981\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\u4e2d\u95f4\u7ed3\u679c\u65f6\u5c31\u9700\u8981 IR \u6c47\u7f16\u3002","title":"\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09"},{"location":"llvm_intro/#ir-x86","text":"\u6ce8\u610f IR \u6c47\u7f16\u5e76\u4e0d\u662f\u771f\u6b63\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u8bed\u8a00\uff08Assembly\uff09\uff0c\u4ed6\u53ea\u662f\u4e00\u79cd\u4e2d\u95f4\u4ea7\u7269\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16\uff0c\u6b63\u5982 IR \u5b57\u8282\u7801\u4e0d\u662f x86 \u7684\u673a\u5668\u7801\u4e00\u6837\u3002IR \u7684\u4e1c\u897f\u90fd\u662f LLVM \u5f00\u53d1\u8005\u81ea\u62df\u7684\u4e00\u5957\u683c\u5f0f\uff0c\u548c\u786c\u4ef6\u65e0\u5173\uff0c\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u65e0\u5173\u3002\u4e0d\u8bba\u76ee\u6807\u5e73\u53f0\u662f\u4ec0\u4e48\uff0c\u6765\u81ea\u4ec0\u4e48\u6e90\u7801\u8bed\u8a00\uff0cLLVM IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u683c\u5f0f\u90fd\u662f\u4e00\u6837\u7684\u3002 \u4f46\u4e0d\u540c\u5e73\u53f0\u7684 IR \u4f1a\u9644\u52a0\u4e0d\u540c\u7684 intrinsics \u6307\u4ee4\uff0c\u9664\u6b64\u4e4b\u5916\u7684\u90e8\u5206\u90fd\u662f\u5171\u901a\u7684\u3002\u7531\u4e8e\u5f88\u591a\u7a0b\u5e8f\u4f1a\u5229\u7528\u76ee\u6807\u786c\u4ef6\u505a\u5224\u65ad\uff08\u4f8b\u5982 #ifdef __x86_64__ \uff09\uff0c\u751f\u6210\u4e0d\u540c\u7684 intrinsics\uff0c\u56e0\u6b64 IR \u5e76\u4e0d\u662f\u5b8c\u5168\u8de8\u5e73\u53f0\u7684\u3002 IR \u7684\u76ee\u7684\u662f\u628a\u5927\u90e8\u5206\u901a\u7528\u7684\u8ba1\u7b97\uff0c\u4f8b\u5982\u52a0\u51cf\u4e58\u9664\u3001\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u7edf\u4e00\u6210\u76f8\u540c\u7684 IR \u6c47\u7f16\u3002\u800c\u4e0d\u662f x86 \u6c47\u7f16\u91cc\u53eb call \uff0cARM \u6c47\u7f16\u91cc\u53eb bl \u7684\u4e11\u6001\uff0c\u8fd9\u5c31\u591f\u4e86\u3002\u5bf9\u4e8e\u5229\u7528\u786c\u4ef6\u7279\u6709\u7684\u6307\u4ee4\uff08\u4f8b\u5982 SSE\u3001NEON \u6307\u4ee4\u96c6\uff09\u6765\u4f18\u5316\uff0c\u4ee5\u53ca\u5185\u8054\u6c47\u7f16\uff08 asm \u5173\u952e\u5b57\uff09\u7b49\uff0cLLVM IR \u4e5f\u662f\u652f\u6301\u7684\u3002 \u901a\u7528\u7684\u90a3\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201ccommon IR\u201d\uff0c\u4f8b\u5982 Function\u3001Instruction \u7b49\u3002\u8fd9\u90e8\u5206\u662f\u8de8\u5e73\u53f0\u7684\uff0c\u7edf\u4e00\u4e86\u5206\u5d29\u79bb\u6790\u7684\u5404\u5927\u786c\u4ef6\u6c47\u7f16\uff0c\u4fbf\u4e8e\u7edf\u4e00\u7f16\u5199\u4f18\u5316\u5f15\u64ce\u3002 \u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201cspecific IR\u201d\uff0c\u4f8b\u5982 MachineFunction\u3001MachineInstr \u7b49\u3002\u8fd9\u90e8\u5206\u57fa\u672c\u662f\u7528\u4e8e\u6a21\u4eff\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff0c\u5c31\u662f\u8fd9\u90e8\u5206\u7684\u5b58\u5728\u5bfc\u81f4\u4e86 LLVM IR \u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 \u5728\u8fdb\u5165\u540e\u7aef\u7684\u201c\u6307\u4ee4\u9009\u62e9\u201d\u9636\u6bb5\u540e\uff0cIR \u8282\u70b9\u4e2d\u901a\u7528\u7684\u90a3\u90e8\u5206\u8282\u70b9\uff0c\u4f1a\u9010\u6b65\u88ab\u66ff\u6362\u4e3a\u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u76f8\u5e94 MachineInstr \u8282\u70b9\uff0c\u5728\u201c\u6307\u4ee4\u9009\u62e9\u201d\u540e\u7684\u9636\u6bb5\u770b\u6765\uff0c\u5c31\u597d\u50cf\u524d\u9762\u8f93\u51fa\u4e86\u4e00\u5927\u5806\u5185\u8054\u6c47\u7f16\u4e00\u6837\uff0c\u6700\u7ec8\uff0c\u9010\u6e10\u53d8\u6210\u4e86\u5b8c\u5168\u7684\u76ee\u6807\u5e73\u53f0\u6c47\u7f16\uff0c\u6700\u7ec8\u8f93\u51fa\u3002","title":"IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16"},{"location":"llvm_intro/#llvm-ir","text":"IR \u548c\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u76f8\u6bd4\uff0c\u4e0d\u4ec5\u4ec5\u662f\u7edf\u4e00\uff0c\u597d\u5904\u6709\u5f88\u591a\u3002","title":"LLVM IR \u7684\u7279\u70b9"},{"location":"llvm_intro/#_9","text":"\u6bcf\u4e2a C++ \u6587\u4ef6\u7f16\u8bd1\u5f97\u5230\u7684 IR \u6c47\u7f16\u5747\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u5b9a\u4e49\uff08\u548c\u5c11\u91cf\u7279\u6b8a\u6307\u4ee4\uff0c\u6bd4\u5982 target triple \uff09\u7ec4\u6210\uff0c\u6240\u6709\u7684 IR \u6307\u4ee4\u90fd\u5305\u5728\u51fd\u6570\u4e2d\u3002 \u51fd\u6570\u662f LLVM \u4f18\u5316\u7684\u57fa\u672c\u5355\u4f4d\uff0c\u7edd\u5927\u591a\u6570 LLVM pass\uff0c\u90fd\u662f\u4ee5\u5355\u4e2a\u51fd\u6570\u4e3a\u5355\u4f4d\u6765\u4f18\u5316\u7684\u3002\u53ea\u6709\u5185\u8054\u4f18\u5316\u548c IPO \u4f18\u5316\uff0c\u53ef\u4ee5\u5b9e\u73b0\u8de8\u51fd\u6570\u7684\u4f18\u5316\u3002 \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u5185\u8054\u4f18\u5316\u4e0d\u4ec5\u4ec5\u662f\u201c\u51fd\u6570\u539f\u5c01\u4e0d\u52a8\u63d2\u5165\u8c03\u7528\u4f4d\u7f6e\u201d\u3002\u628a\u51fd\u6570\u63d2\u5165\u8c03\u7528\u8005\u4f53\u5185\u540e\uff0c\u4e24\u4e2a\u51fd\u6570\u878d\u5408\u4e3a\u4e00\u4e2a\u51fd\u6570\u4e86\uff0c\u4f7f\u4f18\u5316\u5668\u7684\u201c\u89c6\u91ce\u201d\u66f4\u5927\uff08\u56e0\u4e3a\u5927\u90e8\u5206\u4f18\u5316\u4e0d\u80fd\u8de8\u8d8a\u51fd\u6570\u8fb9\u754c\uff09\uff01\u4ece\u800c\u5e2e\u52a9\u4e86\u5176\u4ed6\u4ee5\u51fd\u6570\u4e3a\u8fb9\u754c\u7684\u4f18\u5316 pass \u80fd\u591f\u66f4\u597d\u7684\u4f18\u5316\u3002\u4f8b\u5982\u5728 main \u4e2d\u4ee5\u8fed\u4ee3\u5668\u904d\u5386\u4e00\u4e2a\u5bb9\u5668\uff1a\u672c\u6765 main \u51fd\u6570\u662f\u8c03\u7528\u8fed\u4ee3\u5668\u7684 operator++ \uff0c\u800c operator++ \u4e0d\u5185\u8054\u6389\u7684\u8bdd\uff0c main \u7684\u4f18\u5316\u5668\u6c38\u8fdc\u65e0\u6cd5\u610f\u8bc6\u5230 operator++ \u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u6307\u9488\u7684\u52a0\u6cd5\uff0c\u53ea\u80fd\u8001\u8001\u5b9e\u5b9e\u5206\u914d alloca \u7136\u540e\u83b7\u53d6\u51fa this \u6307\u9488\u4f20\u5165 operator++ \u51fd\u6570\u3002\u800c\u5185\u8054\u4ee5\u540e\uff0c operator++ \u7684\u5185\u5bb9\u66b4\u9732\u5728\u4f18\u5316 pass \u773c\u524d\uff0c\u4ed6\u5c31\u77e5\u9053\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u4f18\u5316\u6210\u4e00\u4e2a\u9759\u6001\u5bc4\u5b58\u5668\u4e86\uff0c\u6839\u672c\u4e0d\u7528\u4e3a\u5176\u5206\u914d\u5185\u5b58\uff01\u6700\u7ec8\u4ea7\u751f\u7684\u6c47\u7f16\u4e00\u4e0b\u5b50\u4ece\u5fc5\u987b\u5206\u914d\u5728\u6808\u5185\u5b58\u4e0a\uff0c\u5230\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u6307\u9488\u653e\u5728\u5bc4\u5b58\u5668\u91cc\u4e86\u3002\u800c IPO (Inter-procedure Optimization) \u5219\u662f\u6839\u636e\u51fd\u6570\u53c2\u6570\u4e3a\u5e38\u6570\u7684\u60c5\u51b5\u505a\u5206\u53d1\uff0c\u5206\u53d1\u540e\u53ef\u4ee5\u9488\u5bf9\u4e0d\u540c\u5e38\u6570\u53c2\u6570\u7684\u7ed3\u679c\u505a\u7279\u5b9a\u4f18\u5316\uff0c\u4f46\u4e0d\u5408\u5e76\u51fd\u6570\uff0c\u65e0\u6cd5\u8d4b\u80fd\u5176\u4ed6\u4f18\u5316 pass\uff0c\u6548\u679c\u770b\u8d77\u6765\u5c31\u6ca1\u6709\u5185\u8054\u5f3a\u4e86\u3002\u4f46\u662f\u8981\u6ce8\u610f\u5f88\u591a\u4f18\u5316 pass \u7684\u5f00\u9500\u662f\u548c\u51fd\u6570\u7684\u5927\u5c0f\uff08IR \u6307\u4ee4\u6570\u91cf\uff09\u6210\u6b63\u6bd4\u7684\uff0c\u6240\u4ee5\u5185\u8054\u592a\u591a\u5c42\u5bfc\u81f4\u4e00\u4e2a\u51fd\u6570\u5f88\u5927\u7684\u8bdd\uff0c\u7f16\u8bd1\u4f1a\u53d8\u5f97\u6bd4\u8f83\u6162\u3002","title":"\u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d"},{"location":"llvm_intro/#_10","text":"\u5bc4\u5b58\u5668\u65e0\u9650\u91cf\u4f9b\u5e94\uff01\u4e00\u4e2a\u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u5b9a\u4e49\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668\uff0c\u65e0\u9700\u8003\u8651\u786c\u4ef6\u5177\u4f53\u63d0\u4f9b\u4e86\u591a\u5c11\u4e2a\u5bc4\u5b58\u5668\u3002\u56e0\u4e3a\u548c\u786c\u4ef6\u5bc4\u5b58\u5668\u8131\u94a9\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u79f0\u4e4b\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u53ea\u5728 LLVM \u4e2d\u7aef\u91cc\u51fa\u73b0\uff0c\u4e3a\u4e86\u4fbf\u4e8e\u4f18\u5316\u548c\u5904\u7406\u91c7\u53d6\u7684\u7b80\u5316\u7b56\u7565\u3002 \u865a\u62df\u5bc4\u5b58\u5668\u7edf\u4e00\u4ee5 %0 %1 %2 \u547d\u540d\u3002\u5982\u679c\u6253\u7b97\u624b\u5199 IR\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5b9a\u4e49\u540d\u5b57\u5982 %x %i \uff0c\u4e0d\u8fc7 Clang \u81ea\u52a8\u751f\u6210\u7684 IR \u4e2d\u5bc4\u5b58\u5668\u90fd\u662f\u4ece 0 \u5f00\u59cb\uff0c\u81ea\u52a8\u9012\u589e\u7684\u547d\u540d\u3002 \u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u4f1a\u628a\u8fd9\u4e9b\u5bc4\u5b58\u5668\u6620\u5c04\u5230\u76f8\u5e94\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u4e0d\u7528\u62c5\u5fc3\uff01\u5982\u679c\u540e\u7aef\u53d1\u73b0 IR \u4e2d\u7684\u5bc4\u5b58\u5668\u7528\u91cf\u8d85\u51fa\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u5bc4\u5b58\u5668\u6570\u91cf\u4e0a\u9650\uff0c\u90a3\u4e48\u4f1a\u9009\u62e9\u4e00\u90e8\u5206\u201c\u6253\u7ffb\u201d\uff08spill\uff09\u5230\u5185\u5b58\u4e2d\u53bb\u3002 \u800c\u4e14\u5982\u679c\u53d1\u73b0\u5bc4\u5b58\u5668\u53ef\u4ee5\u590d\u7528\uff0c\u4e5f\u4f1a\u590d\u7528\u4e4b\u524d\u5df2\u7ecf\u6ca1\u7528\u5230\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982\u4ee5\u4e0b IR \u4e2d\uff0c\u770b\u4f3c\u7528\u5230\u4e86\u4e94\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u5b9e\u9645\u53ea\u9700\u8981\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u53ef\u4ee5\u4e86\uff0c\u56e0\u4e3a %1 \u5728\u88ab %2 \u7684 add \u6307\u4ee4\u7528\u5b8c\u4ee5\u540e\uff0c\u5c31\u6ca1\u4eba\u518d\u4f7f\u7528\u4e86\u3002\u8fd9\u65f6\u5c31\u7a7a\u51fa\u4e86\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u8d44\u6e90\uff0c\u540e\u6765\u65b0\u7684\u5bc4\u5b58\u5668\u53ef\u4ee5\u4ece\u8fd9\u91cc\u9876\u66ff\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, 1 \u5728 LLVM \u4e2d\uff0c\u662f\u5229\u7528\u7ebf\u6027\u626b\u63cf\u6cd5\uff08\u7535\u68af\u7b97\u6cd5\uff09\u6765\u786e\u5b9a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff08\u4ece\u7b2c\u4e00\u6b21\u521b\u5efa\uff0c\u5230\u6700\u540e\u4e00\u6b21\u4f7f\u7528\u4e4b\u95f4\u7684\u65f6\u95f4\u6bb5\uff09\uff0c\u5bf9\u4e8e\u751f\u547d\u5468\u671f\u6709\u91cd\u53e0\u7684\u591a\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u624d\u9700\u8981\u4e3a\u4ed6\u4eec\u5206\u914d\u72ec\u7acb\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\uff0c\u5982\u679c\u751f\u547d\u5468\u671f\u6ca1\u6709\u4ea4\u96c6\uff0c\u90a3\u4e48\u53ef\u4ee5\u8ba9\u65b0\u6765\u7684\u865a\u62df\u5bc4\u5b58\u5668\u590d\u7528\u8001\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u53ea\u9700\u8981\u7528\u5230\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u591f\u4e86\uff1a eax = 0 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 \u800c\u5982\u679c %1 \u5bc4\u5b58\u5668\u540e\u9762\u8fd8\u6709\u4f7f\u7528\uff0c\u90a3\u5c31\u4e0d\u80fd\u628a %1 \u6240\u5728\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u590d\u7528\u4e86\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, %1 ; \u6b64\u5904\u7684\u201c\u4f7f\u7528\u201d\u5ef6\u957f\u4e86 %1 \u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff01 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u81f3\u591a\u9700\u8981\u5206\u914d\u4e24\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u8d44\u6e90\uff1a eax = 0 ecx = add eax, 1 ecx = add ecx, 1 ecx = add ecx, 1 ecx = add ecx, 1 eax = add eax, ecx","title":"\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668"},{"location":"llvm_intro/#_11","text":"\u865a\u62df\u5bc4\u5b58\u5668\u90fd\u662f\u53ea\u8bfb\u7684\uff01\u4e00\u6b21\u6027\u8d4b\u503c\u5b8c\u6bd5\u540e\uff0c\u5c31\u4e0d\u5141\u8bb8\u518d\u6b21\u4fee\u6539\uff0c\u6240\u6709\u7684\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u80fd\u5728\u5b9a\u4e49\u7684\u5730\u65b9\u8d4b\u503c\u3002 \u5982\u679c\u9700\u8981\u80fd\u4fee\u6539\u7684\u53d8\u91cf\uff0c\u9700\u8981\u7528 IR \u4e2d\u7684 alloca \u6307\u4ee4\u5728\u51fd\u6570\u6808\u4e0a\u5206\u914d\uff08\u9759\u6001\u5927\u5c0f\u7684\uff09\u7a7a\u95f4\uff0c\u5176\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\u3002 \u5728 Clang \u4e2d\uff0c\u4f1a\u5148\u628a\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u90fd\u5b9a\u4e49\u4e3a alloca \u7684\uff0c\u5f53\u521d\u59cb\u5316\u53d8\u91cf\u65f6\uff0c\u7528 IR \u4e2d\u7684\u5185\u5b58\u5199\u6307\u4ee4 store \u5199\u5165\u521d\u59cb\u503c\u3002 \u7136\u540e\uff0c\u5728\u5f00\u542f\u4e86\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0cLLVM \u4e2d\u7aef\u4e00\u4e2a\u53eb\u505a mem2reg \u7684\u4f18\u5316 pass\uff0c\u4f1a\u68c0\u6d4b\u5230\u6240\u6709\u53ea\u6709\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u5e38\u91cf\u53d8\u91cf\u7684 alloca\uff0c\u5e76\u5c1d\u8bd5\u628a\u4ed6\u4eec\u4f18\u5316\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\u3002 \u5bf9\u4e8e\u5b58\u5728 if \u6761\u4ef6\u8d4b\u503c\uff0c\u4ee5\u53ca for \u5faa\u73af\u7684\uff0c\u5219\u4f1a\u5229\u7528 Phi \u8282\u70b9\uff0c\u4f9d\u7136\u53ef\u4ee5\u4f18\u5316\u79f0\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002\uff08\u540e\u9762\u7684\u7ae0\u8282\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd Phi \u7684\u77e5\u8bc6\uff09 \u5982\u679c\u5b9e\u5728\u907f\u514d\u4e0d\u4e86 alloca\uff08\u6bd4\u5982\u5bf9\u53d8\u91cf\u7528\u5230\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26\uff0c\u800c\u865a\u62df\u5bc4\u5b58\u5668\u6ca1\u6709\u5185\u5b58\u5730\u5740\uff09\uff0c\u90a3\u5c31\u4f1a\u653e\u5f03\u4f18\u5316\u8fd9\u4e2a\u53d8\u91cf\uff0c\u4f9d\u7136\u4fdd\u6301 alloca + store \u7684\u72b6\u6001\u3002 \u6700\u7ec8\uff0c\u6240\u6709\u80fd\u4f18\u5316\u6210\u7684\uff0c\u90fd\u53d8\u6210\u65e0\u9650\u4f9b\u5e94\u4e14\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u4e86\u3002 \u8fd9\u79cd\u5bc4\u5b58\u5668\u53ea\u8bfb\u7684 IR\uff0c\u88ab\u79f0\u4e3a SSA IR\uff08Static Single Assignment IR\uff09\uff0c\u4e2d\u6587\u5c31\u662f\u662f\u201c\u9759\u6001\u5355\u8d4b\u503c IR\u201d\u3002 \u9759\u6001\uff1a\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u548c\u5e8f\u53f7\u662f\u786e\u5b9a\u7684\uff0c\u5728\u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u56fa\u5b9a\u3002 \u5355\u8d4b\u503c\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u53ea\u80fd\u8d4b\u503c\u4e00\u6b21\uff0c\u4e4b\u540e\u4e0d\u5f97\u4fee\u6539\u3002 SSA IR \u7684\u597d\u5904\u662f\u65b9\u4fbf\u4f18\u5316\uff0c\u4f8b\u5982\uff1a x = 1; x = 2; y = x; return y; \u5f88\u660e\u663e\uff0c\u6211\u4eec\u53ef\u4ee5\u628a x = 1 \u8fd9\u4e00\u884c\u4f18\u5316\u6389\uff0c\u56e0\u4e3a\u540e\u9762\u7684 x = 2 \u5df2\u7ecf\u628a\u4ed6\u8986\u76d6\u4e86\u3002\u4f46\u662f\u5982\u4f55\u786e\u5b9a\u8fd9\u4e00\u70b9\uff1f\u5f88\u56f0\u96be\u3002 \u800c\u5982\u679c\u5148\u901a\u8fc7 mem2reg \u8f6c\u6210 SSA IR \u7684\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u8fd9\u65f6\u4ed6\u4f1a\u6ce8\u610f\u5230 x = 1 \u548c x = 2 \u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u8d4b\u503c\uff0c\u751f\u547d\u5468\u671f\u4e92\u4e0d\u91cd\u53e0\uff0c\u53ef\u4ee5\u62c6\u6210\u4e24\u4e2a\u5e38\u91cf\uff0c\u5b89\u5168\u653e\u8fdb\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002 x1 = 1; // \u68c0\u6d4b\u5230\u201c\u4e0d\u53ef\u8fbe\u201d\u7684\u5bc4\u5b58\u5668 x2 = 2; y = x2; return y; \u7136\u540e\uff0c\u7531\u4e8e x1 \u6839\u672c\u6ca1\u6709\u4f7f\u7528\u8fc7\uff0c\u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u5f88\u5bb9\u6613\u5c31\u628a x1 \u8fd9\u4e2a\u672a\u4f7f\u7528\u7684\u53d8\u91cf\u5254\u9664\u6389\u3002\u5373\u4f7f\u4e0d\u662f\u540e\u7aef\uff0c\u4e2d\u7aef\u7684\u4e00\u4e9b\u5176\u4ed6\u4f18\u5316 pass \u4e5f\u5f88\u5bb9\u6613\u6e05\u9664\u8fd9\u4e9b\u672a\u4f7f\u7528\u7684\u5e38\u91cf\u5bc4\u5b58\u5668\u3002 \u603b\u4e4b\uff0c\u901a\u8fc7 SSA \u89c4\u5219\uff0c\u628a\u201c\u5bc4\u5b58\u5668\u88ab\u8986\u76d6\u201d\u8fd9\u4e2a\u6bd4\u8f83\u96be\u68c0\u6d4b\u7684\u6761\u4ef6\uff0c\u53d8\u6210\u4e86\u201c\u5bc4\u5b58\u5668\u53ea\u5b9a\u4e49\uff0c\u6ca1\u4eba\u4f7f\u7528\u201d\u8fd9\u4e2a\u5f88\u5bb9\u6613\u68c0\u6d4b\u7684\u4e8b\u5b9e\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u7531\u4e8e LLVM \u7684\u7814\u7a76\u4e3b\u8981\u96c6\u4e2d\u5728\u4e2d\u7aef\uff0c\u5728\u4e2d\u7aef\u7684\u8bed\u5883\u4e0b\u63d0\u5230\u7684\u5bc4\u5b58\u5668\uff0c\u5982\u975e\u7279\u522b\u8bf4\u660e\uff0c\u8bfb\u8005\u5e94\u5f53\u9ed8\u8ba4\u6307\u7684\u5c31\u662f LLVM \u865a\u62df\u5bc4\u5b58\u5668\uff0c\u800c\u4e0d\u662f\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u6700\u540e\uff0c\u5728\u201c\u5206\u914d\u5bc4\u5b58\u5668\u201d\u9636\u6bb5\uff0c\u628a\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u5bb9\u7eb3\u4e0d\u4e0b\u6216\u65e0\u6cd5\u53d8\u6210\u5355\u6b21\u9759\u6001\u8d4b\u503c\u7684\u90e8\u5206\u53d8\u91cf\uff0c\u518d\u9009\u62e9\u6027\u5730\u201c\u6253\u7ffb\u201d\u5230\u5185\u5b58\u4e2d\u53bb\u3002\u8fd9\u6837\u4e00\u6765\u4e00\u56de\uff0c\u5728\u4e2d\u7aef\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u540e\u7aef\u53c8\u4e00\u6837\u80fd\u6b63\u5e38\u751f\u6210\u6c47\u7f16\uff0c\u5bf9\u4e8e\u5bc4\u5b58\u5668\u7528\u91cf\u8f83\u5c11\u7684\u51fd\u6570\u5219\u5b8c\u5168\u907f\u514d\u4e86\u5185\u5b58\u8bfb\u5199\u3002\u4e3a\u4e86\u4fdd\u8bc1\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf\u90fd\u5b58\u5230\u5bc4\u5b58\u5668\u4e2d\uff0c\u4f60\u53ef\u4ee5\u81ea\u5df1\u6570\u4e00\u4e0b\uff0c\u6240\u6709\u53d8\u91cf\u751f\u547d\u5468\u671f\u91cd\u53e0\u7684\u6700\u591a\u7684\u6570\u91cf\u662f\u591a\u5c11\uff0c\u662f\u5426\u8d85\u8fc7\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u4e0a\u9650\uff1a\u5bf9 x86 \u6765\u8bf4\uff0c\u5c31\u662f\u9664 rsp \u548c rbp \u5916\u6240\u6709\u7684\u901a\u7528\u5bc4\u5b58\u5668\uff08\u6574\u6570\u53d8\u91cf\uff09\u548c\u6240\u6709 xmm \u7cfb\u5217\u5bc4\u5b58\u5668\uff08\u6d6e\u70b9\u53d8\u91cf\uff09\uff1b\u5982\u679c\u8be5\u51fd\u6570\u4e2d\u8fd8\u8c03\u7528\u4e86\u5176\u4ed6\u51fd\u6570\uff0c\u90a3\u4e48\u5c31\u53ea\u6709\u975e\u6613\u5931\u5bc4\u5b58\u5668\u53ef\u7528\u3002","title":"\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb"},{"location":"llvm_intro/#_12","text":"\u6211\u4eec\u719f\u6089\u7684 x86 \u6c47\u7f16\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u7531\u5176\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\uff08\u4f8b\u5982 add \uff09\u90fd\u662f\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668 + \u6e90\u5bc4\u5b58\u5668\u7684\u7279\u70b9\u5f97\u540d\u3002 add eax, ecx \u6548\u679c\uff1a eax = eax + ecx \u7c7b\u4f3c\u4e8e C \u8bed\u8a00\u4e2d\u7684 += \u8fd0\u7b97\u7b26\uff0c\u4fee\u6539\u662f\u5c31\u5730\u751f\u6548\u5728\u5176\u4e2d\u4e00\u4e2a\u5bc4\u5b58\u5668\u4e0a\u7684\uff0c\u5176\u4e2d\u5de6\u4fa7\u7684\u5bc4\u5b58\u5668\u65e2\u662f\u6e90\u5bc4\u5b58\u5668\u53c8\u662f\u76ee\u7684\u5bc4\u5b58\u5668\u3002 \u4f18\u70b9\uff1a\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u5c31\u5730\u5199\u5165\u53ef\u4ee5\u8282\u7701\u6307\u4ee4\u7801\u7684\u5927\u5c0f\uff0c\u8282\u7701\u7a7a\u95f4\uff0c\u7b26\u5408 x86 \u7684 CISC \u8bbe\u8ba1\u601d\u8def\u3002 \u7f3a\u70b9\uff1a\u5982\u679c\u9700\u8981\u628a\u7ed3\u679c\u5b58\u5728\u53e6\u4e00\u4e2a\u5bc4\u5b58\u5668\u91cc\uff0c\u5c31\u9700\u8981\u5148 mov \u6307\u4ee4\u62f7\u8d1d\u4e00\u4efd\uff0c\u4e14\u5b58\u5728\u526f\u4f5c\u7528\u4e0d\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u800c LLVM \u7684 IR \u662f\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u3002\u4f8b\u5982\uff1a %3 = add %1, %2 \u6548\u679c\uff1a %3 = %1 + %2 \u8fd9\u91cc\uff0c %3 \u662f\u76ee\u6807\u5bc4\u5b58\u5668\uff0c %1 \u548c %2 \u662f\u6e90\u5bc4\u5b58\u5668\uff0c add \u662f\u64cd\u4f5c\u6307\u4ee4\u3002 \u548c\u4e24\u64cd\u4f5c\u6570\u6307\u4ee4\u76f8\u6bd4\uff0c\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u7684\u597d\u5904\u662f\uff1a \u6e90\u5bc4\u5b58\u5668\u53ea\u8bfb\uff0c\u4e0d\u4f1a\u6539\u53d8\uff1a\u5982\u9700\u8ba1\u7b97\u4e00\u52a0\u4e00\u51cf\uff0c\u65e0\u9700\u9884\u5148\u62f7\u8d1d\u4e00\u4efd\u65e7\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u76f4\u63a5 %3 = add %1, %2 \u548c %4 = sub %1, %2 \u5373\u53ef\u3002 \u76ee\u7684\u5bc4\u5b58\u5668\u53ea\u5199\uff0c\u6ee1\u8db3\u4e86\u9759\u6001\u5355\u8d4b\u503c IR\uff08SSA IR\uff09\u7684\u8981\u6c42\uff0c\u4e0d\u9700\u8981\u8003\u8651\u526f\u4f5c\u7528\uff0c\u4f18\u5316\u8d77\u6765\u66f4\u65b9\u4fbf\uff0c\u662f\u4e2d\u95f4 IR \u7684\u7406\u60f3\u8bbe\u8ba1\u3002 \u6240\u6709\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u4e4b\u95f4\u987a\u5e8f\u65e0\u5173\uff0c\u53ef\u4ee5\u4efb\u610f\u8c03\u6362\u987a\u5e8f\uff0c\u53ef\u4ee5\u8f7b\u677e\u901a\u8fc7 DFS \u9012\u5f52\u627e\u51fa\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668\u6240\u6709\u76f4\u63a5\u548c\u95f4\u63a5\u4f9d\u8d56\u7684\u5bc4\u5b58\u5668\uff0c\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u7f3a\u70b9\uff1a\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u4f46\u662f LLVM IR \u662f\u53ea\u5728\u7f16\u8bd1\u671f\u5b58\u5728\u7684\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u5e76\u4e0d\u8fdb\u5165\u6700\u7ec8\u4e8c\u8fdb\u5236\u4ea7\u7269\uff0c\u6700\u7ec8\u7f16\u8bd1\u6210 x86 \u6c47\u7f16\u540e\u4f9d\u7136\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u6240\u4ee5\u8fd9\u4e2a\u7f3a\u70b9\u5e76\u4e0d\u5f71\u54cd\u3002","title":"\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4"},{"location":"llvm_intro/#_13","text":"LLVM IR \u4e2d\uff0c\u6240\u6709\u7684\u5bc4\u5b58\u5668\u5e76\u4e0d\u662f\u539f\u59cb\u7684\u4e8c\u8fdb\u5236\u5185\u5b58\uff0c\u800c\u662f\u6709\u7c7b\u578b\u7684\u3002 \u6709\u4eba\u4f1a\u8bf4\uff0c\u5df2\u7ecf\u8fdb\u5165 IR \u4e86\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u5fc5\u8981\uff1f\u628a\u6240\u6709\u7c7b\u578b\u90fd\u5f53\u6210\u4e8c\u8fdb\u5236\u5185\u5b58\u4e0d\u884c\u5417\uff1f \u5728 IR \u5c42\u9762\u533a\u5206\u7c7b\u578b\u7684\u597d\u5904\uff1a \u53ef\u4ee5\u660e\u786e\u5404\u79cd\u6570\u5b66\u8fd0\u7b97\u64cd\u4f5c\u6570\u7684\u7c7b\u578b\uff08\u4f8b\u5982\u6d6e\u70b9\u6570 f32 \u6216\u6574\u6570 i32 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bc4\u5b58\u5668\u7684\u5927\u5c0f\uff08\u4f8b\u5982 32 \u4f4d\u6574\u6570 i32 \u548c 8 \u4f4d\u6574\u6570 i8 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bf9\u9f50\u5ea6\u3002 \u53ef\u4ee5\u533a\u5206\u51fa\u6307\u9488\u548c\u666e\u901a\u7c7b\u578b\u4e24\u79cd\u4e0d\u540c\u7684\u7528\u9014\uff0c\u9632\u6b62\u6df7\u6dc6\uff08\u4f8b\u5982\u6574\u6570\u7c7b\u578b i32 \u548c\u4ed6\u7684\u6307\u9488 i32* \uff09\u3002 \u5f3a\u7c7b\u578b\u7684 IR \u53ef\u4ee5\u5927\u5927\u5e2e\u52a9\u4f18\u5316 pass \u7406\u89e3\u7a0b\u5e8f\u3002 \u7c7b\u578b\u4e3a\u4ec0\u4e48\u5e2e\u52a9\u4f18\u5316\uff1f\u4f8b\u5982\uff0c\u77e5\u9053\u7c7b\u578b\u4fe1\u606f\u540e\uff0c\u53ef\u4ee5\u914d\u5408 C++ \u7684 strict-aliasing \u89c4\u5219\u6392\u9664\u4e00\u90e8\u5206\u53ef\u80fd\u7684\u6307\u9488\u522b\u540d\uff0c\u79f0\u4e3a\u201c\u57fa\u4e8e\u7c7b\u578b\u7684\u522b\u540d\u5206\u6790\u201d\uff08TBAA, type-based-aliasing-analysis\uff09\u3002 \u522b\u540d\u6307\u7684\u662f\u4e24\u4e2a\u6307\u9488\u6709\u76f8\u4e92\u201c\u7a7f\u63d2\u201d\u7684\u90e8\u5206\uff0c\u6307\u9488\u5b58\u5728\u522b\u540d\u4f1a\u5bfc\u81f4 SIMD \u77e2\u91cf\u4f18\u5316\u5931\u8d25\u3002\u800c C++ \u7684 strict-aliasing \u53ef\u4ee5\u4fdd\u8bc1\u4e0d\u76f8\u5e72\u7c7b\u578b\u7684\u4e24\u4e2a\u6307\u9488\u4e4b\u95f4\u4e0d\u4f1a\u6709\u201c\u7a7f\u63d2\u201d\uff0c\u4ece\u800c\u5e2e\u52a9\u77e2\u91cf\u4f18\u5316\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u4ece int * \u5f3a\u8f6c\u4e3a float * \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u4e3a strict-aliasing \u8981\u6c42\u4e0d\u540c\u7c7b\u578b\u7684\u6307\u9488\u6ca1\u6709\u91cd\u53e0\u90e8\u5206\uff08\u6307\u5411\u76f8\u540c\u7684\u5730\u5740\uff09\uff0c\u5982\u679c\u4f60\u540c\u65f6\u7528\u4e86\u6307\u5411\u540c\u4e00\u4e2a\u5730\u5740\u7684 int * \u548c float * \uff0c\u90a3\u4e48\u5982\u679c LLVM \u5047\u5b9a\u4e86\u4ed6\u4eec\u4e0d\u80fd\u6307\u5411\u540c\u5730\u5740\u6765\u4f18\u5316\uff0c\u5c31\u4f1a\u5bfc\u81f4\u8fd0\u884c\u7ed3\u679c\u51fa\u9519\u3002\u4e0d\u8fc7 int * \u8f6c\u4e3a char * \u3001 unsigned char * \u5374\u662f\u5141\u8bb8\u7684\uff0c\u8fd9\u662f\u56e0\u4e3a\u7ecf\u5e38\u51fa\u73b0\u7528 char \u6765\u505a\u7f13\u51b2\u533a\uff0c\u7136\u540e\u89e3\u6790\u51fa\u7ed3\u6784\u4f53\u7684\u573a\u666f\uff0cC++ \u6807\u51c6\u4e3a\u8fd9\u79cd\u5e38\u7528\u60c5\u51b5\u5f00\u4e86\u540e\u95e8\u3002\u6240\u4ee5\u5982\u679c\u4f60\u9700\u8981\u5728 int \u548c float \u4e4b\u95f4\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 memcpy \u6765\u62f7\u8d1d\uff08 memcpy \u5185\u90e8\u88ab LLVM \u8ba4\u4e3a\u662f\u6309 unsigned char * \u8bbf\u95ee\u7684\uff09\uff0c\u4e0d\u8981\u5f3a\u8f6c\u6307\u9488\u8bbf\u95ee\u3002\u8be6\u89c1\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u3002","title":"\u7c7b\u578b\u7cfb\u7edf"},{"location":"llvm_intro/#_14","text":"LLVM IR \u4e2d\u7684\u57fa\u7840\u7c7b\u578b\u6709\uff1a LLVM \u7c7b\u578b C \u8bed\u8a00\u7c7b\u578b \u89e3\u91ca i1 bool 1 \u4f4d\u6574\u6570/\u5e03\u5c14\u7c7b\u578b i8 char 8 \u4f4d\u6574\u6570\u7c7b\u578b i16 short 16 \u4f4d\u6574\u6570\u7c7b\u578b i32 int 32 \u4f4d\u6574\u6570\u7c7b\u578b i64 long long 64 \u4f4d\u6574\u6570\u7c7b\u578b f16 _Float16 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b bf16 _BFloat16 \u7a84\u5e95 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b f32 float 32 \u4f4d\u6d6e\u70b9\u7c7b\u578b f64 double 64 \u4f4d\u6d6e\u70b9\u7c7b\u578b f80 long double 80 \u4f4d\u6d6e\u70b9\u7c7b\u578b f128 _Float128 128 \u4f4d\u6d6e\u70b9\u7c7b\u578b void void \u7a7a\u7c7b\u578b","title":"\u57fa\u7840\u7c7b\u578b"},{"location":"llvm_intro/#_15","text":"\u5176\u4e2d i1 \u662f\u5e03\u5c14\u7c7b\u578b\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 bool \uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u6bd2\u503c\uff09\u3002","title":"\u5e03\u5c14\u7c7b\u578b"},{"location":"llvm_intro/#_16","text":"\u6240\u6709\u7c7b\u578b\u90fd\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u76f8\u5e94\u7684\u6307\u9488\u7c7b\u578b\uff0c\u7528\u4e00\u4e2a * \u505a\u540e\u7f00\u6765\u8868\u793a\u3002 \u4f8b\u5982\u4e00\u4e2a\u6307\u5411 i8 \u7684\u6307\u9488\uff0c\u7c7b\u578b\u5c31\u662f i8* \uff0c\u5bf9\u5e94 C \u8bed\u8a00\u4e2d\u7684 char * \u7c7b\u578b\u3002 \u6ce8\u610f LLVM IR \u4e2d\u4e0d\u533a\u5206\u7c7b\u578b\u7684 const \u4e0e\u5426\uff0c const \u53ea\u5728 C++ \u8bed\u6cd5\u5c42\u9762\u5b58\u5728\uff0c\u4f8b\u5982 const char * \u548c char * \u5728 LLVM IR \u4e2d\u5bf9\u5e94\u7684\u90fd\u662f i8* \u3002 \u53ef\u4ee5\u7528\u591a\u4e2a * \u540e\u7f00\u8868\u793a\u591a\u91cd\u6307\u9488\uff0c\u4f8b\u5982 char ** \u7c7b\u578b\u5728 LLVM IR \u4e2d\u5c31\u662f i8** \u3002","title":"\u6307\u9488\u7c7b\u578b"},{"location":"llvm_intro/#_17","text":"","title":"\u7ed3\u6784\u4f53\u7c7b\u578b"},{"location":"llvm_intro/#_18","text":"\u6ce8\u610f\u5230\uff0cLLVM \u4e2d\u4f3c\u4e4e\u53ea\u6709 i32 \u800c\u6ca1\u6709 u32 \uff1f\u8fd9\u662f\u56e0\u4e3a LLVM IR \u7684\u7c7b\u578b\u7cfb\u7edf\u5e76\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\u3002 int \u548c unsigned int \u90fd\u7edf\u4e00\u7528 i32 \u8868\u793a\uff1b char \u548c unsigned char \u7edf\u4e00\u7528 i8 \u8868\u793a\u3002 \u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\uff1a LLVM IR \u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u4e0d\u5e94\u8be5\u5305\u542b\u592a\u591a\u8bed\u8a00\u7279\u6027\uff0c\u4fdd\u6301\u7b80\u5355\u3002 \u5927\u591a\u6570\u65f6\u5019\uff0c\u6211\u4eec\u5e76\u4e0d\u5173\u5fc3\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\uff0c\u53ea\u5173\u5fc3\u52a0\u51cf\u6cd5\u540e\u662f\u5426\u6ea2\u51fa\u3002 \u50cf\u52a0\u6cd5\uff08 add \uff09\u548c\u51cf\u6cd5\uff08 sub \uff09\u8fd9\u6837\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u7531\u4e8e\u8865\u7801\u7684\u5de7\u5999\u8bbe\u8ba1\uff0c\u65e0\u8bba\u64cd\u4f5c\u6570\u662f\u5426\u6709\u7b26\u53f7\uff0c\u5176\u7ed3\u679c\u5728\u4e8c\u8fdb\u5236\u4e0a\u90fd\u662f\u4e00\u6837\u7684\u3002 \u50cf\u6309\u4f4d\u6216\uff08 or \uff09\u548c\u6309\u4f4d\u4e0e\uff08 and \uff09\u8fd9\u6837\u7684\u903b\u8f91\u8fd0\u7b97\uff0c\u4e5f\u4e0d\u6d89\u53ca\u7b26\u53f7\u4f4d\uff0c\u90fd\u662f\u5f53\u6210\u666e\u901a\u7684\u4e8c\u8fdb\u5236\u4f4d\u6765\u8fd0\u7b97\uff0c\u7ed3\u679c\u4e5f\u6ca1\u6709\u533a\u522b\u3002 \u4fdd\u6301\u7b80\u5355\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\uff0c\u4f8b\u5982\uff0c\u4e0d\u7528\u8003\u8651 int \u7c7b\u578b\u548c unsigned int \u7c7b\u578b\u4e4b\u95f4\u7684\u6765\u56de\u8f6c\u6362\u3002 \u56e0\u6b64 i32 \u548c u32 \u7684 add \u548c sub \u6307\u4ee4\u53ef\u4ee5\u7edf\u4e00\u5f53\u4f5c i32 \u6765\u52a0\u51cf\u3002 \u800c\u5bf9\u4e8e\u4e58\u6cd5\u548c\u9664\u6cd5\u8fd9\u4e9b\u6709\u7b26\u53f7\u548c\u65e0\u7b26\u53f7\u7ed3\u679c\u4f1a\u4e0d\u540c\u7684\u6570\u5b66\u8fd0\u7b97\uff0cLLVM \u5c06\u4ed6\u4eec\u5206\u79bb\u6210\u4e24\u7ec4 IR \u6307\u4ee4\uff1a\u9488\u5bf9\u6709\u7b26\u53f7\u6570\u7684 smul \u548c sdiv \uff0c\u4ee5\u53ca\u9488\u5bf9\u65e0\u7b26\u53f7\u7684 umul \u548c udiv \u3002 \u6240\u4ee5\uff0cLLVM \u53ea\u662f\u9488\u5bf9\u4e58\u9664\u8fd9\u79cd\u6709\u65e0\u7b26\u53f7\u7ed3\u679c\u4e0d\u540c\u7684\u8fd0\u7b97\uff0c\u533a\u5206\u6210\u4e86\u4e24\u5957\u4e0d\u540c\u7684\u6307\u4ee4\uff1a\u7528 s \u548c u \u524d\u7f00\u533a\u5206\uff0c\u5176\u4f59\u50cf\u52a0\u51cf\u6cd5\u8fd9\u4e9b\u6307\u4ee4\u90fd\u662f\u5171\u7528\u7684\u3002 \u9700\u8981\u533a\u5206\u6709\u65e0\u7b26\u53f7\u7684\u6574\u6570\u8fd0\u7b97\u6307\u4ee4\uff1a\u4e58\u6cd5\u3001\u9664\u6cd5\u3001\u53d6\u6a21\u8fd0\u7b97\u3001\u6309\u4f4d\u53f3\u79fb\u3001\u6bd4\u8f83\u5927\u5c0f\u5173\u7cfb\u3002 \u4e0d\u9700\u8981\u533a\u5206\u7684\uff1a\u52a0\u6cd5\u3001\u51cf\u6cd5\u3001\u6309\u4f4d\u6216\u3001\u6309\u4f4d\u4e0e\u3001\u6309\u4f4d\u5f02\u6216\u3001\u6309\u4f4d\u5de6\u79fb\u3001\u6309\u4f4d\u53d6\u53cd\u3001\u6bd4\u8f83\u662f\u5426\u76f8\u7b49\u3002 \u4ece\u6307\u4ee4\u5c42\u9762\u4e0a\u533a\u5206\u6709\u65e0\u7b26\u53f7\u6570\uff0c\u800c\u7c7b\u578b\u5c42\u9762\u4e0a\u76f8\u540c\u3002\u8ba9\u662f\u5426\u6709\u7b26\u53f7\u53d8\u6210\u4e86\u6307\u4ee4\u7684\u7279\u6027\u800c\u4e0d\u662f\u7c7b\u578b\u7684\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u4e0d\u4ec5 LLVM IR \u4e2d\u5982\u6b64\uff0c\u5728 x86 \u6307\u4ee4\u96c6\u4e2d\u4e5f\u662f\u8fd9\u6837\u8bbe\u8ba1\u7684\u3002 \u81ea\u6b64\uff0c\u6709\u65e0\u7b26\u53f7\u7684\u4fe1\u606f\u53ea\u5728 Clang \u524d\u7aef\u4e2d\u51fa\u73b0\uff0c\u7531 Clang \u6839\u636e\u53d8\u91cf\u7c7b\u578b\u4fe1\u606f\uff0c\u9009\u62e9\u751f\u6210 smul \u6216 umul \u7b49 IR \u6307\u4ee4\uff0c\u7c7b\u578b\u90fd\u662f\u7edf\u4e00\u7684 i32 \u3002","title":"\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7"},{"location":"llvm_intro/#_19","text":"\u8fd9\u91cc\u6211\u4eec\u6709\u5fc5\u8981\u660e\u786e\u4e00\u4e0b\u201c\u5b9a\u4e49(define)\u201d\u548c\u201c\u4f7f\u7528(use)\u201d\u3002\u8fd9\u662f\u4e24\u4e2a\u7f16\u8bd1\u5668\u9886\u57df\u7684\u672f\u8bed\uff0c\u7528\u4e8e\u63cf\u8ff0 SSA IR \u7684\u5bc4\u5b58\u5668\u53ca\u5176\u7528\u51b5\u3002 \u5b9a\u4e49\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u88ab\u8d4b\u503c\u7684\u5730\u65b9\uff0c\u5c31\u662f\u4ed6\u7684\u5b9a\u4e49\u3002 %1 = 1 ; %1 \u7684\u5b9a\u4e49 %2 = 2 ; %2 \u7684\u5b9a\u4e49 %3 = add %1, %2 ; %3 \u7684\u5b9a\u4e49 \u56e0\u4e3a LLVM IR \u662f SSA \u7684\uff0c\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c\u53ea\u80fd\u5728\u521d\u59cb\u5316\u65f6\u88ab\u8d4b\u503c\u4e00\u6b21\u3002\u6240\u4ee5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u662f\u552f\u4e00\u7684\uff0c\u4e5f\u5c31\u662f\u521d\u59cb\u5316\u7684\u90a3\u4e00\u6b21\u8d4b\u503c\u7684\u5730\u65b9\u3002 \u8868\u793a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e2d\uff0c\u5176\u521d\u59cb\u5316\uff0c\u7528\u5230\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\u505a\u53c2\u6570\u3002\u8fd9\u4e9b\u88ab\u5f15\u7528\u4e86\u7684\u201c\u53c2\u6570\u5bc4\u5b58\u5668\u201d\uff0c\u5c31\u662f\u4ed6\u7684\u201c\u4f7f\u7528\u201d\u3002 %1 = 1 %2 = 2 %3 = add %1, %2 ; %3 \u4f7f\u7528\u4e86 %1 \u548c %2 \u521d\u59cb\u5316\u4e3a\u5e38\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 %1 = 233 ; %1 \u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u4eba\uff01 \u5728 LLVM \u4e2d\u7ef4\u62a4\u6709\u201c\u5b9a\u4e49-\u4f7f\u7528(def-use)\u201d\u548c\u201c\u4f7f\u7528-\u5b9a\u4e49(use-def)\u201d\u7684\u53cc\u5411\u6620\u5c04\u5173\u7cfb\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\uff0c\u627e\u5230\u4ed6\u88ab\u54ea\u4e9b\u5bc4\u5b58\u5668\u201c\u4f7f\u7528\u201d\u4e86\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u4f7f\u7528\u201d\uff0c\u627e\u5230\u4ed6\u662f\u5728\u54ea\u91cc\u88ab\u201c\u5b9a\u4e49\u201d\u7684\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u548c\u201c\u4f7f\u7528\u5b9a\u4e49\u201d\u662f\u4e24\u4e2a\u4e92\u9006\u7684\u6620\u5c04\u3002\u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c\u4ed6\u4eec\u90fd\u4e0d\u662f\u4e00\u4e00\u6620\u5c04\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u53ef\u4ee5\u88ab\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u91cd\u590d\u4f7f\u7528\uff0c\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e5f\u53ef\u80fd\u4f7f\u7528\u5230\u4e86\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u6620\u5c04 \u7531\u4e8e\u6307\u4ee4\u5728\u4ed6\u7684\u6e90\u64cd\u4f5c\u6570\u4e2d\u6307\u5b9a\u4e86\u64cd\u4f5c\u6570\u6765\u81ea\u54ea\u4e2a\u5bc4\u5b58\u5668\uff0c\u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\u662f IR \u5929\u751f\u81ea\u5e26\u7684\uff0c\u76f4\u63a5\u901a\u8fc7 IR \u8282\u70b9\u7684 op \u6210\u5458\u51fd\u6570\uff0c\u5c31\u80fd\u67e5\u5230\u4ed6\u4f7f\u7528\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\uff08\u6216\u5e38\u6570\uff09\u3002 llvm::Instruction *pi = ...; for (llvm::Use &U: pi->operands()) { llvm::Value *v = U.get(); // v \u4f7f\u7528\u4e86 pi } \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04 \u800c\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff0c\u5c31\u9700\u8981\u6211\u4eec\u81ea\u5df1\u6784\u5efa\u4e86\u3002 \u5e78\u8fd0\u7684\u662f\uff0cLLVM \u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u4fbf\u7684\u5206\u6790\u5de5\u5177\uff0c\u6765\u81ea\u52a8\u6784\u5efa\u8fd9\u4e2a\u5173\u7cfb\uff1a def-use pass\u3002","title":"\u5b9a\u4e49\u4e0e\u4f7f\u7528"},{"location":"llvm_intro/#pass","text":"LLVM \u4e2d\u7684 pass\uff0c\u662f\u6307\u4e00\u7ec4\u5bf9 IR \u8fdb\u884c\u64cd\u4f5c\u7684\u51fd\u6570\u3002pass \u5206\u4e3a\u5206\u6790\u7c7b pass \u548c\u4f18\u5316\u7c7b pass\u3002 \u5206\u6790\u7c7b pass \u53ea\u662f\u5e2e\u52a9\u6211\u4eec\u89c2\u5bdf IR\uff0c\u83b7\u5f97\u67d0\u4e9b\u6982\u62ec\u4fe1\u606f\uff0c\u5e76\u4e0d\u4fee\u6539 IR\u3002\u73b0\u5728\u6211\u4eec\u8981\u7528\u7684 def-use pass \u5c31\u5c5e\u4e8e\u5206\u6790\u7c7b pass\uff0c\u4ed6\u901a\u8fc7\u4e00\u6b21\u904d\u5386\u627e\u5230\u6240\u6709\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\u5173\u7cfb\u3002\u53ea\u8981 IR \u4e0d\u4fee\u6539\uff0c\u5c31\u53ef\u4ee5\u7f13\u5b58\u4e4b\u524d\u7684\u7ed3\u679c\uff0c\u4f9b\u540e\u6765\u8005\u91cd\u590d\u4f7f\u7528\u3002 \u4f18\u5316\u7c7b pass \u53ef\u4ee5\u4fee\u6539 IR \u7684\u8282\u70b9\uff0c\u4fee\u6539 IR \u539f\u6709\u7684\u7ed3\u6784\uff0c\u4f8b\u5982\u4e4b\u524d\u63d0\u5230\u7684 mem2reg pass \u5c31\u5c5e\u4e8e\u6b64\u7c7b\uff0c\u4ed6\u4f1a\u628a\u6240\u6709\u80fd\u4f18\u5316\u7684 alloca + store \u4fee\u6539\u6210\u9759\u6001\u5355\u8d4b\u503c\u7684\u5bc4\u5b58\u5668\u3002\u7531\u4e8e\u4f1a\u4fee\u6539 IR\uff0c\u53ef\u80fd\u5bfc\u81f4\u67d0\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u5931\u6548\uff0c\u4e0b\u6b21\u518d\u7528\u5230\u65f6\u9700\u8981\u91cd\u8dd1\u3002 \u533a\u522b\uff1a \u5206\u6790\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u5206\u6790\u7ed3\u679c\u7c7b\u578b\u3002\u4f8b\u5982\u5bf9\u4e8e def-use pass\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a Analysis \u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u4e2d\u7ef4\u62a4\u4e86\u4e00\u4e2a \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d \u7684\u53cc\u5411\u6620\u5c04\uff0c\u6211\u4eec def-use pass \u5206\u6790\u5f97\u5230\u7ed3\u679c\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u6620\u5c04\u6765\u67e5\u8be2\u3002 \u4f18\u5316\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u4e5f\u662f\u4e00\u6bb5 IR\uff0c\u88ab\u6539\u53d8\u540e\u7684 IR\u3002LLVM \u5b9e\u73b0\u4f18\u5316\uff0c\u5c31\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u4f18\u5316 pass \u7684\u7ec4\u5408\u5b8c\u6210\u7684\u3002\u6709\u65f6\uff0c\u4f18\u5316 pass \u4f1a\u9700\u8981\u4e00\u4e9b\u5206\u6790\u7684\u7ed3\u679c\uff0c\u624d\u80fd\u8fdb\u884c\uff0c\u56e0\u6b64\u4f18\u5316 pass \u6709\u65f6\u4f1a\u8bf7\u6c42\u4e00\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\uff0cLLVM \u4f1a\u68c0\u67e5\u8fd9\u4e2a\u5206\u6790\u4e4b\u524d\u6709\u6ca1\u6709\u8fdb\u884c\u8fc7\uff0c\u5982\u679c\u6709\uff0c\u5c31\u4f1a\u590d\u7528\u4e0a\u6b21\u5206\u6790\u7684\u7ed3\u679c\uff0c\u4e0d\u4f1a\u91cd\u65b0\u5206\u6790\u6d6a\u8d39\u65f6\u95f4\u3002\u4f18\u5316 pass \u5728\u4fee\u6539\u4e86 IR \u540e\uff0c\u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6807\u5fd7\u4f4d\uff0c\u8868\u793a IR \u4fee\u6539\u540e\uff0c\u54ea\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u5931\u6548\u3002\u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u5c31\u8fd4\u56de all \u5427\uff1a\u672c\u4f18\u5316 pass \u4fee\u6539\u8fc7 IR \u540e\u6240\u6709\u4e4b\u524d\u5206\u6790 pass \u7f13\u5b58\u7684\u7ed3\u679c\u90fd\u4f1a\u5931\u6548\u3002 \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\u662f\u5426\u53ef\u4ee5\u88ab\u4f18\u5316\u6389\uff1f\u68c0\u6d4b\u4ed6\u6709\u6ca1\u6709\u88ab\u522b\u4eba\u201c\u4f7f\u7528\u201d\uff1a\u4e5f\u5c31\u662f\u67e5\u8be2\u4ed6\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\uff0c\u5982\u679c\u53d1\u73b0\u201c\u4f7f\u7528\u8005\u5217\u8868\u201d\u4e3a\u7a7a\uff0c\u5c31\u8bf4\u660e\u8be5\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\u6ca1\u4eba\u4f7f\u7528\uff0c\u53ef\u4ee5\u4f18\u5316\u6389\u3002","title":"\u4f18\u5316\u4e0e\u5206\u6790 pass"},{"location":"llvm_intro/#llvm-ir_1","text":"\u4ee5\u4e0b\u662f\u4e00\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u53ca\u5176\u6240\u5bf9\u5e94\u7684 LLVM IR \u6c47\u7f16\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u770b\u8d77\u6765\u597d\u590d\u6742\uff01\u8ba9\u6211\u4eec\u4e00\u884c\u4e00\u884c\u6765\u89e3\u8bfb\uff1a ; ModuleID = 'a.cpp' \u8fd9\u79cd\u4ee5\u5206\u53f7\u5f00\u5934\u7684\uff0c\u5c31\u662f IR \u6c47\u7f16\u8bed\u6cd5\u4e2d\u7684\u6ce8\u91ca\uff0c\u5206\u53f7\u540e\u9762\u7684\u4e1c\u897f\u4f1a\u88ab\u65e0\u89c6\uff0c\u4e0d\u5f71\u54cd\u5b9e\u9645\u7ed3\u679c\u3002\u5c31\u548c C \u8bed\u8a00\u7684 // \u4e00\u6837\uff0c\u5c5e\u4e8e\u884c\u6ce8\u91ca\u3002 Clang \u751f\u6210\u7684 IR \u6c47\u7f16\u6709\u65f6\u5e26\u6709\u6ce8\u91ca\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u7ed9\u4eba\u770b\u7684\uff0c\u5e76\u4e0d\u5f71\u54cd\u540e\u7aef\u7684\u89e3\u6790\u3002\u8fd9\u91cc\u7684\u6ce8\u91ca\u5f88\u660e\u663e\u662f\u5728\u63d0\u793a\uff0c\u8be5\u6c47\u7f16\u662f\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u7684\uff1f\u662f\u4e00\u4e2a\u53eb a.cpp \u7684\u6587\u4ef6\uff0c\u4f46\u4ed6\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u529b\uff0c\u53ea\u662f\u7ed9\u8bfb\u6c47\u7f16\u7684\u4f60\u6211\u770b\u3002 source_filename = \"a.cpp\"","title":"LLVM IR \u6848\u4f8b\u5206\u6790"},{"location":"llvm_intro/#target","text":"\u8fd9\u624d\u662f\u771f\u6b63\u5bf9 LLVM \u4e2d\u7aef\u6709\u6548\u529b\u7684\u4e1c\u897f\uff0c\u4ed6\u8d4b\u503c\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u63d0\u793a\u8be5 IR \u6c47\u7f16\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u3002\u8fd9\u4e2a source_filename \u5c5e\u6027\uff0c\u662f\u7531 Clang \u5728\u751f\u6210 IR \u6c47\u7f16\u65f6\uff0c\u4e3b\u52a8\u52a0\u4e0a\u544a\u77e5 LLVM \u540e\u7aef\u7684\u3002\u4e5f\u662f\u4e3a\u4e86\u65b9\u4fbf\u8c03\u8bd5\uff0c\u4f8b\u5982\u5f53 LLVM \u4e2d\u7aef\u4e2d\u89e6\u53d1\u4e86\u62a5\u9519\uff0c\u4ed6\u53ef\u4ee5\u4ee5\u8fd9\u4e2a\u6587\u4ef6\u540d\u6765\u63d0\u793a\u7528\u6237\u3002 target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" \u8fd9\u91cc\u6307\u5b9a\u7684\u662f\u5173\u4e8e\u201c\u76ee\u6807\u5e73\u53f0\u201d\u7684\u4e00\u4e9b\u4fe1\u606f\uff0c\u5206\u4e3a\u4e24\u4e2a\u90e8\u5206\u3002 \u76ee\u6807\u5e73\u53f0\u6307\u7684\u662f\u5f53\u524d\u6e90\u7801\u8981\u7f16\u8bd1\u5230\u4ec0\u4e48\u786c\u4ef6\u4e0a\u6267\u884c\uff0c\u6bd4\u5982\u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u76ee\u6807\u5e73\u53f0\u5c31\u662f x86\u3002 \u5176\u4e2d target triple \u662f\u6307\u5b9a\u7684\u76ee\u6807\u5e73\u53f0\u7684\u540d\u5b57\uff0c\u8fd9\u91cc\u6211\u4eec\u662f x86_64-pc-linux-gnu \uff0c\u8868\u793a 64 \u4f4d x86 \u67b6\u6784\uff0c\u684c\u9762\u7aef\uff0cLinux \u7cfb\u7edf\uff0cGNU \u7f16\u8bd1\u5668\u63a5\u53e3\u3002\u4e0d\u540c\u7684 target triple \u4f1a\u5f71\u54cd\u6700\u7ec8\u751f\u6210\u7684\u6c47\u7f16\u4e2d\u51fd\u6570\u8c03\u7528\u7ea6\u5b9a\u3001C++ \u51fd\u6570\u540d\u91cd\u7ec4\u7b49\u7ec6\u8282\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a triple \u5c31\u662f\u6211\u4eec\u5e38\u8bf4\u7684 ABI\uff08\u4e8c\u8fdb\u5236\u5e94\u7528\u7a0b\u5e8f\u63a5\u53e3\uff09\u3002 \u4f8b\u5982\uff0c\u5728 Windows \u4e0a\u4f7f\u7528 clang \uff0c\u53ef\u80fd\u5f97\u5230 target triple \u662f x86_64-pc-windows-msvc \uff08\u5982\u679c\u4f60\u662f MSVC \u7f16\u8bd1\u5668\uff09\u6216\u8005 x86_64-pc-windows-gnu \uff08\u5982\u679c\u4f60\u662f MinGW \u7f16\u8bd1\u5668\uff09\uff0c\u4ea7\u751f\u7684 C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u4f1a\u6709\u4e0d\u540c\u3002\u5728 MacOS \u4e0a\u8fd8\u4f1a\u5f97\u5230 x86_64-apple-darwin \u6216 aarch64-apple-darmin \u3002 \u4e0d\u540c\u7684\u64cd\u4f5c\u7cfb\u7edf\u548c\u786c\u4ef6\uff0c\u90fd\u4f1a\u6709\u4e0d\u540c\u7684 ABI\uff0c\u4f8b\u5982 Linux \u5728 x86_64 \u4e0a\u7684 ABI \u89c4\u5b9a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7531 rdi \u4f20\u5165\uff0c\u800c Windows \u5219\u662f rcx \u3002\u8fd9\u4e9b\u7ec6\u8282\u90fd\u662f\u7531 target triple \u786e\u5b9a\u7684\u3002 target datalayout \u5219\u662f\u6307\u5b9a\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u7c7b\u578b\u5927\u5c0f\u548c\u5e03\u5c40\u7b49\u4fe1\u606f\uff0c\u4f8b\u5982\u6307\u9488\u5927\u5c0f\u3001\u5bf9\u9f50\u65b9\u5f0f\u7b49\u3002\u4f8b\u5982\u5728 x86_64-pc-linux-gnu \u8fd9\u4e2a ABI \u4e0a\uff0c long \u662f 64 \u4f4d\u3002\u800c\u5728 x86_64-pc-windows-msvc \u4e0a\uff0c long \u662f 32 \u4f4d\u3002\u8fd9\u4e9b\u4fe1\u606f\u4f1a\u5f71\u54cd\u540e\u7aef\u4ea7\u751f\u6c47\u7f16\u7684\u5185\u5b58\u5e03\u5c40\uff0c\u56e0\u6b64\uff0cIR \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 target datalayout \u662f\u4e00\u4e2a\u5f88\u957f\u7684\u5b57\u7b26\u4e32\uff0c\u91cc\u9762\u6709\u591a\u4e2a\u7531 - \u5206\u9694\u7684\u5b57\u6bb5\u3002\u6bcf\u4e2a\u5b57\u6bb5\u53ef\u4ee5\u5206\u522b\u7528\u6765\u63cf\u8ff0\u6307\u9488\u3001\u6574\u578b\u3001\u6d6e\u70b9\u578b\u3001\u77e2\u91cf\u3001\u6570\u7ec4\u3001\u7ed3\u6784\u4f53\u3001\u8054\u5408\u4f53\u7b49\u7684\u5927\u5c0f\u548c\u5185\u5b58\u5e03\u5c40\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 \uff0c\u6211\u4eec\u9996\u5148\u6309 - \u62c6\u5206\uff0c\u5f97\u5230\u6bcf\u4e00\u4e2a\u5b50\u5b57\u6bb5\u3002 e // \u8868\u793a\u76ee\u6807\u5e73\u53f0\u7684\u5b57\u8282\u5e8f\uff0ce=\u5c0f\u7aef\uff0cE=\u5927\u7aef m:e // \u8868\u793a C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u91c7\u7528\u4f55\u79cd\u673a\u5236\uff0ce=ELF\u98ce\u683c\uff0cw=Windows\u98ce\u683c\u2026\u2026\u7b49 p270:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p271:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p272:64:64 // \u6307\u9488\u5927\u5c0f 64 \u4f4d\uff0c\u5bf9\u9f50\u5230 64 \u4f4d i64:64 // __int64 \u91c7\u7528 64 \u4f4d\u6765\u5b58\u50a8 i128:128 // __int128 \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 f80:128 // long double \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 n8:16:32:64 // \u6307\u5b9a\u54ea\u4e9b\u662f\u76ee\u6807 CPU \u539f\u751f\u7684\u7c7b\u578b\u5927\u5c0f\uff0c\u5bf9\u4e8e 64 \u4f4d x86 \u6765\u8bf4\uff0c\u5206\u522b\u6709 8 \u4f4d\u300116 \u4f4d\u300132 \u4f4d\u300164 \u4f4d\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u90fd\u5199\u4e0a S128 // \u6808\u6307\u9488\uff08rsp\uff09\u5bf9\u9f50\u5230 128 \u4f4d\uff0816 \u5b57\u8282\uff09\uff0c\u8fd9\u662f 64 \u4f4d x86 ABI \u6240\u8981\u6c42\u7684 target datalayout \u7684\u8be6\u7ec6\u8bed\u6cd5\uff0c\u53ef\u4ee5\u53c2\u8003 LLVM \u5b98\u65b9\u6587\u6863 \u3002 270\u3001271\u3001272 \u662f\u4e09\u4e2a\u679a\u4e3e\u503c\uff0c\u5206\u522b\u8868\u793a PTR32_SPTR \u3001 PTR32_UPTR \u548c PTR64 \uff0c\u8868\u793a\u4e0d\u540c\u7684\u6307\u9488\u7c7b\u578b\u3002\u524d\u4e24\u4e2a\u662f\u56e0\u4e3a x86_64 \u67b6\u6784\u4f9d\u7136\u652f\u6301\u4ee5 32 \u4f4d\u5bc4\u5b58\u5668\u505a\u5730\u5740\u8bbf\u95ee\u5185\u5b58\uff08\u975e\u5e38\u611a\u8822\u7684\u8bbe\u5b9a\uff0c\u8bf7\u5ffd\u89c6\uff09\uff0c\u540e\u9762\u7684 PTR64 \u624d\u662f\u6211\u4eec\u6b63\u5e38\u4f7f\u7528\u7684 64 \u4f4d\u6307\u9488\u3002\u679a\u4e3e\u7684\u5b9a\u4e49\u8bf7\u770b llvm/lib/Target/X86/X86.h \u3002","title":"target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f"},{"location":"llvm_intro/#define","text":"\u7ee7\u7eed\u770b\u4e0b\u53bb: ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { ... } \u9996\u5148\uff0c\u4ee5\u5206\u53f7\u5f00\u5934\u7684 ; Function Attrs: ... \u662f\u6ce8\u91ca\uff0c\u53ef\u4ee5\u5ffd\u7565\u3002 \u6ce8\u91ca\u91cc\u9762\u7684 mustprogress noinline ... \u7b49\uff0c\u8868\u793a\u7684\u662f\u4e0b\u9762\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u5c5e\u6027\u201d\u3002\u4f46\u662f\u6ce8\u91ca\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u679c\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u4f5c\u7528\uff0c\u771f\u6b63\u8bbe\u7f6e\u4e86\u5c5e\u6027\u7684\u662f\u66f4\u4e0b\u9762\u7684 attributes #0 \u6307\u4ee4\uff0cClang \u751f\u6210\u4e00\u4e2a\u6ce8\u91ca\u53ea\u662f\u8ba9\u4f60\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u4e0d\u7528\u8dd1\u5230\u4e0b\u9762\u624d\u80fd\u770b\u5230\u5c5e\u6027\u3002 \u90a3\u4e48\uff0c\u53ea\u5269\u4e0b\u51fd\u6570\u7684\u5b9a\u4e49\u4e86\uff1a define dso_local noundef i32 @main() #0 { ... } define \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u51fd\u6570\u7684\u5b9a\u4e49\u3002 dso_local \u662f\u51fd\u6570 main \u7684\u4fee\u9970\u7b26\uff0c\u542b\u4e49\u76f8\u5f53\u4e8e extern \u8868\u793a\u8be5\u53d8\u91cf\u4e3a\u5bfc\u51fa\u7b26\u53f7\uff0c\u4e14\u8981\u6c42\u7b26\u5408 ODR \u89c4\u5219\u3002\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u610f\u5473\u7740\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u8bbe\u6807\u8bb0\u8be5\u51fd\u6570\u6216\u53d8\u91cf\u88ab\u89e3\u6790\u4e3a\u540c\u4e00\u94fe\u63a5\u5355\u5143\u5185\u7684\u7b26\u53f7\uff0cdso\u4ee3\u8868\u52a8\u6001\u5171\u4eab\u5bf9\u8c61\uff08dynamic shared object\uff09\uff0c\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 noundef \u662f\u8fd4\u56de\u7c7b\u578b i32 \u7684\u4fee\u9970\u7b26\uff0c\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u4f1a\u8fd4\u56de\u4e00\u4e2a\u672a\u5b9a\u4e49\u7684\u503c\uff0c\u6ce8\u610f noundef \u4fee\u9970\u7684\u662f\u53f3\u8fb9\u7684\u8fd4\u56de\u7c7b\u578b i32 \u800c\u4e0d\u662f\u51fd\u6570\u672c\u8eab\u3002\u8fd9\u4e2a\u5c5e\u6027\u53ef\u4ee5\u7528\u4e8e\u5e2e\u52a9\u7f16\u8bd1\u5668\u6392\u9664\u4e00\u4e9b\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e5f\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 i32 \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 int \u3002 @main \u662f\u51fd\u6570\u540d\u5b57\uff0c\u5176\u4e2d @ \u662f\u6240\u6709\u51fd\u6570\u540d\u7684\u56fa\u6709\u524d\u7f00\uff0c\u540e\u9762\u7684 main \u5c31\u662f\u6211\u4eec\u5f53\u524d\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u51fd\u6570\u540d\u5b57\u540e\u9762\u7d27\u63a5\u7740\u7684 () \u8868\u793a\u53c2\u6570\u5217\u8868\uff0c\u6b64\u5904\u6211\u4eec\u7684 main \u51fd\u6570\u521a\u597d\u6ca1\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u6240\u4ee5\u662f\u4e00\u4e2a\u7a7a\u7684\u62ec\u53f7\uff08\u7a0d\u540e\u6211\u4eec\u4f1a\u770b\u4e00\u4e2a\u6709\u53c2\u6570\u7684\u6848\u4f8b\uff09\u3002 #0 \u8868\u793a\u8be5\u51fd\u6570\u7684\u7f16\u53f7\uff0c\u5c31\u548c\u5bc4\u5b58\u5668\u7f16\u53f7\u4e00\u6837\uff0c\u6240\u6709\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u4ece 0 \u5f00\u59cb\u7684\u7f16\u53f7\u3002 {} \u4e2d\u7684\u5185\u5bb9\uff0c\u5c31\u662f\u51fd\u6570\u5757\u5185\u90e8\u7684 IR \u4e86\uff0c\u8fd9\u4e9b\u662f main \u51fd\u6570\u7684\u51fd\u6570\u4f53\uff0c\u6bcf\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u5c31\u4f1a\u6267\u884c\u5176\u4e2d\u7684\u6240\u6709 IR \u8282\u70b9\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7684\u5b9a\u4e49\u4e5f\u662f\u4e00\u4e2a IR \u8282\u70b9\uff0c\u540c\u6837\u6709\u4ece 0 \u5f00\u59cb\u9012\u589e\u7684\u201c\u5bc4\u5b58\u5668\u7f16\u53f7\u201d\uff0c\u4f46\u4ed6\u5e76\u4e0d\u662f\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7528 #n \u8868\u793a\uff0c\u800c\u5bc4\u5b58\u5668\u7528 %n \u8868\u793a\u3002 define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } \u8ba9\u6211\u4eec\u4e00\u6761\u4e00\u6761\u89e3\u6790\u51fd\u6570\u4f53\u5185\u7684\u8fd9\u4e9b IR \u8282\u70b9\u5427\uff01","title":"define \u5b9a\u4e49\u51fd\u6570"},{"location":"llvm_intro/#alloca","text":"%1 = alloca i32, align 4 %1 \u8868\u793a\u4e86\u5bc4\u5b58\u5668\u7684\u540d\u5b57\uff0c = \u53f3\u8fb9\u5c31\u662f\u8be5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u3002\u8fd9\u91cc\u8981\u4ecb\u7ecd LLVM IR \u7684\u4e00\u4e2a\u91cd\u8981\u89c4\u5219\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff01\u5bc4\u5b58\u5668\u4e00\u65e6\u5b9a\u4e49\uff08\u8d4b\u503c\uff09\u8fc7\u4e00\u6b21\u540e\u5c31\u4e0d\u80fd\u518d\u4fee\u6539\uff0c\u9664\u975e\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u5bc4\u5b58\u5668\u3002\u4e3a\u4e86\u4ea7\u751f\u53ef\u4ee5\u52a8\u6001\u4fee\u6539\u7684\u53d8\u91cf\uff0cClang \u5fc5\u987b\u4f7f\u7528 alloca \u6307\u4ee4\u5206\u914d\u4e00\u5757\u201c\u6808\u5185\u5b58\u201d\uff0c\u6808\u5185\u5b58\u603b\u662f\u53ef\u8bfb\u5199\u7684\u3002 alloca \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6808\u5185\u5b58\u5206\u914d\u6307\u4ee4\uff0c\u4ed6\u4f1a\u5728\u5f53\u524d\u51fd\u6570 main \u7684\u6808\u4e0a\u5206\u914d\u4e00\u4e2a\u7c7b\u578b\u4e3a i32 \u7684\u5185\u5b58\u7a7a\u95f4\u3002 i32 \u6307\u5b9a\u4e86\u6808\u5185\u5b58\u8981\u5206\u914d\u7684\u7c7b\u578b\u662f \u201c32 \u4f4d\u6574\u6570\u201d\u3002\u6ce8\u610f LLVM IR \u662f\u4e00\u4e2a\u6709\u7c7b\u578b\u7684 IR\uff0c\u6b64\u5904\u6211\u4eec\u9700\u8981\u6307\u5b9a\u53d8\u91cf\u7684\u5b9e\u9645\u7c7b\u578b i32 \u800c\u4e0d\u662f\u6307\u5b9a\u4e00\u4e2a 4 \u8868\u793a\u5927\u5c0f\u3002 align 4 \u8868\u793a\u8fd4\u56de\u5730\u5740\u6240\u8981\u6c42\u7684\u5bf9\u9f50\u5ea6\uff0c\u6839\u636e C \u8bed\u8a00\u89c4\u5219\u8981\u6c42\uff0c int \u7c7b\u578b\u5fc5\u987b\u5bf9\u9f50\u5230 4 \u5b57\u8282\uff0c\u56e0\u6b64\u6307\u5b9a align 4 \u3002\u5176\u4ed6\u8bed\u8a00\u82e5\u6ca1\u6709\u6b64\u89c4\u5b9a\uff0c\u4e5f\u53ef\u4ee5\u751f\u6210 align 1 \u5728 IR \u4e2d\u3002 alloca \u4f1a\u201c\u8fd4\u56de\u201d\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u521d\u59cb\u5316 %1 \u3002\u7c7b\u578b\u662f i32* \uff08\u8fd9\u91cc\u7684 * \u548c C \u8bed\u8a00\u7684\u6307\u9488\u4e00\u6837\uff0c\u8868\u793a\u524d\u9762\u7c7b\u578b\u7684\u6307\u9488\u7c7b\u578b\uff09\uff0c\u8be5\u6307\u9488\u6307\u5411\u6808\u4e0a\u5206\u914d\u597d\u7684 i32 \u53d8\u91cf\u3002 %1 \u5bc4\u5b58\u5668\u5c31\u8fd9\u6837\u88ab\u5b9a\u4e49\u4e3a\u5b9e\u9645\u53d8\u91cf\u7684\u5730\u5740\u503c\u3002 \u8fd9\u6761 IR \u6307\u4ee4\u6267\u884c\u5b8c\u6bd5\u540e\uff0c %1 \u5bc4\u5b58\u5668\u91cc\u7684\u503c\uff0c\u5c31\u662f\u6307\u5411\u7684\u6307\u9488\u3002\u7531\u4e8e\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c %1 \u8fd9\u4e2a\u6307\u9488\u672c\u8eab\u5728\u51fd\u6570\u9000\u51fa\u524d\uff0c\u5c06\u6c38\u8fdc\u4e0d\u53d8\u3002\u4f46\u662f\u6307\u9488\u4e0d\u80fd\u53d8\uff0c\u6307\u9488\u6307\u5411\u7684\u503c\u53ef\u4ee5\u53d8\uff0c\u6240\u4ee5\u4e4b\u540e\u53ea\u9700\u8981\u4ee5\u6307\u9488\u5f62\u5f0f\u8bfb\u5199\u5176\u6307\u5411\u7684\u5730\u5740\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u53ef\u53d8\u7684\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u53d7\u5236\u4e8e\u5bc4\u5b58\u5668\u4e0d\u53ef\u53d8\u3002 \u5728 LLVM IR \u5c42\u9762\uff0c\u4e0d\u5b58\u5728\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \u3002\u6216\u8005\u8bf4\uff0c\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u4fdd\u5b58\u7684\u672c\u6765\u5c31\u662f\u4ed6\u4eec\u7684\u5730\u5740\uff08\u901a\u8fc7 alloca \u8fd4\u56de\u7684\uff09\u3002\u6b63\u5e38\u8d4b\u503c\u548c\u8bfb\u53d6\u53d8\u91cf\u7684\u64cd\u4f5c\u90fd\u662f\u901a\u8fc7 store \u548c load \u95f4\u63a5\u901a\u8fc7\u53d8\u91cf\u7684\u6307\u9488\u6765\u4fee\u6539\u53d8\u91cf\u7684\uff0c\u5bc4\u5b58\u5668\u672c\u8eab\u4e0d\u53ef\u53d8\u3002\u5982\u679c\u4f7f\u7528\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u5c31\u662f\u539f\u5c01\u4e0d\u52a8\u628a\u5bc4\u5b58\u5668\u7684\u6307\u9488\u503c\u8d4b\u7ed9\u4f60\u800c\u5df2\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u7684\u7c7b\u578b\u672c\u8eab\u5c31\u662f\u6307\u9488\uff08\u6bd4\u5982 char * \uff09\uff0c\u90a3\u4e48\u901a\u8fc7 alloca i8* \u5b9a\u4e49\u7684\u5bc4\u5b58\u5668\u7684\u7c7b\u578b\u5c31\u4f1a\u662f\u4e00\u4e2a\u4e8c\u7ea7\u6307\u9488\uff08 i8** \uff09\u3002 C++ \u5f15\u7528\u5728 LLVM IR \u5c42\u9762\u540c\u6837\u4e5f\u4f1a\u53d8\u6210\u6307\u9488\u7c7b\u578b\u7684\u53d8\u91cf\u3002\u6ce8\u610f\uff0c\u6211\u53ea\u662f\u8bf4 C++ \u5f15\u7528\u548c\u6307\u9488\u4f1a\u5728 LLVM \u4e2d\u4f1a\u540c\u6837\u53d8\u6210\u6307\u9488\u7c7b\u578b\uff0c\u5e76\u4e0d\u662f\u8bf4\u5728 Clang \u524d\u7aef\u91cc\u5f15\u7528\u548c\u6307\u9488\u6ca1\u533a\u522b\u3002 \u6240\u4ee5\uff0c\u8fd9\u91cc\u7684 %1 \u548c %2 \u5176\u5b9e\u662f\u5bf9\u5e94\u6e90\u7801\u4e2d\u7684 a \u548c b \u53d8\u91cf\uff08\u7684\u6307\u9488\uff09\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e int * %1 = alloca(4) \u3002","title":"alloca \u6307\u4ee4"},{"location":"llvm_intro/#store","text":"\u7ee7\u7eed\u63a5\u7740\u770b\uff1a store i32 1, ptr %1, align 4 \u8fd9\u662f\u4e00\u6761 store \u6307\u4ee4\u3002 \u6307\u4ee4\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570 i32 1 \u8868\u793a\u8981\u5b58\u5165\u7684\u503c\uff0c\u8fd9\u91cc\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u5e38\u6570 1 \u3002LLVM IR \u4e2d\u6307\u4ee4\u6240\u6709\u7684\u53c2\u6570\u90fd\u9700\u8981\u5728\u524d\u9762\u6307\u5b9a\u7c7b\u578b\u540d\uff0c\u6211\u4eec\u8981\u5199\u5165\u7684 a \u53d8\u91cf\u662f int \u4e5f\u5c31\u662f i32 \u7c7b\u578b\uff0c\u6240\u4ee5\u7528 i32 \u4fee\u9970\u8981\u5199\u5165\u7684\u503c 1 \u3002 \u7b2c\u4e8c\u4e2a\u53c2\u6570 ptr %1 \u8868\u793a\u8981\u5199\u5165\u5230\u7684\u5730\u5740\uff0c\u5fc5\u987b\u662f\u6307\u9488\u7c7b\u578b\u3002\u8fd9\u91cc\u7684 ptr \u662f i32* \u7684\u7b80\u5199\uff0c\u7b49\u4ef7\u4e8e i32* %1 \u3002\u7531\u4e8e\u521a\u624d %1 \u5b9a\u4e49\u4e3a alloca \uff0c\u4e5f\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\u4e86\u4e00\u4e2a\u53d8\u91cf\uff08C++ \u6e90\u7801\u4e2d\u7684 a \uff09\u3002 %1 \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u5176\u503c\u662f a \u7684\u5730\u5740\u3002\u6240\u4ee5\u6b64\u5904 store \u7684\u6548\u679c\u662f\u5f80\u53d8\u91cf a \u4e2d\u5199\u5165\u4e86\u4e00\u4e2a\u5e38\u6570 1 \u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 alloca \u548c\u7d27\u63a5\u7740\u7684 store \u8fd9\u4e24\u6761\u6307\u4ee4\uff0c\u8fde\u8d77\u6765\uff0c\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\uff08 alloca \uff09\u4e86\u4e00\u4e2a\u53d8\u91cf a \u4e4b\u540e\uff0c\u5411\u5176\u4e2d\u8d4b\u4e86\u4e00\u4e2a\u521d\u59cb\u503c 0 \u3002 \u6ce8\u610f\u5230\uff0c store \u5e76\u6ca1\u6709\u7528\u4e8e\u5b9a\u4e49\u4e00\u4e2a\u5bc4\u5b58\u5668\uff08\u4f8b\u5982 %1 = store ... \uff09\u3002 store \u6307\u4ee4\u6ca1\u6709\u201c\u8fd4\u56de\u503c\u201d\uff0c\u56e0\u6b64\u4ed6\u4e0d\u4f1a\u5b9a\u4e49\u4efb\u4f55\u5bc4\u5b58\u5668\uff1b store \u672c\u8eab\u662f\u56e0\u4e3a\u5176\u5199\u5165\u4ea7\u751f\u7684\u526f\u4f5c\u7528\u800c\u5b58\u5728\uff0c\u4e0d\u9700\u8981\u6709\u4eba\u201c\u4f7f\u7528\u201d\u4ed6\u7684\u503c\u3002 \u56e0\u4e3a\u6709\u526f\u4f5c\u7528\uff0c store \u5c31\u4e0d\u80fd\u7b80\u5355\u5730\u88ab def-use \u5206\u6790 pass \u4f18\u5316\u6389\u4e86\uff0c\u6240\u4ee5\u9700\u8981\u5148\u8fc7\u4e00\u4e2a mem2reg pass \u628a\u80fd\u8f6c\u5316\u6389\u7684 store \u5c3d\u53ef\u80fd\u8f6c\u6210\u5bb9\u6613\u4f18\u5316\u7684\u5bc4\u5b58\u5668\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b store i32 1, ptr %1, align 4 ; a = 1 store i32 2, ptr %2, align 4 ; a = 2 \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e *%1 = 1 \u3002","title":"store \u6307\u4ee4"},{"location":"llvm_intro/#_20","text":"\u5982\u679c\u4f60\u53ea\u662f alloca \uff0c\u800c\u6ca1\u6709\u5f80\u91cc\u9762 store \u8d4b\u503c\u8fc7\u7684\u8bdd\uff0c\u90a3\u4e48\u8be5\u6808\u53d8\u91cf\u7684\u503c\u662f\u201c\u672a\u5b9a\u4e49\u503c\u201d\uff0c\u5728 C++ \u6807\u51c6\u4e2d\uff0c\u8bbf\u95ee\uff08 load \uff09\u4e00\u4e2a\u201c\u672a\u5b9a\u4e49\u503c\u201d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4f8b\u5982\uff1a int a; return a; // \u9519\u8bef\uff1aa \u672a\u521d\u59cb\u5316\uff0c\u91cc\u9762\u7684\u503c\u662f\u672a\u5b9a\u4e49\u503c\uff01 \u8bfb\u53d6\u6ca1\u6709\u521d\u59cb\u5316\u8fc7\u7684\u6808\u53d8\u91cf\uff0c\u5728 x86 \u548c ARM \u7b49\u5177\u4f53\u67b6\u6784\u4e2d\uff0c\u4f60\u53ef\u80fd\u4f1a\u8bfb\u5230\u5185\u5b58\u4e2d\u7684\u968f\u673a\u53d8\u91cf\u3002 \u5728 LLVM \u4e2d\uff0c\u8fd9\u7c7b\u5904\u4e8e\u672a\u521d\u59cb\u5316\u72b6\u6001\u7684\u503c\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u540d\u5b57\uff0c\u53eb\u201c\u6bd2\u503c\u201d\uff08poison value\uff09\u3002 \u6bd2\u503c\u4e0d\u662f C++ \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f\u786c\u4ef6\u67b6\u6784\u7684\u4e00\u90e8\u5206\uff0c\u800c\u662f LLVM \u4e2d\u7aef\u4eba\u4e3a\u5b9a\u4e49\u7684\uff08\u56e0\u4e3a\u5f88\u591a\u7cfb\u7edf\u7ea7\u8bed\u8a00\u90fd\u6709\u652f\u6301\u672a\u521d\u59cb\u5316\u7684\u5185\u5b58\uff0c\u77e5\u9053\u54ea\u4e9b\u503c\u662f\u4e0d\u53ef\u80fd\u7684\u6709\u52a9\u4e8e LLVM \u4f18\u5316\uff09\u3002 \u201c\u6bd2\u503c\u201d\u5e76\u4e0d\u662f\u968f\u673a\u503c\uff0c\u4ed6\u662f i32 \u8868\u793a\u7a7a\u95f4\u4e4b\u5916\u7684\u4e00\u4e2a\u7279\u6b8a\u503c\uff0c\u4e0d\u662f\u88ab 0 \u5230 4294967295 \u8303\u56f4\u5185\u7684\u4efb\u4f55\u6574\u6570\uff0c\u800c\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u7528\u4e8e\u6807\u8bc6\u201c\u672a\u5b9a\u4e49\u884c\u4e3a\u201d\u7684\u4e00\u4e2a LLVM \u4e2d\u624d\u6709\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u610f\u601d\u662f\u201c\u8fd9\u4e2a\u503c\u73b0\u5728\u4e0d\u80fd\u4f7f\u7528\u201d\u3002\u53ea\u4e0d\u8fc7\u5728\u8f6c\u6362\u4e3a\u5177\u4f53\u67b6\u6784\u7684\u6c47\u7f16\u4ee3\u7801\u540e\u5f80\u5f80\u4f1a\u53d8\u6210\u201c\u968f\u673a\u503c\u201d\u8fd9\u4e00\u5177\u4f53\u5b9e\u73b0\uff0c\u4f9d\u8d56\u8fd9\u4e00\u70b9\u7684\u540e\u679c\u662f\u672a\u5b9a\u4e49\u7684\u3002\uff08\u4f8b\u5982\u4f60\u4e0d\u80fd\u7528\u4e00\u4e2a\u201c\u672a\u521d\u59cb\u5316\u53d8\u91cf\u201d\u751f\u6210\u968f\u673a\u6570\uff0c\u5728\u9ad8\u4f18\u5316\u4e0b\u53ef\u80fd\u4ea7\u751f\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u800c\u4e14\u4e5f\u5e76\u4e0d\u4e00\u5b9a\u591f\u968f\u673a\uff09 \u6bd2\u503c\u7684\u7279\u70b9\uff1a alloca \u540e\u6ca1\u6709 store \u8fc7\u7684\u6808\u53d8\u91cf\u521d\u59cb\u5c31\u662f\u4e3a\u6bd2\u503c\u3002\u5982\u679c\u5c1d\u8bd5\u76f4\u63a5 load \u8fd9\u4e2a\u5730\u5740\uff0c\u90a3\u4e48 load \u8fd4\u56de\u7684\u5bc4\u5b58\u5668\u5c31\u548c\u521d\u59cb\u5316\u4e3a\u201c\u6bd2\u503c\u201d\u3002 \u6bd2\u503c\u4f1a\u611f\u67d3\u6240\u6709\u201c\u4f7f\u7528\u201d\u4e86\u4ed6\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982 %1 \u662f\u6bd2\u503c\uff0c\u90a3\u4e48 %2 = add %1, 1 \u4e5f\u662f\u6bd2\u503c\uff0c\u56e0\u4e3a %2 \u201c\u4f7f\u7528\u201d\u4e86\u7684 %1 \u662f\u6bd2\u503c\u3002 \u6807\u8bb0\u4e3a noundef \u7c7b\u578b\u7684\u53d8\u91cf\uff08\u4f8b\u5982 noundef i32 \uff09\uff0c\u5fc5\u987b\u4e0d\u80fd\u662f\u6bd2\u503c\uff0c\u5426\u5219\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u8fd4\u56de\u7c7b\u578b\u6807\u8bb0\u4e3a noundef \uff08\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5e94\u8fd4\u56de\u6bd2\u503c\uff09\u7684\u51fd\u6570\u8fd4\u56de\u4e86\u6bd2\u503c\uff0c\u90a3\u4e48\u5c31\u89e6\u53d1\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\u3002","title":"\u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09"},{"location":"llvm_intro/#load","text":"%3 = load i32, ptr %1, align 4 ; \u52a0\u8f7d a %4 = load i32, ptr %2, align 4 ; \u52a0\u8f7d b load \u6307\u4ee4\u4ece\u5185\u5b58\u7684\u6307\u5b9a\u5730\u5740\u5904\u52a0\u8f7d\u4e00\u4e2a\u6307\u5b9a\u7c7b\u578b\u7684\u6570\u636e\uff0c\u8bfb\u53d6\u5230\u5bc4\u5b58\u5668\u4e2d\u3002 \u5206\u522b\u662f\u5bf9\u5e94\u52a0\u8f7d a \u548c b \u8fd9\u4e24\u4e2a\u53d8\u91cf\uff0c\u6765\u770b\u52a0\u8f7d a \u7684\u8fd9\u6761\u6307\u4ee4\uff1a %3 = load i32, ptr %1, align 4 i32 \u8868\u793a\u52a0\u8f7d\u4e00\u4e2a 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u8fd9\u4f1a\u628a = \u524d\u9762\u7684\u5bc4\u5b58\u5668 %3 \u5b9a\u4e49\u4e3a i32 \u7c7b\u578b\u7684\u3002 ptr %1 \u8868\u793a\u8981\u52a0\u8f7d\u7684\u5185\u5b58\u5730\u5740\uff0c\u6b64\u5904\u5730\u5740\u901a\u8fc7 %1 \u5bc4\u5b58\u5668\u6307\u5b9a\uff0c\u800c %1 \u88ab\u5b9a\u4e49\u4e3a alloca i32 \uff0c\u4e5f\u5c31\u662f\u4e00\u4e2a\u6808\u53d8\u91cf\u7684\u6307\u9488\uff0c\u6240\u4ee5\u6b64\u5904 load i32, ptr %1 \u5c31\u662f\u5728\u52a0\u8f7d\u8fd9\u4e2a\u6808\u53d8\u91cf\u7684\u503c\u3002 \u6ce8\u610f\u8fd9\u91cc\u7684\u53c2\u6570\u6307\u9488 %1 \u5fc5\u987b\u662f\u4e0e\u8981\u52a0\u8f7d\u7c7b\u578b i32 \u5bf9\u5e94\u7684\u6307\u9488\u7c7b\u578b i32* \uff0c\u800c alloca i32 \u8fd4\u56de\u7684\u6070\u597d\u662f i32* \u7c7b\u578b\u7684\u6307\u9488\uff0c\u7b26\u5408\u8981\u6c42\u3002 \u6b64\u5904 ptr %1 \u5b9e\u9645\u4e0a\u662f i32* %1 \u7684\u7b80\u5199\uff0c ptr \u662f\u4e00\u4e2a\u8bed\u6cd5\u7cd6\uff0c\u56e0\u4e3a\u524d\u9762 load i32 \u5df2\u7ecf\u6307\u5b9a\u4e86\u8981\u52a0\u8f7d\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u5177\u4f53\u7684\u6307\u9488\u7c7b\u578b i32* \u53ef\u4ee5\u7701\u7565\uff0c\u7528 ptr \u4ee3\u66ff\u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 \u7531\u4e8e\u4e4b\u524d\u5df2\u7ecf\u5f80 ptr %1 \u6307\u5411\u7684\u5730\u65b9\uff08\u5c40\u90e8\u53d8\u91cf a \uff09\u91cc store \u8fc7\u6574\u6570\u503c 1 \u4e86\uff0c\u6240\u4ee5\u8fd9\u91cc load \u51fa\u6765\u4e5f\u4f1a\u662f 1 \u3002 \u8fd9\u6837\u91cd\u590d\u7684 store \u548c load \u4f1a\u88ab\u540e\u7eed\u7684 LLVM \u4f18\u5316\u6389\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u7684 clang \u6ca1\u6709\u5f00\u542f\u4f18\u5316\uff08\u9ed8\u8ba4 -O0 \uff09\uff0c\u6240\u4ee5\u4f9d\u7136\u4fdd\u6301\u539f\u59cb\u7684 store \u548c load \u91cd\u590d\u52b3\u52a8\uff0c\u5fe0\u5b9e\u590d\u523b\u539f\u672c\u7684 C++ \u4ee3\u7801\u8bed\u4e49\u3002 \u56e0\u4e3a\u5f88\u591a\u8c61\u7259\u5854\u7262\u6e7f\u8981\u4e48\u201c\u547d\u4ee4\u884c\u8c03\u7528\u7f16\u8bd1\u201d\uff0c\u8981\u4e48 IDE \u662f\u9ed8\u8ba4\u7684\u201cDebug\u201d\u6a21\u5f0f\uff0c\u5b83\u4eec\u4e0d\u77e5\u9053\u53ef\u4ee5\u901a\u8fc7 -O \u9009\u9879\u5f00\u542f\u4f18\u5316\uff0c\u751a\u81f3\u6709\u4eba\u8ba4\u4e3a\u201c\u4f18\u5316\u201d\u662f\u4e0d\u6807\u51c6\u7684\uff0c\u8ba4\u4e3a\u4e0d\u5f00\u4f18\u5316\u7684 C++ \u624d\u80fd\u6d4b\u5f97\u771f\u5b9e\u6027\u80fd\u3002\u800c\u5b83\u4eec\u5bf9\u7f16\u8bd1\u5668\u7684\u7406\u89e3\u53c8\u662f\u7c97\u7cd9\u7684\u201c\u6ca1\u6709 AST\uff0c\u6ca1\u6709 IR\uff0c\u524d\u7aef\u89e3\u6790\u7684\u8fc7\u7a0b\u4e2d\u76f4\u63a5\u751f\u6210\u6c47\u7f16\u4ee3\u7801\u201d\uff0c\u6240\u4ee5\u624d\u4f1a\u628a C++ \u51fd\u6570\u5c40\u90e8\u53d8\u91cf\u548c\u4e00\u4e9b CPU \u540e\u7aef\u5177\u4f53\u5b9e\u73b0\u4e2d\u7684\u201c\u6808\u201d\u6df7\u4e3a\u4e00\u8c08\u3002\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u4f53\u5185\u5b9a\u4e49\u7684\u5c40\u90e8\u53d8\u91cf\uff08\u5f8b\u5e08\u7684\u8bf4\u6cd5\u662f\u201c\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u53d8\u91cf\u201d\uff0c\u5f97\u540d\u4e8e\u51fd\u6570\u4f5c\u7528\u57df\u9000\u51fa\u65f6\u4f1a\u81ea\u52a8\u6790\u6784\u548c\u91ca\u653e\u5185\u5b58\uff09\uff0c\u90fd\u53ef\u4ee5\u88ab\u4f18\u5316\u5230\u5bc4\u5b58\u5668\u4e2d\u3002\u8fd8\u6709\u4e00\u4e9b GPU \u76ee\u6807\u67b6\u6784\uff0c\u4f8b\u5982\u5728 CUDA \u4e2d\uff0c\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u6781\u591a\uff0c\u5c40\u90e8\u53d8\u91cf\u51e0\u4e4e\u603b\u662f\u53ef\u4ee5\u653e\u5230\u5728\u5bc4\u5b58\u5668\u4e0a\uff0c\u751a\u81f3\u5c40\u90e8\u6570\u7ec4\u53d8\u91cf\uff08\u5982\u679c\u4e0b\u6807\u8bbf\u95ee\u90fd\u662f\u5e38\u6570\uff09\u4e5f\u53ef\u4ee5\u653e\u5230\u5bc4\u5b58\u5668\u4e0a\u3002\u8981\u662f\u4e0d\u5f00\u5bc4\u5b58\u5668\u4f18\u5316\u5c31\u5168\u90e8\u8981\u6253\u7ffb\u5230\u5168\u5c40\u5185\u5b58\u4e86\uff0c\u4f1a\u53d8\u5f97\u548c\u5168\u5c40\u5185\u5b58\u4e00\u6837\u6162\uff01\u6240\u4ee5 nvcc \u54ea\u6015\u4e0d\u5f00 -O \u7684\u60c5\u51b5\u4e0b\u4e5f\u4f1a\u5c1d\u8bd5\u628a\u5c40\u90e8\u53d8\u91cf\u4f18\u5316\u5230\u786c\u4ef6\u5bc4\u5b58\u5668\u91cc\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %3 = *%1 \u3002","title":"load \u6307\u4ee4"},{"location":"llvm_intro/#add","text":"%5 = add nsw i32 %3, %4 LLVM \u4e2d\u6709\u52a0\u51cf\u4e58\u9664\u7684\u6307\u4ee4\uff0c\u5176\u4e2d add \u5c31\u662f\u5176\u4e2d\u8d1f\u8d23\u6574\u6570\u52a0\u6cd5\u8fd0\u7b97\u7684\u6307\u4ee4\uff0c\u4ed6\u63a5\u53d7\u4e24\u4e2a\u64cd\u4f5c\u6570\u505a\u53c2\u6570\u3002 add \u8868\u793a\u8fd9\u662f\u4e00\u6761\u52a0\u6cd5\u8fd0\u7b97\u6307\u4ee4\u3002 nsw \u662f\u4e00\u4e2a\u4fee\u9970\u7b26\uff0c\u53ef\u4ee5\u5148\u5ffd\u7565\u4e0d\u7ba1\u3002 i32 \u8868\u793a\u52a0\u6cd5\u64cd\u4f5c\u7684\u7c7b\u578b\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5728\u8fdb\u884c\u52a0\u6cd5\u524d\uff0c\u5fc5\u987b\u5148\u628a\u4e24\u8fb9\u7684\u6574\u6570\u7c7b\u578b\u8f6c\u6362\u5230\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u65e0\u6cd5\u76f8\u52a0\u3002 %3, %4 \u8868\u793a\u4e86\u52a0\u6cd5\u7684\u4e24\u4e2a\u64cd\u4f5c\u6570\uff0c\u8fd9\u4e24\u4e2a\u6570\u4f1a\u88ab\u52a0\u8d77\u6765\uff0c\u7ed3\u679c\u5b58\u5230 %5 \u5bc4\u5b58\u5668\u4e2d\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %5 = %3 + %4 \u3002 \u5728 Clang \u524d\u7aef\u4e2d\uff0c\u5982\u679c\u53d1\u73b0\u4e24\u8fb9\u7684\u7c7b\u578b\u5927\u5c0f\u4e0d\u540c\uff1a\u4f1a\u5148\u7528 sext \uff08\u6709\u7b26\u53f7\u6269\u5c55\uff09\u6216 zext \uff08\u65e0\u7b26\u53f7\u6269\u5c55\uff09\u6307\u4ee4\uff0c\u628a\u8f83\u5c0f\u90a3\u8fb9\u7684\u7c7b\u578b\uff0c\u8f6c\u6362\u5230\u4e24\u8005\u4e4b\u95f4\u6700\u5927\u7684\u90a3\u4e2a\u7c7b\u578b\u3002\u7136\u540e\u518d\u505a\u52a0\u6cd5\u3002\u5bf9\u4e8e\u6d6e\u70b9\u6570\u548c\u6574\u6570\u76f8\u52a0\u7684\u60c5\u51b5\uff0c\u5219\u662f\u5148\u628a\u6574\u6570\u8f6c\u6362\u4e3a\u6d6e\u70b9\u6570\u540e\u518d\u8c03\u7528\u6d6e\u70b9\u6570\u52a0\u6cd5 fadd \u3002\u603b\u4e4b\uff0cLLVM IR \u91cc\u6240\u6709\u7684\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\u90fd\u53d1\u751f\u5728\u76f8\u540c\u7c7b\u578b\u4e4b\u95f4\u3002 \u5bf9\u4e8e\u597d\u5947\u5b9d\u5b9d\uff1a nsw \u8868\u793a no signed wrap\uff0c\u610f\u601d\u662f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u8fd9\u4e2a\u662f\u6709\u7b26\u53f7\u52a0\u6cd5\uff0c\u5e76\u4e14\u4fdd\u8bc1\u4e0d\u4f1a\u6ea2\u51fa\u3002\u4e3a\u4ec0\u4e48\u4e0d\u4f1a\u6ea2\u51fa\uff1f\u56e0\u4e3a C++ \u6807\u51c6\u89c4\u5b9a\u201c\u6709\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u52a0\u6cd5\u5982\u679c\u53d1\u751f\u6ea2\u51fa\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u56de\u73af\uff08wrap\uff09\u201d\uff0c\u6240\u4ee5 Clang \u628a\u8fd9\u4e2a\u4fe1\u606f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u7528\u6237\u8fd9\u4e2a\u52a0\u6cd5\u5982\u679c\u6ea2\u51fa\u4e86\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cLLVM \u53ef\u4ee5\u5229\u7528\u8fd9\u4e00\u70b9\u6765\u4f18\u5316\uff01\u6362\u53e5\u8bdd\u8bf4\uff1a nsw \u8868\u793a\u5de6\u53f3\u4e24\u4e2a i32 \u4f5c\u4e3a\u6709\u7b26\u53f7\u6570\u76f8\u52a0\u5982\u679c\u6ea2\u51fa\u4f1a\u8fd4\u56de\u201c\u6bd2\u503c\u201d\u3002\u4f46\u662f C++ \u6807\u51c6\u53c8\u89c4\u5b9a\u65e0\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u6ea2\u51fa\u662f\u5fc5\u5b9a\u56de\u73af\uff0c\u4e0d\u4f1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6240\u4ee5\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b\u628a int \u66ff\u6362\u4e3a unsigned int \uff0c\u4f60\u4f1a\u53d1\u73b0 nsw \u6ca1\u4e86\uff0c\u56e0\u4e3a Clang \u77e5\u9053 C++ \u6807\u51c6\u5141\u8bb8 unsigned int \u52a0\u6cd5\u51fa\u73b0\u56de\u73af\u3002\u53e6\u5916\uff0c\u5982\u679c\u4f7f\u7528 Rust \u7684 i32 \u52a0\u6cd5\uff0c\u4e5f\u4f1a\u6ca1\u6709 nsw \uff0c\u56e0\u4e3a Rust \u6807\u51c6\u89c4\u5b9a\u6574\u6570\u65e0\u8bba\u6709\u6ca1\u6709\u7b26\u53f7\uff0c\u5176\u52a0\u6cd5\u6ea2\u51fa\u603b\u662f\u56de\u73af\uff0c\u4e0d\u4f1a\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u90a3\u4e48 LLVM \u540e\u7aef\u6536\u5230 Rust \u7f16\u8bd1\u5668\u4ea7\u751f\u7684 IR \u540e\uff0c\u5c31\u4e0d\u4f1a\u5047\u5b9a\u52a0\u6cd5\u4e0d\u4f1a\u6ea2\u51fa\u6765\u4f18\u5316\u4e86\u3002 \u8fd9\u6761\u6307\u4ee4\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 a + b \u8868\u8fbe\u5f0f\uff0c\u7528\u4e8e\u8ba1\u7b97\u4e24\u4e2a\u53d8\u91cf\u7684\u548c\uff0c\u8ba1\u7b97\u7ed3\u679c\u5b58\u5165 %5 \u5bc4\u5b58\u5668\u3002","title":"add \u6307\u4ee4"},{"location":"llvm_intro/#ret","text":"ret i32 %5 ret \u8868\u793a\u51fd\u6570\u8fd4\u56de\u3002\u901a\u5e38\u51fa\u73b0\u5728\u51fd\u6570\u7684\u672b\u5c3e\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return \u8bed\u53e5\u3002 \u5982\u679c\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \uff0c\u5219\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u8fd4\u56de\u503c\uff08\u4ee5\u5e38\u6570\u6216\u5bc4\u5b58\u5668\u7684\u5f62\u5f0f\uff09\u3002\u4f8b\u5982\u8fd9\u91cc\u6307\u5b9a\u7684 ret i32 %5 \u5c31\u8868\u793a\u51fd\u6570\u4f1a\u8fd4\u56de\u5bc4\u5b58\u5668 %5 \u7684\u503c\u3002 \u800c %5 \u5c31\u662f\u521a\u624d\u6211\u4eec add \u6307\u4ee4\u7684\u8fd0\u7b97\u7ed3\u679c\uff0c\u6240\u4ee5 ret \u548c add \u8fd9\u4e24\u6761\u6307\u4ee4\u5c31\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return a + b \u3002 \u548c store \u4e00\u6837\uff0c ret \u4e5f\u662f\u4e00\u6761\u65e0\u5bc4\u5b58\u5668\u5b9a\u4e49\u7684\u6307\u4ee4\u3002 \u901a\u5e38\u6765\u8bf4\u4f1a\u662f ret i32 0 \uff0c\u8868\u793a return 0 \u3002","title":"ret \u6307\u4ee4"},{"location":"llvm_intro/#attributes","text":"\u6ce8\u610f\u5230\u51fd\u6570\u5b9a\u4e49\u540e\u9762\u6709 attributes \u6307\u4ee4\uff1a define dso_local noundef i32 @main() #0 { ... } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } \u4f5c\u7528\u662f\u4e3a\u51fd\u6570\u8d4b\u4e88\u5c5e\u6027\u503c\uff0c\u5c5e\u6027\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\u540e\u8d4b\u4e88\u7684\uff0c\u7528 #0 \u6765\u5f15\u7528\u4e4b\u524d\u5b9a\u4e49\u7684\u51fd\u6570 main \u3002 \u683c\u5f0f\u4e3a attributes #\u51fd\u6570\u7f16\u53f7 = { \u5c5e\u6027\u5217\u8868... } \u5c5e\u6027\u5217\u8868\u53ef\u4ee5\u662f noinline \u8fd9\u6837\u7684\u5355\u6761\u5c5e\u6027\uff0c\u4e5f\u53ef\u4ee5\u662f\u5e26\u503c\u53c2\u6570\u7684\uff0c\u4f8b\u5982 \"target-cpu\"=\"x86-64\" \u3002 \u73b0\u5728\u6765\u89e3\u91ca\u5176\u4e2d\u91cd\u8981\u7684\u5c5e\u6027\uff1a mustprogress \u8868\u793a\u5fc5\u5b9a\u524d\u8fdb\u5047\u8bbe\uff0c\u8fd9\u662f C++ \u672a\u5b9a\u4e49\u884c\u4e3a\u89c4\u5b9a\u4e2d\u7684\u4e00\u6761\uff0c\u8981\u6c42\u7a0b\u5e8f\u4e00\u76f4\u5904\u4e8e\u201c\u8fdb\u5c55\u201d\u3002\u610f\u601d\u662f\u4e0d\u5f97\u51fa\u73b0\u65e0\u526f\u4f5c\u7528\u7684\u6b7b\u5faa\u73af\uff0c\u5426\u5219\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982 while (true) {} \u662f\u4e0d\u5141\u8bb8\u7684\uff1b\u4f46\u662f while (true) { volatile int i = 0; } \u5c31\u53ef\u4ee5\uff0c\u56e0\u4e3a volatile \u53d8\u91cf\u7684\u521d\u59cb\u5316\u88ab\u89c6\u4e3a\u526f\u4f5c\u7528\uff1b while (true) { cin >> i; } \u4e5f\u53ef\u4ee5\uff0c\u56e0\u4e3a cin \u5c5e\u4e8e IO \u64cd\u4f5c\uff0c\u662f\u6709\u5bf9\u5916\u754c\u73af\u5883\u9020\u6210\u526f\u4f5c\u7528\u7684\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 clang++ \u5f00\u7740\u4f18\u5316\u7f16\u8bd1 while (1); \u65f6\u4f1a\u4ea7\u751f\u53cd\u5e38\u7684\u6c47\u7f16\u7ed3\u679c\uff0c\u800c clang \u4e0d\u4f1a\u3002\u56e0\u4e3a\u53ea\u6709 C++ \u6807\u51c6\u8981\u6c42\u4e86\u201c\u5fc5\u5b9a\u524d\u8fdb\u201d\uff0c\u800c C \u6807\u51c6\u6ca1\u6709\u3002 C++ \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u524d\u8fdb\uff0c\u4f60\u4eec\u53ea\u80fd\u524d\u8fdb\uff0c\u4e0d\u62e9\u624b\u6bb5\u7684\u524d\u8fdb\uff08\u5b5d\u55b7\uff09 noinline \u6307\u5b9a\u4e86\u8be5\u51fd\u6570\u4e0d\u5f97\u88ab\u5185\u8054\u4f18\u5316\uff0c\u56e0\u4e3a\u6211\u4eec\u662f main \u51fd\u6570\uff0c\u662f\u6ce8\u5b9a\u4e0d\u80fd\u88ab\u5185\u8054\u7684\uff0c\u6240\u4ee5 Clang \u81ea\u52a8\u52a0\u4e0a\u4e86\u8fd9\u6761\u5c5e\u6027\u3002 optnone \u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5141\u8bb8\u4f18\u5316\u3002\u4e0d\u5f00\u542f\u4f18\u5316\uff08 -O0 \uff09\u65f6\uff0cClang \u4f1a\u81ea\u52a8\u4e3a\u6240\u6709\u51fd\u6570\u52a0\u4e0a optnone \u5c5e\u6027\u3002 LLVM \u4e2d\u7aef\u4e00\u65e6\u770b\u5230\u5e26\u6709 optnone \u5c5e\u6027\u7684\u51fd\u6570\uff0c\u4f1a\u8df3\u8fc7\u7edd\u5927\u90e8\u5206\u4f18\u5316 pass\u3002\u53ea\u4fdd\u7559\u6781\u5c11\u4e00\u90e8\u5206\u5fc5\u8981\u7684\u8f6c\u6362 pass\uff0c\u4f8b\u5982\u201c\u6307\u4ee4\u9009\u62e9\u201d\u548c\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u5c31\u4e0d\u4f1a\u88ab optnone \u5c4f\u853d\u3002\u6240\u4ee5\uff0cLLVM \u4e2d\u7aef\u4e2d\u4e00\u4e2a pass \u662f\u4f18\u5316\u6027\u8d28\u7684\u8fd8\u662f\u8f6c\u6362\u6027\u8d28\u7684\uff0c\u5c31\u53ef\u4ee5\u4ece\u4ed6\u662f\u5426\u4f1a\u88ab optnone \u5c4f\u853d\u770b\u51fa\u3002 \u53ea\u6709\u5168\u5c40\u5f00\u542f\u4e86 -O \u9009\u9879\u540e\uff0c\u6216\u662f\u4e3a\u5f53\u524d\u51fd\u6570\u6307\u5b9a\u4e86 __attribute__((optimize(\"-O\"))) \u8fd9\u4e00\u7279\u6b8a\u6269\u5c55\u8bed\u6cd5\u540e\uff0cClang \u624d\u4f1a\u53bb\u9664\u51fd\u6570\u7684 optnone \u5c5e\u6027\uff0c\u8ba9 LLVM \u4e2d\u7aef\u7684\u4f18\u5316 pass \u5f97\u4ee5\u5bf9\u8be5\u51fd\u6570\u751f\u6548\u3002","title":"\u4e3a\u51fd\u6570\u6307\u5b9a attributes"},{"location":"llvm_intro/#clang-ir","text":"\u6211\u4eec\u7f16\u5199\u4e00\u6bb5\u7b80\u5355\u7684 C++ \u201c\u4f60\u597d\uff0c\u4e16\u754c\u201d\u4ee3\u7801\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u6307\u5b9a -S -emit-llvm \u9009\u9879\uff0c\u5c31\u53ef\u4ee5\u8ba9 clang \u751f\u6210 IR \u6c47\u7f16\u4f9b\u4f60\u67e5\u770b\u4e86\uff08 -o \u53ef\u4ee5\u6307\u5b9a\u8f93\u51fa\u5230\u7684\u6587\u4ef6\u8def\u5f84\uff09\u3002 clang -S -emit-llvm a.cpp -o a.ll \u4ee5\u4e0b\u662f Clang \u89e3\u6790\u5f97\u5230\u7684 IR\uff08\u6c47\u7f16\u5f62\u5f0f\u6253\u5370\uff09\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 ; Function Attrs: mustprogress noinline norecurse optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } declare i32 @printf(ptr noundef, ...) #1 attributes #0 = { mustprogress noinline norecurse optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } attributes #1 = { \"frame-pointer\"=\"all\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u8fd8\u662f\u7167\u4f8b\u4ecb\u7ecd\u4e00\u4e0b\u65b0\u51fa\u73b0\u7684\u6307\u4ee4\uff1a","title":"Clang \u751f\u6210 IR \u6c47\u7f16"},{"location":"llvm_intro/#_21","text":"\u8fd9\u91cc\u7684 @.str \u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u3002 @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 \u6ce8\u610f\u5230\u4e86\u5417\uff1f\u5168\u5c40\u51fd\u6570\u548c\u53d8\u91cf\u90fd\u662f @ \u5f00\u5934\u7684\uff0c\u5c40\u90e8\u5bc4\u5b58\u5668\u90fd\u662f % \u5f00\u5934\u7684\uff0c\u51fd\u6570\u7f16\u53f7\u90fd\u662f # \u5f00\u5934\u7684\uff0c\u7f16\u8bd1\u671f\u4fe1\u606f\u90fd\u662f ! \u5f00\u5934\u7684\u3002 \u800c . \u5f00\u5934\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u533f\u540d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u4e0d\u5bf9\u5916\u53ef\u89c1\uff0c\u4f8b\u5982 @.str \u5e76\u4e0d\u4ee3\u8868\u771f\u7684\u6709\u4e00\u4e2a const char str[14] \uff0c\u53ea\u662f\u4e3a\u4e86\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u4e34\u65f6\u751f\u6210\u7684\u4e00\u4e2a\u533f\u540d\u5168\u5c40\u53d8\u91cf\u800c\u5df2\u3002 @.str \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u540d\u5b57\uff0c\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u5168\u5c40\u7684\u5b9a\u4e49\u90fd\u662f\u4ee5 @ \u5f00\u5934\u3002 private \u8868\u793a\u5bf9\u5916\u4e0d\u53ef\u89c1\uff0c\u662f\u4e00\u4e2a\u79c1\u6709\u53d8\u91cf\u3002 unnamed_addr \u8868\u793a\u8be5\u53d8\u91cf\u6ca1\u6709\u540d\u5b57\uff0c\u662f\u533f\u540d\u7684\u3002 constant \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u4e0d\u53ef\u4ee5\u88ab\u4fee\u6539\u3002 [14 x i8] \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u7c7b\u578b\uff0c [14 x i8] \u7684\u610f\u601d\u662f\u4e00\u4e2a\u957f\u5ea6\u4e3a 14 \u7684 i8 \u6570\u7ec4\uff0c\u7531 14 \u4e2a i8 \u7c7b\u578b\u7ec4\u6210\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 \u6570\u7ec4\u7c7b\u578b char [14] \u3002 c\"Hello, world!\\00\" \u8868\u793a\u8be5\u6570\u7ec4\u7684\u521d\u59cb\u5316\u503c\uff0c\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u3002 align 1 \u8868\u793a\u8be5\u5168\u5c40\u53d8\u91cf\u7684\u9996\u5730\u5740\u5bf9\u9f50\u5230 1 \u5b57\u8282\uff0c\u56e0\u4e3a\u8fd9\u662f\u4e00\u4e2a char \u6570\u7ec4\uff0c char \u53ea\u8981\u6c42\u5bf9\u9f50\u5230 1 \u5b57\u8282\u5373\u53ef\u3002 \u548c\u4e0d\u53c2\u4e0e\u7b26\u53f7\u94fe\u63a5\u7684\u5c40\u90e8\u5bc4\u5b58\u5668 % \u4e0d\u540c\uff0c\u5168\u5c40\u53d8\u91cf @ \u540e\u9762\u7684\u540d\u5b57\u5c31\u662f\u4ed6\u4eec\u5728\u94fe\u63a5\u65f6\u5bfc\u51fa\u7b26\u53f7\u7684\u540d\u5b57\u3002\u6240\u4ee5\u5168\u5c40\u53d8\u91cf\u5fc5\u987b\u662f\u6709\u540d\u5b57\u7684\uff0c\u4e0d\u80fd\u7528\u6570\u5b57\u5e8f\u53f7\u8868\u793a\u3002","title":"\u5b9a\u4e49\u5168\u5c40\u53d8\u91cf"},{"location":"llvm_intro/#linkage","text":"\u5982\u679c\u6211\u5b9a\u4e49\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf int i \u4f1a\u4ea7\u751f\u600e\u6837\u7684 IR\uff1f int i = 42; @i = dso_local global i32 42, align 4 align 4 \u662f\u56e0\u4e3a i \u662f int \u6216\u8005\u8bf4 i32 \u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309 C++ \u6807\u51c6\u8981\u6c42\u9700\u8981\u5bf9\u9f50\u5230 4 \u5b57\u8282\u3002 \u8fd9\u91cc global \u548c\u4e4b\u524d\u5e38\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 constant \u4e0d\u540c\uff0c\u8868\u793a\u662f\u53ef\u8bfb\u5199\u7684\u5168\u5c40\u53d8\u91cf\u3002 \u8fd9\u91cc\u7684 dso_local \u4fee\u9970\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u8868\u793a i \u4e3a\u5168\u5c40\u5bfc\u51fa\u7b26\u53f7\uff08ODR external linkage\uff09\u3002 C++ \u4ee3\u7801 LLVM IR \u4e2d\u7684\u4fee\u9970 C++ \u5f8b\u5e08\u672f\u8bed static int i @i = internal internal linkage inline int i @i = linkonce_odr dso_local non-ODR external linkage int i @i = dso_local ODR external linkage int i \uff08\u51fd\u6570\u5c40\u90e8\uff09 %1 %2 %3 \u2026 no linkage\uff0c\u4e0d\u9700\u8981\u77e5\u9053\u540d\u5b57 \u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\u3002","title":"\u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage"},{"location":"llvm_intro/#_22","text":"\u6ce8\u610f\uff0c\u5168\u5c40\u53d8\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 @i \u662f\u4e00\u4e2a\u5730\u5740\uff01\u5c31\u548c alloca \u5b9a\u4e49\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u662f\u6307\u5411\u6808\u4e0a\u5185\u5b58\u7684\u5730\u5740\u4e00\u6837\u3002 \u5982\u679c\u9700\u8981\u52a0\u8f7d\u5176\u4e2d\u7684\u503c\uff0c\u8fd8\u9700\u8981\u7528 load \u547d\u4ee4\u8bfb\u53d6\u5230\u51fd\u6570\u7684\u5c40\u90e8\u5bc4\u5b58\u5668\u4e2d\uff0c\u624d\u80fd\u5c06\u5176\u4e2d\u7684\u503c\u7528\u4e8e\u8fd4\u56de\u3002 static int i = 42; int main() { return i; // \u4f1a\u4ea7\u751f load @i \u6307\u4ee4 } @i = dso_local global i32 42, align 4 ; @i \u662f i32* \u7c7b\u578b define dso_local noundef i32 @main() #0 { %1 = load i32, ptr @i, align 4 ; load \u8bfb\u53d6\u8be5\u6307\u9488\u624d\u80fd\u8bfb\u5230 i \u53d8\u91cf\u7684\u503c ret i32 %1 ; %1 \u4e2d\u662f i \u53d8\u91cf\u7684\u503c } \u5982\u679c\u76f4\u63a5 ret i32 @i \u7684\u8bdd\uff0c\u5c31\u53d8\u6210 return &i \u7684\u6548\u679c\u4e86\u3002","title":"\u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740"},{"location":"llvm_intro/#call","text":"define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } TODO","title":"call \u8c03\u7528\u5176\u4ed6\u51fd\u6570"},{"location":"llvm_intro/#llvm-ir_2","text":"Clang \u7f16\u8bd1\u65f6\u662f\u4ec0\u4e48\u5e73\u53f0\u5c31\u662f\u4ec0\u4e48\u5e73\u53f0\u4e86\uff0c\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7684 IR \u4f1a\u6709\u4e9b\u5fae\u7684\u4e0d\u4e00\u6837\uff08\u7531\u4e8e\u4e00\u4e9b\u8f6f\u4ef6\u9700\u8981\u5229\u7528\u786c\u4ef6 intrinsics\uff09\u3002\u4e00\u4efd IR \u4ece\u751f\u6210\u5f00\u59cb\uff0c\u5c31\u6ce8\u5b9a\u6c38\u8fdc\u53ea\u80fd\u53d8\u6210\u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u3002 \u8fd9\u662f\u56e0\u4e3a\u867d\u7136 IR \u662f\u901a\u7528\u7684\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4f46\u7c7b\u578b\u5927\u5c0f\uff0c\u77e2\u91cf\u5bbd\u5ea6\u7b49\u4fe1\u606f\u548c\u786c\u4ef6\u9ad8\u5ea6\u7ed1\u5b9a\u3002 \u800c\u4e14\u6709\u65f6\u7528\u6237\u9700\u8981\u6839\u636e #ifdef __x86_64__ \u5224\u65ad\uff0c\u9488\u5bf9\u4e0d\u540c\u7684\u786c\u4ef6\uff0c\u4f7f\u7528\u4e0d\u540c\u7684 intrinsics\u3002 \u8fd9\u5bfc\u81f4\u5373\u4f7f\u662f\u540c\u4e00\u4efd .cpp \u6587\u4ef6\uff0c\u9488\u5bf9\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7f16\u8bd1\u7684\u4ea7\u751f\u7684 IR\uff0c\u4e5f\u5fc5\u7136\u662f\u4e0d\u540c\u7684\u3002 \u66f4\u4f55\u51b5 Windows \u548c Linux \u73af\u5883\u7684\u6807\u51c6\u5e93\u4e5f\u4e0d\u4e00\u6837\uff0c\u53ef\u80fd Windows \u7248\u7684\u7ffb\u8bd1\u5355\u5143\u5728\u4f1a\u6709\u4e00\u4e9b Windows \u7279\u6709\u51fd\u6570\u7684\u58f0\u660e\uff0c\u800c Linux \u4e0a\u7f16\u8bd1\u51fa\u6765\u5c31\u6ca1\u6709\u3002 \u603b\u4e4b\uff0c\u56e0\u4e3a\u8fd9\u6837\u90a3\u6837\u7684\u539f\u56e0\uff0cLLVM IR \u5e76\u4e0d\u652f\u6301\u8de8\u5e73\u53f0\u5171\u7528\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a Clang \u7f16\u8bd1\u51fa\u6765\u7684 IR \u6ce8\u5b9a\u662f\u4e0d\u540c\u7684\u3002 \u4e5f\u6709\u4e00\u4e9b\u652f\u6301\u8de8\u5e73\u53f0\u7684 IR\uff0c\u6bd4\u5982 SPIR-V \u548c MLIR\uff0c\u9002\u7528\u4e8e\u6e38\u620f\u5ba2\u6237\u7aef\u90e8\u7f72\u7684\u573a\u666f\u3002\u4f46\u663e\u7136 LLVM \u4f5c\u4e3a\u8ffd\u6c42\u6781\u81f4\u4f18\u5316\u7684\u88f8\u786c\u4ef6\u7f16\u8bd1\u5668\uff0c\u5176 LLVM IR \u5982\u679c\u8981\u6c42\u8de8\u5e73\u53f0\u4f1a\u5f88\u4e0d\u5229\u4e8e Clang \u524d\u7aef\u652f\u6301\u786c\u4ef6 intrinsics\uff0c\u4e5f\u4e0d\u5229\u4e8e LLVM \u4e2d\u7aef\u9488\u5bf9\u76ee\u6807\u786c\u4ef6\u7279\u6027\u505a\u4f18\u5316\uff0c\u4e5f\u4f1a\u65e0\u6cd5\u652f\u6301\u5185\u8054\u6c47\u7f16\uff0c\u6240\u4ee5\u5c31\u653e\u5f03\u4e86\u3002\u6240\u4ee5\u73b0\u5b9e\u4e2d\uff0c\u4eba\u4eec\u4f1a\u5148\u628a Vulkan \u7740\u8272\u5668\u7f16\u8bd1\u6210\u8de8\u5e73\u53f0\u7684 SPIR-V \u4e8c\u8fdb\u5236\u53d1\u5e03\uff0c\u7b49\u90e8\u7f72\u5230\u6e38\u620f\u73a9\u5bb6\u7535\u8111\u4e0a\u540e\uff0c\u7136\u540e\u518d\u8f93\u5165\u663e\u5361\u9a71\u52a8\u4e2d\u7684 LLVM \u5f97\u5230 LLVM IR \u540e\u4f18\u5316\uff0c\u7f16\u8bd1\u751f\u6210\u6700\u9002\u5408\u5f53\u524d\u73a9\u5bb6\u663e\u5361\u4f53\u8d28\u7684 GPU \u6c47\u7f16\u3002","title":"\u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0"},{"location":"llvm_intro/#ir_1","text":"\u4e0a\u9762\u4ecb\u7ecd\u7684 LLVM IR \u6c47\u7f16\uff0c\u662f\u4ee5\u6587\u672c\u5f62\u5f0f\u5b58\u50a8\u548c\u5904\u7406\uff0c\u867d\u7136\u65b9\u4fbf\u4e86\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\uff0c\u4f46\u5bf9\u7a0b\u5e8f\u800c\u8a00\u6548\u7387\u4e0d\u9ad8\u3002 \u56e0\u6b64 LLVM \u53c8\u53d1\u660e\u4e86\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u6765\u5b58\u50a8 IR\uff0c\u4e5f\u5c31\u662f\u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u53ef\u7b80\u5199\u4e3a BC\u3002 \u4ed6\u4eec\u662f \u5b8c\u5168\u7b49\u4ef7\u7684 \uff0c\u90fd\u662f IR \u7684\u4e24\u79cd\u8868\u73b0\u65b9\u5f0f\uff1a\u4e00\u4e2a\u662f\u6587\u672c\u683c\u5f0f\uff08\u9002\u5408\u4eba\u7c7b\u9605\u8bfb\uff09\uff0c\u4e00\u4e2a\u662f\u4e8c\u8fdb\u5236\u683c\u5f0f\uff08\u9002\u5408\u7a0b\u5e8f\u9605\u8bfb\uff09\u3002 IR \u5b57\u8282\u7801\u4e2d\u7684\u6bcf\u4e2a\uff08\u6216\u591a\u4e2a\uff09\u5b57\u8282\u90fd\u53ef\u4ee5\u548c IR \u6c47\u7f16\u4e2d\u7684\u4e00\u884c IR \u6307\u4ee4\u4e00\u4e00\u5bf9\u5e94\u3002","title":"IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801"},{"location":"llvm_intro/#ir-ir","text":"","title":"IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904"},{"location":"llvm_intro/#_23","text":"IR \u6c47\u7f16\uff1a .ll IR \u5b57\u8282\u7801: .bc","title":"\u540e\u7f00\u540d\u4e0d\u540c"},{"location":"llvm_intro/#_24","text":"Clang \u751f\u6210 IR \u6c47\u7f16\uff1a\u4f7f\u7528 -S -emit-llvm \u9009\u9879\u3002 clang -S -emit-llvm a.cpp -o a.ll Clang \u751f\u6210 IR \u5b57\u8282\u7801\uff1a\u4f7f\u7528 -c -emit-llvm \u9009\u9879\u3002 clang -c -emit-llvm a.cpp -o a.bc","title":"\u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c"},{"location":"llvm_intro/#_25","text":"IR \u6c47\u7f16: \u6587\u672c\u683c\u5f0f\uff08a.ll\uff09 ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 1, ptr %2, align 4 %3 = load i32, ptr %2, align 4 %4 = add nsw i32 %3, 1 ret i32 %4 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 17.0.6\"} IR \u5b57\u8282\u7801: \u4e8c\u8fdb\u5236\u683c\u5f0f\uff08a.bc\uff09 00000000 42 43 c0 de 35 14 00 00 05 00 00 00 62 0c 30 24 |BC..5.......b.0$| 00000010 4a 59 be 66 bd fb b4 af 0b 51 80 4c 01 00 00 00 |JY.f.....Q.L....| 00000020 21 0c 00 00 e1 01 00 00 0b 02 21 00 02 00 00 00 |!.........!.....| 00000030 16 00 00 00 07 81 23 91 41 c8 04 49 06 10 32 39 |......#.A..I..29| 00000040 92 01 84 0c 25 05 08 19 1e 04 8b 62 80 0c 45 02 |....%......b..E.| ... \u4ee5\u4e0a\u4e3a\u4f7f\u7528 hexdump \u5de5\u5177\u67e5\u770b\u7684\u5341\u516d\u8fdb\u5236\u5b57\u8282\u53ef\u89c6\u5316\u7ed3\u679c\u3002 .bc \u7684\u5b9e\u9645\u5185\u5bb9\u5b8c\u5168\u662f\u4e8c\u8fdb\u5236\uff0c\u76f4\u63a5 cat \u5230\u7ec8\u7aef\u4f1a\u4e71\u7801\u3002","title":"\u5185\u5bb9\u683c\u5f0f\u4e0d\u540c"},{"location":"llvm_intro/#_26","text":"IR \u6c47\u7f16\u5230 IR \u5b57\u8282\u7801\uff1a llvm-as \uff0c\u628a\u6587\u672c IR \u7f16\u8bd1\u6210\u7d27\u51d1\u538b\u7f29\u7684\u5b57\u8282\u7801\u3002 llvm-as test.ll -o test.bc IR \u5b57\u8282\u7801\u5230 IR \u6c47\u7f16\uff1a llvm-dis \uff0c\u628a\u5b57\u8282\u7801\u91cd\u65b0\u8f6c\u56de\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c IR\u3002 llvm-dis test.bc -o test.ll \u518d\u6b21\u63d0\u9192\uff1a\u8fd9\u4e9b\u662f LLVM \u5185\u90e8\u7684 IR \u7684\u4e24\u79cd\u5f62\u5f0f\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u6c47\u7f16\u548c\u673a\u5668\u7801\u3002","title":"\u4e4b\u95f4\u7684\u8f6c\u6362"},{"location":"llvm_intro/#_27","text":"IR \u5b57\u8282\u7801\u548c IR \u6c47\u7f16\u7684\u5173\u7cfb\uff0c\u6b63\u5982 x86 \u6c47\u7f16\u548c x86 \u673a\u5668\u7801\u7684\u5173\u7cfb\uff0c\u4e4b\u95f4\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb\u3002 IR \u5b57\u8282\u7801\u662f\u4e8c\u8fdb\u5236\u7684\uff0c\u5bf9\u8ba1\u7b97\u673a\u53cb\u597d\uff1b\u800c IR \u6c47\u7f16\u662f\u4eba\u7c7b\u53ef\u8bfb\u7684 ASCII \u5b57\u7b26\uff0c\u65b9\u4fbf\u4eba\u7c7b\u9605\u8bfb\u548c\u8c03\u8bd5\uff0c\u4ed6\u4eec\u672c\u8d28\u4e0a\u90fd\u662f IR\u3002 \u6c47\u7f16\u662f\u7ed9\u4eba\u770b\u7684\u6587\u672c\u6587\u4ef6\uff0c\u673a\u5668\u7801\u662f\u7ed9 CPU \u770b\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\uff1b\u540c\u6837\u5730\uff0cIR \u6c47\u7f16\u662f IR \u7684\u6587\u672c\u683c\u5f0f\uff0c\u662f\u6253\u5370\u7ed9\u4eba\u770b\u7684\uff1b\u800c IR \u5b57\u8282\u7801\u662f\u7ed9 LLVM \u7f16\u8bd1\u5668\u770b\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f IR\uff0c\u89e3\u6790\u8d77\u6765\u66f4\u5feb\uff0c\u4e5f\u8282\u7ea6\u5185\u5b58\u3002 \u4e0d\u8fc7\uff0c\u8981\u6ce8\u610f\u5b57\u8282\u7801\u548c\u673a\u5668\u7801\u4e0d\u540c\uff0c\u4ed6\u4f9d\u7136\u5c5e\u4e8e\u4e2d\u95f4\u8868\u793a\uff08\u53ea\u4e0d\u8fc7\u662f\u538b\u7f29\u5f97\u4eba\u7c7b\u770b\u4e0d\u61c2\u7684\u9ad8\u6548\u4e8c\u8fdb\u5236\u7248 IR\uff09\uff0c\u5e76\u4e0d\u80fd\u76f4\u63a5\u5728\u8ba1\u7b97\u673a\u4e2d\u6267\u884c\uff0cLLVM \u5b57\u8282\u7801\u53ea\u80fd\u5728 lli \u865a\u62df\u673a\u4e2d\u89e3\u91ca\u6267\u884c\uff0c\u6216\u8005\u901a\u8fc7 llc \u7f16\u8bd1\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u540e\u5728\u76ee\u6807\u5e73\u53f0\u88f8\u673a\u6267\u884c\u3002 \u4f46\u548c Java \u7684\u5b57\u8282\u7801\u53c8\u4e0d\u4e00\u6837\uff0cLLVM \u7684\u5b57\u8282\u7801\u672c\u6765\u5c31\u662f\u4e8c\u8fdb\u5236\u7684 IR\u3002\u800c IR \u5e76\u4e0d\u8de8\u5e73\u53f0\uff0c\u6240\u4ee5\u5b57\u8282\u7801\u4e5f\u4e0d\u8de8\u5e73\u53f0\u3002LLVM \u56e2\u961f\u63d0\u4f9b lli \u5de5\u5177\u4e3b\u8981\u662f\u4e3a\u4e86\u65b9\u4fbf\u4e34\u65f6\u6d4b\u8bd5 IR\uff0c\u7528\u4e8e\u751f\u4ea7\u73af\u5883\u7684\u80af\u5b9a\u8fd8\u662f llc \u7f16\u8bd1\u597d\u4ea7\u751f\u771f\u6b63\u7684\u9ad8\u6548\u673a\u5668\u7801\u3002","title":"\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb"},{"location":"llvm_intro/#_28","text":"\u5f97\u5230\u7684 .bc \u5b57\u8282\u7801\u6587\u4ef6\u4e5f\u88ab\u79f0\u4e3a\u4e00\u4e2a\u6a21\u5757\uff08Module\uff09\uff0c\u6a21\u5757\u7531\u4e00\u7cfb\u5217 IR \u9636\u6bb5\u7684\u7ec4\u6210\uff1b\u6b63\u5982\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7531\u5927\u91cf\u6c47\u7f16\u6307\u4ee4\u7ec4\u6210\u4e00\u6837\u3002 \u8fd9\u91cc\u8bf4\u7684 LLVM \u6a21\u5757\u548c C++20 \u7684 Modules \u7279\u6027\u5173\u7cfb\u4e0d\u5927\uff0c\u6a21\u5757\u662f LLVM \u5f88\u65e9\u5c31\u6709\u7684\u6982\u5ff5\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u4e00\u4e2a .cpp \u6587\u4ef6\u7f16\u8bd1\u53ef\u4ee5\u4ea7\u751f IR \u6c47\u7f16\uff08.ll\uff09\uff0cIR \u6c47\u7f16\u53ef\u4ee5\u901a\u8fc7 llvm-as \u7f16\u8bd1\u5f97\u5230\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09\u3002\u56e0\u6b64\u53ef\u4ee5\u7c97\u7565\u7684\u8ba4\u4e3a\uff0c \u4e00\u4e2a\u6e90\u6587\u4ef6\uff08.cpp\uff09\u7f16\u8bd1\u540e\u5c31\u662f\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09 \u3002 \u800c LLVM \u6a21\u5757\uff08.bc\uff09\u53ef\u4ee5\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210\u901a\u7528\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\uff0c\u4ece\u800c\u5c31\u662f\u6211\u4eec\u770b\u5230\u7684\uff1a\u4e00\u4e2a .cpp \u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a .o \u6587\u4ef6\u4e86\u3002 \u6a21\u5757\u4e2d\u5305\u542b\u4e86\u4e4b\u524d\u4ecb\u7ecd\u7684 IR \u6c47\u7f16\u4e2d\u6240\u6709\u7684\u4fe1\u606f\uff0c\u4f8b\u5982\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u5e03\u5c40\u4fe1\u606f\uff0c\u5168\u5c40\u53d8\u91cf\uff0c\u7c7b\u578b\u58f0\u660e\uff0c\u51fd\u6570\u5b9a\u4e49\u548c\u58f0\u660e\u7b49\u3002","title":"\u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757"},{"location":"llvm_intro/#_29","text":"\u5b57\u8282\u7801\uff08.bc\uff09\u662f LLVM \u5185\u90e8\u7684\u6587\u4ef6\u683c\u5f0f\uff0c\u4e0d\u901a\u7528\u3002\u4f46\u7531\u4e8e\u5176\u76f4\u63a5\u5b58\u50a8 IR\uff0c\u65b9\u4fbf LLVM \u5904\u7406\u548c\u4f18\u5316\uff0c\u4e14\u53ef\u4ee5\u5f88\u5bb9\u6613\u901a\u8fc7 llvm-dis \u53cd\u6c47\u7f16\u6210\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\u6765\u67e5\u770b\uff08.ll\uff09\u3002\u901a\u5e38\u7528\u4e8e\u8c03\u8bd5 LLVM\uff0c\u4ee5\u53ca\u76ee\u6807\u5e73\u53f0\u4e0d\u662f CPU \u7684\u60c5\u51b5\uff08\u4f8b\u5982 CUDA PTX\uff09\u3002 \u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u662f\u7c7b Unix \u5e73\u53f0\u901a\u7528\u7684 ELF \u683c\u5f0f\uff08\u5728 Windows \u5e73\u53f0\u5219\u662f .obj \u6587\u4ef6\uff0cCOFF \u683c\u5f0f\uff09\uff0c\u5176\u4ed6\u652f\u6301 ELF \u7684\u7f16\u8bd1\u5668\u548c\u94fe\u63a5\u5668\u4e5f\u53ef\u4ee5\u4f7f\u7528\u3002\u4f8b\u5982 GCC \u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e5f\u53ef\u4ee5\u540c LLVM \u7f16\u8bd1\u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e00\u8d77\u94fe\u63a5\uff0c\u800c\u5982\u679c\u662f .bc \u683c\u5f0f GCC \u5c31\u8ba4\u4e0d\u51fa\u6765\u3002\u7f3a\u70b9\u662f\u4e00\u65e6\u7f16\u8bd1\u6210 .o \u6587\u4ef6\uff0c\u5c31\u65e0\u6cd5\u518d\u53cd\u63a8\u51fa IR \u4e86\uff0c\u53ea\u80fd\u901a\u8fc7 objdump \u53cd\u6c47\u7f16\u5f97\u5230\u6c47\u7f16\u4ee3\u7801\uff0c\u5c31\u4e0d\u65b9\u4fbf LLVM \u518d\u5904\u7406\u548c\u4f18\u5316\u4e86\u3002","title":"\u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b"},{"location":"llvm_intro/#llvm_6","text":"\u603b\u4e4b\u5728 LLVM / Clang \u5de5\u4f5c\u6d41\u4e2d\uff0c\u53ef\u4ee5\u7c97\u7565\u8ba4\u4e3a\uff0c\u4e00\u4e2a .cpp \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u4e5f\u6709\u4e00\u4e9b\u65f6\u5019\uff0c\u6211\u4eec\u7f16\u8bd1\u6a21\u5757\u7684\u76ee\u6807\u5e76\u4e0d\u662f CPU\uff0c\u4f8b\u5982 Taichi \u9879\u76ee\u4e2d\uff0c\u5c31\u662f\u901a\u8fc7 LLVM \u91cd\u65b0\u7f16\u8bd1 Python \u5b57\u8282\u7801\uff0c\u751f\u6210 .bc \u6a21\u5757\uff0c\u7136\u540e\u7f16\u8bd1\u4ea7\u751f PTX \u6c47\u7f16\uff0c\u8f6c\u5316\u4e3a CUBIN \u4e8c\u8fdb\u5236\u540e\uff0c\u63d0\u4ea4\u5230 CUDA \u9a71\u52a8\u4e2d\u6267\u884c\uff08\u5b9e\u9645\u4e0a\u6b64\u5904\u8fd8\u4f1a\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210 SASS \u6c47\u7f16\uff09\u3002 \u5728 LLVM / Clang CUDA \u5de5\u4f5c\u6d41\u4e2d\uff0c\u4e00\u4e2a .cu \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u5c0f\u5f6d\u8001\u5e08\u7ed8\u5236\u4e00\u526f\u4e16\u754c\u540d\u753b\u300aIntel \u8d4b\u80fd AI \u7f16\u8bd1\u5668\u300b\uff0c\u540c\u5b66\u95ee\uff0c\u6211\u53ea\u770b\u5230\u6309\u6469\u5e97\u548c\u6deb\u5a01\u5927\uff0c\u6a31\u7279\u5c14\u5728\u54ea\u5462\uff1f\u7b54\uff1a\u6a31\u7279\u5c14\u5728\u8d4b\u80fd\u3002 \u8fd9\u91cc\u7684 cubin \u5176\u5b9e\u5c31\u662f\u5e38\u542c\u5230\u7684 fatbin\uff0c\u4e8c\u8fdb\u5236\u7248\u7684 PTX \u6c47\u7f16\uff0cNVCC \u7684\u6d41\u7a0b\u4e5f\u548c\u8fd9\u4e2a\u5dee\u4e0d\u591a\u3002","title":"LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe"},{"location":"llvm_intro/#_30","text":"\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\uff08.bc\uff09\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u94fe\u63a5\uff0c\u5f62\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6a21\u5757\uff0c\u5176\u4e2d\u5305\u542b\u6240\u6709\u5b50\u6a21\u5757\u7684\u5185\u5bb9\u3002 llvm-link test1.bc test2.bc -o test.bc \u901a\u8fc7\u94fe\u63a5\uff0c\u53ef\u4ee5\u628a\u591a\u4e2a\u6a21\u5757\u7684 IR \u5408\u5e76\u5230\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u65b9\u4fbf\u540e\u7eed\u4f18\u5316\u548c\u7f16\u8bd1\u3002 \u6ce8\u610f\uff01\u8fd9\u91cc\u7684 IR \u94fe\u63a5\uff08llvm-link\uff09\u53ea\u662f LLVM \u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\u7684\u4e00\u4e2a\u5c0f\u8fc7\u7a0b\uff0c\u548c\u6c47\u7f16\u9636\u6bb5\u540e\u751f\u6210\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7684\u771f\u6b63\u94fe\u63a5\uff08lld\uff09\u4e0d\u540c\u3002\u8fd9\u91cc\u53ea\u662f\u628a\u591a\u4e2a LLM \u6a21\u5757\u5408\u5e76\u6210\u4e00\u4e2a\u6a21\u5757\u800c\u5df2\uff0c\u6700\u540e\u8fd9\u4e2a\u603b\u6a21\u5757\u7f16\u8bd1\u4f9d\u7136\u662f\u5f97\u5230\u5355\u4e2a .o \u6587\u4ef6\uff0c\u8fd8\u662f\u8981\u7ecf\u8fc7\u771f\u6b63\u7684\u94fe\u63a5\u5668\uff08lld\uff09\uff0c\u4e0e\u5176\u4ed6 .o \u6587\u4ef6\u94fe\u63a5\u624d\u80fd\u5f62\u6210\u6700\u7ec8\u53ef\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 \u628a C++ \u6587\u4ef6\u7f16\u8bd1\u751f\u6210\u7684\u5b57\u8282\u7801\u6a21\u5757\u94fe\u63a5\u8d77\u6765\uff0c\u5c31\u50cf\u5f88\u591a\u4e2a C++ \u6587\u4ef6\u7a81\u7136\u56fd\u5b9d\u7279\u5de5\u5408\u4f53\u4e00\u6837\u3002","title":"\u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5"},{"location":"llvm_intro/#llvm-pass","text":"LLVM \u63d0\u4f9b\u4e86 opt \u8fd9\u4e2a\u65b9\u4fbf\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u53ef\u4ee5\u8c03\u7528 LLVM \u4e2d\u6307\u5b9a\u540d\u79f0\u7684\u4f18\u5316\u7c7b pass\uff0c\u7528\u6765\u4f18\u5316\u4f20\u5165\u7684 IR \u6587\u4ef6\uff08\u53ef\u4ee5\u662f IR \u6c47\u7f16\u6216 IR \u5b57\u8282\u7801\uff09\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8f93\u51fa\u7684\u662f\u4e8c\u8fdb\u5236\u7684 IR \u5b57\u8282\u7801\uff0c\u5982\u9700\u8f93\u51fa\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\uff0c\u53ef\u4ee5\u6307\u5b9a -S \u9009\u9879\uff08\u5c31\u548c\u521a\u624d\u6211\u4eec\u4f7f\u7528 clang -S \u8ba9 -emit-llvm \u751f\u6210 IR \u6c47\u7f16\u800c\u4e0d\u662f IR \u5b57\u8282\u7801\u4e00\u6837\uff09\u3002 # \u8f93\u5165 a.ll\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.ll\uff08IR \u6c47\u7f16\uff09 opt -S -p mem2reg a.ll -o a-opt.ll cat a-opt.ll # \u8f93\u5165 a.bc\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.bc\uff08IR \u5b57\u8282\u7801\uff09 opt -p mem2reg a.bc -o a-opt.bc llvm-dis a-opt.bc -o a-opt.ll # \u5982\u679c\u8f93\u51fa\u5b57\u8282\u7801\u683c\u5f0f\uff0c\u8fd8\u9700\u8981 llvm-dis \u624d\u80fd\u8ba9\u4eba\u7c7b\u770b\u61c2","title":"\u8c03\u7528 LLVM pass \u4f18\u5316"},{"location":"llvm_intro/#_31","text":"\u8fd8\u662f\u8fd9\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u4f7f\u7528 clang \u7f16\u8bd1\uff0c\u751f\u6210 IR \u6c47\u7f16\uff1a clang -S -emit-llvm a.cpp -o a.ll \u5f97\u5230 a.ll\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 0, ptr %2, align 4 store i32 1, ptr %3, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %4, 1 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u73b0\u5728\uff0c\u6211\u4eec\u7528 opt \u5de5\u5177\u5bf9\u5176\u8fdb\u884c\u4f18\u5316\uff1a TODO","title":"\u6848\u4f8b"},{"location":"llvm_intro/#_32","text":"","title":"\u57fa\u672c\u5757\u4e0e\u5206\u652f"},{"location":"llvm_intro/#asm","text":"","title":"\u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09"},{"location":"llvm_intro/#_33","text":"","title":"\u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801"},{"location":"llvm_intro/#_34","text":"","title":"\u6784\u5efa\u597d\u4e86\u5417"},{"location":"no_more_new/","text":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb \u4f7f\u7528 new \u548c delete \u662f\u4e00\u79cd\u8fc7\u65f6\u7684\u5185\u5b58\u7ba1\u7406\u65b9\u5f0f\uff0c\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u60ac\u7a7a\u6307\u9488\uff0c\u5e94\u5f53\u6c38\u4e0d\u4f7f\u7528\u3002 \u4f18\u79c0\u7684\u73b0\u4ee3 C++ \u9879\u76ee\uff0c\u90fd\u4f7f\u7528 \u667a\u80fd\u6307\u9488 \u548c \u5bb9\u5668 \u7ba1\u7406\u5185\u5b58\uff0c\u4ece\u6765\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efa\u539f\u59cb\u6307\u9488\u3002 \u4e0b\u5217\u4e09\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 new \u548c delete\uff1a \u4f60\u5728\u5c01\u88c5\u4e00\u4e2a\u975e\u5e38\u5e95\u5c42\u7684\u5185\u5b58\u5206\u914d\u5668\u5e93\u3002 \u4f60\u662f C++98 \u7528\u6237\uff0c\u4e14\u4f60\u7684\u8001\u677f\u4e0d\u5141\u8bb8\u4f7f\u7528 boost\uff08\u5176\u63d0\u4f9b\u4e86\u667a\u80fd\u6307\u9488\uff09\u3002 \u4f60\u60f3\u8981\u521b\u9020\u4e00\u4e9b\u5185\u5b58\u6cc4\u6f0f\u6765\u60e9\u7f5a\u62d6\u6b20\u5de5\u8d44\u7684\u8111\u677f\u3002 \u540c\u7406\uff0cmalloc \u548c free \u4e5f\u662f\u4e0d\u5141\u8bb8\u7684\u3002 \u4e0d\u4ec5 new \u4e0d\u5e94\u8be5\u51fa\u73b0\uff0c\u539f\u59cb\u6307\u9488\u4e5f\u5e94\u8be5\u5c11\u51fa\u73b0\uff0c\u800c\u662f\u66f4\u5b89\u5168\uff0c\u7528\u6cd5\u66f4\u5355\u4e00\u7684 \u5f15\u7528 \u6216 span \u4ee3\u66ff\u3002 \u7528\u6cd5\u66f4\u5355\u4e00\u4e3a\u4ec0\u4e48\u662f\u597d\u4e8b\uff1f\u8bf7\u770b \u5f3a\u7c7b\u578b API \u8bbe\u8ba1\u4e13\u9898\u7ae0 \u3002 \u6848\u4f8b 1 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; } \u8d34\u58eb 1.1 \u6211\u4e00\u822c\u4f1a\u7528\u66f4\u76f4\u89c2\u7684 auto \u5199\u6cd5\uff0c\u8fd9\u6837\u66f4\u80fd\u660e\u786e\u8fd9\u662f\u5728\u521b\u5efa\u4e00\u4e2a vector \u5bf9\u8c61\uff0c\u7136\u540e\u4fdd\u5b58\u5230 mem \u8fd9\u4e2a\u53d8\u91cf\u540d\u4e2d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size()); \u8fd9\u88ab\u79f0\u4e3a auto-idiom\uff1a\u59cb\u7ec8\u4f7f\u7528 auto \u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6c38\u8fdc\u522b\u4f7f\u7528\u53ef\u80fd\u5f15\u53d1\u6b67\u4e49\u7684\u7c7b\u578b\u524d\u7f6e\u3002 \u8d34\u58eb 1.2 \u6709\u7684\u540c\u5b66\u4f1a\u60f3\u5f53\u7136\u5730\u63d0\u51fa\uff0c\u7528\u667a\u80fd\u6307\u9488\u4ee3\u66ff new\u3002 auto mem = make_shared(1024); read(1, mem.get(), 1024); \u53ef new \u7684\u66ff\u4ee3\u54c1\u4ece\u6765\u4e0d\u53ea\u6709\u667a\u80fd\u6307\u9488\u4e00\u4e2a\uff0c\u4e5f\u53ef\u4ee5\u662f vector \u5bb9\u5668\uff01 \u667a\u80fd\u6307\u9488\u53ea\u4f1a\u7528\u4e8e \u5355\u4e2a\u5bf9\u8c61 \uff01 \u52a8\u6001\u957f\u5ea6\u7684\u6570\u7ec4 \uff0c\u6b63\u5e38\u4eba\u90fd\u662f\u7528 vector \u7ba1\u7406\u7684\u3002 \u5f88\u591a\u52a3\u8d28\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u6750\u201d \u90fd\u5ffd\u7565\u4e86\u8fd9\u4e00\u70b9\uff0c\u603b\u662f\u523b\u610f\u5938\u5927\u4e86\u667a\u80fd\u6307\u9488\u7684\u8986\u76d6\u8303\u56f4\uff0c\u4e3a\u4e86\u65b0\u800c\u65b0\uff0c\u800c\u5bf9\u5b9e\u9645\u4e0a\u66f4\u9002\u5408\u7ba1\u7406 \u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4 \u7684 vector \u53ea\u5b57\u4e0d\u63d0\u3002 vector \u7ba1\u7406\u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4\u7684\u4f18\u52bf\uff1a \u4f60\u53ef\u4ee5\u968f\u65f6\u968f\u5730 resize \u548c push_back\uff0c\u52a0\u5165\u65b0\u5143\u7d20\uff0c\u800c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\u8981\u91cd\u65b0\u8c03\u6574\u5927\u5c0f\u5c31\u6bd4\u8f83\u56f0\u96be\u3002 vector \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6df1\u62f7\u8d1d\uff0c\u7b26\u5408 C++ \u5bb9\u5668\u7684\u4e00\u822c\u7ea6\u5b9a\u3002\u800c unique_ptr \u5b8c\u5168\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u6df1\u62f7\u8d1d\u9700\u8981\u989d\u5916\u7684\u4ee3\u7801\uff0cshared_ptr \u5219\u662f\u6d45\u62f7\u8d1d\uff0c\u6709\u65f6\u4f1a\u5bfc\u81f4\u6570\u636e\u8986\u76d6\u3002 \u5176\u5b9e shared_ptr \u4e5f\u4e0d\u662f\u4e0d\u53ef\u4ee5\u7528\uff0c\u7136\u800c\uff0c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\uff0c\u5e76\u4e0d\u80fd\u65b9\u4fbf\u5730\u901a\u8fc7 .size() \u83b7\u53d6\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5fc5\u987b\u7528\u53e6\u4e00\u4e2a\u53d8\u91cf\u5355\u72ec\u5b58\u50a8\u8fd9\u4e2a\u957f\u5ea6\u3002\u8fd9\u5c31\u8fdd\u80cc\u4e86\u5c01\u88c5\u539f\u5219\uff0c\u90a3\u4f1a\u4f7f\u4f60\u7684\u4ee3\u7801\u53d8\u5f97\u4e0d\u53ef\u7ef4\u62a4\u3002 \u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u53ef\u7ef4\u62a4\u6027\u603b\u662f\u6bd4\u6027\u80fd\u91cd\u8981\u7684\uff0c\u4f60\u53ea\u9700\u8981\u6bd4\u8f83 \u4f60\u91cd\u6784\u4ee3\u7801\u82b1\u7684\u65f6\u95f4 \u548c \u8ba1\u7b97\u673a\u8fd0\u884c\u8fd9\u6bb5\u4ee3\u7801\u6240\u9700\u65f6\u95f4 \u5c31\u660e\u767d\u503c\u4e0d\u503c\u4e86\u3002 \u8d34\u58eb 1.3 \u5982\u679c\u662f\u5176\u4ed6\u7c7b\u578b\uff0c\u53ef\u80fd\u9700\u8981\u4e58\u4ee5 sizeof(\u5143\u7d20\u7c7b\u578b) \uff0c\u53d6\u51b3\u4e8e\u90a3\u4e2a C \u51fd\u6570\u8981\u6c42\u7684\u662f\u201c\u5b57\u8282\u6570\u201d\u8fd8\u662f\u201c\u5143\u7d20\u6570\u201d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size() * sizeof(mem[0])); auto max = find_max(mem.data(), mem.size()); \u8d34\u58eb 1.4 \u5bf9\u4e8e\u4f60\u81ea\u5df1\u7684 C++ \u51fd\u6570\uff0c\u5c31\u6ca1\u5fc5\u8981\u518d\u63d0\u4f9b TODO: span, gsl::span, boost::span \u6848\u4f8b 2 \u540c\u5b66\uff1a\u6211\u9700\u8981\u5728\u201c\u5806\u201d\u4e0a\u5206\u914d\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u4ed6\u6301\u4e45\u5b58\u5728\u3002\u4f60\u4e0d\u8ba9\u6211\u7528 new\uff0c\u6211\u53ea\u80fd\u5728\u201c\u6808\u201d\u4e0a\u521b\u5efa\u4e34\u65f6\u5bf9\u8c61\u4e86\uff0c\u5982\u679c\u8981\u8fd4\u56de\u6216\u5b58\u8d77\u6765\u7684\u8bdd\u6839\u672c\u7528\u4e0d\u4e86\u554a\u3002 Foo *hello() { Foo *foo = new Foo(); return foo; } \u5c0f\u5f6d\u8001\u5e08\uff1a\u4f60\u53ef\u4ee5\u4f7f\u7528\u667a\u80fd\u6307\u9488\uff0c\u6700\u9002\u5408\u65b0\u4eba\u4e0a\u624b\u7684\u667a\u80fd\u6307\u9488\u662f shared_ptr\u3002 \u5f53\u6ca1\u6709\u4efb\u4f55\u51fd\u6570\u6216\u5bf9\u8c61\u6301\u6709\u8be5 shared_ptr \u6307\u5411\u7684\u5bf9\u8c61\u65f6\uff0c\u4e5f\u5c31\u662f\u5f53\u8c03\u7528\u8005\u5b58\u50a8 hello() \u8fd4\u56de\u503c\u7684\u51fd\u6570\u4f53\u9000\u51fa\u65f6\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u88ab\u81ea\u52a8\u91ca\u653e\u3002 shared_ptr hello() { shared_ptr foo = make_shared(); return foo; } \u603b\u4e4b\uff0c\u8fd9\u6837\u66ff\u6362\u4f60\u7684\u4ee3\u7801\uff1a T * \u6362\u6210 shared_ptr new T(...) \u6362\u6210 make_shared(...) \u4f60\u7684\u4ee3\u7801\u5c31\u57fa\u672c\u4e0a\u5b89\u5168\u4e86\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8 delete \u4e86\u3002 \u6709\u4e2a\u7528\u4e86 shared_ptr \u8fd8\u4f1a\u5185\u5b58\u6cc4\u6f0f\u7684\u8fb9\u7f18\u60c5\u51b5\uff1a\u5faa\u73af\u5f15\u7528\uff0c\u901a\u5e38\u662f\u5b9e\u73b0\u53cc\u5411\u94fe\u8868\u65f6\uff0cweak_ptr \u53ef\u4ee5\u89e3\u51b3\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 \u8d34\u58eb 2.1 unique_ptr \u548c shared_ptr \u6709\u4ec0\u4e48\u533a\u522b\uff1f\u521d\u5b66\u8005\u5e94\u8be5\u5148\u5b66\u54ea\u4e2a\uff1f unique_ptr \u662f\u72ec\u5360\u6240\u6709\u6743\uff0c\u4ed6\u7684\u9650\u5236\u66f4\u591a\uff0c\u6bd4\u5982\uff1a \u4e0d\u5141\u8bb8\u62f7\u8d1d\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u3002 \u4e0d\u5141\u8bb8\u8d4b\u503c\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u8d4b\u503c\u3002 \u7528 unique_ptr \u4e3b\u8981\u662f\u51fa\u4e8e\u6027\u80fd\u4f18\u52bf\u3002 \u7136\u800c\u6027\u80fd\u603b\u662f\u4e0d\u5982\u5b89\u5168\u91cd\u8981\u7684\uff0c\u4f60\u662f\u60f3\u8981 \u4e00\u4e2a\u9020\u5728\u706b\u661f\u7684\u8c6a\u534e\u5bab\u6bbf\uff0c\u8fd8\u662f\u4e00\u4e2a\u5730\u7403\u7684\u5b89\u5168\u8001\u5bb6\uff1f \u6240\u4ee5\uff0c\u5efa\u8bae\u4f60\u5148\u5168\u90e8\u66ff\u6362\u6210\u6cdb\u7528\u6027\u5f3a\u3001\u6613\u7528\u7684 shared_ptr\u3002\u7b49\u786e\u5b9e\u51fa\u73b0\u6027\u80fd\u74f6\u9888\u65f6\uff0c\u518d\u5bf9\u74f6\u9888\u90e8\u5206\u5355\u72ec\u8c03\u8bd5\u4f18\u5316\u4e5f\u4e0d\u8fdf\u3002 \u5148\u628a\u8001\u5bb6\u9020\u597d\u4e86\uff0c\u7136\u540e\u518d\u60f3\u529e\u6cd5\u79fb\u6c11\u706b\u661f\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u8d34\u58eb 2.2 \u6709\u4e9b\u8001\u5f0f\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u7a0b\u201d \u4e2d\uff0c\u4f1a\u770b\u5230\u8fd9\u6837 new \u4e0e\u667a\u80fd\u6307\u9488\u5e76\u7528\u7684\u5199\u6cd5\uff1a shared_ptr foo(new Foo()); \u4ece C++14 \u5f00\u59cb\uff0c\u8fd9\u5df2\u7ecf\u662f \u8fc7\u65f6\u7684 \uff01\u5177\u6709\u5b89\u5168\u9690\u60a3\uff08\u5982\u679c\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u51fa\u5f02\u5e38\uff09\uff0c\u4e14\u5199\u8d77\u6765\u4e5f\u4e0d\u591f\u76f4\u89c2\u3002 \u73b0\u5728\u4eba\u4eec\u4e00\u822c\u90fd\u4f1a\u7528 make_shared \u51fd\u6570\uff0c\u5176\u5185\u90e8\u5c01\u88c5\u4e0d\u4ec5\u4fdd\u8bc1\u4e86\u5f02\u5e38\u5b89\u5168\uff0c\u800c\u4e14\u4f1a\u4f7f shared_ptr \u7684\u63a7\u5236\u5757\u4e0e Foo \u5bf9\u8c61\u524d\u540e\u7d27\u6328\u7740\uff0c\u53ea\u9700\u4e00\u6b21\u5185\u5b58\u5206\u914d\uff0c\u4e0d\u4ec5\u66f4\u76f4\u89c2\uff0c\u8fd8\u63d0\u5347\u4e86\u6027\u80fd\u3002 auto foo = make_shared(); \u6709\u8da3\u7684\u662f\uff0cmake_shared \u5728 C++11 \u5c31\u5f15\u5165\u4e86\uff0cmake_unique \u5374\u76f4\u5230 C++14 \u624d\u5f15\u5165\u3002 \u4ece C++14 \u5f00\u59cb\uff0c\u5185\u5b58\u5b89\u5168\u7684\u73b0\u4ee3 C++ \u7a0b\u5e8f\u4e2d\u5c31\u4e0d\u4f1a\u51fa\u73b0\u4efb\u4f55\u663e\u5f0f\u7684 new \u4e86\uff0c\u54ea\u6015\u662f\u5305\u5728 shared_ptr \u6216 unique_ptr \u5185\u7684\u4e5f\u4e0d\u884c\u3002\uff08\u9664\u4e86\u6700\u4e0a\u9762\u8bf4\u7684 3 \u79cd\u7279\u6b8a\u60c5\u51b5\uff09 \u8d34\u58eb 2.3 \u5982\u679c\u4f60\u9700\u8981\u8c03\u7528\u7684 C \u8bed\u8a00\u63a5\u53e3\u8fd8\u9700\u8981\u539f\u59cb\u6307\u9488\u7684\u8bdd\uff0c\u7528 .get() \u53ef\u4ee5\u4ece\u667a\u80fd\u6307\u9488\u4e2d\u83b7\u53d6\u539f\u59cb\u6307\u9488\u3002\u5efa\u8bae\u53ea\u5728\u548c C \u8bed\u8a00\u6253\u4ea4\u9053\u65f6 .get() \uff0c\u5176\u4f59\u65f6\u95f4\u4e00\u5f8b shared_ptr \u4fdd\u8bc1\u5b89\u5168\u3002 extern \"C\" void some_c_function(Foo *foo); auto foo = make_shared(); some_c_function(foo.get()); RAII \u6bd4\u8d77\u624b\u52a8 delete \u7684\u4f18\u52bf \u5728\u65e5\u5e38\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u5e38\u5e38\u4f1a\u4f7f\u7528\u201c\u5982\u679c\u9519\u8bef\u4e86\u5c31\u63d0\u524d\u8fd4\u56de\u201d\u7684\u5199\u6cd5\u3002\u8fd9\u88ab\u79f0\u4e3a \u63d0\u524d\u8fd4\u56de (early-return) \uff0c\u4e00\u79cd\u4f18\u8d28\u7684\u4ee3\u7801\u5199\u6cd5\uff0c\u6bd4\u5f04\u4e2a\u5f88\u5927\u7684 else \u5206\u652f\u8981\u53ef\u7ef4\u62a4\u5f97\u591a\u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u7136\u800c\u8fd9\u6709\u65f6\u6211\u4eec\u4f1a\u5fd8\u8bb0\u5728\u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d delete \u4e4b\u524d\u5206\u914d\u8fc7\u7684\u6240\u6709\u6307\u5411\u52a8\u6001\u5185\u5b58\u7684\u6307\u9488\u3002 int func() { Foo *foo = new Foo(); ... if (\u51fa\u9519) { // \u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d\u5fd8\u8bb0 delete foo\uff01 return -1; } ... delete foo; return 0; } \u8fc7\u53bb\uff0c\u4eba\u4eec\u4f7f\u7528 goto \u5927\u6cd5\u62d9\u52a3\u5730\u5728\u63d0\u524d\u8fd4\u56de\u65f6 delete \u52a8\u6001\u5185\u5b58\uff1a int main() { Foo *foo1, *foo2; int ret = 0; foo1 = new Foo(); ... if (\u51fa\u9519) { ret = -1; goto out_foo1; } ... Foo *foo2 = new Foo(); ... if (\u51fa\u9519) { ret = -2; goto out_foo2; } ... out_foo2: delete foo2; out_foo1: delete foo1; return ret; } \u8fd9\u5bf9\u4e8e\u201c\u5199\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5176\u5b9e\u8fd8\u4e0d\u7b97\u4ec0\u4e48\uff0c\u65e0\u975e\u5c31\u662f\u6ce8\u610f\u5339\u914d\uff0c\u53cd\u6b63\u90fd\u662f\u4e00\u6b21\u6027\u5199\u5b8c\u5c31\u5f97\u4e86\u3002 \u771f\u6b63\u906d\u7f6a\u7684\u662f\u201c\u6539\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5982\u679c\u4ed6\u8981\u5220\u6389foo1\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u5728\u4e24\u4e2a\u5730\u65b9\u6765\u56de\u8df3\u8f6c\uff0c\u5982\u679cfoo1\u53d8\u6210 new[] \u4e86\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u8df3\u5230\u4e0b\u9762\u628a delete foo1 \u4e5f\u6539\u6210 delete[] foo1 \u3002\u5982\u679cfoo1\u8981\u6539\u540d\uff0c\u90a3\u4e48\u8fd8\u9700\u8981\u8df3\u5230\u4e0b\u9762 out_foo1: \u6807\u7b7e\u4e5f\u6539\u4e86\u3002\u5982\u679c\u8981\u65b0\u589e\u4e00\u4e2afoo3\u6307\u9488\uff0c\u90a3\u8fd8\u9700\u8981\u8df3\u5230\u4e0a\u9762\u52a0\u4e2a Foo *foo3; \uff0c\u4e0b\u9762\u52a0\u4e2a\u6807\u7b7e\u548c delete\u3002 BUG\u6f2b\u6f2b\u5176\u4fee\u8fdc\u516e\uff0c\u543e\u5c06\u4e0a\u4e0b\u800c\u6c42\u7d22\u3002 \u4f60\u662f\u5426\u9047\u5230\u8fc7\u5199\u7a0b\u5e8f\u68ad\u54c8\uff0c\u4e8b\u540e\u201c\u4e0a\u4e0b\u6c42\u7d22\u201d\u7684\u60c5\u51b5\uff1f\u540c\u4e00\u4e2a\u53d8\u91cf foo \u7684\u751f\u547d\u5468\u671f\u88ab\u6781\u9650\u6495\u626f\uff0c\u5206\u5c45\u4e24\u5730\uff0c\u6781\u5927\u7684\u59a8\u788d\u4e86\u6211\u4eec\u6539\u7a0b\u5e8f\u7684\u6548\u7387\u3002 \u800c\u7edf\u8ba1\u8868\u660e\uff0c\u7a0b\u5e8f\u545810%\u7684\u65f6\u95f4\u7528\u4e8e\u5199\u4ee3\u7801\uff0c90%\u7684\u65f6\u95f4\u82b1\u5728\u6539\u4ee3\u7801\u4e0a\u3002\u8282\u7ea6\u6539\u4ee3\u7801\u7684\u65f6\u95f4\uff0c\u5c31\u662f\u8282\u7ea6\u7a0b\u5e8f\u545890%\u7684\u751f\u547d\u3002\u6539\u4ee3\u7801\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u53ef\u4ee5\u7701\u53bb\u8f6f\u4ef6\u4e2d90%\u7684BUG\u3002 \u6240\u4ee5\uff0c\u9664\u975e\u4f60\u662f\u4e00\u6b21\u6027\u4ea4\u5dee\u9879\u76ee\u4e0d\u6253\u7b97\u66f4\u65b0\u4e86\uff0c\u6216\u8005\u786e\u8ba4\u4e86\u6539\u4ee3\u7801\u7684\u4eba\u4e0d\u4f1a\u662f\u4f60\uff0c\u5426\u5219\u5fc5\u7136\u8981\u7528\u5305\u62ec\u667a\u80fd\u6307\u9488\u3001\u8bbe\u8ba1\u6a21\u5f0f\u5728\u5185\u7684\u5404\u79cd\u624b\u6bb5\u7aed\u529b\u907f\u514d\u4ee3\u7801\u5206\u6563\u5316\u3002 \u5728\u4e00\u4e2a\u5e9e\u5927\u7684\u4ee3\u7801\u7cfb\u7edf\u4e2d\u770b\u5230\u539f\u59cb\u6307\u9488\u662f\u6700\u5934\u75bc\u7684\uff1a Student *getstu(const char *name); \u6ca1\u6709\u4efb\u4f55\u4fe1\u606f\u544a\u8bc9\u6211\uff1a \u8fd9\u4e2a\u6307\u9488\u6307\u5411\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5982\u4f55\uff1f \u8981\u6211\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u5417\uff1f \u5982\u4f55\u91ca\u653e\uff0c delete \u3001 delete[] \u3001 free \u3001\u8fd8\u662f fclose \uff1f \u53ef\u4ee5\u662f\u7a7a\u6307\u9488\u5417\uff1f \u6570\u7ec4\u8fd8\u662f\u5355\u4e2a\u5bf9\u8c61\uff1f \u5982\u679c\u662f\u6570\u7ec4\uff0c\u90a3\u4e48\u957f\u5ea6\u591a\u5c11\uff1f\u662fC\u98ce\u683c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u5417\uff1f \u662f\u5426\u79fb\u4ea4\u6240\u6709\u6743\uff1f \u5171\u4eab\u6216\u72ec\u5360\uff1f \u8be5\u8d44\u6e90\u53ef\u4ee5\u62f7\u8d1d\u5417\uff1f \u5982\u679c\u53ef\u4ee5\uff0c\u5982\u4f55\u62f7\u8d1d\uff1f \u800c\u4f60\u53ea\u80fd\u901a\u8fc7\u67e5\u9605\u6587\u6863\uff0c\u624d\u80fd\u786e\u8ba4\u8fd9\u4e9b\u4fe1\u606f\uff0c\u62d6\u6162\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u800c\u4f7f\u7528 RAII \u5bb9\u5668\uff08\u4e0d\u4ec5\u662f\u53ea\u80fd\u6307\u9488\uff09\u4f5c\u4e3a\u7c7b\u578b\uff0c\u5c31\u80fd\u8ba9\u4eba\u4e00\u773c\u5c31\u770b\u51fa\u4ee5\u4e0a10\u4e2a\u4fe1\u606f\u3002 gsl::not_null> getstu1(std::string_view name); Student &getstu2(std::string_view name); \u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u4e00\u770b\u5c31\u660e\u767d\uff0cgetstu1\u4f1a\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\uff1bgetstu2\u4e0d\u8f6c\u79fb\u6240\u6709\u6743\uff0c\u4ec5\u4ec5\u53ea\u662f\u63d0\u4f9b\u7ed9\u8c03\u7528\u8005\u8bbf\u95ee\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u3002 \u4f20\u7edf\u6307\u9488\u56e0\u4e3a\u8bed\u4e49\u4e0d\u660e\u786e\uff0c\u529f\u80fd\u591a\u6837\u5316\uff0c\u6709\u7528\u9519\u7684\u53ef\u80fd\uff0c\u4f8b\u5982\u7528\u6237\u53ef\u80fd\u5077\u61d2\u4e0d\u770b\u6587\u6863\uff0c\u5c31\u64c5\u81ea\u778e\u5199\uff1a char name; Student *stu = getstu(&name); if (stu == NULL) exit(1); free(stu); \u5b9e\u9645\u4e0a getstu \u7684\u53c2\u6570 name \u9700\u8981\u662f\u4e00\u4e2a C \u98ce\u683c 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u7528\u6237\u5374\u4e0d\u5c0f\u5fc3\u5f53\u4f5c\u5355\u4e2a char \u7684\u6307\u9488\u5199\u4e86\uff0c\u7f16\u8bd1\u5668\u6ca1\u6709\u62a5\u9519\u3002 \u800c stu \u5b9e\u9645\u4e0a\u662f getstu \u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u4e34\u65f6\u5f15\u7528\uff0c\u5e76\u4e0d\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u800c\u7528\u6237\u5374\u60f3\u5f53\u7136\u7684\u91ca\u653e\u4e86\u3002 \u5e76\u4e14\u5b9e\u9645\u4e0a getstu \u4ece\u4e0d\u8fd4\u56de\u7a7a\u6307\u9488\uff0c\u7528\u6237\u6839\u672c\u4e0d\u7528\u63d0\u5fc3\u540a\u80c6\u5730\u68c0\u67e5\u3002 \u4e00\u4e2a\u4f18\u8d28\u7684\u51fd\u6570\u63a5\u53e3\uff0c\u5c31\u4e0d\u5e94\u8be5\u7ed9\u7528\u6237\u8fd9\u79cd\u72af\u9519\u7684\u673a\u4f1a\u3002 \u6211\u77e5\u9053\uff0c\u4f60\u4f1a\u8bf4\uff0c std::string \u4e0d\u4e5f\u80fd\u4ece &name \u6784\u9020\uff0c\u653e\u4efb\u7f16\u8bd1\u901a\u8fc7\uff0c\u4e0d\u4e5f\u4f1a\u72af\u9519\u5417\uff1f \u662f\u8fd9\u6837\u7684\uff0c\u4f60\u751a\u81f3\u53ef\u4ee5\u4ece 0 \u6784\u9020 std::string \uff0c\u7f16\u8bd1\u4e00\u6837\u901a\u8fc7\uff0c\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u5d29\u6e83\uff1a std::string s = 0; // 0 \u88ab\u5f53\u4f5c NULL\uff0c\u4ece\u800c\u8c03\u7528\u6784\u9020\u51fd\u6570 std::string(const char *) \u6807\u51c6\u5e93\u91cc\u4e0d\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u6a21\u5f0f\u7684\u591a\u4e86\u53bb\u4e86\uff0c\u6807\u51c6\u5e93\u7684\u5783\u573e\u662f\u5386\u53f2\u9057\u7559\u95ee\u9898\uff0c\u4e0d\u662f\u5c0f\u5f6d\u8001\u5e08\u7684\u95ee\u9898\u3002 \u800c\u667a\u80fd\u6307\u9488\uff0c\u4e0d\u8bba\u662f\u63d0\u524d\u8fd4\u56de\u8fd8\u662f\u6700\u7ec8\u7684\u8fd4\u56de\uff0c\u53ea\u8981\u662f\u51fd\u6570\u7ed3\u675f\u4e86\uff0c\u90fd\u80fd\u81ea\u52a8\u91ca\u653e\u3002\u667a\u80fd\u6307\u9488\u4f7f\u5f97\u7a0b\u5e8f\u5458\u5199\u51fa\u201c\u63d0\u524d\u8fd4\u56de\u5f0f\u201d\u6beb\u65e0\u7cbe\u795e\u538b\u529b\uff0c\u518d\u4e5f\u4e0d\u7528\u60e6\u8bb0\u7740\u54ea\u4e9b\u9700\u8981\u91ca\u653e\u3002 int func() { shared_ptr foo = make_shared(); ... if (\u51fa\u9519) { return -1; } ... return 0; } shared_ptr \u5c0f\u8bfe\u5802 \u81ea\u52a8\u91ca\u653e void func() { shared_ptr fooPtr = make_shared(); ... } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 fooPtr \u662f\u552f\u4e00\u4e5f\u662f\u6700\u540e\u4e00\u4e2a\u6301\u6709 foo \u5bf9\u8c61\u7684\u667a\u80fd\u6307\u9488\u3002 \u6240\u4ee5\u79bb\u5f00 func \u4f5c\u7528\u57df\u65f6\uff0c\u5176\u6307\u5411\u7684 foo \u5bf9\u8c61\u5c31\u4f1a\u9500\u6bc1\u3002 \u4fdd\u5b58\u7eed\u547d shared_ptr globalPtr; void func() { shared_ptr fooPtr = make_shared(); ... globalPtr = fooPtr; } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 \u4f46\u662f globalPtr \u662f\u5168\u5c40\u53d8\u91cf\uff0c\u76f4\u5230\u7a0b\u5e8f\u9000\u51fa\u624d\u4f1a\u9500\u6bc1\u3002 \u76f8\u5f53\u4e8e\u5e2e\u539f fooPtr \u6307\u5411\u7684\u5bf9\u8c61\u5e2e\u7eed\u547d\u4e86\uff01 \u63d0\u524d\u91ca\u653e void other() { globalPtr = nullptr; // \u76f8\u5f53\u4e8e\u4f20\u7edf\u6307\u9488\u7684 delete } \u4f46\u662f\u5982\u679c\u73b0\u5728\u53c8\u4e00\u4e2a\u51fd\u6570\u7ed9 globalPtr \u5199\u5165\u7a7a\u6307\u9488\u3002 \u8fd9\u65f6\u4e4b\u524d\u5bf9\u539f\u5bf9\u8c61\u7684\u5f15\u7528\u5c31\u6ca1\u6709\u4e86\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u4e00\u4e2a\u7a7a\u6307\u9488\u53ef\u4ee5\u4f7f\u5176\u6307\u5411\u7684\u5bf9\u8c61\u91ca\u653e\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u7a7a\u6307\u9488\u7684\u6548\u679c\u548c delete \u5f88\u50cf\uff0c\u533a\u522b\u5728\u4e8e\uff1a \u5982\u679c\u4f60\u5fd8\u4e86 delete \u5c31\u5b8c\u4e86\uff01 \u4f60\u5c31\u7b97\u4e0d\u5199\u5165\u7a7a\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u4e5f\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u5199\u5165\u7a7a\u6307\u9488\u53ea\u662f\u628a\u6b7b\u671f\u63d0\u524d\u4e86\u4e00\u70b9\u800c\u5df2\u2026\u2026 shared_ptr p = make_shared(); p = nullptr; // 1 p.reset(); // 2 } // 3 P.S. \u540c\u7406\uff0cvector \u4e5f\u53ef\u4ee5\u901a\u8fc7 v = {} \u6216 v.clear() \u6765\u63d0\u524d\u91ca\u653e\u5185\u5b58\u3002 \u603b\u7ed3 \u5f53\u4f60\u9700\u8981\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4\uff1avector \u5f53\u4f60\u9700\u8981\u521b\u5efa\u5355\u4e2a\u5bf9\u8c61\uff1ashared_ptr \u5f53\u4f60\u60f3\u63d0\u524d delete\uff1a\u5199\u5165\u7a7a\u6307\u9488 \u7ebf\u7a0b\u5b89\u5168\uff1f \u4f3c\u4e4e\u5f88\u591a\u4e09\u811a\u732b\u6559\u6750\u90fd\u5728\u6a21\u68f1\u4e24\u53ef\u5730\u8fa9\u8bba\u4e00\u4e2a\u95ee\u9898\uff1ashared_ptr \u5230\u5e95\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff1f \u4e0d\u8bba\u4ec0\u4e48\u7c7b\u578b\uff0c\u90fd\u8981\u770b\u4f60\u7684\u7528\u51b5\uff0c\u624d\u80fd\u77e5\u9053\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\uff0c\u8fd9\u91cc\u5206\u4e3a\u4e09\u79cd\u60c5\u51b5\u8ba8\u8bba\uff1a \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u540c\u4e00\u4e2a\u5730\u65b9\u62f7\u8d1d shared_ptr \u51fa\u6765\u662f\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b\u53ea\u8bfb\u6c38\u8fdc\u5b89\u5168\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1 = a; } void t1() { shared_ptr b2 = a; } \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u5f80\u540c\u4e00\u4e2a\u5730\u65b9\u5199\u5165 shared_ptr \u662f\u4e0d\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b 1 \u5199 n \u8bfb\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1; a = b1; } void t1() { shared_ptr b2; a = b2; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f atomic> \u3002 shared_ptr \u5e76\u4e0d\u4fdd\u62a4\u5176\u6307\u5411 T \u7c7b\u578b\u7684\u7ebf\u7a0b\u5b89\u5168\uff08\u4f60\u81ea\u5df1 T \u5b9e\u73b0\u7684\u5c31\u4e0d\u5b89\u5168\u602a\u6211\u6307\u9488???\uff09\uff1a shared_ptr a; void t1() { a->b1 = 0; } void t1() { a->b1 = 1; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f\u7ed9\u4f60\u7684 T \u7c7b\u578b\u91cc\u9762\u52a0\u4e2a mutex \u4fdd\u62a4\u597d\u81ea\u5df1\uff0c\u800c\u4e0d\u662f\u6765\u602a\u6211\u6307\u9488\u3002 \u76f4\u63a5\u7684\u7b54\u6848\uff1a\u4ed6\u4eec\u8bf4\u7684\u662f\uff0cshared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u8fd9\u4e0d\u662f\u5e9f\u8bdd\u5417\uff1f\u6211\u53ea\u662f\u62f7\u8d1d\u53e6\u4e00\u4e2a shared_ptr\uff0c\u5bf9\u90a3\u4e2a shared_ptr \u53c8\u4e0d\u8fdb\u884c\u66f4\u6539\uff0c\u5f53\u7136\u4e0d\u4f1a\u53d1\u751f\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u6211\u81ea\u5df1\u6790\u6784\u5173\u4f60\u5176\u4ed6 shared_ptr \u4ec0\u4e48\u4e8b\uff0c\u5f53\u7136\u5c31\u6ca1\u6709\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u8fd9\u662f\u975e\u5e38\u76f4\u89c2\u7684\uff0c\u548c\u666e\u901a\u6307\u9488\u7684\u7ebf\u7a0b\u5b89\u5168\u6ca1\u6709\u4efb\u4f55\u4e0d\u540c\u3002 \u4e4b\u6240\u4ee5\u8fd9\u4e9b\u72d7\u5e01\u6559\u6750\u4f1a\u8fa9\u8bba\uff0c\u662f\u56e0\u4e3a\u4ed6\u4eec\u8001\u7231\u591a\u7ba1\u95f2\u4e8b\uff0c\u4ed6\u4eec\u4e86\u89e3\u5230 shared_ptr \u7684\u5e95\u5c42\u7ec6\u8282\u4e2d\u6709\u4e2a\u63a7\u5236\u5757\u7684\u5b58\u5728\uff0c\u800c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u9700\u8981\u4fee\u6539\u63a7\u5236\u5757\u7684\u8ba1\u6570\u503c\uff0c\u6240\u4ee5\u5b9e\u9645\u6807\u51c6\u5e93\u7684\u5b9e\u73b0\u4e2d\uff0c\u4f1a\u628a\u8fd9\u4e2a\u8ba1\u6570\u5668\u8bbe\u4e3a\u539f\u5b50\u7684\uff0c\u6700\u7ec8\u7ed3\u679c\u662f\u4f7f\u5f97 shared_ptr \u5728\u591a\u7ebf\u7a0b\u4e2d\u548c\u666e\u901a\u6307\u9488\u4e00\u6837\u5b89\u5168\u3002\u8fd9\u662f\u6807\u51c6\u5e93\u5e95\u5c42\u5b9e\u73b0\u7ec6\u8282\uff0c\u6211\u4eec\u4f5c\u4e3a\u9ad8\u5c42\u7528\u6237\u5e76\u4e0d\u9700\u8981\u8003\u8651\u4ed6\u5e95\u5c42\u5982\u4f55\u5b9e\u73b0\uff0c\u6211\u4eec\u53ea\u9700\u8981\u8bb0\u4f4f\u539f\u59cb\u6307\u9488\u600e\u6837\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0cshared_ptr \u5c31\u600e\u6837\u7ebf\u7a0b\u5b89\u5168\u3002 \u4f60\u4f1a\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5199\u5165\u540c\u4e00\u4e2a\u539f\u59cb\u6307\u9488\u5417\uff1f\u540c\u6837\u5730\uff0c\u5982\u679c\u4f60\u539f\u59cb\u6307\u9488\u4e0d\u4f1a\u72af\u9519\uff0cshared_ptr \u4e3a\u4ec0\u4e48\u4f1a\u72af\u9519\uff1f \u4f60\u53ef\u4ee5\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u540c\u4e00\u4e2a\u5168\u5c40\u7684\u539f\u59cb\u6307\u9488\u53d8\u91cf\uff0c\u540c\u6837\u5730\uff0cshared_ptr \u4e5f\u53ef\u4ee5\uff0c\u6709\u4efb\u4f55\u533a\u522b\u5417\uff1f \u53cd\u6b63\uff0cshared_ptr \u5185\u90e8\u4e13\u95e8\u4e3a\u7ebf\u7a0b\u5b89\u5168\u505a\u8fc7\u8bbe\u8ba1\uff0c\u4f60\u4e0d\u7528\u53bb\u64cd\u5fc3\u3002 placement new placement new \u548c placement delete \u4e5f\u53ef\u4ee5\u7528 std::construct_at \u548c std::destroy_at \u4ee3\u66ff\uff1a #include struct Foo { explicit Foo(int age) { ... } Foo(Foo &&) = delete; ~Foo() { ... } }; void func() { alignas(Foo) unsigned char buffer[sizeof(Foo)]; Foo *foo = std::construct_at(reinterpret_cast(buffer), 42, \"hello\"); // \u7b49\u4ef7\u4e8e new (buffer) Foo(42); ... std::destroy_at(foo); // \u7b49\u4ef7\u4e8e foo->~Foo(); } \u5728 \u5185\u5b58\u6a21\u578b\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb"},{"location":"no_more_new/#c-new","text":"\u4f7f\u7528 new \u548c delete \u662f\u4e00\u79cd\u8fc7\u65f6\u7684\u5185\u5b58\u7ba1\u7406\u65b9\u5f0f\uff0c\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u60ac\u7a7a\u6307\u9488\uff0c\u5e94\u5f53\u6c38\u4e0d\u4f7f\u7528\u3002 \u4f18\u79c0\u7684\u73b0\u4ee3 C++ \u9879\u76ee\uff0c\u90fd\u4f7f\u7528 \u667a\u80fd\u6307\u9488 \u548c \u5bb9\u5668 \u7ba1\u7406\u5185\u5b58\uff0c\u4ece\u6765\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efa\u539f\u59cb\u6307\u9488\u3002 \u4e0b\u5217\u4e09\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 new \u548c delete\uff1a \u4f60\u5728\u5c01\u88c5\u4e00\u4e2a\u975e\u5e38\u5e95\u5c42\u7684\u5185\u5b58\u5206\u914d\u5668\u5e93\u3002 \u4f60\u662f C++98 \u7528\u6237\uff0c\u4e14\u4f60\u7684\u8001\u677f\u4e0d\u5141\u8bb8\u4f7f\u7528 boost\uff08\u5176\u63d0\u4f9b\u4e86\u667a\u80fd\u6307\u9488\uff09\u3002 \u4f60\u60f3\u8981\u521b\u9020\u4e00\u4e9b\u5185\u5b58\u6cc4\u6f0f\u6765\u60e9\u7f5a\u62d6\u6b20\u5de5\u8d44\u7684\u8111\u677f\u3002 \u540c\u7406\uff0cmalloc \u548c free \u4e5f\u662f\u4e0d\u5141\u8bb8\u7684\u3002 \u4e0d\u4ec5 new \u4e0d\u5e94\u8be5\u51fa\u73b0\uff0c\u539f\u59cb\u6307\u9488\u4e5f\u5e94\u8be5\u5c11\u51fa\u73b0\uff0c\u800c\u662f\u66f4\u5b89\u5168\uff0c\u7528\u6cd5\u66f4\u5355\u4e00\u7684 \u5f15\u7528 \u6216 span \u4ee3\u66ff\u3002 \u7528\u6cd5\u66f4\u5355\u4e00\u4e3a\u4ec0\u4e48\u662f\u597d\u4e8b\uff1f\u8bf7\u770b \u5f3a\u7c7b\u578b API \u8bbe\u8ba1\u4e13\u9898\u7ae0 \u3002","title":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb"},{"location":"no_more_new/#1","text":"\u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; }","title":"\u6848\u4f8b 1"},{"location":"no_more_new/#11","text":"\u6211\u4e00\u822c\u4f1a\u7528\u66f4\u76f4\u89c2\u7684 auto \u5199\u6cd5\uff0c\u8fd9\u6837\u66f4\u80fd\u660e\u786e\u8fd9\u662f\u5728\u521b\u5efa\u4e00\u4e2a vector \u5bf9\u8c61\uff0c\u7136\u540e\u4fdd\u5b58\u5230 mem \u8fd9\u4e2a\u53d8\u91cf\u540d\u4e2d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size()); \u8fd9\u88ab\u79f0\u4e3a auto-idiom\uff1a\u59cb\u7ec8\u4f7f\u7528 auto \u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6c38\u8fdc\u522b\u4f7f\u7528\u53ef\u80fd\u5f15\u53d1\u6b67\u4e49\u7684\u7c7b\u578b\u524d\u7f6e\u3002","title":"\u8d34\u58eb 1.1"},{"location":"no_more_new/#12","text":"\u6709\u7684\u540c\u5b66\u4f1a\u60f3\u5f53\u7136\u5730\u63d0\u51fa\uff0c\u7528\u667a\u80fd\u6307\u9488\u4ee3\u66ff new\u3002 auto mem = make_shared(1024); read(1, mem.get(), 1024); \u53ef new \u7684\u66ff\u4ee3\u54c1\u4ece\u6765\u4e0d\u53ea\u6709\u667a\u80fd\u6307\u9488\u4e00\u4e2a\uff0c\u4e5f\u53ef\u4ee5\u662f vector \u5bb9\u5668\uff01 \u667a\u80fd\u6307\u9488\u53ea\u4f1a\u7528\u4e8e \u5355\u4e2a\u5bf9\u8c61 \uff01 \u52a8\u6001\u957f\u5ea6\u7684\u6570\u7ec4 \uff0c\u6b63\u5e38\u4eba\u90fd\u662f\u7528 vector \u7ba1\u7406\u7684\u3002 \u5f88\u591a\u52a3\u8d28\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u6750\u201d \u90fd\u5ffd\u7565\u4e86\u8fd9\u4e00\u70b9\uff0c\u603b\u662f\u523b\u610f\u5938\u5927\u4e86\u667a\u80fd\u6307\u9488\u7684\u8986\u76d6\u8303\u56f4\uff0c\u4e3a\u4e86\u65b0\u800c\u65b0\uff0c\u800c\u5bf9\u5b9e\u9645\u4e0a\u66f4\u9002\u5408\u7ba1\u7406 \u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4 \u7684 vector \u53ea\u5b57\u4e0d\u63d0\u3002 vector \u7ba1\u7406\u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4\u7684\u4f18\u52bf\uff1a \u4f60\u53ef\u4ee5\u968f\u65f6\u968f\u5730 resize \u548c push_back\uff0c\u52a0\u5165\u65b0\u5143\u7d20\uff0c\u800c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\u8981\u91cd\u65b0\u8c03\u6574\u5927\u5c0f\u5c31\u6bd4\u8f83\u56f0\u96be\u3002 vector \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6df1\u62f7\u8d1d\uff0c\u7b26\u5408 C++ \u5bb9\u5668\u7684\u4e00\u822c\u7ea6\u5b9a\u3002\u800c unique_ptr \u5b8c\u5168\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u6df1\u62f7\u8d1d\u9700\u8981\u989d\u5916\u7684\u4ee3\u7801\uff0cshared_ptr \u5219\u662f\u6d45\u62f7\u8d1d\uff0c\u6709\u65f6\u4f1a\u5bfc\u81f4\u6570\u636e\u8986\u76d6\u3002 \u5176\u5b9e shared_ptr \u4e5f\u4e0d\u662f\u4e0d\u53ef\u4ee5\u7528\uff0c\u7136\u800c\uff0c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\uff0c\u5e76\u4e0d\u80fd\u65b9\u4fbf\u5730\u901a\u8fc7 .size() \u83b7\u53d6\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5fc5\u987b\u7528\u53e6\u4e00\u4e2a\u53d8\u91cf\u5355\u72ec\u5b58\u50a8\u8fd9\u4e2a\u957f\u5ea6\u3002\u8fd9\u5c31\u8fdd\u80cc\u4e86\u5c01\u88c5\u539f\u5219\uff0c\u90a3\u4f1a\u4f7f\u4f60\u7684\u4ee3\u7801\u53d8\u5f97\u4e0d\u53ef\u7ef4\u62a4\u3002 \u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u53ef\u7ef4\u62a4\u6027\u603b\u662f\u6bd4\u6027\u80fd\u91cd\u8981\u7684\uff0c\u4f60\u53ea\u9700\u8981\u6bd4\u8f83 \u4f60\u91cd\u6784\u4ee3\u7801\u82b1\u7684\u65f6\u95f4 \u548c \u8ba1\u7b97\u673a\u8fd0\u884c\u8fd9\u6bb5\u4ee3\u7801\u6240\u9700\u65f6\u95f4 \u5c31\u660e\u767d\u503c\u4e0d\u503c\u4e86\u3002","title":"\u8d34\u58eb 1.2"},{"location":"no_more_new/#13","text":"\u5982\u679c\u662f\u5176\u4ed6\u7c7b\u578b\uff0c\u53ef\u80fd\u9700\u8981\u4e58\u4ee5 sizeof(\u5143\u7d20\u7c7b\u578b) \uff0c\u53d6\u51b3\u4e8e\u90a3\u4e2a C \u51fd\u6570\u8981\u6c42\u7684\u662f\u201c\u5b57\u8282\u6570\u201d\u8fd8\u662f\u201c\u5143\u7d20\u6570\u201d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size() * sizeof(mem[0])); auto max = find_max(mem.data(), mem.size());","title":"\u8d34\u58eb 1.3"},{"location":"no_more_new/#14","text":"\u5bf9\u4e8e\u4f60\u81ea\u5df1\u7684 C++ \u51fd\u6570\uff0c\u5c31\u6ca1\u5fc5\u8981\u518d\u63d0\u4f9b TODO: span, gsl::span, boost::span","title":"\u8d34\u58eb 1.4"},{"location":"no_more_new/#2","text":"\u540c\u5b66\uff1a\u6211\u9700\u8981\u5728\u201c\u5806\u201d\u4e0a\u5206\u914d\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u4ed6\u6301\u4e45\u5b58\u5728\u3002\u4f60\u4e0d\u8ba9\u6211\u7528 new\uff0c\u6211\u53ea\u80fd\u5728\u201c\u6808\u201d\u4e0a\u521b\u5efa\u4e34\u65f6\u5bf9\u8c61\u4e86\uff0c\u5982\u679c\u8981\u8fd4\u56de\u6216\u5b58\u8d77\u6765\u7684\u8bdd\u6839\u672c\u7528\u4e0d\u4e86\u554a\u3002 Foo *hello() { Foo *foo = new Foo(); return foo; } \u5c0f\u5f6d\u8001\u5e08\uff1a\u4f60\u53ef\u4ee5\u4f7f\u7528\u667a\u80fd\u6307\u9488\uff0c\u6700\u9002\u5408\u65b0\u4eba\u4e0a\u624b\u7684\u667a\u80fd\u6307\u9488\u662f shared_ptr\u3002 \u5f53\u6ca1\u6709\u4efb\u4f55\u51fd\u6570\u6216\u5bf9\u8c61\u6301\u6709\u8be5 shared_ptr \u6307\u5411\u7684\u5bf9\u8c61\u65f6\uff0c\u4e5f\u5c31\u662f\u5f53\u8c03\u7528\u8005\u5b58\u50a8 hello() \u8fd4\u56de\u503c\u7684\u51fd\u6570\u4f53\u9000\u51fa\u65f6\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u88ab\u81ea\u52a8\u91ca\u653e\u3002 shared_ptr hello() { shared_ptr foo = make_shared(); return foo; } \u603b\u4e4b\uff0c\u8fd9\u6837\u66ff\u6362\u4f60\u7684\u4ee3\u7801\uff1a T * \u6362\u6210 shared_ptr new T(...) \u6362\u6210 make_shared(...) \u4f60\u7684\u4ee3\u7801\u5c31\u57fa\u672c\u4e0a\u5b89\u5168\u4e86\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8 delete \u4e86\u3002 \u6709\u4e2a\u7528\u4e86 shared_ptr \u8fd8\u4f1a\u5185\u5b58\u6cc4\u6f0f\u7684\u8fb9\u7f18\u60c5\u51b5\uff1a\u5faa\u73af\u5f15\u7528\uff0c\u901a\u5e38\u662f\u5b9e\u73b0\u53cc\u5411\u94fe\u8868\u65f6\uff0cweak_ptr \u53ef\u4ee5\u89e3\u51b3\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002","title":"\u6848\u4f8b 2"},{"location":"no_more_new/#21","text":"unique_ptr \u548c shared_ptr \u6709\u4ec0\u4e48\u533a\u522b\uff1f\u521d\u5b66\u8005\u5e94\u8be5\u5148\u5b66\u54ea\u4e2a\uff1f unique_ptr \u662f\u72ec\u5360\u6240\u6709\u6743\uff0c\u4ed6\u7684\u9650\u5236\u66f4\u591a\uff0c\u6bd4\u5982\uff1a \u4e0d\u5141\u8bb8\u62f7\u8d1d\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u3002 \u4e0d\u5141\u8bb8\u8d4b\u503c\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u8d4b\u503c\u3002 \u7528 unique_ptr \u4e3b\u8981\u662f\u51fa\u4e8e\u6027\u80fd\u4f18\u52bf\u3002 \u7136\u800c\u6027\u80fd\u603b\u662f\u4e0d\u5982\u5b89\u5168\u91cd\u8981\u7684\uff0c\u4f60\u662f\u60f3\u8981 \u4e00\u4e2a\u9020\u5728\u706b\u661f\u7684\u8c6a\u534e\u5bab\u6bbf\uff0c\u8fd8\u662f\u4e00\u4e2a\u5730\u7403\u7684\u5b89\u5168\u8001\u5bb6\uff1f \u6240\u4ee5\uff0c\u5efa\u8bae\u4f60\u5148\u5168\u90e8\u66ff\u6362\u6210\u6cdb\u7528\u6027\u5f3a\u3001\u6613\u7528\u7684 shared_ptr\u3002\u7b49\u786e\u5b9e\u51fa\u73b0\u6027\u80fd\u74f6\u9888\u65f6\uff0c\u518d\u5bf9\u74f6\u9888\u90e8\u5206\u5355\u72ec\u8c03\u8bd5\u4f18\u5316\u4e5f\u4e0d\u8fdf\u3002 \u5148\u628a\u8001\u5bb6\u9020\u597d\u4e86\uff0c\u7136\u540e\u518d\u60f3\u529e\u6cd5\u79fb\u6c11\u706b\u661f\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002","title":"\u8d34\u58eb 2.1"},{"location":"no_more_new/#22","text":"\u6709\u4e9b\u8001\u5f0f\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u7a0b\u201d \u4e2d\uff0c\u4f1a\u770b\u5230\u8fd9\u6837 new \u4e0e\u667a\u80fd\u6307\u9488\u5e76\u7528\u7684\u5199\u6cd5\uff1a shared_ptr foo(new Foo()); \u4ece C++14 \u5f00\u59cb\uff0c\u8fd9\u5df2\u7ecf\u662f \u8fc7\u65f6\u7684 \uff01\u5177\u6709\u5b89\u5168\u9690\u60a3\uff08\u5982\u679c\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u51fa\u5f02\u5e38\uff09\uff0c\u4e14\u5199\u8d77\u6765\u4e5f\u4e0d\u591f\u76f4\u89c2\u3002 \u73b0\u5728\u4eba\u4eec\u4e00\u822c\u90fd\u4f1a\u7528 make_shared \u51fd\u6570\uff0c\u5176\u5185\u90e8\u5c01\u88c5\u4e0d\u4ec5\u4fdd\u8bc1\u4e86\u5f02\u5e38\u5b89\u5168\uff0c\u800c\u4e14\u4f1a\u4f7f shared_ptr \u7684\u63a7\u5236\u5757\u4e0e Foo \u5bf9\u8c61\u524d\u540e\u7d27\u6328\u7740\uff0c\u53ea\u9700\u4e00\u6b21\u5185\u5b58\u5206\u914d\uff0c\u4e0d\u4ec5\u66f4\u76f4\u89c2\uff0c\u8fd8\u63d0\u5347\u4e86\u6027\u80fd\u3002 auto foo = make_shared(); \u6709\u8da3\u7684\u662f\uff0cmake_shared \u5728 C++11 \u5c31\u5f15\u5165\u4e86\uff0cmake_unique \u5374\u76f4\u5230 C++14 \u624d\u5f15\u5165\u3002 \u4ece C++14 \u5f00\u59cb\uff0c\u5185\u5b58\u5b89\u5168\u7684\u73b0\u4ee3 C++ \u7a0b\u5e8f\u4e2d\u5c31\u4e0d\u4f1a\u51fa\u73b0\u4efb\u4f55\u663e\u5f0f\u7684 new \u4e86\uff0c\u54ea\u6015\u662f\u5305\u5728 shared_ptr \u6216 unique_ptr \u5185\u7684\u4e5f\u4e0d\u884c\u3002\uff08\u9664\u4e86\u6700\u4e0a\u9762\u8bf4\u7684 3 \u79cd\u7279\u6b8a\u60c5\u51b5\uff09","title":"\u8d34\u58eb 2.2"},{"location":"no_more_new/#23","text":"\u5982\u679c\u4f60\u9700\u8981\u8c03\u7528\u7684 C \u8bed\u8a00\u63a5\u53e3\u8fd8\u9700\u8981\u539f\u59cb\u6307\u9488\u7684\u8bdd\uff0c\u7528 .get() \u53ef\u4ee5\u4ece\u667a\u80fd\u6307\u9488\u4e2d\u83b7\u53d6\u539f\u59cb\u6307\u9488\u3002\u5efa\u8bae\u53ea\u5728\u548c C \u8bed\u8a00\u6253\u4ea4\u9053\u65f6 .get() \uff0c\u5176\u4f59\u65f6\u95f4\u4e00\u5f8b shared_ptr \u4fdd\u8bc1\u5b89\u5168\u3002 extern \"C\" void some_c_function(Foo *foo); auto foo = make_shared(); some_c_function(foo.get());","title":"\u8d34\u58eb 2.3"},{"location":"no_more_new/#raii-delete","text":"\u5728\u65e5\u5e38\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u5e38\u5e38\u4f1a\u4f7f\u7528\u201c\u5982\u679c\u9519\u8bef\u4e86\u5c31\u63d0\u524d\u8fd4\u56de\u201d\u7684\u5199\u6cd5\u3002\u8fd9\u88ab\u79f0\u4e3a \u63d0\u524d\u8fd4\u56de (early-return) \uff0c\u4e00\u79cd\u4f18\u8d28\u7684\u4ee3\u7801\u5199\u6cd5\uff0c\u6bd4\u5f04\u4e2a\u5f88\u5927\u7684 else \u5206\u652f\u8981\u53ef\u7ef4\u62a4\u5f97\u591a\u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u7136\u800c\u8fd9\u6709\u65f6\u6211\u4eec\u4f1a\u5fd8\u8bb0\u5728\u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d delete \u4e4b\u524d\u5206\u914d\u8fc7\u7684\u6240\u6709\u6307\u5411\u52a8\u6001\u5185\u5b58\u7684\u6307\u9488\u3002 int func() { Foo *foo = new Foo(); ... if (\u51fa\u9519) { // \u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d\u5fd8\u8bb0 delete foo\uff01 return -1; } ... delete foo; return 0; } \u8fc7\u53bb\uff0c\u4eba\u4eec\u4f7f\u7528 goto \u5927\u6cd5\u62d9\u52a3\u5730\u5728\u63d0\u524d\u8fd4\u56de\u65f6 delete \u52a8\u6001\u5185\u5b58\uff1a int main() { Foo *foo1, *foo2; int ret = 0; foo1 = new Foo(); ... if (\u51fa\u9519) { ret = -1; goto out_foo1; } ... Foo *foo2 = new Foo(); ... if (\u51fa\u9519) { ret = -2; goto out_foo2; } ... out_foo2: delete foo2; out_foo1: delete foo1; return ret; } \u8fd9\u5bf9\u4e8e\u201c\u5199\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5176\u5b9e\u8fd8\u4e0d\u7b97\u4ec0\u4e48\uff0c\u65e0\u975e\u5c31\u662f\u6ce8\u610f\u5339\u914d\uff0c\u53cd\u6b63\u90fd\u662f\u4e00\u6b21\u6027\u5199\u5b8c\u5c31\u5f97\u4e86\u3002 \u771f\u6b63\u906d\u7f6a\u7684\u662f\u201c\u6539\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5982\u679c\u4ed6\u8981\u5220\u6389foo1\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u5728\u4e24\u4e2a\u5730\u65b9\u6765\u56de\u8df3\u8f6c\uff0c\u5982\u679cfoo1\u53d8\u6210 new[] \u4e86\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u8df3\u5230\u4e0b\u9762\u628a delete foo1 \u4e5f\u6539\u6210 delete[] foo1 \u3002\u5982\u679cfoo1\u8981\u6539\u540d\uff0c\u90a3\u4e48\u8fd8\u9700\u8981\u8df3\u5230\u4e0b\u9762 out_foo1: \u6807\u7b7e\u4e5f\u6539\u4e86\u3002\u5982\u679c\u8981\u65b0\u589e\u4e00\u4e2afoo3\u6307\u9488\uff0c\u90a3\u8fd8\u9700\u8981\u8df3\u5230\u4e0a\u9762\u52a0\u4e2a Foo *foo3; \uff0c\u4e0b\u9762\u52a0\u4e2a\u6807\u7b7e\u548c delete\u3002 BUG\u6f2b\u6f2b\u5176\u4fee\u8fdc\u516e\uff0c\u543e\u5c06\u4e0a\u4e0b\u800c\u6c42\u7d22\u3002 \u4f60\u662f\u5426\u9047\u5230\u8fc7\u5199\u7a0b\u5e8f\u68ad\u54c8\uff0c\u4e8b\u540e\u201c\u4e0a\u4e0b\u6c42\u7d22\u201d\u7684\u60c5\u51b5\uff1f\u540c\u4e00\u4e2a\u53d8\u91cf foo \u7684\u751f\u547d\u5468\u671f\u88ab\u6781\u9650\u6495\u626f\uff0c\u5206\u5c45\u4e24\u5730\uff0c\u6781\u5927\u7684\u59a8\u788d\u4e86\u6211\u4eec\u6539\u7a0b\u5e8f\u7684\u6548\u7387\u3002 \u800c\u7edf\u8ba1\u8868\u660e\uff0c\u7a0b\u5e8f\u545810%\u7684\u65f6\u95f4\u7528\u4e8e\u5199\u4ee3\u7801\uff0c90%\u7684\u65f6\u95f4\u82b1\u5728\u6539\u4ee3\u7801\u4e0a\u3002\u8282\u7ea6\u6539\u4ee3\u7801\u7684\u65f6\u95f4\uff0c\u5c31\u662f\u8282\u7ea6\u7a0b\u5e8f\u545890%\u7684\u751f\u547d\u3002\u6539\u4ee3\u7801\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u53ef\u4ee5\u7701\u53bb\u8f6f\u4ef6\u4e2d90%\u7684BUG\u3002 \u6240\u4ee5\uff0c\u9664\u975e\u4f60\u662f\u4e00\u6b21\u6027\u4ea4\u5dee\u9879\u76ee\u4e0d\u6253\u7b97\u66f4\u65b0\u4e86\uff0c\u6216\u8005\u786e\u8ba4\u4e86\u6539\u4ee3\u7801\u7684\u4eba\u4e0d\u4f1a\u662f\u4f60\uff0c\u5426\u5219\u5fc5\u7136\u8981\u7528\u5305\u62ec\u667a\u80fd\u6307\u9488\u3001\u8bbe\u8ba1\u6a21\u5f0f\u5728\u5185\u7684\u5404\u79cd\u624b\u6bb5\u7aed\u529b\u907f\u514d\u4ee3\u7801\u5206\u6563\u5316\u3002 \u5728\u4e00\u4e2a\u5e9e\u5927\u7684\u4ee3\u7801\u7cfb\u7edf\u4e2d\u770b\u5230\u539f\u59cb\u6307\u9488\u662f\u6700\u5934\u75bc\u7684\uff1a Student *getstu(const char *name); \u6ca1\u6709\u4efb\u4f55\u4fe1\u606f\u544a\u8bc9\u6211\uff1a \u8fd9\u4e2a\u6307\u9488\u6307\u5411\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5982\u4f55\uff1f \u8981\u6211\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u5417\uff1f \u5982\u4f55\u91ca\u653e\uff0c delete \u3001 delete[] \u3001 free \u3001\u8fd8\u662f fclose \uff1f \u53ef\u4ee5\u662f\u7a7a\u6307\u9488\u5417\uff1f \u6570\u7ec4\u8fd8\u662f\u5355\u4e2a\u5bf9\u8c61\uff1f \u5982\u679c\u662f\u6570\u7ec4\uff0c\u90a3\u4e48\u957f\u5ea6\u591a\u5c11\uff1f\u662fC\u98ce\u683c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u5417\uff1f \u662f\u5426\u79fb\u4ea4\u6240\u6709\u6743\uff1f \u5171\u4eab\u6216\u72ec\u5360\uff1f \u8be5\u8d44\u6e90\u53ef\u4ee5\u62f7\u8d1d\u5417\uff1f \u5982\u679c\u53ef\u4ee5\uff0c\u5982\u4f55\u62f7\u8d1d\uff1f \u800c\u4f60\u53ea\u80fd\u901a\u8fc7\u67e5\u9605\u6587\u6863\uff0c\u624d\u80fd\u786e\u8ba4\u8fd9\u4e9b\u4fe1\u606f\uff0c\u62d6\u6162\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u800c\u4f7f\u7528 RAII \u5bb9\u5668\uff08\u4e0d\u4ec5\u662f\u53ea\u80fd\u6307\u9488\uff09\u4f5c\u4e3a\u7c7b\u578b\uff0c\u5c31\u80fd\u8ba9\u4eba\u4e00\u773c\u5c31\u770b\u51fa\u4ee5\u4e0a10\u4e2a\u4fe1\u606f\u3002 gsl::not_null> getstu1(std::string_view name); Student &getstu2(std::string_view name); \u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u4e00\u770b\u5c31\u660e\u767d\uff0cgetstu1\u4f1a\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\uff1bgetstu2\u4e0d\u8f6c\u79fb\u6240\u6709\u6743\uff0c\u4ec5\u4ec5\u53ea\u662f\u63d0\u4f9b\u7ed9\u8c03\u7528\u8005\u8bbf\u95ee\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u3002 \u4f20\u7edf\u6307\u9488\u56e0\u4e3a\u8bed\u4e49\u4e0d\u660e\u786e\uff0c\u529f\u80fd\u591a\u6837\u5316\uff0c\u6709\u7528\u9519\u7684\u53ef\u80fd\uff0c\u4f8b\u5982\u7528\u6237\u53ef\u80fd\u5077\u61d2\u4e0d\u770b\u6587\u6863\uff0c\u5c31\u64c5\u81ea\u778e\u5199\uff1a char name; Student *stu = getstu(&name); if (stu == NULL) exit(1); free(stu); \u5b9e\u9645\u4e0a getstu \u7684\u53c2\u6570 name \u9700\u8981\u662f\u4e00\u4e2a C \u98ce\u683c 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u7528\u6237\u5374\u4e0d\u5c0f\u5fc3\u5f53\u4f5c\u5355\u4e2a char \u7684\u6307\u9488\u5199\u4e86\uff0c\u7f16\u8bd1\u5668\u6ca1\u6709\u62a5\u9519\u3002 \u800c stu \u5b9e\u9645\u4e0a\u662f getstu \u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u4e34\u65f6\u5f15\u7528\uff0c\u5e76\u4e0d\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u800c\u7528\u6237\u5374\u60f3\u5f53\u7136\u7684\u91ca\u653e\u4e86\u3002 \u5e76\u4e14\u5b9e\u9645\u4e0a getstu \u4ece\u4e0d\u8fd4\u56de\u7a7a\u6307\u9488\uff0c\u7528\u6237\u6839\u672c\u4e0d\u7528\u63d0\u5fc3\u540a\u80c6\u5730\u68c0\u67e5\u3002 \u4e00\u4e2a\u4f18\u8d28\u7684\u51fd\u6570\u63a5\u53e3\uff0c\u5c31\u4e0d\u5e94\u8be5\u7ed9\u7528\u6237\u8fd9\u79cd\u72af\u9519\u7684\u673a\u4f1a\u3002 \u6211\u77e5\u9053\uff0c\u4f60\u4f1a\u8bf4\uff0c std::string \u4e0d\u4e5f\u80fd\u4ece &name \u6784\u9020\uff0c\u653e\u4efb\u7f16\u8bd1\u901a\u8fc7\uff0c\u4e0d\u4e5f\u4f1a\u72af\u9519\u5417\uff1f \u662f\u8fd9\u6837\u7684\uff0c\u4f60\u751a\u81f3\u53ef\u4ee5\u4ece 0 \u6784\u9020 std::string \uff0c\u7f16\u8bd1\u4e00\u6837\u901a\u8fc7\uff0c\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u5d29\u6e83\uff1a std::string s = 0; // 0 \u88ab\u5f53\u4f5c NULL\uff0c\u4ece\u800c\u8c03\u7528\u6784\u9020\u51fd\u6570 std::string(const char *) \u6807\u51c6\u5e93\u91cc\u4e0d\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u6a21\u5f0f\u7684\u591a\u4e86\u53bb\u4e86\uff0c\u6807\u51c6\u5e93\u7684\u5783\u573e\u662f\u5386\u53f2\u9057\u7559\u95ee\u9898\uff0c\u4e0d\u662f\u5c0f\u5f6d\u8001\u5e08\u7684\u95ee\u9898\u3002 \u800c\u667a\u80fd\u6307\u9488\uff0c\u4e0d\u8bba\u662f\u63d0\u524d\u8fd4\u56de\u8fd8\u662f\u6700\u7ec8\u7684\u8fd4\u56de\uff0c\u53ea\u8981\u662f\u51fd\u6570\u7ed3\u675f\u4e86\uff0c\u90fd\u80fd\u81ea\u52a8\u91ca\u653e\u3002\u667a\u80fd\u6307\u9488\u4f7f\u5f97\u7a0b\u5e8f\u5458\u5199\u51fa\u201c\u63d0\u524d\u8fd4\u56de\u5f0f\u201d\u6beb\u65e0\u7cbe\u795e\u538b\u529b\uff0c\u518d\u4e5f\u4e0d\u7528\u60e6\u8bb0\u7740\u54ea\u4e9b\u9700\u8981\u91ca\u653e\u3002 int func() { shared_ptr foo = make_shared(); ... if (\u51fa\u9519) { return -1; } ... return 0; }","title":"RAII \u6bd4\u8d77\u624b\u52a8 delete \u7684\u4f18\u52bf"},{"location":"no_more_new/#shared_ptr","text":"","title":"shared_ptr \u5c0f\u8bfe\u5802"},{"location":"no_more_new/#_1","text":"void func() { shared_ptr fooPtr = make_shared(); ... } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 fooPtr \u662f\u552f\u4e00\u4e5f\u662f\u6700\u540e\u4e00\u4e2a\u6301\u6709 foo \u5bf9\u8c61\u7684\u667a\u80fd\u6307\u9488\u3002 \u6240\u4ee5\u79bb\u5f00 func \u4f5c\u7528\u57df\u65f6\uff0c\u5176\u6307\u5411\u7684 foo \u5bf9\u8c61\u5c31\u4f1a\u9500\u6bc1\u3002","title":"\u81ea\u52a8\u91ca\u653e"},{"location":"no_more_new/#_2","text":"shared_ptr globalPtr; void func() { shared_ptr fooPtr = make_shared(); ... globalPtr = fooPtr; } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 \u4f46\u662f globalPtr \u662f\u5168\u5c40\u53d8\u91cf\uff0c\u76f4\u5230\u7a0b\u5e8f\u9000\u51fa\u624d\u4f1a\u9500\u6bc1\u3002 \u76f8\u5f53\u4e8e\u5e2e\u539f fooPtr \u6307\u5411\u7684\u5bf9\u8c61\u5e2e\u7eed\u547d\u4e86\uff01","title":"\u4fdd\u5b58\u7eed\u547d"},{"location":"no_more_new/#_3","text":"void other() { globalPtr = nullptr; // \u76f8\u5f53\u4e8e\u4f20\u7edf\u6307\u9488\u7684 delete } \u4f46\u662f\u5982\u679c\u73b0\u5728\u53c8\u4e00\u4e2a\u51fd\u6570\u7ed9 globalPtr \u5199\u5165\u7a7a\u6307\u9488\u3002 \u8fd9\u65f6\u4e4b\u524d\u5bf9\u539f\u5bf9\u8c61\u7684\u5f15\u7528\u5c31\u6ca1\u6709\u4e86\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u4e00\u4e2a\u7a7a\u6307\u9488\u53ef\u4ee5\u4f7f\u5176\u6307\u5411\u7684\u5bf9\u8c61\u91ca\u653e\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u7a7a\u6307\u9488\u7684\u6548\u679c\u548c delete \u5f88\u50cf\uff0c\u533a\u522b\u5728\u4e8e\uff1a \u5982\u679c\u4f60\u5fd8\u4e86 delete \u5c31\u5b8c\u4e86\uff01 \u4f60\u5c31\u7b97\u4e0d\u5199\u5165\u7a7a\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u4e5f\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u5199\u5165\u7a7a\u6307\u9488\u53ea\u662f\u628a\u6b7b\u671f\u63d0\u524d\u4e86\u4e00\u70b9\u800c\u5df2\u2026\u2026 shared_ptr p = make_shared(); p = nullptr; // 1 p.reset(); // 2 } // 3 P.S. \u540c\u7406\uff0cvector \u4e5f\u53ef\u4ee5\u901a\u8fc7 v = {} \u6216 v.clear() \u6765\u63d0\u524d\u91ca\u653e\u5185\u5b58\u3002","title":"\u63d0\u524d\u91ca\u653e"},{"location":"no_more_new/#_4","text":"\u5f53\u4f60\u9700\u8981\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4\uff1avector \u5f53\u4f60\u9700\u8981\u521b\u5efa\u5355\u4e2a\u5bf9\u8c61\uff1ashared_ptr \u5f53\u4f60\u60f3\u63d0\u524d delete\uff1a\u5199\u5165\u7a7a\u6307\u9488","title":"\u603b\u7ed3"},{"location":"no_more_new/#_5","text":"\u4f3c\u4e4e\u5f88\u591a\u4e09\u811a\u732b\u6559\u6750\u90fd\u5728\u6a21\u68f1\u4e24\u53ef\u5730\u8fa9\u8bba\u4e00\u4e2a\u95ee\u9898\uff1ashared_ptr \u5230\u5e95\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff1f \u4e0d\u8bba\u4ec0\u4e48\u7c7b\u578b\uff0c\u90fd\u8981\u770b\u4f60\u7684\u7528\u51b5\uff0c\u624d\u80fd\u77e5\u9053\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\uff0c\u8fd9\u91cc\u5206\u4e3a\u4e09\u79cd\u60c5\u51b5\u8ba8\u8bba\uff1a \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u540c\u4e00\u4e2a\u5730\u65b9\u62f7\u8d1d shared_ptr \u51fa\u6765\u662f\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b\u53ea\u8bfb\u6c38\u8fdc\u5b89\u5168\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1 = a; } void t1() { shared_ptr b2 = a; } \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u5f80\u540c\u4e00\u4e2a\u5730\u65b9\u5199\u5165 shared_ptr \u662f\u4e0d\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b 1 \u5199 n \u8bfb\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1; a = b1; } void t1() { shared_ptr b2; a = b2; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f atomic> \u3002 shared_ptr \u5e76\u4e0d\u4fdd\u62a4\u5176\u6307\u5411 T \u7c7b\u578b\u7684\u7ebf\u7a0b\u5b89\u5168\uff08\u4f60\u81ea\u5df1 T \u5b9e\u73b0\u7684\u5c31\u4e0d\u5b89\u5168\u602a\u6211\u6307\u9488???\uff09\uff1a shared_ptr a; void t1() { a->b1 = 0; } void t1() { a->b1 = 1; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f\u7ed9\u4f60\u7684 T \u7c7b\u578b\u91cc\u9762\u52a0\u4e2a mutex \u4fdd\u62a4\u597d\u81ea\u5df1\uff0c\u800c\u4e0d\u662f\u6765\u602a\u6211\u6307\u9488\u3002 \u76f4\u63a5\u7684\u7b54\u6848\uff1a\u4ed6\u4eec\u8bf4\u7684\u662f\uff0cshared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u8fd9\u4e0d\u662f\u5e9f\u8bdd\u5417\uff1f\u6211\u53ea\u662f\u62f7\u8d1d\u53e6\u4e00\u4e2a shared_ptr\uff0c\u5bf9\u90a3\u4e2a shared_ptr \u53c8\u4e0d\u8fdb\u884c\u66f4\u6539\uff0c\u5f53\u7136\u4e0d\u4f1a\u53d1\u751f\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u6211\u81ea\u5df1\u6790\u6784\u5173\u4f60\u5176\u4ed6 shared_ptr \u4ec0\u4e48\u4e8b\uff0c\u5f53\u7136\u5c31\u6ca1\u6709\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u8fd9\u662f\u975e\u5e38\u76f4\u89c2\u7684\uff0c\u548c\u666e\u901a\u6307\u9488\u7684\u7ebf\u7a0b\u5b89\u5168\u6ca1\u6709\u4efb\u4f55\u4e0d\u540c\u3002 \u4e4b\u6240\u4ee5\u8fd9\u4e9b\u72d7\u5e01\u6559\u6750\u4f1a\u8fa9\u8bba\uff0c\u662f\u56e0\u4e3a\u4ed6\u4eec\u8001\u7231\u591a\u7ba1\u95f2\u4e8b\uff0c\u4ed6\u4eec\u4e86\u89e3\u5230 shared_ptr \u7684\u5e95\u5c42\u7ec6\u8282\u4e2d\u6709\u4e2a\u63a7\u5236\u5757\u7684\u5b58\u5728\uff0c\u800c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u9700\u8981\u4fee\u6539\u63a7\u5236\u5757\u7684\u8ba1\u6570\u503c\uff0c\u6240\u4ee5\u5b9e\u9645\u6807\u51c6\u5e93\u7684\u5b9e\u73b0\u4e2d\uff0c\u4f1a\u628a\u8fd9\u4e2a\u8ba1\u6570\u5668\u8bbe\u4e3a\u539f\u5b50\u7684\uff0c\u6700\u7ec8\u7ed3\u679c\u662f\u4f7f\u5f97 shared_ptr \u5728\u591a\u7ebf\u7a0b\u4e2d\u548c\u666e\u901a\u6307\u9488\u4e00\u6837\u5b89\u5168\u3002\u8fd9\u662f\u6807\u51c6\u5e93\u5e95\u5c42\u5b9e\u73b0\u7ec6\u8282\uff0c\u6211\u4eec\u4f5c\u4e3a\u9ad8\u5c42\u7528\u6237\u5e76\u4e0d\u9700\u8981\u8003\u8651\u4ed6\u5e95\u5c42\u5982\u4f55\u5b9e\u73b0\uff0c\u6211\u4eec\u53ea\u9700\u8981\u8bb0\u4f4f\u539f\u59cb\u6307\u9488\u600e\u6837\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0cshared_ptr \u5c31\u600e\u6837\u7ebf\u7a0b\u5b89\u5168\u3002 \u4f60\u4f1a\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5199\u5165\u540c\u4e00\u4e2a\u539f\u59cb\u6307\u9488\u5417\uff1f\u540c\u6837\u5730\uff0c\u5982\u679c\u4f60\u539f\u59cb\u6307\u9488\u4e0d\u4f1a\u72af\u9519\uff0cshared_ptr \u4e3a\u4ec0\u4e48\u4f1a\u72af\u9519\uff1f \u4f60\u53ef\u4ee5\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u540c\u4e00\u4e2a\u5168\u5c40\u7684\u539f\u59cb\u6307\u9488\u53d8\u91cf\uff0c\u540c\u6837\u5730\uff0cshared_ptr \u4e5f\u53ef\u4ee5\uff0c\u6709\u4efb\u4f55\u533a\u522b\u5417\uff1f \u53cd\u6b63\uff0cshared_ptr \u5185\u90e8\u4e13\u95e8\u4e3a\u7ebf\u7a0b\u5b89\u5168\u505a\u8fc7\u8bbe\u8ba1\uff0c\u4f60\u4e0d\u7528\u53bb\u64cd\u5fc3\u3002","title":"\u7ebf\u7a0b\u5b89\u5168\uff1f"},{"location":"no_more_new/#placement-new","text":"placement new \u548c placement delete \u4e5f\u53ef\u4ee5\u7528 std::construct_at \u548c std::destroy_at \u4ee3\u66ff\uff1a #include struct Foo { explicit Foo(int age) { ... } Foo(Foo &&) = delete; ~Foo() { ... } }; void func() { alignas(Foo) unsigned char buffer[sizeof(Foo)]; Foo *foo = std::construct_at(reinterpret_cast(buffer), 42, \"hello\"); // \u7b49\u4ef7\u4e8e new (buffer) Foo(42); ... std::destroy_at(foo); // \u7b49\u4ef7\u4e8e foo->~Foo(); } \u5728 \u5185\u5b58\u6a21\u578b\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"placement new"},{"location":"platform/","text":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 \u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC GCC Clang \u7f16\u8bd1\u5668\u9009\u9879 C++ \u6807\u51c6 \u4f18\u5316\u7b49\u7ea7 \u8c03\u8bd5\u4fe1\u606f \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f C++11 ABI \u95ee\u9898 TODO IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 TODO \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u662f\u5c06\u6e90\u4ee3\u7801 ( .cpp ) \u7f16\u8bd1\u6210\u53ef\u6267\u884c\u7a0b\u5e8f ( .exe ) \u7684\u5de5\u5177\u3002 C++ \u662f \u7f16\u8bd1\u578b\u8bed\u8a00 \uff0c\u6e90\u4ee3\u7801\u4e0d\u80fd\u76f4\u63a5\u6267\u884c\u54e6\uff01\u521a\u5f00\u59cb\u5b66\u7f16\u7a0b\u7684\u5c0f\u5f6d\u8001\u5e08\u66fe\u7ecf\u628a\u7f51\u4e0a\u7684 \u201cHello, World\u201d \u4ee3\u7801\u62f7\u8d1d\u5230 .c \u6e90\u7801\u6587\u4ef6\u4e2d\uff0c\u7136\u540e\u628a\u540e\u7f00\u540d\u6539\u6210 .exe \uff0c\u53d1\u73b0\u8fd9\u6837\u6839\u672c\u6267\u884c\u4e0d\u4e86\u2026\u2026\u540e\u6765\u624d\u77e5\u9053\u9700\u8981\u901a\u8fc7\u4e00\u79cd\u53eb\u505a \u7f16\u8bd1\u5668 \u7f16\u8bd1 .c \u6587\u4ef6\uff0c\u624d\u80fd\u5f97\u5230\u8ba1\u7b97\u673a\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 C++ \u6e90\u7801 .cpp \u662f\u5199\u7ed9\u4eba\u7c7b\u770b\u7684\uff01\u8ba1\u7b97\u673a\u5e76\u4e0d\u8ba4\u8bc6\uff0c\u8ba1\u7b97\u673a\u53ea\u8ba4\u8bc6\u4e8c\u8fdb\u5236\u7684\u673a\u5668\u7801\u3002\u8981\u628a C++ \u6e90\u7801\u8f6c\u6362\u4e3a\u8ba1\u7b97\u673a\u53ef\u4ee5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u6700\u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u6709\uff1aGCC\u3001Clang\u3001MSVC \u4fd7\u79f0\u201c\u5fa1\u4e09\u5bb6\u201d\u3002 \u8fd9\u4e9b\u7f16\u8bd1\u5668\u90fd\u652f\u6301\u4e86\u5927\u90e8\u5206 C++20 \u6807\u51c6\u548c\u5c0f\u90e8\u5206 C++23 \u6807\u51c6\uff0c\u800c C++17 \u6807\u51c6\u90fd\u662f\u5b8c\u5168\u652f\u6301\u7684\u3002 \u6709\u4eba\u8bf4\u8fc7\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f GCC\u3002\u201d GCC \u4e3b\u8981\u53ea\u5728 Linux \u548c MacOS \u7b49 Unix \u7c7b\u7cfb\u7edf\u53ef\u7528\uff0c\u4e0d\u652f\u6301 Windows \u7cfb\u7edf\u3002\u4f46\u662f GCC \u6709\u7740\u5927\u91cf\u597d\u7528\u7684\u6269\u5c55\u529f\u80fd\uff0c\u4f8b\u5982\u5927\u540d\u9f0e\u9f0e\u7684 pbds \uff08\u57fa\u4e8e\u7b56\u7565\u7684\u6570\u636e\u7ed3\u6784\uff09\uff0c\u8fd8\u6709\u5404\u79cd __attribute__ \uff0c\u5404\u79cd __builtin_ \u7cfb\u5217\u51fd\u6570\u3002\u4e0d\u8fc7\u968f\u7740\u65b0\u6807\u51c6\u7684\u51fa\u53f0\uff0c\u5f88\u591a\u539f\u672c\u5c5e\u4e8e GCC \u7684\u529f\u80fd\u90fd\u6210\u4e86\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f8b\u5982 __attribute__((warn_unused)) \u53d8\u6210\u4e86\u6807\u51c6\u7684 [[nodiscard]] \uff0c __builtin_clz \u53d8\u6210\u4e86\u6807\u51c6\u7684 std::countl_zero \uff0c __VA_OPT__ \u540d\u5b57\u90fd\u6ca1\u53d8\u5c31\u8fdb\u4e86 C++20 \u6807\u51c6\u3002 PBDS \u53c8\u79f0 \u201c\u5e73\u677f\u7535\u89c6\u201d \u4e5f\u6709 MinGW \u8fd9\u6837\u7684\u9b54\u6539\u7248 GCC \u7f16\u8bd1\u5668\uff0c\u628a GCC \u79fb\u690d\u5230\u4e86 Windows \u7cfb\u7edf\u4e0a\uff0c\u540c\u65f6\u4e5f\u80fd\u7528 GCC \u7684\u4e00\u4e9b\u7279\u6027\u3002\u4e0d\u8fc7 MinGW \u6700\u8fd1\u5df2\u7ecf\u505c\u6b62\u66f4\u65b0\uff0c\u6700\u65b0\u7684 GCC Windows \u79fb\u690d\u7248\u7531 MinGW-w64 \u7ee7\u7eed\u7ef4\u62a4\u3002 Clang \u662f\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\uff0c\u652f\u6301\u5927\u591a\u6570\u4e3b\u6d41\u5e73\u53f0\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u754c\u7684\u5fa1\u4e09\u5bb6\uff1aLinux\u3001MacOS\u3001Windows\u3002Clang \u652f\u6301\u4e86\u5f88\u5927\u4e00\u90e8\u5206 GCC \u7279\u6027\u548c\u90e8\u5206 MSVC \u7279\u6027\u3002\u5176\u6240\u5c5e\u7684 LLVM \u9879\u76ee\u66f4\u662f\u7f16\u8bd1\u5668\u9886\u57df\u7684\u4e2d\u6d41\u7825\u67f1\uff0c\u4e0d\u4ec5\u652f\u6301 C\u3001C++\u3001Objective-C\u3001Fortran \u7b49\uff0cRust \u548c Swift \u7b49\u8bed\u8a00\u4e5f\u662f\u57fa\u4e8e LLVM \u540e\u7aef\u7f16\u8bd1\u7684\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5f88\u591a\u663e\u5361\u5382\u5546\u7684 OpenGL \u9a71\u52a8\u4e5f\u662f\u57fa\u4e8e LLVM \u5b9e\u73b0\u7f16\u8bd1\u7684\u3002\u5e76\u4e14 Clang \u8eab\u517c\u6570\u804c\uff0c\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u8bd1\uff0c\u8fd8\u652f\u6301\u9759\u6001\u5206\u6790\u3002\u8bb8\u591a IDE \u5e38\u89c1\u7684\u8bed\u8a00\u670d\u52a1\u534f\u8bae (LSP) \u5c31\u662f\u57fa\u4e8e Clang \u7684\u670d\u52a1\u7248\u2014\u2014\u2014\u2014Clangd \u5b9e\u73b0\u7684 (\u4f8b\u5982\u4f60\u53ef\u4ee5\u6309 Ctrl \u70b9\u51fb\uff0c\u8df3\u8f6c\u5230\u51fd\u6570\u5b9a\u4e49\uff0c\u8fd9\u6837\u7684\u529f\u80fd\u5c31\u662f IDE \u901a\u8fc7\u8c03\u7528 Clangd \u7684 LSP \u63a5\u53e3\u5b9e\u73b0\uff09\u3002\u4e0d\u8fc7 Clang \u7684\u6027\u80fd\u4f18\u5316\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u867d\u7136\u6709\u52a9\u4e8e\u6027\u80fd\u63d0\u5347\uff0c\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u72af\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u53ef\u80fd\u4f18\u5316\u51fa\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u5982\u679c\u4f60\u8981\u5b9e\u9a8c\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u662f\u6700\u64c5\u957f\u590d\u73b0\u7684\u3002\u4e14 Clang \u5bf9\u4e00\u4e9b C++ \u65b0\u6807\u51c6\u7279\u6027\u652f\u6301\u76f8\u5bf9\u8f83\u6162\uff0c\u6ca1\u6709 GCC \u548c MSVC \u90a3\u4e48\u4e0a\u5fc3\u3002 \u4f8b\u5982 C++20 \u65e9\u5df2\u5141\u8bb8 lambda \u8868\u8fbe\u5f0f\u6355\u83b7 structural-binding \u53d8\u91cf\uff0c\u800c Clang \u81f3\u4eca\u8fd8\u6ca1\u6709\u652f\u6301\uff0c\u5c3d\u7ba1 Clang \u5df2\u7ecf\u652f\u6301\u4e86\u5f88\u591a\u5176\u4ed6 C++20 \u7279\u6027\u3002 Apple Clang \u662f\u82f9\u679c\u516c\u53f8\u81ea\u5df1\u9b54\u6539\u7684 Clang \u7248\u672c\uff0c\u53ea\u5728 MacOS \u7cfb\u7edf\u4e0a\u53ef\u7528\uff0c\u652f\u6301 Objective-C \u548c Swift \u8bed\u8a00\u3002\u4f46\u662f\u7248\u672c\u8f83\u5b98\u65b9 Clang \u843d\u540e\u4e00\u4e9b\uff0c\u5f88\u591a\u65b0\u7279\u6027\u90fd\u6ca1\u6709\u8ddf\u8fdb\uff0c\u57fa\u672c\u4e0a\u53ea\u6709\u4e13\u95e8\u4f3a\u5019\u82f9\u679c\u7684\u5f00\u53d1\u8005\u4f1a\u7528\u3002 GCC \u548c Clang \u4e5f\u652f\u6301 Objective-C\u3002 MSVC \u662f Windows \u9650\u5b9a\u7684\u7f16\u8bd1\u5668\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a MSVC \u7279\u6709\u7684\u6269\u5c55\u3002\u4e5f\u6709\u4eba\u5728 Clang \u4e0a\u9b54\u6539\u51fa\u4e86 MSVC \u517c\u5bb9\u6a21\u5f0f\uff0c\u517c\u987e Clang \u7279\u6027\u7684\u540c\u65f6\uff0c\u652f\u6301\u4e86 MSVC \u7684\u4e00\u4e9b\u7279\u6027\uff08\u4f8b\u5982 __declspec \uff09\uff0c\u53ef\u4ee5\u7f16\u8bd1\u7528\u4e86 MSVC \u7279\u6027\u7684\u4ee3\u7801\uff0c\u5373 clang-cl \uff0c\u5728\u6700\u65b0\u7684 VS2022 IDE \u4e2d\u4e5f\u96c6\u6210\u4e86 clang-cl \u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cMSVC \u7684\u4f18\u5316\u80fd\u529b\u662f\u6bd4\u8f83\u5dee\u7684\uff0c\u6bd4 GCC \u548c Clang \u90fd\u5dee\uff0c\u4f8b\u5982 MSVC \u51e0\u4e4e\u603b\u662f\u5047\u5b9a\u6240\u6709\u6307\u9488 aliasing\uff0c\u8fd9\u610f\u5473\u7740\u5f53\u9047\u5230\u5f88\u591a\u6307\u9488\u64cd\u4f5c\u7684\u5faa\u73af\u65f6\uff0c\u51e0\u4e4e\u6ca1\u6cd5\u505a\u5faa\u73af\u77e2\u91cf\u5316\u3002\u4f46\u662f\u4e5f\u4f7f\u5f97\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f Bug\uff0c\u53e6\u4e00\u65b9\u9762\uff0c\u8fd9\u4e5f\u5bfc\u81f4\u4e00\u4e9b\u53ea\u7528 MSVC \u7684\u4eba\u4e0d\u77e5\u9053\u67d0\u4e9b\u5199\u6cd5\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 Intel C++ compiler \u662f\u82f1\u7279\u5c14\u5f00\u53d1\u7684 C++ \u7f16\u8bd1\u5668\uff0c\u7531\u4e8e\u662f\u786c\u4ef6\u5382\u5546\u5f00\u53d1\u7684\uff0c\u7279\u522b\u64c5\u957f\u505a\u6027\u80fd\u4f18\u5316\u3002\u4f46\u7531\u4e8e\u66f4\u65b0\u8f83\u6162\uff0c\u57fa\u672c\u6ca1\u6709\u66f4\u4e0a\u65b0\u7279\u6027\uff0c\u4e5f\u6ca1\u4ec0\u4e48\u4eba\u5728\u7528\u4e86\u3002 \u6700\u8fd1\u4ed6\u4eec\u53c8\u51fa\u4e86\u4e2a Intel DPC++ compiler\uff0c\u652f\u6301\u6700\u65b0\u7684\u5e76\u884c\u7f16\u7a0b\u9886\u57df\u7279\u5b9a\u8bed\u8a00 SyCL\u3002 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC cl.exe main.cpp \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main.exe \u4e86\u3002 GCC g++ main.cpp -o main \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main \u4e86\u3002 Linux \u7cfb\u7edf\u7684\u53ef\u6267\u884c\u6587\u4ef6\u5e76\u6ca1\u6709\u540e\u7f00\u540d\uff0c\u6240\u4ee5\u6ca1\u6709 .exe \u540e\u7f00\u3002 Clang Windows \u4e0a\uff1a clang++.exe main.cpp -o main.exe Linux / MacOS \u4e0a\uff1a clang++ main.cpp -o main \u7f16\u8bd1\u5668\u9009\u9879 \u7f16\u8bd1\u5668\u9009\u9879\u662f\u7528\u6765\u63a7\u5236\u7f16\u8bd1\u5668\u7684\u884c\u4e3a\u7684\u3002\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u6709\u4e0d\u540c\u7684\u9009\u9879\uff0c\u8bed\u6cd5\u6709\u5fae\u5999\u7684\u4e0d\u540c\uff0c\u4f46\u5927\u81f4\u529f\u6548\u76f8\u540c\u3002 \u4f8b\u5982\u5f53\u6211\u4eec\u8bf4\u201c\u7f16\u8bd1\u8fd9\u4e2a\u6e90\u7801\u65f6\uff0c\u6211\u7528\u4e86 GCC \u7f16\u8bd1\u5668\uff0c -O3 \u548c -std=c++20 \u9009\u9879\u201d\uff0c\u8bf4\u7684\u5c31\u662f\u628a\u8fd9\u4e9b\u9009\u9879\u52a0\u5230\u4e86 g++ \u7684\u547d\u4ee4\u884c\u53c2\u6570\u4e2d\uff1a g++ -O3 -std=c++20 main.cpp -o main \u5176\u4e2d Clang \u548c GCC \u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\u5f88\u5927\u4ea4\u96c6\u3002\u800c MSVC \u57fa\u672c\u81ea\u6210\u4e00\u6d3e\u3002 Clang \u548c GCC \u7684\u9009\u9879\u90fd\u662f -xxx \u7684\u5f62\u5f0f\uff0cMSVC \u7684\u9009\u9879\u662f /xxx \u7684\u5f62\u5f0f\u3002 \u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\uff1a C++ \u6807\u51c6 \u6307\u5b9a\u8981\u9009\u7528\u7684 C++ \u6807\u51c6\u3002 Clang \u548c GCC\uff1a -std=c++98 \u3001 -std=c++03 \u3001 -std=c++11 \u3001 -std=c++14 \u3001 -std=c++17 \u3001 -std=c++20 \u3001 -std=c++23 MSVC\uff1a /std:c++98 \u3001 /std:c++11 \u3001 /std:c++14 \u3001 /std:c++17 \u3001 /std:c++20 \u3001 /std:c++latest \u4f8b\u5982\u8981\u7f16\u8bd1\u4e00\u4e2a C++20 \u6e90\u7801\u6587\u4ef6\uff0c\u5206\u522b\u7528 GCC\u3001Clang\u3001MSVC\uff1a GCC\uff08Linux\uff09\uff1a g++ -std=c++20 main.cpp -o main Clang\uff08Linux\uff09\uff1a clang++ -std=c++20 main.cpp -o main MSVC\uff08Windows\uff09\uff1a cl.exe /std:c++20 /c main.cpp \u4f18\u5316\u7b49\u7ea7 Clang \u548c GCC\uff1a -O0 \u3001 -O1 \u3001 -O2 \u3001 -O3 \u3001 -Ofast \u3001 -Os \u3001 -Oz \u3001 -Og -O0 \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u7f16\u8bd1\u901f\u5ea6\u6700\u5feb\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u5f00\u53d1\u4eba\u5458\u5185\u90e8\u8c03\u8bd5\u9636\u6bb5\u3002 -O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\uff08\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u7684\u4e0d\u53ef\u62b5\u8fbe\u4ee3\u7801\uff09\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u90e8\u5206\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\uff0c\u7f16\u8bd1\u901f\u5ea6\u8f83\u5feb\uff0c\u6267\u884c\u901f\u5ea6\u4e5f\u6bd4 -O0 \u5feb\u3002\u4f46\u662f\u4f1a\u4e22\u5931\u51fd\u6570\u7684\u884c\u53f7\u4fe1\u606f\uff0c\u5f71\u54cd\u8bf8\u5982 gdb \u7b49\u8c03\u8bd5\uff0c\u5982\u9700\u5feb\u901f\u8c03\u8bd5\u53ef\u4ee5\u7528 -Og \u9009\u9879\u3002 -O2 \uff1a\u6bd4 -O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\uff0c\u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002 -O3 \uff1a\u6bd4 -O2 \u66f4\u6fc0\u8fdb\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u590d\u6742\u7684\u5faa\u73af\u7528 SIMD \u77e2\u91cf\u6307\u4ee4\u4f18\u5316\u52a0\u901f\uff0c\u628a\u4e00\u4e9b\u590d\u6742\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u6027\u80fd\u63d0\u5347\u5f88\u5927\uff0c\u4f46\u662f\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b Bug\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u5219\u7edd\u4e0d\u4f1a\u6709\u95ee\u9898\uff0c\u5bf9\u81ea\u5df1\u7684\u4ee3\u7801\u8d28\u91cf\u6709\u81ea\u4fe1\u5c31\u53ef\u4ee5\u653e\u5fc3\u5f00\uff0c\u7f16\u8bd1\u901f\u5ea6\u4e5f\u4f1a\u5f88\u6162\uff0c\u4e00\u822c\u7528\u4e8e\u7a0b\u5e8f\u6700\u7ec8\u6210\u54c1\u53d1\u5e03\u9636\u6bb5\u3002 -Ofast \uff1a\u5728 -O3 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u5bf9\u6d6e\u70b9\u6570\u7684\u8fd0\u7b97\u8fdb\u884c\u66f4\u6df1\u5c42\u6b21\u7684\u4f18\u5316\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b\u6d6e\u70b9\u6570\u8ba1\u7b97\u7ed3\u679c\u4e0d\u51c6\u786e\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u4e0d\u6d89\u53ca\u5230 NaN \u548c Inf \u7684\u5904\u7406\uff0c\u90a3\u4e48 -Ofast \u4e0d\u4f1a\u6709\u592a\u5927\u7684\u95ee\u9898\uff0c\u4e00\u822c\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u9886\u57df\u7684\u7ec8\u6781\u6027\u80fd\u4f18\u5316\u3002 -Os \uff1a\u5728 -O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u6bd4 -O0 \u3001 -O1 \u3001 -O2 \u90fd\u8981\u5c0f\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Oz \uff1a\u5728 -Os \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u628a\u4ee3\u7801\u538b\u7f29\uff0c\u53ef\u80fd\u628a\u672c\u53ef\u4ee5\u4e00\u6761\u5927\u6307\u4ee4\u5b8c\u6210\u7684\u4efb\u52a1\u4e5f\u62c6\u6210\u591a\u6761\u5c0f\u6307\u4ee4\uff0c\u4e3a\u4e86\u7f29\u5c0f\u5c3a\u5bf8\u727a\u7272\u8fd0\u884c\u65f6\u6027\u80fd\uff0c\u5927\u5e45\u51cf\u5c11\u4e86\u51fd\u6570\u5185\u8054\u7684\u673a\u4f1a\uff0c\u6709\u65f6\u7528\u4e8e\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Og \uff1a\u5728 -O0 \u7684\u57fa\u7840\u4e0a\uff0c\u5c3d\u53ef\u80fd\u4fdd\u7559\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\uff0c\u4e0d\u505a\u7834\u574f\u51fd\u6570\u884c\u53f7\u7b49\u4fe1\u606f\u7684\u4f18\u5316\uff0c\u5efa\u8bae\u914d\u5408\u4ea7\u751f\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\u7684 -g \u9009\u9879\u4f7f\u7528\u3002\u4f46\u8fd8\u662f\u4f1a\u505a\u4e00\u4e9b\u7b80\u5355\u7684\u4f18\u5316\uff0c\u6bd4 -O0 \u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002\u4f46 -Og \u7684\u6240\u6709\u4f18\u5316\u90fd\u4e0d\u4f1a\u6d89\u53ca\u5230\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u6b64\u975e\u5e38\u9002\u5408\u8c03\u8bd5\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u4f46\u662f\u7531\u4e8e\u63d2\u5165\u4e86\u8c03\u8bd5\u4fe1\u606f\uff0c\u6700\u7ec8\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4f1a\u53d8\u5f97\u5f88\u5927\uff0c\u4e00\u822c\u5728\u5f00\u53d1\u4eba\u5458\u8c03\u8bd5\u65f6\u4f7f\u7528\u3002 MSVC\uff1a /Od \u3001 /O1 \u3001 /O2 \u3001 /Ox \u3001 /Ob1 \u3001 /Ob2 \u3001 /Os /Od \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u8c03\u8bd5\u9636\u6bb5\u3002 /O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\u3002 /O2 \uff1a\u6bd4 /O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u8fd8\u4f1a\u5c1d\u8bd5\u628a\u4e00\u4e9b\u5faa\u73af\u77e2\u91cf\u5316\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ox \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u4f18\u5316\uff0c\u4f46\u662f\u4e0d\u4f1a\u5bfc\u81f4\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ob1 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\u3002 /Ob2 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\uff0c\u4f46\u662f\u4f1a\u6269\u5927\u5185\u8054\u8303\u56f4\uff0c\u4e00\u822c\u6bd4 /Ob1 \u66f4\u5feb\uff0c\u4f46\u662f\u4e5f\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u3002 /Os \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 \u6ce8\u610f\uff1a\u51fd\u6570\u5185\u8054\u662f\u4e00\u79cd\u4f18\u5316\u7b56\u7565\uff0c\u548c inline \u5173\u952e\u5b57\u6beb\u65e0\u5173\u7cfb\uff0c\u8bf7\u770b\u7a0d\u540e\u63a8\u51fa\u7684\u7b26\u53f7\u94fe\u63a5\u4e13\u9898\u8bfe\u7a0b\u6216\u62a2\u5148\u770b \u5c0f\u5f6d\u8001\u5e08\u89c6\u9891 \u4e86\u89e3 inline \uff0c\u4ee5\u540e\u7684\u6027\u80fd\u4f18\u5316\u4e13\u9898\u8bfe\u7a0b\u4e5f\u4f1a\u4ecb\u7ecd\u51fd\u6570\u5185\u8054\u4f18\u5316\u7684\u6210\u529f\u6848\u4f8b\u3002 \u8c03\u8bd5\u4fe1\u606f Clang \u548c GCC\uff1a -g \u3001 -g0 \u3001 -g1 \u3001 -g2 \u3001 -g3 MSVC\uff1a /Z7 \u3001 /Zi \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f Clang \u548c GCC\uff1a -Dmacro=value MSVC\uff1a /Dmacro=value \u4f8b\u5982\uff1a \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 libstdc++ \u662f GCC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e GCC \u662f Linux \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libstdc++ \u4e5f\u662f Linux \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002\u4f60\u53ef\u4ee5\u5728\u8fd9\u91cc\u770b\u5230\u4ed6\u7684\u6e90\u7801\uff1ahttps://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3 libc++ \u662f Clang \u5b98\u65b9\u7f16\u5199\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e Clang \u662f MacOS \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libc++ \u4e5f\u662f MacOS \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002libc++ \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u65e9\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\u3002\u9879\u76ee\u7684\u5f00\u6e90\u5730\u5740\u662f\uff1ahttps://github.com/llvm/llvm-project/tree/main/libcxx MSVC STL \u662f MSVC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e MSVC \u662f Windows \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 MSVC STL \u4e5f\u662f Windows \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002MSVC STL \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u665a\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\uff0c\u4f46\u662f\u73b0\u5728\u4ed6\u5df2\u7ecf\u5b8c\u5168\u652f\u6301 C++20\uff0c\u5e76\u4e14\u4e5f\u5b8c\u5168\u5f00\u6e90\u4e86\uff1ahttps://github.com/microsoft/STL \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6807\u51c6\u5e93\u548c\u7f16\u8bd1\u5668\u5e76\u4e0d\u662f\u7ed1\u5b9a\u7684\uff0c\u4f8b\u5982 Clang \u53ef\u4ee5\u7528 libstdc++ \u6216 MSVC STL\uff0cGCC \u4e5f\u53ef\u4ee5\u88ab\u914d\u7f6e\u4f7f\u7528 libc++\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0cClang \u9ed8\u8ba4\u7528\u7684\u5c31\u662f libstdc++\u3002\u9700\u8981\u4e3a Clang \u6307\u5b9a -stdlib=libc++ \u9009\u9879\uff0c\u624d\u80fd\u4f7f\u7528\u3002 \u725b\u5934\u4eba\u7b11\u8bdd\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u6807\u51c6\u5e93\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f libstdc++\u3002\u56e0\u4e3a\u5373\u4f7f\u4ed6\u7684\u7f16\u8bd1\u5668\u662f Clang\uff0c\u4ed6\u7528\u7684\u5927\u6982\u7387\u4f9d\u7136\u662f libstdc++\u3002\u201d \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f TODO C++11 ABI \u95ee\u9898 \u5728\u4e00\u4e9b\u7279\u522b\u53e4\u8001\u7684\u53d1\u884c\u7248\u4e0a\uff08\u6bd4\u5982 Ubuntu 16.04\u3001CentOS\uff09\uff0c\u4ed6\u4eec\u7684\u6807\u51c6\u5e93\u4e0d\u652f\u6301 C++11\uff0c\u53ef\u4ee5\u5f00\u542f\u8fd9\u4e2a\u5b8f\uff1a #define _GLIBCXX_USE_CXX11_ABI 0 \u6216\u8005\u547d\u4ee4\u884c\u9009\u9879 -D_GLIBCXX_USE_CXX11_ABI=0 \u3002 \u4e3a\u4e86\u66f4\u597d\u7684\u5b66\u4e60\u73b0\u4ee3 C++\uff0c\u8fd8\u662f\u5efa\u8bae\u5b89\u88c5\u65b0\u7684\u53d1\u884c\u7248\u3002","title":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9"},{"location":"platform/#_1","text":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC GCC Clang \u7f16\u8bd1\u5668\u9009\u9879 C++ \u6807\u51c6 \u4f18\u5316\u7b49\u7ea7 \u8c03\u8bd5\u4fe1\u606f \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f C++11 ABI \u95ee\u9898 TODO","title":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9"},{"location":"platform/#ide","text":"TODO","title":"IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01"},{"location":"platform/#_2","text":"\u7f16\u8bd1\u5668\u662f\u5c06\u6e90\u4ee3\u7801 ( .cpp ) \u7f16\u8bd1\u6210\u53ef\u6267\u884c\u7a0b\u5e8f ( .exe ) \u7684\u5de5\u5177\u3002 C++ \u662f \u7f16\u8bd1\u578b\u8bed\u8a00 \uff0c\u6e90\u4ee3\u7801\u4e0d\u80fd\u76f4\u63a5\u6267\u884c\u54e6\uff01\u521a\u5f00\u59cb\u5b66\u7f16\u7a0b\u7684\u5c0f\u5f6d\u8001\u5e08\u66fe\u7ecf\u628a\u7f51\u4e0a\u7684 \u201cHello, World\u201d \u4ee3\u7801\u62f7\u8d1d\u5230 .c \u6e90\u7801\u6587\u4ef6\u4e2d\uff0c\u7136\u540e\u628a\u540e\u7f00\u540d\u6539\u6210 .exe \uff0c\u53d1\u73b0\u8fd9\u6837\u6839\u672c\u6267\u884c\u4e0d\u4e86\u2026\u2026\u540e\u6765\u624d\u77e5\u9053\u9700\u8981\u901a\u8fc7\u4e00\u79cd\u53eb\u505a \u7f16\u8bd1\u5668 \u7f16\u8bd1 .c \u6587\u4ef6\uff0c\u624d\u80fd\u5f97\u5230\u8ba1\u7b97\u673a\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 C++ \u6e90\u7801 .cpp \u662f\u5199\u7ed9\u4eba\u7c7b\u770b\u7684\uff01\u8ba1\u7b97\u673a\u5e76\u4e0d\u8ba4\u8bc6\uff0c\u8ba1\u7b97\u673a\u53ea\u8ba4\u8bc6\u4e8c\u8fdb\u5236\u7684\u673a\u5668\u7801\u3002\u8981\u628a C++ \u6e90\u7801\u8f6c\u6362\u4e3a\u8ba1\u7b97\u673a\u53ef\u4ee5\u6267\u884c\u7684\u673a\u5668\u7801\u3002","title":"\u7f16\u8bd1\u5668\u662f\uff1f"},{"location":"platform/#_3","text":"\u6700\u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u6709\uff1aGCC\u3001Clang\u3001MSVC \u4fd7\u79f0\u201c\u5fa1\u4e09\u5bb6\u201d\u3002 \u8fd9\u4e9b\u7f16\u8bd1\u5668\u90fd\u652f\u6301\u4e86\u5927\u90e8\u5206 C++20 \u6807\u51c6\u548c\u5c0f\u90e8\u5206 C++23 \u6807\u51c6\uff0c\u800c C++17 \u6807\u51c6\u90fd\u662f\u5b8c\u5168\u652f\u6301\u7684\u3002 \u6709\u4eba\u8bf4\u8fc7\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f GCC\u3002\u201d GCC \u4e3b\u8981\u53ea\u5728 Linux \u548c MacOS \u7b49 Unix \u7c7b\u7cfb\u7edf\u53ef\u7528\uff0c\u4e0d\u652f\u6301 Windows \u7cfb\u7edf\u3002\u4f46\u662f GCC \u6709\u7740\u5927\u91cf\u597d\u7528\u7684\u6269\u5c55\u529f\u80fd\uff0c\u4f8b\u5982\u5927\u540d\u9f0e\u9f0e\u7684 pbds \uff08\u57fa\u4e8e\u7b56\u7565\u7684\u6570\u636e\u7ed3\u6784\uff09\uff0c\u8fd8\u6709\u5404\u79cd __attribute__ \uff0c\u5404\u79cd __builtin_ \u7cfb\u5217\u51fd\u6570\u3002\u4e0d\u8fc7\u968f\u7740\u65b0\u6807\u51c6\u7684\u51fa\u53f0\uff0c\u5f88\u591a\u539f\u672c\u5c5e\u4e8e GCC \u7684\u529f\u80fd\u90fd\u6210\u4e86\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f8b\u5982 __attribute__((warn_unused)) \u53d8\u6210\u4e86\u6807\u51c6\u7684 [[nodiscard]] \uff0c __builtin_clz \u53d8\u6210\u4e86\u6807\u51c6\u7684 std::countl_zero \uff0c __VA_OPT__ \u540d\u5b57\u90fd\u6ca1\u53d8\u5c31\u8fdb\u4e86 C++20 \u6807\u51c6\u3002 PBDS \u53c8\u79f0 \u201c\u5e73\u677f\u7535\u89c6\u201d \u4e5f\u6709 MinGW \u8fd9\u6837\u7684\u9b54\u6539\u7248 GCC \u7f16\u8bd1\u5668\uff0c\u628a GCC \u79fb\u690d\u5230\u4e86 Windows \u7cfb\u7edf\u4e0a\uff0c\u540c\u65f6\u4e5f\u80fd\u7528 GCC \u7684\u4e00\u4e9b\u7279\u6027\u3002\u4e0d\u8fc7 MinGW \u6700\u8fd1\u5df2\u7ecf\u505c\u6b62\u66f4\u65b0\uff0c\u6700\u65b0\u7684 GCC Windows \u79fb\u690d\u7248\u7531 MinGW-w64 \u7ee7\u7eed\u7ef4\u62a4\u3002 Clang \u662f\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\uff0c\u652f\u6301\u5927\u591a\u6570\u4e3b\u6d41\u5e73\u53f0\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u754c\u7684\u5fa1\u4e09\u5bb6\uff1aLinux\u3001MacOS\u3001Windows\u3002Clang \u652f\u6301\u4e86\u5f88\u5927\u4e00\u90e8\u5206 GCC \u7279\u6027\u548c\u90e8\u5206 MSVC \u7279\u6027\u3002\u5176\u6240\u5c5e\u7684 LLVM \u9879\u76ee\u66f4\u662f\u7f16\u8bd1\u5668\u9886\u57df\u7684\u4e2d\u6d41\u7825\u67f1\uff0c\u4e0d\u4ec5\u652f\u6301 C\u3001C++\u3001Objective-C\u3001Fortran \u7b49\uff0cRust \u548c Swift \u7b49\u8bed\u8a00\u4e5f\u662f\u57fa\u4e8e LLVM \u540e\u7aef\u7f16\u8bd1\u7684\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5f88\u591a\u663e\u5361\u5382\u5546\u7684 OpenGL \u9a71\u52a8\u4e5f\u662f\u57fa\u4e8e LLVM \u5b9e\u73b0\u7f16\u8bd1\u7684\u3002\u5e76\u4e14 Clang \u8eab\u517c\u6570\u804c\uff0c\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u8bd1\uff0c\u8fd8\u652f\u6301\u9759\u6001\u5206\u6790\u3002\u8bb8\u591a IDE \u5e38\u89c1\u7684\u8bed\u8a00\u670d\u52a1\u534f\u8bae (LSP) \u5c31\u662f\u57fa\u4e8e Clang \u7684\u670d\u52a1\u7248\u2014\u2014\u2014\u2014Clangd \u5b9e\u73b0\u7684 (\u4f8b\u5982\u4f60\u53ef\u4ee5\u6309 Ctrl \u70b9\u51fb\uff0c\u8df3\u8f6c\u5230\u51fd\u6570\u5b9a\u4e49\uff0c\u8fd9\u6837\u7684\u529f\u80fd\u5c31\u662f IDE \u901a\u8fc7\u8c03\u7528 Clangd \u7684 LSP \u63a5\u53e3\u5b9e\u73b0\uff09\u3002\u4e0d\u8fc7 Clang \u7684\u6027\u80fd\u4f18\u5316\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u867d\u7136\u6709\u52a9\u4e8e\u6027\u80fd\u63d0\u5347\uff0c\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u72af\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u53ef\u80fd\u4f18\u5316\u51fa\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u5982\u679c\u4f60\u8981\u5b9e\u9a8c\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u662f\u6700\u64c5\u957f\u590d\u73b0\u7684\u3002\u4e14 Clang \u5bf9\u4e00\u4e9b C++ \u65b0\u6807\u51c6\u7279\u6027\u652f\u6301\u76f8\u5bf9\u8f83\u6162\uff0c\u6ca1\u6709 GCC \u548c MSVC \u90a3\u4e48\u4e0a\u5fc3\u3002 \u4f8b\u5982 C++20 \u65e9\u5df2\u5141\u8bb8 lambda \u8868\u8fbe\u5f0f\u6355\u83b7 structural-binding \u53d8\u91cf\uff0c\u800c Clang \u81f3\u4eca\u8fd8\u6ca1\u6709\u652f\u6301\uff0c\u5c3d\u7ba1 Clang \u5df2\u7ecf\u652f\u6301\u4e86\u5f88\u591a\u5176\u4ed6 C++20 \u7279\u6027\u3002 Apple Clang \u662f\u82f9\u679c\u516c\u53f8\u81ea\u5df1\u9b54\u6539\u7684 Clang \u7248\u672c\uff0c\u53ea\u5728 MacOS \u7cfb\u7edf\u4e0a\u53ef\u7528\uff0c\u652f\u6301 Objective-C \u548c Swift \u8bed\u8a00\u3002\u4f46\u662f\u7248\u672c\u8f83\u5b98\u65b9 Clang \u843d\u540e\u4e00\u4e9b\uff0c\u5f88\u591a\u65b0\u7279\u6027\u90fd\u6ca1\u6709\u8ddf\u8fdb\uff0c\u57fa\u672c\u4e0a\u53ea\u6709\u4e13\u95e8\u4f3a\u5019\u82f9\u679c\u7684\u5f00\u53d1\u8005\u4f1a\u7528\u3002 GCC \u548c Clang \u4e5f\u652f\u6301 Objective-C\u3002 MSVC \u662f Windows \u9650\u5b9a\u7684\u7f16\u8bd1\u5668\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a MSVC \u7279\u6709\u7684\u6269\u5c55\u3002\u4e5f\u6709\u4eba\u5728 Clang \u4e0a\u9b54\u6539\u51fa\u4e86 MSVC \u517c\u5bb9\u6a21\u5f0f\uff0c\u517c\u987e Clang \u7279\u6027\u7684\u540c\u65f6\uff0c\u652f\u6301\u4e86 MSVC \u7684\u4e00\u4e9b\u7279\u6027\uff08\u4f8b\u5982 __declspec \uff09\uff0c\u53ef\u4ee5\u7f16\u8bd1\u7528\u4e86 MSVC \u7279\u6027\u7684\u4ee3\u7801\uff0c\u5373 clang-cl \uff0c\u5728\u6700\u65b0\u7684 VS2022 IDE \u4e2d\u4e5f\u96c6\u6210\u4e86 clang-cl \u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cMSVC \u7684\u4f18\u5316\u80fd\u529b\u662f\u6bd4\u8f83\u5dee\u7684\uff0c\u6bd4 GCC \u548c Clang \u90fd\u5dee\uff0c\u4f8b\u5982 MSVC \u51e0\u4e4e\u603b\u662f\u5047\u5b9a\u6240\u6709\u6307\u9488 aliasing\uff0c\u8fd9\u610f\u5473\u7740\u5f53\u9047\u5230\u5f88\u591a\u6307\u9488\u64cd\u4f5c\u7684\u5faa\u73af\u65f6\uff0c\u51e0\u4e4e\u6ca1\u6cd5\u505a\u5faa\u73af\u77e2\u91cf\u5316\u3002\u4f46\u662f\u4e5f\u4f7f\u5f97\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f Bug\uff0c\u53e6\u4e00\u65b9\u9762\uff0c\u8fd9\u4e5f\u5bfc\u81f4\u4e00\u4e9b\u53ea\u7528 MSVC \u7684\u4eba\u4e0d\u77e5\u9053\u67d0\u4e9b\u5199\u6cd5\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 Intel C++ compiler \u662f\u82f1\u7279\u5c14\u5f00\u53d1\u7684 C++ \u7f16\u8bd1\u5668\uff0c\u7531\u4e8e\u662f\u786c\u4ef6\u5382\u5546\u5f00\u53d1\u7684\uff0c\u7279\u522b\u64c5\u957f\u505a\u6027\u80fd\u4f18\u5316\u3002\u4f46\u7531\u4e8e\u66f4\u65b0\u8f83\u6162\uff0c\u57fa\u672c\u6ca1\u6709\u66f4\u4e0a\u65b0\u7279\u6027\uff0c\u4e5f\u6ca1\u4ec0\u4e48\u4eba\u5728\u7528\u4e86\u3002 \u6700\u8fd1\u4ed6\u4eec\u53c8\u51fa\u4e86\u4e2a Intel DPC++ compiler\uff0c\u652f\u6301\u6700\u65b0\u7684\u5e76\u884c\u7f16\u7a0b\u9886\u57df\u7279\u5b9a\u8bed\u8a00 SyCL\u3002","title":"\u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6"},{"location":"platform/#_4","text":"","title":"\u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801"},{"location":"platform/#msvc","text":"cl.exe main.cpp \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main.exe \u4e86\u3002","title":"MSVC"},{"location":"platform/#gcc","text":"g++ main.cpp -o main \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main \u4e86\u3002 Linux \u7cfb\u7edf\u7684\u53ef\u6267\u884c\u6587\u4ef6\u5e76\u6ca1\u6709\u540e\u7f00\u540d\uff0c\u6240\u4ee5\u6ca1\u6709 .exe \u540e\u7f00\u3002","title":"GCC"},{"location":"platform/#clang","text":"Windows \u4e0a\uff1a clang++.exe main.cpp -o main.exe Linux / MacOS \u4e0a\uff1a clang++ main.cpp -o main","title":"Clang"},{"location":"platform/#_5","text":"\u7f16\u8bd1\u5668\u9009\u9879\u662f\u7528\u6765\u63a7\u5236\u7f16\u8bd1\u5668\u7684\u884c\u4e3a\u7684\u3002\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u6709\u4e0d\u540c\u7684\u9009\u9879\uff0c\u8bed\u6cd5\u6709\u5fae\u5999\u7684\u4e0d\u540c\uff0c\u4f46\u5927\u81f4\u529f\u6548\u76f8\u540c\u3002 \u4f8b\u5982\u5f53\u6211\u4eec\u8bf4\u201c\u7f16\u8bd1\u8fd9\u4e2a\u6e90\u7801\u65f6\uff0c\u6211\u7528\u4e86 GCC \u7f16\u8bd1\u5668\uff0c -O3 \u548c -std=c++20 \u9009\u9879\u201d\uff0c\u8bf4\u7684\u5c31\u662f\u628a\u8fd9\u4e9b\u9009\u9879\u52a0\u5230\u4e86 g++ \u7684\u547d\u4ee4\u884c\u53c2\u6570\u4e2d\uff1a g++ -O3 -std=c++20 main.cpp -o main \u5176\u4e2d Clang \u548c GCC \u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\u5f88\u5927\u4ea4\u96c6\u3002\u800c MSVC \u57fa\u672c\u81ea\u6210\u4e00\u6d3e\u3002 Clang \u548c GCC \u7684\u9009\u9879\u90fd\u662f -xxx \u7684\u5f62\u5f0f\uff0cMSVC \u7684\u9009\u9879\u662f /xxx \u7684\u5f62\u5f0f\u3002 \u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\uff1a","title":"\u7f16\u8bd1\u5668\u9009\u9879"},{"location":"platform/#c","text":"\u6307\u5b9a\u8981\u9009\u7528\u7684 C++ \u6807\u51c6\u3002 Clang \u548c GCC\uff1a -std=c++98 \u3001 -std=c++03 \u3001 -std=c++11 \u3001 -std=c++14 \u3001 -std=c++17 \u3001 -std=c++20 \u3001 -std=c++23 MSVC\uff1a /std:c++98 \u3001 /std:c++11 \u3001 /std:c++14 \u3001 /std:c++17 \u3001 /std:c++20 \u3001 /std:c++latest \u4f8b\u5982\u8981\u7f16\u8bd1\u4e00\u4e2a C++20 \u6e90\u7801\u6587\u4ef6\uff0c\u5206\u522b\u7528 GCC\u3001Clang\u3001MSVC\uff1a GCC\uff08Linux\uff09\uff1a g++ -std=c++20 main.cpp -o main Clang\uff08Linux\uff09\uff1a clang++ -std=c++20 main.cpp -o main MSVC\uff08Windows\uff09\uff1a cl.exe /std:c++20 /c main.cpp","title":"C++ \u6807\u51c6"},{"location":"platform/#_6","text":"Clang \u548c GCC\uff1a -O0 \u3001 -O1 \u3001 -O2 \u3001 -O3 \u3001 -Ofast \u3001 -Os \u3001 -Oz \u3001 -Og -O0 \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u7f16\u8bd1\u901f\u5ea6\u6700\u5feb\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u5f00\u53d1\u4eba\u5458\u5185\u90e8\u8c03\u8bd5\u9636\u6bb5\u3002 -O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\uff08\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u7684\u4e0d\u53ef\u62b5\u8fbe\u4ee3\u7801\uff09\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u90e8\u5206\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\uff0c\u7f16\u8bd1\u901f\u5ea6\u8f83\u5feb\uff0c\u6267\u884c\u901f\u5ea6\u4e5f\u6bd4 -O0 \u5feb\u3002\u4f46\u662f\u4f1a\u4e22\u5931\u51fd\u6570\u7684\u884c\u53f7\u4fe1\u606f\uff0c\u5f71\u54cd\u8bf8\u5982 gdb \u7b49\u8c03\u8bd5\uff0c\u5982\u9700\u5feb\u901f\u8c03\u8bd5\u53ef\u4ee5\u7528 -Og \u9009\u9879\u3002 -O2 \uff1a\u6bd4 -O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\uff0c\u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002 -O3 \uff1a\u6bd4 -O2 \u66f4\u6fc0\u8fdb\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u590d\u6742\u7684\u5faa\u73af\u7528 SIMD \u77e2\u91cf\u6307\u4ee4\u4f18\u5316\u52a0\u901f\uff0c\u628a\u4e00\u4e9b\u590d\u6742\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u6027\u80fd\u63d0\u5347\u5f88\u5927\uff0c\u4f46\u662f\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b Bug\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u5219\u7edd\u4e0d\u4f1a\u6709\u95ee\u9898\uff0c\u5bf9\u81ea\u5df1\u7684\u4ee3\u7801\u8d28\u91cf\u6709\u81ea\u4fe1\u5c31\u53ef\u4ee5\u653e\u5fc3\u5f00\uff0c\u7f16\u8bd1\u901f\u5ea6\u4e5f\u4f1a\u5f88\u6162\uff0c\u4e00\u822c\u7528\u4e8e\u7a0b\u5e8f\u6700\u7ec8\u6210\u54c1\u53d1\u5e03\u9636\u6bb5\u3002 -Ofast \uff1a\u5728 -O3 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u5bf9\u6d6e\u70b9\u6570\u7684\u8fd0\u7b97\u8fdb\u884c\u66f4\u6df1\u5c42\u6b21\u7684\u4f18\u5316\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b\u6d6e\u70b9\u6570\u8ba1\u7b97\u7ed3\u679c\u4e0d\u51c6\u786e\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u4e0d\u6d89\u53ca\u5230 NaN \u548c Inf \u7684\u5904\u7406\uff0c\u90a3\u4e48 -Ofast \u4e0d\u4f1a\u6709\u592a\u5927\u7684\u95ee\u9898\uff0c\u4e00\u822c\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u9886\u57df\u7684\u7ec8\u6781\u6027\u80fd\u4f18\u5316\u3002 -Os \uff1a\u5728 -O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u6bd4 -O0 \u3001 -O1 \u3001 -O2 \u90fd\u8981\u5c0f\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Oz \uff1a\u5728 -Os \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u628a\u4ee3\u7801\u538b\u7f29\uff0c\u53ef\u80fd\u628a\u672c\u53ef\u4ee5\u4e00\u6761\u5927\u6307\u4ee4\u5b8c\u6210\u7684\u4efb\u52a1\u4e5f\u62c6\u6210\u591a\u6761\u5c0f\u6307\u4ee4\uff0c\u4e3a\u4e86\u7f29\u5c0f\u5c3a\u5bf8\u727a\u7272\u8fd0\u884c\u65f6\u6027\u80fd\uff0c\u5927\u5e45\u51cf\u5c11\u4e86\u51fd\u6570\u5185\u8054\u7684\u673a\u4f1a\uff0c\u6709\u65f6\u7528\u4e8e\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Og \uff1a\u5728 -O0 \u7684\u57fa\u7840\u4e0a\uff0c\u5c3d\u53ef\u80fd\u4fdd\u7559\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\uff0c\u4e0d\u505a\u7834\u574f\u51fd\u6570\u884c\u53f7\u7b49\u4fe1\u606f\u7684\u4f18\u5316\uff0c\u5efa\u8bae\u914d\u5408\u4ea7\u751f\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\u7684 -g \u9009\u9879\u4f7f\u7528\u3002\u4f46\u8fd8\u662f\u4f1a\u505a\u4e00\u4e9b\u7b80\u5355\u7684\u4f18\u5316\uff0c\u6bd4 -O0 \u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002\u4f46 -Og \u7684\u6240\u6709\u4f18\u5316\u90fd\u4e0d\u4f1a\u6d89\u53ca\u5230\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u6b64\u975e\u5e38\u9002\u5408\u8c03\u8bd5\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u4f46\u662f\u7531\u4e8e\u63d2\u5165\u4e86\u8c03\u8bd5\u4fe1\u606f\uff0c\u6700\u7ec8\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4f1a\u53d8\u5f97\u5f88\u5927\uff0c\u4e00\u822c\u5728\u5f00\u53d1\u4eba\u5458\u8c03\u8bd5\u65f6\u4f7f\u7528\u3002 MSVC\uff1a /Od \u3001 /O1 \u3001 /O2 \u3001 /Ox \u3001 /Ob1 \u3001 /Ob2 \u3001 /Os /Od \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u8c03\u8bd5\u9636\u6bb5\u3002 /O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\u3002 /O2 \uff1a\u6bd4 /O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u8fd8\u4f1a\u5c1d\u8bd5\u628a\u4e00\u4e9b\u5faa\u73af\u77e2\u91cf\u5316\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ox \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u4f18\u5316\uff0c\u4f46\u662f\u4e0d\u4f1a\u5bfc\u81f4\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ob1 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\u3002 /Ob2 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\uff0c\u4f46\u662f\u4f1a\u6269\u5927\u5185\u8054\u8303\u56f4\uff0c\u4e00\u822c\u6bd4 /Ob1 \u66f4\u5feb\uff0c\u4f46\u662f\u4e5f\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u3002 /Os \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 \u6ce8\u610f\uff1a\u51fd\u6570\u5185\u8054\u662f\u4e00\u79cd\u4f18\u5316\u7b56\u7565\uff0c\u548c inline \u5173\u952e\u5b57\u6beb\u65e0\u5173\u7cfb\uff0c\u8bf7\u770b\u7a0d\u540e\u63a8\u51fa\u7684\u7b26\u53f7\u94fe\u63a5\u4e13\u9898\u8bfe\u7a0b\u6216\u62a2\u5148\u770b \u5c0f\u5f6d\u8001\u5e08\u89c6\u9891 \u4e86\u89e3 inline \uff0c\u4ee5\u540e\u7684\u6027\u80fd\u4f18\u5316\u4e13\u9898\u8bfe\u7a0b\u4e5f\u4f1a\u4ecb\u7ecd\u51fd\u6570\u5185\u8054\u4f18\u5316\u7684\u6210\u529f\u6848\u4f8b\u3002","title":"\u4f18\u5316\u7b49\u7ea7"},{"location":"platform/#_7","text":"Clang \u548c GCC\uff1a -g \u3001 -g0 \u3001 -g1 \u3001 -g2 \u3001 -g3 MSVC\uff1a /Z7 \u3001 /Zi","title":"\u8c03\u8bd5\u4fe1\u606f"},{"location":"platform/#_8","text":"","title":"\u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84"},{"location":"platform/#_9","text":"","title":"\u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93"},{"location":"platform/#_10","text":"","title":"\u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84"},{"location":"platform/#_11","text":"Clang \u548c GCC\uff1a -Dmacro=value MSVC\uff1a /Dmacro=value \u4f8b\u5982\uff1a","title":"\u5b9a\u4e49\u5b8f"},{"location":"platform/#_12","text":"","title":"\u8b66\u544a\u5f00\u5173"},{"location":"platform/#_13","text":"libstdc++ \u662f GCC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e GCC \u662f Linux \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libstdc++ \u4e5f\u662f Linux \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002\u4f60\u53ef\u4ee5\u5728\u8fd9\u91cc\u770b\u5230\u4ed6\u7684\u6e90\u7801\uff1ahttps://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3 libc++ \u662f Clang \u5b98\u65b9\u7f16\u5199\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e Clang \u662f MacOS \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libc++ \u4e5f\u662f MacOS \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002libc++ \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u65e9\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\u3002\u9879\u76ee\u7684\u5f00\u6e90\u5730\u5740\u662f\uff1ahttps://github.com/llvm/llvm-project/tree/main/libcxx MSVC STL \u662f MSVC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e MSVC \u662f Windows \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 MSVC STL \u4e5f\u662f Windows \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002MSVC STL \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u665a\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\uff0c\u4f46\u662f\u73b0\u5728\u4ed6\u5df2\u7ecf\u5b8c\u5168\u652f\u6301 C++20\uff0c\u5e76\u4e14\u4e5f\u5b8c\u5168\u5f00\u6e90\u4e86\uff1ahttps://github.com/microsoft/STL \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6807\u51c6\u5e93\u548c\u7f16\u8bd1\u5668\u5e76\u4e0d\u662f\u7ed1\u5b9a\u7684\uff0c\u4f8b\u5982 Clang \u53ef\u4ee5\u7528 libstdc++ \u6216 MSVC STL\uff0cGCC \u4e5f\u53ef\u4ee5\u88ab\u914d\u7f6e\u4f7f\u7528 libc++\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0cClang \u9ed8\u8ba4\u7528\u7684\u5c31\u662f libstdc++\u3002\u9700\u8981\u4e3a Clang \u6307\u5b9a -stdlib=libc++ \u9009\u9879\uff0c\u624d\u80fd\u4f7f\u7528\u3002 \u725b\u5934\u4eba\u7b11\u8bdd\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u6807\u51c6\u5e93\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f libstdc++\u3002\u56e0\u4e3a\u5373\u4f7f\u4ed6\u7684\u7f16\u8bd1\u5668\u662f Clang\uff0c\u4ed6\u7528\u7684\u5927\u6982\u7387\u4f9d\u7136\u662f libstdc++\u3002\u201d","title":"\u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6"},{"location":"platform/#_14","text":"TODO","title":"\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f"},{"location":"platform/#c11-abi","text":"\u5728\u4e00\u4e9b\u7279\u522b\u53e4\u8001\u7684\u53d1\u884c\u7248\u4e0a\uff08\u6bd4\u5982 Ubuntu 16.04\u3001CentOS\uff09\uff0c\u4ed6\u4eec\u7684\u6807\u51c6\u5e93\u4e0d\u652f\u6301 C++11\uff0c\u53ef\u4ee5\u5f00\u542f\u8fd9\u4e2a\u5b8f\uff1a #define _GLIBCXX_USE_CXX11_ABI 0 \u6216\u8005\u547d\u4ee4\u884c\u9009\u9879 -D_GLIBCXX_USE_CXX11_ABI=0 \u3002 \u4e3a\u4e86\u66f4\u597d\u7684\u5b66\u4e60\u73b0\u4ee3 C++\uff0c\u8fd8\u662f\u5efa\u8bae\u5b89\u88c5\u65b0\u7684\u53d1\u884c\u7248\u3002","title":"C++11 ABI \u95ee\u9898"},{"location":"recommend/","text":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee \u8d44\u6e90\u63a8\u8350 hackingcpp.com learncpp.com cppreference.com godbolt.org cppinsights.io quick-bench.com github.com stackoverflow.com effective c++ \u5c0f\u5f6d\u8001\u5e08 (\u53cc\u7b19\u5b50\u4f6f\u8c2c) \u767d\u5f8b\u5e08 (mq\u767dcpp) \u9879\u76ee\u63a8\u8350 \u96c6\u5927\u6210\u8005 boost qt llvm \u73b0\u4ee3 utfcpp fmt spdlog rapidjson nlohmann-json ranges-v3 matchit.cpp \u9ad8\u6027\u80fd tbb cub cutlass thrust highway numcpp amgcl eigen \u56fe\u5f62\u5b66 sfml libigl openvdb cgal \u5b9e\u7528\u6269\u5c55 tsl-robin-map absl backward-cpp iguana magic_enum \u53e4\u4ee3 opencv nothings/stb google/benchmark jsoncpp gtest catch3 tinyxml2 poco incbin \u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b parallel101/course parallel101/opengltutor parallel101/openglslides parallel101/cppguidebook parallel101/simdtutor \u5c0f\u5f6d\u8001\u5e08\u81ea\u7814 zenustech/zeno archibate/co_async parallel101/stl1weekend archibate/mallocvis archibate/reflect-hpp archibate/debug-hpp archibate/hermes archibate/genius.nvim LanbingIce/IsaacSocket-Utility archibate/qdanmu zenustech/zeno3-poc archibate/minilog archibate/threebody-example archibate/babyjson-demo taichi-dev/taichi_three taichi-dev/taichi_blend taichi-dev/taichi.js archibate/ptina zenustech/zenoblend archibate/NBodySolver archibate/vue-class-manage-system archibate/facereco archibate/jsp-chess archibate/pysobol archibate/newos archibate/poczfx archibate/logisim archibate/newton archibate/vimrc GCC \u5efa\u8bae\u5f00\u542f\u7684\u8b66\u544a\u9009\u9879 -Wall -Wextra -Weffc++ -Werror=uninitialized -Werror=return-type -Wconversion -Wsign-compare -Werror=unused-result -Werror=suggest-override -Wzero-as-null-pointer-constant -Wmissing-declarations -Wold-style-cast -Werror=vla -Wnon-virtual-dtor","title":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee"},{"location":"recommend/#_1","text":"","title":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee"},{"location":"recommend/#_2","text":"hackingcpp.com learncpp.com cppreference.com godbolt.org cppinsights.io quick-bench.com github.com stackoverflow.com effective c++ \u5c0f\u5f6d\u8001\u5e08 (\u53cc\u7b19\u5b50\u4f6f\u8c2c) \u767d\u5f8b\u5e08 (mq\u767dcpp)","title":"\u8d44\u6e90\u63a8\u8350"},{"location":"recommend/#_3","text":"","title":"\u9879\u76ee\u63a8\u8350"},{"location":"recommend/#_4","text":"boost qt llvm","title":"\u96c6\u5927\u6210\u8005"},{"location":"recommend/#_5","text":"utfcpp fmt spdlog rapidjson nlohmann-json ranges-v3 matchit.cpp","title":"\u73b0\u4ee3"},{"location":"recommend/#_6","text":"tbb cub cutlass thrust highway numcpp amgcl eigen","title":"\u9ad8\u6027\u80fd"},{"location":"recommend/#_7","text":"sfml libigl openvdb cgal","title":"\u56fe\u5f62\u5b66"},{"location":"recommend/#_8","text":"tsl-robin-map absl backward-cpp iguana magic_enum","title":"\u5b9e\u7528\u6269\u5c55"},{"location":"recommend/#_9","text":"opencv nothings/stb google/benchmark jsoncpp gtest catch3 tinyxml2 poco incbin","title":"\u53e4\u4ee3"},{"location":"recommend/#_10","text":"parallel101/course parallel101/opengltutor parallel101/openglslides parallel101/cppguidebook parallel101/simdtutor","title":"\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b"},{"location":"recommend/#_11","text":"zenustech/zeno archibate/co_async parallel101/stl1weekend archibate/mallocvis archibate/reflect-hpp archibate/debug-hpp archibate/hermes archibate/genius.nvim LanbingIce/IsaacSocket-Utility archibate/qdanmu zenustech/zeno3-poc archibate/minilog archibate/threebody-example archibate/babyjson-demo taichi-dev/taichi_three taichi-dev/taichi_blend taichi-dev/taichi.js archibate/ptina zenustech/zenoblend archibate/NBodySolver archibate/vue-class-manage-system archibate/facereco archibate/jsp-chess archibate/pysobol archibate/newos archibate/poczfx archibate/logisim archibate/newton archibate/vimrc","title":"\u5c0f\u5f6d\u8001\u5e08\u81ea\u7814"},{"location":"recommend/#gcc","text":"-Wall -Wextra -Weffc++ -Werror=uninitialized -Werror=return-type -Wconversion -Wsign-compare -Werror=unused-result -Werror=suggest-override -Wzero-as-null-pointer-constant -Wmissing-declarations -Wold-style-cast -Werror=vla -Wnon-virtual-dtor","title":"GCC \u5efa\u8bae\u5f00\u542f\u7684\u8b66\u544a\u9009\u9879"},{"location":"stl_map/","text":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u8ba9\u9ad8\u6027\u80fd\u6570\u636e\u7ed3\u6784\u60e0\u53ca\u6bcf\u4e00\u4eba STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \u8bfe\u7a0b\u4eae\u70b9 \u8bfe\u7a0b\u5927\u7eb2 \u5b9e\u9a8c\u73af\u5883 \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 map \u7684\u903b\u8f91\u7ed3\u6784 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 map \u7684\u7269\u7406\u7ed3\u6784 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u4e8c\u53c9\u6392\u5e8f\u6811 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u5e73\u8861\u6811 \u7ea2\u9ed1\u6811 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u603b\u7ed3 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type typename \u4fee\u9970 decltype \u5927\u6cd5\u597d \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f count \u548c contains \u6ca1\u533a\u522b end \u4e0d\u80fd\u89e3\u5f15\u7528 find \u7684\u597d\u5904 C++17 \u8bed\u6cd5\u7cd6 \u9898\u5916\u8bdd \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if insert_or_assign insert_or_assign \u7684\u4f18\u52bf \u6548\u7387\u95ee\u9898 [] insert_or_assign \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u6279\u91cf insert \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u5c31\u5730\u5199\u5165\uff01 \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 assign \u51fd\u6570 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u5206\u5974 emplace emplace_hint emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 try_emplace \u66f4\u597d try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u8c03\u7528\u5f00\u9500\u5206\u6790 try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace emplace \u5bb6\u65cf\u603b\u7ed3 map \u4e0e RAII \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u6539\u67e5 \u521d\u59cb\u5316 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract \u7528\u9014\u4e3e\u4f8b insert \u8282\u70b9\u7248 insert_return_type extract + insert \u8fd0\u7528\u6848\u4f8b extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 \u6279\u91cf insert vs merge merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 std::less \u7684\u4f5c\u7528 operator() \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u5efa\u8bae\u7528 function \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u795e\u5947\u7684 multimap \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 \u8bfe\u540e\u7ec3\u4e60 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u54c8\u5e0c\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d \u54c8\u5e0c\u51b2\u7a81 (hash-collision) unordered_map \u4e0e map \u7684\u5f02\u540c \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 hash \u548c equal_to \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 \u81ea\u52a8\u53d6\u6a21 hash \u662f\u4e2a trait \u7c7b \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 \u8d1f\u8f7d\u7387\uff08load_factor\uff09 rehash \u51fd\u6570 hash \u9700\u8981\u7279\u5316 \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 \u66f4\u597d\u7684 hash_combine \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 \u5e94\u7528 \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 \u672c\u671f\u5b5d\u70b9\u603b\u7ed3 \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \ud83d\ude00\ud83d\ude00\ud83d\ude00 \u9762\u5411\u5df2\u7ecf\u4e86\u89e3\u4e00\u5b9a C++ \u8bed\u6cd5\uff0c\u6b63\u5728\u5b66\u4e60\u6807\u51c6\u5e93\u7684\u7ae5\u978b\u3002 C++ \u6807\u51c6\u5e93\u53c8\u79f0 STL\uff0c\u5305\u542b\u4e86\u5927\u91cf\u7a0b\u5e8f\u5458\u5e38\u7528\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\uff0c\u662f Bjarne Stroustrup \u9001\u7ed9\u6240\u6709 C++ \u7a0b\u5e8f\u5458\u7684\u4e00\u628a\u745e\u58eb\u519b\u5200\uff0c\u7136\u800c\u53d1\u73b0\u5f88\u591a\u7ae5\u978b\u5e76\u6ca1\u6709\u5b8c\u5168\u7528\u597d\u4ed6\uff0c\u53cd\u800c\u8fd8\u88ab\u5176\u590d\u6742\u6027\u8bef\u4f24\u4e86\u3002 \u5982\u679c\u4f60\u4e5f\u5bf9\u6807\u51c6\u5e93\u4e00\u77e5\u534a\u89e3\uff0c\u9700\u8981\u7cfb\u7edf\u5b66\u4e60\u7684\u8bdd\uff0c\u90a3\u4e48\u672c\u8bfe\u7a0b\u9002\u5408\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\u5c06\u8fd0\u7528\u4ed6\u7279\u6709\u7684\u5e7d\u9ed8\u7b54\u8fa9\u6bd4\u55bb\uff0c\u5168\u9762\u4ecb\u7ecd\u5404 STL \u5bb9\u5668\u7684\u6240\u6709\u7528\u6cd5\u3002\u7ed3\u5408\u4e00\u7cfb\u5217\u5b9e\u6218\u6848\u4f8b\uff0c\u5256\u6790\u5e38\u89c1\u5751\u70b9\uff0c\u4f7f\u7528\u6280\u5de7\u7b49\u3002\u5bf9\u6bd4\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u4e0e\u53ef\u8bfb\u6027\uff0c\u8fd8\u4f1a\u4e0e Python \u8bed\u8a00\u76f8\u4e92\u7c7b\u6bd4\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u79d1\u666e\u7684\u90e8\u5206\u51b7\u77e5\u8bc6\u53ef\u4ee5\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u52a0\u5206\u9879\u3002 \u672c\u8bfe\u7a0b\u53d7\u5230\u7ae5\u978b\u4e00\u81f4\u597d\u8bc4 \u8bfe\u7a0b\u4eae\u70b9 \ud83d\udc4d\ud83d\udc4d\ud83d\udc4d \u672c\u7cfb\u5217\u8bfe\u7a0b\u4e0e\u300a\u4faf\u6770\u8001\u5e08 STL \u8bfe\u300b\u7684\u533a\u522b\uff1a \u4faf\u6770\u8001\u5e08\u4ef7\u503c 2650 \u5143\uff0c\u672c\u8bfe\u7a0b\u5f55\u64ad\u4e0a\u4f20 B \u7ad9\u514d\u8d39\u89c2\u770b\uff0c\u89c2\u4f17\u53ef\u4ee5\u81ea\u884c\u9009\u62e9\u662f\u5426\u4e00\u952e\u4e09\u8fde\u3002 \u8bfe\u4ef6\u548c\u6848\u4f8b\u6e90\u7801\u5f00\u6e90\uff0c\u4e0a\u4f20\u5728 GitHub\uff0c\u53ef\u4ee5\u81ea\u5df1\u4e0b\u8f7d\u6765\u505a\u4fee\u6539\uff0c\u7136\u540e\u81ea\u5df1\u52a8\u624b\u5b9e\u9a8c\uff0c\u52a0\u6df1\u7406\u89e3\u3002 \u4faf\u6770\u8001\u5e08\u6ce8\u91cd\u7406\u8bba\u548c\u5e95\u5c42\u5b9e\u73b0\u539f\u7406\uff0c\u800c\u672c\u8bfe\u7a0b\u6ce8\u91cd\u5e94\u7528\uff0c\u7ed3\u5408\u5b9e\u6218\u6848\u4f8b\uff0c\u7740\u91cd\u5c55\u5f00\u91cd\u96be\u70b9\uff0c\u5751\u70b9\u7b49\u3002 \u5f88\u591a\u5b66\u6821\u91cc\u6559\u7684\uff0c\u767e\u5ea6\u4e0a\u641c\u7684\uff0c\u5927\u591a\u662f\u8001\u7248\u672c C++\uff0c\u5df2\u7ecf\u8fc7\u65f6\uff0c\u800c\u672c\u8bfe\u7a0b\u57fa\u4e8e\u8f83\u65b0\u7684 C++17 \u548c C++20 \u6807\u51c6\u3002 \u6709\u65f6\u5b58\u5728\u90e8\u5206 C++ \u9ad8\u7ea7\u7528\u6cd5\u8fc7\u4e8e\u8270\u6df1\uff0c\u4e0d\u80fd\u9002\u5408\u6240\u6709\u540c\u5b66\uff0c\u672c\u8bfe\u7a0b\u91c7\u7528\u56e0\u6750\u65bd\u6559\u601d\u60f3\uff1a\u5bf9\u4e8e\u65b0\u624b\uff0c\u53ef\u4ee5\u8df3\u8fc7\u770b\u4e0d\u61c2\u7684\u90e8\u5206\uff0c\u770b\u6211\u63d0\u4f9b\u7684\u201c\u4fdd\u5e95\u7528\u6cd5\u201d\uff0c\u4e0d\u4fdd\u8bc1\u9ad8\u6027\u80fd\u548c\u201c\u4f18\u96c5\u201d\uff0c\u4f46\u81f3\u5c11\u80fd\u7528\uff1b\u5bf9\u5b66\u6709\u4f59\u529b\u7684\u7ae5\u978b\uff0c\u5219\u53ef\u4ee5\u640f\u4e00\u640f\u4e0a\u9650\uff0c\u628a\u9ad8\u7ea7\u7528\u6cd5\u4e5f\u770b\u61c2\uff0c\u63d0\u5347\u9762\u8bd5\u7ade\u4e89\u529b\u3002\u603b\u4e4b\u4e0d\u8bba\u4f60\u662f\u54ea\u4e2a\u9636\u6bb5\u7684\u5b66\u4e60\u8005\uff0c\u90fd\u80fd\u4ece\u6b64\u8bfe\u7a0b\u4e2d\u83b7\u76ca\u3002 \u8bfe\u7a0b\u5927\u7eb2 \u2728\u2728\u2728 \u4e4b\u524d\u51e0\u671f\u8bfe\u7a0b\u7684\u5f55\u64ad\u5df2\u7ecf\u4e0a\u4f20\u5230\u6bd4\u7ad9\u4e86 1 \u3002 vector \u5bb9\u5668\u521d\u4f53\u9a8c & \u8fed\u4ee3\u5668\u5165\u95e8 (BV1qF411T7sd) \u4f60\u6240\u4e0d\u77e5\u9053\u7684 set \u5bb9\u5668 & \u8fed\u4ee3\u5668\u5206\u7c7b (BV1m34y157wb) string\uff0cstring_view\uff0cconst char * \u7684\u7231\u6068\u7ea0\u845b (BV1ja411M7Di) \u4e07\u80fd\u7684 map \u5bb9\u5668\u5168\u5bb6\u6876\u53ca\u5176\u5999\u7528\u4e3e\u4f8b (\u672c\u671f) \u51fd\u5b50 functor \u4e0e lambda \u8868\u8fbe\u5f0f\u77e5\u591a\u5c11 \u901a\u8fc7\u5b9e\u6218\u6848\u4f8b\u6765\u5b66\u4e60 STL \u7b97\u6cd5\u5e93 C++ \u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6d41 & \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 traits \u6280\u672f\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u8fed\u4ee3\u5668\u4e0e\u7b97\u6cd5 allocator\uff0c\u5185\u5b58\u7ba1\u7406\u4e0e\u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u5f02\u5e38\u5904\u7406\u673a\u5236\u7684\u524d\u4e16\u4eca\u751f \u5b9e\u9a8c\u73af\u5883 \u2705\u2705\u2705 \u5c0f\u5f6d\u8001\u5e08\u4e2a\u4eba\u63a8\u8350\u5b9e\u9a8c\u73af\u5883\u5982\u4e0b\uff1a \u8981\u6c42 \u2764\u2764\u2764 \ud83d\udca3\ud83d\udca3\ud83d\udca3 \ud83d\udca9\ud83d\udca9\ud83d\udca9 \ud83d\udc80\ud83d\udc80\ud83d\udc80 \u64cd\u4f5c\u7cfb\u7edf Arch Linux Ubuntu 20.04 Wendous 10 Maike OS \u77e5\u8bc6\u50a8\u5907 \u4f1a\u4e00\u70b9 C++ \u5927\u5b66 C \u8bed\u8a00 Java \u9762\u5411\u5bf9\u8c61 \u7f16\u7a0b\u5c0f\u767d \u7f16\u8bd1\u5668 GCC 9 \u4ee5\u4e0a Clang 12 VS2019 Apple Clang \u6784\u5efa\u7cfb\u7edf CMake 3.18 \u4efb\u610f C++ IDE \u5355\u6587\u4ef6\u7f16\u8bd1\u8fd0\u884c \u547d\u4ee4\u884c\u624b\u52a8\u7f16\u8bd1 \u7f16\u8f91\u5668 Vim/NeoVim CLion VS Code notepad \u6e38\u620f\u96be\u5ea6\uff1a\u2764 = \u7b80\u5355\uff0c\ud83d\udca3 = \u666e\u901a\uff0c\ud83d\udca9 = \u56f0\u96be\uff0c\ud83d\udc80 = \u5730\u72f1\u526f\u672c \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \ud83e\udd70\ud83e\udd70\ud83e\udd70 \u672c\u671f\u5b9e\u9a8c\u6e90\u7801\u5747\u516c\u5e03\u5728\uff1ahttps://github.com/parallel101/course/tree/master/slides/stl_map/experiment/ \u4f8b\u5982\u672c\u671f\u7684\u8bfe\u4ef6\u4f4d\u4e8e course/stlseries/stl_map/slides.md \u3002 \u8bfe\u4ef6\u57fa\u4e8e Mkdocs \u5f00\u53d1\uff0cMarkdown \u683c\u5f0f\u4e66\u5199\uff0c\u5728\u6d4f\u89c8\u5668\u4e2d\u663e\u793a\uff0c\u5728\u672c\u5730\u8fd0\u884c\u8bfe\u4ef6\u9700\u8981 Mkdocs \u73af\u5883\uff1a \u8fd0\u884c\u547d\u4ee4 pip install -r requirements.txt \u5373\u53ef\u81ea\u52a8\u5b89\u88c5 Mkdocs \u7b49\u6240\u9700\u4f9d\u8d56 \u8fd0\u884c\u547d\u4ee4 mkdocs serve \u5373\u53ef\u8fd0\u884c Mkdocs \u670d\u52a1 \u6d4f\u89c8\u5668\u8bbf\u95ee http://127.0.0.1:8000 \u5373\u53ef\u770b\u5230\u8bfe\u4ef6 \u5982\u679c\u4e0d\u60f3\u81ea\u5df1\u914d\u7f6e Mkdocs \u4e5f\u53ef\u4ee5\u76f4\u63a5\u4ee5\u6587\u672c\u6587\u4ef6\u683c\u5f0f\u6253\u5f00 docs/stl_map.md \u6d4f\u89c8\u8bfe\u4ef6\u3002 Mkdocs \u670d\u52a1\u8fd0\u884c\u65f6\uff0c\u4f60\u5bf9 docs/stl_map.md \u7684\u6240\u6709\u4fee\u6539\u4f1a\u7acb\u523b\u5b9e\u65f6\u663e\u73b0\u5728\u6d4f\u89c8\u5668\u4e2d\u3002 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \ud83e\udd7a\ud83e\udd7a\ud83e\udd7a \u6848\u4f8b\u6e90\u7801\u548c\u6240\u9700\u5934\u6587\u4ef6\u4f4d\u4e8e\u8bfe\u4ef6\u540c\u76ee\u5f55\u7684 course/stlseries/stl_map/experiment/ \u6587\u4ef6\u5939\u4e0b\u3002 \u5176\u4e2d main.cpp \u4ec5\u5bfc\u5165\u8fd0\u884c\u6848\u4f8b\u6240\u9700\u7684\u5934\u6587\u4ef6\uff0c\u5177\u4f53\u5404\u4e2a\u6848\u4f8b\u4ee3\u7801\u5206\u5e03\u5728 slides.md \u91cc\u3002 \u5982\u9700\u6d4b\u8bd5\u8bfe\u4ef6\u4e2d\u7684\u5177\u4f53\u4ee3\u7801\uff0c\u53ef\u4ee5\u628a slides.md \u4e2d\u7684\u6848\u4f8b\u4ee3\u7801\u7c98\u8d34\u5230 main.cpp \u7684 main \u51fd\u6570\u4f53\u4e2d\u8fdb\u884c\u5b9e\u9a8c\u3002 \u6b64\u5916\u4e3a\u4e86\u65b9\u4fbf\uff0c\u8fd8\u6709\u4e00\u4e9b\u5f62\u5982 testxxx.cpp \u7684\u6587\u4ef6\u662f\u4e00\u4e9b\u5b8c\u6574\u7684\u6d4b\u8bd5\u6848\u4f8b\uff0c\u4e0d\u7528\u4ece slides.md \u4e2d\u62f7\u8d1d\uff0c\u53ef\u76f4\u63a5\u5355\u72ec\u8fd0\u884c\u3002 \u4e3a\u4e86\u65b9\u4fbf\u540c\u5b66\u4eec\u5b9e\u9a8c\uff0c\u6240\u9700\u5934\u6587\u4ef6\u90fd\u5728\u540c\u4e00\u4e2a\u76ee\u5f55\uff0c\u6ca1\u6709\u7b2c\u4e09\u65b9\u5e93\u4f9d\u8d56\u3002\u65e2\u53ef\u4ee5\u7528 CMake \u6784\u5efa\uff0c\u4e5f\u53ef\u4ee5\u7528\u4efb\u610f\u81ea\u5df1\u559c\u6b22\u7684 IDE \u6216\u7f16\u8f91\u5668 \u5355\u6587\u4ef6\u7f16\u8bd1 \u8fd0\u884c\uff0c\u65e0\u5f3a\u5236\u8981\u6c42\uff0c\u53ea\u9700\u7f16\u8bd1\u5668\u652f\u6301 C++17 \u5373\u53ef\u3002 \u5982\u679c\u4f60\u7528 Visual Studio \u81ea\u5df1\u7684 sln \u7cfb\u7edf\u6784\u5efa\u9879\u76ee\uff0c\u8bb0\u5f97\u5f00\u542f /std:c++17 \u9009\u9879\u3002\u5982\u679c\u4f60\u7528\u6700\u65b0\u7684 Visual Studio\uff08\u5df2\u7ecf\u652f\u6301 CMake\uff09\u5219\u76f4\u63a5\u9009\u62e9\u201c\u6253\u5f00\u6587\u4ef6\u5939\u201d\u6253\u5f00\u672c\u9879\u76ee\u7684 experiment \u76ee\u5f55\u5373\u53ef\u3002 \u5728\u5b9e\u9a8c\u6e90\u7801\u4ed3\u5e93\u4e2d\uff0c\u9644\u8d60\u4e86\u4e00\u4e9b\u5b9e\u7528\u5934\u6587\u4ef6\uff0c\u540c\u978b\u4eec\u53ef\u4ee5\u4e0b\u8f7d\u6765\u7814\u7a76\uff0c\u6216\u8005\u5728\u81ea\u5df1\u7684\u9879\u76ee\u91cc\u968f\u610f\u8fd0\u7528\u3002 \u6587\u4ef6\u540d \u529f\u80fd print.h \u5185\u542b print \u51fd\u6570\uff0c\u652f\u6301\u6253\u5370\u7edd\u5927\u591a\u6570 STL \u5bb9\u5668\uff0c\u65b9\u4fbf\u8c03\u8bd5 map_get.h \u5e26\u9ed8\u8ba4\u503c\u7684 map \u8868\u9879\u67e5\u8be2\uff0c\u7a0d\u540e\u8bfe\u7a0b\u4e2d\u4f1a\u4ecb\u7ecd\u5230 ScopeProfiler.h \u57fa\u4e8e RAII \u7684\u51fd\u6570\u8017\u65f6\u7edf\u8ba1\uff0c\u7528\u4e8e\u6d4b\u91cf\u6027\u80fd OrderedMap.h \u904d\u5386\u987a\u5e8f\u59cb\u7ec8\u4fdd\u6301\u548c\u63d2\u5165\u987a\u5e8f\u4e00\u81f4\u7684\u9b54\u6539\u7248 map cppdemangle.h \u83b7\u5f97\u7c7b\u578b\u7684\u540d\u5b57\uff0c\u4ee5\u6a21\u677f\u53c2\u6570\u4f20\u5165\uff0c\u8be6\u89c1\u8be5\u6587\u4ef6\u4e2d\u7684\u6ce8\u91ca hash.h \u6bd4 std::hash \u66f4\u901a\u7528\u7684 generic_hash \u5b9e\u73b0\uff0c\u652f\u6301\u4efb\u610f\u533a\u95f4\u548c\u5143\u7ec4 bits_stdc++.h \u4eff\u7167 bits/stdc++.h \u7684\u4e07\u80fd\u5934\u6587\u4ef6\u8de8\u5e73\u53f0\u7248\uff0c\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5e93 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e int const &i // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef const int& i // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef template // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef template // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef \u4ec5\u4e3a\u4e2a\u4eba\u4e66\u5199\u4e60\u60ef\u4e0d\u540c\uff0c\u5728 C++ \u7f16\u8bd1\u5668\u770b\u6765\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u6211\u559c\u6b22\u628a const \u540e\u7f6e\uff0c\u5176\u4e00\u662f\u56e0\u4e3a\u8fd9\u6709\u5229\u4e8e\u7406\u89e3 int const * \u548c int *const \u7684\u533a\u522b\uff0c\u5982\u679c\u5199\u6210 const int * \u5c31\u4f1a\u5f88\u56f0\u60d1 const \u7a76\u7adf\u662f\u4fee\u9970\u8c01\u7684\uff0c\u800c\u7528\u6211\u7684\u5199\u6cd5\u53ea\u9700\u8981\u7b80\u5355\u7406\u89e3\u4e3a \u201cconst \u53ea\u4fee\u9970\u4ed6\u524d\u9762\u7684\u201d\u3002\u5176\u4e8c\u6211\u7ecf\u5e38\u9700\u8981\u628a\u51fd\u6570\u53c2\u6570\u4e2d T t \u4fee\u6539\u6210 T const &t \u3002\u8fde\u5728\u4e00\u8d77\u52a0\u8d77\u6765\u6bd4\u8f83\u65b9\u4fbf\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6027\u63d2\u5165 const & \u5373\u53ef\uff0c\u4e0d\u7528\u524d\u540e\u4e24\u4e2a\u5730\u65b9\u5206\u522b\u52a0 const \u548c & \uff0c\u4f60\u89c9\u5f97\u5462\uff1f using namespace std; // \u4ec5\u4e3a\u6559\u5b66\u65b9\u4fbf\u76ee\u7684\uff0c\u4e0d\u5efa\u8bae\u5728\u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4f7f\u7528 \u26a0\ufe0f \u7531\u4e8e\u4f7f\u7528\u4e86 using namespace std \uff0c\u672c\u8bfe\u7a0b\u4ee3\u7801\u4e2d\u7684 std:: \u524d\u7f00\u5747\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a map> m; erase_if(m, pred); \u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4e0d\u5efa\u8bae using namespace std \uff0c\u8bf7\u663e\u5f0f\u5199\u51fa std:: \u524d\u7f00\uff1a std::map> m; std::erase_if(m, pred); \u6211\u4eec\u81ea\u5df1\u505a\u6d4b\u8bd5\u65f6\u7ecf\u5e38\u4f1a\u7528 \u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u3002 \u53ef\u60dc\u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u5728 VS \u4e2d\u4f3c\u4e4e\u4e0d\u5b58\u5728 1 \uff0c\u56e0\u6b64\u6211\u81ea\u5df1\u5199\u4e86\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 \"bits_stdc++.h\" \u653e\u5728\u6e90\u7801\u540c\u76ee\u5f55\uff1a #include \"bits_stdc++.h\" // \u81ea\u52a8\u5bfc\u5165\u6240\u6709\u6807\u51c6\u5e93\u7684\u5934\u6587\u4ef6 \u4e0d\u8fc7\u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u8fd8\u662f\u5efa\u8bae\u6839\u636e\u9700\u8981\u4e00\u4e2a\u4e2a\u5bfc\u5165\uff0c\u4e0d\u8981\u5077\u61d2\u7528\u8fd9\u4e2a\u4e0d\u6807\u51c6\u7684\u5934\u6587\u4ef6\uff1a #include // \u5bfc\u5165 std::map, std::multimap #include // \u5bfc\u5165 std::unordered_map, std::unordered_multimap #include // \u5bfc\u5165 std::string, std::wstring #include // \u5bfc\u5165 std::set_difference, std::set_union, std::set_intersection \u7b49\u4e00\u7cfb\u5217\u5168\u5c40\u51fd\u6570 // \u4e0b\u9762\u4ee3\u7801\u4e2d\u7528\u5230\u54ea\u4e9b\u5bb9\u5668\uff0c\u5c31\u5bfc\u5165\u54ea\u4e9b\u5934\u6587\u4ef6 \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6709\u4e00\u6b21\u4e00\u4e2a\u540c\u5b66\u53d1\u7ed9\u6211\u4e00\u4efd\u6e90\u7801\u6587\u4ef6 tetreader.py\uff0c\u5176\u529f\u80fd\u662f\u8bfb\u53d6\u4e00\u4e2a tet \u683c\u5f0f\u7684\u6587\u4ef6\uff08\u56db\u9762\u4f53\u7f51\u683c\u6a21\u578b\uff09\u3002 \u4ed6\u95ee\u6211\u4e3a\u4ec0\u4e48\u4ed6\u5199\u7684\u8fd9\u4e2a Python \u4ee3\u7801\u8fd9\u4e48\u6162\uff0c\u8bfb\u53d6\u4e00\u4e2a\u7a0d\u5fae\u5927\u4e00\u70b9\u7684\u6a21\u578b\u5c31\u9700\u8981\u597d\u51e0\u79d2\uff0c\u4ed6\u8bf4\u4e45\u4ef0\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u4f18\u5316\u7684\u5927\u540d\uff0c\u60f3\u8981\u6211\u5e2e\u4ed6\u4f18\u5316\u4e00\u4e0b\uff0c\u8fd8\u95ee\u662f\u4e0d\u662f\u5e94\u8be5\u7528 C++ \u5199\u4f1a\u6bd4\u8f83\u9ad8\u6548\u4e00\u70b9\uff1f \u6211\u5e76\u4e0d\u61c2\u5f97\u56db\u9762\u4f53\uff0c\u4f46\u6027\u80fd\u4f18\u5316\u7684\u601d\u8def\u662f\u901a\u7528\u7684\u3002\u6211\u6253\u5f00\u6587\u4ef6\u770b\u4e86\u4e00\u4e0b\uff0c\u6211\u53d1\u73b0\u4ed6\u8bfb\u53d6\u65f6\u9700\u8981\u67e5\u8be2\u4e00\u4e2a\u70b9\u5468\u56f4\u6240\u6709\u7684\u9762\uff0c\u4ed6\u662f\u8fd9\u6837\u67e5\u8be2\u7684\uff1a # \u4ee5\u4e0b\u4e3a\u4ed6\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = [] for ... in ...: face_lut.append(vert_id) # O(1) \u2705 for ... in ...: face_id = face_lut.index(vert_id) # O(N) \u26a0\ufe0f \u6211\u8bf4\u4f60\u8fd9\u4e2a face_lut \u662f\u4e2a\u666e\u901a\u6570\u7ec4\uff0c\u6570\u7ec4\u7684 index \u51fd\u6570\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u4f60\u4e0d\u77e5\u9053\u5417\uff1f\u4ed6\u76f8\u5f53\u4e8e\u66b4\u529b\u904d\u5386\u4e86\u6570\u7ec4\u627e\u5230\u4f60\u9700\u8981\u7684\u503c\uff0c\u4f60\u8fd9\u4e2a index \u7684\u8c03\u7528\u8fd8\u662f\u5728\u4e00\u4e2a\u5faa\u73af\u91cc\u7684\uff0c\u6240\u4ee5\u662f O(N^2) O(N^2) \u590d\u6742\u5ea6\uff01\u96be\u602a\u8fd9\u4e48\u6162\u4e86\u3002 \u540e\u6765\u6211\u7ed9\u4ed6\u6539\u4e86\u4e00\u4e0b\uff0c\u628a\u4ed6\u7684 face_lut \u6539\u6210\u5b57\u5178\uff0c\u7528\u5b57\u5178\u67e5\u627e\uff0c\u9ad8\u6548\u5f97\u591a\u4e86\uff1a # \u4ee5\u4e0b\u4e3a\u6211\u4f18\u5316\u540e\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = {} for ... in ...: face_lut[vert_id] = face_id # O(1)+ \u2705 for ... in ...: face_id = face_lut[vert_id] # O(1)+ \u2705 \u4e00\u6b21\u5b57\u5178\u7684\u67e5\u8be2\u53ea\u9700\u8981 O(1)+ O(1)+ \uff0c\u52a0\u4e0a\u4ed6\u5916\u9762\u7684\u5faa\u73af\u603b\u5171\u53ea\u6709 O(N) O(N) \uff0c\u53d8\u6210\u7ebf\u6027\u590d\u6742\u5ea6\u4e86\u3002\u4ed6\u4e00\u8bd5\uff0c\u679c\u7136\u51e0\u6beb\u79d2\u5c31\u52a0\u8f7d\u5b8c\u4e86\uff0c\u6211\u8bf4\u7528\u5b57\u5178\u52a0\u901f\u67e5\u627e\u8fd9\u4e0d\u662f\u5e38\u8bc6\u5417\uff1f\u8fd8\u6401\u7740 C++ \u5462\uff1f\u4f60\u5c31\u662f CUDA \u6765\u4e86\u4e5f\u538b\u4e0d\u4f4f\u590d\u6742\u5ea6\u7684\u7206\u8868\u5440\uff1f \u4ed6\u5f88\u9ad8\u5174\uff0c\u4e0d\u77e5\u9053\u600e\u4e48\u611f\u8c22\u6211\uff0c\u4e8e\u662f\u5c31\u628a\u6211\u63a8\u8350\u7ed9\u5f20\u5fc3\u6b23\u4e86\u3002 \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 \u4e0d\u8bba\u4ec0\u4e48\u8bed\u8a00\uff0c\u5bb9\u5668\uff08\u6216\u8005\u7528\u5b66\u6821\u91cc\u7684\u8bdd\u8bf4\uff1a\u6570\u636e\u7ed3\u6784\uff09\u7684\u6b63\u786e\u4f7f\u7528\uff0c\u80fd\u591f\u5728\u590d\u6742\u5ea6\u5c42\u9762\u4e0a\uff0c\u5927\u5e45\u63d0\u5347\u6027\u80fd\u3002 C++ \u4e2d\u4e5f\u662f\u5982\u6b64\uff0c\u6709\u6570\u7ec4\uff08vector\uff09\uff0c\u5b57\u5178\uff08map\uff09\uff0c\u8fd8\u6709\u4e0a\u4e00\u8bfe\u8bb2\u8fc7\u7684\u96c6\u5408\uff08set\uff09\u3002 \u4eca\u5929\u6211\u4eec\u8981\u4ecb\u7ecd\u7684\u5c31\u662f C++ \u7684\u5b57\u5178\u5bb9\u5668 map\uff0c\u4ee5\u53ca C++11 \u5f15\u5165\u7684\u53e6\u4e00\u4e2a\u5b57\u5178\u5bb9\u5668 unordered_map\uff0c\u4ed6\u4eec\u7684\u533a\u522b\u6211\u4eec\u6700\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u3002\u6211\u4eec\u5148\u5b66\u4e60\u8f83\u4e3a\u7b80\u5355\u7684 map\uff0c\u968f\u540e\u5b66\u4e60 unordered_map \u65f6\u4e5f\u53ef\u4ee5\u4e3e\u4e00\u53cd\u4e09\u3001\u878d\u4f1a\u8d2f\u901a\u3002 \u4ecb\u7ecd\u5b8c\u8fd9\u4e24\u4e2a\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u5b57\u5178\u5bb9\u5668\u540e\uff0c\u6211\u4eec\u8fd8\u5c06\u4ecb\u7ecd\u4e00\u4e9b\u5e38\u7528\u7684\u7b2c\u4e09\u65b9\u5e93\u5bb9\u5668\uff0c\u4f8b\u5982 absl::flat_hash_map\u3001tbb::concurrent_hash_map\u3001google::dense_hash_map\u3001robin_hood::unordered_map\u3001tsl::robin_pg_map \u7b49\uff0c\u9700\u8981\u6839\u636e\u5e94\u7528\u573a\u666f\u9009\u62e9\u9002\u5408\u7684\u5bb9\u5668\u3002 map/set \u5bb6\u65cf\u90fd\u662f\u9ad8\u6548\u67e5\u627e\u7684\u4e13\u5bb6\uff1a vector \u5bb9\u5668\u7528 std::find \u67e5\u627e\uff1a O(N) O(N) map \u6216 set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(\\log N) O(\\log N) unordered_map \u6216 unordered_set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(1)+ O(1)+ \u4e0d\u4ec5\u662f\u67e5\u627e\uff0cmap \u4eec\u8fd8\u652f\u6301\u9ad8\u6548\u7684\u589e\u5220\u6539\u67e5\u7b49\u64cd\u4f5c\u3002 map \u7684\u903b\u8f91\u7ed3\u6784 \u7279\u70b9\uff1a \u7531\u4e00\u7cfb\u5217 \u952e\u503c\u5bf9 \u7ec4\u6210 \u4e00\u4e2a\u952e\u53ea\u80fd\u5bf9\u5e94\u4e00\u4e2a\u503c \u952e\u4e0d\u5f97\u91cd\u590d\uff0c\u503c\u53ef\u4ee5\u91cd\u590d std::map, std::unordered_map, absl::flat_hash_map, tbb::concurrent_hash_map \u90fd\u6ee1\u8db3\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u4e00\u57fa\u672c\u903b\u8f91\u7ed3\u6784\uff0c\u53ea\u662f\u7269\u7406\u5b9e\u73b0\u4e0d\u540c\u3002 \u9762\u58c1\u8005\u7f57\u8f91\u76d1\u7763\u4f60\u7684\u5b66\u4e60\uff01 \u5728\u7f16\u7a0b\u4e2d\u6211\u4eec\u5e38\u5e38\u9700\u8981\u7528\u5230\u201c\u6620\u5c04\u201d\u7684\u5173\u7cfb\uff0c\u8fd9\u5c31\u975e\u5e38\u9700\u8981\u7528\u5230\u4ee5 map \u4e3a\u9996\u7684\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u7c7b\u5bb9\u5668\u4e86\u3002 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map map \u7684\u5177\u4f53\u5b9e\u73b0\u53ef\u4ee5\u662f\u7ea2\u9ed1\u6811\u3001AVL \u6811\u3001\u7ebf\u6027\u54c8\u5e0c\u8868\u3001\u94fe\u8868\u54c8\u5e0c\u8868\u3001\u8df3\u8868\u2026\u2026\u4e0d\u540c\u7684\u5b9e\u73b0\u5728\u4e0d\u540c\u64cd\u4f5c\u4e0a\u7684\u590d\u6742\u5ea6\u4e0d\u540c\uff0c\u5206\u522b\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u666f\u3002 \u7528\u6cd5\u4e0a\u51e0\u4e4e\u662f\u5dee\u4e0d\u591a\u7684\uff0c\u4ed6\u4eec\u90fd\u6709\u7740\u51e0\u4e4e\u76f8\u540c\u7684\u63a5\u53e3\uff08\u9664\u4e86\u90e8\u5206\u6269\u5c55\u529f\u80fd\uff09\u3002\u5f53\u4f60\u89c9\u5f97\u7ea2\u9ed1\u6811\u7684 std::map \u4e0d\u5408\u9002\u65f6\uff0c\u53ef\u4ee5\u8f7b\u677e\u628a\u5bf9\u8c61\u7c7b\u578b\u5c31\u5730\u66ff\u6362\u4e3a\u94fe\u8868\u54c8\u5e0c\u8868 std::unordered_map \u6216\u662f\u662f\u7ebf\u6027\u54c8\u5e0c\u8868 absl::flat_hash_map\uff0c\u800c\u4e0d\u7528\u5bf9\u5176\u4ed6\u4ee3\u7801\u6709\u4efb\u4f55\u66f4\u6539\u3002 \u8fd9\u5c31\u662f\u6240\u6709 map \u7c7b\u5bb9\u5668\u90fd\u6709\u7740\u76f8\u540c\u7684 \u903b\u8f91\u7ed3\u6784 \uff1a\u90fd\u662f\u4e00\u4e2a\u952e-\u503c\u6620\u5c04\uff0c\u4e0d\u540c\u7684\u53ea\u662f\u4ed6\u4eec\u7684 \u7269\u7406\u7ed3\u6784 \u800c\u5df2\u3002 \u6240\u6709\u7684 map \u5b9e\u73b0\uff0c\u90fd\u4f1a\u6a21\u4eff\u63d0\u4f9b\u548c std::map \u4e00\u6837\u7684 API\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u867d\u7136 std::map \u5b9e\u73b0\u7684\u5f88\u4f4e\u6548\uff0c\u6211\u4eec\u8fd8\u662f\u8981\u5b66\u4ed6\u7684\u539f\u56e0\u3002std::map \u672c\u8eab\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\uff0c\u4f46\u5374\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6240\u6709\u7b2c\u4e09\u65b9\u90fd\u4f1a\u9075\u5faa\u7684\u7edf\u4e00\u63a5\u53e3\u3002\u5b66\u4f1a\u4e86 std::map\uff0c\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93\u7684 map \u7c7b\u5bb9\u5668\u4f60\u90fd\u53ef\u4ee5\u8f7b\u6613\u4e3e\u4e00\u53cd\u4e09\u3002 \u4e0d\u4ec5\u662f\u5404\u79cd\u7b2c\u4e09\u65b9\u7684 map \u5e93\uff0c\u6bd4\u5982 rapidjson \u5e93\u4e2d\u7684 JSON \u5bf9\u8c61\uff0c\u4e5f\u63d0\u4f9b\u4e86\u7c7b\u4f3c std::map \u7684 find \u548c end \u8fed\u4ee3\u5668\u63a5\u53e3\uff1a MemberFind \u548c MemberEnd \uff0c\u6765\u67e5\u627e\u4e00\u4e2a\u5b57\u5178\u7684\u5b50\u952e\uff1b\u51e0\u4f55\u5904\u7406\u5e93 cgal \u4e2d\u7684\u201c\u9876\u70b9\u67e5\u627e\u201d\u529f\u80fd\u4e5f\u662f\u57fa\u4e8e\u7c7b\u4f3c\u7684\u8fed\u4ee3\u5668\u63a5\u53e3\u3002\u603b\u4e4b\uff0c\u5b66\u4f1a std::map \u5c06\u5927\u5927\u6709\u52a9\u4e8e\u4f60\u770b\u61c2\u8fd9\u7c7b\u4e1a\u754c\u516c\u8ba4\u7684\u63a5\u53e3\u89c4\u8303\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 \u6807\u51c6\u5e93\u4e2d\uff0cmap 1 \u662f\u4e00\u4e2a \u6a21\u677f\u7c7b \uff0c\u4ed6\u7684\u952e\u7c7b\u578b\uff0c\u503c\u7c7b\u578b\uff0c\u53ef\u4ee5\u7531\u5c16\u62ec\u53f7\u5185\u7684\u53c2\u6570\u6307\u5b9a\uff0c\u4fbf\u4e8e\u9002\u5e94\u4e0d\u540c\u7684\u7528\u6237\u9700\u6c42\u3002 \u7531\u4e8e C++ \u6807\u51c6\u5e93\u7684\u5bb9\u5668\u5927\u591a\u90fd\u662f\u6a21\u677f\u7c7b\uff0c\u63d0\u4f9b\u7684\u7b97\u6cd5\u4e5f\u5927\u591a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u56e0\u6b64 C++ \u6807\u51c6\u5e93\u5e38\u88ab\u79f0\u4e3a\u6807\u51c6\u6a21\u677f\u5e93 (Standard-Template-Library, STL)\u3002 \u952e\u7c7b\u578b\u548c\u503c\u7c7b\u578b\u53ef\u4ee5\u662f\u4efb\u610f\u7c7b\u578b\uff0c\u5305\u62ec\u57fa\u672c\u7c7b\u578b\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u7c7b\uff0c\u5176\u4ed6 STL \u5bb9\u5668\u7b49\uff0c\u4f53\u73b0\u4e86\u5bb9\u5668\u7684\u6cdb\u7528\u6027\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\uff1a\u952e\u5fc5\u987b\u652f\u6301\u6bd4\u8f83\uff0c\u8fd9\u91cc map \u8981\u6c42\u7684\u662f\u5c0f\u4e8e\u8fd0\u7b97\u7b26 < \u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a string\uff0c\u503c\u7c7b\u578b\u4e3a int \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a int\uff0c\u503c\u7c7b\u578b\u4e3a Student \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map> \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a char\uff0c\u503c\u7c7b\u578b\u4e3a vector \u7684 map \u5bb9\u5668\u3002 \u540e\u9762\u4e3a\u4e86\u65b9\u4fbf\u7814\u7a76\uff0c\u4ee5 map \u5f62\u5f0f\u4e66\u5199\u5f97\u51fa\u7684\u7ed3\u8bba\uff0c\u5bf9\u4e8e\u4efb\u4f55\u5b9e\u9645\u952e\u548c\u503c\u7c7b\u578b\uff0c\u53ea\u9700\u4ee3\u5165 K \u548c V \u5373\u53ef\u3002 \u5df2\u77e5\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 K \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < \u3002 \u53ef\u5f97\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 string \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < 2 \u3002 \u5df2\u77e5\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e K \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 \u53ef\u5f97\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e int \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 map \u7684\u7269\u7406\u7ed3\u6784 map \u548c set \u4e00\u6837\uff0c\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u5b9e\u73b0 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u9ad8\u6548\u67e5\u627e\u3002 vector \u5c31\u662f\u56e0\u4e3a\u5143\u7d20\u6ca1\u6709\u56fa\u5b9a\u7684\u987a\u5e8f\uff0c\u6240\u4ee5\u624d\u9700\u8981\u66b4\u529b\u904d\u5386\u67e5\u627e\u3002 \u5728\u6301\u7eed\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u4e0b\uff0c\u59cb\u7ec8\u7ef4\u6301\u5143\u7d20\u7684\u6709\u5e8f\u6027\uff0c\u6b63\u662f map \u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\u7684\u5173\u952e\u6240\u5728\u3002 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u59cb\u7ec8\u4fdd\u5b58\u5143\u7d20\u6309\u952e\u6392\u5e8f\u7684\u597d\u5904\u662f\uff0c\u5982\u679c\u9700\u8981\u5bfb\u627e\u6307\u5b9a\u952e\u503c\u7684\u5143\u7d20\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u4e8c\u5206\u6cd5\uff1a \u4ece\u6839\u8282\u70b9\u5f00\u59cb\u67e5\u627e\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5c0f\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u5de6\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5927\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u53f3\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u7b49\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u8be5\u8282\u70b9\u5c31\u662f\u8981\u627e\u7684\u8282\u70b9\uff0c\u8fd4\u56de\u8be5\u8282\u70b9\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u662f\u6700\u540e\u4e00\u5c42\u53f6\u5b50\u8282\u70b9\uff0c\u4e5f\u6ca1\u627e\u5230\u76f8\u7b49\u7684\u952e\uff0c\u5219\u8bf4\u660e\u8be5\u952e\u4e0d\u5b58\u5728\u3002 \u628a\u5de6/\u53f3\u5b50\u8282\u70b9\u8bbe\u4e3a\u65b0\u7684\u5f53\u524d\u8282\u70b9\uff0c\u7136\u540e\u56de\u5230\u7b2c 2 \u6b65\uff0c\u91cd\u590d\u8fd9\u4e00\u67e5\u627e\u8fc7\u7a0b\u3002 \u4e8c\u53c9\u6392\u5e8f\u6811 \u7531\u4e8e map \u7684\u5b9e\u73b0\u57fa\u4e8e\u4e8c\u53c9\u6392\u5e8f\u6811\uff0cmap \u989d\u5916\u6709\u4e00\u4e2a\u7279\u70b9\uff1a \u6709\u5e8f \u3002 map (\u6216 set) \u4e2d\u7684\u952e K \u603b\u662f\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u65b9\u4fbf\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u627e\u5230\u5bf9\u5e94\u5143\u7d20\u3002 \u6bcf\u6b21\u63d2\u5165\u65b0\u7684\u952e\u65f6\uff0c\u4f1a\u627e\u5230\u9002\u5f53\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u4f7f\u5f97\u63d2\u5165\u540e\u7684 map \u4ecd\u7136\u6709\u5e8f\u3002 \u6ce8\uff1a\u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\u5b9e\u73b0\u7684 unordered_map (\u548c unordered_set)\uff0c\u5c31\u4e0d\u5177\u5907 \u6709\u5e8f \u8fd9\u4e00\u7279\u70b9\u3002 \u4e24\u8005\u7684\u533a\u522b\u5728\u4e8e\uff1amap \u5728 K \u4e4b\u5916\uff0c\u989d\u5916\u5916\u6302\u4e86\u4e00\u4e2a V \u7c7b\u578b\u3002 map \u4e2d\u7684 V \u7c7b\u578b\u4e0d\u53c2\u4e0e\u6392\u5e8f\uff0c\u53ea\u6309\u7167 K \u8fdb\u884c\u6392\u5e8f\u3002 \u8fd9\u6837\u5f53\u7528\u6237\u6839\u636e K \u627e\u5230\u7684\u662f K-V \u5bf9\uff0c\u7136\u540e\u53ef\u4ee5\u53d6\u51fa K \u5bf9\u5e94\u7684 V\u3002 \u8fd9\u5c31\u5b9e\u73b0\u4e86\u4ece K \u5230 V \u7684\u6620\u5c04\u3002 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u4e8c\u53c9\u6392\u5e8f\u6811\u53ea\u89e3\u51b3\u4e86\u67e5\u627e\u7684\u95ee\u9898\uff0c\u4f46\u662f\u4ed6\u5e76\u4e0d\u80fd\u4fdd\u8bc1\u7ecf\u5386\u4e00\u901a\u63d2\u5165\u540e\u7684\u6811\u4e0d\u4f1a\u201c\u9000\u5316\u201d\u3002 \u5982\u679c\u63d2\u5165\u7684\u65f6\u5019\u4e0d\u5c0f\u5fc3\uff0c\u53ef\u80fd\u4f1a\u8ba9\u6811\u7684\u5f62\u72b6\u53d8\u5f97\u975e\u5e38\u8be1\u5f02\uff01 \u4f8b\u5982\uff0c\u82e5\u63d2\u5165\u6570\u636e\u7684\u987a\u5e8f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u90a3\u5c31\u4f1a\u4e00\u76f4\u5728\u5f80\u53f3\u63d2\u5165\uff0c\u6e05\u4e00\u8272\u7684\u4e00\u8fb9\u5012\uff0c\u4ee5\u81f3\u4e8e\u51e0\u4e4e\u6210\u4e86\u4e00\u6839\u5f80\u53f3\u8dd1\u7684\u94fe\u8868\u3002 \u5982\u679c\u63d2\u5165\u987a\u5e8f\u662f\u4ece\u5927\u5230\u5c0f\uff0c\u5c31\u53d8\u6210\u4e00\u76f4\u5f80\u5de6\u8fb9\u5012\u3002\u5373\u4f7f\u63d2\u5165\u7684\u987a\u5e8f\u4e0d\u90a3\u4e48\u523b\u610f\uff0c\u4f9d\u7136\u53ef\u80fd\u4ea7\u751f\u975e\u5e38\u53d8\u6001\u7684\u5f62\u72b6\uff0c\u8fdd\u80cc\u4e86\u4e8c\u53c9\u6811\u7684\u521d\u8877\u3002 \u54e5\u4fe9\u751f\u5f02\u5f62\u5462\uff1f \u8fd9\u6837\u201c\u9000\u5316\u201d\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u867d\u7136\u80fd\u4fdd\u6301\u6709\u5e8f\uff0c\u4f46\u4e8c\u5206\u67e5\u627e\u65f6\u5c31\u8d77\u4e0d\u5230\u52a0\u901f\u4f5c\u7528\u4e86\u3002 \u5982\u679c\u8981\u627e\u4e00\u4e2a\u4e2d\u95f4\u7684\u5143\u7d20\uff0c\u51e0\u4e4e\u5c31\u548c\u94fe\u8868\u4e00\u6837\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u53f3\u679d\u5e72\u3002 \u4e3a\u4e86\u9650\u5236\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0d\u8981\u957f\u6210\u7578\u5f62\uff0c\u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u6307\u6807\uff1a\u201c\u6df1\u5ea6\u201d\uff0c\u8868\u793a\u4ece\u6839\u8282\u70b9\u5230\u6700\u5e95\u5c42\u53f6\u5b50\u8282\u70b9\u7684\u8ddd\u79bb\u3002 \u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u5c31\u9700\u8981\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u5c3d\u53ef\u80fd\u7684\u4f4e\u3002 \u56e0\u4e3a\u4e8c\u5206\u67e5\u627e\u7684\u6b21\u6570\u5c31\u53d6\u51b3\u4e8e\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u7684\u5e73\u5747\u6df1\u5ea6\uff0c\u8981\u5c3d\u53ef\u80fd\u51cf\u5c11\u5e73\u5747\u9700\u8981\u8bbf\u95ee\u7684\u6b21\u6570\uff0c\u5c31\u662f\u8981\u51cf\u5c11\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u3002 \u4e5f\u5c31\u662f\u8bf4\u8981\u8ba9\u5927\u5bb6\u90fd\u5c3d\u53ef\u80fd\u8d34\u8fd1\u6839\u90e8\uff0c\u4f46\u6211\u4eec\u4e0d\u53ef\u80fd\u8ba9\u6240\u6709\u53f6\u5b50\u90fd\u6700\u8d34\u8fd1\u6839\u90e8\u3002 \u4f8b\u5982\u53f3\u4fa7\u53ea\u6709\u4e00\u4e2a\u53f6\u5b50\u8282\u70b9\uff0c\u4ed6\u81ea\u5df1\u662f\u6df1\u5ea6\u6700\u4f4e\u4e86\uff0c\u4f46\u4ee3\u4ef7\u662f\u5de6\u8fb9\u5168\u90e8\u6324\u5728\u4e00\u6761\u94fe\u8868\u4e0a\u4e86\uff01\u8fd9\u4e0d\u516c\u5e73\u3002 \u5b83\u81ea\u5df1\u5012\u662f\u81ea\u7531\u4e86\uff0c\u4f46\u5b83\u5974\u5f79\u4e86\u6240\u6709\u7684\u4eba\u6c11 \u6240\u4ee5\u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u6211\u4eec\u771f\u6b63\u9700\u8981\u7684\u662f\u8ba9\u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u5c3d\u53ef\u80fd\u201c\u5e73\u7b49\u201d\uff01 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u4e3a\u4e86\u907f\u514d\u4e8c\u53c9\u6811\u957f\u6210\u7578\u5f62\uff0c\u9677\u5165\u4e00\u8fb9\u5012\u7684\u60c5\u51b5\u3002\u6211\u4eec\u9700\u8981\u5728\u6bcf\u6b21\u63d2\u5165\u540e\uff0c\u68c0\u67e5\u4e8c\u53c9\u6811\u662f\u5426\u6df1\u5ea6\u5dee\u8ddd\u8fc7\u5927\u3002 \u5982\u679c\u5dee\u7684\u592a\u591a\u4e86\uff0c\u5c31\u9700\u8981\u8fdb\u884c\u4e00\u7cfb\u5217\u77eb\u6b63\u64cd\u4f5c\uff0c\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\uff0c\u628a\u592a\u957f\u7684\u679d\u5e72\u780d\u65ad\uff0c\u63a5\u5728\u77ed\u7684\u5730\u65b9\uff0c\u5c3d\u53ef\u80fd\u4fdd\u6301\u6240\u6709\u53f6\u5b50\u8def\u5f84\u7684\u6df1\u5ea6\u5dee\u4e0d\u591a\uff0c\u8fd9\u4e2a\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u52a8\u4f5c\u5c31\u662f \u5e73\u8861\u64cd\u4f5c (balancing) \u3002 \u95ee\u9898\u662f\uff0c\u6700\u5927\u80fd\u5bb9\u5fcd\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u591a\u5927\u7684\u6df1\u5ea6\u5dee\u624d\u5f00\u59cb\u77eb\u6b63\uff1f\u9488\u5bf9\u8fd9\u4e2a\u95ee\u9898\uff0c\u4e8c\u53c9\u6392\u5e8f\u6811\u5206\u4e3a\u4e24\u6d3e\uff1a \u5e73\u8861\u6811 \u6700\u7406\u60f3\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u9897\u542b\u6709 N N \u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u81f3\u5c11\u9700\u8981\u6709 \\lceil \\log N \\rceil \\lceil \\log N \\rceil \u6df1\u5ea6\u3002 \u8fd9\u5c31\u662f\u5e73\u8861\u6811\uff08AVL\uff09\uff0c\u4ed6\u5f3a\u5236\u4fdd\u8bc1\u6574\u4e2a\u6811\u5904\u4e8e\u5b8c\u7f8e\u7684\u5e73\u8861\u72b6\u6001\uff0c\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u6df1\u5ea6\u5dee\u8ddd\u4e0d\u4f1a\u8d85\u8fc7 1\uff08\u5f53\u8282\u70b9\u6570\u91cf N N \u4e0d\u662f 2 \u7684\u6574\u6570\u500d\u65f6\uff0c\u8fd9\u662f\u4e0d\u5f97\u4e0d\u5b58\u5728\u7684 1 \u683c\u5dee\u8ddd\uff09\u3002 \u4f18\u70b9\uff1a\u59cb\u7ec8\u4fdd\u6301\u6700\u5b8c\u7f8e\u7684\u5e73\u8861\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u548c\u6700\u574f\u590d\u6742\u5ea6\u6700\u4f4e\u3002\u6240\u4ee5\u5e73\u8861\u6811\u7684\u67e5\u627e\u6027\u80fd\u662f\u6700\u597d\u7684\u3002 \u7f3a\u70b9\uff1a\u7136\u800c\u59cb\u7ec8\u4fdd\u6301\u5b8c\u7f8e\u7684\u5e73\u8861\u610f\u5473\u7740\uff0c\u51e0\u4e4e\u6bcf\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff08\u53ef\u80fd\u4f1a\u7a81\u7136\u4ea7\u751f\u6df1\u5ea6\u5dee\u8ddd\u8d85\u8fc7 1 \u7684\u60c5\u51b5\uff09\uff0c\u5c31\u7acb\u5373\u9700\u8981\u5e73\u8861\u4e00\u6b21\u3002\u5e73\u8861\u4e00\u6b21\u7684\u5f00\u9500\u662f\u6bd4\u8f83\u5927\u7684\uff0c\u6240\u4ee5\u5e73\u8861\u6811\u7684\u6027\u80fd\u662f\u63d2\u5165\u6027\u80fd\u662f\u6bd4\u8f83\u5dee\u7684\u3002 \u5e73\u8861\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u65b9\u5f0f\u662f\u201c\u65cb\u8f6c\u201d\uff0c\u4ed6\u80fd\u59cb\u7ec8\u4fdd\u6301\u6700\u4f4e\u7684\u6df1\u5ea6\u5dee\uff1a \u8fd9\u91cc\u7684\u7ec6\u8282\u6211\u4eec\u4e0d\u4f1a\u6df1\u7a76\uff0c\u90a3\u662f\u6570\u636e\u7ed3\u6784\u8bfe\u7684\u5185\u5bb9\uff0c\u5c4a\u65f6\u4f1a\u5e26\u5927\u5bb6\u624b\u6413\u5e73\u8861\u6811\u548c\u7ea2\u9ed1\u6811\uff0c\u672c\u671f\u53ea\u662f\u7a0d\u5fae\u4e86\u89e3 map \u5e38\u89c1\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5e2e\u52a9\u4f60\u7406\u89e3\u4e3a\u4ec0\u4e48 map \u662f\u6709\u5e8f\u5bb9\u5668\u3002 \u7ea2\u9ed1\u6811 \u800c\u7ea2\u9ed1\u6811\u8ba4\u4e3a\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u603b\u662f\u4fdd\u6301\u6df1\u5ea6\u5dee\u8ddd\u4e3a 1 \u90a3\u4e48\u5c0f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u5373\u53ef\u3002 \u4f8b\u5982\u6700\u6d45\u7684\u4e00\u4e2a\u53f6\u5b50\u662f 6 \u6df1\u5ea6\uff0c\u53e6\u4e00\u4e2a\u6700\u6df1\u7684\u53f6\u5b50\u53ef\u4ee5\u662f 12 \u6df1\u5ea6\u3002\u53ea\u6709\u5f53\u6700\u6df1\u7684\u53f6\u5b50\u8d85\u8fc7 12 \u6df1\u5ea6\u65f6\uff0c\u7ea2\u9ed1\u6811\u624d\u4f1a\u5f00\u59cb\u4e3b\u52a8\u5e72\u9884\u5e73\u8861\uff0c\u907f\u514d\u7ee7\u7eed\u7578\u5f62\u53d1\u5c55\u4e0b\u53bb\u3002 \u7f3a\u70b9\uff1a\u6811\u53ef\u80fd\u6709\u4e00\u5b9a\u7684\u4e00\u8fb9\u5012\u60c5\u51b5\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u7a0d\u5fae\u964d\u4f4e\uff0c\u6700\u574f\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u539f\u6765\u7684 2 \u500d\uff01 \u4f18\u70b9\uff1a\u56e0\u4e3a\u5bf9\u4e0d\u5e73\u8861\u73b0\u8c61\u66f4\u52a0\u5bbd\u677e\uff0c\u6b63\u5e38\u63d2\u5165\u65f6\u57fa\u672c\u4e0d\u9700\u8981\u5e73\u8861\uff0c\u53ea\u6709\u7279\u522b\u626d\u66f2\u4e86\u624d\u4f1a\u4e0b\u573a\u201c\u6551\u6025\u201d\u3002\u6240\u4ee5\u7ea2\u9ed1\u6811\u662f\u727a\u7272\u4e86\u4e00\u90e8\u5206\u67e5\u627e\u6027\u80fd\uff0c\u6362\u53d6\u4e86\u66f4\u597d\u7684\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7684\u7528\u51b5\u662f\u63d2\u5165\u6bd4\u8f83\u5c11\uff0c\u4f46\u662f\u67e5\u8be2\u975e\u5e38\u591a\uff0c\u90a3\u5c31\u9002\u5408\u7528\u5e73\u8861\u6811\u3002 \u7531\u4e8e\u6362\u6765\u7684\u8fd9\u90e8\u5206\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u5b9e\u9645\u4e0a\u6bd4\u635f\u5931\u7684\u67e5\u627e\u6027\u80fd\u591a\uff0c\u800c map \u5e38\u89c1\u7684\u7528\u51b5\u786e\u5b9e\u9700\u8981\u7ecf\u5e38\u589e\u5220\u6539\u67e5\uff0c\u6240\u4ee5\u73b0\u5728 C++ \u6807\u51c6\u5e93\u7684 map \u5e95\u5c42\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u5b9e\u73b0\u7684\u3002 \u5982\u679c\u4f60\u7684\u9700\u6c42\u662f\u5927\u91cf\u67e5\u627e\u7684\u8bdd\uff0c\u5b8c\u5168\u53ef\u4ee5\u8003\u8651\u7528\u67e5\u627e\u5e73\u5747\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u7684\u54c8\u5e0c\u8868 unordered_map\u3002 \u5982\u679c\u662f\u4e00\u6b21\u6027\u63d2\u5165\u5b8c\u6bd5\u540e\u4e0d\u4f1a\u518d\u4fee\u6539\uff0c\u8fd8\u53ef\u4ee5\u7528\u5b8c\u7f8e\u54c8\u5e0c\u8868\uff08frozen_map\uff09\uff0c\u4ed6\u4f1a\u4e3a\u4f60\u7684\u952e\u503c\u5e8f\u5217\u4e13\u95e8\u751f\u6210\u4e00\u4e2a\u4e13\u7528\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u4e14\u4fdd\u8bc1\u5b8c\u5168\u65e0\u51b2\u7a81\u3002\u4f8b\u5982\u4f60\u5728\u505a\u4e00\u79cd\u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u6709\u5f88\u591a\u201c\u5173\u952e\u5b57\u201d\uff0c\u6bd4\u5982\u201cif\u201d\u3001\u201cwhile\u201d\uff0c\u4f60\u9700\u8981\u8fd0\u884c\u65f6\u9891\u7e41\u7684\u67e5\u627e\u8fd9\u4e9b\u5173\u952e\u5b57\uff0c\u800c\u5173\u952e\u5b57\u6709\u54ea\u4e9b\u5728\u7f16\u8bd1\u671f\u662f\u56fa\u5b9a\u7684\uff0c\u90a3\u5c31\u5f88\u9002\u5408\u7528\u5b8c\u7f8e\u54c8\u5e0c\u3002 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u7ea2\u9ed1\u6811\u662f\u5982\u4f55\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u7684\u5462\uff1f \u4ed6\u8bbe\u5b9a\u4e86\u8fd9\u6837 5 \u6761\u89c4\u5219\uff1a \u8282\u70b9\u53ef\u4ee5\u662f\u7ea2\u8272\u6216\u9ed1\u8272\u7684\u3002 \u6839\u8282\u70b9\u603b\u662f\u9ed1\u8272\u7684\u3002 \u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u662f\u9ed1\u8272\uff08\u53f6\u5b50\u8282\u70b9\u5c31\u662f NULL\uff09\u3002 \u7ea2\u8272\u8282\u70b9\u7684\u4e24\u4e2a\u5b50\u8282\u70b9\u5fc5\u987b\u90fd\u662f\u9ed1\u8272\u7684\u3002 \u4ece\u4efb\u4e00\u8282\u70b9\u5230\u5176\u6240\u6709\u53f6\u5b50\u8282\u70b9\u7684\u8def\u5f84\u90fd\u5305\u542b\u76f8\u540c\u6570\u91cf\u7684\u9ed1\u8272\u8282\u70b9\u3002 \u4ec0\u4e48\u89c4\u5219\u7c7b\u602a\u8c08\u2026\u2026 \u770b\u8d77\u6765\u597d\u50cf\u5f88\u590d\u6742\uff0c\u4f46\u5b9e\u9645\u4e0a\u5927\u591a\u662f\u5e9f\u8bdd\uff0c\u6709\u7528\u7684\u53ea\u662f 4 \u548c 5 \u8fd9\u4e24\u6761\u3002 \u89c4\u5219 4 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4e0d\u5f97\u51fa\u73b0\u76f8\u90bb\u7684\u7ea2\u8272\u8282\u70b9\uff08\u76f8\u90bb\u6307\u4e24\u4e2a\u8282\u70b9\u662f\u7236\u5b50\u5173\u7cfb\uff09\u3002\u8fd9\u6761\u89c4\u5219\u8fd8\u6709\u4e00\u4e2a\u9690\u542b\u7684\u4fe1\u606f\uff1a\u9ed1\u8272\u8282\u70b9\u53ef\u4ee5\u76f8\u90bb\uff01 \u89c4\u5219 5 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6240\u6709\u5e95\u5c42\u53f6\u5b50\u7684\u8ddd\u79bb\uff08\u4ee5\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u8ba1\uff09\uff0c\u5fc5\u987b\u76f8\u7b49\u3002 \u56e0\u4e3a\u89c4\u5219 4 \u7684\u5b58\u5728\uff0c\u7ea2\u8272\u8282\u70b9\u4e0d\u53ef\u80fd\u76f8\u90bb\uff0c\u4e5f\u5c31\u662f\u8bf4\u6700\u6df1\u7684\u679d\u5e72\u53ea\u80fd\u662f\uff1a\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1\u3002 \u7ed3\u5408\u89c4\u5219 5 \u6765\u770b\uff0c\u4e5f\u5c31\u662f\u8bf4\u6bcf\u6761\u679d\u5e72\u4e0a\u7684\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u5fc5\u987b\u76f8\u540c\uff0c\u56e0\u4e3a\u6700\u6df1\u7684\u679d\u5e72\u662f 4 \u4e2a\u9ed1\u8282\u70b9\u4e86\uff0c\u6240\u4ee5\u6700\u6d45\u7684\u679d\u5e72\u81f3\u5c11\u4e5f\u5f97\u6709 4 \u4e2a\u8282\u70b9\u5168\u662f\u9ed1\u8272\u7684\uff1a\u9ed1-\u9ed1-\u9ed1-\u9ed1\u3002 \u53ef\u4ee5\u770b\u5230\uff0c\u89c4\u5219 4 \u548c\u89c4\u5219 5 \u8054\u5408\u8d77\u6765\u5b9e\u9645\u4e0a\u5c31\u4fdd\u8bc1\u4e86\uff1a\u6700\u6df1\u679d\u5e72\u7684\u6df1\u5ea6\u4e0d\u4f1a\u8d85\u8fc7\u6700\u6d45\u679d\u5e72\u7684 2 \u500d\u3002 \u5982\u679c\u8d85\u51fa\u4e86 2 \u500d\uff0c\u5c31\u4e0d\u5f97\u4e0d\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u89c4\u5219 4 \u6216 5\uff0c\u4ece\u800c\u89e6\u53d1\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u5e73\u8861\u64cd\u4f5c\uff0c\u4ece\u800c\u963b\u6b62\u4e86\u4e8c\u53c9\u6811\u8fc7\u4e8e\u7578\u5f62\u5316\u3002 \u7ea2\u9ed1\u6811\u5982\u4f55\u5b9e\u73b0\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u7ec6\u8282\u6211\u4eec\u5c31\u4e0d\u518d\u591a\u8c08\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u70b9\u5230\u4e3a\u6b62\uff0c\u63a5\u4e0b\u6765\u76f4\u63a5\u8fdb\u5165\u6b63\u9898\uff1a \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u521b\u5efa\u4e00\u4e2a map \u5bf9\u8c61\uff1a map config; \u4e00\u5f00\u59cb map \u521d\u59cb\u662f\u7a7a\u7684\uff0c\u5982\u4f55\u63d2\u5165\u4e00\u4e9b\u521d\u59cb\u6570\u636e\uff1f config[\"timeout\"] = 985; config[\"delay\"] = 211; \u6570\u636e\u63d2\u5165\u6210\u529f\u4e86\uff0c\u6839\u636e\u952e\u67e5\u8be2\u5bf9\u5e94\u7684\u503c\uff1f print(config[\"timeout\"]); print(config[\"delay\"]); \u67e5\u8be2\u65f6\u5efa\u8bae\u7528 .at(key) \u800c\u4e0d\u662f [key] \uff1a print(config.at(\"timeout\")); print(config.at(\"delay\")); \u8001\u751f\u5e38\u8c08\u7684\u95ee\u9898\uff1amap \u4e2d\u5b58 string \u8fd8\u662f const char *\uff1f map m; m[\"hello\"] = \"old\"; // \u5e38\u91cf\u533a\u7684 \"hello\" char key[] = \"hello\"; // key \u7684\u5730\u5740\u5728\u6808\u4e0a print(key == \"hello\"); // false m[key] = \"new\"; // \u6808\u4e0a\u53d8\u91cf\u7684 key = \"hello\" print(m); // \u4e24\u4e2a\u91cd\u590d\u7684\u952e \"hello\" false {hello: old, hello: new} \u5728 C++ \u4e2d\uff0c\u4efb\u4f55\u65f6\u5019\u90fd\u52a1\u5fc5\u7528 string\uff01\u522b\u7528 C \u8bed\u8a00\u8001\u6389\u7259\u7684 const char *\uff0c\u592a\u5371\u9669\u4e86\u3002 const char * \u5371\u9669\u7684\u539f\u56e0\uff1a const char * \u7684 == \u5224\u65ad\u7684\u662f\u6307\u9488\u7684\u76f8\u7b49\uff0c\u4e24\u4e2a const char * \u53ea\u8981\u5730\u5740\u4e0d\u540c\uff0c\u5373\u4f7f\u5b9e\u9645\u7684\u5b57\u7b26\u4e32\u76f8\u540c\uff0c\u4e5f\u4e0d\u4f1a\u88ab\u89c6\u4e3a\u540c\u4e00\u4e2a\u5143\u7d20\uff08\u5982\u4e0a\u4ee3\u7801\u6848\u4f8b\u6240\u793a\uff09\u3002\u5bfc\u81f4 map \u91cc\u4f1a\u51fa\u73b0\u91cd\u590d\u7684\u952e\uff0c\u4ee5\u53ca\u6309\u952e\u67e5\u627e\u53ef\u80fd\u627e\u4e0d\u5230\u7b49\u3002 \u4fdd\u5b58\u7684\u662f\u5f31\u5f15\u7528\uff0c\u5982\u679c\u4f60\u628a\u5c40\u90e8\u7684 char [] \u6216 string.c_str() \u8fd4\u56de\u7684 const char * \u5b58\u5165 map\uff0c\u7b49\u8fd9\u4e9b\u5c40\u90e8\u91ca\u653e\u4e86\uff0cmap \u4e2d\u7684 const char * \u5c31\u662f\u4e00\u4e2a\u7a7a\u60ac\u6307\u9488\u4e86\uff0c\u4f1a\u9020\u6210 segfault\u3002 \u8bf7\u7528\u5b89\u5168\u7684 string\uff1a map m; m[\"hello\"] = \"old\"; string key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // string \u7684 == \u8fd0\u7b97\u7b26\u662f\u7ecf\u8fc7\u91cd\u8f7d\u7684\uff0c\u6bd4\u8f83\u7684\u662f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u5185\u5bb9\u76f8\u7b49\uff0c\u800c\u4e0d\u662f\u5730\u5740\u76f8\u7b49 {\"hello\": \"new\"} true \u63cf\u8ff0 C++ Java Python \u5185\u5bb9\u76f8\u7b49 string(\"hello\") == string(\"hello\") \"hello\".equals(\"hello\") 'hello' == 'hello' \u5730\u5740\u76f8\u7b49 \"hello\" == \"hello\" \"hello\" == \"hello\" id('hello') == id('hello') \u5982\u679c\u4f60\u7cbe\u901a\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u80fd\u4fdd\u8bc1 key \u6307\u5411\u7684\u5b57\u7b26\u4e32\u6d3b\u7684\u6bd4 m \u4e45\uff0c\u60f3\u8981\u907f\u514d\u62f7\u8d1d\uff0c\u8282\u7701\u6027\u80fd\u3002 string \u7684\u5f31\u5f15\u7528\u7248\u672c\uff1astring_view\uff0c\u540c\u6837\u53ef\u4ee5\u7528\u5c01\u88c5\u4e86\u6b63\u786e\u7684 == \u8fd0\u7b97\u7b26\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\uff1a map m; m[\"hello\"] = \"old\"; string_view key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // \u6b64\u5904 m \u662f\u6808\u4e0a\u53d8\u91cf\uff0ckey \u662f\u5f31\u5f15\u7528\u6307\u5411\u5168\u5c40\u5e38\u91cf\u533a\uff08rodata\uff09\uff0ckey \u6bd4 m \u6d3b\u5f97\u4e45\uff0c\u6ca1\u6709\u7a7a\u60ac\u6307\u9488\u95ee\u9898 {\"hello\": \"new\"} true \u26a0\ufe0f string_view \u5c5e\u4e8e\u4e0d\u5efa\u8bae\u521d\u5b66\u8005\u4f7f\u7528\u7684\u4f18\u5316\u5c0f\u5bc4\u5de7\uff1a\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528\u3002 \u6ce8\uff1amap \u5b9e\u9645\u4e0a\u5b8c\u5168\u6ca1\u6709\u7528\u5230 ==\uff0c\u7528\u5230\u7684\u53ea\u6709 < \u8fd0\u7b97\u7b26\uff0c\u5f53\u9700\u8981\u5224\u5b9a a == b \u65f6\uff0c\u4ed6\u4f1a\u8f6c\u800c\u7528 !(a < b || b < a) \u6765\u5224\u5b9a\u3002 string_view \u4e5f\u5177\u6709\u6b63\u786e\u7684 hash \u7279\u5316\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528\u505a unordered_map \u7684\u952e\u7c7b\u578b\u3002string_view \u8bd5\u56fe\u548c string \u8868\u73b0\u5f97\u5b8c\u5168\u4e00\u6837\uff0c\u533a\u522b\u5728\u4e8e\u4ed6\u662f\u4e2a\u5f31\u5f15\u7528\uff0c\u4e0d\u6301\u6709\u5bf9\u8c61\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\u3002string_view \u5927\u5c0f\u53ea\u6709 16 \u4e2a\u5b57\u8282\uff0c\u5185\u90e8\u662f\u4e00\u4e2a const char * \u548c size_t\uff0c\u4f46\u5c01\u88c5\u4e86\u6b63\u786e\u7684 ==\uff0c<\uff0c> \u548c hash\u3002 C++11 \u65b0\u7279\u6027\u2014\u2014\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\uff0c\u5141\u8bb8\u521b\u5efa map \u65f6\u76f4\u63a5\u6307\u5b9a\u521d\u59cb\u6570\u636e\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211} }; \u901a\u5e38\u6211\u4eec\u4f1a\u6362\u884c\u5199\uff0c\u4e00\u884c\u4e00\u4e2a\u952e\u503c\u5bf9\uff0c\u770b\u8d77\u6765\u6761\u7406\u66f4\u6e05\u6670\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 \u603b\u7ed3\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5\uff1a map m = { {k1, v1}, {k2, v2}, ..., }; \u8ba9 map \u521d\u59cb\u5c31\u5177\u6709\u8fd9\u4e9b\u6570\u636e\u3002 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; \u7b49\u53f7\u53ef\u4ee5\u7701\u7565\uff08\u8fd9\u5176\u5b9e\u76f8\u5f53\u4e8e\u662f\u5728\u8c03\u7528 map \u7684\u6784\u9020\u51fd\u6570\uff09\uff1a map config{ {\"timeout\", 985}, {\"delay\", 211}, }; \u4e5f\u53ef\u4ee5\u5148\u6784\u9020\u518d\u8d4b\u503c\u7ed9 auto \u53d8\u91cf\uff1a auto config = map{ {\"timeout\", 985}, {\"delay\", 211}, }; \u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u5173\u4e8e\u6784\u9020\u51fd\u6570\u3001\u82b1\u62ec\u53f7\u5217\u8868\u7684\u5177\u4f53\u8bed\u6cd5\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u300b\u7cfb\u5217\u7b2c\u4e8c\u8bfe\uff1ahttps://www.bilibili.com/video/BV1LY411H7Gg\u3002\u5728 C++ \u5c0f\u5999\u62db \u4e00\u7ae0\u4e2d\u4e5f\u6709\u4ecb\u7ecd\u3002 \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u53ef\u4ee5\u7528\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\u5c31\u5730\u6784\u9020\u4e00\u4e2a map \u5bf9\u8c61\uff1a void myfunc(map config); // \u51fd\u6570\u58f0\u660e myfunc(map{ // \u76f4\u63a5\u521b\u5efa\u4e00\u4e2a map \u4f20\u5165 {\"timeout\", 985}, {\"delay\", 211}, }); \u7531\u4e8e myfunc \u51fd\u6570\u5177\u6709\u552f\u4e00\u786e\u5b9a\u7684\u91cd\u8f7d\uff0c\u8981\u6784\u9020\u7684\u53c2\u6570\u7c7b\u578b map \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a myfunc({ {\"timeout\", 985}, {\"delay\", 211}, }); \u51fd\u6570\u8fd9\u8fb9\uff0c\u901a\u5e38\u8fd8\u4f1a\u52a0\u4e0a const & \u4fee\u9970\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d\u3002 void myfunc(map const &config); \u4ece vector \u4e2d\u6279\u91cf\u5bfc\u5165\u952e\u503c\u5bf9\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs.begin(), kvs.end()); \u4e0e\u521a\u521a\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u7684\u5199\u6cd5\u7b49\u4ef7\uff0c\u53ea\u4e0d\u8fc7\u662f\u4ece\u73b0\u6709\u7684 vector \u4e2d\u5bfc\u5165\u3002\u540c\u6837\u7684\u5199\u6cd5\u4e5f\u9002\u7528\u4e8e\u4ece array \u5bfc\u5165\u3002 \u5982\u679c\u8bb0\u4e0d\u4f4f\u8fd9\u4e2a\u5199\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5df1\u624b\u5199 for \u5faa\u73af\u904d\u5386 vector \u9010\u4e2a\u9010\u4e2a\u63d2\u5165 map\uff0c\u6548\u679c\u662f\u4e00\u6837\u7684\u3002 \u51b7\u77e5\u8bc6\uff0c\u5982\u679c\u4e0d\u662f vector \u6216 array\uff0c\u800c\u662f\u60f3\u4ece\u4f20\u7edf\u7684 C \u8bed\u8a00\u6570\u7ec4\u4e2d\u5bfc\u5165\uff1a pair kvs[] = { // C \u8bed\u8a00\u539f\u59cb\u6570\u7ec4 {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs, kvs + 2); // C++98 map config(std::begin(kvs), std::end(kvs)); // C++17 \u5176\u4e2d std::begin \u548c std::end \u4e3a C++17 \u65b0\u589e\u51fd\u6570\uff0c\u4e13\u95e8\u7528\u4e8e\u7167\u987e\u6ca1\u6cd5\u6709\u6210\u5458\u51fd\u6570 .begin() \u7684 C \u8bed\u8a00\u6570\u7ec4\u3002\u7c7b\u4f3c\u7684\u5168\u5c40\u51fd\u6570\u8fd8\u6709 std::size \u548c std::data \u7b49\u2026\u2026\u4ed6\u4eec\u90fd\u662f\u65e2\u517c\u5bb9 STL \u5bb9\u5668\u4e5f\u517c\u5bb9 C \u6570\u7ec4\u7684\u3002 \u91cd\u70b9\u6765\u4e86\uff1a\u5982\u4f55\u6839\u636e\u952e\u67e5\u8be2\u76f8\u5e94\u7684\u503c\uff1f \u5f88\u591a\u540c\u5b66\u90fd\u77e5\u9053 map \u5177\u6709 [] \u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c[] \u91cc\u5199\u8981\u67e5\u8be2\u7684\u952e\u5c31\u53ef\u4ee5\u8fd4\u56de\u5bf9\u5e94\u503c\uff0c\u4e5f\u53ef\u4ee5\u7528 = \u5f80\u91cc\u9762\u8d4b\u503c\uff0c\u548c\u67d0\u4e9b\u811a\u672c\u8bed\u8a00\u4e00\u6837\u76f4\u89c2\u6613\u61c2\u3002 config[\"timeout\"] = 985; // \u628a config \u4e2d\u952e timeout \u5bf9\u5e94\u503c\u8bbe\u4e3a 985 auto val = config[\"timeout\"]; // \u8bfb\u53d6 config \u4e2d\u952e timeout \u5bf9\u5e94\u503c print(val); // 985 \u4f46\u5176\u5b9e\u7528 [] \u53bb \u8bfb\u53d6\u5143\u7d20 \u662f\u5f88\u4e0d\u5b89\u5168\u7684\uff0c\u4e0b\u9762\u6211\u4f1a\u505a\u5b9e\u9a8c\u6f14\u793a\u8fd9\u4e00\u70b9\u3002 \u6c89\u9ed8\u7684 []\uff0c\u65e0\u8a00\u7684\u5371\u9669\uff1a\u5f53\u952e\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8fd4\u56de 0 \u800c\u4e0d\u4f1a\u51fa\u9519\uff01 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // 985 print(config[\"tmeout\"]); // \u9ed8\u9ed8\u8fd4\u56de 0 985 0 \u5f53\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c[] \u4f1a\u9ed8\u9ed8\u521b\u5efa\u5e76\u8fd4\u56de 0\uff0c\u800c\u4e0d\u4f1a\u7206\u51fa\u4efb\u4f55\u9519\u8bef\u3002 \u8fd9\u975e\u5e38\u5371\u9669\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b80\u7b80\u5355\u5355\u7684\u62fc\u5199\u9519\u8bef\uff0c\u5c31\u4f1a\u5bfc\u81f4 map \u7684\u67e5\u8be2\u9ed8\u9ed8\u8fd4\u56de 0\uff0c\u4f60\u8fd8\u5728\u90a3\u91cc\u627e\u4e86\u534a\u5929\u6478\u4e0d\u7740\u5934\u8111\uff0c\u6839\u672c\u6ca1\u53d1\u73b0\u9519\u8bef\u539f\u6765\u5728 map \u8fd9\u91cc\u3002 \u7231\u54ed\u7231\u95f9\u7684 at()\uff0c\u53cd\u800c\u66f4\u8ba8\u4eba\u559c\u6b22 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 print(config.at(\"tmeout\")); // \u8be5\u952e\u4e0d\u5b58\u5728\uff01\u54cd\u4eae\u5730\u51fa\u9519 985 terminate called after throwing an instance of 'std::out_of_range' what(): map::at Aborted (core dumped) \u6709\u7ecf\u9a8c\u7684\u8001\u624b\u90fd\u660e\u767d\u4e00\u4e2a\u9053\u7406\uff1a \u53ca\u65f6\u5954\u6e83 \u6bd4 \u5bb9\u5fcd\u9519\u8bef \u66f4\u6709\u5229\u4e8e\u8c03\u8bd5\u3002\u5373 fail-early, fail-loudly 1 \u539f\u5219\u3002 \u4f8b\u5982 JS \u548c Lua \u7684 [] \u8bbf\u95ee\u8d8a\u754c\u4e0d\u62a5\u9519\u800c\u662f\u8fd4\u56de undefined / nil\uff0c\u5bfc\u81f4\u5b9e\u9645\u51fa\u9519\u7684\u4f4d\u7f6e\u5728\u597d\u51e0\u5341\u884c\u4e4b\u540e\uff0c\u65e0\u6cd5\u5b9a\u4f4d\u5230\u771f\u6b63\u51fa\u9519\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u540e\u6765\u53d1\u660e\u4e86\u9519\u8bef\u68c0\u67e5\u66f4\u4e25\u683c\u7684 TS\u3002 \u4f7f\u7528 at() \u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230\u9519\u8bef\uff0c\u662f\u597d\u4e8b\u3002 \u5728\u5b98\u65b9\u6587\u6863\u548c\u5404\u79cd\u6559\u5b66\u8bfe\u4ef6\u4e2d\uff0c\u90fd\u4f1a\u5c55\u793a\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u539f\u578b\u201d\u6765\u8bb2\u89e3\u3002 \u539f\u578b\u5c55\u73b0\u4e86\u4e00\u4e2a\u51fd\u6570\u7684\u540d\u79f0\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u8fd4\u56de\u7c7b\u578b\u7b49\u4fe1\u606f\uff0c\u638c\u63e1\u4e86\u51fd\u6570\u7684\u539f\u578b\u5c31\u7b49\u4e8e\u638c\u63e1\u4e86\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u3002 \u672c\u8bfe\u7a0b\u540e\u9762\u4e5f\u4f1a\u5927\u91cf\u4f7f\u7528\uff0c\u73b0\u5728\u6765\u6559\u4f60\u5982\u4f55\u770b\u61c2\u6210\u5458\u51fd\u6570\u7684\u539f\u578b\u3002 \u5047\u8bbe\u8981\u7814\u7a76\u7684\u7c7b\u578b\u4e3a map \uff0c\u5176\u4e2d K \u548c V \u662f\u6a21\u677f\u53c2\u6570\uff0c\u53ef\u4ee5\u66ff\u6362\u6210\u4f60\u5177\u4f53\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u5f53\u6211\u4f7f\u7528 map \u65f6\uff0c\u5c31\u628a\u4e0b\u9762\u6240\u6709\u7684 K \u66ff\u6362\u6210 string\uff0cV \u66ff\u6362\u6210 int\u3002 map \u7684 [] \u548c at \u5458\u51fd\u6570\uff0c\u539f\u578b\u5982\u4e0b\uff1a V &operator[](K const &k); V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u53ef\u89c1 operator[] \u53ea\u6709\u4e00\u4e2a\u7248\u672c\uff0cat \u5c45\u7136\u6709\u540d\u5b57\u76f8\u540c\u7684\u4e24\u4e2a\uff01\u8fd9\u6837\u4e0d\u4f1a\u53d1\u751f\u51b2\u7a81\u5417\uff1f \u8fd9\u662f\u5229\u7528\u4e86 C++ \u7684\u201c\u91cd\u8f7d\u201d\u529f\u80fd\uff0c\u91cd\u8f7d\u5c31\u662f\u540c\u4e00\u4e2a\u51fd\u6570\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u7248\u672c\uff0c\u5404\u4e2a\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u6253\u7535\u8bdd\u7ed9 110\uff0c\u5047\u5982\u8b66\u5bdf\u53d4\u53d4\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u62a5\u7684\u6848\u5b50\u662f\u7f51\u7edc\u8bc8\u9a97\uff0c\u90a3\u4e48\u4ed6\u4eec\u4f1a\u5e2e\u6211\u8f6c\u63a5\u5230\u7f51\u8b66\u90e8\u95e8\uff1b\u5047\u5982\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u662f\u88ab\u7ed1\u67b6\u4e86\uff0c\u90a3\u4e48\u4ed6\u4eec\u53ef\u80fd\u4f1a\u51fa\u52a8\u6b66\u8b66\u89e3\u6551\u5c0f\u5f6d\u8001\u5e08\u3002\u8fd9\u5c31\u662f 110 \u51fd\u6570\u7684\u4e24\u4e2a\u91cd\u8f7d\uff0c\u6839\u636e\u8c03\u7528\u8005\u4f20\u5165\u7684\u4fe1\u606f\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8f6c\u7ed9\u54ea\u4e00\u4e2a\u5b50\u90e8\u95e8\u3002 \u540c\u7406\uff0c\u7f16\u8bd1\u5668\u4e5f\u662f\u4f1a\u6839\u636e\u8c03\u7528\u65f6\u4f60\u4f20\u5165\u7684\u53c2\u6570\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8c03\u7528\u91cd\u8f7d\u7684\u54ea\u4e00\u4e2a\u5177\u4f53\u7248\u672c\u3002 C \u8bed\u8a00\u6ca1\u6709\u91cd\u8f7d\uff0c\u51fd\u6570\u540d\u5b57\u76f8\u540c\u5c31\u4f1a\u53d1\u751f\u51b2\u7a81\uff0c\u7f16\u8bd1\u5668\u4f1a\u5f53\u573a\u62a5\u9519\u3002 C++ \u652f\u6301\u91cd\u8f7d\uff0c\u53ea\u6709\u5f53\u51fd\u6570\u540d\u5b57\u76f8\u540c\uff0c\u53c2\u6570\u5217\u8868\u4e5f\u76f8\u540c\u65f6\uff0c\u624d\u4f1a\u53d1\u751f\u51b2\u7a81\u3002 \u8fd4\u56de\u503c\u7c7b\u578b\u4e0d\u5f71\u54cd\u91cd\u8f7d\uff0c\u91cd\u8f7d\u53ea\u770b\u53c2\u6570\u5217\u8868\u3002 \u83dc\u9e1f\u6559\u7a0b\u4e0a\u5bf9 C++ \u91cd\u8f7d\u7684\u89e3\u91ca 1 \uff1a C++ \u5141\u8bb8\u5728\u540c\u4e00\u4f5c\u7528\u57df\u4e2d\u7684\u67d0\u4e2a\u51fd\u6570\u548c\u8fd0\u7b97\u7b26\u6307\u5b9a\u591a\u4e2a\u5b9a\u4e49\uff0c\u5206\u522b\u79f0\u4e3a\u51fd\u6570\u91cd\u8f7d\u548c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u91cd\u8f7d\u58f0\u660e\u662f\u6307\u4e00\u4e2a\u4e0e\u4e4b\u524d\u5df2\u7ecf\u5728\u8be5\u4f5c\u7528\u57df\u5185\u58f0\u660e\u8fc7\u7684\u51fd\u6570\u6216\u65b9\u6cd5\u5177\u6709\u76f8\u540c\u540d\u79f0\u7684\u58f0\u660e\uff0c\u4f46\u662f\u5b83\u4eec\u7684\u53c2\u6570\u5217\u8868\u548c\u5b9a\u4e49\uff08\u5b9e\u73b0\uff09\u4e0d\u76f8\u540c\u3002 \u5f53\u60a8\u8c03\u7528\u4e00\u4e2a\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u65f6\uff0c\u7f16\u8bd1\u5668\u901a\u8fc7\u628a\u60a8\u6240\u4f7f\u7528\u7684\u53c2\u6570\u7c7b\u578b\u4e0e\u5b9a\u4e49\u4e2d\u7684\u53c2\u6570\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\uff0c\u51b3\u5b9a\u9009\u7528\u6700\u5408\u9002\u7684\u5b9a\u4e49\u3002\u9009\u62e9\u6700\u5408\u9002\u7684\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u7684\u8fc7\u7a0b\uff0c\u79f0\u4e3a\u91cd\u8f7d\u51b3\u7b56\u3002 \u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\uff0c\u53ef\u4ee5\u58f0\u660e\u51e0\u4e2a\u529f\u80fd\u7c7b\u4f3c\u7684\u540c\u540d\u51fd\u6570\uff0c\u4f46\u662f\u8fd9\u4e9b\u540c\u540d\u51fd\u6570\u7684\u5f62\u5f0f\u53c2\u6570\uff08\u6307\u53c2\u6570\u7684\u4e2a\u6570\u3001\u7c7b\u578b\u6216\u8005\u987a\u5e8f\uff09\u5fc5\u987b\u4e0d\u540c\u3002\u60a8\u4e0d\u80fd\u4ec5\u901a\u8fc7\u8fd4\u56de\u7c7b\u578b\u7684\u4e0d\u540c\u6765\u91cd\u8f7d\u51fd\u6570\u3002 V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u4f46\u662f\u4e0a\u9762\u8fd9\u4e24\u4e2a at \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u90fd\u662f K const & \uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u91cd\u8f7d\u5462\uff1f \u6ce8\u610f\u770b\u7b2c\u4e8c\u4e2a\u7248\u672c\u6700\u540e\u9762\u591a\u4e86\u4e00\u4e2a const \u5173\u952e\u5b57\uff0c\u8fd9\u79cd\u5199\u6cd5\u662f\u4ec0\u4e48\u610f\u601d\uff1f\u5c0f\u5f6d\u8001\u5e08\u5bf9\u5176\u8fdb\u884c\u795b\u9b45\u5316\uff1a V &at(map *this, K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(map const *this, K const &k); // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u539f\u6765\u52a0\u5728\u51fd\u6570\u62ec\u53f7\u540e\u9762\u7684 const\uff0c\u5b9e\u9645\u4e0a\u662f\u7528\u4e8e\u4fee\u9970 this \u6307\u9488\u7684\uff01 \u8be5\u5199\u6cd5\u4ec5\u4f9b\u793a\u610f\uff0c\u5e76\u4e0d\u662f\u771f\u7684\u53ef\u4ee5\u628a this \u5199\u6210\u53c2\u6570 \u6240\u4ee5\u4e24\u4e2a at \u7684\u53c2\u6570\u5217\u8868\u4e0d\u540c\uff0c\u4e0d\u540c\u5728\u4e8e\u4f20\u5165 this \u6307\u9488\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u53ef\u4ee5\u91cd\u8f7d\uff0c\u4e0d\u4f1a\u51b2\u7a81\u3002 \u5f53 map \u5bf9\u8c61\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map const * \uff0c\u6240\u4ee5\u53ea\u80fd\u8c03\u7528\u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at\u3002 \u5f53 map \u5bf9\u8c61\u4e0d\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map * \uff0c\u4e24\u4e2a\u91cd\u8f7d\u90fd\u53ef\u4ee5\u8c03\u7528\uff0c\u4f46\u7531\u4e8e\u7b2c\u4e00\u4e2a\u91cd\u8f7d\u66f4\u52a0\u7b26\u5408\uff0c\u6240\u4ee5\u4f1a\u8c03\u7528\u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at\u3002 \u6709\u8da3\u7684\u662f\uff0cC++23 \u652f\u6301\u4e86\u663e\u5f0f\u5bf9\u8c61\u5f62\u53c2\uff08deducing-this\uff09\uff0cthis \u4e5f\u80fd\u50cf\u666e\u901a\u53c2\u6570\u4e00\u6837\u5b9a\u4e49\u4e86\uff01\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u6210\uff1a class map { ... V &at(this map &self, K const &k) { // \u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u4f7f\u7528self\u4ee3\u66ff\u539f\u6765\u7684this\uff08this\u5c06\u4e0d\u518d\u53ef\u7528\uff09 ... } V const &at(this map const &self, K const &k) { ... } }; \u521a\u521a\u89e3\u91ca\u4e86\u51fd\u6570\u91cd\u8f7d\uff0c\u90a3\u4e48\u8fd0\u7b97\u7b26\u91cd\u8f7d\u5462\uff1f \u56e0\u4e3a\u539f\u672c C \u8bed\u8a00\u5c31\u6709 [] \u8fd0\u7b97\u7b26\uff0c\u4e0d\u8fc7\u90a3\u53ea\u9002\u7528\u4e8e\u539f\u59cb\u6307\u9488\u548c\u539f\u59cb\u6570\u7ec4\u3002\u800c C++ \u5141\u8bb8\u4e5f [] \u8fd0\u7b97\u7b26\u652f\u6301\u5176\u4ed6\u7528\u6237\u81ea\u5b9a\u4e49\u7c7b\u578b\uff08\u6bd4\u5982 std::map\uff09\uff0c\u548c C \u8bed\u8a00\u81ea\u5e26\u7684\u76f8\u6bd4\u5c31\u53ea\u6709\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\uff08\u4e00\u4e2a\u662f\u539f\u59cb\u6570\u7ec4\uff0c\u4e00\u4e2a\u662f std::map\uff09\uff0c\u6240\u4ee5\u548c\u51fd\u6570\u91cd\u8f7d\u5f88\u76f8\u4f3c\uff0c\u8fd9\u5c31\u662f\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 m[\"key\"]; \u4f1a\u88ab\u7f16\u8bd1\u5668\u201c\u7ffb\u8bd1\u201d\u6210\uff1a m.operator[](\"key\"); \u4ee5\u4e0a\u4ee3\u7801\u5e76\u975e\u4ec5\u4f9b\u793a\u610f\uff0c\u662f\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u8fd0\u884c\u7684\u3002 operator[] \u867d\u7136\u770b\u8d77\u6765\u5f88\u590d\u6742\u4e00\u4e2a\u5173\u952e\u5b57\u52a0\u7279\u6b8a\u7b26\u53f7\uff0c\u5176\u5b9e\u65e0\u975e\u5c31\u662f\u4e2a\u7279\u6b8a\u7684\u51fd\u6570\u540d\uff0c\u5b66\u8fc7 Python \u7684\u7ae5\u978b\u53ef\u4ee5\u628a\u4ed6\u60f3\u8c61\u6210 __getitem__ \u3002 V &operator[](K const &k); \u7ed3\u8bba\uff1a[] \u8fd0\u7b97\u7b26\u5b9e\u9645\u4e0a\u662f\u5728\u8c03\u7528 operator[] \u51fd\u6570\u3002 \u6240\u6709\u7684\u6240\u8c13\u201c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u51fd\u6570\u201d\u5b9e\u9645\u4e0a\u90fd\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6807\u8bc6\u7b26\uff0c\u4ee5 operator + \u8fd0\u7b97\u7b26\u7684\u5f62\u5f0f\uff0c\u4ed6\u4eec\u4e24\u4e2a\u7ec4\u6210\u4e00\u4e2a\u6574\u4f53\uff0c\u4f60\u8fd8\u53ef\u4ee5\u8bd5\u8bd5 string(\"hel\").operator+(\"lo\") \uff0c\u548c string(\"hel\") + \"lo\" \u662f\u7b49\u4ef7\u7684\u3002 \u56e0\u4e3a operator[] \u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u540e\u9762\u6ca1\u6709 const \u4fee\u9970\uff0c\u56e0\u6b64\u5f53 map \u4fee\u9970\u4e3a const \u65f6\u7f16\u8bd1\u4f1a\u4e0d\u901a\u8fc7 1 \uff1a const map config = { // \u6b64\u5904\u5982\u679c\u662f\u5e26 const & \u4fee\u9970\u7684\u51fd\u6570\u53c2\u6570\u4e5f\u662f\u540c\u7406 {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // \u7f16\u8bd1\u51fa\u9519 /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp: In function \u2018int main()\u2019: /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp:10:23: error: passing \u2018const std::map, int>\u2019 as \u2018this\u2019 argument discards qualifiers [-fpermissive] 10 | print(config[\"timeout\"]); \u7f16\u8bd1\u5668\u8bf4 discards qualifiers\uff0c\u610f\u601d\u662f map \u6709 const \u4fee\u9970\uff0c\u4f46\u662f operator[] \u6ca1\u6709\u3002 \u8fd9\u5b9e\u9645\u4e0a\u5c31\u662f\u5728\u8bf4\uff1a map const *this \u4e0d\u80fd\u8f6c\u6362\u6210 map *this \u3002 \u6709 const \u4fee\u9970\u7684 map \u4f5c\u4e3a this \u6307\u9488\u4f20\u5165\u6ca1 const \u4fee\u9970\u7684 operator[] \u51fd\u6570\uff0c\u662f\u51cf\u5c11\u4e86\u4fee\u9970\uff08discards qualifers\uff09\u3002 C++ \u89c4\u5b9a\u4f20\u53c2\u65f6\u53ea\u80fd\u589e\u52a0\u4fee\u9970\u4e0d\u80fd\u51cf\u5c11\u4fee\u9970\uff1a\u53ea\u80fd\u4ece map * \u8f6c\u6362\u5230 map const * \u800c\u4e0d\u80fd\u53cd\u4e4b\u3002 \u6240\u4ee5\u5bf9\u7740\u4e00\u4e2a const map \u8c03\u7528\u975e const \u7684\u6210\u5458\u51fd\u6570 operator[] \u5c31\u51fa\u9519\u4e86\uff0c\u76f8\u6bd4\u4e4b\u4e0b at() \u5c31\u53ef\u4ee5\u5728 const \u4fee\u9970\u4e0b\u7f16\u8bd1\u901a\u8fc7\u3002 \u4e3a\u4ec0\u4e48 operator[] \u662f\u975e const \u4fee\u9970\u7684\u5462\uff1f\u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u4e0d\u662f const\uff0c\u610f\u5473\u7740\u4ed6\u4f1a \u5c31\u5730\u4fee\u6539 this \u5bf9\u8c61 \u3002 \u5176\u5b9e\uff0coperator[] \u53d1\u73b0\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config); print(config[\"tmeout\"]); // \u6709\u526f\u4f5c\u7528\uff01 print(config); {\"delay\": 211, \"timeout\": 985} 0 {\"delay\": 211, \"timeout\": 985, \"tmeout\": 0} \u4f1a\u81ea\u52a8\u521b\u5efa\u90a3\u4e2a\u4e0d\u5b58\u5728\u7684\u952e\u503c\uff01 \u4f60\u4ee5\u4e3a\u4f60\u53ea\u662f\u89c2\u5bdf\u4e86\u4e00\u4e0b map \u91cc\u7684 \u201ctmeout\u201d \u5143\u7d20\uff0c\u5374\u610f\u5916\u6539\u53d8\u4e86 map \u7684\u5185\u5bb9\uff0c\u859b\u5b9a\u8c14\u76f4\u547c\u5185\u884c\u3002 \u4e3a\u4ec0\u4e48\u628a [] \u8bbe\u8ba1\u7684\u8fd9\u4e48\u5371\u9669\uff1f \u65e2\u7136\u5df2\u7ecf\u6709\u66f4\u5b89\u5168\u7684 .at()\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u8ba9 [] \u7ee7\u7eed\u5b58\u5728\u5462\uff1f map config = { {\"delay\", 211}, }; config.at(\"timeout\") = 985; // \u952e\u503c\u4e0d\u5b58\u5728\uff0c\u62a5\u9519\uff01 config[\"timeout\"] = 985; // \u6210\u529f\u521b\u5efa\u5e76\u5199\u5165 985 \u7531\u4e0a\u53ef\u89c1\uff0c\u5f53\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u672c\u4e0d\u5b58\u5728\u7684\u952e\u503c\u7684\u65f6\u5019\uff0c\u6070\u6070\u9700\u8981 [] \u7684\u201c\u81ea\u52a8\u521b\u5efa\u201d\u8fd9\u4e00\u7279\u6027\uff0c\u8fd9\u662f at() \u6240\u4e0d\u5177\u6709\u7684\u3002 \u603b\u7ed3\uff1a\u8bfb\u53d6\u65f6\u5e94\u8be5\u7528 at() \u66f4\u5b89\u5168\uff0c\u5199\u5165\u65f6\u624d\u9700\u8981\u7528\u5e26\u6709\u81ea\u52a8\u521b\u5efa\u529f\u80fd\u7684 []\u3002 \u8bb8\u591a\u7b2c\u4e09\u65b9\u5e93\uff0c\u4f8b\u5982 jsoncpp\uff0c\u4ed6\u4eec\u7684\u5b57\u5178\u7c7b\u578b\u4e5f\u4f7f\u7528\u7c7b\u4f3c\u7684\u63a5\u53e3\uff0cat() \u8d1f\u8d23\u8bfb\uff0c[] \u8d1f\u8d23\u5199\uff0c\u5206\u5de5\u660e\u786e\uff01 \u603b\u7ed3 \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 at() \u5199\u5165\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 [] auto val = m.at(\"key\"); m[\"key\"] = val; \u4e3a\u4ec0\u4e48\u5176\u4ed6\u8bed\u8a00\u6bd4\u5982 Python\uff0c\u53ea\u6709\u4e00\u4e2a [] \u5c31\u884c\u4e86\u5462\uff1f\u800c C++ \u9700\u8981\u4e24\u4e2a\uff1f \u56e0\u4e3a Python \u4f1a\u68c0\u6d4b [] \u4f4d\u4e8e\u7b49\u53f7\u5de6\u4fa7\u8fd8\u662f\u53f3\u4fa7\uff0c\u6839\u636e\u60c5\u51b5\u5206\u522b\u8c03\u7528 __getitem__ \u6216\u8005 __setitem__ \u3002 C++ \u7f16\u8bd1\u5668\u6ca1\u6709\u8fd9\u4e2a\u7279\u6b8a\u68c0\u6d4b\uff0c\u4e5f\u68c0\u6d4b\u4e0d\u4e86\uff0c\u56e0\u4e3a C++ \u7684 [] \u53ea\u662f\u8fd4\u56de\u4e86\u4e2a\u5f15\u7528\uff0c\u5e76\u4e0d\u77e5\u9053 [] \u51fd\u6570\u8fd4\u56de\u4ee5\u540e\uff0c\u4f60\u662f\u62ff\u8fd9\u4e2a\u5f15\u7528\u5199\u5165\u8fd8\u662f\u8bfb\u53d6\u3002\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\u4ed6\u9ed8\u8ba4\u4f60\u662f\u5199\u5165\uff0c\u6240\u4ee5\u5148\u5e2e\u4f60\u521b\u5efa\u4e86\u5143\u7d20\uff0c\u8fd4\u56de\u8fd9\u4e2a\u5143\u7d20\u7684\u5f15\u7528\uff0c\u8ba9\u4f60\u5199\u5165\u3002 \u800c Python \u7684\u5f15\u7528\u662f\u4e0d\u80fd\u7528 = \u8986\u76d6\u539f\u503c\u7684\uff0c\u90a3\u6837\u53ea\u4f1a\u8ba9\u53d8\u91cf\u6307\u5411\u65b0\u7684\u5f15\u7528\uff0c\u53ea\u80fd\u7528 .func() \u5f15\u7528\u6210\u5458\u51fd\u6570\u6216\u8005 += \u624d\u80fd\u5c31\u5730\u4fee\u6539\u539f\u53d8\u91cf\uff0c\u8fd9\u662f Python \u8fd9\u7c7b\u811a\u672c\u8bed\u8a00\u548c C++ \u6700\u672c\u8d28\u7684\u4e0d\u540c\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7528 C++ \u7684 map \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u9700\u8981\u663e\u5f0f\u5730\u7528 at() \u544a\u8bc9\u7f16\u8bd1\u5668\u6211\u662f\u6253\u7b97\u8bfb\u53d6\u3002 [] \u627e\u4e0d\u5230\u5c31\u8fd4\u56de\u4e2a\u201c\u9ed8\u8ba4\u503c\u201d\uff0c\u5176\u5b9e\u4e5f\u662f\u5f88\u591a\u8bed\u8a00\u7684\u4f20\u7edf\u5f02\u80fd\u4e86\uff0c\u53ea\u6709\u521a\u597d Python \u6bd4\u8f83\u5bf9\u521d\u5b66\u8005\u53cb\u597d\uff0c\u4f1a\u81ea\u52a8\u5224\u65ad\u4f60\u7684 [] \u662f\u8bfb\u53d6\u8fd8\u662f\u5199\u5165\uff0c\u5982\u679c\u662f\u8bfb\u53d6\uff0c\u5f53\u627e\u4e0d\u5230\u952e\u503c\u65f6\u80fd\u53cb\u5584\u7684\u7ed9\u4f60\u62a5\u9519\u3002 \u8bed\u8a00\u53ca\u5176\u5173\u8054\u5bb9\u5668\u540d C++ map Python dict Lua table JS HashMap Java HashMap \u627e\u4e0d\u5230\u952e\u65f6\u7684\u884c\u4e3a \u9ed8\u9ed8\u8fd4\u56de 0 \u62a5\u9519 KeyError \u9ed8\u9ed8\u8fd4\u56de nil \u9ed8\u9ed8\u8fd4\u56de undefined .get()\uff0c\u9ed8\u9ed8\u8fd4\u56de null \u5176\u4e2d C++ \u7684 [] \u6700\u4e3a\u6076\u52a3\uff0c\u56e0\u4e3a\u53e4\u4ee3 C++ \u4e2d\u5e76\u6ca1\u6709\u4e00\u4e2a null \u6216 nil \u4e4b\u7c7b\u7684\u989d\u5916\u7279\u6b8a\u5e38\u91cf\u3002 [] \u8fd4\u56de\u7684\u5fc5\u987b\u662f\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u7531\u4e8e [] \u4e0d\u80fd\u62a5\u9519\uff0c\u503c\u7684\u7c7b\u578b\u53c8\u5343\u53d8\u4e07\u5316\uff0c map \u7684 [] \u53ea\u80fd\u8fd4\u56de\u201cV \u7c7b\u578b\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u7684\u503c\u201d\uff1a\u5bf9\u4e8e int \u800c\u8a00\u662f 0\uff0c\u5bf9\u4e8e string \u800c\u8a00\u662f \u201c\u201d\uff08\u7a7a\u5b57\u7b26\u4e32\uff09\u3002 \u4e5f\u6b63\u56e0\u5982\u6b64\uff0c\u5982\u679c\u4e00\u4e2a map \u4e2d\u7684 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5c31\u65e0\u6cd5\u4f7f\u7528 [] \u4e86\u3002\u770b\u4f3c\u7f8e\u597d\u7684 [] \u53ea\u662f\u9a97\u9a97\u5c0f\u5f6d\u53cb\u7684\u9762\u5b50\u5de5\u7a0b\uff0c\u6a21\u68f1\u4e24\u53ef\uff0c\u5145\u6ee1\u5371\u9669\u3002\u9ad8\u624b\u90fd\u4f7f\u7528\u66f4\u4e13\u4e1a\u7684\u5199\u5165\u51fd\u6570\uff1ainsert \u6216 insert_or_assign \u4ee3\u66ff\u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\u4e0d\u9700\u8981\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u66f4\u9ad8\u6548\u4e00\u4e9b\uff0c\u7a0d\u540e\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u3002 at \u4e0e [] \u5b9e\u6218\u6f14\u7ec3 \u6211\u4eec\u73b0\u5728\u7684\u7532\u65b9\u662f\u4e00\u4e2a\u5b66\u6821\u7684\u5927\u8001\u677f\uff0c\u4ed6\u5e0c\u671b\u8ba9\u6211\u4eec\u7ba1\u7406\u5b66\u751f\u4fe1\u606f\uff0c\u56e0\u6b64\u9700\u8981\u5efa\u7acb\u4e00\u4e2a\u6620\u5c04\u8868\uff0c\u80fd\u591f\u5feb\u901f\u901a\u8fc7\u5b66\u751f\u540d\u5b57\u67e5\u8be2\u5230\u76f8\u5e94\u7684\u5b66\u751f\u4fe1\u606f\u3002\u601d\u6765\u60f3\u53bb C++ \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668\u6700\u5408\u9002\u3002\u51b3\u5b9a\u8bbe\u8ba1\u5982\u4e0b\uff1a \u952e\u4e3a\u5b66\u751f\u7684\u540d\u5b57\uff0cstring \u7c7b\u578b\u3002 \u503c\u4e3a\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7ed3\u6784\u4f53\uff0cStudent \u7c7b\u578b\uff0c\u91cc\u9762\u5b58\u653e\u5404\u79cd\u5b66\u751f\u4fe1\u606f\u3002 \u7136\u540e\u81ea\u5b9a\u4e49\u4e00\u4e0b Student \u7ed3\u6784\u4f53\uff0c\u73b0\u5728\u628a\u9664\u4e86\u540d\u5b57\u4ee5\u5916\u7684\u5b66\u751f\u4fe1\u606f\u90fd\u585e\u5230\u8fd9\u4e2a\u7ed3\u6784\u4f53\u91cc\u3002 \u521b\u5efa map \u5bf9\u8c61\uff0c\u53d8\u91cf\u540d\u4e3a stus \uff0c\u8fd9\u4e2a map \u5c31\u662f\u7532\u65b9\u8981\u6c42\u7684\u5b66\u751f\u8868\uff0c\u6210\u529f\u4ea4\u5dee\u3002 struct Student { int id; // \u5b66\u53f7 int age; // \u5e74\u9f84 string sex; // \u6027\u522b int money; // \u5b58\u6b3e set skills; // \u6280\u80fd }; map stus; \u73b0\u5728\u5c0f\u5f6d\u8001\u5e08\u548c\u4ed6\u7684\u7ae5\u978b\u4eec\u8981\u8fdb\u5165\u8fd9\u5bb6\u5b66\u6821\u4e86\uff0c\u8ba9\u6211\u4eec\u7528 [] \u5927\u6cd5\u63d2\u5165\u4ed6\u7684\u4e2a\u4eba\u4fe1\u606f\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = Student{20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = Student{20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = Student{20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = Student{20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u7531\u4e8e C++11 \u5141\u8bb8\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b\u4e0d\u5199\uff0c\u6240\u4ee5 Student \u53ef\u4ee5\u7701\u7565\uff0c\u7b80\u5199\u6210\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = {20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = {20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u53c8\u7531\u4e8e map \u652f\u6301\u5728\u521d\u59cb\u5316\u65f6\u5c31\u6307\u5b9a\u6240\u6709\u5143\u7d20\uff0c\u6211\u4eec\u76f4\u63a5\u5199\uff1a map stus = { {\"\u5f6d\u4e8e\u658c\", {20220301, 22, \"\u81ea\u5b9a\u4e49\", 1000, {\"C\", \"C++\"}}}, {\"\u76f8\u4f9d\", {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}}, {\"\u6a31\u82b1\u7c89\u871c\u7cd6\", {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}}, {\"Sputnik02\", {20220301, 19, \"\u7537\", 4000, {\"C++\"}}}, }; \u73b0\u5728\u7532\u65b9\u8981\u6c42\u6dfb\u52a0\u4e00\u4e2a\u201c\u57f9\u8bad\u201d\u51fd\u6570\uff0c\u7528\u4e8e\u4ed6\u4eec\u7684 C++ \u57f9\u8bad\u8bfe\u3002 \u57f9\u8bad\u51fd\u6570\u7684\u53c2\u6570\u4e3a\u5b57\u7b26\u4e32\uff0c\u8868\u793a\u8981\u6d88\u8d39\u5b66\u751f\u7684\u540d\u5b57\u3002\u5982\u679c\u8be5\u540d\u5b57\u5b66\u751f\u4e0d\u5b58\u5728\uff0c\u5219\u5e94\u8be5\u53ca\u65f6\u62a5\u9519\u3002 \u6bcf\u6b21\u57f9\u8bad\u9700\u8981\u6d88\u8d39 2650 \u5143\uff0c\u6d88\u8d39\u6210\u529f\u540e\uff0c\u5f80\u6280\u80fd skills \u96c6\u5408\u4e2d\u52a0\u5165 \u201cC++\u201d\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u8fd9\u662f\u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 stu.money -= 2650; stu.skills.insert(\"C++\"); } \u7136\u800c\uff0c\u8fd9\u6837\u5199\u662f\u4e0d\u5bf9\u7684\uff01 stus.at(stuName) \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528 Student & \u6307\u5411 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u4f46\u662f\u7b49\u53f7\u5de6\u4fa7\uff0c\u5374\u662f\u4e2a\u4e0d\u5e26\u4efb\u4f55\u4fee\u9970\u7684 auto \uff0c\u4ed6\u4f1a\u88ab\u63a8\u5bfc\u4e3a Student \u3002\u5982\u4f55\u4ece\u4e00\u4e2a\u5f15\u7528 Student & \u8f6c\u6362\u4e3a\u5177\u4f53\u7684 Student \uff1f\u627e\u4e0d\u5230 Student(Student &) \uff0c\u4f46\u662f\u627e\u5230\u4e86\u6700\u63a5\u8fd1\u7684 Student(Student const &) \u51fd\u6570\uff08\u8fd9\u662f\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff09\uff0c\u56e0\u6b64\u6211\u4eec\u62f7\u8d1d\u4e86\u4e00\u4efd map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\uff0c\u5230\u6808\u4e0a\u7684 stu \u53d8\u91cf\uff0c\u4e4b\u540e\u4e0d\u8bba\u5982\u4f55\u4fee\u6539\uff0c\u4fee\u6539\u7684\u90fd\u662f\u8fd9\u4e2a\u6808\u4e0a\u5bf9\u8c61\uff0c\u800c\u4e0d\u4f1a\u5bf9 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u4ea7\u751f\u4efb\u4f55\u5f71\u54cd\u3002 \u7ed3\u8bba\uff1a\u628a\u5f15\u7528\u4fdd\u5b58\u5230\u666e\u901a\u53d8\u91cf\u4e2d\uff0c\u5219\u5f15\u7528\u4f1a\u9000\u5316\uff0c\u9020\u6210\u6df1\u62f7\u8d1d\uff01\u4e0d\u4ec5\u5f71\u54cd\u6027\u80fd\uff0c\u8fd8\u5f71\u54cd\u529f\u80fd\uff01stu \u5df2\u7ecf\u662f\u4e00\u4e2a\u72ec\u7acb\u7684 Student \u5bf9\u8c61\uff0c\u5bf9 stu \u7684\u4fee\u6539\u5df2\u7ecf\u4e0d\u4f1a\u5f71\u54cd\u5230 stus.at(stuName) \u6307\u5411\u7684\u90a3\u4e2a Student \u5bf9\u8c61\u4e86\u3002 \u6b64\u65f6\u4f60\u5bf9\u8fd9\u4e2a\u666e\u901a\u53d8\u91cf\u7684\u6240\u6709\u4fee\u6539\uff0c\u90fd\u4e0d\u4f1a\u540c\u6b65\u5230 map \u4e2d\u7684\u90a3\u4e2a Student \u4e2d\u53bb\uff01 \u6211\u4eec\u73b0\u5728\u5bf9\u76f8\u4f9d\u7ae5\u978b\u8fdb\u884c C++ \u57f9\u8bad\uff1a PeiXunCpp(\"\u76f8\u4f9d\"); print(stus.at(\"\u76f8\u4f9d\")); \u7ed3\u679c\u53d1\u73b0\u4ed6\u7684\u5b58\u6b3e\u4e00\u5206\u6ca1\u5c11\uff0c\u4e5f\u6ca1\u5b66\u4f1a C++\uff1a {id: 20220302, age: 21, sex: \"\u7537\", money: 2000, skills: {\"C\", \"Java\"}} \u770b\u6765\u6211\u4eec\u7684\u4fee\u6539\u6ca1\u6709\u5728 map \u4e2d\u751f\u6548\uff1f\u539f\u6765\u662f\u56e0\u4e3a\u6211\u4eec\u5728 PeiXunCpp \u51fd\u6570\u91cc\uff1a auto stu = stus.at(stuName); // \u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 \u4e00\u4e0d\u5c0f\u5fc3\u5c31\u7528\u4e86\u201c\u514b\u9686\u4eba\u201d\u6280\u672f\uff01\u4ece\u5b66\u751f\u8868\u91cc\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\uff0c\u514b\u9686\u4e86\u4e00\u4efd\u653e\u5230\u6808\u4e0a\u7684\u201c\u76f8\u4f9d2\u53f7\u201d\uff01 \u7136\u540e\u6211\u4eec\u6263\u4e86\u8fd9\u4e2a\u4e34\u65f6\u514b\u9686\u4eba\u201c\u76f8\u4f9d2\u53f7\u201d\u7684\u94b1\uff0c\u5e76\u7ed9\u4ed6\u57f9\u8bad C++ \u6280\u672f\u3002 \u7136\u800c\u6211\u4eec\u57f9\u8bad\u7684\u662f\u6808\u4e0a\u7684\u4e34\u65f6\u53d8\u91cf\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u514b\u9686\u524d\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5e76\u6ca1\u6709\u53d7\u5230\u57f9\u8bad\uff0c\u4e5f\u6ca1\u6709\u6263\u94b1\u3002 \u7136\u540e\u5462\uff1f\u6b8b\u5fcd\u7684\u4e8b\u60c5\u53d1\u751f\u4e86\uff01\u5728\u5c0f\u5f6d\u8001\u5e08\u4e00\u901a\u64cd\u4f5c\u57f9\u8bad\u5b8c\u201c\u76f8\u4f9d2\u53f7\u201d\u540e\uff0c\u6211\u4eec\u628a\u4ed6\u9001\u4e0a\u65ad\u5934\u53f0\u2014\u2014\u6790\u6784\u4e86\uff01 \u800c\u8fd9\u4e00\u5207\u201c\u76f8\u4f9d1\u53f7\u201d\u5b8c\u5168\u4e0d\u77e5\u60c5\uff0c\u4ed6\u53ea\u77e5\u9053\u6709\u4eba\u558a\u4ed6\u505a\u514b\u9686\uff0c\u7136\u540e\u5c31\u56de\u5bb6\u73a9 Java \u53bb\u4e86\uff0c\u5e76\u6ca1\u6709\u57f9\u8bad C++ \u7684\u8bb0\u5fc6\u3002 \u8981\u9632\u6b62\u5f15\u7528\u9000\u5316\u6210\u666e\u901a\u53d8\u91cf\uff0c\u9700\u8981\u628a\u53d8\u91cf\u7c7b\u578b\u4e5f\u6539\u6210\u5f15\u7528\uff01\u8fd9\u79cd\u662f\u6d45\u62f7\u8d1d\uff0cstu \u548c stus.at(stuName) \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u4e2a Student \u5bf9\u8c61\u3002\u7528 auto \u6355\u83b7\u7684\u8bdd\uff0c\u6539\u6210 auto & \u5c31\u884c\u3002 void PeiXunCpp(string stuName) { auto &stu = stus.at(stuName); // \u5728\u6808\u4e0a\u521b\u5efa\u4e00\u4e2a\u6307\u5411\u539f Student \u5bf9\u8c61\u7684\u5f15\u7528 stu.money -= 2650; stu.skills.insert(\"C++\"); } {id: 20220302, age: 21, sex: \"\u7537\", money: -650, skills: {\"C\", \"C++\", \"Java\"}} \u7ec8\u4e8e\uff0c\u6b63\u7248\u201c\u76f8\u4f9d1\u53f7\u201d\u672c\u4f53\u978b\u5e9f\u4e86 C++\uff01 \u4e4b\u540e\u5982\u679c\u518d\u4ece\u201c\u76f8\u4f9d1\u53f7\u201d\u8eab\u4e0a\u514b\u9686\uff0c\u514b\u9686\u51fa\u6765\u7684\u201c\u76f8\u4f9dn\u53f7\u201d\u4e5f\u90fd\u4f1a\u5177\u6709\u57f9\u8bad\u8fc7 C++ \u7684\u8bb0\u5fc6\u4e86\u3002 \u5f15\u7528\u76f8\u5f53\u4e8e\u8eab\u4efd\u8bc1\uff0c\u6211\u4eec\u590d\u5370\u4e86\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\uff0c\u8eab\u4efd\u8bc1\u4e0d\u4ec5\u590d\u5370\u8d77\u6765\u6bd4\u514b\u9686\u4e00\u4e2a\u5927\u6d3b\u4eba\u5bb9\u6613\uff08\u62f7\u8d1d\u5f00\u9500\uff09\u4ece\u800c\u63d0\u5347\u6027\u80fd\uff0c\u800c\u4e14\u901a\u8fc7\u8eab\u4efd\u8bc1\u53ef\u4ee5\u627e\u5230\u672c\u4eba\uff0c\u5bf9\u8eab\u4efd\u8bc1\u7684\u4fee\u6539\u4f1a\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u6539\u4e3a\u5bf9\u672c\u4eba\u7684\u4fee\u6539\uff0c\u4f8b\u5982\u901a\u8fc7\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\u5728\u94f6\u884c\u5f00\u5361\u7b49\uff0c\u94f6\u884c\u8981\u7684\u662f\u8eab\u4efd\u8bc1\uff0c\u4e0d\u662f\u514b\u9686\u4eba\u54e6\u3002 \u5f15\u7528\u662f\u4e00\u4e2a\u70eb\u624b\u7684\u9999\u9999\u9762\u5305\uff0c\u666e\u901a\u53d8\u91cf\u5c31\u50cf\u4e00\u4e2a\u81ed\u81ed\u7684\u7b54\u8fa9\u9a6c\u6876\uff0c\u628a\u9762\u5305\u653e\u5230\u9a6c\u6876\uff08auto\uff09\u91cc\uff0c\u9762\u5305\u5c31\u81ed\u6389\uff0c\u8150\u70c2\u6389\uff0c\u4e0d\u80fd\u5403\u4e86\uff01\u8981\u8ba9\u9762\u5305\u8f6c\u79fb\u9635\u5730\u4e86\u4ee5\u540e\u4f9d\u7136\u597d\u5403\uff0c\u9700\u8981\u653e\u5230\u4fdd\u9c9c\u76d2\uff08auto &\uff09\u91cc\u3002 \u8fd9\u5c31\u662f C++ \u7684 decay\uff08\u4e2d\u6587\u521a\u597d\u662f\u201c\u9000\u5316\u201d\u3001\u201c\u53d8\u8d28\u201d\u7684\u610f\u601d\uff09\u89c4\u5219\u3002 \u4ee5\u4e0b\u90fd\u662f\u201c\u9999\u9999\u9762\u5305\u201d\uff0c\u653e\u8fdb\u9a6c\u6876\u91cc\u4f1a\u53d8\u8d28\uff1a T & \u4f1a\u53d8\u8d28\u6210 T \uff08\u5f15\u7528\u53d8\u8d28\u6210\u666e\u901a\u53d8\u91cf\uff09 T [] \u4f1a\u53d8\u8d28\u6210 T * \uff08\u6570\u7ec4\u53d8\u8d28\u6210\u9996\u5730\u5740\u6307\u9488\uff09 T () \u4f1a\u53d8\u8d28\u6210 T (*)() \uff08\u51fd\u6570\u53d8\u8d28\u6210\u51fd\u6570\u6307\u9488\uff09 \u5728\u51fd\u6570\u7684\u53c2\u6570\u4e2d\u3001\u51fd\u6570\u7684\u8fd4\u56de\u503c\u4e2d\u3001auto \u6355\u83b7\u7684\u53d8\u91cf\u4e2d\uff0c\u653e\u5165\u8fd9\u4e9b\u201c\u9999\u9999\u9762\u5305\u201d\u90fd\u4f1a\u53d1\u751f\u53d8\u8d28\uff01 \u5982\u4f55\u907f\u514d\u53d8\u8d28\uff1f\u90a3\u5c31\u4e0d\u8981\u7528\u9a6c\u6876\uff08\u666e\u901a\u53d8\u91cf\uff09\u88c5\u9762\u5305\u5457\uff01\u7528\u4fdd\u9c9c\u76d2\uff08\u5f15\u7528\u53d8\u91cf\uff09\u88c5\uff01 \u907f\u514d\u5f15\u7528 T &t \u53d8\u8d28\uff0c\u5c31\u5f97\u628a\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u6539\u6210\u5f15\u7528\uff0c\u6216\u8005\u7528 auto & \uff0c auto const & \u6355\u83b7\u624d\u884c\u3002 \u907f\u514d\u539f\u751f\u6570\u7ec4 T t[N] \u53d8\u8d28\uff0c\u4e5f\u53ef\u4ee5\u6539\u6210\u5f15\u7528 T (&t)[N] \uff0c\u4f46\u6bd4\u8f83\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u5c01\u88c5\u7684\u5b89\u5168\u9759\u6001\u6570\u7ec4 array \u6216 C++98 \u5c31\u6709\u7684\u5b89\u5168\u52a8\u6001\u6570\u7ec4 vector \u3002 \u907f\u514d\u51fd\u6570 T f() \u53d8\u8d28\uff0c\u53ef\u4ee5 T (&f)() \uff0c\u4f46\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u7684\u51fd\u6570\u5bf9\u8c61 function \u3002 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u9898\u5916\u8bdd\uff1a\u90aa\u6076\u7684\u9000\u5316\u89c4\u5219\u9020\u6210\u7a7a\u60ac\u6307\u9488\u7684\u6848\u4f8b typedef double arr_t[10]; auto func(arr_t val) { arr_t ret; memcpy(ret, val, sizeof(arr_t)); // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; // double [10] \u81ea\u52a8\u53d8\u8d28\u6210 double * } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); // \u6b64\u5904 auto \u4f1a\u88ab\u63a8\u5bfc\u4e3a double * print(std::span(ret, ret + 10)); return 0; } Segmentation fault (core dumped) \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6 ^{14}C ^{14}C \u8bed\u8a00\u201c\u8870\u53d8\u201d\u5bfc\u81f4\u7a0b\u5e8f Segmentation fault \u4e86\u3002 \u4fee\u590d\u65b9\u6cd5\uff1a\u522b\u518d\u7528 C \u8bed\u8a00\u7684\u715e\u7b14\u539f\u59cb\u4eba\u6570\u7ec4\u4e86\uff01\u7528 C++ \u5c01\u88c5\u597d\u7684 array\uff0c\u65e0\u9690\u60a3 typedef std::array arr_t; // \u5982\u9700\u52a8\u6001\u957f\u5ea6\uff0c\u6539\u7528 vector \u4ea6\u53ef auto func(arr_t val) { arr_t ret; ret = val; // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); print(ret); return 0; } {1, 2, 3, 4, 0, 0, 0, 0, 0, 0} \u5982\u679c\u4f60\u8fd8\u662f\u5b66\u4e0d\u4f1a\u600e\u4e48\u4fdd\u7559\u9999\u9999\u5f15\u7528\u7684\u8bdd\uff0c\u571f\u529e\u6cd5\uff1a\u4e5f\u53ef\u4ee5\u5728\u4fee\u6539\u540e\u518d\u6b21\u7528 [] \u5199\u56de\u5b66\u751f\u8868\u3002\u8fd9\u6837\u5b66\u751f\u8868\u91cc\u4e0d\u4f1a C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5c31\u4f1a\u88ab\u6211\u4eec\u6808\u4e0a\u57f9\u8bad\u8fc7 C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u8986\u76d6\uff0c\u73b0\u5728\u5b66\u751f\u8868\u91cc\u7684\u4e5f\u662f\u6709 C++ \u6280\u80fd\u7684\u201c\u76f8\u4f9d\u201d\u8fa3\uff01\u53ea\u4e0d\u8fc7\u9700\u8981\u7ffb\u6765\u8986\u53bb\u514b\u9686\u4e86\u597d\u51e0\u6b21\u6bd4\u8f83\u4f4e\u6548\u800c\u5df2\uff0c\u81f3\u5c11\u80fd\u7528\u4e86\uff0c\u5efa\u8bae\u53ea\u6709\u5b66\u4e0d\u61c2\u5f15\u7528\u7684\u7ae5\u978b\u518d\u7528\u8fd9\u79cd\u4fdd\u5e95\u5199\u6cd5\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u514b\u9686\u4e86\u4e00\u4efd\u201c\u76f8\u4f9d2\u53f7\u201d stu.money -= 2650; stu.skills.insert(\"C++\"); stus[stuName] = stu; // \u201c\u76f8\u4f9d2\u53f7\u201d\u593a\u820d\uff0c\u628a\u201c\u76f8\u4f9d1\u53f7\u201d\u7ed9\u8986\u76d6\u6389\u4e86 } \u72c2\u60f3\uff1a\u5982\u679c\u514b\u9686\u201c\u76f8\u4f9d1\u53f7\u201d\u540c\u5b66\uff0c\u5f97\u5230\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u7136\u540e\u628a\u539f\u6765\u7684\u6740\u2026\u2026\u554a\u4e0d\u5bf9\uff0c\u201c\u6790\u6784\u201d\u6389\uff0c\u7136\u540e\u5bf9\u5916\u8c0e\u79f0\u201c\u8fd9\u8fd8\u662f\u539f\u6765\u7684\u76f8\u4f9d1\u53f7\u5440\uff01\u201d\u4f1a\u4e0d\u4f1a\u88ab\u53d1\u73b0\u5462\uff1f \u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u4e0a\u9762\u4ee3\u7801\u7b2c 5 \u884c\u4e5f\u53ef\u4ee5\u6539\u7528 at\uff0c\u4e3a\u4ec0\u4e48\uff1f\u5c0f\u5f6d\u8001\u5e08\u4e0d\u662f\u8bf4 \u201cat \u7528\u4e8e\u8bfb\u53d6\uff0c[] \u7528\u4e8e\u5199\u5165\u201d \u5417\uff1f \u6211\u4eec\u7ae5\u978b\u8981\u5b66\u4f1a\u53d8\u901a\uff01\u5c0f\u5f6d\u8001\u5e08\u8b66\u544a\u8bf4 \u201c[] \u53ea\u80fd\u7528\u4e8e\u5199\u5165\u201d\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u5e73\u65f6\u7684\u5199\u5165\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u9700\u8981\u5199\u5165\u5230\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u6240\u4ee5 [] \u4f1a\u81ea\u52a8\u521b\u5efa\u5143\u7d20\u5c31\u5f88\u65b9\u4fbf\uff1b\u5982\u679c\u662f at() \u5c31\u4e0d\u7b26\u5408\u201c\u5199\u5165\u65f6\u81ea\u52a8\u521b\u5efa\u4e0d\u5b58\u5728\u7684\u952e\u201c\u3002\u4f46\u662f\u73b0\u5728\u7684\u60c5\u51b5\u662f\u6211\u4eec\u7b2c 2 \u884c\u5df2\u7ecf\u8bbf\u95ee\u8fc7 at(\"\u76f8\u4f9d\") \uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u786e\u8ba4 \"\u76f8\u4f9d\" \u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u56e0\u6b64\u6211\u5199\u5165\u7684\u4e00\u5b9a\u662f\u4e2a\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\uff0c\u8fd9\u65f6 [] \u548c at \u5df2\u7ecf\u6ca1\u533a\u522b\u4e86\uff0c\u6240\u4ee5\u7528 at \u7684\u975e const \u91cd\u8f7d\uff0c\u4e00\u6837\u53ef\u4ee5\u5199\u5165\u3002 \u6211\u4eec\u7ae5\u978b\u4e0d\u662f\u53bb\u6b7b\u8bb0\u786c\u80cc\u300a\u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55\u300b\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u540d\u8a00\u5f53\u505a\u201c\u4e24\u4e2a\u51e1\u662f\u201d\u5723\u7ecf\u3002\u8981\u7406\u89e3\u5c0f\u5f6d\u8001\u5e08\u4f1a\u8fd9\u4e48\u8bf4\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u624d\u80fd\u6839\u636e\u4e0d\u540c\u5b9e\u9645\u60c5\u51b5\uff0c\u5b9e\u4e8b\u6c42\u662f\u770b\u95ee\u9898\uff0c\u624d\u662f\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u552f\u7269\u7f16\u7a0b\u89c2\u7684\uff08\u5b5d\uff09 \u5982\u679c\u8981\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u5462\uff1f\u90a3\u5c31\u4ee5\u5b66\u53f7\u4e3a\u952e\uff0c\u7136\u540e\u628a\u5b66\u751f\u59d3\u540d\u653e\u5230 Student \u7ed3\u6784\u4f53\u4e2d\u3002 \u5982\u679c\u540c\u65f6\u6709\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u548c\u6839\u636e\u59d3\u540d\u67e5\u627e\u4e24\u79cd\u9700\u6c42\u5462\uff1f \u540c\u65f6\u9ad8\u6548\u5730\u6839\u636e\u591a\u4e2a\u952e\u8fdb\u884c\u67e5\u627e\uff0c\u751a\u81f3\u6307\u5b9a\u5404\u79cd\u6761\u4ef6\uff0c\u6bd4\u5982\u67e5\u8be2\u6240\u6709\u4f1a C++ \u7684\u5b66\u751f\u7b49\uff0c\u8fd9\u53ef\u4e0d\u662f map \u80fd\u641e\u5b9a\u7684\uff0c\u6216\u8005\u8bf4\u80fd\u641e\u5b9a\u4f46\u4e0d\u9ad8\u6548\uff08\u6700\u540e\u5f80\u5f80\u53ea\u80fd\u66b4\u529b\u904d\u5386\u67e5\u627e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u592a\u9ad8\uff09\u3002\u8fd9\u662f\u4e2a\u4e13\u95e8\u7684\u7814\u7a76\u9886\u57df\uff0c\u79f0\u4e3a\uff1a\u5173\u7cfb\u6570\u636e\u5e93\u3002 \u5173\u7cfb\u6570\u636e\u5e93\u7684\u5b9e\u73b0\u6709 MySQL\uff0cSQLite\uff0cMongoDB \u7b49\u3002C++ \u7b49\u7f16\u7a0b\u8bed\u8a00\u53ea\u9700\u8c03\u7528\u4ed6\u4eec\u63d0\u4f9b\u7684 API \u5373\u53ef\uff0c\u4e0d\u5fc5\u81ea\u5df1\u624b\u52a8\u5b9e\u73b0\u8fd9\u4e9b\u590d\u6742\u7684\u67e5\u627e\u548c\u63d2\u5165\u7b97\u6cd5\u3002 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u4e13\u4e1a\u7684\u201c\u5b66\u751f\u7ba1\u7406\u7cfb\u7edf\u201d\u90fd\u4f1a\u7528\u5173\u7cfb\u6570\u636e\u5e93\uff0c\u800c\u4e0d\u662f\u81ea\u5df1\u624b\u52a8\u7ef4\u62a4\u4e00\u4e2a map\u3002\u5173\u7cfb\u6570\u636e\u5e93\u5e95\u5c42\u7684\u6570\u636e\u7ed3\u6784\u66f4\u590d\u6742\uff0c\u4f46\u7ecf\u8fc7\u9ad8\u5ea6\u5c01\u88c5\uff0c\u6548\u7387\u66f4\u9ad8\uff0c\u63d0\u4f9b\u7684\u529f\u80fd\u4e5f\u66f4\u5168\u9762\uff0c\u7528\u8d77\u6765\u4e5f\u6bd4\u8f83\u65e0\u611f\u3002\u4f55\u51b5 map \u5b58\u5728\u5185\u5b58\u4e2d\uff0c\u7535\u8111\u4e00\u5173\u673a\uff0c\u5b66\u751f\u6570\u636e\u5c31\u6ca1\u4e86\uff01\u800c\u6570\u636e\u5e93\u53ef\u4ee5\u628a\u6570\u636e\u6301\u4e45\u5316\u5230\u78c1\u76d8\u4e2d\uff0c\u76f8\u5f53\u4e8e\u5728\u78c1\u76d8\u91cc\u6784\u5efa\u51fa\u4e86\u4e00\u9897\u67e5\u627e\u6811\uff0c\u5173\u673a\u540e\u6570\u636e\u4f9d\u7136\u4fdd\u6301\u3002 \u76f8\u4f9d\u540c\u5b66\u597d\u4e0d\u5bb9\u6613\u8003\u51fa\u6ee1\u5206\uff0c\u7ed3\u679c\u5c0f\u5f6d\u8001\u5e08\u4e00\u4e0d\u5c0f\u5fc3\u8e22\u4e86\u4e00\u811a\u7535\u8111\uff0c\u91cd\u542f\uff0c\u5168\u90e8\u5b66\u751f\u6863\u6848\u4e22\u5931\uff0c\u767d\u8003\uff01 \u67e5\u8be2 map \u4e2d\u5143\u7d20\u7684\u6570\u91cf size_t size() const noexcept; \u4f7f\u7528 m.size() \u83b7\u5f97\u7684 map \u5927\u5c0f\uff0c\u6216\u8005\u8bf4\u5176\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002 map m; print(m.size()); // 0 m[\"fuck\"] = 985; print(m.size()); // 1 m[\"dick\"] = 211; print(m.size()); // 2 \u5e94\u7528\u4e3e\u4f8b\uff1a\u7ed9\u6bcf\u4e2a\u952e\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u8ba1\u6570 map m; m[\"fuck\"] = m.size(); m[\"dick\"] = m.size(); \u9700\u8981 C++17 \u4ee5\u4e0a\u7684\u7248\u672c\uff0c\u624d\u80fd\u4fdd\u8bc1\u7b49\u53f7\u53f3\u8fb9\u7684 m.size() \u5148\u4e8e m[\"fuck\"] \u6c42\u503c\u3002C++14 \u4e2d\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u884c\u4e3a\u672a\u5b9a\u4e49\uff0c\u9700\u8981\u6539\u7528 m.insert({\"fuck\", m.size()}) \u7684\u5199\u6cd5\uff08\u51fd\u6570\u53c2\u6570\u603b\u662f\u4f18\u5148\u4e8e\u51fd\u6570\u6c42\u503c\uff0c\u8fd9\u4fdd\u8bc1 m.size() \u5148\u6c42\u503c\uff0c\u7136\u540e\u624d\u53d1\u751f\u5143\u7d20\u63d2\u5165\uff09\u3002 \u5224\u65ad\u4e00\u4e2a\u952e\u662f\u5426\u5b58\u5728\uff1acount \u51fd\u6570 size_t count(K const &k) const; count \u8fd4\u56de\u5bb9\u5668\u4e2d\u952e\u548c\u53c2\u6570 k \u76f8\u7b49\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 count \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u4e00\u4e2a\u952e\u5728 map \u4e2d\u662f\u5426\u5b58\u5728\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.count(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } if (msg.count(\"dick\")) { print(\"\u5b58\u5728dick\uff0c\u5176\u503c\u4e3a\", msg.at(\"suck\")); } else { print(\"\u627e\u4e0d\u5230dick\"); } {\"fuck\": \"rust\", \"hello\": \"world\"} \u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a \"rust\" \u627e\u4e0d\u5230dick C++20 \u4e2d\u5efa\u8bae\u6539\u7528\u8fd4\u56de\u7c7b\u578b\u4e3a bool \u7684 contains \u51fd\u6570\uff0c\u51fd\u6570\u540d\u548c\u7c7b\u578b\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u4f46\u5b9e\u9645\u6548\u679c\u548c count \u662f\u4e00\u6837\u7684\u3002 if (msg.contains(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 \u9664\u4e86\u5199\u5165\u5143\u7d20\u9700\u8981\u7528 [] \u4ee5\u5916\uff0c\u8fd8\u6709\u4e00\u4e9b\u6848\u4f8b\u4e2d\u5408\u7406\u8fd0\u7528 [] \u4f1a\u975e\u5e38\u7684\u65b9\u4fbf\u3002 [] \u7684\u6548\u679c\uff1a\u5f53\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u4e00\u4e2a\u5143\u7d20 1 \u3002 \u5bf9\u4e8e int, float \u7b49\u6570\u503c\u7c7b\u578b\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f 0\u3002 \u5bf9\u4e8e\u6307\u9488\uff08\u5305\u62ec\u667a\u80fd\u6307\u9488\uff09\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f nullptr\u3002 \u5bf9\u4e8e string \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 \u201c\u201d\u3002 \u5bf9\u4e8e vector \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u6570\u7ec4 {}\u3002 \u5bf9\u4e8e\u81ea\u5b9a\u4e49\u7c7b\u800c\u8a00\uff0c\u4f1a\u8c03\u7528\u4f60\u5199\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5219\u6bcf\u4e2a\u6210\u5458\u90fd\u53d6\u9ed8\u8ba4\u503c\u3002 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 vector input = {\"hello\", \"world\", \"hello\"}; map counter; for (auto const &key: input) { counter[key]++; } print(counter); {\"hello\": 2, \"world\": 1} \u5bf9\u6bd4 \u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa 0 \u5143\u7d20\u7684\u7279\u6027 map counter; for (auto const &key: input) { counter[key]++; } \u53e4\u677f\u7684\u5199\u6cd5 map counter; for (auto const &key: input) { if (!counter.count(key)) { counter[key] = 1; } else { counter[key] = counter.at(key) + 1; } } [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b vector input = {\"happy\", \"world\", \"hello\", \"weak\", \"strong\"}; map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); {'h': {\"happy\", \"hello\"}, 'w': {\"world\", \"weak\"}, 's': {\"strong\"}} \u5bf9\u6bd4 \u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa\u201d\u9ed8\u8ba4\u503c\u201d\u5143\u7d20\u7684\u7279\u6027 map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); \u53e4\u677f\u7684\u5199\u6cd5 map> categories; for (auto const &str: input) { char key = str[0]; if (!categories.count(key)) { categories[key] = {str}; } else { categories[key].push_back(str); } } [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf concurrent_map tls; parallel_for([] { Data &data = tls[std::this_thread::get_id()]; ...; }); \u4e0d\u8fc7 thread_local \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u53d6\u4ee3\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 \u53cd\u9762\u5178\u578b\uff1a\u67e5\u627e\u7279\u5b9a\u5143\u7d20\u5728 vector \u4e2d\u7684\u4f4d\u7f6e\uff08\u4e0b\u6807\uff09 size_t array_find(vector const &arr, string const &val) { for (size_t i = 0; i < arr.size(); i++) { if (arr[i] == val) return i; } return (size_t)-1; } vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; print(\"hello\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"fucker\")); // O(N) \u4f4e\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"nice\")); // O(N) \u4f4e\u6548 \u6bcf\u6b21\u8c03\u7528 array_find \uff0c\u90fd\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a0 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N^2) O(N^2) \u3002 \u6ce8\uff1a\u5047\u8bbe vector \u4e2d\u4e0d\u5b58\u5728\u91cd\u590d\u7684\u5143\u7d20 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 \u6b63\u786e\u505a\u6cd5\uff1a\u6784\u5efa vector \u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u4ee5\u540e\u67e5\u627e\u66f4\u9ad8\u6548 vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; map arrinv; for (size_t i = 0; i < arr.size(); i++) { // O(N) \u4e00\u6b21\u6027\u53d7\u82e6 arrinv[arr[i]] = i; } print(\"\u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a\", arrinv); print(\"fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"fucker\")); // O(log N) \u9ad8\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"nice\")); // O(log N) \u9ad8\u6548 \u53ea\u6709\u7b2c\u4e00\u6b21\u6784\u9020\u53cd\u5411\u67e5\u627e\u8868\u65f6\uff0c\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u4ee5\u540e\u6bcf\u6b21\u8c03\u7528 map.at \uff0c\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a{\"day\": 3, \"fucker\", 4, \"hello\": 0, \"nice\": 2, \"world\": 1} fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a4 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u8f76\u4e8b\uff1a\u5728\u6570\u636e\u5e93\u4e2d\uff0c\u8fd9\u79cd\u53cd\u5411\u67e5\u627e\u8868\u88ab\u79f0\u4e3a\u201c\u5012\u5e8f\u7d22\u5f15\u201d\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u5728\u4e0d\u77e5\u9053\u8fd9\u4e2a\u672f\u8bed\u7684\u60c5\u51b5\u4e0b\uff0c\u72ec\u7acb\u4ea7\u751f\u4e86\u53cd\u5411\u67e5\u627e\u8868\u7684\u601d\u60f3 for (size_t i = 0; i < arr.size(); i++) { arrinv[arr[i]] = i; } \u63d0\u524d\u6784\u9020\u597d\u67e5\u627e\u8868 O(N) O(N) \uff0c\u4ee5\u540e\u6bcf\u6b21\u67e5\u627e\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u5c31\u884c\u3002 \uff08\u6b63\u5411\u67e5\u627e\uff09\u5df2\u77e5\u4e0b\u6807 i\uff0c\u6c42\u5143\u7d20 v\uff1a v = arr[i] \uff08\u53cd\u5411\u67e5\u627e\uff09\u5df2\u77e5\u5143\u7d20 v\uff0c\u6c42\u4e0b\u6807 i\uff1a i = arrinv[v] \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N \\log N) O(N \\log N) \uff0c\u6bd4\u4f18\u5316\u524d\u9ad8\u6548\u3002 \u56e0\u6b64\u5f53\u9700\u8981\u591a\u6b21\u67e5\u627e\u4e14\u539f\u6570\u7ec4\u4fdd\u6301\u4e0d\u53d8\u65f6\uff0c\u5f3a\u70c8\u63a8\u8350\u7528\u8fd9\u79cd\u65b9\u6cd5\uff0c\u66f4\u9ad8\u6548\u3002 \u53ea\u6709\u5f53 vector \u66f4\u65b0\u65f6\uff0c\u624d\u9700\u8981\u91cd\u65b0\u6784\u5efa map\u3002\u5982\u679c vector \u7684\u5220\u9664\u91c7\u7528 back-swap-erase\uff08\u89c1 C++ \u5c0f\u5999\u62db \uff09\uff0c\u90a3\u4e48\u65e0\u9700\u5b8c\u5168\u91cd\u6784 map\uff0c\u53ea\u9700\u66f4\u65b0 swap \u7684\u4e24\u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u603b\u590d\u6742\u5ea6 O(\\log N) O(\\log N) \uff0c\u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a O(\\log N) O(\\log N) \u7684\u6709\u4e0b\u6807\u53c8\u80fd\u5feb\u901f\u67e5\u627e\u6570\u7ec4\uff0c\u517c\u5177 map \u548c vector \u7684\u4f18\u52bf\u3002\u5728\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8fdb\u9636\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u6b64\u7c7b\u590d\u5408\u6570\u636e\u7ed3\u6784\u3002 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map \u53ea\u80fd\u901a\u8fc7\u503c\u6620\u5c04\u5230\u952e\uff0c\u80fd\u4e0d\u80fd\u53cd\u8fc7\u6765\u901a\u8fc7\u952e\u67e5\u627e\u503c\uff1f \u6848\u4f8b\uff1a\u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map tab = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; map tabinv; for (auto const &[k, v]: tab) { tabinv[v] = k; } print(tabinv); \u6548\u679c\u5c31\u662f\uff0c\u952e\u53d8\u503c\uff0c\u503c\u53d8\u952e\uff0c\u53cd\u4e00\u53cd\uff0c\u4e24\u4e2a map \u4e92\u4e3a\u9006\u8fd0\u7b97\uff1a {\"rust\": \"fuck\", \"world\": \"hello\"} \u6ce8\u610f\uff1a\u8981\u6c42 tab \u4e2d\u4e0d\u80fd\u5b58\u5728\u91cd\u590d\u7684\u503c\uff0c\u952e\u548c\u503c\u5fc5\u987b\u662f\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\uff0c\u624d\u80fd\u7528\u8fd9\u79cd\u65b9\u5f0f\u6784\u5efa\u53cc\u5411\u67e5\u627e\u8868\u3002\u5426\u5219\u4e00\u4e2a\u503c\u53ef\u80fd\u5bf9\u5e94\u5230\u4e24\u4e2a\u952e\uff0c\u53cd\u5411\u8868\u5fc5\u987b\u662f map> \u4e86\u3002 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1a value_type STL \u5bb9\u5668\u7684\u5143\u7d20\u7c7b\u578b\u90fd\u53ef\u4ee5\u901a\u8fc7\u6210\u5458 value_type \u67e5\u8be2\uff0c\u5e38\u7528\u4e8e\u6cdb\u578b\u7f16\u7a0b\uff08\u53c8\u79f0\u5143\u7f16\u7a0b\uff09\u3002 set::value_type // int vector::value_type // int string::value_type // char \u6b64\u5916\u8fd8\u6709\u5f15\u7528\u7c7b\u578b reference \uff0c\u8fed\u4ee3\u5668\u7c7b\u578b iterator \uff0c\u5e38\u8fed\u4ee3\u5668\u7c7b\u578b const_iterator \u7b49\u3002 \u66fe\u7ecf\u5728 C++98 \u4e2d\u5f88\u5e38\u7528\uff0c\u4e0d\u8fc7\u81ea\u4ece C++11 \u6709\u4e86 auto \u548c decltype \u4ee5\u540e\uff0c\u5c31\u4e0d\u600e\u4e48\u7528\u4e86\uff0c\u53cd\u6b63\u80fd\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 C++23: std::vector arr; for (auto const &elem: arr) { std::println(\"{}\", elem); } C++17: std::vector arr; for (auto const &elem: arr) { std::cout << elem << '\\n'; } C++11: std::vector arr; for (auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } C++98: std::vector arr; for (std::vector::iterator it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } typename \u4fee\u9970 \u5f53\u5bb9\u5668\u6709\u81f3\u5c11\u4e00\u4e2a\u4e0d\u786e\u5b9a\u7684\u7c7b\u578b T \u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u65f6\uff0c\u5c31\u9700\u8981\u524d\u9762\u52a0\u4e0a typename \u4fee\u9970\u4e86\uff1a set::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 typename set::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename set>::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 K\u3001T \u662f\u4e0d\u5b9a\u7c7b\u578b map::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 \u5982\u679c\u4f60\u641e\u4e0d\u6e05\u695a\uff0c\u59cb\u7ec8\u52a0 typename \u5c31\u884c\u4e86\uff0c\u53cd\u6b63\u52a0\u591a\u80af\u5b9a\u4e0d\u4f1a\u6709\u9519\u3002\u4f60\u5c31\u8ba4\u4e3a\uff1a\u8fd9\u5c31\u662f\u4e00\u4e2a\u5e73\u65f6\u53ef\u4ee5\u7701\u7565\uff0c\u5076\u5c14\u4e0d\u80fd\u7701\u7565\u7684\u4e1c\u897f\u3002 typename set::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb typename set::value_type; // \u4e0d\u80fd\u7701\u7565 typename set>::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb \u542b\u6709 T \u7684\u7c7b\u578b\u8868\u8fbe\u5f0f\u79f0\u4e3a dependent-type\uff0c\u6839\u672c\u539f\u56e0\u662f\u56e0\u4e3a\u5728\u4e0d\u77e5\u9053\u5177\u4f53\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\u8fd8\u662f\u503c\u8868\u8fbe\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u7f16\u8bd1\u5668\u65e0\u6cd5\u533a\u5206\u6a21\u677f\u7684 < \u548c\u5c0f\u4e8e\u7b26\u53f7 < \uff0c\u4ee5\u53ca\u7c7b\u578b\u7684\u6307\u9488 * \u548c\u6570\u503c\u4e58\u6cd5 * \u3002\u9ed8\u8ba4\u4f1a\u8ba4\u4e3a\u662f\u5c0f\u4e8e\u7b26\u53f7\u548c\u6570\u503c\u4e58\u6cd5\uff0c\u52a0\u4e0a typename \u540e\u660e\u786e\u524d\u9762\u8fd9\u4e00\u4e32\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\uff0c\u624d\u77e5\u9053\u8fd9\u662f\u6a21\u677f\u7684 < \u548c\u6307\u9488\u7684 * \u3002 decltype \u5927\u6cd5\u597d \u4e5f\u6709\u66f4\u76f4\u89c2\u7684\u83b7\u53d6 STL \u5bb9\u5668\u5143\u7d20\u7c7b\u578b\u7684\u65b9\u6cd5\uff1a std::vector arr; using T = std::decay_t; // T = int decltype \u5fc5\u987b\u914d\u5408 std::decay_t \u624d\u80fd\u7528\uff01\u5426\u5219\u4f1a\u5f97\u5230\u5f15\u7528\u7c7b\u578b int & \uff0c\u540e\u7eed\u4f7f\u7528\u4e2d\u5c31\u5751\u5230\u4f60\uff01\uff08\u56e0\u4e3a arr \u7684 [] \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528\u7c7b\u578b\uff09 // \u9519\u8bef\u793a\u8303 using T = decltype(arr[0]); // T = int & T i = 0; // int &i = 0; \u540e\u7eed\u4f7f\u7528\u4e2d\u7f16\u8bd1\u51fa\u9519\uff01 \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 \u5728\u672c\u8bfe\u7a0b\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\u9644\u5e26\u7684 \u201ccppdemangle.h\u201d\uff0c\u53ef\u4ee5\u5b9e\u73b0\u6839\u636e\u6307\u5b9a\u7684\u7c7b\u578b\u67e5\u8be2\u7c7b\u578b\u540d\u79f0\u5e76\u6253\u5370\u51fa\u6765\u3002 \u8de8\u5e73\u53f0\uff0c\u9700\u8981 C++11\uff0c\u652f\u6301 MSVC\uff0cClang\uff0cGCC \u4e09\u5927\u7f16\u8bd1\u5668\uff0c\u4f8b\u5982\uff1a int i; print(cppdemangle()); print(cppdemangle()); print(cppdemangle()); \u5728\u6211\u7684 GCC 12.2.1 \u4e0a\u5f97\u5230\uff1a \"int &&\" \"std::__cxx11::basic_string, std::allocator >\" \"wchar_t\" map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f map \u5177\u6709\u4e09\u4e2a\u6210\u5458\u7c7b\u578b 1 \uff1a \u5143\u7d20\u7c7b\u578b\uff1a value_type \u952e\u7c7b\u578b\uff1a key_type \u503c\u7c7b\u578b\uff1a mapped_type \u540e\u9762\uff0c\u5c06\u4f1a\u4e00\u76f4\u4ee5\u201c\u5143\u7d20\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cvalue\u201d\uff0c\u201c\u952e\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201ckey\u201d\uff0c\u201c\u503c\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cmapped\u201d \u7528 cppdemangle \u505a\u5b9e\u9a8c\uff0c\u770b\u770b\u8fd9\u4e9b\u6210\u5458\u7c7b\u578b\u5177\u4f53\u662f\u4ec0\u4e48\u5427\uff1a map::value_type // pair map::key_type // int map::mapped_type // float \u7ed3\u8bba\uff1a map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u800c\u4e0d\u662f V \u3002 \u7591\u60d1\uff1a pair \u4e2d\uff0c\u4e3a\u4ec0\u4e48 K \u8981\u52a0 const\uff1f \u6211\u4eec\u5728 set \u8bfe\u4e2d\u8bf4\u8fc7\uff0cset \u5185\u90e8\u91c7\u7528\u7ea2\u9ed1\u6811\u6570\u636e\u7ed3\u6784\u4fdd\u6301\u6709\u5e8f\uff0c\u8fd9\u6837\u624d\u80fd\u5b9e\u73b0\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u9ad8\u6548\u67e5\u627e\u3002 \u952e\u503c\u6539\u53d8\u7684\u8bdd\u4f1a\u9700\u8981\u91cd\u65b0\u6392\u5e8f\uff0c\u5982\u679c\u53ea\u4fee\u6539\u952e\u503c\u800c\u4e0d\u91cd\u65b0\u6392\u5e8f\uff0c\u4f1a\u7834\u574f\u6709\u5e8f\u6027\uff0c\u5bfc\u81f4\u4e8c\u5206\u67e5\u627e\u7ed3\u679c\u9519\u8bef\uff01\u6240\u4ee5 set \u53ea\u63d0\u4f9b\u4e86\u4e0d\u53ef\u53d8\u8fed\u4ee3\u5668\uff08const_iterator\uff09\uff0c\u6ca1\u6709\u53ef\u53d8\u7684\u8fed\u4ee3\u5668\uff0c\u4e0d\u5141\u8bb8\u7528\u6237\u4fee\u6539\u4efb\u4f55\u5143\u7d20\u7684\u503c\u3002 map \u548c set \u4e00\u6837\u4e5f\u662f\u7ea2\u9ed1\u6811\uff0c\u4e0d\u540c\u5728\u4e8e\uff1amap \u53ea\u6709\u952e K \u7684\u90e8\u5206\u4f1a\u53c2\u4e0e\u6392\u5e8f\uff0cV \u662f\u4e2a\u65c1\u89c2\u8005\uff0c\u968f\u4fbf\u4fee\u6539\u4e5f\u6ca1\u5173\u7cfb\u3002 \u6240\u4ee5 map \u6709\u53ef\u53d8\u8fed\u4ee3\u5668\uff0c\u53ea\u662f\u5728\u5176\u503c\u7c7b\u578b value_type \u4e2d\u7ed9\u952e\u7684\u90e8\u5206\uff0cK\uff0c\u52a0\u4e0a\u4e86 const \u4fee\u9970\uff1a\u4e0d\u5141\u8bb8\u4fee\u6539 K\uff0c\u4f46\u53ef\u4ee5\u968f\u610f\u4fee\u6539 V\u3002 \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u4fee\u6539\u952e\u503c\uff0c\u90a3\u4e48\u8bf7\u5148\u53d6\u51fa\u65e7\u503c\uff0c\u628a\u8fd9\u4e2a\u952e\u5220\u4e86\uff0c\u7136\u540e\u518d\u4ee5\u540c\u6837\u7684\u503c\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u5230\u65b0\u7684\u952e\u3002\u76f8\u5f53\u4e8e\u91cd\u65b0\u6784\u5efa\u4e86\u4e00\u4e2a pair \u5bf9\u8c61\u3002 C++17 \u5f00\u59cb\u4e5f\u53ef\u4ee5\u7528\u66f4\u9ad8\u6548 node_handle \u7cfb\u5217 API\uff0c\u907f\u514d\u6570\u636e\u53d1\u751f\u79fb\u52a8\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; begin() \u548c end() \u8fed\u4ee3\u5668\u5206\u522b\u6307\u5411 map \u7684\u9996\u4e2a\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u540e\u4e00\u4f4d\u3002 \u5176\u4e2d end() \u8fed\u4ee3\u5668\u6307\u5411\u7684\u5730\u5740\u4e3a\u865a\u7a7a\u7d22\u654c\uff0c\u4e0d\u53ef\u89e3\u5f15\u7528\uff0c\u4ec5\u4ec5\u4f5c\u4e3a\u4e00\u4e2a\u201c\u6807\u5fd7\u201d\u5b58\u5728\uff08\u56de\u987e\u4e4b\u524d vector \u8bfe\uff09\u3002 \u8fed\u4ee3\u5668\u53ef\u4ee5\u901a\u8fc7 *it \u6216 it-> \u89e3\u5f15\u7528\uff0c\u83b7\u53d6\u5176\u6307\u5411\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u9996\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5c0f\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5927\u7684\u5143\u7d20\u3002 \u4f8b\u5982\u8981\u67e5\u8be2\u6210\u7ee9\u6700\u597d\u548c\u6700\u574f\u7684\u5b66\u751f\uff0c\u53ef\u4ee5\u628a\u6210\u7ee9\u5f53\u505a key\uff0c\u5b66\u751f\u540d\u505a value \u4f9d\u6b21\u63d2\u5165 map\uff0c\u4ed6\u4f1a\u5e2e\u6211\u4eec\u6392\u5e8f\uff1a map score = { {100, \"\u5f6d\u4e8e\u658c\"}, {80, \"\u6a31\u82b1\u7c89\u871c\u7cd6\"}, {0, \"\u76f8\u4f9d\"}, {60, \"Sputnik02\"}, }; string poorestStudent = score.begin()->second; // \u6210\u7ee9\u6700\u5dee\u5b66\u751f\u7684\u59d3\u540d string bestStudent = prev(score.end())->second; // \u6210\u7ee9\u6700\u597d\u5b66\u751f\u7684\u59d3\u540d print(\"\u6700\u4f4e\u5206:\", poorestStudent); print(\"\u6700\u9ad8\u5206:\", bestStudent); \u6700\u4f4e\u5206: \"\u76f8\u4f9d\" \u6700\u9ad8\u5206: \"\u5f6d\u4e8e\u658c\" \u6ce8\uff1a\u4ec5\u5f53\u786e\u4fdd score.size() != 0 \u65f6\u624d\u53ef\u4ee5\u89e3\u5f15\u7528\uff0c\u5426\u5219 begin() \u548c end() \u90fd\u662f\u865a\u7a7a\u8fed\u4ee3\u5668\uff0c\u8fd9\u65f6\u89e3\u5f15\u7528\u4f1a\u5954\u6e83\u3002 map \u7684\u904d\u5386\uff1a\u53e4\u4ee3 C++98 \u7684\u8fed\u4ee3\u5668\u5927\u6cd5 for (map::iterator it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8981\u7279\u522b\u6ce8\u610f\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u6307\u5411\u5143\u7d20\u7684\u6307\u9488\uff0c\u4e0d\u662f\u5143\u7d20\u672c\u8eab\uff01\u8981\u7528 -> \u800c\u4e0d\u662f . \u3002 \u8fd0\u7528 C++11 \u7684 auto \u7b80\u5199\u4e00\u4e0b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\uff08structured-binding\uff09\u8bed\u6cd5 1 \u76f4\u63a5\u62c6\u5f00 pair \u7c7b\u578b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; print(\"Key:\", k); print(\"Value:\", v); } map \u7684\u904d\u5386\uff1a\u73b0\u4ee3 C++17 \u57fa\u4e8e\u8303\u56f4\u7684\u5faa\u73af\uff08range-based loop\uff09 for (auto kv: m) { print(\"Key:\", kv.first); print(\"Value:\", kv.second); } \u540c\u65f6\u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\u8bed\u6cd5 1 \uff1a for (auto [k, v]: m) { print(\"Key:\", k); print(\"Value:\", v); } \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u53e4\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto it = m.begin(); it != m.end(); ++it) { it->second = it->second + 1; } print(m); {\"fuck\": 986, \"rust\": 212} \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u73b0\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto [k, v]: m) { v = v + 1; } print(m); {\"fuck\": 985, \"rust\": 211} \u6ca1\u6709\u6210\u529f\u4fee\u6539\uff01\u4e3a\u4ec0\u4e48\uff1f for (auto [k, v]: m) { v = v + 1; } Range-based loop \u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; v = v + 1; } Structured-binding \u4e5f\u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto tmp = *it; auto k = tmp.first; auto v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u6808\u4e0a\u53d8\u91cf\uff0c\u662f\u5bf9\u539f\u503c\u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u4e0d\u4ec5\u6d6a\u8d39\u6027\u80fd\uff0c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4e0d\u4f1a\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\uff01 for (auto &[k, v]: m) { // \u89e3\u51b3\u65b9\u6848\u662f\u5728\u8fd9\u91cc\u52a0\u4e00\u4e2a\u5c0f\u5c0f\u7684 &\uff0c\u8ba9 range-based loop \u6355\u83b7\u5f15\u7528\u800c\u4e0d\u662f\u62f7\u8d1d v = v + 1; } \u540c\u6837\u662f\u62c6\u9664 Range-based loop \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &[k, v] = *it; v = v + 1; } \u7ee7\u7eed\u62c6\u9664 Structured-binding \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &tmp = *it; auto &k = tmp.first; auto &v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u5f15\u7528\uff0c\u662f\u5bf9\u539f\u503c\u7684\u5f15\u7528\uff08\u7528 Rust \u7684\u8bdd\u8bf4\u53eb borrowed\uff09\u3002\u4e0d\u4ec5\u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\u8282\u7701\u4e86\u6027\u80fd\uff0c\u800c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4f1a\u5b9e\u65f6\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\u3002 \u603b\u7ed3\uff0c\u5f53\u9700\u8981\u5728\u904d\u5386\u7684\u540c\u65f6\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u8981\u7528 auto & \u6355\u83b7\u5f15\u7528\uff1a for (auto &[k, v]: m) { // \u6355\u83b7\u4e00\u4e2a\u5f15\u7528\uff0c\u5199\u5165\u8fd9\u4e2a\u5f15\u7528\u4f1a\u7acb\u5373\u4f5c\u7528\u5728\u539f\u503c\u4e0a v = v + 1; } \u5373\u4f7f\u4e0d\u9700\u8981\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u4e5f\u5efa\u8bae\u7528 auto const & \u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\uff1a for (auto const &[k, v]: m) { // \u6355\u83b7\u53ea\u8bfb\u7684 const \u5f15\u7528\uff0c\u5f15\u7528\u907f\u514d\u62f7\u8d1d\u5f00\u9500\uff0cconst \u907f\u514d\u4e0d\u5c0f\u5fc3\u624b\u6ed1\u5199\u5165 print(v); } \u6ce8\uff1a\u5373\u4f7f\u6355\u83b7\u4e3a auto & \uff0c\u7531\u4e8e map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5 K \u90e8\u5206\u8fd8\u662f\u4f1a\u6355\u83b7\u4e3a K const & \uff0c\u65e0\u6cd5\u5199\u5165\u3002 for (auto &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // OK } \u53ea\u662f\u5982\u679c\u6355\u83b7\u4e3a auto const & \u5c31\u4e24\u4e2a\u90fd\u4e0d\u5141\u8bb8\u5199\u5165\u4e86\u3002 for (auto const &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 } iterator find(K const &k); const_iterator find(K const &k) const; m.find(key) \u51fd\u6570\uff0c\u6839\u636e\u6307\u5b9a\u7684\u952e key \u67e5\u627e\u5143\u7d20 1 \u3002 \u6210\u529f\u627e\u5230\uff0c\u5219\u8fd4\u56de\u6307\u5411\u627e\u5230\u5143\u7d20\u7684\u8fed\u4ee3\u5668 \u627e\u4e0d\u5230\uff0c\u5219\u8fd4\u56de m.end() \u7531\u4e8e STL \u4f20\u7edf\u5f02\u80fd\u4e4b end() \u865a\u7a7a\u7d22\u654c\uff0c\u4ed6\u4e0d\u53ef\u80fd\u6307\u5411\u4efb\u4f55\u503c\uff0c\u6240\u4ee5\u7ecf\u5e38\u4f5c\u4e3a\u627e\u4e0d\u5230\u65f6\u5019\u7f3a\u7701\u7684\u8fd4\u56de\u503c\u3002 \u53ef\u4ee5\u7528 m.find(key) != m.end() \u5224\u65ad\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u5b58\u5728\uff0c\u7b49\u4ef7\u4e8e m.count(key) != 0 \u3002 \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684\u539f\u578b\u4f5c\u7528\u662f\uff1a\u5982\u679c map \u672c\u8eab\u6709 const \u4fee\u9970\uff0c\u5219\u8fd4\u56de\u7684\u4e5f\u662f const \u8fed\u4ee3\u5668\u3002 \u4e3a\u7684\u662f\u9632\u6b62\u4f60\u5728\u4e00\u4e2a const map \u91cc find \u4e86\u4ee5\u540e\u5229\u7528\u8fed\u4ee3\u5668\u53d8\u76f8\u4fee\u6539 map \u91cc\u7684\u503c\u3002 count \u548c contains \u6ca1\u533a\u522b \u5b9e\u9645\u4e0a count \u548c contains \u51fd\u6570\u5c31\u662f\u57fa\u4e8e find \u5b9e\u73b0\u7684\uff0c\u6027\u80fd\u6ca1\u6709\u533a\u522b\uff0cglibc \u6e90\u7801\uff1a #if __cplusplus > 201703L /** * @brief Finds whether an element with the given key exists. * @param __x Key of (key, value) pairs to be located. * @return True if there is an element with the specified key. */ bool contains(const key_type& __x) const { return _M_t.find(__x) != _M_t.end(); } template auto contains(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x), void(), true) { return _M_t._M_find_tr(__x) != _M_t.end(); } #endif /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. * * This function only makes sense for multimaps; for map the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } // \u4ee5\u4e0b\u4e09\u8005\u7b49\u4ef7 m.contains(key) m.count(key) m.find(key) != m.end() end \u4e0d\u80fd\u89e3\u5f15\u7528 \u68c0\u67e5\u8fc7\u4e0d\u662f m.end()\uff0c\u4ee5\u786e\u8ba4\u6210\u529f\u627e\u5230\u540e\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528\u83b7\u53d6\u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c\uff1a map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { auto kv = *it; // \u89e3\u5f15\u7528\u5f97\u5230 K-V \u5bf9 print(kv); // {\"fuck\", 985} print(kv.first); // \"fuck\" print(kv.second); // 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); } find \u7684\u597d\u5904 find \u7684\u9ad8\u6548\u5728\u4e8e\uff0c\u53ef\u4ee5\u628a\u4e24\u6b21\u67e5\u8be2\u5408\u5e76\u6210\u4e00\u6b21\u3002 \u4fdd\u5e95\u5199\u6cd5\uff1a\u5f00\u9500 2 \\log N 2 \\log N if (m.count(\"key\")) { // \u7b2c\u4e00\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(m.at(\"key\")); // \u7b2c\u4e8c\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } \u9ad8\u6548\u5199\u6cd5\uff1a\u5f00\u9500 \\log N \\log N auto it = m.find(\"key\"); // \u4e00\u6b21\u6027\u67e5\u8be2 if (it != m.end()) { // \u67e5\u8be2\u7684\u7ed3\u679c\uff0c\u65e2\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(it->second); // \u4e5f\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } C++17 \u8bed\u6cd5\u7cd6 C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u5982\u4f55\u7b80\u5316 find \u7684\u8fed\u4ee3\u5668\u5224\u65ad auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } auto it = m.find(\"key2\"); // \u7f16\u8bd1\u5668\u62a5\u9519\uff1a\u53d8\u91cf it \u91cd\u590d\u5b9a\u4e49\uff01 if (it != m.end()) { print(it->second); } \u867d\u7136\u5220\u53bb\u524d\u9762\u7684 auto \u53ef\u4ee5\u89e3\u51b3\u95ee\u9898\uff0c\u4f46\u662f\u5982\u679c\u8fd9\u91cc\u662f\u4e0d\u540c\u7c7b\u578b\u7684 map \u5c31\u5c2c\u4e86\uff0c\u5f97\u53e6\u5916\u60f3\u4e00\u4e2a\u53d8\u91cf\u540d\u3002 \u800c C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u6355\u83b7\u7684 it \u662f\u9650\u5236\u5728\u5f53\u524d if \u4f5c\u7528\u57df\u7684\uff0c\u4e0d\u4f1a\u8dd1\u51fa\u53bb\u548c\u522b\u4eba\u53d1\u751f\u51b2\u7a81\u3002 if (auto it = m.find(\"key1\"); it != m.end()) { print(it->second); } if (auto it = m.find(\"key2\"); it != m.end()) { // \u8fd9\u4e2a\u53d8\u91cf it \u662f\u5c40\u57df\u7684\uff0c\u4e0d\u4f1a\u548c\u4e0a\u4e00\u4e2a\u5c40\u57df\u7684 it \u4ea7\u751f\u540d\u5b57\u51b2\u7a81 print(it->second); } \u7b49\u4ef7\u4e8e\uff1a { auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } } \u9898\u5916\u8bdd \u6211\u7ed9 C++ \u6807\u51c6\u59d4\u5458\u4f1a\u63d0\u4e00\u4e2a\u5efa\u8bae\uff0c\u80fd\u4e0d\u80fd\u7ed9\u8fed\u4ee3\u5668\u52a0\u4e00\u4e2a operator bool \u4ee3\u66ff\u70e6\u4eba\u7684 != m.end() \uff1f struct iterator { _RbTreeNode *node; bool operator!=(iterator const &other) const noexcept { return node == other.node; } operator bool() const noexcept { return node; } }; \u90a3\u6837\u7684\u8bdd\u5c31\u53ef\u4ee5\u76f4\u63a5\uff1a if (auto it = m.find(\"key\")) { print(it->second); } \u56e0\u4e3a if-auto \u7701\u7565\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u65f6\uff0c\u9ed8\u8ba4\u5c31\u662f if (auto it = m.find(\"key\"); (bool)it) \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u6ce8\u610f *it \u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u7c7b\u578b\u7684\u952e\u503c\u5bf9\uff0c\u9700\u8981 (*it).second \u624d\u80fd\u83b7\u53d6\u5355\u72ec\u7684\u503c V\u3002 \u597d\u5728 C \u8bed\u8a00\u5c31\u6709 -> \u8fd0\u7b97\u7b26\u4f5c\u4e3a\u8bed\u6cd5\u7cd6\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 it->second \uff0c\u4e0e (*it).second \u7b49\u4ef7\u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { print(it->second); // \u8fed\u4ee3\u5668\u6709\u6548\uff0c\u53ef\u4ee5\u76f4\u63a5\u83b7\u5f97\u503c\u90e8\u5206 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); // \u8fd9\u4e2a\u5206\u652f\u91cc\u4e0d\u5f97\u7528 * \u548c -> \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528 it } \u5927\u591a\u6570\u60c5\u51b5\u4e0b\u6211\u4eec\u67e5\u8be2\u53ea\u9700\u8981\u83b7\u53d6\u503c V \u7684\u90e8\u5206\u5c31\u884c\u4e86\uff0c\u76f4\u63a5 it->second \u5c31\u53ef\u4ee5\u4e86\u2705 \u6ce8\u610f\uff1afind \u627e\u4e0d\u5230\u952e\u65f6\uff0c\u4f1a\u8fd4\u56de m.end() \uff0c\u8fd9\u662f\u4e2a\u65e0\u6548\u8fed\u4ee3\u5668\uff0c\u53ea\u4f5c\u4e3a\u6807\u8bc6\u7b26\u4f7f\u7528\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 find \u6709\u65f6\u4f1a\u8fd4\u56de -1\uff09\u3002 \u6ca1\u6709\u786e\u8ba4 it != m.end() \u524d\uff0c\u4e0d\u53ef\u4ee5\u8bbf\u95ee it->second \uff01\u90a3\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e00\u4e2a\u7a7a\u6307\u9488\uff0c\u4f1a\u9020\u6210 segfault\uff08\u66f4\u4e13\u4e1a\u4e00\u70b9\u8bf4\u662f UB\uff09\u3002 \u8bb0\u4f4f\uff0c\u4e00\u5b9a\u8981\u5728 it != m.end() \u7684\u5206\u652f\u91cc\u624d\u80fd\u8bbf\u95ee it->second \u54e6\uff01\u4f60\u5f97\u5148\u68c0\u67e5\u8fc7\u996d\u7897\u91cc\u6ca1\u6709\u8001\u9f20\ud83d\udca9\u4e4b\u540e\uff0c\u624d\u80fd\u5b89\u5fc3\u5403\u996d\uff01 \u5982\u679c\u4f60\u60f3\u8ba9\u8001\u5988\uff08\u6807\u51c6\u5e93\uff09\u81ea\u52a8\u5e2e\u4f60\u68c0\u67e5\u6709\u6ca1\u6709\u8001\u9f20\ud83d\udca9\uff0c\u90a3\u5c31\u7528\u4f1a\u81ea\u52a8\u62a5\u9519\u7684 at\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 index \u627e\u4e0d\u5230\u76f4\u63a5\u62a5\u9519\uff09\u3002 \u4e4b\u6240\u4ee5\u7528 find\uff0c\u662f\u56e0\u4e3a\u6709\u65f6\u996d\u7897\u91cc\u51fa\u8001\u9f20\ud83d\udca9\uff0c\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff01\u4f8b\u5982\u5f53\u6709\u8001\u9f20\ud83d\udca9\u65f6\u4f60\u53ef\u4ee5\u6539\u5403\u522b\u7684\u96f6\u98df\u3002\u800c at \u8fd9\u4e2a\u826f\u5fc3\u8001\u5988\u5462\uff1f\u4e00\u53d1\u73b0\u8001\u9f20\ud83d\udca9\u5c31\u62d6\u7740\u4f60\u53bb\u8b66\u5bdf\u5c40\u62a5\u6848\uff0c\u96f6\u98df\uff08\u9ed8\u8ba4\u503c\uff09\u4e5f\u4e0d\u8ba9\u4f60\u5403\u4e86\u3002\u4eca\u65e5\u884c\u7a0b\u5168\u90e8\u53d6\u6d88\uff0c\u7ef4\u6743\uff08\u5f02\u5e38\u5904\u7406\uff0c\u627e\u4e0a\u5c42 try-catch \u5757\uff09\u8bbe\u4e3a\u7b2c\u4e00\u8981\u52a1\u3002 iterator find(K const &k); const_iterator find(K const &k) const; \u5982\u679c map \u6ca1\u6709 const \u4fee\u9970\uff0c\u5219\u5176 find \u8fd4\u56de\u7684 it \u4e5f\u662f\u975e const \u8fed\u4ee3\u5668\u3002 const map cm; map::const_iterator cit = cm.find(\"key\"); print(cit->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 cit->second = 1; // \u7f16\u8bd1\u671f\u62a5\u9519: \u4e0d\u5141\u8bb8\u5199\u5165 const \u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c map m; map::iterator it = m.find(\"key\"); print(it->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 it->second = 1; // OK: \u53ef\u4ee5\u5199\u5165 it->second \u53ef\u4ee5\u5199\u5165\uff0cit \u662f\u8fed\u4ee3\u5668\uff0c\u8fed\u4ee3\u5668\u7c7b\u4f3c\u4e8e\u6307\u9488\uff0c\u5199\u5165\u8fed\u4ee3\u5668\u6307\u5411\u7684 second \u5c31\u53ef\u4ee5\u4fee\u6539 map \u91cc\u7684\u503c\u90e8\u5206\u3002 it->first \u662f\u952e\u90e8\u5206\uff0c\u7531\u4e8e map \u7684\u771f\u6b63\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5\u8fd9\u90e8\u5206\u65e0\u6cd5\u88ab\u4fee\u6539\u3002 \u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2 \u4f17\u6240\u5468\u77e5\uff0cPython \u4e2d\u7684 dict \u6709\u4e00\u4e2a m.get(key, defl) \u7684\u529f\u80fd\uff0c\u6548\u679c\u662f\u5f53 key \u4e0d\u5b58\u5728\u65f6\uff0c\u8fd4\u56de defl \u8fd9\u4e2a\u9ed8\u8ba4\u503c\u4ee3\u66ff m[key]\uff0c\u800c C++ \u7684 map \u5374\u6ca1\u6709\uff0c\u53ea\u80fd\u7528\u4e00\u5957\u7ec4\u5408\u62f3\u4ee3\u66ff\uff1a m.count(key) ? m.at(key) : defl \u4f46\u4e0a\u9762\u8fd9\u6837\u5199\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\uff0c\u76f8\u5f53\u4e8e\u67e5\u8be2\u4e86 map \u4e24\u904d\uff0cat \u91cc\u8fd8\u989d\u5916\u505a\u4e86\u4e00\u6b21\u591a\u4f59\u7684\u5f02\u5e38\u5224\u65ad\u3002 \u6b63\u5e38\u6765\u8bf4\u662f\u7528\u901a\u7528 find \u53bb\u627e\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7136\u540e\u5224\u65ad\u662f\u4e0d\u662f end() \u51b3\u5b9a\u8981\u4e0d\u8981\u91c7\u7528\u9ed8\u8ba4\u503c\u3002 auto it = m.find(key); return it != m.end() ? it->second : defl; \u996d\u7897\u91cc\u53d1\u73b0\u4e86\u8001\u9f20\ud83d\udca9\uff1f\u522b\u6025\u7740\u62a5\u8b66\uff0c\u8fd9\u4e5f\u5728\u6211\u7684\u9884\u6599\u4e4b\u4e2d\uff1a\u542f\u7528 B \u8ba1\u5212\uff0c\u6539\u5403 defl \u8fd9\u6b3e\u7f8e\u5473\u96f6\u98df\u5373\u53ef\uff01 \u5982\u679c\u662f\u826f\u5fc3\u8001\u5988 at\uff0c\u5c31\u76f4\u63a5\u542f\u7528 C \u8ba1\u5212\uff1a \u629b\u51fa\u5f02\u5e38\u7136\u540e\u5954\u6e83\u4e86\uff0c\u867d\u7136\u8fd9\u5f88\u65b9\u4fbf\u6211\u4eec\u7a0b\u5e8f\u5458\u8c03\u8bd5\u3002 \u7531\u4e8e\u81ea\u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2\u8fd9\u4e00\u529f\u80fd\u5b9e\u5728\u662f\u592a\u5e38\u7528\u4e86\uff0c\u4e3a\u4e86\u628a\u8fd9\u4e2a\u64cd\u4f5c\u6d53\u7f29\u5230\u4e00\u884c\uff0c\u6211\u5efa\u8bae\u540c\u5b66\u4eec\u5c01\u88c5\u6210\u51fd\u6570\u653e\u5230\u81ea\u5df1\u7684\u9879\u76ee\u516c\u5171\u5934\u6587\u4ef6\uff08\u4e00\u822c\u662f utils.h \u4e4b\u7c7b\u7684\u540d\u79f0\uff09\u91cc\u65b9\u4fbf\u4ee5\u540e\u4f7f\u7528\uff1a template typename M::mapped_type map_get ( M const &m , typename M::key_type const &key , typename M::mapped_type const &defl ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return defl; } } int val = map_get(config, \"timeout\", -1); // \u5982\u679c\u914d\u7f6e\u6587\u4ef6\u91cc\u4e0d\u6307\u5b9a\uff0c\u5219\u9ed8\u8ba4 timeout \u4e3a -1 \u8fd9\u6837\u8fd8\u4e0d\u591f\u4f18\u96c5\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u66f4\u4f18\u96c5\u5730\u8fd0\u7528 C++17 \u7684\u51fd\u6570\u5f0f\u5bb9\u5668 optional\uff1a template std::optional map_get ( M const &m , typename M::key_type const &key ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return std::nullopt; } } \u5f53\u627e\u4e0d\u5230\u65f6\u5c31\u8fd4\u56de nullopt\uff0c\u627e\u5230\u5c31\u8fd4\u56de\u542b\u6709\u503c\u7684 optional\u3002 \u672c\u6bb5\u4ee3\u7801\u5df2\u9644\u5728\u6848\u4f8b\u4ee3\u7801\u5e93\u7684 \u201cmap_get.h\u201d \u6587\u4ef6\u4e2d\uff0c\u7b49\u8bfe\u540e\u53ef\u4ee5\u53bb GitHub \u4e0b\u8f7d\uff0c\u8d76\u7d27\u7528\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u5427\uff01 \u8c03\u7528\u8005\u53ef\u4ee5\u81ea\u884c\u8fd0\u7528 optional \u7684 value_or \u51fd\u6570 1 \u6307\u5b9a\u627e\u4e0d\u5230\u65f6\u91c7\u7528\u7684\u9ed8\u8ba4\u503c\uff1a int val = map_get(config, \"timeout\").value_or(-1); \u5982\u679c\u8981\u5b9e\u73b0 at \u540c\u6837\u7684\u627e\u4e0d\u5230\u5c31\u81ea\u52a8\u62a5\u9519\u529f\u80fd\uff0c\u90a3\u5c31\u6539\u7528 value \u51fd\u6570\uff1a int val = map_get(config, \"timeout\").value(); optional \u5177\u6709 operator bool \u548c\u65e0\u5f02\u5e38\u7684 operator* \uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u914d\u5408 if-auto \u8bed\u6cd5\u7cd6\u4f7f\u7528\uff1a if (auto o_val = map_get(config, \"timeout\")) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u7b49\u4ef7\u4e8e\uff1a auto o_val = map_get(config, \"timeout\"); if (o_val) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u4ee5\u4e0a\u662f\u5178\u578b\u7684\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f (FP)\uff0cC++20 \u8fd8\u5f15\u5165\u4e86\u66f4\u591a\u8fd9\u6837\u7684\u73a9\u610f 2 \uff0c\u7b49\u6709\u7a7a\u4f1a\u4e13\u95e8\u5f00\u8282\u8bfe\u4e3a\u5927\u5bb6\u4e00\u4e00\u4ecb\u7ecd\u3002 auto even = [] (int i) { return 0 == i % 2; }; auto square = [] (int i) { return i * i; }; for (int i: std::views::iota(0, 6) | std::views::filter(even) | std::views::transform(square)) print(i); // 0 4 16 \u73b0\u5728\u5b66\u4e60\u5220\u9664\u5143\u7d20\u7528\u7684 erase \u51fd\u6570\uff0c\u5176\u539f\u578b\u5982\u4e0b 1 \uff1a size_t erase(K const &key); \u6307\u5b9a\u952e\u503c key\uff0cerase \u4f1a\u5220\u9664\u8fd9\u4e2a\u952e\u503c\u5bf9\u5e94\u7684\u5143\u7d20\u3002 \u8fd4\u56de\u4e00\u4e2a\u6574\u6570\uff0c\u8868\u793a\u5220\u9664\u4e86\u591a\u5c11\u4e2a\u5143\u7d20\uff08\u53ea\u80fd\u662f 0 \u6216 1\uff09\u3002 size_t erase(K const &key); erase \u8fd0\u7528\u4e3e\u4f8b\uff1a\u5220\u9664\u4e00\u4e2a\u5143\u7d20 map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); msg.erase(\"fuck\"); print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} {\"hello\": \"world\"} size_t erase(K const &key); erase \u7684\u8fd4\u56de\u503c\u548c count \u4e00\u6837\uff0c\u8fd4\u56de\u6210\u529f\u5220\u9664\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 erase \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u662f\u5426\u5220\u9664\u6210\u529f\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.erase(\"fuck\")) { print(\"\u5220\u9664fuck\u6210\u529f\"); } else { print(\"\u5220\u9664fuck\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } if (msg.erase(\"dick\")) { print(\"\u5220\u9664dick\u6210\u529f\"); } else { print(\"\u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} \u5220\u9664fuck\u6210\u529f \u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728 {\"hello\": \"world\"} size_t erase(K const &key); // \u6307\u5b9a\u952e\u7248 iterator erase(iterator it); // \u5df2\u77e5\u4f4d\u7f6e\u7248 \u533a\u522b\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u5b9e\u9645\u4e0a\u9700\u8981\u5148\u8c03\u7528 find(key) \u627e\u5230\u5143\u7d20\u4f4d\u7f6e\uff0c\u7136\u540e\u624d\u80fd\u5220\u9664\uff0c\u800c\u4e14\u8fd8\u6709\u627e\u4e0d\u5230\u7684\u53ef\u80fd\u6027\u3002 \u800c\u5df2\u77e5\u4f4d\u7f6e\u7684\u8bdd\uff08\u6bd4\u5982\u4f60\u5df2\u7ecf\u4e8b\u5148\u7528 find \u627e\u5230\u4e86\u5143\u7d20\u4f4d\u7f6e\uff09\uff0c\u53ef\u4ee5\u7528 erase(it) \u76f4\u63a5\u7528\u8fed\u4ee3\u5668\u4f5c\u4e3a\u53c2\u6570 \u590d\u6742\u5ea6\u4e0d\u540c\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(\\log N) O(\\log N) \u3002 \u5df2\u77e5\u4f4d\u7f6e\u7248 erase(it) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(1)+ O(1)+ \uff0c\u66f4\u9ad8\u6548\u3002 \u5176\u4e2d + + \u4ee3\u8868\u8fd9\u662f\u5e73\u644a\uff08Amortized\uff09\u4e0b\u6765\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8fd9\u662f\u56e0\u4e3a\u5373\u4f7f\u5df2\u77e5\u4f4d\u7f6e\uff0cerase \u6709\u53ef\u80fd\u6d89\u53ca\u6811\u7684\u66f4\u65b0\uff0c\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u4f46\u662f\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u9700\u8981\u7684\u66f4\u65b0\u5f88\u5c11\uff0c\u5e73\u5747\u4e0b\u6765\u662f O(1) O(1) \u7684\u3002 \u8fd9\u79cd\u60c5\u51b5\u5c31\u4f1a\u7528\u8bb0\u53f7 O(1)+ O(1)+ \u6765\u8868\u793a\u3002 erase(key) \u53ef\u80fd\u662f\u57fa\u4e8e erase(it) \u5b9e\u73b0\u7684\uff1a size_t erase(K const &key) { // \u5c0f\u5f6d\u8001\u5e08\u731c\u60f3\u6807\u51c6\u5e93\u5185\u90e8 auto it = this->find(key); // O(log N) if (it != this->end()) { this->erase(it); // O(1)+ return 1; // \u627e\u5230\u4e86\uff0c\u5220\u9664\u6210\u529f } else { return 0; // \u627e\u4e0d\u5230\uff0c\u6ca1\u6709\u5220\u9664 } } // \u5f00\u9500\u5927\u7684 find(key) \u4f1a\u8986\u76d6\u5c0f\u7684 erase(it)\uff0c\u6240\u4ee5 erase(key) \u7684\u603b\u590d\u6742\u5ea6\u4e3a O(log N) \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u8fd4\u56de\u7684\u662f\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u4f4d\u7f6e\u3002 \u7531\u4e8e map \u5185\u90e8\u4fdd\u6301\u952e\u4ece\u5c0f\u5230\u5927\u5347\u5e8f\u6392\u5217\uff0c\u6240\u8c13\u7684\u4e0b\u4e00\u4e2a\u5c31\u662f\u952e\u6bd4\u5f53\u524d\u952e\u5927\u4e00\u4e2a\u7684\u5143\u7d20\uff0c\u4f8b\u5982\uff1a {\"answer\": 42, \"hello\": 985, \"world\": 211} erase(find(\u201canswer\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201chello\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201chello\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201canswer\u201d\u3002 erase(find(\u201chello\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201cworld\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201cworld\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201chello\u201d\u3002 erase(find(\u201cworld\u201d)) \u4f1a\u8fd4\u56de end()\uff0c\u56e0\u4e3a \u201cworld\u201d \u5df2\u7ecf\u662f\u6700\u5927\u952e\uff0c\u6ca1\u6709\u4e0b\u4e00\u4e2a\u3002 \u6b64\u5916 erase(it) \u8fd8\u6709\u6027\u80fd\u4e0a\u7684\u4f18\u52bf\uff1a \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u7684\u590d\u6742\u5ea6\u662f O(1)+ O(1)+ \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u590d\u6742\u5ea6\u662f O(\\log N) O(\\log N) \u5f53\u5df2\u77e5\u6307\u5411\u8981\u5220\u9664\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u65f6\uff08\u4f8b\u5982\u5148\u901a\u8fc7 find \u627e\u5230\uff09\uff0c\u76f4\u63a5\u6307\u5b9a\u90a3\u4e2a\u8fed\u4ee3\u5668\u6bd4\u6307\u5b9a\u952e\u53c2\u6570\u66f4\u9ad8\u6548\u3002 \u5220\u9664\u6210\u7ee9\u6700\u5dee\u7684\u5b66\u751f\uff1a score.erase(score.begin()); \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 \u5e38\u89c1\u9700\u6c42\u573a\u666f\uff1a\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u9519\u8bef\u793a\u8303\uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto const &[k, v]: msg) { if (k.starts_with(\"fuck\")) { msg.erase(k); // \u904d\u5386\u8fc7\u7a0b\u4e2d\u5220\u9664\u5f53\u524d\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u6b63\u5728\u904d\u5386\u4e2d\u7684\u8fed\u4ee3\u5668\u5931\u6548\uff0c\u5954\u6e83 } } print(msg); Segmentation fault (core dumped) \u5f15\u51fa\u95ee\u9898\uff1a\u8fed\u4ee3\u5668\u5931\u6548 \u6bcf\u5f53\u5f80 map \u4e2d\u63d2\u5165\u65b0\u5143\u7d20\u65f6\uff0c\u539f\u5148\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u4e0d\u4f1a\u5931\u6548\u3002 \u5220\u9664 map \u4e2d\u7684\u5176\u4ed6\u5143\u7d20\u65f6\uff0c\u4e5f\u4e0d\u4f1a\u5931\u6548\u3002 \u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\uff0c\u624d\u4f1a\u5931\u6548 \u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); m[\"dick\"] = 211; print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"dick\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"fuck\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 map \u6bd4\u8d77 unordered_map \u6765\uff0c\u5df2\u7ecf\u662f\u975e\u5e38\u7a33\u5b9a\uff0c\u968f\u4fbf\u589e\u5220\u6539\u67e5\u90fd\u4e0d\u4f1a\u8fed\u4ee3\u5668\u5931\u6548\u3002 \u53ea\u6709\u4e00\u4e2a\u4f8b\u5916\uff1a\u5220\u9664\u7684\u5143\u7d20\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u3002 \u4f60\u62ff\u7740\u4e2a\u4f60\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u7ed3\u679c\u4f60\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\uff0c\u8fd8\u6478\u4e0d\u7740\u5934\u8111\u201c\u5947\u602a\uff0c\u660e\u660e\u5c31\u662f\u8fd9\u4e2a\u5730\u5740\u5440\u201d\uff0c\u8fd9\u65f6\u786e\u5b9e\u65e0\u8bba\u5982\u4f55\u90fd\u4e0d\u80fd\u907f\u514d\u5931\u6548\uff0c\u4e0d\u80fd\u602a map\u3002 \u800c\u521a\u521a\u7684\u6848\u4f8b\u4e2d\uff0c\u6211\u4eec\u5220\u9664\u7684\u6070\u597d\u5c31\u662f\u5f53\u524d\u6b63\u5728\u904d\u5386\u7684\u8fed\u4ee3\u5668\u6b63\u5728\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\uff08\u5373\u4f7f\u4f60\u7528\u4e86 range-based loop \u8bed\u6cd5\u7cd6\u4ed6\u80cc\u540e\u8fd8\u662f\u8fed\u4ee3\u5668\u904d\u5386\uff09\u3002 \u800c\u5f53\u4f60\u5bf9\u7740\u4e00\u4e2a\u5931\u6548\u7684\u8fed\u4ee3\u5668\u6267\u884c ++it \u65f6\uff0c\u5c31\u4ea7\u751f\u4e86 segfault \u9519\u8bef\u3002\u56e0\u4e3a\u7ea2\u9ed1\u6811\u7684\u8fed\u4ee3\u5668\u8981\u627e\u5230\u201c\u4e0b\u4e00\u4e2a\u201d\u8282\u70b9\uff0c\u9700\u8981\u8bbf\u95ee\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u4e2d\u5b58\u7684 next \u6307\u9488\uff0c\u800c\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u90fd\u5df2\u7ecf\u5220\u9664\u4e86\u5df2\u7ecf\u6790\u6784\u4e86\u5df2\u7ecf\u91ca\u653e\u5185\u5b58\u4e86\uff0c\u91cc\u9762\u5b58\u7684 next \u6307\u9488\u4e5f\u5df2\u7ecf\u91ca\u653e\uff0c\u88ab\u5176\u4ed6\u7cfb\u7edf\u6570\u636e\u8986\u76d6\uff0c\u8fd9\u65f6\u4f1a\u8bbf\u95ee\u5230\u9519\u8bef\u7684\u6307\u9488\u2014\u2014\u91ce\u6307\u9488\u3002 \u6240\u4ee5\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u5b8c\u6574\u7684\u5267\u60c5\u662f\uff1a \u4f60\u6709\u597d\u591a\u670b\u53cb\uff0c\u4eca\u5929\u4f60\u8981\u628a\u4ed6\u4eec\u5168\u70b8\u4e86\u3002 1\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 2\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77403\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 \u2026 \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it /* \u8fdb\u5165\u71c3\u70e7\u4e2d\u76841\u53f7\u670b\u53cb\u5bb6 */) { m.erase(it); // \u4e00\u53d1 RPG \u5bfc\u5f39\u70b8\u6bc11\u53f7\u670b\u53cb\u5bb6 } \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it) { m.erase(it); // it \u5df2\u7ecf\u5931\u6548\uff01 } \u6b63\u786e\u7684\u505a\u6cd5\u662f\uff0c\u5148\u8fdb\u51651\u53f7\u670b\u53cb\u5bb6\uff0c\u5b89\u5168\u53d6\u51fa\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761\u540e\uff0c\u518d\u6765\u4e00\u53d1 RPG \u628a1\u53f7\u670b\u53cb\u5bb6\u70b8\u6389\u3002\u8fd9\u6837\u624d\u80fd\u987a\u5229\u627e\u52302\u53f7\u670b\u53cb\u5bb6\uff0c\u4ee5\u6b64\u7c7b\u63a8\u7ee7\u7eed\u62c63\u53f7\u2026\u2026 for (auto it = m.begin(); it != m.end(); ) { auto next_it = it; // \u5148\u8fdb\u51651\u53f7\u670b\u53cb\u7684\u5bb6 ++next_it; // \u62ff\u51fa\u5199\u67092\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761 m.erase(it); // \u518d\u53d1\u5c04 RPG \u5bfc\u5f39 it = next_it; // \u524d\u5f802\u53f7\u670b\u53cb\u5bb6 } \u6ce8\u610f\u5230 erase \u4f1a\u8fd4\u56de\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\u8fd9\u4e2a RPG \u5bfc\u5f39\u975e\u5e38\u667a\u80fd\uff0c\u597d\u50cf\u4ed6\u5c31\u662f\u4e13\u4e3a\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u8bbe\u8ba1\u7684\u4e00\u6837\uff1a\u4ed6\u80fd\u5728\u70b8\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u524d\uff0c\u81ea\u52a8\u62ff\u5230\u5176\u4e2d\u7684\u5b57\u6761\uff0c\u5e76\u628a\u4ed6\u901a\u8fc7\u201c\u5f39\u5c04\u5ea7\u6905\u201d\u5f39\u51fa\u6765\u9001\u5230\u95e8\u5916\u7684\u4f60\u624b\u4e0a\uff0c\u628a\u7eb8\u6761\u5b89\u5168\u9001\u51fa\u6765\u540e\uff0c\u518d\u7206\u70b8\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u3002\u8fd9\u6837\u4f60\u5c31\u4e0d\u7528\u5192\u9669\u8fdb\u5165\u71c3\u70e7\u7684\u623f\u5c4b\u62ff\u5b57\u6761\uff08\u8fed\u4ee3\u5668\u5931\u6548\u5bfc\u81f4 segfault\uff09\uff0c\u4e5f\u4e0d\u7528\u5148\u52b3\u70e6\u60a8\u81ea\u5df1\u5148\u8fdb\u53bb\u4e00\u8d9f\u623f\u5c4b\u62ff\u5b57\u6761\u4e86\uff08\u4e0a\u4e00\u9875\u4e2d\u90a3\u6837\u63d0\u524d\u4fdd\u5b58 next_it\uff09\u3002 for (auto it = m.begin(); it != m.end(); ) { it = m.erase(it); // \u8fd9\u6b3e RPG \u5bfc\u5f39\u201c\u667a\u80fd\u5730\u201d\u5728\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u540c\u65f6\u628a\u5176\u4e2d\u7684\u5b57\u6761\u62ff\u51fa\u6765\u4e86!? } \u53ea\u662f\u6ce8\u610f\u8fd9\u91cc for \u5faa\u73af\u7684\u6b65\u8fdb\u6761\u4ef6 ++it \u8981\u5220\u6389\uff0c\u56e0\u4e3a\u667a\u80fd\u7684 RPG \u5bfc\u5f39 it = m.erase(it) \u5df2\u7ecf\u5e2e\u4f60\u6b65\u8fdb\u4e86\u3002 \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u6b63\u89e3 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto it = m.begin(); it != m.end(); ) { // \u6ca1\u6709 ++it auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u4e0d\u5954\u6e83 for (auto it = m.begin(); it != m.end(); ) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } \u5954\u6e83 for (auto it = m.begin(); it != m.end(); ++it) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { msg.erase(it); // \u6216\u8005 msg.erase(k); } } C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if \u6279\u91cf\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff08C++20 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; std::erase_if(msg, [&] (auto const &kv) { auto &[k, v] = kv; return k.starts_with(\"fuck\"); }); print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u5982\u679c\u4f60\u641e\u4e0d\u61c2\u8fed\u4ee3\u5668\u8fd9\u4e9b\uff0c\u8fd9\u91cc\u6211\u63d0\u4f9b\u4e00\u4e2a\u4fdd\u5e95\u5199\u6cd5\uff0c\u5148\u628a\u952e\u63d0\u524d\u4fdd\u5b58\u5230\u4e00\u4e2a vector \u4e2d\u53bb\uff1a map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; vector keys; // vector \u6216\u8005 set \u90fd\u53ef\u4ee5 for (auto const &[k, v]: msg) { // \u5148\u628a\u6240\u6709\u952e\u63d0\u524d\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc keys.push_back(k); } for (auto const &k: keys) { // \u904d\u5386\u521a\u624d\u4fdd\u5b58\u7684\u952e if (k.starts_with(\"fuck\")) { msg.erase(k); // \u952e\u503c\u5bf9\u5df2\u7ecf\u63d0\u524d\u6df1\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc\uff0c\u8fd9\u65f6\u5220\u9664 map \u91cc\u7684\u952e\u4e0d\u4f1a\u5954\u6e83 } } \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u795b\u9b45\u5927\u5e08\u3002 \u8fd8\u662f\u641e\u4e0d\u61c2\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u65b0\u5efa\u4e00\u4e2a map\uff0c\u6761\u4ef6\u53cd\u4e4b\uff0c\u628a\u4e0d\u9700\u8981\u5220\u9664\u7684\u5143\u7d20\u63d2\u5165\u65b0 map\uff0c\u8fc7\u6ee4\u51fa\u9700\u8981\u4fdd\u7559\u7684\u5143\u7d20\uff0c\u6700\u540e\u518d\u4e00\u6b21\u6027\u7528\u65b0 map \u8986\u76d6\u65e7 map\u3002 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; map newmsg; for (auto const &[k, v]: msg) { if (!k.starts_with(\"fuck\")) { // \u6ce8\u610f\u8fd9\u91cc\u6761\u4ef6\u53cd\u4e86\uff0c\u4e0d\u9700\u8981\u5220\u9664\u7684\u624d\u63d2\u5165 newmsg newmsg[k] = v; } } msg = std::move(newmsg); // \u8986\u76d6\u65e7\u7684 map\uff0c\u7528\u66f4\u9ad8\u6548\u7684\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff0cO(1) \u590d\u6742\u5ea6 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u4fdd\u5e95\u5927\u5e08\u3002 \u63a5\u4e0b\u6765\u5f00\u59cb\u5b66\u4e60\u5982\u4f55\u63d2\u5165\u5143\u7d20\uff0cmap \u7684\u6210\u5458 insert \u51fd\u6570\u539f\u578b\u5982\u4e0b 1 \uff1a pair insert(pair const &kv); pair insert(pair &&kv); \u4ed6\u7684\u53c2\u6570\u7c7b\u578b\u5c31\u662f\u521a\u521a\u4ecb\u7ecd\u7684 value_type \uff0c\u4e5f\u5c31\u662f pair \u3002 pair \u662f\u4e00\u4e2a STL \u4e2d\u5e38\u89c1\u7684\u6a21\u677f\u7c7b\u578b\uff0c pair \u6709\u4e24\u4e2a\u6210\u5458\u53d8\u91cf\uff1a first\uff1aK \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u952e second\uff1aV \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u503c \u6211\u79f0\u4e4b\u4e3a\u201d\u952e\u503c\u5bf9\u201d\u3002 \u8bd5\u7740\u7528 insert \u63d2\u5165\u952e\u503c\u5bf9\uff1a map m; pair p; p.first = \"fuck\"; // \u952e p.second = 985; // \u503c m.insert(p); // pair \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a insert \u53c2\u6570\u6240\u9700\u7684 pair print(m); \u7ed3\u679c\uff1a {\"fuck\": 985} \u7b80\u5316 insert \u76f4\u63a5\u4f7f\u7528 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u521d\u59cb\u5316 first \u548c second pair p(\"fuck\", 985); m.insert(p); \u4e0d\u7528\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0cpair \u8868\u8fbe\u5f0f\u76f4\u63a5\u4f5c\u4e3a insert \u51fd\u6570\u7684\u53c2\u6570 m.insert(pair(\"fuck\", 985)); \u53ef\u4ee5\u7528 std::make_pair \u8fd9\u4e2a\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u63a8\u5bfc\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u7701\u7565 m.insert(make_pair(\"fuck\", 985)); // \u867d\u7136\u4f1a\u63a8\u5bfc\u4e3a pair \u4f46\u8fd8\u662f\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a pair \u7531\u4e8e insert \u51fd\u6570\u539f\u578b\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528 C++11 \u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868 {\u2026}\uff0c\u65e0\u9700\u6307\u5b9a\u7c7b\u578b m.insert({\"fuck\", 985}); // \u2705 \u56e0\u6b64\uff0cinsert \u7684\u6700\u4f73\u7528\u6cd5\u662f\uff1a map m; m.insert({\"key\", \"val\"}); insert \u63d2\u5165\u548c [] \u5199\u5165\u7684\u5f02\u540c\uff1a \u540c\uff1a\u5f53\u952e K \u4e0d\u5b58\u5728\u65f6\uff0cinsert \u548c [] \u90fd\u4f1a\u521b\u5efa\u952e\u503c\u5bf9\u3002 \u5f02\uff1a\u5f53\u952e K \u5df2\u7ecf\u5b58\u5728\u65f6\uff0cinsert \u4e0d\u4f1a\u8986\u76d6\uff0c\u9ed8\u9ed8\u79bb\u5f00\uff1b\u800c [] \u4f1a\u8986\u76d6\u65e7\u7684\u503c\u3002 \u4f8b\u5b50\uff1a map m; m.insert({\"key\", \"old\"}); m.insert({\"key\", \"new\"}); // \u63d2\u5165\u5931\u8d25\uff0c\u9ed8\u9ed8\u653e\u5f03\u4e0d\u51fa\u9519 print(m); {\"key\": \"old\"} map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; // \u5df2\u7ecf\u5b58\u5728\uff1f\u6211\u8e0f\u9a6c\u5f3a\u884c\u8986\u76d6\uff01 print(m); {\"key\": \"new\"} insert \u7684\u8fd4\u56de\u503c\u662f pair \u7c7b\u578b\uff0c STL \u7684\u5c3f\u6027\uff1a\u5728\u9700\u8981\u4e00\u6b21\u6027\u8fd4\u56de\u4e24\u4e2a\u503c\u65f6\u559c\u6b22\u7528 pair \u3002 \u8fd9\u53c8\u662f\u4e00\u4e2a pair \u7c7b\u578b\uff0c\u5176\u5177\u6709\u4e24\u4e2a\u6210\u5458\uff1a first\uff1aiterator \u7c7b\u578b\uff0c\u662f\u4e2a\u8fed\u4ee3\u5668 second\uff1abool \u7c7b\u578b\uff0c\u8868\u793a\u63d2\u5165\u6210\u529f\u4e0e\u5426\uff0c\u5982\u679c\u53d1\u751f\u952e\u51b2\u7a81\u5219\u4e3a false \u5176\u4e2d first \u8fd9\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\uff1a \u5982\u679c\u63d2\u5165\u6210\u529f\uff08second \u4e3a true\uff09\uff0c\u6307\u5411\u521a\u521a\u6210\u529f\u63d2\u5165\u7684\u5143\u7d20\u4f4d\u7f6e \u5982\u679c\u63d2\u5165\u5931\u8d25\uff08second \u4e3a false\uff09\uff0c\u8bf4\u660e\u5df2\u7ecf\u6709\u76f8\u540c\u7684\u952e K \u5b58\u5728\uff0c\u53d1\u751f\u4e86\u952e\u51b2\u7a81\uff0c\u6307\u5411\u5df2\u7ecf\u5b58\u5728\u7684\u90a3\u4e2a\u5143\u7d20 \u5176\u5b9e insert \u8fd4\u56de\u7684 first \u8fed\u4ee3\u5668\u7b49\u4ef7\u4e8e\u63d2\u5165\u4ee5\u540e\u518d\u91cd\u65b0\u7528 find \u627e\u5230\u521a\u521a\u63d2\u5165\u7684\u90a3\u4e2a\u952e\uff0c\u53ea\u662f\u6548\u7387\u66f4\u9ad8\uff1a auto it = m.insert({k, v}).first; // \u9ad8\u6548\uff0c\u53ea\u9700\u904d\u5386\u4e00\u6b21 m.insert({k, v}); // \u63d2\u5165\u5b8c\u5c31\u5fd8\u4e8b\u4e86 auto it = m.find(k); // \u91cd\u65b0\u904d\u5386\u7b2c\u4e8c\u6b21\uff0c\u4f46\u7ed3\u679c\u4e00\u6837 \u53c2\u8003 C \u7f16\u7a0b\u7f51 1 \u5bf9 insert \u8fd4\u56de\u503c\u7684\u89e3\u91ca\uff1a \u5f53\u8be5\u65b9\u6cd5\u5c06\u65b0\u952e\u503c\u5bf9\u6210\u529f\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u65f6\uff0c\u8fd4\u56de\u7684\u8fed\u4ee3\u5668\u6307\u5411\u65b0\u6dfb\u52a0\u7684\u952e\u503c\u5bf9\uff1b \u53cd\u4e4b\uff0c\u5982\u679c\u6dfb\u52a0\u5931\u8d25\uff0c\u8be5\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\u5bb9\u5668\u4e2d\u548c\u8981\u6dfb\u52a0\u952e\u503c\u5bf9\u952e\u76f8\u540c\u7684\u90a3\u4e2a\u952e\u503c\u5bf9\u3002 \u53ef\u4ee5\u7528 insert \u8fd4\u56de\u7684 second \u5224\u65ad\u63d2\u5165\u591a\u6b21\u662f\u5426\u6210\u529f\uff1a map m; print(m.insert({\"key\", \"old\"}).second); // true print(m.insert({\"key\", \"new\"}).second); // false m.erase(\"key\"); // \u628a\u539f\u6765\u7684 {\"key\", \"old\"} \u5220\u4e86 print(m.insert({\"key\", \"new\"}).second); // true \u4e5f\u53ef\u4ee5\u7528 structured-binding \u8bed\u6cd5\u62c6\u89e3\u4ed6\u8fd4\u56de\u7684 pair \uff1a map counter; auto [it, success] = counter.insert(\"key\", 1); // \u76f4\u63a5\u7528 if (!success) { // \u5982\u679c\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4fee\u6539\u5176\u503c+1 it->second = it->second + 1; } else { // \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6253\u5370\u4ee5\u4e0b\u4fe1\u606f print(\"created a new entry!\"); } \u4ee5\u4e0a\u8fd9\u4e00\u957f\u4e32\u4ee3\u7801\u548c\u4e4b\u524d\u201c\u4f18\u96c5\u201d\u7684\u8ba1\u6570 [] \u7b49\u4ef7\uff1a counter[\"key\"]++; insert_or_assign \u5728 C++17 \u4e2d\uff0c[] \u5199\u5165\u6709\u4e86\u4e2a\u66f4\u9ad8\u6548\u7684\u66ff\u4ee3\u54c1 insert_or_assign 1 \uff1a pair insert_or_assign(K const &k, V v); pair insert_or_assign(K &&k, V v); \u6b63\u5982\u4ed6\u540d\u5b57\u7684\u542b\u4e49\uff0c\u201c\u63d2\u5165\u6216\u8005\u5199\u5165\u201d\uff1a \u5982\u679c K \u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff08\u63d2\u5165\uff09 \u5982\u679c K \u5df2\u7ecf\u5b58\u5728\u5219\u8986\u76d6\uff08\u5199\u5165\uff09 \u7528\u6cd5\u5982\u4e0b\uff1a m.insert_or_assign(\"key\", \"new\"); // \u4e0e insert \u4e0d\u540c\uff0c\u4ed6\u4e0d\u9700\u8981 {...}\uff0c\u4ed6\u7684\u53c2\u6570\u5c31\u662f\u4e24\u4e2a\u5355\u72ec\u7684 K \u548c V \u8fd4\u56de\u503c\u4f9d\u65e7\u662f pair \u3002\u7531\u4e8e\u8fd9\u51fd\u6570\u5728\u952e\u51b2\u7a81\u65f6\u4f1a\u8986\u76d6\uff0c\u6309\u7406\u8bf4\u662f\u5fc5\u5b9a\u6210\u529f\u4e86\uff0c\u56e0\u6b64\u8fd9\u4e2a bool \u7684\u542b\u4e49\u4ece\u201c\u662f\u5426\u63d2\u5165\u6210\u529f\u201d\u53d8\u4e3a\u201c\u662f\u5426\u521b\u5efa\u4e86\u5143\u7d20\u201d\uff0c\u5982\u679c\u662f\u521b\u5efa\u7684\u65b0\u5143\u7d20\u8fd4\u56detrue\uff0c\u5982\u679c\u8986\u76d6\u4e86\u65e7\u5143\u7d20\u8fd4\u56defalse\u3002 insert_or_assign \u7684\u4f18\u52bf \u770b\u6765 insert_or_assign \u548c [] \u7684\u6548\u679c\u5b8c\u5168\u76f8\u540c\uff01\u90fd\u662f\u5728\u952e\u503c\u51b2\u7a81\u65f6\u8986\u76d6\u65e7\u503c\u3002 \u65e2\u7136 [] \u5df2\u7ecf\u53ef\u4ee5\u505a\u5230\u540c\u6837\u7684\u6548\u679c\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u53d1\u660e\u4e2a insert_or_assign \u5462\uff1f insert_or_assign \u7684\u4f18\u70b9\u662f \u4e0d\u9700\u8981\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 \uff0c\u53ef\u4ee5\u63d0\u5347\u6027\u80fd\u3002 \u5176\u5e94\u7528\u573a\u666f\u6709\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff1a \u23f1 \u60a8\u7279\u522b\u5728\u4e4e\u6027\u80fd \u274c \u6709\u65f6 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u7528 [] \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \ud83e\udd75 \u5f3a\u8feb\u75c7\u53d1\u4f5c \u5426\u5219\u7528 [] \u5199\u5165\u4e5f\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u800c\u4e14 insert_or_assign \u80fd\u53d6\u4ee3 [] \u7684\u5c97\u4f4d\u4ec5\u9650\u4e8e\u7eaf\u5199\u5165\uff0c\u4e4b\u524d counter[key]++ \u8fd9\u79cd\u201c\u4f18\u96c5\u201d\u5199\u6cd5\u4f9d\u7136\u662f\u9700\u8981\u7528 [] \u7684\u3002 \u6548\u7387\u95ee\u9898 \u521b\u5efa\u65b0\u952e\u65f6\uff0cinsert_or_assign \u66f4\u9ad8\u6548\u3002 [] map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 V() \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) insert_or_assign map m; m.insert_or_assign(\"key\", \"old\"); m.insert_or_assign(\"key\", \"new\"); print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u6784\u9020\u51fd\u6570 V(V &&) \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 \u603b\u7ed3\uff0c\u5982\u679c\u4f60\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u5e76\u4e14\u662f C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 insert_or_assign \u8bfb\u53d6\u7528 at \u5982\u679c\u6ca1\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u6216\u8005\u4f60\u7684\u7f16\u8bd1\u5668\u4e0d\u652f\u6301 C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 [] \u8bfb\u53d6\u7528 at \u6700\u540e\uff0c\u5982\u679c\u4f60\u662f\u8fd8\u539f\u8bba\u8005\uff0c\u53ea\u9700\u8981 find \u548c insert \u51fd\u6570\u5c31\u662f\u5b8c\u5907\u7684\u4e86\uff0c\u522b\u7684\u51fd\u6570\u90fd\u4e0d\u7528\u53bb\u8bb0\u3002\u6240\u6709 at\u3001[]\u3001insert_or_assign \u4e4b\u7c7b\u7684\u64cd\u4f5c\u90fd\u53ef\u4ee5\u901a\u8fc7 find \u548c insert \u7684\u7ec4\u5408\u62f3\u5b9e\u73b0\uff0c\u4f8b\u5982\u521a\u521a\u6211\u4eec\u81ea\u5b9a\u4e49\u7684 map_get\u3002 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u56de\u987e\u4e4b\u524d\u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u5982\u679c\u6709\u91cd\u590d\uff0c\u5982\u4f55\u533a\u5206\u627e\u7b2c\u4e00\u4e2a\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\uff1f \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u6700\u540e\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert_or_assign(arr[i], i); // \u7b49\u4ef7\u4e8e arrinv[arr[i]] = i; } \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u7b2c\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert({arr[i], i}); } \u6279\u91cf insert \u521a\u521a\u4ecb\u7ecd\u7684\u90a3\u4e9b insert \u4e00\u6b21\u53ea\u80fd\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0cinsert \u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u7248\u672c\uff0c\u7528\u4e8e\u6279\u91cf\u63d2\u5165\u4e00\u7cfb\u5217\u5143\u7d20\u3002 template void insert(InputIt beg, InputIt end); \u53c2\u6570 1 \u662f\u4e24\u4e2a\u8fed\u4ee3\u5668 beg \u548c end\uff0c\u7ec4\u6210\u4e00\u4e2a\u533a\u95f4\uff0c\u4e4b\u95f4\u662f\u4f60\u8981\u63d2\u5165\u7684\u6570\u636e\u3002 \u8be5\u533a\u95f4\u53ef\u4ee5\u662f\u4efb\u4f55\u5176\u4ed6\u5bb9\u5668\u7684 begin() \u548c end() \u8fed\u4ee3\u5668\u2014\u2014\u90a3\u4f1a\u628a\u8be5\u5bb9\u5668\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u63d2\u5165\u5230\u672c map \u4e2d\u53bb\u3002 \u4f8b\u5982\uff0c\u628a vector \u4e2d\u7684\u952e\u503c\u5bf9\u6279\u91cf\u63d2\u5165 map\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); // {\"delay\": 211, \"timeout\": 985} \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6ce8\uff1a\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5982\u679c vector \u4e2d\u6709\u91cd\u590d\u7684\u952e\uff0c\u5219\u4f1a\u4ee5\u952e\u7b2c\u4e00\u6b21\u51fa\u73b0\u65f6\u7684\u503c\u4e3a\u51c6\uff0c\u4e4b\u540e\u91cd\u590d\u51fa\u73b0\u7684\u952e\u4f1a\u88ab\u5ffd\u89c6\u3002 vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); {\"delay\": 211, \"timeout\": 985} vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config = { {\"timeout\", 404}, }; config.insert(kvs.begin(), kvs.end()); print(config); vector> v; {\"delay\": 211, \"timeout\": 404} \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u6279\u91cf insert \u8fd0\u7528\u6848\u4f8b\uff1a\u4e24\u4e2a map \u5408\u5e76 \u8fd9\u4e2a\u6279\u91cf insert \u8f93\u5165\u7684\u8fed\u4ee3\u5668\u53ef\u4ee5\u662f\u4efb\u4f55\u5bb9\u5668\uff0c\u751a\u81f3\u53ef\u4ee5\u662f\u53e6\u4e00\u4e2a map \u5bb9\u5668\u3002 \u8fd0\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u4e24\u4e2a map \u7684\u5e76\u96c6\u64cd\u4f5c\u3002 map m1 = { // \u7b2c\u4e00\u4e2a map {\"answer\", 42}, {\"timeout\", 7}, }; map m2 = { // \u7b2c\u4e8c\u4e2a map {\"timeout\", 985}, {\"delay\", 211}, }; m1.insert(m2.begin(), m2.end()); // \u628a m2 \u7684\u5185\u5bb9\u4e0e m1 \u5408\u5e76\uff0c\u7ed3\u679c\u5199\u56de\u5230 m1 print(m1); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd8\u662f\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5f53\u9047\u5230\u91cd\u590d\u7684\u952e\u65f6\uff08\u4f8b\u5982\u4e0a\u9762\u7684 \u201ctimeout\u201d\uff09\uff0c\u4f1a\u4ee5 m1 \u4e2d\u7684\u503c\u4e3a\u51c6\u3002 \u5c31\u5730\u5199\u5165\uff01 \u4f7f\u7528 m1.insert(m2.begin(), m2.end()) \u540e\uff0c\u5408\u5e76\u7684\u7ed3\u679c\u4f1a\u5c31\u5730\u5199\u5165 m1\u3002 \u5982\u679c\u5e0c\u671b\u5408\u5e76\u7ed3\u679c\u653e\u5230\u4e00\u4e2a\u65b0\u7684 map \u5bb9\u5668\u4e2d\u800c\u4e0d\u662f\u5c31\u5730\u4fee\u6539 m1\uff0c\u8bf7\u5148\u81ea\u884c\u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d\uff1a const map m1 = { // \u7b2c\u4e00\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"answer\", 42}, {\"timeout\", 7}, }; const map m2 = { // \u7b2c\u4e8c\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"timeout\", 985}, {\"delay\", 211}, }; auto m12 = m1; // \u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d m12\uff0c\u907f\u514d insert \u5c31\u5730\u4fee\u6539 m1 m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 auto m12 = m1; m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m1 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u521a\u521a\u5199\u7684 m1 \u548c m2 \u5408\u5e76\uff0c\u9047\u5230\u91cd\u590d\u65f6\u4f1a\u4f18\u5148\u91c7\u53d6 m1 \u91cc\u7684\u503c\uff0c\u5982\u679c\u5e0c\u671b\u4f18\u5148\u91c7\u53d6 m2 \u7684\u5462\uff1f\u53cd\u4e00\u53cd\u5c31\u53ef\u4ee5\u4e86\uff1a auto m12 = m2; m12.insert(m1.begin(), m1.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m2 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 985} \u8981\u662f\u5b66\u4e0d\u4f1a\u6279\u91cf insert\uff0c\u90a3\u624b\u5199\u4e00\u4e2a for \u5faa\u73af\u904d\u5386 m2\uff0c\u7136\u540e m1.insert_or_assign(k2, v2) \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u603b\u4e4b\u8981\u61c2\u5f97\u53d8\u901a\uff0c\u52a8\u52a8\u8111\uff0c\u603b\u662f\u6709\u4fdd\u5e95\u5199\u6cd5\u7684\u3002 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 \u6709\u540c\u5b66\u5c31\u95ee\u4e86\uff0c\u8fd9\u4e2a insert \u5b9e\u73b0\u4e86 map \u7684\u5e76\u96c6\u64cd\u4f5c\uff0c\u90a3\u4ea4\u96c6\u64cd\u4f5c\u5462\uff1f\u8fd9\u5176\u5b9e\u662f set \u7684\u5e38\u89c4\u64cd\u4f5c\u800c\u4e0d\u662f map \u7684\uff1a set_intersection\uff08\u53d6\u96c6\u5408\u4ea4\u96c6\uff09 set_union\uff08\u53d6\u96c6\u5408\u5e76\u96c6\uff09 set_difference\uff08\u53d6\u96c6\u5408\u5dee\u96c6\uff09 set_symmetric_difference\uff08\u53d6\u96c6\u5408\u5bf9\u79f0\u5dee\u96c6\uff09 \u975e\u5e38\u62b1\u6b49\u5728\u4e4b\u524d\u7684 set \u8bfe\u4e2d\u5b8c\u5168\u6ca1\u6709\u63d0\u53ca\uff0c\u56e0\u4e3a\u6211\u8ba4\u4e3a\u90a3\u662f \u5934\u6587\u4ef6\u91cc\u7684\u4e1c\u897f\u3002 \u4e0d\u8fc7\u522b\u62c5\u5fc3\uff0c\u4e4b\u540e\u6211\u4eec\u4f1a\u4e13\u95e8\u6709\u4e00\u8282 algorithm \u8bfe\u8be6\u89e3 STL \u4e2d\u8fd9\u4e9b\u5168\u5c40\u51fd\u6570\u2014\u2014\u6211\u79f0\u4e4b\u4e3a\u7b97\u6cd5\u6a21\u677f\uff0c\u56e0\u4e3a\u4ed6\u63d0\u4f9b\u4e86\u5f88\u591a\u5e38\u7528\u7684\u7b97\u6cd5\uff0c\u5bf9\u5c0f\u5f6d\u8001\u5e08\u8fd9\u79cd\u7b97\u6cd5\u5f31\u9e21\u800c\u8a00\uff0c\u5b9e\u5728\u975e\u5e38\u597d\u7528\uff0c\u5988\u5988\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3\u6211\u7684 ACM \u5956\u676f\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u5236\u4f5c\u5b8c algorithm \u8bfe\u4e4b\u524d\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u81ea\u884c\u53c2\u8003 https://blog.csdn.net/u013095333/article/details/89322501 \u63d0\u524d\u8fdb\u884c\u5b66\u4e60\u8fd9\u56db\u4e2a\u51fd\u6570\u3002 std::set_union(A.begin(), A.end(), B.begin(), B.end(), std::inserter(C, C.begin())); // C = A U B \u6ce8\uff1aset_union \u4ec5\u4ec5\u8981\u6c42\u8f93\u5165\u7684\u4e24\u4e2a\u533a\u95f4\u6709\u5e8f\uff0c\u53ef\u4ee5\u662f set\uff0c\u4e5f\u53ef\u4ee5\u662f\u6392\u5e8f\u8fc7\u7684 vector\u3002\u800c\u4e14\u901a\u8fc7\u91cd\u8f7d\u8fd0\u7b97\u7b26\u6216\u8005\u6307\u5b9a compare \u51fd\u6570\uff0c\u540c\u6837\u53ef\u4ee5\u6a21\u62df map \u53ea\u5bf9 key \u90e8\u5206\u6392\u5e8f\u7684\u6548\u679c\u2014\u2014\u53c2\u8003 thrust::sort_by_key\uff0c\u4f46\u5f88\u53ef\u60dc STL \u6ca1\u6709\u8fd9\u51fd\u6570\uff0c\u9700\u8981\u81ea\u5b9a\u4e49 compare \u51fd\u6570\u6a21\u62df\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u662f\u5f88\u5bb9\u6613\u57fa\u4e8e map \u7684 contains\u3001erase\u3001insert \u7b49\u63a5\u53e3\u201c\u52a8\u52a8\u8111\u201d\u5199\u51fa\u4fdd\u5e95\u5199\u6cd5\uff1a map m12; for (const auto &[k, v] : m2) { if (m1.contains(k)) { // \u6b64\u5904\u4e3a count \u4e5f\u53ef\u4ee5 // \u4ea4\u96c6\u64cd\u4f5c\uff1a\u5982\u679c m1 \u548c m2 \u90fd\u6709\u8fd9\u4e2a\u952e\uff0c\u5219\u63d2\u5165\u4ed6\u4fe9\u7684\u4ea4\u96c6 m12 m12.insert({k, v}); } } insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 C++11 \u8fd8\u5f15\u5165\u4e86\u4e00\u4e2a\u4ee5\u521d\u59cb\u5316\u5217\u8868\uff08initializer_list\uff09\u4e3a\u53c2\u6570\u7684 insert \u7248\u672c\uff1a void insert(initializer_list> ilist); \u7528\u6cd5\u548c map \u7684\u6784\u9020\u51fd\u6570\u4e00\u6837\uff0c\u8fd8\u662f\u7528\u82b1\u62ec\u53f7\u5217\u8868\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m.insert({ // \u6279\u91cf\u518d\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, // \"timeout\" \u53d1\u751f\u952e\u51b2\u7a81\uff0c\u6839\u636e insert \u7684\u7279\u6027\uff0c\u4e0d\u4f1a\u8986\u76d6 {\"delay\", 211}, }); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd9\u91cc\u8fd8\u662f\u548c\u9010\u4e2a insert \u4e00\u6837\uff0c\u91cd\u590d\u7684\u952e \u201ctimeout\u201d \u6ca1\u6709\u88ab\u8986\u76d6\uff0c\u4f9d\u65e7\u4e86\u4fdd\u7559\u539f\u503c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 m.insert({ {\"timeout\", 985}, {\"delay\", 211}, }); \u603b\u4e4b\u8fd9\u73a9\u610f\u548c\u5206\u522b\u8c03\u7528\u4e24\u6b21 insert \u7b49\u4ef7\uff1a m.insert({\"timeout\", 985}); m.insert({\"delay\", 211}); \u5982\u679c\u9700\u8981\u8986\u76d6\u539f\u503c\u7684\u6279\u91cf\u5199\u5165\uff0c\u8fd8\u662f\u5f97\u4e56\u4e56\u5199\u4e2a for \u5faa\u73af\u8c03\u7528 [] \u6216 insert_or_assign\u3002 \u95ee\uff1a\u65e2\u7136\u548c\u6279\u91cf\u63d2\u5165\u6ca1\u4ec0\u4e48\u533a\u522b\uff0c\u590d\u6742\u5ea6\u4e5f\u4e00\u6837\u662f O(\\log N) O(\\log N) \uff0c\u90a3\u6279\u91cf insert \u7a76\u7adf\u8fd8\u6709\u4ec0\u4e48\u5b58\u5728\u7684\u5fc5\u8981\u5462\uff1fmap \u53c8\u4e0d\u50cf vector \u4e00\u4e2a\u4e2a\u5206\u522b\u63d2\u5165\u4f1a\u53d8\u6210 O(N^2) O(N^2) \u590d\u6742\u5ea6\uff0c\u786e\u5b9e\u9700\u8981\u63d0\u4f9b\u4e2a\u6279\u91cf\u63d2\u5165\u7684\u65b9\u6cd5\u3002 \u7b54\uff1a \u662f\u4e3a\u4e86\u7edf\u4e00\uff0c\u65e2\u7136 vector \u90fd\u6709\u6279\u91cf insert\uff0c\u90a3 set \u548c map \u4e5f\u5f97\u6709\u624d\u7b26\u5408\u5b8c\u7f8e\u4e3b\u4e49\u7f8e\u5b66\uff0c\u800c\u4e14\u7528\u4ed6\u6765\u5408\u5e76\u4e24\u4e2a map \u4e5f\u5f88\u65b9\u4fbf\u3002 \u590d\u6742\u5ea6\u5e76\u4e0d\u4e00\u6837\uff0c\u5f53\u8f93\u5165\u5df2\u7ecf\u6709\u5e8f\u65f6\uff0c\u6279\u91cf insert \u4f1a\u6bd4\u9010\u4e2a insert \u66f4\u5feb\uff0c\u53ea\u9700 O(N) O(N) \u800c\u4e0d\u662f O(N \\log N) O(N \\log N) \uff1b\u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \uff0c\u7a0d\u540e\u4f1a\u8bb2\u539f\u7406\u3002 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 map &operator=(initializer_list> ilist); map \u4e5f\u652f\u6301\u8d4b\u503c\u51fd\u6570\uff0c\u4e0d\u4ec5\u6709 map \u81ea\u5df1\u7ed9\u81ea\u5df1\u8d4b\u503c\u7684\u79fb\u52a8\u8d4b\u503c\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff0c\u8fd8\u6709\u4ece\u5217\u8868\u521d\u59cb\u5316\u7684\u51fd\u6570\u3002 \u7528\u6cd5\u662f\u7b49\u53f7\u53f3\u8fb9\u4e00\u4e2a\u82b1\u62ec\u53f7\u5217\u8868\uff0c\u4f5c\u7528\u662f\u6e05\u7a7a\u539f\u6709\u5185\u5bb9\uff0c\u76f4\u63a5\u8bbe\u4e3a\u4e00\u4e2a\u5168\u65b0\u7684 map\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m = { // \u539f\u6709\u5185\u5bb9\u5168\u90e8\u6e05\u7a7a\uff01\u91cd\u65b0\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, {\"delay\", 211}, }; {\"delay\": 211, \"timeout\": 985} \u76f8\u5f53\u4e8e clear \u4e86\u518d\u91cd\u65b0 insert\uff0c\u539f\u6709\u7684 \u201canswer\u201d \u952e\u4e5f\u88ab\u5220\u6389\u4e86\u3002 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 \u8981\u6ce8\u610f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) \u548c\u6784\u9020\u51fd\u6570 map(initializer_list) \u662f\u4e0d\u540c\u7684\u3002 \u6784\u9020\u51fd\u6570\u662f\u521d\u59cb\u5316\u65f6\u8c03\u7528\u7684\uff08\u65e0\u8bba\u6709\u6ca1\u6709 = \u53f7\uff09\uff0c\u8d4b\u503c\u51fd\u6570\u662f\u540e\u671f\u91cd\u65b0\u8d4b\u503c\u65f6\u8c03\u7528\u7684\u3002 map m{ // \u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; map m = { // \u867d\u7136\u6709\u7b49\u53f7\uff0c\u4f46\u8fd9\u91cc\u662f\u521d\u59cb\u5316\u8bed\u5883\uff0c\u8c03\u7528\u7684\u4f9d\u7136\u662f\u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; m = { // m \u5df2\u7ecf\u521d\u59cb\u5316\u8fc7\uff0c\u8fd9\u91cc\u662f\u91cd\u65b0\u8d4b\u503c\uff0c\u624d\u662f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) {\"timeout\", 985}, {\"delay\", 211}, }; \u5982\u679c\u4e00\u4e2a\u7c7b\u8981\u652f\u6301\u521d\u59cb\u5316\uff0c\u53c8\u8981\u652f\u6301\u540e\u671f\u91cd\u65b0\u8d4b\u503c\uff0c\u90a3\u4e48\u6784\u9020\u51fd\u6570\u548c\u8d4b\u503c\u51fd\u6570\u90fd\u8981\u5b9e\u73b0\u3002 \u4f46\u4e5f\u53ef\u4ee5\u9009\u62e9\u53ea\u5b9a\u4e49 operator=(map &&) \u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u800c\u4e0d\u5b9a\u4e49 operator=(initializer_list) \u3002\u8fd9\u6837\u5f53\u8bd5\u56fe operator=(initializer_list) \u65f6\uff0c\u4f1a\u5339\u914d\u5230 map(initializer_list) \u8fd9\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\uff0c\u7136\u540e\u8c03\u7528\u5230 operator=(map &&) \u3002\u6807\u51c6\u5e93\u9009\u62e9\u5c06\u4e24\u4e2a\u90fd\u5b9a\u4e49\u53ef\u80fd\u662f\u5904\u4e8e\u907f\u514d\u4e00\u6b21 map \u79fb\u52a8\u7684\u6548\u7387\u8003\u91cf\u3002 assign \u51fd\u6570 map \u8fd8\u6709\u4e00\u4e2a assign \u51fd\u6570\uff0c\u4ed6\u548c operator= \u7b49\u4ef7\uff1a void assign(initializer_list> ilist); assign \u7684\u989d\u5916\u597d\u5904\u662f\u4ed6\u62e5\u6709\u4e24\u4e2a\u8fed\u4ee3\u5668\u53c2\u6570\u7ec4\u6210\u533a\u95f4\u7684\u7248\u672c\uff0c\u548c\u6279\u91cf insert \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7 assign \u4f1a\u6e05\u9664\u5df2\u6709\u7684\u5143\u7d20\u3002 template void assign(InputIt first, InputIt last); \u548c operator=(map(first, last)) \u7b49\u4ef7\u3002 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert iterator insert(const_iterator pos, pair const &kv); \u8fd9\u53c8\u662f insert \u51fd\u6570\u7684\u4e00\u4e2a\u91cd\u8f7d\u7248\uff0c\u589e\u52a0\u4e86 pos \u53c2\u6570\u63d0\u793a\u63d2\u5165\u4f4d\u7f6e\uff0c\u5b98\u65b9\u6587\u6863\u79f0 1 \uff1a Inserts value in the position as close as possible to the position just prior to pos. \u628a\u5143\u7d20\uff08\u952e\u503c\u5bf9\uff09\u63d2\u5165\u5230\u4f4d\u4e8e pos \u4e4b\u524d\uff0c\u53c8\u79bb pos \u5c3d\u53ef\u80fd\u8fd1\u7684\u5730\u65b9\u3002 \u7136\u800c map \u4f5c\u4e3a\u7ea2\u9ed1\u6811\u5e94\u8be5\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0c\u63d2\u5165\u4f4d\u7f6e\u53ef\u4ee5\u7531 K \u552f\u4e00\u786e\u5b9a\uff0c\u4e3a\u5565\u8fd8\u8981\u63d0\u793a\uff1f \u662f\u4e3a\u4e86\u5728\u5df2\u77e5\u8981\u63d2\u5165\u7684\u5927\u81f4\u4f4d\u7f6e\u65f6\uff0c\u80fd\u591f\u63d0\u5347\u6027\u80fd\u3002 \uff08\u5e26\u63d0\u793a\u7684 insert \u7248\u672c\uff09\u4e2d\u4f20\u5165\u7684\u8fed\u4ee3\u5668\uff0c\u4ec5\u662f\u7ed9 map \u5bb9\u5668\u63d0\u4f9b\u4e00\u4e2a\u5efa\u8bae\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u88ab\u5bb9\u5668\u91c7\u7eb3\u3002\u8be5\u8fed\u4ee3\u5668\u8868\u660e\u5c06\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\uff0c\u5e76\u4e0d\u662f\u6b64\u8fed\u4ee3\u5668\u8bf4\u4e86\u7b97\uff0c\u6700\u7ec8\u4ecd\u53d6\u51b3\u4e8e\u8be5\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c\u3002 2 \u4e5f\u5c31\u662f\u8bf4\u8fd9\u73a9\u610f\u8fd8\u4e0d\u4e00\u5b9a\u7ba1\u7528\uff0c\u53ea\u662f\u63d0\u793a\u6027\u8d28\u7684\uff08\u548c mmap \u51fd\u6570\u7684 start \u53c2\u6570\u5f88\u50cf\uff0c\u4f60\u53ef\u4ee5\u6307\u5b9a\uff0c\u4f46\u53ea\u662f\u4e2a\u63d0\u793a\uff0c\u6307\u5b9a\u4e86\u4e0d\u4e00\u5b9a\u6709\u4ec0\u4e48\u8f6f\u7528\uff0c\u5177\u4f53\u4ec0\u4e48\u5730\u5740\u8fd8\u662f\u64cd\u4f5c\u7cfb\u7edf\u8bf4\u4e86\u7b97\uff0c\u4ed6\u4ece\u8fd4\u56de\u503c\u91cc\u7ed9\u4f60\u7684\u5730\u5740\u624d\u662f\u6b63\u786e\u7b54\u6848\uff09\u3002\u4f8b\u5982\u5df2\u77e5\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u60f3\u8981\u63d2\u5165 \u201ckea\u201d\uff0c\u90a3\u4e48\u6307\u5b9a\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\u5c31\u4f1a\u8ba9 insert \u80fd\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230 \u201ckea\u201d \u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba iterator insert(const_iterator pos, pair const &kv); \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u7684\u51c6\u786e\u65f6\uff0cinsert \u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u4f4e\u81f3 O(1)+ O(1)+ \u3002 \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u4e0d\u51c6\u786e\u65f6\uff0c\u548c\u666e\u901a\u7684 insert \u4e00\u6837\uff0c\u8fd8\u662f O(\\log N) O(\\log N) \u3002 \u8fd4\u56de\u6307\u5411\u6210\u529f\u63d2\u5165\u5143\u7d20\u4f4d\u7f6e\u7684\u8fed\u4ee3\u5668\u3002 \u60f3\u60f3\u770b\uff0c\u8fd9\u4e09\u4e2a\u770b\u4f3c\u4e0d\u76f8\u5e72\u7684\u7279\u6027\uff0c\u80fd\u6709\u4ec0\u4e48\u7528\u5462\uff1f \u53ef\u4ee5\u8ba9\u5df2\u7ecf\u6709\u5e8f\u6570\u636e\u7684\u6279\u91cf\u63d2\u5165\u66f4\u9ad8\u6548\uff01 \u4f17\u6240\u5468\u77e5\uff0c\u666e\u901a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4e3a O(N \\log N) O(N \\log N) \u3002 vector> arr; map tab; for (auto const &[k, v]: arr) { tab.insert({k, v}); // O(log N) } // \u603b\u5171 O(N log N) \u5047\u5982\u8f93\u5165\u672c\u5c31\u6709\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(N) O(N) \u3002 \u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \u4e0d\u53d8\u3002 vector> arr; map tab; auto hint = tab.begin(); for (auto const &[k, v]: arr) { hint = tab.insert(hint, {k, v}); // \u5e73\u5747 O(1) } // \u603b\u5171 O(N) \u60f3\u4e00\u60f3\uff0c\u4e3a\u4ec0\u4e48\uff1f \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u4f60\u662f\u4e00\u540d\u5c0f\u5b66\u8001\u5e08\uff0c\u9a6c\u4e0a\u5c31\u8981\u51fa\u65e9\u64cd\u4e86\uff0c\u4e3a\u5e94\u4ed8\u9886\u5bfc\u9762\u5b50\uff0c\u4f60\u9700\u8981\u7ed9\u4f60\u7684\u5b66\u751f\u6392\u961f\uff0c\u6839\u636e\u4e2a\u5b50\u4ece\u77ee\u5230\u9ad8\u6392\u5217\u3002 \u4e0d\u8fc7\u8fd9\u6240\u5c0f\u5b66\u7684\u5b66\u751f\u90fd\u6bd4\u8f83\u61d2\u6563\uff0c\u6709\u7684\u6765\u5f97\u65e9\u6709\u7684\u6765\u5f97\u665a\uff0c\u800c\u4e14\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u4ed6\u4eec\u7684\u9ad8\u77ee\u65e0\u5173\u3002 \u4f60\u672c\u6765\u6253\u7b97\u7b49\u6240\u6709\u4eba\u5230\u9f50\u4e4b\u540e\u518d\u4e00\u6b21\u6027\u5b8c\u6210\u6392\u5e8f\uff08std::sort\uff09\u7684\uff0c\u4f46\u662f\u540c\u5b66\u6765\u7684\u65f6\u95f4\u5b9e\u5728\u662f\u592a\u5206\u6563\u4e86\uff1a\u660e\u660e 8 \u70b9\u5c31\u8981\u51fa\u65e9\u64cd\uff0c\u6700\u665a\u7684\u540c\u5b66\u5374 7 \u70b9 59 \u5206\u624d\u5230\u8fbe\u3002\u610f\u5473\u7740\u4f60\u9700\u8981\u4e00\u76f4\u5e72\u7b49\u7740\u8fd9\u4e2a\u61d2\u6563\u7684\u540c\u5b66\uff0c\u6700\u540e\u5728 1 \u5206\u949f\u65f6\u95f4\u5185\u4e34\u65f6\u62b1\u4f5b\u811a\uff0c\u5b8c\u6210\u5feb\u901f\u6392\u5e8f\u3002\u8fd9\u662f\u4e0d\u53ef\u80fd\u7684\uff0c\u53ea\u80fd\u5728\u540c\u5b66\u9646\u7eed\u62b5\u8fbe\u7684\u540c\u65f6\u8fdb\u884c\u6392\u5e8f\uff0c\u8fd9\u5c31\u662f\u5806\u6392\u5e8f\uff0c\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u6392\u5e8f\uff0c\u6bcf\u6b21\u63d2\u5165\u540e\u90fd\u4fdd\u8bc1\u6709\u5e8f\uff0c\u4e0e\u63d2\u5165\u6392\u5e8f\u4e0d\u540c\u4ed6\u4f7f\u7528\u5806\u5185\u5b58\u4e2d\u7684\u8282\u70b9\u800c\u4e0d\u662f\u6570\u7ec4\u907f\u514d\u6602\u8d35\u7684\u6570\u7ec4\u5e73\u79fb\u64cd\u4f5c\u3002 \u6bcf\u5f53\u6765\u4e00\u4e2a\u5b66\u751f\uff0c\u4f60\u5c31\u5f97\u628a\u4ed6\u63d2\u5165\u5230\u73b0\u6709\u7684\u4e00\u4e2a\u5df2\u7ecf\u6392\u597d\u7684\u961f\u4f0d\u4e2d\u53bb\u3002 \u5982\u4f55\u786e\u5b9a\u63d2\u5165\u7684\u4f4d\u7f6e\uff1f\u4e8c\u5206\u6cd5\u3002\u5148\u4ece\u73b0\u6709\u961f\u4f0d\u7684\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\uff0c\u6bd4\u8f83\u4e2d\u95f4\u8fd9\u4e2a\u5b66\u751f\u548c\u65b0\u6765\u7684\u5b66\u751f\u54ea\u4e2a\u9ad8\u54ea\u4e2a\u77ee\uff0c\u5982\u679c\u53d1\u73b0\u65b0\u6765\u7684\u5b66\u751f\u9ad8\uff0c\u5219\u7ee7\u7eed\u4ece\u961f\u5217\u7684 3/4 \u5904\u90a3\u4e2a\u540c\u5b66\u5f00\u59cb\u6bd4\u9ad8\u77ee\uff0c\u5982\u679c\u65b0\u6765\u7684\u5b66\u751f\u77ee\u5c31\u4ece\u961f\u5217\u7684 1/4 \u5904\u7ee7\u7eed\u6bd4\u8f83\u3002\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6700\u7ec8\u552f\u4e00\u786e\u5b9a\u65b0\u540c\u5b66\u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002\u56e0\u4e3a\u6bcf\u6b21\u786e\u5b9a\u7684\u8303\u56f4\u5c31\u5c0f\u4e00\u534a\uff0c\u6240\u4ee5\u6700\u591a\u53ea\u9700\u8981 \\log N \\log N \u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u6210\u529f\u63d2\u5165\uff0c\u5176\u4e2d N N \u662f\u5f53\u524d\u5df2\u6709\u5b66\u751f\u7684\u6570\u91cf\u3002 \u603b\u5171\u8981\u6765 N N \u540d\u5b66\u751f\uff0c\u5219\u4f60\u603b\u5171\u9700\u8981\u6bd4\u8f83 N \\log N N \\log N \u6b21\u3002\u80fd\u4e0d\u80fd\u4f18\u5316\uff1f\u8ba9\u6211\u4eec\u5c0f\u5f6d\u8001\u5e08\u7701\u529b\u70b9\uff1f \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u540e\u6765\u4f60\u53d1\u73b0\u4e00\u4e2a\u89c4\u5f8b\uff0c\u4f3c\u4e4e\u5b66\u751f\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u6709\u5173\uff1a\u77ee\u5c0f\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u65e9\uff0c\u9ad8\u5927\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u665a\u3002 \u77e5\u9053\u8fd9\u4e2a\u89c4\u5f8b\u540e\uff0c\u4f60\u6539\u53d8\u4f60\u7684\u7b56\u7565\uff1a\u4e8c\u5206\u6cd5\u65f6\uff0c\u4e0d\u662f\u5148\u4ece\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\u67e5\u627e\uff0c\u800c\u662f\u4ece\u6700\u672b\u5c3e\u5f00\u59cb\u67e5\u627e\u3002\u56e0\u4e3a\u77ee\u5c0f\u540c\u5b66\u4f1a\u65e9\u5230\uff0c\u5bfc\u81f4\u6bcf\u6b21\u65b0\u6765\u7684\u540c\u5b66\u5f80\u5f80\u603b\u662f\u961f\u5217\u4e2d\u6700\u9ad8\u7684\u90a3\u4e00\u4e2a\u3002\u6240\u4ee5\u53ef\u4ee5\u4ece\u961f\u4f0d\u7684\u672b\u5c3e\uff08\u6700\u9ad8\u7684\u5730\u65b9\uff09\u5f00\u59cb\u627e\uff0c\u4f8b\u5982\u6709 64 \u540d\u540c\u5b66\u5219\u4f18\u5148\u548c 65/64 \u5904\u6bd4\u8f83\uff0c\u627e\u4e0d\u5230\u518d\u5f80\u4e0a\u4e00\u7ea7\u548c 31/32 \u5904\u6bd4\u8f83\u3002 \u8fd9\u4e2a\u7b56\u7565\u4e5f\u6709\u7f3a\u70b9\uff1a\u5bf9\u4e8e\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u65e0\u5173\u3001\u751a\u81f3\u8d1f\u76f8\u5173\u7684\u60c5\u51b5\uff0c\u6bcf\u6b21\u63d2\u5165\u7684\u6d88\u8017\u5c31\u4f1a\u53d8\u6210 2 \\log N 2 \\log N \u4e86\u3002 \u6700\u7ec8\u6211\u4eec\u51b3\u5b9a\u91c7\u7528\u7684\u7b56\u7565\u662f\uff1a\u4e0d\u662f\u4ece\u4e2d\u95f4\uff0c\u4e5f\u4e0d\u662f\u4ece\u5f00\u5934\uff0c\u4e5f\u4e0d\u662f\u4ece\u672b\u5c3e\uff0c\u800c\u662f \u8bb0\u4f4f\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e \uff0c\u4e0b\u4e00\u6b21\u4ece\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e\u5f00\u59cb\u627e\u3002\u8fd9\u4e2a\u8bb0\u5fc6\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u5c31\u662f\u521a\u521a\u4ee3\u7801\u4e2d\u90a3\u4e2a\u4f4d\u7f6e\u63d0\u793a\u8fed\u4ee3\u5668 hint\u3002 \u8fd9\u6b63\u662f\u6211\u4eec\u4ee3\u7801\u7684\u5199\u6cd5\uff1a hint = tab.insert(hint, {k, v}); \u5b9e\u9645\u4e0a\uff0cinsert \u7684\u6279\u91cf\u63d2\u5165\u7248 insert(arr.begin(), arr.end()) \u5185\u90e8\u5c31\u4f1a\u4f7f\u7528\u8fd9\u79cd\u5e26\u63d0\u793a\u7684\u65b9\u5f0f\uff0c\u9010\u4e2a\u63d2\u5165\u3002 vector> arr; \u5206\u5974 emplace insert \u7684\u7a76\u6781\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace template pair emplace(Args &&...args); \u867d\u7136\u53d8\u957f\u53c2\u6570\u5217\u8868 Args &&...args \u770b\u8d77\u6765\u5f88\u9177\uff0c\u7136\u800c\u7531\u4e8e map \u7684\u7279\u6b8a\u6027\uff0c\u5176\u5143\u7d20\u7c7b\u578b\u662f pair \uff0c\u800c pair \u7684\u6784\u9020\u51fd\u6570\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\uff0c\u5bfc\u81f4\u5b9e\u9645\u4e0a\u8fd9\u4e2a\u770b\u4f3c\u70ab\u9177\u7684\u53d8\u957f\u53c2\u6570\u5217\u8868\u5f80\u5f80\u53ea\u80fd\u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\uff0c\u56e0\u6b64\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u5b9e\u9645\u4e0a\u53ea\u80fd\u662f\uff1a pair emplace(K k, V v); \u5199\u6cd5\uff1a m.emplace(key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert({key, val}); \u8fd4\u56de\u503c\u8fd8\u662f pair \uff0c\u5176\u610f\u4e49\u548c insert \u4e00\u6837\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002 emplace_hint insert \u7684\u5b87\u5b99\u65e0\u654c\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace_hint 1 template iterator emplace_hint(const_iterator pos, Args &&...args); \u5199\u6cd5\uff1a m.emplace_hint(pos, key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert(pos, {key, val}); \u4e4b\u6240\u4ee5\u8981\u5206\u4e24\u4e2a\u51fd\u6570\u540d emplace \u548c emplace_hint \u800c\u4e0d\u662f\u5229\u7528\u91cd\u8f7d\u533a\u5206\uff0c\u662f\u56e0\u4e3a\u76f4\u63a5\u4f20\u5165 pos \u4f1a\u88ab emplace \u5f53\u505a pair \u7684\u6784\u9020\u53c2\u6570\uff0c\u800c\u4e0d\u662f\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u3002 emplace \u5bf9\u5e94\u4e8e\u666e\u901a\u7684 insert(pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u5bf9\u5e94\u4e8e\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert(const_iterator, pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u548c\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u4e00\u6837\uff0c\u662f\u5355\u72ec\u4e00\u4e2a iterator\u3002 emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 template pair emplace(Args &&...args); emplace \u5bf9\u4e8e set\uff0c\u5143\u7d20\u7c7b\u578b\u662f\u6bd4\u8f83\u5927\u7684\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 set> \uff0c\u53ef\u80fd\u786e\u5b9e\u80fd\u8d77\u5230\u51cf\u5c11\u79fb\u52a8\u6784\u9020\u51fd\u6570\u5f00\u9500\u7684\u4f5c\u7528\u3002 \u4f46\u662f\u8fd9\u4e2a map \u4ed6\u7684\u5143\u7d20\u7c7b\u578b\u4e0d\u662f\u76f4\u63a5\u7684 V \u800c\u662f\u4e00\u4e2a pair\uff0c\u4ed6\u5206\u7684\u662f pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709\u7528\uff0cV \u90e8\u5206\u8fd8\u662f\u4f1a\u9020\u6210\u4e00\u6b21\u989d\u5916\u7684\u79fb\u52a8\u5f00\u9500\uff0c\u6240\u4ee5\u8fd9\u73a9\u610f\u9664\u4e86\u59a8\u788d\u7c7b\u578b\u5b89\u5168\u548c\u53ef\u8bfb\u6027\u4ee5\u5916\uff0c\u6ca1\u6709\u4efb\u4f55\u6536\u76ca\u3002 set \u53ef\u4ee5\u7528 emplace/emplace_hint\u3002 vector \u53ef\u4ee5\u7528 emplace_back\u3002 \u4e0d\u5efa\u8bae\u5728 map \u4e0a\u4f7f\u7528 emplace/emplace_hint\uff0c\u8bf7\u6539\u7528 try_emplace\u3002 try_emplace \u66f4\u597d emplace \u53ea\u652f\u6301 pair \u7684\u5c31\u5730\u6784\u9020\uff0c\u8fd9\u6709\u4ec0\u4e48\u7528\uff1f\u6211\u4eec\u8981\u7684\u662f pair \u4e2d\u503c\u7c7b\u578b\u7684\u5c31\u5730\u6784\u9020\uff01\u8fd9\u5c31\u662f try_emplace \u7684\u4f5c\u7528\u4e86\uff0c\u4ed6\u5bf9 key \u90e8\u5206\u4f9d\u7136\u662f\u4f20\u7edf\u7684\u79fb\u52a8\uff0c\u53ea\u5bf9 value \u90e8\u5206\u91c7\u7528\u5c31\u5730\u6784\u9020\u3002 \u8fd9\u662f\u89c2\u5bdf\u5230\u5927\u591a\u662f\u503c\u7c7b\u578b\u5f88\u5927\uff0c\u6025\u9700\u5c31\u5730\u6784\u9020\uff0c\u800c\u952e\u7c7b\u578b\u6ca1\u7528\u591a\u5c11\u5c31\u5730\u6784\u9020\u7684\u9700\u6c42\u3002\u4f8b\u5982 map> \u5982\u679c\u60f3\u4e0d\u7528 try_emplace\uff0c\u5b8c\u5168\u57fa\u4e8e emplace \u5b9e\u73b0\u9488\u5bf9\u503c value \u7684\u5c31\u5730\u6784\u9020\u9700\u8981\u7528\u5230 std::piecewise_construct \u548c std::forward_as_tuple\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 insert \u7684\u6258\u9a6c\u65af\u9ec4\u91d1\u5927\u56de\u65cb\u5206\u5974\u7248\uff1atry_emplace\uff08C++17 \u5f15\u5165\uff09 template pair try_emplace(K const &k, Args &&...args); \u5199\u6cd5\uff1a m.try_emplace(key, arg1, arg2, ...); \u4ed6\u7b49\u4ef7\u4e8e\uff1a m.insert({key, V(arg1, arg2, ...)}); \u540e\u9762\u7684\u53d8\u957f\u53c2\u6570\u4e5f\u53ef\u4ee5\u5b8c\u5168\u6ca1\u6709\uff1a m.try_emplace(key); \u4ed6\u7b49\u4ef7\u4e8e\u8c03\u7528 V \u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a m.insert({key, V()}); \u7531\u4e8e emplace \u5b9e\u5728\u662f\u61a8\u61a8\uff0c\u4ed6\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u7684\u662f pair\uff0c\u7136\u800c pair \u7684\u6784\u9020\u51fd\u6570\u6b63\u5e38\u4e0d\u5c31\u662f\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\u5417\uff0c\u53d8\u957f\u6ca1\u6709\u7528\u3002\u5b9e\u9645\u6709\u7528\u7684\u5f80\u5f80\u662f\u6211\u4eec\u5e0c\u671b\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u503c\u7c7b\u578b V\uff0c\u5bf9 K \u90e8\u5206\u5e76\u4e0d\u5173\u7cfb\u3002\u56e0\u6b64 C++17 \u5f15\u5165\u4e86 try_emplace\uff0c\u5176\u952e\u90e8\u5206\u4fdd\u6301 K const & \uff0c\u503c\u90e8\u5206\u91c7\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u3002 \u6211\u7684\u8bc4\u4ef7\u662f\uff1a\u8fd9\u4e2a\u6bd4 emplace \u5b9e\u7528\u591a\u4e86\uff0c\u5982\u679c\u8981\u4e0e vector \u7684 emplace_back \u5bf9\u6807\uff0c\u90a3\u4e48 map \u4e0e\u4e4b\u5bf9\u5e94\u7684\u4e00\u5b9a\u662f try_emplace\u3002\u540c\u5b66\u4eec\u5982\u679c\u8981\u5206\u5974\u7684\u8bdd\u8fd8\u662f\u5efa\u8bae\u7528 try_emplace\u3002 try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 insert \u7c7b\u51fd\u6570\u603b\u662f\u4e0d\u53ef\u907f\u514d\u7684\u9700\u8981\u79fb\u52a8\u6784\u9020\uff1a\u5148\u5728\u51fd\u6570\u4e2d\u6784\u9020\u51fa\u4e34\u65f6\u5bf9\u8c61\uff0c\u7136\u540e\u6784\u9020\u5230\u771f\u6b63\u7684 pair \u4e0a\u3002 \u800c try_emplace \u53ef\u4ee5\u5141\u8bb8\u4f60\u5c31\u5730\u6784\u9020\u503c\u5bf9\u8c61\uff0c\u907f\u514d\u79fb\u52a8\u9020\u6210\u5f00\u9500\u3002 try_emplace \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u952e\uff0c\u7b2c\u4e8c\u4e2a\u5f00\u59cb\u662f\u4f20\u7ed9\u6784\u9020\u51fd\u6570\u7684\u53c2\u6570\uff0c\u5982\u53ea\u6709\u7b2c\u4e00\u4e2a\u53c2\u6570\u5219\u662f\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570\u3002 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(int i) { printf(\"MyClass(int)\\n\"); } MyClass(const char *p, float x) { printf(\"MyClass(const char *, float)\\n\"); } }; map m; m.try_emplace(\"key\"); // MyClass() m.try_emplace(\"key\", 42); // MyClass(int) m.try_emplace(\"key\", \"hell\", 3.14f); // MyClass(const char *, float) // \u7b49\u4ef7\u4e8e\uff1a m.insert({\"key\", MyClass()}); // MyClass() m.insert({\"key\", MyClass(42)}); // MyClass(int) m.insert({\"key\", MyClass(\"hell\", 3.14f)}); // MyClass(const char *, float) \u5bf9\u4e8e\u79fb\u52a8\u5f00\u9500\u8f83\u5927\u7684\u7c7b\u578b\uff08\u4f8b\u5982 array \uff09\uff0ctry_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff1b\u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u503c\u7c7b\u578b\uff0c\u5c31\u5fc5\u987b\u4f7f\u7528 try_emplace \u4e86\u3002 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 // \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u6548\u679c\u7b49\u4ef7\uff0c\u53ea\u6709\u6027\u80fd\u4e0d\u540c m.try_emplace(key, arg1, arg2, ...); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 m.insert({key, V(arg1, arg2, ...)}); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 2\u6b21\u79fb\u52a8\u51fd\u6570 m.insert(make_pair(key, V(arg1, arg2, ...))); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 3\u6b21\u79fb\u52a8\u51fd\u6570 \u4f46\u662f\u7531\u4e8e try_emplace \u662f\u7528\u5706\u62ec\u53f7\u5e2e\u4f60\u8c03\u7528\u7684\u6784\u9020\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u3002 \u5bfc\u81f4\u4f60\u8981\u4e48\u65e0\u6cd5\u7701\u7565\u7c7b\u578b\uff0c\u8981\u4e48\u4f60\u5f97\u624b\u52a8\u5b9a\u4e49\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff1a struct Student { // \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u82b1\u62ec\u53f7\u8bed\u6cd5\u8fdb\u884c\u521d\u59cb\u5316 string sex; int age; }; map m; m.insert({\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}}); // OK: insert \u53c2\u6570\u7c7b\u578b\u5df2\u77e5\uff0cStudent \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff0c\u4f46\u662f\u4f1a\u9020\u6210 2 \u6b21\u79fb\u52a8 m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // ERROR: \u4e0d\u5b58\u5728\u6784\u9020\u51fd\u6570 Student(string, int)\uff1bC++20 \u5f00\u59cb\u5219 OK: C++20 \u8d77\u805a\u5408\u521d\u59cb\u5316\u540c\u65f6\u652f\u6301\u82b1\u62ec\u53f7\u548c\u5706\u62ec\u53f7 m.try_emplace(\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}); // ERROR: \u53c2\u6570\u7c7b\u578b\u662f\u6a21\u677f\u7c7b\u578b\uff0c\u672a\u77e5\uff0c\u65e0\u6cd5\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b m.try_emplace(\"\u5f6d\u4e8e\u658c\", Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: \u660e\u786e\u6307\u5b9a\u7c7b\u578b\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff1b\u4f46\u8fd9\u6837\u53c8\u4f1a\u9020\u6210 1 \u6b21\u79fb\u52a8\uff0c\u5931\u53bb\u4e86 try_emplace \u907f\u514d\u79fb\u52a8\u7684\u610f\u4e49 \u6b64\u5916\u8fd8\u8981\u6ce8\u610f\u4e0d\u8bba insert\u3001emplace\u3001emplace_hint\u3001try_emplace\uff0c\u90fd\u662f\u4e00\u4e2a\u5c3f\u6027\uff1a\u952e\u51b2\u7a81\u65f6\u4e0d\u4f1a\u8986\u76d6\u5df2\u6709\u5143\u7d20\u3002 \u5982\u679c\u9700\u8981\u8986\u76d6\u6027\u7684\u63d2\u5165\uff0c\u8fd8\u5f97\u4e56\u4e56\u7528 [] \u6216\u8005 insert_or_assign \u51fd\u6570\u3002 \u7531\u4e8e try_emplace \u91cc\u5199\u6b7b\u4e86\u5706\u62ec\u53f7\uff0c\u6211\u4eec\u53ea\u597d\u624b\u52a8\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\u624d\u80fd\u52b3\u9a7e try_emplace \u5c31\u5730\u6784\u9020\u3002 struct Student { string sex; int age; Student(string sex, int age) : sex(std::move(sex)) , age(age) {} // \u7531\u4e8e try_emplace \u4f1a\u5c31\u5730\u6784\u9020\u5bf9\u8c61\uff0c\u5176\u503c\u7c7b\u578b\u53ef\u4ee5\u6ca1\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u800c insert \u4f1a\u51fa\u9519 Student(Student &&) = delete; Student &operator=(Student &&) = delete; Student(Student const &) = delete; Student &operator=(Student const &) = delete; }; map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570 Student(string, int) \u5c31\u5730\u6784\u9020\u5bf9\u8c61 m.insert({\"\u5f6d\u4e8e\u658c\", Student(\"\u81ea\u5b9a\u4e49\", 22)}); // ERROR: insert \u9700\u8981\u79fb\u52a8 Student \u800c Student \u7684\u79fb\u52a8\u88ab delete \u4e86\uff01 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 \u65e0\u6784\u9020\u51fd\u6570\u65f6\uff0cC++11 \u652f\u6301\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff08\u5b98\u65b9\u540d: \u805a\u5408\u521d\u59cb\u5316 1 \uff09\uff0cC++20 \u5f00\u59cb\u805a\u5408\u521d\u59cb\u5316\u4e5f\u80fd\u7528\u5706\u62ec\u53f7\uff08\u6240\u4ee5 emplace / try_emplace \u8fd9\u7c7b\u51fd\u6570\u53d8\u5f97\u66f4\u597d\u7528\u4e86\uff09\uff1a struct Student { string sex; int age; }; auto s1 = Student{\"\u81ea\u5b9a\u4e49\", 22}; // C++11 \u8d77 OK: \u65e0\u6784\u9020\u51fd\u6570\u65f6\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5 auto s2 = Student(\"\u81ea\u5b9a\u4e49\", 22); // C++20 \u8d77 OK: \u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u751f\u6210\u5706\u62ec\u53f7\u6784\u9020\u51fd\u6570 Student(string, int) \u548c\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u65f6\u4e00\u6837\uff0c\u53ef\u4ee5\u7701\u7565\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u8fd9\u90e8\u5206\u53c2\u6570\u4f1a\u7528\u4ed6\u4eec\u7684\u9ed8\u8ba4\u503c\uff1a auto s1 = Student(\"\u81ea\u5b9a\u4e49\", 22); // OK: sex \u4e3a \"\u81ea\u5b9a\u4e49\"\uff0cage \u4e3a 22 auto s2 = Student(\"\u81ea\u5b9a\u4e49\"); // OK: \u7701\u7565 age \u81ea\u52a8\u4e3a 0 auto s3 = Student(); // OK: \u7701\u7565 sex \u81ea\u52a8\u4e3a \"\" \u4e0d\u8fc7\u4ed6\u548c\u82b1\u62ec\u53f7\u4e0d\u4e00\u6837\u7684\u662f\uff0c\u4f5c\u4e3a\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\u7684\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u7c7b\u578b\u540d\u4e0d\u80fd\u7701\u7565\u4e86\uff1a void func(Student const &stu); // \u5df2\u77e5\u51fd\u6570\u7b7e\u540d func(Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5 func({\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5\uff0c\u5df2\u77e5\u51fd\u6570\u5177\u6709\u552f\u4e00\u91cd\u8f7d\u7684\u60c5\u51b5\u4e0b\u7c7b\u540d\u53ef\u4ee5\u7701\u7565 func(Student(\"\u81ea\u5b9a\u4e49\", 22)); // OK: C++20 \u8bed\u6cd5 func((\"\u81ea\u5b9a\u4e49\", 22)); // ERROR: \u65e0\u6cd5\u4ece int \u8f6c\u6362\u4e3a Student C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u6240\u4ee5\u73b0\u5728 try_emplace \u4e5f\u53ef\u4ee5\u5c31\u5730\u6784\u9020\u65e0\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u4e86\uff1a map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 22} m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 0} m.try_emplace(\"\u5f6d\u4e8e\u658c\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\", 0} \u65b9\u4fbf\uff01 \u5173\u4e8e\u66f4\u591a C++20 \u7684\u805a\u5408\u521d\u59cb\u5316\u5c0f\u77e5\u8bc6\uff0c\u53ef\u4ee5\u770b\u8fd9\u671f CppCon \u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=flLNi0aejew \u4e3a\u65b9\u4fbf\u4f60\u5728\u6bd4\u7ad9\u641c\u7d22\u642c\u8fd0\uff0c\u4ed6\u7684\u6807\u9898\u662f\uff1aLightning Talk: Direct Aggregate Initialisation - Timur Doumler - CppCon 2021 \u8c03\u7528\u5f00\u9500\u5206\u6790 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(MyClass &&) noexcept { printf(\"MyClass(MyClass &&)\\n\"); } MyClass &operator=(MyClass &&) noexcept { printf(\"MyClass &operator=(MyClass &&)\\n\"); return *this; } }; map tab; printf(\"insert\u7684\u5f00\u9500:\\n\"); tab.insert({1, MyClass()}); printf(\"try_emplace\u7684\u5f00\u9500:\\n\"); tab.try_emplace(2); // try_emplace \u53ea\u6709\u4e00\u4e2a key \u53c2\u6570\u65f6\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570 MyClass() insert \u8c03\u7528\u4e86\u4e24\u6b21\u79fb\u52a8\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 insert \u628a\u53c2\u6570 pair \u79fb\u8fdb\u7ea2\u9ed1\u6811\u8282\u70b9\u91cc\u3002 \u800c try_emplace \u5185\u90e8\u4f7f\u7528\u4e86\u73b0\u4ee3 C++ \u7684\u5c31\u5730\u6784\u9020\uff08placement new\uff09\uff0c\u76f4\u63a5\u5728\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u5185\u5b58\u4e2d\u6784\u9020 MyClass\uff0c\u65e0\u9700\u53cd\u590d\u79fb\u52a8\uff0c\u5bf9\u4e8e\u5c3a\u5bf8\u8f83\u5927\u7684\u503c\u7c7b\u578b\u4f1a\u66f4\u9ad8\u6548\u3002 insert\u7684\u5f00\u9500: MyClass() MyClass(MyClass &&) MyClass(MyClass &&) try_emplace\u7684\u5f00\u9500: MyClass() try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u63d0\u5347\u4e86 1.42 \u500d\u6027\u80fd\uff0c\u4e0d\u80fd\u8bf4\u662f\u60ca\u5929\u5730\u6ce3\u9b3c\u795e\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u804a\u80dc\u4e8e\u65e0\u4e86\u3002\u8fd9\u91cc\u7684\u503c\u7c7b\u578b string \u53ea\u6709 32 \u5b57\u8282\u8fd8\u4e0d\u591f\u660e\u663e\uff0c\u53ef\u80fd\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\u4f1a\u6709\u660e\u663e\u7684\u4f18\u52bf\u3002\u8fd9\u79cd\u4f18\u5316\u7684\u7406\u8bba\u4e0a\u9650\u662f 3 \u500d\uff0c\u6700\u591a\u80fd\u4ece try_emplace \u83b7\u5f97 3 \u500d\u6027\u80fd\u63d0\u5347\u3002 template static void test_insert(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) 2\u6b21string(string &&) tab.insert({i, \"hello\"}); } } template static void test_try_emplace(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) tab.try_emplace(i, \"hello\"); } } int main() { for (int i = 0; i < 1000; i++) { map tab; test_insert(tab); doNotOptimize(tab); } for (int i = 0; i < 1000; i++) { map tab; test_try_emplace(tab); doNotOptimize(tab); } printScopeProfiler(); } avg | min | max | total | cnt | tag 39| 34| 218| 39927| 1000| test_insert 28| 27| 91| 28181| 1000| test_try_emplace \u5982\u679c\u6539\u6210\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\uff0c\u53ef\u4ee5\u63d0\u5347 2.3 \u500d\u3002 struct MyClass { int arr[4096]; }; avg | min | max | total | cnt | tag 1312| 1193| 18298| 1312871| 1000| test_insert 573| 537| 1064| 573965| 1000| test_try_emplace \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace insert \u7684\u70ab\u5f69\u4e2d\u4e8c\u6447\u6446\u6df7\u6c8c\u5927\u9b54\u738b\u5206\u5974\u7248\uff1a\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace template iterator try_emplace(const_iterator pos, K const &k, Args &&...args); \u5199\u6cd5\uff1a hint = m.try_emplace(hint, key, arg1, arg2, ...); \u7b49\u4ef7\u4e8e\uff1a hint = m.insert(hint, {key, V(arg1, arg2, ...)}); \u8fd9\u6b21\u4e0d\u9700\u8981\u518d\u5206\u4e00\u4e2a\u4ec0\u4e48 try_emplace_hint \u51fa\u6765\u4e86\uff0c\u662f\u56e0\u4e3a try_emplace \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f K \u7c7b\u578b\u800c\u4e0d\u662f\u6cdb\u578b\uff0c\u4e0d\u53ef\u80fd\u548c const_iterator \u7c7b\u578b\u6df7\u6dc6\uff0c\u56e0\u6b64 C++ \u59d4\u5458\u4f1a\u6700\u7ec8\u51b3\u5b9a\u76f4\u63a5\u5171\u7528\u540c\u4e00\u4e2a\u540d\u5b57\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u91cd\u8f7d\u4e86\u3002 emplace \u5bb6\u65cf\u603b\u7ed3 \u603b\u7ed3\uff0c\u5982\u4f55\u7528 emplace \u5bb6\u65cf\u4f18\u5316\uff1f\u5206\u76f4\u63a5\u63d2\u5165\u548c\u5e26\u63d0\u793a\u63d2\u5165\u4e24\u79cd\u7528\u6cd5\uff0c\u548c\u4f60\u662f\u5426\u9700\u8981\u9ad8\u6027\u80fd\u4e24\u79cd\u9700\u6c42\uff0c\u8fd9\u91cc\u6807\u4e86\u201c\u63a8\u8350\u201d\u7684\u662f\u5efa\u8bae\u91c7\u7528\u7684\uff1a // \u76f4\u63a5\u63d2\u5165\u7248 m.insert({\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 m.try_emplace(\"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 m.emplace(\"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 m.emplace(std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 // \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7248 hint = m.insert(hint, {\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 hint = m.try_emplace(hint, \"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 hint = m.emplace_hint(hint, \"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 hint = m.emplace_hint(hint, std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 map \u4e0e RAII \u68a6\u5e7b\u8054\u52a8\uff1amap \u5bb9\u5668\u4e0e RAII \u7684\u53cc\u5411\u5954\u8d74 \u5982\u679c map \u4e2d\u5143\u7d20\u7684\u503c\u7c7b\u578b\u662f RAII \u7c7b\u578b\uff0c\u5176\u6790\u6784\u51fd\u6570\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u8c03\u7528\u3002 map \u88ab\u79fb\u52a8\u65f6\uff0c\u4e0d\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u79fb\u52a8\u51fd\u6570\uff0c\u56e0\u4e3a map \u91cc\u53ea\u5b58\u7740\u6307\u5411\u7ea2\u9ed1\u6811\u6839\u8282\u70b9\u7684\u6307\u9488\uff0c\u53ea\u9700\u6307\u9488\u79fb\u52a8\u5373\u53ef\u3002 map \u88ab\u62f7\u8d1d\u65f6\uff0c\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u62f7\u8d1d\u51fd\u6570\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u5219 map \u7684\u62f7\u8d1d\u4e5f\u4f1a\u88ab\u7981\u7528\uff08delete\uff09\u6389\u3002 map \u88ab\u6790\u6784\u65f6\uff0c\u5176\u6240\u6709\u5143\u7d20\u90fd\u4f1a\u88ab\u6790\u6784\u3002 \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\\n\", i); } RAII &operator=(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\u8d4b\u503c\\n\", i); return *this; } ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; RAII &operator=(RAII &&) = delete; RAII(RAII const &) = delete; RAII &operator=(RAII const &) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u65b0\u624b\u5b9a\u4e49 RAII \u7c7b\u65f6\uff0c\u8bb0\u5f97\u628a\u79fb\u52a8\u548c\u62f7\u8d1d 4 \u4e2a\u51fd\u6570\u5168\u90e8\u5220\u9664\u3002\u6ca1\u9519\uff0c \u79fb\u52a8\u4e5f\u8981\u5220\u9664 \uff0c\u5f88\u591a\u65b0\u624b\u4f1a\u89c9\u5f97\u8d44\u6e90\u7c7b\u5e94\u8be5\u53ef\u4ee5\u79fb\u52a8\u7684\u5440\uff1f\u8981\u662f\u60f3\u4fdd\u7559\u79fb\u52a8\uff0c\u5c31\u5f97\u9884\u7559\u4e00\u4e2a i == 0 \u7684\u7a7a\u72b6\u6001\uff0c\u90a3\u79cd\u5904\u7406\u5f88\u590d\u6742\u7684\u3002\u603b\u4e4b\u4e00\u65e6\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5168\u90e8 4 \u4e2a\u51fd\u6570\u90fd\u5f97\u5220\u9664\uff0c\u9664\u975e\u4f60\u6709\u76f8\u5173\u7ecf\u9a8c\u3002\u53c2\u89c1 C++ \u751f\u547d\u5468\u671f\u4e0e\u6790\u6784\u51fd\u6570\u4e13\u9898 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u8fd9\u65f6\u5c31\u4f53\u73b0\u51fa try_emplace \u7684\u597d\u5904\u4e86\uff1a\u503c\u7c7b\u578b\u4e0d\u9700\u8981\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\u4e5f\u53ef\u4ee5\u63d2\u5165\u3002 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u5269\u4e0b 3 \u4e2a\uff0c\u8fd9\u662f\u56e0\u4e3a\u770b\u5230\u4f60\u7528\u4e86 && \u5c31\u77e5\u9053\u4f60\u662f\u61c2 C++11 \u7684\uff0c\u6240\u4ee5\u4e0d\u7528\u7167\u987e C++98 \u517c\u5bb9\u6027\u4fdd\u7559\u70e6\u4eba\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u5220\u4e86\uff0c\u8fd9\u662f\u4e2a\u6807\u51c6\uff0c\u6240\u6709 C++ \u7f16\u8bd1\u5668\u90fd\u662f\u8fd9\u6837\u7684\uff08\u8981\u6211\u8bf4\uff0c\u5efa\u8bae\u6539\u6210\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\u5c31\u81ea\u52a8\u5220\u5168 4 \u4e2a\u51fd\u6570\uff0c\u53ef\u60dc\u6807\u51c6\u59d4\u5458\u4f1a\u8981\u7167\u987e\u517c\u5bb9\u6027\u2026\uff09 \u4ee5\u540e RAII \u7c7b\u53ea\u9700\u8981\u4e00\u884c C(C &&) = delete \u5c31\u591f\u4e86\u3002 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u5982\u679c\u4f60\u60f3\u7528\u66f4\u53ef\u8bfb\u7684 insert\uff0cRAII \u8d44\u6e90\u7c7b\u53c8\u4e0d\u652f\u6301\u79fb\u52a8\uff0c\u53ef\u4ee5\u7528 unique_ptr \u5305\u88c5\u4e00\u4e0b\uff1a ```cpp int main() { { map> m; m.insert(\"\u8d44\u6e901\u53f7\", std::make_unique(1)); m.insert(\"\u8d44\u6e902\u53f7\", std::make_unique(2)); m.erase(\"\u8d44\u6e901\u53f7\"); m.insert(\"\u8d44\u6e903\u53f7\", std::make_unique(3)); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u5bf9\u4e8e\u5f88\u5927\u7684 V \u7c7b\u578b\uff0c\u4e5f\u53ef\u4ee5\u6539\u7528 map> \u907f\u514d\u53cd\u590d\u79fb\u52a8\u5143\u7d20\u672c\u4f53\u3002\uff08\u7528\u5728\u9700\u8981\u53cd\u590d\u6269\u5bb9\u7684 vector \u4e2d\u4e5f\u6709\u5947\u6548\uff09 \u56e0\u4e3a\u5305\u62ec map \u5728\u5185\u7684\u6240\u6709\u5bb9\u5668\u90fd\u5b8c\u7f8e\u652f\u6301 RAII \u7c7b\u578b\uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u7528\u667a\u80fd\u6307\u9488\u4f5c\u4e3a\u8fd9\u4e9b\u5bb9\u5668\u7684\u5143\u7d20\u3002 struct MyData { int value; // \u5047\u8bbe\u8fd9\u4e2a\u5f88\u5927 explicit MyData(int value_) : value(value_) {} }; map> m; m.insert({\"answer\", make_unique(42)}); // \u53ea\u6709 8 \u5b57\u8282\u7684 unique_ptr \u88ab\u79fb\u52a8 2 \u6b21 m.insert({\"fuck\", make_unique(985)}); print(m.at(\"answer\")->value); // 42 // \u2191\u7b49\u4ef7\u4e8e\uff1aprint((*m.at(\"answer\")).value); map> \u4e2d\uff0c\u667a\u80fd\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u91ca\u653e\u3002 map \u4e2d\uff0cC \u8bed\u8a00\u539f\u59cb\u6307\u9488\u4e0d\u5177\u5907 RAII \u529f\u80fd\uff0c\u9664\u975e\u8be5\u6307\u9488\u88ab\u5176\u4ed6\u667a\u80fd\u6307\u9488\u6253\u7406\u7740\uff0c\u6216\u8005\u7528\u6237\u5220\u9664\u5143\u7d20\u4e4b\u524d\u624b\u52a8 delete\uff0c\u5426\u5219\u5f53\u5143\u7d20\u5220\u9664\u65f6\u5185\u5b58\u4f1a\u6cc4\u9732\uff01 \u6211\u63a8\u8350\u5b8c\u5168\u91c7\u7528\u667a\u80fd\u6307\u9488\u6765\u81ea\u52a8\u7ba1\u7406\u5185\u5b58\uff0c\u667a\u80fd\u6307\u9488\u548c\u540c\u6837\u7b26\u5408 RAII \u601d\u60f3\u7684\u5404\u5927\u5bb9\u5668\u4e5f\u662f\u76f8\u6027\u5f88\u597d\u7684\u3002 \u5982\u679c\u9700\u8981\u6d45\u62f7\u8d1d\u7684\u8bdd\uff0c\u5219\u53ef\u4ee5\u6539\u7528 map> \uff0c\u5c0f\u5f6d\u8001\u5e08\u5728\u4ed6\u7684 Zeno \u9879\u76ee\u4e2d\u5c31\u662f\u8fd9\u6837\u7528\u7684\u3002 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.insert(make_pair(key, val)) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++98 \ud83d\udca9 m.insert({key, val}) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \u2764 m.emplace(key, val) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \ud83d\udca9 m.try_emplace(key, valargs...) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++17 \ud83d\udca3 m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 C++17 \u2764 m[key] = val \u63d2\u5165\u6216\u8986\u76d6 C++98 \ud83d\udca3 m.erase(key) \u5220\u9664\u6307\u5b9a\u5143\u7d20 C++98 \u2764 \u6539\u67e5 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.at(key) \u627e\u4e0d\u5230\u5219\u51fa\u9519\uff0c\u627e\u5230\u5219\u8fd4\u56de\u5f15\u7528 C++98 \u2764 m[key] \u627e\u4e0d\u5230\u5219\u81ea\u52a8\u521b\u5efa 0 \u503c\uff0c\u8fd4\u56de\u5f15\u7528 C++98 \ud83d\udca3 myutils::map_get(m, key, defl) \u627e\u4e0d\u5230\u5219\u8fd4\u56de\u9ed8\u8ba4\u503c C++98 \u2764 m.find(key) == m.end() \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \ud83d\udca3 m.count(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \u2764 m.contains(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++20 \ud83d\udca9 \u521d\u59cb\u5316 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 map m = {{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 auto m = map{{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \ud83d\udca9 func({{k1, v1}, {k2, v2}}) \u7ed9\u51fd\u6570\u53c2\u6570\u4f20\u5165\u4e00\u4e2a map C++11 \u2764 m = {{k1, v1}, {k2, v2}} \u91cd\u7f6e\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 m.clear() \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++98 \u2764 m = {} \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++11 \ud83d\udca3 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract C++17 \u65b0\u589e\u7684 extract \u51fd\u6570 1 \u53ef\u4ee5\u201c\u5265\u79bb\u201d\u51fa\u5355\u4e2a\u8282\u70b9\uff1a node_type extract(K const &key); node_type extract(const_iterator pos); auto node = m.extract(\"fuck\"); auto &k = node.key(); // \u952e\uff08\u5f15\u7528\uff09 auto &v = node.mapped(); // \u503c\uff08\u5f15\u7528\uff09 \u5176\u529f\u80fd\u4e0e erase \u7c7b\u4f3c\uff0c\u90fd\u4f1a\u5c06\u5143\u7d20\u4ece map \u4e2d\u5220\u9664\uff0c\u4f46 extract \u53ea\u662f\u628a\u8282\u70b9\u4ece map \u4e2d\u79fb\u8d70\uff0c\u5e76\u4e0d\u4f1a\u76f4\u63a5\u9500\u6bc1\u8282\u70b9\u3002 extract \u4f1a\u8fd4\u56de\u8fd9\u4e2a\u521a\u88ab\u201c\u5265\u79bb\u201d\u51fa\u6765\u8282\u70b9\u7684\u53e5\u67c4\uff0c\u7c7b\u578b\u4e3a node_type\uff0c\u8282\u70b9\u7684\u751f\u6740\u5927\u6743\u5c31\u8fd9\u6837\u8fd4\u56de\u7ed9\u4e86\u7528\u6237\u6765\u5904\u7f6e\u3002 node_type \u662f\u6307\u5411\u6e38\u79bb\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff0c\u79f0\u4e3a\u8282\u70b9\u53e5\u67c4 2 \u3002\u53ea\u53ef\u79fb\u52a8\u4e0d\u53ef\u62f7\u8d1d\uff0c\u7c7b\u4f3c\u4e00\u4e2a\u6307\u5411\u8282\u70b9\u7684 unique_ptr\u3002 \u5f53\u8c03\u7528 extract(key) \u65f6\u4f1a\u628a key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u7ea2\u9ed1\u6811\u8282\u70b9\u201c\u8131\u79bb\u201d\u51fa\u6765\u2014\u2014\u4e0d\u662f\u76f4\u63a5\u91ca\u653e\u8282\u70b9\u5185\u5b58\u5e76\u9500\u6bc1\u952e\u503c\u5bf9\u8c61\uff0c\u800c\u662f\u628a\u5220\u9664\u7684\u8282\u70b9\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u8c03\u7528\u8005\uff0c\u4ee5\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488 node_type \u7684\u5f62\u5f0f\u3002 \u8c03\u7528 extract \u540e\uff0c\u8282\u70b9\u53e5\u67c4\u6307\u5411\u7684\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u5df2\u7ecf\u4ece map \u4e2d\u79fb\u9664\uff08\u5176 left\u3001right\u3001parent \u7b49\u6307\u9488\u4e3a NULL\uff09\uff0c\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\u3002 \u8282\u70b9\u4e2d\u4e0d\u4ec5\u5b58\u50a8\u7740\u6211\u4eec\u611f\u5174\u8da3\u7684\u952e\u548c\u503c\uff0c\u8fd8\u6709 left\u3001right\u3001parent\u3001color \u7b49\u7528\u4e8e\u7ef4\u62a4\u6570\u636e\u7ed3\u6784\u7684\u6210\u5458\u53d8\u91cf\uff0c\u5bf9\u7528\u6237\u4e0d\u53ef\u89c1\u3002 \u53ea\u662f\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u7ef4\u6301\u7740\u8282\u70b9\u7684\u751f\u547d\u5468\u671f\uff0c\u4fdd\u62a4\u7740\u952e key() \u548c\u503c mapped() \u6ca1\u6709\u88ab\u9500\u6bc1\uff0c\u5185\u5b58\u6ca1\u6709\u88ab\u91ca\u653e\u3002 \u5982\u679c\u8c03\u7528\u8005\u63a5\u4e0b\u6765\u4e0d\u505a\u64cd\u4f5c\uff0c\u90a3\u4e48\u5f53\u79bb\u5f00\u8c03\u7528\u8005\u6240\u5728\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u8fd9\u4e2a\u7279\u6b8a\u7684 unique_ptr \u4f1a\u81ea\u52a8\u91ca\u653e\u5176\u6307\u5411\u8282\u70b9\u3002 \u5bf9\u4e8e\u7b2c\u4e00\u4e2a\u6309\u952e\u53d6\u51fa\u8282\u70b9\u53e5\u67c4\u7684 extract \u91cd\u8f7d\uff1a\u5982\u679c\u952e\u503c\u4e0d\u5b58\u5728\uff0c\u90a3\u4e48 extract \u4f1a\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u7684\u7a7a\u8282\u70b9\u53e5\u67c4\uff0c\u7c7b\u4f3c\u4e8e\u7a7a\u6307\u9488\u3002\u53ef\u4ee5\u901a\u8fc7 (bool)node \u6765\u5224\u65ad\u4e00\u4e2a\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u7a7a\u3002 \u5bf9\u4e8e\u7b2c\u4e8c\u4e2a\u6309\u8fed\u4ee3\u5668\u53d6\u51fa\u53e5\u67c4\u7684 extract\uff1a\u603b\u662f\u6210\u529f\uff0c\u56e0\u4e3a\u65e2\u7136\u4f60\u5df2\u7ecf\u83b7\u5f97\u4e86\u8fed\u4ee3\u5668\uff0c\u80af\u5b9a\u662f find \u83b7\u5f97\u7684\uff0c\u800c find \u627e\u4e0d\u5230\u8fd4\u56de\u7684 end \u4f20\u5165 extract \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u6b63\u5982 erase \u8fed\u4ee3\u5668\u7248\u91cd\u8f7d erase(it) \u603b\u662f\u6210\u529f\u4e00\u6837\u3002 \u7528\u9014\u4e3e\u4f8b \u8c03\u7528\u8005\u7a0d\u540e\u53ef\u4ee5\u76f4\u63a5\u9500\u6bc1\u8fd9\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff1a { auto node = m.extract(\"fuck\"); print(node.key(), node.mapped()); } // node \u5728\u6b64\u81ea\u52a8\u9500\u6bc1 \u4e5f\u53ef\u4ee5\u505a\u4e00\u4e9b\u4fee\u6539\u540e\uff08\u4f8b\u5982\u4fee\u6539\u952e\u503c\uff09\uff0c\u7a0d\u540e\u91cd\u65b0\u7528 insert(node) \u91cd\u65b0\u628a\u4ed6\u63d2\u5165\u56de\u53bb\uff1a auto node = m.extract(\"fuck\"); node.key() = \"love\"; m.insert(std::move(node)); \u8fc7\u53bb\uff0c\u901a\u8fc7\u8fed\u4ee3\u5668\u6765\u4fee\u6539\u952e\u503c\u662f\u4e0d\u5141\u8bb8\u7684\uff1a map m; auto it = m.find(\"fuck\"); assert(it != m.end()); // *it \u662f pair it->first = \"love\"; // \u9519\u8bef\uff01first \u662f const string \u7c7b\u578b m.insert(*it); \u56e0\u4e3a\u76f4\u63a5\u4fee\u6539\u5728 map \u91cc\u9762\u7684\u4e00\u4e2a\u8282\u70b9\u7684\u952e\uff0c\u4f1a\u5bfc\u81f4\u6392\u5e8f\u5931\u6548\uff0c\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u3002\u800c extract \u53d6\u51fa\u6765\u7684\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u53ef\u4ee5\u4fee\u6539 .key() \uff0c\u4e0d\u4f1a\u5f71\u54cd\u4efb\u4f55\u7ea2\u9ed1\u6811\u7684\u987a\u5e8f\uff0c\u4ed6\u5df2\u7ecf\u4e0d\u5728\u6811\u91cc\u9762\u4e86\u3002 \u6216\u8005\u63d2\u5165\u5230\u53e6\u4e00\u4e2a\u4e0d\u540c\u7684 map \u5bf9\u8c61\uff08\u4f46\u952e\u548c\u503c\u7c7b\u578b\u76f8\u540c\uff09\u91cc\uff1a // \u4ece m1 \u632a\u5230 m2 auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); \u4f18\u70b9\u5728\u4e8e\uff0cextract \u548c\u8282\u70b9\u7248 insert \u4e0d\u6d89\u53ca\u5185\u5b58\u7684\u91cd\u65b0\u5206\u914d\u4e0e\u91ca\u653e\uff0c\u4e0d\u6d89\u53ca\u5143\u7d20\u7c7b\u578b\u7684\u79fb\u52a8\uff08\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e\u667a\u80fd\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u7684\u79fb\u52a8\u5e76\u4e0d\u4f1a\u5bfc\u81f4\u5176\u6307\u5411\u5bf9\u8c61\u7684\u79fb\u52a8\uff09\uff0c\u6240\u4ee5\u4f1a\u6bd4\u4e0b\u9762\u8fd9\u79cd\u4f20\u7edf\u5199\u6cd5\u66f4\u9ad8\u6548\uff1a // \u4ece m1 \u632a\u5230 m2\uff1a\u4f20\u7edf\u5199\u6cd5 if (m1.count(\"fuck\")) { auto value = std::move(m1.at(\"fuck\")); m2[\"fuck\"] = std::move(value); m1.erase(it); } \u4e0d\u7528 auto \u5b8c\u6574\u5199\u51fa\u5168\u90e8\u7c7b\u578b\u7684\u5f62\u5f0f\uff08\u53e4\u4ee3 C++98 \u4f5c\u98ce\uff09\uff1a typename map::node_type node = m.extract(\"fuck\"); K &k = node.key(); V &v = node.mapped(); set \u4e5f\u6709 extract \u51fd\u6570\uff0c\u5176\u8282\u70b9\u53e5\u67c4\u6ca1\u6709 key() \u548c mapped() \u4e86\uff0c\u800c\u662f\u53ea\u6709\u4e00\u4e2a value()\uff0c\u83b7\u53d6\u5176\u4e2d\u7684\u503c set s = {\"fuck\", \"suck\", \"dick\"}; set::node_type node = s.extract(\"fuck\"); V &v = node.value(); insert \u8282\u70b9\u7248 insert \u51fd\u6570\uff1a\u63d2\u5165\u6e38\u79bb\u8282\u70b9\u7684\u7248\u672c insert_return_type insert(node_type &&node); iterator insert(const_iterator pos, node_type &&node); // \u5e26\u63d0\u793a\u7684\u7248\u672c \u53ef\u4ee5\u7528 insert(move(node)) \u76f4\u63a5\u63d2\u5165\u4e00\u4e2a\u8282\u70b9\u3002 map m1 = { {\"fuck\", 985}, {\"dick\", 211}, }; map m2; auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); // \u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u4e0d\u53ef\u62f7\u8d1d\uff0c\u9700\u8981\u7528\u79fb\u52a8\u8bed\u4e49\u8fdb\u884c\u63d2\u5165 \u8c03\u7528 insert(move(node)) \u540e\u7531\u4e8e\u6240\u6709\u6743\u88ab\u79fb\u8d70\uff0cnode \u5c06\u4f1a\u5904\u4e8e\u201c\u7a7a\u6307\u9488\u201d\u72b6\u6001\uff0c\u53ef\u4ee5\u7528 node.empty() \u67e5\u8be2\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u201c\u7a7a\u201d\u72b6\u6001\uff0c\u5373\u8282\u70b9\u6240\u6709\u6743\u662f\u5426\u5df2\u7ecf\u79fb\u8d70\u3002 insert_return_type \u8fd9\u4e2a\u7248\u672c\u7684 insert \u8fd4\u56de\u503c\u7c7b\u578b insert_return_type \u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff08\u6211\u7684\u5929\u4ed6\u4eec\u7ec8\u4e8e\u80af\u7528\u7ed3\u6784\u4f53\u800c\u4e0d\u662f pair \u4e86\uff09\uff1a struct insert_return_type { iterator position; bool inserted; node_type node; }; insert_return_type insert(node_type &&nh); \u5b98\u65b9\u8bf4\u6cd5\u662f 1 \uff1a If nh is empty, inserted is false, position is end(), and node is empty. Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty. If the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key(). extract + insert \u8fd0\u7528\u6848\u4f8b map hells = { {666, \"devil\"}, }; map schools = { {985, \"professor\"}, {211, \"doctor\"}, {996, \"fucker\"}, }; auto node = schools.extract(996); hells.insert(std::move(node)); print(schools); print(hells); {211: \"doctor\", 985: \"professor\"} {666: \"devil\", 996: \"fucker\"} extract + insert(move(node)) \u5bf9\u6bd4 find + insert({key, val})\uff0c\u53ef\u4ee5\u907f\u514d\u952e\u548c\u503c\u7c7b\u578b\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u5f00\u9500\uff0c\u81f3\u59cb\u81f3\u7ec8\u79fb\u52a8\u7684\u53ea\u662f\u4e00\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u6307\u9488\uff0c\u5143\u7d20\u6ca1\u6709\u88ab\u79fb\u52a8\uff0c\u4e5f\u6ca1\u6709\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u4e0d\u5fc5\u8981\u7684\u5206\u914d\u548c\u91ca\u653e\u3002 \u4f46\u662f insert(move(node)) \u4ec5\u9002\u7528\u4e8e\u4ece extract \u4e2d\u53d6\u51fa\u73b0\u6709\u8282\u70b9\u7684\u60c5\u51b5\uff0c\u5982\u679c\u8981\u65b0\u5efa\u8282\u70b9\u8fd8\u5f97\u9760 insert({key, val}) \u6216\u8005 try_emplace(key, val) \u7684\u3002 extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u5df2\u77e5\u4e24\u4e2a\u6620\u5c04\u8868 tab1 \u548c tab2\uff0c\u548c\u4e00\u4e2a\u63a5\u53d7 K \u7c7b\u578b\u505a\u53c2\u6570\u7684\u4eff\u51fd\u6570 cond\u3002 \u8981\u6c42\u628a tab1 \u4e2d\u952e\u7b26\u5408 cond \u6761\u4ef6\u7684\u5143\u7d20\u79fb\u52a8\u5230 tab2 \u4e2d\u53bb\uff0c\u5176\u4f59\u4fdd\u7559\u5728 tab1 \u4e2d\u3002 \u6211\u4eec\u7f16\u5199\u56db\u4efd\u540c\u6837\u529f\u80fd\u7684\u7a0b\u5e8f\uff0c\u5206\u522b\u91c7\u7528\uff1a extract + \u5e26\u63d0\u793a\u7684 insert erase + \u5e26\u63d0\u793a\u7684 insert extract + \u76f4\u63a5 insert erase + \u76f4\u63a5 insert template void filter_with_extract(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); tab2.insert(std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); tab2.insert(std::move(kv)); } else ++it; } } template void filter_with_extract_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); hint = tab2.insert(hint, std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); hint = tab2.insert(hint, std::move(kv)); } else ++it; } } extract vs erase \u6027\u80fd\u6d4b\u8bd5\u7ed3\u679c (testextractvserase.cpp)\uff1a avg | min | max | total | cnt | tag 889| 803| 2388| 889271| 1000| filter_with_erase 642| 595| 1238| 642542| 1000| filter_with_extract 525| 491| 1398| 525137| 1000| filter_with_erase_with_hint 305| 289| 842| 305472| 1000| filter_with_extract_with_hint extract + \u5e26\u63d0\u793a\u7684 insert \u83b7\u80dc\uff0c\u5373\u51fd\u6570 filter_with_extract_with_hint \u662f\u6027\u80fd\u6700\u597d\u7684\u90a3\u4e00\u4e2a\u3002 \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u7531\u4e8e\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\uff0c\u6e38\u79bb\u8282\u70b9\u4e0d\u5c5e\u4e8e\u4efb\u4f55 map \u4e2d\uff0c\u4e0d\u9700\u8981\u6ee1\u8db3\u6392\u5e8f\u6027\u8d28\uff0c\u56e0\u6b64 node.key() \u53ef\u4fee\u6539\u3002 \u5148\u7528 extract \u53d6\u51fa\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u4fee\u6539\u5b8c\u8282\u70b9\u7684\u952e\u540e\u518d\u91cd\u65b0\u63d2\u5165\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u505a\u5230\u4ee5\u524d\u505a\u4e0d\u5230\u7684\u4fee\u6539\u952e\u503c\u3002 map m = { {\"fuck\", 985}, }; auto node = m.extract(\"fuck\"); // \u79fb\u51fa \"fuck\" \u952e\u5bf9\u5e94\u7684\u8282\u70b9\uff0c\u6b64\u65f6 m \u4f1a\u53d8\u4e3a\u7a7a node.key() = \"fxxk\"; // \u4fee\u6539\u952e\uff08\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->first \u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u952e\u7684\uff0c\u56e0\u4e3a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u8282\u70b9\u4e0d\u662f\u6e38\u79bb\u72b6\u6001\uff0c\u4fee\u6539\u952e\u4f1a\u7834\u574f\u6392\u5e8f\uff09 node.mapped() = 211; // \u4fee\u6539\u503c\uff08\u8fd9\u4e2a\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->second \u4e5f\u53ef\u4ee5\u4fee\u6539\uff09 m.insert(move(node)); // \u628a\u4fee\u6539\u597d\u7684\u8282\u70b9\u63d2\u5165\u56de\u53bb print(m); // {{\"fxxk\": 211}} \u76f8\u5f53\u4e8e\u4f60\u7ed9\u5c0f\u5b66\u751f\u6392\u961f\u65f6\uff0c\u6709\u4e00\u4e2a\u5c0f\u5b66\u751f\u7a81\u7136\u77ac\u95f4\u4e0d\u77e5\u9053\u5403\u4e86\u4ec0\u4e48\u6fc0\u7d20\u957f\u9ad8\u4e86\uff0c\u4f60\u7684\u961f\u4f0d\u5c31\u4f1a\u4e71\u6389\u3002 \u6240\u4ee5\u9700\u8981\u8ba9\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5148\u51fa\u5217\uff0c\u8ba9\u4ed6\u5355\u72ec\u4e00\u4e2a\u4eba\u957f\u9ad8\uff0c\u7b49\u4ed6\u957f\u9ad8\u5b8c\u4e86\u518d\u63d2\u5165\u56de\u961f\u5217\u3002 \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert \u4f46\u662f\u5c0f\u5b66\u751f\u957f\u9ad8\u7684\u91cf\u53ef\u80fd\u662f\u6709\u9650\u7684\uff08\u65b0\u7684\u952e\u53ef\u80fd\u548c\u8001\u952e\u5f88\u63a5\u8fd1\uff09\u3002 \u8fd9\u65f6\u63d2\u5165\u53ef\u4ee5\u4f18\u5148\u4ece\u4ed6\u957f\u9ad8\u4e4b\u524d\u7684\u4f4d\u7f6e\u5f00\u59cb\u4e8c\u5206\u6cd5\uff0c\u4e5f\u5c31\u662f\u7528 extract \u4e4b\u524d\uff0c\u8fd9\u4e2a\u5c0f\u5b66\u751f\u540e\u4e00\u4f4d\u540c\u5b66\u7684\u4f4d\u7f6e\uff0c\u4f5c\u4e3a insert \u7684\u63d0\u793a\uff0c\u8ba9 insert \u66f4\u5feb\u5b9a\u4f4d\u5230\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5e94\u8be5\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 auto it = m.find(\"fuck\"); assert(it != m.end()); // \u5047\u5b9a \"fuck\" \u5fc5\u987b\u5b58\u5728\uff08\u5982\u679c\u4e0d\u5b58\u5728\u4f1a\u8fd4\u56de end\uff09 auto next_it = std::next(it); // \u4e0b\u4e00\u4f4d\u540c\u5b66\uff08\u53ef\u80fd\u4f1a\u5f97\u5230 end\uff0c\u4f46\u6ca1\u5173\u7cfb\uff0c\u56e0\u4e3a insert \u7684\u63d0\u793a\u4e5f\u5141\u8bb8\u4e3a end \u8fed\u4ee3\u5668\uff09 auto node = m.extract(it); node.key() = \"fxxk\"; // \u4fee\u6539\u952e\u503c\uff0c\u53d8\u5316\u4e0d\u5927 m.insert(next_it, move(node)); // \u5982\u679c\u952e\u503c\u53d8\u52a8\u4e0d\u5927\uff0c\u4f18\u5148\u5c1d\u8bd5\u5728\u8001\u4f4d\u7f6e\u63d2\u5165 \u8fd9\u91cc\u7684 std::next(it) \u5bf9\u4e8e\u7b49\u4ef7\u4e8e it + 1\u3002\u4f46\u662f map \u5c5e\u4e8e\u53cc\u5411\u8fed\u4ee3\u5668\uff08\u800c\u4e0d\u662f\u968f\u673a\u8fed\u4ee3\u5668\uff09\uff0c\u4e0d\u652f\u6301\u52a0\u6cd5\u64cd\u4f5c\uff0c\u53ea\u652f\u6301\u5c31\u5730 ++\u3002\u6240\u4ee5 std::next \u5185\u90e8\u7b49\u4ef7\u4e8e\uff1a auto next(auto it) { auto next_it = it; // \u5148\u62f7\u8d1d\u4e00\u4efd\uff0c\u9632\u6b62\u539f\u8fed\u4ee3\u5668\u88ab\u7834\u574f\uff08\u8fed\u4ee3\u5668\u90fd\u652f\u6301\u62f7\u8d1d\uff0c\u6027\u8d28\u4e0a\u662f\u6d45\u62f7\u8d1d\uff09 ++next_it; // \u518d\u8ba9 next_it \u5c31\u5730\u81ea\u589e\u5230\u4e0b\u4e00\u4f4d return next_it; // \u8fd4\u56de\u73b0\u5728\u5df2\u7ecf\u76f8\u5f53\u4e8e it + 1 \u7684 next_it } \u5982\u679c\u952e\u4e0d\u53d8\uff0c\u6216\u8005\u952e\u53d8\u4e86\u4ee5\u540e\uff0c\u63d2\u5165\u4f4d\u7f6e\u4e0d\u53d8\u7684\u8bdd\uff0c\u90a3\u4e48\u8fd9\u6b21 insert \u53ef\u4ee5\u4f4e\u81f3 O(1) O(1) \u590d\u6742\u5ea6\u3002 map m = { {\"dick\", 211}, {\"fuck\", 985}, // \"fuck\" -> \"fxxk\" \u540e\uff0c\u91cd\u65b0\u63d2\u5165\uff0c\u5176\u4f9d\u5b57\u5178\u5e8f\u7684\u201c\u5927\u5c0f\u201d\u4f9d\u7136\u662f\u4ecb\u4e8e \"dick\" \u548c \"suck\" {\"suck\", 996}, }; merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 C++17 \u65b0\u589e\u7684 merge \u51fd\u6570 1 template void merge(map &__source); \u6ce8\uff1aset \u4e5f\u6709 merge \u51fd\u6570 \u6ce8\u610f\u5230 merge \u7684\u53c2\u6570\u662f\u53e6\u4e00\u4e2a map\uff0c\u53ef\u53d8\u5f15\u7528\uff0c\u5fc5\u987b\u548c\u672c map \u540c\u7c7b\u578b\uff08\u8fd9\u662f\u4e3a\u4e86\u4fdd\u8bc1\u8282\u70b9\u53e5\u67c4\u7c7b\u578b\u76f8\u540c\uff09\uff0c\u4f46\u5141\u8bb8\u6709\u4e0d\u540c\u7684\u6bd4\u8f83\u51fd\u6570 merge(source) \u4f1a\u628a source \u4e2d\u7684\u6240\u6709\u8282\u70b9\u90fd \u79fb\u52a8 \u5e76\u5408\u5e76\u5230\u672c map\uff0c\u6ce8\u610f\u662f \u79fb\u52a8 \u800c\u4e0d\u662f\u62f7\u8d1d\uff0csource \u5c06\u4f1a\u88ab\u6e05\u7a7a\uff0c\u8fd9\u6837\u662f\u4e3a\u4e86\u66f4\u9ad8\u6548\u3002 insert(source.begin(), source.end()) \u5219\u662f\u628a source \u91cc\u7684\u5143\u7d20\u62f7\u8d1d\u540e\u63d2\u5165\u5230\u672c map\uff0c\u66f4\u4f4e\u6548\uff0c\u56e0\u4e3a\u9700\u8981\u62f7\u8d1d\uff0c\u8fd8\u5f97\u65b0\u5efa\u7ea2\u9ed1\u6811\u8282\u70b9\uff0c\u989d\u5916\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 \u5bf9\u4e8e\u952e\u5b58\u5728\u51b2\u7a81\u7684\u60c5\u51b5\uff1a merge: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u79fb\u52a8\uff0c\u4fdd\u7559\u5728 source \u91cc\u3002 insert: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u63d2\u5165\u672c map\u3002\u65e0\u8bba\u6709\u6ca1\u6709\u63d2\u5165\u672c map\uff0c\u539f source \u4e2d\u7684\u952e\u90fd\u4e0d\u4f1a\u88ab\u6e05\u9664\u3002 \u56e0\u6b64\uff0cmerge \u4e5f\u5e76\u4e0d\u603b\u662f\u5b8c\u5168\u6e05\u7a7a source\uff0c\u5f53 source \u548c\u672c map \u6709\u51b2\u7a81\u65f6\uff0c\u51b2\u7a81\u7684\u952e\u5c31\u4fdd\u7559\u5728 source \u91cc\u4e86\u3002 merge \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u624b\u52a8\u7528 extract \u548c insert \u6765\u79fb\u52a8\u8282\u70b9\u7684\u4ee3\u7801\uff1a // m1.merge(m2) \u7b49\u4ef7\u4e8e\uff1a auto hint = m1.begin(); for (auto it = m2.begin(); it != m2.end(); ++it) { if (!m1.contains(it->first)) { auto node = m2.extract(it); hint = m1.insert(hint, node); } } \u6279\u91cf insert vs merge \u540c\u6837\u505a\u5230\u4e24\u4e2a map \u5408\u5e76\uff0c m1.merge(m2) \u4e0e m1.insert(m2.begin(), m2.end()) \u6027\u80fd\u6bd4\u8f83\uff1a #include #include #include \"benchmark/benchmark.h\" using namespace std; static void BM_Insert(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.insert(m1.begin(), m1.end()); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Insert)->Arg(1000); static void BM_Merge(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.merge(m1); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Merge)->Arg(1000); merge \u51fd\u6570\u4e0d\u4f1a\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u5185\u5b58\u5206\u914d\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u6240\u4ee5\u66f4\u9ad8\u6548\u3002\u4f46\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u4ed6\u4f1a\u6e05\u7a7a m2\uff01 merge \u76f8\u5f53\u4e8e\u628a m2 \u7684\u5143\u7d20\u201c\u79fb\u52a8\u201d\u5230 m1 \u4e2d\u53bb\u4e86\u3002 insert \u5219\u662f\u628a m2 \u7684\u5143\u7d20\u201c\u62f7\u8d1d\u201d\u4e86\u4e00\u4efd\u63d2\u5165\u5230 m1 \u4e2d\u53bb\uff0c\u6548\u7387\u81ea\u7136\u4f4e\u4e0b\u3002 \u5982\u679c\u4e0d\u60f3\u7834\u574f\u6389 m2\uff0c\u6216\u8005\u4f60\u7528\u4e0d\u4e0a C++17\uff0c\u5219\u4ecd\u9700\u8981\u4f20\u7edf\u7684 insert\u3002 merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c merge(m2) \u548c insert(m2.begin(), m2.end()) \u4e00\u6837\u5c3f\u6027\uff1a\u5982\u679c m2 \u4e2d\u7684\u952e\u5728 m1 \u4e2d\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4e0d\u4f1a extract \u8be5 m2 \u4e2d\u7684\u8282\u70b9\uff0c\u4ecd\u7136\u7559\u5728 m2 \u4e2d\u3002 int main() { std::map ma {{1, \"apple\"}, {5, \"pear\"}, {10, \"banana\"}}; std::map mb {{2, \"zorro\"}, {4, \"batman\"}, {5, \"X\"}, {8, \"alpaca\"}}; std::map u; u.merge(ma); std::cout << \"ma.size(): \" << ma.size() << '\\n'; u.merge(mb); std::cout << \"mb.size(): \" << mb.size() << '\\n'; std::cout << \"mb.at(5): \" << mb.at(5) << '\\n'; for(auto const &kv: u) std::cout << kv.first << \", \" << kv.second << '\\n'; } map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 map \u5bb9\u5668\u7684\u5168\u90e8\u53c2\u6570\u4e3a\uff1a std::map \u5176\u4e2d\u7b2c 3\u30014 \u4e2a\u53c2\u6570 Cmp \u548c Alloc \u53ef\u4ee5\u7701\u7565\u3002 Cmp \u9ed8\u8ba4\u4e3a std::less Alloc \u9ed8\u8ba4\u4e3a std::allocator> \u56e0\u6b64 map \u7684\u5b8c\u6574\u6a21\u677f\u53c2\u6570\u662f\uff1a std::map, std::allocator>> \u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 map \u3002 \u5176\u4e2d allocator \u6211\u4eec\u4ee5\u540e\u4e13\u95e8\u5f00\u4e00\u8282\u8bfe\u8bb2\uff0c\u5176\u4ed6\u5f88\u591a\u5bb9\u5668\u90fd\u6709 allocator\u3002 \u4eca\u5929\u53ea\u7814\u7a76 Cmp \u8fd9\u4e2a\u53c2\u6570\uff0c\u4ed6\u51b3\u5b9a\u4e86 map \u5982\u4f55\u6392\u5e8f\uff0c\u5224\u65ad\u76f8\u7b49\u3002 std::map> \u8fd9\u4e2a std::less \u662f\u4e2a\u4ec0\u4e48\u5462\uff1f\u662f\u4e00\u4e2a\u4eff\u51fd\u6570(functor)\u3002 template struct less { constexpr bool operator()(T const &x, T const &y) const { return x < y; } }; \u5177\u6709\u6210\u5458\u51fd\u6570 operator() \u7684\u7c7b\u578b\uff0c\u90fd\u88ab\u79f0\u4e4b\u4e3a\u4eff\u51fd\u6570\u3002 std::less \u7684\u4f5c\u7528 \u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u5706\u62ec\u53f7\u5f53\u505a\u666e\u901a\u51fd\u6570\u8c03\u7528\uff0c\u8fd9\u5c31\u662f\u201c\u4eff\u51fd\u6570\u201d\u7684\u5f97\u540d\u539f\u56e0\uff0c\u4f8b\u5982\uff1a less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true operator() \u6ce8\u610f\u4eff\u51fd\u6570\u7684\u6210\u5458\u51fd\u6570 operator() \u662f\u4e24\u4e2a\u62ec\u53f7\uff1a operator()(...) \u7b2c\u4e00\u4e2a\u62ec\u53f7\u662f operator() \u7684\u4e00\u90e8\u5206\uff0c\u8868\u793a\u8fd9\u662f\u5bf9\u5706\u62ec\u53f7 () \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u7b2c\u4e8c\u4e2a\u62ec\u53f7\u662f\u51fd\u6570\u7684\u53c2\u6570\u5217\u8868\uff0c\u91cc\u9762\u662f operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u5f62\u53c2\u3002 operator() \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __call__ \u3002\u6b63\u5982 operator< \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __lt__ \u3002\u8fd9\u91cc operator \u548c () \u662f\u4e00\u4e2a\u6574\u4f53\uff0c\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e86\u4e00\u4e2a\u6807\u8bc6\u7b26\u3002 \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f std::map> \u6211\u4eec\u4e4b\u524d\u63d0\u5230 map \u5185\u90e8\u7684\u5143\u7d20\u59cb\u7ec8\u6309\u7167\u952e K \u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002 map \u51b3\u5b9a\u5927\u5c0f\u987a\u5e8f\u7684\uff0c\u5e76\u4e0d\u662f\u76f4\u63a5\u8c03\u7528 K \u7c7b\u578b\u7684\u6bd4\u8f83\u8fd0\u7b97\u7b26 operator< \u3002 \u800c\u662f\u8c03\u7528\u4ed6\u7684\u6a21\u677f\u53c2\u6570 Cmp \u7c7b\u578b\u7684 operator() \u3002 \u8fd9\u662f\u4e3a\u4e86\u5141\u8bb8\u7528\u6237\u901a\u8fc7\u4fee\u6539\u8fd9\u4e2a\u53c2\u6570\uff0c\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\uff0c\u9632\u6b62 map \u6570\u636e\u7ed3\u6784\u4e0e\u5177\u4f53\u7684\u6bd4\u8f83\u65b9\u6cd5\u8026\u5408\u3002 \u7531\u4e8e\u9ed8\u8ba4\u7684 Cmp \u662f less \uff0c\u8c03\u7528 Cmp()(x, y) \u5c31\u76f8\u5f53\u4e8e x < y \uff0c\u7531\u6b64\u5b9e\u73b0\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002 \u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u4fee\u6539\u8fd9\u4e00\u9ed8\u8ba4\u884c\u4e3a\u3002 \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u4e00\u4e2a\u7c7b\u578b\u8981\u60f3\u4f5c\u4e3a map \u7684\u952e\uff0c\u53ea\u9700\u8981\u4ed6\u652f\u6301 < \u8fd0\u7b97\u7b26\u5373\u53ef\uff0c\u4e0d\u5fc5\u5b9a\u4e49\u5176\u4ed6 > \u3001 == \u8fd0\u7b97\u7b26\u3002 \u5f53 map \u9700\u8981\u5224\u65ad\u4e24\u4e2a\u952e\u662f\u5426\u76f8\u7b49\u65f6 x == y \uff0c\u4f1a\u7528 !(x < y) && !(y < x) \u6765\u7b49\u4ef7\u5730\u8ba1\u7b97\u3002 string, string_view, int, float, void *, shared_ptr, pair, tuple, array\u2026 \u8fd9\u4e9b\u7c7b\u578b\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u90fd\u53ef\u4ee5\u4f5c\u4e3a map \u7684\u952e\u3002 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u5982\u679c\u4f60\u5199\u4e86\u4e2a\u81ea\u5b9a\u4e49\u7c7b Student\uff0c\u8981\u8ba9\u4ed6\u4f5c\u4e3a map \u7684\u952e\u7c7b\u578b\uff0c\u6709\u4e09\u79cd\u65b9\u6cd5\uff1a \u4e00\u3001\u5728 Student \u7c7b\u4e2d\u6dfb\u52a0 operator< struct Student { string name; int id; string sex; bool operator<(Student const &that) const { return x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))); // \u7b49\u4ef7\u4e8e\uff1a return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); // tuple \u5b9e\u73b0\u4e86\u6b63\u786e\u7684 operator< \u8fd0\u7b97\u7b26 } }; map stutab; \u4e8c\u3001\u7279\u5316 less \uff0c\u6dfb\u52a0 operator() struct Student { string name; int id; string sex; }; template <> struct std::less { // \u7528\u6237\u53ef\u4ee5\u7279\u5316\u6807\u51c6\u5e93\u4e2d\u7684 trait bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u5982\u679c map \u5916\u9762\u8981\u7528\u7528\u5230\u8fd9\u4e2a\u7c7b\u7684\u5927\u5c0f\u6bd4\u8f83\uff0c\u4e5f\u53ea\u80fd\u7528 less()(stu1, stu2) \u4ee3\u66ff stu1 < stu2 \u3002 \u4e09\u3001\u91cd\u65b0\u81ea\u5b9a\u4e49\u4e00\u4e2a\u4eff\u51fd\u6570\u7c7b LessStudent \uff0c\u6dfb\u52a0 operator() \uff0c\u7136\u540e\u628a\u8fd9\u4e2a LessStudent \u4f5c\u4e3a map \u7684\u6bd4\u8f83\u5668\u4f20\u5165\u6a21\u677f struct Student { string name; int id; string sex; }; struct LessStudent { bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u6bcf\u6b21\u521b\u5efa\u65b0\u7684 map \u65f6\uff0c\u90fd\u9700\u8981\u52a0\u4e00\u4e2a LessStudent \u53c2\u6570\u3002 \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 \u5982\u679c\u5e0c\u671b map \u5728\u67e5\u627e\u65f6\u53ea\u6839\u636e\u5b66\u751f\u59d3\u540d\u7d22\u5f15\uff0c\u5219\u53ea\u9700\u8981\u6539\u4e00\u4e0b\u6bd4\u8f83\u5668\u7684\u5b9e\u73b0\uff0c\u8ba9\u4ed6\u53ea\u6bd4\u8f83\u59d3\u540d\u5b57\u6bb5\u5373\u53ef\u3002 struct LessStudent { bool operator()(Student const &x, Student const &y) const { return x.name < y.name; } }; \u4e0a\u9762\u8fd9\u6837\u7684\u6bd4\u8f83\u5668\uff0cmap \u4f1a\u8ba4\u4e3a\u59d3\u540d name \u76f8\u540c\u7684 Student \u5c31\u662f\u76f8\u7b49\u7684\uff0c\u5e76\u53bb\u91cd\u3002\u5373\u4f7f id \u548c sex \u4e0d\u540c\uff0c\u53ea\u8981\u540d\u5b57\u76f8\u7b49\u5c31\u4f1a\u89c6\u4e3a\u91cd\u590d\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u9488\u5bf9\u7279\u5b9a\u5b57\u6bb5\u7684\u53bb\u91cd\u3002 \u7ed3\u8bba\uff1amap \u7684\u6392\u5e8f\u548c\u53bb\u91cd\uff0c\u90fd\u53d6\u51b3\u4e8e\u4e8e\u4f60\u7684\u6bd4\u8f83\u5668\u5982\u4f55\u5b9e\u73b0\uff01\u6bd4\u8f83\u5668\u91cc\u6ca1\u6bd4\u8f83\u7684\u5b57\u6bb5\uff0c\u5c31\u4f1a\u88ab\u5ffd\u7565\u800c\u4e0d\u53c2\u4e0e\u6392\u5e8f\u3001\u7d22\u5f15\u3001\u548c\u53bb\u91cd\u3002 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u56db\uff08\u540c\u4e00\uff09\u3001\u5229\u7528 C++20 \u65b0\u7279\u6027\uff0c\u4e09\u8def\u6bd4\u8f83\u8fd0\u7b97\u7b26 <=> \uff1a\u5982\u679c\u81ea\u5b9a\u4e49\u7c7b\u7684\u6bcf\u4e2a\u6210\u5458\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u53ef\u4ee5\u628a operator<=> \u51fd\u6570\u58f0\u660e\u4e3a default \uff0c\u7136\u540e\u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u6dfb\u52a0\u81ea\u5b9a\u4e49\u7c7b\u7684\u6240\u6709\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 struct Student { string name; int id; string sex; auto operator<=>(Student const &) const = default; }; \u6b64\u65f6\u9ed8\u8ba4\u7684 operator< \u5b9e\u73b0\u7b49\u4ef7\u4e8e x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))) \u3002 <=> \u7684\u8fd4\u56de\u7c7b\u578b\u662f std::strong_ordering \uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u4e09\u79cd\u53d6\u503c\u7684\u5f3a\u679a\u4e3e\u7c7b\u578b <=> \u5bf9\u5e94\u7684\u4eff\u51fd\u6570\u4e3a std::compare_three_way \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 libstdc++ \u5934\u6587\u4ef6\u4e2d\u7684 less \u548c greater \u5b9e\u73b0\u53c2\u8003\uff1a template struct less : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template struct greater : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; \u7c7b\u4f3c\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u8fd8\u6709\uff1a \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b x == y std::equal_to x != y std::not_equal_to x < y std::less x > y std::greater x <= y std::less_equal x >= y std::greater_equal x + y std::plus x - y std::minus x * y std::multiplies x / y std::divides x % y std::modulus -x std::negate \u4ed6\u4eec\u90fd\u5728 #include \u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u3002 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u6848\u4f8b\uff1a\u4f7f\u7528 greater \u4eff\u51fd\u6570\uff0c\u8ba9 map \u53cd\u8fc7\u6765\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\uff1a auto ilist = { {985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}, }; map m1 = ilist; // \u4ece\u5c0f\u5230\u5927\u6392\u5e8f map> m2 = ilist; // \u4ece\u5927\u5230\u5c0f\u6392\u5e8f print(m1); // {{211, \"\u811a\u8e22\"}, {985, \"\u62f3\u6253\"}} print(m2); // {{985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}} \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u81ea\u5b9a\u4e49\u6bd4\u8f83\u4eff\u51fd\u6570\uff0c\u5b9e\u73b0\u65e0\u89c6\u952e\u5927\u5c0f\u5199\u7684 map \u5bb9\u5668\uff1a struct LessIgnoreCase { bool operator()(std::string const &lhs, std::string const &rhs) const { return std::lexicographical_compare // \u4f4d\u4e8e \u5934\u6587\u4ef6\uff0c\u548c std::string \u540c\u6b3e\u7684\u5b57\u5178\u5e8f\u6bd4\u8f83 ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); } }; int main() { map m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"STUdy\"}, \"cpp\"}, {{\"stUDy\"}, \"js\"}, }; print(m); print(\"fuck\u5bf9\u5e94\u7684\u503c\u4e3a:\", m.at(\"fuck\")); return 0; } {\"Fuck\": \"rust\", \"STUdy\": \"cpp\"} fuck\u5bf9\u5e94\u7684\u503c\u4e3a: \"rust\" \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 C++11 \u7684 lambda \u8868\u8fbe\u5f0f\u4e5f\u662f\u4eff\u51fd\u6570\uff0c\u914d\u5408 decltype \u540e\u5c31\u53ef\u4ee5\u4f20\u5165 map \u4f5c\u4e3a\u6bd4\u8f83\u5668\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m({ {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }, cmp); print(m); auto val = m.at({\"fuck\"}); print(val); \u5199\u7684\u66f4\u6e05\u6670\u4e00\u70b9\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m(cmp); m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }; print(m); auto val = m.at({\"fuck\"}); print(val); map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u521a\u521a\u7528\u5230\u7684\u4e24\u4e2a map \u6784\u9020\u51fd\u6570\uff1a template > class map { explicit map(Cmp cmp); map(initializer_list> ilist, Cmp cmp); }; \u57fa\u672c\u6bcf\u4e2a map \u7684\u6784\u9020\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u63d0\u4f9b\u989d\u5916 cmp \u53c2\u6570\u7684\u7248\u672c\uff0c\u7edf\u4e00\u90fd\u662f\u5728\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u540e\u9762\u8ffd\u52a0\u3002 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u4f20\u5165\u7684\u4eff\u51fd\u6570 cmp \u751a\u81f3\u53ef\u4ee5\u6355\u83b7\u5176\u4ed6\u53d8\u91cf\uff0c\u8fd9\u79cd\u6355\u83b7\u4e86\u53d8\u91cf\u7684\u4eff\u51fd\u6570\u79f0\u4e4b\u4e3a\u6709\u72b6\u6001\u4eff\u51fd\u6570 - stateful functor\uff0c\u548c\u65e0\u72b6\u6001\u4eff\u51fd\u6570 - stateless functor \u76f8\u5bf9\uff1a vector arr = {1, 4, 2, 8, 5, 7}; auto cmp = [&] (int i, int j) { return arr[i] < arr[j]; }; map m(cmp); \u5229\u7528\u6709\u72b6\u6001\u4eff\u51fd\u6570\u53ef\u4ee5\u5b9e\u73b0 argsort \u7b49\u64cd\u4f5c\uff0c\u4f8b\u5982\u4e0a\u9762\u4ee3\u7801\u5c31\u662f\u6839\u636e\u5728 arr \u91cc\u5bf9\u5e94\u7d22\u5f15\u7684\u503c\u6765\u6392\u5e8f\u3002 \u7531\u4e8e map \u9700\u8981\u6bd4\u8f83\u4eff\u51fd\u6570\u4e3a\u7eaf\u51fd\u6570(pure function)\uff0c\u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c\u8bf7\u4fdd\u8bc1 map \u5b58\u5728\u671f\u95f4 arr \u7684\u5185\u5bb9\u4e0d\u53d1\u751f\u53d8\u5316\uff0c\u5426\u5219 map \u57fa\u4e8e\u6392\u5e8f\u7684\u4e8c\u5206\u67e5\u627e\u529f\u80fd\u4f1a\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u4f20\u5165\u6bd4\u8f83\u5668\u4eff\u51fd\u6570\u662f\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u5178\u578b\u7684\u7b56\u7565\u6a21\u5f0f\uff0c\u901a\u8fc7\u4f9d\u8d56\u6ce8\u5165\uff0c\u5141\u8bb8\u6211\u4eec\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\u3002 \u5efa\u8bae\u7528 function \u5982\u679c\u5acc decltype \u9ebb\u70e6\uff08\u96be\u4ee5\u5728\u5168\u5c40\u6216\u7c7b\u5185\u90e8\u7528\uff09\uff0cfunction \u5bb9\u5668\u4f5c\u4e3a\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u7edf\u4e00\u4e86\uff1a auto cmp = [] (int i, int j) { return i < j; }; map> m; \u7a0d\u540e\u8fd8\u53ef\u4ee5\u901a\u8fc7 key_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u952e\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff0c\u8fd9\u4e2a\u5c31\u662f\u4f60\u521a\u521a\u4f20\u5165\u7684 cmp \u53c2\u6570\uff1a m.key_comp()(1, 2); // \u7b49\u4ef7\u4e8e cmp(1, 2) value_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u5143\u7d20\uff08\u952e-\u503c\u5bf9\uff09\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff08\u4ed6\u5e2e\u4f60\u9002\u914d\u53c2\u6570\u7c7b\u578b\u4e86\uff09\uff1a m.value_comp()({1, 0}, {2, 0}); // \u7b49\u4ef7\u4e8e cmp(1, 2) \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 C++14 \u65b0\u589e\u4e86\u201c\u900f\u660e(transparent)\u201d\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u3002 \u5bf9\u4e8e less\u3001greater \u8fd9\u7c7b\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u4eff\u51fd\u6570\uff0c\u6307\u5b9a\u6a21\u677f\u53c2\u6570\u4e3a void \u5373\u53ef\u8ba9\u4e00\u4e2a\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u53d8\u6210\u201c\u900f\u660e\u201d\u7684\u3002\u4f8b\u5982\u5bf9 less \u800c\u8a00\uff0c\u4ed6\u7684\u900f\u660e\u7248\u5c31\u662f less \u3002 C++14 \u4e4b\u524d\u7528\u7684\u90fd\u662f\u201c\u4e0d\u900f\u660e\u201d\u7248\u7684\u4eff\u51fd\u6570\uff0c\u5fc5\u987b\u6307\u5b9a\u4e00\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u4f8b\u5982 less \u5c31\u53ea\u80fd\u7528\u4e8e int \u7c7b\u578b\u7684\u6bd4\u8f83\uff0c less \u5c31\u53ea\u80fd\u7528\u4e8e string \u7c7b\u578b\u7684\u6bd4\u8f83\u3002 \u65e0\u6cd5\u7528 less \u4eff\u51fd\u6570\u6bd4\u8f83 string \u7c7b\u578b\u3002 \u800c less \u662f\u901a\u7528\u7684\uff0c\u4ed6\u7684 operator() \u51fd\u6570\u662f\u6cdb\u578b\u7684\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u3002 template <> struct less { // \u9488\u5bf9 void \u7684\u7279\u5316 // \u6807\u51c6\u59d4\u5458\u4f1a\u60f3\uff1a\u7531\u4e8e void \u7c7b\u578b\u4e0d\u53ef\u80fd\u6709 < \u8fd0\u7b97\u7b26\u7684\u9700\u6c42\uff0c\u6240\u4ee5\u4ed6\u4eec\u5e72\u8106\u62ff void \u4f5c\u4e3a\u900f\u660e\u7248\u7684\u6a21\u677f\u53c2\u6570\u201c\u5360\u4f4d\u7b26\u201d\u4e86 template constexpr decltype(auto) operator()(Tx &&x, Ty &&y) const { return forward(x) < forward(y); } struct is_transparent; // \u7a7a\u7c7b\uff0c\u4ec5\u4f9b SFINAE \u5143\u7f16\u7a0b\u65f6\u68c0\u6d4b\u4e00\u4e2a\u4eff\u51fd\u6570\u662f\u5426\u900f\u660e\u65f6\u4f7f\u7528 }; \u6211\u7684\u601d\u8003\uff1a\u4e0d\u900f\u660e\u7248\u7684 less \u6cdb\u578b\u4f53\u73b0\u5728\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u4e0a\uff0c\u800c\u900f\u660e\u7248\u7684\u4f53\u73b0\u5728\u4e86\u6210\u5458\u51fd\u6570 operator() \u7684\u6a21\u677f\u53c2\u6570\u4e0a\u3002 \u8fd9\u91cc\u7528 void \u7279\u5316\u53ea\u662f\u4e00\u4e2a\u5077\u61d2\uff0c void \u5e76\u6ca1\u6709\u4ec0\u4e48\u7279\u6b8a\u7684\uff0c\u5b9e\u9645\u4e0a\u5e94\u8be5\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u6ca1\u6709\u6a21\u677f\u7684 transparent_less \u7c7b\uff0c\u4f46\u4ed6\u4eec\u5c31\u662f\u61d2\u5f97\u5f15\u5165\u65b0\u6807\u8bc6\u7b26\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u201c\u900f\u660e\u201d\u7248\u7684\u597d\u5904\u662f\u53ef\u4ee5\u540c\u4e00\u4e2a\u517c\u5bb9\u4efb\u610f\u7c7b\u578b\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a cmp \u5bf9\u8c61\u3002\u800c\u4e0d\u900f\u660e\u7248\u7684\u597d\u5904\u662f\u65b9\u4fbf\u7279\u5316 traits\uff0c\u4f46\u6bd5\u7adf < \u8fd0\u7b97\u7b26\u662f\u53ef\u4ee5\u7528\u6237\u81ea\u5b9a\u4e49(\u8fd0\u7b97\u7b26\u91cd\u8f7d)\u7684\uff0c\u6ca1\u5fc5\u8981\u7528 traits \u7279\u5316\uff0c\u6240\u4ee5\u4ed6\u4eec\u9010\u6b65\u53d1\u73b0\u900f\u660e\u7248\u9999\u4e86\uff0c\u8fd8\u80fd\u652f\u6301\u5de6\u53f3\u53c2\u6570\u4e3a\u4e0d\u540c\u7c7b\u578b\u3002 less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u4f46\u4e5f\u8981\u7279\u522b\u6ce8\u610f\u4e0d\u80fd\u518d\u4f9d\u8d56\u53c2\u6570\u7c7b\u578b\u81ea\u52a8\u7684\u9690\u5f0f\u8f6c\u6362\u4e86\uff0c\u5fc5\u987b\u81f3\u5c11\u5199\u5b8c\u6574\u5176\u4e2d\u4e00\u4e2a string(\"hello\") \u624d\u80fd\u89e6\u53d1 string \u7684 operator< \u800c\u4e0d\u662f const char * \u7684\u6307\u9488\u6bd4\u5927\u5c0f\u3002\u5982\u679c\u53ea\u5199 cmp(\"cmake\", \"cppcon\") \u5219\u662f\u5728\u6bd4\u8f83\u6307\u9488\u7684\u5730\u5740\u5927\u5c0f\uff0c\u7ed3\u679c\u662f\u4e0d\u4e00\u5b9a\u7684\u3002 \u7531\u4e8e C++14 \u7684 less \u6a21\u677f\u53c2\u6570 T \u9ed8\u8ba4\u4e3a void\uff0c\u6240\u4ee5 less \u8fd8\u53ef\u4ee5\u7b80\u5199\u6210 less<> \u3002 less<> cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u666e\u901a find \u51fd\u6570\uff1a\u952e\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570 iterator find(K const &k); const_iterator find(K const &k) const; C++14 \u65b0\u589e\u6cdb\u578b\u7248\u7684 find \u51fd\u6570 1 \uff1a\u4efb\u610f\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570\uff0c\u53ea\u8981\u8be5\u7c7b\u578b\u652f\u6301\u4e0e\u548c\u952e\u6bd4\u5927\u5c0f\u3002 template iterator find(Kt &&k); template const_iterator find(Kt &&k) const; \u8fd9\u91cc\u7684 Kt \u662f\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\uff0c\u6b64\u5904 && \u662f\u4e07\u80fd\u5f15\u7528\u4e0d\u662f\u53f3\u503c\u5f15\u7528\u3002 \u76f8\u540c\u70b9\uff1a\u627e\u5230\u4e86\u5c31\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u4e0e\u8be5\u53c2\u6570\u76f8\u7b49\u7684\u5143\u7d20\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8fd8\u662f\u8fd4\u56de end()\u3002 \u4e0d\u540c\u70b9\uff1a\u6cdb\u578b\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b Kt \u4e0d\u5fc5\u548c\u952e\u7c7b\u578b K \u4e00\u81f4\uff0c\u53ea\u8981 Kt \u548c K \u53ef\u4ee5\u6bd4\u8f83\u5927\u5c0f\uff08< \u8fd0\u7b97\u7b26\uff09\u5373\u53ef\u3002 \u4e0d\u4ec5 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u8981\u60f3\u7528\u6cdb\u578b\u7248\u7684 find \u51fd\u6570\u6709\u4e00\u4e2a\u6761\u4ef6\uff1a map \u7684\u6bd4\u8f83\u5668\u5fc5\u987b\u662f\u201c\u900f\u660e(transparent)\u201d\u7684\uff0c\u4e5f\u5c31\u662f less \u8fd9\u79cd\u3002\u5426\u5219\u6cdb\u578b\u7248\u7684 find(Kt &&) \u4e0d\u4f1a\u53c2\u4e0e\u91cd\u8f7d\uff0c\u4e5f\u5c31\u662f\u53ea\u80fd\u8c03\u7528\u4f20\u7edf\u7684 find(K const &) \u3002 \u4f46\u662f map \u9ed8\u8ba4\u7684\u6bd4\u8f83\u5668\u662f less \uff0c\u4ed6\u662f\u4e0d\u900f\u660e\u7684\uff0c\u6bd4\u8f83\u7684\u4e24\u8fb9\u5fc5\u987b\u90fd\u662f K \u7c7b\u578b\u3002\u5982\u679c\u5176\u4e2d\u4e00\u8fb9\u4e0d\u662f\u7684\u8bdd\uff0c\u5c31\u5f97\u5148\u9690\u5f0f\u8f6c\u6362\u4e3a K \u624d\u80fd\u7528\u3002 \u8fd9\u662f\u65e9\u671f C++98 \u8bbe\u8ba1\u7684\u5931\u8d25\uff0c\u5f53\u65f6\u4ed6\u4eec\u6ca1\u60f3\u5230 find \u8fd8\u53ef\u4ee5\u63a5\u53d7 string_view \u548c const char * \u8fd9\u7c7b\u53ef\u4ee5\u548c string \u6bd4\u8f83\uff0c\u4f46\u6784\u9020\u4f1a\u5ec9\u4ef7\u5f97\u591a\u7684\u5f31\u5f15\u7528\u7c7b\u578b\u3002 \u53ea\u597d\u540e\u6765\u5f15\u5165\u4e86\u900f\u660e\u6bd4\u8f83\u5668\u4f01\u56fe\u529b\u633d\u72c2\u6f9c\uff0c\u7136\u800c\u4e3a\u4e86\u5386\u53f2\u517c\u5bb9\uff0c map \u9ed8\u8ba4\u4ecd\u7136\u662f map> \u3002 \u5982\u679c\u6211\u4eec\u540c\u5b66\u7684\u7f16\u8bd1\u5668\u652f\u6301 C++14\uff0c\u5efa\u8bae\u5168\u90e8\u6539\u7528\u8fd9\u79cd\u5199\u6cd5 map> \uff0c\u4ece\u800c\u7528\u4e0a\u66f4\u9ad8\u6548\u7684 find\u3001at\u3001erase\u3001count\u3001contains \u7b49\u9700\u8981\u6309\u952e\u67e5\u627e\u5143\u7d20\u7684\u51fd\u6570\u3002 \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u9664\u975e\u4f20\u5165\u7684\u521a\u597d\u5c31\u662f\u4e00\u4e2a string \u7684 const \u5f15\u7528\uff0c\u5426\u5219\u5c31\u4f1a\u53d1\u751f\u9690\u5f0f\u6784\u9020 string \u7684\u64cd\u4f5c\u3002 \u5982\u679c\u4f20\u5165\u7684\u662f\u4e00\u4e2a string_view \u6216 const char * \uff0c\u90a3\u4e48\u9700\u8981\u4ece\u4ed6\u4eec\u6784\u9020\u51fa\u4e00\u4e2a string \uff0c\u7136\u540e\u624d\u80fd\u4f20\u5165\u4f20\u7edf\u7684 find(string const &) \u51fd\u6570\u3002\u800c string \u7684\u6784\u9020\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e14\u53ef\u80fd\u4ea7\u751f\u5185\u5b58\u5206\u914d\u3002 \u5bf9\u4e8e\u6bd4\u8f83\u5927\u7684\u5b57\u7b26\u4e32\u505a\u952e\u503c\uff0c\u6bcf\u6b21\u67e5\u627e\u90fd\u9700\u8981\u91cd\u65b0\u6784\u9020\u4e00\u4e2a string \u5bf9\u8c61\uff0c\u5f00\u9500\u4f1a\u6bd4\u8f83\u5927\u3002 map lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(string(\"a-very-very-very-very-long-key\")); // \u9690\u5f0f\u6784\u9020\u4e86\u4e00\u4e2a string\uff0c\u5bfc\u81f4\u6df1\u62f7\u8d1d\u4e86\u6574\u4e2a\u5b57\u7b26\u4e32\uff01 \u800c\u542f\u7528\u4e86\u900f\u660e\u6bd4\u8f83\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u6bcf\u6b21\u90fd\u62f7\u8d1d\u6574\u4e2a\u5b57\u7b26\u4e32\u6765\u6784\u9020 string \u4e86\u3002\u56e0\u4e3a find\u3001at \u8fd9\u7c7b\u51fd\u6570\u4f1a\u542f\u7528\u4e00\u4e2a\u6cdb\u578b\u7684\u7248\u672c at(Kt &&) \uff0cKt \u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\uff0c\u53ea\u8981\u4ed6\u652f\u6301\u4e0e string \u6bd4\u8f83\u3002\u53ef\u4ee5\u662f const char * \uff0c string_view \u6216\u53e6\u4e00\u4e2a string \u3002 map> lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(\"a-very-very-very-very-long-key\"); \u56e0\u4e3a\u4e0d\u7528\u62f7\u8d1d\u4e86\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5bf9\u4e8e\u952e\u5b57\u7b26\u4e32\u975e\u5e38\u957f\u7684\u60c5\u51b5\u3002 at \u5185\u90e8\u4e5f\u4e0d\u4f1a\u6784\u9020\u4efb\u4f55\u65b0\u7684 string \uff0c\u4ed6\u4f1a\u62ff\u7740 const char * \u548c\u7ea2\u9ed1\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u8c03\u7528 == \u6bd4\u8f83\u3002 string == const char * \u662f\u5b89\u5168\u7684\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\u3002 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u67d0\u6709\u67d0\u4e9b\u7279\u6b8a\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u628a\u6307\u9488\uff0c\u751a\u81f3\u667a\u80fd\u6307\u9488\uff01\u653e\u8fdb map \u6216 set \u7684\u952e\u4e2d\uff0c\u7528\u4e8e\u5feb\u901f\u6309\u6307\u9488\u7684\u503c\u67e5\u627e\u5230\u5143\u7d20\u3002\uff08\u662f\u7684\u4f60\u6ca1\u542c\u9519\uff0c\u662f\u653e\u5728 \u952e\u7c7b\u578b \u91cc\uff01\uff09 \u8f76\u4e8b\uff1a\u628a\u6307\u9488\u653e\u5728\u952e\u91cc\u5e76\u4e0d\u7f55\u89c1\uff0c\u5e38\u89c1\u7684\u4e00\u4e2a\u7528\u6cd5\u662f set \u3002\u597d\u5904\u662f\u5f53 Node \u6790\u6784\u65f6\uff0c\u4ed6\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528 set.erase(this) \u628a\u81ea\u5df1\u5254\u9664\u6389\u3002\u800c\u666e\u901a\u7684 set \u5c31\u5f88\u96be\u505a\u5230\u8fd9\u4e00\u70b9\u4e86\uff0c\u4f60\u65e0\u6cd5\u901a\u8fc7 Node \u7684 this \u6307\u9488\u83b7\u5f97\u4ed6\u5728 set \u4e2d\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u65e0\u6cd5\u77e5\u9053\u81ea\u5df1\u4f4d\u4e8e\u54ea\u4e2a set \u4e2d\u3002\u4fb5\u5165\u5f0f\u7ea2\u9ed1\u6811\u5b8c\u7f8e\u89e3\u51b3\u4e86\u8fd9\u4e00\u75db\u70b9\uff0cLLVM \u548c Linux \u5185\u6838\u4e2d\u90fd\u5927\u91cf\u8fd0\u7528\u4e86\u4fb5\u5165\u5f0f\u94fe\u8868/LRU/\u7ea2\u9ed1\u6811\uff0c\u4ee5\u540e\u7684\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4e2d\u4f1a\u4e3a\u4f60\u8bb2\u89e3\u3002 map lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); \u5982\u679c\u662f\u667a\u80fd\u6307\u9488\uff0c\u5c31\u6bd4\u8f83\u56f0\u96be\u4e86\uff0c\u7279\u522b\u662f unique_ptr \u3002\u5982\u679c\u4f60\u5df2\u77e5\u4e00\u4e2a\u539f\u59cb\u6307\u9488\uff0c\u60f3\u8981\u5728 map \u4e2d\u67e5\u627e\u6307\u5411\u540c\u6837\u7684\u667a\u80fd\u6307\u9488\u952e\u3002 map, int> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece Node * \u9690\u5f0f\u6784\u9020 unique_ptr \u8fc7\u53bb\uff0c\u4eba\u4eec\u4e0d\u5f97\u4e0d\u7528\u4e00\u79cd\u79f0\u4e3a stale-ptr\uff08\u53d8\u8d28\u6307\u9488\uff09\u7684\u9ed1\u79d1\u6280\uff0c\u6765\u6784\u9020\u4e00\u4e2a\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u4f2a unique_ptr \u51fa\u6765\uff1a map, int> lut; Node *raw_ptr = get_some_ptr(); unique_ptr stale_ptr(raw_ptr); // \u4e00\u4e2a\u5e76\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u201c\u53d8\u8d28\u667a\u80fd\u6307\u9488\u201d lut.find(stale_ptr); // OK: \u5339\u914d\u5230 find(unique_ptr const &) \u91cd\u8f7d stale_ptr.release(); // \u5fc5\u987b\uff01\u5426\u5219\u4f1a\u51fa\u73b0\u53cc\u91cd\u91ca\u653e (double-free) \u9519\u8bef \u800c C++14 \u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u5b9a\u4e49\u4e00\u4e2a\u900f\u660e\u7684\u6bd4\u8f83\u51fd\u6570\uff0c\u652f\u6301 Node * \u4e0e unique_ptr \u4e92\u76f8\u6bd4\u8f83\u5373\u53ef\uff1a struct transparent_ptr_less { template bool operator()(T *const &p1, T const &p2) const { return p1 < p2; } template bool operator()(T *const &p1, unique_ptr const &p2) const { return p1 < p2.get(); } template bool operator()(unique_ptr const &p1, T *const &p2) const { return p1.get() < p2; } template bool operator()(unique_ptr const &p1, unique_ptr const &p2) const { return p1.get() < p2.get(); } using is_transparent = std::true_type; }; map, int, transparent_ptr_less> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // OK: \u5339\u914d\u5230\u6cdb\u578b\u7684 find(Kt &&) \u91cd\u8f7d\uff0c\u5176\u4e2d Kt \u63a8\u5bfc\u4e3a Node *const & \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u4ee5\u4e0b\u6458\u81ea cppreference \u4e0a\u6cdb\u578b find \u7684\u5b98\u65b9\u6848\u4f8b\uff1a struct FatKey { int x; int data[1000]; }; struct LightKey { int x; }; // Note: as detailed above, the container must use std::less<> (or other // transparent Comparator) to access these overloads. // This includes standard overloads, such as between std::string and std::string_view. bool operator<(const FatKey& fk, const LightKey& lk) { return fk.x < lk.x; } bool operator<(const LightKey& lk, const FatKey& fk) { return lk.x < fk.x; } bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.x < fk2.x; } int main() { // transparent comparison demo std::map> example = {{{1, {}}, 'a'}, {{2, {}}, 'b'}}; LightKey lk = {2}; if (auto search = example.find(lk); search != example.end()) std::cout << \"Found \" << search->first.x << \" \" << search->second << '\\n'; else std::cout << \"Not found\\n\"; } Found 2 b \u795e\u5947\u7684 multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\u7684 multimap map \u4e2d\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e00\u4e2a\u503c\uff0c\u800c multimap \u4e00\u4e2a\u952e\u53ef\u4ee5\u5bf9\u5e94\u591a\u4e2a\u503c\u3002 map\uff1a\u6392\u5e8f + \u53bb\u91cd\uff1b multimap\uff1a\u53ea\u6392\u5e8f\uff0c\u4e0d\u53bb\u91cd\u3002 // map \u7684\u63d2\u5165\u51fd\u6570\uff1a pair insert(pair const &kv); pair insert(pair &&kv); // multimap \u7684\u63d2\u5165\u51fd\u6570\uff1a iterator insert(pair const &kv); iterator insert(pair &&kv); \u56e0\u4e3a multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\uff0c\u6240\u4ee5\u63d2\u5165\u603b\u662f\u6210\u529f\uff0c\u4e0e\u666e\u901a map \u76f8\u6bd4\u4e0d\u7528\u8fd4\u56de bool \u8868\u793a\u662f\u5426\u6210\u529f\u4e86\u3002 \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); print(tab); {\"cpp\": \"smart\", \"cpp\": \"fast\", \"java\": \"pig\", \"rust\": \"silly\", \"rust\": \"trash\", \"rust\": \"trash\", \"rust\": \"lazy\"} \u63d2\u5165\u8fdb multimap \u7684\u91cd\u590d\u952e\u4f1a\u7d27\u6328\u7740\uff0c\u4ed6\u4eec\u4e4b\u95f4\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u63d2\u5165\u7684\u987a\u5e8f\u3002\u4f8b\u5982\u4e0a\u9762\u952e\u540c\u6837\u662f \u201ccpp\u201d \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u201dsmart\u201d \u5148\u4e8e \u201cfast\u201d \u63d2\u5165\uff0c\u6240\u4ee5 \u201csmart\u201d \u9760\u524d\u4e86\u3002 \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 multimap / multiset \u7684\u4f5c\u7528\u901a\u5e38\u5c31\u4e0d\u662f\u952e\u503c\u6620\u5c04\u4e86\uff0c\u800c\u662f\u5229\u7528\u7ea2\u9ed1\u6811\u4f1a\u4fdd\u6301\u5143\u7d20\u6709\u5e8f\u7684\u7279\u6027\uff08\u4efb\u4f55\u4e8c\u53c9\u641c\u7d22\u6811\u90fd\u8fd9\u6837\uff09\u5b9e\u73b0\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u52a8\u6001\u6392\u5e8f\u3002 \u4f20\u7edf\u6392\u5e8f\u65b9\u5f0f\uff1a std::vector arr; int i; while (cin >> i) { arr.push_back(i); } std::sort(arr.begin(), arr.end(), std::less()); multiset \u6392\u5e8f\u65b9\u5f0f\uff1a std::multiset tab; int i; while (cin >> i) { tab.insert(i); } // \u65e0\u9700\u518d\u6392\u5e8f\uff0ctab \u4e2d\u7684\u952e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\u4e86\uff01 // \u5982\u9700\u53d6\u51fa\u5230 vector: std::vector arr(tab.begin(), tab.end()); \u5229\u7528 multimap \u952e-\u503c\u5bf9\u7684\u7279\u70b9\uff0c\u8fd8\u80fd\u8f7b\u6613\u5b9e\u73b0\u53ea\u5bf9\u952e\u6392\u5e8f\uff0c\u503c\u7684\u90e8\u5206\u4e0d\u53c2\u4e0e\u6392\u5e8f\u7684\u6548\u679c\u3002 multimap \u6392\u5e8f\u7684\u597d\u5904\u662f\uff1a \u52a8\u6001\u6392\u5e8f\uff0c\u5728\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\u5c31\u4fdd\u6301\u6574\u4e2a\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6027\uff0c\u6700\u540e\u4efb\u4f55\u65e0\u9700\u989d\u5916\u64cd\u4f5c\u3002 \u5728\u4e00\u6b21\u6b21\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u65f6\u6bcf\u523b\u90fd\u662f\u6709\u5e8f\u7684\uff0c\u800c\u4e0d\u5fc5\u7b49\u5230\u6700\u540e\u624d\u53d8\u5f97\u6709\u5e8f\u3002 \u53ef\u4ee5\u968f\u65f6\u52a8\u6001\u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff0c\u540c\u6837\u4e0d\u4f1a\u7834\u574f\u6709\u5e8f\u6027\u3002 \u8fd8\u5f88\u65b9\u4fbf\u968f\u65f6\u6309\u952e\u503c\u67e5\u627e\u5230\u548c\u6211\u76f8\u7b49\u7684\u5143\u7d20\u3002 \u5982\u679c\u8fd8\u989d\u5916\u9700\u8981\u53bb\u91cd\uff0c\u5219\u53ea\u9700\u6539\u7528\u666e\u901a map \u666e\u901a map \u8f7b\u677e\u5b9e\u73b0\u53bb\u91cd + \u52a8\u6001\u6392\u5e8f\uff0c\u5982\u4f55\u5904\u7f6e\u91cd\u590d\u7684\u952e\u968f\u4f60\u51b3\u5b9a\uff1a \u666e\u901a map \u7684 insert \u53ea\u63a5\u53d7\u7b2c\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u666e\u901a map \u7684 insert_or_assign \u53ea\u4fdd\u7559\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c \u56e0\u4e3a multimap \u4e2d\uff0c\u4e00\u4e2a\u952e\u4e0d\u518d\u5bf9\u4e8e\u5355\u4e2a\u503c\u4e86\uff1b\u6240\u4ee5 multimap \u6ca1\u6709 [] \u548c at \u4e86\uff0c\u4e5f\u6ca1\u6709 insert_or_assign \uff08\u53cd\u6b63 insert \u6c38\u8fdc\u4e0d\u4f1a\u53d1\u751f\u952e\u51b2\u7a81\uff01\uff09 pair equal_range(K const &k); template pair equal_range(Kt &&k); \u8981\u67e5\u8be2 multimap \u4e2d\u7684\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e86\u54ea\u4e9b\u503c\uff0c\u53ef\u4ee5\u7528 equal_range \u83b7\u53d6\u4e00\u524d\u4e00\u540e\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4ed6\u4eec\u5f62\u6210\u4e00\u4e2a\u533a\u95f4\u3002\u8fd9\u4e2a\u533a\u95f4\u5185\u6240\u6709\u7684\u5143\u7d20\u90fd\u662f\u540c\u6837\u7684\u952e\u3002 multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); auto range = tab.equal_range(\"cpp\"); for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } cpp smart cpp fast equal_range \u8fd4\u56de\u4e24\u4e2a\u8fed\u4ee3\u5668\u76f8\u7b49\u65f6\uff08\u5373\u533a\u95f4\u5927\u5c0f\u4e3a 0\uff09\uff0c\u5c31\u4ee3\u8868\u627e\u4e0d\u5230\u8be5\u952e\u503c\u3002 auto range = tab.equal_range(\"html\"); if (range.first == range.second) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } } equal_range \u8fd4\u56de\u7684\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4e5f\u53ef\u4ee5\u7528 lower_bound \u548c upper_bound \u5206\u522b\u83b7\u5f97\uff1a auto begin_it = tab.lower_bound(\"html\"); auto end_it = tab.upper_bound(\"html\"); if (begin_it == end_it) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = begin_it; it != end_it; ++it) { print(it->first, it->second); } } lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 lower_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\u7b49\u4e8e\uff08>=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 upper_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\uff08>\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 lower_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\uff08<\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 upper_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\u7b49\u4e8e\uff08<=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 \u4f8b\u5982\u6211\u8981\u5bf9\u4e00\u7cfb\u5217\u5c0f\u5f6d\u53cb\u7684\u6210\u7ee9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u8981\u6c42\u67e5\u51fa\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u6240\u6709\u540c\u5b66\uff0c\u53d1\u653e\u201c\u5c0f\u7ea2\u82b1\u201d\uff1a struct Student { string name; int score; }; vector students; \u5c31\u53ef\u4ee5\u628a\u6210\u7ee9 int \u4f5c\u4e3a\u952e\uff0c\u5b66\u751f\u540d\u5b57\u4f5c\u4e3a\u503c\uff0c\u63d2\u5165 multimap\u3002 \u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d multimap \u5c31\u81ea\u52a8\u4e3a\u4f60\u52a8\u6001\u6392\u5e8f\u4e86\u3002 multimap sorted; for (auto const &stu: students) { sorted.insert({stu.score, stu.name}); } \u7136\u540e\uff0c\u8981\u627e\u51fa\u6240\u6709\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u540c\u5b66\uff0c\u4e5f\u5c31\u662f lower_bound(60) \u5230 end() \u8fd9\u4e2a\u533a\u95f4\uff1a // where score >= 60 for (auto it = sorted.lower_bound(60); it != sorted.end(); ++it) { print(\"\u606d\u559c {} \u540c\u5b66\uff0c\u8003\u51fa\u4e86 {} \u5206\uff0c\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u7ea2\u82b1\", it->second, it->first); } \u627e\u51fa 30\uff08\u542b\uff09\u5230 60\uff08\u4e0d\u542b\uff09\u5206\u7684\u540c\u5b66\u4e5f\u5f88\u5bb9\u6613\uff1a // where 30 <= score and score < 60 for (auto it = sorted.upper_bound(30); it != sorted.lower_bound(60); ++it) { print(\"{} \u540c\u5b66\u8003\u51fa\u4e86 {} \u5206\uff0c\u4e0d\u8981\u7070\u5fc3\uff01\u5c0f\u5f6d\u8001\u5e08\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u9ec4\u82b1\uff0c\u8868\u793a\u9ec4\u724c\u8b66\u544a\", it->second, it->first); } \u8bfe\u540e\u7ec3\u4e60 \u5c1d\u8bd5\u7528 multimap \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5b66\u751f\u6210\u7ee9\u7ba1\u7406\u7cfb\u7edf\uff0c\u8981\u6c42\u5982\u4e0b\uff1a \u5b66\u751f\u4fe1\u606f\u5305\u62ec\u59d3\u540d\u548c\u6210\u7ee9\u3002 \u80fd\u591f\u52a8\u6001\u63d2\u5165\u548c\u5220\u9664\u5b66\u751f\u4fe1\u606f\uff0c\u59cb\u7ec8\u4fdd\u6301\u6309\u6210\u7ee9\u6392\u5e8f\u3002 \u80fd\u591f\u67e5\u8be2\u7ed9\u5b9a\u6210\u7ee9\u8303\u56f4\u5185\u7684\u6240\u6709\u5b66\u751f\u3002 \u5b9e\u9645\u4e0a\uff0c\u6570\u636e\u5e93\u5c31\u662f\u8fd9\u6837\u5b9e\u73b0\u7684\uff0c\u6211\u4eec\u7684 multimap \u53ea\u662f\u7b80\u5355\u5730\u5bf9\u6210\u7ee9\u8fd9\u4e00\u4e2a\u5b57\u6bb5\u6392\u5e8f\uff0c\u800c\u4e13\u4e1a\u7684\u5173\u7cfb\u6570\u636e\u5e93\u4f1a\u4e3a\u6bcf\u4e2a\u5b57\u6bb5\u90fd\u5efa\u7acb\u7d22\u5f15\uff0c\u5206\u522b\u6392\u5e8f\u540e\u5b58\u50a8\uff0c\u4ee5\u52a0\u901f\u67e5\u627e\u3002\u5b66\u6709\u4f59\u529b\u7684\u540c\u5b66\u53ef\u4ee5\u5c1d\u8bd5\u8ba9\u5b66\u751f\u4fe1\u606f\u5305\u542b\u59d3\u540d\u3001\u6210\u7ee9\u3001\u5e74\u9f84\u3001\u5b66\u53f7\uff0c\u7136\u540e\u5206\u522b\u6784\u5efa\u8fd9\u56db\u4e2a\u5b57\u6bb5\u7684\u7d22\u5f15\uff0c\u652f\u6301\u6307\u5b9a\u503c\u67e5\u627e\u548c\u8303\u56f4\u67e5\u627e\uff0c\u5176\u4e2d\u59d3\u540d\u548c\u5b66\u53f7\u8981\u6c42\u552f\u4e00\u6027\u3002\u63d0\u793a\uff1a\u7528\u4e4b\u524d\u63d0\u5230\u7684 vector + map \u7684\u65b9\u6cd5\u3002\u505a\u51fa\u6765\u4ee5\u540e\uff0c\u9762\u8bd5\u6570\u636e\u5e93\u65f6\u4f60\u5c31\u53ef\u4ee5\u79c0\u7406\u89e3\u4e86\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m1 = move(m2) \u79fb\u52a8 O(1) O(1) m1 = m2 \u62f7\u8d1d O(N) O(N) swap(m1, m2) \u4ea4\u6362 O(1) O(1) m.clear() \u6e05\u7a7a O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert({key, val}) \u63d2\u5165\u952e\u503c\u5bf9 O(\\log N) O(\\log N) m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u51c6\u786e O(1) O(1) + m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u4e0d\u51c6\u786e O(\\log N) O(\\log N) m[key] = val \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert({vals\u2026}) \u8bbe M \u4e3a\u5f85\u63d2\u5165\u5143\u7d20\uff08vals\uff09\u7684\u6570\u91cf O(M \\log N) O(M \\log N) map m = \u5982\u679c vals \u65e0\u5e8f O(N \\log N) O(N \\log N) map m = \u5982\u679c vals \u5df2\u4e8b\u5148\u4ece\u5c0f\u5230\u5927\u6392\u5217 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.at(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u503c\u7684\u5f15\u7528 O(\\log N) O(\\log N) m.find(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u8fed\u4ee3\u5668 O(\\log N) O(\\log N) m.count(key) \u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u952e\u5143\u7d20\uff0c\u8fd4\u56de\u76f8\u540c\u952e\u7684\u5143\u7d20\u6570\u91cf\uff08\u53ea\u80fd\u4e3a 0 \u6216 1\uff09 O(\\log N) O(\\log N) m.equal_range(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u786e\u5b9a\u4e0a\u4e0b\u754c\uff0c\u8fd4\u56de\u533a\u95f4 O(\\log N) O(\\log N) m.size() map \u4e2d\u6240\u6709\u5143\u7d20\u7684\u6570\u91cf O(1) O(1) m.erase(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u5220\u9664\u5143\u7d20 O(\\log N) O(\\log N) m.erase(it) \u6839\u636e\u627e\u5230\u7684\u8fed\u4ee3\u5668\uff0c\u5220\u9664\u5143\u7d20 O(1)+ O(1)+ m.erase(beg, end) \u6279\u91cf\u5220\u9664\u533a\u95f4\u5185\u7684\u5143\u7d20\uff0c\u8bbe\u8be5\u533a\u95f4\uff08beg \u548c end \u4e4b\u95f4\uff09\u6709 M \u4e2a\u5143\u7d20 O(M + \\log N) O(M + \\log N) erase_if(m, cond) \u6279\u91cf\u5220\u9664\u6240\u6709\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert(node) O(\\log N) O(\\log N) node = m.extract(it) O(1)+ O(1)+ node = m.extract(key) O(\\log N) O(\\log N) m1.merge(m2) \u5408\u5e76\u4e24\u4e2a map\uff0c\u6e05\u7a7a m2\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) m1.insert(m2.begin(), m2.end()) \u5408\u5e76\u4e24\u4e2a map\uff0cm2 \u4fdd\u6301\u4e0d\u53d8\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) \u54c8\u5e0c\u8868 unordered_map C++11 \u65b0\u589e\uff1a\u57fa\u4e8e\u54c8\u5e0c (hash) \u7684\u6620\u5c04\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u4e4b\u524d\u63d0\u5230\uff0cmap \u5e95\u5c42\u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5927\u591a\u6570\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(\\log N) O(\\log N) \u7ea7\u522b\u7684\uff0c\u5176\u4e2d\u90e8\u5206\u6309\u8fed\u4ee3\u5668\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(1) O(1) \u3002 \u800c unordered_map \u5219\u662f\u57fa\u4e8e\u54c8\u5e0c\u8868\u7684\u66f4\u9ad8\u6548\u67e5\u627e\uff0c\u53ea\u9700 O(1) O(1) \u590d\u6742\u5ea6\uff01\u4ed6\u80fd\u5b9e\u73b0\u5982\u6b64\u9ad8\u6548\u67e5\u627e\u5f97\u76ca\u4e8e\u54c8\u5e0c\u51fd\u6570\u53ef\u4ee5\u628a\u6563\u5217\u552f\u4e00\u5b9a\u4f4d\u5230\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0b\u6807\u4e2d\u53bb\uff0c\u800c\u6570\u7ec4\u7684\u7d22\u5f15\u662f O(1) O(1) \u7684\u3002\u7f3a\u70b9\u662f\u54c8\u5e0c\u503c\u53ef\u80fd\u4ea7\u751f\u51b2\u7a81\uff0c\u800c\u4e14\u54c8\u5e0c\u6570\u7ec4\u53ef\u80fd\u6709\u7a7a\u4f4d\u6ca1\u6709\u586b\u6ee1\uff0c\u6d6a\u8d39\u4e00\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u3002\u603b\u7684\u6765\u8bf4\u54c8\u5e0c\u8868\u5728\u5e73\u5747\u590d\u6742\u5ea6\u4e0a\uff08 O(1) O(1) \uff09\u6bd4\u7ea2\u9ed1\u6811\u8fd9\u7c7b\u57fa\u4e8e\u6811\u7684\u590d\u6742\u5ea6\uff08 O(\\log N) O(\\log N) \uff09\u66f4\u4f4e\uff0c\u867d\u7136\u56fa\u6709\u5ef6\u8fdf\u9ad8\uff0c\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u8fd8\u5bb9\u6613\u88ab\u54c8\u5e0c\u51b2\u7a81\u653b\u51fb\u3002 \u54c8\u5e0c\u8868\u7ed3\u6784\u7b80\u5355\u65e0\u8111\uff0c\u5728\u5de8\u91cf\u7684\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u65f6\u4f1a\u53d1\u6325\u51fa\u660e\u663e\u7684\u6027\u80fd\u4f18\u52bf\uff0c\u5e38\u7528\u4e8e\u9700\u8981\u9ad8\u541e\u5410\u91cf\u4f46\u4e0d\u592a\u5728\u4e4e\u5ef6\u8fdf\u7684\u56fe\u5f62\u5b66\u5e94\u7528\u3002 \u800c\u5404\u79cd\u57fa\u4e8e\u6811\u7684\u6570\u636e\u7ed3\u6784\uff0c\u590d\u6742\u5ea6\u66f4\u52a0\u7a33\u5b9a\uff0c\u770b\u4f3c\u9002\u5408\u5c0f\u89c4\u6a21\u6570\u636e\uff0c\u4f46\u662f\u56e0\u4e3a\u4fdd\u6301\u6709\u5e8f\u7684\u7279\u6027\uff0c\u975e\u5e38\u9002\u5408\u6570\u636e\u5e93\u8fd9\u79cd\u9700\u8981\u8303\u56f4\u67e5\u8be2\u7684\u60c5\u51b5\uff0c\u4e14\u6709\u5e8f\u6027\u53cd\u800c\u6709\u5229\u4e8e\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u65e0\u5e8f\u7684\u54c8\u5e0c\u8868\u96be\u4ee5\u80dc\u4efb\u3002 \u6700\u8fd1\u65b0\u63d0\u51fa\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u8df3\u8868\uff0c\u4e5f\u662f\u6709\u5e8f\u7684\uff0c\u4f46\u57fa\u4e8e\u94fe\u8868\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u5728 Redis \u7b49\u8f6f\u4ef6\u4e2d\u90fd\u6709\u5e94\u7528\u3002\u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u5e76\u5e26\u4f60\u624b\u6413\u6240\u6709\u8fd9\u4e9b\uff01 \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d unordered_map \u5982\u4f55\u5feb\u901f\u68c0\u7d22\u6570\u636e\uff1f\u9ad8\u6548\u7684\u79d8\u8bc0\u5728\u4e8e unordered_map \u5185\u90e8\u662f\u4e00\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u7531\u8bb8\u591a\u201c\u6876\u201d\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u63d2\u5165\u65f6\u628a\u952e\u503c\u5bf9\u5b58\u5230\u952e\u7684 hash \u5bf9\u5e94\u7f16\u53f7\u7684\u6876\u53bb\uff0c\u67e5\u8be2\u65f6\u5c31\u6839\u636e hash \u53bb\u7ebf\u6027\u5730\u67e5\u627e\u6876\uff08\u8fd9\u4e00\u64cd\u4f5c\u662f O(1) O(1) \u7684\uff09\u3002 \u4f8b\u5982\u952e\u4e3a \u201chello\u201d\uff0c\u5047\u8bbe\u7b97\u51fa\u4ed6\u7684 hash \u4e3a 42\u3002\u800c\u5f53\u524d\u6876\u7684\u6570\u91cf\u662f 32 \u4e2a\uff0c\u5219\u4f1a\u628a \u201chello\u201d \u5b58\u5230 42 % 32 = 10 \u53f7\u6876\u53bb\u3002\u67e5\u8be2\u65f6\uff0c\u540c\u6837\u8ba1\u7b97\u51fa hash(\u201chello\u201d) % 32 = 10 \u53f7\u6876\uff0c\u7136\u540e\u5c31\u53ef\u4ee5\u4ece 10 \u53f7\u6876\u53d6\u51fa \u201chello\u201d \u5bf9\u5e94\u7684\u6570\u636e\u4e86\u3002 template class unordered_map { array, 32> buckets; void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97\u51fa\u6765\u7684 hash \u53ef\u80fd\u5f88\u5927\uff0c\u53d6\u6a21\u53ef\u4ee5\u9632\u6b62 h >= buckets.size() buckets[h] = kv; } V &at(K k) { size_t h = hash(k) % buckets.size(); auto &kv = buckets[h]; if (k != kv.first) throw out_of_range{}; return kv.second; } }; \u54c8\u5e0c\u51b2\u7a81 (hash-collision) \u4f46\u662f\u8fd9\u91cc\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u4e24\u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u521a\u597d hash \u4ee5\u540e\u7684\u6a21\u76f8\u540c\u600e\u4e48\u529e\uff1f\u8fd9\u79cd\u73b0\u8c61\u79f0\u4e3a hash \u51b2\u7a81\u3002 C++ \u6807\u51c6\u5e93\u7684\u89e3\u51b3\u65b9\u6848\u662f\u91c7\u7528\u94fe\u8868\u6cd5\uff1a\u4e00\u4e2a\u6876\u4e0d\u662f\u5355\u72ec\u7684\u4e00\u4e2a K-V \u5bf9\uff0c\u800c\u662f\u6570\u4e2a K-V \u5bf9\u7ec4\u6210\u7684\u5355\u94fe\u8868\uff08forward_list\uff09\u3002\u4e00\u4e2a\u6876\u4e0d\u662f\u53ea\u5b58\u50a8\u4e00\u4e2a\u6570\u636e\uff0c\u800c\u662f\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u591a\u4e2a\u6570\u636e\uff080\u5230\u221e\u4e2a\uff09\u3002 \u63d2\u5165\u65f6\uff0c\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5f80\u94fe\u8868\u7684\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684 K-V \u5bf9\u3002\u67e5\u627e\u65f6\uff0c\u5148\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5728\u8fd9\u4e2a\u6876\u91cc\u7684\u94fe\u8868\u91cc\u987a\u5e8f\u904d\u5386\u67e5\u627e\uff0c\u7531\u4e8e\u7b2c\u4e00\u6b65\u7684\u6876\u67e5\u627e\u662f O(1) O(1) \u7684\uff0c\u867d\u7136\u6700\u540e\u8fd8\u662f\u94fe\u8868\u66b4\u529b\u67e5\u627e\uff0c\u4f46\u662f\u5df2\u7ecf\u88ab\u6876\u5206\u644a\u4e86\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u56e0\u6b64\u67e5\u627e\u7684\u5e73\u5747\u590d\u6742\u5ea6\u8fd8\u662f O(1)+ O(1)+ \u7684\u3002 void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 buckets[h].push_front(kv); // \u5355\u94fe\u8868\u7684\u5934\u63d2\uff0c\u662f\u6700\u9ad8\u6548\u7684 } V &at(K k) { size_t h = hash(k) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 for (auto &kv: buckets[h]) { if (k == kv.first) // \u53ef\u80fd\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u952e\u521a\u597d\u6709\u76f8\u540c\u7684 hash \u6a21\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5224\u65ad\u952e\u786e\u5b9e\u76f8\u7b49\u624d\u80fd\u8fd4\u56de return kv.second; } throw out_of_range{}; } \u8fd9\u91cc\u8fd8\u662f\u6709\u4e00\u4e2a\u95ee\u9898\uff0chash \u51b2\u7a81\u65f6\uff0c\u5bf9\u94fe\u8868\u7684\u66b4\u529b\u904d\u5386\u67e5\u627e\u590d\u6742\u5ea6\u662f O(N) O(N) \u7684\uff0c\u968f\u7740\u8d8a\u6765\u8d8a\u591a\u7684\u5143\u7d20\u88ab\u63d2\u5165\u8fdb\u6765\uff0c32 \u4e2a\u6876\u5c06\u4f1a\u62e5\u6324\u4e0d\u582a\u3002\u5047\u8bbe\u6709 n \u4e2a\u5143\u7d20\uff0c\u5219\u5e73\u5747\u6bcf\u4e2a\u6876\u90fd\u4f1a\u6709 n / 32 \u4e2a\u5143\u7d20\uff0c\u9700\u8981 n / 32 \u6b21\u904d\u5386\u3002\u6240\u4ee5\u5143\u7d20\u6570\u91cf\u5145\u5206\u5927\u65f6 unordered_map \u53c8\u4f1a\u9000\u5316\u6210\u66b4\u529b\u904d\u5386\u7684 O(N) O(N) \u590d\u6742\u5ea6\uff0c\u6ee1\u8db3\u4e0d\u4e86\u6211\u4eec\u7528\u4ed6\u52a0\u901f\u67e5\u627e\u7684\u76ee\u7684\u3002 \u6876\u7684\u6570\u91cf\u76f8\u6bd4\u5143\u7d20\u7684\u6570\u91cf\u8d8a\u662f\u4e0d\u8db3\uff0c\u8d8a\u662f\u62e5\u6324\uff0c\u8d8a\u662f\u5bb9\u6613\u9000\u5316\u6210\u94fe\u8868\u3002 \u56e0\u6b64 C++ \u6807\u51c6\u5e93\u89c4\u5b9a\uff0c\u63d2\u5165\u65f6\uff0c\u5f53\u68c0\u6d4b\u5230\u5e73\u5747\u6bcf\u4e2a\u6876\u91cc\u90fd\u6709 1 \u4e2a\u5143\u7d20\u65f6\uff0c\u4e5f\u5c31\u662f\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u6570\u91cf\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\uff0c\u4e00\u6b21\u6027\u8ba9\u6876\u7684\u6570\u91cf\u6269\u5145 2 \u500d\uff0c\u5e76\u91cd\u65b0\u8ba1\u7b97\u6bcf\u4e2a\u5143\u7d20\u7684 hash \u6a21\uff08\u6876\u7f16\u53f7\uff09\u5168\u90e8\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u3002 \u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u7684\u6570\u91cf\u88ab\u79f0\u4e3a\u201c\u8d1f\u8f7d\u7387\uff08load factor\uff09\uff0c\u5bf9\u4e8e\u94fe\u8868\u6cd5\u7684\u54c8\u5e0c\u8868 unordered_map \u6765\u8bf4\uff0c\u8d1f\u8f7d\u7387\u53ef\u4ee5\u9ad8\u4e8e 1\uff1b\u5bf9\u4e8e\u7ebf\u6027\u5730\u5740\u6cd5\u7684 flat_hash_map \u5219\u6700\u9ad8\u4e3a 1\u3002C++ \u6807\u51c6\u5e93\u901a\u5e38\u7684 unordered_map \u5b9e\u73b0\u4e2d\uff0c\u8d1f\u8f7d\u7387\u9ad8\u4e8e 1 \u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\u3002\u53ef\u4ee5\u901a\u8fc7 .load_factor() \u51fd\u6570\u67e5\u8be2\u4e00\u4e2a unordered_map \u7684\u8d1f\u8f7d\u7387\u3002 template class unordered_map { vector>> buckets; // \u56e0\u4e3a\u9700\u8981\u52a8\u6001\u6269\u5bb9\uff0c\u6876\u6570\u7ec4\u53d8\u6210\u4e86\u52a8\u6001\u6570\u7ec4 vector size_t size = 0; // \u8bb0\u5f55\u5f53\u524d\u5bb9\u5668\u5171\u6709\u591a\u5c11\u4e2a\u5143\u7d20 void insert(pair kv) { if (size + 1 > buckets.size()) reserve(n); // \u5982\u679c\u63d2\u5165\u540e\u7684\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u5bb9\u91cf\uff0c\u5219\u6269\u5bb9 size_t h = hash(kv.first) % buckets.size(); buckets[h].push_front(kv); size++; // insert \u65f6 size \u81ea\u52a8\u52a0 1\uff0cerase \u65f6\u4e5f\u8981\u8bb0\u5f97\u51cf 1 } void reserve(size_t n) { if (n <= buckets.size()) return; // \u5982\u679c\u8981\u6c42\u7684\u5927\u5c0f\u5df2\u7ecf\u6ee1\u8db3\uff0c\u4e0d\u9700\u8981\u6269\u5bb9 buckets.resize(max(n, buckets.size() * 2)); // \u628a\u6876\u6570\u7ec4\u81f3\u5c11\u6269\u5927 2 \u500d\uff08\u907f\u514d\u91cd\u590d\u6269\u5bb9\uff09\uff0c\u81f3\u591a\u6269\u5230 n \u6b64\u5904\u7701\u7565 rehash \u7684\u5177\u4f53\u5b9e\u73b0 // \u6876\u7684\u6570\u91cf\u53d1\u751f\u53d8\u5316\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u8ba1\u7b97\u4e00\u904d\u6240\u6709\u5143\u7d20 hash \u7684\u6a21\uff0c\u5e76\u91cd\u65b0\u63d2\u5165 } }; \u6bcf\u4e2a key \u6240\u5728\u7684\u6876\u7f16\u53f7\u8ba1\u7b97\u516c\u5f0f\uff1abucket_index(key) = hash(key) % bucket_count() \u8fd8\u662f\u5b58\u5728\u95ee\u9898\uff0c\u521a\u521a\u7684 insert \u6839\u672c\u6ca1\u6709\u68c0\u6d4b\u8981\u63d2\u5165\u7684\u952e\u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e86\u3002\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u8fd8\u63d2\u5165\uff0c\u90a3\u5c31\u53d8\u6210 unordered_multimap \u4e86\uff01\u6211\u4eec\u662f\u666e\u901a\u7684\u9700\u8981\u53bb\u91cd\u7684 unordered_map\uff0c\u6240\u4ee5\u63d2\u5165\u65f6\u5148\u9700\u8981\u904d\u5386\u4e0b\u94fe\u8868\u68c0\u6d4b\u4e00\u4e0b\u3002 template class unordered_map { vector>> buckets; size_t size = 0; struct iterator { explicit iterator(pair &kv) { /* ... */ } // ... }; pair insert(pair kv) { if (size + 1 > buckets.size()) reserve(size + 1); size_t h = hash(kv.first) % buckets.size(); for (auto &kv2: buckets[h]) { if (kv.first == kv2.first) // \u68c0\u6d4b\u662f\u5426\u53d1\u751f\u4e86\u51b2\u7a81 return {iterator(kv2), false}; // \u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6307\u5411\u5df2\u5b58\u5728\u7684\u952e\u7684\u8fed\u4ee3\u5668 } buckets[h].push_front(kv); size++; return {iterator(buckets.front()), true}; // \u6ca1\u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6210\u529f\u63d2\u5165\u5143\u7d20\u7684\u8fed\u4ee3\u5668 } }; unordered_map \u4e0e map \u7684\u5f02\u540c \u7528\u6cd5\u4e0a\uff0cunordered_map \u57fa\u672c\u4e0e map \u76f8\u540c\uff0c\u4ee5\u4e0b\u7740\u91cd\u4ecb\u7ecd\u4ed6\u4eec\u7684\u4e0d\u540c\u70b9\u3002 \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 map \u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u987a\u5e8f\u6392\u5217\uff0c\u904d\u5386\u65f6\u4e5f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u6bd4\u5927\u5c0f\uff08std::less \u6216 <\uff09\u3002 unordered_map \u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\uff0c\u91cc\u9762\u5143\u7d20\u987a\u5e8f\u968f\u673a\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u54c8\u5e0c\u503c\u8ba1\u7b97\uff08std::hash\uff09\u548c\u5224\u65ad\u76f8\u7b49\uff08std::equal_to \u6216 ==\uff09\u3002 map \u4e2d\u7684\u5143\u7d20\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0cunordered_map \u91cc\u9762\u7684\u5143\u7d20\u662f\u968f\u673a\u7684\u3002 \u8fd9\u4e5f\u610f\u5473\u7740 std::set_union \u8fd9\u7c7b\u8981\u6c42\u8f93\u5165\u533a\u95f4\u6709\u5e8f\u7684 algorithm \u51fd\u6570\u65e0\u6cd5\u9002\u7528\u4e8e unordered_map/set\u3002 hash \u548c equal_to map \u53ea\u9700\u8981 K \u7c7b\u578b\u652f\u6301\u4e00\u4e2a less \u5c31\u80fd\u5de5\u4f5c\u3002 \u800c unordered_map \u9700\u8981 K \u652f\u6301\u7684 trait \u6709\u4e24\u4e2a\uff1ahash \u548c equal_to\u3002 unordered_map \u7684\u5b8c\u6574\u5f62\u6001\u662f\uff1a unordered_map, equal_to, allocator>> \u5176\u4e2d allocator \u6211\u4eec\u7167\u4f8b\u5148\u8df3\u8fc7\u4e0d\u8bb2\uff0c\u4e4b\u540e\u5206\u914d\u5668\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4ecb\u7ecd\u3002 hash \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u6c42\u952e\u7684\u54c8\u5e0c\u503c\uff1fhash \u4eff\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a K \u7c7b\u578b\u7684\u952e\uff0c\u8fd4\u56de\u4e00\u4e2a size_t\uff08\u5728 64 \u4f4d\u7cfb\u7edf\u4e0a\u662f\u4e2a\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff0c\u8868\u793a\u54c8\u5e0c\u503c\uff09\u3002 equal_to \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u5224\u65ad\u4e24\u4e2a\u952e\u76f8\u7b49\uff1f\u5982\u679c\u4e24\u4e2a\u952e\u5b8c\u5168\u76f8\u7b49\uff0c\u4ed6\u4f1a\u8fd4\u56de true\u3002 \u8fd9\u91cc\u5bf9 hash \u7684\u5b9e\u73b0\u53ea\u6709\u4e00\u4e2a\u8981\u6c42\uff0c \u5982\u679c\u4e24\u4e2a\u952e\u76f8\u7b49\uff0c\u5219\u4ed6\u4eec\u7684\u54c8\u5e0c\u5fc5\u5b9a\u4e5f\u76f8\u7b49\uff0c\u53cd\u4e4b\u5219\u4e0d\u4e00\u5b9a \u3002 \u8fd9\u4e2a\u5047\u8bbe\u6784\u6210\u4e86 unordered_map \u5f97\u4ee5\u9ad8\u6548\u7684\u57fa\u77f3\uff0c\u4ed6\u4f7f\u5f97 unordered_map \u53ef\u4ee5\u66f4\u5feb\u6392\u9664\u4e0d\u53ef\u80fd\u7684\u7b54\u6848\uff0c\u800c\u4e0d\u5fc5\u50cf vector \u7684\u67e5\u627e\u90a3\u6837\u9700\u8981\u53bb\u66b4\u529b\u904d\u5386\u5168\u90e8\u5143\u7d20\uff0c\u53ea\u9700\u8981\u904d\u5386\u54c8\u5e0c\u76f8\u7b49\u7684\u90a3\u4e00\u90e8\u5206\u5143\u7d20\u5c31\u591f\u4e86\u3002 template, // \u9ed8\u8ba4\u7684\u54c8\u5e0c\u51fd\u6570\u5b9e\u73b0\uff0c\u652f\u6301\u4e86 int, void *, string \u7b49\u7c7b\u578b typename _Pred = equal_to<_Key>, // \u9ed8\u8ba4\u7684 == \u8fd0\u7b97\u7b26 typename _Alloc = allocator>> class unordered_map \u6362\u8a00\u4e4b\uff0c\u53ea\u8981 unordered_map \u53d1\u73b0\u4e24\u4e2a\u952e\u4e0d\u76f8\u7b49\uff0c\u5c31\u4e0d\u7528\u518d\u505a\u5177\u4f53\u503c\u7684\u6bd4\u8f83\u4e86\uff0c\u4ed6\u4eec\u4e0d\u53ef\u80fd\u76f8\u7b49\u4e86\uff01 \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 hash \u8fd4\u56de\u7684 size_t \u8fd9\u4e2a\u6574\u6570\u53ef\u4ee5\u7406\u89e3\u4e3a\u4e00\u4e2a\u5bf9\u4efb\u610f\u7c7b\u578b\u7684\u201c\u6458\u8981\u201d\u3002 \u628a\u4e00\u4e2a\u5f88\u590d\u6742\u7684\u7c7b\u578b\uff08\u4f8b\u5982 string\uff09\u538b\u7f29\u6210\u4e00\u4e2a unordered_map \u5f88\u8f7b\u6613\u5c31\u80fd\u6bd4\u8f83\u7684 size_t \u6574\u6570\uff0c\u6574\u6570\u6bd4\u8f83\u8d77\u6765\u5c31\u5f88\u5bb9\u6613\uff0c\u800c\u4e14\u8fd8\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff08string \u4e0d\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff09\u3002 \u8fd9\u79cd\u6458\u8981\u7684\u5173\u952e\u5728\u4e8e\u5982\u4f55\u628a\u4e00\u4e2a\u6781\u4e3a\u590d\u6742\u7684\u7c7b\u578b\u201c\u6620\u5c04\u201d\u5230\u5c0f\u5c0f\u7684 size_t \u4e0a\u53bb\uff0c\u5e76\u4e14\u5206\u5e03\u5f97\u5c3d\u53ef\u80fd\u5747\u5300\uff0c\u4e0d\u8981\u51b2\u7a81\u3002 \u8fd9\u5c31\u9700\u8981\u6211\u4eec\u628a\u8fd9\u4e2a\u6781\u4e3a\u590d\u6742\u7c7b\u578b\u7684\u6bcf\u4e2a\u6210\u5458\uff08\u5bf9 string \u800c\u8a00\u5c31\u662f\u6bcf\u4e2a\u5b57\u7b26\uff09\u90fd\u52a0\u5230\u6700\u7ec8\u7ed3\u679c\u7684\u8868\u8fbe\u5f0f\u4e2d\u3002 \u4ee5\u5b57\u7b26\u4e32\u7c7b\u578b string \u4e3a\u4f8b\uff0c\u5e38\u89c1\u7684\u4e00\u79cd\u751f\u6210\u201c\u6458\u8981\u201d\u7684\u65b9\u6cd5\u662f\uff0c\u7528\u4e00\u4e2a\u4efb\u610f\u7d20\u6570\u7684\u4e58\u65b9\u5e8f\u5217\u548c\u5404\u5b57\u7b26\u7684 ASCII \u7801\u505a\u70b9\u79ef\uff1a size_t hash_string(string const &s) { size_t h = 0; for (char c: s) { h = h * 37 + c; } return h; } \u4f8b\u5982\u5bf9\u4e8e\u5b57\u7b26\u4e32 \u201chello\u201d\uff0c\u5219 hash \u53ef\u4ee5\u751f\u6210\u8fd9\u6837\u4e00\u4e2a\u6458\u8981\uff1a size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u76f8\u5f53\u4e8e h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o \u4e5f\u6709\u5176\u4ed6\u66f4\u9ad8\u6548\u7684\u751f\u6210\u6458\u8981\u7684\u65b9\u6cd5\uff0c\u4f8b\u5982\u501f\u52a9\u4f4d\u8fd0\u7b97\u3002 \u751a\u81f3\u8fd8\u6709\u5077\u61d2\u76f4\u63a5\u62ff strlen \u5f53\u54c8\u5e0c\u51fd\u6570\u7684\u201c\u4e16\u754c\u4e0a\u6700\u597d\u7684\u54c8\u5e0c\u8868\u201d\uff0c\u6211\u4e0d\u8bf4\u662f\u8c01\u3002\uff08\u5176\u5b9e\u662f\u65e9\u671f PHP \u5566\uff09 \u81ea\u52a8\u53d6\u6a21 size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u968f\u7740\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u589e\u52a0\uff0c\u8fd9\u4e2a h \u80af\u5b9a\u4f1a\u8d85\u8fc7 size_t \u7684\u8868\u793a\u8303\u56f4\uff0c\u4f46\u662f\u6ca1\u5173\u7cfb\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u7684\u4e58\u6cd5\u3001\u52a0\u6cd5\u6ea2\u51fa\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ed6\u4f1a\u81ea\u52a8 wrapping\uff08\u53d6\u5173\u4e8e 2^{64} 2^{64} \u7684\u6a21\uff09\uff0c\u4e5f\u5c31\u662f\u53ea\u4fdd\u7559\u4e58\u6cd5\u7ed3\u679c\u548c 2^64 \u53d6\u6a21\u7684\u90e8\u5206\u3002 \u53d6\u6a21\u4e5f\u662f\u5bf9\u54c8\u5e0c\u503c\u5e38\u89c1\u7684\u4e00\u4e2a\u64cd\u4f5c\uff0c\u53cd\u6b63\u54c8\u5e0c\u503c\u662f\u968f\u673a\u7684\uff0c\u53d6\u6a21\u4ee5\u540e\u4e5f\u662f\u968f\u673a\u7684\uff0c\u4f46\u662f\u7f29\u5c0f\u4e86\u8303\u56f4\u3002 \u57fa\u672c\u5047\u8bbe\uff1am \u8db3\u591f\u5c0f\u65f6\uff0c\u4e00\u4e2a\u5747\u5300\u7684\u5206\u5e03\u53d6\u4ee5 m \u7684\u6a21\u4ee5\u540e\u4ecd\u7136\u5e94\u8be5\u662f\u5747\u5300\u7684 unordered_map \u4e2d\u6876\u7684\u6570\u91cf\u662f\u6709\u9650\u7684\uff0c\u4e3a\u4e86\u628a\u8303\u56f4\u4ece 0 0 \u5230 2^{64} - 1 2^{64} - 1 \u7684\u54c8\u5e0c\u503c\u6620\u5c04\u4e3a 0 \u5230 bucket_count - 1 \u7684\u6876\u5e8f\u53f7\uff0c\u4ed6\u5185\u90e8\u4f1a\u628a\u952e\u7684\u54c8\u5e0c\u503c\u53d6\u4ee5\u6876\u6570\u91cf\u7684\u6a21\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u952e\u8981\u5b58\u50a8\u5230\u7684\u6876\u7684\u5e8f\u53f7\uff1a bucket_index = hash(key) % bucket_count hash \u662f\u4e2a trait \u7c7b std::hash \u5c31\u662f\u6807\u51c6\u5e93\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u7684\u4eff\u51fd\u6570\u7c7b\u4e86\uff0c\u4ed6\u548c std::less \u4e00\u6837\uff0c\u662f\u4e00\u4e2a trait \u7c7b\u3002 \u4e00\u4e9b\u5e38\u89c1\u7684\u7c7b\u578b\u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u9488\u5bf9\u81ea\u5b9a\u4e49\u7c7b\u578b\u6dfb\u52a0\u7279\u5316\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316 } }; template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u5bf9 T * \u7684\u504f\u7279\u5316 } }; std::hash \u9488\u5bf9\u6bcf\u4e2a\u4e0d\u540c\u7684\u7c7b\u578b\u505a\u4e86\u7279\u5316\uff0c\u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u8ba1\u7b97 string \u7c7b\u578b\u7684 hash \u65f6\uff1a string str = \"Hello, world\"; size_t h = hash()(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); \u6ce8\u610f\uff1a\u8fd9\u91cc\u6709\u4e24\u4e2a\u62ec\u53f7\uff0c\u7b2c\u4e00\u4e2a\u662f\u7a7a\u7684\u3002\u7b2c\u4e00\u4e2a\u62ec\u53f7\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u4e2a\u7528str\u4f5c\u4e3a\u5b9e\u53c2\u8c03\u7528\u4eff\u51fd\u6570\u7684 operator() \u3002\u5f53\u7136\u8fd8\u522b\u5fd8\u4e86\u7b2c\u4e00\u4e2a\u5c16\u62ec\u53f7\uff0c\u8fd9\u4e2a\u5c16\u62ec\u53f7\u91cc\u7684 string \u8868\u793a\u7684\u662f hash \u4eff\u51fd\u6570\u63a5\u4e0b\u6765\u8981\u63a5\u53d7\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u4e4b\u6240\u4ee5\u4f5c\u4e3a\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u800c\u4e0d\u662f\u6a21\u677f\u51fd\u6570\uff0c\u662f\u4e3a\u4e86\u65b9\u4fbf\u7279\u5316\u548c\u504f\u7279\u5316\u3002\u540c\u5b66\u4eec\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5199\u4e00\u4e2a\u8fd9\u6837\u7684\u51fd\u6570\uff0c\u7528\u8d77\u6765\u5c31\u4e0d\u7528\u6307\u5b9a\u7c7b\u578b\uff08\u5982\u8fd9\u91cc\u7684 string\uff09\u4e86\uff0c\u8ba9\u6a21\u677f\u51fd\u6570\u81ea\u52a8\u63a8\u5bfc\u53c2\u6570\u7c7b\u578b\uff08\u7c7b\u4f3c\u4e8e make_pair\uff09\uff1a template size_t do_hash(T const &t) { return hash()(t); } int main() { string str = \"Hello, world\"; size_t h = do_hash(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); } \"Hello, world\" \u7684\u54c8\u5e0c\u662f 14701251851404232991 \u5bf9\u4efb\u610f\u7c7b\u578b\u54c8\u5e0c\u7684\u7ed3\u679c\u90fd\u662f\u4e00\u4e2a size_t\uff0c\u5176\u5728 32 \u4f4d\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint32_t\uff0c\u5728\u6211\u4eec 64 \u4e3a\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint64_t\u3002\u9009\u62e9 size_t \u662f\u4e3a\u4e86\u80fd\u54c8\u5e0c\u4e86\u4ee5\u540e\u76f4\u63a5\u7528\u4e8e unordered_map \u4e2d\u6876\u7684\u7d22\u5f15\u3002 \u7531\u4e8e hash \u662f\u7528\u4f5c\u54c8\u5e0c\u8868\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7528\u4e8e\u52a0\u5bc6\u9886\u57df\uff08\u8bf7\u4f60\u79fb\u6b65 md5\uff09\uff0c\u6216\u662f\u7528\u4e8e\u968f\u673a\u6570\u751f\u6210\uff08\u8bf7\u79fb\u6b65 mt19937\uff09\uff0c\u56e0\u6b64\u5bf9\u4e8e\u4efb\u610f\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u6839\u636e\u4ed6\u751f\u6210\u4e00\u4e2a size_t \u7684\u54c8\u5e0c\u503c\u5373\u53ef\uff0c\u53ea\u8981\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5206\u5e03\u5747\u5300\u5373\u53ef\uff0c\u4e0d\u4e00\u5b9a\u8981\u6709\u968f\u673a\u6027\u3002\u4f8b\u5982\u6807\u51c6\u5e93\u5bf9 int \u7684 hash \u5b9e\u73b0\u5c31\u662f\u4e2a\u6052\u7b49\u51fd\u6570\u2014\u2014\u76f4\u63a5\u8fd4\u56de\u5176\u6574\u6570\u503c\uff0c\u4e0d\u7528\u505a\u4efb\u4f55\u8ba1\u7b97\uff1a template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316\u771f\u662f\u4ec0\u4e48\u4e5f\u4e0d\u505a\u5462\uff1f } }; \u800c\u5bf9\u4e8e\u4efb\u610f\u6307\u9488\u7684\u5b9e\u73b0\u5219\u662f\u76f4\u63a5\u628a\u6307\u9488 bit-cast \u6210 size_t\uff1a template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u6307\u9488\u5f3a\u5236\u8f6c\u6362\u4e3a\u6574\u6570 } }; int i = 42; int j = hash()(i); // \u6ca1\u60f3\u5230\u7f62\uff01\u6211\u7cfb\u6052\u7b49\u51fd\u6570\u54d2 print(i, j); 42 42 \u8bb0\u4f4f\uff0cstd::hash \u4e0d\u662f\u4e3a\u4e86\u52a0\u5bc6\u6216\u968f\u673a\u800c\u751f\u7684\uff0c\u4ed6\u7684\u529f\u80fd\u4ec5\u4ec5\u662f\u5c3d\u53ef\u80fd\u5feb\u901f\u5730\u628a\u4efb\u610f\u7c7b\u578b T \u6620\u5c04\u5230 size_t \u800c\u5df2\u3002 \u81f3\u4e8e\u8fd9\u5bf9 unordered_map \u7684\u6027\u80fd\u6709\u4f55\u5f71\u54cd\uff1f\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5f71\u54cd\uff0c\u9664\u975e\u8f93\u5165\u952e\u6545\u610f\u8bbe\u4e3a\u548c bucket_count \u540c\u6a21\uff0c\u6bd5\u7adf\u53cd\u6b63\u4f60\u4e5f\u65e0\u6cd5\u65ad\u5b9a\u8f93\u5165\u952e\u7684\u6392\u5e03\u6a21\u5f0f\uff0c\u4e0d\u8bba\u9009\u4ec0\u4e48\u54c8\u5e0c\u51fd\u6570\u53ea\u8981\u4fdd\u8bc1\u5747\u5300\u90fd\u662f\u53ef\u4ee5\u7684\u3002\u800c\u6052\u7b49\u51fd\u6570\u521a\u597d\u662f\u5747\u5300\u7684\uff0c\u53c8\u4e0d\u7528\u989d\u5916\u7684\u82b1\u91cc\u80e1\u54e8\u4f4d\u8fd0\u7b97\u6d6a\u8d39\u65f6\u95f4\uff0c\u53cd\u800c\u53ef\u80fd\u56e0\u4e3a\u952e\u6709\u5e8f\u800c\u63d0\u5347\u4e86\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u63d0\u5347\u4e86\u6027\u80fd\uff0c\u6240\u4ee5\u5404\u5927\u5382\u5546\u7684\u6807\u51c6\u5e93\u90fd\u662f\u8fd9\u4e48\u505a\u7684\u3002 \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(1)+ O(1)+ \u590d\u6742\u5ea6\u7684\u3002 \u770b\u8d77\u6765 unordered_map \u66f4\u9ad8\u6548\uff1f\u90a3\u8fd8\u8981 map \u5e72\u4ec0\u4e48\uff1f\u5b8c\u5168\u4e0a\u4f4d\u66ff\u4ee3\u554a\uff1f \u4f46\u662f\u6211\u4eec\u8981\u6ce8\u610f\uff0c\u4e0a\u9762\u6240\u8bf4\u7684\u590d\u6742\u5ea6 O(1) O(1) \u53ea\u662f\u5e73\u5747\u4e0b\u6765\u7684\uff0c\u5e76\u4e0d\u4ee3\u8868\u6bcf\u4e00\u6b21 unordered_map \u63d2\u5165\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(1) O(1) \uff01\u6240\u4ee5\uff0c\u590d\u6742\u5ea6\u8868\u793a\u6cd5\u91cc\u7684\u8fd9\u4e2a + \u53f7\u5c31\u662f\u8fd9\u4e2a\u610f\u601d\uff0c\u4ee3\u8868\u6211\u8fd9\u4e2a\u590d\u6742\u5ea6\u53ea\u662f\u591a\u6b21\u8fd0\u884c\u53d6\u5e73\u5747\uff0c\u5982\u679c\u53ea\u8003\u8651\u5355\u6b21\u6700\u574f\u7684\u60c5\u51b5\uff0c\u53ef\u80fd\u66f4\u9ad8\u3002 map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u4e5f\u53ea\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u53ef\u4ee5\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u3002 \u5904\u7406\u5f88\u9ad8\u7684\u6570\u636e\u91cf\u65f6\uff0c\u8fd9\u4e00\u70b9\u6700\u574f\u7684\u60c5\u51b5\u4f1a\u88ab\u5e73\u644a\u6389\uff0cunordered_map \u66f4\u9ad8\u6548\u3002 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u6240\u4ee5 unordered_map \u4e0d\u7a33\u5b9a\uff0c\u867d\u7136\u5e73\u5747\u662f O(1) O(1) \u590d\u6742\u5ea6\uff0c\u4f46\u6700\u574f\u53ef\u8fbe\u5230 O(N) O(N) \u590d\u6742\u5ea6\u3002\u80cc\u540e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\u5462\uff1f \u539f\u6765 unordered_map \u548c vector \u4e00\u6837\uff0c\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u52a8\u6001\u6269\u5bb9\u7684\u5bb9\u5668\u3002 \u5982\u679c\u4e0d\u6269\u5bb9\uff0c\u90a3\u4e48\u5f53\u5f88\u591a\u5143\u7d20\u6324\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u94fe\u8868\u7684\u538b\u529b\u5c31\u4f1a\u53d8\u5927\uff0c\u4f1a\u5f88\u4f4e\u6548\uff0c\u56e0\u6b64 unordered_map \u5fc5\u987b\u6269\u5bb9\u3002\u4f46\u662f\u5728\u6269\u5bb9\u7684\u65f6\u5019\u662f\u9700\u8981\u8fdb\u884c rehash \u64cd\u4f5c\u7684\u3002\u4e00\u6b21\u6269\u5bb9\uff0c\u5c31\u9700\u8981\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e00\u904d\u3002 \u7ed3\u679c\u5c31\u662f unordered_map \u7684\u63d2\u5165\u5982\u679c\u6ca1\u89e6\u53d1 rehash\uff0c\u90a3\u5c31\u662f O(1) O(1) \u7684\u3002\u89e6\u53d1\u4e86\uff0c\u90a3\u5c31\u662f\u6700\u574f\u7684\u60c5\u51b5\uff0c O(N) O(N) \u7684\u3002\u4f46\u662f\u4e0d\u89e6\u53d1\u7684\u60c5\u51b5\u8fdc\u591a\u4e8e\u89e6\u53d1\u4e86\u7684\uff0c\u6240\u4ee5\u5e73\u5747\u4e0b\u6765\u8fd8\u662f O(1) O(1) \uff0c\u4e3a\u4e86\u63d0\u9192\u4eba\u4eec\u4ed6\u6700\u574f\u7684\u60c5\u51b5\uff0c\u6240\u4ee5\u5199\u4f5c O(1)+ O(1)+ \uff0c\u8bfb\u4f5c\u201c\u5e73\u644a O1\u201d\uff08Amortized Constant\uff09\u3002 \u6b64\u5916\uff0c\u4e0d\u4ec5 unordered_map \u7684\u63d2\u5165\u51fd\u6570\u662f O(1)+ O(1)+ \uff0c\u4ed6\u7684\u67e5\u8be2\u51fd\u6570\u4e5f\u662f O(1)+ O(1)+ \u3002\u4e3a\u4ec0\u4e48\u5462\uff1f\u8bbe\u60f3\u4f60\u5728\u7f16\u5199\u4e00\u4e2a\u5bcc\u8fde\u7f51\u670d\u52a1\u5668\uff0c\u5982\u679c\u9ed1\u5ba2\u5df2\u77e5\u4f60\u7684 hash \u51fd\u6570\uff0c\u90a3\u4ed6\u5c31\u53ef\u4ee5\u901a\u8fc7\u6784\u9020\u4e00\u7cfb\u5217\u7279\u6b8a\u8bbe\u8ba1\u597d\u7684 key\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u521a\u597d\u76f8\u7b49\uff08\u6216\u540c\u6a21\uff09\uff0c\u8fd9\u6837\u5c31\u4f7f\u5f97\u6240\u6709 key \u521a\u597d\u5168\u90e8\u843d\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u5bfc\u81f4 unordered_map \u9000\u5316\u6210\u7ebf\u6027\u7684\u94fe\u8868\uff0c\u6240\u6709\u7684\u67e5\u8be2\u548c\u63d2\u5165\u90fd\u53d8\u6210\u4e86\u8fd9\u4e00\u4e2a\u6876\u4e0a\u7684\u94fe\u8868\u904d\u5386\u64cd\u4f5c\uff0c\u590d\u6742\u5ea6\u8fbe\u5230\u6700\u574f\u7684 O(N) O(N) \uff0c\u8fd9\u4e00\u73b0\u8c61\u53eb\u505a hash \u9000\u5316\u3002 \u56e0\u6b64 hash \u51fd\u6570\u7684\u597d\u574f\u51b3\u5b9a\u7740 unordered_map \u6027\u80fd\uff0c\u5bf9\u4e8e\u5b89\u5168\u9886\u57df\u6765\u8bf4\uff0c\u8fd8\u8981\u4fdd\u8bc1 hash \u51fd\u6570\u65e0\u6cd5\u88ab\u9ed1\u5ba2\u7834\u89e3\u3002\u53ea\u8981 hash \u51fd\u6570\u8db3\u591f\u968f\u673a\uff0c\u5c31\u80fd\u4fdd\u8bc1\u952e\u4e0d\u51b2\u7a81\uff0c\u5c31\u5f88\u5feb\uff0c\u4e00\u65e6\u51fa\u73b0\u952e\u51b2\u7a81\u5c31\u4f1a\u53d8\u6162\u3002\u4f46\u9700\u8981\u9891\u7e41\u4f7f\u7528\u7684 hash \u51fd\u6570\u8ba1\u7b97\u96be\u5ea6\u53c8\u4e0d\u80fd\u592a\u5927\uff0c\u90a3\u53c8\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u56e0\u6b64 hash \u4e5f\u4e0d\u80fd\u592a\u8fc7\u590d\u6742\u3002 \u6807\u51c6\u5e93\u91cc\u5b58\u5728\u8fd9\u79cd\u201c\u5e73\u644a\u590d\u6742\u5ea6\u201d\u7684\u4f8b\u5b50\u8fd8\u6709\u5f88\u591a\uff0c\u4f8b\u5982 vector \u7684 push_back \u4e0d reserve \u7684\u8bdd\uff0c\u5c31\u662f O(1)+ O(1)+ \u7684\uff0c\u56e0\u4e3a\u4ed6\u9700\u8981\u52a8\u6001\u6269\u5bb9\u3002 \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u4e00\u4e9b\u5b9e\u65f6\u6027\u8981\u6c42\u5f88\u9ad8\u7684\u9886\u57df\u5c31\u4e0d\u80fd\u7528 unordered_map\u3002\u4f8b\u5982\u4f60\u9020\u4e86\u4e2a\u706b\u7bad\uff0c\u89c4\u5b9a\uff1a\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u9700\u8981\u5728 1000 \u03bcs \u5185\u5bf9\u5916\u754c\u53d8\u5316\u505a\u51fa\u5b9e\u65f6\u53cd\u5e94\uff0c\u5982\u679c\u4e0d\u80fd\u53ca\u65f6\u505a\u51fa\u53cd\u5e94\uff0c\u706b\u7bad\u5c31\u4f1a\u505a\u6258\u9a6c\u65af\u56de\u65cb\u7ed9\u4f60\u770b\u3002 \u4f60\u5728\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u4e2d\u7528\u4e86 unordered_map\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u4e0d\u65ad\u8fd0\u884c\uff0c\u4ee5\u4fbf\u63a7\u5236\u706b\u7bad\u505a\u51fa\u6b63\u786e\u7684\u673a\u52a8\uff0c\u5bf9\u6297\u4fa7\u5411\u98ce\u5e72\u6270\u3002\u7b2c\u4e00\u6b21\u8fd0\u884c\u4ed6\u5728 180 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 250 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 245 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u9ad8\u6548\u3002 \u4f46\u662f\u7a81\u7136\u6709\u4e00\u6b21\uff0cunordered_map \u89c9\u5f97\u4ed6\u5185\u90e8\u201c\u6876\u592a\u4e71\u201d\u4e86\uff0c\u6025\u9700\u91cd\u65b0\u6269\u5bb9\u5e76 rehash \u4e00\u4e0b\u201c\u5fe7\u5316\u6027\u80fd\u201d\u3002\u7136\u540e\uff0c\u4ed6\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e86\u4e00\u904d\uff0c\u79fb\u52a8\u5b8c\u4e86\uff0c\u628a\u5904\u7406\u5b8c\u7684\u6570\u636e\u8fd4\u56de\u7ed9\u706b\u7bad\u59ff\u6001\u8c03\u63a7\u7cfb\u7edf\uff0c\u8ba4\u4e3a\u5927\u529f\u544a\u6210\u3002\u4f46\u5f53\u4ed6\u7741\u5f00\u773c\u775b\u4e00\u770b\uff0c\u521a\u60f3\u8981\u63a7\u5236\u4e00\u4e0b\u59ff\u6001\u5462\uff1f\u5374\u53d1\u73b0\u81ea\u5df1\u5df2\u7ecf\u5728\u505a\u6258\u9a6c\u65af\u56de\u65cb\u4e86\uff01\u539f\u6765\u6211\u8fd9\u4e00\u201c\u5fe7\u5316\u201d\u5c31\u5fe7\u4e86 4000 \u03bcs\uff0c\u8d85\u51fa\u4e86\u706b\u7bad\u5b9e\u65f6\u54cd\u5e94\u7684\u786c\u6027\u6307\u6807\uff0c\u5bfc\u81f4\u897f\u88c5\u9ab0\u5b50\u4eba\u5377\u6b3e\u8dd1\u8def\uff0c\u5c0f\u5f6d\u8001\u5e08\u7834\u4ea7\u3002 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u521b\u4e1a\uff0c\u8fd9\u6b21\u4ed6\u9009\u7528\u4e86\u7a33\u5b9a\u7684 map\uff0c\u7b2c\u4e00\u6b21\u4ed6\u5728 810 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 680 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 730 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u4f4e\u6548\u3002\u4f46\u662f\u4ed6\u6bcf\u4e00\u6b21\u90fd\u80fd\u6210\u529f\u5361\u70b9\u7ed9\u4f60\u5b8c\u6210\u4efb\u52a1\uff0c\u4ece\u6765\u4e0d\u4f1a\u7a81\u7136\u8d85\u8fc7 O(\\log N) O(\\log N) \uff0c\u4ed6\u7684\u6700\u574f\u60c5\u51b5\u662f\u53ef\u63a7\u7684\uff0c\u4ece\u800c\u907f\u514d\u4e86\u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb\u3002\u5c0f\u5f6d\u8001\u5e08\u6700\u7ec8\u521b\u4e1a\u6210\u529f\uff0c1000 \u5e74\u540e\uff0c\u6211\u53f8\u6210\u529f\u5efa\u9020\u5b8c\u6210 Type-II \u6587\u660e\u6240\u6025\u9700\u7684\u6234\u68ee\u7403\uff0c\u5411\u661f\u8fb0\u5927\u6d77\u8fdb\u519b\u3002 \u5bf9\u5b9e\u65f6\u6027\u8981\u6c42\u9ad8\u7684\u8fd9\u7c7b\u9886\u57df\u5305\u62ec\uff0c\u97f3\u89c6\u9891\uff0c\u9020\u706b\u7bad\uff0c\u91cf\u5316\u4ea4\u6613\u7b49\u3002\u8fd9\u7c7b\u4f4e\u5ef6\u8fdf\u4f4e\u541e\u5410\u91cf\u7684\u9886\u57df\u5bf9\u5e73\u644a\u590d\u6742\u5ea6\u5f88\u53cd\u611f\uff0c\u4ed6\u4eec\u53ea\u770b\u91cd\u6700\u574f\u7684\u590d\u6742\u5ea6\uff0c\u800c\u4e0d\u662f\u5e73\u5747\u7684\u3002 \u4f46\u5bf9\u4e8e\u4e3b\u6253\u4e00\u4e2a\u9ad8\u541e\u5410\u91cf\u65e0\u6240\u8c13\u5ef6\u8fdf\u7684\u79bb\u7ebf\u56fe\u5f62\u5b66\uff0c\u79bb\u7ebf\u79d1\u5b66\u8ba1\u7b97\uff0c\u5b9e\u65f6\u6027\u4e0d\u91cd\u8981\u7684\u751f\u6001\u5316\u53cd\u573a\u666f\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba4\u4e3a unordered_map \u7684\u5e73\u644a O(1)+ O(1)+ \u5c31\u662f\u6bd4 map \u9ad8\u6548\u7684\u3002 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 map \u548c unordered_map \u90fd\u662f\u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\u624d\u4f1a\u5931\u6548\uff0c\u8fd9\u70b9\u76f8\u540c\u3002 \u4f46 unordered_map \u6269\u5bb9\u65f6\u5019\u7684 rehash \u64cd\u4f5c\u4f1a\u9020\u6210\u6240\u6709\u8fed\u4ee3\u5668\u5931\u6548\u3002 insert \u53ef\u80fd\u5bfc\u81f4 unordered_map \u6269\u5bb9\uff0c\u5176\u4ed6\u53ea\u8bfb\u64cd\u4f5c\u4e0d\u4f1a\u3002 \u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u88ab\u5220\u9664\u65f6\uff0c\u4e0d\u8bba map \u548c unordered_map \u90fd\u4f1a\u5931\u6548\u3002 unordered_map \u5728 insert \u65f6\u5982\u679c\u53d1\u751f\u6269\u5bb9\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u5931\u6548\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528 reserve \u907f\u514d insert \u65f6\u6269\u5bb9\u3002 \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 clear swap opeartor= rehash vector \u662f \u5426 \u662f - map \u662f \u5426 \u662f - unordered_map \u662f \u5426 \u662f - \u5bb9\u5668 find count at [] vector \u5426 \u5426 \u5426 \u5426 map \u5426 \u5426 \u5426 \u5426 unordered_map \u5426 \u5426 \u5426 \u662f\uff0c\u5982\u679c\u521b\u5efa\u4e86\u65b0\u5143\u7d20\u4e14 size / bucket_count > max_load_factor \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 push_back insert erase reserve vector \u662f\uff0c\u5982\u679c size > capacity \u662f\uff0c\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216 size > capacity \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u5143\u7d20\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684 \u662f map - \u5426 \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 - unordered_map - \u662f\uff0c\u5982\u679c size / bucket_count > max_load_factor \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 \u662f \u4e5f\u53ef\u4ee5\u67e5\u770b\u5b98\u65b9\u7248\u300a\u8fed\u4ee3\u5668\u5931\u6548\u8868\u300b\uff1ahttps://en.cppreference.com/w/cpp/container#Iterator_invalidation \u8d1f\u8f7d\u7387\uff08load_factor\uff09 \u8ba1\u7b97\u516c\u5f0f\uff1a\u8d1f\u8f7d\u56e0\u5b50(load_factor) = \u5f53\u524d\u5143\u7d20\u6570\u91cf(size) \u00f7 \u5f53\u524d\u6876\u7684\u6570\u91cf(bucket_count) \u63d2\u5165\u65b0\u5143\u7d20\u540e\uff0c\u5f53\u68c0\u6d4b\u5230\u8d1f\u8f7d\u56e0\u5b50\u5927\u4e8e\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4 1.0\uff09\u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fdb\u884c rehash \u64cd\u4f5c\u3002 \u4e3a\u4e86\u907f\u514d\u91cd\u590d\u5c0f\u89c4\u6a21\u6269\u5bb9\u6d6a\u8d39\u65f6\u95f4\uff0c\u8fd9\u6b21 rehash \u4f1a\u4e00\u6b21\u6027\u6269\u5bb9\u4e24\u500d\uff08\u8ddf vector \u7684 push_back \u6269\u5bb9\u7c7b\u4f3c\uff09\u3002 \u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 max_load_factor \u51fd\u6570\u8c03\u6574\u3002\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 load_factor \u51fd\u6570\u67e5\u8be2\u3002 \u76f4\u89c2\u7406\u89e3\uff1a\u5f53\u6bcf\u4e2a\u6876\u5e73\u5747\u90fd\u6709\u4e00\u4e2a\u5143\u7d20\u65f6\uff0cunordered_map \u5c31\u4f1a\u8ba4\u4e3a\u5df2\u7ecf\u5f88\u6ee1\u4e86\uff0c\u5c31\u4f1a\u6269\u5bb9\u5e76\u91cd\u65b0\u5206\u914d\u4f4d\u7f6e\u3002 \u7531\u4e8e\u9ed8\u8ba4\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u662f 1.0\uff0c\u6240\u4ee5\u6269\u5bb9\u6761\u4ef6\u7b49\u4ef7\u4e8e size > bucket_count rehash \u51fd\u6570 \u5728\u64cd\u4f5c unordered_map \u5bb9\u5668\u8fc7\u7a0b\uff08\u5c24\u5176\u662f\u5411\u5bb9\u5668\u4e2d\u6dfb\u52a0\u65b0\u952e\u503c\u5bf9\uff09\u4e2d\uff0c\u4e00\u65e6\u5f53\u524d\u5bb9\u5668\u7684\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4\u503c\u4e3a 1.0\uff09\uff0c\u8be5\u5bb9\u5668\u5c31\u4f1a\u9002\u5f53\u589e\u52a0\u6876\u7684\u6570\u91cf\uff08\u901a\u5e38\u662f\u7ffb\u4e00\u500d\uff09\uff0c\u5e76\u81ea\u52a8\u6267\u884c rehash() \u6210\u5458\u65b9\u6cd5\uff0c\u91cd\u65b0\u8c03\u6574\u5404\u4e2a\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff08\u6b64\u8fc7\u7a0b\u53c8\u79f0\u201c\u91cd\u54c8\u5e0c\u201d\uff09\uff0c\u6b64\u8fc7\u7a0b\u5f88\u53ef\u80fd\u5bfc\u81f4\u4e4b\u524d\u521b\u5efa\u7684\u8fed\u4ee3\u5668\u5931\u6548\u3002 1 \u9664\u4e86\u6269\u5bb9\u65f6\u81ea\u52a8\u7684 rehash\uff0c\u786e\u8ba4\u6570\u636e\u63d2\u5165\u5b8c\u6bd5\u4e0d\u4f1a\u518d\u6539\u52a8\u65f6\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u6765\u4f18\u5316\u5bb9\u5668\u4e2d\u5143\u7d20\u7684\u6392\u5e03\uff0c\u63d0\u5347\u6027\u80fd\u3002 unordered_map umap; for (int i = 1; i <= 50; i++) { umap.emplace(i, i); } auto pair = umap.equal_range(49); //\u83b7\u53d6\u952e\u4e3a 49 \u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u533a\u95f4\uff0c\u7531\u4e8e\u4e0d\u662f multimap\uff0c\u533a\u95f4\u5927\u5c0f\u53ea\u80fd\u4e3a 0 \u6216 1 for (auto iter = pair.first; iter != pair.second; ++iter) { //\u8f93\u51fa pair \u8303\u56f4\u5185\u7684\u6bcf\u4e2a\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c cout << iter->first << '\\n'; } umap.rehash(10); //\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u91cd\u54c8\u5e0c\u4e3a 10 \u4e2a\u6876 for (auto iter = pair.first; iter != pair.second; ++iter) { // \u91cd\u54c8\u5e0c\u4e4b\u540e\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u4f1a\u53d1\u751f\u53d8\u5316 cout << iter->first << '\\n'; } 49 Segmentation fault (core dumped) hash \u9700\u8981\u7279\u5316 \u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6620\u5c04\u8868 map \u53ea\u9700\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7684 less \u5373\u53ef\uff0c\u800c unordered_map \u9700\u8981\u54c8\u5e0c\u548c\u76f8\u7b49\u4e24\u4e2a trait\uff0c\u4ed6\u4eec\u5206\u522b\u540d\u53eb std::hash \u548c std::equal_to\u3002 \u867d\u7136\u4e24\u8005\u90fd\u662f\u4eff\u51fd\u6570\uff0c\u4f46\u4e5f\u6709\u5f88\u591a\u533a\u522b\uff1a hash \u53ea\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u800c equal_to \u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\u3002 hash \u8fd4\u56de size_t\uff0c\u800c equal_to \u8fd4\u56de bool \u7c7b\u578b\u3002 equal_to \u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u8c03\u7528\u8fd0\u7b97\u7b26 ==\u3002\u800c hash \u6ca1\u6709\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u4e5f\u6ca1\u76f8\u5e94\u7684\u8fd0\u7b97\u7b26\uff0c\u53ea\u80fd\u624b\u52a8\u7279\u5316\u3002 \u6b63\u56e0\u4e3a\u5982\u6b64\uff0c\u901a\u5e38\u6211\u4eec\u9700\u8981\u8ba9\u4e00\u4e2a\u7c7b\uff08\u4f8b\u5982 Student\uff09\u652f\u6301 equal_to \u6216 less \u8fd9\u4e9b\u6709\u76f8\u5e94\u8fd0\u7b97\u7b26\u7684\u4eff\u51fd\u6570\u65f6\uff0c\u76f4\u63a5\u5728\u7c7b\u578b\u5185\u90e8\u5b9a\u4e49 operator== \u6216 operator< \u5373\u53ef\uff0c\u800c hash \u5219\u662f\u53ea\u80fd\u7528\u7279\u5316\u7684\u65b9\u6cd5\u624d\u80fd\u652f\u6301\u4e0a\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template struct equal_to { bool operator()(T const &x, T const &y) const noexcept { return x == y; } }; \u6709\u4e9b\u7c7b\u578b\u80fd\u7528\u4f5c map \u7684\u952e\uff0c\u4f46\u4e0d\u80fd\u7528\u4f5c unordered_map \u7684\u952e\u3002\u8fd9\u662f\u56e0\u4e3a\u5077\u61d2\u7684\u6807\u51c6\u5e93\u6ca1\u5bf9\u4ed6\u4eec\u7684 hash \u7279\u5316\uff01 \u4f8b\u5982 tuple \u652f\u6301 < \u8fd0\u7b97\u7b26\uff0c\u652f\u6301 less\u3002 \u4f46\u662f tuple \u6ca1\u6709 hash \u7684\u7279\u5316\uff0c\u4e0d\u652f\u6301 hash\u3002 tuple tup; size_t h = hash>()(tup); // \u7f16\u8bd1\u671f\u62a5\u9519\uff1a\u67e5\u65e0\u6b64\u51fd\u6570\uff01 unordered_map> \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u548c less \u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u662f\u6709\u4e09\u79cd\u89e3\u51b3\u65b9\u6848\uff1a \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u7279\u5316\uff0cequal_to \u7684\u7279\u5316 template <> struct std::hash { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; template <> struct std::equal_to { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u4e00\u4e2a equal_to \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u7136\u540e\u4f20\u5165 unordered_map \u505a\u6a21\u677f\u53c2\u6570 template <> struct HashStudent { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; struct EqualStudent { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u6ce8\uff1a\u5982\u679c Student \u5df2\u7ecf\u5b9a\u4e49\u4e86 operator== \uff0c\u5219\u8fd9\u91cc\u4e0d\u7528 EqualStudent\uff0c\u9ed8\u8ba4\u7684 equal_to \u4f1a\u81ea\u52a8\u8c03\u7528 == \u8fd0\u7b97\u7b26\u7684\u3002 \u5bf9\u4e8e tuple \u800c\u8a00\uff0ctuple \u5df2\u7ecf\u6709\u4e86 == \u8fd0\u7b97\u7b26\uff0c\u4e0d\u7528\u7279\u5316 equal_to \u4e86\uff0c\u53ea\u9700\u8981\u7279\u5316\u6216\u6307\u5b9a hash \u5373\u53ef template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; unordered_map, int> stutab; \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); // \u628a\u4efb\u610f\u591a\u4e2a\u5143\u7d20\u54c8\u5e0c\u901a\u8fc7\u201c\u4f4d\u5f02\u6216(^)\u201d\u62fc\u51d1\u6210\u4e00\u4e2a\u5355\u72ec\u7684\u54c8\u5e0c } template struct std::hash> { size_t operator()(std::tuple const &x) const { // std::apply \u4f1a\u628a tuple \u91cc\u7684\u5143\u7d20\u5168\u90e8\u5c55\u5f00\u6765\u8c03\u7528 hash_combine\uff0c\u76f8\u5f53\u4e8e Python \u91cc\u7684 *args return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 106 \u8fd9\u91cc\u7684\u8ba1\u7b97\u662f\uff1a42 ^ 64 = 106\uff0c\u4f4d\u5f02\u6216\u7684\u77e5\u8bc6\u53ef\u4ee5\u53bb Bing \u641c\u7d22\u4e00\u4e0b\uff0c\u6216\u8005\u95ee\u4e00\u4e0b GPT\uff0cCS \u5b66\u751f\u5e94\u8be5\u90fd\u77e5\u9053\u7684\u3002 \u66f4\u597d\u7684 hash_combine \u4f46\u662f\u7b80\u7b80\u5355\u5355\u7528\u4e00\u4e2a\u4f4d\u5f02\u6216 ^ \u6765\u628a\u4e24\u4e2a\u6210\u5458\u7684\u54c8\u5e0c\u7ec4\u5408\u8d77\u6765\uff0c\u6709\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u5982\u679c tuple \u91cc\u7684\u4e24\u4e2a\u6210\u5458\u503c\u521a\u597d\u4e00\u6837\uff0c\u5219\u5176\u4e24\u4e2a\u54c8\u5e0c\u503c\u4e5f\u4f1a\u4e00\u6837\uff0c\u90a3\u4e48\u4ed6\u4eec\u901a\u8fc7\u4f4d\u5f02\u6216 ^ \u5408\u5e76\u7684\u7ed3\u679c\u5c31\u4f1a\u59cb\u7ec8\u4e3a 0\u3002 \u4f8b\u5982\u4e0d\u8bba (42, 42) \u8fd8\u662f (64, 64) \u8fd9\u4e24\u4e2a tuple\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u503c\u90fd\u4f1a\u4e3a 0\u3002\u660e\u660e\u5177\u4f53\u503c\u4e0d\u540c\u54c8\u5e0c\u503c\u5374\u76f8\u540c\uff0c\u8fd9\u5c31\u662f\u53d1\u751f\u4e86\u54c8\u5e0c\u51b2\u7a81\uff0c\u8fd9\u4f1a\u4e25\u91cd\u5f71\u54cd unordered_map \u7684\u6027\u80fd\uff0c\u662f\u5fc5\u987b\u907f\u514d\u7684\u3002 \u7528 + \u6765\u7ec4\u5408\u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u7b2c\u4e00\u4e2a\u6210\u5458\u521a\u597d\u662f\u53e6\u4e00\u4e2a\u7684\u76f8\u53cd\u6570\uff0c\u6216\u53ea\u8981\u662f\u4e24\u4e2a\u6570\u52a0\u8d77\u6765\u548c\u76f8\u7b49\uff0c\u5c31\u4f1a\u51b2\u7a81\u3002 \u4f8b\u5982\u5982\u679c\u6211\u4eec\u7528 unordered_map \u6784\u5efa\u4e00\u5f20\u5730\u56fe\u7684\u8bdd\uff0c\u5c31\u53d1\u73b0\u5f53\u73a9\u5bb6\u5728\u5f80\u659c\u4e0a\u65b9\u79fb\u52a8\u65f6\u5c31\u4f1a\u53d8\u5f97\u7279\u522b\u5361\u987f\uff0c\u539f\u6765\u662f\u56e0\u4e3a\u73a9\u5bb6\u7684\u5386\u53f2\u8f68\u8ff9\u521a\u597d\u662f\u4e00\u6761 y = x \u7684\u66f2\u7ebf\uff0c\u659c\u7387\u4e3a 1\uff0c\u7531\u4e8e\u6211\u4eec\u91c7\u7528 ^ \u6765\u7ec4\u5408\u54c8\u5e0c\uff0c\u5c31\u5bfc\u81f4\u521a\u597d\u8fd9\u6761\u7ebf\u4e0a\u6240\u6709\u7684\u70b9\u90fd\u4f1a\u584c\u7f29\u5230 0 \u53f7\u6876\u53bb\uff0c\u8ba9 unordered_map \u9000\u5316\u6210\u4e86 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 template inline size_t hash_combine(Ts const &...ts) { size_t h = 0; ((h ^= std::hash()(ts) + 0x9e3779b9 + (h << 6) + (h >> 2)), ...); return h; } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 175247763666 \u53ef\u4ee5\u770b\u5230\u968f\u673a\u6027\u5927\u5927\u63d0\u5347\u4e86\u3002 \u5e94\u7528 \u7528 hash_combine \u6539\u8fdb\u521a\u521a Student \u7684\u54c8\u5e0c\u51fd\u6570\u3002 template <> struct std::hash { bool operator()(Student const &x) const { return hash_combine(hash()(x.name), hash(x.id), hash(x.sex)); } }; \u540c\u7406\u53ef\u5f97 array \u7684\u7279\u5316 template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u7d20\u6570\u4e58\u65b9\u6cd5\u6765\u63d0\u5347\u54c8\u5e0c\u51fd\u6570\u7684\u5747\u5300\u6027\u548c\u968f\u673a\u6027\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h = h * 18412483 + hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u6700\u9ad8\u7ea7\u7684\uff0c\u57fa\u4e8e\u4f4d\u8fd0\u7b97\u7684\uff0c\u6700\u9ad8\u6548\u7684\uff0cboost::hash_combine \u7684\u5b9e\u73b0\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t) + 0x9e3779b9 + (h << 6) + (h >> 2); } return h; } }; unordered_map, int> stutab; \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 TODO map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API Student(Student &&) = delete; // \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u4e0b\u9762\u51e0\u4e2a\uff0c\u4e0d\u7528\u5199\u5168\uff1a // Student &operator=(Student &&) = delete; // Student(Student const &) = delete; // Student &operator=(Student const &) = delete; TODO \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 TODO \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 TODO \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 TODO \u672c\u671f\u5b5d\u70b9\u603b\u7ed3 \u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528 \u9a6c\u6876\u88c5\u9762\u5305 \u201c\u6790\u6784\u201d\u76f8\u4f9d1\u53f7 \u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55 \u770b\u5230\u8001\u9f20\ud83d\udca9\u8fc7\u6fc0\u53cd\u5e94 \u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b \u5c0f\u5b66\u751f\u65e9\u64cd\u6392\u961f \u5c0f\u9ec4\u82b1\u8868\u793a\u9ec4\u724c\u8b66\u544a \u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb http://c.biancheng.net/view/7236.html \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 https://en.cppreference.com/w/cpp/container/node_handle \u21a9 \u21a9 \u21a9 \u21a9","title":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec"},{"location":"stl_map/#stl-stdmap","text":"\u8ba9\u9ad8\u6027\u80fd\u6570\u636e\u7ed3\u6784\u60e0\u53ca\u6bcf\u4e00\u4eba STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \u8bfe\u7a0b\u4eae\u70b9 \u8bfe\u7a0b\u5927\u7eb2 \u5b9e\u9a8c\u73af\u5883 \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 map \u7684\u903b\u8f91\u7ed3\u6784 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 map \u7684\u7269\u7406\u7ed3\u6784 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u4e8c\u53c9\u6392\u5e8f\u6811 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u5e73\u8861\u6811 \u7ea2\u9ed1\u6811 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u603b\u7ed3 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type typename \u4fee\u9970 decltype \u5927\u6cd5\u597d \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f count \u548c contains \u6ca1\u533a\u522b end \u4e0d\u80fd\u89e3\u5f15\u7528 find \u7684\u597d\u5904 C++17 \u8bed\u6cd5\u7cd6 \u9898\u5916\u8bdd \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if insert_or_assign insert_or_assign \u7684\u4f18\u52bf \u6548\u7387\u95ee\u9898 [] insert_or_assign \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u6279\u91cf insert \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u5c31\u5730\u5199\u5165\uff01 \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 assign \u51fd\u6570 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u5206\u5974 emplace emplace_hint emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 try_emplace \u66f4\u597d try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u8c03\u7528\u5f00\u9500\u5206\u6790 try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace emplace \u5bb6\u65cf\u603b\u7ed3 map \u4e0e RAII \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u6539\u67e5 \u521d\u59cb\u5316 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract \u7528\u9014\u4e3e\u4f8b insert \u8282\u70b9\u7248 insert_return_type extract + insert \u8fd0\u7528\u6848\u4f8b extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 \u6279\u91cf insert vs merge merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 std::less \u7684\u4f5c\u7528 operator() \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u5efa\u8bae\u7528 function \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u795e\u5947\u7684 multimap \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 \u8bfe\u540e\u7ec3\u4e60 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u54c8\u5e0c\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d \u54c8\u5e0c\u51b2\u7a81 (hash-collision) unordered_map \u4e0e map \u7684\u5f02\u540c \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 hash \u548c equal_to \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 \u81ea\u52a8\u53d6\u6a21 hash \u662f\u4e2a trait \u7c7b \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 \u8d1f\u8f7d\u7387\uff08load_factor\uff09 rehash \u51fd\u6570 hash \u9700\u8981\u7279\u5316 \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 \u66f4\u597d\u7684 hash_combine \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 \u5e94\u7528 \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 \u672c\u671f\u5b5d\u70b9\u603b\u7ed3","title":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec"},{"location":"stl_map/#_1","text":"","title":"\u524d\u8a00"},{"location":"stl_map/#_2","text":"\ud83d\ude00\ud83d\ude00\ud83d\ude00 \u9762\u5411\u5df2\u7ecf\u4e86\u89e3\u4e00\u5b9a C++ \u8bed\u6cd5\uff0c\u6b63\u5728\u5b66\u4e60\u6807\u51c6\u5e93\u7684\u7ae5\u978b\u3002 C++ \u6807\u51c6\u5e93\u53c8\u79f0 STL\uff0c\u5305\u542b\u4e86\u5927\u91cf\u7a0b\u5e8f\u5458\u5e38\u7528\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\uff0c\u662f Bjarne Stroustrup \u9001\u7ed9\u6240\u6709 C++ \u7a0b\u5e8f\u5458\u7684\u4e00\u628a\u745e\u58eb\u519b\u5200\uff0c\u7136\u800c\u53d1\u73b0\u5f88\u591a\u7ae5\u978b\u5e76\u6ca1\u6709\u5b8c\u5168\u7528\u597d\u4ed6\uff0c\u53cd\u800c\u8fd8\u88ab\u5176\u590d\u6742\u6027\u8bef\u4f24\u4e86\u3002 \u5982\u679c\u4f60\u4e5f\u5bf9\u6807\u51c6\u5e93\u4e00\u77e5\u534a\u89e3\uff0c\u9700\u8981\u7cfb\u7edf\u5b66\u4e60\u7684\u8bdd\uff0c\u90a3\u4e48\u672c\u8bfe\u7a0b\u9002\u5408\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\u5c06\u8fd0\u7528\u4ed6\u7279\u6709\u7684\u5e7d\u9ed8\u7b54\u8fa9\u6bd4\u55bb\uff0c\u5168\u9762\u4ecb\u7ecd\u5404 STL \u5bb9\u5668\u7684\u6240\u6709\u7528\u6cd5\u3002\u7ed3\u5408\u4e00\u7cfb\u5217\u5b9e\u6218\u6848\u4f8b\uff0c\u5256\u6790\u5e38\u89c1\u5751\u70b9\uff0c\u4f7f\u7528\u6280\u5de7\u7b49\u3002\u5bf9\u6bd4\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u4e0e\u53ef\u8bfb\u6027\uff0c\u8fd8\u4f1a\u4e0e Python \u8bed\u8a00\u76f8\u4e92\u7c7b\u6bd4\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u79d1\u666e\u7684\u90e8\u5206\u51b7\u77e5\u8bc6\u53ef\u4ee5\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u52a0\u5206\u9879\u3002 \u672c\u8bfe\u7a0b\u53d7\u5230\u7ae5\u978b\u4e00\u81f4\u597d\u8bc4","title":"\u8bfe\u7a0b\u7b80\u4ecb"},{"location":"stl_map/#_3","text":"\ud83d\udc4d\ud83d\udc4d\ud83d\udc4d \u672c\u7cfb\u5217\u8bfe\u7a0b\u4e0e\u300a\u4faf\u6770\u8001\u5e08 STL \u8bfe\u300b\u7684\u533a\u522b\uff1a \u4faf\u6770\u8001\u5e08\u4ef7\u503c 2650 \u5143\uff0c\u672c\u8bfe\u7a0b\u5f55\u64ad\u4e0a\u4f20 B \u7ad9\u514d\u8d39\u89c2\u770b\uff0c\u89c2\u4f17\u53ef\u4ee5\u81ea\u884c\u9009\u62e9\u662f\u5426\u4e00\u952e\u4e09\u8fde\u3002 \u8bfe\u4ef6\u548c\u6848\u4f8b\u6e90\u7801\u5f00\u6e90\uff0c\u4e0a\u4f20\u5728 GitHub\uff0c\u53ef\u4ee5\u81ea\u5df1\u4e0b\u8f7d\u6765\u505a\u4fee\u6539\uff0c\u7136\u540e\u81ea\u5df1\u52a8\u624b\u5b9e\u9a8c\uff0c\u52a0\u6df1\u7406\u89e3\u3002 \u4faf\u6770\u8001\u5e08\u6ce8\u91cd\u7406\u8bba\u548c\u5e95\u5c42\u5b9e\u73b0\u539f\u7406\uff0c\u800c\u672c\u8bfe\u7a0b\u6ce8\u91cd\u5e94\u7528\uff0c\u7ed3\u5408\u5b9e\u6218\u6848\u4f8b\uff0c\u7740\u91cd\u5c55\u5f00\u91cd\u96be\u70b9\uff0c\u5751\u70b9\u7b49\u3002 \u5f88\u591a\u5b66\u6821\u91cc\u6559\u7684\uff0c\u767e\u5ea6\u4e0a\u641c\u7684\uff0c\u5927\u591a\u662f\u8001\u7248\u672c C++\uff0c\u5df2\u7ecf\u8fc7\u65f6\uff0c\u800c\u672c\u8bfe\u7a0b\u57fa\u4e8e\u8f83\u65b0\u7684 C++17 \u548c C++20 \u6807\u51c6\u3002 \u6709\u65f6\u5b58\u5728\u90e8\u5206 C++ \u9ad8\u7ea7\u7528\u6cd5\u8fc7\u4e8e\u8270\u6df1\uff0c\u4e0d\u80fd\u9002\u5408\u6240\u6709\u540c\u5b66\uff0c\u672c\u8bfe\u7a0b\u91c7\u7528\u56e0\u6750\u65bd\u6559\u601d\u60f3\uff1a\u5bf9\u4e8e\u65b0\u624b\uff0c\u53ef\u4ee5\u8df3\u8fc7\u770b\u4e0d\u61c2\u7684\u90e8\u5206\uff0c\u770b\u6211\u63d0\u4f9b\u7684\u201c\u4fdd\u5e95\u7528\u6cd5\u201d\uff0c\u4e0d\u4fdd\u8bc1\u9ad8\u6027\u80fd\u548c\u201c\u4f18\u96c5\u201d\uff0c\u4f46\u81f3\u5c11\u80fd\u7528\uff1b\u5bf9\u5b66\u6709\u4f59\u529b\u7684\u7ae5\u978b\uff0c\u5219\u53ef\u4ee5\u640f\u4e00\u640f\u4e0a\u9650\uff0c\u628a\u9ad8\u7ea7\u7528\u6cd5\u4e5f\u770b\u61c2\uff0c\u63d0\u5347\u9762\u8bd5\u7ade\u4e89\u529b\u3002\u603b\u4e4b\u4e0d\u8bba\u4f60\u662f\u54ea\u4e2a\u9636\u6bb5\u7684\u5b66\u4e60\u8005\uff0c\u90fd\u80fd\u4ece\u6b64\u8bfe\u7a0b\u4e2d\u83b7\u76ca\u3002","title":"\u8bfe\u7a0b\u4eae\u70b9"},{"location":"stl_map/#_4","text":"\u2728\u2728\u2728 \u4e4b\u524d\u51e0\u671f\u8bfe\u7a0b\u7684\u5f55\u64ad\u5df2\u7ecf\u4e0a\u4f20\u5230\u6bd4\u7ad9\u4e86 1 \u3002 vector \u5bb9\u5668\u521d\u4f53\u9a8c & \u8fed\u4ee3\u5668\u5165\u95e8 (BV1qF411T7sd) \u4f60\u6240\u4e0d\u77e5\u9053\u7684 set \u5bb9\u5668 & \u8fed\u4ee3\u5668\u5206\u7c7b (BV1m34y157wb) string\uff0cstring_view\uff0cconst char * \u7684\u7231\u6068\u7ea0\u845b (BV1ja411M7Di) \u4e07\u80fd\u7684 map \u5bb9\u5668\u5168\u5bb6\u6876\u53ca\u5176\u5999\u7528\u4e3e\u4f8b (\u672c\u671f) \u51fd\u5b50 functor \u4e0e lambda \u8868\u8fbe\u5f0f\u77e5\u591a\u5c11 \u901a\u8fc7\u5b9e\u6218\u6848\u4f8b\u6765\u5b66\u4e60 STL \u7b97\u6cd5\u5e93 C++ \u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6d41 & \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 traits \u6280\u672f\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u8fed\u4ee3\u5668\u4e0e\u7b97\u6cd5 allocator\uff0c\u5185\u5b58\u7ba1\u7406\u4e0e\u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u5f02\u5e38\u5904\u7406\u673a\u5236\u7684\u524d\u4e16\u4eca\u751f","title":"\u8bfe\u7a0b\u5927\u7eb2"},{"location":"stl_map/#_5","text":"\u2705\u2705\u2705 \u5c0f\u5f6d\u8001\u5e08\u4e2a\u4eba\u63a8\u8350\u5b9e\u9a8c\u73af\u5883\u5982\u4e0b\uff1a \u8981\u6c42 \u2764\u2764\u2764 \ud83d\udca3\ud83d\udca3\ud83d\udca3 \ud83d\udca9\ud83d\udca9\ud83d\udca9 \ud83d\udc80\ud83d\udc80\ud83d\udc80 \u64cd\u4f5c\u7cfb\u7edf Arch Linux Ubuntu 20.04 Wendous 10 Maike OS \u77e5\u8bc6\u50a8\u5907 \u4f1a\u4e00\u70b9 C++ \u5927\u5b66 C \u8bed\u8a00 Java \u9762\u5411\u5bf9\u8c61 \u7f16\u7a0b\u5c0f\u767d \u7f16\u8bd1\u5668 GCC 9 \u4ee5\u4e0a Clang 12 VS2019 Apple Clang \u6784\u5efa\u7cfb\u7edf CMake 3.18 \u4efb\u610f C++ IDE \u5355\u6587\u4ef6\u7f16\u8bd1\u8fd0\u884c \u547d\u4ee4\u884c\u624b\u52a8\u7f16\u8bd1 \u7f16\u8f91\u5668 Vim/NeoVim CLion VS Code notepad \u6e38\u620f\u96be\u5ea6\uff1a\u2764 = \u7b80\u5355\uff0c\ud83d\udca3 = \u666e\u901a\uff0c\ud83d\udca9 = \u56f0\u96be\uff0c\ud83d\udc80 = \u5730\u72f1\u526f\u672c","title":"\u5b9e\u9a8c\u73af\u5883"},{"location":"stl_map/#_6","text":"\ud83e\udd70\ud83e\udd70\ud83e\udd70 \u672c\u671f\u5b9e\u9a8c\u6e90\u7801\u5747\u516c\u5e03\u5728\uff1ahttps://github.com/parallel101/course/tree/master/slides/stl_map/experiment/ \u4f8b\u5982\u672c\u671f\u7684\u8bfe\u4ef6\u4f4d\u4e8e course/stlseries/stl_map/slides.md \u3002 \u8bfe\u4ef6\u57fa\u4e8e Mkdocs \u5f00\u53d1\uff0cMarkdown \u683c\u5f0f\u4e66\u5199\uff0c\u5728\u6d4f\u89c8\u5668\u4e2d\u663e\u793a\uff0c\u5728\u672c\u5730\u8fd0\u884c\u8bfe\u4ef6\u9700\u8981 Mkdocs \u73af\u5883\uff1a \u8fd0\u884c\u547d\u4ee4 pip install -r requirements.txt \u5373\u53ef\u81ea\u52a8\u5b89\u88c5 Mkdocs \u7b49\u6240\u9700\u4f9d\u8d56 \u8fd0\u884c\u547d\u4ee4 mkdocs serve \u5373\u53ef\u8fd0\u884c Mkdocs \u670d\u52a1 \u6d4f\u89c8\u5668\u8bbf\u95ee http://127.0.0.1:8000 \u5373\u53ef\u770b\u5230\u8bfe\u4ef6 \u5982\u679c\u4e0d\u60f3\u81ea\u5df1\u914d\u7f6e Mkdocs \u4e5f\u53ef\u4ee5\u76f4\u63a5\u4ee5\u6587\u672c\u6587\u4ef6\u683c\u5f0f\u6253\u5f00 docs/stl_map.md \u6d4f\u89c8\u8bfe\u4ef6\u3002 Mkdocs \u670d\u52a1\u8fd0\u884c\u65f6\uff0c\u4f60\u5bf9 docs/stl_map.md \u7684\u6240\u6709\u4fee\u6539\u4f1a\u7acb\u523b\u5b9e\u65f6\u663e\u73b0\u5728\u6d4f\u89c8\u5668\u4e2d\u3002","title":"\u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6"},{"location":"stl_map/#_7","text":"\ud83e\udd7a\ud83e\udd7a\ud83e\udd7a \u6848\u4f8b\u6e90\u7801\u548c\u6240\u9700\u5934\u6587\u4ef6\u4f4d\u4e8e\u8bfe\u4ef6\u540c\u76ee\u5f55\u7684 course/stlseries/stl_map/experiment/ \u6587\u4ef6\u5939\u4e0b\u3002 \u5176\u4e2d main.cpp \u4ec5\u5bfc\u5165\u8fd0\u884c\u6848\u4f8b\u6240\u9700\u7684\u5934\u6587\u4ef6\uff0c\u5177\u4f53\u5404\u4e2a\u6848\u4f8b\u4ee3\u7801\u5206\u5e03\u5728 slides.md \u91cc\u3002 \u5982\u9700\u6d4b\u8bd5\u8bfe\u4ef6\u4e2d\u7684\u5177\u4f53\u4ee3\u7801\uff0c\u53ef\u4ee5\u628a slides.md \u4e2d\u7684\u6848\u4f8b\u4ee3\u7801\u7c98\u8d34\u5230 main.cpp \u7684 main \u51fd\u6570\u4f53\u4e2d\u8fdb\u884c\u5b9e\u9a8c\u3002 \u6b64\u5916\u4e3a\u4e86\u65b9\u4fbf\uff0c\u8fd8\u6709\u4e00\u4e9b\u5f62\u5982 testxxx.cpp \u7684\u6587\u4ef6\u662f\u4e00\u4e9b\u5b8c\u6574\u7684\u6d4b\u8bd5\u6848\u4f8b\uff0c\u4e0d\u7528\u4ece slides.md \u4e2d\u62f7\u8d1d\uff0c\u53ef\u76f4\u63a5\u5355\u72ec\u8fd0\u884c\u3002 \u4e3a\u4e86\u65b9\u4fbf\u540c\u5b66\u4eec\u5b9e\u9a8c\uff0c\u6240\u9700\u5934\u6587\u4ef6\u90fd\u5728\u540c\u4e00\u4e2a\u76ee\u5f55\uff0c\u6ca1\u6709\u7b2c\u4e09\u65b9\u5e93\u4f9d\u8d56\u3002\u65e2\u53ef\u4ee5\u7528 CMake \u6784\u5efa\uff0c\u4e5f\u53ef\u4ee5\u7528\u4efb\u610f\u81ea\u5df1\u559c\u6b22\u7684 IDE \u6216\u7f16\u8f91\u5668 \u5355\u6587\u4ef6\u7f16\u8bd1 \u8fd0\u884c\uff0c\u65e0\u5f3a\u5236\u8981\u6c42\uff0c\u53ea\u9700\u7f16\u8bd1\u5668\u652f\u6301 C++17 \u5373\u53ef\u3002 \u5982\u679c\u4f60\u7528 Visual Studio \u81ea\u5df1\u7684 sln \u7cfb\u7edf\u6784\u5efa\u9879\u76ee\uff0c\u8bb0\u5f97\u5f00\u542f /std:c++17 \u9009\u9879\u3002\u5982\u679c\u4f60\u7528\u6700\u65b0\u7684 Visual Studio\uff08\u5df2\u7ecf\u652f\u6301 CMake\uff09\u5219\u76f4\u63a5\u9009\u62e9\u201c\u6253\u5f00\u6587\u4ef6\u5939\u201d\u6253\u5f00\u672c\u9879\u76ee\u7684 experiment \u76ee\u5f55\u5373\u53ef\u3002 \u5728\u5b9e\u9a8c\u6e90\u7801\u4ed3\u5e93\u4e2d\uff0c\u9644\u8d60\u4e86\u4e00\u4e9b\u5b9e\u7528\u5934\u6587\u4ef6\uff0c\u540c\u978b\u4eec\u53ef\u4ee5\u4e0b\u8f7d\u6765\u7814\u7a76\uff0c\u6216\u8005\u5728\u81ea\u5df1\u7684\u9879\u76ee\u91cc\u968f\u610f\u8fd0\u7528\u3002 \u6587\u4ef6\u540d \u529f\u80fd print.h \u5185\u542b print \u51fd\u6570\uff0c\u652f\u6301\u6253\u5370\u7edd\u5927\u591a\u6570 STL \u5bb9\u5668\uff0c\u65b9\u4fbf\u8c03\u8bd5 map_get.h \u5e26\u9ed8\u8ba4\u503c\u7684 map \u8868\u9879\u67e5\u8be2\uff0c\u7a0d\u540e\u8bfe\u7a0b\u4e2d\u4f1a\u4ecb\u7ecd\u5230 ScopeProfiler.h \u57fa\u4e8e RAII \u7684\u51fd\u6570\u8017\u65f6\u7edf\u8ba1\uff0c\u7528\u4e8e\u6d4b\u91cf\u6027\u80fd OrderedMap.h \u904d\u5386\u987a\u5e8f\u59cb\u7ec8\u4fdd\u6301\u548c\u63d2\u5165\u987a\u5e8f\u4e00\u81f4\u7684\u9b54\u6539\u7248 map cppdemangle.h \u83b7\u5f97\u7c7b\u578b\u7684\u540d\u5b57\uff0c\u4ee5\u6a21\u677f\u53c2\u6570\u4f20\u5165\uff0c\u8be6\u89c1\u8be5\u6587\u4ef6\u4e2d\u7684\u6ce8\u91ca hash.h \u6bd4 std::hash \u66f4\u901a\u7528\u7684 generic_hash \u5b9e\u73b0\uff0c\u652f\u6301\u4efb\u610f\u533a\u95f4\u548c\u5143\u7ec4 bits_stdc++.h \u4eff\u7167 bits/stdc++.h \u7684\u4e07\u80fd\u5934\u6587\u4ef6\u8de8\u5e73\u53f0\u7248\uff0c\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5e93","title":"\u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801"},{"location":"stl_map/#_8","text":"int const &i // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef const int& i // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef template // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef template // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef \u4ec5\u4e3a\u4e2a\u4eba\u4e66\u5199\u4e60\u60ef\u4e0d\u540c\uff0c\u5728 C++ \u7f16\u8bd1\u5668\u770b\u6765\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u6211\u559c\u6b22\u628a const \u540e\u7f6e\uff0c\u5176\u4e00\u662f\u56e0\u4e3a\u8fd9\u6709\u5229\u4e8e\u7406\u89e3 int const * \u548c int *const \u7684\u533a\u522b\uff0c\u5982\u679c\u5199\u6210 const int * \u5c31\u4f1a\u5f88\u56f0\u60d1 const \u7a76\u7adf\u662f\u4fee\u9970\u8c01\u7684\uff0c\u800c\u7528\u6211\u7684\u5199\u6cd5\u53ea\u9700\u8981\u7b80\u5355\u7406\u89e3\u4e3a \u201cconst \u53ea\u4fee\u9970\u4ed6\u524d\u9762\u7684\u201d\u3002\u5176\u4e8c\u6211\u7ecf\u5e38\u9700\u8981\u628a\u51fd\u6570\u53c2\u6570\u4e2d T t \u4fee\u6539\u6210 T const &t \u3002\u8fde\u5728\u4e00\u8d77\u52a0\u8d77\u6765\u6bd4\u8f83\u65b9\u4fbf\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6027\u63d2\u5165 const & \u5373\u53ef\uff0c\u4e0d\u7528\u524d\u540e\u4e24\u4e2a\u5730\u65b9\u5206\u522b\u52a0 const \u548c & \uff0c\u4f60\u89c9\u5f97\u5462\uff1f using namespace std; // \u4ec5\u4e3a\u6559\u5b66\u65b9\u4fbf\u76ee\u7684\uff0c\u4e0d\u5efa\u8bae\u5728\u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4f7f\u7528 \u26a0\ufe0f \u7531\u4e8e\u4f7f\u7528\u4e86 using namespace std \uff0c\u672c\u8bfe\u7a0b\u4ee3\u7801\u4e2d\u7684 std:: \u524d\u7f00\u5747\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a map> m; erase_if(m, pred); \u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4e0d\u5efa\u8bae using namespace std \uff0c\u8bf7\u663e\u5f0f\u5199\u51fa std:: \u524d\u7f00\uff1a std::map> m; std::erase_if(m, pred); \u6211\u4eec\u81ea\u5df1\u505a\u6d4b\u8bd5\u65f6\u7ecf\u5e38\u4f1a\u7528 \u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u3002 \u53ef\u60dc\u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u5728 VS \u4e2d\u4f3c\u4e4e\u4e0d\u5b58\u5728 1 \uff0c\u56e0\u6b64\u6211\u81ea\u5df1\u5199\u4e86\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 \"bits_stdc++.h\" \u653e\u5728\u6e90\u7801\u540c\u76ee\u5f55\uff1a #include \"bits_stdc++.h\" // \u81ea\u52a8\u5bfc\u5165\u6240\u6709\u6807\u51c6\u5e93\u7684\u5934\u6587\u4ef6 \u4e0d\u8fc7\u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u8fd8\u662f\u5efa\u8bae\u6839\u636e\u9700\u8981\u4e00\u4e2a\u4e2a\u5bfc\u5165\uff0c\u4e0d\u8981\u5077\u61d2\u7528\u8fd9\u4e2a\u4e0d\u6807\u51c6\u7684\u5934\u6587\u4ef6\uff1a #include // \u5bfc\u5165 std::map, std::multimap #include // \u5bfc\u5165 std::unordered_map, std::unordered_multimap #include // \u5bfc\u5165 std::string, std::wstring #include // \u5bfc\u5165 std::set_difference, std::set_union, std::set_intersection \u7b49\u4e00\u7cfb\u5217\u5168\u5c40\u51fd\u6570 // \u4e0b\u9762\u4ee3\u7801\u4e2d\u7528\u5230\u54ea\u4e9b\u5bb9\u5668\uff0c\u5c31\u5bfc\u5165\u54ea\u4e9b\u5934\u6587\u4ef6","title":"\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e"},{"location":"stl_map/#_9","text":"","title":"\u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6"},{"location":"stl_map/#_10","text":"\u6709\u4e00\u6b21\u4e00\u4e2a\u540c\u5b66\u53d1\u7ed9\u6211\u4e00\u4efd\u6e90\u7801\u6587\u4ef6 tetreader.py\uff0c\u5176\u529f\u80fd\u662f\u8bfb\u53d6\u4e00\u4e2a tet \u683c\u5f0f\u7684\u6587\u4ef6\uff08\u56db\u9762\u4f53\u7f51\u683c\u6a21\u578b\uff09\u3002 \u4ed6\u95ee\u6211\u4e3a\u4ec0\u4e48\u4ed6\u5199\u7684\u8fd9\u4e2a Python \u4ee3\u7801\u8fd9\u4e48\u6162\uff0c\u8bfb\u53d6\u4e00\u4e2a\u7a0d\u5fae\u5927\u4e00\u70b9\u7684\u6a21\u578b\u5c31\u9700\u8981\u597d\u51e0\u79d2\uff0c\u4ed6\u8bf4\u4e45\u4ef0\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u4f18\u5316\u7684\u5927\u540d\uff0c\u60f3\u8981\u6211\u5e2e\u4ed6\u4f18\u5316\u4e00\u4e0b\uff0c\u8fd8\u95ee\u662f\u4e0d\u662f\u5e94\u8be5\u7528 C++ \u5199\u4f1a\u6bd4\u8f83\u9ad8\u6548\u4e00\u70b9\uff1f \u6211\u5e76\u4e0d\u61c2\u5f97\u56db\u9762\u4f53\uff0c\u4f46\u6027\u80fd\u4f18\u5316\u7684\u601d\u8def\u662f\u901a\u7528\u7684\u3002\u6211\u6253\u5f00\u6587\u4ef6\u770b\u4e86\u4e00\u4e0b\uff0c\u6211\u53d1\u73b0\u4ed6\u8bfb\u53d6\u65f6\u9700\u8981\u67e5\u8be2\u4e00\u4e2a\u70b9\u5468\u56f4\u6240\u6709\u7684\u9762\uff0c\u4ed6\u662f\u8fd9\u6837\u67e5\u8be2\u7684\uff1a # \u4ee5\u4e0b\u4e3a\u4ed6\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = [] for ... in ...: face_lut.append(vert_id) # O(1) \u2705 for ... in ...: face_id = face_lut.index(vert_id) # O(N) \u26a0\ufe0f \u6211\u8bf4\u4f60\u8fd9\u4e2a face_lut \u662f\u4e2a\u666e\u901a\u6570\u7ec4\uff0c\u6570\u7ec4\u7684 index \u51fd\u6570\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u4f60\u4e0d\u77e5\u9053\u5417\uff1f\u4ed6\u76f8\u5f53\u4e8e\u66b4\u529b\u904d\u5386\u4e86\u6570\u7ec4\u627e\u5230\u4f60\u9700\u8981\u7684\u503c\uff0c\u4f60\u8fd9\u4e2a index \u7684\u8c03\u7528\u8fd8\u662f\u5728\u4e00\u4e2a\u5faa\u73af\u91cc\u7684\uff0c\u6240\u4ee5\u662f O(N^2) O(N^2) \u590d\u6742\u5ea6\uff01\u96be\u602a\u8fd9\u4e48\u6162\u4e86\u3002 \u540e\u6765\u6211\u7ed9\u4ed6\u6539\u4e86\u4e00\u4e0b\uff0c\u628a\u4ed6\u7684 face_lut \u6539\u6210\u5b57\u5178\uff0c\u7528\u5b57\u5178\u67e5\u627e\uff0c\u9ad8\u6548\u5f97\u591a\u4e86\uff1a # \u4ee5\u4e0b\u4e3a\u6211\u4f18\u5316\u540e\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = {} for ... in ...: face_lut[vert_id] = face_id # O(1)+ \u2705 for ... in ...: face_id = face_lut[vert_id] # O(1)+ \u2705 \u4e00\u6b21\u5b57\u5178\u7684\u67e5\u8be2\u53ea\u9700\u8981 O(1)+ O(1)+ \uff0c\u52a0\u4e0a\u4ed6\u5916\u9762\u7684\u5faa\u73af\u603b\u5171\u53ea\u6709 O(N) O(N) \uff0c\u53d8\u6210\u7ebf\u6027\u590d\u6742\u5ea6\u4e86\u3002\u4ed6\u4e00\u8bd5\uff0c\u679c\u7136\u51e0\u6beb\u79d2\u5c31\u52a0\u8f7d\u5b8c\u4e86\uff0c\u6211\u8bf4\u7528\u5b57\u5178\u52a0\u901f\u67e5\u627e\u8fd9\u4e0d\u662f\u5e38\u8bc6\u5417\uff1f\u8fd8\u6401\u7740 C++ \u5462\uff1f\u4f60\u5c31\u662f CUDA \u6765\u4e86\u4e5f\u538b\u4e0d\u4f4f\u590d\u6742\u5ea6\u7684\u7206\u8868\u5440\uff1f \u4ed6\u5f88\u9ad8\u5174\uff0c\u4e0d\u77e5\u9053\u600e\u4e48\u611f\u8c22\u6211\uff0c\u4e8e\u662f\u5c31\u628a\u6211\u63a8\u8350\u7ed9\u5f20\u5fc3\u6b23\u4e86\u3002","title":"\u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b"},{"location":"stl_map/#_11","text":"\u4e0d\u8bba\u4ec0\u4e48\u8bed\u8a00\uff0c\u5bb9\u5668\uff08\u6216\u8005\u7528\u5b66\u6821\u91cc\u7684\u8bdd\u8bf4\uff1a\u6570\u636e\u7ed3\u6784\uff09\u7684\u6b63\u786e\u4f7f\u7528\uff0c\u80fd\u591f\u5728\u590d\u6742\u5ea6\u5c42\u9762\u4e0a\uff0c\u5927\u5e45\u63d0\u5347\u6027\u80fd\u3002 C++ \u4e2d\u4e5f\u662f\u5982\u6b64\uff0c\u6709\u6570\u7ec4\uff08vector\uff09\uff0c\u5b57\u5178\uff08map\uff09\uff0c\u8fd8\u6709\u4e0a\u4e00\u8bfe\u8bb2\u8fc7\u7684\u96c6\u5408\uff08set\uff09\u3002 \u4eca\u5929\u6211\u4eec\u8981\u4ecb\u7ecd\u7684\u5c31\u662f C++ \u7684\u5b57\u5178\u5bb9\u5668 map\uff0c\u4ee5\u53ca C++11 \u5f15\u5165\u7684\u53e6\u4e00\u4e2a\u5b57\u5178\u5bb9\u5668 unordered_map\uff0c\u4ed6\u4eec\u7684\u533a\u522b\u6211\u4eec\u6700\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u3002\u6211\u4eec\u5148\u5b66\u4e60\u8f83\u4e3a\u7b80\u5355\u7684 map\uff0c\u968f\u540e\u5b66\u4e60 unordered_map \u65f6\u4e5f\u53ef\u4ee5\u4e3e\u4e00\u53cd\u4e09\u3001\u878d\u4f1a\u8d2f\u901a\u3002 \u4ecb\u7ecd\u5b8c\u8fd9\u4e24\u4e2a\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u5b57\u5178\u5bb9\u5668\u540e\uff0c\u6211\u4eec\u8fd8\u5c06\u4ecb\u7ecd\u4e00\u4e9b\u5e38\u7528\u7684\u7b2c\u4e09\u65b9\u5e93\u5bb9\u5668\uff0c\u4f8b\u5982 absl::flat_hash_map\u3001tbb::concurrent_hash_map\u3001google::dense_hash_map\u3001robin_hood::unordered_map\u3001tsl::robin_pg_map \u7b49\uff0c\u9700\u8981\u6839\u636e\u5e94\u7528\u573a\u666f\u9009\u62e9\u9002\u5408\u7684\u5bb9\u5668\u3002 map/set \u5bb6\u65cf\u90fd\u662f\u9ad8\u6548\u67e5\u627e\u7684\u4e13\u5bb6\uff1a vector \u5bb9\u5668\u7528 std::find \u67e5\u627e\uff1a O(N) O(N) map \u6216 set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(\\log N) O(\\log N) unordered_map \u6216 unordered_set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(1)+ O(1)+ \u4e0d\u4ec5\u662f\u67e5\u627e\uff0cmap \u4eec\u8fd8\u652f\u6301\u9ad8\u6548\u7684\u589e\u5220\u6539\u67e5\u7b49\u64cd\u4f5c\u3002","title":"\u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6"},{"location":"stl_map/#map","text":"\u7279\u70b9\uff1a \u7531\u4e00\u7cfb\u5217 \u952e\u503c\u5bf9 \u7ec4\u6210 \u4e00\u4e2a\u952e\u53ea\u80fd\u5bf9\u5e94\u4e00\u4e2a\u503c \u952e\u4e0d\u5f97\u91cd\u590d\uff0c\u503c\u53ef\u4ee5\u91cd\u590d std::map, std::unordered_map, absl::flat_hash_map, tbb::concurrent_hash_map \u90fd\u6ee1\u8db3\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u4e00\u57fa\u672c\u903b\u8f91\u7ed3\u6784\uff0c\u53ea\u662f\u7269\u7406\u5b9e\u73b0\u4e0d\u540c\u3002 \u9762\u58c1\u8005\u7f57\u8f91\u76d1\u7763\u4f60\u7684\u5b66\u4e60\uff01 \u5728\u7f16\u7a0b\u4e2d\u6211\u4eec\u5e38\u5e38\u9700\u8981\u7528\u5230\u201c\u6620\u5c04\u201d\u7684\u5173\u7cfb\uff0c\u8fd9\u5c31\u975e\u5e38\u9700\u8981\u7528\u5230\u4ee5 map \u4e3a\u9996\u7684\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u7c7b\u5bb9\u5668\u4e86\u3002","title":"map \u7684\u903b\u8f91\u7ed3\u6784"},{"location":"stl_map/#stdmap","text":"map \u7684\u5177\u4f53\u5b9e\u73b0\u53ef\u4ee5\u662f\u7ea2\u9ed1\u6811\u3001AVL \u6811\u3001\u7ebf\u6027\u54c8\u5e0c\u8868\u3001\u94fe\u8868\u54c8\u5e0c\u8868\u3001\u8df3\u8868\u2026\u2026\u4e0d\u540c\u7684\u5b9e\u73b0\u5728\u4e0d\u540c\u64cd\u4f5c\u4e0a\u7684\u590d\u6742\u5ea6\u4e0d\u540c\uff0c\u5206\u522b\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u666f\u3002 \u7528\u6cd5\u4e0a\u51e0\u4e4e\u662f\u5dee\u4e0d\u591a\u7684\uff0c\u4ed6\u4eec\u90fd\u6709\u7740\u51e0\u4e4e\u76f8\u540c\u7684\u63a5\u53e3\uff08\u9664\u4e86\u90e8\u5206\u6269\u5c55\u529f\u80fd\uff09\u3002\u5f53\u4f60\u89c9\u5f97\u7ea2\u9ed1\u6811\u7684 std::map \u4e0d\u5408\u9002\u65f6\uff0c\u53ef\u4ee5\u8f7b\u677e\u628a\u5bf9\u8c61\u7c7b\u578b\u5c31\u5730\u66ff\u6362\u4e3a\u94fe\u8868\u54c8\u5e0c\u8868 std::unordered_map \u6216\u662f\u662f\u7ebf\u6027\u54c8\u5e0c\u8868 absl::flat_hash_map\uff0c\u800c\u4e0d\u7528\u5bf9\u5176\u4ed6\u4ee3\u7801\u6709\u4efb\u4f55\u66f4\u6539\u3002 \u8fd9\u5c31\u662f\u6240\u6709 map \u7c7b\u5bb9\u5668\u90fd\u6709\u7740\u76f8\u540c\u7684 \u903b\u8f91\u7ed3\u6784 \uff1a\u90fd\u662f\u4e00\u4e2a\u952e-\u503c\u6620\u5c04\uff0c\u4e0d\u540c\u7684\u53ea\u662f\u4ed6\u4eec\u7684 \u7269\u7406\u7ed3\u6784 \u800c\u5df2\u3002 \u6240\u6709\u7684 map \u5b9e\u73b0\uff0c\u90fd\u4f1a\u6a21\u4eff\u63d0\u4f9b\u548c std::map \u4e00\u6837\u7684 API\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u867d\u7136 std::map \u5b9e\u73b0\u7684\u5f88\u4f4e\u6548\uff0c\u6211\u4eec\u8fd8\u662f\u8981\u5b66\u4ed6\u7684\u539f\u56e0\u3002std::map \u672c\u8eab\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\uff0c\u4f46\u5374\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6240\u6709\u7b2c\u4e09\u65b9\u90fd\u4f1a\u9075\u5faa\u7684\u7edf\u4e00\u63a5\u53e3\u3002\u5b66\u4f1a\u4e86 std::map\uff0c\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93\u7684 map \u7c7b\u5bb9\u5668\u4f60\u90fd\u53ef\u4ee5\u8f7b\u6613\u4e3e\u4e00\u53cd\u4e09\u3002 \u4e0d\u4ec5\u662f\u5404\u79cd\u7b2c\u4e09\u65b9\u7684 map \u5e93\uff0c\u6bd4\u5982 rapidjson \u5e93\u4e2d\u7684 JSON \u5bf9\u8c61\uff0c\u4e5f\u63d0\u4f9b\u4e86\u7c7b\u4f3c std::map \u7684 find \u548c end \u8fed\u4ee3\u5668\u63a5\u53e3\uff1a MemberFind \u548c MemberEnd \uff0c\u6765\u67e5\u627e\u4e00\u4e2a\u5b57\u5178\u7684\u5b50\u952e\uff1b\u51e0\u4f55\u5904\u7406\u5e93 cgal \u4e2d\u7684\u201c\u9876\u70b9\u67e5\u627e\u201d\u529f\u80fd\u4e5f\u662f\u57fa\u4e8e\u7c7b\u4f3c\u7684\u8fed\u4ee3\u5668\u63a5\u53e3\u3002\u603b\u4e4b\uff0c\u5b66\u4f1a std::map \u5c06\u5927\u5927\u6709\u52a9\u4e8e\u4f60\u770b\u61c2\u8fd9\u7c7b\u4e1a\u754c\u516c\u8ba4\u7684\u63a5\u53e3\u89c4\u8303\u3002","title":"\u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map"},{"location":"stl_map/#map_1","text":"\u6807\u51c6\u5e93\u4e2d\uff0cmap 1 \u662f\u4e00\u4e2a \u6a21\u677f\u7c7b \uff0c\u4ed6\u7684\u952e\u7c7b\u578b\uff0c\u503c\u7c7b\u578b\uff0c\u53ef\u4ee5\u7531\u5c16\u62ec\u53f7\u5185\u7684\u53c2\u6570\u6307\u5b9a\uff0c\u4fbf\u4e8e\u9002\u5e94\u4e0d\u540c\u7684\u7528\u6237\u9700\u6c42\u3002 \u7531\u4e8e C++ \u6807\u51c6\u5e93\u7684\u5bb9\u5668\u5927\u591a\u90fd\u662f\u6a21\u677f\u7c7b\uff0c\u63d0\u4f9b\u7684\u7b97\u6cd5\u4e5f\u5927\u591a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u56e0\u6b64 C++ \u6807\u51c6\u5e93\u5e38\u88ab\u79f0\u4e3a\u6807\u51c6\u6a21\u677f\u5e93 (Standard-Template-Library, STL)\u3002 \u952e\u7c7b\u578b\u548c\u503c\u7c7b\u578b\u53ef\u4ee5\u662f\u4efb\u610f\u7c7b\u578b\uff0c\u5305\u62ec\u57fa\u672c\u7c7b\u578b\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u7c7b\uff0c\u5176\u4ed6 STL \u5bb9\u5668\u7b49\uff0c\u4f53\u73b0\u4e86\u5bb9\u5668\u7684\u6cdb\u7528\u6027\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\uff1a\u952e\u5fc5\u987b\u652f\u6301\u6bd4\u8f83\uff0c\u8fd9\u91cc map \u8981\u6c42\u7684\u662f\u5c0f\u4e8e\u8fd0\u7b97\u7b26 < \u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a string\uff0c\u503c\u7c7b\u578b\u4e3a int \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a int\uff0c\u503c\u7c7b\u578b\u4e3a Student \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map> \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a char\uff0c\u503c\u7c7b\u578b\u4e3a vector \u7684 map \u5bb9\u5668\u3002 \u540e\u9762\u4e3a\u4e86\u65b9\u4fbf\u7814\u7a76\uff0c\u4ee5 map \u5f62\u5f0f\u4e66\u5199\u5f97\u51fa\u7684\u7ed3\u8bba\uff0c\u5bf9\u4e8e\u4efb\u4f55\u5b9e\u9645\u952e\u548c\u503c\u7c7b\u578b\uff0c\u53ea\u9700\u4ee3\u5165 K \u548c V \u5373\u53ef\u3002 \u5df2\u77e5\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 K \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < \u3002 \u53ef\u5f97\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 string \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < 2 \u3002 \u5df2\u77e5\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e K \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 \u53ef\u5f97\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e int \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002","title":"\u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668"},{"location":"stl_map/#map_2","text":"map \u548c set \u4e00\u6837\uff0c\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u5b9e\u73b0 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u9ad8\u6548\u67e5\u627e\u3002 vector \u5c31\u662f\u56e0\u4e3a\u5143\u7d20\u6ca1\u6709\u56fa\u5b9a\u7684\u987a\u5e8f\uff0c\u6240\u4ee5\u624d\u9700\u8981\u66b4\u529b\u904d\u5386\u67e5\u627e\u3002 \u5728\u6301\u7eed\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u4e0b\uff0c\u59cb\u7ec8\u7ef4\u6301\u5143\u7d20\u7684\u6709\u5e8f\u6027\uff0c\u6b63\u662f map \u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\u7684\u5173\u952e\u6240\u5728\u3002","title":"map \u7684\u7269\u7406\u7ed3\u6784"},{"location":"stl_map/#_12","text":"\u59cb\u7ec8\u4fdd\u5b58\u5143\u7d20\u6309\u952e\u6392\u5e8f\u7684\u597d\u5904\u662f\uff0c\u5982\u679c\u9700\u8981\u5bfb\u627e\u6307\u5b9a\u952e\u503c\u7684\u5143\u7d20\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u4e8c\u5206\u6cd5\uff1a \u4ece\u6839\u8282\u70b9\u5f00\u59cb\u67e5\u627e\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5c0f\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u5de6\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5927\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u53f3\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u7b49\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u8be5\u8282\u70b9\u5c31\u662f\u8981\u627e\u7684\u8282\u70b9\uff0c\u8fd4\u56de\u8be5\u8282\u70b9\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u662f\u6700\u540e\u4e00\u5c42\u53f6\u5b50\u8282\u70b9\uff0c\u4e5f\u6ca1\u627e\u5230\u76f8\u7b49\u7684\u952e\uff0c\u5219\u8bf4\u660e\u8be5\u952e\u4e0d\u5b58\u5728\u3002 \u628a\u5de6/\u53f3\u5b50\u8282\u70b9\u8bbe\u4e3a\u65b0\u7684\u5f53\u524d\u8282\u70b9\uff0c\u7136\u540e\u56de\u5230\u7b2c 2 \u6b65\uff0c\u91cd\u590d\u8fd9\u4e00\u67e5\u627e\u8fc7\u7a0b\u3002","title":"\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5"},{"location":"stl_map/#_13","text":"\u7531\u4e8e map \u7684\u5b9e\u73b0\u57fa\u4e8e\u4e8c\u53c9\u6392\u5e8f\u6811\uff0cmap \u989d\u5916\u6709\u4e00\u4e2a\u7279\u70b9\uff1a \u6709\u5e8f \u3002 map (\u6216 set) \u4e2d\u7684\u952e K \u603b\u662f\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u65b9\u4fbf\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u627e\u5230\u5bf9\u5e94\u5143\u7d20\u3002 \u6bcf\u6b21\u63d2\u5165\u65b0\u7684\u952e\u65f6\uff0c\u4f1a\u627e\u5230\u9002\u5f53\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u4f7f\u5f97\u63d2\u5165\u540e\u7684 map \u4ecd\u7136\u6709\u5e8f\u3002 \u6ce8\uff1a\u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\u5b9e\u73b0\u7684 unordered_map (\u548c unordered_set)\uff0c\u5c31\u4e0d\u5177\u5907 \u6709\u5e8f \u8fd9\u4e00\u7279\u70b9\u3002 \u4e24\u8005\u7684\u533a\u522b\u5728\u4e8e\uff1amap \u5728 K \u4e4b\u5916\uff0c\u989d\u5916\u5916\u6302\u4e86\u4e00\u4e2a V \u7c7b\u578b\u3002 map \u4e2d\u7684 V \u7c7b\u578b\u4e0d\u53c2\u4e0e\u6392\u5e8f\uff0c\u53ea\u6309\u7167 K \u8fdb\u884c\u6392\u5e8f\u3002 \u8fd9\u6837\u5f53\u7528\u6237\u6839\u636e K \u627e\u5230\u7684\u662f K-V \u5bf9\uff0c\u7136\u540e\u53ef\u4ee5\u53d6\u51fa K \u5bf9\u5e94\u7684 V\u3002 \u8fd9\u5c31\u5b9e\u73b0\u4e86\u4ece K \u5230 V \u7684\u6620\u5c04\u3002","title":"\u4e8c\u53c9\u6392\u5e8f\u6811"},{"location":"stl_map/#_14","text":"\u4e8c\u53c9\u6392\u5e8f\u6811\u53ea\u89e3\u51b3\u4e86\u67e5\u627e\u7684\u95ee\u9898\uff0c\u4f46\u662f\u4ed6\u5e76\u4e0d\u80fd\u4fdd\u8bc1\u7ecf\u5386\u4e00\u901a\u63d2\u5165\u540e\u7684\u6811\u4e0d\u4f1a\u201c\u9000\u5316\u201d\u3002 \u5982\u679c\u63d2\u5165\u7684\u65f6\u5019\u4e0d\u5c0f\u5fc3\uff0c\u53ef\u80fd\u4f1a\u8ba9\u6811\u7684\u5f62\u72b6\u53d8\u5f97\u975e\u5e38\u8be1\u5f02\uff01 \u4f8b\u5982\uff0c\u82e5\u63d2\u5165\u6570\u636e\u7684\u987a\u5e8f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u90a3\u5c31\u4f1a\u4e00\u76f4\u5728\u5f80\u53f3\u63d2\u5165\uff0c\u6e05\u4e00\u8272\u7684\u4e00\u8fb9\u5012\uff0c\u4ee5\u81f3\u4e8e\u51e0\u4e4e\u6210\u4e86\u4e00\u6839\u5f80\u53f3\u8dd1\u7684\u94fe\u8868\u3002 \u5982\u679c\u63d2\u5165\u987a\u5e8f\u662f\u4ece\u5927\u5230\u5c0f\uff0c\u5c31\u53d8\u6210\u4e00\u76f4\u5f80\u5de6\u8fb9\u5012\u3002\u5373\u4f7f\u63d2\u5165\u7684\u987a\u5e8f\u4e0d\u90a3\u4e48\u523b\u610f\uff0c\u4f9d\u7136\u53ef\u80fd\u4ea7\u751f\u975e\u5e38\u53d8\u6001\u7684\u5f62\u72b6\uff0c\u8fdd\u80cc\u4e86\u4e8c\u53c9\u6811\u7684\u521d\u8877\u3002 \u54e5\u4fe9\u751f\u5f02\u5f62\u5462\uff1f \u8fd9\u6837\u201c\u9000\u5316\u201d\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u867d\u7136\u80fd\u4fdd\u6301\u6709\u5e8f\uff0c\u4f46\u4e8c\u5206\u67e5\u627e\u65f6\u5c31\u8d77\u4e0d\u5230\u52a0\u901f\u4f5c\u7528\u4e86\u3002 \u5982\u679c\u8981\u627e\u4e00\u4e2a\u4e2d\u95f4\u7684\u5143\u7d20\uff0c\u51e0\u4e4e\u5c31\u548c\u94fe\u8868\u4e00\u6837\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u53f3\u679d\u5e72\u3002 \u4e3a\u4e86\u9650\u5236\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0d\u8981\u957f\u6210\u7578\u5f62\uff0c\u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u6307\u6807\uff1a\u201c\u6df1\u5ea6\u201d\uff0c\u8868\u793a\u4ece\u6839\u8282\u70b9\u5230\u6700\u5e95\u5c42\u53f6\u5b50\u8282\u70b9\u7684\u8ddd\u79bb\u3002 \u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u5c31\u9700\u8981\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u5c3d\u53ef\u80fd\u7684\u4f4e\u3002 \u56e0\u4e3a\u4e8c\u5206\u67e5\u627e\u7684\u6b21\u6570\u5c31\u53d6\u51b3\u4e8e\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u7684\u5e73\u5747\u6df1\u5ea6\uff0c\u8981\u5c3d\u53ef\u80fd\u51cf\u5c11\u5e73\u5747\u9700\u8981\u8bbf\u95ee\u7684\u6b21\u6570\uff0c\u5c31\u662f\u8981\u51cf\u5c11\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u3002 \u4e5f\u5c31\u662f\u8bf4\u8981\u8ba9\u5927\u5bb6\u90fd\u5c3d\u53ef\u80fd\u8d34\u8fd1\u6839\u90e8\uff0c\u4f46\u6211\u4eec\u4e0d\u53ef\u80fd\u8ba9\u6240\u6709\u53f6\u5b50\u90fd\u6700\u8d34\u8fd1\u6839\u90e8\u3002 \u4f8b\u5982\u53f3\u4fa7\u53ea\u6709\u4e00\u4e2a\u53f6\u5b50\u8282\u70b9\uff0c\u4ed6\u81ea\u5df1\u662f\u6df1\u5ea6\u6700\u4f4e\u4e86\uff0c\u4f46\u4ee3\u4ef7\u662f\u5de6\u8fb9\u5168\u90e8\u6324\u5728\u4e00\u6761\u94fe\u8868\u4e0a\u4e86\uff01\u8fd9\u4e0d\u516c\u5e73\u3002 \u5b83\u81ea\u5df1\u5012\u662f\u81ea\u7531\u4e86\uff0c\u4f46\u5b83\u5974\u5f79\u4e86\u6240\u6709\u7684\u4eba\u6c11 \u6240\u4ee5\u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u6211\u4eec\u771f\u6b63\u9700\u8981\u7684\u662f\u8ba9\u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u5c3d\u53ef\u80fd\u201c\u5e73\u7b49\u201d\uff01","title":"\u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898"},{"location":"stl_map/#vs","text":"\u4e3a\u4e86\u907f\u514d\u4e8c\u53c9\u6811\u957f\u6210\u7578\u5f62\uff0c\u9677\u5165\u4e00\u8fb9\u5012\u7684\u60c5\u51b5\u3002\u6211\u4eec\u9700\u8981\u5728\u6bcf\u6b21\u63d2\u5165\u540e\uff0c\u68c0\u67e5\u4e8c\u53c9\u6811\u662f\u5426\u6df1\u5ea6\u5dee\u8ddd\u8fc7\u5927\u3002 \u5982\u679c\u5dee\u7684\u592a\u591a\u4e86\uff0c\u5c31\u9700\u8981\u8fdb\u884c\u4e00\u7cfb\u5217\u77eb\u6b63\u64cd\u4f5c\uff0c\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\uff0c\u628a\u592a\u957f\u7684\u679d\u5e72\u780d\u65ad\uff0c\u63a5\u5728\u77ed\u7684\u5730\u65b9\uff0c\u5c3d\u53ef\u80fd\u4fdd\u6301\u6240\u6709\u53f6\u5b50\u8def\u5f84\u7684\u6df1\u5ea6\u5dee\u4e0d\u591a\uff0c\u8fd9\u4e2a\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u52a8\u4f5c\u5c31\u662f \u5e73\u8861\u64cd\u4f5c (balancing) \u3002 \u95ee\u9898\u662f\uff0c\u6700\u5927\u80fd\u5bb9\u5fcd\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u591a\u5927\u7684\u6df1\u5ea6\u5dee\u624d\u5f00\u59cb\u77eb\u6b63\uff1f\u9488\u5bf9\u8fd9\u4e2a\u95ee\u9898\uff0c\u4e8c\u53c9\u6392\u5e8f\u6811\u5206\u4e3a\u4e24\u6d3e\uff1a","title":"\u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811"},{"location":"stl_map/#_15","text":"\u6700\u7406\u60f3\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u9897\u542b\u6709 N N \u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u81f3\u5c11\u9700\u8981\u6709 \\lceil \\log N \\rceil \\lceil \\log N \\rceil \u6df1\u5ea6\u3002 \u8fd9\u5c31\u662f\u5e73\u8861\u6811\uff08AVL\uff09\uff0c\u4ed6\u5f3a\u5236\u4fdd\u8bc1\u6574\u4e2a\u6811\u5904\u4e8e\u5b8c\u7f8e\u7684\u5e73\u8861\u72b6\u6001\uff0c\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u6df1\u5ea6\u5dee\u8ddd\u4e0d\u4f1a\u8d85\u8fc7 1\uff08\u5f53\u8282\u70b9\u6570\u91cf N N \u4e0d\u662f 2 \u7684\u6574\u6570\u500d\u65f6\uff0c\u8fd9\u662f\u4e0d\u5f97\u4e0d\u5b58\u5728\u7684 1 \u683c\u5dee\u8ddd\uff09\u3002 \u4f18\u70b9\uff1a\u59cb\u7ec8\u4fdd\u6301\u6700\u5b8c\u7f8e\u7684\u5e73\u8861\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u548c\u6700\u574f\u590d\u6742\u5ea6\u6700\u4f4e\u3002\u6240\u4ee5\u5e73\u8861\u6811\u7684\u67e5\u627e\u6027\u80fd\u662f\u6700\u597d\u7684\u3002 \u7f3a\u70b9\uff1a\u7136\u800c\u59cb\u7ec8\u4fdd\u6301\u5b8c\u7f8e\u7684\u5e73\u8861\u610f\u5473\u7740\uff0c\u51e0\u4e4e\u6bcf\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff08\u53ef\u80fd\u4f1a\u7a81\u7136\u4ea7\u751f\u6df1\u5ea6\u5dee\u8ddd\u8d85\u8fc7 1 \u7684\u60c5\u51b5\uff09\uff0c\u5c31\u7acb\u5373\u9700\u8981\u5e73\u8861\u4e00\u6b21\u3002\u5e73\u8861\u4e00\u6b21\u7684\u5f00\u9500\u662f\u6bd4\u8f83\u5927\u7684\uff0c\u6240\u4ee5\u5e73\u8861\u6811\u7684\u6027\u80fd\u662f\u63d2\u5165\u6027\u80fd\u662f\u6bd4\u8f83\u5dee\u7684\u3002 \u5e73\u8861\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u65b9\u5f0f\u662f\u201c\u65cb\u8f6c\u201d\uff0c\u4ed6\u80fd\u59cb\u7ec8\u4fdd\u6301\u6700\u4f4e\u7684\u6df1\u5ea6\u5dee\uff1a \u8fd9\u91cc\u7684\u7ec6\u8282\u6211\u4eec\u4e0d\u4f1a\u6df1\u7a76\uff0c\u90a3\u662f\u6570\u636e\u7ed3\u6784\u8bfe\u7684\u5185\u5bb9\uff0c\u5c4a\u65f6\u4f1a\u5e26\u5927\u5bb6\u624b\u6413\u5e73\u8861\u6811\u548c\u7ea2\u9ed1\u6811\uff0c\u672c\u671f\u53ea\u662f\u7a0d\u5fae\u4e86\u89e3 map \u5e38\u89c1\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5e2e\u52a9\u4f60\u7406\u89e3\u4e3a\u4ec0\u4e48 map \u662f\u6709\u5e8f\u5bb9\u5668\u3002","title":"\u5e73\u8861\u6811"},{"location":"stl_map/#_16","text":"\u800c\u7ea2\u9ed1\u6811\u8ba4\u4e3a\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u603b\u662f\u4fdd\u6301\u6df1\u5ea6\u5dee\u8ddd\u4e3a 1 \u90a3\u4e48\u5c0f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u5373\u53ef\u3002 \u4f8b\u5982\u6700\u6d45\u7684\u4e00\u4e2a\u53f6\u5b50\u662f 6 \u6df1\u5ea6\uff0c\u53e6\u4e00\u4e2a\u6700\u6df1\u7684\u53f6\u5b50\u53ef\u4ee5\u662f 12 \u6df1\u5ea6\u3002\u53ea\u6709\u5f53\u6700\u6df1\u7684\u53f6\u5b50\u8d85\u8fc7 12 \u6df1\u5ea6\u65f6\uff0c\u7ea2\u9ed1\u6811\u624d\u4f1a\u5f00\u59cb\u4e3b\u52a8\u5e72\u9884\u5e73\u8861\uff0c\u907f\u514d\u7ee7\u7eed\u7578\u5f62\u53d1\u5c55\u4e0b\u53bb\u3002 \u7f3a\u70b9\uff1a\u6811\u53ef\u80fd\u6709\u4e00\u5b9a\u7684\u4e00\u8fb9\u5012\u60c5\u51b5\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u7a0d\u5fae\u964d\u4f4e\uff0c\u6700\u574f\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u539f\u6765\u7684 2 \u500d\uff01 \u4f18\u70b9\uff1a\u56e0\u4e3a\u5bf9\u4e0d\u5e73\u8861\u73b0\u8c61\u66f4\u52a0\u5bbd\u677e\uff0c\u6b63\u5e38\u63d2\u5165\u65f6\u57fa\u672c\u4e0d\u9700\u8981\u5e73\u8861\uff0c\u53ea\u6709\u7279\u522b\u626d\u66f2\u4e86\u624d\u4f1a\u4e0b\u573a\u201c\u6551\u6025\u201d\u3002\u6240\u4ee5\u7ea2\u9ed1\u6811\u662f\u727a\u7272\u4e86\u4e00\u90e8\u5206\u67e5\u627e\u6027\u80fd\uff0c\u6362\u53d6\u4e86\u66f4\u597d\u7684\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7684\u7528\u51b5\u662f\u63d2\u5165\u6bd4\u8f83\u5c11\uff0c\u4f46\u662f\u67e5\u8be2\u975e\u5e38\u591a\uff0c\u90a3\u5c31\u9002\u5408\u7528\u5e73\u8861\u6811\u3002 \u7531\u4e8e\u6362\u6765\u7684\u8fd9\u90e8\u5206\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u5b9e\u9645\u4e0a\u6bd4\u635f\u5931\u7684\u67e5\u627e\u6027\u80fd\u591a\uff0c\u800c map \u5e38\u89c1\u7684\u7528\u51b5\u786e\u5b9e\u9700\u8981\u7ecf\u5e38\u589e\u5220\u6539\u67e5\uff0c\u6240\u4ee5\u73b0\u5728 C++ \u6807\u51c6\u5e93\u7684 map \u5e95\u5c42\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u5b9e\u73b0\u7684\u3002 \u5982\u679c\u4f60\u7684\u9700\u6c42\u662f\u5927\u91cf\u67e5\u627e\u7684\u8bdd\uff0c\u5b8c\u5168\u53ef\u4ee5\u8003\u8651\u7528\u67e5\u627e\u5e73\u5747\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u7684\u54c8\u5e0c\u8868 unordered_map\u3002 \u5982\u679c\u662f\u4e00\u6b21\u6027\u63d2\u5165\u5b8c\u6bd5\u540e\u4e0d\u4f1a\u518d\u4fee\u6539\uff0c\u8fd8\u53ef\u4ee5\u7528\u5b8c\u7f8e\u54c8\u5e0c\u8868\uff08frozen_map\uff09\uff0c\u4ed6\u4f1a\u4e3a\u4f60\u7684\u952e\u503c\u5e8f\u5217\u4e13\u95e8\u751f\u6210\u4e00\u4e2a\u4e13\u7528\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u4e14\u4fdd\u8bc1\u5b8c\u5168\u65e0\u51b2\u7a81\u3002\u4f8b\u5982\u4f60\u5728\u505a\u4e00\u79cd\u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u6709\u5f88\u591a\u201c\u5173\u952e\u5b57\u201d\uff0c\u6bd4\u5982\u201cif\u201d\u3001\u201cwhile\u201d\uff0c\u4f60\u9700\u8981\u8fd0\u884c\u65f6\u9891\u7e41\u7684\u67e5\u627e\u8fd9\u4e9b\u5173\u952e\u5b57\uff0c\u800c\u5173\u952e\u5b57\u6709\u54ea\u4e9b\u5728\u7f16\u8bd1\u671f\u662f\u56fa\u5b9a\u7684\uff0c\u90a3\u5c31\u5f88\u9002\u5408\u7528\u5b8c\u7f8e\u54c8\u5e0c\u3002","title":"\u7ea2\u9ed1\u6811"},{"location":"stl_map/#_17","text":"\u7ea2\u9ed1\u6811\u662f\u5982\u4f55\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u7684\u5462\uff1f \u4ed6\u8bbe\u5b9a\u4e86\u8fd9\u6837 5 \u6761\u89c4\u5219\uff1a \u8282\u70b9\u53ef\u4ee5\u662f\u7ea2\u8272\u6216\u9ed1\u8272\u7684\u3002 \u6839\u8282\u70b9\u603b\u662f\u9ed1\u8272\u7684\u3002 \u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u662f\u9ed1\u8272\uff08\u53f6\u5b50\u8282\u70b9\u5c31\u662f NULL\uff09\u3002 \u7ea2\u8272\u8282\u70b9\u7684\u4e24\u4e2a\u5b50\u8282\u70b9\u5fc5\u987b\u90fd\u662f\u9ed1\u8272\u7684\u3002 \u4ece\u4efb\u4e00\u8282\u70b9\u5230\u5176\u6240\u6709\u53f6\u5b50\u8282\u70b9\u7684\u8def\u5f84\u90fd\u5305\u542b\u76f8\u540c\u6570\u91cf\u7684\u9ed1\u8272\u8282\u70b9\u3002 \u4ec0\u4e48\u89c4\u5219\u7c7b\u602a\u8c08\u2026\u2026 \u770b\u8d77\u6765\u597d\u50cf\u5f88\u590d\u6742\uff0c\u4f46\u5b9e\u9645\u4e0a\u5927\u591a\u662f\u5e9f\u8bdd\uff0c\u6709\u7528\u7684\u53ea\u662f 4 \u548c 5 \u8fd9\u4e24\u6761\u3002 \u89c4\u5219 4 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4e0d\u5f97\u51fa\u73b0\u76f8\u90bb\u7684\u7ea2\u8272\u8282\u70b9\uff08\u76f8\u90bb\u6307\u4e24\u4e2a\u8282\u70b9\u662f\u7236\u5b50\u5173\u7cfb\uff09\u3002\u8fd9\u6761\u89c4\u5219\u8fd8\u6709\u4e00\u4e2a\u9690\u542b\u7684\u4fe1\u606f\uff1a\u9ed1\u8272\u8282\u70b9\u53ef\u4ee5\u76f8\u90bb\uff01 \u89c4\u5219 5 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6240\u6709\u5e95\u5c42\u53f6\u5b50\u7684\u8ddd\u79bb\uff08\u4ee5\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u8ba1\uff09\uff0c\u5fc5\u987b\u76f8\u7b49\u3002 \u56e0\u4e3a\u89c4\u5219 4 \u7684\u5b58\u5728\uff0c\u7ea2\u8272\u8282\u70b9\u4e0d\u53ef\u80fd\u76f8\u90bb\uff0c\u4e5f\u5c31\u662f\u8bf4\u6700\u6df1\u7684\u679d\u5e72\u53ea\u80fd\u662f\uff1a\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1\u3002 \u7ed3\u5408\u89c4\u5219 5 \u6765\u770b\uff0c\u4e5f\u5c31\u662f\u8bf4\u6bcf\u6761\u679d\u5e72\u4e0a\u7684\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u5fc5\u987b\u76f8\u540c\uff0c\u56e0\u4e3a\u6700\u6df1\u7684\u679d\u5e72\u662f 4 \u4e2a\u9ed1\u8282\u70b9\u4e86\uff0c\u6240\u4ee5\u6700\u6d45\u7684\u679d\u5e72\u81f3\u5c11\u4e5f\u5f97\u6709 4 \u4e2a\u8282\u70b9\u5168\u662f\u9ed1\u8272\u7684\uff1a\u9ed1-\u9ed1-\u9ed1-\u9ed1\u3002 \u53ef\u4ee5\u770b\u5230\uff0c\u89c4\u5219 4 \u548c\u89c4\u5219 5 \u8054\u5408\u8d77\u6765\u5b9e\u9645\u4e0a\u5c31\u4fdd\u8bc1\u4e86\uff1a\u6700\u6df1\u679d\u5e72\u7684\u6df1\u5ea6\u4e0d\u4f1a\u8d85\u8fc7\u6700\u6d45\u679d\u5e72\u7684 2 \u500d\u3002 \u5982\u679c\u8d85\u51fa\u4e86 2 \u500d\uff0c\u5c31\u4e0d\u5f97\u4e0d\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u89c4\u5219 4 \u6216 5\uff0c\u4ece\u800c\u89e6\u53d1\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u5e73\u8861\u64cd\u4f5c\uff0c\u4ece\u800c\u963b\u6b62\u4e86\u4e8c\u53c9\u6811\u8fc7\u4e8e\u7578\u5f62\u5316\u3002 \u7ea2\u9ed1\u6811\u5982\u4f55\u5b9e\u73b0\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u7ec6\u8282\u6211\u4eec\u5c31\u4e0d\u518d\u591a\u8c08\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u70b9\u5230\u4e3a\u6b62\uff0c\u63a5\u4e0b\u6765\u76f4\u63a5\u8fdb\u5165\u6b63\u9898\uff1a","title":"\u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6"},{"location":"stl_map/#map_3","text":"\u521b\u5efa\u4e00\u4e2a map \u5bf9\u8c61\uff1a map config; \u4e00\u5f00\u59cb map \u521d\u59cb\u662f\u7a7a\u7684\uff0c\u5982\u4f55\u63d2\u5165\u4e00\u4e9b\u521d\u59cb\u6570\u636e\uff1f config[\"timeout\"] = 985; config[\"delay\"] = 211; \u6570\u636e\u63d2\u5165\u6210\u529f\u4e86\uff0c\u6839\u636e\u952e\u67e5\u8be2\u5bf9\u5e94\u7684\u503c\uff1f print(config[\"timeout\"]); print(config[\"delay\"]); \u67e5\u8be2\u65f6\u5efa\u8bae\u7528 .at(key) \u800c\u4e0d\u662f [key] \uff1a print(config.at(\"timeout\")); print(config.at(\"delay\")); \u8001\u751f\u5e38\u8c08\u7684\u95ee\u9898\uff1amap \u4e2d\u5b58 string \u8fd8\u662f const char *\uff1f map m; m[\"hello\"] = \"old\"; // \u5e38\u91cf\u533a\u7684 \"hello\" char key[] = \"hello\"; // key \u7684\u5730\u5740\u5728\u6808\u4e0a print(key == \"hello\"); // false m[key] = \"new\"; // \u6808\u4e0a\u53d8\u91cf\u7684 key = \"hello\" print(m); // \u4e24\u4e2a\u91cd\u590d\u7684\u952e \"hello\" false {hello: old, hello: new} \u5728 C++ \u4e2d\uff0c\u4efb\u4f55\u65f6\u5019\u90fd\u52a1\u5fc5\u7528 string\uff01\u522b\u7528 C \u8bed\u8a00\u8001\u6389\u7259\u7684 const char *\uff0c\u592a\u5371\u9669\u4e86\u3002 const char * \u5371\u9669\u7684\u539f\u56e0\uff1a const char * \u7684 == \u5224\u65ad\u7684\u662f\u6307\u9488\u7684\u76f8\u7b49\uff0c\u4e24\u4e2a const char * \u53ea\u8981\u5730\u5740\u4e0d\u540c\uff0c\u5373\u4f7f\u5b9e\u9645\u7684\u5b57\u7b26\u4e32\u76f8\u540c\uff0c\u4e5f\u4e0d\u4f1a\u88ab\u89c6\u4e3a\u540c\u4e00\u4e2a\u5143\u7d20\uff08\u5982\u4e0a\u4ee3\u7801\u6848\u4f8b\u6240\u793a\uff09\u3002\u5bfc\u81f4 map \u91cc\u4f1a\u51fa\u73b0\u91cd\u590d\u7684\u952e\uff0c\u4ee5\u53ca\u6309\u952e\u67e5\u627e\u53ef\u80fd\u627e\u4e0d\u5230\u7b49\u3002 \u4fdd\u5b58\u7684\u662f\u5f31\u5f15\u7528\uff0c\u5982\u679c\u4f60\u628a\u5c40\u90e8\u7684 char [] \u6216 string.c_str() \u8fd4\u56de\u7684 const char * \u5b58\u5165 map\uff0c\u7b49\u8fd9\u4e9b\u5c40\u90e8\u91ca\u653e\u4e86\uff0cmap \u4e2d\u7684 const char * \u5c31\u662f\u4e00\u4e2a\u7a7a\u60ac\u6307\u9488\u4e86\uff0c\u4f1a\u9020\u6210 segfault\u3002 \u8bf7\u7528\u5b89\u5168\u7684 string\uff1a map m; m[\"hello\"] = \"old\"; string key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // string \u7684 == \u8fd0\u7b97\u7b26\u662f\u7ecf\u8fc7\u91cd\u8f7d\u7684\uff0c\u6bd4\u8f83\u7684\u662f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u5185\u5bb9\u76f8\u7b49\uff0c\u800c\u4e0d\u662f\u5730\u5740\u76f8\u7b49 {\"hello\": \"new\"} true \u63cf\u8ff0 C++ Java Python \u5185\u5bb9\u76f8\u7b49 string(\"hello\") == string(\"hello\") \"hello\".equals(\"hello\") 'hello' == 'hello' \u5730\u5740\u76f8\u7b49 \"hello\" == \"hello\" \"hello\" == \"hello\" id('hello') == id('hello') \u5982\u679c\u4f60\u7cbe\u901a\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u80fd\u4fdd\u8bc1 key \u6307\u5411\u7684\u5b57\u7b26\u4e32\u6d3b\u7684\u6bd4 m \u4e45\uff0c\u60f3\u8981\u907f\u514d\u62f7\u8d1d\uff0c\u8282\u7701\u6027\u80fd\u3002 string \u7684\u5f31\u5f15\u7528\u7248\u672c\uff1astring_view\uff0c\u540c\u6837\u53ef\u4ee5\u7528\u5c01\u88c5\u4e86\u6b63\u786e\u7684 == \u8fd0\u7b97\u7b26\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\uff1a map m; m[\"hello\"] = \"old\"; string_view key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // \u6b64\u5904 m \u662f\u6808\u4e0a\u53d8\u91cf\uff0ckey \u662f\u5f31\u5f15\u7528\u6307\u5411\u5168\u5c40\u5e38\u91cf\u533a\uff08rodata\uff09\uff0ckey \u6bd4 m \u6d3b\u5f97\u4e45\uff0c\u6ca1\u6709\u7a7a\u60ac\u6307\u9488\u95ee\u9898 {\"hello\": \"new\"} true \u26a0\ufe0f string_view \u5c5e\u4e8e\u4e0d\u5efa\u8bae\u521d\u5b66\u8005\u4f7f\u7528\u7684\u4f18\u5316\u5c0f\u5bc4\u5de7\uff1a\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528\u3002 \u6ce8\uff1amap \u5b9e\u9645\u4e0a\u5b8c\u5168\u6ca1\u6709\u7528\u5230 ==\uff0c\u7528\u5230\u7684\u53ea\u6709 < \u8fd0\u7b97\u7b26\uff0c\u5f53\u9700\u8981\u5224\u5b9a a == b \u65f6\uff0c\u4ed6\u4f1a\u8f6c\u800c\u7528 !(a < b || b < a) \u6765\u5224\u5b9a\u3002 string_view \u4e5f\u5177\u6709\u6b63\u786e\u7684 hash \u7279\u5316\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528\u505a unordered_map \u7684\u952e\u7c7b\u578b\u3002string_view \u8bd5\u56fe\u548c string \u8868\u73b0\u5f97\u5b8c\u5168\u4e00\u6837\uff0c\u533a\u522b\u5728\u4e8e\u4ed6\u662f\u4e2a\u5f31\u5f15\u7528\uff0c\u4e0d\u6301\u6709\u5bf9\u8c61\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\u3002string_view \u5927\u5c0f\u53ea\u6709 16 \u4e2a\u5b57\u8282\uff0c\u5185\u90e8\u662f\u4e00\u4e2a const char * \u548c size_t\uff0c\u4f46\u5c01\u88c5\u4e86\u6b63\u786e\u7684 ==\uff0c<\uff0c> \u548c hash\u3002 C++11 \u65b0\u7279\u6027\u2014\u2014\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\uff0c\u5141\u8bb8\u521b\u5efa map \u65f6\u76f4\u63a5\u6307\u5b9a\u521d\u59cb\u6570\u636e\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211} }; \u901a\u5e38\u6211\u4eec\u4f1a\u6362\u884c\u5199\uff0c\u4e00\u884c\u4e00\u4e2a\u952e\u503c\u5bf9\uff0c\u770b\u8d77\u6765\u6761\u7406\u66f4\u6e05\u6670\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 \u603b\u7ed3\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5\uff1a map m = { {k1, v1}, {k2, v2}, ..., }; \u8ba9 map \u521d\u59cb\u5c31\u5177\u6709\u8fd9\u4e9b\u6570\u636e\u3002 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; \u7b49\u53f7\u53ef\u4ee5\u7701\u7565\uff08\u8fd9\u5176\u5b9e\u76f8\u5f53\u4e8e\u662f\u5728\u8c03\u7528 map \u7684\u6784\u9020\u51fd\u6570\uff09\uff1a map config{ {\"timeout\", 985}, {\"delay\", 211}, }; \u4e5f\u53ef\u4ee5\u5148\u6784\u9020\u518d\u8d4b\u503c\u7ed9 auto \u53d8\u91cf\uff1a auto config = map{ {\"timeout\", 985}, {\"delay\", 211}, }; \u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u5173\u4e8e\u6784\u9020\u51fd\u6570\u3001\u82b1\u62ec\u53f7\u5217\u8868\u7684\u5177\u4f53\u8bed\u6cd5\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u300b\u7cfb\u5217\u7b2c\u4e8c\u8bfe\uff1ahttps://www.bilibili.com/video/BV1LY411H7Gg\u3002\u5728 C++ \u5c0f\u5999\u62db \u4e00\u7ae0\u4e2d\u4e5f\u6709\u4ecb\u7ecd\u3002 \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u53ef\u4ee5\u7528\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\u5c31\u5730\u6784\u9020\u4e00\u4e2a map \u5bf9\u8c61\uff1a void myfunc(map config); // \u51fd\u6570\u58f0\u660e myfunc(map{ // \u76f4\u63a5\u521b\u5efa\u4e00\u4e2a map \u4f20\u5165 {\"timeout\", 985}, {\"delay\", 211}, }); \u7531\u4e8e myfunc \u51fd\u6570\u5177\u6709\u552f\u4e00\u786e\u5b9a\u7684\u91cd\u8f7d\uff0c\u8981\u6784\u9020\u7684\u53c2\u6570\u7c7b\u578b map \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a myfunc({ {\"timeout\", 985}, {\"delay\", 211}, }); \u51fd\u6570\u8fd9\u8fb9\uff0c\u901a\u5e38\u8fd8\u4f1a\u52a0\u4e0a const & \u4fee\u9970\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d\u3002 void myfunc(map const &config); \u4ece vector \u4e2d\u6279\u91cf\u5bfc\u5165\u952e\u503c\u5bf9\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs.begin(), kvs.end()); \u4e0e\u521a\u521a\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u7684\u5199\u6cd5\u7b49\u4ef7\uff0c\u53ea\u4e0d\u8fc7\u662f\u4ece\u73b0\u6709\u7684 vector \u4e2d\u5bfc\u5165\u3002\u540c\u6837\u7684\u5199\u6cd5\u4e5f\u9002\u7528\u4e8e\u4ece array \u5bfc\u5165\u3002 \u5982\u679c\u8bb0\u4e0d\u4f4f\u8fd9\u4e2a\u5199\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5df1\u624b\u5199 for \u5faa\u73af\u904d\u5386 vector \u9010\u4e2a\u9010\u4e2a\u63d2\u5165 map\uff0c\u6548\u679c\u662f\u4e00\u6837\u7684\u3002 \u51b7\u77e5\u8bc6\uff0c\u5982\u679c\u4e0d\u662f vector \u6216 array\uff0c\u800c\u662f\u60f3\u4ece\u4f20\u7edf\u7684 C \u8bed\u8a00\u6570\u7ec4\u4e2d\u5bfc\u5165\uff1a pair kvs[] = { // C \u8bed\u8a00\u539f\u59cb\u6570\u7ec4 {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs, kvs + 2); // C++98 map config(std::begin(kvs), std::end(kvs)); // C++17 \u5176\u4e2d std::begin \u548c std::end \u4e3a C++17 \u65b0\u589e\u51fd\u6570\uff0c\u4e13\u95e8\u7528\u4e8e\u7167\u987e\u6ca1\u6cd5\u6709\u6210\u5458\u51fd\u6570 .begin() \u7684 C \u8bed\u8a00\u6570\u7ec4\u3002\u7c7b\u4f3c\u7684\u5168\u5c40\u51fd\u6570\u8fd8\u6709 std::size \u548c std::data \u7b49\u2026\u2026\u4ed6\u4eec\u90fd\u662f\u65e2\u517c\u5bb9 STL \u5bb9\u5668\u4e5f\u517c\u5bb9 C \u6570\u7ec4\u7684\u3002 \u91cd\u70b9\u6765\u4e86\uff1a\u5982\u4f55\u6839\u636e\u952e\u67e5\u8be2\u76f8\u5e94\u7684\u503c\uff1f \u5f88\u591a\u540c\u5b66\u90fd\u77e5\u9053 map \u5177\u6709 [] \u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c[] \u91cc\u5199\u8981\u67e5\u8be2\u7684\u952e\u5c31\u53ef\u4ee5\u8fd4\u56de\u5bf9\u5e94\u503c\uff0c\u4e5f\u53ef\u4ee5\u7528 = \u5f80\u91cc\u9762\u8d4b\u503c\uff0c\u548c\u67d0\u4e9b\u811a\u672c\u8bed\u8a00\u4e00\u6837\u76f4\u89c2\u6613\u61c2\u3002 config[\"timeout\"] = 985; // \u628a config \u4e2d\u952e timeout \u5bf9\u5e94\u503c\u8bbe\u4e3a 985 auto val = config[\"timeout\"]; // \u8bfb\u53d6 config \u4e2d\u952e timeout \u5bf9\u5e94\u503c print(val); // 985 \u4f46\u5176\u5b9e\u7528 [] \u53bb \u8bfb\u53d6\u5143\u7d20 \u662f\u5f88\u4e0d\u5b89\u5168\u7684\uff0c\u4e0b\u9762\u6211\u4f1a\u505a\u5b9e\u9a8c\u6f14\u793a\u8fd9\u4e00\u70b9\u3002 \u6c89\u9ed8\u7684 []\uff0c\u65e0\u8a00\u7684\u5371\u9669\uff1a\u5f53\u952e\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8fd4\u56de 0 \u800c\u4e0d\u4f1a\u51fa\u9519\uff01 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // 985 print(config[\"tmeout\"]); // \u9ed8\u9ed8\u8fd4\u56de 0 985 0 \u5f53\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c[] \u4f1a\u9ed8\u9ed8\u521b\u5efa\u5e76\u8fd4\u56de 0\uff0c\u800c\u4e0d\u4f1a\u7206\u51fa\u4efb\u4f55\u9519\u8bef\u3002 \u8fd9\u975e\u5e38\u5371\u9669\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b80\u7b80\u5355\u5355\u7684\u62fc\u5199\u9519\u8bef\uff0c\u5c31\u4f1a\u5bfc\u81f4 map \u7684\u67e5\u8be2\u9ed8\u9ed8\u8fd4\u56de 0\uff0c\u4f60\u8fd8\u5728\u90a3\u91cc\u627e\u4e86\u534a\u5929\u6478\u4e0d\u7740\u5934\u8111\uff0c\u6839\u672c\u6ca1\u53d1\u73b0\u9519\u8bef\u539f\u6765\u5728 map \u8fd9\u91cc\u3002 \u7231\u54ed\u7231\u95f9\u7684 at()\uff0c\u53cd\u800c\u66f4\u8ba8\u4eba\u559c\u6b22 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 print(config.at(\"tmeout\")); // \u8be5\u952e\u4e0d\u5b58\u5728\uff01\u54cd\u4eae\u5730\u51fa\u9519 985 terminate called after throwing an instance of 'std::out_of_range' what(): map::at Aborted (core dumped) \u6709\u7ecf\u9a8c\u7684\u8001\u624b\u90fd\u660e\u767d\u4e00\u4e2a\u9053\u7406\uff1a \u53ca\u65f6\u5954\u6e83 \u6bd4 \u5bb9\u5fcd\u9519\u8bef \u66f4\u6709\u5229\u4e8e\u8c03\u8bd5\u3002\u5373 fail-early, fail-loudly 1 \u539f\u5219\u3002 \u4f8b\u5982 JS \u548c Lua \u7684 [] \u8bbf\u95ee\u8d8a\u754c\u4e0d\u62a5\u9519\u800c\u662f\u8fd4\u56de undefined / nil\uff0c\u5bfc\u81f4\u5b9e\u9645\u51fa\u9519\u7684\u4f4d\u7f6e\u5728\u597d\u51e0\u5341\u884c\u4e4b\u540e\uff0c\u65e0\u6cd5\u5b9a\u4f4d\u5230\u771f\u6b63\u51fa\u9519\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u540e\u6765\u53d1\u660e\u4e86\u9519\u8bef\u68c0\u67e5\u66f4\u4e25\u683c\u7684 TS\u3002 \u4f7f\u7528 at() \u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230\u9519\u8bef\uff0c\u662f\u597d\u4e8b\u3002 \u5728\u5b98\u65b9\u6587\u6863\u548c\u5404\u79cd\u6559\u5b66\u8bfe\u4ef6\u4e2d\uff0c\u90fd\u4f1a\u5c55\u793a\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u539f\u578b\u201d\u6765\u8bb2\u89e3\u3002 \u539f\u578b\u5c55\u73b0\u4e86\u4e00\u4e2a\u51fd\u6570\u7684\u540d\u79f0\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u8fd4\u56de\u7c7b\u578b\u7b49\u4fe1\u606f\uff0c\u638c\u63e1\u4e86\u51fd\u6570\u7684\u539f\u578b\u5c31\u7b49\u4e8e\u638c\u63e1\u4e86\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u3002 \u672c\u8bfe\u7a0b\u540e\u9762\u4e5f\u4f1a\u5927\u91cf\u4f7f\u7528\uff0c\u73b0\u5728\u6765\u6559\u4f60\u5982\u4f55\u770b\u61c2\u6210\u5458\u51fd\u6570\u7684\u539f\u578b\u3002 \u5047\u8bbe\u8981\u7814\u7a76\u7684\u7c7b\u578b\u4e3a map \uff0c\u5176\u4e2d K \u548c V \u662f\u6a21\u677f\u53c2\u6570\uff0c\u53ef\u4ee5\u66ff\u6362\u6210\u4f60\u5177\u4f53\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u5f53\u6211\u4f7f\u7528 map \u65f6\uff0c\u5c31\u628a\u4e0b\u9762\u6240\u6709\u7684 K \u66ff\u6362\u6210 string\uff0cV \u66ff\u6362\u6210 int\u3002 map \u7684 [] \u548c at \u5458\u51fd\u6570\uff0c\u539f\u578b\u5982\u4e0b\uff1a V &operator[](K const &k); V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u53ef\u89c1 operator[] \u53ea\u6709\u4e00\u4e2a\u7248\u672c\uff0cat \u5c45\u7136\u6709\u540d\u5b57\u76f8\u540c\u7684\u4e24\u4e2a\uff01\u8fd9\u6837\u4e0d\u4f1a\u53d1\u751f\u51b2\u7a81\u5417\uff1f \u8fd9\u662f\u5229\u7528\u4e86 C++ \u7684\u201c\u91cd\u8f7d\u201d\u529f\u80fd\uff0c\u91cd\u8f7d\u5c31\u662f\u540c\u4e00\u4e2a\u51fd\u6570\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u7248\u672c\uff0c\u5404\u4e2a\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u6253\u7535\u8bdd\u7ed9 110\uff0c\u5047\u5982\u8b66\u5bdf\u53d4\u53d4\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u62a5\u7684\u6848\u5b50\u662f\u7f51\u7edc\u8bc8\u9a97\uff0c\u90a3\u4e48\u4ed6\u4eec\u4f1a\u5e2e\u6211\u8f6c\u63a5\u5230\u7f51\u8b66\u90e8\u95e8\uff1b\u5047\u5982\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u662f\u88ab\u7ed1\u67b6\u4e86\uff0c\u90a3\u4e48\u4ed6\u4eec\u53ef\u80fd\u4f1a\u51fa\u52a8\u6b66\u8b66\u89e3\u6551\u5c0f\u5f6d\u8001\u5e08\u3002\u8fd9\u5c31\u662f 110 \u51fd\u6570\u7684\u4e24\u4e2a\u91cd\u8f7d\uff0c\u6839\u636e\u8c03\u7528\u8005\u4f20\u5165\u7684\u4fe1\u606f\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8f6c\u7ed9\u54ea\u4e00\u4e2a\u5b50\u90e8\u95e8\u3002 \u540c\u7406\uff0c\u7f16\u8bd1\u5668\u4e5f\u662f\u4f1a\u6839\u636e\u8c03\u7528\u65f6\u4f60\u4f20\u5165\u7684\u53c2\u6570\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8c03\u7528\u91cd\u8f7d\u7684\u54ea\u4e00\u4e2a\u5177\u4f53\u7248\u672c\u3002 C \u8bed\u8a00\u6ca1\u6709\u91cd\u8f7d\uff0c\u51fd\u6570\u540d\u5b57\u76f8\u540c\u5c31\u4f1a\u53d1\u751f\u51b2\u7a81\uff0c\u7f16\u8bd1\u5668\u4f1a\u5f53\u573a\u62a5\u9519\u3002 C++ \u652f\u6301\u91cd\u8f7d\uff0c\u53ea\u6709\u5f53\u51fd\u6570\u540d\u5b57\u76f8\u540c\uff0c\u53c2\u6570\u5217\u8868\u4e5f\u76f8\u540c\u65f6\uff0c\u624d\u4f1a\u53d1\u751f\u51b2\u7a81\u3002 \u8fd4\u56de\u503c\u7c7b\u578b\u4e0d\u5f71\u54cd\u91cd\u8f7d\uff0c\u91cd\u8f7d\u53ea\u770b\u53c2\u6570\u5217\u8868\u3002 \u83dc\u9e1f\u6559\u7a0b\u4e0a\u5bf9 C++ \u91cd\u8f7d\u7684\u89e3\u91ca 1 \uff1a C++ \u5141\u8bb8\u5728\u540c\u4e00\u4f5c\u7528\u57df\u4e2d\u7684\u67d0\u4e2a\u51fd\u6570\u548c\u8fd0\u7b97\u7b26\u6307\u5b9a\u591a\u4e2a\u5b9a\u4e49\uff0c\u5206\u522b\u79f0\u4e3a\u51fd\u6570\u91cd\u8f7d\u548c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u91cd\u8f7d\u58f0\u660e\u662f\u6307\u4e00\u4e2a\u4e0e\u4e4b\u524d\u5df2\u7ecf\u5728\u8be5\u4f5c\u7528\u57df\u5185\u58f0\u660e\u8fc7\u7684\u51fd\u6570\u6216\u65b9\u6cd5\u5177\u6709\u76f8\u540c\u540d\u79f0\u7684\u58f0\u660e\uff0c\u4f46\u662f\u5b83\u4eec\u7684\u53c2\u6570\u5217\u8868\u548c\u5b9a\u4e49\uff08\u5b9e\u73b0\uff09\u4e0d\u76f8\u540c\u3002 \u5f53\u60a8\u8c03\u7528\u4e00\u4e2a\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u65f6\uff0c\u7f16\u8bd1\u5668\u901a\u8fc7\u628a\u60a8\u6240\u4f7f\u7528\u7684\u53c2\u6570\u7c7b\u578b\u4e0e\u5b9a\u4e49\u4e2d\u7684\u53c2\u6570\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\uff0c\u51b3\u5b9a\u9009\u7528\u6700\u5408\u9002\u7684\u5b9a\u4e49\u3002\u9009\u62e9\u6700\u5408\u9002\u7684\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u7684\u8fc7\u7a0b\uff0c\u79f0\u4e3a\u91cd\u8f7d\u51b3\u7b56\u3002 \u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\uff0c\u53ef\u4ee5\u58f0\u660e\u51e0\u4e2a\u529f\u80fd\u7c7b\u4f3c\u7684\u540c\u540d\u51fd\u6570\uff0c\u4f46\u662f\u8fd9\u4e9b\u540c\u540d\u51fd\u6570\u7684\u5f62\u5f0f\u53c2\u6570\uff08\u6307\u53c2\u6570\u7684\u4e2a\u6570\u3001\u7c7b\u578b\u6216\u8005\u987a\u5e8f\uff09\u5fc5\u987b\u4e0d\u540c\u3002\u60a8\u4e0d\u80fd\u4ec5\u901a\u8fc7\u8fd4\u56de\u7c7b\u578b\u7684\u4e0d\u540c\u6765\u91cd\u8f7d\u51fd\u6570\u3002 V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u4f46\u662f\u4e0a\u9762\u8fd9\u4e24\u4e2a at \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u90fd\u662f K const & \uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u91cd\u8f7d\u5462\uff1f \u6ce8\u610f\u770b\u7b2c\u4e8c\u4e2a\u7248\u672c\u6700\u540e\u9762\u591a\u4e86\u4e00\u4e2a const \u5173\u952e\u5b57\uff0c\u8fd9\u79cd\u5199\u6cd5\u662f\u4ec0\u4e48\u610f\u601d\uff1f\u5c0f\u5f6d\u8001\u5e08\u5bf9\u5176\u8fdb\u884c\u795b\u9b45\u5316\uff1a V &at(map *this, K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(map const *this, K const &k); // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u539f\u6765\u52a0\u5728\u51fd\u6570\u62ec\u53f7\u540e\u9762\u7684 const\uff0c\u5b9e\u9645\u4e0a\u662f\u7528\u4e8e\u4fee\u9970 this \u6307\u9488\u7684\uff01 \u8be5\u5199\u6cd5\u4ec5\u4f9b\u793a\u610f\uff0c\u5e76\u4e0d\u662f\u771f\u7684\u53ef\u4ee5\u628a this \u5199\u6210\u53c2\u6570 \u6240\u4ee5\u4e24\u4e2a at \u7684\u53c2\u6570\u5217\u8868\u4e0d\u540c\uff0c\u4e0d\u540c\u5728\u4e8e\u4f20\u5165 this \u6307\u9488\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u53ef\u4ee5\u91cd\u8f7d\uff0c\u4e0d\u4f1a\u51b2\u7a81\u3002 \u5f53 map \u5bf9\u8c61\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map const * \uff0c\u6240\u4ee5\u53ea\u80fd\u8c03\u7528\u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at\u3002 \u5f53 map \u5bf9\u8c61\u4e0d\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map * \uff0c\u4e24\u4e2a\u91cd\u8f7d\u90fd\u53ef\u4ee5\u8c03\u7528\uff0c\u4f46\u7531\u4e8e\u7b2c\u4e00\u4e2a\u91cd\u8f7d\u66f4\u52a0\u7b26\u5408\uff0c\u6240\u4ee5\u4f1a\u8c03\u7528\u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at\u3002 \u6709\u8da3\u7684\u662f\uff0cC++23 \u652f\u6301\u4e86\u663e\u5f0f\u5bf9\u8c61\u5f62\u53c2\uff08deducing-this\uff09\uff0cthis \u4e5f\u80fd\u50cf\u666e\u901a\u53c2\u6570\u4e00\u6837\u5b9a\u4e49\u4e86\uff01\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u6210\uff1a class map { ... V &at(this map &self, K const &k) { // \u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u4f7f\u7528self\u4ee3\u66ff\u539f\u6765\u7684this\uff08this\u5c06\u4e0d\u518d\u53ef\u7528\uff09 ... } V const &at(this map const &self, K const &k) { ... } }; \u521a\u521a\u89e3\u91ca\u4e86\u51fd\u6570\u91cd\u8f7d\uff0c\u90a3\u4e48\u8fd0\u7b97\u7b26\u91cd\u8f7d\u5462\uff1f \u56e0\u4e3a\u539f\u672c C \u8bed\u8a00\u5c31\u6709 [] \u8fd0\u7b97\u7b26\uff0c\u4e0d\u8fc7\u90a3\u53ea\u9002\u7528\u4e8e\u539f\u59cb\u6307\u9488\u548c\u539f\u59cb\u6570\u7ec4\u3002\u800c C++ \u5141\u8bb8\u4e5f [] \u8fd0\u7b97\u7b26\u652f\u6301\u5176\u4ed6\u7528\u6237\u81ea\u5b9a\u4e49\u7c7b\u578b\uff08\u6bd4\u5982 std::map\uff09\uff0c\u548c C \u8bed\u8a00\u81ea\u5e26\u7684\u76f8\u6bd4\u5c31\u53ea\u6709\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\uff08\u4e00\u4e2a\u662f\u539f\u59cb\u6570\u7ec4\uff0c\u4e00\u4e2a\u662f std::map\uff09\uff0c\u6240\u4ee5\u548c\u51fd\u6570\u91cd\u8f7d\u5f88\u76f8\u4f3c\uff0c\u8fd9\u5c31\u662f\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 m[\"key\"]; \u4f1a\u88ab\u7f16\u8bd1\u5668\u201c\u7ffb\u8bd1\u201d\u6210\uff1a m.operator[](\"key\"); \u4ee5\u4e0a\u4ee3\u7801\u5e76\u975e\u4ec5\u4f9b\u793a\u610f\uff0c\u662f\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u8fd0\u884c\u7684\u3002 operator[] \u867d\u7136\u770b\u8d77\u6765\u5f88\u590d\u6742\u4e00\u4e2a\u5173\u952e\u5b57\u52a0\u7279\u6b8a\u7b26\u53f7\uff0c\u5176\u5b9e\u65e0\u975e\u5c31\u662f\u4e2a\u7279\u6b8a\u7684\u51fd\u6570\u540d\uff0c\u5b66\u8fc7 Python \u7684\u7ae5\u978b\u53ef\u4ee5\u628a\u4ed6\u60f3\u8c61\u6210 __getitem__ \u3002 V &operator[](K const &k); \u7ed3\u8bba\uff1a[] \u8fd0\u7b97\u7b26\u5b9e\u9645\u4e0a\u662f\u5728\u8c03\u7528 operator[] \u51fd\u6570\u3002 \u6240\u6709\u7684\u6240\u8c13\u201c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u51fd\u6570\u201d\u5b9e\u9645\u4e0a\u90fd\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6807\u8bc6\u7b26\uff0c\u4ee5 operator + \u8fd0\u7b97\u7b26\u7684\u5f62\u5f0f\uff0c\u4ed6\u4eec\u4e24\u4e2a\u7ec4\u6210\u4e00\u4e2a\u6574\u4f53\uff0c\u4f60\u8fd8\u53ef\u4ee5\u8bd5\u8bd5 string(\"hel\").operator+(\"lo\") \uff0c\u548c string(\"hel\") + \"lo\" \u662f\u7b49\u4ef7\u7684\u3002 \u56e0\u4e3a operator[] \u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u540e\u9762\u6ca1\u6709 const \u4fee\u9970\uff0c\u56e0\u6b64\u5f53 map \u4fee\u9970\u4e3a const \u65f6\u7f16\u8bd1\u4f1a\u4e0d\u901a\u8fc7 1 \uff1a const map config = { // \u6b64\u5904\u5982\u679c\u662f\u5e26 const & \u4fee\u9970\u7684\u51fd\u6570\u53c2\u6570\u4e5f\u662f\u540c\u7406 {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // \u7f16\u8bd1\u51fa\u9519 /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp: In function \u2018int main()\u2019: /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp:10:23: error: passing \u2018const std::map, int>\u2019 as \u2018this\u2019 argument discards qualifiers [-fpermissive] 10 | print(config[\"timeout\"]); \u7f16\u8bd1\u5668\u8bf4 discards qualifiers\uff0c\u610f\u601d\u662f map \u6709 const \u4fee\u9970\uff0c\u4f46\u662f operator[] \u6ca1\u6709\u3002 \u8fd9\u5b9e\u9645\u4e0a\u5c31\u662f\u5728\u8bf4\uff1a map const *this \u4e0d\u80fd\u8f6c\u6362\u6210 map *this \u3002 \u6709 const \u4fee\u9970\u7684 map \u4f5c\u4e3a this \u6307\u9488\u4f20\u5165\u6ca1 const \u4fee\u9970\u7684 operator[] \u51fd\u6570\uff0c\u662f\u51cf\u5c11\u4e86\u4fee\u9970\uff08discards qualifers\uff09\u3002 C++ \u89c4\u5b9a\u4f20\u53c2\u65f6\u53ea\u80fd\u589e\u52a0\u4fee\u9970\u4e0d\u80fd\u51cf\u5c11\u4fee\u9970\uff1a\u53ea\u80fd\u4ece map * \u8f6c\u6362\u5230 map const * \u800c\u4e0d\u80fd\u53cd\u4e4b\u3002 \u6240\u4ee5\u5bf9\u7740\u4e00\u4e2a const map \u8c03\u7528\u975e const \u7684\u6210\u5458\u51fd\u6570 operator[] \u5c31\u51fa\u9519\u4e86\uff0c\u76f8\u6bd4\u4e4b\u4e0b at() \u5c31\u53ef\u4ee5\u5728 const \u4fee\u9970\u4e0b\u7f16\u8bd1\u901a\u8fc7\u3002 \u4e3a\u4ec0\u4e48 operator[] \u662f\u975e const \u4fee\u9970\u7684\u5462\uff1f\u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u4e0d\u662f const\uff0c\u610f\u5473\u7740\u4ed6\u4f1a \u5c31\u5730\u4fee\u6539 this \u5bf9\u8c61 \u3002 \u5176\u5b9e\uff0coperator[] \u53d1\u73b0\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config); print(config[\"tmeout\"]); // \u6709\u526f\u4f5c\u7528\uff01 print(config); {\"delay\": 211, \"timeout\": 985} 0 {\"delay\": 211, \"timeout\": 985, \"tmeout\": 0} \u4f1a\u81ea\u52a8\u521b\u5efa\u90a3\u4e2a\u4e0d\u5b58\u5728\u7684\u952e\u503c\uff01 \u4f60\u4ee5\u4e3a\u4f60\u53ea\u662f\u89c2\u5bdf\u4e86\u4e00\u4e0b map \u91cc\u7684 \u201ctmeout\u201d \u5143\u7d20\uff0c\u5374\u610f\u5916\u6539\u53d8\u4e86 map \u7684\u5185\u5bb9\uff0c\u859b\u5b9a\u8c14\u76f4\u547c\u5185\u884c\u3002 \u4e3a\u4ec0\u4e48\u628a [] \u8bbe\u8ba1\u7684\u8fd9\u4e48\u5371\u9669\uff1f \u65e2\u7136\u5df2\u7ecf\u6709\u66f4\u5b89\u5168\u7684 .at()\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u8ba9 [] \u7ee7\u7eed\u5b58\u5728\u5462\uff1f map config = { {\"delay\", 211}, }; config.at(\"timeout\") = 985; // \u952e\u503c\u4e0d\u5b58\u5728\uff0c\u62a5\u9519\uff01 config[\"timeout\"] = 985; // \u6210\u529f\u521b\u5efa\u5e76\u5199\u5165 985 \u7531\u4e0a\u53ef\u89c1\uff0c\u5f53\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u672c\u4e0d\u5b58\u5728\u7684\u952e\u503c\u7684\u65f6\u5019\uff0c\u6070\u6070\u9700\u8981 [] \u7684\u201c\u81ea\u52a8\u521b\u5efa\u201d\u8fd9\u4e00\u7279\u6027\uff0c\u8fd9\u662f at() \u6240\u4e0d\u5177\u6709\u7684\u3002 \u603b\u7ed3\uff1a\u8bfb\u53d6\u65f6\u5e94\u8be5\u7528 at() \u66f4\u5b89\u5168\uff0c\u5199\u5165\u65f6\u624d\u9700\u8981\u7528\u5e26\u6709\u81ea\u52a8\u521b\u5efa\u529f\u80fd\u7684 []\u3002 \u8bb8\u591a\u7b2c\u4e09\u65b9\u5e93\uff0c\u4f8b\u5982 jsoncpp\uff0c\u4ed6\u4eec\u7684\u5b57\u5178\u7c7b\u578b\u4e5f\u4f7f\u7528\u7c7b\u4f3c\u7684\u63a5\u53e3\uff0cat() \u8d1f\u8d23\u8bfb\uff0c[] \u8d1f\u8d23\u5199\uff0c\u5206\u5de5\u660e\u786e\uff01","title":"\u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668"},{"location":"stl_map/#_18","text":"\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 at() \u5199\u5165\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 [] auto val = m.at(\"key\"); m[\"key\"] = val; \u4e3a\u4ec0\u4e48\u5176\u4ed6\u8bed\u8a00\u6bd4\u5982 Python\uff0c\u53ea\u6709\u4e00\u4e2a [] \u5c31\u884c\u4e86\u5462\uff1f\u800c C++ \u9700\u8981\u4e24\u4e2a\uff1f \u56e0\u4e3a Python \u4f1a\u68c0\u6d4b [] \u4f4d\u4e8e\u7b49\u53f7\u5de6\u4fa7\u8fd8\u662f\u53f3\u4fa7\uff0c\u6839\u636e\u60c5\u51b5\u5206\u522b\u8c03\u7528 __getitem__ \u6216\u8005 __setitem__ \u3002 C++ \u7f16\u8bd1\u5668\u6ca1\u6709\u8fd9\u4e2a\u7279\u6b8a\u68c0\u6d4b\uff0c\u4e5f\u68c0\u6d4b\u4e0d\u4e86\uff0c\u56e0\u4e3a C++ \u7684 [] \u53ea\u662f\u8fd4\u56de\u4e86\u4e2a\u5f15\u7528\uff0c\u5e76\u4e0d\u77e5\u9053 [] \u51fd\u6570\u8fd4\u56de\u4ee5\u540e\uff0c\u4f60\u662f\u62ff\u8fd9\u4e2a\u5f15\u7528\u5199\u5165\u8fd8\u662f\u8bfb\u53d6\u3002\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\u4ed6\u9ed8\u8ba4\u4f60\u662f\u5199\u5165\uff0c\u6240\u4ee5\u5148\u5e2e\u4f60\u521b\u5efa\u4e86\u5143\u7d20\uff0c\u8fd4\u56de\u8fd9\u4e2a\u5143\u7d20\u7684\u5f15\u7528\uff0c\u8ba9\u4f60\u5199\u5165\u3002 \u800c Python \u7684\u5f15\u7528\u662f\u4e0d\u80fd\u7528 = \u8986\u76d6\u539f\u503c\u7684\uff0c\u90a3\u6837\u53ea\u4f1a\u8ba9\u53d8\u91cf\u6307\u5411\u65b0\u7684\u5f15\u7528\uff0c\u53ea\u80fd\u7528 .func() \u5f15\u7528\u6210\u5458\u51fd\u6570\u6216\u8005 += \u624d\u80fd\u5c31\u5730\u4fee\u6539\u539f\u53d8\u91cf\uff0c\u8fd9\u662f Python \u8fd9\u7c7b\u811a\u672c\u8bed\u8a00\u548c C++ \u6700\u672c\u8d28\u7684\u4e0d\u540c\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7528 C++ \u7684 map \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u9700\u8981\u663e\u5f0f\u5730\u7528 at() \u544a\u8bc9\u7f16\u8bd1\u5668\u6211\u662f\u6253\u7b97\u8bfb\u53d6\u3002 [] \u627e\u4e0d\u5230\u5c31\u8fd4\u56de\u4e2a\u201c\u9ed8\u8ba4\u503c\u201d\uff0c\u5176\u5b9e\u4e5f\u662f\u5f88\u591a\u8bed\u8a00\u7684\u4f20\u7edf\u5f02\u80fd\u4e86\uff0c\u53ea\u6709\u521a\u597d Python \u6bd4\u8f83\u5bf9\u521d\u5b66\u8005\u53cb\u597d\uff0c\u4f1a\u81ea\u52a8\u5224\u65ad\u4f60\u7684 [] \u662f\u8bfb\u53d6\u8fd8\u662f\u5199\u5165\uff0c\u5982\u679c\u662f\u8bfb\u53d6\uff0c\u5f53\u627e\u4e0d\u5230\u952e\u503c\u65f6\u80fd\u53cb\u5584\u7684\u7ed9\u4f60\u62a5\u9519\u3002 \u8bed\u8a00\u53ca\u5176\u5173\u8054\u5bb9\u5668\u540d C++ map Python dict Lua table JS HashMap Java HashMap \u627e\u4e0d\u5230\u952e\u65f6\u7684\u884c\u4e3a \u9ed8\u9ed8\u8fd4\u56de 0 \u62a5\u9519 KeyError \u9ed8\u9ed8\u8fd4\u56de nil \u9ed8\u9ed8\u8fd4\u56de undefined .get()\uff0c\u9ed8\u9ed8\u8fd4\u56de null \u5176\u4e2d C++ \u7684 [] \u6700\u4e3a\u6076\u52a3\uff0c\u56e0\u4e3a\u53e4\u4ee3 C++ \u4e2d\u5e76\u6ca1\u6709\u4e00\u4e2a null \u6216 nil \u4e4b\u7c7b\u7684\u989d\u5916\u7279\u6b8a\u5e38\u91cf\u3002 [] \u8fd4\u56de\u7684\u5fc5\u987b\u662f\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u7531\u4e8e [] \u4e0d\u80fd\u62a5\u9519\uff0c\u503c\u7684\u7c7b\u578b\u53c8\u5343\u53d8\u4e07\u5316\uff0c map \u7684 [] \u53ea\u80fd\u8fd4\u56de\u201cV \u7c7b\u578b\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u7684\u503c\u201d\uff1a\u5bf9\u4e8e int \u800c\u8a00\u662f 0\uff0c\u5bf9\u4e8e string \u800c\u8a00\u662f \u201c\u201d\uff08\u7a7a\u5b57\u7b26\u4e32\uff09\u3002 \u4e5f\u6b63\u56e0\u5982\u6b64\uff0c\u5982\u679c\u4e00\u4e2a map \u4e2d\u7684 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5c31\u65e0\u6cd5\u4f7f\u7528 [] \u4e86\u3002\u770b\u4f3c\u7f8e\u597d\u7684 [] \u53ea\u662f\u9a97\u9a97\u5c0f\u5f6d\u53cb\u7684\u9762\u5b50\u5de5\u7a0b\uff0c\u6a21\u68f1\u4e24\u53ef\uff0c\u5145\u6ee1\u5371\u9669\u3002\u9ad8\u624b\u90fd\u4f7f\u7528\u66f4\u4e13\u4e1a\u7684\u5199\u5165\u51fd\u6570\uff1ainsert \u6216 insert_or_assign \u4ee3\u66ff\u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\u4e0d\u9700\u8981\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u66f4\u9ad8\u6548\u4e00\u4e9b\uff0c\u7a0d\u540e\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u3002 at \u4e0e [] \u5b9e\u6218\u6f14\u7ec3 \u6211\u4eec\u73b0\u5728\u7684\u7532\u65b9\u662f\u4e00\u4e2a\u5b66\u6821\u7684\u5927\u8001\u677f\uff0c\u4ed6\u5e0c\u671b\u8ba9\u6211\u4eec\u7ba1\u7406\u5b66\u751f\u4fe1\u606f\uff0c\u56e0\u6b64\u9700\u8981\u5efa\u7acb\u4e00\u4e2a\u6620\u5c04\u8868\uff0c\u80fd\u591f\u5feb\u901f\u901a\u8fc7\u5b66\u751f\u540d\u5b57\u67e5\u8be2\u5230\u76f8\u5e94\u7684\u5b66\u751f\u4fe1\u606f\u3002\u601d\u6765\u60f3\u53bb C++ \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668\u6700\u5408\u9002\u3002\u51b3\u5b9a\u8bbe\u8ba1\u5982\u4e0b\uff1a \u952e\u4e3a\u5b66\u751f\u7684\u540d\u5b57\uff0cstring \u7c7b\u578b\u3002 \u503c\u4e3a\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7ed3\u6784\u4f53\uff0cStudent \u7c7b\u578b\uff0c\u91cc\u9762\u5b58\u653e\u5404\u79cd\u5b66\u751f\u4fe1\u606f\u3002 \u7136\u540e\u81ea\u5b9a\u4e49\u4e00\u4e0b Student \u7ed3\u6784\u4f53\uff0c\u73b0\u5728\u628a\u9664\u4e86\u540d\u5b57\u4ee5\u5916\u7684\u5b66\u751f\u4fe1\u606f\u90fd\u585e\u5230\u8fd9\u4e2a\u7ed3\u6784\u4f53\u91cc\u3002 \u521b\u5efa map \u5bf9\u8c61\uff0c\u53d8\u91cf\u540d\u4e3a stus \uff0c\u8fd9\u4e2a map \u5c31\u662f\u7532\u65b9\u8981\u6c42\u7684\u5b66\u751f\u8868\uff0c\u6210\u529f\u4ea4\u5dee\u3002 struct Student { int id; // \u5b66\u53f7 int age; // \u5e74\u9f84 string sex; // \u6027\u522b int money; // \u5b58\u6b3e set skills; // \u6280\u80fd }; map stus; \u73b0\u5728\u5c0f\u5f6d\u8001\u5e08\u548c\u4ed6\u7684\u7ae5\u978b\u4eec\u8981\u8fdb\u5165\u8fd9\u5bb6\u5b66\u6821\u4e86\uff0c\u8ba9\u6211\u4eec\u7528 [] \u5927\u6cd5\u63d2\u5165\u4ed6\u7684\u4e2a\u4eba\u4fe1\u606f\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = Student{20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = Student{20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = Student{20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = Student{20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u7531\u4e8e C++11 \u5141\u8bb8\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b\u4e0d\u5199\uff0c\u6240\u4ee5 Student \u53ef\u4ee5\u7701\u7565\uff0c\u7b80\u5199\u6210\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = {20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = {20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u53c8\u7531\u4e8e map \u652f\u6301\u5728\u521d\u59cb\u5316\u65f6\u5c31\u6307\u5b9a\u6240\u6709\u5143\u7d20\uff0c\u6211\u4eec\u76f4\u63a5\u5199\uff1a map stus = { {\"\u5f6d\u4e8e\u658c\", {20220301, 22, \"\u81ea\u5b9a\u4e49\", 1000, {\"C\", \"C++\"}}}, {\"\u76f8\u4f9d\", {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}}, {\"\u6a31\u82b1\u7c89\u871c\u7cd6\", {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}}, {\"Sputnik02\", {20220301, 19, \"\u7537\", 4000, {\"C++\"}}}, }; \u73b0\u5728\u7532\u65b9\u8981\u6c42\u6dfb\u52a0\u4e00\u4e2a\u201c\u57f9\u8bad\u201d\u51fd\u6570\uff0c\u7528\u4e8e\u4ed6\u4eec\u7684 C++ \u57f9\u8bad\u8bfe\u3002 \u57f9\u8bad\u51fd\u6570\u7684\u53c2\u6570\u4e3a\u5b57\u7b26\u4e32\uff0c\u8868\u793a\u8981\u6d88\u8d39\u5b66\u751f\u7684\u540d\u5b57\u3002\u5982\u679c\u8be5\u540d\u5b57\u5b66\u751f\u4e0d\u5b58\u5728\uff0c\u5219\u5e94\u8be5\u53ca\u65f6\u62a5\u9519\u3002 \u6bcf\u6b21\u57f9\u8bad\u9700\u8981\u6d88\u8d39 2650 \u5143\uff0c\u6d88\u8d39\u6210\u529f\u540e\uff0c\u5f80\u6280\u80fd skills \u96c6\u5408\u4e2d\u52a0\u5165 \u201cC++\u201d\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u8fd9\u662f\u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 stu.money -= 2650; stu.skills.insert(\"C++\"); } \u7136\u800c\uff0c\u8fd9\u6837\u5199\u662f\u4e0d\u5bf9\u7684\uff01 stus.at(stuName) \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528 Student & \u6307\u5411 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u4f46\u662f\u7b49\u53f7\u5de6\u4fa7\uff0c\u5374\u662f\u4e2a\u4e0d\u5e26\u4efb\u4f55\u4fee\u9970\u7684 auto \uff0c\u4ed6\u4f1a\u88ab\u63a8\u5bfc\u4e3a Student \u3002\u5982\u4f55\u4ece\u4e00\u4e2a\u5f15\u7528 Student & \u8f6c\u6362\u4e3a\u5177\u4f53\u7684 Student \uff1f\u627e\u4e0d\u5230 Student(Student &) \uff0c\u4f46\u662f\u627e\u5230\u4e86\u6700\u63a5\u8fd1\u7684 Student(Student const &) \u51fd\u6570\uff08\u8fd9\u662f\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff09\uff0c\u56e0\u6b64\u6211\u4eec\u62f7\u8d1d\u4e86\u4e00\u4efd map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\uff0c\u5230\u6808\u4e0a\u7684 stu \u53d8\u91cf\uff0c\u4e4b\u540e\u4e0d\u8bba\u5982\u4f55\u4fee\u6539\uff0c\u4fee\u6539\u7684\u90fd\u662f\u8fd9\u4e2a\u6808\u4e0a\u5bf9\u8c61\uff0c\u800c\u4e0d\u4f1a\u5bf9 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u4ea7\u751f\u4efb\u4f55\u5f71\u54cd\u3002 \u7ed3\u8bba\uff1a\u628a\u5f15\u7528\u4fdd\u5b58\u5230\u666e\u901a\u53d8\u91cf\u4e2d\uff0c\u5219\u5f15\u7528\u4f1a\u9000\u5316\uff0c\u9020\u6210\u6df1\u62f7\u8d1d\uff01\u4e0d\u4ec5\u5f71\u54cd\u6027\u80fd\uff0c\u8fd8\u5f71\u54cd\u529f\u80fd\uff01stu \u5df2\u7ecf\u662f\u4e00\u4e2a\u72ec\u7acb\u7684 Student \u5bf9\u8c61\uff0c\u5bf9 stu \u7684\u4fee\u6539\u5df2\u7ecf\u4e0d\u4f1a\u5f71\u54cd\u5230 stus.at(stuName) \u6307\u5411\u7684\u90a3\u4e2a Student \u5bf9\u8c61\u4e86\u3002 \u6b64\u65f6\u4f60\u5bf9\u8fd9\u4e2a\u666e\u901a\u53d8\u91cf\u7684\u6240\u6709\u4fee\u6539\uff0c\u90fd\u4e0d\u4f1a\u540c\u6b65\u5230 map \u4e2d\u7684\u90a3\u4e2a Student \u4e2d\u53bb\uff01 \u6211\u4eec\u73b0\u5728\u5bf9\u76f8\u4f9d\u7ae5\u978b\u8fdb\u884c C++ \u57f9\u8bad\uff1a PeiXunCpp(\"\u76f8\u4f9d\"); print(stus.at(\"\u76f8\u4f9d\")); \u7ed3\u679c\u53d1\u73b0\u4ed6\u7684\u5b58\u6b3e\u4e00\u5206\u6ca1\u5c11\uff0c\u4e5f\u6ca1\u5b66\u4f1a C++\uff1a {id: 20220302, age: 21, sex: \"\u7537\", money: 2000, skills: {\"C\", \"Java\"}} \u770b\u6765\u6211\u4eec\u7684\u4fee\u6539\u6ca1\u6709\u5728 map \u4e2d\u751f\u6548\uff1f\u539f\u6765\u662f\u56e0\u4e3a\u6211\u4eec\u5728 PeiXunCpp \u51fd\u6570\u91cc\uff1a auto stu = stus.at(stuName); // \u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 \u4e00\u4e0d\u5c0f\u5fc3\u5c31\u7528\u4e86\u201c\u514b\u9686\u4eba\u201d\u6280\u672f\uff01\u4ece\u5b66\u751f\u8868\u91cc\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\uff0c\u514b\u9686\u4e86\u4e00\u4efd\u653e\u5230\u6808\u4e0a\u7684\u201c\u76f8\u4f9d2\u53f7\u201d\uff01 \u7136\u540e\u6211\u4eec\u6263\u4e86\u8fd9\u4e2a\u4e34\u65f6\u514b\u9686\u4eba\u201c\u76f8\u4f9d2\u53f7\u201d\u7684\u94b1\uff0c\u5e76\u7ed9\u4ed6\u57f9\u8bad C++ \u6280\u672f\u3002 \u7136\u800c\u6211\u4eec\u57f9\u8bad\u7684\u662f\u6808\u4e0a\u7684\u4e34\u65f6\u53d8\u91cf\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u514b\u9686\u524d\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5e76\u6ca1\u6709\u53d7\u5230\u57f9\u8bad\uff0c\u4e5f\u6ca1\u6709\u6263\u94b1\u3002 \u7136\u540e\u5462\uff1f\u6b8b\u5fcd\u7684\u4e8b\u60c5\u53d1\u751f\u4e86\uff01\u5728\u5c0f\u5f6d\u8001\u5e08\u4e00\u901a\u64cd\u4f5c\u57f9\u8bad\u5b8c\u201c\u76f8\u4f9d2\u53f7\u201d\u540e\uff0c\u6211\u4eec\u628a\u4ed6\u9001\u4e0a\u65ad\u5934\u53f0\u2014\u2014\u6790\u6784\u4e86\uff01 \u800c\u8fd9\u4e00\u5207\u201c\u76f8\u4f9d1\u53f7\u201d\u5b8c\u5168\u4e0d\u77e5\u60c5\uff0c\u4ed6\u53ea\u77e5\u9053\u6709\u4eba\u558a\u4ed6\u505a\u514b\u9686\uff0c\u7136\u540e\u5c31\u56de\u5bb6\u73a9 Java \u53bb\u4e86\uff0c\u5e76\u6ca1\u6709\u57f9\u8bad C++ \u7684\u8bb0\u5fc6\u3002 \u8981\u9632\u6b62\u5f15\u7528\u9000\u5316\u6210\u666e\u901a\u53d8\u91cf\uff0c\u9700\u8981\u628a\u53d8\u91cf\u7c7b\u578b\u4e5f\u6539\u6210\u5f15\u7528\uff01\u8fd9\u79cd\u662f\u6d45\u62f7\u8d1d\uff0cstu \u548c stus.at(stuName) \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u4e2a Student \u5bf9\u8c61\u3002\u7528 auto \u6355\u83b7\u7684\u8bdd\uff0c\u6539\u6210 auto & \u5c31\u884c\u3002 void PeiXunCpp(string stuName) { auto &stu = stus.at(stuName); // \u5728\u6808\u4e0a\u521b\u5efa\u4e00\u4e2a\u6307\u5411\u539f Student \u5bf9\u8c61\u7684\u5f15\u7528 stu.money -= 2650; stu.skills.insert(\"C++\"); } {id: 20220302, age: 21, sex: \"\u7537\", money: -650, skills: {\"C\", \"C++\", \"Java\"}} \u7ec8\u4e8e\uff0c\u6b63\u7248\u201c\u76f8\u4f9d1\u53f7\u201d\u672c\u4f53\u978b\u5e9f\u4e86 C++\uff01 \u4e4b\u540e\u5982\u679c\u518d\u4ece\u201c\u76f8\u4f9d1\u53f7\u201d\u8eab\u4e0a\u514b\u9686\uff0c\u514b\u9686\u51fa\u6765\u7684\u201c\u76f8\u4f9dn\u53f7\u201d\u4e5f\u90fd\u4f1a\u5177\u6709\u57f9\u8bad\u8fc7 C++ \u7684\u8bb0\u5fc6\u4e86\u3002 \u5f15\u7528\u76f8\u5f53\u4e8e\u8eab\u4efd\u8bc1\uff0c\u6211\u4eec\u590d\u5370\u4e86\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\uff0c\u8eab\u4efd\u8bc1\u4e0d\u4ec5\u590d\u5370\u8d77\u6765\u6bd4\u514b\u9686\u4e00\u4e2a\u5927\u6d3b\u4eba\u5bb9\u6613\uff08\u62f7\u8d1d\u5f00\u9500\uff09\u4ece\u800c\u63d0\u5347\u6027\u80fd\uff0c\u800c\u4e14\u901a\u8fc7\u8eab\u4efd\u8bc1\u53ef\u4ee5\u627e\u5230\u672c\u4eba\uff0c\u5bf9\u8eab\u4efd\u8bc1\u7684\u4fee\u6539\u4f1a\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u6539\u4e3a\u5bf9\u672c\u4eba\u7684\u4fee\u6539\uff0c\u4f8b\u5982\u901a\u8fc7\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\u5728\u94f6\u884c\u5f00\u5361\u7b49\uff0c\u94f6\u884c\u8981\u7684\u662f\u8eab\u4efd\u8bc1\uff0c\u4e0d\u662f\u514b\u9686\u4eba\u54e6\u3002 \u5f15\u7528\u662f\u4e00\u4e2a\u70eb\u624b\u7684\u9999\u9999\u9762\u5305\uff0c\u666e\u901a\u53d8\u91cf\u5c31\u50cf\u4e00\u4e2a\u81ed\u81ed\u7684\u7b54\u8fa9\u9a6c\u6876\uff0c\u628a\u9762\u5305\u653e\u5230\u9a6c\u6876\uff08auto\uff09\u91cc\uff0c\u9762\u5305\u5c31\u81ed\u6389\uff0c\u8150\u70c2\u6389\uff0c\u4e0d\u80fd\u5403\u4e86\uff01\u8981\u8ba9\u9762\u5305\u8f6c\u79fb\u9635\u5730\u4e86\u4ee5\u540e\u4f9d\u7136\u597d\u5403\uff0c\u9700\u8981\u653e\u5230\u4fdd\u9c9c\u76d2\uff08auto &\uff09\u91cc\u3002 \u8fd9\u5c31\u662f C++ \u7684 decay\uff08\u4e2d\u6587\u521a\u597d\u662f\u201c\u9000\u5316\u201d\u3001\u201c\u53d8\u8d28\u201d\u7684\u610f\u601d\uff09\u89c4\u5219\u3002 \u4ee5\u4e0b\u90fd\u662f\u201c\u9999\u9999\u9762\u5305\u201d\uff0c\u653e\u8fdb\u9a6c\u6876\u91cc\u4f1a\u53d8\u8d28\uff1a T & \u4f1a\u53d8\u8d28\u6210 T \uff08\u5f15\u7528\u53d8\u8d28\u6210\u666e\u901a\u53d8\u91cf\uff09 T [] \u4f1a\u53d8\u8d28\u6210 T * \uff08\u6570\u7ec4\u53d8\u8d28\u6210\u9996\u5730\u5740\u6307\u9488\uff09 T () \u4f1a\u53d8\u8d28\u6210 T (*)() \uff08\u51fd\u6570\u53d8\u8d28\u6210\u51fd\u6570\u6307\u9488\uff09 \u5728\u51fd\u6570\u7684\u53c2\u6570\u4e2d\u3001\u51fd\u6570\u7684\u8fd4\u56de\u503c\u4e2d\u3001auto \u6355\u83b7\u7684\u53d8\u91cf\u4e2d\uff0c\u653e\u5165\u8fd9\u4e9b\u201c\u9999\u9999\u9762\u5305\u201d\u90fd\u4f1a\u53d1\u751f\u53d8\u8d28\uff01 \u5982\u4f55\u907f\u514d\u53d8\u8d28\uff1f\u90a3\u5c31\u4e0d\u8981\u7528\u9a6c\u6876\uff08\u666e\u901a\u53d8\u91cf\uff09\u88c5\u9762\u5305\u5457\uff01\u7528\u4fdd\u9c9c\u76d2\uff08\u5f15\u7528\u53d8\u91cf\uff09\u88c5\uff01 \u907f\u514d\u5f15\u7528 T &t \u53d8\u8d28\uff0c\u5c31\u5f97\u628a\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u6539\u6210\u5f15\u7528\uff0c\u6216\u8005\u7528 auto & \uff0c auto const & \u6355\u83b7\u624d\u884c\u3002 \u907f\u514d\u539f\u751f\u6570\u7ec4 T t[N] \u53d8\u8d28\uff0c\u4e5f\u53ef\u4ee5\u6539\u6210\u5f15\u7528 T (&t)[N] \uff0c\u4f46\u6bd4\u8f83\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u5c01\u88c5\u7684\u5b89\u5168\u9759\u6001\u6570\u7ec4 array \u6216 C++98 \u5c31\u6709\u7684\u5b89\u5168\u52a8\u6001\u6570\u7ec4 vector \u3002 \u907f\u514d\u51fd\u6570 T f() \u53d8\u8d28\uff0c\u53ef\u4ee5 T (&f)() \uff0c\u4f46\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u7684\u51fd\u6570\u5bf9\u8c61 function \u3002","title":"\u603b\u7ed3"},{"location":"stl_map/#c","text":"\u9898\u5916\u8bdd\uff1a\u90aa\u6076\u7684\u9000\u5316\u89c4\u5219\u9020\u6210\u7a7a\u60ac\u6307\u9488\u7684\u6848\u4f8b typedef double arr_t[10]; auto func(arr_t val) { arr_t ret; memcpy(ret, val, sizeof(arr_t)); // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; // double [10] \u81ea\u52a8\u53d8\u8d28\u6210 double * } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); // \u6b64\u5904 auto \u4f1a\u88ab\u63a8\u5bfc\u4e3a double * print(std::span(ret, ret + 10)); return 0; } Segmentation fault (core dumped) \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6 ^{14}C ^{14}C \u8bed\u8a00\u201c\u8870\u53d8\u201d\u5bfc\u81f4\u7a0b\u5e8f Segmentation fault \u4e86\u3002 \u4fee\u590d\u65b9\u6cd5\uff1a\u522b\u518d\u7528 C \u8bed\u8a00\u7684\u715e\u7b14\u539f\u59cb\u4eba\u6570\u7ec4\u4e86\uff01\u7528 C++ \u5c01\u88c5\u597d\u7684 array\uff0c\u65e0\u9690\u60a3 typedef std::array arr_t; // \u5982\u9700\u52a8\u6001\u957f\u5ea6\uff0c\u6539\u7528 vector \u4ea6\u53ef auto func(arr_t val) { arr_t ret; ret = val; // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); print(ret); return 0; } {1, 2, 3, 4, 0, 0, 0, 0, 0, 0} \u5982\u679c\u4f60\u8fd8\u662f\u5b66\u4e0d\u4f1a\u600e\u4e48\u4fdd\u7559\u9999\u9999\u5f15\u7528\u7684\u8bdd\uff0c\u571f\u529e\u6cd5\uff1a\u4e5f\u53ef\u4ee5\u5728\u4fee\u6539\u540e\u518d\u6b21\u7528 [] \u5199\u56de\u5b66\u751f\u8868\u3002\u8fd9\u6837\u5b66\u751f\u8868\u91cc\u4e0d\u4f1a C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5c31\u4f1a\u88ab\u6211\u4eec\u6808\u4e0a\u57f9\u8bad\u8fc7 C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u8986\u76d6\uff0c\u73b0\u5728\u5b66\u751f\u8868\u91cc\u7684\u4e5f\u662f\u6709 C++ \u6280\u80fd\u7684\u201c\u76f8\u4f9d\u201d\u8fa3\uff01\u53ea\u4e0d\u8fc7\u9700\u8981\u7ffb\u6765\u8986\u53bb\u514b\u9686\u4e86\u597d\u51e0\u6b21\u6bd4\u8f83\u4f4e\u6548\u800c\u5df2\uff0c\u81f3\u5c11\u80fd\u7528\u4e86\uff0c\u5efa\u8bae\u53ea\u6709\u5b66\u4e0d\u61c2\u5f15\u7528\u7684\u7ae5\u978b\u518d\u7528\u8fd9\u79cd\u4fdd\u5e95\u5199\u6cd5\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u514b\u9686\u4e86\u4e00\u4efd\u201c\u76f8\u4f9d2\u53f7\u201d stu.money -= 2650; stu.skills.insert(\"C++\"); stus[stuName] = stu; // \u201c\u76f8\u4f9d2\u53f7\u201d\u593a\u820d\uff0c\u628a\u201c\u76f8\u4f9d1\u53f7\u201d\u7ed9\u8986\u76d6\u6389\u4e86 } \u72c2\u60f3\uff1a\u5982\u679c\u514b\u9686\u201c\u76f8\u4f9d1\u53f7\u201d\u540c\u5b66\uff0c\u5f97\u5230\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u7136\u540e\u628a\u539f\u6765\u7684\u6740\u2026\u2026\u554a\u4e0d\u5bf9\uff0c\u201c\u6790\u6784\u201d\u6389\uff0c\u7136\u540e\u5bf9\u5916\u8c0e\u79f0\u201c\u8fd9\u8fd8\u662f\u539f\u6765\u7684\u76f8\u4f9d1\u53f7\u5440\uff01\u201d\u4f1a\u4e0d\u4f1a\u88ab\u53d1\u73b0\u5462\uff1f \u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u4e0a\u9762\u4ee3\u7801\u7b2c 5 \u884c\u4e5f\u53ef\u4ee5\u6539\u7528 at\uff0c\u4e3a\u4ec0\u4e48\uff1f\u5c0f\u5f6d\u8001\u5e08\u4e0d\u662f\u8bf4 \u201cat \u7528\u4e8e\u8bfb\u53d6\uff0c[] \u7528\u4e8e\u5199\u5165\u201d \u5417\uff1f \u6211\u4eec\u7ae5\u978b\u8981\u5b66\u4f1a\u53d8\u901a\uff01\u5c0f\u5f6d\u8001\u5e08\u8b66\u544a\u8bf4 \u201c[] \u53ea\u80fd\u7528\u4e8e\u5199\u5165\u201d\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u5e73\u65f6\u7684\u5199\u5165\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u9700\u8981\u5199\u5165\u5230\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u6240\u4ee5 [] \u4f1a\u81ea\u52a8\u521b\u5efa\u5143\u7d20\u5c31\u5f88\u65b9\u4fbf\uff1b\u5982\u679c\u662f at() \u5c31\u4e0d\u7b26\u5408\u201c\u5199\u5165\u65f6\u81ea\u52a8\u521b\u5efa\u4e0d\u5b58\u5728\u7684\u952e\u201c\u3002\u4f46\u662f\u73b0\u5728\u7684\u60c5\u51b5\u662f\u6211\u4eec\u7b2c 2 \u884c\u5df2\u7ecf\u8bbf\u95ee\u8fc7 at(\"\u76f8\u4f9d\") \uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u786e\u8ba4 \"\u76f8\u4f9d\" \u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u56e0\u6b64\u6211\u5199\u5165\u7684\u4e00\u5b9a\u662f\u4e2a\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\uff0c\u8fd9\u65f6 [] \u548c at \u5df2\u7ecf\u6ca1\u533a\u522b\u4e86\uff0c\u6240\u4ee5\u7528 at \u7684\u975e const \u91cd\u8f7d\uff0c\u4e00\u6837\u53ef\u4ee5\u5199\u5165\u3002 \u6211\u4eec\u7ae5\u978b\u4e0d\u662f\u53bb\u6b7b\u8bb0\u786c\u80cc\u300a\u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55\u300b\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u540d\u8a00\u5f53\u505a\u201c\u4e24\u4e2a\u51e1\u662f\u201d\u5723\u7ecf\u3002\u8981\u7406\u89e3\u5c0f\u5f6d\u8001\u5e08\u4f1a\u8fd9\u4e48\u8bf4\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u624d\u80fd\u6839\u636e\u4e0d\u540c\u5b9e\u9645\u60c5\u51b5\uff0c\u5b9e\u4e8b\u6c42\u662f\u770b\u95ee\u9898\uff0c\u624d\u662f\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u552f\u7269\u7f16\u7a0b\u89c2\u7684\uff08\u5b5d\uff09 \u5982\u679c\u8981\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u5462\uff1f\u90a3\u5c31\u4ee5\u5b66\u53f7\u4e3a\u952e\uff0c\u7136\u540e\u628a\u5b66\u751f\u59d3\u540d\u653e\u5230 Student \u7ed3\u6784\u4f53\u4e2d\u3002 \u5982\u679c\u540c\u65f6\u6709\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u548c\u6839\u636e\u59d3\u540d\u67e5\u627e\u4e24\u79cd\u9700\u6c42\u5462\uff1f \u540c\u65f6\u9ad8\u6548\u5730\u6839\u636e\u591a\u4e2a\u952e\u8fdb\u884c\u67e5\u627e\uff0c\u751a\u81f3\u6307\u5b9a\u5404\u79cd\u6761\u4ef6\uff0c\u6bd4\u5982\u67e5\u8be2\u6240\u6709\u4f1a C++ \u7684\u5b66\u751f\u7b49\uff0c\u8fd9\u53ef\u4e0d\u662f map \u80fd\u641e\u5b9a\u7684\uff0c\u6216\u8005\u8bf4\u80fd\u641e\u5b9a\u4f46\u4e0d\u9ad8\u6548\uff08\u6700\u540e\u5f80\u5f80\u53ea\u80fd\u66b4\u529b\u904d\u5386\u67e5\u627e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u592a\u9ad8\uff09\u3002\u8fd9\u662f\u4e2a\u4e13\u95e8\u7684\u7814\u7a76\u9886\u57df\uff0c\u79f0\u4e3a\uff1a\u5173\u7cfb\u6570\u636e\u5e93\u3002 \u5173\u7cfb\u6570\u636e\u5e93\u7684\u5b9e\u73b0\u6709 MySQL\uff0cSQLite\uff0cMongoDB \u7b49\u3002C++ \u7b49\u7f16\u7a0b\u8bed\u8a00\u53ea\u9700\u8c03\u7528\u4ed6\u4eec\u63d0\u4f9b\u7684 API \u5373\u53ef\uff0c\u4e0d\u5fc5\u81ea\u5df1\u624b\u52a8\u5b9e\u73b0\u8fd9\u4e9b\u590d\u6742\u7684\u67e5\u627e\u548c\u63d2\u5165\u7b97\u6cd5\u3002 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u4e13\u4e1a\u7684\u201c\u5b66\u751f\u7ba1\u7406\u7cfb\u7edf\u201d\u90fd\u4f1a\u7528\u5173\u7cfb\u6570\u636e\u5e93\uff0c\u800c\u4e0d\u662f\u81ea\u5df1\u624b\u52a8\u7ef4\u62a4\u4e00\u4e2a map\u3002\u5173\u7cfb\u6570\u636e\u5e93\u5e95\u5c42\u7684\u6570\u636e\u7ed3\u6784\u66f4\u590d\u6742\uff0c\u4f46\u7ecf\u8fc7\u9ad8\u5ea6\u5c01\u88c5\uff0c\u6548\u7387\u66f4\u9ad8\uff0c\u63d0\u4f9b\u7684\u529f\u80fd\u4e5f\u66f4\u5168\u9762\uff0c\u7528\u8d77\u6765\u4e5f\u6bd4\u8f83\u65e0\u611f\u3002\u4f55\u51b5 map \u5b58\u5728\u5185\u5b58\u4e2d\uff0c\u7535\u8111\u4e00\u5173\u673a\uff0c\u5b66\u751f\u6570\u636e\u5c31\u6ca1\u4e86\uff01\u800c\u6570\u636e\u5e93\u53ef\u4ee5\u628a\u6570\u636e\u6301\u4e45\u5316\u5230\u78c1\u76d8\u4e2d\uff0c\u76f8\u5f53\u4e8e\u5728\u78c1\u76d8\u91cc\u6784\u5efa\u51fa\u4e86\u4e00\u9897\u67e5\u627e\u6811\uff0c\u5173\u673a\u540e\u6570\u636e\u4f9d\u7136\u4fdd\u6301\u3002 \u76f8\u4f9d\u540c\u5b66\u597d\u4e0d\u5bb9\u6613\u8003\u51fa\u6ee1\u5206\uff0c\u7ed3\u679c\u5c0f\u5f6d\u8001\u5e08\u4e00\u4e0d\u5c0f\u5fc3\u8e22\u4e86\u4e00\u811a\u7535\u8111\uff0c\u91cd\u542f\uff0c\u5168\u90e8\u5b66\u751f\u6863\u6848\u4e22\u5931\uff0c\u767d\u8003\uff01 \u67e5\u8be2 map \u4e2d\u5143\u7d20\u7684\u6570\u91cf size_t size() const noexcept; \u4f7f\u7528 m.size() \u83b7\u5f97\u7684 map \u5927\u5c0f\uff0c\u6216\u8005\u8bf4\u5176\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002 map m; print(m.size()); // 0 m[\"fuck\"] = 985; print(m.size()); // 1 m[\"dick\"] = 211; print(m.size()); // 2 \u5e94\u7528\u4e3e\u4f8b\uff1a\u7ed9\u6bcf\u4e2a\u952e\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u8ba1\u6570 map m; m[\"fuck\"] = m.size(); m[\"dick\"] = m.size(); \u9700\u8981 C++17 \u4ee5\u4e0a\u7684\u7248\u672c\uff0c\u624d\u80fd\u4fdd\u8bc1\u7b49\u53f7\u53f3\u8fb9\u7684 m.size() \u5148\u4e8e m[\"fuck\"] \u6c42\u503c\u3002C++14 \u4e2d\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u884c\u4e3a\u672a\u5b9a\u4e49\uff0c\u9700\u8981\u6539\u7528 m.insert({\"fuck\", m.size()}) \u7684\u5199\u6cd5\uff08\u51fd\u6570\u53c2\u6570\u603b\u662f\u4f18\u5148\u4e8e\u51fd\u6570\u6c42\u503c\uff0c\u8fd9\u4fdd\u8bc1 m.size() \u5148\u6c42\u503c\uff0c\u7136\u540e\u624d\u53d1\u751f\u5143\u7d20\u63d2\u5165\uff09\u3002 \u5224\u65ad\u4e00\u4e2a\u952e\u662f\u5426\u5b58\u5728\uff1acount \u51fd\u6570 size_t count(K const &k) const; count \u8fd4\u56de\u5bb9\u5668\u4e2d\u952e\u548c\u53c2\u6570 k \u76f8\u7b49\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 count \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u4e00\u4e2a\u952e\u5728 map \u4e2d\u662f\u5426\u5b58\u5728\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.count(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } if (msg.count(\"dick\")) { print(\"\u5b58\u5728dick\uff0c\u5176\u503c\u4e3a\", msg.at(\"suck\")); } else { print(\"\u627e\u4e0d\u5230dick\"); } {\"fuck\": \"rust\", \"hello\": \"world\"} \u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a \"rust\" \u627e\u4e0d\u5230dick C++20 \u4e2d\u5efa\u8bae\u6539\u7528\u8fd4\u56de\u7c7b\u578b\u4e3a bool \u7684 contains \u51fd\u6570\uff0c\u51fd\u6570\u540d\u548c\u7c7b\u578b\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u4f46\u5b9e\u9645\u6548\u679c\u548c count \u662f\u4e00\u6837\u7684\u3002 if (msg.contains(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); }","title":"C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45"},{"location":"stl_map/#_19","text":"\u9664\u4e86\u5199\u5165\u5143\u7d20\u9700\u8981\u7528 [] \u4ee5\u5916\uff0c\u8fd8\u6709\u4e00\u4e9b\u6848\u4f8b\u4e2d\u5408\u7406\u8fd0\u7528 [] \u4f1a\u975e\u5e38\u7684\u65b9\u4fbf\u3002 [] \u7684\u6548\u679c\uff1a\u5f53\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u4e00\u4e2a\u5143\u7d20 1 \u3002 \u5bf9\u4e8e int, float \u7b49\u6570\u503c\u7c7b\u578b\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f 0\u3002 \u5bf9\u4e8e\u6307\u9488\uff08\u5305\u62ec\u667a\u80fd\u6307\u9488\uff09\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f nullptr\u3002 \u5bf9\u4e8e string \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 \u201c\u201d\u3002 \u5bf9\u4e8e vector \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u6570\u7ec4 {}\u3002 \u5bf9\u4e8e\u81ea\u5b9a\u4e49\u7c7b\u800c\u8a00\uff0c\u4f1a\u8c03\u7528\u4f60\u5199\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5219\u6bcf\u4e2a\u6210\u5458\u90fd\u53d6\u9ed8\u8ba4\u503c\u3002","title":"\u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528"},{"location":"stl_map/#_20","text":"vector input = {\"hello\", \"world\", \"hello\"}; map counter; for (auto const &key: input) { counter[key]++; } print(counter); {\"hello\": 2, \"world\": 1}","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1"},{"location":"stl_map/#_21","text":"\u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa 0 \u5143\u7d20\u7684\u7279\u6027 map counter; for (auto const &key: input) { counter[key]++; } \u53e4\u677f\u7684\u5199\u6cd5 map counter; for (auto const &key: input) { if (!counter.count(key)) { counter[key] = 1; } else { counter[key] = counter.at(key) + 1; } }","title":"\u5bf9\u6bd4"},{"location":"stl_map/#_22","text":"vector input = {\"happy\", \"world\", \"hello\", \"weak\", \"strong\"}; map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); {'h': {\"happy\", \"hello\"}, 'w': {\"world\", \"weak\"}, 's': {\"strong\"}}","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b"},{"location":"stl_map/#_23","text":"\u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa\u201d\u9ed8\u8ba4\u503c\u201d\u5143\u7d20\u7684\u7279\u6027 map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); \u53e4\u677f\u7684\u5199\u6cd5 map> categories; for (auto const &str: input) { char key = str[0]; if (!categories.count(key)) { categories[key] = {str}; } else { categories[key].push_back(str); } }","title":"\u5bf9\u6bd4"},{"location":"stl_map/#_24","text":"concurrent_map tls; parallel_for([] { Data &data = tls[std::this_thread::get_id()]; ...; }); \u4e0d\u8fc7 thread_local \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u53d6\u4ee3\u3002","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf"},{"location":"stl_map/#_25","text":"\u53cd\u9762\u5178\u578b\uff1a\u67e5\u627e\u7279\u5b9a\u5143\u7d20\u5728 vector \u4e2d\u7684\u4f4d\u7f6e\uff08\u4e0b\u6807\uff09 size_t array_find(vector const &arr, string const &val) { for (size_t i = 0; i < arr.size(); i++) { if (arr[i] == val) return i; } return (size_t)-1; } vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; print(\"hello\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"fucker\")); // O(N) \u4f4e\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"nice\")); // O(N) \u4f4e\u6548 \u6bcf\u6b21\u8c03\u7528 array_find \uff0c\u90fd\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a0 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N^2) O(N^2) \u3002 \u6ce8\uff1a\u5047\u8bbe vector \u4e2d\u4e0d\u5b58\u5728\u91cd\u590d\u7684\u5143\u7d20","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868"},{"location":"stl_map/#map_4","text":"\u6b63\u786e\u505a\u6cd5\uff1a\u6784\u5efa vector \u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u4ee5\u540e\u67e5\u627e\u66f4\u9ad8\u6548 vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; map arrinv; for (size_t i = 0; i < arr.size(); i++) { // O(N) \u4e00\u6b21\u6027\u53d7\u82e6 arrinv[arr[i]] = i; } print(\"\u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a\", arrinv); print(\"fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"fucker\")); // O(log N) \u9ad8\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"nice\")); // O(log N) \u9ad8\u6548 \u53ea\u6709\u7b2c\u4e00\u6b21\u6784\u9020\u53cd\u5411\u67e5\u627e\u8868\u65f6\uff0c\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u4ee5\u540e\u6bcf\u6b21\u8c03\u7528 map.at \uff0c\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a{\"day\": 3, \"fucker\", 4, \"hello\": 0, \"nice\": 2, \"world\": 1} fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a4 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u8f76\u4e8b\uff1a\u5728\u6570\u636e\u5e93\u4e2d\uff0c\u8fd9\u79cd\u53cd\u5411\u67e5\u627e\u8868\u88ab\u79f0\u4e3a\u201c\u5012\u5e8f\u7d22\u5f15\u201d\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u5728\u4e0d\u77e5\u9053\u8fd9\u4e2a\u672f\u8bed\u7684\u60c5\u51b5\u4e0b\uff0c\u72ec\u7acb\u4ea7\u751f\u4e86\u53cd\u5411\u67e5\u627e\u8868\u7684\u601d\u60f3 for (size_t i = 0; i < arr.size(); i++) { arrinv[arr[i]] = i; } \u63d0\u524d\u6784\u9020\u597d\u67e5\u627e\u8868 O(N) O(N) \uff0c\u4ee5\u540e\u6bcf\u6b21\u67e5\u627e\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u5c31\u884c\u3002 \uff08\u6b63\u5411\u67e5\u627e\uff09\u5df2\u77e5\u4e0b\u6807 i\uff0c\u6c42\u5143\u7d20 v\uff1a v = arr[i] \uff08\u53cd\u5411\u67e5\u627e\uff09\u5df2\u77e5\u5143\u7d20 v\uff0c\u6c42\u4e0b\u6807 i\uff1a i = arrinv[v] \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N \\log N) O(N \\log N) \uff0c\u6bd4\u4f18\u5316\u524d\u9ad8\u6548\u3002 \u56e0\u6b64\u5f53\u9700\u8981\u591a\u6b21\u67e5\u627e\u4e14\u539f\u6570\u7ec4\u4fdd\u6301\u4e0d\u53d8\u65f6\uff0c\u5f3a\u70c8\u63a8\u8350\u7528\u8fd9\u79cd\u65b9\u6cd5\uff0c\u66f4\u9ad8\u6548\u3002 \u53ea\u6709\u5f53 vector \u66f4\u65b0\u65f6\uff0c\u624d\u9700\u8981\u91cd\u65b0\u6784\u5efa map\u3002\u5982\u679c vector \u7684\u5220\u9664\u91c7\u7528 back-swap-erase\uff08\u89c1 C++ \u5c0f\u5999\u62db \uff09\uff0c\u90a3\u4e48\u65e0\u9700\u5b8c\u5168\u91cd\u6784 map\uff0c\u53ea\u9700\u66f4\u65b0 swap \u7684\u4e24\u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u603b\u590d\u6742\u5ea6 O(\\log N) O(\\log N) \uff0c\u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a O(\\log N) O(\\log N) \u7684\u6709\u4e0b\u6807\u53c8\u80fd\u5feb\u901f\u67e5\u627e\u6570\u7ec4\uff0c\u517c\u5177 map \u548c vector \u7684\u4f18\u52bf\u3002\u5728\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8fdb\u9636\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u6b64\u7c7b\u590d\u5408\u6570\u636e\u7ed3\u6784\u3002","title":"map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868"},{"location":"stl_map/#map-map","text":"map \u53ea\u80fd\u901a\u8fc7\u503c\u6620\u5c04\u5230\u952e\uff0c\u80fd\u4e0d\u80fd\u53cd\u8fc7\u6765\u901a\u8fc7\u952e\u67e5\u627e\u503c\uff1f \u6848\u4f8b\uff1a\u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map tab = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; map tabinv; for (auto const &[k, v]: tab) { tabinv[v] = k; } print(tabinv); \u6548\u679c\u5c31\u662f\uff0c\u952e\u53d8\u503c\uff0c\u503c\u53d8\u952e\uff0c\u53cd\u4e00\u53cd\uff0c\u4e24\u4e2a map \u4e92\u4e3a\u9006\u8fd0\u7b97\uff1a {\"rust\": \"fuck\", \"world\": \"hello\"} \u6ce8\u610f\uff1a\u8981\u6c42 tab \u4e2d\u4e0d\u80fd\u5b58\u5728\u91cd\u590d\u7684\u503c\uff0c\u952e\u548c\u503c\u5fc5\u987b\u662f\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\uff0c\u624d\u80fd\u7528\u8fd9\u79cd\u65b9\u5f0f\u6784\u5efa\u53cc\u5411\u67e5\u627e\u8868\u3002\u5426\u5219\u4e00\u4e2a\u503c\u53ef\u80fd\u5bf9\u5e94\u5230\u4e24\u4e2a\u952e\uff0c\u53cd\u5411\u8868\u5fc5\u987b\u662f map> \u4e86\u3002","title":"map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868"},{"location":"stl_map/#value_type","text":"STL \u5bb9\u5668\u7684\u5143\u7d20\u7c7b\u578b\u90fd\u53ef\u4ee5\u901a\u8fc7\u6210\u5458 value_type \u67e5\u8be2\uff0c\u5e38\u7528\u4e8e\u6cdb\u578b\u7f16\u7a0b\uff08\u53c8\u79f0\u5143\u7f16\u7a0b\uff09\u3002 set::value_type // int vector::value_type // int string::value_type // char \u6b64\u5916\u8fd8\u6709\u5f15\u7528\u7c7b\u578b reference \uff0c\u8fed\u4ee3\u5668\u7c7b\u578b iterator \uff0c\u5e38\u8fed\u4ee3\u5668\u7c7b\u578b const_iterator \u7b49\u3002 \u66fe\u7ecf\u5728 C++98 \u4e2d\u5f88\u5e38\u7528\uff0c\u4e0d\u8fc7\u81ea\u4ece C++11 \u6709\u4e86 auto \u548c decltype \u4ee5\u540e\uff0c\u5c31\u4e0d\u600e\u4e48\u7528\u4e86\uff0c\u53cd\u6b63\u80fd\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 C++23: std::vector arr; for (auto const &elem: arr) { std::println(\"{}\", elem); } C++17: std::vector arr; for (auto const &elem: arr) { std::cout << elem << '\\n'; } C++11: std::vector arr; for (auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } C++98: std::vector arr; for (std::vector::iterator it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; }","title":"\u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type"},{"location":"stl_map/#typename","text":"\u5f53\u5bb9\u5668\u6709\u81f3\u5c11\u4e00\u4e2a\u4e0d\u786e\u5b9a\u7684\u7c7b\u578b T \u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u65f6\uff0c\u5c31\u9700\u8981\u524d\u9762\u52a0\u4e0a typename \u4fee\u9970\u4e86\uff1a set::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 typename set::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename set>::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 K\u3001T \u662f\u4e0d\u5b9a\u7c7b\u578b map::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 \u5982\u679c\u4f60\u641e\u4e0d\u6e05\u695a\uff0c\u59cb\u7ec8\u52a0 typename \u5c31\u884c\u4e86\uff0c\u53cd\u6b63\u52a0\u591a\u80af\u5b9a\u4e0d\u4f1a\u6709\u9519\u3002\u4f60\u5c31\u8ba4\u4e3a\uff1a\u8fd9\u5c31\u662f\u4e00\u4e2a\u5e73\u65f6\u53ef\u4ee5\u7701\u7565\uff0c\u5076\u5c14\u4e0d\u80fd\u7701\u7565\u7684\u4e1c\u897f\u3002 typename set::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb typename set::value_type; // \u4e0d\u80fd\u7701\u7565 typename set>::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb \u542b\u6709 T \u7684\u7c7b\u578b\u8868\u8fbe\u5f0f\u79f0\u4e3a dependent-type\uff0c\u6839\u672c\u539f\u56e0\u662f\u56e0\u4e3a\u5728\u4e0d\u77e5\u9053\u5177\u4f53\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\u8fd8\u662f\u503c\u8868\u8fbe\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u7f16\u8bd1\u5668\u65e0\u6cd5\u533a\u5206\u6a21\u677f\u7684 < \u548c\u5c0f\u4e8e\u7b26\u53f7 < \uff0c\u4ee5\u53ca\u7c7b\u578b\u7684\u6307\u9488 * \u548c\u6570\u503c\u4e58\u6cd5 * \u3002\u9ed8\u8ba4\u4f1a\u8ba4\u4e3a\u662f\u5c0f\u4e8e\u7b26\u53f7\u548c\u6570\u503c\u4e58\u6cd5\uff0c\u52a0\u4e0a typename \u540e\u660e\u786e\u524d\u9762\u8fd9\u4e00\u4e32\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\uff0c\u624d\u77e5\u9053\u8fd9\u662f\u6a21\u677f\u7684 < \u548c\u6307\u9488\u7684 * \u3002","title":"typename \u4fee\u9970"},{"location":"stl_map/#decltype","text":"\u4e5f\u6709\u66f4\u76f4\u89c2\u7684\u83b7\u53d6 STL \u5bb9\u5668\u5143\u7d20\u7c7b\u578b\u7684\u65b9\u6cd5\uff1a std::vector arr; using T = std::decay_t; // T = int decltype \u5fc5\u987b\u914d\u5408 std::decay_t \u624d\u80fd\u7528\uff01\u5426\u5219\u4f1a\u5f97\u5230\u5f15\u7528\u7c7b\u578b int & \uff0c\u540e\u7eed\u4f7f\u7528\u4e2d\u5c31\u5751\u5230\u4f60\uff01\uff08\u56e0\u4e3a arr \u7684 [] \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528\u7c7b\u578b\uff09 // \u9519\u8bef\u793a\u8303 using T = decltype(arr[0]); // T = int & T i = 0; // int &i = 0; \u540e\u7eed\u4f7f\u7528\u4e2d\u7f16\u8bd1\u51fa\u9519\uff01","title":"decltype \u5927\u6cd5\u597d"},{"location":"stl_map/#_26","text":"\u5728\u672c\u8bfe\u7a0b\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\u9644\u5e26\u7684 \u201ccppdemangle.h\u201d\uff0c\u53ef\u4ee5\u5b9e\u73b0\u6839\u636e\u6307\u5b9a\u7684\u7c7b\u578b\u67e5\u8be2\u7c7b\u578b\u540d\u79f0\u5e76\u6253\u5370\u51fa\u6765\u3002 \u8de8\u5e73\u53f0\uff0c\u9700\u8981 C++11\uff0c\u652f\u6301 MSVC\uff0cClang\uff0cGCC \u4e09\u5927\u7f16\u8bd1\u5668\uff0c\u4f8b\u5982\uff1a int i; print(cppdemangle()); print(cppdemangle()); print(cppdemangle()); \u5728\u6211\u7684 GCC 12.2.1 \u4e0a\u5f97\u5230\uff1a \"int &&\" \"std::__cxx11::basic_string, std::allocator >\" \"wchar_t\"","title":"\u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177"},{"location":"stl_map/#map_5","text":"map \u5177\u6709\u4e09\u4e2a\u6210\u5458\u7c7b\u578b 1 \uff1a \u5143\u7d20\u7c7b\u578b\uff1a value_type \u952e\u7c7b\u578b\uff1a key_type \u503c\u7c7b\u578b\uff1a mapped_type \u540e\u9762\uff0c\u5c06\u4f1a\u4e00\u76f4\u4ee5\u201c\u5143\u7d20\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cvalue\u201d\uff0c\u201c\u952e\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201ckey\u201d\uff0c\u201c\u503c\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cmapped\u201d \u7528 cppdemangle \u505a\u5b9e\u9a8c\uff0c\u770b\u770b\u8fd9\u4e9b\u6210\u5458\u7c7b\u578b\u5177\u4f53\u662f\u4ec0\u4e48\u5427\uff1a map::value_type // pair map::key_type // int map::mapped_type // float \u7ed3\u8bba\uff1a map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u800c\u4e0d\u662f V \u3002 \u7591\u60d1\uff1a pair \u4e2d\uff0c\u4e3a\u4ec0\u4e48 K \u8981\u52a0 const\uff1f \u6211\u4eec\u5728 set \u8bfe\u4e2d\u8bf4\u8fc7\uff0cset \u5185\u90e8\u91c7\u7528\u7ea2\u9ed1\u6811\u6570\u636e\u7ed3\u6784\u4fdd\u6301\u6709\u5e8f\uff0c\u8fd9\u6837\u624d\u80fd\u5b9e\u73b0\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u9ad8\u6548\u67e5\u627e\u3002 \u952e\u503c\u6539\u53d8\u7684\u8bdd\u4f1a\u9700\u8981\u91cd\u65b0\u6392\u5e8f\uff0c\u5982\u679c\u53ea\u4fee\u6539\u952e\u503c\u800c\u4e0d\u91cd\u65b0\u6392\u5e8f\uff0c\u4f1a\u7834\u574f\u6709\u5e8f\u6027\uff0c\u5bfc\u81f4\u4e8c\u5206\u67e5\u627e\u7ed3\u679c\u9519\u8bef\uff01\u6240\u4ee5 set \u53ea\u63d0\u4f9b\u4e86\u4e0d\u53ef\u53d8\u8fed\u4ee3\u5668\uff08const_iterator\uff09\uff0c\u6ca1\u6709\u53ef\u53d8\u7684\u8fed\u4ee3\u5668\uff0c\u4e0d\u5141\u8bb8\u7528\u6237\u4fee\u6539\u4efb\u4f55\u5143\u7d20\u7684\u503c\u3002 map \u548c set \u4e00\u6837\u4e5f\u662f\u7ea2\u9ed1\u6811\uff0c\u4e0d\u540c\u5728\u4e8e\uff1amap \u53ea\u6709\u952e K \u7684\u90e8\u5206\u4f1a\u53c2\u4e0e\u6392\u5e8f\uff0cV \u662f\u4e2a\u65c1\u89c2\u8005\uff0c\u968f\u4fbf\u4fee\u6539\u4e5f\u6ca1\u5173\u7cfb\u3002 \u6240\u4ee5 map \u6709\u53ef\u53d8\u8fed\u4ee3\u5668\uff0c\u53ea\u662f\u5728\u5176\u503c\u7c7b\u578b value_type \u4e2d\u7ed9\u952e\u7684\u90e8\u5206\uff0cK\uff0c\u52a0\u4e0a\u4e86 const \u4fee\u9970\uff1a\u4e0d\u5141\u8bb8\u4fee\u6539 K\uff0c\u4f46\u53ef\u4ee5\u968f\u610f\u4fee\u6539 V\u3002 \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u4fee\u6539\u952e\u503c\uff0c\u90a3\u4e48\u8bf7\u5148\u53d6\u51fa\u65e7\u503c\uff0c\u628a\u8fd9\u4e2a\u952e\u5220\u4e86\uff0c\u7136\u540e\u518d\u4ee5\u540c\u6837\u7684\u503c\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u5230\u65b0\u7684\u952e\u3002\u76f8\u5f53\u4e8e\u91cd\u65b0\u6784\u5efa\u4e86\u4e00\u4e2a pair \u5bf9\u8c61\u3002 C++17 \u5f00\u59cb\u4e5f\u53ef\u4ee5\u7528\u66f4\u9ad8\u6548 node_handle \u7cfb\u5217 API\uff0c\u907f\u514d\u6570\u636e\u53d1\u751f\u79fb\u52a8\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; begin() \u548c end() \u8fed\u4ee3\u5668\u5206\u522b\u6307\u5411 map \u7684\u9996\u4e2a\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u540e\u4e00\u4f4d\u3002 \u5176\u4e2d end() \u8fed\u4ee3\u5668\u6307\u5411\u7684\u5730\u5740\u4e3a\u865a\u7a7a\u7d22\u654c\uff0c\u4e0d\u53ef\u89e3\u5f15\u7528\uff0c\u4ec5\u4ec5\u4f5c\u4e3a\u4e00\u4e2a\u201c\u6807\u5fd7\u201d\u5b58\u5728\uff08\u56de\u987e\u4e4b\u524d vector \u8bfe\uff09\u3002 \u8fed\u4ee3\u5668\u53ef\u4ee5\u901a\u8fc7 *it \u6216 it-> \u89e3\u5f15\u7528\uff0c\u83b7\u53d6\u5176\u6307\u5411\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u9996\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5c0f\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5927\u7684\u5143\u7d20\u3002 \u4f8b\u5982\u8981\u67e5\u8be2\u6210\u7ee9\u6700\u597d\u548c\u6700\u574f\u7684\u5b66\u751f\uff0c\u53ef\u4ee5\u628a\u6210\u7ee9\u5f53\u505a key\uff0c\u5b66\u751f\u540d\u505a value \u4f9d\u6b21\u63d2\u5165 map\uff0c\u4ed6\u4f1a\u5e2e\u6211\u4eec\u6392\u5e8f\uff1a map score = { {100, \"\u5f6d\u4e8e\u658c\"}, {80, \"\u6a31\u82b1\u7c89\u871c\u7cd6\"}, {0, \"\u76f8\u4f9d\"}, {60, \"Sputnik02\"}, }; string poorestStudent = score.begin()->second; // \u6210\u7ee9\u6700\u5dee\u5b66\u751f\u7684\u59d3\u540d string bestStudent = prev(score.end())->second; // \u6210\u7ee9\u6700\u597d\u5b66\u751f\u7684\u59d3\u540d print(\"\u6700\u4f4e\u5206:\", poorestStudent); print(\"\u6700\u9ad8\u5206:\", bestStudent); \u6700\u4f4e\u5206: \"\u76f8\u4f9d\" \u6700\u9ad8\u5206: \"\u5f6d\u4e8e\u658c\" \u6ce8\uff1a\u4ec5\u5f53\u786e\u4fdd score.size() != 0 \u65f6\u624d\u53ef\u4ee5\u89e3\u5f15\u7528\uff0c\u5426\u5219 begin() \u548c end() \u90fd\u662f\u865a\u7a7a\u8fed\u4ee3\u5668\uff0c\u8fd9\u65f6\u89e3\u5f15\u7528\u4f1a\u5954\u6e83\u3002 map \u7684\u904d\u5386\uff1a\u53e4\u4ee3 C++98 \u7684\u8fed\u4ee3\u5668\u5927\u6cd5 for (map::iterator it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8981\u7279\u522b\u6ce8\u610f\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u6307\u5411\u5143\u7d20\u7684\u6307\u9488\uff0c\u4e0d\u662f\u5143\u7d20\u672c\u8eab\uff01\u8981\u7528 -> \u800c\u4e0d\u662f . \u3002 \u8fd0\u7528 C++11 \u7684 auto \u7b80\u5199\u4e00\u4e0b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\uff08structured-binding\uff09\u8bed\u6cd5 1 \u76f4\u63a5\u62c6\u5f00 pair \u7c7b\u578b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; print(\"Key:\", k); print(\"Value:\", v); } map \u7684\u904d\u5386\uff1a\u73b0\u4ee3 C++17 \u57fa\u4e8e\u8303\u56f4\u7684\u5faa\u73af\uff08range-based loop\uff09 for (auto kv: m) { print(\"Key:\", kv.first); print(\"Value:\", kv.second); } \u540c\u65f6\u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\u8bed\u6cd5 1 \uff1a for (auto [k, v]: m) { print(\"Key:\", k); print(\"Value:\", v); } \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u53e4\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto it = m.begin(); it != m.end(); ++it) { it->second = it->second + 1; } print(m); {\"fuck\": 986, \"rust\": 212} \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u73b0\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto [k, v]: m) { v = v + 1; } print(m); {\"fuck\": 985, \"rust\": 211} \u6ca1\u6709\u6210\u529f\u4fee\u6539\uff01\u4e3a\u4ec0\u4e48\uff1f for (auto [k, v]: m) { v = v + 1; } Range-based loop \u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; v = v + 1; } Structured-binding \u4e5f\u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto tmp = *it; auto k = tmp.first; auto v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u6808\u4e0a\u53d8\u91cf\uff0c\u662f\u5bf9\u539f\u503c\u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u4e0d\u4ec5\u6d6a\u8d39\u6027\u80fd\uff0c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4e0d\u4f1a\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\uff01 for (auto &[k, v]: m) { // \u89e3\u51b3\u65b9\u6848\u662f\u5728\u8fd9\u91cc\u52a0\u4e00\u4e2a\u5c0f\u5c0f\u7684 &\uff0c\u8ba9 range-based loop \u6355\u83b7\u5f15\u7528\u800c\u4e0d\u662f\u62f7\u8d1d v = v + 1; } \u540c\u6837\u662f\u62c6\u9664 Range-based loop \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &[k, v] = *it; v = v + 1; } \u7ee7\u7eed\u62c6\u9664 Structured-binding \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &tmp = *it; auto &k = tmp.first; auto &v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u5f15\u7528\uff0c\u662f\u5bf9\u539f\u503c\u7684\u5f15\u7528\uff08\u7528 Rust \u7684\u8bdd\u8bf4\u53eb borrowed\uff09\u3002\u4e0d\u4ec5\u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\u8282\u7701\u4e86\u6027\u80fd\uff0c\u800c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4f1a\u5b9e\u65f6\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\u3002 \u603b\u7ed3\uff0c\u5f53\u9700\u8981\u5728\u904d\u5386\u7684\u540c\u65f6\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u8981\u7528 auto & \u6355\u83b7\u5f15\u7528\uff1a for (auto &[k, v]: m) { // \u6355\u83b7\u4e00\u4e2a\u5f15\u7528\uff0c\u5199\u5165\u8fd9\u4e2a\u5f15\u7528\u4f1a\u7acb\u5373\u4f5c\u7528\u5728\u539f\u503c\u4e0a v = v + 1; } \u5373\u4f7f\u4e0d\u9700\u8981\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u4e5f\u5efa\u8bae\u7528 auto const & \u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\uff1a for (auto const &[k, v]: m) { // \u6355\u83b7\u53ea\u8bfb\u7684 const \u5f15\u7528\uff0c\u5f15\u7528\u907f\u514d\u62f7\u8d1d\u5f00\u9500\uff0cconst \u907f\u514d\u4e0d\u5c0f\u5fc3\u624b\u6ed1\u5199\u5165 print(v); } \u6ce8\uff1a\u5373\u4f7f\u6355\u83b7\u4e3a auto & \uff0c\u7531\u4e8e map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5 K \u90e8\u5206\u8fd8\u662f\u4f1a\u6355\u83b7\u4e3a K const & \uff0c\u65e0\u6cd5\u5199\u5165\u3002 for (auto &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // OK } \u53ea\u662f\u5982\u679c\u6355\u83b7\u4e3a auto const & \u5c31\u4e24\u4e2a\u90fd\u4e0d\u5141\u8bb8\u5199\u5165\u4e86\u3002 for (auto const &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 } iterator find(K const &k); const_iterator find(K const &k) const; m.find(key) \u51fd\u6570\uff0c\u6839\u636e\u6307\u5b9a\u7684\u952e key \u67e5\u627e\u5143\u7d20 1 \u3002 \u6210\u529f\u627e\u5230\uff0c\u5219\u8fd4\u56de\u6307\u5411\u627e\u5230\u5143\u7d20\u7684\u8fed\u4ee3\u5668 \u627e\u4e0d\u5230\uff0c\u5219\u8fd4\u56de m.end() \u7531\u4e8e STL \u4f20\u7edf\u5f02\u80fd\u4e4b end() \u865a\u7a7a\u7d22\u654c\uff0c\u4ed6\u4e0d\u53ef\u80fd\u6307\u5411\u4efb\u4f55\u503c\uff0c\u6240\u4ee5\u7ecf\u5e38\u4f5c\u4e3a\u627e\u4e0d\u5230\u65f6\u5019\u7f3a\u7701\u7684\u8fd4\u56de\u503c\u3002 \u53ef\u4ee5\u7528 m.find(key) != m.end() \u5224\u65ad\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u5b58\u5728\uff0c\u7b49\u4ef7\u4e8e m.count(key) != 0 \u3002 \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684\u539f\u578b\u4f5c\u7528\u662f\uff1a\u5982\u679c map \u672c\u8eab\u6709 const \u4fee\u9970\uff0c\u5219\u8fd4\u56de\u7684\u4e5f\u662f const \u8fed\u4ee3\u5668\u3002 \u4e3a\u7684\u662f\u9632\u6b62\u4f60\u5728\u4e00\u4e2a const map \u91cc find \u4e86\u4ee5\u540e\u5229\u7528\u8fed\u4ee3\u5668\u53d8\u76f8\u4fee\u6539 map \u91cc\u7684\u503c\u3002","title":"map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f"},{"location":"stl_map/#count-contains","text":"\u5b9e\u9645\u4e0a count \u548c contains \u51fd\u6570\u5c31\u662f\u57fa\u4e8e find \u5b9e\u73b0\u7684\uff0c\u6027\u80fd\u6ca1\u6709\u533a\u522b\uff0cglibc \u6e90\u7801\uff1a #if __cplusplus > 201703L /** * @brief Finds whether an element with the given key exists. * @param __x Key of (key, value) pairs to be located. * @return True if there is an element with the specified key. */ bool contains(const key_type& __x) const { return _M_t.find(__x) != _M_t.end(); } template auto contains(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x), void(), true) { return _M_t._M_find_tr(__x) != _M_t.end(); } #endif /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. * * This function only makes sense for multimaps; for map the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } // \u4ee5\u4e0b\u4e09\u8005\u7b49\u4ef7 m.contains(key) m.count(key) m.find(key) != m.end()","title":"count \u548c contains \u6ca1\u533a\u522b"},{"location":"stl_map/#end","text":"\u68c0\u67e5\u8fc7\u4e0d\u662f m.end()\uff0c\u4ee5\u786e\u8ba4\u6210\u529f\u627e\u5230\u540e\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528\u83b7\u53d6\u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c\uff1a map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { auto kv = *it; // \u89e3\u5f15\u7528\u5f97\u5230 K-V \u5bf9 print(kv); // {\"fuck\", 985} print(kv.first); // \"fuck\" print(kv.second); // 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); }","title":"end \u4e0d\u80fd\u89e3\u5f15\u7528"},{"location":"stl_map/#find","text":"find \u7684\u9ad8\u6548\u5728\u4e8e\uff0c\u53ef\u4ee5\u628a\u4e24\u6b21\u67e5\u8be2\u5408\u5e76\u6210\u4e00\u6b21\u3002 \u4fdd\u5e95\u5199\u6cd5\uff1a\u5f00\u9500 2 \\log N 2 \\log N if (m.count(\"key\")) { // \u7b2c\u4e00\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(m.at(\"key\")); // \u7b2c\u4e8c\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } \u9ad8\u6548\u5199\u6cd5\uff1a\u5f00\u9500 \\log N \\log N auto it = m.find(\"key\"); // \u4e00\u6b21\u6027\u67e5\u8be2 if (it != m.end()) { // \u67e5\u8be2\u7684\u7ed3\u679c\uff0c\u65e2\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(it->second); // \u4e5f\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f }","title":"find \u7684\u597d\u5904"},{"location":"stl_map/#c17","text":"C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u5982\u4f55\u7b80\u5316 find \u7684\u8fed\u4ee3\u5668\u5224\u65ad auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } auto it = m.find(\"key2\"); // \u7f16\u8bd1\u5668\u62a5\u9519\uff1a\u53d8\u91cf it \u91cd\u590d\u5b9a\u4e49\uff01 if (it != m.end()) { print(it->second); } \u867d\u7136\u5220\u53bb\u524d\u9762\u7684 auto \u53ef\u4ee5\u89e3\u51b3\u95ee\u9898\uff0c\u4f46\u662f\u5982\u679c\u8fd9\u91cc\u662f\u4e0d\u540c\u7c7b\u578b\u7684 map \u5c31\u5c2c\u4e86\uff0c\u5f97\u53e6\u5916\u60f3\u4e00\u4e2a\u53d8\u91cf\u540d\u3002 \u800c C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u6355\u83b7\u7684 it \u662f\u9650\u5236\u5728\u5f53\u524d if \u4f5c\u7528\u57df\u7684\uff0c\u4e0d\u4f1a\u8dd1\u51fa\u53bb\u548c\u522b\u4eba\u53d1\u751f\u51b2\u7a81\u3002 if (auto it = m.find(\"key1\"); it != m.end()) { print(it->second); } if (auto it = m.find(\"key2\"); it != m.end()) { // \u8fd9\u4e2a\u53d8\u91cf it \u662f\u5c40\u57df\u7684\uff0c\u4e0d\u4f1a\u548c\u4e0a\u4e00\u4e2a\u5c40\u57df\u7684 it \u4ea7\u751f\u540d\u5b57\u51b2\u7a81 print(it->second); } \u7b49\u4ef7\u4e8e\uff1a { auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } }","title":"C++17 \u8bed\u6cd5\u7cd6"},{"location":"stl_map/#_27","text":"\u6211\u7ed9 C++ \u6807\u51c6\u59d4\u5458\u4f1a\u63d0\u4e00\u4e2a\u5efa\u8bae\uff0c\u80fd\u4e0d\u80fd\u7ed9\u8fed\u4ee3\u5668\u52a0\u4e00\u4e2a operator bool \u4ee3\u66ff\u70e6\u4eba\u7684 != m.end() \uff1f struct iterator { _RbTreeNode *node; bool operator!=(iterator const &other) const noexcept { return node == other.node; } operator bool() const noexcept { return node; } }; \u90a3\u6837\u7684\u8bdd\u5c31\u53ef\u4ee5\u76f4\u63a5\uff1a if (auto it = m.find(\"key\")) { print(it->second); } \u56e0\u4e3a if-auto \u7701\u7565\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u65f6\uff0c\u9ed8\u8ba4\u5c31\u662f if (auto it = m.find(\"key\"); (bool)it)","title":"\u9898\u5916\u8bdd"},{"location":"stl_map/#map-pair","text":"\u6ce8\u610f *it \u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u7c7b\u578b\u7684\u952e\u503c\u5bf9\uff0c\u9700\u8981 (*it).second \u624d\u80fd\u83b7\u53d6\u5355\u72ec\u7684\u503c V\u3002 \u597d\u5728 C \u8bed\u8a00\u5c31\u6709 -> \u8fd0\u7b97\u7b26\u4f5c\u4e3a\u8bed\u6cd5\u7cd6\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 it->second \uff0c\u4e0e (*it).second \u7b49\u4ef7\u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { print(it->second); // \u8fed\u4ee3\u5668\u6709\u6548\uff0c\u53ef\u4ee5\u76f4\u63a5\u83b7\u5f97\u503c\u90e8\u5206 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); // \u8fd9\u4e2a\u5206\u652f\u91cc\u4e0d\u5f97\u7528 * \u548c -> \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528 it } \u5927\u591a\u6570\u60c5\u51b5\u4e0b\u6211\u4eec\u67e5\u8be2\u53ea\u9700\u8981\u83b7\u53d6\u503c V \u7684\u90e8\u5206\u5c31\u884c\u4e86\uff0c\u76f4\u63a5 it->second \u5c31\u53ef\u4ee5\u4e86\u2705 \u6ce8\u610f\uff1afind \u627e\u4e0d\u5230\u952e\u65f6\uff0c\u4f1a\u8fd4\u56de m.end() \uff0c\u8fd9\u662f\u4e2a\u65e0\u6548\u8fed\u4ee3\u5668\uff0c\u53ea\u4f5c\u4e3a\u6807\u8bc6\u7b26\u4f7f\u7528\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 find \u6709\u65f6\u4f1a\u8fd4\u56de -1\uff09\u3002 \u6ca1\u6709\u786e\u8ba4 it != m.end() \u524d\uff0c\u4e0d\u53ef\u4ee5\u8bbf\u95ee it->second \uff01\u90a3\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e00\u4e2a\u7a7a\u6307\u9488\uff0c\u4f1a\u9020\u6210 segfault\uff08\u66f4\u4e13\u4e1a\u4e00\u70b9\u8bf4\u662f UB\uff09\u3002 \u8bb0\u4f4f\uff0c\u4e00\u5b9a\u8981\u5728 it != m.end() \u7684\u5206\u652f\u91cc\u624d\u80fd\u8bbf\u95ee it->second \u54e6\uff01\u4f60\u5f97\u5148\u68c0\u67e5\u8fc7\u996d\u7897\u91cc\u6ca1\u6709\u8001\u9f20\ud83d\udca9\u4e4b\u540e\uff0c\u624d\u80fd\u5b89\u5fc3\u5403\u996d\uff01 \u5982\u679c\u4f60\u60f3\u8ba9\u8001\u5988\uff08\u6807\u51c6\u5e93\uff09\u81ea\u52a8\u5e2e\u4f60\u68c0\u67e5\u6709\u6ca1\u6709\u8001\u9f20\ud83d\udca9\uff0c\u90a3\u5c31\u7528\u4f1a\u81ea\u52a8\u62a5\u9519\u7684 at\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 index \u627e\u4e0d\u5230\u76f4\u63a5\u62a5\u9519\uff09\u3002 \u4e4b\u6240\u4ee5\u7528 find\uff0c\u662f\u56e0\u4e3a\u6709\u65f6\u996d\u7897\u91cc\u51fa\u8001\u9f20\ud83d\udca9\uff0c\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff01\u4f8b\u5982\u5f53\u6709\u8001\u9f20\ud83d\udca9\u65f6\u4f60\u53ef\u4ee5\u6539\u5403\u522b\u7684\u96f6\u98df\u3002\u800c at \u8fd9\u4e2a\u826f\u5fc3\u8001\u5988\u5462\uff1f\u4e00\u53d1\u73b0\u8001\u9f20\ud83d\udca9\u5c31\u62d6\u7740\u4f60\u53bb\u8b66\u5bdf\u5c40\u62a5\u6848\uff0c\u96f6\u98df\uff08\u9ed8\u8ba4\u503c\uff09\u4e5f\u4e0d\u8ba9\u4f60\u5403\u4e86\u3002\u4eca\u65e5\u884c\u7a0b\u5168\u90e8\u53d6\u6d88\uff0c\u7ef4\u6743\uff08\u5f02\u5e38\u5904\u7406\uff0c\u627e\u4e0a\u5c42 try-catch \u5757\uff09\u8bbe\u4e3a\u7b2c\u4e00\u8981\u52a1\u3002 iterator find(K const &k); const_iterator find(K const &k) const; \u5982\u679c map \u6ca1\u6709 const \u4fee\u9970\uff0c\u5219\u5176 find \u8fd4\u56de\u7684 it \u4e5f\u662f\u975e const \u8fed\u4ee3\u5668\u3002 const map cm; map::const_iterator cit = cm.find(\"key\"); print(cit->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 cit->second = 1; // \u7f16\u8bd1\u671f\u62a5\u9519: \u4e0d\u5141\u8bb8\u5199\u5165 const \u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c map m; map::iterator it = m.find(\"key\"); print(it->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 it->second = 1; // OK: \u53ef\u4ee5\u5199\u5165 it->second \u53ef\u4ee5\u5199\u5165\uff0cit \u662f\u8fed\u4ee3\u5668\uff0c\u8fed\u4ee3\u5668\u7c7b\u4f3c\u4e8e\u6307\u9488\uff0c\u5199\u5165\u8fed\u4ee3\u5668\u6307\u5411\u7684 second \u5c31\u53ef\u4ee5\u4fee\u6539 map \u91cc\u7684\u503c\u90e8\u5206\u3002 it->first \u662f\u952e\u90e8\u5206\uff0c\u7531\u4e8e map \u7684\u771f\u6b63\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5\u8fd9\u90e8\u5206\u65e0\u6cd5\u88ab\u4fee\u6539\u3002 \u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2 \u4f17\u6240\u5468\u77e5\uff0cPython \u4e2d\u7684 dict \u6709\u4e00\u4e2a m.get(key, defl) \u7684\u529f\u80fd\uff0c\u6548\u679c\u662f\u5f53 key \u4e0d\u5b58\u5728\u65f6\uff0c\u8fd4\u56de defl \u8fd9\u4e2a\u9ed8\u8ba4\u503c\u4ee3\u66ff m[key]\uff0c\u800c C++ \u7684 map \u5374\u6ca1\u6709\uff0c\u53ea\u80fd\u7528\u4e00\u5957\u7ec4\u5408\u62f3\u4ee3\u66ff\uff1a m.count(key) ? m.at(key) : defl \u4f46\u4e0a\u9762\u8fd9\u6837\u5199\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\uff0c\u76f8\u5f53\u4e8e\u67e5\u8be2\u4e86 map \u4e24\u904d\uff0cat \u91cc\u8fd8\u989d\u5916\u505a\u4e86\u4e00\u6b21\u591a\u4f59\u7684\u5f02\u5e38\u5224\u65ad\u3002 \u6b63\u5e38\u6765\u8bf4\u662f\u7528\u901a\u7528 find \u53bb\u627e\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7136\u540e\u5224\u65ad\u662f\u4e0d\u662f end() \u51b3\u5b9a\u8981\u4e0d\u8981\u91c7\u7528\u9ed8\u8ba4\u503c\u3002 auto it = m.find(key); return it != m.end() ? it->second : defl; \u996d\u7897\u91cc\u53d1\u73b0\u4e86\u8001\u9f20\ud83d\udca9\uff1f\u522b\u6025\u7740\u62a5\u8b66\uff0c\u8fd9\u4e5f\u5728\u6211\u7684\u9884\u6599\u4e4b\u4e2d\uff1a\u542f\u7528 B \u8ba1\u5212\uff0c\u6539\u5403 defl \u8fd9\u6b3e\u7f8e\u5473\u96f6\u98df\u5373\u53ef\uff01 \u5982\u679c\u662f\u826f\u5fc3\u8001\u5988 at\uff0c\u5c31\u76f4\u63a5\u542f\u7528 C \u8ba1\u5212\uff1a \u629b\u51fa\u5f02\u5e38\u7136\u540e\u5954\u6e83\u4e86\uff0c\u867d\u7136\u8fd9\u5f88\u65b9\u4fbf\u6211\u4eec\u7a0b\u5e8f\u5458\u8c03\u8bd5\u3002 \u7531\u4e8e\u81ea\u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2\u8fd9\u4e00\u529f\u80fd\u5b9e\u5728\u662f\u592a\u5e38\u7528\u4e86\uff0c\u4e3a\u4e86\u628a\u8fd9\u4e2a\u64cd\u4f5c\u6d53\u7f29\u5230\u4e00\u884c\uff0c\u6211\u5efa\u8bae\u540c\u5b66\u4eec\u5c01\u88c5\u6210\u51fd\u6570\u653e\u5230\u81ea\u5df1\u7684\u9879\u76ee\u516c\u5171\u5934\u6587\u4ef6\uff08\u4e00\u822c\u662f utils.h \u4e4b\u7c7b\u7684\u540d\u79f0\uff09\u91cc\u65b9\u4fbf\u4ee5\u540e\u4f7f\u7528\uff1a template typename M::mapped_type map_get ( M const &m , typename M::key_type const &key , typename M::mapped_type const &defl ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return defl; } } int val = map_get(config, \"timeout\", -1); // \u5982\u679c\u914d\u7f6e\u6587\u4ef6\u91cc\u4e0d\u6307\u5b9a\uff0c\u5219\u9ed8\u8ba4 timeout \u4e3a -1 \u8fd9\u6837\u8fd8\u4e0d\u591f\u4f18\u96c5\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u66f4\u4f18\u96c5\u5730\u8fd0\u7528 C++17 \u7684\u51fd\u6570\u5f0f\u5bb9\u5668 optional\uff1a template std::optional map_get ( M const &m , typename M::key_type const &key ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return std::nullopt; } } \u5f53\u627e\u4e0d\u5230\u65f6\u5c31\u8fd4\u56de nullopt\uff0c\u627e\u5230\u5c31\u8fd4\u56de\u542b\u6709\u503c\u7684 optional\u3002 \u672c\u6bb5\u4ee3\u7801\u5df2\u9644\u5728\u6848\u4f8b\u4ee3\u7801\u5e93\u7684 \u201cmap_get.h\u201d \u6587\u4ef6\u4e2d\uff0c\u7b49\u8bfe\u540e\u53ef\u4ee5\u53bb GitHub \u4e0b\u8f7d\uff0c\u8d76\u7d27\u7528\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u5427\uff01 \u8c03\u7528\u8005\u53ef\u4ee5\u81ea\u884c\u8fd0\u7528 optional \u7684 value_or \u51fd\u6570 1 \u6307\u5b9a\u627e\u4e0d\u5230\u65f6\u91c7\u7528\u7684\u9ed8\u8ba4\u503c\uff1a int val = map_get(config, \"timeout\").value_or(-1); \u5982\u679c\u8981\u5b9e\u73b0 at \u540c\u6837\u7684\u627e\u4e0d\u5230\u5c31\u81ea\u52a8\u62a5\u9519\u529f\u80fd\uff0c\u90a3\u5c31\u6539\u7528 value \u51fd\u6570\uff1a int val = map_get(config, \"timeout\").value(); optional \u5177\u6709 operator bool \u548c\u65e0\u5f02\u5e38\u7684 operator* \uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u914d\u5408 if-auto \u8bed\u6cd5\u7cd6\u4f7f\u7528\uff1a if (auto o_val = map_get(config, \"timeout\")) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u7b49\u4ef7\u4e8e\uff1a auto o_val = map_get(config, \"timeout\"); if (o_val) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u4ee5\u4e0a\u662f\u5178\u578b\u7684\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f (FP)\uff0cC++20 \u8fd8\u5f15\u5165\u4e86\u66f4\u591a\u8fd9\u6837\u7684\u73a9\u610f 2 \uff0c\u7b49\u6709\u7a7a\u4f1a\u4e13\u95e8\u5f00\u8282\u8bfe\u4e3a\u5927\u5bb6\u4e00\u4e00\u4ecb\u7ecd\u3002 auto even = [] (int i) { return 0 == i % 2; }; auto square = [] (int i) { return i * i; }; for (int i: std::views::iota(0, 6) | std::views::filter(even) | std::views::transform(square)) print(i); // 0 4 16 \u73b0\u5728\u5b66\u4e60\u5220\u9664\u5143\u7d20\u7528\u7684 erase \u51fd\u6570\uff0c\u5176\u539f\u578b\u5982\u4e0b 1 \uff1a size_t erase(K const &key); \u6307\u5b9a\u952e\u503c key\uff0cerase \u4f1a\u5220\u9664\u8fd9\u4e2a\u952e\u503c\u5bf9\u5e94\u7684\u5143\u7d20\u3002 \u8fd4\u56de\u4e00\u4e2a\u6574\u6570\uff0c\u8868\u793a\u5220\u9664\u4e86\u591a\u5c11\u4e2a\u5143\u7d20\uff08\u53ea\u80fd\u662f 0 \u6216 1\uff09\u3002 size_t erase(K const &key); erase \u8fd0\u7528\u4e3e\u4f8b\uff1a\u5220\u9664\u4e00\u4e2a\u5143\u7d20 map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); msg.erase(\"fuck\"); print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} {\"hello\": \"world\"} size_t erase(K const &key); erase \u7684\u8fd4\u56de\u503c\u548c count \u4e00\u6837\uff0c\u8fd4\u56de\u6210\u529f\u5220\u9664\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 erase \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u662f\u5426\u5220\u9664\u6210\u529f\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.erase(\"fuck\")) { print(\"\u5220\u9664fuck\u6210\u529f\"); } else { print(\"\u5220\u9664fuck\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } if (msg.erase(\"dick\")) { print(\"\u5220\u9664dick\u6210\u529f\"); } else { print(\"\u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} \u5220\u9664fuck\u6210\u529f \u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728 {\"hello\": \"world\"} size_t erase(K const &key); // \u6307\u5b9a\u952e\u7248 iterator erase(iterator it); // \u5df2\u77e5\u4f4d\u7f6e\u7248 \u533a\u522b\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u5b9e\u9645\u4e0a\u9700\u8981\u5148\u8c03\u7528 find(key) \u627e\u5230\u5143\u7d20\u4f4d\u7f6e\uff0c\u7136\u540e\u624d\u80fd\u5220\u9664\uff0c\u800c\u4e14\u8fd8\u6709\u627e\u4e0d\u5230\u7684\u53ef\u80fd\u6027\u3002 \u800c\u5df2\u77e5\u4f4d\u7f6e\u7684\u8bdd\uff08\u6bd4\u5982\u4f60\u5df2\u7ecf\u4e8b\u5148\u7528 find \u627e\u5230\u4e86\u5143\u7d20\u4f4d\u7f6e\uff09\uff0c\u53ef\u4ee5\u7528 erase(it) \u76f4\u63a5\u7528\u8fed\u4ee3\u5668\u4f5c\u4e3a\u53c2\u6570 \u590d\u6742\u5ea6\u4e0d\u540c\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(\\log N) O(\\log N) \u3002 \u5df2\u77e5\u4f4d\u7f6e\u7248 erase(it) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(1)+ O(1)+ \uff0c\u66f4\u9ad8\u6548\u3002 \u5176\u4e2d + + \u4ee3\u8868\u8fd9\u662f\u5e73\u644a\uff08Amortized\uff09\u4e0b\u6765\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8fd9\u662f\u56e0\u4e3a\u5373\u4f7f\u5df2\u77e5\u4f4d\u7f6e\uff0cerase \u6709\u53ef\u80fd\u6d89\u53ca\u6811\u7684\u66f4\u65b0\uff0c\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u4f46\u662f\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u9700\u8981\u7684\u66f4\u65b0\u5f88\u5c11\uff0c\u5e73\u5747\u4e0b\u6765\u662f O(1) O(1) \u7684\u3002 \u8fd9\u79cd\u60c5\u51b5\u5c31\u4f1a\u7528\u8bb0\u53f7 O(1)+ O(1)+ \u6765\u8868\u793a\u3002 erase(key) \u53ef\u80fd\u662f\u57fa\u4e8e erase(it) \u5b9e\u73b0\u7684\uff1a size_t erase(K const &key) { // \u5c0f\u5f6d\u8001\u5e08\u731c\u60f3\u6807\u51c6\u5e93\u5185\u90e8 auto it = this->find(key); // O(log N) if (it != this->end()) { this->erase(it); // O(1)+ return 1; // \u627e\u5230\u4e86\uff0c\u5220\u9664\u6210\u529f } else { return 0; // \u627e\u4e0d\u5230\uff0c\u6ca1\u6709\u5220\u9664 } } // \u5f00\u9500\u5927\u7684 find(key) \u4f1a\u8986\u76d6\u5c0f\u7684 erase(it)\uff0c\u6240\u4ee5 erase(key) \u7684\u603b\u590d\u6742\u5ea6\u4e3a O(log N) \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u8fd4\u56de\u7684\u662f\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u4f4d\u7f6e\u3002 \u7531\u4e8e map \u5185\u90e8\u4fdd\u6301\u952e\u4ece\u5c0f\u5230\u5927\u5347\u5e8f\u6392\u5217\uff0c\u6240\u8c13\u7684\u4e0b\u4e00\u4e2a\u5c31\u662f\u952e\u6bd4\u5f53\u524d\u952e\u5927\u4e00\u4e2a\u7684\u5143\u7d20\uff0c\u4f8b\u5982\uff1a {\"answer\": 42, \"hello\": 985, \"world\": 211} erase(find(\u201canswer\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201chello\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201chello\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201canswer\u201d\u3002 erase(find(\u201chello\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201cworld\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201cworld\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201chello\u201d\u3002 erase(find(\u201cworld\u201d)) \u4f1a\u8fd4\u56de end()\uff0c\u56e0\u4e3a \u201cworld\u201d \u5df2\u7ecf\u662f\u6700\u5927\u952e\uff0c\u6ca1\u6709\u4e0b\u4e00\u4e2a\u3002 \u6b64\u5916 erase(it) \u8fd8\u6709\u6027\u80fd\u4e0a\u7684\u4f18\u52bf\uff1a \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u7684\u590d\u6742\u5ea6\u662f O(1)+ O(1)+ \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u590d\u6742\u5ea6\u662f O(\\log N) O(\\log N) \u5f53\u5df2\u77e5\u6307\u5411\u8981\u5220\u9664\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u65f6\uff08\u4f8b\u5982\u5148\u901a\u8fc7 find \u627e\u5230\uff09\uff0c\u76f4\u63a5\u6307\u5b9a\u90a3\u4e2a\u8fed\u4ee3\u5668\u6bd4\u6307\u5b9a\u952e\u53c2\u6570\u66f4\u9ad8\u6548\u3002 \u5220\u9664\u6210\u7ee9\u6700\u5dee\u7684\u5b66\u751f\uff1a score.erase(score.begin());","title":"\u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair"},{"location":"stl_map/#_28","text":"\u5e38\u89c1\u9700\u6c42\u573a\u666f\uff1a\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u9519\u8bef\u793a\u8303\uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto const &[k, v]: msg) { if (k.starts_with(\"fuck\")) { msg.erase(k); // \u904d\u5386\u8fc7\u7a0b\u4e2d\u5220\u9664\u5f53\u524d\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u6b63\u5728\u904d\u5386\u4e2d\u7684\u8fed\u4ee3\u5668\u5931\u6548\uff0c\u5954\u6e83 } } print(msg); Segmentation fault (core dumped) \u5f15\u51fa\u95ee\u9898\uff1a\u8fed\u4ee3\u5668\u5931\u6548 \u6bcf\u5f53\u5f80 map \u4e2d\u63d2\u5165\u65b0\u5143\u7d20\u65f6\uff0c\u539f\u5148\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u4e0d\u4f1a\u5931\u6548\u3002 \u5220\u9664 map \u4e2d\u7684\u5176\u4ed6\u5143\u7d20\u65f6\uff0c\u4e5f\u4e0d\u4f1a\u5931\u6548\u3002 \u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\uff0c\u624d\u4f1a\u5931\u6548 \u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); m[\"dick\"] = 211; print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"dick\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"fuck\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 map \u6bd4\u8d77 unordered_map \u6765\uff0c\u5df2\u7ecf\u662f\u975e\u5e38\u7a33\u5b9a\uff0c\u968f\u4fbf\u589e\u5220\u6539\u67e5\u90fd\u4e0d\u4f1a\u8fed\u4ee3\u5668\u5931\u6548\u3002 \u53ea\u6709\u4e00\u4e2a\u4f8b\u5916\uff1a\u5220\u9664\u7684\u5143\u7d20\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u3002 \u4f60\u62ff\u7740\u4e2a\u4f60\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u7ed3\u679c\u4f60\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\uff0c\u8fd8\u6478\u4e0d\u7740\u5934\u8111\u201c\u5947\u602a\uff0c\u660e\u660e\u5c31\u662f\u8fd9\u4e2a\u5730\u5740\u5440\u201d\uff0c\u8fd9\u65f6\u786e\u5b9e\u65e0\u8bba\u5982\u4f55\u90fd\u4e0d\u80fd\u907f\u514d\u5931\u6548\uff0c\u4e0d\u80fd\u602a map\u3002 \u800c\u521a\u521a\u7684\u6848\u4f8b\u4e2d\uff0c\u6211\u4eec\u5220\u9664\u7684\u6070\u597d\u5c31\u662f\u5f53\u524d\u6b63\u5728\u904d\u5386\u7684\u8fed\u4ee3\u5668\u6b63\u5728\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\uff08\u5373\u4f7f\u4f60\u7528\u4e86 range-based loop \u8bed\u6cd5\u7cd6\u4ed6\u80cc\u540e\u8fd8\u662f\u8fed\u4ee3\u5668\u904d\u5386\uff09\u3002 \u800c\u5f53\u4f60\u5bf9\u7740\u4e00\u4e2a\u5931\u6548\u7684\u8fed\u4ee3\u5668\u6267\u884c ++it \u65f6\uff0c\u5c31\u4ea7\u751f\u4e86 segfault \u9519\u8bef\u3002\u56e0\u4e3a\u7ea2\u9ed1\u6811\u7684\u8fed\u4ee3\u5668\u8981\u627e\u5230\u201c\u4e0b\u4e00\u4e2a\u201d\u8282\u70b9\uff0c\u9700\u8981\u8bbf\u95ee\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u4e2d\u5b58\u7684 next \u6307\u9488\uff0c\u800c\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u90fd\u5df2\u7ecf\u5220\u9664\u4e86\u5df2\u7ecf\u6790\u6784\u4e86\u5df2\u7ecf\u91ca\u653e\u5185\u5b58\u4e86\uff0c\u91cc\u9762\u5b58\u7684 next \u6307\u9488\u4e5f\u5df2\u7ecf\u91ca\u653e\uff0c\u88ab\u5176\u4ed6\u7cfb\u7edf\u6570\u636e\u8986\u76d6\uff0c\u8fd9\u65f6\u4f1a\u8bbf\u95ee\u5230\u9519\u8bef\u7684\u6307\u9488\u2014\u2014\u91ce\u6307\u9488\u3002 \u6240\u4ee5\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u5b8c\u6574\u7684\u5267\u60c5\u662f\uff1a \u4f60\u6709\u597d\u591a\u670b\u53cb\uff0c\u4eca\u5929\u4f60\u8981\u628a\u4ed6\u4eec\u5168\u70b8\u4e86\u3002 1\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 2\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77403\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 \u2026 \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it /* \u8fdb\u5165\u71c3\u70e7\u4e2d\u76841\u53f7\u670b\u53cb\u5bb6 */) { m.erase(it); // \u4e00\u53d1 RPG \u5bfc\u5f39\u70b8\u6bc11\u53f7\u670b\u53cb\u5bb6 } \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it) { m.erase(it); // it \u5df2\u7ecf\u5931\u6548\uff01 } \u6b63\u786e\u7684\u505a\u6cd5\u662f\uff0c\u5148\u8fdb\u51651\u53f7\u670b\u53cb\u5bb6\uff0c\u5b89\u5168\u53d6\u51fa\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761\u540e\uff0c\u518d\u6765\u4e00\u53d1 RPG \u628a1\u53f7\u670b\u53cb\u5bb6\u70b8\u6389\u3002\u8fd9\u6837\u624d\u80fd\u987a\u5229\u627e\u52302\u53f7\u670b\u53cb\u5bb6\uff0c\u4ee5\u6b64\u7c7b\u63a8\u7ee7\u7eed\u62c63\u53f7\u2026\u2026 for (auto it = m.begin(); it != m.end(); ) { auto next_it = it; // \u5148\u8fdb\u51651\u53f7\u670b\u53cb\u7684\u5bb6 ++next_it; // \u62ff\u51fa\u5199\u67092\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761 m.erase(it); // \u518d\u53d1\u5c04 RPG \u5bfc\u5f39 it = next_it; // \u524d\u5f802\u53f7\u670b\u53cb\u5bb6 } \u6ce8\u610f\u5230 erase \u4f1a\u8fd4\u56de\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\u8fd9\u4e2a RPG \u5bfc\u5f39\u975e\u5e38\u667a\u80fd\uff0c\u597d\u50cf\u4ed6\u5c31\u662f\u4e13\u4e3a\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u8bbe\u8ba1\u7684\u4e00\u6837\uff1a\u4ed6\u80fd\u5728\u70b8\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u524d\uff0c\u81ea\u52a8\u62ff\u5230\u5176\u4e2d\u7684\u5b57\u6761\uff0c\u5e76\u628a\u4ed6\u901a\u8fc7\u201c\u5f39\u5c04\u5ea7\u6905\u201d\u5f39\u51fa\u6765\u9001\u5230\u95e8\u5916\u7684\u4f60\u624b\u4e0a\uff0c\u628a\u7eb8\u6761\u5b89\u5168\u9001\u51fa\u6765\u540e\uff0c\u518d\u7206\u70b8\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u3002\u8fd9\u6837\u4f60\u5c31\u4e0d\u7528\u5192\u9669\u8fdb\u5165\u71c3\u70e7\u7684\u623f\u5c4b\u62ff\u5b57\u6761\uff08\u8fed\u4ee3\u5668\u5931\u6548\u5bfc\u81f4 segfault\uff09\uff0c\u4e5f\u4e0d\u7528\u5148\u52b3\u70e6\u60a8\u81ea\u5df1\u5148\u8fdb\u53bb\u4e00\u8d9f\u623f\u5c4b\u62ff\u5b57\u6761\u4e86\uff08\u4e0a\u4e00\u9875\u4e2d\u90a3\u6837\u63d0\u524d\u4fdd\u5b58 next_it\uff09\u3002 for (auto it = m.begin(); it != m.end(); ) { it = m.erase(it); // \u8fd9\u6b3e RPG \u5bfc\u5f39\u201c\u667a\u80fd\u5730\u201d\u5728\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u540c\u65f6\u628a\u5176\u4e2d\u7684\u5b57\u6761\u62ff\u51fa\u6765\u4e86!? } \u53ea\u662f\u6ce8\u610f\u8fd9\u91cc for \u5faa\u73af\u7684\u6b65\u8fdb\u6761\u4ef6 ++it \u8981\u5220\u6389\uff0c\u56e0\u4e3a\u667a\u80fd\u7684 RPG \u5bfc\u5f39 it = m.erase(it) \u5df2\u7ecf\u5e2e\u4f60\u6b65\u8fdb\u4e86\u3002 \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u6b63\u89e3 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto it = m.begin(); it != m.end(); ) { // \u6ca1\u6709 ++it auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u4e0d\u5954\u6e83 for (auto it = m.begin(); it != m.end(); ) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } \u5954\u6e83 for (auto it = m.begin(); it != m.end(); ++it) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { msg.erase(it); // \u6216\u8005 msg.erase(k); } }","title":"\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20"},{"location":"stl_map/#c20-erase_if","text":"\u6279\u91cf\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff08C++20 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; std::erase_if(msg, [&] (auto const &kv) { auto &[k, v] = kv; return k.starts_with(\"fuck\"); }); print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u5982\u679c\u4f60\u641e\u4e0d\u61c2\u8fed\u4ee3\u5668\u8fd9\u4e9b\uff0c\u8fd9\u91cc\u6211\u63d0\u4f9b\u4e00\u4e2a\u4fdd\u5e95\u5199\u6cd5\uff0c\u5148\u628a\u952e\u63d0\u524d\u4fdd\u5b58\u5230\u4e00\u4e2a vector \u4e2d\u53bb\uff1a map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; vector keys; // vector \u6216\u8005 set \u90fd\u53ef\u4ee5 for (auto const &[k, v]: msg) { // \u5148\u628a\u6240\u6709\u952e\u63d0\u524d\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc keys.push_back(k); } for (auto const &k: keys) { // \u904d\u5386\u521a\u624d\u4fdd\u5b58\u7684\u952e if (k.starts_with(\"fuck\")) { msg.erase(k); // \u952e\u503c\u5bf9\u5df2\u7ecf\u63d0\u524d\u6df1\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc\uff0c\u8fd9\u65f6\u5220\u9664 map \u91cc\u7684\u952e\u4e0d\u4f1a\u5954\u6e83 } } \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u795b\u9b45\u5927\u5e08\u3002 \u8fd8\u662f\u641e\u4e0d\u61c2\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u65b0\u5efa\u4e00\u4e2a map\uff0c\u6761\u4ef6\u53cd\u4e4b\uff0c\u628a\u4e0d\u9700\u8981\u5220\u9664\u7684\u5143\u7d20\u63d2\u5165\u65b0 map\uff0c\u8fc7\u6ee4\u51fa\u9700\u8981\u4fdd\u7559\u7684\u5143\u7d20\uff0c\u6700\u540e\u518d\u4e00\u6b21\u6027\u7528\u65b0 map \u8986\u76d6\u65e7 map\u3002 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; map newmsg; for (auto const &[k, v]: msg) { if (!k.starts_with(\"fuck\")) { // \u6ce8\u610f\u8fd9\u91cc\u6761\u4ef6\u53cd\u4e86\uff0c\u4e0d\u9700\u8981\u5220\u9664\u7684\u624d\u63d2\u5165 newmsg newmsg[k] = v; } } msg = std::move(newmsg); // \u8986\u76d6\u65e7\u7684 map\uff0c\u7528\u66f4\u9ad8\u6548\u7684\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff0cO(1) \u590d\u6742\u5ea6 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u4fdd\u5e95\u5927\u5e08\u3002 \u63a5\u4e0b\u6765\u5f00\u59cb\u5b66\u4e60\u5982\u4f55\u63d2\u5165\u5143\u7d20\uff0cmap \u7684\u6210\u5458 insert \u51fd\u6570\u539f\u578b\u5982\u4e0b 1 \uff1a pair insert(pair const &kv); pair insert(pair &&kv); \u4ed6\u7684\u53c2\u6570\u7c7b\u578b\u5c31\u662f\u521a\u521a\u4ecb\u7ecd\u7684 value_type \uff0c\u4e5f\u5c31\u662f pair \u3002 pair \u662f\u4e00\u4e2a STL \u4e2d\u5e38\u89c1\u7684\u6a21\u677f\u7c7b\u578b\uff0c pair \u6709\u4e24\u4e2a\u6210\u5458\u53d8\u91cf\uff1a first\uff1aK \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u952e second\uff1aV \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u503c \u6211\u79f0\u4e4b\u4e3a\u201d\u952e\u503c\u5bf9\u201d\u3002 \u8bd5\u7740\u7528 insert \u63d2\u5165\u952e\u503c\u5bf9\uff1a map m; pair p; p.first = \"fuck\"; // \u952e p.second = 985; // \u503c m.insert(p); // pair \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a insert \u53c2\u6570\u6240\u9700\u7684 pair print(m); \u7ed3\u679c\uff1a {\"fuck\": 985} \u7b80\u5316 insert \u76f4\u63a5\u4f7f\u7528 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u521d\u59cb\u5316 first \u548c second pair p(\"fuck\", 985); m.insert(p); \u4e0d\u7528\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0cpair \u8868\u8fbe\u5f0f\u76f4\u63a5\u4f5c\u4e3a insert \u51fd\u6570\u7684\u53c2\u6570 m.insert(pair(\"fuck\", 985)); \u53ef\u4ee5\u7528 std::make_pair \u8fd9\u4e2a\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u63a8\u5bfc\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u7701\u7565 m.insert(make_pair(\"fuck\", 985)); // \u867d\u7136\u4f1a\u63a8\u5bfc\u4e3a pair \u4f46\u8fd8\u662f\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a pair \u7531\u4e8e insert \u51fd\u6570\u539f\u578b\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528 C++11 \u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868 {\u2026}\uff0c\u65e0\u9700\u6307\u5b9a\u7c7b\u578b m.insert({\"fuck\", 985}); // \u2705 \u56e0\u6b64\uff0cinsert \u7684\u6700\u4f73\u7528\u6cd5\u662f\uff1a map m; m.insert({\"key\", \"val\"}); insert \u63d2\u5165\u548c [] \u5199\u5165\u7684\u5f02\u540c\uff1a \u540c\uff1a\u5f53\u952e K \u4e0d\u5b58\u5728\u65f6\uff0cinsert \u548c [] \u90fd\u4f1a\u521b\u5efa\u952e\u503c\u5bf9\u3002 \u5f02\uff1a\u5f53\u952e K \u5df2\u7ecf\u5b58\u5728\u65f6\uff0cinsert \u4e0d\u4f1a\u8986\u76d6\uff0c\u9ed8\u9ed8\u79bb\u5f00\uff1b\u800c [] \u4f1a\u8986\u76d6\u65e7\u7684\u503c\u3002 \u4f8b\u5b50\uff1a map m; m.insert({\"key\", \"old\"}); m.insert({\"key\", \"new\"}); // \u63d2\u5165\u5931\u8d25\uff0c\u9ed8\u9ed8\u653e\u5f03\u4e0d\u51fa\u9519 print(m); {\"key\": \"old\"} map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; // \u5df2\u7ecf\u5b58\u5728\uff1f\u6211\u8e0f\u9a6c\u5f3a\u884c\u8986\u76d6\uff01 print(m); {\"key\": \"new\"} insert \u7684\u8fd4\u56de\u503c\u662f pair \u7c7b\u578b\uff0c STL \u7684\u5c3f\u6027\uff1a\u5728\u9700\u8981\u4e00\u6b21\u6027\u8fd4\u56de\u4e24\u4e2a\u503c\u65f6\u559c\u6b22\u7528 pair \u3002 \u8fd9\u53c8\u662f\u4e00\u4e2a pair \u7c7b\u578b\uff0c\u5176\u5177\u6709\u4e24\u4e2a\u6210\u5458\uff1a first\uff1aiterator \u7c7b\u578b\uff0c\u662f\u4e2a\u8fed\u4ee3\u5668 second\uff1abool \u7c7b\u578b\uff0c\u8868\u793a\u63d2\u5165\u6210\u529f\u4e0e\u5426\uff0c\u5982\u679c\u53d1\u751f\u952e\u51b2\u7a81\u5219\u4e3a false \u5176\u4e2d first \u8fd9\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\uff1a \u5982\u679c\u63d2\u5165\u6210\u529f\uff08second \u4e3a true\uff09\uff0c\u6307\u5411\u521a\u521a\u6210\u529f\u63d2\u5165\u7684\u5143\u7d20\u4f4d\u7f6e \u5982\u679c\u63d2\u5165\u5931\u8d25\uff08second \u4e3a false\uff09\uff0c\u8bf4\u660e\u5df2\u7ecf\u6709\u76f8\u540c\u7684\u952e K \u5b58\u5728\uff0c\u53d1\u751f\u4e86\u952e\u51b2\u7a81\uff0c\u6307\u5411\u5df2\u7ecf\u5b58\u5728\u7684\u90a3\u4e2a\u5143\u7d20 \u5176\u5b9e insert \u8fd4\u56de\u7684 first \u8fed\u4ee3\u5668\u7b49\u4ef7\u4e8e\u63d2\u5165\u4ee5\u540e\u518d\u91cd\u65b0\u7528 find \u627e\u5230\u521a\u521a\u63d2\u5165\u7684\u90a3\u4e2a\u952e\uff0c\u53ea\u662f\u6548\u7387\u66f4\u9ad8\uff1a auto it = m.insert({k, v}).first; // \u9ad8\u6548\uff0c\u53ea\u9700\u904d\u5386\u4e00\u6b21 m.insert({k, v}); // \u63d2\u5165\u5b8c\u5c31\u5fd8\u4e8b\u4e86 auto it = m.find(k); // \u91cd\u65b0\u904d\u5386\u7b2c\u4e8c\u6b21\uff0c\u4f46\u7ed3\u679c\u4e00\u6837 \u53c2\u8003 C \u7f16\u7a0b\u7f51 1 \u5bf9 insert \u8fd4\u56de\u503c\u7684\u89e3\u91ca\uff1a \u5f53\u8be5\u65b9\u6cd5\u5c06\u65b0\u952e\u503c\u5bf9\u6210\u529f\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u65f6\uff0c\u8fd4\u56de\u7684\u8fed\u4ee3\u5668\u6307\u5411\u65b0\u6dfb\u52a0\u7684\u952e\u503c\u5bf9\uff1b \u53cd\u4e4b\uff0c\u5982\u679c\u6dfb\u52a0\u5931\u8d25\uff0c\u8be5\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\u5bb9\u5668\u4e2d\u548c\u8981\u6dfb\u52a0\u952e\u503c\u5bf9\u952e\u76f8\u540c\u7684\u90a3\u4e2a\u952e\u503c\u5bf9\u3002 \u53ef\u4ee5\u7528 insert \u8fd4\u56de\u7684 second \u5224\u65ad\u63d2\u5165\u591a\u6b21\u662f\u5426\u6210\u529f\uff1a map m; print(m.insert({\"key\", \"old\"}).second); // true print(m.insert({\"key\", \"new\"}).second); // false m.erase(\"key\"); // \u628a\u539f\u6765\u7684 {\"key\", \"old\"} \u5220\u4e86 print(m.insert({\"key\", \"new\"}).second); // true \u4e5f\u53ef\u4ee5\u7528 structured-binding \u8bed\u6cd5\u62c6\u89e3\u4ed6\u8fd4\u56de\u7684 pair \uff1a map counter; auto [it, success] = counter.insert(\"key\", 1); // \u76f4\u63a5\u7528 if (!success) { // \u5982\u679c\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4fee\u6539\u5176\u503c+1 it->second = it->second + 1; } else { // \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6253\u5370\u4ee5\u4e0b\u4fe1\u606f print(\"created a new entry!\"); } \u4ee5\u4e0a\u8fd9\u4e00\u957f\u4e32\u4ee3\u7801\u548c\u4e4b\u524d\u201c\u4f18\u96c5\u201d\u7684\u8ba1\u6570 [] \u7b49\u4ef7\uff1a counter[\"key\"]++;","title":"C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if"},{"location":"stl_map/#insert_or_assign","text":"\u5728 C++17 \u4e2d\uff0c[] \u5199\u5165\u6709\u4e86\u4e2a\u66f4\u9ad8\u6548\u7684\u66ff\u4ee3\u54c1 insert_or_assign 1 \uff1a pair insert_or_assign(K const &k, V v); pair insert_or_assign(K &&k, V v); \u6b63\u5982\u4ed6\u540d\u5b57\u7684\u542b\u4e49\uff0c\u201c\u63d2\u5165\u6216\u8005\u5199\u5165\u201d\uff1a \u5982\u679c K \u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff08\u63d2\u5165\uff09 \u5982\u679c K \u5df2\u7ecf\u5b58\u5728\u5219\u8986\u76d6\uff08\u5199\u5165\uff09 \u7528\u6cd5\u5982\u4e0b\uff1a m.insert_or_assign(\"key\", \"new\"); // \u4e0e insert \u4e0d\u540c\uff0c\u4ed6\u4e0d\u9700\u8981 {...}\uff0c\u4ed6\u7684\u53c2\u6570\u5c31\u662f\u4e24\u4e2a\u5355\u72ec\u7684 K \u548c V \u8fd4\u56de\u503c\u4f9d\u65e7\u662f pair \u3002\u7531\u4e8e\u8fd9\u51fd\u6570\u5728\u952e\u51b2\u7a81\u65f6\u4f1a\u8986\u76d6\uff0c\u6309\u7406\u8bf4\u662f\u5fc5\u5b9a\u6210\u529f\u4e86\uff0c\u56e0\u6b64\u8fd9\u4e2a bool \u7684\u542b\u4e49\u4ece\u201c\u662f\u5426\u63d2\u5165\u6210\u529f\u201d\u53d8\u4e3a\u201c\u662f\u5426\u521b\u5efa\u4e86\u5143\u7d20\u201d\uff0c\u5982\u679c\u662f\u521b\u5efa\u7684\u65b0\u5143\u7d20\u8fd4\u56detrue\uff0c\u5982\u679c\u8986\u76d6\u4e86\u65e7\u5143\u7d20\u8fd4\u56defalse\u3002","title":"insert_or_assign"},{"location":"stl_map/#insert_or_assign_1","text":"\u770b\u6765 insert_or_assign \u548c [] \u7684\u6548\u679c\u5b8c\u5168\u76f8\u540c\uff01\u90fd\u662f\u5728\u952e\u503c\u51b2\u7a81\u65f6\u8986\u76d6\u65e7\u503c\u3002 \u65e2\u7136 [] \u5df2\u7ecf\u53ef\u4ee5\u505a\u5230\u540c\u6837\u7684\u6548\u679c\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u53d1\u660e\u4e2a insert_or_assign \u5462\uff1f insert_or_assign \u7684\u4f18\u70b9\u662f \u4e0d\u9700\u8981\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 \uff0c\u53ef\u4ee5\u63d0\u5347\u6027\u80fd\u3002 \u5176\u5e94\u7528\u573a\u666f\u6709\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff1a \u23f1 \u60a8\u7279\u522b\u5728\u4e4e\u6027\u80fd \u274c \u6709\u65f6 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u7528 [] \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \ud83e\udd75 \u5f3a\u8feb\u75c7\u53d1\u4f5c \u5426\u5219\u7528 [] \u5199\u5165\u4e5f\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u800c\u4e14 insert_or_assign \u80fd\u53d6\u4ee3 [] \u7684\u5c97\u4f4d\u4ec5\u9650\u4e8e\u7eaf\u5199\u5165\uff0c\u4e4b\u524d counter[key]++ \u8fd9\u79cd\u201c\u4f18\u96c5\u201d\u5199\u6cd5\u4f9d\u7136\u662f\u9700\u8981\u7528 [] \u7684\u3002","title":"insert_or_assign \u7684\u4f18\u52bf"},{"location":"stl_map/#_29","text":"\u521b\u5efa\u65b0\u952e\u65f6\uff0cinsert_or_assign \u66f4\u9ad8\u6548\u3002","title":"\u6548\u7387\u95ee\u9898"},{"location":"stl_map/#_30","text":"map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 V() \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&)","title":"[]"},{"location":"stl_map/#insert_or_assign_2","text":"map m; m.insert_or_assign(\"key\", \"old\"); m.insert_or_assign(\"key\", \"new\"); print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u6784\u9020\u51fd\u6570 V(V &&)","title":"insert_or_assign"},{"location":"stl_map/#_31","text":"\u603b\u7ed3\uff0c\u5982\u679c\u4f60\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u5e76\u4e14\u662f C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 insert_or_assign \u8bfb\u53d6\u7528 at \u5982\u679c\u6ca1\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u6216\u8005\u4f60\u7684\u7f16\u8bd1\u5668\u4e0d\u652f\u6301 C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 [] \u8bfb\u53d6\u7528 at \u6700\u540e\uff0c\u5982\u679c\u4f60\u662f\u8fd8\u539f\u8bba\u8005\uff0c\u53ea\u9700\u8981 find \u548c insert \u51fd\u6570\u5c31\u662f\u5b8c\u5907\u7684\u4e86\uff0c\u522b\u7684\u51fd\u6570\u90fd\u4e0d\u7528\u53bb\u8bb0\u3002\u6240\u6709 at\u3001[]\u3001insert_or_assign \u4e4b\u7c7b\u7684\u64cd\u4f5c\u90fd\u53ef\u4ee5\u901a\u8fc7 find \u548c insert \u7684\u7ec4\u5408\u62f3\u5b9e\u73b0\uff0c\u4f8b\u5982\u521a\u521a\u6211\u4eec\u81ea\u5b9a\u4e49\u7684 map_get\u3002","title":"\u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48"},{"location":"stl_map/#insert_or_assign-vs-insert","text":"\u56de\u987e\u4e4b\u524d\u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u5982\u679c\u6709\u91cd\u590d\uff0c\u5982\u4f55\u533a\u5206\u627e\u7b2c\u4e00\u4e2a\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\uff1f \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u6700\u540e\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert_or_assign(arr[i], i); // \u7b49\u4ef7\u4e8e arrinv[arr[i]] = i; } \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u7b2c\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert({arr[i], i}); }","title":"insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898"},{"location":"stl_map/#insert","text":"\u521a\u521a\u4ecb\u7ecd\u7684\u90a3\u4e9b insert \u4e00\u6b21\u53ea\u80fd\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0cinsert \u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u7248\u672c\uff0c\u7528\u4e8e\u6279\u91cf\u63d2\u5165\u4e00\u7cfb\u5217\u5143\u7d20\u3002 template void insert(InputIt beg, InputIt end); \u53c2\u6570 1 \u662f\u4e24\u4e2a\u8fed\u4ee3\u5668 beg \u548c end\uff0c\u7ec4\u6210\u4e00\u4e2a\u533a\u95f4\uff0c\u4e4b\u95f4\u662f\u4f60\u8981\u63d2\u5165\u7684\u6570\u636e\u3002 \u8be5\u533a\u95f4\u53ef\u4ee5\u662f\u4efb\u4f55\u5176\u4ed6\u5bb9\u5668\u7684 begin() \u548c end() \u8fed\u4ee3\u5668\u2014\u2014\u90a3\u4f1a\u628a\u8be5\u5bb9\u5668\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u63d2\u5165\u5230\u672c map \u4e2d\u53bb\u3002 \u4f8b\u5982\uff0c\u628a vector \u4e2d\u7684\u952e\u503c\u5bf9\u6279\u91cf\u63d2\u5165 map\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); // {\"delay\": 211, \"timeout\": 985}","title":"\u6279\u91cf insert"},{"location":"stl_map/#insert_1","text":"\u6ce8\uff1a\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5982\u679c vector \u4e2d\u6709\u91cd\u590d\u7684\u952e\uff0c\u5219\u4f1a\u4ee5\u952e\u7b2c\u4e00\u6b21\u51fa\u73b0\u65f6\u7684\u503c\u4e3a\u51c6\uff0c\u4e4b\u540e\u91cd\u590d\u51fa\u73b0\u7684\u952e\u4f1a\u88ab\u5ffd\u89c6\u3002 vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); {\"delay\": 211, \"timeout\": 985} vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config = { {\"timeout\", 404}, }; config.insert(kvs.begin(), kvs.end()); print(config); vector> v; {\"delay\": 211, \"timeout\": 404}","title":"\u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219"},{"location":"stl_map/#insert-map","text":"\u6279\u91cf insert \u8fd0\u7528\u6848\u4f8b\uff1a\u4e24\u4e2a map \u5408\u5e76 \u8fd9\u4e2a\u6279\u91cf insert \u8f93\u5165\u7684\u8fed\u4ee3\u5668\u53ef\u4ee5\u662f\u4efb\u4f55\u5bb9\u5668\uff0c\u751a\u81f3\u53ef\u4ee5\u662f\u53e6\u4e00\u4e2a map \u5bb9\u5668\u3002 \u8fd0\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u4e24\u4e2a map \u7684\u5e76\u96c6\u64cd\u4f5c\u3002 map m1 = { // \u7b2c\u4e00\u4e2a map {\"answer\", 42}, {\"timeout\", 7}, }; map m2 = { // \u7b2c\u4e8c\u4e2a map {\"timeout\", 985}, {\"delay\", 211}, }; m1.insert(m2.begin(), m2.end()); // \u628a m2 \u7684\u5185\u5bb9\u4e0e m1 \u5408\u5e76\uff0c\u7ed3\u679c\u5199\u56de\u5230 m1 print(m1); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd8\u662f\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5f53\u9047\u5230\u91cd\u590d\u7684\u952e\u65f6\uff08\u4f8b\u5982\u4e0a\u9762\u7684 \u201ctimeout\u201d\uff09\uff0c\u4f1a\u4ee5 m1 \u4e2d\u7684\u503c\u4e3a\u51c6\u3002","title":"\u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76"},{"location":"stl_map/#_32","text":"\u4f7f\u7528 m1.insert(m2.begin(), m2.end()) \u540e\uff0c\u5408\u5e76\u7684\u7ed3\u679c\u4f1a\u5c31\u5730\u5199\u5165 m1\u3002 \u5982\u679c\u5e0c\u671b\u5408\u5e76\u7ed3\u679c\u653e\u5230\u4e00\u4e2a\u65b0\u7684 map \u5bb9\u5668\u4e2d\u800c\u4e0d\u662f\u5c31\u5730\u4fee\u6539 m1\uff0c\u8bf7\u5148\u81ea\u884c\u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d\uff1a const map m1 = { // \u7b2c\u4e00\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"answer\", 42}, {\"timeout\", 7}, }; const map m2 = { // \u7b2c\u4e8c\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"timeout\", 985}, {\"delay\", 211}, }; auto m12 = m1; // \u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d m12\uff0c\u907f\u514d insert \u5c31\u5730\u4fee\u6539 m1 m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c {\"answer\": 42, \"delay\": 211, \"timeout\": 7}","title":"\u5c31\u5730\u5199\u5165\uff01"},{"location":"stl_map/#insert_2","text":"auto m12 = m1; m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m1 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u521a\u521a\u5199\u7684 m1 \u548c m2 \u5408\u5e76\uff0c\u9047\u5230\u91cd\u590d\u65f6\u4f1a\u4f18\u5148\u91c7\u53d6 m1 \u91cc\u7684\u503c\uff0c\u5982\u679c\u5e0c\u671b\u4f18\u5148\u91c7\u53d6 m2 \u7684\u5462\uff1f\u53cd\u4e00\u53cd\u5c31\u53ef\u4ee5\u4e86\uff1a auto m12 = m2; m12.insert(m1.begin(), m1.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m2 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 985} \u8981\u662f\u5b66\u4e0d\u4f1a\u6279\u91cf insert\uff0c\u90a3\u624b\u5199\u4e00\u4e2a for \u5faa\u73af\u904d\u5386 m2\uff0c\u7136\u540e m1.insert_or_assign(k2, v2) \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u603b\u4e4b\u8981\u61c2\u5f97\u53d8\u901a\uff0c\u52a8\u52a8\u8111\uff0c\u603b\u662f\u6709\u4fdd\u5e95\u5199\u6cd5\u7684\u3002","title":"\u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684"},{"location":"stl_map/#_33","text":"\u6709\u540c\u5b66\u5c31\u95ee\u4e86\uff0c\u8fd9\u4e2a insert \u5b9e\u73b0\u4e86 map \u7684\u5e76\u96c6\u64cd\u4f5c\uff0c\u90a3\u4ea4\u96c6\u64cd\u4f5c\u5462\uff1f\u8fd9\u5176\u5b9e\u662f set \u7684\u5e38\u89c4\u64cd\u4f5c\u800c\u4e0d\u662f map \u7684\uff1a set_intersection\uff08\u53d6\u96c6\u5408\u4ea4\u96c6\uff09 set_union\uff08\u53d6\u96c6\u5408\u5e76\u96c6\uff09 set_difference\uff08\u53d6\u96c6\u5408\u5dee\u96c6\uff09 set_symmetric_difference\uff08\u53d6\u96c6\u5408\u5bf9\u79f0\u5dee\u96c6\uff09 \u975e\u5e38\u62b1\u6b49\u5728\u4e4b\u524d\u7684 set \u8bfe\u4e2d\u5b8c\u5168\u6ca1\u6709\u63d0\u53ca\uff0c\u56e0\u4e3a\u6211\u8ba4\u4e3a\u90a3\u662f \u5934\u6587\u4ef6\u91cc\u7684\u4e1c\u897f\u3002 \u4e0d\u8fc7\u522b\u62c5\u5fc3\uff0c\u4e4b\u540e\u6211\u4eec\u4f1a\u4e13\u95e8\u6709\u4e00\u8282 algorithm \u8bfe\u8be6\u89e3 STL \u4e2d\u8fd9\u4e9b\u5168\u5c40\u51fd\u6570\u2014\u2014\u6211\u79f0\u4e4b\u4e3a\u7b97\u6cd5\u6a21\u677f\uff0c\u56e0\u4e3a\u4ed6\u63d0\u4f9b\u4e86\u5f88\u591a\u5e38\u7528\u7684\u7b97\u6cd5\uff0c\u5bf9\u5c0f\u5f6d\u8001\u5e08\u8fd9\u79cd\u7b97\u6cd5\u5f31\u9e21\u800c\u8a00\uff0c\u5b9e\u5728\u975e\u5e38\u597d\u7528\uff0c\u5988\u5988\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3\u6211\u7684 ACM \u5956\u676f\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u5236\u4f5c\u5b8c algorithm \u8bfe\u4e4b\u524d\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u81ea\u884c\u53c2\u8003 https://blog.csdn.net/u013095333/article/details/89322501 \u63d0\u524d\u8fdb\u884c\u5b66\u4e60\u8fd9\u56db\u4e2a\u51fd\u6570\u3002 std::set_union(A.begin(), A.end(), B.begin(), B.end(), std::inserter(C, C.begin())); // C = A U B \u6ce8\uff1aset_union \u4ec5\u4ec5\u8981\u6c42\u8f93\u5165\u7684\u4e24\u4e2a\u533a\u95f4\u6709\u5e8f\uff0c\u53ef\u4ee5\u662f set\uff0c\u4e5f\u53ef\u4ee5\u662f\u6392\u5e8f\u8fc7\u7684 vector\u3002\u800c\u4e14\u901a\u8fc7\u91cd\u8f7d\u8fd0\u7b97\u7b26\u6216\u8005\u6307\u5b9a compare \u51fd\u6570\uff0c\u540c\u6837\u53ef\u4ee5\u6a21\u62df map \u53ea\u5bf9 key \u90e8\u5206\u6392\u5e8f\u7684\u6548\u679c\u2014\u2014\u53c2\u8003 thrust::sort_by_key\uff0c\u4f46\u5f88\u53ef\u60dc STL \u6ca1\u6709\u8fd9\u51fd\u6570\uff0c\u9700\u8981\u81ea\u5b9a\u4e49 compare \u51fd\u6570\u6a21\u62df\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u662f\u5f88\u5bb9\u6613\u57fa\u4e8e map \u7684 contains\u3001erase\u3001insert \u7b49\u63a5\u53e3\u201c\u52a8\u52a8\u8111\u201d\u5199\u51fa\u4fdd\u5e95\u5199\u6cd5\uff1a map m12; for (const auto &[k, v] : m2) { if (m1.contains(k)) { // \u6b64\u5904\u4e3a count \u4e5f\u53ef\u4ee5 // \u4ea4\u96c6\u64cd\u4f5c\uff1a\u5982\u679c m1 \u548c m2 \u90fd\u6709\u8fd9\u4e2a\u952e\uff0c\u5219\u63d2\u5165\u4ed6\u4fe9\u7684\u4ea4\u96c6 m12 m12.insert({k, v}); } }","title":"\u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49"},{"location":"stl_map/#insert_3","text":"C++11 \u8fd8\u5f15\u5165\u4e86\u4e00\u4e2a\u4ee5\u521d\u59cb\u5316\u5217\u8868\uff08initializer_list\uff09\u4e3a\u53c2\u6570\u7684 insert \u7248\u672c\uff1a void insert(initializer_list> ilist); \u7528\u6cd5\u548c map \u7684\u6784\u9020\u51fd\u6570\u4e00\u6837\uff0c\u8fd8\u662f\u7528\u82b1\u62ec\u53f7\u5217\u8868\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m.insert({ // \u6279\u91cf\u518d\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, // \"timeout\" \u53d1\u751f\u952e\u51b2\u7a81\uff0c\u6839\u636e insert \u7684\u7279\u6027\uff0c\u4e0d\u4f1a\u8986\u76d6 {\"delay\", 211}, }); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd9\u91cc\u8fd8\u662f\u548c\u9010\u4e2a insert \u4e00\u6837\uff0c\u91cd\u590d\u7684\u952e \u201ctimeout\u201d \u6ca1\u6709\u88ab\u8986\u76d6\uff0c\u4f9d\u65e7\u4e86\u4fdd\u7559\u539f\u503c\u3002","title":"insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868"},{"location":"stl_map/#insert_4","text":"m.insert({ {\"timeout\", 985}, {\"delay\", 211}, }); \u603b\u4e4b\u8fd9\u73a9\u610f\u548c\u5206\u522b\u8c03\u7528\u4e24\u6b21 insert \u7b49\u4ef7\uff1a m.insert({\"timeout\", 985}); m.insert({\"delay\", 211}); \u5982\u679c\u9700\u8981\u8986\u76d6\u539f\u503c\u7684\u6279\u91cf\u5199\u5165\uff0c\u8fd8\u662f\u5f97\u4e56\u4e56\u5199\u4e2a for \u5faa\u73af\u8c03\u7528 [] \u6216 insert_or_assign\u3002 \u95ee\uff1a\u65e2\u7136\u548c\u6279\u91cf\u63d2\u5165\u6ca1\u4ec0\u4e48\u533a\u522b\uff0c\u590d\u6742\u5ea6\u4e5f\u4e00\u6837\u662f O(\\log N) O(\\log N) \uff0c\u90a3\u6279\u91cf insert \u7a76\u7adf\u8fd8\u6709\u4ec0\u4e48\u5b58\u5728\u7684\u5fc5\u8981\u5462\uff1fmap \u53c8\u4e0d\u50cf vector \u4e00\u4e2a\u4e2a\u5206\u522b\u63d2\u5165\u4f1a\u53d8\u6210 O(N^2) O(N^2) \u590d\u6742\u5ea6\uff0c\u786e\u5b9e\u9700\u8981\u63d0\u4f9b\u4e2a\u6279\u91cf\u63d2\u5165\u7684\u65b9\u6cd5\u3002 \u7b54\uff1a \u662f\u4e3a\u4e86\u7edf\u4e00\uff0c\u65e2\u7136 vector \u90fd\u6709\u6279\u91cf insert\uff0c\u90a3 set \u548c map \u4e5f\u5f97\u6709\u624d\u7b26\u5408\u5b8c\u7f8e\u4e3b\u4e49\u7f8e\u5b66\uff0c\u800c\u4e14\u7528\u4ed6\u6765\u5408\u5e76\u4e24\u4e2a map \u4e5f\u5f88\u65b9\u4fbf\u3002 \u590d\u6742\u5ea6\u5e76\u4e0d\u4e00\u6837\uff0c\u5f53\u8f93\u5165\u5df2\u7ecf\u6709\u5e8f\u65f6\uff0c\u6279\u91cf insert \u4f1a\u6bd4\u9010\u4e2a insert \u66f4\u5feb\uff0c\u53ea\u9700 O(N) O(N) \u800c\u4e0d\u662f O(N \\log N) O(N \\log N) \uff1b\u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \uff0c\u7a0d\u540e\u4f1a\u8bb2\u539f\u7406\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528"},{"location":"stl_map/#operator","text":"map &operator=(initializer_list> ilist); map \u4e5f\u652f\u6301\u8d4b\u503c\u51fd\u6570\uff0c\u4e0d\u4ec5\u6709 map \u81ea\u5df1\u7ed9\u81ea\u5df1\u8d4b\u503c\u7684\u79fb\u52a8\u8d4b\u503c\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff0c\u8fd8\u6709\u4ece\u5217\u8868\u521d\u59cb\u5316\u7684\u51fd\u6570\u3002 \u7528\u6cd5\u662f\u7b49\u53f7\u53f3\u8fb9\u4e00\u4e2a\u82b1\u62ec\u53f7\u5217\u8868\uff0c\u4f5c\u7528\u662f\u6e05\u7a7a\u539f\u6709\u5185\u5bb9\uff0c\u76f4\u63a5\u8bbe\u4e3a\u4e00\u4e2a\u5168\u65b0\u7684 map\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m = { // \u539f\u6709\u5185\u5bb9\u5168\u90e8\u6e05\u7a7a\uff01\u91cd\u65b0\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, {\"delay\", 211}, }; {\"delay\": 211, \"timeout\": 985} \u76f8\u5f53\u4e8e clear \u4e86\u518d\u91cd\u65b0 insert\uff0c\u539f\u6709\u7684 \u201canswer\u201d \u952e\u4e5f\u88ab\u5220\u6389\u4e86\u3002","title":"operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868"},{"location":"stl_map/#_34","text":"\u8981\u6ce8\u610f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) \u548c\u6784\u9020\u51fd\u6570 map(initializer_list) \u662f\u4e0d\u540c\u7684\u3002 \u6784\u9020\u51fd\u6570\u662f\u521d\u59cb\u5316\u65f6\u8c03\u7528\u7684\uff08\u65e0\u8bba\u6709\u6ca1\u6709 = \u53f7\uff09\uff0c\u8d4b\u503c\u51fd\u6570\u662f\u540e\u671f\u91cd\u65b0\u8d4b\u503c\u65f6\u8c03\u7528\u7684\u3002 map m{ // \u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; map m = { // \u867d\u7136\u6709\u7b49\u53f7\uff0c\u4f46\u8fd9\u91cc\u662f\u521d\u59cb\u5316\u8bed\u5883\uff0c\u8c03\u7528\u7684\u4f9d\u7136\u662f\u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; m = { // m \u5df2\u7ecf\u521d\u59cb\u5316\u8fc7\uff0c\u8fd9\u91cc\u662f\u91cd\u65b0\u8d4b\u503c\uff0c\u624d\u662f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) {\"timeout\", 985}, {\"delay\", 211}, }; \u5982\u679c\u4e00\u4e2a\u7c7b\u8981\u652f\u6301\u521d\u59cb\u5316\uff0c\u53c8\u8981\u652f\u6301\u540e\u671f\u91cd\u65b0\u8d4b\u503c\uff0c\u90a3\u4e48\u6784\u9020\u51fd\u6570\u548c\u8d4b\u503c\u51fd\u6570\u90fd\u8981\u5b9e\u73b0\u3002 \u4f46\u4e5f\u53ef\u4ee5\u9009\u62e9\u53ea\u5b9a\u4e49 operator=(map &&) \u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u800c\u4e0d\u5b9a\u4e49 operator=(initializer_list) \u3002\u8fd9\u6837\u5f53\u8bd5\u56fe operator=(initializer_list) \u65f6\uff0c\u4f1a\u5339\u914d\u5230 map(initializer_list) \u8fd9\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\uff0c\u7136\u540e\u8c03\u7528\u5230 operator=(map &&) \u3002\u6807\u51c6\u5e93\u9009\u62e9\u5c06\u4e24\u4e2a\u90fd\u5b9a\u4e49\u53ef\u80fd\u662f\u5904\u4e8e\u907f\u514d\u4e00\u6b21 map \u79fb\u52a8\u7684\u6548\u7387\u8003\u91cf\u3002","title":"\u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790"},{"location":"stl_map/#assign","text":"map \u8fd8\u6709\u4e00\u4e2a assign \u51fd\u6570\uff0c\u4ed6\u548c operator= \u7b49\u4ef7\uff1a void assign(initializer_list> ilist); assign \u7684\u989d\u5916\u597d\u5904\u662f\u4ed6\u62e5\u6709\u4e24\u4e2a\u8fed\u4ee3\u5668\u53c2\u6570\u7ec4\u6210\u533a\u95f4\u7684\u7248\u672c\uff0c\u548c\u6279\u91cf insert \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7 assign \u4f1a\u6e05\u9664\u5df2\u6709\u7684\u5143\u7d20\u3002 template void assign(InputIt first, InputIt last); \u548c operator=(map(first, last)) \u7b49\u4ef7\u3002","title":"assign \u51fd\u6570"},{"location":"stl_map/#insert_5","text":"iterator insert(const_iterator pos, pair const &kv); \u8fd9\u53c8\u662f insert \u51fd\u6570\u7684\u4e00\u4e2a\u91cd\u8f7d\u7248\uff0c\u589e\u52a0\u4e86 pos \u53c2\u6570\u63d0\u793a\u63d2\u5165\u4f4d\u7f6e\uff0c\u5b98\u65b9\u6587\u6863\u79f0 1 \uff1a Inserts value in the position as close as possible to the position just prior to pos. \u628a\u5143\u7d20\uff08\u952e\u503c\u5bf9\uff09\u63d2\u5165\u5230\u4f4d\u4e8e pos \u4e4b\u524d\uff0c\u53c8\u79bb pos \u5c3d\u53ef\u80fd\u8fd1\u7684\u5730\u65b9\u3002 \u7136\u800c map \u4f5c\u4e3a\u7ea2\u9ed1\u6811\u5e94\u8be5\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0c\u63d2\u5165\u4f4d\u7f6e\u53ef\u4ee5\u7531 K \u552f\u4e00\u786e\u5b9a\uff0c\u4e3a\u5565\u8fd8\u8981\u63d0\u793a\uff1f \u662f\u4e3a\u4e86\u5728\u5df2\u77e5\u8981\u63d2\u5165\u7684\u5927\u81f4\u4f4d\u7f6e\u65f6\uff0c\u80fd\u591f\u63d0\u5347\u6027\u80fd\u3002 \uff08\u5e26\u63d0\u793a\u7684 insert \u7248\u672c\uff09\u4e2d\u4f20\u5165\u7684\u8fed\u4ee3\u5668\uff0c\u4ec5\u662f\u7ed9 map \u5bb9\u5668\u63d0\u4f9b\u4e00\u4e2a\u5efa\u8bae\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u88ab\u5bb9\u5668\u91c7\u7eb3\u3002\u8be5\u8fed\u4ee3\u5668\u8868\u660e\u5c06\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\uff0c\u5e76\u4e0d\u662f\u6b64\u8fed\u4ee3\u5668\u8bf4\u4e86\u7b97\uff0c\u6700\u7ec8\u4ecd\u53d6\u51b3\u4e8e\u8be5\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c\u3002 2 \u4e5f\u5c31\u662f\u8bf4\u8fd9\u73a9\u610f\u8fd8\u4e0d\u4e00\u5b9a\u7ba1\u7528\uff0c\u53ea\u662f\u63d0\u793a\u6027\u8d28\u7684\uff08\u548c mmap \u51fd\u6570\u7684 start \u53c2\u6570\u5f88\u50cf\uff0c\u4f60\u53ef\u4ee5\u6307\u5b9a\uff0c\u4f46\u53ea\u662f\u4e2a\u63d0\u793a\uff0c\u6307\u5b9a\u4e86\u4e0d\u4e00\u5b9a\u6709\u4ec0\u4e48\u8f6f\u7528\uff0c\u5177\u4f53\u4ec0\u4e48\u5730\u5740\u8fd8\u662f\u64cd\u4f5c\u7cfb\u7edf\u8bf4\u4e86\u7b97\uff0c\u4ed6\u4ece\u8fd4\u56de\u503c\u91cc\u7ed9\u4f60\u7684\u5730\u5740\u624d\u662f\u6b63\u786e\u7b54\u6848\uff09\u3002\u4f8b\u5982\u5df2\u77e5\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u60f3\u8981\u63d2\u5165 \u201ckea\u201d\uff0c\u90a3\u4e48\u6307\u5b9a\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\u5c31\u4f1a\u8ba9 insert \u80fd\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230 \u201ckea\u201d \u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002","title":"\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert"},{"location":"stl_map/#_35","text":"iterator insert(const_iterator pos, pair const &kv); \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u7684\u51c6\u786e\u65f6\uff0cinsert \u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u4f4e\u81f3 O(1)+ O(1)+ \u3002 \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u4e0d\u51c6\u786e\u65f6\uff0c\u548c\u666e\u901a\u7684 insert \u4e00\u6837\uff0c\u8fd8\u662f O(\\log N) O(\\log N) \u3002 \u8fd4\u56de\u6307\u5411\u6210\u529f\u63d2\u5165\u5143\u7d20\u4f4d\u7f6e\u7684\u8fed\u4ee3\u5668\u3002 \u60f3\u60f3\u770b\uff0c\u8fd9\u4e09\u4e2a\u770b\u4f3c\u4e0d\u76f8\u5e72\u7684\u7279\u6027\uff0c\u80fd\u6709\u4ec0\u4e48\u7528\u5462\uff1f \u53ef\u4ee5\u8ba9\u5df2\u7ecf\u6709\u5e8f\u6570\u636e\u7684\u6279\u91cf\u63d2\u5165\u66f4\u9ad8\u6548\uff01 \u4f17\u6240\u5468\u77e5\uff0c\u666e\u901a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4e3a O(N \\log N) O(N \\log N) \u3002 vector> arr; map tab; for (auto const &[k, v]: arr) { tab.insert({k, v}); // O(log N) } // \u603b\u5171 O(N log N) \u5047\u5982\u8f93\u5165\u672c\u5c31\u6709\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(N) O(N) \u3002 \u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \u4e0d\u53d8\u3002 vector> arr; map tab; auto hint = tab.begin(); for (auto const &[k, v]: arr) { hint = tab.insert(hint, {k, v}); // \u5e73\u5747 O(1) } // \u603b\u5171 O(N) \u60f3\u4e00\u60f3\uff0c\u4e3a\u4ec0\u4e48\uff1f","title":"\u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba"},{"location":"stl_map/#_36","text":"\u4f60\u662f\u4e00\u540d\u5c0f\u5b66\u8001\u5e08\uff0c\u9a6c\u4e0a\u5c31\u8981\u51fa\u65e9\u64cd\u4e86\uff0c\u4e3a\u5e94\u4ed8\u9886\u5bfc\u9762\u5b50\uff0c\u4f60\u9700\u8981\u7ed9\u4f60\u7684\u5b66\u751f\u6392\u961f\uff0c\u6839\u636e\u4e2a\u5b50\u4ece\u77ee\u5230\u9ad8\u6392\u5217\u3002 \u4e0d\u8fc7\u8fd9\u6240\u5c0f\u5b66\u7684\u5b66\u751f\u90fd\u6bd4\u8f83\u61d2\u6563\uff0c\u6709\u7684\u6765\u5f97\u65e9\u6709\u7684\u6765\u5f97\u665a\uff0c\u800c\u4e14\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u4ed6\u4eec\u7684\u9ad8\u77ee\u65e0\u5173\u3002 \u4f60\u672c\u6765\u6253\u7b97\u7b49\u6240\u6709\u4eba\u5230\u9f50\u4e4b\u540e\u518d\u4e00\u6b21\u6027\u5b8c\u6210\u6392\u5e8f\uff08std::sort\uff09\u7684\uff0c\u4f46\u662f\u540c\u5b66\u6765\u7684\u65f6\u95f4\u5b9e\u5728\u662f\u592a\u5206\u6563\u4e86\uff1a\u660e\u660e 8 \u70b9\u5c31\u8981\u51fa\u65e9\u64cd\uff0c\u6700\u665a\u7684\u540c\u5b66\u5374 7 \u70b9 59 \u5206\u624d\u5230\u8fbe\u3002\u610f\u5473\u7740\u4f60\u9700\u8981\u4e00\u76f4\u5e72\u7b49\u7740\u8fd9\u4e2a\u61d2\u6563\u7684\u540c\u5b66\uff0c\u6700\u540e\u5728 1 \u5206\u949f\u65f6\u95f4\u5185\u4e34\u65f6\u62b1\u4f5b\u811a\uff0c\u5b8c\u6210\u5feb\u901f\u6392\u5e8f\u3002\u8fd9\u662f\u4e0d\u53ef\u80fd\u7684\uff0c\u53ea\u80fd\u5728\u540c\u5b66\u9646\u7eed\u62b5\u8fbe\u7684\u540c\u65f6\u8fdb\u884c\u6392\u5e8f\uff0c\u8fd9\u5c31\u662f\u5806\u6392\u5e8f\uff0c\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u6392\u5e8f\uff0c\u6bcf\u6b21\u63d2\u5165\u540e\u90fd\u4fdd\u8bc1\u6709\u5e8f\uff0c\u4e0e\u63d2\u5165\u6392\u5e8f\u4e0d\u540c\u4ed6\u4f7f\u7528\u5806\u5185\u5b58\u4e2d\u7684\u8282\u70b9\u800c\u4e0d\u662f\u6570\u7ec4\u907f\u514d\u6602\u8d35\u7684\u6570\u7ec4\u5e73\u79fb\u64cd\u4f5c\u3002 \u6bcf\u5f53\u6765\u4e00\u4e2a\u5b66\u751f\uff0c\u4f60\u5c31\u5f97\u628a\u4ed6\u63d2\u5165\u5230\u73b0\u6709\u7684\u4e00\u4e2a\u5df2\u7ecf\u6392\u597d\u7684\u961f\u4f0d\u4e2d\u53bb\u3002 \u5982\u4f55\u786e\u5b9a\u63d2\u5165\u7684\u4f4d\u7f6e\uff1f\u4e8c\u5206\u6cd5\u3002\u5148\u4ece\u73b0\u6709\u961f\u4f0d\u7684\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\uff0c\u6bd4\u8f83\u4e2d\u95f4\u8fd9\u4e2a\u5b66\u751f\u548c\u65b0\u6765\u7684\u5b66\u751f\u54ea\u4e2a\u9ad8\u54ea\u4e2a\u77ee\uff0c\u5982\u679c\u53d1\u73b0\u65b0\u6765\u7684\u5b66\u751f\u9ad8\uff0c\u5219\u7ee7\u7eed\u4ece\u961f\u5217\u7684 3/4 \u5904\u90a3\u4e2a\u540c\u5b66\u5f00\u59cb\u6bd4\u9ad8\u77ee\uff0c\u5982\u679c\u65b0\u6765\u7684\u5b66\u751f\u77ee\u5c31\u4ece\u961f\u5217\u7684 1/4 \u5904\u7ee7\u7eed\u6bd4\u8f83\u3002\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6700\u7ec8\u552f\u4e00\u786e\u5b9a\u65b0\u540c\u5b66\u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002\u56e0\u4e3a\u6bcf\u6b21\u786e\u5b9a\u7684\u8303\u56f4\u5c31\u5c0f\u4e00\u534a\uff0c\u6240\u4ee5\u6700\u591a\u53ea\u9700\u8981 \\log N \\log N \u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u6210\u529f\u63d2\u5165\uff0c\u5176\u4e2d N N \u662f\u5f53\u524d\u5df2\u6709\u5b66\u751f\u7684\u6570\u91cf\u3002 \u603b\u5171\u8981\u6765 N N \u540d\u5b66\u751f\uff0c\u5219\u4f60\u603b\u5171\u9700\u8981\u6bd4\u8f83 N \\log N N \\log N \u6b21\u3002\u80fd\u4e0d\u80fd\u4f18\u5316\uff1f\u8ba9\u6211\u4eec\u5c0f\u5f6d\u8001\u5e08\u7701\u529b\u70b9\uff1f","title":"\u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd"},{"location":"stl_map/#_37","text":"\u540e\u6765\u4f60\u53d1\u73b0\u4e00\u4e2a\u89c4\u5f8b\uff0c\u4f3c\u4e4e\u5b66\u751f\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u6709\u5173\uff1a\u77ee\u5c0f\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u65e9\uff0c\u9ad8\u5927\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u665a\u3002 \u77e5\u9053\u8fd9\u4e2a\u89c4\u5f8b\u540e\uff0c\u4f60\u6539\u53d8\u4f60\u7684\u7b56\u7565\uff1a\u4e8c\u5206\u6cd5\u65f6\uff0c\u4e0d\u662f\u5148\u4ece\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\u67e5\u627e\uff0c\u800c\u662f\u4ece\u6700\u672b\u5c3e\u5f00\u59cb\u67e5\u627e\u3002\u56e0\u4e3a\u77ee\u5c0f\u540c\u5b66\u4f1a\u65e9\u5230\uff0c\u5bfc\u81f4\u6bcf\u6b21\u65b0\u6765\u7684\u540c\u5b66\u5f80\u5f80\u603b\u662f\u961f\u5217\u4e2d\u6700\u9ad8\u7684\u90a3\u4e00\u4e2a\u3002\u6240\u4ee5\u53ef\u4ee5\u4ece\u961f\u4f0d\u7684\u672b\u5c3e\uff08\u6700\u9ad8\u7684\u5730\u65b9\uff09\u5f00\u59cb\u627e\uff0c\u4f8b\u5982\u6709 64 \u540d\u540c\u5b66\u5219\u4f18\u5148\u548c 65/64 \u5904\u6bd4\u8f83\uff0c\u627e\u4e0d\u5230\u518d\u5f80\u4e0a\u4e00\u7ea7\u548c 31/32 \u5904\u6bd4\u8f83\u3002 \u8fd9\u4e2a\u7b56\u7565\u4e5f\u6709\u7f3a\u70b9\uff1a\u5bf9\u4e8e\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u65e0\u5173\u3001\u751a\u81f3\u8d1f\u76f8\u5173\u7684\u60c5\u51b5\uff0c\u6bcf\u6b21\u63d2\u5165\u7684\u6d88\u8017\u5c31\u4f1a\u53d8\u6210 2 \\log N 2 \\log N \u4e86\u3002 \u6700\u7ec8\u6211\u4eec\u51b3\u5b9a\u91c7\u7528\u7684\u7b56\u7565\u662f\uff1a\u4e0d\u662f\u4ece\u4e2d\u95f4\uff0c\u4e5f\u4e0d\u662f\u4ece\u5f00\u5934\uff0c\u4e5f\u4e0d\u662f\u4ece\u672b\u5c3e\uff0c\u800c\u662f \u8bb0\u4f4f\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e \uff0c\u4e0b\u4e00\u6b21\u4ece\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e\u5f00\u59cb\u627e\u3002\u8fd9\u4e2a\u8bb0\u5fc6\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u5c31\u662f\u521a\u521a\u4ee3\u7801\u4e2d\u90a3\u4e2a\u4f4d\u7f6e\u63d0\u793a\u8fed\u4ee3\u5668 hint\u3002 \u8fd9\u6b63\u662f\u6211\u4eec\u4ee3\u7801\u7684\u5199\u6cd5\uff1a hint = tab.insert(hint, {k, v}); \u5b9e\u9645\u4e0a\uff0cinsert \u7684\u6279\u91cf\u63d2\u5165\u7248 insert(arr.begin(), arr.end()) \u5185\u90e8\u5c31\u4f1a\u4f7f\u7528\u8fd9\u79cd\u5e26\u63d0\u793a\u7684\u65b9\u5f0f\uff0c\u9010\u4e2a\u63d2\u5165\u3002 vector> arr;","title":"\u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5"},{"location":"stl_map/#emplace","text":"insert \u7684\u7a76\u6781\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace template pair emplace(Args &&...args); \u867d\u7136\u53d8\u957f\u53c2\u6570\u5217\u8868 Args &&...args \u770b\u8d77\u6765\u5f88\u9177\uff0c\u7136\u800c\u7531\u4e8e map \u7684\u7279\u6b8a\u6027\uff0c\u5176\u5143\u7d20\u7c7b\u578b\u662f pair \uff0c\u800c pair \u7684\u6784\u9020\u51fd\u6570\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\uff0c\u5bfc\u81f4\u5b9e\u9645\u4e0a\u8fd9\u4e2a\u770b\u4f3c\u70ab\u9177\u7684\u53d8\u957f\u53c2\u6570\u5217\u8868\u5f80\u5f80\u53ea\u80fd\u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\uff0c\u56e0\u6b64\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u5b9e\u9645\u4e0a\u53ea\u80fd\u662f\uff1a pair emplace(K k, V v); \u5199\u6cd5\uff1a m.emplace(key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert({key, val}); \u8fd4\u56de\u503c\u8fd8\u662f pair \uff0c\u5176\u610f\u4e49\u548c insert \u4e00\u6837\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002","title":"\u5206\u5974 emplace"},{"location":"stl_map/#emplace_hint","text":"insert \u7684\u5b87\u5b99\u65e0\u654c\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace_hint 1 template iterator emplace_hint(const_iterator pos, Args &&...args); \u5199\u6cd5\uff1a m.emplace_hint(pos, key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert(pos, {key, val}); \u4e4b\u6240\u4ee5\u8981\u5206\u4e24\u4e2a\u51fd\u6570\u540d emplace \u548c emplace_hint \u800c\u4e0d\u662f\u5229\u7528\u91cd\u8f7d\u533a\u5206\uff0c\u662f\u56e0\u4e3a\u76f4\u63a5\u4f20\u5165 pos \u4f1a\u88ab emplace \u5f53\u505a pair \u7684\u6784\u9020\u53c2\u6570\uff0c\u800c\u4e0d\u662f\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u3002 emplace \u5bf9\u5e94\u4e8e\u666e\u901a\u7684 insert(pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u5bf9\u5e94\u4e8e\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert(const_iterator, pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u548c\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u4e00\u6837\uff0c\u662f\u5355\u72ec\u4e00\u4e2a iterator\u3002","title":"emplace_hint"},{"location":"stl_map/#emplace_1","text":"template pair emplace(Args &&...args); emplace \u5bf9\u4e8e set\uff0c\u5143\u7d20\u7c7b\u578b\u662f\u6bd4\u8f83\u5927\u7684\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 set> \uff0c\u53ef\u80fd\u786e\u5b9e\u80fd\u8d77\u5230\u51cf\u5c11\u79fb\u52a8\u6784\u9020\u51fd\u6570\u5f00\u9500\u7684\u4f5c\u7528\u3002 \u4f46\u662f\u8fd9\u4e2a map \u4ed6\u7684\u5143\u7d20\u7c7b\u578b\u4e0d\u662f\u76f4\u63a5\u7684 V \u800c\u662f\u4e00\u4e2a pair\uff0c\u4ed6\u5206\u7684\u662f pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709\u7528\uff0cV \u90e8\u5206\u8fd8\u662f\u4f1a\u9020\u6210\u4e00\u6b21\u989d\u5916\u7684\u79fb\u52a8\u5f00\u9500\uff0c\u6240\u4ee5\u8fd9\u73a9\u610f\u9664\u4e86\u59a8\u788d\u7c7b\u578b\u5b89\u5168\u548c\u53ef\u8bfb\u6027\u4ee5\u5916\uff0c\u6ca1\u6709\u4efb\u4f55\u6536\u76ca\u3002 set \u53ef\u4ee5\u7528 emplace/emplace_hint\u3002 vector \u53ef\u4ee5\u7528 emplace_back\u3002 \u4e0d\u5efa\u8bae\u5728 map \u4e0a\u4f7f\u7528 emplace/emplace_hint\uff0c\u8bf7\u6539\u7528 try_emplace\u3002","title":"emplace \u7684\u539f\u7406\u548c\u4f18\u70b9"},{"location":"stl_map/#try_emplace","text":"emplace \u53ea\u652f\u6301 pair \u7684\u5c31\u5730\u6784\u9020\uff0c\u8fd9\u6709\u4ec0\u4e48\u7528\uff1f\u6211\u4eec\u8981\u7684\u662f pair \u4e2d\u503c\u7c7b\u578b\u7684\u5c31\u5730\u6784\u9020\uff01\u8fd9\u5c31\u662f try_emplace \u7684\u4f5c\u7528\u4e86\uff0c\u4ed6\u5bf9 key \u90e8\u5206\u4f9d\u7136\u662f\u4f20\u7edf\u7684\u79fb\u52a8\uff0c\u53ea\u5bf9 value \u90e8\u5206\u91c7\u7528\u5c31\u5730\u6784\u9020\u3002 \u8fd9\u662f\u89c2\u5bdf\u5230\u5927\u591a\u662f\u503c\u7c7b\u578b\u5f88\u5927\uff0c\u6025\u9700\u5c31\u5730\u6784\u9020\uff0c\u800c\u952e\u7c7b\u578b\u6ca1\u7528\u591a\u5c11\u5c31\u5730\u6784\u9020\u7684\u9700\u6c42\u3002\u4f8b\u5982 map> \u5982\u679c\u60f3\u4e0d\u7528 try_emplace\uff0c\u5b8c\u5168\u57fa\u4e8e emplace \u5b9e\u73b0\u9488\u5bf9\u503c value \u7684\u5c31\u5730\u6784\u9020\u9700\u8981\u7528\u5230 std::piecewise_construct \u548c std::forward_as_tuple\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 insert \u7684\u6258\u9a6c\u65af\u9ec4\u91d1\u5927\u56de\u65cb\u5206\u5974\u7248\uff1atry_emplace\uff08C++17 \u5f15\u5165\uff09 template pair try_emplace(K const &k, Args &&...args); \u5199\u6cd5\uff1a m.try_emplace(key, arg1, arg2, ...); \u4ed6\u7b49\u4ef7\u4e8e\uff1a m.insert({key, V(arg1, arg2, ...)}); \u540e\u9762\u7684\u53d8\u957f\u53c2\u6570\u4e5f\u53ef\u4ee5\u5b8c\u5168\u6ca1\u6709\uff1a m.try_emplace(key); \u4ed6\u7b49\u4ef7\u4e8e\u8c03\u7528 V \u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a m.insert({key, V()}); \u7531\u4e8e emplace \u5b9e\u5728\u662f\u61a8\u61a8\uff0c\u4ed6\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u7684\u662f pair\uff0c\u7136\u800c pair \u7684\u6784\u9020\u51fd\u6570\u6b63\u5e38\u4e0d\u5c31\u662f\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\u5417\uff0c\u53d8\u957f\u6ca1\u6709\u7528\u3002\u5b9e\u9645\u6709\u7528\u7684\u5f80\u5f80\u662f\u6211\u4eec\u5e0c\u671b\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u503c\u7c7b\u578b V\uff0c\u5bf9 K \u90e8\u5206\u5e76\u4e0d\u5173\u7cfb\u3002\u56e0\u6b64 C++17 \u5f15\u5165\u4e86 try_emplace\uff0c\u5176\u952e\u90e8\u5206\u4fdd\u6301 K const & \uff0c\u503c\u90e8\u5206\u91c7\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u3002 \u6211\u7684\u8bc4\u4ef7\u662f\uff1a\u8fd9\u4e2a\u6bd4 emplace \u5b9e\u7528\u591a\u4e86\uff0c\u5982\u679c\u8981\u4e0e vector \u7684 emplace_back \u5bf9\u6807\uff0c\u90a3\u4e48 map \u4e0e\u4e4b\u5bf9\u5e94\u7684\u4e00\u5b9a\u662f try_emplace\u3002\u540c\u5b66\u4eec\u5982\u679c\u8981\u5206\u5974\u7684\u8bdd\u8fd8\u662f\u5efa\u8bae\u7528 try_emplace\u3002","title":"try_emplace \u66f4\u597d"},{"location":"stl_map/#try_emplace_1","text":"insert \u7c7b\u51fd\u6570\u603b\u662f\u4e0d\u53ef\u907f\u514d\u7684\u9700\u8981\u79fb\u52a8\u6784\u9020\uff1a\u5148\u5728\u51fd\u6570\u4e2d\u6784\u9020\u51fa\u4e34\u65f6\u5bf9\u8c61\uff0c\u7136\u540e\u6784\u9020\u5230\u771f\u6b63\u7684 pair \u4e0a\u3002 \u800c try_emplace \u53ef\u4ee5\u5141\u8bb8\u4f60\u5c31\u5730\u6784\u9020\u503c\u5bf9\u8c61\uff0c\u907f\u514d\u79fb\u52a8\u9020\u6210\u5f00\u9500\u3002 try_emplace \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u952e\uff0c\u7b2c\u4e8c\u4e2a\u5f00\u59cb\u662f\u4f20\u7ed9\u6784\u9020\u51fd\u6570\u7684\u53c2\u6570\uff0c\u5982\u53ea\u6709\u7b2c\u4e00\u4e2a\u53c2\u6570\u5219\u662f\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570\u3002 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(int i) { printf(\"MyClass(int)\\n\"); } MyClass(const char *p, float x) { printf(\"MyClass(const char *, float)\\n\"); } }; map m; m.try_emplace(\"key\"); // MyClass() m.try_emplace(\"key\", 42); // MyClass(int) m.try_emplace(\"key\", \"hell\", 3.14f); // MyClass(const char *, float) // \u7b49\u4ef7\u4e8e\uff1a m.insert({\"key\", MyClass()}); // MyClass() m.insert({\"key\", MyClass(42)}); // MyClass(int) m.insert({\"key\", MyClass(\"hell\", 3.14f)}); // MyClass(const char *, float) \u5bf9\u4e8e\u79fb\u52a8\u5f00\u9500\u8f83\u5927\u7684\u7c7b\u578b\uff08\u4f8b\u5982 array \uff09\uff0ctry_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff1b\u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u503c\u7c7b\u578b\uff0c\u5c31\u5fc5\u987b\u4f7f\u7528 try_emplace \u4e86\u3002","title":"try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01"},{"location":"stl_map/#try_emplace_2","text":"// \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u6548\u679c\u7b49\u4ef7\uff0c\u53ea\u6709\u6027\u80fd\u4e0d\u540c m.try_emplace(key, arg1, arg2, ...); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 m.insert({key, V(arg1, arg2, ...)}); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 2\u6b21\u79fb\u52a8\u51fd\u6570 m.insert(make_pair(key, V(arg1, arg2, ...))); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 3\u6b21\u79fb\u52a8\u51fd\u6570 \u4f46\u662f\u7531\u4e8e try_emplace \u662f\u7528\u5706\u62ec\u53f7\u5e2e\u4f60\u8c03\u7528\u7684\u6784\u9020\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u3002 \u5bfc\u81f4\u4f60\u8981\u4e48\u65e0\u6cd5\u7701\u7565\u7c7b\u578b\uff0c\u8981\u4e48\u4f60\u5f97\u624b\u52a8\u5b9a\u4e49\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff1a struct Student { // \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u82b1\u62ec\u53f7\u8bed\u6cd5\u8fdb\u884c\u521d\u59cb\u5316 string sex; int age; }; map m; m.insert({\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}}); // OK: insert \u53c2\u6570\u7c7b\u578b\u5df2\u77e5\uff0cStudent \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff0c\u4f46\u662f\u4f1a\u9020\u6210 2 \u6b21\u79fb\u52a8 m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // ERROR: \u4e0d\u5b58\u5728\u6784\u9020\u51fd\u6570 Student(string, int)\uff1bC++20 \u5f00\u59cb\u5219 OK: C++20 \u8d77\u805a\u5408\u521d\u59cb\u5316\u540c\u65f6\u652f\u6301\u82b1\u62ec\u53f7\u548c\u5706\u62ec\u53f7 m.try_emplace(\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}); // ERROR: \u53c2\u6570\u7c7b\u578b\u662f\u6a21\u677f\u7c7b\u578b\uff0c\u672a\u77e5\uff0c\u65e0\u6cd5\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b m.try_emplace(\"\u5f6d\u4e8e\u658c\", Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: \u660e\u786e\u6307\u5b9a\u7c7b\u578b\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff1b\u4f46\u8fd9\u6837\u53c8\u4f1a\u9020\u6210 1 \u6b21\u79fb\u52a8\uff0c\u5931\u53bb\u4e86 try_emplace \u907f\u514d\u79fb\u52a8\u7684\u610f\u4e49 \u6b64\u5916\u8fd8\u8981\u6ce8\u610f\u4e0d\u8bba insert\u3001emplace\u3001emplace_hint\u3001try_emplace\uff0c\u90fd\u662f\u4e00\u4e2a\u5c3f\u6027\uff1a\u952e\u51b2\u7a81\u65f6\u4e0d\u4f1a\u8986\u76d6\u5df2\u6709\u5143\u7d20\u3002 \u5982\u679c\u9700\u8981\u8986\u76d6\u6027\u7684\u63d2\u5165\uff0c\u8fd8\u5f97\u4e56\u4e56\u7528 [] \u6216\u8005 insert_or_assign \u51fd\u6570\u3002 \u7531\u4e8e try_emplace \u91cc\u5199\u6b7b\u4e86\u5706\u62ec\u53f7\uff0c\u6211\u4eec\u53ea\u597d\u624b\u52a8\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\u624d\u80fd\u52b3\u9a7e try_emplace \u5c31\u5730\u6784\u9020\u3002 struct Student { string sex; int age; Student(string sex, int age) : sex(std::move(sex)) , age(age) {} // \u7531\u4e8e try_emplace \u4f1a\u5c31\u5730\u6784\u9020\u5bf9\u8c61\uff0c\u5176\u503c\u7c7b\u578b\u53ef\u4ee5\u6ca1\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u800c insert \u4f1a\u51fa\u9519 Student(Student &&) = delete; Student &operator=(Student &&) = delete; Student(Student const &) = delete; Student &operator=(Student const &) = delete; }; map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570 Student(string, int) \u5c31\u5730\u6784\u9020\u5bf9\u8c61 m.insert({\"\u5f6d\u4e8e\u658c\", Student(\"\u81ea\u5b9a\u4e49\", 22)}); // ERROR: insert \u9700\u8981\u79fb\u52a8 Student \u800c Student \u7684\u79fb\u52a8\u88ab delete \u4e86\uff01","title":"\u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9"},{"location":"stl_map/#_38","text":"\u65e0\u6784\u9020\u51fd\u6570\u65f6\uff0cC++11 \u652f\u6301\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff08\u5b98\u65b9\u540d: \u805a\u5408\u521d\u59cb\u5316 1 \uff09\uff0cC++20 \u5f00\u59cb\u805a\u5408\u521d\u59cb\u5316\u4e5f\u80fd\u7528\u5706\u62ec\u53f7\uff08\u6240\u4ee5 emplace / try_emplace \u8fd9\u7c7b\u51fd\u6570\u53d8\u5f97\u66f4\u597d\u7528\u4e86\uff09\uff1a struct Student { string sex; int age; }; auto s1 = Student{\"\u81ea\u5b9a\u4e49\", 22}; // C++11 \u8d77 OK: \u65e0\u6784\u9020\u51fd\u6570\u65f6\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5 auto s2 = Student(\"\u81ea\u5b9a\u4e49\", 22); // C++20 \u8d77 OK: \u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u751f\u6210\u5706\u62ec\u53f7\u6784\u9020\u51fd\u6570 Student(string, int) \u548c\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u65f6\u4e00\u6837\uff0c\u53ef\u4ee5\u7701\u7565\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u8fd9\u90e8\u5206\u53c2\u6570\u4f1a\u7528\u4ed6\u4eec\u7684\u9ed8\u8ba4\u503c\uff1a auto s1 = Student(\"\u81ea\u5b9a\u4e49\", 22); // OK: sex \u4e3a \"\u81ea\u5b9a\u4e49\"\uff0cage \u4e3a 22 auto s2 = Student(\"\u81ea\u5b9a\u4e49\"); // OK: \u7701\u7565 age \u81ea\u52a8\u4e3a 0 auto s3 = Student(); // OK: \u7701\u7565 sex \u81ea\u52a8\u4e3a \"\" \u4e0d\u8fc7\u4ed6\u548c\u82b1\u62ec\u53f7\u4e0d\u4e00\u6837\u7684\u662f\uff0c\u4f5c\u4e3a\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\u7684\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u7c7b\u578b\u540d\u4e0d\u80fd\u7701\u7565\u4e86\uff1a void func(Student const &stu); // \u5df2\u77e5\u51fd\u6570\u7b7e\u540d func(Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5 func({\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5\uff0c\u5df2\u77e5\u51fd\u6570\u5177\u6709\u552f\u4e00\u91cd\u8f7d\u7684\u60c5\u51b5\u4e0b\u7c7b\u540d\u53ef\u4ee5\u7701\u7565 func(Student(\"\u81ea\u5b9a\u4e49\", 22)); // OK: C++20 \u8bed\u6cd5 func((\"\u81ea\u5b9a\u4e49\", 22)); // ERROR: \u65e0\u6cd5\u4ece int \u8f6c\u6362\u4e3a Student","title":"\u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316"},{"location":"stl_map/#c20","text":"\u6240\u4ee5\u73b0\u5728 try_emplace \u4e5f\u53ef\u4ee5\u5c31\u5730\u6784\u9020\u65e0\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u4e86\uff1a map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 22} m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 0} m.try_emplace(\"\u5f6d\u4e8e\u658c\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\", 0} \u65b9\u4fbf\uff01 \u5173\u4e8e\u66f4\u591a C++20 \u7684\u805a\u5408\u521d\u59cb\u5316\u5c0f\u77e5\u8bc6\uff0c\u53ef\u4ee5\u770b\u8fd9\u671f CppCon \u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=flLNi0aejew \u4e3a\u65b9\u4fbf\u4f60\u5728\u6bd4\u7ad9\u641c\u7d22\u642c\u8fd0\uff0c\u4ed6\u7684\u6807\u9898\u662f\uff1aLightning Talk: Direct Aggregate Initialisation - Timur Doumler - CppCon 2021","title":"C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9"},{"location":"stl_map/#_39","text":"struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(MyClass &&) noexcept { printf(\"MyClass(MyClass &&)\\n\"); } MyClass &operator=(MyClass &&) noexcept { printf(\"MyClass &operator=(MyClass &&)\\n\"); return *this; } }; map tab; printf(\"insert\u7684\u5f00\u9500:\\n\"); tab.insert({1, MyClass()}); printf(\"try_emplace\u7684\u5f00\u9500:\\n\"); tab.try_emplace(2); // try_emplace \u53ea\u6709\u4e00\u4e2a key \u53c2\u6570\u65f6\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570 MyClass() insert \u8c03\u7528\u4e86\u4e24\u6b21\u79fb\u52a8\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 insert \u628a\u53c2\u6570 pair \u79fb\u8fdb\u7ea2\u9ed1\u6811\u8282\u70b9\u91cc\u3002 \u800c try_emplace \u5185\u90e8\u4f7f\u7528\u4e86\u73b0\u4ee3 C++ \u7684\u5c31\u5730\u6784\u9020\uff08placement new\uff09\uff0c\u76f4\u63a5\u5728\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u5185\u5b58\u4e2d\u6784\u9020 MyClass\uff0c\u65e0\u9700\u53cd\u590d\u79fb\u52a8\uff0c\u5bf9\u4e8e\u5c3a\u5bf8\u8f83\u5927\u7684\u503c\u7c7b\u578b\u4f1a\u66f4\u9ad8\u6548\u3002 insert\u7684\u5f00\u9500: MyClass() MyClass(MyClass &&) MyClass(MyClass &&) try_emplace\u7684\u5f00\u9500: MyClass()","title":"\u8c03\u7528\u5f00\u9500\u5206\u6790"},{"location":"stl_map/#try_emplace_3","text":"\u63d0\u5347\u4e86 1.42 \u500d\u6027\u80fd\uff0c\u4e0d\u80fd\u8bf4\u662f\u60ca\u5929\u5730\u6ce3\u9b3c\u795e\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u804a\u80dc\u4e8e\u65e0\u4e86\u3002\u8fd9\u91cc\u7684\u503c\u7c7b\u578b string \u53ea\u6709 32 \u5b57\u8282\u8fd8\u4e0d\u591f\u660e\u663e\uff0c\u53ef\u80fd\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\u4f1a\u6709\u660e\u663e\u7684\u4f18\u52bf\u3002\u8fd9\u79cd\u4f18\u5316\u7684\u7406\u8bba\u4e0a\u9650\u662f 3 \u500d\uff0c\u6700\u591a\u80fd\u4ece try_emplace \u83b7\u5f97 3 \u500d\u6027\u80fd\u63d0\u5347\u3002 template static void test_insert(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) 2\u6b21string(string &&) tab.insert({i, \"hello\"}); } } template static void test_try_emplace(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) tab.try_emplace(i, \"hello\"); } } int main() { for (int i = 0; i < 1000; i++) { map tab; test_insert(tab); doNotOptimize(tab); } for (int i = 0; i < 1000; i++) { map tab; test_try_emplace(tab); doNotOptimize(tab); } printScopeProfiler(); } avg | min | max | total | cnt | tag 39| 34| 218| 39927| 1000| test_insert 28| 27| 91| 28181| 1000| test_try_emplace \u5982\u679c\u6539\u6210\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\uff0c\u53ef\u4ee5\u63d0\u5347 2.3 \u500d\u3002 struct MyClass { int arr[4096]; }; avg | min | max | total | cnt | tag 1312| 1193| 18298| 1312871| 1000| test_insert 573| 537| 1064| 573965| 1000| test_try_emplace","title":"try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b"},{"location":"stl_map/#try_emplace_4","text":"insert \u7684\u70ab\u5f69\u4e2d\u4e8c\u6447\u6446\u6df7\u6c8c\u5927\u9b54\u738b\u5206\u5974\u7248\uff1a\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace template iterator try_emplace(const_iterator pos, K const &k, Args &&...args); \u5199\u6cd5\uff1a hint = m.try_emplace(hint, key, arg1, arg2, ...); \u7b49\u4ef7\u4e8e\uff1a hint = m.insert(hint, {key, V(arg1, arg2, ...)}); \u8fd9\u6b21\u4e0d\u9700\u8981\u518d\u5206\u4e00\u4e2a\u4ec0\u4e48 try_emplace_hint \u51fa\u6765\u4e86\uff0c\u662f\u56e0\u4e3a try_emplace \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f K \u7c7b\u578b\u800c\u4e0d\u662f\u6cdb\u578b\uff0c\u4e0d\u53ef\u80fd\u548c const_iterator \u7c7b\u578b\u6df7\u6dc6\uff0c\u56e0\u6b64 C++ \u59d4\u5458\u4f1a\u6700\u7ec8\u51b3\u5b9a\u76f4\u63a5\u5171\u7528\u540c\u4e00\u4e2a\u540d\u5b57\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u91cd\u8f7d\u4e86\u3002","title":"\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace"},{"location":"stl_map/#emplace_2","text":"\u603b\u7ed3\uff0c\u5982\u4f55\u7528 emplace \u5bb6\u65cf\u4f18\u5316\uff1f\u5206\u76f4\u63a5\u63d2\u5165\u548c\u5e26\u63d0\u793a\u63d2\u5165\u4e24\u79cd\u7528\u6cd5\uff0c\u548c\u4f60\u662f\u5426\u9700\u8981\u9ad8\u6027\u80fd\u4e24\u79cd\u9700\u6c42\uff0c\u8fd9\u91cc\u6807\u4e86\u201c\u63a8\u8350\u201d\u7684\u662f\u5efa\u8bae\u91c7\u7528\u7684\uff1a // \u76f4\u63a5\u63d2\u5165\u7248 m.insert({\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 m.try_emplace(\"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 m.emplace(\"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 m.emplace(std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 // \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7248 hint = m.insert(hint, {\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 hint = m.try_emplace(hint, \"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 hint = m.emplace_hint(hint, \"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 hint = m.emplace_hint(hint, std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5","title":"emplace \u5bb6\u65cf\u603b\u7ed3"},{"location":"stl_map/#map-raii","text":"\u68a6\u5e7b\u8054\u52a8\uff1amap \u5bb9\u5668\u4e0e RAII \u7684\u53cc\u5411\u5954\u8d74 \u5982\u679c map \u4e2d\u5143\u7d20\u7684\u503c\u7c7b\u578b\u662f RAII \u7c7b\u578b\uff0c\u5176\u6790\u6784\u51fd\u6570\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u8c03\u7528\u3002 map \u88ab\u79fb\u52a8\u65f6\uff0c\u4e0d\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u79fb\u52a8\u51fd\u6570\uff0c\u56e0\u4e3a map \u91cc\u53ea\u5b58\u7740\u6307\u5411\u7ea2\u9ed1\u6811\u6839\u8282\u70b9\u7684\u6307\u9488\uff0c\u53ea\u9700\u6307\u9488\u79fb\u52a8\u5373\u53ef\u3002 map \u88ab\u62f7\u8d1d\u65f6\uff0c\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u62f7\u8d1d\u51fd\u6570\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u5219 map \u7684\u62f7\u8d1d\u4e5f\u4f1a\u88ab\u7981\u7528\uff08delete\uff09\u6389\u3002 map \u88ab\u6790\u6784\u65f6\uff0c\u5176\u6240\u6709\u5143\u7d20\u90fd\u4f1a\u88ab\u6790\u6784\u3002","title":"map \u4e0e RAII"},{"location":"stl_map/#1","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\\n\", i); } RAII &operator=(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\u8d4b\u503c\\n\", i); return *this; } ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e","title":"\u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8"},{"location":"stl_map/#2","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; RAII &operator=(RAII &&) = delete; RAII(RAII const &) = delete; RAII &operator=(RAII const &) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u65b0\u624b\u5b9a\u4e49 RAII \u7c7b\u65f6\uff0c\u8bb0\u5f97\u628a\u79fb\u52a8\u548c\u62f7\u8d1d 4 \u4e2a\u51fd\u6570\u5168\u90e8\u5220\u9664\u3002\u6ca1\u9519\uff0c \u79fb\u52a8\u4e5f\u8981\u5220\u9664 \uff0c\u5f88\u591a\u65b0\u624b\u4f1a\u89c9\u5f97\u8d44\u6e90\u7c7b\u5e94\u8be5\u53ef\u4ee5\u79fb\u52a8\u7684\u5440\uff1f\u8981\u662f\u60f3\u4fdd\u7559\u79fb\u52a8\uff0c\u5c31\u5f97\u9884\u7559\u4e00\u4e2a i == 0 \u7684\u7a7a\u72b6\u6001\uff0c\u90a3\u79cd\u5904\u7406\u5f88\u590d\u6742\u7684\u3002\u603b\u4e4b\u4e00\u65e6\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5168\u90e8 4 \u4e2a\u51fd\u6570\u90fd\u5f97\u5220\u9664\uff0c\u9664\u975e\u4f60\u6709\u76f8\u5173\u7ecf\u9a8c\u3002\u53c2\u89c1 C++ \u751f\u547d\u5468\u671f\u4e0e\u6790\u6784\u51fd\u6570\u4e13\u9898 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u8fd9\u65f6\u5c31\u4f53\u73b0\u51fa try_emplace \u7684\u597d\u5904\u4e86\uff1a\u503c\u7c7b\u578b\u4e0d\u9700\u8981\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\u4e5f\u53ef\u4ee5\u63d2\u5165\u3002","title":"\u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8"},{"location":"stl_map/#_40","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u5269\u4e0b 3 \u4e2a\uff0c\u8fd9\u662f\u56e0\u4e3a\u770b\u5230\u4f60\u7528\u4e86 && \u5c31\u77e5\u9053\u4f60\u662f\u61c2 C++11 \u7684\uff0c\u6240\u4ee5\u4e0d\u7528\u7167\u987e C++98 \u517c\u5bb9\u6027\u4fdd\u7559\u70e6\u4eba\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u5220\u4e86\uff0c\u8fd9\u662f\u4e2a\u6807\u51c6\uff0c\u6240\u6709 C++ \u7f16\u8bd1\u5668\u90fd\u662f\u8fd9\u6837\u7684\uff08\u8981\u6211\u8bf4\uff0c\u5efa\u8bae\u6539\u6210\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\u5c31\u81ea\u52a8\u5220\u5168 4 \u4e2a\u51fd\u6570\uff0c\u53ef\u60dc\u6807\u51c6\u59d4\u5458\u4f1a\u8981\u7167\u987e\u517c\u5bb9\u6027\u2026\uff09 \u4ee5\u540e RAII \u7c7b\u53ea\u9700\u8981\u4e00\u884c C(C &&) = delete \u5c31\u591f\u4e86\u3002 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e","title":"\u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570"},{"location":"stl_map/#_41","text":"\u5982\u679c\u4f60\u60f3\u7528\u66f4\u53ef\u8bfb\u7684 insert\uff0cRAII \u8d44\u6e90\u7c7b\u53c8\u4e0d\u652f\u6301\u79fb\u52a8\uff0c\u53ef\u4ee5\u7528 unique_ptr \u5305\u88c5\u4e00\u4e0b\uff1a ```cpp int main() { { map> m; m.insert(\"\u8d44\u6e901\u53f7\", std::make_unique(1)); m.insert(\"\u8d44\u6e902\u53f7\", std::make_unique(2)); m.erase(\"\u8d44\u6e901\u53f7\"); m.insert(\"\u8d44\u6e903\u53f7\", std::make_unique(3)); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; }","title":"\u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406"},{"location":"stl_map/#_42","text":"\u5bf9\u4e8e\u5f88\u5927\u7684 V \u7c7b\u578b\uff0c\u4e5f\u53ef\u4ee5\u6539\u7528 map> \u907f\u514d\u53cd\u590d\u79fb\u52a8\u5143\u7d20\u672c\u4f53\u3002\uff08\u7528\u5728\u9700\u8981\u53cd\u590d\u6269\u5bb9\u7684 vector \u4e2d\u4e5f\u6709\u5947\u6548\uff09 \u56e0\u4e3a\u5305\u62ec map \u5728\u5185\u7684\u6240\u6709\u5bb9\u5668\u90fd\u5b8c\u7f8e\u652f\u6301 RAII \u7c7b\u578b\uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u7528\u667a\u80fd\u6307\u9488\u4f5c\u4e3a\u8fd9\u4e9b\u5bb9\u5668\u7684\u5143\u7d20\u3002 struct MyData { int value; // \u5047\u8bbe\u8fd9\u4e2a\u5f88\u5927 explicit MyData(int value_) : value(value_) {} }; map> m; m.insert({\"answer\", make_unique(42)}); // \u53ea\u6709 8 \u5b57\u8282\u7684 unique_ptr \u88ab\u79fb\u52a8 2 \u6b21 m.insert({\"fuck\", make_unique(985)}); print(m.at(\"answer\")->value); // 42 // \u2191\u7b49\u4ef7\u4e8e\uff1aprint((*m.at(\"answer\")).value); map> \u4e2d\uff0c\u667a\u80fd\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u91ca\u653e\u3002 map \u4e2d\uff0cC \u8bed\u8a00\u539f\u59cb\u6307\u9488\u4e0d\u5177\u5907 RAII \u529f\u80fd\uff0c\u9664\u975e\u8be5\u6307\u9488\u88ab\u5176\u4ed6\u667a\u80fd\u6307\u9488\u6253\u7406\u7740\uff0c\u6216\u8005\u7528\u6237\u5220\u9664\u5143\u7d20\u4e4b\u524d\u624b\u52a8 delete\uff0c\u5426\u5219\u5f53\u5143\u7d20\u5220\u9664\u65f6\u5185\u5b58\u4f1a\u6cc4\u9732\uff01 \u6211\u63a8\u8350\u5b8c\u5168\u91c7\u7528\u667a\u80fd\u6307\u9488\u6765\u81ea\u52a8\u7ba1\u7406\u5185\u5b58\uff0c\u667a\u80fd\u6307\u9488\u548c\u540c\u6837\u7b26\u5408 RAII \u601d\u60f3\u7684\u5404\u5927\u5bb9\u5668\u4e5f\u662f\u76f8\u6027\u5f88\u597d\u7684\u3002 \u5982\u679c\u9700\u8981\u6d45\u62f7\u8d1d\u7684\u8bdd\uff0c\u5219\u53ef\u4ee5\u6539\u7528 map> \uff0c\u5c0f\u5f6d\u8001\u5e08\u5728\u4ed6\u7684 Zeno \u9879\u76ee\u4e2d\u5c31\u662f\u8fd9\u6837\u7528\u7684\u3002","title":"\u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8"},{"location":"stl_map/#_43","text":"","title":"\u589e\u5220\u6539\u67e5\u603b\u7ed3"},{"location":"stl_map/#_44","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.insert(make_pair(key, val)) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++98 \ud83d\udca9 m.insert({key, val}) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \u2764 m.emplace(key, val) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \ud83d\udca9 m.try_emplace(key, valargs...) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++17 \ud83d\udca3 m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 C++17 \u2764 m[key] = val \u63d2\u5165\u6216\u8986\u76d6 C++98 \ud83d\udca3 m.erase(key) \u5220\u9664\u6307\u5b9a\u5143\u7d20 C++98 \u2764","title":"\u589e\u5220"},{"location":"stl_map/#_45","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.at(key) \u627e\u4e0d\u5230\u5219\u51fa\u9519\uff0c\u627e\u5230\u5219\u8fd4\u56de\u5f15\u7528 C++98 \u2764 m[key] \u627e\u4e0d\u5230\u5219\u81ea\u52a8\u521b\u5efa 0 \u503c\uff0c\u8fd4\u56de\u5f15\u7528 C++98 \ud83d\udca3 myutils::map_get(m, key, defl) \u627e\u4e0d\u5230\u5219\u8fd4\u56de\u9ed8\u8ba4\u503c C++98 \u2764 m.find(key) == m.end() \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \ud83d\udca3 m.count(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \u2764 m.contains(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++20 \ud83d\udca9","title":"\u6539\u67e5"},{"location":"stl_map/#_46","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 map m = {{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 auto m = map{{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \ud83d\udca9 func({{k1, v1}, {k2, v2}}) \u7ed9\u51fd\u6570\u53c2\u6570\u4f20\u5165\u4e00\u4e2a map C++11 \u2764 m = {{k1, v1}, {k2, v2}} \u91cd\u7f6e\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 m.clear() \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++98 \u2764 m = {} \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++11 \ud83d\udca3","title":"\u521d\u59cb\u5316"},{"location":"stl_map/#_47","text":"","title":"\u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3"},{"location":"stl_map/#extract","text":"C++17 \u65b0\u589e\u7684 extract \u51fd\u6570 1 \u53ef\u4ee5\u201c\u5265\u79bb\u201d\u51fa\u5355\u4e2a\u8282\u70b9\uff1a node_type extract(K const &key); node_type extract(const_iterator pos); auto node = m.extract(\"fuck\"); auto &k = node.key(); // \u952e\uff08\u5f15\u7528\uff09 auto &v = node.mapped(); // \u503c\uff08\u5f15\u7528\uff09 \u5176\u529f\u80fd\u4e0e erase \u7c7b\u4f3c\uff0c\u90fd\u4f1a\u5c06\u5143\u7d20\u4ece map \u4e2d\u5220\u9664\uff0c\u4f46 extract \u53ea\u662f\u628a\u8282\u70b9\u4ece map \u4e2d\u79fb\u8d70\uff0c\u5e76\u4e0d\u4f1a\u76f4\u63a5\u9500\u6bc1\u8282\u70b9\u3002 extract \u4f1a\u8fd4\u56de\u8fd9\u4e2a\u521a\u88ab\u201c\u5265\u79bb\u201d\u51fa\u6765\u8282\u70b9\u7684\u53e5\u67c4\uff0c\u7c7b\u578b\u4e3a node_type\uff0c\u8282\u70b9\u7684\u751f\u6740\u5927\u6743\u5c31\u8fd9\u6837\u8fd4\u56de\u7ed9\u4e86\u7528\u6237\u6765\u5904\u7f6e\u3002 node_type \u662f\u6307\u5411\u6e38\u79bb\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff0c\u79f0\u4e3a\u8282\u70b9\u53e5\u67c4 2 \u3002\u53ea\u53ef\u79fb\u52a8\u4e0d\u53ef\u62f7\u8d1d\uff0c\u7c7b\u4f3c\u4e00\u4e2a\u6307\u5411\u8282\u70b9\u7684 unique_ptr\u3002 \u5f53\u8c03\u7528 extract(key) \u65f6\u4f1a\u628a key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u7ea2\u9ed1\u6811\u8282\u70b9\u201c\u8131\u79bb\u201d\u51fa\u6765\u2014\u2014\u4e0d\u662f\u76f4\u63a5\u91ca\u653e\u8282\u70b9\u5185\u5b58\u5e76\u9500\u6bc1\u952e\u503c\u5bf9\u8c61\uff0c\u800c\u662f\u628a\u5220\u9664\u7684\u8282\u70b9\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u8c03\u7528\u8005\uff0c\u4ee5\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488 node_type \u7684\u5f62\u5f0f\u3002 \u8c03\u7528 extract \u540e\uff0c\u8282\u70b9\u53e5\u67c4\u6307\u5411\u7684\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u5df2\u7ecf\u4ece map \u4e2d\u79fb\u9664\uff08\u5176 left\u3001right\u3001parent \u7b49\u6307\u9488\u4e3a NULL\uff09\uff0c\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\u3002 \u8282\u70b9\u4e2d\u4e0d\u4ec5\u5b58\u50a8\u7740\u6211\u4eec\u611f\u5174\u8da3\u7684\u952e\u548c\u503c\uff0c\u8fd8\u6709 left\u3001right\u3001parent\u3001color \u7b49\u7528\u4e8e\u7ef4\u62a4\u6570\u636e\u7ed3\u6784\u7684\u6210\u5458\u53d8\u91cf\uff0c\u5bf9\u7528\u6237\u4e0d\u53ef\u89c1\u3002 \u53ea\u662f\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u7ef4\u6301\u7740\u8282\u70b9\u7684\u751f\u547d\u5468\u671f\uff0c\u4fdd\u62a4\u7740\u952e key() \u548c\u503c mapped() \u6ca1\u6709\u88ab\u9500\u6bc1\uff0c\u5185\u5b58\u6ca1\u6709\u88ab\u91ca\u653e\u3002 \u5982\u679c\u8c03\u7528\u8005\u63a5\u4e0b\u6765\u4e0d\u505a\u64cd\u4f5c\uff0c\u90a3\u4e48\u5f53\u79bb\u5f00\u8c03\u7528\u8005\u6240\u5728\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u8fd9\u4e2a\u7279\u6b8a\u7684 unique_ptr \u4f1a\u81ea\u52a8\u91ca\u653e\u5176\u6307\u5411\u8282\u70b9\u3002 \u5bf9\u4e8e\u7b2c\u4e00\u4e2a\u6309\u952e\u53d6\u51fa\u8282\u70b9\u53e5\u67c4\u7684 extract \u91cd\u8f7d\uff1a\u5982\u679c\u952e\u503c\u4e0d\u5b58\u5728\uff0c\u90a3\u4e48 extract \u4f1a\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u7684\u7a7a\u8282\u70b9\u53e5\u67c4\uff0c\u7c7b\u4f3c\u4e8e\u7a7a\u6307\u9488\u3002\u53ef\u4ee5\u901a\u8fc7 (bool)node \u6765\u5224\u65ad\u4e00\u4e2a\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u7a7a\u3002 \u5bf9\u4e8e\u7b2c\u4e8c\u4e2a\u6309\u8fed\u4ee3\u5668\u53d6\u51fa\u53e5\u67c4\u7684 extract\uff1a\u603b\u662f\u6210\u529f\uff0c\u56e0\u4e3a\u65e2\u7136\u4f60\u5df2\u7ecf\u83b7\u5f97\u4e86\u8fed\u4ee3\u5668\uff0c\u80af\u5b9a\u662f find \u83b7\u5f97\u7684\uff0c\u800c find \u627e\u4e0d\u5230\u8fd4\u56de\u7684 end \u4f20\u5165 extract \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u6b63\u5982 erase \u8fed\u4ee3\u5668\u7248\u91cd\u8f7d erase(it) \u603b\u662f\u6210\u529f\u4e00\u6837\u3002","title":"extract"},{"location":"stl_map/#_48","text":"\u8c03\u7528\u8005\u7a0d\u540e\u53ef\u4ee5\u76f4\u63a5\u9500\u6bc1\u8fd9\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff1a { auto node = m.extract(\"fuck\"); print(node.key(), node.mapped()); } // node \u5728\u6b64\u81ea\u52a8\u9500\u6bc1 \u4e5f\u53ef\u4ee5\u505a\u4e00\u4e9b\u4fee\u6539\u540e\uff08\u4f8b\u5982\u4fee\u6539\u952e\u503c\uff09\uff0c\u7a0d\u540e\u91cd\u65b0\u7528 insert(node) \u91cd\u65b0\u628a\u4ed6\u63d2\u5165\u56de\u53bb\uff1a auto node = m.extract(\"fuck\"); node.key() = \"love\"; m.insert(std::move(node)); \u8fc7\u53bb\uff0c\u901a\u8fc7\u8fed\u4ee3\u5668\u6765\u4fee\u6539\u952e\u503c\u662f\u4e0d\u5141\u8bb8\u7684\uff1a map m; auto it = m.find(\"fuck\"); assert(it != m.end()); // *it \u662f pair it->first = \"love\"; // \u9519\u8bef\uff01first \u662f const string \u7c7b\u578b m.insert(*it); \u56e0\u4e3a\u76f4\u63a5\u4fee\u6539\u5728 map \u91cc\u9762\u7684\u4e00\u4e2a\u8282\u70b9\u7684\u952e\uff0c\u4f1a\u5bfc\u81f4\u6392\u5e8f\u5931\u6548\uff0c\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u3002\u800c extract \u53d6\u51fa\u6765\u7684\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u53ef\u4ee5\u4fee\u6539 .key() \uff0c\u4e0d\u4f1a\u5f71\u54cd\u4efb\u4f55\u7ea2\u9ed1\u6811\u7684\u987a\u5e8f\uff0c\u4ed6\u5df2\u7ecf\u4e0d\u5728\u6811\u91cc\u9762\u4e86\u3002 \u6216\u8005\u63d2\u5165\u5230\u53e6\u4e00\u4e2a\u4e0d\u540c\u7684 map \u5bf9\u8c61\uff08\u4f46\u952e\u548c\u503c\u7c7b\u578b\u76f8\u540c\uff09\u91cc\uff1a // \u4ece m1 \u632a\u5230 m2 auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); \u4f18\u70b9\u5728\u4e8e\uff0cextract \u548c\u8282\u70b9\u7248 insert \u4e0d\u6d89\u53ca\u5185\u5b58\u7684\u91cd\u65b0\u5206\u914d\u4e0e\u91ca\u653e\uff0c\u4e0d\u6d89\u53ca\u5143\u7d20\u7c7b\u578b\u7684\u79fb\u52a8\uff08\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e\u667a\u80fd\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u7684\u79fb\u52a8\u5e76\u4e0d\u4f1a\u5bfc\u81f4\u5176\u6307\u5411\u5bf9\u8c61\u7684\u79fb\u52a8\uff09\uff0c\u6240\u4ee5\u4f1a\u6bd4\u4e0b\u9762\u8fd9\u79cd\u4f20\u7edf\u5199\u6cd5\u66f4\u9ad8\u6548\uff1a // \u4ece m1 \u632a\u5230 m2\uff1a\u4f20\u7edf\u5199\u6cd5 if (m1.count(\"fuck\")) { auto value = std::move(m1.at(\"fuck\")); m2[\"fuck\"] = std::move(value); m1.erase(it); } \u4e0d\u7528 auto \u5b8c\u6574\u5199\u51fa\u5168\u90e8\u7c7b\u578b\u7684\u5f62\u5f0f\uff08\u53e4\u4ee3 C++98 \u4f5c\u98ce\uff09\uff1a typename map::node_type node = m.extract(\"fuck\"); K &k = node.key(); V &v = node.mapped(); set \u4e5f\u6709 extract \u51fd\u6570\uff0c\u5176\u8282\u70b9\u53e5\u67c4\u6ca1\u6709 key() \u548c mapped() \u4e86\uff0c\u800c\u662f\u53ea\u6709\u4e00\u4e2a value()\uff0c\u83b7\u53d6\u5176\u4e2d\u7684\u503c set s = {\"fuck\", \"suck\", \"dick\"}; set::node_type node = s.extract(\"fuck\"); V &v = node.value();","title":"\u7528\u9014\u4e3e\u4f8b"},{"location":"stl_map/#insert_6","text":"insert \u51fd\u6570\uff1a\u63d2\u5165\u6e38\u79bb\u8282\u70b9\u7684\u7248\u672c insert_return_type insert(node_type &&node); iterator insert(const_iterator pos, node_type &&node); // \u5e26\u63d0\u793a\u7684\u7248\u672c \u53ef\u4ee5\u7528 insert(move(node)) \u76f4\u63a5\u63d2\u5165\u4e00\u4e2a\u8282\u70b9\u3002 map m1 = { {\"fuck\", 985}, {\"dick\", 211}, }; map m2; auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); // \u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u4e0d\u53ef\u62f7\u8d1d\uff0c\u9700\u8981\u7528\u79fb\u52a8\u8bed\u4e49\u8fdb\u884c\u63d2\u5165 \u8c03\u7528 insert(move(node)) \u540e\u7531\u4e8e\u6240\u6709\u6743\u88ab\u79fb\u8d70\uff0cnode \u5c06\u4f1a\u5904\u4e8e\u201c\u7a7a\u6307\u9488\u201d\u72b6\u6001\uff0c\u53ef\u4ee5\u7528 node.empty() \u67e5\u8be2\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u201c\u7a7a\u201d\u72b6\u6001\uff0c\u5373\u8282\u70b9\u6240\u6709\u6743\u662f\u5426\u5df2\u7ecf\u79fb\u8d70\u3002","title":"insert \u8282\u70b9\u7248"},{"location":"stl_map/#insert_return_type","text":"\u8fd9\u4e2a\u7248\u672c\u7684 insert \u8fd4\u56de\u503c\u7c7b\u578b insert_return_type \u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff08\u6211\u7684\u5929\u4ed6\u4eec\u7ec8\u4e8e\u80af\u7528\u7ed3\u6784\u4f53\u800c\u4e0d\u662f pair \u4e86\uff09\uff1a struct insert_return_type { iterator position; bool inserted; node_type node; }; insert_return_type insert(node_type &&nh); \u5b98\u65b9\u8bf4\u6cd5\u662f 1 \uff1a If nh is empty, inserted is false, position is end(), and node is empty. Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty. If the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().","title":"insert_return_type"},{"location":"stl_map/#extract-insert","text":"map hells = { {666, \"devil\"}, }; map schools = { {985, \"professor\"}, {211, \"doctor\"}, {996, \"fucker\"}, }; auto node = schools.extract(996); hells.insert(std::move(node)); print(schools); print(hells); {211: \"doctor\", 985: \"professor\"} {666: \"devil\", 996: \"fucker\"} extract + insert(move(node)) \u5bf9\u6bd4 find + insert({key, val})\uff0c\u53ef\u4ee5\u907f\u514d\u952e\u548c\u503c\u7c7b\u578b\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u5f00\u9500\uff0c\u81f3\u59cb\u81f3\u7ec8\u79fb\u52a8\u7684\u53ea\u662f\u4e00\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u6307\u9488\uff0c\u5143\u7d20\u6ca1\u6709\u88ab\u79fb\u52a8\uff0c\u4e5f\u6ca1\u6709\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u4e0d\u5fc5\u8981\u7684\u5206\u914d\u548c\u91ca\u653e\u3002 \u4f46\u662f insert(move(node)) \u4ec5\u9002\u7528\u4e8e\u4ece extract \u4e2d\u53d6\u51fa\u73b0\u6709\u8282\u70b9\u7684\u60c5\u51b5\uff0c\u5982\u679c\u8981\u65b0\u5efa\u8282\u70b9\u8fd8\u5f97\u9760 insert({key, val}) \u6216\u8005 try_emplace(key, val) \u7684\u3002","title":"extract + insert \u8fd0\u7528\u6848\u4f8b"},{"location":"stl_map/#extract_1","text":"\u5df2\u77e5\u4e24\u4e2a\u6620\u5c04\u8868 tab1 \u548c tab2\uff0c\u548c\u4e00\u4e2a\u63a5\u53d7 K \u7c7b\u578b\u505a\u53c2\u6570\u7684\u4eff\u51fd\u6570 cond\u3002 \u8981\u6c42\u628a tab1 \u4e2d\u952e\u7b26\u5408 cond \u6761\u4ef6\u7684\u5143\u7d20\u79fb\u52a8\u5230 tab2 \u4e2d\u53bb\uff0c\u5176\u4f59\u4fdd\u7559\u5728 tab1 \u4e2d\u3002 \u6211\u4eec\u7f16\u5199\u56db\u4efd\u540c\u6837\u529f\u80fd\u7684\u7a0b\u5e8f\uff0c\u5206\u522b\u91c7\u7528\uff1a extract + \u5e26\u63d0\u793a\u7684 insert erase + \u5e26\u63d0\u793a\u7684 insert extract + \u76f4\u63a5 insert erase + \u76f4\u63a5 insert template void filter_with_extract(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); tab2.insert(std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); tab2.insert(std::move(kv)); } else ++it; } } template void filter_with_extract_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); hint = tab2.insert(hint, std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); hint = tab2.insert(hint, std::move(kv)); } else ++it; } } extract vs erase \u6027\u80fd\u6d4b\u8bd5\u7ed3\u679c (testextractvserase.cpp)\uff1a avg | min | max | total | cnt | tag 889| 803| 2388| 889271| 1000| filter_with_erase 642| 595| 1238| 642542| 1000| filter_with_extract 525| 491| 1398| 525137| 1000| filter_with_erase_with_hint 305| 289| 842| 305472| 1000| filter_with_extract_with_hint extract + \u5e26\u63d0\u793a\u7684 insert \u83b7\u80dc\uff0c\u5373\u51fd\u6570 filter_with_extract_with_hint \u662f\u6027\u80fd\u6700\u597d\u7684\u90a3\u4e00\u4e2a\u3002","title":"extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b"},{"location":"stl_map/#_49","text":"\u7531\u4e8e\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\uff0c\u6e38\u79bb\u8282\u70b9\u4e0d\u5c5e\u4e8e\u4efb\u4f55 map \u4e2d\uff0c\u4e0d\u9700\u8981\u6ee1\u8db3\u6392\u5e8f\u6027\u8d28\uff0c\u56e0\u6b64 node.key() \u53ef\u4fee\u6539\u3002 \u5148\u7528 extract \u53d6\u51fa\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u4fee\u6539\u5b8c\u8282\u70b9\u7684\u952e\u540e\u518d\u91cd\u65b0\u63d2\u5165\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u505a\u5230\u4ee5\u524d\u505a\u4e0d\u5230\u7684\u4fee\u6539\u952e\u503c\u3002 map m = { {\"fuck\", 985}, }; auto node = m.extract(\"fuck\"); // \u79fb\u51fa \"fuck\" \u952e\u5bf9\u5e94\u7684\u8282\u70b9\uff0c\u6b64\u65f6 m \u4f1a\u53d8\u4e3a\u7a7a node.key() = \"fxxk\"; // \u4fee\u6539\u952e\uff08\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->first \u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u952e\u7684\uff0c\u56e0\u4e3a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u8282\u70b9\u4e0d\u662f\u6e38\u79bb\u72b6\u6001\uff0c\u4fee\u6539\u952e\u4f1a\u7834\u574f\u6392\u5e8f\uff09 node.mapped() = 211; // \u4fee\u6539\u503c\uff08\u8fd9\u4e2a\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->second \u4e5f\u53ef\u4ee5\u4fee\u6539\uff09 m.insert(move(node)); // \u628a\u4fee\u6539\u597d\u7684\u8282\u70b9\u63d2\u5165\u56de\u53bb print(m); // {{\"fxxk\": 211}} \u76f8\u5f53\u4e8e\u4f60\u7ed9\u5c0f\u5b66\u751f\u6392\u961f\u65f6\uff0c\u6709\u4e00\u4e2a\u5c0f\u5b66\u751f\u7a81\u7136\u77ac\u95f4\u4e0d\u77e5\u9053\u5403\u4e86\u4ec0\u4e48\u6fc0\u7d20\u957f\u9ad8\u4e86\uff0c\u4f60\u7684\u961f\u4f0d\u5c31\u4f1a\u4e71\u6389\u3002 \u6240\u4ee5\u9700\u8981\u8ba9\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5148\u51fa\u5217\uff0c\u8ba9\u4ed6\u5355\u72ec\u4e00\u4e2a\u4eba\u957f\u9ad8\uff0c\u7b49\u4ed6\u957f\u9ad8\u5b8c\u4e86\u518d\u63d2\u5165\u56de\u961f\u5217\u3002","title":"\u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c"},{"location":"stl_map/#insert_7","text":"\u4f46\u662f\u5c0f\u5b66\u751f\u957f\u9ad8\u7684\u91cf\u53ef\u80fd\u662f\u6709\u9650\u7684\uff08\u65b0\u7684\u952e\u53ef\u80fd\u548c\u8001\u952e\u5f88\u63a5\u8fd1\uff09\u3002 \u8fd9\u65f6\u63d2\u5165\u53ef\u4ee5\u4f18\u5148\u4ece\u4ed6\u957f\u9ad8\u4e4b\u524d\u7684\u4f4d\u7f6e\u5f00\u59cb\u4e8c\u5206\u6cd5\uff0c\u4e5f\u5c31\u662f\u7528 extract \u4e4b\u524d\uff0c\u8fd9\u4e2a\u5c0f\u5b66\u751f\u540e\u4e00\u4f4d\u540c\u5b66\u7684\u4f4d\u7f6e\uff0c\u4f5c\u4e3a insert \u7684\u63d0\u793a\uff0c\u8ba9 insert \u66f4\u5feb\u5b9a\u4f4d\u5230\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5e94\u8be5\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 auto it = m.find(\"fuck\"); assert(it != m.end()); // \u5047\u5b9a \"fuck\" \u5fc5\u987b\u5b58\u5728\uff08\u5982\u679c\u4e0d\u5b58\u5728\u4f1a\u8fd4\u56de end\uff09 auto next_it = std::next(it); // \u4e0b\u4e00\u4f4d\u540c\u5b66\uff08\u53ef\u80fd\u4f1a\u5f97\u5230 end\uff0c\u4f46\u6ca1\u5173\u7cfb\uff0c\u56e0\u4e3a insert \u7684\u63d0\u793a\u4e5f\u5141\u8bb8\u4e3a end \u8fed\u4ee3\u5668\uff09 auto node = m.extract(it); node.key() = \"fxxk\"; // \u4fee\u6539\u952e\u503c\uff0c\u53d8\u5316\u4e0d\u5927 m.insert(next_it, move(node)); // \u5982\u679c\u952e\u503c\u53d8\u52a8\u4e0d\u5927\uff0c\u4f18\u5148\u5c1d\u8bd5\u5728\u8001\u4f4d\u7f6e\u63d2\u5165 \u8fd9\u91cc\u7684 std::next(it) \u5bf9\u4e8e\u7b49\u4ef7\u4e8e it + 1\u3002\u4f46\u662f map \u5c5e\u4e8e\u53cc\u5411\u8fed\u4ee3\u5668\uff08\u800c\u4e0d\u662f\u968f\u673a\u8fed\u4ee3\u5668\uff09\uff0c\u4e0d\u652f\u6301\u52a0\u6cd5\u64cd\u4f5c\uff0c\u53ea\u652f\u6301\u5c31\u5730 ++\u3002\u6240\u4ee5 std::next \u5185\u90e8\u7b49\u4ef7\u4e8e\uff1a auto next(auto it) { auto next_it = it; // \u5148\u62f7\u8d1d\u4e00\u4efd\uff0c\u9632\u6b62\u539f\u8fed\u4ee3\u5668\u88ab\u7834\u574f\uff08\u8fed\u4ee3\u5668\u90fd\u652f\u6301\u62f7\u8d1d\uff0c\u6027\u8d28\u4e0a\u662f\u6d45\u62f7\u8d1d\uff09 ++next_it; // \u518d\u8ba9 next_it \u5c31\u5730\u81ea\u589e\u5230\u4e0b\u4e00\u4f4d return next_it; // \u8fd4\u56de\u73b0\u5728\u5df2\u7ecf\u76f8\u5f53\u4e8e it + 1 \u7684 next_it } \u5982\u679c\u952e\u4e0d\u53d8\uff0c\u6216\u8005\u952e\u53d8\u4e86\u4ee5\u540e\uff0c\u63d2\u5165\u4f4d\u7f6e\u4e0d\u53d8\u7684\u8bdd\uff0c\u90a3\u4e48\u8fd9\u6b21 insert \u53ef\u4ee5\u4f4e\u81f3 O(1) O(1) \u590d\u6742\u5ea6\u3002 map m = { {\"dick\", 211}, {\"fuck\", 985}, // \"fuck\" -> \"fxxk\" \u540e\uff0c\u91cd\u65b0\u63d2\u5165\uff0c\u5176\u4f9d\u5b57\u5178\u5e8f\u7684\u201c\u5927\u5c0f\u201d\u4f9d\u7136\u662f\u4ecb\u4e8e \"dick\" \u548c \"suck\" {\"suck\", 996}, };","title":"\u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert"},{"location":"stl_map/#mergemap","text":"C++17 \u65b0\u589e\u7684 merge \u51fd\u6570 1 template void merge(map &__source); \u6ce8\uff1aset \u4e5f\u6709 merge \u51fd\u6570 \u6ce8\u610f\u5230 merge \u7684\u53c2\u6570\u662f\u53e6\u4e00\u4e2a map\uff0c\u53ef\u53d8\u5f15\u7528\uff0c\u5fc5\u987b\u548c\u672c map \u540c\u7c7b\u578b\uff08\u8fd9\u662f\u4e3a\u4e86\u4fdd\u8bc1\u8282\u70b9\u53e5\u67c4\u7c7b\u578b\u76f8\u540c\uff09\uff0c\u4f46\u5141\u8bb8\u6709\u4e0d\u540c\u7684\u6bd4\u8f83\u51fd\u6570 merge(source) \u4f1a\u628a source \u4e2d\u7684\u6240\u6709\u8282\u70b9\u90fd \u79fb\u52a8 \u5e76\u5408\u5e76\u5230\u672c map\uff0c\u6ce8\u610f\u662f \u79fb\u52a8 \u800c\u4e0d\u662f\u62f7\u8d1d\uff0csource \u5c06\u4f1a\u88ab\u6e05\u7a7a\uff0c\u8fd9\u6837\u662f\u4e3a\u4e86\u66f4\u9ad8\u6548\u3002 insert(source.begin(), source.end()) \u5219\u662f\u628a source \u91cc\u7684\u5143\u7d20\u62f7\u8d1d\u540e\u63d2\u5165\u5230\u672c map\uff0c\u66f4\u4f4e\u6548\uff0c\u56e0\u4e3a\u9700\u8981\u62f7\u8d1d\uff0c\u8fd8\u5f97\u65b0\u5efa\u7ea2\u9ed1\u6811\u8282\u70b9\uff0c\u989d\u5916\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 \u5bf9\u4e8e\u952e\u5b58\u5728\u51b2\u7a81\u7684\u60c5\u51b5\uff1a merge: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u79fb\u52a8\uff0c\u4fdd\u7559\u5728 source \u91cc\u3002 insert: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u63d2\u5165\u672c map\u3002\u65e0\u8bba\u6709\u6ca1\u6709\u63d2\u5165\u672c map\uff0c\u539f source \u4e2d\u7684\u952e\u90fd\u4e0d\u4f1a\u88ab\u6e05\u9664\u3002 \u56e0\u6b64\uff0cmerge \u4e5f\u5e76\u4e0d\u603b\u662f\u5b8c\u5168\u6e05\u7a7a source\uff0c\u5f53 source \u548c\u672c map \u6709\u51b2\u7a81\u65f6\uff0c\u51b2\u7a81\u7684\u952e\u5c31\u4fdd\u7559\u5728 source \u91cc\u4e86\u3002 merge \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u624b\u52a8\u7528 extract \u548c insert \u6765\u79fb\u52a8\u8282\u70b9\u7684\u4ee3\u7801\uff1a // m1.merge(m2) \u7b49\u4ef7\u4e8e\uff1a auto hint = m1.begin(); for (auto it = m2.begin(); it != m2.end(); ++it) { if (!m1.contains(it->first)) { auto node = m2.extract(it); hint = m1.insert(hint, node); } }","title":"merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09"},{"location":"stl_map/#insert-vs-merge","text":"\u540c\u6837\u505a\u5230\u4e24\u4e2a map \u5408\u5e76\uff0c m1.merge(m2) \u4e0e m1.insert(m2.begin(), m2.end()) \u6027\u80fd\u6bd4\u8f83\uff1a #include #include #include \"benchmark/benchmark.h\" using namespace std; static void BM_Insert(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.insert(m1.begin(), m1.end()); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Insert)->Arg(1000); static void BM_Merge(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.merge(m1); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Merge)->Arg(1000); merge \u51fd\u6570\u4e0d\u4f1a\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u5185\u5b58\u5206\u914d\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u6240\u4ee5\u66f4\u9ad8\u6548\u3002\u4f46\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u4ed6\u4f1a\u6e05\u7a7a m2\uff01 merge \u76f8\u5f53\u4e8e\u628a m2 \u7684\u5143\u7d20\u201c\u79fb\u52a8\u201d\u5230 m1 \u4e2d\u53bb\u4e86\u3002 insert \u5219\u662f\u628a m2 \u7684\u5143\u7d20\u201c\u62f7\u8d1d\u201d\u4e86\u4e00\u4efd\u63d2\u5165\u5230 m1 \u4e2d\u53bb\uff0c\u6548\u7387\u81ea\u7136\u4f4e\u4e0b\u3002 \u5982\u679c\u4e0d\u60f3\u7834\u574f\u6389 m2\uff0c\u6216\u8005\u4f60\u7528\u4e0d\u4e0a C++17\uff0c\u5219\u4ecd\u9700\u8981\u4f20\u7edf\u7684 insert\u3002","title":"\u6279\u91cf insert vs merge"},{"location":"stl_map/#merge-insert","text":"merge(m2) \u548c insert(m2.begin(), m2.end()) \u4e00\u6837\u5c3f\u6027\uff1a\u5982\u679c m2 \u4e2d\u7684\u952e\u5728 m1 \u4e2d\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4e0d\u4f1a extract \u8be5 m2 \u4e2d\u7684\u8282\u70b9\uff0c\u4ecd\u7136\u7559\u5728 m2 \u4e2d\u3002 int main() { std::map ma {{1, \"apple\"}, {5, \"pear\"}, {10, \"banana\"}}; std::map mb {{2, \"zorro\"}, {4, \"batman\"}, {5, \"X\"}, {8, \"alpaca\"}}; std::map u; u.merge(ma); std::cout << \"ma.size(): \" << ma.size() << '\\n'; u.merge(mb); std::cout << \"mb.size(): \" << mb.size() << '\\n'; std::cout << \"mb.at(5): \" << mb.at(5) << '\\n'; for(auto const &kv: u) std::cout << kv.first << \", \" << kv.second << '\\n'; }","title":"merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c"},{"location":"stl_map/#map_6","text":"map \u5bb9\u5668\u7684\u5168\u90e8\u53c2\u6570\u4e3a\uff1a std::map \u5176\u4e2d\u7b2c 3\u30014 \u4e2a\u53c2\u6570 Cmp \u548c Alloc \u53ef\u4ee5\u7701\u7565\u3002 Cmp \u9ed8\u8ba4\u4e3a std::less Alloc \u9ed8\u8ba4\u4e3a std::allocator> \u56e0\u6b64 map \u7684\u5b8c\u6574\u6a21\u677f\u53c2\u6570\u662f\uff1a std::map, std::allocator>> \u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 map \u3002 \u5176\u4e2d allocator \u6211\u4eec\u4ee5\u540e\u4e13\u95e8\u5f00\u4e00\u8282\u8bfe\u8bb2\uff0c\u5176\u4ed6\u5f88\u591a\u5bb9\u5668\u90fd\u6709 allocator\u3002 \u4eca\u5929\u53ea\u7814\u7a76 Cmp \u8fd9\u4e2a\u53c2\u6570\uff0c\u4ed6\u51b3\u5b9a\u4e86 map \u5982\u4f55\u6392\u5e8f\uff0c\u5224\u65ad\u76f8\u7b49\u3002 std::map> \u8fd9\u4e2a std::less \u662f\u4e2a\u4ec0\u4e48\u5462\uff1f\u662f\u4e00\u4e2a\u4eff\u51fd\u6570(functor)\u3002 template struct less { constexpr bool operator()(T const &x, T const &y) const { return x < y; } }; \u5177\u6709\u6210\u5458\u51fd\u6570 operator() \u7684\u7c7b\u578b\uff0c\u90fd\u88ab\u79f0\u4e4b\u4e3a\u4eff\u51fd\u6570\u3002","title":"map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668"},{"location":"stl_map/#stdless","text":"\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u5706\u62ec\u53f7\u5f53\u505a\u666e\u901a\u51fd\u6570\u8c03\u7528\uff0c\u8fd9\u5c31\u662f\u201c\u4eff\u51fd\u6570\u201d\u7684\u5f97\u540d\u539f\u56e0\uff0c\u4f8b\u5982\uff1a less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true","title":"std::less \u7684\u4f5c\u7528"},{"location":"stl_map/#operator_1","text":"\u6ce8\u610f\u4eff\u51fd\u6570\u7684\u6210\u5458\u51fd\u6570 operator() \u662f\u4e24\u4e2a\u62ec\u53f7\uff1a operator()(...) \u7b2c\u4e00\u4e2a\u62ec\u53f7\u662f operator() \u7684\u4e00\u90e8\u5206\uff0c\u8868\u793a\u8fd9\u662f\u5bf9\u5706\u62ec\u53f7 () \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u7b2c\u4e8c\u4e2a\u62ec\u53f7\u662f\u51fd\u6570\u7684\u53c2\u6570\u5217\u8868\uff0c\u91cc\u9762\u662f operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u5f62\u53c2\u3002 operator() \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __call__ \u3002\u6b63\u5982 operator< \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __lt__ \u3002\u8fd9\u91cc operator \u548c () \u662f\u4e00\u4e2a\u6574\u4f53\uff0c\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e86\u4e00\u4e2a\u6807\u8bc6\u7b26\u3002","title":"operator()"},{"location":"stl_map/#_50","text":"std::map> \u6211\u4eec\u4e4b\u524d\u63d0\u5230 map \u5185\u90e8\u7684\u5143\u7d20\u59cb\u7ec8\u6309\u7167\u952e K \u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002 map \u51b3\u5b9a\u5927\u5c0f\u987a\u5e8f\u7684\uff0c\u5e76\u4e0d\u662f\u76f4\u63a5\u8c03\u7528 K \u7c7b\u578b\u7684\u6bd4\u8f83\u8fd0\u7b97\u7b26 operator< \u3002 \u800c\u662f\u8c03\u7528\u4ed6\u7684\u6a21\u677f\u53c2\u6570 Cmp \u7c7b\u578b\u7684 operator() \u3002 \u8fd9\u662f\u4e3a\u4e86\u5141\u8bb8\u7528\u6237\u901a\u8fc7\u4fee\u6539\u8fd9\u4e2a\u53c2\u6570\uff0c\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\uff0c\u9632\u6b62 map \u6570\u636e\u7ed3\u6784\u4e0e\u5177\u4f53\u7684\u6bd4\u8f83\u65b9\u6cd5\u8026\u5408\u3002 \u7531\u4e8e\u9ed8\u8ba4\u7684 Cmp \u662f less \uff0c\u8c03\u7528 Cmp()(x, y) \u5c31\u76f8\u5f53\u4e8e x < y \uff0c\u7531\u6b64\u5b9e\u73b0\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002 \u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u4fee\u6539\u8fd9\u4e00\u9ed8\u8ba4\u884c\u4e3a\u3002","title":"\u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f"},{"location":"stl_map/#_51","text":"\u4e00\u4e2a\u7c7b\u578b\u8981\u60f3\u4f5c\u4e3a map \u7684\u952e\uff0c\u53ea\u9700\u8981\u4ed6\u652f\u6301 < \u8fd0\u7b97\u7b26\u5373\u53ef\uff0c\u4e0d\u5fc5\u5b9a\u4e49\u5176\u4ed6 > \u3001 == \u8fd0\u7b97\u7b26\u3002 \u5f53 map \u9700\u8981\u5224\u65ad\u4e24\u4e2a\u952e\u662f\u5426\u76f8\u7b49\u65f6 x == y \uff0c\u4f1a\u7528 !(x < y) && !(y < x) \u6765\u7b49\u4ef7\u5730\u8ba1\u7b97\u3002 string, string_view, int, float, void *, shared_ptr, pair, tuple, array\u2026 \u8fd9\u4e9b\u7c7b\u578b\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u90fd\u53ef\u4ee5\u4f5c\u4e3a map \u7684\u952e\u3002","title":"\u53ea\u9700\u8981\u5c0f\u4e8e\u53f7"},{"location":"stl_map/#_52","text":"\u5982\u679c\u4f60\u5199\u4e86\u4e2a\u81ea\u5b9a\u4e49\u7c7b Student\uff0c\u8981\u8ba9\u4ed6\u4f5c\u4e3a map \u7684\u952e\u7c7b\u578b\uff0c\u6709\u4e09\u79cd\u65b9\u6cd5\uff1a \u4e00\u3001\u5728 Student \u7c7b\u4e2d\u6dfb\u52a0 operator< struct Student { string name; int id; string sex; bool operator<(Student const &that) const { return x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))); // \u7b49\u4ef7\u4e8e\uff1a return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); // tuple \u5b9e\u73b0\u4e86\u6b63\u786e\u7684 operator< \u8fd0\u7b97\u7b26 } }; map stutab; \u4e8c\u3001\u7279\u5316 less \uff0c\u6dfb\u52a0 operator() struct Student { string name; int id; string sex; }; template <> struct std::less { // \u7528\u6237\u53ef\u4ee5\u7279\u5316\u6807\u51c6\u5e93\u4e2d\u7684 trait bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u5982\u679c map \u5916\u9762\u8981\u7528\u7528\u5230\u8fd9\u4e2a\u7c7b\u7684\u5927\u5c0f\u6bd4\u8f83\uff0c\u4e5f\u53ea\u80fd\u7528 less()(stu1, stu2) \u4ee3\u66ff stu1 < stu2 \u3002 \u4e09\u3001\u91cd\u65b0\u81ea\u5b9a\u4e49\u4e00\u4e2a\u4eff\u51fd\u6570\u7c7b LessStudent \uff0c\u6dfb\u52a0 operator() \uff0c\u7136\u540e\u628a\u8fd9\u4e2a LessStudent \u4f5c\u4e3a map \u7684\u6bd4\u8f83\u5668\u4f20\u5165\u6a21\u677f struct Student { string name; int id; string sex; }; struct LessStudent { bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u6bcf\u6b21\u521b\u5efa\u65b0\u7684 map \u65f6\uff0c\u90fd\u9700\u8981\u52a0\u4e00\u4e2a LessStudent \u53c2\u6570\u3002","title":"\u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f"},{"location":"stl_map/#_53","text":"\u5982\u679c\u5e0c\u671b map \u5728\u67e5\u627e\u65f6\u53ea\u6839\u636e\u5b66\u751f\u59d3\u540d\u7d22\u5f15\uff0c\u5219\u53ea\u9700\u8981\u6539\u4e00\u4e0b\u6bd4\u8f83\u5668\u7684\u5b9e\u73b0\uff0c\u8ba9\u4ed6\u53ea\u6bd4\u8f83\u59d3\u540d\u5b57\u6bb5\u5373\u53ef\u3002 struct LessStudent { bool operator()(Student const &x, Student const &y) const { return x.name < y.name; } }; \u4e0a\u9762\u8fd9\u6837\u7684\u6bd4\u8f83\u5668\uff0cmap \u4f1a\u8ba4\u4e3a\u59d3\u540d name \u76f8\u540c\u7684 Student \u5c31\u662f\u76f8\u7b49\u7684\uff0c\u5e76\u53bb\u91cd\u3002\u5373\u4f7f id \u548c sex \u4e0d\u540c\uff0c\u53ea\u8981\u540d\u5b57\u76f8\u7b49\u5c31\u4f1a\u89c6\u4e3a\u91cd\u590d\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u9488\u5bf9\u7279\u5b9a\u5b57\u6bb5\u7684\u53bb\u91cd\u3002 \u7ed3\u8bba\uff1amap \u7684\u6392\u5e8f\u548c\u53bb\u91cd\uff0c\u90fd\u53d6\u51b3\u4e8e\u4e8e\u4f60\u7684\u6bd4\u8f83\u5668\u5982\u4f55\u5b9e\u73b0\uff01\u6bd4\u8f83\u5668\u91cc\u6ca1\u6bd4\u8f83\u7684\u5b57\u6bb5\uff0c\u5c31\u4f1a\u88ab\u5ffd\u7565\u800c\u4e0d\u53c2\u4e0e\u6392\u5e8f\u3001\u7d22\u5f15\u3001\u548c\u53bb\u91cd\u3002","title":"\u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15"},{"location":"stl_map/#c20_1","text":"\u56db\uff08\u540c\u4e00\uff09\u3001\u5229\u7528 C++20 \u65b0\u7279\u6027\uff0c\u4e09\u8def\u6bd4\u8f83\u8fd0\u7b97\u7b26 <=> \uff1a\u5982\u679c\u81ea\u5b9a\u4e49\u7c7b\u7684\u6bcf\u4e2a\u6210\u5458\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u53ef\u4ee5\u628a operator<=> \u51fd\u6570\u58f0\u660e\u4e3a default \uff0c\u7136\u540e\u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u6dfb\u52a0\u81ea\u5b9a\u4e49\u7c7b\u7684\u6240\u6709\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 struct Student { string name; int id; string sex; auto operator<=>(Student const &) const = default; }; \u6b64\u65f6\u9ed8\u8ba4\u7684 operator< \u5b9e\u73b0\u7b49\u4ef7\u4e8e x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))) \u3002 <=> \u7684\u8fd4\u56de\u7c7b\u578b\u662f std::strong_ordering \uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u4e09\u79cd\u53d6\u503c\u7684\u5f3a\u679a\u4e3e\u7c7b\u578b <=> \u5bf9\u5e94\u7684\u4eff\u51fd\u6570\u4e3a std::compare_three_way","title":"C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=>"},{"location":"stl_map/#_54","text":"libstdc++ \u5934\u6587\u4ef6\u4e2d\u7684 less \u548c greater \u5b9e\u73b0\u53c2\u8003\uff1a template struct less : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template struct greater : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; \u7c7b\u4f3c\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u8fd8\u6709\uff1a \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b x == y std::equal_to x != y std::not_equal_to x < y std::less x > y std::greater x <= y std::less_equal x >= y std::greater_equal x + y std::plus x - y std::minus x * y std::multiplies x / y std::divides x % y std::modulus -x std::negate \u4ed6\u4eec\u90fd\u5728 #include \u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u3002","title":"\u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876"},{"location":"stl_map/#greater","text":"\u6848\u4f8b\uff1a\u4f7f\u7528 greater \u4eff\u51fd\u6570\uff0c\u8ba9 map \u53cd\u8fc7\u6765\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\uff1a auto ilist = { {985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}, }; map m1 = ilist; // \u4ece\u5c0f\u5230\u5927\u6392\u5e8f map> m2 = ilist; // \u4ece\u5927\u5230\u5c0f\u6392\u5e8f print(m1); // {{211, \"\u811a\u8e22\"}, {985, \"\u62f3\u6253\"}} print(m2); // {{985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}}","title":"greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f"},{"location":"stl_map/#_55","text":"\u81ea\u5b9a\u4e49\u6bd4\u8f83\u4eff\u51fd\u6570\uff0c\u5b9e\u73b0\u65e0\u89c6\u952e\u5927\u5c0f\u5199\u7684 map \u5bb9\u5668\uff1a struct LessIgnoreCase { bool operator()(std::string const &lhs, std::string const &rhs) const { return std::lexicographical_compare // \u4f4d\u4e8e \u5934\u6587\u4ef6\uff0c\u548c std::string \u540c\u6b3e\u7684\u5b57\u5178\u5e8f\u6bd4\u8f83 ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); } }; int main() { map m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"STUdy\"}, \"cpp\"}, {{\"stUDy\"}, \"js\"}, }; print(m); print(\"fuck\u5bf9\u5e94\u7684\u503c\u4e3a:\", m.at(\"fuck\")); return 0; } {\"Fuck\": \"rust\", \"STUdy\": \"cpp\"} fuck\u5bf9\u5e94\u7684\u503c\u4e3a: \"rust\"","title":"\u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668"},{"location":"stl_map/#lambda","text":"C++11 \u7684 lambda \u8868\u8fbe\u5f0f\u4e5f\u662f\u4eff\u51fd\u6570\uff0c\u914d\u5408 decltype \u540e\u5c31\u53ef\u4ee5\u4f20\u5165 map \u4f5c\u4e3a\u6bd4\u8f83\u5668\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m({ {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }, cmp); print(m); auto val = m.at({\"fuck\"}); print(val); \u5199\u7684\u66f4\u6e05\u6670\u4e00\u70b9\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m(cmp); m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }; print(m); auto val = m.at({\"fuck\"}); print(val);","title":"\u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668"},{"location":"stl_map/#map_7","text":"\u521a\u521a\u7528\u5230\u7684\u4e24\u4e2a map \u6784\u9020\u51fd\u6570\uff1a template > class map { explicit map(Cmp cmp); map(initializer_list> ilist, Cmp cmp); }; \u57fa\u672c\u6bcf\u4e2a map \u7684\u6784\u9020\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u63d0\u4f9b\u989d\u5916 cmp \u53c2\u6570\u7684\u7248\u672c\uff0c\u7edf\u4e00\u90fd\u662f\u5728\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u540e\u9762\u8ffd\u52a0\u3002","title":"map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684"},{"location":"stl_map/#_56","text":"\u4f20\u5165\u7684\u4eff\u51fd\u6570 cmp \u751a\u81f3\u53ef\u4ee5\u6355\u83b7\u5176\u4ed6\u53d8\u91cf\uff0c\u8fd9\u79cd\u6355\u83b7\u4e86\u53d8\u91cf\u7684\u4eff\u51fd\u6570\u79f0\u4e4b\u4e3a\u6709\u72b6\u6001\u4eff\u51fd\u6570 - stateful functor\uff0c\u548c\u65e0\u72b6\u6001\u4eff\u51fd\u6570 - stateless functor \u76f8\u5bf9\uff1a vector arr = {1, 4, 2, 8, 5, 7}; auto cmp = [&] (int i, int j) { return arr[i] < arr[j]; }; map m(cmp); \u5229\u7528\u6709\u72b6\u6001\u4eff\u51fd\u6570\u53ef\u4ee5\u5b9e\u73b0 argsort \u7b49\u64cd\u4f5c\uff0c\u4f8b\u5982\u4e0a\u9762\u4ee3\u7801\u5c31\u662f\u6839\u636e\u5728 arr \u91cc\u5bf9\u5e94\u7d22\u5f15\u7684\u503c\u6765\u6392\u5e8f\u3002 \u7531\u4e8e map \u9700\u8981\u6bd4\u8f83\u4eff\u51fd\u6570\u4e3a\u7eaf\u51fd\u6570(pure function)\uff0c\u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c\u8bf7\u4fdd\u8bc1 map \u5b58\u5728\u671f\u95f4 arr \u7684\u5185\u5bb9\u4e0d\u53d1\u751f\u53d8\u5316\uff0c\u5426\u5219 map \u57fa\u4e8e\u6392\u5e8f\u7684\u4e8c\u5206\u67e5\u627e\u529f\u80fd\u4f1a\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u4f20\u5165\u6bd4\u8f83\u5668\u4eff\u51fd\u6570\u662f\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u5178\u578b\u7684\u7b56\u7565\u6a21\u5f0f\uff0c\u901a\u8fc7\u4f9d\u8d56\u6ce8\u5165\uff0c\u5141\u8bb8\u6211\u4eec\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\u3002","title":"\u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668"},{"location":"stl_map/#function","text":"\u5982\u679c\u5acc decltype \u9ebb\u70e6\uff08\u96be\u4ee5\u5728\u5168\u5c40\u6216\u7c7b\u5185\u90e8\u7528\uff09\uff0cfunction \u5bb9\u5668\u4f5c\u4e3a\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u7edf\u4e00\u4e86\uff1a auto cmp = [] (int i, int j) { return i < j; }; map> m; \u7a0d\u540e\u8fd8\u53ef\u4ee5\u901a\u8fc7 key_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u952e\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff0c\u8fd9\u4e2a\u5c31\u662f\u4f60\u521a\u521a\u4f20\u5165\u7684 cmp \u53c2\u6570\uff1a m.key_comp()(1, 2); // \u7b49\u4ef7\u4e8e cmp(1, 2) value_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u5143\u7d20\uff08\u952e-\u503c\u5bf9\uff09\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff08\u4ed6\u5e2e\u4f60\u9002\u914d\u53c2\u6570\u7c7b\u578b\u4e86\uff09\uff1a m.value_comp()({1, 0}, {2, 0}); // \u7b49\u4ef7\u4e8e cmp(1, 2)","title":"\u5efa\u8bae\u7528 function"},{"location":"stl_map/#map_8","text":"","title":"\u900f\u660e map"},{"location":"stl_map/#_57","text":"C++14 \u65b0\u589e\u4e86\u201c\u900f\u660e(transparent)\u201d\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u3002 \u5bf9\u4e8e less\u3001greater \u8fd9\u7c7b\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u4eff\u51fd\u6570\uff0c\u6307\u5b9a\u6a21\u677f\u53c2\u6570\u4e3a void \u5373\u53ef\u8ba9\u4e00\u4e2a\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u53d8\u6210\u201c\u900f\u660e\u201d\u7684\u3002\u4f8b\u5982\u5bf9 less \u800c\u8a00\uff0c\u4ed6\u7684\u900f\u660e\u7248\u5c31\u662f less \u3002 C++14 \u4e4b\u524d\u7528\u7684\u90fd\u662f\u201c\u4e0d\u900f\u660e\u201d\u7248\u7684\u4eff\u51fd\u6570\uff0c\u5fc5\u987b\u6307\u5b9a\u4e00\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u4f8b\u5982 less \u5c31\u53ea\u80fd\u7528\u4e8e int \u7c7b\u578b\u7684\u6bd4\u8f83\uff0c less \u5c31\u53ea\u80fd\u7528\u4e8e string \u7c7b\u578b\u7684\u6bd4\u8f83\u3002 \u65e0\u6cd5\u7528 less \u4eff\u51fd\u6570\u6bd4\u8f83 string \u7c7b\u578b\u3002 \u800c less \u662f\u901a\u7528\u7684\uff0c\u4ed6\u7684 operator() \u51fd\u6570\u662f\u6cdb\u578b\u7684\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u3002 template <> struct less { // \u9488\u5bf9 void \u7684\u7279\u5316 // \u6807\u51c6\u59d4\u5458\u4f1a\u60f3\uff1a\u7531\u4e8e void \u7c7b\u578b\u4e0d\u53ef\u80fd\u6709 < \u8fd0\u7b97\u7b26\u7684\u9700\u6c42\uff0c\u6240\u4ee5\u4ed6\u4eec\u5e72\u8106\u62ff void \u4f5c\u4e3a\u900f\u660e\u7248\u7684\u6a21\u677f\u53c2\u6570\u201c\u5360\u4f4d\u7b26\u201d\u4e86 template constexpr decltype(auto) operator()(Tx &&x, Ty &&y) const { return forward(x) < forward(y); } struct is_transparent; // \u7a7a\u7c7b\uff0c\u4ec5\u4f9b SFINAE \u5143\u7f16\u7a0b\u65f6\u68c0\u6d4b\u4e00\u4e2a\u4eff\u51fd\u6570\u662f\u5426\u900f\u660e\u65f6\u4f7f\u7528 }; \u6211\u7684\u601d\u8003\uff1a\u4e0d\u900f\u660e\u7248\u7684 less \u6cdb\u578b\u4f53\u73b0\u5728\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u4e0a\uff0c\u800c\u900f\u660e\u7248\u7684\u4f53\u73b0\u5728\u4e86\u6210\u5458\u51fd\u6570 operator() \u7684\u6a21\u677f\u53c2\u6570\u4e0a\u3002 \u8fd9\u91cc\u7528 void \u7279\u5316\u53ea\u662f\u4e00\u4e2a\u5077\u61d2\uff0c void \u5e76\u6ca1\u6709\u4ec0\u4e48\u7279\u6b8a\u7684\uff0c\u5b9e\u9645\u4e0a\u5e94\u8be5\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u6ca1\u6709\u6a21\u677f\u7684 transparent_less \u7c7b\uff0c\u4f46\u4ed6\u4eec\u5c31\u662f\u61d2\u5f97\u5f15\u5165\u65b0\u6807\u8bc6\u7b26\u3002","title":"\u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570"},{"location":"stl_map/#_58","text":"\u201c\u900f\u660e\u201d\u7248\u7684\u597d\u5904\u662f\u53ef\u4ee5\u540c\u4e00\u4e2a\u517c\u5bb9\u4efb\u610f\u7c7b\u578b\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a cmp \u5bf9\u8c61\u3002\u800c\u4e0d\u900f\u660e\u7248\u7684\u597d\u5904\u662f\u65b9\u4fbf\u7279\u5316 traits\uff0c\u4f46\u6bd5\u7adf < \u8fd0\u7b97\u7b26\u662f\u53ef\u4ee5\u7528\u6237\u81ea\u5b9a\u4e49(\u8fd0\u7b97\u7b26\u91cd\u8f7d)\u7684\uff0c\u6ca1\u5fc5\u8981\u7528 traits \u7279\u5316\uff0c\u6240\u4ee5\u4ed6\u4eec\u9010\u6b65\u53d1\u73b0\u900f\u660e\u7248\u9999\u4e86\uff0c\u8fd8\u80fd\u652f\u6301\u5de6\u53f3\u53c2\u6570\u4e3a\u4e0d\u540c\u7c7b\u578b\u3002 less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u4f46\u4e5f\u8981\u7279\u522b\u6ce8\u610f\u4e0d\u80fd\u518d\u4f9d\u8d56\u53c2\u6570\u7c7b\u578b\u81ea\u52a8\u7684\u9690\u5f0f\u8f6c\u6362\u4e86\uff0c\u5fc5\u987b\u81f3\u5c11\u5199\u5b8c\u6574\u5176\u4e2d\u4e00\u4e2a string(\"hello\") \u624d\u80fd\u89e6\u53d1 string \u7684 operator< \u800c\u4e0d\u662f const char * \u7684\u6307\u9488\u6bd4\u5927\u5c0f\u3002\u5982\u679c\u53ea\u5199 cmp(\"cmake\", \"cppcon\") \u5219\u662f\u5728\u6bd4\u8f83\u6307\u9488\u7684\u5730\u5740\u5927\u5c0f\uff0c\u7ed3\u679c\u662f\u4e0d\u4e00\u5b9a\u7684\u3002 \u7531\u4e8e C++14 \u7684 less \u6a21\u677f\u53c2\u6570 T \u9ed8\u8ba4\u4e3a void\uff0c\u6240\u4ee5 less \u8fd8\u53ef\u4ee5\u7b80\u5199\u6210 less<> \u3002 less<> cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570"},{"location":"stl_map/#find_1","text":"\u666e\u901a find \u51fd\u6570\uff1a\u952e\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570 iterator find(K const &k); const_iterator find(K const &k) const; C++14 \u65b0\u589e\u6cdb\u578b\u7248\u7684 find \u51fd\u6570 1 \uff1a\u4efb\u610f\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570\uff0c\u53ea\u8981\u8be5\u7c7b\u578b\u652f\u6301\u4e0e\u548c\u952e\u6bd4\u5927\u5c0f\u3002 template iterator find(Kt &&k); template const_iterator find(Kt &&k) const; \u8fd9\u91cc\u7684 Kt \u662f\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\uff0c\u6b64\u5904 && \u662f\u4e07\u80fd\u5f15\u7528\u4e0d\u662f\u53f3\u503c\u5f15\u7528\u3002 \u76f8\u540c\u70b9\uff1a\u627e\u5230\u4e86\u5c31\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u4e0e\u8be5\u53c2\u6570\u76f8\u7b49\u7684\u5143\u7d20\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8fd8\u662f\u8fd4\u56de end()\u3002 \u4e0d\u540c\u70b9\uff1a\u6cdb\u578b\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b Kt \u4e0d\u5fc5\u548c\u952e\u7c7b\u578b K \u4e00\u81f4\uff0c\u53ea\u8981 Kt \u548c K \u53ef\u4ee5\u6bd4\u8f83\u5927\u5c0f\uff08< \u8fd0\u7b97\u7b26\uff09\u5373\u53ef\u3002 \u4e0d\u4ec5","title":"\u6cdb\u578b\u7248\u7684 find \u51fd\u6570"},{"location":"stl_map/#find_2","text":"\u8981\u60f3\u7528\u6cdb\u578b\u7248\u7684 find \u51fd\u6570\u6709\u4e00\u4e2a\u6761\u4ef6\uff1a map \u7684\u6bd4\u8f83\u5668\u5fc5\u987b\u662f\u201c\u900f\u660e(transparent)\u201d\u7684\uff0c\u4e5f\u5c31\u662f less \u8fd9\u79cd\u3002\u5426\u5219\u6cdb\u578b\u7248\u7684 find(Kt &&) \u4e0d\u4f1a\u53c2\u4e0e\u91cd\u8f7d\uff0c\u4e5f\u5c31\u662f\u53ea\u80fd\u8c03\u7528\u4f20\u7edf\u7684 find(K const &) \u3002 \u4f46\u662f map \u9ed8\u8ba4\u7684\u6bd4\u8f83\u5668\u662f less \uff0c\u4ed6\u662f\u4e0d\u900f\u660e\u7684\uff0c\u6bd4\u8f83\u7684\u4e24\u8fb9\u5fc5\u987b\u90fd\u662f K \u7c7b\u578b\u3002\u5982\u679c\u5176\u4e2d\u4e00\u8fb9\u4e0d\u662f\u7684\u8bdd\uff0c\u5c31\u5f97\u5148\u9690\u5f0f\u8f6c\u6362\u4e3a K \u624d\u80fd\u7528\u3002 \u8fd9\u662f\u65e9\u671f C++98 \u8bbe\u8ba1\u7684\u5931\u8d25\uff0c\u5f53\u65f6\u4ed6\u4eec\u6ca1\u60f3\u5230 find \u8fd8\u53ef\u4ee5\u63a5\u53d7 string_view \u548c const char * \u8fd9\u7c7b\u53ef\u4ee5\u548c string \u6bd4\u8f83\uff0c\u4f46\u6784\u9020\u4f1a\u5ec9\u4ef7\u5f97\u591a\u7684\u5f31\u5f15\u7528\u7c7b\u578b\u3002 \u53ea\u597d\u540e\u6765\u5f15\u5165\u4e86\u900f\u660e\u6bd4\u8f83\u5668\u4f01\u56fe\u529b\u633d\u72c2\u6f9c\uff0c\u7136\u800c\u4e3a\u4e86\u5386\u53f2\u517c\u5bb9\uff0c map \u9ed8\u8ba4\u4ecd\u7136\u662f map> \u3002 \u5982\u679c\u6211\u4eec\u540c\u5b66\u7684\u7f16\u8bd1\u5668\u652f\u6301 C++14\uff0c\u5efa\u8bae\u5168\u90e8\u6539\u7528\u8fd9\u79cd\u5199\u6cd5 map> \uff0c\u4ece\u800c\u7528\u4e0a\u66f4\u9ad8\u6548\u7684 find\u3001at\u3001erase\u3001count\u3001contains \u7b49\u9700\u8981\u6309\u952e\u67e5\u627e\u5143\u7d20\u7684\u51fd\u6570\u3002","title":"\u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e"},{"location":"stl_map/#_59","text":"\u9664\u975e\u4f20\u5165\u7684\u521a\u597d\u5c31\u662f\u4e00\u4e2a string \u7684 const \u5f15\u7528\uff0c\u5426\u5219\u5c31\u4f1a\u53d1\u751f\u9690\u5f0f\u6784\u9020 string \u7684\u64cd\u4f5c\u3002 \u5982\u679c\u4f20\u5165\u7684\u662f\u4e00\u4e2a string_view \u6216 const char * \uff0c\u90a3\u4e48\u9700\u8981\u4ece\u4ed6\u4eec\u6784\u9020\u51fa\u4e00\u4e2a string \uff0c\u7136\u540e\u624d\u80fd\u4f20\u5165\u4f20\u7edf\u7684 find(string const &) \u51fd\u6570\u3002\u800c string \u7684\u6784\u9020\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e14\u53ef\u80fd\u4ea7\u751f\u5185\u5b58\u5206\u914d\u3002 \u5bf9\u4e8e\u6bd4\u8f83\u5927\u7684\u5b57\u7b26\u4e32\u505a\u952e\u503c\uff0c\u6bcf\u6b21\u67e5\u627e\u90fd\u9700\u8981\u91cd\u65b0\u6784\u9020\u4e00\u4e2a string \u5bf9\u8c61\uff0c\u5f00\u9500\u4f1a\u6bd4\u8f83\u5927\u3002 map lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(string(\"a-very-very-very-very-long-key\")); // \u9690\u5f0f\u6784\u9020\u4e86\u4e00\u4e2a string\uff0c\u5bfc\u81f4\u6df1\u62f7\u8d1d\u4e86\u6574\u4e2a\u5b57\u7b26\u4e32\uff01 \u800c\u542f\u7528\u4e86\u900f\u660e\u6bd4\u8f83\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u6bcf\u6b21\u90fd\u62f7\u8d1d\u6574\u4e2a\u5b57\u7b26\u4e32\u6765\u6784\u9020 string \u4e86\u3002\u56e0\u4e3a find\u3001at \u8fd9\u7c7b\u51fd\u6570\u4f1a\u542f\u7528\u4e00\u4e2a\u6cdb\u578b\u7684\u7248\u672c at(Kt &&) \uff0cKt \u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\uff0c\u53ea\u8981\u4ed6\u652f\u6301\u4e0e string \u6bd4\u8f83\u3002\u53ef\u4ee5\u662f const char * \uff0c string_view \u6216\u53e6\u4e00\u4e2a string \u3002 map> lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(\"a-very-very-very-very-long-key\"); \u56e0\u4e3a\u4e0d\u7528\u62f7\u8d1d\u4e86\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5bf9\u4e8e\u952e\u5b57\u7b26\u4e32\u975e\u5e38\u957f\u7684\u60c5\u51b5\u3002 at \u5185\u90e8\u4e5f\u4e0d\u4f1a\u6784\u9020\u4efb\u4f55\u65b0\u7684 string \uff0c\u4ed6\u4f1a\u62ff\u7740 const char * \u548c\u7ea2\u9ed1\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u8c03\u7528 == \u6bd4\u8f83\u3002 string == const char * \u662f\u5b89\u5168\u7684\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\u3002","title":"\u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#_60","text":"\u67d0\u6709\u67d0\u4e9b\u7279\u6b8a\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u628a\u6307\u9488\uff0c\u751a\u81f3\u667a\u80fd\u6307\u9488\uff01\u653e\u8fdb map \u6216 set \u7684\u952e\u4e2d\uff0c\u7528\u4e8e\u5feb\u901f\u6309\u6307\u9488\u7684\u503c\u67e5\u627e\u5230\u5143\u7d20\u3002\uff08\u662f\u7684\u4f60\u6ca1\u542c\u9519\uff0c\u662f\u653e\u5728 \u952e\u7c7b\u578b \u91cc\uff01\uff09 \u8f76\u4e8b\uff1a\u628a\u6307\u9488\u653e\u5728\u952e\u91cc\u5e76\u4e0d\u7f55\u89c1\uff0c\u5e38\u89c1\u7684\u4e00\u4e2a\u7528\u6cd5\u662f set \u3002\u597d\u5904\u662f\u5f53 Node \u6790\u6784\u65f6\uff0c\u4ed6\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528 set.erase(this) \u628a\u81ea\u5df1\u5254\u9664\u6389\u3002\u800c\u666e\u901a\u7684 set \u5c31\u5f88\u96be\u505a\u5230\u8fd9\u4e00\u70b9\u4e86\uff0c\u4f60\u65e0\u6cd5\u901a\u8fc7 Node \u7684 this \u6307\u9488\u83b7\u5f97\u4ed6\u5728 set \u4e2d\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u65e0\u6cd5\u77e5\u9053\u81ea\u5df1\u4f4d\u4e8e\u54ea\u4e2a set \u4e2d\u3002\u4fb5\u5165\u5f0f\u7ea2\u9ed1\u6811\u5b8c\u7f8e\u89e3\u51b3\u4e86\u8fd9\u4e00\u75db\u70b9\uff0cLLVM \u548c Linux \u5185\u6838\u4e2d\u90fd\u5927\u91cf\u8fd0\u7528\u4e86\u4fb5\u5165\u5f0f\u94fe\u8868/LRU/\u7ea2\u9ed1\u6811\uff0c\u4ee5\u540e\u7684\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4e2d\u4f1a\u4e3a\u4f60\u8bb2\u89e3\u3002 map lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); \u5982\u679c\u662f\u667a\u80fd\u6307\u9488\uff0c\u5c31\u6bd4\u8f83\u56f0\u96be\u4e86\uff0c\u7279\u522b\u662f unique_ptr \u3002\u5982\u679c\u4f60\u5df2\u77e5\u4e00\u4e2a\u539f\u59cb\u6307\u9488\uff0c\u60f3\u8981\u5728 map \u4e2d\u67e5\u627e\u6307\u5411\u540c\u6837\u7684\u667a\u80fd\u6307\u9488\u952e\u3002 map, int> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece Node * \u9690\u5f0f\u6784\u9020 unique_ptr \u8fc7\u53bb\uff0c\u4eba\u4eec\u4e0d\u5f97\u4e0d\u7528\u4e00\u79cd\u79f0\u4e3a stale-ptr\uff08\u53d8\u8d28\u6307\u9488\uff09\u7684\u9ed1\u79d1\u6280\uff0c\u6765\u6784\u9020\u4e00\u4e2a\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u4f2a unique_ptr \u51fa\u6765\uff1a map, int> lut; Node *raw_ptr = get_some_ptr(); unique_ptr stale_ptr(raw_ptr); // \u4e00\u4e2a\u5e76\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u201c\u53d8\u8d28\u667a\u80fd\u6307\u9488\u201d lut.find(stale_ptr); // OK: \u5339\u914d\u5230 find(unique_ptr const &) \u91cd\u8f7d stale_ptr.release(); // \u5fc5\u987b\uff01\u5426\u5219\u4f1a\u51fa\u73b0\u53cc\u91cd\u91ca\u653e (double-free) \u9519\u8bef \u800c C++14 \u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u5b9a\u4e49\u4e00\u4e2a\u900f\u660e\u7684\u6bd4\u8f83\u51fd\u6570\uff0c\u652f\u6301 Node * \u4e0e unique_ptr \u4e92\u76f8\u6bd4\u8f83\u5373\u53ef\uff1a struct transparent_ptr_less { template bool operator()(T *const &p1, T const &p2) const { return p1 < p2; } template bool operator()(T *const &p1, unique_ptr const &p2) const { return p1 < p2.get(); } template bool operator()(unique_ptr const &p1, T *const &p2) const { return p1.get() < p2; } template bool operator()(unique_ptr const &p1, unique_ptr const &p2) const { return p1.get() < p2.get(); } using is_transparent = std::true_type; }; map, int, transparent_ptr_less> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // OK: \u5339\u914d\u5230\u6cdb\u578b\u7684 find(Kt &&) \u91cd\u8f7d\uff0c\u5176\u4e2d Kt \u63a8\u5bfc\u4e3a Node *const &","title":"\u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#_61","text":"\u4ee5\u4e0b\u6458\u81ea cppreference \u4e0a\u6cdb\u578b find \u7684\u5b98\u65b9\u6848\u4f8b\uff1a struct FatKey { int x; int data[1000]; }; struct LightKey { int x; }; // Note: as detailed above, the container must use std::less<> (or other // transparent Comparator) to access these overloads. // This includes standard overloads, such as between std::string and std::string_view. bool operator<(const FatKey& fk, const LightKey& lk) { return fk.x < lk.x; } bool operator<(const LightKey& lk, const FatKey& fk) { return lk.x < fk.x; } bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.x < fk2.x; } int main() { // transparent comparison demo std::map> example = {{{1, {}}, 'a'}, {{2, {}}, 'b'}}; LightKey lk = {2}; if (auto search = example.find(lk); search != example.end()) std::cout << \"Found \" << search->first.x << \" \" << search->second << '\\n'; else std::cout << \"Not found\\n\"; } Found 2 b","title":"\u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#multimap","text":"\u5141\u8bb8\u91cd\u590d\u952e\u503c\u7684 multimap map \u4e2d\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e00\u4e2a\u503c\uff0c\u800c multimap \u4e00\u4e2a\u952e\u53ef\u4ee5\u5bf9\u5e94\u591a\u4e2a\u503c\u3002 map\uff1a\u6392\u5e8f + \u53bb\u91cd\uff1b multimap\uff1a\u53ea\u6392\u5e8f\uff0c\u4e0d\u53bb\u91cd\u3002 // map \u7684\u63d2\u5165\u51fd\u6570\uff1a pair insert(pair const &kv); pair insert(pair &&kv); // multimap \u7684\u63d2\u5165\u51fd\u6570\uff1a iterator insert(pair const &kv); iterator insert(pair &&kv); \u56e0\u4e3a multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\uff0c\u6240\u4ee5\u63d2\u5165\u603b\u662f\u6210\u529f\uff0c\u4e0e\u666e\u901a map \u76f8\u6bd4\u4e0d\u7528\u8fd4\u56de bool \u8868\u793a\u662f\u5426\u6210\u529f\u4e86\u3002","title":"\u795e\u5947\u7684 multimap"},{"location":"stl_map/#_62","text":"multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); print(tab); {\"cpp\": \"smart\", \"cpp\": \"fast\", \"java\": \"pig\", \"rust\": \"silly\", \"rust\": \"trash\", \"rust\": \"trash\", \"rust\": \"lazy\"} \u63d2\u5165\u8fdb multimap \u7684\u91cd\u590d\u952e\u4f1a\u7d27\u6328\u7740\uff0c\u4ed6\u4eec\u4e4b\u95f4\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u63d2\u5165\u7684\u987a\u5e8f\u3002\u4f8b\u5982\u4e0a\u9762\u952e\u540c\u6837\u662f \u201ccpp\u201d \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u201dsmart\u201d \u5148\u4e8e \u201cfast\u201d \u63d2\u5165\uff0c\u6240\u4ee5 \u201csmart\u201d \u9760\u524d\u4e86\u3002","title":"\u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f"},{"location":"stl_map/#_63","text":"multimap / multiset \u7684\u4f5c\u7528\u901a\u5e38\u5c31\u4e0d\u662f\u952e\u503c\u6620\u5c04\u4e86\uff0c\u800c\u662f\u5229\u7528\u7ea2\u9ed1\u6811\u4f1a\u4fdd\u6301\u5143\u7d20\u6709\u5e8f\u7684\u7279\u6027\uff08\u4efb\u4f55\u4e8c\u53c9\u641c\u7d22\u6811\u90fd\u8fd9\u6837\uff09\u5b9e\u73b0\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u52a8\u6001\u6392\u5e8f\u3002 \u4f20\u7edf\u6392\u5e8f\u65b9\u5f0f\uff1a std::vector arr; int i; while (cin >> i) { arr.push_back(i); } std::sort(arr.begin(), arr.end(), std::less()); multiset \u6392\u5e8f\u65b9\u5f0f\uff1a std::multiset tab; int i; while (cin >> i) { tab.insert(i); } // \u65e0\u9700\u518d\u6392\u5e8f\uff0ctab \u4e2d\u7684\u952e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\u4e86\uff01 // \u5982\u9700\u53d6\u51fa\u5230 vector: std::vector arr(tab.begin(), tab.end()); \u5229\u7528 multimap \u952e-\u503c\u5bf9\u7684\u7279\u70b9\uff0c\u8fd8\u80fd\u8f7b\u6613\u5b9e\u73b0\u53ea\u5bf9\u952e\u6392\u5e8f\uff0c\u503c\u7684\u90e8\u5206\u4e0d\u53c2\u4e0e\u6392\u5e8f\u7684\u6548\u679c\u3002 multimap \u6392\u5e8f\u7684\u597d\u5904\u662f\uff1a \u52a8\u6001\u6392\u5e8f\uff0c\u5728\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\u5c31\u4fdd\u6301\u6574\u4e2a\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6027\uff0c\u6700\u540e\u4efb\u4f55\u65e0\u9700\u989d\u5916\u64cd\u4f5c\u3002 \u5728\u4e00\u6b21\u6b21\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u65f6\u6bcf\u523b\u90fd\u662f\u6709\u5e8f\u7684\uff0c\u800c\u4e0d\u5fc5\u7b49\u5230\u6700\u540e\u624d\u53d8\u5f97\u6709\u5e8f\u3002 \u53ef\u4ee5\u968f\u65f6\u52a8\u6001\u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff0c\u540c\u6837\u4e0d\u4f1a\u7834\u574f\u6709\u5e8f\u6027\u3002 \u8fd8\u5f88\u65b9\u4fbf\u968f\u65f6\u6309\u952e\u503c\u67e5\u627e\u5230\u548c\u6211\u76f8\u7b49\u7684\u5143\u7d20\u3002 \u5982\u679c\u8fd8\u989d\u5916\u9700\u8981\u53bb\u91cd\uff0c\u5219\u53ea\u9700\u6539\u7528\u666e\u901a map \u666e\u901a map \u8f7b\u677e\u5b9e\u73b0\u53bb\u91cd + \u52a8\u6001\u6392\u5e8f\uff0c\u5982\u4f55\u5904\u7f6e\u91cd\u590d\u7684\u952e\u968f\u4f60\u51b3\u5b9a\uff1a \u666e\u901a map \u7684 insert \u53ea\u63a5\u53d7\u7b2c\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u666e\u901a map \u7684 insert_or_assign \u53ea\u4fdd\u7559\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002","title":"\u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01"},{"location":"stl_map/#_64","text":"\u56e0\u4e3a multimap \u4e2d\uff0c\u4e00\u4e2a\u952e\u4e0d\u518d\u5bf9\u4e8e\u5355\u4e2a\u503c\u4e86\uff1b\u6240\u4ee5 multimap \u6ca1\u6709 [] \u548c at \u4e86\uff0c\u4e5f\u6ca1\u6709 insert_or_assign \uff08\u53cd\u6b63 insert \u6c38\u8fdc\u4e0d\u4f1a\u53d1\u751f\u952e\u51b2\u7a81\uff01\uff09 pair equal_range(K const &k); template pair equal_range(Kt &&k); \u8981\u67e5\u8be2 multimap \u4e2d\u7684\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e86\u54ea\u4e9b\u503c\uff0c\u53ef\u4ee5\u7528 equal_range \u83b7\u53d6\u4e00\u524d\u4e00\u540e\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4ed6\u4eec\u5f62\u6210\u4e00\u4e2a\u533a\u95f4\u3002\u8fd9\u4e2a\u533a\u95f4\u5185\u6240\u6709\u7684\u5143\u7d20\u90fd\u662f\u540c\u6837\u7684\u952e\u3002 multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); auto range = tab.equal_range(\"cpp\"); for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } cpp smart cpp fast equal_range \u8fd4\u56de\u4e24\u4e2a\u8fed\u4ee3\u5668\u76f8\u7b49\u65f6\uff08\u5373\u533a\u95f4\u5927\u5c0f\u4e3a 0\uff09\uff0c\u5c31\u4ee3\u8868\u627e\u4e0d\u5230\u8be5\u952e\u503c\u3002 auto range = tab.equal_range(\"html\"); if (range.first == range.second) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } } equal_range \u8fd4\u56de\u7684\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4e5f\u53ef\u4ee5\u7528 lower_bound \u548c upper_bound \u5206\u522b\u83b7\u5f97\uff1a auto begin_it = tab.lower_bound(\"html\"); auto end_it = tab.upper_bound(\"html\"); if (begin_it == end_it) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = begin_it; it != end_it; ++it) { print(it->first, it->second); } }","title":"\u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c"},{"location":"stl_map/#lowerupper_bound","text":"lower_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\u7b49\u4e8e\uff08>=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 upper_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\uff08>\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 lower_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\uff08<\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 upper_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\u7b49\u4e8e\uff08<=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 \u4f8b\u5982\u6211\u8981\u5bf9\u4e00\u7cfb\u5217\u5c0f\u5f6d\u53cb\u7684\u6210\u7ee9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u8981\u6c42\u67e5\u51fa\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u6240\u6709\u540c\u5b66\uff0c\u53d1\u653e\u201c\u5c0f\u7ea2\u82b1\u201d\uff1a struct Student { string name; int score; }; vector students; \u5c31\u53ef\u4ee5\u628a\u6210\u7ee9 int \u4f5c\u4e3a\u952e\uff0c\u5b66\u751f\u540d\u5b57\u4f5c\u4e3a\u503c\uff0c\u63d2\u5165 multimap\u3002 \u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d multimap \u5c31\u81ea\u52a8\u4e3a\u4f60\u52a8\u6001\u6392\u5e8f\u4e86\u3002 multimap sorted; for (auto const &stu: students) { sorted.insert({stu.score, stu.name}); } \u7136\u540e\uff0c\u8981\u627e\u51fa\u6240\u6709\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u540c\u5b66\uff0c\u4e5f\u5c31\u662f lower_bound(60) \u5230 end() \u8fd9\u4e2a\u533a\u95f4\uff1a // where score >= 60 for (auto it = sorted.lower_bound(60); it != sorted.end(); ++it) { print(\"\u606d\u559c {} \u540c\u5b66\uff0c\u8003\u51fa\u4e86 {} \u5206\uff0c\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u7ea2\u82b1\", it->second, it->first); } \u627e\u51fa 30\uff08\u542b\uff09\u5230 60\uff08\u4e0d\u542b\uff09\u5206\u7684\u540c\u5b66\u4e5f\u5f88\u5bb9\u6613\uff1a // where 30 <= score and score < 60 for (auto it = sorted.upper_bound(30); it != sorted.lower_bound(60); ++it) { print(\"{} \u540c\u5b66\u8003\u51fa\u4e86 {} \u5206\uff0c\u4e0d\u8981\u7070\u5fc3\uff01\u5c0f\u5f6d\u8001\u5e08\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u9ec4\u82b1\uff0c\u8868\u793a\u9ec4\u724c\u8b66\u544a\", it->second, it->first); }","title":"lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2"},{"location":"stl_map/#_65","text":"\u5c1d\u8bd5\u7528 multimap \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5b66\u751f\u6210\u7ee9\u7ba1\u7406\u7cfb\u7edf\uff0c\u8981\u6c42\u5982\u4e0b\uff1a \u5b66\u751f\u4fe1\u606f\u5305\u62ec\u59d3\u540d\u548c\u6210\u7ee9\u3002 \u80fd\u591f\u52a8\u6001\u63d2\u5165\u548c\u5220\u9664\u5b66\u751f\u4fe1\u606f\uff0c\u59cb\u7ec8\u4fdd\u6301\u6309\u6210\u7ee9\u6392\u5e8f\u3002 \u80fd\u591f\u67e5\u8be2\u7ed9\u5b9a\u6210\u7ee9\u8303\u56f4\u5185\u7684\u6240\u6709\u5b66\u751f\u3002 \u5b9e\u9645\u4e0a\uff0c\u6570\u636e\u5e93\u5c31\u662f\u8fd9\u6837\u5b9e\u73b0\u7684\uff0c\u6211\u4eec\u7684 multimap \u53ea\u662f\u7b80\u5355\u5730\u5bf9\u6210\u7ee9\u8fd9\u4e00\u4e2a\u5b57\u6bb5\u6392\u5e8f\uff0c\u800c\u4e13\u4e1a\u7684\u5173\u7cfb\u6570\u636e\u5e93\u4f1a\u4e3a\u6bcf\u4e2a\u5b57\u6bb5\u90fd\u5efa\u7acb\u7d22\u5f15\uff0c\u5206\u522b\u6392\u5e8f\u540e\u5b58\u50a8\uff0c\u4ee5\u52a0\u901f\u67e5\u627e\u3002\u5b66\u6709\u4f59\u529b\u7684\u540c\u5b66\u53ef\u4ee5\u5c1d\u8bd5\u8ba9\u5b66\u751f\u4fe1\u606f\u5305\u542b\u59d3\u540d\u3001\u6210\u7ee9\u3001\u5e74\u9f84\u3001\u5b66\u53f7\uff0c\u7136\u540e\u5206\u522b\u6784\u5efa\u8fd9\u56db\u4e2a\u5b57\u6bb5\u7684\u7d22\u5f15\uff0c\u652f\u6301\u6307\u5b9a\u503c\u67e5\u627e\u548c\u8303\u56f4\u67e5\u627e\uff0c\u5176\u4e2d\u59d3\u540d\u548c\u5b66\u53f7\u8981\u6c42\u552f\u4e00\u6027\u3002\u63d0\u793a\uff1a\u7528\u4e4b\u524d\u63d0\u5230\u7684 vector + map \u7684\u65b9\u6cd5\u3002\u505a\u51fa\u6765\u4ee5\u540e\uff0c\u9762\u8bd5\u6570\u636e\u5e93\u65f6\u4f60\u5c31\u53ef\u4ee5\u79c0\u7406\u89e3\u4e86\u3002","title":"\u8bfe\u540e\u7ec3\u4e60"},{"location":"stl_map/#_66","text":"\u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m1 = move(m2) \u79fb\u52a8 O(1) O(1) m1 = m2 \u62f7\u8d1d O(N) O(N) swap(m1, m2) \u4ea4\u6362 O(1) O(1) m.clear() \u6e05\u7a7a O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert({key, val}) \u63d2\u5165\u952e\u503c\u5bf9 O(\\log N) O(\\log N) m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u51c6\u786e O(1) O(1) + m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u4e0d\u51c6\u786e O(\\log N) O(\\log N) m[key] = val \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert({vals\u2026}) \u8bbe M \u4e3a\u5f85\u63d2\u5165\u5143\u7d20\uff08vals\uff09\u7684\u6570\u91cf O(M \\log N) O(M \\log N) map m = \u5982\u679c vals \u65e0\u5e8f O(N \\log N) O(N \\log N) map m = \u5982\u679c vals \u5df2\u4e8b\u5148\u4ece\u5c0f\u5230\u5927\u6392\u5217 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.at(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u503c\u7684\u5f15\u7528 O(\\log N) O(\\log N) m.find(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u8fed\u4ee3\u5668 O(\\log N) O(\\log N) m.count(key) \u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u952e\u5143\u7d20\uff0c\u8fd4\u56de\u76f8\u540c\u952e\u7684\u5143\u7d20\u6570\u91cf\uff08\u53ea\u80fd\u4e3a 0 \u6216 1\uff09 O(\\log N) O(\\log N) m.equal_range(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u786e\u5b9a\u4e0a\u4e0b\u754c\uff0c\u8fd4\u56de\u533a\u95f4 O(\\log N) O(\\log N) m.size() map \u4e2d\u6240\u6709\u5143\u7d20\u7684\u6570\u91cf O(1) O(1) m.erase(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u5220\u9664\u5143\u7d20 O(\\log N) O(\\log N) m.erase(it) \u6839\u636e\u627e\u5230\u7684\u8fed\u4ee3\u5668\uff0c\u5220\u9664\u5143\u7d20 O(1)+ O(1)+ m.erase(beg, end) \u6279\u91cf\u5220\u9664\u533a\u95f4\u5185\u7684\u5143\u7d20\uff0c\u8bbe\u8be5\u533a\u95f4\uff08beg \u548c end \u4e4b\u95f4\uff09\u6709 M \u4e2a\u5143\u7d20 O(M + \\log N) O(M + \\log N) erase_if(m, cond) \u6279\u91cf\u5220\u9664\u6240\u6709\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert(node) O(\\log N) O(\\log N) node = m.extract(it) O(1)+ O(1)+ node = m.extract(key) O(\\log N) O(\\log N) m1.merge(m2) \u5408\u5e76\u4e24\u4e2a map\uff0c\u6e05\u7a7a m2\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) m1.insert(m2.begin(), m2.end()) \u5408\u5e76\u4e24\u4e2a map\uff0cm2 \u4fdd\u6301\u4e0d\u53d8\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N)","title":"\u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e"},{"location":"stl_map/#unordered_map","text":"C++11 \u65b0\u589e\uff1a\u57fa\u4e8e\u54c8\u5e0c (hash) \u7684\u6620\u5c04\u8868 unordered_map","title":"\u54c8\u5e0c\u8868 unordered_map"},{"location":"stl_map/#unordered_map-map","text":"\u4e4b\u524d\u63d0\u5230\uff0cmap \u5e95\u5c42\u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5927\u591a\u6570\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(\\log N) O(\\log N) \u7ea7\u522b\u7684\uff0c\u5176\u4e2d\u90e8\u5206\u6309\u8fed\u4ee3\u5668\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(1) O(1) \u3002 \u800c unordered_map \u5219\u662f\u57fa\u4e8e\u54c8\u5e0c\u8868\u7684\u66f4\u9ad8\u6548\u67e5\u627e\uff0c\u53ea\u9700 O(1) O(1) \u590d\u6742\u5ea6\uff01\u4ed6\u80fd\u5b9e\u73b0\u5982\u6b64\u9ad8\u6548\u67e5\u627e\u5f97\u76ca\u4e8e\u54c8\u5e0c\u51fd\u6570\u53ef\u4ee5\u628a\u6563\u5217\u552f\u4e00\u5b9a\u4f4d\u5230\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0b\u6807\u4e2d\u53bb\uff0c\u800c\u6570\u7ec4\u7684\u7d22\u5f15\u662f O(1) O(1) \u7684\u3002\u7f3a\u70b9\u662f\u54c8\u5e0c\u503c\u53ef\u80fd\u4ea7\u751f\u51b2\u7a81\uff0c\u800c\u4e14\u54c8\u5e0c\u6570\u7ec4\u53ef\u80fd\u6709\u7a7a\u4f4d\u6ca1\u6709\u586b\u6ee1\uff0c\u6d6a\u8d39\u4e00\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u3002\u603b\u7684\u6765\u8bf4\u54c8\u5e0c\u8868\u5728\u5e73\u5747\u590d\u6742\u5ea6\u4e0a\uff08 O(1) O(1) \uff09\u6bd4\u7ea2\u9ed1\u6811\u8fd9\u7c7b\u57fa\u4e8e\u6811\u7684\u590d\u6742\u5ea6\uff08 O(\\log N) O(\\log N) \uff09\u66f4\u4f4e\uff0c\u867d\u7136\u56fa\u6709\u5ef6\u8fdf\u9ad8\uff0c\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u8fd8\u5bb9\u6613\u88ab\u54c8\u5e0c\u51b2\u7a81\u653b\u51fb\u3002 \u54c8\u5e0c\u8868\u7ed3\u6784\u7b80\u5355\u65e0\u8111\uff0c\u5728\u5de8\u91cf\u7684\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u65f6\u4f1a\u53d1\u6325\u51fa\u660e\u663e\u7684\u6027\u80fd\u4f18\u52bf\uff0c\u5e38\u7528\u4e8e\u9700\u8981\u9ad8\u541e\u5410\u91cf\u4f46\u4e0d\u592a\u5728\u4e4e\u5ef6\u8fdf\u7684\u56fe\u5f62\u5b66\u5e94\u7528\u3002 \u800c\u5404\u79cd\u57fa\u4e8e\u6811\u7684\u6570\u636e\u7ed3\u6784\uff0c\u590d\u6742\u5ea6\u66f4\u52a0\u7a33\u5b9a\uff0c\u770b\u4f3c\u9002\u5408\u5c0f\u89c4\u6a21\u6570\u636e\uff0c\u4f46\u662f\u56e0\u4e3a\u4fdd\u6301\u6709\u5e8f\u7684\u7279\u6027\uff0c\u975e\u5e38\u9002\u5408\u6570\u636e\u5e93\u8fd9\u79cd\u9700\u8981\u8303\u56f4\u67e5\u8be2\u7684\u60c5\u51b5\uff0c\u4e14\u6709\u5e8f\u6027\u53cd\u800c\u6709\u5229\u4e8e\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u65e0\u5e8f\u7684\u54c8\u5e0c\u8868\u96be\u4ee5\u80dc\u4efb\u3002 \u6700\u8fd1\u65b0\u63d0\u51fa\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u8df3\u8868\uff0c\u4e5f\u662f\u6709\u5e8f\u7684\uff0c\u4f46\u57fa\u4e8e\u94fe\u8868\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u5728 Redis \u7b49\u8f6f\u4ef6\u4e2d\u90fd\u6709\u5e94\u7528\u3002\u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u5e76\u5e26\u4f60\u624b\u6413\u6240\u6709\u8fd9\u4e9b\uff01","title":"unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c"},{"location":"stl_map/#unordered_map_1","text":"unordered_map \u5982\u4f55\u5feb\u901f\u68c0\u7d22\u6570\u636e\uff1f\u9ad8\u6548\u7684\u79d8\u8bc0\u5728\u4e8e unordered_map \u5185\u90e8\u662f\u4e00\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u7531\u8bb8\u591a\u201c\u6876\u201d\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u63d2\u5165\u65f6\u628a\u952e\u503c\u5bf9\u5b58\u5230\u952e\u7684 hash \u5bf9\u5e94\u7f16\u53f7\u7684\u6876\u53bb\uff0c\u67e5\u8be2\u65f6\u5c31\u6839\u636e hash \u53bb\u7ebf\u6027\u5730\u67e5\u627e\u6876\uff08\u8fd9\u4e00\u64cd\u4f5c\u662f O(1) O(1) \u7684\uff09\u3002 \u4f8b\u5982\u952e\u4e3a \u201chello\u201d\uff0c\u5047\u8bbe\u7b97\u51fa\u4ed6\u7684 hash \u4e3a 42\u3002\u800c\u5f53\u524d\u6876\u7684\u6570\u91cf\u662f 32 \u4e2a\uff0c\u5219\u4f1a\u628a \u201chello\u201d \u5b58\u5230 42 % 32 = 10 \u53f7\u6876\u53bb\u3002\u67e5\u8be2\u65f6\uff0c\u540c\u6837\u8ba1\u7b97\u51fa hash(\u201chello\u201d) % 32 = 10 \u53f7\u6876\uff0c\u7136\u540e\u5c31\u53ef\u4ee5\u4ece 10 \u53f7\u6876\u53d6\u51fa \u201chello\u201d \u5bf9\u5e94\u7684\u6570\u636e\u4e86\u3002 template class unordered_map { array, 32> buckets; void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97\u51fa\u6765\u7684 hash \u53ef\u80fd\u5f88\u5927\uff0c\u53d6\u6a21\u53ef\u4ee5\u9632\u6b62 h >= buckets.size() buckets[h] = kv; } V &at(K k) { size_t h = hash(k) % buckets.size(); auto &kv = buckets[h]; if (k != kv.first) throw out_of_range{}; return kv.second; } };","title":"\u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d"},{"location":"stl_map/#hash-collision","text":"\u4f46\u662f\u8fd9\u91cc\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u4e24\u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u521a\u597d hash \u4ee5\u540e\u7684\u6a21\u76f8\u540c\u600e\u4e48\u529e\uff1f\u8fd9\u79cd\u73b0\u8c61\u79f0\u4e3a hash \u51b2\u7a81\u3002 C++ \u6807\u51c6\u5e93\u7684\u89e3\u51b3\u65b9\u6848\u662f\u91c7\u7528\u94fe\u8868\u6cd5\uff1a\u4e00\u4e2a\u6876\u4e0d\u662f\u5355\u72ec\u7684\u4e00\u4e2a K-V \u5bf9\uff0c\u800c\u662f\u6570\u4e2a K-V \u5bf9\u7ec4\u6210\u7684\u5355\u94fe\u8868\uff08forward_list\uff09\u3002\u4e00\u4e2a\u6876\u4e0d\u662f\u53ea\u5b58\u50a8\u4e00\u4e2a\u6570\u636e\uff0c\u800c\u662f\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u591a\u4e2a\u6570\u636e\uff080\u5230\u221e\u4e2a\uff09\u3002 \u63d2\u5165\u65f6\uff0c\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5f80\u94fe\u8868\u7684\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684 K-V \u5bf9\u3002\u67e5\u627e\u65f6\uff0c\u5148\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5728\u8fd9\u4e2a\u6876\u91cc\u7684\u94fe\u8868\u91cc\u987a\u5e8f\u904d\u5386\u67e5\u627e\uff0c\u7531\u4e8e\u7b2c\u4e00\u6b65\u7684\u6876\u67e5\u627e\u662f O(1) O(1) \u7684\uff0c\u867d\u7136\u6700\u540e\u8fd8\u662f\u94fe\u8868\u66b4\u529b\u67e5\u627e\uff0c\u4f46\u662f\u5df2\u7ecf\u88ab\u6876\u5206\u644a\u4e86\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u56e0\u6b64\u67e5\u627e\u7684\u5e73\u5747\u590d\u6742\u5ea6\u8fd8\u662f O(1)+ O(1)+ \u7684\u3002 void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 buckets[h].push_front(kv); // \u5355\u94fe\u8868\u7684\u5934\u63d2\uff0c\u662f\u6700\u9ad8\u6548\u7684 } V &at(K k) { size_t h = hash(k) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 for (auto &kv: buckets[h]) { if (k == kv.first) // \u53ef\u80fd\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u952e\u521a\u597d\u6709\u76f8\u540c\u7684 hash \u6a21\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5224\u65ad\u952e\u786e\u5b9e\u76f8\u7b49\u624d\u80fd\u8fd4\u56de return kv.second; } throw out_of_range{}; } \u8fd9\u91cc\u8fd8\u662f\u6709\u4e00\u4e2a\u95ee\u9898\uff0chash \u51b2\u7a81\u65f6\uff0c\u5bf9\u94fe\u8868\u7684\u66b4\u529b\u904d\u5386\u67e5\u627e\u590d\u6742\u5ea6\u662f O(N) O(N) \u7684\uff0c\u968f\u7740\u8d8a\u6765\u8d8a\u591a\u7684\u5143\u7d20\u88ab\u63d2\u5165\u8fdb\u6765\uff0c32 \u4e2a\u6876\u5c06\u4f1a\u62e5\u6324\u4e0d\u582a\u3002\u5047\u8bbe\u6709 n \u4e2a\u5143\u7d20\uff0c\u5219\u5e73\u5747\u6bcf\u4e2a\u6876\u90fd\u4f1a\u6709 n / 32 \u4e2a\u5143\u7d20\uff0c\u9700\u8981 n / 32 \u6b21\u904d\u5386\u3002\u6240\u4ee5\u5143\u7d20\u6570\u91cf\u5145\u5206\u5927\u65f6 unordered_map \u53c8\u4f1a\u9000\u5316\u6210\u66b4\u529b\u904d\u5386\u7684 O(N) O(N) \u590d\u6742\u5ea6\uff0c\u6ee1\u8db3\u4e0d\u4e86\u6211\u4eec\u7528\u4ed6\u52a0\u901f\u67e5\u627e\u7684\u76ee\u7684\u3002 \u6876\u7684\u6570\u91cf\u76f8\u6bd4\u5143\u7d20\u7684\u6570\u91cf\u8d8a\u662f\u4e0d\u8db3\uff0c\u8d8a\u662f\u62e5\u6324\uff0c\u8d8a\u662f\u5bb9\u6613\u9000\u5316\u6210\u94fe\u8868\u3002 \u56e0\u6b64 C++ \u6807\u51c6\u5e93\u89c4\u5b9a\uff0c\u63d2\u5165\u65f6\uff0c\u5f53\u68c0\u6d4b\u5230\u5e73\u5747\u6bcf\u4e2a\u6876\u91cc\u90fd\u6709 1 \u4e2a\u5143\u7d20\u65f6\uff0c\u4e5f\u5c31\u662f\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u6570\u91cf\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\uff0c\u4e00\u6b21\u6027\u8ba9\u6876\u7684\u6570\u91cf\u6269\u5145 2 \u500d\uff0c\u5e76\u91cd\u65b0\u8ba1\u7b97\u6bcf\u4e2a\u5143\u7d20\u7684 hash \u6a21\uff08\u6876\u7f16\u53f7\uff09\u5168\u90e8\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u3002 \u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u7684\u6570\u91cf\u88ab\u79f0\u4e3a\u201c\u8d1f\u8f7d\u7387\uff08load factor\uff09\uff0c\u5bf9\u4e8e\u94fe\u8868\u6cd5\u7684\u54c8\u5e0c\u8868 unordered_map \u6765\u8bf4\uff0c\u8d1f\u8f7d\u7387\u53ef\u4ee5\u9ad8\u4e8e 1\uff1b\u5bf9\u4e8e\u7ebf\u6027\u5730\u5740\u6cd5\u7684 flat_hash_map \u5219\u6700\u9ad8\u4e3a 1\u3002C++ \u6807\u51c6\u5e93\u901a\u5e38\u7684 unordered_map \u5b9e\u73b0\u4e2d\uff0c\u8d1f\u8f7d\u7387\u9ad8\u4e8e 1 \u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\u3002\u53ef\u4ee5\u901a\u8fc7 .load_factor() \u51fd\u6570\u67e5\u8be2\u4e00\u4e2a unordered_map \u7684\u8d1f\u8f7d\u7387\u3002 template class unordered_map { vector>> buckets; // \u56e0\u4e3a\u9700\u8981\u52a8\u6001\u6269\u5bb9\uff0c\u6876\u6570\u7ec4\u53d8\u6210\u4e86\u52a8\u6001\u6570\u7ec4 vector size_t size = 0; // \u8bb0\u5f55\u5f53\u524d\u5bb9\u5668\u5171\u6709\u591a\u5c11\u4e2a\u5143\u7d20 void insert(pair kv) { if (size + 1 > buckets.size()) reserve(n); // \u5982\u679c\u63d2\u5165\u540e\u7684\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u5bb9\u91cf\uff0c\u5219\u6269\u5bb9 size_t h = hash(kv.first) % buckets.size(); buckets[h].push_front(kv); size++; // insert \u65f6 size \u81ea\u52a8\u52a0 1\uff0cerase \u65f6\u4e5f\u8981\u8bb0\u5f97\u51cf 1 } void reserve(size_t n) { if (n <= buckets.size()) return; // \u5982\u679c\u8981\u6c42\u7684\u5927\u5c0f\u5df2\u7ecf\u6ee1\u8db3\uff0c\u4e0d\u9700\u8981\u6269\u5bb9 buckets.resize(max(n, buckets.size() * 2)); // \u628a\u6876\u6570\u7ec4\u81f3\u5c11\u6269\u5927 2 \u500d\uff08\u907f\u514d\u91cd\u590d\u6269\u5bb9\uff09\uff0c\u81f3\u591a\u6269\u5230 n \u6b64\u5904\u7701\u7565 rehash \u7684\u5177\u4f53\u5b9e\u73b0 // \u6876\u7684\u6570\u91cf\u53d1\u751f\u53d8\u5316\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u8ba1\u7b97\u4e00\u904d\u6240\u6709\u5143\u7d20 hash \u7684\u6a21\uff0c\u5e76\u91cd\u65b0\u63d2\u5165 } }; \u6bcf\u4e2a key \u6240\u5728\u7684\u6876\u7f16\u53f7\u8ba1\u7b97\u516c\u5f0f\uff1abucket_index(key) = hash(key) % bucket_count() \u8fd8\u662f\u5b58\u5728\u95ee\u9898\uff0c\u521a\u521a\u7684 insert \u6839\u672c\u6ca1\u6709\u68c0\u6d4b\u8981\u63d2\u5165\u7684\u952e\u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e86\u3002\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u8fd8\u63d2\u5165\uff0c\u90a3\u5c31\u53d8\u6210 unordered_multimap \u4e86\uff01\u6211\u4eec\u662f\u666e\u901a\u7684\u9700\u8981\u53bb\u91cd\u7684 unordered_map\uff0c\u6240\u4ee5\u63d2\u5165\u65f6\u5148\u9700\u8981\u904d\u5386\u4e0b\u94fe\u8868\u68c0\u6d4b\u4e00\u4e0b\u3002 template class unordered_map { vector>> buckets; size_t size = 0; struct iterator { explicit iterator(pair &kv) { /* ... */ } // ... }; pair insert(pair kv) { if (size + 1 > buckets.size()) reserve(size + 1); size_t h = hash(kv.first) % buckets.size(); for (auto &kv2: buckets[h]) { if (kv.first == kv2.first) // \u68c0\u6d4b\u662f\u5426\u53d1\u751f\u4e86\u51b2\u7a81 return {iterator(kv2), false}; // \u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6307\u5411\u5df2\u5b58\u5728\u7684\u952e\u7684\u8fed\u4ee3\u5668 } buckets[h].push_front(kv); size++; return {iterator(buckets.front()), true}; // \u6ca1\u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6210\u529f\u63d2\u5165\u5143\u7d20\u7684\u8fed\u4ee3\u5668 } };","title":"\u54c8\u5e0c\u51b2\u7a81 (hash-collision)"},{"location":"stl_map/#unordered_map-map_1","text":"\u7528\u6cd5\u4e0a\uff0cunordered_map \u57fa\u672c\u4e0e map \u76f8\u540c\uff0c\u4ee5\u4e0b\u7740\u91cd\u4ecb\u7ecd\u4ed6\u4eec\u7684\u4e0d\u540c\u70b9\u3002","title":"unordered_map \u4e0e map \u7684\u5f02\u540c"},{"location":"stl_map/#1_1","text":"map \u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u987a\u5e8f\u6392\u5217\uff0c\u904d\u5386\u65f6\u4e5f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u6bd4\u5927\u5c0f\uff08std::less \u6216 <\uff09\u3002 unordered_map \u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\uff0c\u91cc\u9762\u5143\u7d20\u987a\u5e8f\u968f\u673a\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u54c8\u5e0c\u503c\u8ba1\u7b97\uff08std::hash\uff09\u548c\u5224\u65ad\u76f8\u7b49\uff08std::equal_to \u6216 ==\uff09\u3002 map \u4e2d\u7684\u5143\u7d20\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0cunordered_map \u91cc\u9762\u7684\u5143\u7d20\u662f\u968f\u673a\u7684\u3002 \u8fd9\u4e5f\u610f\u5473\u7740 std::set_union \u8fd9\u7c7b\u8981\u6c42\u8f93\u5165\u533a\u95f4\u6709\u5e8f\u7684 algorithm \u51fd\u6570\u65e0\u6cd5\u9002\u7528\u4e8e unordered_map/set\u3002","title":"\u533a\u522b 1\uff1a\u6709\u5e8f\u6027"},{"location":"stl_map/#hash-equal_to","text":"map \u53ea\u9700\u8981 K \u7c7b\u578b\u652f\u6301\u4e00\u4e2a less \u5c31\u80fd\u5de5\u4f5c\u3002 \u800c unordered_map \u9700\u8981 K \u652f\u6301\u7684 trait \u6709\u4e24\u4e2a\uff1ahash \u548c equal_to\u3002 unordered_map \u7684\u5b8c\u6574\u5f62\u6001\u662f\uff1a unordered_map, equal_to, allocator>> \u5176\u4e2d allocator \u6211\u4eec\u7167\u4f8b\u5148\u8df3\u8fc7\u4e0d\u8bb2\uff0c\u4e4b\u540e\u5206\u914d\u5668\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4ecb\u7ecd\u3002 hash \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u6c42\u952e\u7684\u54c8\u5e0c\u503c\uff1fhash \u4eff\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a K \u7c7b\u578b\u7684\u952e\uff0c\u8fd4\u56de\u4e00\u4e2a size_t\uff08\u5728 64 \u4f4d\u7cfb\u7edf\u4e0a\u662f\u4e2a\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff0c\u8868\u793a\u54c8\u5e0c\u503c\uff09\u3002 equal_to \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u5224\u65ad\u4e24\u4e2a\u952e\u76f8\u7b49\uff1f\u5982\u679c\u4e24\u4e2a\u952e\u5b8c\u5168\u76f8\u7b49\uff0c\u4ed6\u4f1a\u8fd4\u56de true\u3002 \u8fd9\u91cc\u5bf9 hash \u7684\u5b9e\u73b0\u53ea\u6709\u4e00\u4e2a\u8981\u6c42\uff0c \u5982\u679c\u4e24\u4e2a\u952e\u76f8\u7b49\uff0c\u5219\u4ed6\u4eec\u7684\u54c8\u5e0c\u5fc5\u5b9a\u4e5f\u76f8\u7b49\uff0c\u53cd\u4e4b\u5219\u4e0d\u4e00\u5b9a \u3002 \u8fd9\u4e2a\u5047\u8bbe\u6784\u6210\u4e86 unordered_map \u5f97\u4ee5\u9ad8\u6548\u7684\u57fa\u77f3\uff0c\u4ed6\u4f7f\u5f97 unordered_map \u53ef\u4ee5\u66f4\u5feb\u6392\u9664\u4e0d\u53ef\u80fd\u7684\u7b54\u6848\uff0c\u800c\u4e0d\u5fc5\u50cf vector \u7684\u67e5\u627e\u90a3\u6837\u9700\u8981\u53bb\u66b4\u529b\u904d\u5386\u5168\u90e8\u5143\u7d20\uff0c\u53ea\u9700\u8981\u904d\u5386\u54c8\u5e0c\u76f8\u7b49\u7684\u90a3\u4e00\u90e8\u5206\u5143\u7d20\u5c31\u591f\u4e86\u3002 template, // \u9ed8\u8ba4\u7684\u54c8\u5e0c\u51fd\u6570\u5b9e\u73b0\uff0c\u652f\u6301\u4e86 int, void *, string \u7b49\u7c7b\u578b typename _Pred = equal_to<_Key>, // \u9ed8\u8ba4\u7684 == \u8fd0\u7b97\u7b26 typename _Alloc = allocator>> class unordered_map \u6362\u8a00\u4e4b\uff0c\u53ea\u8981 unordered_map \u53d1\u73b0\u4e24\u4e2a\u952e\u4e0d\u76f8\u7b49\uff0c\u5c31\u4e0d\u7528\u518d\u505a\u5177\u4f53\u503c\u7684\u6bd4\u8f83\u4e86\uff0c\u4ed6\u4eec\u4e0d\u53ef\u80fd\u76f8\u7b49\u4e86\uff01","title":"hash \u548c equal_to"},{"location":"stl_map/#_67","text":"hash \u8fd4\u56de\u7684 size_t \u8fd9\u4e2a\u6574\u6570\u53ef\u4ee5\u7406\u89e3\u4e3a\u4e00\u4e2a\u5bf9\u4efb\u610f\u7c7b\u578b\u7684\u201c\u6458\u8981\u201d\u3002 \u628a\u4e00\u4e2a\u5f88\u590d\u6742\u7684\u7c7b\u578b\uff08\u4f8b\u5982 string\uff09\u538b\u7f29\u6210\u4e00\u4e2a unordered_map \u5f88\u8f7b\u6613\u5c31\u80fd\u6bd4\u8f83\u7684 size_t \u6574\u6570\uff0c\u6574\u6570\u6bd4\u8f83\u8d77\u6765\u5c31\u5f88\u5bb9\u6613\uff0c\u800c\u4e14\u8fd8\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff08string \u4e0d\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff09\u3002 \u8fd9\u79cd\u6458\u8981\u7684\u5173\u952e\u5728\u4e8e\u5982\u4f55\u628a\u4e00\u4e2a\u6781\u4e3a\u590d\u6742\u7684\u7c7b\u578b\u201c\u6620\u5c04\u201d\u5230\u5c0f\u5c0f\u7684 size_t \u4e0a\u53bb\uff0c\u5e76\u4e14\u5206\u5e03\u5f97\u5c3d\u53ef\u80fd\u5747\u5300\uff0c\u4e0d\u8981\u51b2\u7a81\u3002 \u8fd9\u5c31\u9700\u8981\u6211\u4eec\u628a\u8fd9\u4e2a\u6781\u4e3a\u590d\u6742\u7c7b\u578b\u7684\u6bcf\u4e2a\u6210\u5458\uff08\u5bf9 string \u800c\u8a00\u5c31\u662f\u6bcf\u4e2a\u5b57\u7b26\uff09\u90fd\u52a0\u5230\u6700\u7ec8\u7ed3\u679c\u7684\u8868\u8fbe\u5f0f\u4e2d\u3002 \u4ee5\u5b57\u7b26\u4e32\u7c7b\u578b string \u4e3a\u4f8b\uff0c\u5e38\u89c1\u7684\u4e00\u79cd\u751f\u6210\u201c\u6458\u8981\u201d\u7684\u65b9\u6cd5\u662f\uff0c\u7528\u4e00\u4e2a\u4efb\u610f\u7d20\u6570\u7684\u4e58\u65b9\u5e8f\u5217\u548c\u5404\u5b57\u7b26\u7684 ASCII \u7801\u505a\u70b9\u79ef\uff1a size_t hash_string(string const &s) { size_t h = 0; for (char c: s) { h = h * 37 + c; } return h; } \u4f8b\u5982\u5bf9\u4e8e\u5b57\u7b26\u4e32 \u201chello\u201d\uff0c\u5219 hash \u53ef\u4ee5\u751f\u6210\u8fd9\u6837\u4e00\u4e2a\u6458\u8981\uff1a size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u76f8\u5f53\u4e8e h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o \u4e5f\u6709\u5176\u4ed6\u66f4\u9ad8\u6548\u7684\u751f\u6210\u6458\u8981\u7684\u65b9\u6cd5\uff0c\u4f8b\u5982\u501f\u52a9\u4f4d\u8fd0\u7b97\u3002 \u751a\u81f3\u8fd8\u6709\u5077\u61d2\u76f4\u63a5\u62ff strlen \u5f53\u54c8\u5e0c\u51fd\u6570\u7684\u201c\u4e16\u754c\u4e0a\u6700\u597d\u7684\u54c8\u5e0c\u8868\u201d\uff0c\u6211\u4e0d\u8bf4\u662f\u8c01\u3002\uff08\u5176\u5b9e\u662f\u65e9\u671f PHP \u5566\uff09","title":"\u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3"},{"location":"stl_map/#_68","text":"size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u968f\u7740\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u589e\u52a0\uff0c\u8fd9\u4e2a h \u80af\u5b9a\u4f1a\u8d85\u8fc7 size_t \u7684\u8868\u793a\u8303\u56f4\uff0c\u4f46\u662f\u6ca1\u5173\u7cfb\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u7684\u4e58\u6cd5\u3001\u52a0\u6cd5\u6ea2\u51fa\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ed6\u4f1a\u81ea\u52a8 wrapping\uff08\u53d6\u5173\u4e8e 2^{64} 2^{64} \u7684\u6a21\uff09\uff0c\u4e5f\u5c31\u662f\u53ea\u4fdd\u7559\u4e58\u6cd5\u7ed3\u679c\u548c 2^64 \u53d6\u6a21\u7684\u90e8\u5206\u3002 \u53d6\u6a21\u4e5f\u662f\u5bf9\u54c8\u5e0c\u503c\u5e38\u89c1\u7684\u4e00\u4e2a\u64cd\u4f5c\uff0c\u53cd\u6b63\u54c8\u5e0c\u503c\u662f\u968f\u673a\u7684\uff0c\u53d6\u6a21\u4ee5\u540e\u4e5f\u662f\u968f\u673a\u7684\uff0c\u4f46\u662f\u7f29\u5c0f\u4e86\u8303\u56f4\u3002 \u57fa\u672c\u5047\u8bbe\uff1am \u8db3\u591f\u5c0f\u65f6\uff0c\u4e00\u4e2a\u5747\u5300\u7684\u5206\u5e03\u53d6\u4ee5 m \u7684\u6a21\u4ee5\u540e\u4ecd\u7136\u5e94\u8be5\u662f\u5747\u5300\u7684 unordered_map \u4e2d\u6876\u7684\u6570\u91cf\u662f\u6709\u9650\u7684\uff0c\u4e3a\u4e86\u628a\u8303\u56f4\u4ece 0 0 \u5230 2^{64} - 1 2^{64} - 1 \u7684\u54c8\u5e0c\u503c\u6620\u5c04\u4e3a 0 \u5230 bucket_count - 1 \u7684\u6876\u5e8f\u53f7\uff0c\u4ed6\u5185\u90e8\u4f1a\u628a\u952e\u7684\u54c8\u5e0c\u503c\u53d6\u4ee5\u6876\u6570\u91cf\u7684\u6a21\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u952e\u8981\u5b58\u50a8\u5230\u7684\u6876\u7684\u5e8f\u53f7\uff1a bucket_index = hash(key) % bucket_count","title":"\u81ea\u52a8\u53d6\u6a21"},{"location":"stl_map/#hash-trait","text":"std::hash \u5c31\u662f\u6807\u51c6\u5e93\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u7684\u4eff\u51fd\u6570\u7c7b\u4e86\uff0c\u4ed6\u548c std::less \u4e00\u6837\uff0c\u662f\u4e00\u4e2a trait \u7c7b\u3002 \u4e00\u4e9b\u5e38\u89c1\u7684\u7c7b\u578b\u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u9488\u5bf9\u81ea\u5b9a\u4e49\u7c7b\u578b\u6dfb\u52a0\u7279\u5316\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316 } }; template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u5bf9 T * \u7684\u504f\u7279\u5316 } }; std::hash \u9488\u5bf9\u6bcf\u4e2a\u4e0d\u540c\u7684\u7c7b\u578b\u505a\u4e86\u7279\u5316\uff0c\u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u8ba1\u7b97 string \u7c7b\u578b\u7684 hash \u65f6\uff1a string str = \"Hello, world\"; size_t h = hash()(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); \u6ce8\u610f\uff1a\u8fd9\u91cc\u6709\u4e24\u4e2a\u62ec\u53f7\uff0c\u7b2c\u4e00\u4e2a\u662f\u7a7a\u7684\u3002\u7b2c\u4e00\u4e2a\u62ec\u53f7\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u4e2a\u7528str\u4f5c\u4e3a\u5b9e\u53c2\u8c03\u7528\u4eff\u51fd\u6570\u7684 operator() \u3002\u5f53\u7136\u8fd8\u522b\u5fd8\u4e86\u7b2c\u4e00\u4e2a\u5c16\u62ec\u53f7\uff0c\u8fd9\u4e2a\u5c16\u62ec\u53f7\u91cc\u7684 string \u8868\u793a\u7684\u662f hash \u4eff\u51fd\u6570\u63a5\u4e0b\u6765\u8981\u63a5\u53d7\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u4e4b\u6240\u4ee5\u4f5c\u4e3a\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u800c\u4e0d\u662f\u6a21\u677f\u51fd\u6570\uff0c\u662f\u4e3a\u4e86\u65b9\u4fbf\u7279\u5316\u548c\u504f\u7279\u5316\u3002\u540c\u5b66\u4eec\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5199\u4e00\u4e2a\u8fd9\u6837\u7684\u51fd\u6570\uff0c\u7528\u8d77\u6765\u5c31\u4e0d\u7528\u6307\u5b9a\u7c7b\u578b\uff08\u5982\u8fd9\u91cc\u7684 string\uff09\u4e86\uff0c\u8ba9\u6a21\u677f\u51fd\u6570\u81ea\u52a8\u63a8\u5bfc\u53c2\u6570\u7c7b\u578b\uff08\u7c7b\u4f3c\u4e8e make_pair\uff09\uff1a template size_t do_hash(T const &t) { return hash()(t); } int main() { string str = \"Hello, world\"; size_t h = do_hash(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); } \"Hello, world\" \u7684\u54c8\u5e0c\u662f 14701251851404232991 \u5bf9\u4efb\u610f\u7c7b\u578b\u54c8\u5e0c\u7684\u7ed3\u679c\u90fd\u662f\u4e00\u4e2a size_t\uff0c\u5176\u5728 32 \u4f4d\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint32_t\uff0c\u5728\u6211\u4eec 64 \u4e3a\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint64_t\u3002\u9009\u62e9 size_t \u662f\u4e3a\u4e86\u80fd\u54c8\u5e0c\u4e86\u4ee5\u540e\u76f4\u63a5\u7528\u4e8e unordered_map \u4e2d\u6876\u7684\u7d22\u5f15\u3002 \u7531\u4e8e hash \u662f\u7528\u4f5c\u54c8\u5e0c\u8868\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7528\u4e8e\u52a0\u5bc6\u9886\u57df\uff08\u8bf7\u4f60\u79fb\u6b65 md5\uff09\uff0c\u6216\u662f\u7528\u4e8e\u968f\u673a\u6570\u751f\u6210\uff08\u8bf7\u79fb\u6b65 mt19937\uff09\uff0c\u56e0\u6b64\u5bf9\u4e8e\u4efb\u610f\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u6839\u636e\u4ed6\u751f\u6210\u4e00\u4e2a size_t \u7684\u54c8\u5e0c\u503c\u5373\u53ef\uff0c\u53ea\u8981\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5206\u5e03\u5747\u5300\u5373\u53ef\uff0c\u4e0d\u4e00\u5b9a\u8981\u6709\u968f\u673a\u6027\u3002\u4f8b\u5982\u6807\u51c6\u5e93\u5bf9 int \u7684 hash \u5b9e\u73b0\u5c31\u662f\u4e2a\u6052\u7b49\u51fd\u6570\u2014\u2014\u76f4\u63a5\u8fd4\u56de\u5176\u6574\u6570\u503c\uff0c\u4e0d\u7528\u505a\u4efb\u4f55\u8ba1\u7b97\uff1a template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316\u771f\u662f\u4ec0\u4e48\u4e5f\u4e0d\u505a\u5462\uff1f } }; \u800c\u5bf9\u4e8e\u4efb\u610f\u6307\u9488\u7684\u5b9e\u73b0\u5219\u662f\u76f4\u63a5\u628a\u6307\u9488 bit-cast \u6210 size_t\uff1a template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u6307\u9488\u5f3a\u5236\u8f6c\u6362\u4e3a\u6574\u6570 } }; int i = 42; int j = hash()(i); // \u6ca1\u60f3\u5230\u7f62\uff01\u6211\u7cfb\u6052\u7b49\u51fd\u6570\u54d2 print(i, j); 42 42 \u8bb0\u4f4f\uff0cstd::hash \u4e0d\u662f\u4e3a\u4e86\u52a0\u5bc6\u6216\u968f\u673a\u800c\u751f\u7684\uff0c\u4ed6\u7684\u529f\u80fd\u4ec5\u4ec5\u662f\u5c3d\u53ef\u80fd\u5feb\u901f\u5730\u628a\u4efb\u610f\u7c7b\u578b T \u6620\u5c04\u5230 size_t \u800c\u5df2\u3002 \u81f3\u4e8e\u8fd9\u5bf9 unordered_map \u7684\u6027\u80fd\u6709\u4f55\u5f71\u54cd\uff1f\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5f71\u54cd\uff0c\u9664\u975e\u8f93\u5165\u952e\u6545\u610f\u8bbe\u4e3a\u548c bucket_count \u540c\u6a21\uff0c\u6bd5\u7adf\u53cd\u6b63\u4f60\u4e5f\u65e0\u6cd5\u65ad\u5b9a\u8f93\u5165\u952e\u7684\u6392\u5e03\u6a21\u5f0f\uff0c\u4e0d\u8bba\u9009\u4ec0\u4e48\u54c8\u5e0c\u51fd\u6570\u53ea\u8981\u4fdd\u8bc1\u5747\u5300\u90fd\u662f\u53ef\u4ee5\u7684\u3002\u800c\u6052\u7b49\u51fd\u6570\u521a\u597d\u662f\u5747\u5300\u7684\uff0c\u53c8\u4e0d\u7528\u989d\u5916\u7684\u82b1\u91cc\u80e1\u54e8\u4f4d\u8fd0\u7b97\u6d6a\u8d39\u65f6\u95f4\uff0c\u53cd\u800c\u53ef\u80fd\u56e0\u4e3a\u952e\u6709\u5e8f\u800c\u63d0\u5347\u4e86\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u63d0\u5347\u4e86\u6027\u80fd\uff0c\u6240\u4ee5\u5404\u5927\u5382\u5546\u7684\u6807\u51c6\u5e93\u90fd\u662f\u8fd9\u4e48\u505a\u7684\u3002","title":"hash \u662f\u4e2a trait \u7c7b"},{"location":"stl_map/#2_1","text":"map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(1)+ O(1)+ \u590d\u6742\u5ea6\u7684\u3002 \u770b\u8d77\u6765 unordered_map \u66f4\u9ad8\u6548\uff1f\u90a3\u8fd8\u8981 map \u5e72\u4ec0\u4e48\uff1f\u5b8c\u5168\u4e0a\u4f4d\u66ff\u4ee3\u554a\uff1f \u4f46\u662f\u6211\u4eec\u8981\u6ce8\u610f\uff0c\u4e0a\u9762\u6240\u8bf4\u7684\u590d\u6742\u5ea6 O(1) O(1) \u53ea\u662f\u5e73\u5747\u4e0b\u6765\u7684\uff0c\u5e76\u4e0d\u4ee3\u8868\u6bcf\u4e00\u6b21 unordered_map \u63d2\u5165\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(1) O(1) \uff01\u6240\u4ee5\uff0c\u590d\u6742\u5ea6\u8868\u793a\u6cd5\u91cc\u7684\u8fd9\u4e2a + \u53f7\u5c31\u662f\u8fd9\u4e2a\u610f\u601d\uff0c\u4ee3\u8868\u6211\u8fd9\u4e2a\u590d\u6742\u5ea6\u53ea\u662f\u591a\u6b21\u8fd0\u884c\u53d6\u5e73\u5747\uff0c\u5982\u679c\u53ea\u8003\u8651\u5355\u6b21\u6700\u574f\u7684\u60c5\u51b5\uff0c\u53ef\u80fd\u66f4\u9ad8\u3002 map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u4e5f\u53ea\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u53ef\u4ee5\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u3002 \u5904\u7406\u5f88\u9ad8\u7684\u6570\u636e\u91cf\u65f6\uff0c\u8fd9\u4e00\u70b9\u6700\u574f\u7684\u60c5\u51b5\u4f1a\u88ab\u5e73\u644a\u6389\uff0cunordered_map \u66f4\u9ad8\u6548\u3002","title":"\u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6"},{"location":"stl_map/#_69","text":"\u6240\u4ee5 unordered_map \u4e0d\u7a33\u5b9a\uff0c\u867d\u7136\u5e73\u5747\u662f O(1) O(1) \u590d\u6742\u5ea6\uff0c\u4f46\u6700\u574f\u53ef\u8fbe\u5230 O(N) O(N) \u590d\u6742\u5ea6\u3002\u80cc\u540e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\u5462\uff1f \u539f\u6765 unordered_map \u548c vector \u4e00\u6837\uff0c\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u52a8\u6001\u6269\u5bb9\u7684\u5bb9\u5668\u3002 \u5982\u679c\u4e0d\u6269\u5bb9\uff0c\u90a3\u4e48\u5f53\u5f88\u591a\u5143\u7d20\u6324\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u94fe\u8868\u7684\u538b\u529b\u5c31\u4f1a\u53d8\u5927\uff0c\u4f1a\u5f88\u4f4e\u6548\uff0c\u56e0\u6b64 unordered_map \u5fc5\u987b\u6269\u5bb9\u3002\u4f46\u662f\u5728\u6269\u5bb9\u7684\u65f6\u5019\u662f\u9700\u8981\u8fdb\u884c rehash \u64cd\u4f5c\u7684\u3002\u4e00\u6b21\u6269\u5bb9\uff0c\u5c31\u9700\u8981\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e00\u904d\u3002 \u7ed3\u679c\u5c31\u662f unordered_map \u7684\u63d2\u5165\u5982\u679c\u6ca1\u89e6\u53d1 rehash\uff0c\u90a3\u5c31\u662f O(1) O(1) \u7684\u3002\u89e6\u53d1\u4e86\uff0c\u90a3\u5c31\u662f\u6700\u574f\u7684\u60c5\u51b5\uff0c O(N) O(N) \u7684\u3002\u4f46\u662f\u4e0d\u89e6\u53d1\u7684\u60c5\u51b5\u8fdc\u591a\u4e8e\u89e6\u53d1\u4e86\u7684\uff0c\u6240\u4ee5\u5e73\u5747\u4e0b\u6765\u8fd8\u662f O(1) O(1) \uff0c\u4e3a\u4e86\u63d0\u9192\u4eba\u4eec\u4ed6\u6700\u574f\u7684\u60c5\u51b5\uff0c\u6240\u4ee5\u5199\u4f5c O(1)+ O(1)+ \uff0c\u8bfb\u4f5c\u201c\u5e73\u644a O1\u201d\uff08Amortized Constant\uff09\u3002 \u6b64\u5916\uff0c\u4e0d\u4ec5 unordered_map \u7684\u63d2\u5165\u51fd\u6570\u662f O(1)+ O(1)+ \uff0c\u4ed6\u7684\u67e5\u8be2\u51fd\u6570\u4e5f\u662f O(1)+ O(1)+ \u3002\u4e3a\u4ec0\u4e48\u5462\uff1f\u8bbe\u60f3\u4f60\u5728\u7f16\u5199\u4e00\u4e2a\u5bcc\u8fde\u7f51\u670d\u52a1\u5668\uff0c\u5982\u679c\u9ed1\u5ba2\u5df2\u77e5\u4f60\u7684 hash \u51fd\u6570\uff0c\u90a3\u4ed6\u5c31\u53ef\u4ee5\u901a\u8fc7\u6784\u9020\u4e00\u7cfb\u5217\u7279\u6b8a\u8bbe\u8ba1\u597d\u7684 key\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u521a\u597d\u76f8\u7b49\uff08\u6216\u540c\u6a21\uff09\uff0c\u8fd9\u6837\u5c31\u4f7f\u5f97\u6240\u6709 key \u521a\u597d\u5168\u90e8\u843d\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u5bfc\u81f4 unordered_map \u9000\u5316\u6210\u7ebf\u6027\u7684\u94fe\u8868\uff0c\u6240\u6709\u7684\u67e5\u8be2\u548c\u63d2\u5165\u90fd\u53d8\u6210\u4e86\u8fd9\u4e00\u4e2a\u6876\u4e0a\u7684\u94fe\u8868\u904d\u5386\u64cd\u4f5c\uff0c\u590d\u6742\u5ea6\u8fbe\u5230\u6700\u574f\u7684 O(N) O(N) \uff0c\u8fd9\u4e00\u73b0\u8c61\u53eb\u505a hash \u9000\u5316\u3002 \u56e0\u6b64 hash \u51fd\u6570\u7684\u597d\u574f\u51b3\u5b9a\u7740 unordered_map \u6027\u80fd\uff0c\u5bf9\u4e8e\u5b89\u5168\u9886\u57df\u6765\u8bf4\uff0c\u8fd8\u8981\u4fdd\u8bc1 hash \u51fd\u6570\u65e0\u6cd5\u88ab\u9ed1\u5ba2\u7834\u89e3\u3002\u53ea\u8981 hash \u51fd\u6570\u8db3\u591f\u968f\u673a\uff0c\u5c31\u80fd\u4fdd\u8bc1\u952e\u4e0d\u51b2\u7a81\uff0c\u5c31\u5f88\u5feb\uff0c\u4e00\u65e6\u51fa\u73b0\u952e\u51b2\u7a81\u5c31\u4f1a\u53d8\u6162\u3002\u4f46\u9700\u8981\u9891\u7e41\u4f7f\u7528\u7684 hash \u51fd\u6570\u8ba1\u7b97\u96be\u5ea6\u53c8\u4e0d\u80fd\u592a\u5927\uff0c\u90a3\u53c8\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u56e0\u6b64 hash \u4e5f\u4e0d\u80fd\u592a\u8fc7\u590d\u6742\u3002 \u6807\u51c6\u5e93\u91cc\u5b58\u5728\u8fd9\u79cd\u201c\u5e73\u644a\u590d\u6742\u5ea6\u201d\u7684\u4f8b\u5b50\u8fd8\u6709\u5f88\u591a\uff0c\u4f8b\u5982 vector \u7684 push_back \u4e0d reserve \u7684\u8bdd\uff0c\u5c31\u662f O(1)+ O(1)+ \u7684\uff0c\u56e0\u4e3a\u4ed6\u9700\u8981\u52a8\u6001\u6269\u5bb9\u3002","title":"\u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a"},{"location":"stl_map/#_70","text":"\u4e00\u4e9b\u5b9e\u65f6\u6027\u8981\u6c42\u5f88\u9ad8\u7684\u9886\u57df\u5c31\u4e0d\u80fd\u7528 unordered_map\u3002\u4f8b\u5982\u4f60\u9020\u4e86\u4e2a\u706b\u7bad\uff0c\u89c4\u5b9a\uff1a\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u9700\u8981\u5728 1000 \u03bcs \u5185\u5bf9\u5916\u754c\u53d8\u5316\u505a\u51fa\u5b9e\u65f6\u53cd\u5e94\uff0c\u5982\u679c\u4e0d\u80fd\u53ca\u65f6\u505a\u51fa\u53cd\u5e94\uff0c\u706b\u7bad\u5c31\u4f1a\u505a\u6258\u9a6c\u65af\u56de\u65cb\u7ed9\u4f60\u770b\u3002 \u4f60\u5728\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u4e2d\u7528\u4e86 unordered_map\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u4e0d\u65ad\u8fd0\u884c\uff0c\u4ee5\u4fbf\u63a7\u5236\u706b\u7bad\u505a\u51fa\u6b63\u786e\u7684\u673a\u52a8\uff0c\u5bf9\u6297\u4fa7\u5411\u98ce\u5e72\u6270\u3002\u7b2c\u4e00\u6b21\u8fd0\u884c\u4ed6\u5728 180 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 250 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 245 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u9ad8\u6548\u3002 \u4f46\u662f\u7a81\u7136\u6709\u4e00\u6b21\uff0cunordered_map \u89c9\u5f97\u4ed6\u5185\u90e8\u201c\u6876\u592a\u4e71\u201d\u4e86\uff0c\u6025\u9700\u91cd\u65b0\u6269\u5bb9\u5e76 rehash \u4e00\u4e0b\u201c\u5fe7\u5316\u6027\u80fd\u201d\u3002\u7136\u540e\uff0c\u4ed6\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e86\u4e00\u904d\uff0c\u79fb\u52a8\u5b8c\u4e86\uff0c\u628a\u5904\u7406\u5b8c\u7684\u6570\u636e\u8fd4\u56de\u7ed9\u706b\u7bad\u59ff\u6001\u8c03\u63a7\u7cfb\u7edf\uff0c\u8ba4\u4e3a\u5927\u529f\u544a\u6210\u3002\u4f46\u5f53\u4ed6\u7741\u5f00\u773c\u775b\u4e00\u770b\uff0c\u521a\u60f3\u8981\u63a7\u5236\u4e00\u4e0b\u59ff\u6001\u5462\uff1f\u5374\u53d1\u73b0\u81ea\u5df1\u5df2\u7ecf\u5728\u505a\u6258\u9a6c\u65af\u56de\u65cb\u4e86\uff01\u539f\u6765\u6211\u8fd9\u4e00\u201c\u5fe7\u5316\u201d\u5c31\u5fe7\u4e86 4000 \u03bcs\uff0c\u8d85\u51fa\u4e86\u706b\u7bad\u5b9e\u65f6\u54cd\u5e94\u7684\u786c\u6027\u6307\u6807\uff0c\u5bfc\u81f4\u897f\u88c5\u9ab0\u5b50\u4eba\u5377\u6b3e\u8dd1\u8def\uff0c\u5c0f\u5f6d\u8001\u5e08\u7834\u4ea7\u3002 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u521b\u4e1a\uff0c\u8fd9\u6b21\u4ed6\u9009\u7528\u4e86\u7a33\u5b9a\u7684 map\uff0c\u7b2c\u4e00\u6b21\u4ed6\u5728 810 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 680 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 730 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u4f4e\u6548\u3002\u4f46\u662f\u4ed6\u6bcf\u4e00\u6b21\u90fd\u80fd\u6210\u529f\u5361\u70b9\u7ed9\u4f60\u5b8c\u6210\u4efb\u52a1\uff0c\u4ece\u6765\u4e0d\u4f1a\u7a81\u7136\u8d85\u8fc7 O(\\log N) O(\\log N) \uff0c\u4ed6\u7684\u6700\u574f\u60c5\u51b5\u662f\u53ef\u63a7\u7684\uff0c\u4ece\u800c\u907f\u514d\u4e86\u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb\u3002\u5c0f\u5f6d\u8001\u5e08\u6700\u7ec8\u521b\u4e1a\u6210\u529f\uff0c1000 \u5e74\u540e\uff0c\u6211\u53f8\u6210\u529f\u5efa\u9020\u5b8c\u6210 Type-II \u6587\u660e\u6240\u6025\u9700\u7684\u6234\u68ee\u7403\uff0c\u5411\u661f\u8fb0\u5927\u6d77\u8fdb\u519b\u3002 \u5bf9\u5b9e\u65f6\u6027\u8981\u6c42\u9ad8\u7684\u8fd9\u7c7b\u9886\u57df\u5305\u62ec\uff0c\u97f3\u89c6\u9891\uff0c\u9020\u706b\u7bad\uff0c\u91cf\u5316\u4ea4\u6613\u7b49\u3002\u8fd9\u7c7b\u4f4e\u5ef6\u8fdf\u4f4e\u541e\u5410\u91cf\u7684\u9886\u57df\u5bf9\u5e73\u644a\u590d\u6742\u5ea6\u5f88\u53cd\u611f\uff0c\u4ed6\u4eec\u53ea\u770b\u91cd\u6700\u574f\u7684\u590d\u6742\u5ea6\uff0c\u800c\u4e0d\u662f\u5e73\u5747\u7684\u3002 \u4f46\u5bf9\u4e8e\u4e3b\u6253\u4e00\u4e2a\u9ad8\u541e\u5410\u91cf\u65e0\u6240\u8c13\u5ef6\u8fdf\u7684\u79bb\u7ebf\u56fe\u5f62\u5b66\uff0c\u79bb\u7ebf\u79d1\u5b66\u8ba1\u7b97\uff0c\u5b9e\u65f6\u6027\u4e0d\u91cd\u8981\u7684\u751f\u6001\u5316\u53cd\u573a\u666f\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba4\u4e3a unordered_map \u7684\u5e73\u644a O(1)+ O(1)+ \u5c31\u662f\u6bd4 map \u9ad8\u6548\u7684\u3002","title":"\u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236"},{"location":"stl_map/#3","text":"map \u548c unordered_map \u90fd\u662f\u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\u624d\u4f1a\u5931\u6548\uff0c\u8fd9\u70b9\u76f8\u540c\u3002 \u4f46 unordered_map \u6269\u5bb9\u65f6\u5019\u7684 rehash \u64cd\u4f5c\u4f1a\u9020\u6210\u6240\u6709\u8fed\u4ee3\u5668\u5931\u6548\u3002 insert \u53ef\u80fd\u5bfc\u81f4 unordered_map \u6269\u5bb9\uff0c\u5176\u4ed6\u53ea\u8bfb\u64cd\u4f5c\u4e0d\u4f1a\u3002 \u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u88ab\u5220\u9664\u65f6\uff0c\u4e0d\u8bba map \u548c unordered_map \u90fd\u4f1a\u5931\u6548\u3002 unordered_map \u5728 insert \u65f6\u5982\u679c\u53d1\u751f\u6269\u5bb9\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u5931\u6548\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528 reserve \u907f\u514d insert \u65f6\u6269\u5bb9\u3002 \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 clear swap opeartor= rehash vector \u662f \u5426 \u662f - map \u662f \u5426 \u662f - unordered_map \u662f \u5426 \u662f - \u5bb9\u5668 find count at [] vector \u5426 \u5426 \u5426 \u5426 map \u5426 \u5426 \u5426 \u5426 unordered_map \u5426 \u5426 \u5426 \u662f\uff0c\u5982\u679c\u521b\u5efa\u4e86\u65b0\u5143\u7d20\u4e14 size / bucket_count > max_load_factor \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 push_back insert erase reserve vector \u662f\uff0c\u5982\u679c size > capacity \u662f\uff0c\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216 size > capacity \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u5143\u7d20\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684 \u662f map - \u5426 \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 - unordered_map - \u662f\uff0c\u5982\u679c size / bucket_count > max_load_factor \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 \u662f \u4e5f\u53ef\u4ee5\u67e5\u770b\u5b98\u65b9\u7248\u300a\u8fed\u4ee3\u5668\u5931\u6548\u8868\u300b\uff1ahttps://en.cppreference.com/w/cpp/container#Iterator_invalidation","title":"\u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6"},{"location":"stl_map/#load_factor","text":"\u8ba1\u7b97\u516c\u5f0f\uff1a\u8d1f\u8f7d\u56e0\u5b50(load_factor) = \u5f53\u524d\u5143\u7d20\u6570\u91cf(size) \u00f7 \u5f53\u524d\u6876\u7684\u6570\u91cf(bucket_count) \u63d2\u5165\u65b0\u5143\u7d20\u540e\uff0c\u5f53\u68c0\u6d4b\u5230\u8d1f\u8f7d\u56e0\u5b50\u5927\u4e8e\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4 1.0\uff09\u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fdb\u884c rehash \u64cd\u4f5c\u3002 \u4e3a\u4e86\u907f\u514d\u91cd\u590d\u5c0f\u89c4\u6a21\u6269\u5bb9\u6d6a\u8d39\u65f6\u95f4\uff0c\u8fd9\u6b21 rehash \u4f1a\u4e00\u6b21\u6027\u6269\u5bb9\u4e24\u500d\uff08\u8ddf vector \u7684 push_back \u6269\u5bb9\u7c7b\u4f3c\uff09\u3002 \u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 max_load_factor \u51fd\u6570\u8c03\u6574\u3002\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 load_factor \u51fd\u6570\u67e5\u8be2\u3002 \u76f4\u89c2\u7406\u89e3\uff1a\u5f53\u6bcf\u4e2a\u6876\u5e73\u5747\u90fd\u6709\u4e00\u4e2a\u5143\u7d20\u65f6\uff0cunordered_map \u5c31\u4f1a\u8ba4\u4e3a\u5df2\u7ecf\u5f88\u6ee1\u4e86\uff0c\u5c31\u4f1a\u6269\u5bb9\u5e76\u91cd\u65b0\u5206\u914d\u4f4d\u7f6e\u3002 \u7531\u4e8e\u9ed8\u8ba4\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u662f 1.0\uff0c\u6240\u4ee5\u6269\u5bb9\u6761\u4ef6\u7b49\u4ef7\u4e8e size > bucket_count","title":"\u8d1f\u8f7d\u7387\uff08load_factor\uff09"},{"location":"stl_map/#rehash","text":"\u5728\u64cd\u4f5c unordered_map \u5bb9\u5668\u8fc7\u7a0b\uff08\u5c24\u5176\u662f\u5411\u5bb9\u5668\u4e2d\u6dfb\u52a0\u65b0\u952e\u503c\u5bf9\uff09\u4e2d\uff0c\u4e00\u65e6\u5f53\u524d\u5bb9\u5668\u7684\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4\u503c\u4e3a 1.0\uff09\uff0c\u8be5\u5bb9\u5668\u5c31\u4f1a\u9002\u5f53\u589e\u52a0\u6876\u7684\u6570\u91cf\uff08\u901a\u5e38\u662f\u7ffb\u4e00\u500d\uff09\uff0c\u5e76\u81ea\u52a8\u6267\u884c rehash() \u6210\u5458\u65b9\u6cd5\uff0c\u91cd\u65b0\u8c03\u6574\u5404\u4e2a\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff08\u6b64\u8fc7\u7a0b\u53c8\u79f0\u201c\u91cd\u54c8\u5e0c\u201d\uff09\uff0c\u6b64\u8fc7\u7a0b\u5f88\u53ef\u80fd\u5bfc\u81f4\u4e4b\u524d\u521b\u5efa\u7684\u8fed\u4ee3\u5668\u5931\u6548\u3002 1 \u9664\u4e86\u6269\u5bb9\u65f6\u81ea\u52a8\u7684 rehash\uff0c\u786e\u8ba4\u6570\u636e\u63d2\u5165\u5b8c\u6bd5\u4e0d\u4f1a\u518d\u6539\u52a8\u65f6\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u6765\u4f18\u5316\u5bb9\u5668\u4e2d\u5143\u7d20\u7684\u6392\u5e03\uff0c\u63d0\u5347\u6027\u80fd\u3002 unordered_map umap; for (int i = 1; i <= 50; i++) { umap.emplace(i, i); } auto pair = umap.equal_range(49); //\u83b7\u53d6\u952e\u4e3a 49 \u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u533a\u95f4\uff0c\u7531\u4e8e\u4e0d\u662f multimap\uff0c\u533a\u95f4\u5927\u5c0f\u53ea\u80fd\u4e3a 0 \u6216 1 for (auto iter = pair.first; iter != pair.second; ++iter) { //\u8f93\u51fa pair \u8303\u56f4\u5185\u7684\u6bcf\u4e2a\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c cout << iter->first << '\\n'; } umap.rehash(10); //\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u91cd\u54c8\u5e0c\u4e3a 10 \u4e2a\u6876 for (auto iter = pair.first; iter != pair.second; ++iter) { // \u91cd\u54c8\u5e0c\u4e4b\u540e\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u4f1a\u53d1\u751f\u53d8\u5316 cout << iter->first << '\\n'; } 49 Segmentation fault (core dumped)","title":"rehash \u51fd\u6570"},{"location":"stl_map/#hash","text":"\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6620\u5c04\u8868 map \u53ea\u9700\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7684 less \u5373\u53ef\uff0c\u800c unordered_map \u9700\u8981\u54c8\u5e0c\u548c\u76f8\u7b49\u4e24\u4e2a trait\uff0c\u4ed6\u4eec\u5206\u522b\u540d\u53eb std::hash \u548c std::equal_to\u3002 \u867d\u7136\u4e24\u8005\u90fd\u662f\u4eff\u51fd\u6570\uff0c\u4f46\u4e5f\u6709\u5f88\u591a\u533a\u522b\uff1a hash \u53ea\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u800c equal_to \u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\u3002 hash \u8fd4\u56de size_t\uff0c\u800c equal_to \u8fd4\u56de bool \u7c7b\u578b\u3002 equal_to \u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u8c03\u7528\u8fd0\u7b97\u7b26 ==\u3002\u800c hash \u6ca1\u6709\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u4e5f\u6ca1\u76f8\u5e94\u7684\u8fd0\u7b97\u7b26\uff0c\u53ea\u80fd\u624b\u52a8\u7279\u5316\u3002 \u6b63\u56e0\u4e3a\u5982\u6b64\uff0c\u901a\u5e38\u6211\u4eec\u9700\u8981\u8ba9\u4e00\u4e2a\u7c7b\uff08\u4f8b\u5982 Student\uff09\u652f\u6301 equal_to \u6216 less \u8fd9\u4e9b\u6709\u76f8\u5e94\u8fd0\u7b97\u7b26\u7684\u4eff\u51fd\u6570\u65f6\uff0c\u76f4\u63a5\u5728\u7c7b\u578b\u5185\u90e8\u5b9a\u4e49 operator== \u6216 operator< \u5373\u53ef\uff0c\u800c hash \u5219\u662f\u53ea\u80fd\u7528\u7279\u5316\u7684\u65b9\u6cd5\u624d\u80fd\u652f\u6301\u4e0a\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template struct equal_to { bool operator()(T const &x, T const &y) const noexcept { return x == y; } }; \u6709\u4e9b\u7c7b\u578b\u80fd\u7528\u4f5c map \u7684\u952e\uff0c\u4f46\u4e0d\u80fd\u7528\u4f5c unordered_map \u7684\u952e\u3002\u8fd9\u662f\u56e0\u4e3a\u5077\u61d2\u7684\u6807\u51c6\u5e93\u6ca1\u5bf9\u4ed6\u4eec\u7684 hash \u7279\u5316\uff01 \u4f8b\u5982 tuple \u652f\u6301 < \u8fd0\u7b97\u7b26\uff0c\u652f\u6301 less\u3002 \u4f46\u662f tuple \u6ca1\u6709 hash \u7684\u7279\u5316\uff0c\u4e0d\u652f\u6301 hash\u3002 tuple tup; size_t h = hash>()(tup); // \u7f16\u8bd1\u671f\u62a5\u9519\uff1a\u67e5\u65e0\u6b64\u51fd\u6570\uff01 unordered_map>","title":"hash \u9700\u8981\u7279\u5316"},{"location":"stl_map/#tuple","text":"\u548c less \u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u662f\u6709\u4e09\u79cd\u89e3\u51b3\u65b9\u6848\uff1a \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u7279\u5316\uff0cequal_to \u7684\u7279\u5316 template <> struct std::hash { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; template <> struct std::equal_to { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u4e00\u4e2a equal_to \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u7136\u540e\u4f20\u5165 unordered_map \u505a\u6a21\u677f\u53c2\u6570 template <> struct HashStudent { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; struct EqualStudent { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u6ce8\uff1a\u5982\u679c Student \u5df2\u7ecf\u5b9a\u4e49\u4e86 operator== \uff0c\u5219\u8fd9\u91cc\u4e0d\u7528 EqualStudent\uff0c\u9ed8\u8ba4\u7684 equal_to \u4f1a\u81ea\u52a8\u8c03\u7528 == \u8fd0\u7b97\u7b26\u7684\u3002 \u5bf9\u4e8e tuple \u800c\u8a00\uff0ctuple \u5df2\u7ecf\u6709\u4e86 == \u8fd0\u7b97\u7b26\uff0c\u4e0d\u7528\u7279\u5316 equal_to \u4e86\uff0c\u53ea\u9700\u8981\u7279\u5316\u6216\u6307\u5b9a hash \u5373\u53ef template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; unordered_map, int> stutab;","title":"\u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570"},{"location":"stl_map/#_71","text":"template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); // \u628a\u4efb\u610f\u591a\u4e2a\u5143\u7d20\u54c8\u5e0c\u901a\u8fc7\u201c\u4f4d\u5f02\u6216(^)\u201d\u62fc\u51d1\u6210\u4e00\u4e2a\u5355\u72ec\u7684\u54c8\u5e0c } template struct std::hash> { size_t operator()(std::tuple const &x) const { // std::apply \u4f1a\u628a tuple \u91cc\u7684\u5143\u7d20\u5168\u90e8\u5c55\u5f00\u6765\u8c03\u7528 hash_combine\uff0c\u76f8\u5f53\u4e8e Python \u91cc\u7684 *args return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 106 \u8fd9\u91cc\u7684\u8ba1\u7b97\u662f\uff1a42 ^ 64 = 106\uff0c\u4f4d\u5f02\u6216\u7684\u77e5\u8bc6\u53ef\u4ee5\u53bb Bing \u641c\u7d22\u4e00\u4e0b\uff0c\u6216\u8005\u95ee\u4e00\u4e0b GPT\uff0cCS \u5b66\u751f\u5e94\u8be5\u90fd\u77e5\u9053\u7684\u3002","title":"\u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01"},{"location":"stl_map/#hash_combine","text":"\u4f46\u662f\u7b80\u7b80\u5355\u5355\u7528\u4e00\u4e2a\u4f4d\u5f02\u6216 ^ \u6765\u628a\u4e24\u4e2a\u6210\u5458\u7684\u54c8\u5e0c\u7ec4\u5408\u8d77\u6765\uff0c\u6709\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u5982\u679c tuple \u91cc\u7684\u4e24\u4e2a\u6210\u5458\u503c\u521a\u597d\u4e00\u6837\uff0c\u5219\u5176\u4e24\u4e2a\u54c8\u5e0c\u503c\u4e5f\u4f1a\u4e00\u6837\uff0c\u90a3\u4e48\u4ed6\u4eec\u901a\u8fc7\u4f4d\u5f02\u6216 ^ \u5408\u5e76\u7684\u7ed3\u679c\u5c31\u4f1a\u59cb\u7ec8\u4e3a 0\u3002 \u4f8b\u5982\u4e0d\u8bba (42, 42) \u8fd8\u662f (64, 64) \u8fd9\u4e24\u4e2a tuple\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u503c\u90fd\u4f1a\u4e3a 0\u3002\u660e\u660e\u5177\u4f53\u503c\u4e0d\u540c\u54c8\u5e0c\u503c\u5374\u76f8\u540c\uff0c\u8fd9\u5c31\u662f\u53d1\u751f\u4e86\u54c8\u5e0c\u51b2\u7a81\uff0c\u8fd9\u4f1a\u4e25\u91cd\u5f71\u54cd unordered_map \u7684\u6027\u80fd\uff0c\u662f\u5fc5\u987b\u907f\u514d\u7684\u3002 \u7528 + \u6765\u7ec4\u5408\u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u7b2c\u4e00\u4e2a\u6210\u5458\u521a\u597d\u662f\u53e6\u4e00\u4e2a\u7684\u76f8\u53cd\u6570\uff0c\u6216\u53ea\u8981\u662f\u4e24\u4e2a\u6570\u52a0\u8d77\u6765\u548c\u76f8\u7b49\uff0c\u5c31\u4f1a\u51b2\u7a81\u3002 \u4f8b\u5982\u5982\u679c\u6211\u4eec\u7528 unordered_map \u6784\u5efa\u4e00\u5f20\u5730\u56fe\u7684\u8bdd\uff0c\u5c31\u53d1\u73b0\u5f53\u73a9\u5bb6\u5728\u5f80\u659c\u4e0a\u65b9\u79fb\u52a8\u65f6\u5c31\u4f1a\u53d8\u5f97\u7279\u522b\u5361\u987f\uff0c\u539f\u6765\u662f\u56e0\u4e3a\u73a9\u5bb6\u7684\u5386\u53f2\u8f68\u8ff9\u521a\u597d\u662f\u4e00\u6761 y = x \u7684\u66f2\u7ebf\uff0c\u659c\u7387\u4e3a 1\uff0c\u7531\u4e8e\u6211\u4eec\u91c7\u7528 ^ \u6765\u7ec4\u5408\u54c8\u5e0c\uff0c\u5c31\u5bfc\u81f4\u521a\u597d\u8fd9\u6761\u7ebf\u4e0a\u6240\u6709\u7684\u70b9\u90fd\u4f1a\u584c\u7f29\u5230 0 \u53f7\u6876\u53bb\uff0c\u8ba9 unordered_map \u9000\u5316\u6210\u4e86 O(N) O(N) \u590d\u6742\u5ea6\u3002","title":"\u66f4\u597d\u7684 hash_combine"},{"location":"stl_map/#boosthash_combine","text":"template inline size_t hash_combine(Ts const &...ts) { size_t h = 0; ((h ^= std::hash()(ts) + 0x9e3779b9 + (h << 6) + (h >> 2)), ...); return h; } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 175247763666 \u53ef\u4ee5\u770b\u5230\u968f\u673a\u6027\u5927\u5927\u63d0\u5347\u4e86\u3002","title":"\u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5"},{"location":"stl_map/#_72","text":"\u7528 hash_combine \u6539\u8fdb\u521a\u521a Student \u7684\u54c8\u5e0c\u51fd\u6570\u3002 template <> struct std::hash { bool operator()(Student const &x) const { return hash_combine(hash()(x.name), hash(x.id), hash(x.sex)); } }; \u540c\u7406\u53ef\u5f97 array \u7684\u7279\u5316 template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u7d20\u6570\u4e58\u65b9\u6cd5\u6765\u63d0\u5347\u54c8\u5e0c\u51fd\u6570\u7684\u5747\u5300\u6027\u548c\u968f\u673a\u6027\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h = h * 18412483 + hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u6700\u9ad8\u7ea7\u7684\uff0c\u57fa\u4e8e\u4f4d\u8fd0\u7b97\u7684\uff0c\u6700\u9ad8\u6548\u7684\uff0cboost::hash_combine \u7684\u5b9e\u73b0\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t) + 0x9e3779b9 + (h << 6) + (h >> 2); } return h; } }; unordered_map, int> stutab;","title":"\u5e94\u7528"},{"location":"stl_map/#_73","text":"","title":"\u7ecf\u5178\u6848\u4f8b"},{"location":"stl_map/#map-function","text":"TODO","title":"map \u548c function \u7ed3\u5408\u4f7f\u7528"},{"location":"stl_map/#map-variant","text":"","title":"map \u548c variant \u7ed3\u5408\u4f7f\u7528"},{"location":"stl_map/#map-string_view","text":"","title":"map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b"},{"location":"stl_map/#c-api","text":"Student(Student &&) = delete; // \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u4e0b\u9762\u51e0\u4e2a\uff0c\u4e0d\u7528\u5199\u5168\uff1a // Student &operator=(Student &&) = delete; // Student(Student const &) = delete; // Student &operator=(Student const &) = delete; TODO","title":"\u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API"},{"location":"stl_map/#_74","text":"TODO","title":"\u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04"},{"location":"stl_map/#_75","text":"TODO","title":"\u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570"},{"location":"stl_map/#_76","text":"TODO","title":"\u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168"},{"location":"stl_map/#_77","text":"\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528 \u9a6c\u6876\u88c5\u9762\u5305 \u201c\u6790\u6784\u201d\u76f8\u4f9d1\u53f7 \u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55 \u770b\u5230\u8001\u9f20\ud83d\udca9\u8fc7\u6fc0\u53cd\u5e94 \u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b \u5c0f\u5b66\u751f\u65e9\u64cd\u6392\u961f \u5c0f\u9ec4\u82b1\u8868\u793a\u9ec4\u724c\u8b66\u544a \u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb http://c.biancheng.net/view/7236.html \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 https://en.cppreference.com/w/cpp/container/node_handle \u21a9 \u21a9 \u21a9 \u21a9","title":"\u672c\u671f\u5b5d\u70b9\u603b\u7ed3"},{"location":"symbols/","text":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage) \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 mq \u767d\u5728 \u5ddd\u4e0a \u66f0\uff1a \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u56e0\u4e3a Game \u5728\u6b64\u5904\u4e3a\u4e0d\u5b8c\u6574\u7c7b\u578b \u6211\u80fd\u660e\u767d\u5176\u610f\u601d\uff0c\u5b9a\u4e49\u4e00\u5b9a\u662f\u58f0\u660e\uff0c\u58f0\u660e\u5374\u4e0d\u4e00\u5b9a\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u7528\u4e86\uff1a\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u8bcd\u8bed\uff0c\u5f88\u4e13\u4e1a\u7684\u63aa\u8f9e\u3002 \u4e0d\u8fc7\u6211\u89c9\u5f97\u5927\u591a\u6570\u666e\u901a\u5f00\u53d1\u8005\u5e76\u4e0d\u591f\u6e05\u695a\u8fd9\u4e00\u70b9\uff0c\u770b\u5230\u8fd9\u6bb5\u6ce8\u91ca\u540c\u6837\u4f1a\u611f\u5230\u7591\u60d1\u3002 \u5728\u4ed6\u4eec\u773c\u91cc\u58f0\u660e\u548c\u5b9a\u4e49\u662f\u4e24\u79cd\u4e1c\u897f\uff0c\u6b64\u5904\u5982\u679c\u76f4\u63a5\u7528\u58f0\u660e\u5b83\u4eec\u53ef\u80fd\u5c31\u4e0d\u4f1a\u6709\u7406\u89e3\u95ee\u9898\u4e86\u3002\u4f8b\u5982\uff1a\u201c\u53ea\u662f\u58f0\u660e\uff0c\u4e0d\u662f\u5b9a\u4e49\u201d\u4e4b\u7c7b\u7684\u63aa\u8f9e\u3002 \u6216\u8bb8\u6211\u4eec\u5e94\u8be5\u8003\u8651\u5728\u4fdd\u8bc1\u4e13\u4e1a\u4ee5\u53ca\u4e25\u8c28\u7684\u60c5\u51b5\u4e0b\uff0c\u7a0d\u5fae\u8865\u5145\u89e3\u91ca\u4e00\u4e0b\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u7528\u8bcd\u3002 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage) \u51fd\u6570\u548c\u53d8\u91cf\uff0c\u5728\u5bf9\u5916\u7684\u53ef\u89c1\u6027\u8fd9\u65b9\u9762\uff0c\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u5916\u90e8\u94fe\u63a5 (ODR external linkage)\uff1a\u5bf9\u5176\u4ed6\u7ffb\u8bd1\u5355\u5143\u53ef\u89c1 \u5171\u4eab\u94fe\u63a5 (non-ODR external linkage) \u5185\u90e8\u94fe\u63a5 (internal linkage) \u65e0\u94fe\u63a5 (no linkage) \u51fd\u6570\u548c\u53d8\u91cf\u7684\u53ef\u89c1\u6027\u8fd9\u4e00\u5c5e\u6027\uff0c\u88ab C++ \u5b98\u65b9\u79f0\u4e3a\u94fe\u63a5\uff08linkage\uff09\uff0c\u662f\u56e0\u4e3a\u7b26\u53f7\u7684\u53ef\u89c1\u6027\u5904\u7406\u901a\u5e38\u662f\u94fe\u63a5\u5668\uff08ld\uff09\u8d1f\u8d23\u7684\uff0c\u4e0d\u540c\u7c7b\u578b\u94fe\u63a5\uff08linkage\uff09\u7684\u6548\u679c\uff0c\u5728\u94fe\u63a5\uff08link\uff09\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002 \u5b9a\u4e49\u5728\u5168\u5c40\uff08\u540d\u5b57\u7a7a\u95f4\uff09\u4e2d\u7684\u60c5\u51b5\uff1a int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int i; // \u53d8\u91cf\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d inline int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d \u5b9a\u4e49\u5728\u7c7b\uff08class\uff09\u4e2d\u7684\u60c5\u51b5\uff1a struct Class { int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u65e0\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d };","title":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"symbols/#_1","text":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage)","title":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"symbols/#_2","text":"mq \u767d\u5728 \u5ddd\u4e0a \u66f0\uff1a \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u56e0\u4e3a Game \u5728\u6b64\u5904\u4e3a\u4e0d\u5b8c\u6574\u7c7b\u578b \u6211\u80fd\u660e\u767d\u5176\u610f\u601d\uff0c\u5b9a\u4e49\u4e00\u5b9a\u662f\u58f0\u660e\uff0c\u58f0\u660e\u5374\u4e0d\u4e00\u5b9a\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u7528\u4e86\uff1a\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u8bcd\u8bed\uff0c\u5f88\u4e13\u4e1a\u7684\u63aa\u8f9e\u3002 \u4e0d\u8fc7\u6211\u89c9\u5f97\u5927\u591a\u6570\u666e\u901a\u5f00\u53d1\u8005\u5e76\u4e0d\u591f\u6e05\u695a\u8fd9\u4e00\u70b9\uff0c\u770b\u5230\u8fd9\u6bb5\u6ce8\u91ca\u540c\u6837\u4f1a\u611f\u5230\u7591\u60d1\u3002 \u5728\u4ed6\u4eec\u773c\u91cc\u58f0\u660e\u548c\u5b9a\u4e49\u662f\u4e24\u79cd\u4e1c\u897f\uff0c\u6b64\u5904\u5982\u679c\u76f4\u63a5\u7528\u58f0\u660e\u5b83\u4eec\u53ef\u80fd\u5c31\u4e0d\u4f1a\u6709\u7406\u89e3\u95ee\u9898\u4e86\u3002\u4f8b\u5982\uff1a\u201c\u53ea\u662f\u58f0\u660e\uff0c\u4e0d\u662f\u5b9a\u4e49\u201d\u4e4b\u7c7b\u7684\u63aa\u8f9e\u3002 \u6216\u8bb8\u6211\u4eec\u5e94\u8be5\u8003\u8651\u5728\u4fdd\u8bc1\u4e13\u4e1a\u4ee5\u53ca\u4e25\u8c28\u7684\u60c5\u51b5\u4e0b\uff0c\u7a0d\u5fae\u8865\u5145\u89e3\u91ca\u4e00\u4e0b\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u7528\u8bcd\u3002","title":"\u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406"},{"location":"symbols/#_3","text":"","title":"\u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027"},{"location":"symbols/#tu","text":"","title":"\u7ffb\u8bd1\u5355\u5143 (TU)"},{"location":"symbols/#linkage","text":"\u51fd\u6570\u548c\u53d8\u91cf\uff0c\u5728\u5bf9\u5916\u7684\u53ef\u89c1\u6027\u8fd9\u65b9\u9762\uff0c\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u5916\u90e8\u94fe\u63a5 (ODR external linkage)\uff1a\u5bf9\u5176\u4ed6\u7ffb\u8bd1\u5355\u5143\u53ef\u89c1 \u5171\u4eab\u94fe\u63a5 (non-ODR external linkage) \u5185\u90e8\u94fe\u63a5 (internal linkage) \u65e0\u94fe\u63a5 (no linkage) \u51fd\u6570\u548c\u53d8\u91cf\u7684\u53ef\u89c1\u6027\u8fd9\u4e00\u5c5e\u6027\uff0c\u88ab C++ \u5b98\u65b9\u79f0\u4e3a\u94fe\u63a5\uff08linkage\uff09\uff0c\u662f\u56e0\u4e3a\u7b26\u53f7\u7684\u53ef\u89c1\u6027\u5904\u7406\u901a\u5e38\u662f\u94fe\u63a5\u5668\uff08ld\uff09\u8d1f\u8d23\u7684\uff0c\u4e0d\u540c\u7c7b\u578b\u94fe\u63a5\uff08linkage\uff09\u7684\u6548\u679c\uff0c\u5728\u94fe\u63a5\uff08link\uff09\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002 \u5b9a\u4e49\u5728\u5168\u5c40\uff08\u540d\u5b57\u7a7a\u95f4\uff09\u4e2d\u7684\u60c5\u51b5\uff1a int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int i; // \u53d8\u91cf\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d inline int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d \u5b9a\u4e49\u5728\u7c7b\uff08class\uff09\u4e2d\u7684\u60c5\u51b5\uff1a struct Class { int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u65e0\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d };","title":"\u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage)"},{"location":"test_and_safe/","text":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09","title":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"test_and_safe/#_1","text":"","title":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/","text":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09 \u521b\u5efa\u7ebf\u7a0b TODO \u4e3a\u4ec0\u4e48\u6570\u636e\u7ade\u4e89 if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } auto it = table.find(\"\u5c0f\u5f6d\u8001\u5e08\"); if (it != table.end()) { return it->second; } else { return 0; } \u5c0f\u5f6d\u8001\u5e08\u5bf9\u8bdd\u4e00\u5219 \u5173\u4e8e SharedPtr \u7684\u539f\u5b50\u5b89\u5168\u5b9e\u73b0\u3002 \u5bf9\u8bdd\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/issues/4 \u4ee3\u7801\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/blob/main/SharedPtr.hpp sharedptr\u5f15\u7528\u8ba1\u6570\u51cf\u88ab\u5c01\u88c5\u6210\u5982\u4e0b\u7684\u51fd\u6570 void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u8be5if\u5757\u5148\u5224\u65ad\u539f\u59cb\u5f15\u7528\u8ba1\u6570\u662f\u5426\u7b49\u4e8e1\uff0c\u5982\u679c\u4e3a\u771f\u5219\u8fdb\u884cdelete\u3002\u7136\u800c\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u5e76\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002\u662f\u5426\u5b58\u5728\u8fd9\u6837\u4e00\u79cd\u60c5\u51b5\uff1a\u5224\u65ad\u6761\u4ef6\u6210\u7acb\uff0c\u4f46\u5728delete\u524d\u6709\u5176\u5b83\u7ebf\u7a0b\u7ed9\u5f15\u7528\u8ba1\u6570+1\uff1f\u6b64\u65f6\u8fdb\u884cdelete\u5c31\u51fa\u9519\u4e86\u5427 \u5c0f\u5f6d\u8001\u5e08 \u6ca1\u6709\u95ee\u9898\u7684\uff0c\u56e0\u4e3afetch_sub\u8fd4\u56de1\uff0c\u5b9e\u9645\u4e0a\u8bf4\u660e\u5f15\u7528\u8ba1\u6570\u5df2\u7ecf\u662f0\u4e86\uff0cfetch_sub\u8fd4\u56de\u7684\u662f\u201c\u65e7\u503c\u201d\uff0c\u76f8\u5f53\u4e8e\u540e\u7f6ei\u2013\uff0c\u77e5\u9053\u5427\u3002\u5982\u679c\u5df2\u7ecf\u4e3a0\uff0c\u90a3\u5c31\u6ca1\u6709\u4efb\u4f55\u5176\u4ed6\u4eba\u6301\u6709\u8be5\u6307\u9488\uff0c\u6211\u662f\u72ec\u5360\u7684\uff0c\u90a3\u968f\u4fbfdelete\u3002 \u8fd9\u6837\u5427\uff0c\u6211\u4e5f\u542c\u4e0d\u61c2\u4f60\u5728\u8bb2\u4ec0\u4e48\uff0c\u4f60\u6765\u5199\u4e00\u4efd\u4f60\u8ba4\u4e3a\u4f1a\u4ea7\u751f\u95ee\u9898\u7684\u4ee3\u7801\uff0c\u8ba9\u6211\u5206\u6790\u3002 \u540c\u5b66 \u6211\u8bbe\u60f3\u4e86\u5982\u4e0b\u7684\u4ee3\u7801\uff1a shared_ptr a = make_shared(); void fun1() { a = nullptr; // \u6790\u6784a } void func2() { auto b = a; // \u62f7\u8d1da\u5230b } int main(){ auto t1=std::thread(func1); auto t2=std::thread(func2); t1.join(); t2.join(); return 0; } \u5728\u8fd9\u6bb5\u4ee3\u7801\u4e2d\uff0c\u7ebf\u7a0b1\u6790\u6784a\uff0c\u800c\u7ebf\u7a0b2\u62f7\u8d1da\u5230b\u3002\u7531\u4e8e\u591a\u7ebf\u7a0b\u7684\u7f18\u6545\uff0c\u6211\u8ba4\u4e3a\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u7684\u60c5\u51b5\uff0c\u7ebf\u7a0b1\u6267\u884c\u5224\u65ad\u65f6 if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) \u7531\u4e8efunc2\u521a\u8fdb\u5165\u5c1a\u672a\u6267\u884c\u62f7\u8d1d\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u7b49\u4e8e1\u8fd8\u4e0d\u662f2\uff0c\u6240\u4ee5\u8be5\u5224\u65ad\u4e3atrue\u3002\u4e8e\u662f\uff0c\u7ebf\u7a0b1\u51c6\u5907\u6267\u884c delete this \u5c06_SpCounter\u91ca\u653e\uff0c\u5c31\u5728\u8fd9\u65f6\u7ebf\u7a0b2\u5c06func2\u5f7b\u5e95\u6267\u884c\u4e86\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u53c8\u4ece0\u53d8\u4e3a\u4e861\uff0c\u7136\u800c\u7ebf\u7a0b1\u5e76\u4e0d\u77e5\u9053\u8fd9\u4e2a\u53d8\u5316\uff0c\u5b83\u4ecd\u7136\u6309\u7167\u539f\u672c\u7684\u8f68\u8ff9\u53bb\u6267\u884cdelete this\u3002\u6240\u4ee5\u6211\u8ba4\u4e3a\u8fd9\u5c31\u51fa\u9519\u4e86\uff0c\u800c\u51fa\u9519\u7684\u539f\u56e0\u662f void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u6b64\u5904\u7684\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u800c\u975e\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002 \u5f88\u62b1\u6b49\u4e4b\u524d\u672a\u80fd\u53ca\u65f6\u56de\u590d \u5c0f\u5f6d\u8001\u5e08 \u662f\u7684\uff0c\u8fd9\u6bb5\u4ee3\u7801\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u7136\u800c C++ \u6807\u51c6\u53ea\u8981\u6c42\u4e86\uff1a - \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 - \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6211\u7684\u539f\u5b50\u53d8\u91cf\u5df2\u7ecf\u4fdd\u8bc1\u4e86 \u62f7\u8d1d+\u62f7\u8d1d \u7684\u5b89\u5168\uff0c\u7b26\u5408 C++ \u6807\u51c6\u7684\u8981\u6c42\u3002 \u6790\u6784+\u62f7\u8d1d \u7684\u60c5\u51b5\uff0cC++ \u6807\u51c6\u5c31\u5e76\u4e0d\u8981\u6c42\u5b89\u5168\uff0c\u6240\u4ee5\u6211\u7684 shared_ptr \u4e5f\u6ca1\u6709\u8d23\u4efb\u53bb\u4fdd\u8bc1\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u5b89\u5168\u3002 \u6bd4\u5982\u6807\u51c6\u4e0d\u8981\u6c42 vector \u7684 clear \u548c push_back \u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u90a3\u4e48\u6211\u5c31\u4e0d\u9700\u8981\u628a vector \u5b9e\u73b0\u4e3a\u5b89\u5168\u7684\u3002 \u5982\u679c\u6807\u51c6\u89c4\u5b9a\u4e86\u54ea\u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u6211\u518d\u53bb\u505a\u3002 \u6bd4\u5982\u6807\u51c6\u5c31\u89c4\u5b9a\u4e86 size \u548c data \u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u6211\u53ea\u9700\u8981\u7b26\u5408\u8fd9\u4e2a\u5c31\u53ef\u4ee5\u3002 \u6807\u51c6\u90fd\u6ca1\u6709\u89c4\u5b9a\u5fc5\u987b\u5b89\u5168\u7684\u60c5\u51b5\uff0c\u6211\u7684\u5bb9\u5668\u5982\u679c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6211\u4e0d\u8d1f\u8d23\u4efb\u3002 \u4f8b\u5982\uff0cC++ \u6807\u51c6\u5bf9 shared_ptr \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 C++ \u6807\u51c6\u5bf9 atomic> \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6240\u4ee5\uff0c\u53ea\u6709\u5f53\u6211\u662f\u5728\u5b9e\u73b0atomic_shared_ptr\u65f6\uff0c\u624d\u9700\u8981\u8003\u8651\u4f60\u8bf4\u7684\u8fd9\u79cd\u60c5\u51b5\uff0c\u800c\u6211\u73b0\u5728\u5b9e\u73b0\u7684\u662fshared_ptr\uff0c\u4e0d\u9700\u8981\u8003\u8651 \u6790\u6784+\u62f7\u8d1d \u7684\u5b89\u5168\u3002 \u4e3a\u4ec0\u4e48\u62f7\u8d1d+\u62f7\u8d1d\u662f\u5b89\u5168\u7684\uff1f\u6211\u600e\u4e48\u6ca1\u770b\u5230cppreference\u8bf4\uff1f\u8fd9\u5f88\u590d\u6742\uff0c\u662f\u53e6\u4e00\u53e5\u8bdd\u91cc\u900f\u9732\u7684\u901a\u7528\u89c4\u5219\uff0c\u9002\u7528\u4e8e\u6240\u6709\u5bb9\u5668\uff0c\u5305\u62ecshared_ptr\u3001unique_ptr\u3001vector\u7b49\u5168\u90e8\u7684\u5bb9\u5668\uff1a \u4e24\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4e00\u4e2a\u975econst\u6210\u5458\u51fd\u6570+\u4e00\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8fd9\u53e5\u8bdd\u81ea\u52a8\u9002\u7528\u4e8e\u6240\u6709\u7684\u5bb9\u5668\u4e86\uff0c\u6240\u4ee5\u4f60\u770b\u5230shared_ptr\u91cc\u6ca1\u6709\u8bf4\uff0c\u4f46\u662f\u6211\u77e5\u9053\u4ed6\u662f\u5728\u53e6\u4e00\u4e2a\u5173\u4e8e\u7ebf\u7a0b\u5b89\u5168\u7684\u9875\u9762\u4e0a\u3002 \u90a3\u4e48\u5f88\u660e\u663e\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570 shared_ptr(shared_ptr const &that) \u662fconst\u7684\uff08\u5bf9\u4e8e\u88ab\u62f7\u8d1d\u7684that\uff09\uff0c\u800c\u6790\u6784\u51fd\u6570\u90fd\u662f\u975econst\u7684\uff0c\u6240\u4ee5\u5982\u679c\u6ca1\u6709\u7279\u522b\u8bf4\u660e\uff0c\u4e00\u4e2a\u5bb9\u5668\u540c\u65f6\u8c03\u7528\u62f7\u8d1d+\u6790\u6784\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u800catomic_shared_ptr\u5c31\u5c5e\u4e8e\u7279\u522b\u8bf4\u660e\u4e86\uff0c\u6240\u4ee5\u4ed6\u7279\u522b\u5730\u540c\u65f6\u8bbf\u95eeconst\u548c\u975econst\u51fd\u6570\u662f\u5b89\u5168\u7684\u3002 \u5b8c\u6574\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u89c4\u5219\u8868\uff1a \u8bfb+\u8bfb=\u5b89\u5168 \u8bfb+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u5199+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u6240\u4ee5\u5b9e\u9645\u4e0asharedptr\u6240\u8c13\u7684\u201c\u7ebf\u7a0b\u5b89\u5168\u201d\uff0c\u53ea\u4e0d\u8fc7\u662f\u62f7\u8d1d+\u62f7\u8d1d\u8fd9\u4e00\u60c5\u51b5\u7684\u5b89\u5168\u548c\u62f7\u8d1d+\u6790\u6784\u4e0d\u540c shared_ptr \u5b9e\u4f8b\uff0c\u540c\u4e00\u4e2a shared_ptr \u7684\u5e76\u53d1\u975econst\u8bbf\u95ee\u662f\u6ca1\u4fdd\u8bc1\u7684\uff0c shared_ptr \u6307\u5411\u7684\u90a3\u4e2a T \u4e5f\u662f\u4e0d\u4fdd\u8bc1\u7684\uff08\u7531 T \u7684\u5b9e\u73b0\u8005\u201c\u4f60\u201d\u6765\u4fdd\u8bc1\uff09\u3002 shared_ptr \u4e0d\u662f\u6709\u4e09\u5c42\u5417\uff1f\u901a\u4fd7\u7684\u8bf4\u5c31\u662f\u4ed6\u53ea\u9700\u8981\u4fdd\u8bc1\u4e2d\u95f4\u8fd9\u5c42\u63a7\u5236\u5757\u7684\u7ebf\u7a0b\u5b89\u5168\u6027\uff0c\u4e0d\u4fdd\u8bc1 shared_ptr \u5bf9\u8c61\u548c T \u5bf9\u8c61\u7684\u5b89\u5168\u6027\u3002","title":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/#c","text":"","title":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/#_1","text":"TODO","title":"\u521b\u5efa\u7ebf\u7a0b"},{"location":"threading/#_2","text":"if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } auto it = table.find(\"\u5c0f\u5f6d\u8001\u5e08\"); if (it != table.end()) { return it->second; } else { return 0; }","title":"\u4e3a\u4ec0\u4e48\u6570\u636e\u7ade\u4e89"},{"location":"threading/#_3","text":"\u5173\u4e8e SharedPtr \u7684\u539f\u5b50\u5b89\u5168\u5b9e\u73b0\u3002 \u5bf9\u8bdd\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/issues/4 \u4ee3\u7801\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/blob/main/SharedPtr.hpp sharedptr\u5f15\u7528\u8ba1\u6570\u51cf\u88ab\u5c01\u88c5\u6210\u5982\u4e0b\u7684\u51fd\u6570 void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u8be5if\u5757\u5148\u5224\u65ad\u539f\u59cb\u5f15\u7528\u8ba1\u6570\u662f\u5426\u7b49\u4e8e1\uff0c\u5982\u679c\u4e3a\u771f\u5219\u8fdb\u884cdelete\u3002\u7136\u800c\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u5e76\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002\u662f\u5426\u5b58\u5728\u8fd9\u6837\u4e00\u79cd\u60c5\u51b5\uff1a\u5224\u65ad\u6761\u4ef6\u6210\u7acb\uff0c\u4f46\u5728delete\u524d\u6709\u5176\u5b83\u7ebf\u7a0b\u7ed9\u5f15\u7528\u8ba1\u6570+1\uff1f\u6b64\u65f6\u8fdb\u884cdelete\u5c31\u51fa\u9519\u4e86\u5427 \u5c0f\u5f6d\u8001\u5e08 \u6ca1\u6709\u95ee\u9898\u7684\uff0c\u56e0\u4e3afetch_sub\u8fd4\u56de1\uff0c\u5b9e\u9645\u4e0a\u8bf4\u660e\u5f15\u7528\u8ba1\u6570\u5df2\u7ecf\u662f0\u4e86\uff0cfetch_sub\u8fd4\u56de\u7684\u662f\u201c\u65e7\u503c\u201d\uff0c\u76f8\u5f53\u4e8e\u540e\u7f6ei\u2013\uff0c\u77e5\u9053\u5427\u3002\u5982\u679c\u5df2\u7ecf\u4e3a0\uff0c\u90a3\u5c31\u6ca1\u6709\u4efb\u4f55\u5176\u4ed6\u4eba\u6301\u6709\u8be5\u6307\u9488\uff0c\u6211\u662f\u72ec\u5360\u7684\uff0c\u90a3\u968f\u4fbfdelete\u3002 \u8fd9\u6837\u5427\uff0c\u6211\u4e5f\u542c\u4e0d\u61c2\u4f60\u5728\u8bb2\u4ec0\u4e48\uff0c\u4f60\u6765\u5199\u4e00\u4efd\u4f60\u8ba4\u4e3a\u4f1a\u4ea7\u751f\u95ee\u9898\u7684\u4ee3\u7801\uff0c\u8ba9\u6211\u5206\u6790\u3002 \u540c\u5b66 \u6211\u8bbe\u60f3\u4e86\u5982\u4e0b\u7684\u4ee3\u7801\uff1a shared_ptr a = make_shared(); void fun1() { a = nullptr; // \u6790\u6784a } void func2() { auto b = a; // \u62f7\u8d1da\u5230b } int main(){ auto t1=std::thread(func1); auto t2=std::thread(func2); t1.join(); t2.join(); return 0; } \u5728\u8fd9\u6bb5\u4ee3\u7801\u4e2d\uff0c\u7ebf\u7a0b1\u6790\u6784a\uff0c\u800c\u7ebf\u7a0b2\u62f7\u8d1da\u5230b\u3002\u7531\u4e8e\u591a\u7ebf\u7a0b\u7684\u7f18\u6545\uff0c\u6211\u8ba4\u4e3a\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u7684\u60c5\u51b5\uff0c\u7ebf\u7a0b1\u6267\u884c\u5224\u65ad\u65f6 if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) \u7531\u4e8efunc2\u521a\u8fdb\u5165\u5c1a\u672a\u6267\u884c\u62f7\u8d1d\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u7b49\u4e8e1\u8fd8\u4e0d\u662f2\uff0c\u6240\u4ee5\u8be5\u5224\u65ad\u4e3atrue\u3002\u4e8e\u662f\uff0c\u7ebf\u7a0b1\u51c6\u5907\u6267\u884c delete this \u5c06_SpCounter\u91ca\u653e\uff0c\u5c31\u5728\u8fd9\u65f6\u7ebf\u7a0b2\u5c06func2\u5f7b\u5e95\u6267\u884c\u4e86\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u53c8\u4ece0\u53d8\u4e3a\u4e861\uff0c\u7136\u800c\u7ebf\u7a0b1\u5e76\u4e0d\u77e5\u9053\u8fd9\u4e2a\u53d8\u5316\uff0c\u5b83\u4ecd\u7136\u6309\u7167\u539f\u672c\u7684\u8f68\u8ff9\u53bb\u6267\u884cdelete this\u3002\u6240\u4ee5\u6211\u8ba4\u4e3a\u8fd9\u5c31\u51fa\u9519\u4e86\uff0c\u800c\u51fa\u9519\u7684\u539f\u56e0\u662f void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u6b64\u5904\u7684\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u800c\u975e\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002 \u5f88\u62b1\u6b49\u4e4b\u524d\u672a\u80fd\u53ca\u65f6\u56de\u590d \u5c0f\u5f6d\u8001\u5e08 \u662f\u7684\uff0c\u8fd9\u6bb5\u4ee3\u7801\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u7136\u800c C++ \u6807\u51c6\u53ea\u8981\u6c42\u4e86\uff1a - \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 - \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6211\u7684\u539f\u5b50\u53d8\u91cf\u5df2\u7ecf\u4fdd\u8bc1\u4e86 \u62f7\u8d1d+\u62f7\u8d1d \u7684\u5b89\u5168\uff0c\u7b26\u5408 C++ \u6807\u51c6\u7684\u8981\u6c42\u3002 \u6790\u6784+\u62f7\u8d1d \u7684\u60c5\u51b5\uff0cC++ \u6807\u51c6\u5c31\u5e76\u4e0d\u8981\u6c42\u5b89\u5168\uff0c\u6240\u4ee5\u6211\u7684 shared_ptr \u4e5f\u6ca1\u6709\u8d23\u4efb\u53bb\u4fdd\u8bc1\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u5b89\u5168\u3002 \u6bd4\u5982\u6807\u51c6\u4e0d\u8981\u6c42 vector \u7684 clear \u548c push_back \u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u90a3\u4e48\u6211\u5c31\u4e0d\u9700\u8981\u628a vector \u5b9e\u73b0\u4e3a\u5b89\u5168\u7684\u3002 \u5982\u679c\u6807\u51c6\u89c4\u5b9a\u4e86\u54ea\u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u6211\u518d\u53bb\u505a\u3002 \u6bd4\u5982\u6807\u51c6\u5c31\u89c4\u5b9a\u4e86 size \u548c data \u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u6211\u53ea\u9700\u8981\u7b26\u5408\u8fd9\u4e2a\u5c31\u53ef\u4ee5\u3002 \u6807\u51c6\u90fd\u6ca1\u6709\u89c4\u5b9a\u5fc5\u987b\u5b89\u5168\u7684\u60c5\u51b5\uff0c\u6211\u7684\u5bb9\u5668\u5982\u679c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6211\u4e0d\u8d1f\u8d23\u4efb\u3002 \u4f8b\u5982\uff0cC++ \u6807\u51c6\u5bf9 shared_ptr \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 C++ \u6807\u51c6\u5bf9 atomic> \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6240\u4ee5\uff0c\u53ea\u6709\u5f53\u6211\u662f\u5728\u5b9e\u73b0atomic_shared_ptr\u65f6\uff0c\u624d\u9700\u8981\u8003\u8651\u4f60\u8bf4\u7684\u8fd9\u79cd\u60c5\u51b5\uff0c\u800c\u6211\u73b0\u5728\u5b9e\u73b0\u7684\u662fshared_ptr\uff0c\u4e0d\u9700\u8981\u8003\u8651 \u6790\u6784+\u62f7\u8d1d \u7684\u5b89\u5168\u3002 \u4e3a\u4ec0\u4e48\u62f7\u8d1d+\u62f7\u8d1d\u662f\u5b89\u5168\u7684\uff1f\u6211\u600e\u4e48\u6ca1\u770b\u5230cppreference\u8bf4\uff1f\u8fd9\u5f88\u590d\u6742\uff0c\u662f\u53e6\u4e00\u53e5\u8bdd\u91cc\u900f\u9732\u7684\u901a\u7528\u89c4\u5219\uff0c\u9002\u7528\u4e8e\u6240\u6709\u5bb9\u5668\uff0c\u5305\u62ecshared_ptr\u3001unique_ptr\u3001vector\u7b49\u5168\u90e8\u7684\u5bb9\u5668\uff1a \u4e24\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4e00\u4e2a\u975econst\u6210\u5458\u51fd\u6570+\u4e00\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8fd9\u53e5\u8bdd\u81ea\u52a8\u9002\u7528\u4e8e\u6240\u6709\u7684\u5bb9\u5668\u4e86\uff0c\u6240\u4ee5\u4f60\u770b\u5230shared_ptr\u91cc\u6ca1\u6709\u8bf4\uff0c\u4f46\u662f\u6211\u77e5\u9053\u4ed6\u662f\u5728\u53e6\u4e00\u4e2a\u5173\u4e8e\u7ebf\u7a0b\u5b89\u5168\u7684\u9875\u9762\u4e0a\u3002 \u90a3\u4e48\u5f88\u660e\u663e\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570 shared_ptr(shared_ptr const &that) \u662fconst\u7684\uff08\u5bf9\u4e8e\u88ab\u62f7\u8d1d\u7684that\uff09\uff0c\u800c\u6790\u6784\u51fd\u6570\u90fd\u662f\u975econst\u7684\uff0c\u6240\u4ee5\u5982\u679c\u6ca1\u6709\u7279\u522b\u8bf4\u660e\uff0c\u4e00\u4e2a\u5bb9\u5668\u540c\u65f6\u8c03\u7528\u62f7\u8d1d+\u6790\u6784\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u800catomic_shared_ptr\u5c31\u5c5e\u4e8e\u7279\u522b\u8bf4\u660e\u4e86\uff0c\u6240\u4ee5\u4ed6\u7279\u522b\u5730\u540c\u65f6\u8bbf\u95eeconst\u548c\u975econst\u51fd\u6570\u662f\u5b89\u5168\u7684\u3002 \u5b8c\u6574\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u89c4\u5219\u8868\uff1a \u8bfb+\u8bfb=\u5b89\u5168 \u8bfb+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u5199+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u6240\u4ee5\u5b9e\u9645\u4e0asharedptr\u6240\u8c13\u7684\u201c\u7ebf\u7a0b\u5b89\u5168\u201d\uff0c\u53ea\u4e0d\u8fc7\u662f\u62f7\u8d1d+\u62f7\u8d1d\u8fd9\u4e00\u60c5\u51b5\u7684\u5b89\u5168\u548c\u62f7\u8d1d+\u6790\u6784\u4e0d\u540c shared_ptr \u5b9e\u4f8b\uff0c\u540c\u4e00\u4e2a shared_ptr \u7684\u5e76\u53d1\u975econst\u8bbf\u95ee\u662f\u6ca1\u4fdd\u8bc1\u7684\uff0c shared_ptr \u6307\u5411\u7684\u90a3\u4e2a T \u4e5f\u662f\u4e0d\u4fdd\u8bc1\u7684\uff08\u7531 T \u7684\u5b9e\u73b0\u8005\u201c\u4f60\u201d\u6765\u4fdd\u8bc1\uff09\u3002 shared_ptr \u4e0d\u662f\u6709\u4e09\u5c42\u5417\uff1f\u901a\u4fd7\u7684\u8bf4\u5c31\u662f\u4ed6\u53ea\u9700\u8981\u4fdd\u8bc1\u4e2d\u95f4\u8fd9\u5c42\u63a7\u5236\u5757\u7684\u7ebf\u7a0b\u5b89\u5168\u6027\uff0c\u4e0d\u4fdd\u8bc1 shared_ptr \u5bf9\u8c61\u548c T \u5bf9\u8c61\u7684\u5b89\u5168\u6027\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u5bf9\u8bdd\u4e00\u5219"},{"location":"type_rich_api/","text":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u5982\u4f55\u5199\u51fa\u6613\u4e8e\u7ef4\u62a4\u7684\u4ee3\u7801\uff0c\u963b\u6b62\u72af\u9519\uff1f \u7c7b\u578b\u5c31\u662f\u6700\u597d\u7684\u6ce8\u91ca\uff01 Type is all you need \u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 \u2014 \u2014 \u2014 \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u2014 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u2014 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u2014 \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u2014 RAII \u5c01\u88c5 \u2014 \u2014 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 void foo(string name, int age, int phone, int address); foo(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 12345, 67890); \u75db\u70b9\uff1a\u53c2\u6570\u591a\uff0c\u7c7b\u578b\u76f8\u4f3c\uff0c\u5bb9\u6613\u987a\u5e8f\u5199\u9519\u800c\u81ea\u5df1\u4e0d\u5bdf\u89c9 \u5929\u4e66\uff1a\u9605\u8bfb\u4ee3\u7801\u65f6\u770b\u4e0d\u89c1\u53c2\u6570\u540d\uff0c\u4e0d\u6e05\u695a\u6bcf\u4e2a\u53c2\u6570\u5206\u522b\u4ee3\u8868\u4ec0\u4e48 \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void foo(FooOptions opts); foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .phone = 12345, .address = 67890}); \u2714\ufe0f \u4f18\u96c5\uff0c\u6bcf\u4e2a\u53c2\u6570\u8d1f\u8d23\u505a\u4ec0\u4e48\u4e00\u76ee\u4e86\u7136 \u2014 \u4e5f\u6709\u67d0\u4e9b\u5927\u5382\u63a8\u5d07\u6ce8\u91ca\u53c2\u6570\u540d\u6765\u589e\u5f3a\u53ef\u8bfb\u6027\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*age=*/24, /*phone=*/12345, /*address=*/67890); \u4f46\u6ce8\u91ca\u53ef\u4ee5\u9a97\u4eba\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*phone=*/12345, /*age=*/24, /*address=*/67890); \u8fd9\u91cc age \u548c phone \u53c2\u6570\u5199\u53cd\u4e86\uff01\u9605\u8bfb\u8005\u5982\u679c\u4e0d\u770b\u4e0b foo \u7684\u5b9a\u4e49\uff0c\u6839\u672c\u53d1\u73b0\u4e0d\u4e86 \u800c\u4ee3\u7801\u4e0d\u4f1a\uff1a // \u5373\u4f7f\u987a\u5e8f\u5199\u9519\uff0c\u53ea\u8981\u540d\u5b57\u5199\u5bf9\u4f9d\u7136\u53ef\u4ee5\u6b63\u5e38\u8fd0\u884c foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u603b\u4e4b\uff0c\u597d\u7684 API \u8bbe\u8ba1\u7edd\u4e0d\u4f1a\u7ed9\u4eba\u7559\u4e0b\u72af\u9519\u7684\u673a\u4f1a\uff01 \u2014 \u518d\u6765\u770b\u4e00\u4e2a\u573a\u666f\uff0c\u5047\u8bbefoo\u5185\u90e8\u9700\u8981\u628a\u6240\u6709\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570bar\uff1a void bar(int index, string name, int age, int phone, int address); void foo(string name, int age, int phone, int address) { bar(get_hash_index(name), name, age, phone, address); } \u75db\u70b9\uff1a\u4f60\u9700\u8981\u4e0d\u65ad\u5730\u590d\u5236\u7c98\u8d34\u6240\u6709\u8fd9\u4e9b\u53c2\u6570\uff0c\u975e\u5e38\u5bb9\u6613\u6284\u9519 \u75db\u70b9\uff1a\u4e00\u65e6\u53c2\u6570\u7c7b\u578b\u6709\u6240\u4fee\u6539\uff0c\u6216\u8005\u8981\u52a0\u65b0\u53c2\u6570\uff0c\u9700\u8981\u6bcf\u4e2a\u5730\u65b9\u90fd\u6539\u4e00\u4e0b \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void bar(int index, FooOptions opts); void foo(FooOptions opts) { // \u6240\u6709\u903b\u8f91\u4e0a\u76f8\u5173\u7684\u53c2\u6570\u5168\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u65b9\u4fbf\u4f7f\u7528\u66f4\u65b9\u4fbf\u9605\u8bfb bar(get_hash_index(opts.name), opts); } \u2714\ufe0f \u4f18\u96c5 \u2014 \u5f53\u8001\u677f\u8981\u6c42\u4f60\u589e\u52a0\u4e00\u4e2a\u53c2\u6570 sex\uff0c\u52a0\u5728 age \u540e\u9762\uff1a -void foo(string name, int age, int phone, int address); +void foo(string name, int age, int sex, int phone, int address); \u4f60\u624b\u5fd9\u811a\u4e71\u5730\u6253\u5f00\u6240\u6709\u8c03\u7528\u4e86 foo \u7684\u6587\u4ef6\uff0c\u53d1\u73b0\u6709\u5927\u91cf\u5730\u65b9\u9700\u8981\u4fee\u6539\u2026 \u800c\u4f18\u96c5\u7684 API \u603b\u8bbe\u8ba1\u5e08\u5c0f\u5f6d\u8001\u5e08\u53ea\u9700\u8f7b\u8f7b\u4fee\u6539\u4e00\u5904\uff1a struct FooOptions { string name; int age; int sex = 0; // \u4ee4 sex \u9ed8\u8ba4\u4e3a 0 int phone; int address; }; \u6240\u6709\u7684\u8001\u4ee3\u7801\u4f9d\u7136\u7167\u5e38\u8c03\u7528\u65b0\u7684 foo \u51fd\u6570\uff0c\u672a\u6307\u5b9a\u7684 sex \u4f1a\u5177\u6709\u7ed3\u6784\u4f53\u91cc\u5b9a\u4e49\u7684\u9ed8\u8ba4\u503c 0\uff1a foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u5f53\u4f60\u9700\u8981\u591a\u4e2a\u8fd4\u56de\u503c\u65f6\uff1a\u4e0d\u8981\u8fd4\u56de pair \u6216 tuple\uff01 \u4e00\u4e9b STL \u5bb9\u5668\u7684 API \u8bbe\u8ba1\u662f\u53cd\u9762\u5178\u578b\uff0c\u4f8b\u5982\uff1a std::pair insert(std::pair entry); \u7528\u7684\u65f6\u5019\u6bcf\u6b21\u90fd\u8981\u60f3\u4e00\u4e0b\uff0c\u5230\u5e95\u7b2c\u4e00\u4e2a\u662f bool \u8fd8\u662f\u7b2c\u4e8c\u4e2a\u662f bool \u6765\u7740\uff1f\u7136\u540e\u770b\u4e00\u773c IDE \u63d0\u793a\uff0c\u624d\u53cd\u5e94\u8fc7\u6765\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.first << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.second << '\\n'; first\uff1fsecond\uff1f\u8fd9\u7b97\u4ec0\u4e48\u9b3c\uff1f \u66f4\u597d\u7684\u505a\u6cd5\u662f\u8fd4\u56de\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; insert_result_t insert(std::pair entry); \u76f4\u63a5\u901a\u8fc7\u540d\u5b57\u8bbf\u95ee\u6210\u5458\uff0c\u8bed\u4e49\u6e05\u6670\u660e\u786e\uff0c\u6211\u7ba1\u4f60\u662f\u7b2c\u4e00\u4e2a\u7b2c\u4e8c\u4e2a\uff0c\u6211\u53ea\u60f3\u8981\u8868\u793a\u201c\u662f\u5426\u6210\u529f(success)\u201d\u7684\u90a3\u4e2a\u53d8\u91cf\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.success << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.position << '\\n'; \u6700\u597d\u5f53\u7136\u662f\u8fd4\u56de\u548c\u53c2\u6570\u7c7b\u578b\u90fd\u662f\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; struct map_entry_t { K key; V value; }; insert_result_t insert(map_entry_t entry); \u8fd9\u91cc\u8bf4\u7684\u90fd\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u4f60\u53ef\u80fd\u6682\u65f6\u4e0d\u4f1a\u8ba4\u540c\uff0c\u7b49\u4f60\u5927\u624b\u5927\u811a\u72af\u4e86\u51e0\u4e2a\u9519\u4ee5\u540e\uff0c\u4f60\u81ea\u7136\u4f1a\u5fc3\u670d\u53e3\u670d\u3002 \u5c0f\u5f6d\u8001\u5e08\u4ee5\u524d\u4e5f\u548c\u4f60\u4e00\u6837\u662f\u6307\u9488\u4ed9\u4eba\uff0c\u4e0d\u559c\u6b22\u5f3a\u7c7b\u578b\uff0c\u559c\u6b22 void * \u6ee1\u5929\u98de\uff0c\u7136\u540e\u968f\u4fbf\u6539\u4e24\u884c\u5c31\u8e66\u51fa\u4e2a Segmentation Fault\uff0c\u6307\u9488\u4e00\u65f6\u723d\uff0c\u8c03\u8bd5\u706b\u846c\u573a\uff0c\u7136\u540e\u624d\u5f00\u59cb\u53cd\u601d\u3002 STL \u4e2d\u4f9d\u7136\u5728\u5927\u91cf\u7528 pair \u662f\u56e0\u4e3a map \u5bb9\u5668\u51fa\u73b0\u7684\u5f88\u65e9\uff0c\u5386\u53f2\u539f\u56e0\u3002 \u6211\u4eec\u81ea\u5df1\u9879\u76ee\u7684 API \u5c31\u4e0d\u8981\u8bbe\u8ba1\u6210\u8fd9\u718a\u6837\u4e86\u3002 \u5f53\u7136\uff0c\u548c\u67d0\u4e9b\u4e8c\u7ea7\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u76f8\u6bd4 cudaError_t cudaMalloc(void **pret); \uff0c\u8fd4\u56de pair \u5df2\u7ecf\u7b97\u5148\u8fdb\u7684\u4e86 \u4f8b\u5982 C++17 \u4e2d\u7684 from_chars \u51fd\u6570\uff0c\u4ed6\u7684\u8fd4\u56de\u7c7b\u578b\u5c31\u662f\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct from_chars_result { const char *ptr; errc ec; }; from_chars_result from_chars(const char *first, const char *last, int &value); \u8fd9\u8bf4\u660e\u4ed6\u4eec\u4e5f\u5df2\u7ecf\u610f\u8bc6\u5230\u4e86\u4ee5\u524d\u52a8\u4e0d\u52a8\u8fd4\u56de pair \u7684\u8bbe\u8ba1\u662f\u6709\u95ee\u9898\u7684\uff0c\u5df2\u7ecf\u5728\u65b0\u6807\u51c6\u4e2d\u5f00\u59cb\u6539\u7528\u66f4\u597d\u7684\u8bbe\u8ba1\u3002 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u8fd9\u4e2a\u51fd\u6570\uff1a void foo(char *x); \u8fd9\u91cc\u7684 x \u6709\u53ef\u80fd\u662f\uff1a 0\u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u53ea\u8bfb\uff0c\u4f46\u662f\u4f5c\u8005\u5fd8\u4e86\u52a0 const \u6307\u5411\u5355\u4e2a\u5b57\u7b26\uff0c\u7528\u4e8e\u8fd4\u56de\u5355\u4e2a char\uff08\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\uff09 \u6307\u5411\u4e00\u4e2a\u5b57\u7b26\u6570\u7ec4\u7f13\u51b2\u533a\uff0c\u7528\u4e8e\u8fd4\u56de\u5b57\u7b26\u4e32\uff0c\u4f46\u7f13\u51b2\u533a\u5927\u5c0f\u7684\u786e\u5b9a\u65b9\u5f0f\u672a\u77e5 \u5982\u679c\u4f5c\u8005\u6ca1\u5199\u6587\u6863\uff0c\u53d8\u91cf\u540d\u53c8\u975e\u5e38\u542b\u7cca\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u8fd9\u4e2a x \u53c2\u6570\u8981\u600e\u4e48\u7528\u3002 \u7c7b\u578b\u5199\u7684\u597d\uff0c\u80fd\u8d77\u5230\u6ce8\u91ca\u7684\u4f5c\u7528\uff01 void foo(string x); \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\u4e86\uff0c\u5f88\u660e\u663e\uff0c\u662f\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u53c2\u6570\u3002 void foo(string &x); \u770b\u8d77\u6765\u662f\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u4f46\u662f\u901a\u8fc7\u5f15\u7528\u4f20\u53c2\u7684\u65b9\u5f0f\u6765\u8fd4\u56de\u7684 string foo(); \u901a\u8fc7\u5e38\u89c4\u65b9\u5f0f\u76f4\u63a5\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 void foo(vector x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7ec4\u6210\u7684\u6570\u7ec4\uff01 void foo(span x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\u5207\u7247\u3002 void foo(string_view x); \u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5207\u7247\uff0c\u53ef\u80fd\u662f\u4f5c\u8005\u60f3\u8981\u907f\u514d\u62f7\u8d1d\u5f00\u9500\u3002 \u2014 \u8fd8\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using ISBN = string; BookInfo foo(ISBN isbn); \u8fd9\u6837\u7528\u6237\u4e00\u770b\u5c31\u660e\u767d\uff0c\u8fd9\u4e2a\u51fd\u6570\u662f\u63a5\u6536\u4e00\u4e2a ISBN \u7f16\u53f7\uff08\u51fa\u7248\u520a\u7269\u90fd\u6709\u4e00\u4e2a\u8fd9\u79cd\u7f16\u53f7\uff09\uff0c\u8fd4\u56de\u5173\u4e8e\u8fd9\u672c\u4e66\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 \u5c3d\u7ba1\u51fd\u6570\u540d foo \u8ba9\u4eba\u6478\u4e0d\u7740\u5934\u8111\uff0c\u4f46\u4ec5\u51ed\u76f4\u89c2\u7684\u7c7b\u578b\u6807\u8bc6\uff0c\u6211\u4eec\u5c31\u80fd\u51fd\u6570\u529f\u80fd\u628a\u731c\u7684\u4e03\u4e03\u516b\u516b\u3002 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u6ce8\u610f\uff0c\u8fd9\u91cc foo \u8fd4\u56de\u4e86\u4e00\u4e2a\u6307\u9488\uff01 BookInfo * foo(ISBN isbn); \u4ed6\u4ee3\u8868\u4ec0\u4e48\u610f\u601d\u5462\uff1f \u6307\u5411\u4e00\u4e2a\u5185\u5b58\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u4e66\u76ee\u9879\uff0c\u7531 foo \u8d1f\u8d23\u7ba1\u7406\u8fd9\u7247\u5185\u5b58 \u8fd4\u56de\u4e00\u4e2a new \u51fa\u6765\u7684 BookInfo \u7ed3\u6784\u4f53\uff0c\u7531\u7528\u6237\u8d1f\u8d23 delete \u91ca\u653e\u5185\u5b58 \u662f\u5426\u8fd8\u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u627e\u4e0d\u5230\u7684\u60c5\u51b5\uff1f \u751a\u81f3\u6709\u53ef\u80fd\u8fd4\u56de\u7684\u662f\u4e00\u4e2a BookInfo \u6570\u7ec4\uff1f\u6307\u9488\u6307\u5411\u6570\u7ec4\u7684\u9996\u4e2a\u5143\u7d20\uff0c\u6570\u7ec4\u957f\u5ea6\u7684\u5224\u5b9a\u65b9\u5f0f\u672a\u77e5\u2026 \u592a\u591a\u6b67\u4e49\u4e86\uff01 BookInfo & foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u4f1a\u8d1f\u8d23\u7ba1\u7406 BookInfo \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f\uff0c\u7528\u6237\u83b7\u5f97\u7684\u53ea\u662f\u4e00\u4e2a\u4e34\u65f6\u7684\u5f15\u7528\uff0c\u5e76\u4e0d\u6301\u6709\u6240\u6709\u6743\u3002 \u5f15\u7528\u7684\u7279\u70b9\uff1a \u4e00\u5b9a\u4e0d\u4f1a\u662f NULL\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de NULL \u7684\u7591\u8651\uff09 \u65e0\u6cd5 delete \u4e00\u4e2a\u5f15\u7528\uff08\u6392\u9664\u53ef\u80fd\u9700\u8981\u7528\u6237\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u7684\u7591\u8651\uff09 \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de\u6570\u7ec4\u9996\u5143\u7d20\u6307\u9488\u7684\u7591\u8651\uff09 \u6539\u7528\u5f15\u7528\u8fd4\u56de\u503c\uff0c\u4e00\u4e0b\u5b50\u601d\u8def\u5c31\u6e05\u6670\u4e86\u5f88\u591a\u3002\u6ca1\u6709\u90a3\u4e48\u591a\u6000\u7591\u548c\u731c\u6d4b\u4e86\uff0c\u7528\u9014\u5355\u4e00\uff0c\u7528\u6cd5\u660e\u786e\uff0c\u5f15\u7528\u771f\u662f\u7edd\u7edd\u5b50\u3002 std::unique_ptr foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684 BookInfo\uff0c\u5e76\u628a\u751f\u547d\u5468\u671f\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u7528\u6237\u3002 unique_ptr \u7684\u7279\u70b9\uff1a \u72ec\u5360\u6240\u6709\u6743\uff0c\u4e0d\u4f1a\u4e0e\u5176\u4ed6\u7ebf\u7a0b\u5171\u4eab\uff08\u6392\u9664\u53ef\u80fd\u591a\u7ebf\u7a0b\u7ade\u4e89\u7684\u7591\u8651\uff09 \u751f\u547d\u5468\u671f\u5df2\u7ecf\u79fb\u4ea4\u7ed9\u7528\u6237\uff0cunique_ptr \u53d8\u91cf\u79bb\u5f00\u7528\u6237\u7684\u4f5c\u7528\u57df\u540e\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u65e0\u9700\u624b\u52a8 delete \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u5982\u679c\u8981\u8868\u793a\u6570\u7ec4\uff0c\u4f1a\u7528 unique_ptr \u6216\u8005 vector \uff09 \u4f46\u662f unique_ptr \u6709\u4e00\u4e2a\u81f4\u547d\u7684\u7126\u8651\u70b9\uff1a\u4ed6\u53ef\u4ee5\u4e3a NULL\uff01 \u6240\u4ee5\u5f53\u4f60\u770b\u5230\u4e00\u4e2a\u51fd\u6570\u8fd4\u56de unique_ptr \u6216 shared_ptr\uff0c\u5c3d\u7ba1\u51cf\u5c11\u4e86\u5f88\u591a\u7684\u7591\u8651\uff0c\u4f46\u201c\u53ef\u80fd\u4e3aNULL\u201d\u7684\u62c5\u5fe7\u4ecd\u7136\u5b58\u5728\uff01 \u8981\u4e48 foo \u7684\u4f5c\u8005\u5728\u6ce8\u91ca\u6216\u6587\u6863\u91cc\u5199\u660e\uff0c\u201cfoo \u4e0d\u4f1a\u8fd4\u56de NULL\u201d\u6216\u8005\u201cfoo \u627e\u4e0d\u5230\u65f6\u4f1a\u8fd4\u56de NULL\u201d\uff0c\u6253\u6d88\u4f60\u7684\u7591\u8651\u3002 \u4f46\u6211\u4eec\u7684\u8bc9\u6c42\u662f\u901a\u8fc7\u7c7b\u578b\uff0c\u4e00\u773c\u5c31\u80fd\u770b\u51fa\u51fd\u6570\u6240\u6709\u7684\u53ef\u80fd\u6027\uff0c\u800c\u4e0d\u8981\u53bb\u4f9d\u8d56\u53ef\u80fd\u9a97\u4eba\u7684\u6ce8\u91ca\u3002 \u4e3a\u6b64\u5fae\u8f6f\u5b9e\u73b0\u4e86 gsl \u5e93\uff0c\u901a\u8fc7\u7c7b\u578b\u4fee\u9970\u89e3\u51b3\u6307\u9488\u7c7b\u8bed\u4e49\u542b\u7cca\u4e0d\u6e05\u7684\u95ee\u9898\uff1a \u4ed6\u89c4\u5b9a\uff0c\u6240\u6709\u5957\u4e86\u4e00\u5c42 gsl::not_null \u7684\u539f\u59cb\u6307\u9488\u6216\u667a\u80fd\u6307\u9488\uff0c\u91cc\u9762\u90fd\u5fc5\u7136\u4e0d\u4f1a\u4e3a NULL\u3002 \u5728 not_null \u7c7b\u7684\u6784\u9020\u51fd\u6570\u4e2d\uff0c\u6709\u76f8\u5e94\u7684\u65ad\u8a00\u68c0\u67e5\u4f20\u5165\u7684\u6307\u9488\u662f\u5426\u4e3a\u7a7a\uff0c\u5982\u679c\u4e3a\u7a7a\u4f1a\u76f4\u63a5\u62a5\u9519\u9000\u51fa\u3002 gsl::not_null p = nullptr; // \u7f16\u8bd1\u671f\u62a5\u9519\uff0c\u56e0\u4e3a\u4ed6\u91cc\u9762\u5199\u7740 not_null(nullptr_t) = delete; gsl::not_null p = fopen(...); // \u5982\u679c fopen \u6253\u5f00\u5931\u8d25\uff0c\u4e14\u4e3a Debug \u6784\u5efa\uff0c\u8fd0\u884c\u65f6\u4f1a\u89e6\u53d1\u65ad\u8a00\u9519\u8bef \u4fee\u6539\u540e\u7684\u51fd\u6570\u63a5\u53e3\u5982\u4e0b\uff1a gsl::not_null> foo(ISBN isbn); \u56e0\u4e3a gsl::not_null \u7684\u6784\u9020\u51fd\u6570\u4e2d\u4f1a\u68c0\u6d4b\u7a7a\u6307\u9488\uff0c\u5c31\u5411\u7528\u6237\u4fdd\u8bc1\u4e86\u6211\u8fd4\u56de\u7684\u4e0d\u4f1a\u662f NULL\u3002 \u4f46\u662f\uff0c\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u4f60\u5982\u679c\u8981\u8f6c\u79fb\u6240\u6709\u6743\u7684\u8bdd\uff0c\u6211\u76f4\u63a5\u8fd4\u56de BookInfo \u672c\u8eab\u4e0d\u5c31\u884c\u4e86\uff1f \u9664\u975e BookInfo \u7279\u522b\u5927\uff0c\u5927\u5230\u79fb\u52a8\u8fd4\u56de\u7684\u5f00\u9500\u90fd\u4e0d\u5f97\u4e86\u3002 \u76f4\u63a5\u8fd4\u56de\u7c7b\u578b\u672c\u8eab\uff0c\u5c31\u662f\u4e00\u5b9a\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u7684\uff0c\u4e14\u4e5f\u80fd\u8bf4\u660e\u79fb\u4ea4\u4e86\u5bf9\u8c61\u6240\u6709\u6743\u7ed9\u7528\u6237\u3002 BookInfo foo(ISBN isbn); \u2014 \u5176\u5b9e GSL \u91cc\u5927\u91cf\u90fd\u662f\u8fd9\u79cd\u53ef\u6709\u53ef\u65e0\u7684\u73a9\u610f\uff0c\u6bd4\u5982 C++20 \u5df2\u7ecf\u6709\u4e86 std::span \u548c std::byte\uff0c\u4f46\u662f GSL \u8fd8\u7ed9\u4f60\u5f04\u4e86\u4e2a gsl::span \u548c gsl::byte\uff0c\u4e3b\u8981\u662f\u4e3a\u4e86\u517c\u5bb9\u4f4e\u7248\u672c\u7f16\u8bd1\u5668\uff0c\u5982\u679c\u4f60\u5728\u65b0\u9879\u76ee\u91cc\u80fd\u76f4\u63a5\u7528\u4e0a C++20 \u6807\u51c6\u7684\u8bdd\uff0c\u4e2a\u4eba\u4e0d\u662f\u5f88\u63a8\u8350\u518d\u53bb\u7528\u4e86\u3002 \u518d\u6bd4\u5982 gsl::czstring \u662f const char * \u7684\u7c7b\u578b\u522b\u540d\uff0c\u660e\u786e\u8868\u793a\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\uff0c\u4e3a\u7684\u662f\u548c\u201c\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u201d\u533a\u5206\u5f00\u6765\uff0c\u6709\u5fc5\u8981\u5417\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u6211\u4eec\u73b0\u5728 const char * \u57fa\u672c\u4e0a\u5c31\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\u4e00\u79cd\u7528\u6cd5\uff0c\u800c\u4e14\u6211\u4eec\u5927\u591a\u4e5f\u90fd\u662f\u7528 string \u5c31\u53ef\u4ee5\u4e86\uff0cconst char * \u53c8\u4e0d\u5b89\u5168\uff0c\u53c8\u8bed\u4e49\u6a21\u68f1\u4e24\u53ef\uff0c\u4f55\u5fc5\u518d\u53bb\u4e3a\u4e86\u7528\u5b83\u4e13\u95e8\u5f15\u5165\u4e2a\u5e93\uff0c\u6574\u4e2a\u7c7b\u578b\u522b\u540d\u5462\uff1f using czstring = const char *; void foo(czstring s) { // \u53d1\u660e GSL \u7684\u4eba\u771f\u662f\u4e2a\u5929\u624d\uff01 if (s == \"\u5c0f\u5f6d\u8001\u5e08\") // \u9519\u8bef\uff01 if (strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u9519\u8bef\uff01 if (!strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u7ec8\u4e8e\u6b63\u786e // \u7136\u800c\u6211\u5b8c\u5168\u53ef\u4ee5\u76f4\u63a5\u7528 string\uff0c== \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u80fd\u76f4\u63a5\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9 // \u8fd8\u80fd\u968f\u65f6\u968f\u5730 substr \u5207\u7247\uff0cfind \u67e5\u627e\uff0csize \u5e38\u6570\u590d\u6742\u5ea6\u67e5\u5927\u5c0f } \u4f7f\u7528\u5404\u5f0f\u5404\u6837\u529f\u80fd\u660e\u786e\u7684\u7c7b\u578b\u548c\u5bb9\u5668\uff0c\u6bd4\u5982 string\uff0cvector\uff0c\u6216\u5f15\u7528\u3002 \u800c\u4e0d\u662f\u529f\u80fd\u592a\u591a\u7684\u6307\u9488\uff0c\u8ba9\u7528\u6237\u5b66\u4e60\u4f60\u7684 API \u65f6\u4ea7\u751f\u8bef\u89e3\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u5982\u679c\u9700\u8981\u6307\u9488\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 const \u9650\u5b9a\uff0c\u6765\u544a\u8bc9\u7528\u6237\u8fd9\u4e2a\u6307\u9488\u662f\u53ea\u8bfb\u7684\u8fd8\u662f\u53ef\u5199\u7684\u3002 \u603b\u4e4b\uff0c\u4ee3\u7801\u4e0d\u4f1a\u6492\u8c0e\uff0c\u4ee3\u7801\u5c42\u9762\u80fd\u7981\u6b62\u7684\uff0c\u80fd\u5c3d\u91cf\u9650\u5236\u7528\u6cd5\u7684\uff0c\u5c31\u4e0d\u8981\u7528\u6ce8\u91ca\u548c\u6587\u6863\u53bb\u534f\u5546\u89e3\u51b3\u3002 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u5047\u8bbe\u4f60\u6b63\u5728\u5b66\u4e60\u8fd9\u4e2a Linux \u7cfb\u7edf API \u51fd\u6570\uff1a ssize_t read(int fd, char *buf, size_t len); // fd - \u6587\u4ef6\u53e5\u67c4\uff0cint \u7c7b\u578b \u4f46\u662f\u4f60\u6ca1\u6709\u770b\u4ed6\u7684\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u548c\u540d\u5b57\u3002\u4f60\u662f\u8fd9\u6837\u8c03\u7528\u7684\uff1a int fd = open(...); char buf[32]; read(32, buf, fd); char buf[32]; read(32, buf, fd); \u4f60\u8fd9\u91cc\u7684 32 \u672c\u610f\u662f\u7f13\u51b2\u533a\u7684\u5927\u5c0f\uff0c\u5374\u4e0d\u5e78\u5730\u548c fd \u53c2\u6570\u5199\u9519\u4e86\u4f4d\u7f6e\uff0c\u800c\u7f16\u8bd1\u5668\u6beb\u65e0\u62a5\u9519\uff0c\u4f60\u6d51\u7136\u4e0d\u77e5\u3002 \u2014 \u4ec5\u4ec5\u53ea\u662f\u88c5\u6a21\u4f5c\u6837\u7684\u7528 typedef \u5b9a\u4e49\u4e2a\u597d\u770b\u7684\u7c7b\u578b\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\uff01 \u4ed6\u8fde\u4f60\u7684\u53c2\u6570\u540d fd \u90fd\u80fd\u770b\u4e0d\u89c1\uff0c\u4f60\u89c9\u5f97\u4ed6\u4f1a\u770b\u5230\u4f60\u7684\u53c2\u6570\u7c7b\u578b\u662f\u4e2a\u522b\u540d\uff1f \u7528\u6237\u4e00\u6837\u53ef\u4ee5\u7528\u4e00\u4e2a\u6839\u672c\u4e0d\u662f\u6587\u4ef6\u53e5\u67c4\u7684\u81ed\u6574\u6570\u6765\u8c03\u7528\u4f60\uff0c\u800c\u5f97\u4e0d\u5230\u4efb\u4f55\u8b66\u544a\u6216\u62a5\u9519\uff1a typedef int FileHandle; ssize_t read(FileHandle fd, char *buf, size_t len); read(32, buf, fd); // \u7167\u6837\u7f16\u8bd1\u901a\u8fc7\uff01 \u5982\u679c\u6211\u4eec\u628a\u6587\u4ef6\u53e5\u67c4\u5b9a\u4e49\u4e3a\u4e00\u4e2a\u7ed3\u6784\u4f53\uff1a struct FileHandle { int handle; explicit FileHandle(int handle) : handle(handle) {} }; ssize_t read(FileHandle handle, char *buf, size_t len); \u5c31\u80fd\u5728\u7528\u6237\u72af\u9a6c\u864e\u7684\u65f6\u5019\uff0c\u7ed9\u4ed6\u5f39\u51fa\u4e00\u4e2a\u7f16\u8bd1\u9519\u8bef\uff1a read(32, buf, fd); // \u7f16\u8bd1\u62a5\u9519\uff1a\u65e0\u6cd5\u5c06 int \u7c7b\u578b\u7684 32 \u9690\u5f0f\u8f6c\u6362\u4e3a FileHandle\uff01 \u5bf9\u4e8e\u6574\u6570\u7c7b\u578b\uff0c\u4e5f\u6709\u7684\u4eba\u559c\u6b22\u7528 C++11 \u7684\u5f3a\u7c7b\u578b\u679a\u4e3e\uff1a enum class FileHandle : int {}; \u8fd9\u6837\u4e00\u6765\uff0c\u5982\u679c\u7528\u6237\u771f\u7684\u662f\u60f3\u8981\u8bfb\u53d6\u201c32\u53f7\u53e5\u67c4\u201d\u7684\u6587\u4ef6\uff0c\u4ed6\u5c31\u5fc5\u987b\u663e\u5f0f\u5730\u5199\u51fa\u5b8c\u6574\u7c7b\u578b\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff1a read(FileHandle(32), buf, fd); // \u7f16\u8bd1\u901a\u8fc7\u4e86 \u5f3a\u8feb\u4f60\u5199\u4e0a\u7c7b\u578b\u540d\uff0c\u5c31\u7ed9\u4e86\u4f60\u4e00\u6b21\u518d\u601d\u8003\u7684\u673a\u4f1a\uff0c\u8ba9\u4f60\u7a81\u7136\u60ca\u9192\uff1a \u54e6\u5929\u54ea\uff0c\u6211\u600e\u4e48\u628a\u7f13\u51b2\u533a\u5927\u5c0f\u5f53\u6210\u53e5\u67c4\u6765\u4f20\u9012\u4e86\uff01 \u4ece\u800c\u51cf\u5c11\u7741\u7740\u773c\u775b\u8fd8\u72af\u9519\u7684\u53ef\u80fd\u3002 \u7136\u540e\uff0c\u4f60\u7684 open \u51fd\u6570\u4e5f\u8fd4\u56de FileHandle\uff0c\u6574\u4e2a\u4ee3\u7801\u4e2d\u5c31\u4e0d\u7528\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u4e86\u3002 FileHandle fd = open(std::filesystem::path(\"\u8def\u5f84\"), OpenFlag::Read); char buf[32]; read(fd, buf, 32); \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u5047\u5982\u4f60\u624b\u4e00\u6ed1\uff0c\u6216\u8005\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u628a buf \u7f13\u51b2\u533a\u5c11\u7559\u4e86\u4e24\u4e2a\u5b57\u8282\uff1a char buf[30]; read(fd, buf, 32); \u4f46\u4f60 read \u7684\u53c2\u6570\u4f9d\u7136\u662f 32\uff0c\u5c31\u4ea7\u751f\u4e86\u6570\u7ec4\u8d8a\u754c\uff0c\u53c8\u672a\u5b9a\u4e49\u884c\u4e3a\u4e86\u3002 \u6211\u4eec\u91c7\u7528\u5c01\u88c5\u7cbe\u795e\uff0c\u628a\u76f8\u5173\u7684 buf \u548c size \u5c01\u88c5\u6210\u4e00\u4e2a\u53c2\u6570\uff1a struct Span { char *data; size_t size; }; ssize_t read(FileHandle fd, Span buf); read(fd, Span{buf, 32}); \u6ce8\u610f\uff1aSpan \u4e0d\u9700\u8981\u4ee5\u5f15\u7528\u5f62\u5f0f\u4f20\u5165\u51fd\u6570\uff01 void read(std::string &buf); // \u5982\u679c\u662f string \u7c7b\u578b\uff0c\u53c2\u6570\u9700\u8981\u4e3a\u5f15\u7528\uff0c\u624d\u80fd\u8ba9 read \u80fd\u591f\u4fee\u6539 buf \u5b57\u7b26\u4e32 void read(Span buf); // Span \u4e0d\u9700\u8981\uff0c\u56e0\u4e3a Span \u5e76\u4e0d\u662f\u72ec\u5360\u8d44\u6e90\u7684\u7c7b\uff0cSpan \u672c\u8eab\u5c31\u662f\u4e2a\u8f7b\u91cf\u7ea7\u7684\u5f15\u7528 vector \u548c string \u8fd9\u79cd\u5177\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\u7684 RAII \u5c01\u88c5\u7c7b\u624d\u9700\u8981\u4f20\u5165\u5f15\u7528 string &buf \uff0c\u5982\u679c\u76f4\u63a5\u4f20\u5165\u4f1a\u53d1\u751f\u6df1\u62f7\u8d1d\uff0c\u5bfc\u81f4 read \u5185\u90e8\u4fee\u6539\u7684\u662f string \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u65e0\u6cd5\u5f71\u54cd\u5230\u5916\u754c\u539f\u6765\u7684 string\u3002 \u5982\u679c\u662f Span \u53c2\u6570\u5c31\u4e0d\u9700\u8981 Span &buf \u5f15\u7528\u4e86\uff0cSpan \u5e76\u4e0d\u662f RAII \u5c01\u88c5\u7c7b\uff0c\u5e76\u4e0d\u6301\u6709\u751f\u547d\u5468\u671f\uff0c\u5e76\u6ca1\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\uff0c\u4ed6\u53ea\u662f\u4e2a\u5bf9\u5916\u90e8\u5df2\u6709 vector\u3001string\u3001\u6216 char[] \u7684\u5f15\u7528\u3002\u6216\u8005\u8bf4 Span \u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u5bf9\u539f\u7f13\u51b2\u533a\u7684\u5f15\u7528\uff0c\u76f4\u63a5\u4f20\u5165 read \u5185\u90e8\u4e00\u6837\u53ef\u4ee5\u4fee\u6539\u4f60\u7684\u7f13\u51b2\u533a\u3002 \u2014 \u7528 Span \u7ed3\u6784\u4f53\u867d\u7136\u770b\u8d77\u6765\u66f4\u660e\u786e\u4e86\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u89e3\u51b3\u7528\u6237\u53ef\u80fd\u624b\u6ed1\u5199\u9519\u7f13\u51b2\u533a\u957f\u5ea6\u7684\u95ee\u9898\uff1a char buf[30]; read(fd, Span{buf, 32}); \u4e3a\u6b64\uff0c\u6211\u4eec\u5728 Span \u91cc\u52a0\u5165\u4e00\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} }; \u8fd9\u5c06\u5141\u8bb8 char [N] \u9690\u5f0f\u8f6c\u6362\u4e3a Span\uff0c\u4e14\u957f\u5ea6\u81ea\u52a8\u5c31\u662f N \u7684\u503c\u3002 \u6b64\u5904\u5982\u679c\u5199 Span(char buf[N]) \uff0c\u4f1a\u88ab C \u8bed\u8a00\u7684\u67d0\u6761\u6c99\u96d5\u89c4\u5219\uff0c\u51fd\u6570\u7b7e\u540d\u4f1a\u7b49\u4ef7\u4e8e Span(char *buf) \uff0c\u4ece\u800c\u53ea\u80fd\u83b7\u53d6\u8d77\u59cb\u5730\u5740\uff0c\u800c\u63a8\u5bfc\u4e0d\u4e86\u957f\u5ea6\u3002\u4f7f\u7528\u6570\u7ec4\u5f15\u7528\u4f5c\u4e3a\u53c2\u6570 Span(char (&buf)[N]) \u5c31\u4e0d\u4f1a\u88ab C \u8bed\u8a00\u81ea\u52a8\u9000\u5316\u6210\u8d77\u59cb\u5730\u5740\u6307\u9488\u4e86\u3002 \u7528\u6237\u53ea\u9700\u8981\uff1a char buf[30]; read(fd, Span{buf}); \u7b49\u4ef7\u4e8e Span{buf, 30} \uff0c\u6570\u7ec4\u957f\u5ea6\u81ea\u52a8\u63a8\u5bfc\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u7701\u7565 Span \u4e0d\u5199\uff1a char buf[30]; read(fd, buf); // \u81ea\u52a8\u8f6c\u6362\u6210 Span{buf, 30} \u52a0\u5165\u66f4\u591a\u7c7b\u578b\u7684\u652f\u6301\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(std::array &arr) : data(arr.data()), size(N) {} Span(std::vector &vec) : data(vec.data()), size(vec.size()) {} // \u5982\u679c\u6709\u9700\u8981\uff0c\u4e5f\u53ef\u4ee5\u663e\u5f0f\u5199\u51fa Span(buf, 30) \u4ece\u9996\u5730\u5740\u548c\u957f\u5ea6\u6784\u9020\u51fa\u4e00\u4e2a Span \u6765 explicit Span(char *data, size_t size) : data(data), size(size) {} }; \u73b0\u5728 C \u6570\u7ec4\u3001array\u3001vector\u3001\u90fd\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a Span \u4e86\uff1a char buf1[30]; Span span1 = buf1; std::array buf2; Span span2 = buf2; std::vector buf(30); Span span3 = buf3; const char *str = \"hello\"; Span span4 = Span(str, strlen(str)); \u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u81ea\u52a8\u652f\u6301\u4efb\u4f55\u5177\u6709 data \u548c size \u6210\u5458\u7684\u5404\u79cd\u6807\u51c6\u5e93\u5bb9\u5668\uff0c\u5305\u62ec\u7b2c\u4e09\u65b9\u7684\uff0c\u53ea\u8981\u4ed6\u63d0\u4f9b data \u548c size \u51fd\u6570\u3002 template concept has_data_size = requires (Arr arr) { { arr.data() } -> std::convertible_to; { arr.size() } -> std::same_as; }; struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(Arr &&arr) : data(arr.data()), size(arr.size()) {} // \u6ee1\u8db3 has_data_size \u7684\u4efb\u4f55\u7c7b\u578b\u90fd\u53ef\u4ee5\u6784\u9020\u51fa Span // \u800c\u6807\u51c6\u5e93\u7684 vector\u3001string\u3001array \u5bb9\u5668\u90fd\u542b\u6709 .data() \u548c .size() \u6210\u5458\u51fd\u6570 }; \u2014 \u5982\u679c\u7528\u6237\u786e\u5b9e\u6709\u4fee\u6539\u957f\u5ea6\u7684\u9700\u8981\uff0c\u53ef\u4ee5\u901a\u8fc7 subspan \u6210\u5458\u51fd\u6570\u5b9e\u73b0\uff1a char buf[32]; read(fd, Span(buf).subspan(0, 10)); // \u53ea\u8bfb\u53d6\u524d 10 \u4e2a\u5b57\u8282\uff01 subspan \u5185\u90e8\u5b9e\u73b0\u539f\u7406\uff1a struct Span { char *data; size_t size; Span subspan(size_t start, size_t length = (size_t)-1) const { if (start > size) // \u5982\u679c\u8d77\u59cb\u4f4d\u7f6e\u8d85\u51fa\u8303\u56f4\uff0c\u5219\u629b\u51fa\u5f02\u5e38 throw std::out_of_range(\"subspan start out of range\"); auto restSize = size - start; if (length > restSize) // \u5982\u679c\u957f\u5ea6\u8d85\u8fc7\u4e0a\u9650\uff0c\u5219\u81ea\u52a8\u622a\u65ad length = restSize; return Span(data + start, length); } }; \u2014 \u53ef\u4ee5\u628a Span \u53d8\u6210\u6a21\u677f\u7c7b\uff0c\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u6570\u7ec4\uff0c\u6bd4\u5982 Span \u3002 template concept has_data_size = requires (Arr arr) { { std::data(arr) } -> std::convertible_to; { std::size(arr) } -> std::same_as; // \u4f7f\u7528 std::data \u800c\u4e0d\u662f .data() \u7684\u597d\u5904\uff1a // std::data \u5bf9\u4e8e char (&buf)[N] \u8fd9\u79cd\u6570\u7ec4\u7c7b\u578b\u4e5f\u6709\u91cd\u8f7d\uff01 // \u4f8b\u5982 std::size(buf) \u4f1a\u5f97\u5230 int buf[N] \u7684\u6b63\u786e\u957f\u5ea6 N // \u800c sizeof buf \u4f1a\u5f97\u5230 N * sizeof(int) // \u7c7b\u4f3c\u4e8e sizeof(buf) / sizeof(buf[0]) \u7684\u6548\u679c // \u4e0d\u8fc7\u5982\u679c buf \u662f\u666e\u901a int * \u6307\u9488\uff0c\u4f1a\u91cd\u8f7d\u5931\u8d25\uff0c\u76f4\u63a5\u62a5\u9519\uff0c\u6ca1\u6709\u5b89\u5168\u9690\u60a3 }; template struct Span { T *data; size_t size; template Arr> Span(Arr &&arr) : data(std::data(arr)), size(std::size(arr)) {} // \ud83d\udc46 \u540c\u65f6\u56ca\u62ec\u4e86 vector\u3001string\u3001array\u3001\u539f\u59cb\u6570\u7ec4 }; template Span(Arr &&t) -> Span()))>>; \u2014 Span \u8868\u793a\u53ef\u8bfb\u5199\u7684\u6570\u7ec4\u3002 \u5bf9\u4e8e\u53ea\u8bfb\u7684\u6570\u7ec4\uff0c\u7528 Span \u5c31\u53ef\u4ee5\u3002 ssize_t read(FileHandle fd, Span buf); // buf \u53ef\u8bfb\u5199\uff01 ssize_t write(FileHandle fd, Span buf); // buf \u53ea\u8bfb\uff01 \u2014 \u597d\u6d88\u606f\uff01\u8fd9\u4e1c\u897f\u5728 C++20 \u5df2\u7ecf\u5b9e\u88c5\uff0c\u90a3\u5c31\u662f std::span\u3002 \u6ca1\u6709 C++20 \u5f00\u53d1\u73af\u5883\u7684\u540c\u5b66\uff0c\u4e5f\u53ef\u4ee5\u7528 GSL \u5e93\u7684 gsl::span\uff0c\u6216\u8005 ABSL \u5e93\u7684 absl::Span \u6765\u4f53\u9a8c\u3002 C++17 \u8fd8\u6709\u4e13\u95e8\u9488\u5bf9\u5b57\u7b26\u4e32\u7684\u533a\u95f4\u7c7b std::string_view\uff0c\u53ef\u4ee5\u4ece std::string \u9690\u5f0f\u6784\u9020\uff0c\u7528\u6cd5\u7c7b\u4f3c\uff0c\u4e0d\u8fc7\u5207\u7247\u51fd\u6570\u662f substr\uff0c\u8fd8\u652f\u6301 find\u3001find_first_of \u7b49 std::string \u6709\u7684\u5b57\u7b26\u4e32\u4e13\u5c5e\u51fd\u6570\u3002 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ef\u8bfb\u53ef\u5199\u6570\u7ec4 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ea\u8bfb\u6570\u7ec4 std::string_view - \u4efb\u610f\u5b57\u7b26\u4e32 \u5728 read \u51fd\u6570\u5185\u90e8\uff0c\u53ef\u4ee5\u7528 .data() \u548c .size() \u91cd\u65b0\u53d6\u51fa\u72ec\u7acb\u7684\u9996\u5730\u5740\u6307\u9488\u548c\u7f13\u51b2\u533a\u957f\u5ea6\uff0c\u7528\u4e8e\u4f3a\u5019 C \u8bed\u8a00\u7684\u8001\u51fd\u6570\uff1a ssize_t read(FileHandle fd, std::span buf) { memset(buf.data(), 0, buf.size()); // \u8bfe\u540e\u4f5c\u4e1a\uff0c\u7528\u6240\u5b66\u77e5\u8bc6\uff0c\u4f18\u5316 C \u8bed\u8a00\u7684 memset \u51fd\u6570\u5427\uff01 ... } \u4e5f\u53ef\u4ee5\u7528 range-based for \u5faa\u73af\u6765\u904d\u5386\uff1a ssize_t read(FileHandle fd, std::span buf) { for (auto & c : buf) { // \u6ce8\u610f\u8fd9\u91cc\u4e00\u5b9a\u8981\u7528 auto & \u54e6\uff01\u5426\u5219\u65e0\u6cd5\u4fee\u6539 buf \u5185\u5bb9 c = 'c'; ... } } \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u6709\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u521a\u624d\u7684 foo\uff0c\u4f1a\u9700\u8981\u8868\u793a\u201c\u53ef\u80fd\u627e\u4e0d\u5230\u8be5\u4e66\u672c\u201d\u7684\u60c5\u51b5\u3002 \u7c97\u7cd9\u7684 API \u8bbe\u8ba1\u8005\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\uff0c\u7136\u540e\u5728\u6587\u6863\u91cc\u8bf4\u201c\u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u8fd4\u56de NULL\uff01\u201d BookInfo *foo(ISBN isbn); \u5982\u679c\u662f\u8fd9\u6837\u7684\u51fd\u6570\u7b7e\u540d\uff0c\u662f\u4e0d\u662f\u4f60\u5f88\u5bb9\u6613\u5fd8\u8bb0 foo \u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\uff1f \u6bd4\u5982 malloc \u51fd\u6570\u5728\u5206\u914d\u5931\u8d25\u65f6\uff0c\u5c31\u4f1a\u8fd4\u56de NULL \u5e76\u8bbe\u7f6e errno \u4e3a ENOMEM\u3002 \u5728 man malloc \u6587\u6863\u4e2d\u5199\u7684\u6e05\u6e05\u695a\u695a\uff0c\u4f46\u662f\u8c01\u4f1a\u8bb0\u5f97\u8fd9\u4e2a\u8bbe\u5b9a\uff1f malloc \u5b8c\u968f\u624b\u5c31\u76f4\u63a5\u8bbf\u95ee\u4e86\uff08\u7a7a\u6307\u9488\u89e3\u5f15\u7528\u5c5e\u672a\u5b9a\u4e49\u884c\u4e3a\uff09\u3002 \u5728\u73b0\u4ee3 C++17 \u4e2d\u5f15\u5165\u4e86 optional\uff0c\u4ed6\u662f\u4e2a\u6a21\u677f\u7c7b\u578b\u3002 \u5f62\u5982 optional \u7684\u7c7b\u578b\u6709\u4e24\u79cd\u53ef\u80fd\u7684\u72b6\u6001\uff1a \u4e3a\u7a7a\uff08nullopt\uff09 \u6709\u503c\uff08T\uff09 \u5982\u679c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u6210\u529f\u8fd4\u56de T\uff0c\u4e5f\u53ef\u80fd\u5931\u8d25\uff0c\u90a3\u5c31\u53ef\u4ee5\u8ba9\u4ed6\u8fd4\u56de optional \uff0c\u7528 nullopt \u6765\u8868\u793a\u5931\u8d25\u3002 std::optional foo(ISBN isbn) { if (\u627e\u5230\u4e86) { return BookInfo(...); } else { return std::nullopt; } } nullopt \u548c\u6307\u9488\u7684 nullptr \u7c7b\u4f3c\uff0c\u4f46 optional \u7684\u7528\u9014\u66f4\u52a0\u5355\u4e00\uff0c\u66f4\u5177\u8bf4\u660e\u6027\u3002 \u5982\u679c\u4f60\u8fd4\u56de\u4e2a\u6307\u9488\u4eba\u5bb6\u4e0d\u4e00\u5b9a\u77e5\u9053\u4f60\u7684\u610f\u601d\u662f\u53ef\u80fd\u8fd4\u56de nullptr\uff0c\u53ef\u80fd\u8fd8\u4ee5\u4e3a\u4f60\u662f\u4e3a\u4e86\u8fd4\u56de\u4e2a new \u51fa\u6765\u7684\u6570\u7ec4\uff0c\u8bed\u4e49\u4e0d\u660e\u786e\u3002 \u8c03\u7528\u7684\u5730\u65b9\u8fd9\u6837\u5199\uff1a auto book = foo(isbn); if (book.has_value()) { // book.has_vlaue() \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u7c7b\u578b\u53ef\u4ee5\u5728 if \u6761\u4ef6\u4e2d\u81ea\u52a8\u8f6c\u6362\u4e3a bool\uff0c\u5224\u65ad\u662f\u5426\u6709\u503c\uff0c\u7b49\u4ef7\u4e8e .has_value() \uff1a auto book = foo(isbn); if (book) { // (bool)book \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8bfb\u53d6\u5176\u4e2d\u7684\u503c\uff0c\u7b49\u4ef7\u4e8e .value() \uff09\uff1a auto book = foo(isbn); if (book) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u8fd0\u7528 C++17 \u7684\u5c31\u5730 if \u8bed\u6cd5\uff1a if (auto book = foo(isbn); book.has_value()) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u7531\u4e8e auto \u51fa\u6765\u7684 optional \u53d8\u91cf\u53ef\u4ee5\u8f6c\u6362\u4e3a bool\uff0c\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u53ef\u4ee5\u7701\u7565\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", *book); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u4e5f\u652f\u6301 -> \u8fd0\u7b97\u7b26\u8bbf\u95ee\u6210\u5458\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", book->name); book->readOnline(); } optional \u7684 .value() \uff0c\u5982\u679c\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa std::bad_optional_access \u5f02\u5e38\u3002 \u7528\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4fbf\u6377\u5730\u628a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u8f6c\u6362\u4e3a\u5f02\u5e38\u629b\u51fa\u7ed9\u4e0a\u6e38\u8c03\u7528\u8005\uff0c\u800c\u4e0d\u7528\u6210\u5806\u7684 if \u5224\u65ad\u548c\u8fd4\u56de\u3002 BookInfo book = foo(isbn).value(); \u4e5f\u53ef\u4ee5\u901a\u8fc7 .value_or(\u9ed8\u8ba4\u503c) \u6307\u5b9a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u65f6\u7684\u9ed8\u8ba4\u503c\uff1a BookInfo defaultBook; BookInfo book = foo(isbn).value_or(defaultBook); \u2014 \u4f60\u63a5\u624b\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\u8f6c\u6574\u6570\uff08\u53ef\u80fd\u8f6c\u6362\u5931\u8d25\uff09\u7684\u51fd\u6570 API\uff1a // \u6587\u6863\uff1a\u5982\u679c\u5b57\u7b26\u4e32\u89e3\u6790\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de -1 \u5e76\u8bbe\u7f6e errno \u4e3a EINVAL\uff01\u8bb0\u5f97\u68c0\u67e5\uff01\u82e5\u4f60\u5fd8\u8bb0\u68c0\u67e5\u540e\u679c\u81ea\u8d1f\uff01 // \u5f53\u6307\u5b9a n \u4e3a 0 \u65f6\uff0cstr \u4e3a C \u8bed\u8a00\u7ecf\u5178\u6b3e 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u3002 // \u5f53\u6307\u5b9a n \u4e0d\u4e3a 0 \u65f6\uff0cstr \u7684\u957f\u5ea6\u56fa\u5b9a\u4e3a n\uff0c\u7528\u4e8e\u7167\u987e\u53c2\u6570\u53ef\u80fd\u4e0d\u4e3a 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u7684\u60c5\u51b5\u3002 int parseInt(const char *str, size_t n); \u90a3\u4e48\u6211\u5982\u679c\u68c0\u6d4b\u5230 -1\uff0c\u9b3c\u77e5\u9053\u662f\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u5b57\u5c31\u662f -1\uff0c\u8fd8\u662f\u56e0\u4e3a\u51fa\u9519\u624d\u8fd4\u56de -1\uff1f\u8fd8\u8981\u6211\u53bb\u68c0\u67e5 errno\uff0c\u4e07\u4e00\u4e0a\u4e00\u4e2a\u51fd\u6570\u51fa\u9519\u7559\u4e0b\u7684 EINVAL \u5462\uff1f\u4e07\u4e00\u6211\u5fd8\u8bb0\u68c0\u67e5\u5462\uff1f \u8fd0\u7528\u672c\u671f\u8bfe\u7a0b\u6240\u5b66\u77e5\u8bc6\u4f18\u5316\uff1a std::optional parseInt(std::string_view str); \u662f\u4e0d\u662f\u529f\u80fd\uff0c\u8fd4\u56de\u503c\uff0c\u53ef\u80fd\u5b58\u5728\u7684\u9519\u8bef\u60c5\u51b5\uff0c\u4e00\u76ee\u4e86\u7136\u4e86\uff1f\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48\u96be\u61c2\u7684\u6ce8\u91ca\uff0c\u6587\u6863\u3002 \u5982\u679c\u8c03\u7528\u8005\u60f3\u5047\u5b9a\u5b57\u7b26\u4e32\u89e3\u6790\u4e0d\u4f1a\u51fa\u9519\uff1a parseInt(\"233\").value(); \u5982\u679c\u8c03\u7528\u8005\u60f3\u5f53\u51fa\u9519\u65f6\u9ed8\u8ba4\u8fd4\u56de 0\uff1a parseInt(\"233\").value_or(0); parseInt \u5185\u90e8\u5b9e\u73b0\u53ef\u80fd\u5982\u4e0b\uff1a std::optional parseInt(std::string_view str) { int value; auto result = std::from_chars(str.data(), str.data() + str.size(), std::ref(value)); if (result.ec == std::errc()) return value; else return std::nullopt; } \u2014 \u8c03\u7528\u8005\u7684\u53c2\u6570\u4e0d\u8bba\u662f string \u8fd8\u662f C \u8bed\u8a00\u98ce\u683c\u7684 const char *\uff0c\u90fd\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a\u901a\u7528\u7684 string_view\u3002 parseInt(\"-1\"); string s; cin >> s; parseInt(s); char perfGeek[2] = {'-', '1'}; parseInt(std::string_view{perfGeek, 2}); \u7b11\u70b9\u89e3\u6790\uff1a\u4e0a\u9762\u7684\u4ee3\u7801\u6709\u4e00\u5904\u9519\u8bef\uff0c\u4f60\u80fd\u53d1\u89c9\u5417\uff1f \u2014 cin >> s; cin >> \u53ef\u80fd\u4f1a\u5931\u8d25\uff01\u6ca1 \u60f3 \u5230 \u5427 \u8981\u662f int \u7b49 POD \u7c7b\u578b\uff0c\u5982\u679c\u4e0d\u68c0\u6d4b\uff0c\u4f1a\u51fa\u73b0\u672a\u521d\u59cb\u5316\u7684 int \u503c\uff0c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 int i; cin >> i; return i; // \u5982\u679c\u7528\u6237\u7684\u8f93\u5165\u503c\u4e0d\u662f\u5408\u6cd5\u7684\u6574\u6570\uff0c\u8fd9\u91cc\u4f1a\u4ea7\u751f\u5178\u4e2d\u5178\u4e4b\u5185\u5b58\u4e2d\u7684\u968f\u673a\u6570\u70eb\u70eb\u70eb\u70e4\u9984\u9968\uff01 \u5b98\u65b9\u63a8\u8350\u7684\u505a\u6cd5\u662f\u6bcf\u6b21\u90fd\u8981\u68c0\u6d4b\u662f\u5426\u5931\u8d25\uff01 int i; if (!(cin >> i)) { throw std::runtime_error(\"\u8bfb\u5165 int \u53d8\u91cf\u5931\u8d25\uff01\"); } return i; \u4f46\u662f\u8c01\u8bb0\u5f97\u4f4f\uff1f\u6240\u4ee5\u4ece\u4e00\u5f00\u59cb\u5c31\u4e0d\u8981\u8bbe\u8ba1\u8fd9\u79cd\u7cdf\u7cd5\u7684 API\u3002 \u7279\u522b\u662f cin >> \u8fd9\u79cd\u901a\u8fc7\u5f15\u7528\u8fd4\u56de i\uff0c\u5374\u8981\u4eba\u8bb0\u5f97\u5224\u65ad\u8fd4\u56de bool \u8868\u793a\u6210\u8d25\uff0c\u5fd8\u8bb0\u5224\u65ad\u8fd8\u4f1a\u7ed9\u4f60\u7559\u7740\u672a\u521d\u59cb\u5316\u7684\u715e\u7b14\u8bbe\u8ba1\u3002 \u5982\u679c\u8ba9\u6211\u6765\u8bbe\u8ba1 cin \u7684\u8bdd\uff1a std::optional readInt(); int i = cin.readInt().value(); \u8fd9\u6837\u5982\u679c\u7528\u6237\u8981\u8bfb\u53d6\u5230\u503c\u7684\u8bdd\uff0c\u5fc5\u7136\u8981 .value() \uff0c\u4ece\u800c\u5982\u679c readInt \u5931\u8d25\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5c31\u5fc5\u7136\u629b\u51fa\u5f02\u5e38\uff0c\u907f\u514d\u4e86\u7528\u6237\u5fd8\u8bb0\u5224\u65ad\u9519\u8bef\u7684\u53ef\u80fd\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684\u4e00\u6b3e co_async \u534f\u7a0b\u5e93\u4e2d\uff0c\u5c31\u91cd\u65b0\u8bbe\u8ba1\u4e86\u81ea\u5df1\u7684\u5f02\u6b65\u5b57\u7b26\u6d41\u7c7b\uff0c\u4f8b\u5982\u5176\u4e2d getline \u51fd\u6570\u4f1a\u8fd4\u56de std::expected \u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u2014 BookInfo * foo(ISBN isbn); \u8fd9\u662f\u4e2a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u7684\u51fd\u6570\uff0c\u5355\u4ece\u51fd\u6570\u58f0\u660e\u6765\u770b\uff0c\u4f60\u80fd\u5426\u77e5\u9053\u4ed6\u6709\u6ca1\u6709\u53ef\u80fd\u8fd4\u56de\u7a7a\u6307\u9488\uff1f\u4e0d\u786e\u5b9a\u3002 std::optional foo(ISBN isbn); \u73b0\u5728\u662f\u4e0d\u662f\u5f88\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo *\uff0c\u5927\u6982\u662f\u4e0d\u4f1a\u4e3a NULL \u7684\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e0b\u66f4\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo * \u56e0\u4e3a\u5957\u4e86\u4e00\u5c42 gsl::not_null\uff0c\u5fc5\u5b9a\u4e0d\u80fd\u4e3a NULL\uff08\u5426\u5219\u4f1a\u88ab gsl::not_null \u7684\u65ad\u8a00\u68c0\u6d4b\u5230\uff09\uff0c\u51fd\u6570\u7684\u4f5c\u8005\u662f\u7edd\u5bf9\u4e0d\u4f1a\u6545\u610f\u8fd4\u56de\u4e2a NULL \u7684\u3002 \u5982\u679c\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de nullopt\uff0c\u800c\u4e0d\u662f\u610f\u4e49\u4e0d\u660e\u8fd8\u5bb9\u6613\u5fd8\u8bb0\u7684\u7a7a\u6307\u9488\u3002 \u2014 \u8fd8\u662f\u4e0d\u5efa\u8bae\u76f4\u63a5\u7528\u539f\u59cb\u6307\u9488\uff0c\u5efa\u8bae\u7528\u667a\u80fd\u6307\u9488\u6216\u5f15\u7528\u3002 std::optional>> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4eab\u6709\u6240\u6709\u6743\u7684\u72ec\u5360\u6307\u9488\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211 optional \u51fa\u9519\u4e86\u600e\u4e48\u529e\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4e0d\u4eab\u6709\u6240\u6709\u6743\u7684\u5f15\u7528\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 reference_wrapper \u662f\u5bf9\u5f15\u7528\u7684\u5305\u88c5\uff0c\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u5f15\u7528\uff1a int i; std::reference_wrapper ref = i; int &r = ref; // r \u6307\u5411 i \u4f7f\u5f15\u7528\u53ef\u4ee5\u5b58\u5230\u5404\u79cd\u5bb9\u5668\u91cc\uff1a \u4e14\u9047\u5230 auto \u4e0d\u4f1a\u81ea\u52a8\u9000\u5316\uff08decay\uff09\uff1a int i; std::reference_wrapper ref = i; auto ref2 = ref; // ref2 \u63a8\u5bfc\u4e3a std::reference_wrapper int &r = i; auto r2 = r; // r2 \u63a8\u5bfc\u4e3a int \u4e14\u6c38\u8fdc\u4e0d\u4f1a\u4e3a NULL\uff1a std::reference_wrapper ref; // \u7f16\u8bd1\u9519\u8bef\uff1a\u5f15\u7528\u5fc5\u987b\u521d\u59cb\u5316\uff0creference_wrapper \u5f53\u7136\u4e5f\u5fc5\u987b\u521d\u59cb\u5316 \u4e5f\u53ef\u4ee5\u901a\u8fc7 * \u6216 -> \u89e3\u5f15\u7528\uff1a BookInfo book; std::reference_wrapper refBook = book; refBook->readOnline(); BookInfo deepCopyBook = *refBook; \u2014 \u6ce8\u610f .value() \u548c * \u662f\u6709\u533a\u522b\u7684\uff0c * \u4e0d\u4f1a\u68c0\u6d4b\u662f\u5426\u4e3a\u7a7a\uff0c\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u4f46\u66f4\u9ad8\u6548\u3002 o.value(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38 *o; // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 o->readOnline(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u56e0\u6b64\u4e00\u822c\u4f1a\u5728\u5224\u65ad\u4e86 optional \u4e0d\u4e3a\u7a7a\u4ee5\u540e\u624d\u4f1a\u53bb\u8bbf\u95ee * \u548c -> \u3002\u800c .value() \u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u3002 print(foo().value()); // .value() \u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\uff0c\u4e0d\u7528\u5224\u65ad if (auto o = foo()) { // \u5224\u65ad\u8fc7\u786e\u8ba4\u4e0d\u4e3a\u7a7a\u4e86\uff0c\u624d\u80fd\u8bbf\u95ee *o // \u5728\u5df2\u7ecf\u5224\u65ad\u8fc7\u4e0d\u4e3a\u7a7a\u7684 if \u5206\u652f\u4e2d\uff0c\u7528 * \u6bd4 .value() \u66f4\u9ad8\u6548 print(*o); } \u5171\u4eab\u6240\u6709\u6743 * n - shared_ptr * 1 - shared_ptr \u72ec\u5360\u6240\u6709\u6743 * n - vector , unique_ptr * 1 - unique_ptr \u6ca1\u6240\u6709\u6743 * n - span * 1 - reference_wrapper , T & \u2014 \u63a5\u4e0b\u6765\u4ecb\u7ecd optional \u7684\u4e00\u4e9b\u8fdb\u9636\u7528\u6cd5\u3002 std::optional o = BookInfo(1, 2, 3); // \u521d\u59cb\u5316\u4e3a BookInfo \u503c std::optional o; // \u4e0d\u5199\u65f6\u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u7a7a\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt o.emplace(1, 2, 3); // \u5c31\u5730\u6784\u9020\uff0c\u7b49\u4ef7\u4e8e o = BookInfo(1, 2, 3); \u4f46\u4e0d\u9700\u8981\u79fb\u52a8 BookInfo \u4e86 o.reset(); // \u5c31\u5730\u9500\u6bc1\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt; \u2014 \u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 int \u503c\u52a0 1\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readInt(); if (o) { o = *o + 1; } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 transform\uff1a std::optional o = cin.readInt(); o = o.transform([] (int n) { return n + 1; }); \u2014 \u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 string \u503c\u89e3\u6790\u4e3a int\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\u3002\u4e14\u89e3\u6790\u51fd\u6570\u53ef\u80fd\u5931\u8d25\uff0c\u5931\u8d25\u5219\u4e5f\u8981\u5c06 optional \u7f6e\u4e3a\u7a7a\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readLine(); std::optional o2; if (o) { o2 = parseInt(*o); } std::optional parseInt(std::string_view sv) { ... } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 and_then\uff1a auto o = cin.readLine().and_then(parseInt); \u2014 \u5f53\u627e\u4e0d\u5230\u6307\u5b9a\u4e66\u7c4d\u65f6\uff0c\u8fd4\u56de\u4e00\u672c\u9ed8\u8ba4\u4e66\u7c4d\u4f5c\u4e3a\u66ff\u4ee3\uff1a auto o = findBook(isbn).value_or(getDefaultBook()); \u7f3a\u70b9\uff1a\u7531\u4e8e value_or \u7684\u53c2\u6570\u4f1a\u63d0\u524d\u88ab\u6c42\u503c\uff0c\u5373\u4f7f findBook \u6210\u529f\u627e\u5230\u4e86\u4e66\u7c4d\uff0c\u4e5f\u4f1a\u6267\u884c getDefaultBook \u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u4f5c\u4e3a\u6b7b\u4ea1\u53f3\u503c\u4e22\u5f03\u3002\u5982\u679c\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\u7684\u8fc7\u7a0b\u5f88\u6162\uff0c\u90a3\u4e48\u5c31\u975e\u5e38\u4f4e\u6548\u3002 \u4e3a\u6b64\uff0cC++23 \u5f15\u5165\u4e86 or_else \u51fd\u6570\u3002 \u53ea\u6709 findBook \u627e\u4e0d\u5230\u65f6\u624d\u4f1a\u6267\u884c lambda \u4e2d\u7684\u51fd\u6570\u4f53\uff1a auto o = findBook(isbn).or_else([] -> std::optional { cout << \"findBook \u51fa\u9519\u4e86\uff0c\u73b0\u5728\u5f00\u59cb\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\uff0c\u975e\u5e38\u6162\\n\"; return getDefaultBook(); }); \u2014 \u6b64\u7c7b\u51fd\u6570\u90fd\u53ef\u4ee5\u53cd\u590d\u5d4c\u5957\uff1a int i = cin.readLine() .or_else(getDefaultLine) .and_then(parseInt) .transform([] (auto i) { return i * 2; }) .value_or(0); \u52a0\u5165\u51fd\u6570\u5f0f\u795e\u6559\u5427\uff0c\u51fd\u95e8\uff01 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u4f8b\u5982 std::stack \u7684\u8bbe\u8ba1\u5c31\u975e\u5e38\u5931\u8d25\uff1a if (!stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u6211\u4eec\u5fc5\u987b\u5224\u65ad stack \u4e0d\u4e3a\u7a7a\uff0c\u624d\u80fd\u5f39\u51fa\u6808\u9876\u5143\u7d20\u3002\u5bf9\u7740\u4e00\u4e2a\u7a7a\u7684\u6808 pop \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u800c pop() \u53c8\u662f\u4e00\u4e2a\u8fd4\u56de void \u7684\u51fd\u6570\uff0c\u4ed6\u53ea\u662f\u5220\u9664\u6808\u9876\u5143\u7d20\uff0c\u5e76\u4e0d\u4f1a\u8fd4\u56de\u5143\u7d20\u3002 \u6211\u4eec\u5fc5\u987b\u5148\u8c03\u7528 top() \u628a\u6808\u9876\u53d6\u51fa\u6765\uff0c\u7136\u540e\u624d\u80fd pop\uff01 \u660e\u660e\u662f\u540c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5374\u8981\u62c6\u6210\u4e09\u4e2a\u51fd\u6570\u6765\u5b8c\u6210\uff0c\u5f88\u70c2\u3002\u5982\u679c\u4f60\u4e0d\u614e\u628a\u5224\u65ad\u6761\u4ef6\u5199\u53cd\uff1a if (stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u5c31\u4e00\u4e2a Segmentation Fault \u8e66\u4f60\u8138\u4e0a\uff0c\u4f60\u627e\u534a\u5929\u90fd\u627e\u4e0d\u5230\u81ea\u5df1\u54ea\u9519\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u8bbe\u8ba1\uff0c\u6574\u5408\u6210\u4e00\u4e2a\u51fd\u6570\uff1a std::optional pop(); \u8bed\u4e49\u660e\u786e\uff0c\u7528\u8d77\u6765\u4e5f\u65b9\u4fbf\uff0c\u7528\u6237\u4e0d\u5bb9\u6613\u72af\u9519\u3002 if (auto val = stack.pop()) { ... } \u628a\u591a\u4e2a\u672c\u5c31\u5c5e\u4e8e\u540c\u4e00\u4ef6\u4e8b\u7684\u51fd\u6570\uff0c\u6574\u5408\u6210\u4e00\u4e2a\uff0c\u907f\u514d\u7528\u6237\u4e2d\u95f4\u51fa\u7eb0\u6f0f\u3002 \u4ece\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u4e0a\uff0c\u9650\u5b9a\u81ea\u7531\u5ea6\uff0c\u51cf\u8f7b\u7528\u6237\u601d\u8003\u8d1f\u62c5\u3002 \u2014 \u4f17\u6240\u5468\u77e5\uff0cvector \u6709\u4e24\u4e2a\u51fd\u6570\u7528\u4e8e\u8bbf\u95ee\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 int &operator[](size_t index); int &at(size_t index); vec[3]; // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u53d1\u751f\u6570\u7ec4\u8d8a\u754c\uff01\u8fd9\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vec.at(3); // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u629b\u51fa out_of_range \u5f02\u5e38 \u7528\u6237\u901a\u5e38\u4f1a\u6839\u636e\u81ea\u5df1\u7684\u9700\u8981\uff0c\u5982\u679c\u4ed6\u4eec\u975e\u5e38\u81ea\u4fe1\u81ea\u5df1\u7684\u7d22\u5f15\u4e0d\u4f1a\u8d8a\u754c\uff0c\u53ef\u4ee5\u7528\u9ad8\u6548\u7684 []\uff0c\u4e0d\u505a\u68c0\u6d4b\u3002 \u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u53ef\u4ee5\u7528\u66f4\u5b89\u5168\u7684 at()\uff0c\u4e00\u65e6\u8d8a\u754c\u81ea\u52a8\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u8c03\u8bd5\u3002 \u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u8bbe\u8ba1\u4e00\u4e2a .get() \u51fd\u6570\uff1a std::optional get(size_t index); \u5f53\u68c0\u6d4b\u5230\u6570\u7ec4\u8d8a\u754c\u65f6\uff0c\u8fd4\u56de nullopt\u3002 *vec.get(3); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u6027\u80fd\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ece\u800c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u4f18\u5316\u6389\u8d8a\u754c\u7684\u8def\u5f84 vec.get(3).value(); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u5b89\u5168\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u4e00\u4e2a\u5f02\u5e38 vec.get(3).value_or(0); // \u5982\u679c\u7528\u6237\u60f3\u8981\u5728\u8d8a\u754c\u65f6\u83b7\u5f97\u9ed8\u8ba4\u503c 0 \u8fd9\u6837\u5c31\u53ea\u9700\u8981\u4e00\u4e2a\u51fd\u6570\uff0c\u4e0d\u8bba\u7528\u6237\u60f3\u8981\u7684\u662f\u4ec0\u4e48\uff0c\u90fd\u53ea\u9700\u8981\u8fd9\u4e00\u4e2a\u7edf\u4e00\u7684 get() \u51fd\u6570\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8fd9\u4e2a\u53ea\u80fd get\uff0c\u8981\u5982\u4f55 set \u5440\uff1f std::optional get(size_t index); bool set(size_t index, int value); // \u5982\u679c\u8d8a\u754c\uff0c\u8fd4\u56de false \u7f3a\u70b91\uff1a\u8fd4\u56de bool \u65e0\u6cd5\u8fd0\u7528 optional \u7684\u5c0f\u6280\u5de7\uff1a\u901a\u8fc7 value() \u8f6c\u5316\u4e3a\u5f02\u5e38\uff0c\u4e14\u7528\u6237\u5bb9\u6613\u5fd8\u8bb0\u68c0\u67e5\u8fd4\u56de\u503c\u3002 \u7f3a\u70b92\uff1a\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f size_t \u4e00\u4e2a\u662f int\uff0c\u8fd8\u662f\u5f88\u5bb9\u6613\u987a\u5e8f\u641e\u6df7\u3002 std::optional> get(size_t index); auto x = **vec.get(3); // \u6027\u80fd\u8bfb auto x = *vec.get(3).value(); // \u5b89\u5168\u8bfb *vec.get(3) = 42; // \u6027\u80fd\u5199 vec.get(3).value() = 42; // \u5b89\u5168\u5199 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 void Sleep(int delay); \u8c01\u77e5\u9053\u8fd9\u4e2a delay \u7684\u5355\u4f4d\u662f\u4ec0\u4e48\uff1f\u79d2\uff1f\u6beb\u79d2\uff1f void Sleep(int ms); \u597d\u5427\uff0c\u662f\u6beb\u79d2\u3002\u53ef\u662f\u9664\u975e\u770b\u4e00\u773c\u51fd\u6570\u5b9a\u4e49\u6216\u6587\u6863\uff0c\u8c01\u60f3\u5f97\u5230\u8fd9\u662f\u4e2a\u6beb\u79d2\uff1f \u4e00\u4e2a\u7528\u6237\u60f3\u8981\u7761 3 \u79d2\uff0c\u4ed6\u5199\u9053\uff1a Sleep(3); \u7f16\u8bd1\u5668\u6ca1\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u4e00\u8fd0\u884c\u53ea\u7761\u4e86 3 \u6beb\u79d2\u3002 \u7528\u6237\u5927\u53d1\u96f7\u9706\u4ee5\u4e3a\u4f60\u7684 Sleep \u51fd\u6570\u6709 BUG\uff0c\u6211\u8ba9\u4ed6\u7761 3 \u79d2\u600e\u4e48\u597d\u50cf\u6839\u672c\u6ca1\u7761\u554a\u3002 \u2014 void SleepMilliSeconds(int ms); \u6539\u4e2a\u51fd\u6570\u540d\u53ef\u4ee5\u89e3\u51b3\u4e00\u90e8\u5206\u95ee\u9898\uff0c\u5f53\u7528\u6237\u8c03\u7528\u65f6\uff0c\u4ed6\u9700\u8981\u624b\u52a8\u6253\u51fa MilliSeconds \uff0c\u4ece\u800c\u5f3a\u8feb\u4ed6\u6e05\u9192\u4e00\u4e0b\uff0c\u81ea\u5df1\u7ed9\u7684 3 \u5230\u5e95\u662f\u4e0d\u662f\u81ea\u5df1\u60f3\u8981\u7684\u3002 \u2014 struct MilliSeconds { int count; explicit MilliSeconds(int count) : count(count) {} }; void Sleep(MilliSeconds delay); \u73b0\u5728\uff0c\u5982\u679c\u7528\u6237\u5199\u51fa Sleep(3); \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\u3002 \u4ed6\u5fc5\u987b\u660e\u786e\u5199\u51fa Sleep(MilliSeconds(3)); \u624d\u80fd\u901a\u8fc7\u7f16\u8bd1\u3002 \u2014 \u6807\u51c6\u5e93\u7684 chrono \u6a21\u5757\u5c31\u5927\u91cf\u8fd0\u7528\u4e86\u8fd9\u79cd\u5f3a\u7c7b\u578b\u5c01\u88c5\uff1a this_thread::sleep_for(chrono::seconds(3)); \u5982\u679c\u4f60 using namespace std::literials; \u8fd8\u53ef\u4ee5\u8fd9\u6837\u5feb\u6377\u5730\u521b\u5efa\u5b57\u9762\u91cf\uff1a this_thread::sleep_for(3ms); // 3 \u6beb\u79d2 this_thread::sleep_for(3s); // 3 \u79d2 this_thread::sleep_for(3m); // 3 \u5206\u949f this_thread::sleep_for(3h); // 3 \u5c0f\u65f6 \u4e14\u652f\u6301\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c\u4e0d\u540c\u5355\u4f4d\u4e4b\u95f4\u8fd8\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\uff1a this_thread::sleep_for(1s + 200ms); chrono::minutes three_minutes = 180s; \u2014 chrono \u662f\u4e00\u4e2a\u4f18\u79c0\u7684\u7c7b\u578b\u5c01\u88c5\u6848\u4f8b\uff0c\u628a time_t \u7c7b\u578b\u5c01\u88c5\u6210\u4e86\u5f3a\u7c7b\u578b\u7684 duration \u548c time_point\u3002 \u65f6\u95f4\u70b9\uff08time_point\uff09\u8868\u793a\u67d0\u4e2a\u5177\u4f53\u7684\u65f6\u95f4\uff0c\u4f8b\u5982 2024 \u5e74 5 \u6708 16 \u65e5 18:06:28\u3002 \u65f6\u95f4\u6bb5\uff08duration\uff09\u8868\u793a\u4e00\u6bb5\u65f6\u95f4\u7684\u957f\u5ea6\uff0c\u4f8b\u5982 1 \u5929\uff0c2 \u5c0f\u65f6\uff0c3 \u5206\u949f\uff0c4 \u79d2\u3002 \u65f6\u95f4\u6bb5\u5f88\u5bb9\u6613\u8868\u793a\uff0c\u53ea\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u5355\u4f4d\uff0c\u6bd4\u5982\u79d2\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u6570\u5b57\u5c31\u53ef\u4ee5\u8868\u793a\u591a\u5c11\u79d2\u7684\u65f6\u95f4\u6bb5\u3002 \u4f46\u662f\u65f6\u95f4\u70b9\u5c31\u5f88\u96be\u8868\u793a\u4e86\uff0c\u4f8b\u5982\u4f60\u65e0\u6cd5 Unix \u65f6\u95f4\u6233\u7528\u4e00\u4e2a\u6570\u5b57\u6765\u8868\u793a\u65f6\u95f4\u70b9\uff0c\u6570\u5b57\u7684\u542b\u4e49\u662f\u4ece\u5f53\u524d\u65f6\u95f4\u5230 1970 \u5e74 1 \u6708 1 \u65e5 00:00:00 \u7684\u79d2\u6570\u3002 \u4f8b\u5982\u5199\u4f5c\u8fd9\u7bc7\u6587\u7ae0\u7684\u65f6\u95f4\u6233\u662f 1715853968 (2024/5/16 18:06)\u3002 C \u8bed\u8a00\u7528\u4e00\u4e2a time_t \uff0c\u5b9e\u9645\u4e0a\u662f long \u7684\u7c7b\u578b\u522b\u540d\u6765\u8868\u793a\u65f6\u95f4\u6233\uff0c\u4f46\u5b83\u6709\u4e00\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff1a \u5b83\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u70b9\uff0c\u4e5f\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u6bb5\uff0c\u8fd9\u5c31\u9020\u6210\u4e86\u5de8\u5927\u7684\u6df7\u4e71\u3002 time_t t0 = time(NULL); // \u65f6\u95f4\u70b9 ... time_t t1 = time(NULL); // \u65f6\u95f4\u70b9 time_t dt = t1 - t0; // \u65f6\u95f4\u6bb5 \u75db\u70b9\uff1a\u5982\u679c\u8fd9\u91cc\u7684\u8d1f\u53f7\u5199\u9519\uff0c\u5199\u6210 t1 + t0 \uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u62a5\u9519\uff0c\u4f60\u53ef\u80fd\u6839\u672c\u6ca1\u53d1\u73b0\uff0c\u6d6a\u8d39\u5927\u91cf\u65f6\u95f4\u8c03\u8bd5\u6700\u540e\u53ea\u53d1\u73b0\u4e00\u4e2a\u4f4e\u7ea7\u9519\u8bef\u3002 \u6a21\u7cca\uff1a\u65f6\u95f4\u70b9\uff08t0\u3001t1\uff09\u548c\u65f6\u95f4\u6bb5\uff08dt\uff09\u90fd\u662f time_t\uff0c\u521d\u6b21\u9605\u8bfb\u4ee3\u7801\u5f88\u5bb9\u6613\u5206\u4e0d\u6e05\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5\u3002 \u5982\u679c\u4e0d\u614e\u628a\u201c\u65f6\u95f4\u70b9\u201d\u7684 time_t \u4f20\u5165\u5230\u672c\u5e94\u53ea\u652f\u6301\u201c\u65f6\u95f4\u6bb5\u201d\u7684 sleep \u51fd\u6570\uff0c\u4f1a\u51fa\u73b0\u201c\u7761\u7f8e\u4eba\u201d\u7684\u5947\u89c2\uff1a time_t t = time(NULL); // \u8fd4\u56de 1715853968 \u8868\u793a\u5f53\u524d\u65f6\u95f4\u70b9 sleep(t); // \u4e0d\u5c0f\u5fc3\u628a\u65f6\u95f4\u70b9\u5f53\u6210\u65f6\u95f4\u6bb5\u6765\u7528\u4e86\uff01 \u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u7761 1715853968 \u79d2\u540e\u624d\u9192\uff0c\u5373 54 \u5e74\u540e\uff01 chrono::system_clock::time_point last = chrono::system_clock::now(); ... chrono::system_clock::time_point now = chrono::system_clock::now(); chrono::system_clock::duration dt = now - last; cout << \"\u7528\u4e86 \" << duration_cast(dt).count() << \" \u79d2\\n\"; \u4e00\u770b\u5c31\u77e5\u9053\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5 \u7528\u9519\u4e86\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \u5355\u4f4d\u8f6c\u6362\u4e0d\u4f1a\u6df7\u6dc6 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u70b9 = \u7f16\u8bd1\u51fa\u9519\uff01\u56e0\u4e3a\u65f6\u95f4\u70b9\u4e4b\u95f4\u4e0d\u5141\u8bb8\u76f8\u52a0\uff0c2024 + 2024\uff0c\u4f60\u662f\u60f3\u52a0\u5230 4048 \u5e74\u53bb\u5417\uff1f \u65f6\u95f4\u70b9 - \u65f6\u95f4\u70b9 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u70b9 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u6bb5 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 \u00d7 \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 / \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u8fd9\u5c31\u662f\u672c\u671f\u8bfe\u7a0b\u7684\u4e3b\u9898\uff0c\u901a\u8fc7\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u5bf9\u53ef\u80fd\u7684\u7528\u6cd5\u52a0\u4ee5\u4e25\u683c\u7684\u9650\u5236\uff0c\u6700\u5927\u9650\u5ea6\u963b\u6b62\u7528\u6237\u4e0d\u7ecf\u610f\u95f4\u5199\u51fa\u9519\u8bef\u7684\u4ee3\u7801\u3002 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u4f60\u7684\u8001\u677f\u8981\u6c42\u4e00\u4e2a\u8bbe\u5b9a\u5ba2\u6237\u6027\u522b\u7684\u51fd\u6570\uff1a void foo(int sex); \u8001\u677f\u53e3\u5934\u548c\u5458\u5de5\u7ea6\u5b9a\u8bf4\uff0c0\u8868\u793a\u5973\uff0c1\u8868\u793a\u7537\uff0c2\u8868\u793a\u81ea\u5b9a\u4e49\u3002 \u8fd9\u8c01\u8bb0\u5f97\u4f4f\uff1f\u8bbe\u60f3\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u7684\u4ee3\u7801\uff1a foo(1); \u4f60\u80fd\u731c\u5230\u8fd9\u4e2a 1 \u662f\u4ec0\u4e48\u610f\u601d\u5417\uff1f \u89e3\u51b3\u65b9\u6cd5\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff0c\u7ed9\u6bcf\u4e2a\u6570\u503c\u4e00\u4e2a\u552f\u4e00\u7684\u540d\u5b57\uff1a enum Sex { Female = 0, Male = 1, Custom = 2, }; void foo(Sex sex); \u518d\u5047\u8bbe\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\uff1a foo(Male); \u662f\u4e0d\u662f\u5c31\u4e00\u76ee\u4e86\u7136\u5566\uff1f \u2014 \u679a\u4e3e\u7684\u503c\u4e5f\u53ef\u4ee5\u4e0d\u7528\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u6309 0\u30011\u30012 \u7684\u987a\u5e8f\u5206\u914d\u503c\uff1a enum Sex { Female, // 0 Male, // 1 Custom, // 2 }; \u53ef\u4ee5\u6307\u5b9a\u4ece 1 \u5f00\u59cb\u8ba1\u6570\uff1a enum Sex { Female = 1, Male, // 2 Custom, // 3 }; \u2014 \u4f46\u679a\u4e3e\u7c7b\u578b\u8fd8\u662f\u53ef\u4ee5\u9a97\u4eba\uff0c\u518d\u5047\u8bbe\u4f60\u662f\u65b0\u6765\u7684\uff0c\u770b\u5230\uff1a foo(Male, 24); \u662f\u4e0d\u662f\u60f3\u5f53\u7136\u7684\u611f\u89c9\u8fd9\u4e2a\u4ee3\u7801\u6ca1\u95ee\u9898\uff1f \u4f46\u5f53\u4f60\u770b\u5230 foo \u51c6\u786e\u7684\u51fd\u6570\u5b9a\u4e49\u65f6\uff0c\u50bb\u773c\u4e86\uff1a void foo(int age, Sex sex); \u76f8\u5f53\u4e8e\u6ce8\u518c\u4e86\u4e00\u4e2a 1 \u5c81\uff0c\u6027\u522b\u662f 24 \u7684\u4f2a\u4eba\u3002\u4e14\u7a0b\u5e8f\u5458\u5f88\u5bb9\u6613\u770b\u4e0d\u51fa\u95ee\u9898\uff0c\u7f16\u8bd1\u5668\u4e5f\u4e0d\u62a5\u9519\u3002 \u4e3a\u6b64\uff0cC++11 \u5f15\u5165\u4e86 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff1a enum class Sex { Female = 0, Male = 1, Custom = 2, }; \u73b0\u5728\uff0c\u5982\u679c\u4f60\u518d\u4e0d\u5c0f\u5fc3\u628a sex \u4f20\u5165 age \u7684\u8bdd\uff0c\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\uff01\u56e0\u4e3a\u5f3a\u7c7b\u578b\u679a\u4e3e\u4e0d\u5141\u8bb8\u4e0e int \u9690\u5f0f\u8f6c\u6362\u3002 \u800c\u4e14\u5f3a\u7c7b\u578b\u679a\u4e3e\u4f1a\u9700\u8981\u663e\u5f0f\u5199\u51fa Sex:: \u7c7b\u578b\u524d\u7f00\uff0c\u5f53\u4f60\u6709\u5f88\u591a\u679a\u4e3e\u7c7b\u578b\u65f6\u4e0d\u5bb9\u6613\u6df7\u6dc6\uff1a foo(24, Sex::Male); \u5982\u679c\u4f60\u7684 Sex \u8303\u56f4\u5f88\u5c0f\uff0c\u53ea\u9700\u8981 uint8_t \u7684\u5185\u5b58\u5c31\u591f\uff0c\u53ef\u4ee5\u7528\u8fd9\u4e2a\u8bed\u6cd5\u6307\u5b9a\u679a\u4e3e\u7684\u201c\u540e\u53f0\u7c7b\u578b\u201d\uff1a enum class Sex : uint8_t { Female = 0, Male = 1, Custom = 2, }; static_assert(sizeof(Sex) == 1); \u2014 \u5047\u5982\u4f60\u7684\u6240\u6709 age \u90fd\u662f int \u7c7b\u578b\u7684\uff0c\u4f46\u662f\u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u5fc3\u8840\u6765\u6f6e\uff1a \u8bf4\u4e3a\u4e86\u201c\u4f18\u5316\u5b58\u50a8\u7a7a\u95f4\u201d\uff0c\u60f3\u8981\u628a\u6240\u6709 age \u6539\u6210 uint8_t \u7c7b\u578b\u7684\uff01 \u4e3a\u4e86\u9884\u9632\u672a\u6765\u53ef\u80fd\u9700\u8981\u6539\u53d8\u7c7b\u578b\u7684\u9700\u6c42\uff0c\u4e5f\u662f\u4e3a\u4e86\u53ef\u8bfb\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using Age = int; void foo(Age age, Sex sex); \u8fd9\u6837\u5f53\u8001\u677f\u9700\u8981\u6539\u53d8\u5e95\u5c42\u7c7b\u578b\u65f6\uff0c\u53ea\u9700\u8981\u6539\u52a8\u4e00\u884c\uff1a using Age = uint8_t; \u5c31\u80fd\u81ea\u52a8\u8ba9\u6240\u6709\u4ee3\u7801\u90fd\u4f7f\u7528 uint8_t \u4f5c\u4e3a age \u4e86\u3002 \u2014 \u4f46\u662f\u7c7b\u578b\u522b\u540d\u6bd5\u7adf\u53ea\u662f\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u4fdd\u969c\uff1a using Age = int; using Phone = int; foo(Age age, Phone phone); void bar() { Age age = 42; Phone phone = 12345; foo(phone, age); // \u4e0d\u5c0f\u5fc3\u5199\u53cd\u4e86\uff01\u800c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u63d0\u9192\u4f60\uff01 } \u56e0\u4e3a Age \u548c Phone \u53ea\u662f\u7c7b\u578b\u522b\u540d\uff0c\u5b9e\u9645\u4e0a\u8fd8\u662f\u540c\u6837\u7684 int \u7c7b\u578b\u2026\u6240\u4ee5\u7f16\u8bd1\u5668\u751a\u81f3\u4e0d\u4f1a\u6709\u4efb\u4f55\u8b66\u544a\u3002 \u6709\u4e00\u79cd\u5f88\u6781\u7aef\u7684\u505a\u6cd5\u662f\u628a Age \u548c Phone \u4e5f\u505a\u6210\u679a\u4e3e\uff0c\u4f46\u6ca1\u6709\u5b9a\u4e49\u4efb\u4f55\u503c\uff1a enum class Age : int {}; enum class Phone : int {}; \u8fd9\u6837\u7528\u5230\u7684\u65f6\u5019\u5c31\u53ea\u80fd\u901a\u8fc7\u5f3a\u5236\u8f6c\u6362\u7684\u8bed\u6cd5\uff1a foo(Age(42), Phone(12345)); \u5e76\u4e14\u5982\u679c\u5199\u9519\u987a\u5e8f\uff0c\u5c1d\u8bd5\u628a Phone \u4f20\u5165 Age \u7c7b\u578b\u7684\u53c2\u6570\uff0c\u7f16\u8bd1\u5668\u4f1a\u7acb\u5373\u62a5\u9519\uff0c\u963b\u6b62\u4f60\u57cb\u4e0b BUG \u9690\u60a3\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u7684\u65b9\u6cd5\u4ee5\u540e\uff0c\u4e0d\u80fd\u505a\u52a0\u6cd5\u4e86\u600e\u4e48\u529e\uff1f Age(42) + Age(1) // \u7f16\u8bd1\u5668\u9519\u8bef\uff01 \u8fd9\u662f\u56e0\u4e3a Age \u662f\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u4e0d\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a int \u540e\u505a\u52a0\u6cd5\u3002 \u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff1a enum class Age : int {}; inline Age operator+(Age a, Age b) { return Age((int)a + (int)b); } \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u76f4\u63a5\u8ba9\u52a0\u6cd5\u8fd0\u7b97\u7b26\u5bf9\u4e8e\u6240\u6709\u679a\u4e3e\u7c7b\u578b\u90fd\u9ed8\u8ba4\u751f\u6548\uff1a template requires std::is_enum_v T operator+(T a, T b) { using U = std::underlying_type_t; return T((U)a + (U)b); } \u6709\u65f6\u8fd9\u53cd\u800c\u662f\u4e2a\u4f18\u70b9\uff0c\u6bd4\u5982\u4f60\u53ef\u4ee5\u53ea\u5b9a\u4e49\u52a0\u6cd5\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u8ba9 Age \u4e0d\u652f\u6301\u4e58\u6cd5\uff0c\u9700\u8981\u624b\u52a8\u8f6c\u6362\u540e\u624d\u80fd\u4e58\uff0c\u907f\u514d\u65e0\u610f\u4e2d\u72af\u9519\u7684\u53ef\u80fd\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u63a8\u8350\u7684 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff0c\u4e0d\u652f\u6301\u6211\u6700\u7231\u7684\u6216\u8fd0\u7b97 | \u4e86\u600e\u4e48\u529e\uff1f enum class OpenFlag { Create = 1, Read = 2, Write = 4, Truncate = 8, Append = 16, Binary = 32, }; inline OpenFlag operator|(OpenFlag a, OpenFlag b) { return OpenFlag((int)a | (int)b); } inline OpenFlag operator&(OpenFlag a, OpenFlag b) { return OpenFlag((int)a & (int)b); } inline OpenFlag operator~(OpenFlag a) { return OpenFlag(~(int)a); } \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5f88\u559c\u6b22\u5f3a\u7c7b\u578b\u679a\u4e3e\u8fd9\u4e00\u5957\uff0c\u4f46\u6211\u7684\u53c2\u6570\u4e0d\u662f\u6574\u6570\u7c7b\u578b\uff0c\u800c\u662f double\u3001string \u7b49\u7c7b\u578b\uff0c\u600e\u4e48\u529e\uff1f struct Name { private: std::string value; public: explicit operator std::string() const { return value; } explicit Name(std::string value) : value(value) {} }; \u8fd9\u91cc\u6211\u4eec\u5199 explicit \u5c31\u53ef\u4ee5\u963b\u6b62\u9690\u5f0f\u7c7b\u578b\u8f6c\u6362\uff0c\u8d77\u5230\u4e0e\u5f3a\u7c7b\u578b\u679a\u4e3e\u7c7b\u4f3c\u7684\u4f5c\u7528\u3002 \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff1a // \u6b64\u5904\u4f7f\u7528 CRTP \u6a21\u5f0f\u662f\u4e3a\u4e86\u8ba9 Typed \u6bcf\u6b21\u90fd\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684\u57fa\u7c7b\uff0c\u963b\u6b62 object-slicing template struct Typed { protected: T value; public: explicit operator T() const { return value; } explicit Typed(T value) : value(value) {} }; struct Name : Typed {}; struct Meter : Typed { using Typed::Typed; }; struct Kilometer : Typed { using Typed::Typed; operator Meter() const { // \u5141\u8bb8\u9690\u5f0f\u8f6c\u6362\u4e3a\u7c73 return Meter(value * 1000); } }; Meter m = Kilometer(1); // m = Meter(1000); foo(m); \u2014 RAII \u5c01\u88c5 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7684\u51fd\u6570\u5c31\u662f\u6d89\u53ca\u201c\u5f00\u59cb\u201d\u548c\u201c\u7ed3\u675f\u201d\u4e24\u4e2a\u64cd\u4f5c\uff0c\u7528\u6237\u7684\u64cd\u4f5c\u9700\u8981\u7a7f\u63d2\u5728\u5176\u4e2d\u95f4\uff0c\u600e\u4e48\u6574\u5408\u5462\uff1f mysql_connection *conn = mysql_connect(\"127.0.0.1\"); mysql_execute(conn, \"drop database paolu\"); mysql_close(conn); // \u7528\u6237\u53ef\u80fd\u5fd8\u8bb0\u5173\u95ed\u8fde\u63a5\uff01\u7834\u574f\u5e93\u8bbe\u8ba1\u8005\u60f3\u8981\u7684\u7528\u6cd5 \u8fd9\u79cd\u5927\u591a\u662f\u83b7\u53d6\u8d44\u6e90\uff0c\u548c\u91ca\u653e\u8d44\u6e90\u4e24\u4e2a\u64cd\u4f5c\u3002 \u56e0\u4e3a mysql \u662f\u4e2a C \u8bed\u8a00\u7684\u5e93\uff0c\u4ed6\u6ca1\u6709 RAII \u5c01\u88c5\uff0c\u8ba9\u4ed6\u624b\u52a8\u5c01\u88c5\u6709\u7684\u540c\u5b66\u53c8\u5acc\u5f03\u9ebb\u70e6\u3002 \u8fd9\u65f6\u6211\u4f1a\u544a\u8bc9\u4ed6\u4eec\u4e00\u4e2a shared_ptr \u5c0f\u5999\u62db\uff1a\u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u6307\u5b9a\u91ca\u653e\u51fd\u6570\uff0c\u4ee3\u66ff\u9ed8\u8ba4\u7684 delete auto conn = std::shared_ptr(mysql_connect(\"127.0.0.1\"), mysql_close); mysql_execute(conn.get(), \"drop database paolu\"); // conn \u79bb\u5f00\u4f5c\u7528\u57df\u65f6\uff0c\u4f1a\u81ea\u52a8\u8c03\u7528 mysql_close\uff0c\u675c\u7edd\u4e86\u4e00\u4e2a\u51fa\u9519\u7684\u53ef\u80fd \u2014 \u4ee5\u5c01\u88c5 C \u8bed\u8a00\u7684 FILE \u4e3a\u4f8b\u3002 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *file); \u8fd9\u4e2a size \u548c nmemb \u771f\u662f\u592a\u7cdf\u7cd5\u4e86\uff0c\u672c\u610f\u662f\u4e3a\u4e86\u652f\u6301\u4e0d\u540c\u5143\u7d20\u7c7b\u578b\u7684\u6570\u7ec4\u3002 size \u662f\u5143\u7d20\u672c\u8eab\u5927\u5c0f\uff0cnmemb \u662f\u5143\u7d20\u6570\u91cf\u3002\u5b9e\u9645\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u662f size * nmemb\u3002 \u6211\u5c31\u7ecf\u5e38\u628a ptr \u548c file \u987a\u5e8f\u5199\u53cd\uff0c\u8fd9\u4e2a\u83ab\u540d\u5176\u5999\u7684\u53c2\u6570\u987a\u5e8f\u592a\u53cd\u76f4\u89c9\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u8fd0\u7528\u73b0\u4ee3 C++ \u601d\u60f3\u5c01\u88c5\u4e4b\uff1a using FileHandle = std::shared_ptr; enum class OpenMode { Read, Write, Append, }; inline OpenMode operator|(OpenMode a, OpenMode b) { return OpenMode((int)a | (int)b); } auto modeLut = std::map{ {OpenMode::Read, \"r\"}, {OpenMode::Write, \"w\"}, {OpenMode::Append, \"a\"}, {OpenMode::Read | OpenMode::Write, \"w+\"}, {OpenMode::Read | OpenMode::Append, \"a+\"}, }; FileHandle file_open(std::filesystem::path path, OpenMode mode) { #ifdef _WIN32 return std::shared_ptr(_wfopen(path.wstring().c_str(), modeLut.at(mode).c_str()), fclose); #else return std::shared_ptr(fopen(path.string().c_str(), modeLut.at(mode).c_str()), fclose); #endif } struct [[nodiscard]] FileResult { std::optional numElements; std::errc errorCode; // std::errc \u662f\u4e2a\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u7528\u4e8e\u53d6\u4ee3 C \u8bed\u8a00 errno \u7684 int \u7c7b\u578b bool isEndOfFile; }; template FileResult file_read(FileHandle file, std::span elements) { auto n = fread(elements.data(), sizeof(T), elements.size(), file.get()); return { .numElements = n == 0 ? std::optional(n) : std::nullopt, .errorCode = std::errc(ferror(file.get())), .isEndOfFile = (bool)feof(file.get()), }; } \u662f\u4e0d\u662f\u63a5\u53e3\u66f4\u52a0\u7b80\u5355\u6613\u61c2\uff0c\u6ca1\u6709\u72af\u9519\u7684\u673a\u4f1a\u4e86\uff1f FileHandle file = file_open(\"hello.txt\", OpenMode::Read); int arr[32]; file_read(file, arr).numElements.value(); // \u5982\u679c\u6ca1\u6709\u8bfb\u5230\u4e1c\u897f\uff0c\u8fd9\u91cc\u4f1a\u629b\u51fa\u5f02\u5e38 // \u9000\u51fa\u4f5c\u7528\u57df\u65f6\uff0cshared_ptr \u4f1a\u81ea\u52a8\u4e3a\u4f60\u5173\u95ed\u6587\u4ef6\uff0c\u65e0\u9700\u518d\u63d0\u4f9b file_close \u51fd\u6570 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014 TODO","title":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357"},{"location":"type_rich_api/#api","text":"\u5982\u4f55\u5199\u51fa\u6613\u4e8e\u7ef4\u62a4\u7684\u4ee3\u7801\uff0c\u963b\u6b62\u72af\u9519\uff1f \u7c7b\u578b\u5c31\u662f\u6700\u597d\u7684\u6ce8\u91ca\uff01 Type is all you need \u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 \u2014 \u2014 \u2014 \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u2014 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u2014 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u2014 \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u2014 RAII \u5c01\u88c5 \u2014 \u2014 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014","title":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357"},{"location":"type_rich_api/#_1","text":"","title":"—"},{"location":"type_rich_api/#_2","text":"","title":"\u7ed3\u6784\u4f53\u4f20\u53c2"},{"location":"type_rich_api/#_3","text":"void foo(string name, int age, int phone, int address); foo(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 12345, 67890); \u75db\u70b9\uff1a\u53c2\u6570\u591a\uff0c\u7c7b\u578b\u76f8\u4f3c\uff0c\u5bb9\u6613\u987a\u5e8f\u5199\u9519\u800c\u81ea\u5df1\u4e0d\u5bdf\u89c9 \u5929\u4e66\uff1a\u9605\u8bfb\u4ee3\u7801\u65f6\u770b\u4e0d\u89c1\u53c2\u6570\u540d\uff0c\u4e0d\u6e05\u695a\u6bcf\u4e2a\u53c2\u6570\u5206\u522b\u4ee3\u8868\u4ec0\u4e48 \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void foo(FooOptions opts); foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .phone = 12345, .address = 67890}); \u2714\ufe0f \u4f18\u96c5\uff0c\u6bcf\u4e2a\u53c2\u6570\u8d1f\u8d23\u505a\u4ec0\u4e48\u4e00\u76ee\u4e86\u7136","title":"—"},{"location":"type_rich_api/#_4","text":"\u4e5f\u6709\u67d0\u4e9b\u5927\u5382\u63a8\u5d07\u6ce8\u91ca\u53c2\u6570\u540d\u6765\u589e\u5f3a\u53ef\u8bfb\u6027\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*age=*/24, /*phone=*/12345, /*address=*/67890); \u4f46\u6ce8\u91ca\u53ef\u4ee5\u9a97\u4eba\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*phone=*/12345, /*age=*/24, /*address=*/67890); \u8fd9\u91cc age \u548c phone \u53c2\u6570\u5199\u53cd\u4e86\uff01\u9605\u8bfb\u8005\u5982\u679c\u4e0d\u770b\u4e0b foo \u7684\u5b9a\u4e49\uff0c\u6839\u672c\u53d1\u73b0\u4e0d\u4e86 \u800c\u4ee3\u7801\u4e0d\u4f1a\uff1a // \u5373\u4f7f\u987a\u5e8f\u5199\u9519\uff0c\u53ea\u8981\u540d\u5b57\u5199\u5bf9\u4f9d\u7136\u53ef\u4ee5\u6b63\u5e38\u8fd0\u884c foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u603b\u4e4b\uff0c\u597d\u7684 API \u8bbe\u8ba1\u7edd\u4e0d\u4f1a\u7ed9\u4eba\u7559\u4e0b\u72af\u9519\u7684\u673a\u4f1a\uff01","title":"—"},{"location":"type_rich_api/#_5","text":"\u518d\u6765\u770b\u4e00\u4e2a\u573a\u666f\uff0c\u5047\u8bbefoo\u5185\u90e8\u9700\u8981\u628a\u6240\u6709\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570bar\uff1a void bar(int index, string name, int age, int phone, int address); void foo(string name, int age, int phone, int address) { bar(get_hash_index(name), name, age, phone, address); } \u75db\u70b9\uff1a\u4f60\u9700\u8981\u4e0d\u65ad\u5730\u590d\u5236\u7c98\u8d34\u6240\u6709\u8fd9\u4e9b\u53c2\u6570\uff0c\u975e\u5e38\u5bb9\u6613\u6284\u9519 \u75db\u70b9\uff1a\u4e00\u65e6\u53c2\u6570\u7c7b\u578b\u6709\u6240\u4fee\u6539\uff0c\u6216\u8005\u8981\u52a0\u65b0\u53c2\u6570\uff0c\u9700\u8981\u6bcf\u4e2a\u5730\u65b9\u90fd\u6539\u4e00\u4e0b \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void bar(int index, FooOptions opts); void foo(FooOptions opts) { // \u6240\u6709\u903b\u8f91\u4e0a\u76f8\u5173\u7684\u53c2\u6570\u5168\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u65b9\u4fbf\u4f7f\u7528\u66f4\u65b9\u4fbf\u9605\u8bfb bar(get_hash_index(opts.name), opts); } \u2714\ufe0f \u4f18\u96c5","title":"—"},{"location":"type_rich_api/#_6","text":"\u5f53\u8001\u677f\u8981\u6c42\u4f60\u589e\u52a0\u4e00\u4e2a\u53c2\u6570 sex\uff0c\u52a0\u5728 age \u540e\u9762\uff1a -void foo(string name, int age, int phone, int address); +void foo(string name, int age, int sex, int phone, int address); \u4f60\u624b\u5fd9\u811a\u4e71\u5730\u6253\u5f00\u6240\u6709\u8c03\u7528\u4e86 foo \u7684\u6587\u4ef6\uff0c\u53d1\u73b0\u6709\u5927\u91cf\u5730\u65b9\u9700\u8981\u4fee\u6539\u2026 \u800c\u4f18\u96c5\u7684 API \u603b\u8bbe\u8ba1\u5e08\u5c0f\u5f6d\u8001\u5e08\u53ea\u9700\u8f7b\u8f7b\u4fee\u6539\u4e00\u5904\uff1a struct FooOptions { string name; int age; int sex = 0; // \u4ee4 sex \u9ed8\u8ba4\u4e3a 0 int phone; int address; }; \u6240\u6709\u7684\u8001\u4ee3\u7801\u4f9d\u7136\u7167\u5e38\u8c03\u7528\u65b0\u7684 foo \u51fd\u6570\uff0c\u672a\u6307\u5b9a\u7684 sex \u4f1a\u5177\u6709\u7ed3\u6784\u4f53\u91cc\u5b9a\u4e49\u7684\u9ed8\u8ba4\u503c 0\uff1a foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890});","title":"—"},{"location":"type_rich_api/#_7","text":"","title":"—"},{"location":"type_rich_api/#_8","text":"\u5f53\u4f60\u9700\u8981\u591a\u4e2a\u8fd4\u56de\u503c\u65f6\uff1a\u4e0d\u8981\u8fd4\u56de pair \u6216 tuple\uff01 \u4e00\u4e9b STL \u5bb9\u5668\u7684 API \u8bbe\u8ba1\u662f\u53cd\u9762\u5178\u578b\uff0c\u4f8b\u5982\uff1a std::pair insert(std::pair entry); \u7528\u7684\u65f6\u5019\u6bcf\u6b21\u90fd\u8981\u60f3\u4e00\u4e0b\uff0c\u5230\u5e95\u7b2c\u4e00\u4e2a\u662f bool \u8fd8\u662f\u7b2c\u4e8c\u4e2a\u662f bool \u6765\u7740\uff1f\u7136\u540e\u770b\u4e00\u773c IDE \u63d0\u793a\uff0c\u624d\u53cd\u5e94\u8fc7\u6765\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.first << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.second << '\\n'; first\uff1fsecond\uff1f\u8fd9\u7b97\u4ec0\u4e48\u9b3c\uff1f \u66f4\u597d\u7684\u505a\u6cd5\u662f\u8fd4\u56de\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; insert_result_t insert(std::pair entry); \u76f4\u63a5\u901a\u8fc7\u540d\u5b57\u8bbf\u95ee\u6210\u5458\uff0c\u8bed\u4e49\u6e05\u6670\u660e\u786e\uff0c\u6211\u7ba1\u4f60\u662f\u7b2c\u4e00\u4e2a\u7b2c\u4e8c\u4e2a\uff0c\u6211\u53ea\u60f3\u8981\u8868\u793a\u201c\u662f\u5426\u6210\u529f(success)\u201d\u7684\u90a3\u4e2a\u53d8\u91cf\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.success << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.position << '\\n'; \u6700\u597d\u5f53\u7136\u662f\u8fd4\u56de\u548c\u53c2\u6570\u7c7b\u578b\u90fd\u662f\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; struct map_entry_t { K key; V value; }; insert_result_t insert(map_entry_t entry); \u8fd9\u91cc\u8bf4\u7684\u90fd\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u4f60\u53ef\u80fd\u6682\u65f6\u4e0d\u4f1a\u8ba4\u540c\uff0c\u7b49\u4f60\u5927\u624b\u5927\u811a\u72af\u4e86\u51e0\u4e2a\u9519\u4ee5\u540e\uff0c\u4f60\u81ea\u7136\u4f1a\u5fc3\u670d\u53e3\u670d\u3002 \u5c0f\u5f6d\u8001\u5e08\u4ee5\u524d\u4e5f\u548c\u4f60\u4e00\u6837\u662f\u6307\u9488\u4ed9\u4eba\uff0c\u4e0d\u559c\u6b22\u5f3a\u7c7b\u578b\uff0c\u559c\u6b22 void * \u6ee1\u5929\u98de\uff0c\u7136\u540e\u968f\u4fbf\u6539\u4e24\u884c\u5c31\u8e66\u51fa\u4e2a Segmentation Fault\uff0c\u6307\u9488\u4e00\u65f6\u723d\uff0c\u8c03\u8bd5\u706b\u846c\u573a\uff0c\u7136\u540e\u624d\u5f00\u59cb\u53cd\u601d\u3002 STL \u4e2d\u4f9d\u7136\u5728\u5927\u91cf\u7528 pair \u662f\u56e0\u4e3a map \u5bb9\u5668\u51fa\u73b0\u7684\u5f88\u65e9\uff0c\u5386\u53f2\u539f\u56e0\u3002 \u6211\u4eec\u81ea\u5df1\u9879\u76ee\u7684 API \u5c31\u4e0d\u8981\u8bbe\u8ba1\u6210\u8fd9\u718a\u6837\u4e86\u3002 \u5f53\u7136\uff0c\u548c\u67d0\u4e9b\u4e8c\u7ea7\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u76f8\u6bd4 cudaError_t cudaMalloc(void **pret); \uff0c\u8fd4\u56de pair \u5df2\u7ecf\u7b97\u5148\u8fdb\u7684\u4e86 \u4f8b\u5982 C++17 \u4e2d\u7684 from_chars \u51fd\u6570\uff0c\u4ed6\u7684\u8fd4\u56de\u7c7b\u578b\u5c31\u662f\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct from_chars_result { const char *ptr; errc ec; }; from_chars_result from_chars(const char *first, const char *last, int &value); \u8fd9\u8bf4\u660e\u4ed6\u4eec\u4e5f\u5df2\u7ecf\u610f\u8bc6\u5230\u4e86\u4ee5\u524d\u52a8\u4e0d\u52a8\u8fd4\u56de pair \u7684\u8bbe\u8ba1\u662f\u6709\u95ee\u9898\u7684\uff0c\u5df2\u7ecf\u5728\u65b0\u6807\u51c6\u4e2d\u5f00\u59cb\u6539\u7528\u66f4\u597d\u7684\u8bbe\u8ba1\u3002","title":"\u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53"},{"location":"type_rich_api/#_9","text":"","title":"—"},{"location":"type_rich_api/#_10","text":"\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u8fd9\u4e2a\u51fd\u6570\uff1a void foo(char *x); \u8fd9\u91cc\u7684 x \u6709\u53ef\u80fd\u662f\uff1a 0\u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u53ea\u8bfb\uff0c\u4f46\u662f\u4f5c\u8005\u5fd8\u4e86\u52a0 const \u6307\u5411\u5355\u4e2a\u5b57\u7b26\uff0c\u7528\u4e8e\u8fd4\u56de\u5355\u4e2a char\uff08\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\uff09 \u6307\u5411\u4e00\u4e2a\u5b57\u7b26\u6570\u7ec4\u7f13\u51b2\u533a\uff0c\u7528\u4e8e\u8fd4\u56de\u5b57\u7b26\u4e32\uff0c\u4f46\u7f13\u51b2\u533a\u5927\u5c0f\u7684\u786e\u5b9a\u65b9\u5f0f\u672a\u77e5 \u5982\u679c\u4f5c\u8005\u6ca1\u5199\u6587\u6863\uff0c\u53d8\u91cf\u540d\u53c8\u975e\u5e38\u542b\u7cca\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u8fd9\u4e2a x \u53c2\u6570\u8981\u600e\u4e48\u7528\u3002 \u7c7b\u578b\u5199\u7684\u597d\uff0c\u80fd\u8d77\u5230\u6ce8\u91ca\u7684\u4f5c\u7528\uff01 void foo(string x); \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\u4e86\uff0c\u5f88\u660e\u663e\uff0c\u662f\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u53c2\u6570\u3002 void foo(string &x); \u770b\u8d77\u6765\u662f\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u4f46\u662f\u901a\u8fc7\u5f15\u7528\u4f20\u53c2\u7684\u65b9\u5f0f\u6765\u8fd4\u56de\u7684 string foo(); \u901a\u8fc7\u5e38\u89c4\u65b9\u5f0f\u76f4\u63a5\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 void foo(vector x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7ec4\u6210\u7684\u6570\u7ec4\uff01 void foo(span x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\u5207\u7247\u3002 void foo(string_view x); \u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5207\u7247\uff0c\u53ef\u80fd\u662f\u4f5c\u8005\u60f3\u8981\u907f\u514d\u62f7\u8d1d\u5f00\u9500\u3002","title":"\u7c7b\u578b\u5373\u6ce8\u91ca"},{"location":"type_rich_api/#_11","text":"\u8fd8\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using ISBN = string; BookInfo foo(ISBN isbn); \u8fd9\u6837\u7528\u6237\u4e00\u770b\u5c31\u660e\u767d\uff0c\u8fd9\u4e2a\u51fd\u6570\u662f\u63a5\u6536\u4e00\u4e2a ISBN \u7f16\u53f7\uff08\u51fa\u7248\u520a\u7269\u90fd\u6709\u4e00\u4e2a\u8fd9\u79cd\u7f16\u53f7\uff09\uff0c\u8fd4\u56de\u5173\u4e8e\u8fd9\u672c\u4e66\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 \u5c3d\u7ba1\u51fd\u6570\u540d foo \u8ba9\u4eba\u6478\u4e0d\u7740\u5934\u8111\uff0c\u4f46\u4ec5\u51ed\u76f4\u89c2\u7684\u7c7b\u578b\u6807\u8bc6\uff0c\u6211\u4eec\u5c31\u80fd\u51fd\u6570\u529f\u80fd\u628a\u731c\u7684\u4e03\u4e03\u516b\u516b\u3002","title":"—"},{"location":"type_rich_api/#_12","text":"","title":"—"},{"location":"type_rich_api/#_13","text":"\u6ce8\u610f\uff0c\u8fd9\u91cc foo \u8fd4\u56de\u4e86\u4e00\u4e2a\u6307\u9488\uff01 BookInfo * foo(ISBN isbn); \u4ed6\u4ee3\u8868\u4ec0\u4e48\u610f\u601d\u5462\uff1f \u6307\u5411\u4e00\u4e2a\u5185\u5b58\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u4e66\u76ee\u9879\uff0c\u7531 foo \u8d1f\u8d23\u7ba1\u7406\u8fd9\u7247\u5185\u5b58 \u8fd4\u56de\u4e00\u4e2a new \u51fa\u6765\u7684 BookInfo \u7ed3\u6784\u4f53\uff0c\u7531\u7528\u6237\u8d1f\u8d23 delete \u91ca\u653e\u5185\u5b58 \u662f\u5426\u8fd8\u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u627e\u4e0d\u5230\u7684\u60c5\u51b5\uff1f \u751a\u81f3\u6709\u53ef\u80fd\u8fd4\u56de\u7684\u662f\u4e00\u4e2a BookInfo \u6570\u7ec4\uff1f\u6307\u9488\u6307\u5411\u6570\u7ec4\u7684\u9996\u4e2a\u5143\u7d20\uff0c\u6570\u7ec4\u957f\u5ea6\u7684\u5224\u5b9a\u65b9\u5f0f\u672a\u77e5\u2026 \u592a\u591a\u6b67\u4e49\u4e86\uff01 BookInfo & foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u4f1a\u8d1f\u8d23\u7ba1\u7406 BookInfo \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f\uff0c\u7528\u6237\u83b7\u5f97\u7684\u53ea\u662f\u4e00\u4e2a\u4e34\u65f6\u7684\u5f15\u7528\uff0c\u5e76\u4e0d\u6301\u6709\u6240\u6709\u6743\u3002 \u5f15\u7528\u7684\u7279\u70b9\uff1a \u4e00\u5b9a\u4e0d\u4f1a\u662f NULL\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de NULL \u7684\u7591\u8651\uff09 \u65e0\u6cd5 delete \u4e00\u4e2a\u5f15\u7528\uff08\u6392\u9664\u53ef\u80fd\u9700\u8981\u7528\u6237\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u7684\u7591\u8651\uff09 \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de\u6570\u7ec4\u9996\u5143\u7d20\u6307\u9488\u7684\u7591\u8651\uff09 \u6539\u7528\u5f15\u7528\u8fd4\u56de\u503c\uff0c\u4e00\u4e0b\u5b50\u601d\u8def\u5c31\u6e05\u6670\u4e86\u5f88\u591a\u3002\u6ca1\u6709\u90a3\u4e48\u591a\u6000\u7591\u548c\u731c\u6d4b\u4e86\uff0c\u7528\u9014\u5355\u4e00\uff0c\u7528\u6cd5\u660e\u786e\uff0c\u5f15\u7528\u771f\u662f\u7edd\u7edd\u5b50\u3002 std::unique_ptr foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684 BookInfo\uff0c\u5e76\u628a\u751f\u547d\u5468\u671f\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u7528\u6237\u3002 unique_ptr \u7684\u7279\u70b9\uff1a \u72ec\u5360\u6240\u6709\u6743\uff0c\u4e0d\u4f1a\u4e0e\u5176\u4ed6\u7ebf\u7a0b\u5171\u4eab\uff08\u6392\u9664\u53ef\u80fd\u591a\u7ebf\u7a0b\u7ade\u4e89\u7684\u7591\u8651\uff09 \u751f\u547d\u5468\u671f\u5df2\u7ecf\u79fb\u4ea4\u7ed9\u7528\u6237\uff0cunique_ptr \u53d8\u91cf\u79bb\u5f00\u7528\u6237\u7684\u4f5c\u7528\u57df\u540e\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u65e0\u9700\u624b\u52a8 delete \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u5982\u679c\u8981\u8868\u793a\u6570\u7ec4\uff0c\u4f1a\u7528 unique_ptr \u6216\u8005 vector \uff09 \u4f46\u662f unique_ptr \u6709\u4e00\u4e2a\u81f4\u547d\u7684\u7126\u8651\u70b9\uff1a\u4ed6\u53ef\u4ee5\u4e3a NULL\uff01 \u6240\u4ee5\u5f53\u4f60\u770b\u5230\u4e00\u4e2a\u51fd\u6570\u8fd4\u56de unique_ptr \u6216 shared_ptr\uff0c\u5c3d\u7ba1\u51cf\u5c11\u4e86\u5f88\u591a\u7684\u7591\u8651\uff0c\u4f46\u201c\u53ef\u80fd\u4e3aNULL\u201d\u7684\u62c5\u5fe7\u4ecd\u7136\u5b58\u5728\uff01 \u8981\u4e48 foo \u7684\u4f5c\u8005\u5728\u6ce8\u91ca\u6216\u6587\u6863\u91cc\u5199\u660e\uff0c\u201cfoo \u4e0d\u4f1a\u8fd4\u56de NULL\u201d\u6216\u8005\u201cfoo \u627e\u4e0d\u5230\u65f6\u4f1a\u8fd4\u56de NULL\u201d\uff0c\u6253\u6d88\u4f60\u7684\u7591\u8651\u3002 \u4f46\u6211\u4eec\u7684\u8bc9\u6c42\u662f\u901a\u8fc7\u7c7b\u578b\uff0c\u4e00\u773c\u5c31\u80fd\u770b\u51fa\u51fd\u6570\u6240\u6709\u7684\u53ef\u80fd\u6027\uff0c\u800c\u4e0d\u8981\u53bb\u4f9d\u8d56\u53ef\u80fd\u9a97\u4eba\u7684\u6ce8\u91ca\u3002 \u4e3a\u6b64\u5fae\u8f6f\u5b9e\u73b0\u4e86 gsl \u5e93\uff0c\u901a\u8fc7\u7c7b\u578b\u4fee\u9970\u89e3\u51b3\u6307\u9488\u7c7b\u8bed\u4e49\u542b\u7cca\u4e0d\u6e05\u7684\u95ee\u9898\uff1a \u4ed6\u89c4\u5b9a\uff0c\u6240\u6709\u5957\u4e86\u4e00\u5c42 gsl::not_null \u7684\u539f\u59cb\u6307\u9488\u6216\u667a\u80fd\u6307\u9488\uff0c\u91cc\u9762\u90fd\u5fc5\u7136\u4e0d\u4f1a\u4e3a NULL\u3002 \u5728 not_null \u7c7b\u7684\u6784\u9020\u51fd\u6570\u4e2d\uff0c\u6709\u76f8\u5e94\u7684\u65ad\u8a00\u68c0\u67e5\u4f20\u5165\u7684\u6307\u9488\u662f\u5426\u4e3a\u7a7a\uff0c\u5982\u679c\u4e3a\u7a7a\u4f1a\u76f4\u63a5\u62a5\u9519\u9000\u51fa\u3002 gsl::not_null p = nullptr; // \u7f16\u8bd1\u671f\u62a5\u9519\uff0c\u56e0\u4e3a\u4ed6\u91cc\u9762\u5199\u7740 not_null(nullptr_t) = delete; gsl::not_null p = fopen(...); // \u5982\u679c fopen \u6253\u5f00\u5931\u8d25\uff0c\u4e14\u4e3a Debug \u6784\u5efa\uff0c\u8fd0\u884c\u65f6\u4f1a\u89e6\u53d1\u65ad\u8a00\u9519\u8bef \u4fee\u6539\u540e\u7684\u51fd\u6570\u63a5\u53e3\u5982\u4e0b\uff1a gsl::not_null> foo(ISBN isbn); \u56e0\u4e3a gsl::not_null \u7684\u6784\u9020\u51fd\u6570\u4e2d\u4f1a\u68c0\u6d4b\u7a7a\u6307\u9488\uff0c\u5c31\u5411\u7528\u6237\u4fdd\u8bc1\u4e86\u6211\u8fd4\u56de\u7684\u4e0d\u4f1a\u662f NULL\u3002 \u4f46\u662f\uff0c\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u4f60\u5982\u679c\u8981\u8f6c\u79fb\u6240\u6709\u6743\u7684\u8bdd\uff0c\u6211\u76f4\u63a5\u8fd4\u56de BookInfo \u672c\u8eab\u4e0d\u5c31\u884c\u4e86\uff1f \u9664\u975e BookInfo \u7279\u522b\u5927\uff0c\u5927\u5230\u79fb\u52a8\u8fd4\u56de\u7684\u5f00\u9500\u90fd\u4e0d\u5f97\u4e86\u3002 \u76f4\u63a5\u8fd4\u56de\u7c7b\u578b\u672c\u8eab\uff0c\u5c31\u662f\u4e00\u5b9a\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u7684\uff0c\u4e14\u4e5f\u80fd\u8bf4\u660e\u79fb\u4ea4\u4e86\u5bf9\u8c61\u6240\u6709\u6743\u7ed9\u7528\u6237\u3002 BookInfo foo(ISBN isbn);","title":"\u62d2\u7edd\u6307\u9488\uff01"},{"location":"type_rich_api/#_14","text":"\u5176\u5b9e GSL \u91cc\u5927\u91cf\u90fd\u662f\u8fd9\u79cd\u53ef\u6709\u53ef\u65e0\u7684\u73a9\u610f\uff0c\u6bd4\u5982 C++20 \u5df2\u7ecf\u6709\u4e86 std::span \u548c std::byte\uff0c\u4f46\u662f GSL \u8fd8\u7ed9\u4f60\u5f04\u4e86\u4e2a gsl::span \u548c gsl::byte\uff0c\u4e3b\u8981\u662f\u4e3a\u4e86\u517c\u5bb9\u4f4e\u7248\u672c\u7f16\u8bd1\u5668\uff0c\u5982\u679c\u4f60\u5728\u65b0\u9879\u76ee\u91cc\u80fd\u76f4\u63a5\u7528\u4e0a C++20 \u6807\u51c6\u7684\u8bdd\uff0c\u4e2a\u4eba\u4e0d\u662f\u5f88\u63a8\u8350\u518d\u53bb\u7528\u4e86\u3002 \u518d\u6bd4\u5982 gsl::czstring \u662f const char * \u7684\u7c7b\u578b\u522b\u540d\uff0c\u660e\u786e\u8868\u793a\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\uff0c\u4e3a\u7684\u662f\u548c\u201c\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u201d\u533a\u5206\u5f00\u6765\uff0c\u6709\u5fc5\u8981\u5417\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u6211\u4eec\u73b0\u5728 const char * \u57fa\u672c\u4e0a\u5c31\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\u4e00\u79cd\u7528\u6cd5\uff0c\u800c\u4e14\u6211\u4eec\u5927\u591a\u4e5f\u90fd\u662f\u7528 string \u5c31\u53ef\u4ee5\u4e86\uff0cconst char * \u53c8\u4e0d\u5b89\u5168\uff0c\u53c8\u8bed\u4e49\u6a21\u68f1\u4e24\u53ef\uff0c\u4f55\u5fc5\u518d\u53bb\u4e3a\u4e86\u7528\u5b83\u4e13\u95e8\u5f15\u5165\u4e2a\u5e93\uff0c\u6574\u4e2a\u7c7b\u578b\u522b\u540d\u5462\uff1f using czstring = const char *; void foo(czstring s) { // \u53d1\u660e GSL \u7684\u4eba\u771f\u662f\u4e2a\u5929\u624d\uff01 if (s == \"\u5c0f\u5f6d\u8001\u5e08\") // \u9519\u8bef\uff01 if (strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u9519\u8bef\uff01 if (!strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u7ec8\u4e8e\u6b63\u786e // \u7136\u800c\u6211\u5b8c\u5168\u53ef\u4ee5\u76f4\u63a5\u7528 string\uff0c== \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u80fd\u76f4\u63a5\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9 // \u8fd8\u80fd\u968f\u65f6\u968f\u5730 substr \u5207\u7247\uff0cfind \u67e5\u627e\uff0csize \u5e38\u6570\u590d\u6742\u5ea6\u67e5\u5927\u5c0f } \u4f7f\u7528\u5404\u5f0f\u5404\u6837\u529f\u80fd\u660e\u786e\u7684\u7c7b\u578b\u548c\u5bb9\u5668\uff0c\u6bd4\u5982 string\uff0cvector\uff0c\u6216\u5f15\u7528\u3002 \u800c\u4e0d\u662f\u529f\u80fd\u592a\u591a\u7684\u6307\u9488\uff0c\u8ba9\u7528\u6237\u5b66\u4e60\u4f60\u7684 API \u65f6\u4ea7\u751f\u8bef\u89e3\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u5982\u679c\u9700\u8981\u6307\u9488\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 const \u9650\u5b9a\uff0c\u6765\u544a\u8bc9\u7528\u6237\u8fd9\u4e2a\u6307\u9488\u662f\u53ea\u8bfb\u7684\u8fd8\u662f\u53ef\u5199\u7684\u3002 \u603b\u4e4b\uff0c\u4ee3\u7801\u4e0d\u4f1a\u6492\u8c0e\uff0c\u4ee3\u7801\u5c42\u9762\u80fd\u7981\u6b62\u7684\uff0c\u80fd\u5c3d\u91cf\u9650\u5236\u7528\u6cd5\u7684\uff0c\u5c31\u4e0d\u8981\u7528\u6ce8\u91ca\u548c\u6587\u6863\u53bb\u534f\u5546\u89e3\u51b3\u3002","title":"—"},{"location":"type_rich_api/#_15","text":"","title":"—"},{"location":"type_rich_api/#_16","text":"\u5047\u8bbe\u4f60\u6b63\u5728\u5b66\u4e60\u8fd9\u4e2a Linux \u7cfb\u7edf API \u51fd\u6570\uff1a ssize_t read(int fd, char *buf, size_t len); // fd - \u6587\u4ef6\u53e5\u67c4\uff0cint \u7c7b\u578b \u4f46\u662f\u4f60\u6ca1\u6709\u770b\u4ed6\u7684\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u548c\u540d\u5b57\u3002\u4f60\u662f\u8fd9\u6837\u8c03\u7528\u7684\uff1a int fd = open(...); char buf[32]; read(32, buf, fd); char buf[32]; read(32, buf, fd); \u4f60\u8fd9\u91cc\u7684 32 \u672c\u610f\u662f\u7f13\u51b2\u533a\u7684\u5927\u5c0f\uff0c\u5374\u4e0d\u5e78\u5730\u548c fd \u53c2\u6570\u5199\u9519\u4e86\u4f4d\u7f6e\uff0c\u800c\u7f16\u8bd1\u5668\u6beb\u65e0\u62a5\u9519\uff0c\u4f60\u6d51\u7136\u4e0d\u77e5\u3002","title":"\u5f3a\u7c7b\u578b\u5c01\u88c5"},{"location":"type_rich_api/#_17","text":"\u4ec5\u4ec5\u53ea\u662f\u88c5\u6a21\u4f5c\u6837\u7684\u7528 typedef \u5b9a\u4e49\u4e2a\u597d\u770b\u7684\u7c7b\u578b\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\uff01 \u4ed6\u8fde\u4f60\u7684\u53c2\u6570\u540d fd \u90fd\u80fd\u770b\u4e0d\u89c1\uff0c\u4f60\u89c9\u5f97\u4ed6\u4f1a\u770b\u5230\u4f60\u7684\u53c2\u6570\u7c7b\u578b\u662f\u4e2a\u522b\u540d\uff1f \u7528\u6237\u4e00\u6837\u53ef\u4ee5\u7528\u4e00\u4e2a\u6839\u672c\u4e0d\u662f\u6587\u4ef6\u53e5\u67c4\u7684\u81ed\u6574\u6570\u6765\u8c03\u7528\u4f60\uff0c\u800c\u5f97\u4e0d\u5230\u4efb\u4f55\u8b66\u544a\u6216\u62a5\u9519\uff1a typedef int FileHandle; ssize_t read(FileHandle fd, char *buf, size_t len); read(32, buf, fd); // \u7167\u6837\u7f16\u8bd1\u901a\u8fc7\uff01 \u5982\u679c\u6211\u4eec\u628a\u6587\u4ef6\u53e5\u67c4\u5b9a\u4e49\u4e3a\u4e00\u4e2a\u7ed3\u6784\u4f53\uff1a struct FileHandle { int handle; explicit FileHandle(int handle) : handle(handle) {} }; ssize_t read(FileHandle handle, char *buf, size_t len); \u5c31\u80fd\u5728\u7528\u6237\u72af\u9a6c\u864e\u7684\u65f6\u5019\uff0c\u7ed9\u4ed6\u5f39\u51fa\u4e00\u4e2a\u7f16\u8bd1\u9519\u8bef\uff1a read(32, buf, fd); // \u7f16\u8bd1\u62a5\u9519\uff1a\u65e0\u6cd5\u5c06 int \u7c7b\u578b\u7684 32 \u9690\u5f0f\u8f6c\u6362\u4e3a FileHandle\uff01 \u5bf9\u4e8e\u6574\u6570\u7c7b\u578b\uff0c\u4e5f\u6709\u7684\u4eba\u559c\u6b22\u7528 C++11 \u7684\u5f3a\u7c7b\u578b\u679a\u4e3e\uff1a enum class FileHandle : int {}; \u8fd9\u6837\u4e00\u6765\uff0c\u5982\u679c\u7528\u6237\u771f\u7684\u662f\u60f3\u8981\u8bfb\u53d6\u201c32\u53f7\u53e5\u67c4\u201d\u7684\u6587\u4ef6\uff0c\u4ed6\u5c31\u5fc5\u987b\u663e\u5f0f\u5730\u5199\u51fa\u5b8c\u6574\u7c7b\u578b\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff1a read(FileHandle(32), buf, fd); // \u7f16\u8bd1\u901a\u8fc7\u4e86 \u5f3a\u8feb\u4f60\u5199\u4e0a\u7c7b\u578b\u540d\uff0c\u5c31\u7ed9\u4e86\u4f60\u4e00\u6b21\u518d\u601d\u8003\u7684\u673a\u4f1a\uff0c\u8ba9\u4f60\u7a81\u7136\u60ca\u9192\uff1a \u54e6\u5929\u54ea\uff0c\u6211\u600e\u4e48\u628a\u7f13\u51b2\u533a\u5927\u5c0f\u5f53\u6210\u53e5\u67c4\u6765\u4f20\u9012\u4e86\uff01 \u4ece\u800c\u51cf\u5c11\u7741\u7740\u773c\u775b\u8fd8\u72af\u9519\u7684\u53ef\u80fd\u3002 \u7136\u540e\uff0c\u4f60\u7684 open \u51fd\u6570\u4e5f\u8fd4\u56de FileHandle\uff0c\u6574\u4e2a\u4ee3\u7801\u4e2d\u5c31\u4e0d\u7528\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u4e86\u3002 FileHandle fd = open(std::filesystem::path(\"\u8def\u5f84\"), OpenFlag::Read); char buf[32]; read(fd, buf, 32);","title":"—"},{"location":"type_rich_api/#_18","text":"","title":"—"},{"location":"type_rich_api/#span","text":"","title":"span \u201c\u80d6\u6307\u9488\u201d"},{"location":"type_rich_api/#_19","text":"\u5047\u5982\u4f60\u624b\u4e00\u6ed1\uff0c\u6216\u8005\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u628a buf \u7f13\u51b2\u533a\u5c11\u7559\u4e86\u4e24\u4e2a\u5b57\u8282\uff1a char buf[30]; read(fd, buf, 32); \u4f46\u4f60 read \u7684\u53c2\u6570\u4f9d\u7136\u662f 32\uff0c\u5c31\u4ea7\u751f\u4e86\u6570\u7ec4\u8d8a\u754c\uff0c\u53c8\u672a\u5b9a\u4e49\u884c\u4e3a\u4e86\u3002 \u6211\u4eec\u91c7\u7528\u5c01\u88c5\u7cbe\u795e\uff0c\u628a\u76f8\u5173\u7684 buf \u548c size \u5c01\u88c5\u6210\u4e00\u4e2a\u53c2\u6570\uff1a struct Span { char *data; size_t size; }; ssize_t read(FileHandle fd, Span buf); read(fd, Span{buf, 32}); \u6ce8\u610f\uff1aSpan \u4e0d\u9700\u8981\u4ee5\u5f15\u7528\u5f62\u5f0f\u4f20\u5165\u51fd\u6570\uff01 void read(std::string &buf); // \u5982\u679c\u662f string \u7c7b\u578b\uff0c\u53c2\u6570\u9700\u8981\u4e3a\u5f15\u7528\uff0c\u624d\u80fd\u8ba9 read \u80fd\u591f\u4fee\u6539 buf \u5b57\u7b26\u4e32 void read(Span buf); // Span \u4e0d\u9700\u8981\uff0c\u56e0\u4e3a Span \u5e76\u4e0d\u662f\u72ec\u5360\u8d44\u6e90\u7684\u7c7b\uff0cSpan \u672c\u8eab\u5c31\u662f\u4e2a\u8f7b\u91cf\u7ea7\u7684\u5f15\u7528 vector \u548c string \u8fd9\u79cd\u5177\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\u7684 RAII \u5c01\u88c5\u7c7b\u624d\u9700\u8981\u4f20\u5165\u5f15\u7528 string &buf \uff0c\u5982\u679c\u76f4\u63a5\u4f20\u5165\u4f1a\u53d1\u751f\u6df1\u62f7\u8d1d\uff0c\u5bfc\u81f4 read \u5185\u90e8\u4fee\u6539\u7684\u662f string \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u65e0\u6cd5\u5f71\u54cd\u5230\u5916\u754c\u539f\u6765\u7684 string\u3002 \u5982\u679c\u662f Span \u53c2\u6570\u5c31\u4e0d\u9700\u8981 Span &buf \u5f15\u7528\u4e86\uff0cSpan \u5e76\u4e0d\u662f RAII \u5c01\u88c5\u7c7b\uff0c\u5e76\u4e0d\u6301\u6709\u751f\u547d\u5468\u671f\uff0c\u5e76\u6ca1\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\uff0c\u4ed6\u53ea\u662f\u4e2a\u5bf9\u5916\u90e8\u5df2\u6709 vector\u3001string\u3001\u6216 char[] \u7684\u5f15\u7528\u3002\u6216\u8005\u8bf4 Span \u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u5bf9\u539f\u7f13\u51b2\u533a\u7684\u5f15\u7528\uff0c\u76f4\u63a5\u4f20\u5165 read \u5185\u90e8\u4e00\u6837\u53ef\u4ee5\u4fee\u6539\u4f60\u7684\u7f13\u51b2\u533a\u3002","title":"—"},{"location":"type_rich_api/#_20","text":"\u7528 Span \u7ed3\u6784\u4f53\u867d\u7136\u770b\u8d77\u6765\u66f4\u660e\u786e\u4e86\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u89e3\u51b3\u7528\u6237\u53ef\u80fd\u624b\u6ed1\u5199\u9519\u7f13\u51b2\u533a\u957f\u5ea6\u7684\u95ee\u9898\uff1a char buf[30]; read(fd, Span{buf, 32}); \u4e3a\u6b64\uff0c\u6211\u4eec\u5728 Span \u91cc\u52a0\u5165\u4e00\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} }; \u8fd9\u5c06\u5141\u8bb8 char [N] \u9690\u5f0f\u8f6c\u6362\u4e3a Span\uff0c\u4e14\u957f\u5ea6\u81ea\u52a8\u5c31\u662f N \u7684\u503c\u3002 \u6b64\u5904\u5982\u679c\u5199 Span(char buf[N]) \uff0c\u4f1a\u88ab C \u8bed\u8a00\u7684\u67d0\u6761\u6c99\u96d5\u89c4\u5219\uff0c\u51fd\u6570\u7b7e\u540d\u4f1a\u7b49\u4ef7\u4e8e Span(char *buf) \uff0c\u4ece\u800c\u53ea\u80fd\u83b7\u53d6\u8d77\u59cb\u5730\u5740\uff0c\u800c\u63a8\u5bfc\u4e0d\u4e86\u957f\u5ea6\u3002\u4f7f\u7528\u6570\u7ec4\u5f15\u7528\u4f5c\u4e3a\u53c2\u6570 Span(char (&buf)[N]) \u5c31\u4e0d\u4f1a\u88ab C \u8bed\u8a00\u81ea\u52a8\u9000\u5316\u6210\u8d77\u59cb\u5730\u5740\u6307\u9488\u4e86\u3002 \u7528\u6237\u53ea\u9700\u8981\uff1a char buf[30]; read(fd, Span{buf}); \u7b49\u4ef7\u4e8e Span{buf, 30} \uff0c\u6570\u7ec4\u957f\u5ea6\u81ea\u52a8\u63a8\u5bfc\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u7701\u7565 Span \u4e0d\u5199\uff1a char buf[30]; read(fd, buf); // \u81ea\u52a8\u8f6c\u6362\u6210 Span{buf, 30} \u52a0\u5165\u66f4\u591a\u7c7b\u578b\u7684\u652f\u6301\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(std::array &arr) : data(arr.data()), size(N) {} Span(std::vector &vec) : data(vec.data()), size(vec.size()) {} // \u5982\u679c\u6709\u9700\u8981\uff0c\u4e5f\u53ef\u4ee5\u663e\u5f0f\u5199\u51fa Span(buf, 30) \u4ece\u9996\u5730\u5740\u548c\u957f\u5ea6\u6784\u9020\u51fa\u4e00\u4e2a Span \u6765 explicit Span(char *data, size_t size) : data(data), size(size) {} }; \u73b0\u5728 C \u6570\u7ec4\u3001array\u3001vector\u3001\u90fd\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a Span \u4e86\uff1a char buf1[30]; Span span1 = buf1; std::array buf2; Span span2 = buf2; std::vector buf(30); Span span3 = buf3; const char *str = \"hello\"; Span span4 = Span(str, strlen(str)); \u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u81ea\u52a8\u652f\u6301\u4efb\u4f55\u5177\u6709 data \u548c size \u6210\u5458\u7684\u5404\u79cd\u6807\u51c6\u5e93\u5bb9\u5668\uff0c\u5305\u62ec\u7b2c\u4e09\u65b9\u7684\uff0c\u53ea\u8981\u4ed6\u63d0\u4f9b data \u548c size \u51fd\u6570\u3002 template concept has_data_size = requires (Arr arr) { { arr.data() } -> std::convertible_to; { arr.size() } -> std::same_as; }; struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(Arr &&arr) : data(arr.data()), size(arr.size()) {} // \u6ee1\u8db3 has_data_size \u7684\u4efb\u4f55\u7c7b\u578b\u90fd\u53ef\u4ee5\u6784\u9020\u51fa Span // \u800c\u6807\u51c6\u5e93\u7684 vector\u3001string\u3001array \u5bb9\u5668\u90fd\u542b\u6709 .data() \u548c .size() \u6210\u5458\u51fd\u6570 };","title":"—"},{"location":"type_rich_api/#_21","text":"\u5982\u679c\u7528\u6237\u786e\u5b9e\u6709\u4fee\u6539\u957f\u5ea6\u7684\u9700\u8981\uff0c\u53ef\u4ee5\u901a\u8fc7 subspan \u6210\u5458\u51fd\u6570\u5b9e\u73b0\uff1a char buf[32]; read(fd, Span(buf).subspan(0, 10)); // \u53ea\u8bfb\u53d6\u524d 10 \u4e2a\u5b57\u8282\uff01 subspan \u5185\u90e8\u5b9e\u73b0\u539f\u7406\uff1a struct Span { char *data; size_t size; Span subspan(size_t start, size_t length = (size_t)-1) const { if (start > size) // \u5982\u679c\u8d77\u59cb\u4f4d\u7f6e\u8d85\u51fa\u8303\u56f4\uff0c\u5219\u629b\u51fa\u5f02\u5e38 throw std::out_of_range(\"subspan start out of range\"); auto restSize = size - start; if (length > restSize) // \u5982\u679c\u957f\u5ea6\u8d85\u8fc7\u4e0a\u9650\uff0c\u5219\u81ea\u52a8\u622a\u65ad length = restSize; return Span(data + start, length); } };","title":"—"},{"location":"type_rich_api/#_22","text":"\u53ef\u4ee5\u628a Span \u53d8\u6210\u6a21\u677f\u7c7b\uff0c\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u6570\u7ec4\uff0c\u6bd4\u5982 Span \u3002 template concept has_data_size = requires (Arr arr) { { std::data(arr) } -> std::convertible_to; { std::size(arr) } -> std::same_as; // \u4f7f\u7528 std::data \u800c\u4e0d\u662f .data() \u7684\u597d\u5904\uff1a // std::data \u5bf9\u4e8e char (&buf)[N] \u8fd9\u79cd\u6570\u7ec4\u7c7b\u578b\u4e5f\u6709\u91cd\u8f7d\uff01 // \u4f8b\u5982 std::size(buf) \u4f1a\u5f97\u5230 int buf[N] \u7684\u6b63\u786e\u957f\u5ea6 N // \u800c sizeof buf \u4f1a\u5f97\u5230 N * sizeof(int) // \u7c7b\u4f3c\u4e8e sizeof(buf) / sizeof(buf[0]) \u7684\u6548\u679c // \u4e0d\u8fc7\u5982\u679c buf \u662f\u666e\u901a int * \u6307\u9488\uff0c\u4f1a\u91cd\u8f7d\u5931\u8d25\uff0c\u76f4\u63a5\u62a5\u9519\uff0c\u6ca1\u6709\u5b89\u5168\u9690\u60a3 }; template struct Span { T *data; size_t size; template Arr> Span(Arr &&arr) : data(std::data(arr)), size(std::size(arr)) {} // \ud83d\udc46 \u540c\u65f6\u56ca\u62ec\u4e86 vector\u3001string\u3001array\u3001\u539f\u59cb\u6570\u7ec4 }; template Span(Arr &&t) -> Span()))>>;","title":"—"},{"location":"type_rich_api/#_23","text":"Span \u8868\u793a\u53ef\u8bfb\u5199\u7684\u6570\u7ec4\u3002 \u5bf9\u4e8e\u53ea\u8bfb\u7684\u6570\u7ec4\uff0c\u7528 Span \u5c31\u53ef\u4ee5\u3002 ssize_t read(FileHandle fd, Span buf); // buf \u53ef\u8bfb\u5199\uff01 ssize_t write(FileHandle fd, Span buf); // buf \u53ea\u8bfb\uff01","title":"—"},{"location":"type_rich_api/#_24","text":"\u597d\u6d88\u606f\uff01\u8fd9\u4e1c\u897f\u5728 C++20 \u5df2\u7ecf\u5b9e\u88c5\uff0c\u90a3\u5c31\u662f std::span\u3002 \u6ca1\u6709 C++20 \u5f00\u53d1\u73af\u5883\u7684\u540c\u5b66\uff0c\u4e5f\u53ef\u4ee5\u7528 GSL \u5e93\u7684 gsl::span\uff0c\u6216\u8005 ABSL \u5e93\u7684 absl::Span \u6765\u4f53\u9a8c\u3002 C++17 \u8fd8\u6709\u4e13\u95e8\u9488\u5bf9\u5b57\u7b26\u4e32\u7684\u533a\u95f4\u7c7b std::string_view\uff0c\u53ef\u4ee5\u4ece std::string \u9690\u5f0f\u6784\u9020\uff0c\u7528\u6cd5\u7c7b\u4f3c\uff0c\u4e0d\u8fc7\u5207\u7247\u51fd\u6570\u662f substr\uff0c\u8fd8\u652f\u6301 find\u3001find_first_of \u7b49 std::string \u6709\u7684\u5b57\u7b26\u4e32\u4e13\u5c5e\u51fd\u6570\u3002 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ef\u8bfb\u53ef\u5199\u6570\u7ec4 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ea\u8bfb\u6570\u7ec4 std::string_view - \u4efb\u610f\u5b57\u7b26\u4e32 \u5728 read \u51fd\u6570\u5185\u90e8\uff0c\u53ef\u4ee5\u7528 .data() \u548c .size() \u91cd\u65b0\u53d6\u51fa\u72ec\u7acb\u7684\u9996\u5730\u5740\u6307\u9488\u548c\u7f13\u51b2\u533a\u957f\u5ea6\uff0c\u7528\u4e8e\u4f3a\u5019 C \u8bed\u8a00\u7684\u8001\u51fd\u6570\uff1a ssize_t read(FileHandle fd, std::span buf) { memset(buf.data(), 0, buf.size()); // \u8bfe\u540e\u4f5c\u4e1a\uff0c\u7528\u6240\u5b66\u77e5\u8bc6\uff0c\u4f18\u5316 C \u8bed\u8a00\u7684 memset \u51fd\u6570\u5427\uff01 ... } \u4e5f\u53ef\u4ee5\u7528 range-based for \u5faa\u73af\u6765\u904d\u5386\uff1a ssize_t read(FileHandle fd, std::span buf) { for (auto & c : buf) { // \u6ce8\u610f\u8fd9\u91cc\u4e00\u5b9a\u8981\u7528 auto & \u54e6\uff01\u5426\u5219\u65e0\u6cd5\u4fee\u6539 buf \u5185\u5bb9 c = 'c'; ... } }","title":"—"},{"location":"type_rich_api/#_25","text":"","title":"—"},{"location":"type_rich_api/#_26","text":"","title":"\u7a7a\u503c\u8bed\u4e49"},{"location":"type_rich_api/#_27","text":"\u6709\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u521a\u624d\u7684 foo\uff0c\u4f1a\u9700\u8981\u8868\u793a\u201c\u53ef\u80fd\u627e\u4e0d\u5230\u8be5\u4e66\u672c\u201d\u7684\u60c5\u51b5\u3002 \u7c97\u7cd9\u7684 API \u8bbe\u8ba1\u8005\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\uff0c\u7136\u540e\u5728\u6587\u6863\u91cc\u8bf4\u201c\u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u8fd4\u56de NULL\uff01\u201d BookInfo *foo(ISBN isbn); \u5982\u679c\u662f\u8fd9\u6837\u7684\u51fd\u6570\u7b7e\u540d\uff0c\u662f\u4e0d\u662f\u4f60\u5f88\u5bb9\u6613\u5fd8\u8bb0 foo \u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\uff1f \u6bd4\u5982 malloc \u51fd\u6570\u5728\u5206\u914d\u5931\u8d25\u65f6\uff0c\u5c31\u4f1a\u8fd4\u56de NULL \u5e76\u8bbe\u7f6e errno \u4e3a ENOMEM\u3002 \u5728 man malloc \u6587\u6863\u4e2d\u5199\u7684\u6e05\u6e05\u695a\u695a\uff0c\u4f46\u662f\u8c01\u4f1a\u8bb0\u5f97\u8fd9\u4e2a\u8bbe\u5b9a\uff1f malloc \u5b8c\u968f\u624b\u5c31\u76f4\u63a5\u8bbf\u95ee\u4e86\uff08\u7a7a\u6307\u9488\u89e3\u5f15\u7528\u5c5e\u672a\u5b9a\u4e49\u884c\u4e3a\uff09\u3002 \u5728\u73b0\u4ee3 C++17 \u4e2d\u5f15\u5165\u4e86 optional\uff0c\u4ed6\u662f\u4e2a\u6a21\u677f\u7c7b\u578b\u3002 \u5f62\u5982 optional \u7684\u7c7b\u578b\u6709\u4e24\u79cd\u53ef\u80fd\u7684\u72b6\u6001\uff1a \u4e3a\u7a7a\uff08nullopt\uff09 \u6709\u503c\uff08T\uff09 \u5982\u679c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u6210\u529f\u8fd4\u56de T\uff0c\u4e5f\u53ef\u80fd\u5931\u8d25\uff0c\u90a3\u5c31\u53ef\u4ee5\u8ba9\u4ed6\u8fd4\u56de optional \uff0c\u7528 nullopt \u6765\u8868\u793a\u5931\u8d25\u3002 std::optional foo(ISBN isbn) { if (\u627e\u5230\u4e86) { return BookInfo(...); } else { return std::nullopt; } } nullopt \u548c\u6307\u9488\u7684 nullptr \u7c7b\u4f3c\uff0c\u4f46 optional \u7684\u7528\u9014\u66f4\u52a0\u5355\u4e00\uff0c\u66f4\u5177\u8bf4\u660e\u6027\u3002 \u5982\u679c\u4f60\u8fd4\u56de\u4e2a\u6307\u9488\u4eba\u5bb6\u4e0d\u4e00\u5b9a\u77e5\u9053\u4f60\u7684\u610f\u601d\u662f\u53ef\u80fd\u8fd4\u56de nullptr\uff0c\u53ef\u80fd\u8fd8\u4ee5\u4e3a\u4f60\u662f\u4e3a\u4e86\u8fd4\u56de\u4e2a new \u51fa\u6765\u7684\u6570\u7ec4\uff0c\u8bed\u4e49\u4e0d\u660e\u786e\u3002 \u8c03\u7528\u7684\u5730\u65b9\u8fd9\u6837\u5199\uff1a auto book = foo(isbn); if (book.has_value()) { // book.has_vlaue() \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u7c7b\u578b\u53ef\u4ee5\u5728 if \u6761\u4ef6\u4e2d\u81ea\u52a8\u8f6c\u6362\u4e3a bool\uff0c\u5224\u65ad\u662f\u5426\u6709\u503c\uff0c\u7b49\u4ef7\u4e8e .has_value() \uff1a auto book = foo(isbn); if (book) { // (bool)book \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8bfb\u53d6\u5176\u4e2d\u7684\u503c\uff0c\u7b49\u4ef7\u4e8e .value() \uff09\uff1a auto book = foo(isbn); if (book) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u8fd0\u7528 C++17 \u7684\u5c31\u5730 if \u8bed\u6cd5\uff1a if (auto book = foo(isbn); book.has_value()) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u7531\u4e8e auto \u51fa\u6765\u7684 optional \u53d8\u91cf\u53ef\u4ee5\u8f6c\u6362\u4e3a bool\uff0c\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u53ef\u4ee5\u7701\u7565\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", *book); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u4e5f\u652f\u6301 -> \u8fd0\u7b97\u7b26\u8bbf\u95ee\u6210\u5458\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", book->name); book->readOnline(); } optional \u7684 .value() \uff0c\u5982\u679c\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa std::bad_optional_access \u5f02\u5e38\u3002 \u7528\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4fbf\u6377\u5730\u628a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u8f6c\u6362\u4e3a\u5f02\u5e38\u629b\u51fa\u7ed9\u4e0a\u6e38\u8c03\u7528\u8005\uff0c\u800c\u4e0d\u7528\u6210\u5806\u7684 if \u5224\u65ad\u548c\u8fd4\u56de\u3002 BookInfo book = foo(isbn).value(); \u4e5f\u53ef\u4ee5\u901a\u8fc7 .value_or(\u9ed8\u8ba4\u503c) \u6307\u5b9a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u65f6\u7684\u9ed8\u8ba4\u503c\uff1a BookInfo defaultBook; BookInfo book = foo(isbn).value_or(defaultBook);","title":"—"},{"location":"type_rich_api/#_28","text":"\u4f60\u63a5\u624b\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\u8f6c\u6574\u6570\uff08\u53ef\u80fd\u8f6c\u6362\u5931\u8d25\uff09\u7684\u51fd\u6570 API\uff1a // \u6587\u6863\uff1a\u5982\u679c\u5b57\u7b26\u4e32\u89e3\u6790\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de -1 \u5e76\u8bbe\u7f6e errno \u4e3a EINVAL\uff01\u8bb0\u5f97\u68c0\u67e5\uff01\u82e5\u4f60\u5fd8\u8bb0\u68c0\u67e5\u540e\u679c\u81ea\u8d1f\uff01 // \u5f53\u6307\u5b9a n \u4e3a 0 \u65f6\uff0cstr \u4e3a C \u8bed\u8a00\u7ecf\u5178\u6b3e 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u3002 // \u5f53\u6307\u5b9a n \u4e0d\u4e3a 0 \u65f6\uff0cstr \u7684\u957f\u5ea6\u56fa\u5b9a\u4e3a n\uff0c\u7528\u4e8e\u7167\u987e\u53c2\u6570\u53ef\u80fd\u4e0d\u4e3a 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u7684\u60c5\u51b5\u3002 int parseInt(const char *str, size_t n); \u90a3\u4e48\u6211\u5982\u679c\u68c0\u6d4b\u5230 -1\uff0c\u9b3c\u77e5\u9053\u662f\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u5b57\u5c31\u662f -1\uff0c\u8fd8\u662f\u56e0\u4e3a\u51fa\u9519\u624d\u8fd4\u56de -1\uff1f\u8fd8\u8981\u6211\u53bb\u68c0\u67e5 errno\uff0c\u4e07\u4e00\u4e0a\u4e00\u4e2a\u51fd\u6570\u51fa\u9519\u7559\u4e0b\u7684 EINVAL \u5462\uff1f\u4e07\u4e00\u6211\u5fd8\u8bb0\u68c0\u67e5\u5462\uff1f \u8fd0\u7528\u672c\u671f\u8bfe\u7a0b\u6240\u5b66\u77e5\u8bc6\u4f18\u5316\uff1a std::optional parseInt(std::string_view str); \u662f\u4e0d\u662f\u529f\u80fd\uff0c\u8fd4\u56de\u503c\uff0c\u53ef\u80fd\u5b58\u5728\u7684\u9519\u8bef\u60c5\u51b5\uff0c\u4e00\u76ee\u4e86\u7136\u4e86\uff1f\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48\u96be\u61c2\u7684\u6ce8\u91ca\uff0c\u6587\u6863\u3002 \u5982\u679c\u8c03\u7528\u8005\u60f3\u5047\u5b9a\u5b57\u7b26\u4e32\u89e3\u6790\u4e0d\u4f1a\u51fa\u9519\uff1a parseInt(\"233\").value(); \u5982\u679c\u8c03\u7528\u8005\u60f3\u5f53\u51fa\u9519\u65f6\u9ed8\u8ba4\u8fd4\u56de 0\uff1a parseInt(\"233\").value_or(0); parseInt \u5185\u90e8\u5b9e\u73b0\u53ef\u80fd\u5982\u4e0b\uff1a std::optional parseInt(std::string_view str) { int value; auto result = std::from_chars(str.data(), str.data() + str.size(), std::ref(value)); if (result.ec == std::errc()) return value; else return std::nullopt; }","title":"—"},{"location":"type_rich_api/#_29","text":"\u8c03\u7528\u8005\u7684\u53c2\u6570\u4e0d\u8bba\u662f string \u8fd8\u662f C \u8bed\u8a00\u98ce\u683c\u7684 const char *\uff0c\u90fd\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a\u901a\u7528\u7684 string_view\u3002 parseInt(\"-1\"); string s; cin >> s; parseInt(s); char perfGeek[2] = {'-', '1'}; parseInt(std::string_view{perfGeek, 2}); \u7b11\u70b9\u89e3\u6790\uff1a\u4e0a\u9762\u7684\u4ee3\u7801\u6709\u4e00\u5904\u9519\u8bef\uff0c\u4f60\u80fd\u53d1\u89c9\u5417\uff1f","title":"—"},{"location":"type_rich_api/#_30","text":"cin >> s; cin >> \u53ef\u80fd\u4f1a\u5931\u8d25\uff01\u6ca1 \u60f3 \u5230 \u5427 \u8981\u662f int \u7b49 POD \u7c7b\u578b\uff0c\u5982\u679c\u4e0d\u68c0\u6d4b\uff0c\u4f1a\u51fa\u73b0\u672a\u521d\u59cb\u5316\u7684 int \u503c\uff0c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 int i; cin >> i; return i; // \u5982\u679c\u7528\u6237\u7684\u8f93\u5165\u503c\u4e0d\u662f\u5408\u6cd5\u7684\u6574\u6570\uff0c\u8fd9\u91cc\u4f1a\u4ea7\u751f\u5178\u4e2d\u5178\u4e4b\u5185\u5b58\u4e2d\u7684\u968f\u673a\u6570\u70eb\u70eb\u70eb\u70e4\u9984\u9968\uff01 \u5b98\u65b9\u63a8\u8350\u7684\u505a\u6cd5\u662f\u6bcf\u6b21\u90fd\u8981\u68c0\u6d4b\u662f\u5426\u5931\u8d25\uff01 int i; if (!(cin >> i)) { throw std::runtime_error(\"\u8bfb\u5165 int \u53d8\u91cf\u5931\u8d25\uff01\"); } return i; \u4f46\u662f\u8c01\u8bb0\u5f97\u4f4f\uff1f\u6240\u4ee5\u4ece\u4e00\u5f00\u59cb\u5c31\u4e0d\u8981\u8bbe\u8ba1\u8fd9\u79cd\u7cdf\u7cd5\u7684 API\u3002 \u7279\u522b\u662f cin >> \u8fd9\u79cd\u901a\u8fc7\u5f15\u7528\u8fd4\u56de i\uff0c\u5374\u8981\u4eba\u8bb0\u5f97\u5224\u65ad\u8fd4\u56de bool \u8868\u793a\u6210\u8d25\uff0c\u5fd8\u8bb0\u5224\u65ad\u8fd8\u4f1a\u7ed9\u4f60\u7559\u7740\u672a\u521d\u59cb\u5316\u7684\u715e\u7b14\u8bbe\u8ba1\u3002 \u5982\u679c\u8ba9\u6211\u6765\u8bbe\u8ba1 cin \u7684\u8bdd\uff1a std::optional readInt(); int i = cin.readInt().value(); \u8fd9\u6837\u5982\u679c\u7528\u6237\u8981\u8bfb\u53d6\u5230\u503c\u7684\u8bdd\uff0c\u5fc5\u7136\u8981 .value() \uff0c\u4ece\u800c\u5982\u679c readInt \u5931\u8d25\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5c31\u5fc5\u7136\u629b\u51fa\u5f02\u5e38\uff0c\u907f\u514d\u4e86\u7528\u6237\u5fd8\u8bb0\u5224\u65ad\u9519\u8bef\u7684\u53ef\u80fd\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684\u4e00\u6b3e co_async \u534f\u7a0b\u5e93\u4e2d\uff0c\u5c31\u91cd\u65b0\u8bbe\u8ba1\u4e86\u81ea\u5df1\u7684\u5f02\u6b65\u5b57\u7b26\u6d41\u7c7b\uff0c\u4f8b\u5982\u5176\u4e2d getline \u51fd\u6570\u4f1a\u8fd4\u56de std::expected \u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"—"},{"location":"type_rich_api/#_31","text":"BookInfo * foo(ISBN isbn); \u8fd9\u662f\u4e2a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u7684\u51fd\u6570\uff0c\u5355\u4ece\u51fd\u6570\u58f0\u660e\u6765\u770b\uff0c\u4f60\u80fd\u5426\u77e5\u9053\u4ed6\u6709\u6ca1\u6709\u53ef\u80fd\u8fd4\u56de\u7a7a\u6307\u9488\uff1f\u4e0d\u786e\u5b9a\u3002 std::optional foo(ISBN isbn); \u73b0\u5728\u662f\u4e0d\u662f\u5f88\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo *\uff0c\u5927\u6982\u662f\u4e0d\u4f1a\u4e3a NULL \u7684\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e0b\u66f4\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo * \u56e0\u4e3a\u5957\u4e86\u4e00\u5c42 gsl::not_null\uff0c\u5fc5\u5b9a\u4e0d\u80fd\u4e3a NULL\uff08\u5426\u5219\u4f1a\u88ab gsl::not_null \u7684\u65ad\u8a00\u68c0\u6d4b\u5230\uff09\uff0c\u51fd\u6570\u7684\u4f5c\u8005\u662f\u7edd\u5bf9\u4e0d\u4f1a\u6545\u610f\u8fd4\u56de\u4e2a NULL \u7684\u3002 \u5982\u679c\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de nullopt\uff0c\u800c\u4e0d\u662f\u610f\u4e49\u4e0d\u660e\u8fd8\u5bb9\u6613\u5fd8\u8bb0\u7684\u7a7a\u6307\u9488\u3002","title":"—"},{"location":"type_rich_api/#_32","text":"\u8fd8\u662f\u4e0d\u5efa\u8bae\u76f4\u63a5\u7528\u539f\u59cb\u6307\u9488\uff0c\u5efa\u8bae\u7528\u667a\u80fd\u6307\u9488\u6216\u5f15\u7528\u3002 std::optional>> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4eab\u6709\u6240\u6709\u6743\u7684\u72ec\u5360\u6307\u9488\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211 optional \u51fa\u9519\u4e86\u600e\u4e48\u529e\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4e0d\u4eab\u6709\u6240\u6709\u6743\u7684\u5f15\u7528\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 reference_wrapper \u662f\u5bf9\u5f15\u7528\u7684\u5305\u88c5\uff0c\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u5f15\u7528\uff1a int i; std::reference_wrapper ref = i; int &r = ref; // r \u6307\u5411 i \u4f7f\u5f15\u7528\u53ef\u4ee5\u5b58\u5230\u5404\u79cd\u5bb9\u5668\u91cc\uff1a \u4e14\u9047\u5230 auto \u4e0d\u4f1a\u81ea\u52a8\u9000\u5316\uff08decay\uff09\uff1a int i; std::reference_wrapper ref = i; auto ref2 = ref; // ref2 \u63a8\u5bfc\u4e3a std::reference_wrapper int &r = i; auto r2 = r; // r2 \u63a8\u5bfc\u4e3a int \u4e14\u6c38\u8fdc\u4e0d\u4f1a\u4e3a NULL\uff1a std::reference_wrapper ref; // \u7f16\u8bd1\u9519\u8bef\uff1a\u5f15\u7528\u5fc5\u987b\u521d\u59cb\u5316\uff0creference_wrapper \u5f53\u7136\u4e5f\u5fc5\u987b\u521d\u59cb\u5316 \u4e5f\u53ef\u4ee5\u901a\u8fc7 * \u6216 -> \u89e3\u5f15\u7528\uff1a BookInfo book; std::reference_wrapper refBook = book; refBook->readOnline(); BookInfo deepCopyBook = *refBook;","title":"—"},{"location":"type_rich_api/#_33","text":"\u6ce8\u610f .value() \u548c * \u662f\u6709\u533a\u522b\u7684\uff0c * \u4e0d\u4f1a\u68c0\u6d4b\u662f\u5426\u4e3a\u7a7a\uff0c\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u4f46\u66f4\u9ad8\u6548\u3002 o.value(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38 *o; // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 o->readOnline(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u56e0\u6b64\u4e00\u822c\u4f1a\u5728\u5224\u65ad\u4e86 optional \u4e0d\u4e3a\u7a7a\u4ee5\u540e\u624d\u4f1a\u53bb\u8bbf\u95ee * \u548c -> \u3002\u800c .value() \u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u3002 print(foo().value()); // .value() \u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\uff0c\u4e0d\u7528\u5224\u65ad if (auto o = foo()) { // \u5224\u65ad\u8fc7\u786e\u8ba4\u4e0d\u4e3a\u7a7a\u4e86\uff0c\u624d\u80fd\u8bbf\u95ee *o // \u5728\u5df2\u7ecf\u5224\u65ad\u8fc7\u4e0d\u4e3a\u7a7a\u7684 if \u5206\u652f\u4e2d\uff0c\u7528 * \u6bd4 .value() \u66f4\u9ad8\u6548 print(*o); } \u5171\u4eab\u6240\u6709\u6743 * n - shared_ptr * 1 - shared_ptr \u72ec\u5360\u6240\u6709\u6743 * n - vector , unique_ptr * 1 - unique_ptr \u6ca1\u6240\u6709\u6743 * n - span * 1 - reference_wrapper , T &","title":"—"},{"location":"type_rich_api/#_34","text":"\u63a5\u4e0b\u6765\u4ecb\u7ecd optional \u7684\u4e00\u4e9b\u8fdb\u9636\u7528\u6cd5\u3002 std::optional o = BookInfo(1, 2, 3); // \u521d\u59cb\u5316\u4e3a BookInfo \u503c std::optional o; // \u4e0d\u5199\u65f6\u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u7a7a\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt o.emplace(1, 2, 3); // \u5c31\u5730\u6784\u9020\uff0c\u7b49\u4ef7\u4e8e o = BookInfo(1, 2, 3); \u4f46\u4e0d\u9700\u8981\u79fb\u52a8 BookInfo \u4e86 o.reset(); // \u5c31\u5730\u9500\u6bc1\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt;","title":"—"},{"location":"type_rich_api/#_35","text":"\u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 int \u503c\u52a0 1\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readInt(); if (o) { o = *o + 1; } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 transform\uff1a std::optional o = cin.readInt(); o = o.transform([] (int n) { return n + 1; });","title":"—"},{"location":"type_rich_api/#_36","text":"\u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 string \u503c\u89e3\u6790\u4e3a int\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\u3002\u4e14\u89e3\u6790\u51fd\u6570\u53ef\u80fd\u5931\u8d25\uff0c\u5931\u8d25\u5219\u4e5f\u8981\u5c06 optional \u7f6e\u4e3a\u7a7a\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readLine(); std::optional o2; if (o) { o2 = parseInt(*o); } std::optional parseInt(std::string_view sv) { ... } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 and_then\uff1a auto o = cin.readLine().and_then(parseInt);","title":"—"},{"location":"type_rich_api/#_37","text":"\u5f53\u627e\u4e0d\u5230\u6307\u5b9a\u4e66\u7c4d\u65f6\uff0c\u8fd4\u56de\u4e00\u672c\u9ed8\u8ba4\u4e66\u7c4d\u4f5c\u4e3a\u66ff\u4ee3\uff1a auto o = findBook(isbn).value_or(getDefaultBook()); \u7f3a\u70b9\uff1a\u7531\u4e8e value_or \u7684\u53c2\u6570\u4f1a\u63d0\u524d\u88ab\u6c42\u503c\uff0c\u5373\u4f7f findBook \u6210\u529f\u627e\u5230\u4e86\u4e66\u7c4d\uff0c\u4e5f\u4f1a\u6267\u884c getDefaultBook \u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u4f5c\u4e3a\u6b7b\u4ea1\u53f3\u503c\u4e22\u5f03\u3002\u5982\u679c\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\u7684\u8fc7\u7a0b\u5f88\u6162\uff0c\u90a3\u4e48\u5c31\u975e\u5e38\u4f4e\u6548\u3002 \u4e3a\u6b64\uff0cC++23 \u5f15\u5165\u4e86 or_else \u51fd\u6570\u3002 \u53ea\u6709 findBook \u627e\u4e0d\u5230\u65f6\u624d\u4f1a\u6267\u884c lambda \u4e2d\u7684\u51fd\u6570\u4f53\uff1a auto o = findBook(isbn).or_else([] -> std::optional { cout << \"findBook \u51fa\u9519\u4e86\uff0c\u73b0\u5728\u5f00\u59cb\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\uff0c\u975e\u5e38\u6162\\n\"; return getDefaultBook(); });","title":"—"},{"location":"type_rich_api/#_38","text":"\u6b64\u7c7b\u51fd\u6570\u90fd\u53ef\u4ee5\u53cd\u590d\u5d4c\u5957\uff1a int i = cin.readLine() .or_else(getDefaultLine) .and_then(parseInt) .transform([] (auto i) { return i * 2; }) .value_or(0); \u52a0\u5165\u51fd\u6570\u5f0f\u795e\u6559\u5427\uff0c\u51fd\u95e8\uff01","title":"—"},{"location":"type_rich_api/#_39","text":"","title":"—"},{"location":"type_rich_api/#stl","text":"","title":"\u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1"},{"location":"type_rich_api/#_40","text":"\u4f8b\u5982 std::stack \u7684\u8bbe\u8ba1\u5c31\u975e\u5e38\u5931\u8d25\uff1a if (!stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u6211\u4eec\u5fc5\u987b\u5224\u65ad stack \u4e0d\u4e3a\u7a7a\uff0c\u624d\u80fd\u5f39\u51fa\u6808\u9876\u5143\u7d20\u3002\u5bf9\u7740\u4e00\u4e2a\u7a7a\u7684\u6808 pop \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u800c pop() \u53c8\u662f\u4e00\u4e2a\u8fd4\u56de void \u7684\u51fd\u6570\uff0c\u4ed6\u53ea\u662f\u5220\u9664\u6808\u9876\u5143\u7d20\uff0c\u5e76\u4e0d\u4f1a\u8fd4\u56de\u5143\u7d20\u3002 \u6211\u4eec\u5fc5\u987b\u5148\u8c03\u7528 top() \u628a\u6808\u9876\u53d6\u51fa\u6765\uff0c\u7136\u540e\u624d\u80fd pop\uff01 \u660e\u660e\u662f\u540c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5374\u8981\u62c6\u6210\u4e09\u4e2a\u51fd\u6570\u6765\u5b8c\u6210\uff0c\u5f88\u70c2\u3002\u5982\u679c\u4f60\u4e0d\u614e\u628a\u5224\u65ad\u6761\u4ef6\u5199\u53cd\uff1a if (stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u5c31\u4e00\u4e2a Segmentation Fault \u8e66\u4f60\u8138\u4e0a\uff0c\u4f60\u627e\u534a\u5929\u90fd\u627e\u4e0d\u5230\u81ea\u5df1\u54ea\u9519\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u8bbe\u8ba1\uff0c\u6574\u5408\u6210\u4e00\u4e2a\u51fd\u6570\uff1a std::optional pop(); \u8bed\u4e49\u660e\u786e\uff0c\u7528\u8d77\u6765\u4e5f\u65b9\u4fbf\uff0c\u7528\u6237\u4e0d\u5bb9\u6613\u72af\u9519\u3002 if (auto val = stack.pop()) { ... } \u628a\u591a\u4e2a\u672c\u5c31\u5c5e\u4e8e\u540c\u4e00\u4ef6\u4e8b\u7684\u51fd\u6570\uff0c\u6574\u5408\u6210\u4e00\u4e2a\uff0c\u907f\u514d\u7528\u6237\u4e2d\u95f4\u51fa\u7eb0\u6f0f\u3002 \u4ece\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u4e0a\uff0c\u9650\u5b9a\u81ea\u7531\u5ea6\uff0c\u51cf\u8f7b\u7528\u6237\u601d\u8003\u8d1f\u62c5\u3002","title":"—"},{"location":"type_rich_api/#_41","text":"\u4f17\u6240\u5468\u77e5\uff0cvector \u6709\u4e24\u4e2a\u51fd\u6570\u7528\u4e8e\u8bbf\u95ee\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 int &operator[](size_t index); int &at(size_t index); vec[3]; // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u53d1\u751f\u6570\u7ec4\u8d8a\u754c\uff01\u8fd9\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vec.at(3); // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u629b\u51fa out_of_range \u5f02\u5e38 \u7528\u6237\u901a\u5e38\u4f1a\u6839\u636e\u81ea\u5df1\u7684\u9700\u8981\uff0c\u5982\u679c\u4ed6\u4eec\u975e\u5e38\u81ea\u4fe1\u81ea\u5df1\u7684\u7d22\u5f15\u4e0d\u4f1a\u8d8a\u754c\uff0c\u53ef\u4ee5\u7528\u9ad8\u6548\u7684 []\uff0c\u4e0d\u505a\u68c0\u6d4b\u3002 \u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u53ef\u4ee5\u7528\u66f4\u5b89\u5168\u7684 at()\uff0c\u4e00\u65e6\u8d8a\u754c\u81ea\u52a8\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u8c03\u8bd5\u3002 \u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u8bbe\u8ba1\u4e00\u4e2a .get() \u51fd\u6570\uff1a std::optional get(size_t index); \u5f53\u68c0\u6d4b\u5230\u6570\u7ec4\u8d8a\u754c\u65f6\uff0c\u8fd4\u56de nullopt\u3002 *vec.get(3); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u6027\u80fd\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ece\u800c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u4f18\u5316\u6389\u8d8a\u754c\u7684\u8def\u5f84 vec.get(3).value(); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u5b89\u5168\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u4e00\u4e2a\u5f02\u5e38 vec.get(3).value_or(0); // \u5982\u679c\u7528\u6237\u60f3\u8981\u5728\u8d8a\u754c\u65f6\u83b7\u5f97\u9ed8\u8ba4\u503c 0 \u8fd9\u6837\u5c31\u53ea\u9700\u8981\u4e00\u4e2a\u51fd\u6570\uff0c\u4e0d\u8bba\u7528\u6237\u60f3\u8981\u7684\u662f\u4ec0\u4e48\uff0c\u90fd\u53ea\u9700\u8981\u8fd9\u4e00\u4e2a\u7edf\u4e00\u7684 get() \u51fd\u6570\u3002","title":"—"},{"location":"type_rich_api/#_42","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8fd9\u4e2a\u53ea\u80fd get\uff0c\u8981\u5982\u4f55 set \u5440\uff1f std::optional get(size_t index); bool set(size_t index, int value); // \u5982\u679c\u8d8a\u754c\uff0c\u8fd4\u56de false \u7f3a\u70b91\uff1a\u8fd4\u56de bool \u65e0\u6cd5\u8fd0\u7528 optional \u7684\u5c0f\u6280\u5de7\uff1a\u901a\u8fc7 value() \u8f6c\u5316\u4e3a\u5f02\u5e38\uff0c\u4e14\u7528\u6237\u5bb9\u6613\u5fd8\u8bb0\u68c0\u67e5\u8fd4\u56de\u503c\u3002 \u7f3a\u70b92\uff1a\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f size_t \u4e00\u4e2a\u662f int\uff0c\u8fd8\u662f\u5f88\u5bb9\u6613\u987a\u5e8f\u641e\u6df7\u3002 std::optional> get(size_t index); auto x = **vec.get(3); // \u6027\u80fd\u8bfb auto x = *vec.get(3).value(); // \u5b89\u5168\u8bfb *vec.get(3) = 42; // \u6027\u80fd\u5199 vec.get(3).value() = 42; // \u5b89\u5168\u5199","title":"—"},{"location":"type_rich_api/#_43","text":"","title":"—"},{"location":"type_rich_api/#stl_1","text":"","title":"\u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206"},{"location":"type_rich_api/#_44","text":"void Sleep(int delay); \u8c01\u77e5\u9053\u8fd9\u4e2a delay \u7684\u5355\u4f4d\u662f\u4ec0\u4e48\uff1f\u79d2\uff1f\u6beb\u79d2\uff1f void Sleep(int ms); \u597d\u5427\uff0c\u662f\u6beb\u79d2\u3002\u53ef\u662f\u9664\u975e\u770b\u4e00\u773c\u51fd\u6570\u5b9a\u4e49\u6216\u6587\u6863\uff0c\u8c01\u60f3\u5f97\u5230\u8fd9\u662f\u4e2a\u6beb\u79d2\uff1f \u4e00\u4e2a\u7528\u6237\u60f3\u8981\u7761 3 \u79d2\uff0c\u4ed6\u5199\u9053\uff1a Sleep(3); \u7f16\u8bd1\u5668\u6ca1\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u4e00\u8fd0\u884c\u53ea\u7761\u4e86 3 \u6beb\u79d2\u3002 \u7528\u6237\u5927\u53d1\u96f7\u9706\u4ee5\u4e3a\u4f60\u7684 Sleep \u51fd\u6570\u6709 BUG\uff0c\u6211\u8ba9\u4ed6\u7761 3 \u79d2\u600e\u4e48\u597d\u50cf\u6839\u672c\u6ca1\u7761\u554a\u3002","title":"—"},{"location":"type_rich_api/#_45","text":"void SleepMilliSeconds(int ms); \u6539\u4e2a\u51fd\u6570\u540d\u53ef\u4ee5\u89e3\u51b3\u4e00\u90e8\u5206\u95ee\u9898\uff0c\u5f53\u7528\u6237\u8c03\u7528\u65f6\uff0c\u4ed6\u9700\u8981\u624b\u52a8\u6253\u51fa MilliSeconds \uff0c\u4ece\u800c\u5f3a\u8feb\u4ed6\u6e05\u9192\u4e00\u4e0b\uff0c\u81ea\u5df1\u7ed9\u7684 3 \u5230\u5e95\u662f\u4e0d\u662f\u81ea\u5df1\u60f3\u8981\u7684\u3002","title":"—"},{"location":"type_rich_api/#_46","text":"struct MilliSeconds { int count; explicit MilliSeconds(int count) : count(count) {} }; void Sleep(MilliSeconds delay); \u73b0\u5728\uff0c\u5982\u679c\u7528\u6237\u5199\u51fa Sleep(3); \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\u3002 \u4ed6\u5fc5\u987b\u660e\u786e\u5199\u51fa Sleep(MilliSeconds(3)); \u624d\u80fd\u901a\u8fc7\u7f16\u8bd1\u3002","title":"—"},{"location":"type_rich_api/#_47","text":"\u6807\u51c6\u5e93\u7684 chrono \u6a21\u5757\u5c31\u5927\u91cf\u8fd0\u7528\u4e86\u8fd9\u79cd\u5f3a\u7c7b\u578b\u5c01\u88c5\uff1a this_thread::sleep_for(chrono::seconds(3)); \u5982\u679c\u4f60 using namespace std::literials; \u8fd8\u53ef\u4ee5\u8fd9\u6837\u5feb\u6377\u5730\u521b\u5efa\u5b57\u9762\u91cf\uff1a this_thread::sleep_for(3ms); // 3 \u6beb\u79d2 this_thread::sleep_for(3s); // 3 \u79d2 this_thread::sleep_for(3m); // 3 \u5206\u949f this_thread::sleep_for(3h); // 3 \u5c0f\u65f6 \u4e14\u652f\u6301\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c\u4e0d\u540c\u5355\u4f4d\u4e4b\u95f4\u8fd8\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\uff1a this_thread::sleep_for(1s + 200ms); chrono::minutes three_minutes = 180s;","title":"—"},{"location":"type_rich_api/#_48","text":"chrono \u662f\u4e00\u4e2a\u4f18\u79c0\u7684\u7c7b\u578b\u5c01\u88c5\u6848\u4f8b\uff0c\u628a time_t \u7c7b\u578b\u5c01\u88c5\u6210\u4e86\u5f3a\u7c7b\u578b\u7684 duration \u548c time_point\u3002 \u65f6\u95f4\u70b9\uff08time_point\uff09\u8868\u793a\u67d0\u4e2a\u5177\u4f53\u7684\u65f6\u95f4\uff0c\u4f8b\u5982 2024 \u5e74 5 \u6708 16 \u65e5 18:06:28\u3002 \u65f6\u95f4\u6bb5\uff08duration\uff09\u8868\u793a\u4e00\u6bb5\u65f6\u95f4\u7684\u957f\u5ea6\uff0c\u4f8b\u5982 1 \u5929\uff0c2 \u5c0f\u65f6\uff0c3 \u5206\u949f\uff0c4 \u79d2\u3002 \u65f6\u95f4\u6bb5\u5f88\u5bb9\u6613\u8868\u793a\uff0c\u53ea\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u5355\u4f4d\uff0c\u6bd4\u5982\u79d2\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u6570\u5b57\u5c31\u53ef\u4ee5\u8868\u793a\u591a\u5c11\u79d2\u7684\u65f6\u95f4\u6bb5\u3002 \u4f46\u662f\u65f6\u95f4\u70b9\u5c31\u5f88\u96be\u8868\u793a\u4e86\uff0c\u4f8b\u5982\u4f60\u65e0\u6cd5 Unix \u65f6\u95f4\u6233\u7528\u4e00\u4e2a\u6570\u5b57\u6765\u8868\u793a\u65f6\u95f4\u70b9\uff0c\u6570\u5b57\u7684\u542b\u4e49\u662f\u4ece\u5f53\u524d\u65f6\u95f4\u5230 1970 \u5e74 1 \u6708 1 \u65e5 00:00:00 \u7684\u79d2\u6570\u3002 \u4f8b\u5982\u5199\u4f5c\u8fd9\u7bc7\u6587\u7ae0\u7684\u65f6\u95f4\u6233\u662f 1715853968 (2024/5/16 18:06)\u3002 C \u8bed\u8a00\u7528\u4e00\u4e2a time_t \uff0c\u5b9e\u9645\u4e0a\u662f long \u7684\u7c7b\u578b\u522b\u540d\u6765\u8868\u793a\u65f6\u95f4\u6233\uff0c\u4f46\u5b83\u6709\u4e00\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff1a \u5b83\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u70b9\uff0c\u4e5f\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u6bb5\uff0c\u8fd9\u5c31\u9020\u6210\u4e86\u5de8\u5927\u7684\u6df7\u4e71\u3002 time_t t0 = time(NULL); // \u65f6\u95f4\u70b9 ... time_t t1 = time(NULL); // \u65f6\u95f4\u70b9 time_t dt = t1 - t0; // \u65f6\u95f4\u6bb5 \u75db\u70b9\uff1a\u5982\u679c\u8fd9\u91cc\u7684\u8d1f\u53f7\u5199\u9519\uff0c\u5199\u6210 t1 + t0 \uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u62a5\u9519\uff0c\u4f60\u53ef\u80fd\u6839\u672c\u6ca1\u53d1\u73b0\uff0c\u6d6a\u8d39\u5927\u91cf\u65f6\u95f4\u8c03\u8bd5\u6700\u540e\u53ea\u53d1\u73b0\u4e00\u4e2a\u4f4e\u7ea7\u9519\u8bef\u3002 \u6a21\u7cca\uff1a\u65f6\u95f4\u70b9\uff08t0\u3001t1\uff09\u548c\u65f6\u95f4\u6bb5\uff08dt\uff09\u90fd\u662f time_t\uff0c\u521d\u6b21\u9605\u8bfb\u4ee3\u7801\u5f88\u5bb9\u6613\u5206\u4e0d\u6e05\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5\u3002 \u5982\u679c\u4e0d\u614e\u628a\u201c\u65f6\u95f4\u70b9\u201d\u7684 time_t \u4f20\u5165\u5230\u672c\u5e94\u53ea\u652f\u6301\u201c\u65f6\u95f4\u6bb5\u201d\u7684 sleep \u51fd\u6570\uff0c\u4f1a\u51fa\u73b0\u201c\u7761\u7f8e\u4eba\u201d\u7684\u5947\u89c2\uff1a time_t t = time(NULL); // \u8fd4\u56de 1715853968 \u8868\u793a\u5f53\u524d\u65f6\u95f4\u70b9 sleep(t); // \u4e0d\u5c0f\u5fc3\u628a\u65f6\u95f4\u70b9\u5f53\u6210\u65f6\u95f4\u6bb5\u6765\u7528\u4e86\uff01 \u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u7761 1715853968 \u79d2\u540e\u624d\u9192\uff0c\u5373 54 \u5e74\u540e\uff01 chrono::system_clock::time_point last = chrono::system_clock::now(); ... chrono::system_clock::time_point now = chrono::system_clock::now(); chrono::system_clock::duration dt = now - last; cout << \"\u7528\u4e86 \" << duration_cast(dt).count() << \" \u79d2\\n\"; \u4e00\u770b\u5c31\u77e5\u9053\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5 \u7528\u9519\u4e86\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \u5355\u4f4d\u8f6c\u6362\u4e0d\u4f1a\u6df7\u6dc6 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u70b9 = \u7f16\u8bd1\u51fa\u9519\uff01\u56e0\u4e3a\u65f6\u95f4\u70b9\u4e4b\u95f4\u4e0d\u5141\u8bb8\u76f8\u52a0\uff0c2024 + 2024\uff0c\u4f60\u662f\u60f3\u52a0\u5230 4048 \u5e74\u53bb\u5417\uff1f \u65f6\u95f4\u70b9 - \u65f6\u95f4\u70b9 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u70b9 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u6bb5 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 \u00d7 \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 / \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u8fd9\u5c31\u662f\u672c\u671f\u8bfe\u7a0b\u7684\u4e3b\u9898\uff0c\u901a\u8fc7\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u5bf9\u53ef\u80fd\u7684\u7528\u6cd5\u52a0\u4ee5\u4e25\u683c\u7684\u9650\u5236\uff0c\u6700\u5927\u9650\u5ea6\u963b\u6b62\u7528\u6237\u4e0d\u7ecf\u610f\u95f4\u5199\u51fa\u9519\u8bef\u7684\u4ee3\u7801\u3002","title":"—"},{"location":"type_rich_api/#_49","text":"","title":"—"},{"location":"type_rich_api/#_50","text":"","title":"\u679a\u4e3e\u7c7b\u578b"},{"location":"type_rich_api/#_51","text":"\u4f60\u7684\u8001\u677f\u8981\u6c42\u4e00\u4e2a\u8bbe\u5b9a\u5ba2\u6237\u6027\u522b\u7684\u51fd\u6570\uff1a void foo(int sex); \u8001\u677f\u53e3\u5934\u548c\u5458\u5de5\u7ea6\u5b9a\u8bf4\uff0c0\u8868\u793a\u5973\uff0c1\u8868\u793a\u7537\uff0c2\u8868\u793a\u81ea\u5b9a\u4e49\u3002 \u8fd9\u8c01\u8bb0\u5f97\u4f4f\uff1f\u8bbe\u60f3\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u7684\u4ee3\u7801\uff1a foo(1); \u4f60\u80fd\u731c\u5230\u8fd9\u4e2a 1 \u662f\u4ec0\u4e48\u610f\u601d\u5417\uff1f \u89e3\u51b3\u65b9\u6cd5\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff0c\u7ed9\u6bcf\u4e2a\u6570\u503c\u4e00\u4e2a\u552f\u4e00\u7684\u540d\u5b57\uff1a enum Sex { Female = 0, Male = 1, Custom = 2, }; void foo(Sex sex); \u518d\u5047\u8bbe\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\uff1a foo(Male); \u662f\u4e0d\u662f\u5c31\u4e00\u76ee\u4e86\u7136\u5566\uff1f","title":"—"},{"location":"type_rich_api/#_52","text":"\u679a\u4e3e\u7684\u503c\u4e5f\u53ef\u4ee5\u4e0d\u7528\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u6309 0\u30011\u30012 \u7684\u987a\u5e8f\u5206\u914d\u503c\uff1a enum Sex { Female, // 0 Male, // 1 Custom, // 2 }; \u53ef\u4ee5\u6307\u5b9a\u4ece 1 \u5f00\u59cb\u8ba1\u6570\uff1a enum Sex { Female = 1, Male, // 2 Custom, // 3 };","title":"—"},{"location":"type_rich_api/#_53","text":"\u4f46\u679a\u4e3e\u7c7b\u578b\u8fd8\u662f\u53ef\u4ee5\u9a97\u4eba\uff0c\u518d\u5047\u8bbe\u4f60\u662f\u65b0\u6765\u7684\uff0c\u770b\u5230\uff1a foo(Male, 24); \u662f\u4e0d\u662f\u60f3\u5f53\u7136\u7684\u611f\u89c9\u8fd9\u4e2a\u4ee3\u7801\u6ca1\u95ee\u9898\uff1f \u4f46\u5f53\u4f60\u770b\u5230 foo \u51c6\u786e\u7684\u51fd\u6570\u5b9a\u4e49\u65f6\uff0c\u50bb\u773c\u4e86\uff1a void foo(int age, Sex sex); \u76f8\u5f53\u4e8e\u6ce8\u518c\u4e86\u4e00\u4e2a 1 \u5c81\uff0c\u6027\u522b\u662f 24 \u7684\u4f2a\u4eba\u3002\u4e14\u7a0b\u5e8f\u5458\u5f88\u5bb9\u6613\u770b\u4e0d\u51fa\u95ee\u9898\uff0c\u7f16\u8bd1\u5668\u4e5f\u4e0d\u62a5\u9519\u3002 \u4e3a\u6b64\uff0cC++11 \u5f15\u5165\u4e86 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff1a enum class Sex { Female = 0, Male = 1, Custom = 2, }; \u73b0\u5728\uff0c\u5982\u679c\u4f60\u518d\u4e0d\u5c0f\u5fc3\u628a sex \u4f20\u5165 age \u7684\u8bdd\uff0c\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\uff01\u56e0\u4e3a\u5f3a\u7c7b\u578b\u679a\u4e3e\u4e0d\u5141\u8bb8\u4e0e int \u9690\u5f0f\u8f6c\u6362\u3002 \u800c\u4e14\u5f3a\u7c7b\u578b\u679a\u4e3e\u4f1a\u9700\u8981\u663e\u5f0f\u5199\u51fa Sex:: \u7c7b\u578b\u524d\u7f00\uff0c\u5f53\u4f60\u6709\u5f88\u591a\u679a\u4e3e\u7c7b\u578b\u65f6\u4e0d\u5bb9\u6613\u6df7\u6dc6\uff1a foo(24, Sex::Male); \u5982\u679c\u4f60\u7684 Sex \u8303\u56f4\u5f88\u5c0f\uff0c\u53ea\u9700\u8981 uint8_t \u7684\u5185\u5b58\u5c31\u591f\uff0c\u53ef\u4ee5\u7528\u8fd9\u4e2a\u8bed\u6cd5\u6307\u5b9a\u679a\u4e3e\u7684\u201c\u540e\u53f0\u7c7b\u578b\u201d\uff1a enum class Sex : uint8_t { Female = 0, Male = 1, Custom = 2, }; static_assert(sizeof(Sex) == 1);","title":"—"},{"location":"type_rich_api/#_54","text":"\u5047\u5982\u4f60\u7684\u6240\u6709 age \u90fd\u662f int \u7c7b\u578b\u7684\uff0c\u4f46\u662f\u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u5fc3\u8840\u6765\u6f6e\uff1a \u8bf4\u4e3a\u4e86\u201c\u4f18\u5316\u5b58\u50a8\u7a7a\u95f4\u201d\uff0c\u60f3\u8981\u628a\u6240\u6709 age \u6539\u6210 uint8_t \u7c7b\u578b\u7684\uff01 \u4e3a\u4e86\u9884\u9632\u672a\u6765\u53ef\u80fd\u9700\u8981\u6539\u53d8\u7c7b\u578b\u7684\u9700\u6c42\uff0c\u4e5f\u662f\u4e3a\u4e86\u53ef\u8bfb\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using Age = int; void foo(Age age, Sex sex); \u8fd9\u6837\u5f53\u8001\u677f\u9700\u8981\u6539\u53d8\u5e95\u5c42\u7c7b\u578b\u65f6\uff0c\u53ea\u9700\u8981\u6539\u52a8\u4e00\u884c\uff1a using Age = uint8_t; \u5c31\u80fd\u81ea\u52a8\u8ba9\u6240\u6709\u4ee3\u7801\u90fd\u4f7f\u7528 uint8_t \u4f5c\u4e3a age \u4e86\u3002","title":"—"},{"location":"type_rich_api/#_55","text":"\u4f46\u662f\u7c7b\u578b\u522b\u540d\u6bd5\u7adf\u53ea\u662f\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u4fdd\u969c\uff1a using Age = int; using Phone = int; foo(Age age, Phone phone); void bar() { Age age = 42; Phone phone = 12345; foo(phone, age); // \u4e0d\u5c0f\u5fc3\u5199\u53cd\u4e86\uff01\u800c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u63d0\u9192\u4f60\uff01 } \u56e0\u4e3a Age \u548c Phone \u53ea\u662f\u7c7b\u578b\u522b\u540d\uff0c\u5b9e\u9645\u4e0a\u8fd8\u662f\u540c\u6837\u7684 int \u7c7b\u578b\u2026\u6240\u4ee5\u7f16\u8bd1\u5668\u751a\u81f3\u4e0d\u4f1a\u6709\u4efb\u4f55\u8b66\u544a\u3002 \u6709\u4e00\u79cd\u5f88\u6781\u7aef\u7684\u505a\u6cd5\u662f\u628a Age \u548c Phone \u4e5f\u505a\u6210\u679a\u4e3e\uff0c\u4f46\u6ca1\u6709\u5b9a\u4e49\u4efb\u4f55\u503c\uff1a enum class Age : int {}; enum class Phone : int {}; \u8fd9\u6837\u7528\u5230\u7684\u65f6\u5019\u5c31\u53ea\u80fd\u901a\u8fc7\u5f3a\u5236\u8f6c\u6362\u7684\u8bed\u6cd5\uff1a foo(Age(42), Phone(12345)); \u5e76\u4e14\u5982\u679c\u5199\u9519\u987a\u5e8f\uff0c\u5c1d\u8bd5\u628a Phone \u4f20\u5165 Age \u7c7b\u578b\u7684\u53c2\u6570\uff0c\u7f16\u8bd1\u5668\u4f1a\u7acb\u5373\u62a5\u9519\uff0c\u963b\u6b62\u4f60\u57cb\u4e0b BUG \u9690\u60a3\u3002","title":"—"},{"location":"type_rich_api/#_56","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u7684\u65b9\u6cd5\u4ee5\u540e\uff0c\u4e0d\u80fd\u505a\u52a0\u6cd5\u4e86\u600e\u4e48\u529e\uff1f Age(42) + Age(1) // \u7f16\u8bd1\u5668\u9519\u8bef\uff01 \u8fd9\u662f\u56e0\u4e3a Age \u662f\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u4e0d\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a int \u540e\u505a\u52a0\u6cd5\u3002 \u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff1a enum class Age : int {}; inline Age operator+(Age a, Age b) { return Age((int)a + (int)b); } \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u76f4\u63a5\u8ba9\u52a0\u6cd5\u8fd0\u7b97\u7b26\u5bf9\u4e8e\u6240\u6709\u679a\u4e3e\u7c7b\u578b\u90fd\u9ed8\u8ba4\u751f\u6548\uff1a template requires std::is_enum_v T operator+(T a, T b) { using U = std::underlying_type_t; return T((U)a + (U)b); } \u6709\u65f6\u8fd9\u53cd\u800c\u662f\u4e2a\u4f18\u70b9\uff0c\u6bd4\u5982\u4f60\u53ef\u4ee5\u53ea\u5b9a\u4e49\u52a0\u6cd5\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u8ba9 Age \u4e0d\u652f\u6301\u4e58\u6cd5\uff0c\u9700\u8981\u624b\u52a8\u8f6c\u6362\u540e\u624d\u80fd\u4e58\uff0c\u907f\u514d\u65e0\u610f\u4e2d\u72af\u9519\u7684\u53ef\u80fd\u3002","title":"—"},{"location":"type_rich_api/#_57","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u63a8\u8350\u7684 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff0c\u4e0d\u652f\u6301\u6211\u6700\u7231\u7684\u6216\u8fd0\u7b97 | \u4e86\u600e\u4e48\u529e\uff1f enum class OpenFlag { Create = 1, Read = 2, Write = 4, Truncate = 8, Append = 16, Binary = 32, }; inline OpenFlag operator|(OpenFlag a, OpenFlag b) { return OpenFlag((int)a | (int)b); } inline OpenFlag operator&(OpenFlag a, OpenFlag b) { return OpenFlag((int)a & (int)b); } inline OpenFlag operator~(OpenFlag a) { return OpenFlag(~(int)a); }","title":"—"},{"location":"type_rich_api/#_58","text":"","title":"—"},{"location":"type_rich_api/#_59","text":"","title":"\u5176\u4ed6\u7c7b\u578b\u5957\u76ae"},{"location":"type_rich_api/#_60","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5f88\u559c\u6b22\u5f3a\u7c7b\u578b\u679a\u4e3e\u8fd9\u4e00\u5957\uff0c\u4f46\u6211\u7684\u53c2\u6570\u4e0d\u662f\u6574\u6570\u7c7b\u578b\uff0c\u800c\u662f double\u3001string \u7b49\u7c7b\u578b\uff0c\u600e\u4e48\u529e\uff1f struct Name { private: std::string value; public: explicit operator std::string() const { return value; } explicit Name(std::string value) : value(value) {} }; \u8fd9\u91cc\u6211\u4eec\u5199 explicit \u5c31\u53ef\u4ee5\u963b\u6b62\u9690\u5f0f\u7c7b\u578b\u8f6c\u6362\uff0c\u8d77\u5230\u4e0e\u5f3a\u7c7b\u578b\u679a\u4e3e\u7c7b\u4f3c\u7684\u4f5c\u7528\u3002 \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff1a // \u6b64\u5904\u4f7f\u7528 CRTP \u6a21\u5f0f\u662f\u4e3a\u4e86\u8ba9 Typed \u6bcf\u6b21\u90fd\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684\u57fa\u7c7b\uff0c\u963b\u6b62 object-slicing template struct Typed { protected: T value; public: explicit operator T() const { return value; } explicit Typed(T value) : value(value) {} }; struct Name : Typed {}; struct Meter : Typed { using Typed::Typed; }; struct Kilometer : Typed { using Typed::Typed; operator Meter() const { // \u5141\u8bb8\u9690\u5f0f\u8f6c\u6362\u4e3a\u7c73 return Meter(value * 1000); } }; Meter m = Kilometer(1); // m = Meter(1000); foo(m);","title":"—"},{"location":"type_rich_api/#_61","text":"","title":"—"},{"location":"type_rich_api/#raii","text":"","title":"RAII \u5c01\u88c5"},{"location":"type_rich_api/#_62","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7684\u51fd\u6570\u5c31\u662f\u6d89\u53ca\u201c\u5f00\u59cb\u201d\u548c\u201c\u7ed3\u675f\u201d\u4e24\u4e2a\u64cd\u4f5c\uff0c\u7528\u6237\u7684\u64cd\u4f5c\u9700\u8981\u7a7f\u63d2\u5728\u5176\u4e2d\u95f4\uff0c\u600e\u4e48\u6574\u5408\u5462\uff1f mysql_connection *conn = mysql_connect(\"127.0.0.1\"); mysql_execute(conn, \"drop database paolu\"); mysql_close(conn); // \u7528\u6237\u53ef\u80fd\u5fd8\u8bb0\u5173\u95ed\u8fde\u63a5\uff01\u7834\u574f\u5e93\u8bbe\u8ba1\u8005\u60f3\u8981\u7684\u7528\u6cd5 \u8fd9\u79cd\u5927\u591a\u662f\u83b7\u53d6\u8d44\u6e90\uff0c\u548c\u91ca\u653e\u8d44\u6e90\u4e24\u4e2a\u64cd\u4f5c\u3002 \u56e0\u4e3a mysql \u662f\u4e2a C \u8bed\u8a00\u7684\u5e93\uff0c\u4ed6\u6ca1\u6709 RAII \u5c01\u88c5\uff0c\u8ba9\u4ed6\u624b\u52a8\u5c01\u88c5\u6709\u7684\u540c\u5b66\u53c8\u5acc\u5f03\u9ebb\u70e6\u3002 \u8fd9\u65f6\u6211\u4f1a\u544a\u8bc9\u4ed6\u4eec\u4e00\u4e2a shared_ptr \u5c0f\u5999\u62db\uff1a\u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u6307\u5b9a\u91ca\u653e\u51fd\u6570\uff0c\u4ee3\u66ff\u9ed8\u8ba4\u7684 delete auto conn = std::shared_ptr(mysql_connect(\"127.0.0.1\"), mysql_close); mysql_execute(conn.get(), \"drop database paolu\"); // conn \u79bb\u5f00\u4f5c\u7528\u57df\u65f6\uff0c\u4f1a\u81ea\u52a8\u8c03\u7528 mysql_close\uff0c\u675c\u7edd\u4e86\u4e00\u4e2a\u51fa\u9519\u7684\u53ef\u80fd","title":"—"},{"location":"type_rich_api/#_63","text":"\u4ee5\u5c01\u88c5 C \u8bed\u8a00\u7684 FILE \u4e3a\u4f8b\u3002 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *file); \u8fd9\u4e2a size \u548c nmemb \u771f\u662f\u592a\u7cdf\u7cd5\u4e86\uff0c\u672c\u610f\u662f\u4e3a\u4e86\u652f\u6301\u4e0d\u540c\u5143\u7d20\u7c7b\u578b\u7684\u6570\u7ec4\u3002 size \u662f\u5143\u7d20\u672c\u8eab\u5927\u5c0f\uff0cnmemb \u662f\u5143\u7d20\u6570\u91cf\u3002\u5b9e\u9645\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u662f size * nmemb\u3002 \u6211\u5c31\u7ecf\u5e38\u628a ptr \u548c file \u987a\u5e8f\u5199\u53cd\uff0c\u8fd9\u4e2a\u83ab\u540d\u5176\u5999\u7684\u53c2\u6570\u987a\u5e8f\u592a\u53cd\u76f4\u89c9\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u8fd0\u7528\u73b0\u4ee3 C++ \u601d\u60f3\u5c01\u88c5\u4e4b\uff1a using FileHandle = std::shared_ptr; enum class OpenMode { Read, Write, Append, }; inline OpenMode operator|(OpenMode a, OpenMode b) { return OpenMode((int)a | (int)b); } auto modeLut = std::map{ {OpenMode::Read, \"r\"}, {OpenMode::Write, \"w\"}, {OpenMode::Append, \"a\"}, {OpenMode::Read | OpenMode::Write, \"w+\"}, {OpenMode::Read | OpenMode::Append, \"a+\"}, }; FileHandle file_open(std::filesystem::path path, OpenMode mode) { #ifdef _WIN32 return std::shared_ptr(_wfopen(path.wstring().c_str(), modeLut.at(mode).c_str()), fclose); #else return std::shared_ptr(fopen(path.string().c_str(), modeLut.at(mode).c_str()), fclose); #endif } struct [[nodiscard]] FileResult { std::optional numElements; std::errc errorCode; // std::errc \u662f\u4e2a\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u7528\u4e8e\u53d6\u4ee3 C \u8bed\u8a00 errno \u7684 int \u7c7b\u578b bool isEndOfFile; }; template FileResult file_read(FileHandle file, std::span elements) { auto n = fread(elements.data(), sizeof(T), elements.size(), file.get()); return { .numElements = n == 0 ? std::optional(n) : std::nullopt, .errorCode = std::errc(ferror(file.get())), .isEndOfFile = (bool)feof(file.get()), }; } \u662f\u4e0d\u662f\u63a5\u53e3\u66f4\u52a0\u7b80\u5355\u6613\u61c2\uff0c\u6ca1\u6709\u72af\u9519\u7684\u673a\u4f1a\u4e86\uff1f FileHandle file = file_open(\"hello.txt\", OpenMode::Read); int arr[32]; file_read(file, arr).numElements.value(); // \u5982\u679c\u6ca1\u6709\u8bfb\u5230\u4e1c\u897f\uff0c\u8fd9\u91cc\u4f1a\u629b\u51fa\u5f02\u5e38 // \u9000\u51fa\u4f5c\u7528\u57df\u65f6\uff0cshared_ptr \u4f1a\u81ea\u52a8\u4e3a\u4f60\u5173\u95ed\u6587\u4ef6\uff0c\u65e0\u9700\u518d\u63d0\u4f9b file_close \u51fd\u6570","title":"—"},{"location":"type_rich_api/#_64","text":"","title":"—"},{"location":"type_rich_api/#mutex","text":"","title":"Mutex \u5c01\u88c5"},{"location":"type_rich_api/#_65","text":"","title":"—"},{"location":"type_rich_api/#_66","text":"","title":"—"},{"location":"type_rich_api/#cuda","text":"","title":"\u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218"},{"location":"type_rich_api/#_67","text":"","title":"—"},{"location":"type_rich_api/#_68","text":"","title":"\u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236"},{"location":"type_rich_api/#_69","text":"","title":"—"},{"location":"type_rich_api/#_70","text":"","title":"—"},{"location":"type_rich_api/#getset","text":"","title":"\u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f"},{"location":"type_rich_api/#_71","text":"TODO","title":"—"},{"location":"undef/","text":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f \u9664\u6570\u4e0d\u80fd\u4e3a 0 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 \u603b\u7ed3 CppCon \u76f8\u5173\u89c6\u9891 \u5982\u6709\u758f\u6f0f\uff0c\u53ef\u4ee5\u5728 GitHub \u8865\u5145\u3002 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u53ef\u4ee5\u5e2e\u52a9\u4f60\u76d1\u6d4b\u672a\u5b9a\u4e49\u884c\u4e3a msvc: Debug \u914d\u7f6e gcc: \u5b9a\u4e49 _GLIBCXX_DEBUG \u5b8f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u53ea\u8981\u89e3\u5f15\u7528\u5c31\u9519\u4e86\uff0c\u65e0\u8bba\u662f\u5426\u8bfb\u53d6\u6216\u5199\u5165 int *p = nullptr; *p; // \u9519\uff01 &*p; // \u9519\uff01 *p = 0; // \u9519\uff01 int i = *p; // \u9519\uff01 unique_ptr p = nullptr; p.get(); // \u53ef\u4ee5 &*p; // \u9519\uff01 \u4f8b\u5982\u5728 Debug \u914d\u7f6e\u7684 MSVC STL \u4e2d\uff0c &*p \u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38\uff0c\u800c p.get() \u4e0d\u4f1a\u3002 if (&*p != nullptr) { // \u53ef\u80fd\u88ab\u4f18\u5316\u4e3a if (1)\uff0c\u56e0\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u88ab\u6392\u9664\u4e86 } if (p != nullptr) { // \u4e0d\u4f1a\u88ab\u4f18\u5316\uff0c\u6b63\u5e38\u5224\u65ad } \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 std::vector v = {1, 2, 3, 4}; int *begin = &*v.begin(); int *end = &*v.end(); // \u9519\uff01 std::vector v = {}; int *begin = &*v.begin(); // \u9519! int *end = &*v.end(); // \u9519\uff01 \u5efa\u8bae\u6539\u7528 data \u548c size std::vector v = {1, 2, 3, 4}; int *begin = v.data(); int *end = v.data() + v.size(); this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a struct C { void print() { if (this == nullptr) { // \u6b64\u5206\u652f\u53ef\u80fd\u4f1a\u88ab\u4f18\u5316\u4e3a if (0) { ... } \u4ece\u800c\u6c38\u4e0d\u751f\u6548 std::cout << \"this \u662f\u7a7a\\n\"; } } }; void func() { C *c = nullptr; c->print(); // \u9519\uff01 } \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 struct C{ void f() {} static void f2() {} }; void func(){ C* c = nullptr; c->f(); // \u884c\u4e3a\u672a\u5b9a\u4e49 c->f2(); // \u884c\u4e3a\u672a\u5b9a\u4e49 } \u672c\u8d28\u4e0a\u662f\u56e0\u4e3a \u7a7a\u6307\u9488\u89e3\u5f15\u7528 \u3002\u5bf9\u4e8e\u5185\u5efa\u7c7b\u578b\uff0c\u8868\u8fbe\u5f0f E1->E2 \u4e0e (*E1).E2 \u4e25\u683c\u7b49\u4ef7\uff0c\u4efb\u4f55\u6307\u9488\u7c7b\u578b\u90fd\u662f\u5185\u5efa\u7c7b\u578b\u3002 c->f() \u3001 c->f2() \u7b49\u4ef7\u4e8e\uff1a (*c).f(); (*c).f2(); \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee int i; float f = *(float *)&i; // \u9519\uff01 \u4f8b\u5916\uff1achar\u3001signed char\u3001unsigned char \u548c std::byte \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b int i; char *buf = (char *)&i; // \u53ef\u4ee5 buf[0] = 1; // \u53ef\u4ee5 uint8_t \u662f unsigned char \u7684\u522b\u540d\uff0c\u6240\u4ee5\u4e5f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b \u4f8b\u5916\uff1aint \u548c unsigned int \u4e92\u76f8\u517c\u5bb9 int i; unsigned int f = *(unsigned int *)&i; // \u53ef\u4ee5 \u4f8b\u5916\uff1aconst int * \u548c int * \u4e92\u76f8\u517c\u5bb9\uff08\u4e8c\u7ea7\u6307\u9488\u5f3a\u8f6c\uff09 const int *cp; int *p = *(int **)&cp; // \u53ef\u4ee5 \u6ce8\u610f\uff1a\u53ea\u53d6\u51b3\u4e8e\u8bbf\u95ee\u65f6\u7684\u7c7b\u578b\u662f\u5426\u6b63\u786e\uff0c\u4e2d\u95f4\u53ef\u4ee5\u8f6c\u6362\u4e3a\u522b\u7684\u7c7b\u578b\uff08\u5982 void * \u548c uintptr_t\uff09\uff0c\u53ea\u9700\u6700\u540e\u8bbf\u95ee\u65f6\u8f6c\u6362\u56de\u6b63\u786e\u7684\u6307\u9488\u7c7b\u578b\u5373\u53ef int i; *(int *)(uintptr_t)&i; // \u53ef\u4ee5 *(int *)(void *)&i; // \u53ef\u4ee5 *(int *)(float *)&i; // \u53ef\u4ee5 union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 float bitCast(int i) { union { int i; float f; } u; u.i = i; return u.f; // \u9519\uff01 } \u7279\u4f8b\uff1a\u516c\u5171\u7684\u524d\u7f00\u6210\u5458\u53ef\u4ee5\u5b89\u5168\u5730\u8bbf\u95ee int foo(int i) { union { struct { int tag; int value; } m1; struct { int tag; float value; } m2; } u; u.m1.tag = i; return u.m2.tag; // \u53ef\u4ee5 } \u5982\u9700\u5728 float \u548c int \u4e4b\u95f4\u6309\u4f4d\u8f6c\u6362\uff0c\u5efa\u8bae\u6539\u7528 memcpy\uff0c\u56e0\u4e3a memcpy \u5185\u90e8\u88ab\u8ba4\u4e3a\u662f\u4ee5 char \u6307\u9488\u8bbf\u95ee\u7684\uff0cchar \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b float bitCast(int i) { float f; memcpy(&f, &i, sizeof(i)); return f; } \u6216 C++20 \u7684 std::bit_cast float bitCast(int i) { float f = std::bit_cast(i); return f; } T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) struct alignas(64) C { // \u5047\u8bbe alignof(int) \u662f 4 int i; char c; }; C *p = (C *)malloc(sizeof(C)); // \u9519\uff01malloc \u4ea7\u751f\u7684\u6307\u9488\u53ea\u4fdd\u8bc1\u5bf9\u9f50\u5230 max_align_t\uff08GCC \u4e0a\u662f 16 \u5b57\u8282\uff09\u5927\u5c0f\uff0c\u5e76\u4e0d\u4fdd\u8bc1\u5bf9\u9f50\u5230 C \u6240\u9700\u7684 64 \u5b57\u8282 C *p = new C; // \u53ef\u4ee5\uff0cnew T \u603b\u662f\u4fdd\u8bc1\u5bf9\u9f50\u5230 alignof(T) char buf[sizeof(int)]; int *p = (int *)buf; // \u9519\uff01 alignas(alignof(int)) char buf[sizeof(int)]; int *p = (int *)buf; // \u53ef\u4ee5 char buf[sizeof(int) * 2]; int *p = (int *)(((uintptr_t)buf + sizeof(int) - 1) & ~(alignof(int) - 1)); // \u53ef\u4ee5 \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee struct Base {}; struct Derived : Base {}; Base b; Derived d = *(Derived *)&b; // \u9519\uff01 Derived d = *static_cast(&b); // \u9519\uff01 Derived d = static_cast(b); // \u9519\uff01 Derived obj; Base *bp = &obj; Derived d = *(Derived *)bp; // \u53ef\u4ee5 Derived d = *static_cast(bp); // \u53ef\u4ee5 Derived d = static_cast(*bp); // \u53ef\u4ee5 bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u5e03\u5c14\u7c7b\u578b bool\uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 char c = 0; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = false char c = 1; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = true char c = 2; bool b = *(bool *)&c; // \u672a\u5b9a\u4e49\u884c\u4e3a \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa int i = INT_MAX; i + 1; // \u9519\uff01 \u4f46\u65e0\u7b26\u53f7\u53ef\u4ee5\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u4fdd\u8bc1\uff1a\u6ea2\u51fa\u5fc5\u5b9a\u56de\u73af (wrap-around) unsigned int i = UINT_MAX; i + 1; // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230 0 \u5982\u9700\u5bf9\u6709\u7b26\u53f7\u6574\u6570\u505a\u56de\u73af\uff0c\u53ef\u4ee5\u5148\u8f6c\u6362\u4e3a\u76f8\u5e94\u7684 unsigned \u7c7b\u578b\uff0c\u7b97\u5b8c\u540e\u518d\u8f6c\u56de\u6765 int i = INT_MAX; (int)((unsigned int)i + 1); // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u8d1f\u6570 INT_MIN \u5982\u4e0b\u5199\u6cd5\u66f4\u5177\u6709\u53ef\u79fb\u690d\u6027\uff0c\u56e0\u4e3a\u65e0\u7b26\u53f7\u6570\u5411\u6709\u7b26\u53f7\u6570\u8f6c\u578b\u65f6\u82e5\u8d85\u51fa\u6709\u7b26\u53f7\u6570\u7684\u8868\u793a\u8303\u56f4\u5219\u4e3a\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff08\u7f16\u8bd1\u5668\u5382\u5546\u51b3\u5b9a\u7ed3\u679c\uff0c\u4f46\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff09 std::bit_cast((unsigned int)i + i); \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u8fd0\u7b97\u7ed3\u679c\u7ed3\u679c\u5fc5\u987b\u5728\u8868\u793a\u8303\u56f4\u5185\uff1a\u4f8b\u5982\u5bf9\u4e8e int a \u548c int b\uff0c\u82e5 a/b \u7684\u7ed3\u679c\u4e0d\u53ef\u7528 int \u8868\u793a\uff0c\u90a3\u4e48 a/b \u548c a%b \u5747\u672a\u5b9a\u4e49 INT_MIN % -1; // \u9519\uff01 INT_MIN / -1; // \u9519\uff01 \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f unsigned int i = 0; i << 31; // \u53ef\u4ee5 i << 32; // \u9519\uff01 i << 0; // \u53ef\u4ee5 i << -1; // \u9519\uff01 \u5bf9\u4e8e\u6709\u7b26\u53f7\u6574\u6570\uff0c\u5de6\u79fb\u8fd8\u4e0d\u5f97\u7834\u574f\u7b26\u53f7\u4f4d int i = 0; i << 1; // \u53ef\u4ee5 i << 31; // \u9519\uff01 unsigned int u = 0; u << 31; // \u53ef\u4ee5 \u5982\u9700\u5904\u7406\u6765\u81ea\u7528\u6237\u8f93\u5165\u7684\u4f4d\u79fb\u6570\u91cf\uff0c\u53ef\u4ee5\u5148\u505a\u8303\u56f4\u68c0\u6d4b int shift; cin >> shift; unsigned int u = 0; int i = 0; (shift > 0 && shift < 32) ? (u << shift) : 0; // \u53ef\u4ee5 (shift > 0 && shift < 31) ? (i << shift) : 0; // \u53ef\u4ee5 \u9664\u6570\u4e0d\u80fd\u4e3a 0 int i = 42; int j = 0; i / j; // \u9519\uff01 i % j; // \u9519\uff01 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 int i = 5; int j = (++i) + (++i); // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int a[10] = {}; int j = a[i++] + a[i++]; // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int j = (++i) + i; // j \u7684\u503c\u672a\u5b9a\u4e49 int i1 = 5; int i2 = 5; int j = (++i1) + (++i2); // \u6b63\u786e\uff0cj \u4f1a\u5f97\u5230 12 \u8f6c\u53d1\u7ed9\u4f60\u8eab\u8fb9\u7684\u8c2d\u6d69\u5f3a\u53d7\u5bb3\u8005\u770b\uff08 i+++++i \uff09\u3002 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u5728\u6807\u51c6\u770b\u6765\uff0c+ \u8fd0\u7b97\u7b26\u4e24\u4fa7\u662f\u201c\u540c\u65f6\u201d\u6c42\u503c\u7684\uff0c\u5373\u201cinterleaved\u201d\uff0c\u5b9e\u9645\u6267\u884c\u987a\u5e8f\u5e76\u4e0d\u786e\u5b9a\u3002 \u5bf9\u4e8e a + b\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u5b9a\u603b\u662f\u5de6\u4fa7\u8868\u8fbe\u5f0f a \u5148\u6c42\u503c\u3002 \u4e0d\u8fc7\uff0c\u867d\u7136\u8fd0\u7b97\u7b26\u4e24\u4e2a\u53c2\u6570\u7684\u6c42\u503c\u987a\u5e8f\u201c\u672a\u6307\u5b9a(unspecified)\u201d\uff0c\u4f46\u5e76\u4e0d\u662f\u201c\u672a\u5b9a\u4e49(undefined)\u201d\u3002 \u4f46\u5de6\u53f3\u4e24\u4fa7\u6d89\u53ca\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97\u7b26\u7684\u60c5\u51b5\u4ecd\u7136\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } int j = f1() + f2(); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1\uff0c\u4f46 j \u6700\u7ec8\u7684\u7ed3\u679c\u4e00\u5b9a\u662f 3 \u672a\u6307\u5b9a\u548c\u672a\u5b9a\u4e49\u662f\u4e0d\u540c\u7684\uff01\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u7a0b\u5e8f\u662f\u975e\u6cd5(ill-formed)\u7684\uff0c\u4f46\u672a\u6307\u5b9a\u53ea\u662f\u4f1a\u8ba9\u7ed3\u679c\u65e0\u6cd5\u786e\u5b9a\uff0c\u4f46\u4e00\u5b9a\u80fd\u6b63\u5e38\u8fd0\u884c\uff1a\u8981\u4e48 f1 \u5148\u8fd0\u884c\uff0c\u8981\u4e48 f2 \u5148\u8fd0\u884c\u3002 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { printf(\"%d %d\\n\", i, j); } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2 1 2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 1 2 \u4ee3\u7801\u4e2d\uff0cf1 \u548c f2 \u7684\u6c42\u503c\u987a\u5e8f\u867d\u7136\u672a\u6307\u5b9a\uff0c\u4f46\u53ef\u4ee5\u4fdd\u8bc1 foo \u51fd\u6570\u4f53\u4e00\u5b9a\u5728\u6267\u884c\u5b8c\u6bd5\u540e\u624d\u4f1a\u5f00\u59cb\u3002 \u540c\u4e00\u6761\u8bed\u53e5\u4e2d\u6240\u6709\u5b50\u8868\u8fbe\u5f0f\u7684\u6267\u884c\u987a\u5e8f\u5c31\u50cf\u4e00\u9897\u6811\uff0c\u6811\u4e2d\u4e24\u4e2a\u5b50\u8282\u70b9\u6267\u884c\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684\uff1b\u4f46\u53ef\u4ee5\u80af\u5b9a\u7684\u662f\uff0c\u6811\u7684\u5b50\u8282\u70b9\u4e00\u5b9a\u5148\u4e8e\u4ed6\u4eec\u7684\u7236\u8282\u70b9\u6267\u884c\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u53ea\u662f\u672a\u6307\u5b9a(unspecified)\u884c\u4e3a\u800c\u4e0d\u662f\u672a\u5b9a\u4e49(undefined)\u884c\u4e3a\uff0c\u7ed3\u679c\u5fc5\u7136\u662f f1 f2 \u6216 f2 f1 \u4e24\u79cd\u53ef\u80fd\u4e4b\u4e00\uff0c\u4e0d\u4f1a\u8ba9\u7a0b\u5e8f\u51fa\u73b0\u672a\u5b9a\u4e49\u503c\u7684\u60c5\u51b5\u3002 \u6ce8\u610f\uff0c\u6c42\u503c\u987a\u5e8f\u672a\u6307\u5b9a\u4ec5\u9650\u540c\u4e00\u8bed\u53e5\uff08\u201c\u540c\u4e00\u884c\u201d\uff09\u5185\uff0c\u5bf9\u4e8e\u4e92\u76f8\u72ec\u7acb\u7684\u591a\u6761\u8bed\u53e5\uff0c\u4f9d\u7136\u662f\u6709\u5f3a\u5148\u540e\u987a\u5e8f\u7684\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 f1(); f2(); // \u5fc5\u7136\u6253\u5370 f1 f2 \u4e0d\u8fc7\uff0c\u6d89\u53ca\u81ea\u589e\u7684\u8bdd\uff0c\u5c31\u8fd8\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u800c\u4e0d\u662f\u672a\u6307\u5b9a\u4e86\u3002 int i = 5; foo(i++, i++); // \u4f1a\u6253\u5370\u51fa\u4ec0\u4e48\uff1f\u672a\u5b9a\u4e49\u884c\u4e3a int i = 5; int j = 5; foo(i++, j++); // \u5fc5\u7136\u6253\u5370\u51fa 5 5 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 int func() { int i = 42; // \u9519\uff01\u4f1a\u5bfc\u81f4 func \u8fd4\u56de\u65f6\u7a0b\u5e8f\u5d29\u6e83\uff0c\u4e14\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\uff0c\u4e0d\u62a5\u9519 } int func() { int i = 42; return i; // \u6b63\u786e } void func() { int i = 42; // \u8fd4\u56de void \u7684\u51fd\u6570\uff0creturn \u8bed\u53e5\u53ef\u4ee5\u7701\u7565 } \u5751\u4eba\u4e4b\u5904\u5728\u4e8e\uff0c\u5fd8\u8bb0\u5199\uff0c\u4e0d\u4f1a\u62a5\u9519\uff0c\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\u3002 \u4e3a\u4e86\u907f\u514d\u5fd8\u8bb0\u5199 return \u8bed\u53e5\uff0c\u5efa\u8bae gcc \u7f16\u8bd1\u5668\u5f00\u542f -Werror=return-type \u9009\u9879\uff0c\u5c06\u4e0d\u5199\u8fd4\u56de\u8bed\u53e5\u7684\u8b66\u544a\u8f6c\u5316\u4e3a\u9519\u8bef \u6ce8\u610f\uff0c\u5728\u6709\u5206\u652f\u7684\u975e void \u51fd\u6570\u4e2d\uff0c\u5fc5\u987b\u6240\u6709\u53ef\u8fbe\u5206\u652f\u90fd\u6709 return \u8bed\u53e5 int func(int x) { if (x < 0) return -x; if (x > 0) return x; // \u5982\u679c\u8c03\u7528\u4e86 func(0)\uff0c\u90a3\u4e48\u4f1a\u62b5\u8fbe\u6ca1\u6709 return \u7684\u5206\u652f\uff0c\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a } \u6ca1\u6709 return \u7684\u5206\u652f\u76f8\u5f53\u4e8e\u5199\u4e86\u4e00\u4e2a std::unreachable() \u4f46\u4e5f\u6709\u4f8b\u5916\uff1a \u4e3b\u51fd\u6570 main \u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u81ea\u5e26 return 0; \u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6709 co_return \u6216\u8005\u534f\u7a0b\u8fd4\u56de\u7c7b\u578b\u4e3a void \u4e14\u5177\u6709\u81f3\u5c11\u4e00\u4e2a co_await \u51fa\u73b0 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a typedef void (*func_t)(); func_t func = nullptr; func(); // \u9519\uff01 \u300a\u7ecf\u5178\u518d\u73b0\u300b #include static void func() { printf(\"func called\\n\"); } typedef void (*func_t)(); static func_t fp = nullptr; extern void set_fp() { // \u5bfc\u51fa\u7b26\u53f7\uff0c\u867d\u7136\u6ca1\u4eba\u8c03\u7528\uff0c\u5374\u5f71\u54cd\u4e86 clang \u7684\u4f18\u5316\u51b3\u7b56 fp = func; } int main() { fp(); // Release \u65f6\uff0cclang \u4f1a\u628a\u8fd9\u4e00\u884c\u76f4\u63a5\u4f18\u5316\u6210 func() return 0; } \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d void f1(int *p) { printf(\"f1(%p)\", p); } void (*fp)(const int *); fp = (void (*)(const int *)) f1; // \u9519\u8bef int i; fp = (void (*)(const int *)) &i; // \u9519\u8bef \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c struct Class { void mf() { printf(\"\u6210\u5458\u51fd\u6570\\n\"); } }; union { void (Class::*member_func)(); void (*free_func)(Class *); } u; u.member_func = &Class::mf; Class c; u.free_func(&c); // \u9519\u8bef \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf int i; cout << i; // \u9519\uff01 int i = 0; cout << i; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 int arr[10]; cout << arr[0]; // \u9519\uff01 int arr[10] = {}; cout << arr[0]; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c int arr[10]; int *p = &arr[0]; p + 1; // \u53ef\u4ee5 p + 10; // \u53ef\u4ee5 p + 11; // \u9519\uff01 \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 int arr[10]; int *p = &arr[0]; int *end = p + 10; // \u53ef\u4ee5 *end; // \u9519\uff01 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 int *p; *p; // \u9519\uff01 struct Dog { int age; }; struct Person { Dog *dog; }; Person *p = new Person; cout << p->dog->age; // \u9519\uff01 p->dog = new Dog; cout << p->dog->age; // \u53ef\u4ee5 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 int *p = new int; *p; // \u53ef\u4ee5 delete p; *p; // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); *p; // \u53ef\u4ee5 free(p); *p; // \u9519\uff01 int *func() { int arr[10]; return arr; // \u9519\uff01 } int main() { int *p = func(); p[0]; // \u9519\uff01arr \u5df2\u7ecf\u6790\u6784\uff0c\u4e0d\u80fd\u901a\u8fc7\u7a7a\u60ac\u6307\u9488 / \u7a7a\u60ac\u5f15\u7528\u7ee7\u7eed\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 } \u5efa\u8bae\u6539\u7528\u66f4\u5b89\u5168\u7684 array \u6216 vector \u5bb9\u5668 array func() { array arr; return arr; } int main() { auto arr = func(); arr[0]; // \u53ef\u4ee5\uff0c\u8bbf\u95ee\u5230\u7684\u662f main \u51fd\u6570\u5c40\u90e8\u53d8\u91cf arr\uff0c\u662f\u5bf9 func \u4e2d\u539f arr \u7684\u4e00\u4efd\u62f7\u8d1d } new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d int *p = new int; free(p); // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); free(p); // \u6b63\u786e int *p = new int[3]; delete p; // \u9519\uff01 int *p = new int[3]; delete[] p; // \u6b63\u786e vector a(3); unique_ptr a = make_unique(42); \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 struct C { int i; ~C() { i = 0; } }; C *c = (C *)malloc(sizeof(C)); cout << c->i; // \u53ef\u4ee5 c->~C(); cout << c->i; // \u9519\uff01 free(c); std::string func() { std::string s = \"hello\"; std::string s2 = std::move(s); return s; // \u8bed\u8a00\uff1aOK\uff0c\u6807\u51c6\u5e93\u4f5c\u8005\uff1as \u4e0d\u4e00\u5b9a\u662f\u7a7a\u5b57\u7b26\u4e32 } \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 void func() {} printf(\"*func = %d\\n\", *((int *)func)); // \u9519\u8bef C++ \u5185\u5b58\u6a21\u578b\u662f\u54c8\u4f5b\u67b6\u6784\uff08\u4ee3\u7801\u4e0e\u6570\u636e\u5206\u79bb\uff09\uff0c\u4e0d\u662f\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\uff08\u4ee3\u7801\u4e5f\u662f\u6570\u636e\uff09 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 isdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true isdigit('a'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false isdigit('\\xef'); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u5728 MSVC \u7684 Debug \u6a21\u5f0f\u4e0b\u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38 char s[] = \"\u4f60\u597dA\"; // UTF-8 \u7f16\u7801\u7684\u4e2d\u6587 // \"\u4f60\u597da\"\uff1f std::transform(std::begin(s), std::end(s), std::begin(s), ::tolower); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u56e0\u4e3a UTF-8 \u7f16\u7801\u4f1a\u4ea7\u751f\u5927\u4e8e 128 \u7684\u5b57\u8282 MSVC STL \u4e2d is \u7cfb\u5217\u51fd\u6570\u7684\u65ad\u8a00\uff1a assert(-1 <= c && c < 256); \u7406\u8bba\u4e0a\u53ef\u4ee5\u8fd9\u6837\u65ad\u8a00\uff1a assert(0 <= c && c <= 127); \u89e3\u51b3\u65b9\u6cd5\uff1a\u8981\u4e48\u6539\u7528 iswdigit\uff08MSVC\uff1a0-65536\uff0cGCC\uff1a0-0x010ffff\uff09 iswdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true iswdigit('\\xef'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false iswspace(L'\\ufeff'); // \u53ef\u4ee5\uff0cUTF-8 locale \u65f6\u8fd4\u56de true\uff0cASCII locale \u65f6\u8fd4\u56de false \u8981\u4e48\u81ea\u5df1\u5b9e\u73b0\u5224\u65ad if ('0' <= c && c <= '9') // \u4ee3\u66ff isdigit(c) if (strchr(\" \\n\\t\\r\", c)) // \u4ee3\u66ff isspace(c) memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 void *dst = nullptr; void *src = nullptr; size_t size = 0; memcpy(dst, src, size); // \u9519\uff01\u5373\u4f7f size \u4e3a 0\uff0csrc \u548c dst \u4e5f\u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 \u53ef\u4ee5\u7ed9 size \u52a0\u4e2a\u5224\u65ad void *dst = nullptr; void *src = nullptr; size_t size = 0; if (size != 0) // \u53ef\u4ee5 memcpy(dst, src, size); memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst char arr[10]; memcpy(arr, arr + 1, 9); // \u9519\uff01\u6709\u7684\u540c\u5b66\uff0c\u4ee5\u4e3a\u8fd9\u4e2a\u662f\u5bf9\u7684\uff1f\u9519\u4e86\uff0cmemcpy \u7684 src \u548c dst memcpy(arr + 1, arr, 9); // \u9519\uff01 memcpy(arr + 5, arr, 5); // \u53ef\u4ee5 memcpy(arr, arr + 5, 5); // \u53ef\u4ee5 \u5982\u9700\u62f7\u8d1d\u5e26\u91cd\u590d\u533a\u95f4\u7684\u5185\u5b58\uff0c\u53ef\u4ee5\u7528 memmove char arr[10]; memmove(arr, arr + 1, 9); // \u53ef\u4ee5 memmove(arr + 1, arr, 9); // \u53ef\u4ee5 memmove(arr + 5, arr, 5); // \u53ef\u4ee5 memmove(arr, arr + 5, 5); // \u53ef\u4ee5 \u4ece memcpy \u7684 src \u548c dst \u6307\u9488\u53c2\u6570\u662f restrict \u4fee\u9970\u7684\uff0c\u800c memmove \u6ca1\u6709\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\u6765\uff0cmemcpy \u4e0d\u5141\u8bb8\u4efb\u4f55\u5f62\u5f0f\u7684\u6307\u9488\u91cd\u53e0\uff0c\u65e0\u8bba\u5148\u540e\u987a\u5e8f v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a std::vector v = {}; int i = v.back(); // \u9519\uff01back() \u5e76\u4e0d\u4f1a\u5bf9 v \u662f\u5426\u6709\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u505a\u68c0\u67e5\uff0c\u6b64\u5904\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 int i = v.empty() ? 0 : v.back(); // \u66f4\u5b89\u5168\uff0c\u5f53 v \u4e3a\u7a7a\u65f6\u8fd4\u56de 0 vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a std::vector v = { 1, 2, 3 }; v[3]; // \u9519\uff01\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 \u53ef\u4ee5\u7528 at \u6210\u5458\u51fd\u6570 std::vector v = { 1, 2, 3 }; v.at(3); // \u5b89\u5168\uff0c\u4f1a\u68c0\u6d4b\u5230\u8d8a\u754c\uff0c\u629b\u51fa std::out_of_range \u5f02\u5e38 \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 std::vector v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 v.begin() \u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u8fed\u4ee3\u5668\u4e0d\u5931\u6548\u3002 std::deque v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u53ef\u4ee5 https://www.geeksforgeeks.org/iterator-invalidation-cpp https://en.cppreference.com/w/cpp/container \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 std::vector v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f7f\u5143\u7d20\u5168\u90e8\u79fb\u52a8\u5230\u4e86\u65b0\u7684\u4e00\u6bb5\u5185\u5b58\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 ref \u5f15\u7528\u5931\u6548 ref = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u5f15\u7528\u4e0d\u5931\u6548\u3002 std::deque v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u5143\u7d20\u79fb\u52a8\uff0c\u4f7f\u5f15\u7528\u5931\u6548 ref = 0; // \u53ef\u4ee5 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { cout << s.size(); // \u8bfb\u8bbf\u95ee } std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { s.push_back('b'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } \u66f4\u51c6\u786e\u7684\u8bf4\u6cd5\u662f\uff1a\u591a\u4e2a\u7ebf\u7a0b\uff08\u65e0 happens before \u5173\u7cfb\u5730\uff09\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u5e26\u6709\u526f\u4f5c\u7528\uff08\u5199\u8bbf\u95ee\u6216\u5e26\u6709volatile\u7684\u8bfb\u8bbf\u95ee\uff09\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a // \u516b\u80a1\u6587\u6559\u6750\u5e38\u89c1\u7684\u9519\u8bef\u5199\u6cd5\uff01volatile \u5e76\u4e0d\u4fdd\u8bc1\u539f\u5b50\u6027\u548c\u5185\u5b58\u5e8f\uff0c\u8fd9\u6837\u5199\u662f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u6539\u7528 std::atomic volatile int ready = 0; int data; void t1() { data = 42; ready = 1; } void t2() { while (ready == 0) ; printf(\"%d\\n\", data); } \u5efa\u8bae\u5229\u7528 mutex\uff0ccounting_semaphore\uff0catomic \u7b49\u591a\u7ebf\u7a0b\u540c\u6b65\u5de5\u5177\uff0c\u4fdd\u8bc1\u591a\u4e2a\u7ebf\u7a0b\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\u65f6\uff0c\u987a\u5e8f\u6709\u5148\u6709\u540e\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u53d1\u751f\uff0c\u90a3\u5c31\u662f\u5b89\u5168\u7684 std::string s; std::mutex m; void t1() { std::lock_guard l(m); s.push_back('a'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } void t2() { std::lock_guard l(m); s.push_back('b'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e92\u65a5\u9501\u4fdd\u8bc1\u4e86\u8981\u4e48 t1 happens before t2\uff0c\u8981\u4e48 t2 happens before t1\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::counting_semaphore<1> sem(1); void t1() { s.push_back('a'); sem.release(); // \u4ee4 t2 \u5fc5\u987b\u53d1\u751f\u5728 t1 \u4e4b\u540e } void t2() { sem.acquire(); // t2 \u5fc5\u987b\u7b49\u5f85 t1 release \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4fe1\u53f7\u91cf\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::atomic ready{false}; void t1() { s.push_back('a'); ready.store(true, std::memory_order_release); // \u4ee4 s \u7684\u4fee\u6539\u5bf9\u5176\u4ed6 acquire \u4e86 ready \u7684\u7ebf\u7a0b\u53ef\u89c1 } void t2() { while (!ready.load(std::memory_order_acquire)) // t2 \u5fc5\u987b\u7b49\u5f85 t1 store \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c ; s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u539f\u5b50\u53d8\u91cf\u7684 acquire/release \u5185\u5b58\u5e8f\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); // \u9519\uff01 m2.unlock(); m1.unlock(); } void t2() { m2.lock(); m1.lock(); // \u9519\uff01 m1.unlock(); m2.unlock(); } \u89e3\u51b3\u65b9\u6cd5\uff1a\u4e0d\u8981\u5728\u591a\u4e2a mutex \u4e0a\u540c\u65f6\u4e0a\u9501\uff0c\u5982\u679c\u786e\u5b9e\u8981\u591a\u4e2a mutex\uff0c\u4fdd\u8bc1\u987a\u5e8f\u4e00\u81f4 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } void t2() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } \u6216\u4f7f\u7528 std::lock std::mutex m1, m2; void t1() { std::lock(m1, m2); std::unlock(m1, m2); } void t2() { std::lock(m2, m1); std::unlock(m2, m1); } \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 std::mutex m; void t1() { m.lock(); m.lock(); // \u9519\uff01 m.try_lock(); // \u9519\uff01try_lock \u4e5f\u4e0d\u5141\u8bb8\uff01 m.unlock(); m.unlock(); } void t2() { m.try_lock(); // \u53ef\u4ee5 } \u89e3\u51b3\u65b9\u6cd5\uff1a\u6539\u7528 recursive_mutex\uff0c\u6216\u4f7f\u7528\u9002\u5f53\u7684\u6761\u4ef6\u53d8\u91cf std::recursive_mutex m; void t1() { m.lock(); m.lock(); // \u53ef\u4ee5 m.try_lock(); // \u53ef\u4ee5\uff0c\u8fd4\u56de true m.unlock(); m.unlock(); m.unlock(); } \u603b\u7ed3 \u4e0d\u8981\u73a9\u7a7a\u6307\u9488 \u4e0d\u8981\u8d8a\u754c\uff0c\u7528\u66f4\u5b89\u5168\u7684 at\uff0csubspan \u7b49 \u4e0d\u8981\u4e0d\u521d\u59cb\u5316\u53d8\u91cf\uff08auto-idiom\uff09 \u5f00\u542f -Werror=return-type \u4e0d\u8981\u91cd\u590d\u4e0a\u9501 mutex \u4ed4\u7ec6\u770b\u5e93\u51fd\u6570\u7684\u6587\u6863 \u7528\u667a\u80fd\u6307\u9488\u7ba1\u7406\u5355\u4e2a\u5bf9\u8c61 \u7528 vector \u7ba1\u7406\u591a\u4e2a\u5bf9\u8c61\u7ec4\u6210\u7684\u8fde\u7eed\u5185\u5b58 \u907f\u514d\u7a7a\u60ac\u5f15\u7528 \u5f00 Debug \u6a21\u5f0f\u7684 STL \u6307\u5b9a CMake \u7684\u6a21\u5f0f\uff1a cmake -B build -DCMAKE_BUILD_TYPE=Debug Debug: -O0 -g \u7f16\u8bd1\u9009\u9879 Release: -O3 -DNDEBUG \u7f16\u8bd1\u9009\u9879 \u6307\u5b9a MSVC \u7684\u6a21\u5f0f\uff1a cmake --build build --config Debug Debug: \u751f\u6210 zenod.dll \uff0c\u94fe\u63a5 Debug \u7684 ABI Release: \u751f\u6210 zeno.dll \uff0c\u94fe\u63a5 Release \u7684 ABI CppCon \u76f8\u5173\u89c6\u9891 \u987a\u4fbf\u63a8\u4e2a CppCon \u5c0f\u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=ehyHyAIa5so \u6807\u9898\u662f\u300aCppCon 2017: Piotr Padlewski \u201cUndefined Behaviour is awesome!\u201d\u300b\uff08\u7206\u5b5d\uff09","title":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868"},{"location":"undef/#_1","text":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f \u9664\u6570\u4e0d\u80fd\u4e3a 0 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 \u603b\u7ed3 CppCon \u76f8\u5173\u89c6\u9891 \u5982\u6709\u758f\u6f0f\uff0c\u53ef\u4ee5\u5728 GitHub \u8865\u5145\u3002","title":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868"},{"location":"undef/#_2","text":"\u53ef\u4ee5\u5e2e\u52a9\u4f60\u76d1\u6d4b\u672a\u5b9a\u4e49\u884c\u4e3a msvc: Debug \u914d\u7f6e gcc: \u5b9a\u4e49 _GLIBCXX_DEBUG \u5b8f","title":"\u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f"},{"location":"undef/#_3","text":"","title":"\u7a7a\u6307\u9488\u7c7b"},{"location":"undef/#_4","text":"\u53ea\u8981\u89e3\u5f15\u7528\u5c31\u9519\u4e86\uff0c\u65e0\u8bba\u662f\u5426\u8bfb\u53d6\u6216\u5199\u5165 int *p = nullptr; *p; // \u9519\uff01 &*p; // \u9519\uff01 *p = 0; // \u9519\uff01 int i = *p; // \u9519\uff01 unique_ptr p = nullptr; p.get(); // \u53ef\u4ee5 &*p; // \u9519\uff01 \u4f8b\u5982\u5728 Debug \u914d\u7f6e\u7684 MSVC STL \u4e2d\uff0c &*p \u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38\uff0c\u800c p.get() \u4e0d\u4f1a\u3002 if (&*p != nullptr) { // \u53ef\u80fd\u88ab\u4f18\u5316\u4e3a if (1)\uff0c\u56e0\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u88ab\u6392\u9664\u4e86 } if (p != nullptr) { // \u4e0d\u4f1a\u88ab\u4f18\u5316\uff0c\u6b63\u5e38\u5224\u65ad }","title":"\u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09"},{"location":"undef/#end","text":"std::vector v = {1, 2, 3, 4}; int *begin = &*v.begin(); int *end = &*v.end(); // \u9519\uff01 std::vector v = {}; int *begin = &*v.begin(); // \u9519! int *end = &*v.end(); // \u9519\uff01 \u5efa\u8bae\u6539\u7528 data \u548c size std::vector v = {1, 2, 3, 4}; int *begin = v.data(); int *end = v.data() + v.size();","title":"\u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668"},{"location":"undef/#this","text":"struct C { void print() { if (this == nullptr) { // \u6b64\u5206\u652f\u53ef\u80fd\u4f1a\u88ab\u4f18\u5316\u4e3a if (0) { ... } \u4ece\u800c\u6c38\u4e0d\u751f\u6548 std::cout << \"this \u662f\u7a7a\\n\"; } } }; void func() { C *c = nullptr; c->print(); // \u9519\uff01 }","title":"this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a"},{"location":"undef/#_5","text":"struct C{ void f() {} static void f2() {} }; void func(){ C* c = nullptr; c->f(); // \u884c\u4e3a\u672a\u5b9a\u4e49 c->f2(); // \u884c\u4e3a\u672a\u5b9a\u4e49 } \u672c\u8d28\u4e0a\u662f\u56e0\u4e3a \u7a7a\u6307\u9488\u89e3\u5f15\u7528 \u3002\u5bf9\u4e8e\u5185\u5efa\u7c7b\u578b\uff0c\u8868\u8fbe\u5f0f E1->E2 \u4e0e (*E1).E2 \u4e25\u683c\u7b49\u4ef7\uff0c\u4efb\u4f55\u6307\u9488\u7c7b\u578b\u90fd\u662f\u5185\u5efa\u7c7b\u578b\u3002 c->f() \u3001 c->f2() \u7b49\u4ef7\u4e8e\uff1a (*c).f(); (*c).f2();","title":"\u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570"},{"location":"undef/#_6","text":"","title":"\u6307\u9488\u522b\u540d\u7c7b"},{"location":"undef/#reinterpret_cast","text":"int i; float f = *(float *)&i; // \u9519\uff01 \u4f8b\u5916\uff1achar\u3001signed char\u3001unsigned char \u548c std::byte \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b int i; char *buf = (char *)&i; // \u53ef\u4ee5 buf[0] = 1; // \u53ef\u4ee5 uint8_t \u662f unsigned char \u7684\u522b\u540d\uff0c\u6240\u4ee5\u4e5f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b \u4f8b\u5916\uff1aint \u548c unsigned int \u4e92\u76f8\u517c\u5bb9 int i; unsigned int f = *(unsigned int *)&i; // \u53ef\u4ee5 \u4f8b\u5916\uff1aconst int * \u548c int * \u4e92\u76f8\u517c\u5bb9\uff08\u4e8c\u7ea7\u6307\u9488\u5f3a\u8f6c\uff09 const int *cp; int *p = *(int **)&cp; // \u53ef\u4ee5 \u6ce8\u610f\uff1a\u53ea\u53d6\u51b3\u4e8e\u8bbf\u95ee\u65f6\u7684\u7c7b\u578b\u662f\u5426\u6b63\u786e\uff0c\u4e2d\u95f4\u53ef\u4ee5\u8f6c\u6362\u4e3a\u522b\u7684\u7c7b\u578b\uff08\u5982 void * \u548c uintptr_t\uff09\uff0c\u53ea\u9700\u6700\u540e\u8bbf\u95ee\u65f6\u8f6c\u6362\u56de\u6b63\u786e\u7684\u6307\u9488\u7c7b\u578b\u5373\u53ef int i; *(int *)(uintptr_t)&i; // \u53ef\u4ee5 *(int *)(void *)&i; // \u53ef\u4ee5 *(int *)(float *)&i; // \u53ef\u4ee5","title":"reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee"},{"location":"undef/#union","text":"float bitCast(int i) { union { int i; float f; } u; u.i = i; return u.f; // \u9519\uff01 } \u7279\u4f8b\uff1a\u516c\u5171\u7684\u524d\u7f00\u6210\u5458\u53ef\u4ee5\u5b89\u5168\u5730\u8bbf\u95ee int foo(int i) { union { struct { int tag; int value; } m1; struct { int tag; float value; } m2; } u; u.m1.tag = i; return u.m2.tag; // \u53ef\u4ee5 } \u5982\u9700\u5728 float \u548c int \u4e4b\u95f4\u6309\u4f4d\u8f6c\u6362\uff0c\u5efa\u8bae\u6539\u7528 memcpy\uff0c\u56e0\u4e3a memcpy \u5185\u90e8\u88ab\u8ba4\u4e3a\u662f\u4ee5 char \u6307\u9488\u8bbf\u95ee\u7684\uff0cchar \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b float bitCast(int i) { float f; memcpy(&f, &i, sizeof(i)); return f; } \u6216 C++20 \u7684 std::bit_cast float bitCast(int i) { float f = std::bit_cast(i); return f; }","title":"union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458"},{"location":"undef/#t-alignoft","text":"struct alignas(64) C { // \u5047\u8bbe alignof(int) \u662f 4 int i; char c; }; C *p = (C *)malloc(sizeof(C)); // \u9519\uff01malloc \u4ea7\u751f\u7684\u6307\u9488\u53ea\u4fdd\u8bc1\u5bf9\u9f50\u5230 max_align_t\uff08GCC \u4e0a\u662f 16 \u5b57\u8282\uff09\u5927\u5c0f\uff0c\u5e76\u4e0d\u4fdd\u8bc1\u5bf9\u9f50\u5230 C \u6240\u9700\u7684 64 \u5b57\u8282 C *p = new C; // \u53ef\u4ee5\uff0cnew T \u603b\u662f\u4fdd\u8bc1\u5bf9\u9f50\u5230 alignof(T) char buf[sizeof(int)]; int *p = (int *)buf; // \u9519\uff01 alignas(alignof(int)) char buf[sizeof(int)]; int *p = (int *)buf; // \u53ef\u4ee5 char buf[sizeof(int) * 2]; int *p = (int *)(((uintptr_t)buf + sizeof(int) - 1) & ~(alignof(int) - 1)); // \u53ef\u4ee5","title":"T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T)"},{"location":"undef/#static_cast","text":"struct Base {}; struct Derived : Base {}; Base b; Derived d = *(Derived *)&b; // \u9519\uff01 Derived d = *static_cast(&b); // \u9519\uff01 Derived d = static_cast(b); // \u9519\uff01 Derived obj; Base *bp = &obj; Derived d = *(Derived *)bp; // \u53ef\u4ee5 Derived d = *static_cast(bp); // \u53ef\u4ee5 Derived d = static_cast(*bp); // \u53ef\u4ee5","title":"\u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee"},{"location":"undef/#bool-0-1","text":"\u5e03\u5c14\u7c7b\u578b bool\uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 char c = 0; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = false char c = 1; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = true char c = 2; bool b = *(bool *)&c; // \u672a\u5b9a\u4e49\u884c\u4e3a","title":"bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c"},{"location":"undef/#_7","text":"","title":"\u7b97\u6570\u7c7b"},{"location":"undef/#_8","text":"int i = INT_MAX; i + 1; // \u9519\uff01 \u4f46\u65e0\u7b26\u53f7\u53ef\u4ee5\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u4fdd\u8bc1\uff1a\u6ea2\u51fa\u5fc5\u5b9a\u56de\u73af (wrap-around) unsigned int i = UINT_MAX; i + 1; // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230 0 \u5982\u9700\u5bf9\u6709\u7b26\u53f7\u6574\u6570\u505a\u56de\u73af\uff0c\u53ef\u4ee5\u5148\u8f6c\u6362\u4e3a\u76f8\u5e94\u7684 unsigned \u7c7b\u578b\uff0c\u7b97\u5b8c\u540e\u518d\u8f6c\u56de\u6765 int i = INT_MAX; (int)((unsigned int)i + 1); // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u8d1f\u6570 INT_MIN \u5982\u4e0b\u5199\u6cd5\u66f4\u5177\u6709\u53ef\u79fb\u690d\u6027\uff0c\u56e0\u4e3a\u65e0\u7b26\u53f7\u6570\u5411\u6709\u7b26\u53f7\u6570\u8f6c\u578b\u65f6\u82e5\u8d85\u51fa\u6709\u7b26\u53f7\u6570\u7684\u8868\u793a\u8303\u56f4\u5219\u4e3a\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff08\u7f16\u8bd1\u5668\u5382\u5546\u51b3\u5b9a\u7ed3\u679c\uff0c\u4f46\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff09 std::bit_cast((unsigned int)i + i); \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u8fd0\u7b97\u7ed3\u679c\u7ed3\u679c\u5fc5\u987b\u5728\u8868\u793a\u8303\u56f4\u5185\uff1a\u4f8b\u5982\u5bf9\u4e8e int a \u548c int b\uff0c\u82e5 a/b \u7684\u7ed3\u679c\u4e0d\u53ef\u7528 int \u8868\u793a\uff0c\u90a3\u4e48 a/b \u548c a%b \u5747\u672a\u5b9a\u4e49 INT_MIN % -1; // \u9519\uff01 INT_MIN / -1; // \u9519\uff01","title":"\u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa"},{"location":"undef/#_9","text":"unsigned int i = 0; i << 31; // \u53ef\u4ee5 i << 32; // \u9519\uff01 i << 0; // \u53ef\u4ee5 i << -1; // \u9519\uff01 \u5bf9\u4e8e\u6709\u7b26\u53f7\u6574\u6570\uff0c\u5de6\u79fb\u8fd8\u4e0d\u5f97\u7834\u574f\u7b26\u53f7\u4f4d int i = 0; i << 1; // \u53ef\u4ee5 i << 31; // \u9519\uff01 unsigned int u = 0; u << 31; // \u53ef\u4ee5 \u5982\u9700\u5904\u7406\u6765\u81ea\u7528\u6237\u8f93\u5165\u7684\u4f4d\u79fb\u6570\u91cf\uff0c\u53ef\u4ee5\u5148\u505a\u8303\u56f4\u68c0\u6d4b int shift; cin >> shift; unsigned int u = 0; int i = 0; (shift > 0 && shift < 32) ? (u << shift) : 0; // \u53ef\u4ee5 (shift > 0 && shift < 31) ? (i << shift) : 0; // \u53ef\u4ee5","title":"\u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f"},{"location":"undef/#0","text":"int i = 42; int j = 0; i / j; // \u9519\uff01 i % j; // \u9519\uff01","title":"\u9664\u6570\u4e0d\u80fd\u4e3a 0"},{"location":"undef/#_10","text":"","title":"\u6c42\u503c\u987a\u5e8f\u7c7b"},{"location":"undef/#_11","text":"int i = 5; int j = (++i) + (++i); // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int a[10] = {}; int j = a[i++] + a[i++]; // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int j = (++i) + i; // j \u7684\u503c\u672a\u5b9a\u4e49 int i1 = 5; int i2 = 5; int j = (++i1) + (++i2); // \u6b63\u786e\uff0cj \u4f1a\u5f97\u5230 12 \u8f6c\u53d1\u7ed9\u4f60\u8eab\u8fb9\u7684\u8c2d\u6d69\u5f3a\u53d7\u5bb3\u8005\u770b\uff08 i+++++i \uff09\u3002","title":"\u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97"},{"location":"undef/#_12","text":"\u5728\u6807\u51c6\u770b\u6765\uff0c+ \u8fd0\u7b97\u7b26\u4e24\u4fa7\u662f\u201c\u540c\u65f6\u201d\u6c42\u503c\u7684\uff0c\u5373\u201cinterleaved\u201d\uff0c\u5b9e\u9645\u6267\u884c\u987a\u5e8f\u5e76\u4e0d\u786e\u5b9a\u3002 \u5bf9\u4e8e a + b\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u5b9a\u603b\u662f\u5de6\u4fa7\u8868\u8fbe\u5f0f a \u5148\u6c42\u503c\u3002 \u4e0d\u8fc7\uff0c\u867d\u7136\u8fd0\u7b97\u7b26\u4e24\u4e2a\u53c2\u6570\u7684\u6c42\u503c\u987a\u5e8f\u201c\u672a\u6307\u5b9a(unspecified)\u201d\uff0c\u4f46\u5e76\u4e0d\u662f\u201c\u672a\u5b9a\u4e49(undefined)\u201d\u3002 \u4f46\u5de6\u53f3\u4e24\u4fa7\u6d89\u53ca\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97\u7b26\u7684\u60c5\u51b5\u4ecd\u7136\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } int j = f1() + f2(); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1\uff0c\u4f46 j \u6700\u7ec8\u7684\u7ed3\u679c\u4e00\u5b9a\u662f 3 \u672a\u6307\u5b9a\u548c\u672a\u5b9a\u4e49\u662f\u4e0d\u540c\u7684\uff01\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u7a0b\u5e8f\u662f\u975e\u6cd5(ill-formed)\u7684\uff0c\u4f46\u672a\u6307\u5b9a\u53ea\u662f\u4f1a\u8ba9\u7ed3\u679c\u65e0\u6cd5\u786e\u5b9a\uff0c\u4f46\u4e00\u5b9a\u80fd\u6b63\u5e38\u8fd0\u884c\uff1a\u8981\u4e48 f1 \u5148\u8fd0\u884c\uff0c\u8981\u4e48 f2 \u5148\u8fd0\u884c\u3002","title":"\u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684"},{"location":"undef/#_13","text":"int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { printf(\"%d %d\\n\", i, j); } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2 1 2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 1 2 \u4ee3\u7801\u4e2d\uff0cf1 \u548c f2 \u7684\u6c42\u503c\u987a\u5e8f\u867d\u7136\u672a\u6307\u5b9a\uff0c\u4f46\u53ef\u4ee5\u4fdd\u8bc1 foo \u51fd\u6570\u4f53\u4e00\u5b9a\u5728\u6267\u884c\u5b8c\u6bd5\u540e\u624d\u4f1a\u5f00\u59cb\u3002 \u540c\u4e00\u6761\u8bed\u53e5\u4e2d\u6240\u6709\u5b50\u8868\u8fbe\u5f0f\u7684\u6267\u884c\u987a\u5e8f\u5c31\u50cf\u4e00\u9897\u6811\uff0c\u6811\u4e2d\u4e24\u4e2a\u5b50\u8282\u70b9\u6267\u884c\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684\uff1b\u4f46\u53ef\u4ee5\u80af\u5b9a\u7684\u662f\uff0c\u6811\u7684\u5b50\u8282\u70b9\u4e00\u5b9a\u5148\u4e8e\u4ed6\u4eec\u7684\u7236\u8282\u70b9\u6267\u884c\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u53ea\u662f\u672a\u6307\u5b9a(unspecified)\u884c\u4e3a\u800c\u4e0d\u662f\u672a\u5b9a\u4e49(undefined)\u884c\u4e3a\uff0c\u7ed3\u679c\u5fc5\u7136\u662f f1 f2 \u6216 f2 f1 \u4e24\u79cd\u53ef\u80fd\u4e4b\u4e00\uff0c\u4e0d\u4f1a\u8ba9\u7a0b\u5e8f\u51fa\u73b0\u672a\u5b9a\u4e49\u503c\u7684\u60c5\u51b5\u3002 \u6ce8\u610f\uff0c\u6c42\u503c\u987a\u5e8f\u672a\u6307\u5b9a\u4ec5\u9650\u540c\u4e00\u8bed\u53e5\uff08\u201c\u540c\u4e00\u884c\u201d\uff09\u5185\uff0c\u5bf9\u4e8e\u4e92\u76f8\u72ec\u7acb\u7684\u591a\u6761\u8bed\u53e5\uff0c\u4f9d\u7136\u662f\u6709\u5f3a\u5148\u540e\u987a\u5e8f\u7684\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 f1(); f2(); // \u5fc5\u7136\u6253\u5370 f1 f2 \u4e0d\u8fc7\uff0c\u6d89\u53ca\u81ea\u589e\u7684\u8bdd\uff0c\u5c31\u8fd8\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u800c\u4e0d\u662f\u672a\u6307\u5b9a\u4e86\u3002 int i = 5; foo(i++, i++); // \u4f1a\u6253\u5370\u51fa\u4ec0\u4e48\uff1f\u672a\u5b9a\u4e49\u884c\u4e3a int i = 5; int j = 5; foo(i++, j++); // \u5fc5\u7136\u6253\u5370\u51fa 5 5","title":"\u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684"},{"location":"undef/#_14","text":"","title":"\u51fd\u6570\u7c7b"},{"location":"undef/#void-return","text":"int func() { int i = 42; // \u9519\uff01\u4f1a\u5bfc\u81f4 func \u8fd4\u56de\u65f6\u7a0b\u5e8f\u5d29\u6e83\uff0c\u4e14\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\uff0c\u4e0d\u62a5\u9519 } int func() { int i = 42; return i; // \u6b63\u786e } void func() { int i = 42; // \u8fd4\u56de void \u7684\u51fd\u6570\uff0creturn \u8bed\u53e5\u53ef\u4ee5\u7701\u7565 } \u5751\u4eba\u4e4b\u5904\u5728\u4e8e\uff0c\u5fd8\u8bb0\u5199\uff0c\u4e0d\u4f1a\u62a5\u9519\uff0c\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\u3002 \u4e3a\u4e86\u907f\u514d\u5fd8\u8bb0\u5199 return \u8bed\u53e5\uff0c\u5efa\u8bae gcc \u7f16\u8bd1\u5668\u5f00\u542f -Werror=return-type \u9009\u9879\uff0c\u5c06\u4e0d\u5199\u8fd4\u56de\u8bed\u53e5\u7684\u8b66\u544a\u8f6c\u5316\u4e3a\u9519\u8bef \u6ce8\u610f\uff0c\u5728\u6709\u5206\u652f\u7684\u975e void \u51fd\u6570\u4e2d\uff0c\u5fc5\u987b\u6240\u6709\u53ef\u8fbe\u5206\u652f\u90fd\u6709 return \u8bed\u53e5 int func(int x) { if (x < 0) return -x; if (x > 0) return x; // \u5982\u679c\u8c03\u7528\u4e86 func(0)\uff0c\u90a3\u4e48\u4f1a\u62b5\u8fbe\u6ca1\u6709 return \u7684\u5206\u652f\uff0c\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a } \u6ca1\u6709 return \u7684\u5206\u652f\u76f8\u5f53\u4e8e\u5199\u4e86\u4e00\u4e2a std::unreachable() \u4f46\u4e5f\u6709\u4f8b\u5916\uff1a \u4e3b\u51fd\u6570 main \u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u81ea\u5e26 return 0; \u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6709 co_return \u6216\u8005\u534f\u7a0b\u8fd4\u56de\u7c7b\u578b\u4e3a void \u4e14\u5177\u6709\u81f3\u5c11\u4e00\u4e2a co_await \u51fa\u73b0","title":"\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5"},{"location":"undef/#_15","text":"typedef void (*func_t)(); func_t func = nullptr; func(); // \u9519\uff01 \u300a\u7ecf\u5178\u518d\u73b0\u300b #include static void func() { printf(\"func called\\n\"); } typedef void (*func_t)(); static func_t fp = nullptr; extern void set_fp() { // \u5bfc\u51fa\u7b26\u53f7\uff0c\u867d\u7136\u6ca1\u4eba\u8c03\u7528\uff0c\u5374\u5f71\u54cd\u4e86 clang \u7684\u4f18\u5316\u51b3\u7b56 fp = func; } int main() { fp(); // Release \u65f6\uff0cclang \u4f1a\u628a\u8fd9\u4e00\u884c\u76f4\u63a5\u4f18\u5316\u6210 func() return 0; }","title":"\u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a"},{"location":"undef/#_16","text":"void f1(int *p) { printf(\"f1(%p)\", p); } void (*fp)(const int *); fp = (void (*)(const int *)) f1; // \u9519\u8bef int i; fp = (void (*)(const int *)) &i; // \u9519\u8bef","title":"\u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d"},{"location":"undef/#_17","text":"struct Class { void mf() { printf(\"\u6210\u5458\u51fd\u6570\\n\"); } }; union { void (Class::*member_func)(); void (*free_func)(Class *); } u; u.member_func = &Class::mf; Class c; u.free_func(&c); // \u9519\u8bef","title":"\u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c"},{"location":"undef/#_18","text":"","title":"\u751f\u547d\u5468\u671f\u7c7b"},{"location":"undef/#_19","text":"int i; cout << i; // \u9519\uff01 int i = 0; cout << i; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 int arr[10]; cout << arr[0]; // \u9519\uff01 int arr[10] = {}; cout << arr[0]; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0","title":"\u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf"},{"location":"undef/#_20","text":"int arr[10]; int *p = &arr[0]; p + 1; // \u53ef\u4ee5 p + 10; // \u53ef\u4ee5 p + 11; // \u9519\uff01","title":"\u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c"},{"location":"undef/#end_1","text":"int arr[10]; int *p = &arr[0]; int *end = p + 10; // \u53ef\u4ee5 *end; // \u9519\uff01","title":"\u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528"},{"location":"undef/#_21","text":"int *p; *p; // \u9519\uff01 struct Dog { int age; }; struct Person { Dog *dog; }; Person *p = new Person; cout << p->dog->age; // \u9519\uff01 p->dog = new Dog; cout << p->dog->age; // \u53ef\u4ee5","title":"\u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488"},{"location":"undef/#_22","text":"int *p = new int; *p; // \u53ef\u4ee5 delete p; *p; // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); *p; // \u53ef\u4ee5 free(p); *p; // \u9519\uff01 int *func() { int arr[10]; return arr; // \u9519\uff01 } int main() { int *p = func(); p[0]; // \u9519\uff01arr \u5df2\u7ecf\u6790\u6784\uff0c\u4e0d\u80fd\u901a\u8fc7\u7a7a\u60ac\u6307\u9488 / \u7a7a\u60ac\u5f15\u7528\u7ee7\u7eed\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 } \u5efa\u8bae\u6539\u7528\u66f4\u5b89\u5168\u7684 array \u6216 vector \u5bb9\u5668 array func() { array arr; return arr; } int main() { auto arr = func(); arr[0]; // \u53ef\u4ee5\uff0c\u8bbf\u95ee\u5230\u7684\u662f main \u51fd\u6570\u5c40\u90e8\u53d8\u91cf arr\uff0c\u662f\u5bf9 func \u4e2d\u539f arr \u7684\u4e00\u4efd\u62f7\u8d1d }","title":"\u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58"},{"location":"undef/#new-new-malloc-delete-delete-free","text":"int *p = new int; free(p); // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); free(p); // \u6b63\u786e int *p = new int[3]; delete p; // \u9519\uff01 int *p = new int[3]; delete[] p; // \u6b63\u786e vector a(3); unique_ptr a = make_unique(42);","title":"new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d"},{"location":"undef/#_23","text":"struct C { int i; ~C() { i = 0; } }; C *c = (C *)malloc(sizeof(C)); cout << c->i; // \u53ef\u4ee5 c->~C(); cout << c->i; // \u9519\uff01 free(c); std::string func() { std::string s = \"hello\"; std::string s2 = std::move(s); return s; // \u8bed\u8a00\uff1aOK\uff0c\u6807\u51c6\u5e93\u4f5c\u8005\uff1as \u4e0d\u4e00\u5b9a\u662f\u7a7a\u5b57\u7b26\u4e32 }","title":"\u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61"},{"location":"undef/#_24","text":"void func() {} printf(\"*func = %d\\n\", *((int *)func)); // \u9519\u8bef C++ \u5185\u5b58\u6a21\u578b\u662f\u54c8\u4f5b\u67b6\u6784\uff08\u4ee3\u7801\u4e0e\u6570\u636e\u5206\u79bb\uff09\uff0c\u4e0d\u662f\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\uff08\u4ee3\u7801\u4e5f\u662f\u6570\u636e\uff09","title":"\u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528"},{"location":"undef/#_25","text":"","title":"\u5e93\u51fd\u6570\u7c7b"},{"location":"undef/#ctypeh-0127-ascii","text":"isdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true isdigit('a'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false isdigit('\\xef'); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u5728 MSVC \u7684 Debug \u6a21\u5f0f\u4e0b\u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38 char s[] = \"\u4f60\u597dA\"; // UTF-8 \u7f16\u7801\u7684\u4e2d\u6587 // \"\u4f60\u597da\"\uff1f std::transform(std::begin(s), std::end(s), std::begin(s), ::tolower); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u56e0\u4e3a UTF-8 \u7f16\u7801\u4f1a\u4ea7\u751f\u5927\u4e8e 128 \u7684\u5b57\u8282 MSVC STL \u4e2d is \u7cfb\u5217\u51fd\u6570\u7684\u65ad\u8a00\uff1a assert(-1 <= c && c < 256); \u7406\u8bba\u4e0a\u53ef\u4ee5\u8fd9\u6837\u65ad\u8a00\uff1a assert(0 <= c && c <= 127); \u89e3\u51b3\u65b9\u6cd5\uff1a\u8981\u4e48\u6539\u7528 iswdigit\uff08MSVC\uff1a0-65536\uff0cGCC\uff1a0-0x010ffff\uff09 iswdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true iswdigit('\\xef'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false iswspace(L'\\ufeff'); // \u53ef\u4ee5\uff0cUTF-8 locale \u65f6\u8fd4\u56de true\uff0cASCII locale \u65f6\u8fd4\u56de false \u8981\u4e48\u81ea\u5df1\u5b9e\u73b0\u5224\u65ad if ('0' <= c && c <= '9') // \u4ee3\u66ff isdigit(c) if (strchr(\" \\n\\t\\r\", c)) // \u4ee3\u66ff isspace(c)","title":"ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09"},{"location":"undef/#memcpy-src-dst","text":"void *dst = nullptr; void *src = nullptr; size_t size = 0; memcpy(dst, src, size); // \u9519\uff01\u5373\u4f7f size \u4e3a 0\uff0csrc \u548c dst \u4e5f\u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 \u53ef\u4ee5\u7ed9 size \u52a0\u4e2a\u5224\u65ad void *dst = nullptr; void *src = nullptr; size_t size = 0; if (size != 0) // \u53ef\u4ee5 memcpy(dst, src, size);","title":"memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488"},{"location":"undef/#memcpy-src-dst_1","text":"char arr[10]; memcpy(arr, arr + 1, 9); // \u9519\uff01\u6709\u7684\u540c\u5b66\uff0c\u4ee5\u4e3a\u8fd9\u4e2a\u662f\u5bf9\u7684\uff1f\u9519\u4e86\uff0cmemcpy \u7684 src \u548c dst memcpy(arr + 1, arr, 9); // \u9519\uff01 memcpy(arr + 5, arr, 5); // \u53ef\u4ee5 memcpy(arr, arr + 5, 5); // \u53ef\u4ee5 \u5982\u9700\u62f7\u8d1d\u5e26\u91cd\u590d\u533a\u95f4\u7684\u5185\u5b58\uff0c\u53ef\u4ee5\u7528 memmove char arr[10]; memmove(arr, arr + 1, 9); // \u53ef\u4ee5 memmove(arr + 1, arr, 9); // \u53ef\u4ee5 memmove(arr + 5, arr, 5); // \u53ef\u4ee5 memmove(arr, arr + 5, 5); // \u53ef\u4ee5 \u4ece memcpy \u7684 src \u548c dst \u6307\u9488\u53c2\u6570\u662f restrict \u4fee\u9970\u7684\uff0c\u800c memmove \u6ca1\u6709\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\u6765\uff0cmemcpy \u4e0d\u5141\u8bb8\u4efb\u4f55\u5f62\u5f0f\u7684\u6307\u9488\u91cd\u53e0\uff0c\u65e0\u8bba\u5148\u540e\u987a\u5e8f","title":"memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst"},{"location":"undef/#vback-v","text":"std::vector v = {}; int i = v.back(); // \u9519\uff01back() \u5e76\u4e0d\u4f1a\u5bf9 v \u662f\u5426\u6709\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u505a\u68c0\u67e5\uff0c\u6b64\u5904\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 int i = v.empty() ? 0 : v.back(); // \u66f4\u5b89\u5168\uff0c\u5f53 v \u4e3a\u7a7a\u65f6\u8fd4\u56de 0","title":"v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a"},{"location":"undef/#vector-operator-i","text":"std::vector v = { 1, 2, 3 }; v[3]; // \u9519\uff01\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 \u53ef\u4ee5\u7528 at \u6210\u5458\u51fd\u6570 std::vector v = { 1, 2, 3 }; v.at(3); // \u5b89\u5168\uff0c\u4f1a\u68c0\u6d4b\u5230\u8d8a\u754c\uff0c\u629b\u51fa std::out_of_range \u5f02\u5e38","title":"vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a"},{"location":"undef/#_26","text":"std::vector v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 v.begin() \u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u8fed\u4ee3\u5668\u4e0d\u5931\u6548\u3002 std::deque v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u53ef\u4ee5 https://www.geeksforgeeks.org/iterator-invalidation-cpp https://en.cppreference.com/w/cpp/container","title":"\u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548"},{"location":"undef/#_27","text":"std::vector v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f7f\u5143\u7d20\u5168\u90e8\u79fb\u52a8\u5230\u4e86\u65b0\u7684\u4e00\u6bb5\u5185\u5b58\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 ref \u5f15\u7528\u5931\u6548 ref = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u5f15\u7528\u4e0d\u5931\u6548\u3002 std::deque v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u5143\u7d20\u79fb\u52a8\uff0c\u4f7f\u5f15\u7528\u5931\u6548 ref = 0; // \u53ef\u4ee5","title":"\u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548"},{"location":"undef/#_28","text":"","title":"\u591a\u7ebf\u7a0b\u7c7b"},{"location":"undef/#_29","text":"std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { cout << s.size(); // \u8bfb\u8bbf\u95ee } std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { s.push_back('b'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } \u66f4\u51c6\u786e\u7684\u8bf4\u6cd5\u662f\uff1a\u591a\u4e2a\u7ebf\u7a0b\uff08\u65e0 happens before \u5173\u7cfb\u5730\uff09\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u5e26\u6709\u526f\u4f5c\u7528\uff08\u5199\u8bbf\u95ee\u6216\u5e26\u6709volatile\u7684\u8bfb\u8bbf\u95ee\uff09\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a // \u516b\u80a1\u6587\u6559\u6750\u5e38\u89c1\u7684\u9519\u8bef\u5199\u6cd5\uff01volatile \u5e76\u4e0d\u4fdd\u8bc1\u539f\u5b50\u6027\u548c\u5185\u5b58\u5e8f\uff0c\u8fd9\u6837\u5199\u662f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u6539\u7528 std::atomic volatile int ready = 0; int data; void t1() { data = 42; ready = 1; } void t2() { while (ready == 0) ; printf(\"%d\\n\", data); } \u5efa\u8bae\u5229\u7528 mutex\uff0ccounting_semaphore\uff0catomic \u7b49\u591a\u7ebf\u7a0b\u540c\u6b65\u5de5\u5177\uff0c\u4fdd\u8bc1\u591a\u4e2a\u7ebf\u7a0b\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\u65f6\uff0c\u987a\u5e8f\u6709\u5148\u6709\u540e\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u53d1\u751f\uff0c\u90a3\u5c31\u662f\u5b89\u5168\u7684 std::string s; std::mutex m; void t1() { std::lock_guard l(m); s.push_back('a'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } void t2() { std::lock_guard l(m); s.push_back('b'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e92\u65a5\u9501\u4fdd\u8bc1\u4e86\u8981\u4e48 t1 happens before t2\uff0c\u8981\u4e48 t2 happens before t1\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::counting_semaphore<1> sem(1); void t1() { s.push_back('a'); sem.release(); // \u4ee4 t2 \u5fc5\u987b\u53d1\u751f\u5728 t1 \u4e4b\u540e } void t2() { sem.acquire(); // t2 \u5fc5\u987b\u7b49\u5f85 t1 release \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4fe1\u53f7\u91cf\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::atomic ready{false}; void t1() { s.push_back('a'); ready.store(true, std::memory_order_release); // \u4ee4 s \u7684\u4fee\u6539\u5bf9\u5176\u4ed6 acquire \u4e86 ready \u7684\u7ebf\u7a0b\u53ef\u89c1 } void t2() { while (!ready.load(std::memory_order_acquire)) // t2 \u5fc5\u987b\u7b49\u5f85 t1 store \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c ; s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u539f\u5b50\u53d8\u91cf\u7684 acquire/release \u5185\u5b58\u5e8f\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684","title":"\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09"},{"location":"undef/#mutex","text":"std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); // \u9519\uff01 m2.unlock(); m1.unlock(); } void t2() { m2.lock(); m1.lock(); // \u9519\uff01 m1.unlock(); m2.unlock(); } \u89e3\u51b3\u65b9\u6cd5\uff1a\u4e0d\u8981\u5728\u591a\u4e2a mutex \u4e0a\u540c\u65f6\u4e0a\u9501\uff0c\u5982\u679c\u786e\u5b9e\u8981\u591a\u4e2a mutex\uff0c\u4fdd\u8bc1\u987a\u5e8f\u4e00\u81f4 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } void t2() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } \u6216\u4f7f\u7528 std::lock std::mutex m1, m2; void t1() { std::lock(m1, m2); std::unlock(m1, m2); } void t2() { std::lock(m2, m1); std::unlock(m2, m1); }","title":"\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09"},{"location":"undef/#recursive_mutex-mutex","text":"std::mutex m; void t1() { m.lock(); m.lock(); // \u9519\uff01 m.try_lock(); // \u9519\uff01try_lock \u4e5f\u4e0d\u5141\u8bb8\uff01 m.unlock(); m.unlock(); } void t2() { m.try_lock(); // \u53ef\u4ee5 } \u89e3\u51b3\u65b9\u6cd5\uff1a\u6539\u7528 recursive_mutex\uff0c\u6216\u4f7f\u7528\u9002\u5f53\u7684\u6761\u4ef6\u53d8\u91cf std::recursive_mutex m; void t1() { m.lock(); m.lock(); // \u53ef\u4ee5 m.try_lock(); // \u53ef\u4ee5\uff0c\u8fd4\u56de true m.unlock(); m.unlock(); m.unlock(); }","title":"\u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09"},{"location":"undef/#_30","text":"\u4e0d\u8981\u73a9\u7a7a\u6307\u9488 \u4e0d\u8981\u8d8a\u754c\uff0c\u7528\u66f4\u5b89\u5168\u7684 at\uff0csubspan \u7b49 \u4e0d\u8981\u4e0d\u521d\u59cb\u5316\u53d8\u91cf\uff08auto-idiom\uff09 \u5f00\u542f -Werror=return-type \u4e0d\u8981\u91cd\u590d\u4e0a\u9501 mutex \u4ed4\u7ec6\u770b\u5e93\u51fd\u6570\u7684\u6587\u6863 \u7528\u667a\u80fd\u6307\u9488\u7ba1\u7406\u5355\u4e2a\u5bf9\u8c61 \u7528 vector \u7ba1\u7406\u591a\u4e2a\u5bf9\u8c61\u7ec4\u6210\u7684\u8fde\u7eed\u5185\u5b58 \u907f\u514d\u7a7a\u60ac\u5f15\u7528 \u5f00 Debug \u6a21\u5f0f\u7684 STL \u6307\u5b9a CMake \u7684\u6a21\u5f0f\uff1a cmake -B build -DCMAKE_BUILD_TYPE=Debug Debug: -O0 -g \u7f16\u8bd1\u9009\u9879 Release: -O3 -DNDEBUG \u7f16\u8bd1\u9009\u9879 \u6307\u5b9a MSVC \u7684\u6a21\u5f0f\uff1a cmake --build build --config Debug Debug: \u751f\u6210 zenod.dll \uff0c\u94fe\u63a5 Debug \u7684 ABI Release: \u751f\u6210 zeno.dll \uff0c\u94fe\u63a5 Release \u7684 ABI","title":"\u603b\u7ed3"},{"location":"undef/#cppcon","text":"\u987a\u4fbf\u63a8\u4e2a CppCon \u5c0f\u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=ehyHyAIa5so \u6807\u9898\u662f\u300aCppCon 2017: Piotr Padlewski \u201cUndefined Behaviour is awesome!\u201d\u300b\uff08\u7206\u5b5d\uff09","title":"CppCon \u76f8\u5173\u89c6\u9891"},{"location":"unicode/","text":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u96c6 ASCII Latin-1 Unicode \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801 UTF-32 UTF-8 \u517c\u5bb9 ASCII \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d UTF-16 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 BOM \u6807\u8bb0 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u7684\u7f3a\u9677 GBK GB18030 \u603b\u7ed3 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 UTF-8 \u9635\u8425 UTF-16 \u9635\u8425 UTF-32 \u9635\u8425 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale UTF \u4e4b\u95f4\u4e92\u8f6c GBK \u548c UTF \u4e92\u8f6c UTF \u548c ANSI \u4e92\u8f6c \u5927\u603b\u7ed3 GBK \u548c Shift-JIS \u4e92\u8f6c \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u66f4\u591a\u529f\u80fd\uff1f\uff01 Windows \u7528\u6237\uff1aMultiByteToWideChar MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b Linux \u7528\u6237\uff1aiconv iconv \u547d\u4ee4\u884c\u5de5\u5177 \u672c\u5730\u5316 (locale) \u533a\u5206\u5b57\u7b26\u7c7b\u578b \u5bbd\u5b57\u7b26\u7c7b\u578b wchar_t \u5e94\u7528\u6848\u4f8b \u533a\u57df\u8bbe\u7f6e\u4e0e locale locale \u7684\u547d\u540d\u89c4\u8303 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7279\u6b8a locale\uff1a\"C\" LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801 LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 std::locale \u5bf9\u8c61 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale \u5bbd\u5b57\u7b26\u6d41 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 Windows \u4e13\u9898 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 TCHAR \u6d41\u6d3e UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 Qt QString QTextCodec from/toLocal8Bits/Utf8/Latin1/Ascii \u5b57\u7b26\u4e32\u5e38\u91cf QTextStream Python 3 str Rust &str \u548c String Java String COW \u5b57\u7b26\u4e32 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 Grapheme \u6b63\u89c4\u5316 \u96f6\u5bbd\u7a7a\u683c \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 UniFont \u5b57\u4f53 \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f Latin-1 \u7684\u8f6c\u6362 Latin-1 \u7684\u5999\u7528 Base64 \u9632\u4e71\u7801 UTF-7 \u5b57\u7b26\u7f16\u7801\u731c\u6d4b \u5b57\u7b26\u96c6 \u8ba1\u7b97\u673a\u4e0d\u80fd\u76f4\u63a5\u5b58\u50a8\u5b57\u7b26\uff0c\u800c\u662f\u7528\u6570\u5b57\u6765\u4ee3\u66ff\uff0c\u8fd9\u5c31\u662f\u5b57\u7b26\u96c6\uff0c\u4e3a\u6bcf\u4e2a\u5b57\u7b26\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57\u3002 ASCII ASCII \u4e3a\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u7ec4\u3001\u6807\u70b9\u7b26\u53f7\u7b49 128 \u4e2a\u5b57\u7b26\uff0c\u6bcf\u4e2a\u90fd\u7528\u4e00\u4e2a 0 \u5230 127 \u8303\u56f4\u5185\u7684\u6570\u5b57\u5bf9\u5e94\u3002 \u5982\u679c\u4f60\u60f3\u8981\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u5c31\u5728\u8fd9\u4e2a\u8868\u91cc\u5bfb\u627e\u5230\u76f8\u5e94\u7684\u6570\u5b57\u7f16\u53f7\uff0c\u7136\u540e\u5b58\u8fd9\u4e2a\u7f16\u53f7\u5373\u53ef\u3002 \u4f8b\u5982\u4e0b\u9762\u7684\u4e00\u4e32\u6570\u5b57\uff1a 80 101 110 103 \u5728 ASCII \u8868\u4e2d\u67e5\u627e\uff0c\u53d1\u73b0\u8fd9\u4e9b\u6570\u5b57\u5206\u522b\u5bf9\u5e94 P \u3001 e \u3001 n \u3001 g \u56db\u4e2a\u5b57\u6bcd\uff0c\u8fde\u8d77\u6765\u5c31\u8fd8\u539f\u5f97\u5230\u4e86\u539f\u672c\u7684\u5b57\u7b26\u4e32\u201cPeng\u201d\u3002 Latin-1 Latin-1 \u6269\u5145\u4e86 ASCII \u5b57\u7b26\u96c6\uff0c\u4fdd\u6301 ASCII \u539f\u6709 0 \u5230 127 \u7684\u90e8\u5206\u6620\u5c04\u4e0d\u53d8\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 128 \u5230 255 \u7684\u6620\u5c04\u5173\u7cfb\u3002\u56e0\u6b64\u4e5f\u88ab\u79f0\u4e3a EASCII\uff08\u6269\u5c55 ASCII\uff09\u3002 Unicode Unicode \u5b57\u7b26\u96c6\u4e3a\u5168\u4e16\u754c\u7684\u6240\u6709\u5b57\u7b26\u90fd\u5bf9\u5e94\u4e86\u4e00\u4e2a\u6574\u6570\u3002 \u5b57\u7b26 \u7f16\u53f7 \u6211 25105 \u6212 25106 \u6213 25107 \u6214 25108 \u6215 25109 \u6216 25110 \u6217 25111 \u6218 25112 \u6219 25113 \u621a 25114 \u51fa\u4e8e\u5386\u53f2\u517c\u5bb9\u6027\u8003\u8651\uff0cUnicode \u5728 0 \u5230 256 \u533a\u95f4\u5185\u7684\u6620\u5c04\u548c ASCII\u3001Latin-1 \u662f\u5b8c\u5168\u76f8\u540c\u7684\u3002 \u5b57\u7b26 \u7f16\u53f7 P 80 e 101 n 110 g 103 Unicode \u7ecf\u8fc7\u4e86\u8bb8\u591a\u7248\u672c\u7684\u53d1\u5c55\uff0c\u65e9\u671f\u7684 Unicode \u53ea\u6536\u5f55\u4e86 65536 (0x10000) \u4e2a\u5b57\u7b26\uff0c\u540e\u6765\u6269\u5145\u5230\u4e86 1114112 (0x110000) \u4e2a\u5b57\u7b26\u3002 \u603b\u4e4b\uff0c\u73b0\u5728 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u867d\u7136\u5360\u7528\u4e86 1114112 \u8fd9\u591a\u683c\u7801\u70b9\u7a7a\u95f4\uff0c\u4e0d\u8fc7\u5176\u4e2d\u5f88\u591a\u90fd\u662f\u7a7a\u53f7\uff0c\u7559\u5f85\u672a\u6765\u6269\u5145\u4f7f\u7528\u3002 Unicode \u5b57\u7b26\u6620\u5c04\u8868\u53ef\u4ee5\u5728\u7f51\u4e0a\u627e\u5230\uff1a https://symbl.cc/en/unicode-table/ https://www.compart.com/en/unicode/ \u603b\u7ed3 \u5b57\u7b26\u96c6: \u4ece\u5b57\u7b26\u5230\u6574\u6570\u7684\u4e00\u4e00\u6620\u5c04\u3002 ASCII: \u53ea\u6536\u5f55\u4e86\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 Latin-1: \u5728 ASCII \u57fa\u7840\u4e0a\u8ffd\u52a0\u4e86\u6ce8\u97f3\u5b57\u6bcd\uff0c\u6ee1\u8db3\u6b27\u6d32\u7528\u6237\u9700\u8981\u3002 Unicode: \u6536\u5f55\u4e86\u5168\u4e16\u754c\u6240\u6709\u6587\u5b57\u548c\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 \u8ba1\u7b97\u673a\u5b58\u50a8\u5b57\u7b26\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u5b58\u50a8\u4e86\u90a3\u4e2a\u5bf9\u5e94\u7684\u6574\u6570\u3002 \u8fd9\u4e9b\u6574\u6570\u5c31\u88ab\u79f0\u4e3a \u7801\u70b9 (code point) \uff0c\u6bcf\u4e2a\u5b57\u7b26\u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002 \u4e0d\u8fc7\uff0c\u7a0b\u5e8f\u5458\u901a\u5e38\u559c\u6b22\u7528\u5341\u516d\u8fdb\u5236\u4e66\u5199\u6570\u5b57\uff1a \u5b57\u7b26 \u7f16\u53f7 \u6211 0x6211 \u6212 0x6212 \u6213 0x6213 \u6214 0x6214 \u6215 0x6215 \u6216 0x6216 \u6217 0x6217 \u6218 0x6218 \u6219 0x6219 \u621a 0x621A \u4f8b\u5982\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\uff0c\u5728 Unicode \u8868\u4e2d\u7f16\u53f7\u4e3a 0x6211\u3002\u4e8e\u662f\u5f53\u8ba1\u7b97\u673a\u9700\u8981\u8868\u793a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\u65f6\uff0c\u5c31\u7528 0x6211 \u8fd9\u4e2a\u6574\u6570\u4ee3\u66ff\u3002 \u5982\u679c\u8981\u8868\u793a\u591a\u4e2a\u5b57\u7b26\uff0c\u90a3\u5c31\u7528\u4e00\u4e2a\u6574\u6570\u7684\u6570\u7ec4\u5427\uff01 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5904\u7406\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a 0x6211 0x7231 0x30EDE 0x30EDE 0x9762 0x21 \u8fd9\u4e00\u4e32\u6570\u5b57\u4ee3\u66ff\u3002 \u5982\u679c\u4f60\u8fd9\u91cc\u770b\u5230\u7684\u662f\u201c\u6211\u7231\u53e3\u53e3\u9762!\u201d\u8bf4\u660e\u4f60\u7684\u5b57\u4f53\u4e0d\u652f\u6301\u201cbi\u00e1ng\u201d\u8fd9\u4e2a\u5b57\u3002\u5f53\u6d4f\u89c8\u5668\u9047\u5230\u5f53\u524d\u5b57\u4f53\u4e0d\u652f\u6301\u7684 Unicode \u5b57\u7b26\u65f6\uff0c\u5c31\u4f1a\u66ff\u6362\u4e3a\u65b9\u5757\u3002\u5efa\u8bae\u5b89\u88c5\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u8f83\u591a\u7684 \u201cNoto Sans CJK SC\u201d \u5b57\u4f53\uff0c\u4e5f\u53ef\u4ee5\u5b89\u88c5\u652f\u6301\u4e00\u5207 Unicode \u5b57\u7b26\u7684 \u201cUniFonts\u201d\u3002 sudo apt-get install -y fonts-noto-cjk \u201c\ud883\udede(bi\u00e1ng)\ud883\udede(bi\u00e1ng)\u9762\u201d\u662f\u6d41\u884c\u4e8e\u4e2d\u56fd\u9655\u897f\u5173\u4e2d\u5730\u533a\u7684\u4e00\u79cd\u77e5\u540d\u4f20\u7edf\u98ce\u5473\u9762\u98df\uff0c\u5c5e\u4e8e\u626f\u9762\uff0c\u901a\u8fc7\u63c9\u3001\u62bb\u3001\u7529\u3001\u626f\u7b49\u6b65\u9aa4\u5236\u4f5c\uff0c\u9762\u5bbd\u800c\u539a\uff0c\u72b9\u5982\u201c\u88e4\u8170\u5e26\u201d\uff0c\u53e3\u611f\u52b2\u9053\uff0c\u98df\u7528\u524d\u52a0\u5165\u5404\u8272\u81ca\u5b50\u6216\u6cb9\u6cfc\u8fa3\u5b50\u3002\u4f46\u662f\uff0c\u5c0f\u5f6d\u8001\u5e08\u5176\u5b9e\u5e76\u6ca1\u6709\u5403\u8fc7\uff0c\u53ea\u662f\u56e0\u4e3a\u7a00\u6709\u5b57\u4f53\u770b\u8d77\u6765\u6bd4\u8f83\u597d\u73a9\u3002 \u5b57\u7b26\u7f16\u7801 Unicode \u53ea\u662f\u6307\u5b9a\u4e86\u6574\u6570\uff0c\u6ca1\u6709\u89c4\u5b9a\u6574\u6570\u5982\u4f55\u5728\u5185\u5b58\u4e2d\u5b58\u5728\u3002 \u5b57\u7b26\u7f16\u7801: \u5c06\u5b57\u7b26\u7684\u6574\u6570\u7f16\u53f7\u5e8f\u5217\u5316\u4e3a\u8ba1\u7b97\u673a\u53ef\u76f4\u63a5\u5b58\u50a8\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u5b9e\u9645\u5b58\u5728\u7684\u6574\u6570\u7c7b\u578b\u3002 Unicode \u5b57\u7b26\u53ef\u4ee5\u9009\u7528\u4ee5\u4e0b\u8fd9\u4e9b\u5b57\u7b26\u7f16\u7801\u6765\u5e8f\u5217\u5316\uff1a UTF-32: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u4e2a uint32_t \u6574\u6570\u5b58\u50a8\u3002 UTF-16: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 2 \u4e2a uint16_t \u6574\u6570\u5b58\u50a8\u3002 UTF-8: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u5b58\u50a8\u3002 \u7ffb\u8bd1\u51fa\u6765\u7684\u8fd9\u4e9b\u5c0f\u6574\u6570\u53eb \u7801\u4f4d (code unit) \u3002\u4f8b\u5982\u5bf9\u4e8e UTF-8 \u800c\u8a00\uff0c\u6bcf\u4e2a uint8_t \u5c31\u662f\u4ed6\u7684\u7801\u4f4d\u3002 UTF-32 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u6700\u5927\u503c 0x10FFFF \u6709 21 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0cC \u8bed\u8a00\u4e2d uint32_t \u80fd\u5bb9\u7eb3 32 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0c\u6240\u4ee5\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u662f\u76f4\u63a5\u7528 uint32_t \u6570\u7ec4\u6765\u4e00\u4e2a\u4e2a\u5bb9\u7eb3 Unicode \u5b57\u7b26\u7801\u70b9\u3002\u867d\u7136\u6d6a\u8d39\u4e86 11 \u4f4d\uff0c\u4f46\u81f3\u5c11\u6240\u6709 Unicode \u5b57\u7b26\u90fd\u80fd\u5b89\u5168\u5bb9\u7eb3\u3002 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a std::vector s = { 0x00006211, // \u6211 0x00007231, // \u7231 0x00030EDE, // \ud883\udede 0x00030EDE, // \ud883\udede 0x00009762, // \u9762 0x00000021, // ! }; \u8fd9\u4e2a\u6570\u7ec4\u8868\u793a\u3002 UTF-32 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u56fa\u5b9a\u5bf9\u5e94\u4e00\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-32 \u662f \u5b9a\u957f\u7f16\u7801 \u3002\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5c31\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002 \u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u6570\u7ec4\u7684\u7d22\u5f15\u64cd\u4f5c\u3002 \u65e0\u8bba\u5bf9\u6570\u7ec4\u5982\u4f55\u5207\u7247\uff0c\u90fd\u4e0d\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u7834\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u5c31\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u53cd\u8f6c\uff0c\u4e0d\u4f1a\u4ea7\u751f\u7834\u574f\u5b57\u7b26\u7684\u95ee\u9898\u3002 \u7f3a\u70b9\u662f\uff1a \u6d6a\u8d39\u5b58\u50a8\u7a7a\u95f4\u3002 \u5b9a\u957f\u7f16\u7801\u5f88\u65b9\u4fbf\uff0c\u6211\u4eec\u63a8\u8350\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\uff0c\u7edf\u4e00\u91c7\u7528 UTF-32 \u5f62\u5f0f\u5904\u7406\u6587\u5b57\u3002 UTF-32 \u4e5f\u88ab\u79f0\u4e3a UCS-4\uff0c\u4ed6\u4fe9\u662f\u540c\u4e49\u8bcd\u3002 UTF-8 UTF-32 \u867d\u7136\u65b9\u4fbf\u4e86\u6587\u5b57\u5904\u7406\uff0c\u7136\u800c\uff0c\u5374\u6d6a\u8d39\u4e86\u5927\u91cf\u7684\u5b58\u50a8\u7a7a\u95f4\uff0c\u4e0d\u5229\u4e8e\u6587\u5b57\u5b58\u50a8\uff01\u4e00\u4e2a\u5b57\u7b26\uff0c\u65e0\u8bba\u4ed6\u662f\u5e38\u7528\u8fd8\u662f\u4e0d\u5e38\u7528\uff0c\u90fd\u8981\u9738\u5360 4 \u4e2a\u5b57\u8282\u7684\u7a7a\u95f4\u3002 Unicode \u7f16\u7801\u5b57\u7b26\u65f6\uff0c\u7279\u610f\u628a\u5e38\u7528\u7684\u5b57\u7b26\u9760\u524d\u6392\u5217\u4e86\u3002 \u4e16\u754c\u4e0a\u5e38\u7528\u8bed\u8a00\u6587\u5b57\u90fd\u88ab\u523b\u610f\u7f16\u7801\u5728\u4e86 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u8d85\u8fc7 0x10000 \u7684\u57fa\u672c\u90fd\u662f\u4e0d\u5e38\u7528\u7684\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\uff0c\u5f88\u591a\u90fd\u662f\u5df2\u7ecf\u65e0\u4eba\u4f7f\u7528\u7684\u53e4\u4ee3\u6587\u5b57\u548c\u751f\u50fb\u5b57\uff0c\u4f8b\u5982\u201c\ud883\udede\u201d\u3002\u4ec5\u4ec5\u662f\u4e3a\u4e86\u8fd9\u4e9b\u5076\u5c14\u4f7f\u7528\u7684\u7f55\u89c1\u6587\u5b57\uff0c\u5c31\u8981\u6c42\u6240\u6709\u6587\u5b57\u90fd\u7528\u540c\u6837\u7684 4 \u5b57\u8282\u5bbd\u5ea6\u5b58\u50a8\uff0c\u5b9e\u5728\u662f\u6709\u70b9\u6d6a\u8d39\u3002 \u5728 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u540c\u6837\u6709\u6309\u7167\u5e38\u7528\u5ea6\u6392\u5e8f\uff1a 0 \u5230 0x7F \u662f\uff08\u6b27\u7f8e\u7528\u6237\uff09\u6700\u5e38\u7528\u7684\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u534a\u89d2\u6807\u70b9\u3002 0x80 \u5230 0x7FF \u662f\u8868\u97f3\u6587\u5b57\u533a\uff0c\u5e38\u7528\u7684\u6ce8\u97f3\u5b57\u6bcd\u3001\u62c9\u4e01\u5b57\u6bcd\u3001\u5e0c\u814a\u5b57\u6bcd\u3001\u897f\u91cc\u5c14\u5b57\u6bcd\u3001\u5e0c\u4f2f\u6765\u5b57\u6bcd\u7b49\u3002 0x800 \u5230 0xFFFF \u662f\u8868\u610f\u6587\u5b57\uff0c\u7b80\u7e41\u4e2d\u6587\u3001\u65e5\u6587\u3001\u97e9\u6587\u3001\u6cf0\u6587\u3001\u9a6c\u6765\u6587\u3001\u963f\u62c9\u4f2f\u6587\u7b49\u3002 0x10000 \u5230 0x10FFFF \u662f\u4e0d\u5e38\u7528\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\u3002 UTF-8 \u5c31\u662f\u4e3a\u4e86\u89e3\u51b3\u538b\u7f29\u95ee\u9898\u800c\u8bde\u751f\u7684\u3002 UTF-8 \u628a\u4e00\u4e2a\u7801\u70b9\u5e8f\u5217\u5316\u4e3a\u4e00\u4e2a\u6216\u591a\u4e2a\u7801\u4f4d\uff0c\u4e00\u4e2a\u7801\u4f4d\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u8868\u793a\u3002 0 \u5230 0x7F \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 1 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 2 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 3 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 4 \u4e2a\u5b57\u8282\u8868\u793a\u3002 \u5e8f\u5217\u5316\u89c4\u5219\u5982\u4e0b\uff1a \u517c\u5bb9 ASCII \u5bf9\u4e8e 0 \u5230 0x7F \u7684\u5b57\u7b26\uff0c\u8fd9\u4e2a\u8303\u56f4\u7684\u5b57\u7b26\u9700\u8981 7 \u4f4d\u5b58\u50a8\u3002 \u6211\u4eec\u9009\u62e9\u76f4\u63a5\u5b58\u50a8\u5176\u503c\u3002 \u4f8b\u5982 \u2018P\u2019 \u4f1a\u88ab\u76f4\u63a5\u5b58\u50a8\u5176 Unicode \u503c\u7684 80\uff080x50\uff09\uff1a 01010000 \u7531\u4e8e Unicode \u5728 0 \u5230 0x7F \u8303\u56f4\u5185\u4e0e ASCII \u8868\u76f8\u540c\uff0c\u800c UTF-8 \u53c8\u628a 0 \u5230 0x7F \u7684\u503c\u76f4\u63a5\u5b58\u50a8\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u517c\u5bb9 ASCII\u3002\u8fd9\u4f7f\u5f97\u539f\u672c\u8bbe\u8ba1\u4e8e\u5904\u7406 ASCII \u7684 C \u8bed\u8a00\u51fd\u6570\uff0c\u4f8b\u5982 strlen\u3001strcat\u3001sprintf \u7b49\uff0c\u90fd\u53ef\u4ee5\u76f4\u63a5\u65e0\u7f1d\u5207\u6362\u5230 UTF-8\u3002\u53cd\u4e4b\u4ea6\u7136\uff0c\u4efb\u4f55\u8bbe\u8ba1\u7528\u4e8e UTF-8 \u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u5b8c\u5168\u63a5\u53d7 ASCII \u683c\u5f0f\u7684\u8f93\u5165\u6587\u672c\u3002 \u4f46\u90e8\u5206\u6d89\u53ca\u5b57\u7b26\u957f\u5ea6\u7684\u51fd\u6570\u4f1a\u6709\u4e9b\u8bb8\u4e0d\u517c\u5bb9\uff0c\u4f8b\u5982 strlen \u6c42\u51fa\u7684\u957f\u5ea6\u4f1a\u53d8\u6210\u5b57\u8282\u7684\u6570\u91cf\u800c\u4e0d\u662f\u5b57\u7b26\u7684\u6570\u91cf\u4e86\uff0c\u4f8b\u5982 strlen(\"\u6211\u4eec\") \u4f1a\u5f97\u5230 6 \u800c\u4e0d\u662f 2\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6784\u9020\u5c31\u50cf\u4e00\u5217\u5c0f\u706b\u8f66\u4e00\u6837\uff0c\u4e0d\u540c\u8303\u56f4\u5185\u7684\u7801\u4f4d\u4f1a\u88ab\u7f16\u7801\u6210\u4e0d\u540c\u957f\u5ea6\u7684\u5217\u8f66\uff0c\u4f46\u4ed6\u4eec\u90fd\u6709\u4e00\u4e2a\u8f66\u5934\u3002 \u6839\u636e\u706b\u8f66\u5934\u7684\u201c\u7b49\u7ea7\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u540e\u9762\u62c9\u7740\u51e0\u8282\u8f66\u53a2\u3002 \u706b\u8f66\u5934\u662f\u4ec0\u4e48\u7b49\u7ea7\u7531\u4ed6\u7684\u4e8c\u8fdb\u5236\u524d\u7f00\u51b3\u5b9a\uff1a \u5982\u679c\u662f 0 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u662f\u5355\u72ec\u4e00\u53f0\u706b\u8f66\u5934\uff0c\u540e\u9762\u6ca1\u6709\u8f66\u53a2\u4e86\uff0c\u8fd9\u8868\u793a\u8f66\u5934\u91cc\u9762\u76f4\u63a5\u88c5\u7740 0 \u5230 0x7F \u8303\u56f4\u7684\u666e\u901a ASCII \u5b57\u7b26\u3002 \u5982\u679c\u662f 110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e00\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u6b27\u6d32\u5b57\u7b26\u3002 \u5982\u679c\u662f 1110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e24\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u4e16\u754c\u5e38\u7528\u5b57\u7b26\u3002 \u5982\u679c\u662f 11110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e09\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u751f\u50fb\u5b57\u7b26\u3002 \u5982\u679c\u662f 10 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u8fd9\u662f\u4e00\u8282\u8f66\u53a2\uff0c\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002\u5982\u679c\u4f60\u770b\u5230\u4e00\u8282\u5355\u72ec\u7684\u8f66\u53a2\u5728\u524d\u9762\u65e0\u5934\u9a7e\u9a76\uff0c\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\u3002 \u5c0f\u670b\u53cb\u7528\u5c0f\u53f7\u5217\u8f66\u88c5\uff0c\u5927\u670b\u53cb\u7528\u5927\u53f7\u5217\u8f66\u88c5\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u4e32\u4e8c\u8fdb\u5236\uff1a 11100110 10000010 10000001 \u9996\u5148\uff0c\u770b\u5230\u7b2c\u4e00\u4e2a\u5b57\u8282\uff0c\u662f 1110 \u5f00\u5934\u7684\u4e09\u7ea7\u8f66\u5934\uff01\u8bf4\u660e\u540e\u9762\u8fd8\u6709\u4e24\u8282\u8f66\u53a2\u662f\u5c5e\u4e8e\u4ed6\u7684\u3002\u706b\u8f66\u5934\u4e2d 4 \u4f4d\u7528\u4e8e\u8868\u793a\u8f66\u5934\u7b49\u7ea7\u4e86\uff0c\u5269\u4e0b\u8fd8\u6709 4 \u4f4d\u7528\u4e8e\u88c5\u4e58\u5ba2\u3002 \u8f66\u53a2\u4e5f\u6709\u56fa\u5b9a\u7684\u524d\u7f00\uff0c\u6240\u6709\u7684\u8f66\u53a2\u90fd\u5fc5\u987b\u662f 10 \u5f00\u5934\u7684\u3002\u53bb\u9664\u8fd9\u5f00\u5934\u7684 2 \u4f4d\uff0c\u5269\u4e0b\u7684 6 \u4f4d\u5c31\u662f\u4e58\u5ba2\u3002 \u5bf9\u4e8e\u8fd9\u79cd\u4e09\u7ea7\u5217\u8f66\uff0c4 + 6 + 6 \u603b\u5171 16 \u4f4d\u4e8c\u8fdb\u5236\uff0c\u521a\u597d\u53ef\u4ee5\u88c5\u5f97\u4e0b 0xFFFF \u5185\u7684\u4e58\u5ba2\u3002 0110 000010 000001 \u7f16\u7801\u65f6\u5219\u662f\u53cd\u8fc7\u6765\u3002 \u4e58\u5ba2\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e09\u7247\uff0c\u4f8b\u5982\u5bf9\u4e8e\u201c\u6211\u201d\u8fd9\u4e2a\u4e58\u5ba2\uff0c\u201c\u6211\u201d\u7684\u7801\u70b9\u662f 0x6211\uff0c\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u662f\uff1a 110001000010001 \u628a\u4e58\u5ba2\u5207\u5206\u6210\u9ad8 4 \u4f4d\u3001\u4e2d 6 \u4f4d\u548c\u4f4e 6 \u4f4d\uff08\u4e0d\u8db3\u65f6\u5728\u524d\u9762\u8865\u96f6\uff09\uff1a 0110 001000 010001 \u52a0\u4e0a 1110 \u3001 10 \u548c 10 \u524d\u7f00\u540e\uff0c\u5f62\u6210\u4e00\u5217\u706b\u8f66\uff1a 11100110 10001000 10010001 \u8fd9\u6837\uff0c\u6211\u4eec\u5c31\u628a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\uff0c\u7f16\u7801\u6210\u4e86\u4e09\u8282\u5217\u8f66\uff0c\u585e\u8fdb\u5b57\u8282\u6d41\u7684\u7f51\u7edc\u96a7\u9053\u91cc\u4e86\u3002 \u603b\u7ed3\uff1a \u524d\u7f00\u662f 0 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 7 \u540d\u3002 \u524d\u7f00\u662f 10 \u7684\u662f\u8f66\u53a2\uff1a\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002 \u524d\u7f00\u662f 110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 5 \u540d + 1 \u8282\u8f66\u53a2\u8f7d\u5ba2 6 \u540d = \u5171 11 \u540d\u3002 \u524d\u7f00\u662f 1110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 4 \u540d + 2 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 16 \u540d\u3002 \u524d\u7f00\u662f 11110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 3 \u540d + 3 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 21 \u540d\u3002 \u9ad8\u7ea7\u8f66\u5934\u88c5\u4e86\u9632\u5f39\u94a2\u677f\uff0c\u8f7d\u5ba2\u7a7a\u95f4\u53d8\u5c11\uff0c\u53ea\u597d\u5300\u5230\u540e\u9762\u7684\u8f66\u53a2\u3002 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u5982\u679c\u53d1\u73b0 10 \u5f00\u5934\u7684\u72ec\u7acb\u8f66\u53a2\uff0c\u5c31\u8bf4\u660e\u51fa\u95ee\u9898\u4e86\uff0c\u53ef\u80fd\u662f\u706b\u8f66\u88ab\u9519\u8bef\u62e6\u8170\u622a\u65ad\uff0c\u4e5f\u53ef\u80fd\u662f\u5b57\u7b26\u4e32\u88ab\u9519\u8bef\u5730\u53cd\u8f6c\u3002\u56e0\u4e3a 10 \u53ea\u53ef\u80fd\u662f\u706b\u8f66\u8f66\u53a2\uff0c\u4e0d\u53ef\u80fd\u51fa\u73b0\u5728\u706b\u8f66\u5934\u90e8\u3002\u6b64\u65f6\u89e3\u7801\u5668\u5e94\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u66ff\u6362\u3002 10000010 10000001 \u5728\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u5982\u679c\u4f60\u4e0d\u59a5\u5584\u5904\u7406 TCP \u7c98\u5305\u95ee\u9898\uff0c\u5c31\u53ef\u80fd\u706b\u8f66\u5934\u8fdb\u53bb\u4e86\uff0c\u706b\u8f66\u5c3e\u5df4\u8fd8\u9732\u5728\u96a7\u9053\u5916\u9762\uff0c\u4e00\u6bb5\u5b8c\u6574\u7684\u5217\u8f66\u88ab\u5207\u65ad\uff0c\u5bfc\u81f4 UTF-8 \u89e3\u8bfb\u7684\u65f6\u5019\u51fa\u9519\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u8bbe\u7acb\u4e00\u4e2a\u72b6\u6001\u673a\u6765\u89e3\u7801 UTF-8\u3002C \u8bed\u8a00\u7684 mbstate_t \u5c31\u662f\u8fd9\u79cd\u72b6\u6001\u673a\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u9664\u6b64\u4e4b\u5916\uff0c\u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\uff0c\u5374\u53d1\u73b0\u91cc\u9762\u88c5\u7740 0x394 (\u201c\u0394\u201d)\uff0c\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u5c31\u80fd\u88c5\u4e0b\u7684\u6b27\u6d32\u5b57\u7b26\uff0c\u5374\u7528\u4e86\u4e09\u7ea7\u706b\u8f66\u5934\u88c5\uff0c\u8bf4\u660e\u88c5\u7bb1\u90a3\u8fb9\u7684\u4eba\u5077\u61d2\u6ee5\u7528\u8d44\u6e90\u4e86\uff01\u8fd9\u79cd\u60c5\u51b5\u4e0b UTF-8 \u89e3\u7801\u5668\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u8981\u4fdd\u8bc1\u7f16\u7801\u7684\u552f\u4e00\u6027\uff0c0x394 \u662f 0x7F \u5230 0x7FF \u8303\u56f4\u7684\uff0c\u5c31\u5e94\u8be5\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u88c5\u3002 \u4ee5\u53ca\uff0c\u5982\u679c\u53d1\u73b0 11111 \u5f00\u5934\u7684\u4e94\u7ea7\u706b\u8f66\u5934\uff0c\u4e5f\u8981\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u6700\u591a\u53ea\u652f\u6301\u56db\u7ea7\u706b\u8f66\u5934\u3002 \u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u56db\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u7684\u5b57\u7b26\u8303\u56f4\u8d85\u8fc7\u4e86 0x10FFFF\uff0c\u8fd9\u8d85\u51fa\u4e86 Unicode \u7684\u8303\u56f4\uff0c\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\u3002\u5982\u679c\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u53d1\u73b0\u5b57\u7b26\u8303\u56f4\u5904\u5728\u4fdd\u7559\u533a 0xD800 \u5230 0xDFFF \u5185\uff0c\u8fd9\u662f Unicode \u627f\u8bfa\u6c38\u4e0d\u52a0\u5165\u5b57\u7b26\u7684\u533a\u95f4\uff08\u7a0d\u540e\u8bb2\u89e3 UTF-16 \u65f6\u4f1a\u89e3\u91ca\u4e3a\u4ec0\u4e48\uff09\uff0c\u4e5f\u8981\u62a5\u9519\u3002\u603b\u4e4b Unicode \u7801\u70b9\u7684\u5408\u6cd5\u8303\u56f4\u662f 0x0 \u5230 0xD7FF\uff0c0xE000 \u5230 0x10FFFF\u3002 \u603b\u4e4b\uff0cUTF-8 \u5177\u6709\u4e00\u5b9a\u7684\u5197\u4f59\u548c\u81ea\u7ea0\u9519\u80fd\u529b\uff0c\u5982\u679c\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u5dee\u9519\uff0c\u53ef\u80fd\u4f1a\u7206\u51fa\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u3002\u8fd9\u4e2a\u7279\u6b8a\u5b57\u7b26\u662f Unicode \u5b98\u65b9\u89c4\u5b9a\u7684\uff0c\u7801\u70b9\u4e3a 0xFFFD\uff0c\u51fa\u73b0\u4ed6\u5c31\u610f\u5473\u7740 UTF-8 \u89e3\u7801\u5931\u8d25\u4e86\u3002 \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u4ee5 UTF-8 \u683c\u5f0f\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff1a std::vector s = { 0xE6, 0x88, 0x91, // \u6211\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xE7, 0x88, 0xB1, // \u7231\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xE9, 0x9D, 0xA2, // \u9762\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0x21, // !\uff0c\u8fd9\u662f\u4e2a ASCII \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u76f4\u63a5\u7528\u5355\u4e2a\u706b\u8f66\u5934\u88c5 }; UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u53ef\u80fd\u5bf9\u5e94\u591a\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u662f\u4e00\u79cd \u53d8\u957f\u7f16\u7801 \u3002\u53d8\u957f\u7f16\u7801\u7684\u7f3a\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4e0d\u4e00\u5b9a\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002\u56e0\u6b64\uff0c\u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\u3002 \u6570\u7ec4\u7684\u5355\u4e2a\u5143\u7d20\u7d22\u5f15\uff0c\u65e0\u6cd5\u4fdd\u8bc1\u53d6\u51fa\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u3002 \u5bf9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u53ef\u80fd\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u5207\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u4e0d\u4e00\u5b9a\u80fd\u628a\u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\uff0c\u56e0\u4e3a\u53ef\u80fd\u4e0d\u614e\u628a\u4e00\u4e2a\u5b57\u7b26\u7684\u591a\u4e2a\u7801\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u5b57\u7b26\u7834\u574f\u3002 \u4f18\u70b9\u662f\uff1a \u8282\u7ea6\u5b58\u50a8\u7a7a\u95f4\u3002 \u6211\u4eec\u63a8\u8350\u53ea\u5728\u7f51\u7edc\u901a\u4fe1\u3001\u786c\u76d8\u5b58\u50a8\u65f6\uff0c\u91c7\u7528 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u6587\u5b57\u3002 \u603b\u7ed3\uff1a UTF-8 \u9002\u5408\u5b58\u50a8\uff0cUTF-32 \u9002\u5408\u5904\u7406 \u3002 \u6211\u4eec\u5efa\u8bae\u8ba1\u7b97\u673a\u4ece\u786c\u76d8\u6216\u7f51\u7edc\u4e2d\u8bfb\u51fa UTF-8 \u5b57\u7b26\u4e32\u540e\uff0c\u7acb\u5373\u5c06\u5176\u8f6c\u6362\u4e3a UTF-32\uff0c\u4ee5\u65b9\u4fbf\u540e\u7eed\u6587\u5b57\u5904\u7406\u3002\u5f53\u9700\u8981\u5199\u5165\u786c\u76d8\u6216\u7f51\u7edc\u65f6\uff0c\u518d\u8f6c\u6362\u56de UTF-8\uff0c\u907f\u514d\u786c\u76d8\u5bb9\u91cf\u548c\u7f51\u7edc\u5e26\u5bbd\u7684\u6d6a\u8d39\u3002 \u8ba1\u7b97\u673a\u9700\u8981\u5916\u7801\u548c\u5185\u7801\u4e24\u79cd\uff1a \u5916\u7801=\u786c\u76d8\u4e2d\u7684\u6587\u672c=UTF-8 \u5185\u7801=\u5185\u5b58\u4e2d\u7684\u6587\u672c=UTF-32 UTF-16 UTF-16 \u7684\u7b56\u7565\u662f\uff1a\u65e2\u7136\u5927\u591a\u6570\u5e38\u7528\u5b57\u7b26\u7684\u7801\u70b9\u90fd\u5728 0x0 \u5230 0xFFFF \u5185\uff0c\u7528 uint32_t \u6765\u5b58\u50a8\u4e5f\u592a\u6d6a\u8d39\u4e86\u3002\u4ed6\u7684\u65b9\u6848\u5982\u4e0b\uff1a \u5bf9\u4e8e 0x0 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u5c31\u7528\u4e00\u4e2a uint16_t \u76f4\u63a5\u5b58\u3002 \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u53cd\u6b63\u4e0d\u5e38\u89c1\uff0c\u5c31\u62c6\u6210\u4e24\u4e2a uint16_t \u5b58\u3002\u8fd9\u4e2a\u62c6\u7684\u65b9\u6848\u5f88\u6709\u8bb2\u7a76\uff0c\u5982\u679c\u53ea\u662f\u666e\u901a\u7684\u62c6\uff0c\u7531\u4e8e\u89e3\u7801\u65f6\u6536\u5230\u7684\u662f\u4e2a\u6ca1\u5934\u6ca1\u5c3e\u7684\u5b57\u8282\u5e8f\u5217\uff0c\u65e0\u6cd5\u5206\u8fa8\u8fd9\u5230\u5e95\u662f\u4e24\u4e2a uint16_t \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u8fd8\u662f\u4e00\u4e2a uint16_t \u7684\u666e\u901a\u5b57\u7b26\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u628a\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u201c\ud883\udede\u201d\uff0c0x30EDE\u3002\u62c6\u6210\u4e24\u4e2a uint16_t \uff0c\u5f97\u5230 0x3 \u548c 0x0EDE\u3002\u5982\u679c\u76f4\u63a5\u5b58\u50a8\u8fd9\u4e24\u4e2a uint16_t \uff1a 0x0003 0x0EDE \u4e4b\u540e\u89e3\u7801\u65f6\uff0c\u5148\u8bfb\u5230 0x0003\uff0c\u8fd8\u4f1a\u4ee5\u4e3a\u4ed6\u662f\u5355\u72ec\u7684\u4e00\u4e2a uint16_t \uff0c\u8868\u793a 3 \u53f7\u5b57\u7b26\u201c\u201d\u3002\u540e\u9762\u7684 0x0EDE \u5c31\u53d8\u6210\u4e86\u4e00\u4e2a\u5355\u72ec\u7684 0x0EDE\uff0c\u53d8\u6210\u4e86 0x0EDE \u53f7\u5b57\u7b26 \u201c\u0ede\u201d\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u201c\ud883\udede\u201d\u5c31\u53d8\u6210\u4e86\u4e24\u4e2a\u6beb\u4e0d\u76f8\u5e72\u7684\u5b57\u7b26\uff0c\u201c\u0ede\u201d\u4e86\u3002 \u4e3a\u4e86\u907f\u514d\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u4e24\u4e2a uint16_t \u9700\u8981\u91c7\u7528\u4e00\u79cd\u7279\u6b8a\u7684\u65b9\u5f0f\u4ee5\u793a\u533a\u5206\u3002\u8ba9\u89e3\u7801\u5668\u4e00\u770b\u5230\uff0c\u5c31\u80fd\u786e\u5b9a\u8fd9\u4e24\u4e2a uint16_t \u9700\u8981\u7ec4\u88c5\u6210\u540c\u4e00\u4e2a\u5b57\u7b26\u3002 \u8fd9\u5c31\u7528\u5230\u4e86\u4e00\u4e2a\u201c\u6f0f\u6d1e\u201d\uff1aUnicode \u5e76\u6ca1\u6709\u628a\u7801\u70b9\u5206\u914d\u7684\u6ee1\u6ee1\u5f53\u5f53\uff0c\u6216\u8bb8\u662f\u51fa\u4e8e\u5148\u89c1\u4e4b\u660e\uff0c\u5728 0xD800 \u5230 0xDFFF \u4e4b\u95f4\u9884\u7559\u4e86\u4e00\u5927\u6bb5\u7a7a\u53f7\uff1a UTF-16 \u5c31\u662f\u5229\u7528\u4e86\u8fd9\u4e00\u6bb5\u7a7a\u95f4\uff0c\u4ed6\u89c4\u5b9a\uff1a0xD800 \u5230 0xDFFF \u4e4b\u95f4\u7684\u7801\u70b9\u5c06\u6c38\u8fdc\u4e0d\u7528\u6765\u8868\u793a\u5b57\u7b26\uff0c\u800c\u662f\u4f5c\u4e3a \u4ee3\u7406\u5bf9 (surrogate-pair) \u3002\u5176\u4e2d 0xD800 \u5230 0xDBFF \u662f \u9ad8\u4f4d\u4ee3\u7406 (high surrogate) \uff0c0xDC00 \u5230 0xDFFF \u662f \u4f4e\u4f4d\u4ee3\u7406 (low surrogate) \u3002\u9ad8\u4ee3\u7406\u5728\u524d\uff0c\u4f4e\u4ee3\u7406\u5728\u540e\u3002 \u4e00\u4e2a\u8d85\u8fc7 0xFFFF \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f1a\u88ab\u62c6\u6210\u4e24\u6bb5\uff0c\u4e00\u6bb5\u653e\u5728\u9ad8\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u6bb5\u653e\u5728\u4f4e\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u524d\u4e00\u540e\u653e\u5165 uint16_t \u5e8f\u5217\u4e2d\u3002 \u642d\u8f7d\u8d85\u5bbd\u8d85\u9650\u8d27\u7269\u7684\u8f66\u8f86\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e24\u6bb5\u518d\u8fdb\u5165\u96a7\u9053\u3002 \u5177\u4f53\u62c6\u5206\u65b9\u6cd5\u5982\u4e0b\uff1a \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7801\u70b9\uff0c\u9996\u5148\u5c06\u5176\u503c\u51cf\u53bb 0x10000\uff0c\u53d8\u6210\u4e00\u4e2a\u8303\u56f4 0x0 \u5230 0xFFFFF \u8303\u56f4\u5185\u7684\u6570\u5b57\uff0c\u8fd9\u80fd\u4fdd\u8bc1\u4ed6\u4eec\u53ea\u9700 20 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u53ef\u8868\u793a\u3002 \u4f8b\u5982\u201c\ud883\udede\u201d\u5bf9\u5e94\u7684\u7801\u70b9 0x30EDE\uff0c\u51cf\u53bb\u540e\u5c31\u53d8\u6210 0x20EDE\u3002 \u7136\u540e\uff0c\u5199\u51fa 0x20EDE \u7684\u4e8c\u8fdb\u5236\u8868\u793a\uff1a 00100000111011011110 \u603b\u5171 20 \u4f4d\uff0c\u6211\u4eec\u5c06\u5176\u62c6\u6210\u9ad8\u4f4e\u5404 10 \u4f4d\uff1a 0010000011 1011011110 \u5404\u81ea\u5199\u51fa\u76f8\u5e94\u7684\u5341\u516d\u8fdb\u5236\u6570\uff1a 0x083 0x2DE \u56e0\u4e3a\u6700\u591a\u53ea\u6709 10 \u4f4d\uff0c\u8fd9\u4e24\u4e2a\u6570\u90fd\u4f1a\u5728 0 \u5230 0x3FF \u7684\u8303\u56f4\u5185\u3002 \u800c 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u9884\u7559\u7684\u7a7a\u95f4\uff0c\u521a\u597d\u53ef\u4ee5\u5206\u522b\u5bb9\u7eb3 0x400 \u4e2a\u6570\uff01 \u6240\u4ee5\uff0c\u6211\u4eec\u5c06\u62c6\u5206\u51fa\u6765\u7684\u4e24\u4e2a 10 \u4f4d\u6570\uff0c\u5206\u522b\u52a0\u4e0a 0xD800 \u548c 0xDC00\uff1a 0xD800+0x083=0xD883 0xDC00+0x2DE=0xDFDE \u8fd9\u4e24\u4e2a\u6570\uff0c\u5fc5\u5b9a\u662f 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u6570\u3002\u800c\u8fd9\u4e24\u4e2a\u8303\u56f4\u90fd\u662f Unicode \u59d4\u5458\u4f1a\u9884\u7559\u7684\u4ee3\u7406\u5bf9\u533a\u95f4\uff0c\u7edd\u5bf9\u6ca1\u6709\u666e\u901a\u5b57\u7b26\u3002\u6240\u4ee5\uff0c\u751f\u6210\u7684\u4e24\u4e2a\u4ee3\u7406\u5bf9\u4e0d\u4f1a\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u53ef\u4ee5\u653e\u5fc3\u653e\u8fdb uint16_t \u6570\u7ec4\uff0c\u89e3\u7801\u5668\u5982\u679c\u68c0\u6d4b\u5230\u4ee3\u7406\u5bf9\uff0c\u5c31\u8bf4\u660e\u662f\u4e24\u8282\u8f66\u53a2\uff0c\u53ef\u4ee5\u653e\u5fc3\u8fde\u7eed\u8bfb\u53d6\u4e24\u4e2a uint16_t \u3002 \u6240\u4ee5\uff0c 0xD883 0xDFDE \u5c31\u662f\u201c\ud883\udede\u201d\u7528 UTF-16 \u7f16\u7801\u540e\u7684\u7ed3\u679c\u3002 \u4ee3\u7406\u5b57\u7b26\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\uff0c\u5f53\u89e3\u7801\u5668\u68c0\u6d4b\u5230\u4e00\u4e2a 0xD800 \u5230 0xDBFF \u8303\u56f4\u5185\u7684\u9ad8\u4ee3\u7406\u65f6\uff0c\u5c31\u9884\u793a\u7740\u8fd8\u9700\u8981\u518d\u8bfb\u53d6\u4e00\u4e2a\u4f4e\u4ee3\u7406\uff0c\u624d\u80fd\u62fc\u63a5\u6210\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u3002 \u5982\u679c\u63a5\u4e0b\u6765\u8bfb\u5230\u7684\u4e0d\u662f 0xDC00 \u5230 0xDFFF \u8303\u56f4\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u800c\u662f\u666e\u901a\u5b57\u7b26\u7684\u8bdd\uff0c\u90a3\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u53ef\u80fd\u662f\u4e2d\u95f4\u88ab\u4eba\u4e22\u5305\u4e86\uff0c\u9700\u8981\u62a5\u9519\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u9876\u66ff\u3002 \u53e6\u5916\uff0c\u5982\u679c\u8bfb\u5230\u4e86\u4e00\u4e2a\u5355\u72ec\u5b58\u5728\u7684 0xD800 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u90a3\u4e5f\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u56e0\u4e3a\u4ee3\u7406\u5b57\u7b26\u53ea\u6709\u6210\u5bf9\u51fa\u73b0\u624d\u6709\u610f\u4e49\uff0c\u4f4e\u4ee3\u7406\u5b57\u7b26\u4e0d\u53ef\u80fd\u5355\u72ec\u5728\u5f00\u5934\u51fa\u73b0\u3002 \u53ef\u89c1\uff0cUTF-16 \u548c UTF-8 \u4e00\u6837\uff0c\u90fd\u662f\u201c\u5c0f\u706b\u8f66\u201d\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0cUTF-16 \u540c\u6837\u4e5f\u6709\u7740\u7c7b\u4f3c\u4e8e UTF-8 \u7684\u6297\u5e72\u6270\u673a\u5236\u3002 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 \u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u591a\u5b57\u8282\u7684\u6574\u6570\u7c7b\u578b\uff08\u5982 uint16_t \u548c uint32_t \uff09\u9700\u8981\u88ab\u62c6\u6210\u591a\u4e2a\u5b57\u8282\u6765\u5b58\u50a8\u3002\u62c6\u5f00\u540e\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u6309\u4ec0\u4e48\u987a\u5e8f\u5b58\u5165\u5185\u5b58\uff1f\u4e0d\u540c\u7684\u786c\u4ef6\u67b6\u6784\u4ea7\u751f\u4e86\u4e89\u6267\uff1a \u5927\u7aef\u6d3e (bit endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u4e5f\u5c31\u662f\u5927\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5c0f\u7aef\u6d3e (little endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u4e5f\u5c31\u662f\u5c0f\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u8ba1\u7b97\u673a\u7535\u8def\u7684\u8ba1\u7b97\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x78 0x56 0x34 0x12 \u4f8b\u5982\uff0cIntel \u7684 x86 \u67b6\u6784\u548c ARM \u516c\u53f8\u7684 ARM \u67b6\u6784\u90fd\u662f\u5c0f\u7aef\u6d3e\uff0c\u800c Motorola \u516c\u53f8\u7684 68k \u67b6\u6784\u548c Sun \u516c\u53f8\u7684 SPARC \u67b6\u6784\u90fd\u662f\u5927\u7aef\u6d3e\u3002 \u8fd9\u5176\u5b9e\u662f\u5f88\u65e0\u804a\u7684\u4e89\u6267\uff0c\u4e3a\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u6539\u53d8\u8ba1\u7b97\u673a\u7684\u8bbe\u8ba1\u6beb\u65e0\u9053\u7406\uff0c\u6bd5\u7adf\u4e16\u754c\u4e0a\u4e5f\u6709\u4ece\u53f3\u5f80\u5de6\u4e66\u5199\u7684\u6587\u5b57\u548c\u4ece\u4e0a\u5f80\u4e0b\u4e66\u5199\u7684\u6587\u5b57\uff0c\u751a\u81f3\u6709\u5de6\u53f3\u6765\u56de\u4e66\u5199\u7684\u6587\u5b57\u2026\u2026\u5982\u679c\u8981\u4f3a\u5019\u4eba\u7c7b\uff0c\u4f60\u600e\u4e48\u4e0d\u6539\u6210\u5341\u8fdb\u5236\u5462\uff1f\u603b\u4e4b\uff0c\u6211\u8ba4\u4e3a\u5c0f\u7aef\u624d\u662f\u6700\u9002\u5408\u8ba1\u7b97\u673a\u7684\uff0c\u5e02\u9762\u4e0a\u5927\u591a\u6570\u4e3b\u6d41\u786c\u4ef6\u90fd\u662f\u5c0f\u7aef\u67b6\u6784\u3002 \u5728\u7f51\u7edc\u901a\u4fe1\u65f6\uff0c\u53d1\u6d88\u606f\u548c\u6536\u6d88\u606f\u7684\u53ef\u80fd\u662f\u4e0d\u540c\u7684\u67b6\u6784\uff0c\u5982\u679c\u53d1\u6d88\u606f\u7684\u662f\u5c0f\u7aef\u67b6\u6784\uff0c\u6536\u6d88\u606f\u7684\u662f\u5927\u7aef\u67b6\u6784\uff0c\u90a3\u4e48\u53d1\u51fa\u53bb\u7684\u662f 0x12345678\uff0c\u6536\u5230\u7684\u5c31\u4f1a\u53d8\u6210 0x78563421 \u4e86\u3002 \u56e0\u6b64\u4e92\u8054\u7f51\u4e00\u822c\u89c4\u5b9a\uff0c\u6240\u6709\u591a\u5b57\u8282\u7684\u6570\u636e\u5728\u7f51\u7edc\u5305\u4e2d\u7edf\u4e00\u91c7\u7528\u5927\u7aef\u3002\u5bf9\u4e8e\u5927\u7aef\u67b6\u6784\uff0c\u4ed6\u4eec\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u5bf9\u4e8e\u5c0f\u7aef\u67b6\u6784\uff0c\u5728\u53d1\u5305\u524d\u9700\u8981\u628a\u81ea\u5df1\u7684\u5c0f\u7aef\u6570\u636e\u505a\u5b57\u8282\u5e8f\u53cd\u8f6c\uff0c\u53d8\u6210\u5927\u7aef\u7684\u4ee5\u540e\uff0c\u518d\u53d1\u9001\u3002\u4e4b\u540e\u7684\u7f51\u7edc\u4e13\u9898\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u89e3\u8fd9\u4e00\u5757\u3002 \u57fa\u4e8e\u5b57\u8282\u7801\u7684\u865a\u62df\u673a\u8bed\u8a00\u901a\u5e38\u4f1a\u89c4\u5b9a\u4e00\u4e2a\u5b57\u8282\u5e8f\uff1a\u50cf Java \u8fd9\u79cd\u9762\u5411\u4e92\u8054\u7f51\u8bed\u8a00\uff0c\u7d22\u6027\u4e5f\u89c4\u5b9a\u4e86\u7edf\u4e00\u91c7\u7528\u5927\u7aef\uff0c\u65e0\u8bba JVM \u8fd0\u884c\u5728\u5927\u7aef\u673a\u5668\u8fd8\u662f\u5c0f\u7aef\u673a\u5668\u4e0a\u3002\u8fd9\u4f7f\u5f97\u4ed6\u4e0e\u4e92\u8054\u7f51\u901a\u4fe1\u6bd4\u8f83\u65b9\u4fbf\uff0c\u800c\u5728 x86 \u548c ARM \u67b6\u6784\u4e0a\uff0c\u4e0e\u672c\u5730\u53ea\u63a5\u53d7\u5c0f\u7aef\u6570\u636e\u7684 API\uff0c\u4f8b\u5982 OpenGL\uff0c\u6c9f\u901a\u8f83\u4e3a\u56f0\u96be\uff0c\u9700\u8981\u505a\u989d\u5916\u7684\u5b57\u8282\u5e8f\u8f6c\u6362\u3002\u800c C# \u4e3b\u6253\u6e38\u620f\u4e1a\u52a1\uff08\u4f8b\u5982 Unity\uff09\uff0c\u9700\u8981\u8003\u8651\u6027\u80fd\uff0c\u6240\u4ee5\u89c4\u5b9a\u5168\u90e8\u91c7\u7528\u5c0f\u7aef\u3002\u4f5c\u4e3a\u5e95\u5c42\u7f16\u7a0b\u8bed\u8a00\u7684 C++ \u5219\u662f\u5165\u4e61\u968f\u4fd7\uff0c\u4f60\u7684\u786c\u4ef6\u662f\u4ec0\u4e48\u7aef\uff0c\u4ed6\u5c31\u662f\u4ec0\u4e48\u7aef\uff0c\u4e0d\u4e3b\u52a8\u505a\u4efb\u4f55\u989d\u5916\u7684\u8f6c\u6362\u3002 UTF-16 \u548c UTF-32 \u7684\u7801\u4f4d\u90fd\u662f\u591a\u5b57\u8282\u7684\uff0c\u4e5f\u4f1a\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u3002\u4f8b\u5982\uff0cUTF-16 \u4e2d\u7684 uint16_t \u5e8f\u5217\uff1a 0x1234 0x5678 \u5728\u5927\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5728\u5c0f\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x34 0x12 0x78 0x56 \u8fd9\u6837\u4e00\u6765\uff0cUTF-16 \u548c UTF-32 \u7684\u5b57\u8282\u6d41\uff0c\u5728\u4e0d\u540c\u7684\u673a\u5668\u4e0a\uff0c\u53ef\u80fd\u4f1a\u6709\u4e0d\u540c\u7684\u987a\u5e8f\u3002\u8fd9\u7ed9\u8de8\u5e73\u53f0\u7684\u6587\u672c\u5904\u7406\u5e26\u6765\u4e86\u9ebb\u70e6\u3002 \u6240\u4ee5\u5f53\u4f60\u9700\u8981\u628a UTF-16 \u5b58\u5165\u786c\u76d8\u548c\u5728\u7f51\u7edc\u53d1\u9001\u65f6\uff0c\u8fd8\u9700\u8981\u989d\u5916\u6307\u660e\u4f60\u7528\u7684\u662f\u5927\u7aef\u7684 UTF-16 \u8fd8\u662f\u5c0f\u7aef\u7684 UTF-16\u3002 \u56e0\u6b64 UTF-16 \u548c UTF-32 \u8fdb\u4e00\u6b65\u5206\u88c2\u4e3a\uff1a UTF-16LE\uff1a\u5c0f\u7aef\u7684 UTF-16 UTF-16BE\uff1a\u5927\u7aef\u7684 UTF-16 UTF-32LE\uff1a\u5c0f\u7aef\u7684 UTF-32 UTF-32BE\uff1a\u5927\u7aef\u7684 UTF-32 \u5982\u679c\u53ea\u5728\u5185\u5b58\u7684 wchar_t \u4e2d\u4f7f\u7528\u5c31\u4e0d\u7528\u533a\u5206\uff0c\u9ed8\u8ba4\u8ddf\u968f\u5f53\u524d\u673a\u5668\u7684\u5927\u5c0f\u7aef\u3002\u6240\u4ee5 UTF-16 \u548c UTF-32 \u901a\u5e38\u53ea\u4f1a\u51fa\u73b0\u5728\u5185\u5b58\u4e2d\u7528\u4e8e\u5feb\u901f\u5904\u7406\u548c\u8ba1\u7b97\uff0c\u5f88\u5c11\u7528\u5728\u5b58\u50a8\u548c\u901a\u4fe1\u4e2d\u3002 UTF-8 \u662f\u57fa\u4e8e\u5355\u5b57\u8282\u7684\u7801\u4f4d\uff0c\u706b\u8f66\u5934\u7684\u987a\u5e8f\u4e5f\u6709\u4e25\u683c\u89c4\u5b9a\uff0c\u706b\u8f66\u5934\u603b\u662f\u5728\u6700\u524d\uff0c\u6839\u672c\u4e0d\u53d7\u5b57\u8282\u5e8f\u5927\u5c0f\u7aef\u5f71\u54cd\uff0c\u4e5f\u5c31\u6ca1\u6709\u5f71\u54cd\u3002 \u7531\u4e8e\u538b\u7f29\u7387\u4f4e\uff0c\u53c8\u5b58\u5728\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u800c\u4e92\u8054\u7f51\u6570\u636e\u9700\u8981\u4fdd\u8bc1\u76f8\u540c\u7684\u5927\u5c0f\u7aef\uff0c\u5728\u6536\u53d1\u5305\u65f6\u9700\u8981\u989d\u5916\u8f6c\u6362\uff0c\u56e0\u800c\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u7f51\u7edc\u3002\u800c UTF-8 \u7684\u5b58\u50a8\u5355\u4f4d\u662f\u5b57\u8282\uff0c\u5929\u751f\u6ca1\u6709\u5927\u5c0f\u7aef\u56f0\u6270\u3002\u66f4\u5999\u7684\u662f\uff0c\u4ed6\u4e14\u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u800c\u4e92\u8054\u7f51\u53c8\u662f\u53e4\u8463\u4e2d\u95f4\u4ef6\u6700\u591a\u7684\u5730\u65b9\u2026\u2026 \u603b\u4e4b\uff0c\u5b8c\u5168\u57fa\u4e8e\u5b57\u8282\u7684 UTF-8 \u662f\u6700\u9002\u5408\u7f51\u7edc\u901a\u4fe1\u548c\u786c\u76d8\u5b58\u50a8\u7684\u6587\u672c\u7f16\u7801\u683c\u5f0f\uff0c\u800c UTF-32 \u662f\u6700\u9002\u5408\u5728\u5185\u5b58\u4e2d\u5904\u7406\u7684\u683c\u5f0f\u3002 BOM \u6807\u8bb0 0xFEFF \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u4e0d\u53ef\u89c1\u5b57\u7b26\u201c\ufeff\u201d\uff0c\u8fd9\u662f\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u6ca1\u6709\u4efb\u4f55\u6548\u679c\u3002 \u4f60\u53ef\u4ee5\u628a\u8fd9\u4e2a\u5b57\u7b26\u52a0\u5728\u6587\u672c\u6587\u4ef6\u7684\u5934\u90e8\uff0c\u544a\u8bc9\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\uff0c\u8fd9\u4e2a\u6587\u4ef6\u662f\u7528\u4ec0\u4e48\u7f16\u7801\u7684\u3002 \u5982\u679c\u662f UTF-16 \u548c UTF-32\uff0c\u56e0\u4e3a 0xFEFF \u4e0d\u5bf9\u79f0\uff0c\u4ed6\u8fd8\u80fd\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\u3002\u56e0\u6b64 0xFEFF \u88ab\u79f0\u4e3a\u5b57\u8282\u5e8f\u6807\u5fd7\uff08Byte-order-mark\uff0cBOM\uff09\u3002 \u5982\u679c\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u90a3\u4e48\u4ed6\u7167\u5e38\u8bfb\u51fa 0xFEFF\uff0c\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u5728\u6587\u672c\u4e2d\u4e0d\u663e\u793a\uff0c\u4e0d\u5f71\u54cd\u89c6\u89c9\u7ed3\u679c\u3002 \u4e00\u4e9b\u8001\u7684\u7f16\u8bd1\u5668\uff08\u8fdc\u53e4 MinGW\uff0c\u73b0\u5728\u5df2\u7ecf\u6ca1\u6709\u4e86\uff09\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u4f1a\u628a\u5e26\u6709 BOM \u7684 UTF-8 \u7684 .cpp \u6e90\u7801\u6587\u4ef6\uff0c\u5f53\u4f5c\u5934\u90e8\u5e26\u6709\u9519\u8bef\u5b57\u7b26\u7684\u4e71\u7801\u6587\u4ef6\uff0c\u4ece\u800c\u62a5\u9519\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u7684\u8bb0\u4e8b\u672c\u4fdd\u5b58\u4e3a UTF-8 \u65f6\uff0c\u603b\u662f\u4f1a\u52a0\u4e0a BOM\u3002\u5982\u679c\u8bb0\u4e8b\u672c\u53d1\u73b0\u4e00\u4e2a\u6587\u4ef6\u6ca1\u6709 BOM\uff0c\u4f1a\u5f53\u4f5c ANSI\uff08GBK\uff09\u6765\u8bfb\u53d6\u3002 0xFEFF \u5728\u4e0d\u540c\u7684\u7f16\u7801\u4e0b\u4f1a\u4ea7\u751f\u4e0d\u540c\u7684\u7ed3\u679c\uff1a UTF-8\uff1a 0xEF 0xBB 0xBF \uff0c\u4ed6\u4f1a\u5360\u7528 3 \u5b57\u8282\uff0c\u800c\u4e14\u4e0d\u4f1a\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\uff0c\u56e0\u4e3a UTF-8 \u662f\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u7684\u3002 UTF-16\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE \u3002 UTF-32\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0x00 0x00 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE 0x00 0x00 \u3002 \u56e0\u6b64\uff0c\u5728\u6587\u672c\u5934\u90e8\u52a0\u4e0a BOM \u6709\u52a9\u4e8e\u8f6f\u4ef6\u63a8\u6d4b\u8be5\u6587\u4ef6\u662f\u4ec0\u4e48\u7f16\u7801\u7684\uff08\u5982\u679c\u90a3\u8f6f\u4ef6\u652f\u6301\u89e3\u6790 BOM \u7684\u8bdd\uff09\u3002 \u4f8b\u5982 Windows \u73af\u5883\u4e2d\uff0c\u6240\u6709\u7684\u6587\u672c\u6587\u4ef6\u90fd\u88ab\u9ed8\u8ba4\u5047\u5b9a\u4e3a ANSI\uff08GBK\uff09\u7f16\u7801\uff0c\u5982\u679c\u4f60\u8981\u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u4e3a UTF-8 \u7f16\u7801\uff0c\u5c31\u9700\u8981\u52a0\u4e0a BOM \u6807\u5fd7\u3002\u5f53 MSVC \u8bfb\u53d6\u65f6\uff0c\u770b\u5230\u5f00\u5934\u662f 0xEF 0xBB 0xBF \uff0c\u5c31\u660e\u767d\u8fd9\u662f\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u6587\u4ef6\u3002\u8fd9\u6837\uff0cMSVC \u5c31\u80fd\u6b63\u786e\u5730\u5904\u7406\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4e86\u3002\u5982\u679c MSVC \u6ca1\u770b\u5230 BOM\uff0c\u4f1a\u9ed8\u8ba4\u4ee5\u4e3a\u662f ANSI\uff08GBK\uff09\u7f16\u7801\u7684\uff0c\u4ece\u800c\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4f1a\u4e71\u7801\u3002\u5f00\u542f /utf-8 \u9009\u9879\u4e5f\u80fd\u8ba9 MSVC \u628a\u6ca1\u6709 BOM \u7684\u6e90\u7801\u6587\u4ef6\u5f53\u4f5c UTF-8 \u6765\u89e3\u6790\uff0c\u9002\u5408\u8de8\u5e73\u53f0\u5b9d\u5b9d\u4f53\u8d28\u3002 \u5176\u5b9e Windows \u7528\u6237\u53ef\u4ee5\u5728\u63a7\u5236\u9762\u677f\u7684\u201c\u65f6\u949f\u548c\u533a\u57df\u201d\u91cc\uff0c\u627e\u5230\u201c\u533a\u57df\u201d\u9009\u9879\u3002\u5728\u201c\u533a\u57df\u201d\u9009\u9879\u5361\u91cc\uff0c\u70b9\u51fb\u201c\u66f4\u6539\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u7136\u540e\u5f39\u51fa\u7684\u5bf9\u8bdd\u6846\u91cc\uff0c\u52fe\u9009\u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u63d0\u4f9b\u5168\u7403\u8bed\u8a00\u652f\u6301\u201d\uff0c\u91cd\u542f\u540e\uff0c\u5c31\u53ef\u4ee5\u5728\u7a0b\u5e8f\u4e2d\u9ed8\u8ba4\u4f7f\u7528 UTF-8\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684 GBK \u4e86\u3002\u8fd9\u4f1a\u628a ANSI \u53d8\u6210 UTF-8\uff0c\u8ba9\u8bb0\u4e8b\u672c\u7b49\u8f6f\u4ef6\u628a\u65e0 BOM \u7684\u6587\u4ef6\u90fd\u5f53\u4f5c UTF-8\uff0c\u8ba9\u5404\u79cd\u8f6f\u4ef6\u90fd\u8ba4\u4e3a\u5b57\u7b26\u4e32\u662f UTF-8 \u7b49\u7b49\u3002\u8fd9\u53ef\u4ee5\u89e3\u51b3\u90e8\u5206\u7f8e\u56fd\u8f6f\u4ef6\u65e0\u6cd5\u5904\u7406\u4e2d\u6587\u3001\u4e71\u7801\u7b49\u95ee\u9898\uff0c\u56e0\u4e3a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u5e38\u5e38\u65e0\u610f\u8bc6\u5730\u7528 UTF-8 \u5b57\u7b26\u4e32\u672a\u7ecf\u5904\u7406\u76f4\u63a5\u8c03\u7528 A \u51fd\u6570\u3002\u4e0d\u8fc7\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4f60\u8fd0\u884c\u5176\u4ed6\u5047\u5b9a\u4e86 GBK \u7684\u4e2d\u56fd\u7279\u4f9b\u7a0b\u5e8f\u4e71\u7801\uff0c\u4e5f\u4f1a\u5bfc\u81f4\u4f60\u7684\u6bd5\u4e1a\u7b54\u8fa9\u5bfc\u5e08\u53d1\u6765\u7684 ZIP \u53d8\u6210\u4e71\u7801\u3002\u800c\u4e14\u6211\u4eec\u4f5c\u4e3a\u5ba2\u6237\u7aef\u7684\u5f00\u53d1\u8005\uff0c\u6211\u4eec\u603b\u4e0d\u80fd\u5f3a\u6c42\u6240\u6709\u5ba2\u6237\u7528\u6211\u4eec\u7684\u8f6f\u4ef6\u524d\uff0c\u6539\u53d8\u4ed6\u4eec\u7684\u63a7\u5236\u9762\u677f\u6765\u9002\u5e94\u6211\u4eec\u7684\u7a0b\u5e8f\u5427\uff1f\u6240\u4ee5\u8fd8\u662f\u9700\u8981\u7ed5\u5f00 GBK\uff0c\u76f4\u63a5\u8c03\u7528 UTF-16 \u7684 W \u7c7b API\u3002 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u53d1\u5e03\u4e8e 1980 \u5e74\uff0c\u662f\u4e00\u4e2a\u53e4\u8001\u7684\u6c49\u5b57\u7f16\u7801\u6807\u51c6\uff0c\u517c\u5bb9 ASCII\u3002 \u201cGB\u201d \u8868\u793a Guo Biao\uff08\u56fd\u6807\uff09\u7684\u610f\u601d\u3002 GB2312 \u89c4\u5b9a\u4e86 6763 \u4e2a\u6c49\u5b57\u548c 682 \u4e2a\u7279\u6b8a\u7b26\u53f7\uff0c\u5171 7445 \u4e2a\u5b57\u7b26\u3002 GB2312 \u8ba9\u82f1\u6587\u548c\u6570\u5b57\u91c7\u7528\u548c ASCII \u76f8\u540c\u7684\u5355\u5b57\u8282\u7f16\u7801\uff0c\u800c\u5bf9\u4e8e\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u91c7\u7528\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u5176\u4e2d\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u7684\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u4e24\u4e2a\u5b57\u8282\u90fd\u5728 0xA1 \u5230 0xFE \u7684\u8303\u56f4\u5185\uff0c\u907f\u514d\u4e86\u4e0e\u5355\u5b57\u8282\u7684 ASCII \u7f16\u7801\u7a7a\u95f4\u51b2\u7a81\u3002 H i \u5f6d \u5b9d 0x48 0x69 0xC5 0xED 0xB1 0xA6 2 \u4e2a\u5b57\u8282\u5206\u522b\u88ab\u79f0\u4e3a\u201c\u533a\u7801\u201d\u548c\u201c\u4f4d\u7801\u201d\uff0c\u8303\u56f4\u90fd\u662f\u5728 0xA1 \u5230 0xFE \u533a\u95f4\u5185\u3002 \u201c\u7279\u6b8a\u7b26\u53f7\u201d\uff0c\u5171 682 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xA1A1 \u5230 0xA9FE\u3002 \u201c\u4e00\u7ea7\u6c49\u5b57\u201d\uff0c\u90fd\u662f\u6bd4\u8f83\u5e38\u7528\u7684\u6c49\u5b57\uff0c\u6309\u62fc\u97f3\u987a\u5e8f\u6392\u5e8f\uff0c\u5171 3755 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xB0A1 \u5230 0xF7FE\u3002 \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u662f\u4e00\u4e9b\u751f\u50fb\u5b57\uff0c\u6309\u90e8\u9996/\u7b14\u753b\u6392\u5e8f\uff0c\u5171 3008 \u4e2a\uff0c\u8fd9\u4e9b\u6c49\u5b57\u7684\u5b57\u7b26\u4ece 0x8140 \u5230 0xA0FE\u3002 GBK \u4e2d\u6c49\u5b57\u7684\u7f16\u53f7\u548c Unicode \u5e76\u4e0d\u662f\u76f8\u540c\u7684\uff0c\u8fd9\u4e5f\u662f GB2312 \u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6\u7528 UTF-8 \u6216 UTF-16 \u6253\u5f00\u4f1a\u4ea7\u751f\u4e71\u7801\u7684\u6839\u672c\u539f\u56e0\u3002 \u4f8b\u5982\u6c49\u5b57 \u201c\u5f6d\u201d \u5c31\u5c5e\u4e8e \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u5728 GB2312 \u4e2d\u7f16\u53f7\u4e3a 0xC5ED\uff0cUnicode \u4e2d\u7f16\u53f7\u4e3a 0x5F6D\u3002 \u5168\u89d2\u7a7a\u683c \u201c\u3000\u201d\uff0c\u5728 GB2312 \u4e2d\u7684\u7f16\u53f7\u4e3a 0xA1A1\uff0cUnicode \u4e2d\u7684\u7f16\u53f7\u4e3a 0x3000\u3002 GB2312 \u7684\u7f3a\u9677 GBK \u548c UTF-8 \u7684\u5171\u540c\u70b9\u5728\u4e8e\uff0c\u4ed6\u4eec\u90fd\u907f\u5f00\u4e86 0 ~ 127 \u7684 ASCII \u7a7a\u95f4\uff0c\u6240\u4ee5\u5b8c\u5168\u517c\u5bb9 ASCII\u3002 \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u5982\u679c\u5728\u4e00\u4e2a GBK \u7f16\u7801\u7684\u4e2d\u6587\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u4e2d\u6587\uff0c\u53ef\u80fd\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\uff0c\u800c UTF-8 \u4e0d\u4f1a\u3002\u8fd9\u662f\u56e0\u4e3a GBK \u6ca1\u6709\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u4ed6\u524d\u540e\u4e24\u4e2a\u8f66\u53a2\u5e76\u6ca1\u6709\u4e0d\u540c\u3002 \u5f53 GBK \u88ab\u5207\u7247\u65f6\uff0c\u5c31\u5bb9\u6613\u51fa\u73b0\u8fde\u9501\u53cd\u5e94\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.substr(1); // \"\u64a9\u683d\u91c7\ufffd\" // \u590d\u73b0\u65b9\u5f0f: MSVC \u4e2d\u56fd\u533a Windows\uff0c/std:c++17\uff0c\u4e0d\u5f00\u542f /utf-8 \u53c2\u6570\uff08\u8fd9\u65f6\u5b57\u7b26\u4e32\u5e38\u91cf\u90fd\u662f GBK \u7f16\u7801\u7684\uff09 \u6838\u53cd\u5e94\u5806\uff0c\u542f\u52a8\uff01 \u7279\u522b\u662f\u5f53\u4f60\u8bd5\u56fe find \u4e00\u4e2a\u4e2d\u6587\u5b50\u5b57\u7b26\u4e32\u65f6\uff0cGBK \u7f16\u7801\u7684\u591a\u5b57\u8282\u5b57\u7b26\u4e32\u53ef\u80fd\u4ea7\u751f\u627e\u5230\u4e86\u7684\u5047\u8c61\u3002\u5b9e\u9645\u4e0a\u627e\u5230\u7684\u4f4d\u7f6e\u6839\u672c\u662f\u5207\u65ad\u4e86\u5355\u4e2a\u5b8c\u6574\u7684\u4e2d\u6587\u5b57\u7b26\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.find(\"\u91c7\"); // 5\uff0c\u628a\u201c\u5706\u201d\u7684\u540e\u534a\u6bb5 0xAD \u548c\u201c\u795e\u201d\u7684\u524d\u534a\u6bb5 0xC9 \u5f53\u6210\u4e00\u4e2a\u5b57\u201c\u91c7\u201d (0xAD 0xC9) \u4e86 \u800c UTF-8 \u5219\u80fd\u6709\u6548\u9650\u5236\u9519\u8bef\u7684\u4f20\u64ad\u3002 std::string u8s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xE6 0xB2 0x89 0xE8 0xBF 0xB7 0xE5 0x9C 0x86 0xE7 0xA5 0x9E std::cout << u8s.substr(1); // \"\ufffd\u8ff7\u5706\u795e\" std::cout << u8s.find(\"\u91c7\"); // \u627e\u4e0d\u5230\uff0c\u8fd4\u56de -1 \u56e0\u4e3a UTF-8 \u7684\u5934\u90e8\u5c0f\u706b\u8f66\u548c\u5c3e\u90e8\u8f66\u53a2\u91c7\u7528\u4e86\u72ec\u7acb\u7684\u7f16\u7801\uff0cfind \u4e0d\u53ef\u80fd\u901a\u8fc7\u4efb\u4f55\u5408\u6cd5\u7684 UTF-8 \u5b50\u5b57\u7b26\u4e32\u5b9a\u4f4d\u5230\u9519\u8bef\u7684\u4e2d\u95f4\u4f4d\u7f6e\u3002 GB2312 \u548c GBK \u7684\u7279\u6b8a\u6027\uff1a\u4ed6\u65e2\u662f\u5b57\u7b26\u96c6\uff0c\u53c8\u662f\u5b57\u7b26\u7f16\u7801\u3002\u9664 Unicode \u5916\u5927\u591a\u6570\u5b57\u7b26\u96c6\u90fd\u662f\u8fd9\u6837\uff0c\u81ea\u5df1\u5c31\u662f\u81ea\u5df1\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u6ca1\u6709\u5176\u4ed6\u7f16\u7801\u65b9\u5f0f\u3002\u53ea\u6709 Unicode \u628a\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u7684\u6982\u5ff5\u5206\u7684\u5f88\u6e05\u695a\uff0c\u56e0\u4e3a Unicode \u5b57\u7b26\u96c6\u6709 UTF-8\u3001UTF-\u3002 GBK GBK \u540c\u6837\u662f\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u662f\u5bf9 GB2312 \u7684\u6269\u5c55\u3002 GBK \u5728\u4fdd\u6301 GB2312 \u90e8\u5206\u4e0d\u53d8\u7684\u57fa\u7840\u4e0a\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u6536\u5f55\u7684\u6709\uff1a GB2312 \u4e2d\u7684\u5168\u90e8\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7 BIG-5\uff08\u7e41\u4f53\u4e2d\u6587\u7684\u7f16\u7801\uff09\u4e2d\u7684\u5168\u90e8\u6c49\u5b57 GB13000\uff08\u5373 Unicode\uff09\u4e2d\u7684\u5176\u4ed6\u4e2d\u65e5\u97e9\u6c49\u5b57 \u5176\u4ed6\u5c1a\u672a\u6536\u5f55\u7684\u7279\u6b8a\u6c49\u5b57\u3001\u90e8\u9996\u3001\u7b26\u53f7\u7b49 \u201cK\u201d \u8868\u793a Kuo\uff08\u6269\u5c55\uff09\u7684\u610f\u601d\u3002 GB2312\uff1a\u9996\u5b57\u8282 0xA1 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282 0xA1 \u5230 0xFE\u3002 GBK\uff1a\u9996\u5b57\u8282 0x81 \u5230 0xFE \uff0c\u5c3e\u5b57\u8282 0x40 \u5230 0xFE \u3002 \u6ce8\u610f\u5230 GBK \u7684\u5c3e\u5b57\u8282\u8fdb\u5165\u4e86 0x40\uff0cASCII \u7684\u8303\u56f4\u3002 \u8fd9\u4f7f\u5f97 GBK \u6bd4 GB2312 \u66f4\u5371\u9669\uff0c\u4f8b\u5982 \u201c\u4fb0\u201d \u8fd9\u4e2a\u5b57\uff0c\u4f1a\u88ab\u7f16\u7801\u6210 0x82 0x43\u3002 \u800c 0x43 \u521a\u597d\u662f ASCII \u5b57\u7b26 \u201cC\u201d \u7684\u7f16\u7801\u3002\u5982\u679c\u53d1\u751f\u5b57\u7b26\u4e32\u5207\u7247\uff0c\u53ef\u80fd\u5bfc\u81f4 \u201c\u4fb0\u201d \u53d8\u6210 \u201c\ufffdC\u201d\u3002\u5e76\u4e14\u5982\u679c\u521a\u597d\u7a0b\u5e8f\u5728 .find('C') \uff0c\u90a3\u4e48 \u201c\u4fb0\u201d \u7684\u540e\u534a\u4e2a\u5b57\u8282\u4f1a\u88ab\u5f53\u4f5c \u201cC\u201d \u800c\u627e\u5230\u3002 \u4e0d\u8fc7\uff0cGBK \u8bbe\u8ba1\u65f6\u7279\u610f\u907f\u5f00\u4e86 0x40 \u4ee5\u4e0b\u7684 ASCII \u5b57\u7b26\uff0c\u4f8b\u5982 0x2F \u662f \u201c/\u201d \u7684 ASCII \u7f16\u7801\uff0c\u5e38\u7528\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7684\u8def\u5f84\u5206\u9694\u7b26\u3002 \u7136\u800c\uff0cWindows \u6240\u7528\u7684\u8def\u5f84\u5206\u9694\u7b26\u662f\u53cd\u659c\u6760 \u201c\\\u201d\uff0c\u4ed6\u7684 ASCII \u7f16\u7801\u662f 0x5C\u3002 \u4f8b\u5982 \u201c\u4fd3\u201d\uff0cGBK \u7f16\u7801 0x82 0x5C\uff0c\u8fd9\u4e2a\u5b57\u5c31\u53ef\u80fd\u88ab\u9519\u8bef\u89e3\u8bfb\u6210 \u201c\ufffd\\\u201d\uff0c\u4f7f\u7a0b\u5e8f\u8bef\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u6587\u4ef6\u5939\u7684\u8def\u5f84\uff0c\u4ece\u800c\u5bfc\u81f4\u7a0b\u5e8f\u51fa\u9519\uff0c\u6216\u7559\u4e0b\u88ab\u9ed1\u5ba2\u653b\u51fb\u7684\u9690\u60a3\u3002 \u867d\u7136 Windows \u7cfb\u7edf\u5185\u90e8\u7edf\u4e00\u91c7\u7528 Unicode\uff08UTF-16\uff09\u6765\u5b58\u50a8\u548c\u5904\u7406\u8def\u5f84\uff0c\u4f46\u603b\u67b6\u4e0d\u4f4f\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\uff0c\u4f9d\u7136\u6267\u7740\u4e8e ANSI\uff08GBK\uff09\uff0c\u5982\u679c\u7528\u6237\u65e0\u610f\u6216\u6076\u610f\u8f93\u5165\u201c\u4fd3\u554a.txt\u201d\uff0c\u5c31\u6709\u53ef\u80fd\u4ea7\u751f\u9690\u60a3\u3002 \u800c UTF-8 \u540c\u6837\u517c\u5bb9 ASCII\uff0c\u5f97\u76ca\u4e8e\u5197\u4f59\u7684\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u5c31\u6ca1\u6709\u8fd9\u6837\u7684\u95ee\u9898\u3002 \u201cGBK\u201d \u867d\u7136\u51a0\u4ee5\u201c\u56fd\u6807\u201d\u4e4b\u540d\uff0c\u4f46\u5b9e\u9645\u4e0a\u662f\u5fae\u8f6f\u64c5\u81ea\u63a8\u51fa\u7684\uff01\u6839\u672c\u4e0d\u662f\u4ec0\u4e48\u56fd\u5bb6\u6807\u51c6\uff08\u4f60\u731c\u4ed6\u4e3a\u4ec0\u4e48\u6ca1\u6709\u56fd\u5bb6\u6587\u4ef6\u7f16\u53f7\uff09\u3002\u672c\u6765\u6211\u56fd\u5b98\u65b9\u90fd\u6253\u7b97\u63a8\u51fa GB13000 \u4e86\uff0c\u76f4\u63a5\u5b8c\u5168\u517c\u5bb9 Unicode \u5b57\u7b26\u96c6\u3002\u7136\u800c\u5fae\u8f6f\u81ea\u4f5c\u4e3b\u5f20\u628a\u4ed6 Wendous \u7684 GB2312 \u5347\u7ea7\u5230 GBK\uff08\u6bd4\u5c14\u76d6\u5b50\u4ee5\u4e3a\u81ea\u5df1\u517c\u5bb9\u538b\u5012\u4e00\u5207\uff0c\u62fd\u6b7b\u4e86\uff09\uff0c\u672c\u6765\u597d\u597d\u7684 GB13000 \u6807\u51c6\u53ea\u597d\u4f5c\u7f62\u3002\u4e3a\u4e86\u517c\u5bb9\u5df2\u7ecf\u5347\u7ea7\u6210 GBK \u7684 Wendous \u7cfb\u7edf\uff0c\u56fd\u5bb6\u53ea\u597d\u91cd\u65b0\u5236\u4f5c\u4e86\u4e00\u4efd GB18030 \u6807\u51c6\uff0c\u517c\u5bb9 GBK \u548c GB2312\u3002 GB18030 \u4e8e 2000 \u5e74 3 \u6708\u53d1\u5e03\u7684\u6c49\u5b57\u7f16\u7801\u56fd\u5bb6\u6807\u51c6\uff0c\u5b8c\u5168\u517c\u5bb9 GBK \u548c GB2312\u3002 \u91c7\u7528\u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u53ef\u4ee5\u7f16\u7801\u4e3a 1 \u5b57\u8282\u30012 \u5b57\u8282\u3001\u6216 4 \u5b57\u8282\u3002 \u5176\u4e2d 1 \u5b57\u8282\u7684\u90e8\u5206\u53d6\u503c\u8303\u56f4\u662f 0 \u5230 0x7F\uff0c\u548c ASCII \u76f8\u540c\u3002 2 \u5b57\u8282\u7684\u90e8\u5206\u9996\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282\u8303\u56f4 0x40 \u5230 0xFE\uff0c\u548c GBK \u76f8\u540c\u3002 4 \u5b57\u8282\u7684\u90e8\u5206\u7b2c\u4e00\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u4e8c\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\uff0c\u7b2c\u4e09\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u56db\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\u3002 \u5b57\u7b26\u5904\u7406\u8f6f\u4ef6\u5728\u5904\u7406 GB18030 \u7684\u6587\u672c\u65f6\uff0c\u4ece\u5de6\u5f80\u53f3\u4f9d\u6b21\u626b\u63cf\u6bcf\u4e2a\u5b57\u8282\uff1a \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u53ea\u5360\u7528\u4e86\u4e00\u4e2a\u5b57\u8282 \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 1\uff0c\u90a3\u4e48\u8be5\u5b57\u7b26\u53ef\u80fd\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282\uff0c\u4e5f\u53ef\u80fd\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282\uff0c\u4e0d\u80fd\u5984\u4e0b\u65ad\u8bba\uff0c\u6240\u4ee5\u8fd8\u8981\u7ee7\u7eed\u5f80\u540e\u626b\u63cf\uff1a \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6709\u4e24\u4e2a\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282 \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6ca1\u6709\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282 \u5f53\u5b57\u7b26\u5360\u7528\u4e24\u4e2a\u6216\u8005\u56db\u4e2a\u5b57\u8282\u65f6\uff0cGB18030 \u7f16\u7801\u603b\u8981\u68c0\u6d4b\u4e24\u6b21\uff0c\u5904\u7406\u6548\u7387\u6bd4 GB2312 \u548c GBK \u90fd\u4f4e\u3002\u800c\u4e14\u548c GBK \u4e00\u6837\uff0c\u6709\u7740\u4e0d\u80fd\u81ea\u7ea0\u9519\uff0c\u5bb9\u6613\u4f7f\u7f16\u7801\u9519\u8bef\u8fde\u9501\u53cd\u5e94\u7684\u95ee\u9898\u3002 GB18030 \u7f16\u7801\u7a7a\u95f4\u5de8\u5927\uff0c\u4e0d\u4ec5\u56ca\u62ec\u4e86\u4e2d\u65e5\u97e9\u6c49\u5b57\uff0c\u6240\u6709 Unicode \u4e2d\u7684\u5b57\u7b26\u4e5f\u90fd\u88ab\u7eb3\u5165\u5176\u4e2d\uff01\u4e5f\u5c31\u662f\u8bf4\uff0cUnicode \u5b57\u7b26\u7528 GB18030 \u7f16\u7801\u662f\u65e0\u635f\u7684\uff0c\u548c UTF-8 \u4e00\u6837\uff0c\u800c\u4e14\u8fd8\u5b8c\u5168\u517c\u5bb9\u4e86 GBK\uff08\u4e2d\u56fd\u533a Windows \u7684\u9ed8\u8ba4\u7f16\u7801\uff09\u3002 \u6240\u4ee5\uff0cGB18030 \u5b57\u7b26\u7f16\u7801\u5bf9\u5e94\u7684\u5b57\u7b26\u96c6\u5b9e\u9645\u4e0a\u662f Unicode\u3002 \u5c3d\u7ba1\u5982\u6b64\uff0cWindows \u81f3\u4eca\uff08\u6211\u6d4b\u7684\u662f Win10\uff0c\u4e0d\u77e5\u9053 Win11 \u5b83\u4eec\u6539\u8fdb\u6ca1\u6709\uff09\u91c7\u7528\u7684\u4f9d\u7136\u662f GBK \u7f16\u7801\uff1a A \u7cfb API \u65e0\u6cd5\u6b63\u786e\u8bc6\u522b GB18030 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff0c\u6587\u4ef6\u8def\u5f84\u540d\u3002\u660e\u660e\u4e2d\u56fd\u653f\u5e9c\u90fd\u7ed9\u4f60\u505a\u5b8c\u5168\u517c\u5bb9\u4f60\u7684 GBK \u4e86\uff0c\u8fd8\u6536\u5f55\u6240\u6709 Unicode \u5b57\u7b26\u4e86\uff0c\u5b8c\u5168\u53ef\u4ee5\u65e0\u7f1d\u589e\u91cf\u5347\u7ea7\u7684\u4e1c\u897f\uff0c\u6ce5\u7801\u6c9f\u69fd\u7684\u6bd4\u5c14\u76d6\u5b50\u8fd8\u4e0d\u5feb\u70b9\u9ed8\u8ba4\u5207\u6362\u5230 GB18030\uff0c\u60f3\u4e0d\u901a\uff08\u81f4\u656c\u4f20\u5947\u9634\u4e95\u76d6\u6bd4\u5c14\u76d6\u5b50\uff09 \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801\u517c\u5bb9\u6027\uff1aUTF-8 != GB18030 > GBK > GB2312 > ASCII \u5b57\u7b26\u96c6\u5927\u5c0f\uff1aUnicode = GB18030 > GBK > GB2312 > ASCII \u603b\u4e4b\uff0cGB \u7cfb\u5217\u7f16\u7801\u9762\u5bf9\u5207\u7247\u548c\u67e5\u627e\u5b58\u5728\u4e00\u5b9a\u7684\u95ee\u9898\uff0c\u6709\u6761\u4ef6\u7684\u8bdd\uff0c\u5efa\u8bae Windows \u7a0b\u5e8f\u5c3d\u5feb\u5347\u7ea7\u5230 UTF-8 \u5916\u7801\u3001UTF-16 \u5185\u7801\u7684\u5de5\u4f5c\u6d41\u4e0a\u6765\uff0c\u56de\u907f\u6389\u53f2\u5c71\u7684\u5f71\u54cd\u3002 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u7c7b\u578b \u5927\u5c0f \u7f16\u7801 \u5b57\u9762\u91cf Linux char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e $LC_ALL \u201chello\u201d Windows char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e \u201chello\u201d Linux wchar_t 4 \u5b57\u8282 UTF-32 L\u201dhello\u201d Windows wchar_t 2 \u5b57\u8282 UTF-16LE L\u201dhello\u201d char8_t 1 \u5b57\u8282 UTF-8 u8\u201dhello\u201d char16_t 2 \u5b57\u8282 UTF-16 u\u201dhello\u201d char32_t 4 \u5b57\u8282 UTF-32 U\u201dhello\u201d \u7531\u6b64\u53ef\u89c1\uff0c char \u548c wchar_t \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f GBK\u3002\u5bf9\u4e8e\u7f8e\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\u3002 \u5bf9\u4e8e Linux \u7528\u6237\u6765\u8bf4\uff0c\u5982\u679c\u4f60\u6ca1\u6709\u4e13\u95e8\u4fee\u6539\u8fc7\uff0c $LC_ALL \u9ed8\u8ba4\u662f en_US.UTF-8 \u6216 C.UTF-8 \u3002 \u8fd9\u5e26\u6765\u4e86\u5de8\u5927\u7684\u6df7\u6dc6\uff01\u5f88\u591a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u6f5c\u610f\u8bc6\u91cc\u4f1a\u60f3\u5f53\u7136\u5730\u628a char \u5f53\u4f5c UTF-8 \u6765\u7528\u3002\u5f88\u591a\u5f00\u6e90\u9879\u76ee\uff0c\u7b2c\u4e09\u65b9\u5e93\uff0c\u751a\u81f3\u5f88\u591a\u56fd\u4eba\u505a\u7684\u9879\u76ee\uff0c\u90fd\u88ab\u8fd9\u79cd\u201c\u60f3\u5f53\u7136\u201d\u4f20\u67d3\u4e86\u3002 \u597d\u6d88\u606f\u662f\u65e0\u8bba\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u662f\u4ec0\u4e48\uff0c\u80af\u5b9a\u517c\u5bb9 ASCII\u3002\u4f8b\u5982 GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u5426\u5219\u5c31\u548c\u6240\u6709\u7684 C \u8bed\u8a00\u7ecf\u5178\u51fd\u6570\u5982 strlen \uff0c\u6362\u884c\u7b26 '\\n' \uff0c\u8def\u5f84\u5206\u9694\u7b26 '/' \u548c '\\\\' \u51b2\u7a81\u4e86\u3002 wchar_t \u5c31\u597d\u4e00\u4e9b\uff0c\u867d\u7136\u5728 Windows \u7cfb\u7edf\u4e0a\u662f\u7cdf\u7cd5\u7684 UTF-16\uff0c\u4f46\u81f3\u5c11\u7a33\u5b9a\u4e86\uff0c\u4e0d\u4f1a\u968f\u7740\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u800c\u968f\u610f\u6539\u53d8\uff0c\u53ea\u8981\u4f60\u4e0d\u6253\u7b97\u8de8\u5e73\u53f0\uff0c wchar_t \u5c31\u662f Windows \u7a0b\u5e8f\u7684\u6807\u914d\u3002 \u6839\u636e Windows \u5b98\u65b9\u6587\u6863\u7684\u8bf4\u6cd5\uff0c wchar_t \u662f UTF-16LE\u3002 \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u7684\u706b\u8f66\u5934\u548c\u8f66\u53a2\uff0c\u90fd\u662f 1 \u5f00\u5934\u7684\uff0c\u800c ASCII \u7684\u5355\u4f53\u706b\u8f66\u5934\u6c38\u8fdc\u662f 0 \u5f00\u5934\u3002\u8fd9\u5f88\u91cd\u8981\uff0c\u4e0d\u4ec5\u706b\u8f66\u5934\u9700\u8981\u548c ASCII \u533a\u5206\u5f00\u6765\uff0c\u8f66\u53a2\u4e5f\u9700\u8981\u3002\u8003\u8651\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff1a std::u32string path = \"\u4e00\u4e2a\u8001\u4f2f.txt\"; \u201c\u4e00\u4e2a\u8001\u4f2f\u201d \u8f6c\u6362\u4e3a Unicode \u7801\u70b9\u5206\u522b\u662f\uff1a 0x4E00 0x4E2A 0x8001 0x4F2F \u5982\u679c\u8ba9\u4ed6\u4eec\u539f\u5c01\u4e0d\u52a8\u76f4\u63a5\u5b58\u50a8\u8fdb char \u6570\u7ec4\u91cc\uff1a 0x4E 0x00 0x4E 0x2A 0x80 0x01 0x4F 0x2F \u5c31\u51fa\u95ee\u9898\u4e86\uff01\u9996\u5148\uff0c\u8fd9\u91cc 0x4E00 \u7684 0x00 \u90e8\u5206\uff0c\u4f1a\u88ab C \u8bed\u8a00\u5f53\u4f5c\u662f\u5b57\u7b26\u4e32\u7684\u7ed3\u5c3e\u3002\u5982\u679c\u62ff\u8fd9\u6837\u7684\u5b57\u7b26\u4e32\u53bb\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u7684 open \u51fd\u6570\uff0c\u4ed6\u4f1a\u4ee5\u4e3a\u4f60\u5728\u6253\u5f00 0x4E \u5355\u4e2a\u5b57\u7b26\u7684\u6587\u4ef6\u540d\uff0c\u4e5f\u5c31\u662f \"N\" \u3002 \u66f4\u7cdf\u7cd5\u7684\u662f\uff0c0x2F \u5bf9\u5e94\u7684 ASCII \u5b57\u7b26\u662f '/' \uff0c\u662f\u8def\u5f84\u5206\u9694\u7b26\u3002\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u4ee5\u4e3a\u4f60\u8981\u521b\u5efa\u4e00\u4e2a\u5b50\u6587\u4ef6\u5939\u4e0b\u7684\u6587\u4ef6 \"N\\x00N*\\x80\\x01O/.txt\" \uff0c\u6587\u4ef6\u5939\u540d\u5b57\u53eb \"N\\x00N*\\x80\\x01O\" \u800c\u6587\u4ef6\u53eb \".txt\" \u3002 \u4e3a\u4e86\u80fd\u8ba9\u9488\u5bf9 ASCII \u8bbe\u8ba1\u7684\u64cd\u4f5c\u7cfb\u7edf API \u652f\u6301\u4e2d\u6587\u6587\u4ef6\u540d\uff0c\u5c31\u53ea\u80fd\u7ed5\u5f00\u6240\u6709 0x7F \u4ee5\u4e0b\u7684\u503c\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 UTF-8 \u5bf9\u8f66\u53a2\u4e5f\u5168\u90e8\u62ac\u9ad8\u5230 0x80 \u4ee5\u4e0a\uff0c\u907f\u514d\u64cd\u4f5c\u7cfb\u7edf\u4e0d\u614e\u628a\u8f66\u53a2\u5f53\u4f5c\u662f '/' \u6216 '\\0' \u3002 UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u7531\u4e8e\u5de8\u5927\u7684\u60ef\u6027\uff0c\u5f88\u591a\u4eba\u90fd\u60f3\u5f53\u7136\u7684\u628a std::string \u5f53\u4f5c UTF-8 \u6765\u4f7f\u7528\u3002\u5bf9\u4e8e\u7b80\u5355\u7684\u6253\u5370\uff0c\u5e38\u89c4\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u5b57\u7b26\u4e32\u64cd\u4f5c\u6709\u4e0b\u9762\u8fd9\u51e0\u79cd\uff0c\u5f97\u76ca\u4e8e UTF-8 \u4f18\u79c0\u7684\u5e8f\u5217\u5316\u6d89\u53ca\u548c\u5197\u4f59\u6297\u5e72\u6270\u673a\u5236\uff0c\u7edd\u5927\u591a\u6570 ASCII \u652f\u6301\u7684\u64cd\u4f5c\uff0cUTF-8 \u5b57\u7b26\u4e32\u90fd\u80fd\u8f7b\u677e\u80dc\u4efb\uff0c\u552f\u72ec\u5176\u4e2d \u6d89\u53ca\u201c\u7d22\u5f15\u201d\u548c\u201c\u957f\u5ea6\u201d\u7684 \u4e00\u90e8\u5206\u64cd\u4f5c\u4e0d\u884c\u3002\u8fd9\u662f\u7531\u4e8e\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff0c\u5982\u679c\u9700\u8981\u505a\u201c\u7d22\u5f15\u201d\u7c7b\u64cd\u4f5c\uff0c\u8fd8\u662f\u5efa\u8bae\u5148\u8f6c\u6362\u6210\u5b9a\u957f\u7684 UTF-32 \u7f16\u7801\u3002 \u64cd\u4f5c UTF-8 UTF-32 GBK \u6c42\u5b57\u7b26\u4e32\u957f\u5ea6 \u00d7 \u221a \u00d7 \u5224\u65ad\u76f8\u7b49 \u221a \u221a \u221a \u5b57\u5178\u5e8f\u7684\u5927\u5c0f\u6bd4\u8f83 \u221a \u221a \u00d7 \u5b57\u7b26\u4e32\u62fc\u63a5 \u221a \u221a \u221a \u641c\u7d22\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u641c\u7d22\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u4e0b\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u83b7\u53d6\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u904d\u5386\u6240\u6709\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u5b50\u5b57\u7b26\u4e32\u5207\u7247 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u7247 \u00d7 \u221a \u00d7 \u67e5\u627e\u5e76\u66ff\u6362\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u67e5\u627e\u5e76\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u5220\u9664\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u4e3a\u4ec0\u4e48\uff1f\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u5b9e\u9a8c\uff1a std::string s = \"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \uff08\u4f7f\u7528 /utf-8 \u7f16\u8bd1\uff09\u8fd0\u884c\u540e\uff0c\u4f1a\u5f97\u5230 6\u3002 \u56e0\u4e3a std::string \u7684 size() \u8fd4\u56de\u7684\u662f char \u7684\u6570\u91cf\uff0c\u800c\u4e0d\u662f\u771f\u6b63\u5b57\u7b26\u7684\u6570\u91cf\u3002\u5728 UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u975e ASCII \u7684\u5b57\u7b26\u4f1a\u88ab\u7f16\u7801\u4e3a\u591a\u4e2a char \uff0c\u5bf9\u4e8e\u4e2d\u6587\u800c\u8a00\uff0c\u4e2d\u6587\u90fd\u5728 0x2E80 \u5230 0x9FFF \u8303\u56f4\u5185\uff0c\u5c5e\u4e8e\u4e09\u7ea7\u5217\u8f66\uff0c\u4e5f\u5c31\u662f\u6bcf\u4e2a\u6c49\u5b57\u4f1a\u88ab\u7f16\u7801\u6210 3 \u4e2a char \u3002 char \u662f\u5b57\u8282\uff08\u7801\u4f4d\uff09\u800c\u4e0d\u662f\u771f\u6b63\u7684\u5b57\u7b26\uff08\u7801\u70b9\uff09\u3002\u771f\u6b63\u7684 Unicode \u5b57\u7b26\u5e94\u8be5\u662f char32_t \u7c7b\u578b\u7684\u3002\u8c03\u7528 std::string \u7684 size() \u6216\u8005 strlen \u5f97\u5230\u7684\u53ea\u662f\u201c\u5b57\u8282\u6570\u91cf\u201d\u3002 \u800c UTF-32 \u4e2d\uff0c\u6bcf\u4e2a\u5b57\u7b26\uff08\u7801\u70b9\uff09\u90fd\u5bf9\u5e94\u4e00\u4e2a\u72ec\u7acb\u7684 char32_t \uff08\u7801\u4f4d\uff09\uff0c size() \u5c31\u662f\u771f\u6b63\u7684\u201c\u5b57\u7b26\u6570\u91cf\u201d\uff0c\u8fd9\u5c31\u662f\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 std::u32string s = U\"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \u5982\u679c\u4f60\u7684\u64cd\u4f5c\u53ea\u6d89\u53ca\u5b57\u7b26\u4e32\u67e5\u62fc\u63a5\u4e0e\u67e5\u627e\uff0c\u90a3\u5c31\u53ef\u4ee5\u7528 UTF-8\u3002\u5982\u679c\u5927\u91cf\u6d89\u53ca\u7d22\u5f15\uff0c\u5207\u7247\uff0c\u5355\u4e2a\u5b57\u7b26\u7684\u64cd\u4f5c\uff0c\u90a3\u5c31\u5fc5\u987b\u7528 UTF-32\uff08\u5426\u5219\u4e00\u9047\u5230\u6c49\u5b57\u5c31\u4f1a\u51fa\u9519\uff09\u3002 std::vector slogan = { \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\", \"\u5168\u4e16\u754c\u7a0b\u5e8f\u5458\u5927\u56e2\u7ed3\u4e07\u5c81\", }; std::string joined; for (auto const &s: slogan) { joined += s; // \u53ea\u662f\u62fc\u63a5\u800c\u5df2\uff0cUTF-8 \u6ca1\u95ee\u9898 } UTF-8 \u6309\u7d22\u5f15\u5207\u7247\u7684\u51fa\u9519\u6848\u4f8b\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-8 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u8282\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\ufffd\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-32 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u7b26\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u53ea\u6709\u5f53\u7d22\u5f15\u662f\u6765\u81ea find \u7684\u7ed3\u679c\u65f6\uff0cUTF-8 \u5b57\u7b26\u4e32\u7684\u5207\u7247\u624d\u80fd\u6b63\u5e38\u5de5\u4f5c\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(\"\u516c\"); // pos = 12 fmt::println(\"UTF-8 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u8282\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(U'\u516c'); // pos = 4 fmt::println(\"UTF-32 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u7b26\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u6ce8\u610f\u5230\u8fd9\u91cc UTF-8 \u7684 \"\u516c\" \u9700\u8981\u662f\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u5b57\u7b26\u3002 UTF-8 \u65e0\u6cd5\u53d6\u51fa\u5355\u4e2a\u975e ASCII \u5b57\u7b26\uff0c\u5bf9\u4e8e\u5355\u4e2a\u4e2d\u6587\u5b57\u7b26\uff0c\u4ecd\u7136\u53ea\u80fd\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u8868\u8fbe\uff08\u7531\u591a\u4e2a\u5b57\u8282\u7ec4\u6210\uff09\u3002 std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-8 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u8282\uff1a{}\", s[0]); // \u53ef\u80fd\u4f1a\u6253\u5370 \u2018\u00e5\u2019 (0xE5)\uff0c\u56e0\u4e3a\u201c\u5c0f\u201d\u7684 UTF-8 \u7f16\u7801\u662f 0xE5 0xB0 0x8F // \u4e5f\u53ef\u80fd\u662f\u4e71\u7801\u201c\ufffd\u201d\uff0c\u53d6\u51b3\u4e8e\u7ec8\u7aef\u7406\u89e3\u7684\u7f16\u7801\u683c\u5f0f std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-32 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u7b26\uff1a{}\", s[0]); // \u4f1a\u6253\u5370 \u2018\u5c0f\u2019 UTF-8 \u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\u4e5f\u4f1a\u51fa\u95ee\u9898\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u4e71\u7801 std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u628a\u6309\u5b57\u7b26\u6b63\u5e38\u53cd\u8f6c\uff0c\u5f97\u5230 \u201c\u5c81\u4e07\u8bfe\u5f00\u516c\u5e08\u8001\u5f6d\u5c0f\u201d \u603b\u7ed3\uff1aUTF-8 \u53ea\u80fd\u62fc\u63a5\u3001\u67e5\u627e\u3001\u6253\u5370\u3002\u4e0d\u80fd\u7d22\u5f15\u3001\u5207\u7247\u3001\u53cd\u8f6c\u3002 \u6309\u7d22\u5f15\u5207\u7247\u4e0d\u884c\uff0c\u4f46\u5982\u679c\u7d22\u5f15\u662f find \u51fa\u6765\u7684\u5c31\u6ca1\u95ee\u9898\u3002 \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5728 Windows \u5b98\u65b9\u7684\u8bf4\u8f9e\u4e2d\uff0c\u6709\u201cUnicode \u7f16\u7801\u201d\u548c\u201cANSI \u7f16\u7801\u201d\u7684\u8bf4\u6cd5\u3002\u5f53\u4f60\u4f7f\u7528 Windows \u81ea\u5e26\u7684\u8bb0\u4e8b\u672c\u7a0b\u5e8f ( notepad.exe ) \u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u65f6\uff0c\u5c31\u4f1a\u770b\u5230\u8fd9\u6837\u7684\u9009\u5355\uff1a \u7ffb\u8bd1\u4e00\u4e0b\uff1a \u201cANSI\u201d\u6307\u7684\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u8bbe\u7f6e\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\u3002 \u6240\u8c13\u201cUnicode\u201d\u5176\u5b9e\u6307\u7684\u662f UTF-16\u3002 \u6240\u8c13\u201cUnicode big endian\u201d\u6307\u7684\u662f\u5927\u7aef UTF-16\u3002 \u201cUTF-8\u201d\u6307\u7684\u662f UTF-8 with BOM \u800c\u4e0d\u662f\u6b63\u5e38\u7684 UTF-8\u3002 \u5b9e\u9645\u4e0a Unicode \u53ea\u662f\u4e00\u4e2a\u5b57\u7b26\u96c6\uff0c\u53ea\u662f\u628a\u5b57\u7b26\u6620\u5c04\u5230\u6574\u6570\uff0c\u66f4\u6ca1\u6709\u4ec0\u4e48\u5927\u7aef\u5c0f\u7aef\uff0cUTF-16 \u624d\u662f\u7f16\u7801\u683c\u5f0f\u3002 \u800c ANSI \u672c\u6765\u5e94\u8be5\u662f ASCII \u7684\u610f\u601d\uff0c char \u672c\u6765\u5c31\u53ea\u652f\u6301 ASCII\u3002 \u4f46\u7531\u4e8e\u5f53\u65f6\u5404\u56fd\u8feb\u5207\u9700\u8981\u652f\u6301\u81ea\u5df1\u672c\u56fd\u7684\u6587\u5b57\uff0c\u5c31\u5728\u517c\u5bb9 ASCII \u7684\u57fa\u7840\u4e0a\uff0c\u53d1\u5c55\u51fa\u4e86\u81ea\u5df1\u7684\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u3002\u8fd9\u4e9b\u5f53\u5730\u7279\u4f9b\u7684\u5b57\u7b26\u96c6\u91cc\u53ea\u5305\u542b\u4e86\u672c\u56fd\u6587\u5b57\uff0c\u6240\u6709\u8fd9\u4e9b\u5404\u56fd\u7684\u5b57\u7b26\u7f16\u7801\u4e5f\u90fd\u548c UTF-8 \u7c7b\u4f3c\uff0c\u91c7\u7528\u706b\u8f66\u5934\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0c\u5bf9 0 \u5f00\u5934\u7684 ASCII \u90e8\u5206\u4e5f\u90fd\u662f\u517c\u5bb9\u3002\u6240\u4ee5 Windows \u7d22\u6027\u628a ANSI \u5f53\u4f5c\u201c\u5404\u56fd\u672c\u5730\u6587\u5b57\u7f16\u7801\u201d\u7684\u7b80\u79f0\u4e86\u3002\u4f46\u540e\u6765\u4e92\u8054\u7f51\u7684\u51fa\u73b0\uff0c\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u5e26\u6765\u4e86\u5de8\u5927\u7684\u4fe1\u606f\u4ea4\u6362\u56f0\u96be\u3002 \u4f8b\u5982\u4f60\u5728\u73a9\u4e00\u4e9b\u65e5\u672c\u7684 galgame \u65f6\uff0c\u4f1a\u53d1\u73b0\u91cc\u9762\u6587\u5b57\u5168\u90e8\u4e71\u7801\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u5728\u5404\u4e2a\u5730\u533a\u53d1\u884c\u7684\u662f\u201c\u7279\u4f9b\u7248\u201d\uff1a\u5728\u4e2d\u56fd\u5927\u9646\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 GBK \u5b57\u7b26\u96c6\uff0c\u5728\u65e5\u672c\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 Shift-JIS \u5b57\u7b26\u96c6\u3002\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u7a0b\u5e8f\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u5b58\u50a8\u7684\u662f Shift-JIS \u7684\u90a3\u4e9b\u201c\u6574\u6570\u201d\u3002\u8fd9\u5bfc\u81f4\u65e5\u672c\u7684 galgame \u5728\u4e2d\u56fd\u5927\u9646\u7279\u4f9b\u7684 Windows \u4e2d\uff0c\u628a Shift-JIS \u7684\u201c\u6574\u6570\u201d\u7528 GBK \u7684\u8868\u6765\u89e3\u8bfb\u4e86\uff0c\u4ece\u800c\u4e71\u7801\uff08GBK \u91cc\u7684\u65e5\u6587\u533a\u57df\u5e76\u6ca1\u6709\u548c Shift-JIS \u91cd\u53e0\uff09\u3002\u9700\u8981\u7528 Locale Emulator \u628a Shift-JIS \u7ffb\u8bd1\u6210 Unicode \u8bfb\u7ed9 Windows \u542c\u3002\u5982\u679c\u65e5\u672c\u7a0b\u5e8f\u5458\u4ece\u4e00\u5f00\u59cb\u5c31\u7edf\u4e00\u7528 Unicode \u6765\u5b58\u50a8\uff0c\u4e2d\u56fd\u533a\u73a9\u5bb6\u7684 Windows \u4e5f\u7edf\u4e00\u7528 Unicode \u89e3\u6790\uff0c\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cUnicode \u7ec4\u7ec7\u51fa\u73b0\u4e86\uff0c\u4ed6\u7684\u4f7f\u547d\u5c31\u662f\u7edf\u4e00\u5168\u4e16\u754c\u7684\u5b57\u7b26\u96c6\uff0c\u4fdd\u8bc1\u5168\u4e16\u754c\u6240\u6709\u7684\u6587\u5b57\u90fd\u80fd\u5728\u5168\u4e16\u754c\u6240\u6709\u7684\u8ba1\u7b97\u673a\u4e0a\u663e\u793a\u51fa\u6765\u3002\u9996\u5148\u521b\u529e\u4e86 Unicode \u5b57\u7b26\u96c6\uff0c\u7136\u540e\u89c4\u5b9a\u4e86 UTF-8\u3001UTF-16\u3001UTF-32 \u4e09\u79cd\u5b57\u7b26\u7f16\u7801\uff0c\u6700\u7ec8 UTF-8 \u6210\u4e3a\u5916\u7801\u7684\u4e3b\u6d41\uff0cUTF-32 \u6210\u4e3a\u5185\u7801\u7684\u4e3b\u6d41\u3002 \u63a5\u4e0b\u6765\u4e3a\u4e86\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u6211\u4eec\u7d22\u6027\u5c31\u987a\u7740\u5fae\u8f6f\u7684\u8fd9\u4e2a\u8bf4\u6cd5\uff1a \u7ba1 char \u53eb ANSI\uff1a\u968f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002 \u7ba1 wchar_t \u53eb Unicode\uff1a\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u5728 Linux \u4e0a\u662f UTF-32\u3002 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5fae\u8f6f\u7ba1 UTF-16 \u53eb Unicode \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u95ee\u9898\uff1a \u56e0\u4e3a\u5f53\u5e74 Unicode 5.0 \u7684\u65f6\u5019\u53ea\u6709 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff0c16 \u4f4d\u5c31\u88c5\u5f97\u4e0b\uff0c\u6240\u4ee5\u5f53\u65f6 UTF-16 \u8fd8\u662f\u4e00\u4e2a \u5b9a\u957f\u7f16\u7801 \u3002\u5fae\u8f6f\u4e8e\u662f\u51b3\u5b9a\u628a wchar_t \u5b9a\u4e49\u6210 2 \u5b57\u8282\uff0c\u5e76\u5728 NT \u5185\u6838\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u7cfb\u7edf\u8c03\u7528\u90fd\u5347\u7ea7\u6210\u4e86\u57fa\u4e8e wchar_t \u5b57\u7b26\u4e32\u7684 \u201cW \u7cfb\u201d API\u3002 \u6bd4\u5c14\u76d6\u5b50\u5f53\u65f6\u4ee5\u4e3a\u8fd9\u6837 UTF-16 \u5b9a\u957f\u5185\u7801\u5c31\u4e00\u52b3\u6c38\u9038\u4e86\uff0c\u5e76\u53f7\u53ec\u6240\u6709\u7a0b\u5e8f\u90fd\u6539\u7528 UTF-16 \u505a\u5185\u7801\uff0c\u522b\u7528 \u201cA \u7cfb\u201d API \u4e86\u3002 \u8d77\u521d\uff0c\u6240\u6709\u4eba\u90fd\u4ee5\u4e3a UTF-16 \u5c31\u662f\u6700\u7ec8\u7b54\u6848\u3002 \u6ca1\u60f3\u5230\u540e\u6765 Unicode \u59d4\u5458\u4f1a\u201c\u80cc\u523a\u201d\u4e86\u6bd4\u5c14\u76d6\u5b50\uff01\u5077\u5077\u628a\u8303\u56f4\u66f4\u65b0\u5230\u4e86 0x10FFFF\uff0c\u7a81\u7834\u4e86 16 \u4f4d\u6574\u6570\u7684\u5bb9\u91cf\u3002\u539f\u6765\u7684 UTF-16 \u5df2\u7ecf\u5bb9\u7eb3\u4e0d\u4e0b\uff0c\u53ea\u597d\u5229\u7528\u4e4b\u524d\u9884\u7559\u7684 0xD800 \u5230 0xDFFF \u7a7a\u53f7\u533a\u95f4\u4e11\u964b\u5730\u5b9e\u73b0\u4e86\u53d8\u957f\u7f16\u7801\u3002 \u76f4\u5230 UTF-16 \u4e00\u591c\u4e4b\u95f4\u6210\u4e86\u4e11\u964b\u7684 \u53d8\u957f\u7f16\u7801 \u3002 \u95f9\u4e86\u534a\u5929\uff0cWindows \u8d39\u5fc3\u8d39\u529b\u66ff Unicode \u59d4\u5458\u4f1a\u597d\u4e0d\u5bb9\u6613\u63a8\u5e7f\u7684 wchar_t \uff0c\u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801 \u7684\u597d\u5904\u3002\u53ef \u201cW \u7cfb\u201d API \u5374\u53c8\u710a\u6b7b\u5728\u4e86 NT \u5185\u6838\u6700\u5e95\u5c42\uff0c\u53cd\u590d\u6765\u5751\u7b2c\u4e00\u6b21\u7528 Windows \u7f16\u7a0b\u7684\u521d\u5b66\u8005\u3002 \u6bd4\u5c14\u76d6\u5b50\uff1a\u4f60\u8fd9\u6837\u663e\u5f97\u6211\u5f88\u5c0f\u4e11\u8bf6\uff1f \u9664 Windows \u5916\uff0cJava \u4e5f\u662f\u201cUTF-16 \u80cc\u523a\u201d\u7684\u53d7\u5bb3\u8005\uff0c\u4ed6\u4eec\u60f3\u5f53\u7136\u7684\u628a char \u5b9a\u4e49\u4e3a UTF-16\uff0c\u4ee5\u4e3a\u8fd9\u5c31\u662f\u672a\u6765\u6c38\u4e45\u7684\u5b9a\u957f\u5185\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u2026\u2026 \u76f4\u5230 Unicode \u52a0\u5165\u4e86 0x10FFFF\uff0cJava \u4e0d\u5f97\u4e0d\u91cd\u65b0\u5b9a\u4e49\u4e86\u4e2a Character \u4f5c\u4e3a UTF-32 \u5b57\u7b26\uff0c\u8fd8\u5f04\u4e2a char \u5230 Character \u7684\u8f6c\u6362\uff0c\u597d\u4e0d\u5c34\u5c2c\uff01 Linux \u6210\u7acb\u4e8e 1991 \u5e74\uff0c\u5f53\u65f6 Unicode \u4e5f\u624d\u521a\u521a\u51fa\u73b0\u3002Unicode \u5ba3\u5e03\u52a0\u5165 0x10FFFF \u540e\uff0cLinux \u624d\u5f00\u59cb\u5f15\u5165\u652f\u6301 Unicode\u3002\u5728\u77e5\u9053\u4e86 Unicode \u5305\u542b 0x10FFFF \u540e\uff0c\u4ed6\u4eec\u4e00\u5f00\u59cb\u5c31\u628a wchar_t \u5b9a\u4e49\u6210 4 \u5b57\u8282\uff0c\u9003\u8fc7\u4e86 UTF-16 \u7684\u80cc\u523a\u3002 \u540e\u6765\u65b0\u51fa\u7684\u8bed\u8a00\uff0c\u5982 Python 3\u3001Go\u3001Rust\u3001Swift\u3001Kotlin\uff0c\u628a\u5b57\u7b26\u94a6\u5b9a\u4e3a UTF-32 \u4e86\u3002\u4ed6\u4eec\u53ea\u6709\u5728\u8c03\u7528 Windows API \u65f6\uff0c\u624d\u4f1a\u4e34\u65f6\u8f6c\u6362\u4e3a UTF-16 \u6765\u8c03\u7528\uff0c\u9664\u6b64\u4e4b\u5916\u518d\u65e0 UTF-16 \u51fa\u73b0\u3002 \u8bb8\u591a\u7cdf\u7cd5\u7684\u535a\u5ba2\u58f0\u79f0\uff1a\u662f\u56e0\u4e3a\u201cUTF-16 \u6700\u6709\u5229\u4e8e\u4e2d\u6587\u538b\u7f29\u201d\uff0c\u6240\u4ee5 Java \u548c Windows \u624d\u91c7\u7528\u7684\uff1f\u7136\u800c\u5c31\u6211\u4e86\u89e3\u5230\u7684\u5b9e\u9645\u60c5\u51b5\u662f\u56e0\u4e3a\u4ed6\u4eec\u9519\u8bef\u7684\u4ee5\u4e3a 0xFFFF \u662f Unicode \u7684\u4e0a\u9650\u624d\u9519\u8bef\u91c7\u7528\u4e86\uff0c\u4e0d\u7136\u4e3a\u4ec0\u4e48\u540e\u6765\u7684\u65b0\u8bed\u8a00\u90fd\u91c7\u7528\u4e86 UTF-32 \u5185\u7801 + UTF-8 \u5916\u7801\u7684\u7ec4\u5408\uff1f\u800c\u4e14\u5728\u5916\u7801\u4e2d\u91c7\u7528 UTF-8 \u6216 UTF-16 \u538b\u7f29\u786e\u5b9e\u6ca1\u95ee\u9898\uff0c\u4f46\u662f Java \u548c Windows \u7684\u5931\u8bef\u5728\u4e8e\u628a UTF-16 \u5f53\u4f5c\u5185\u7801\u4e86\uff01\u5185\u7801\u5c31\u7406\u5e94\u662f\u5b9a\u957f\u7f16\u7801\u7684\u624d\u65b9\u4fbf\uff0c\u5982\u679c\u4f60\u6709\u4e0d\u540c\u60f3\u6cd5\uff0c\u6b22\u8fce\u7559\u8a00\u8ba8\u8bba\u3002 \u603b\u4e4b\uff0cUTF-16 \u662f\u7cdf\u7c95\uff0c\u4f46\u4ed6\u662f Windows \u552f\u4e00\u5b8c\u6574\u652f\u6301\u7684 Unicode \u63a5\u53e3\u3002\u4e0d\u5efa\u8bae\u8f6f\u4ef6\u5185\u90e8\u7528 UTF-16 \u5b58\u50a8\u6587\u5b57\uff0c\u4f60\u53ef\u4ee5\u7528\u66f4\u7d27\u51d1\u7684 UTF-8 \u6216\u66f4\u65b9\u4fbf\u5207\u7247\u7684 UTF-32\uff0c\u53ea\u9700\u5728\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u524d\u4e34\u65f6\u8f6c\u6362\u6210 UTF-16 \u5c31\u884c\u3002 \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u5fc5\u987b\u6307\u51fa\uff1a\u5728 std::string \u4e2d\u88c5 UTF-8 \u5e76\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5728 std::u8string \u91cc\u540c\u6837\u53ef\u4ee5\u88c5 GBK\u3002\u8fd9\u5c31\u597d\u6bd4\u4e00\u4e2a\u540d\u53eb Age \u7684\u679a\u4e3e\u7c7b\u578b\uff0c\u5b9e\u9645\u5374\u88c5\u7740\u6027\u522b\u4e00\u6837\u3002 enum Age { // \u9519\u8bef\u793a\u8303 Male, Female, Custom, }; // \u9664\u4e86\u8ff7\u60d1\u540c\u4e8b\u5916\uff0c\u628a\u5e74\u9f84\u548c\u6027\u522b\u7684\u7c7b\u578b\u6df7\u7528\u6ca1\u6709\u597d\u5904 void registerStudent(Age age, Age sex); \u533a\u5206\u7c7b\u578b\u53ea\u662f\u5927\u591a\u6570\u4eba\u8bbe\u8ba1\u63a5\u53e3\u7684\u89c4\u8303\uff0c\u53ea\u662f\u65b9\u4fbf\u4f60\u901a\u8fc7\u770b\u51fd\u6570\u63a5\u53e3\u4e00\u773c\u533a\u5206\u8fd9\u4e2a\u51fd\u6570\u63a5\u53d7\u7684\u662f\u4ec0\u4e48\u683c\u5f0f\u7684\u5b57\u7b26\u4e32\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u6027\u3002\u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4e00\u770b\u5c31\u77e5\u9053\u8fd9\u4e9b\u51fd\u6570\u9700\u8981\u7684\u662f\u4ec0\u4e48\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 void thisFuncAcceptsANSI(std::string msg); void thisFuncAcceptsUTF8(std::u8string msg); void thisFuncAcceptsUTF16(std::u16string msg); void thisFuncAcceptsUnicode(std::wstring msg); void thisFuncAcceptsUTF32(std::u32string msg); \u6ca1\u6709 char8_t \u4e4b\u524d\uff0c\u7528\u7c7b\u578b\u522b\u540d\u540c\u6837\u53ef\u4ee5\u8d77\u5230\u5dee\u4e0d\u591a\u7684\u8bf4\u660e\u6548\u679c\uff08\u7f3a\u70b9\u662f\u65e0\u6cd5\u91cd\u8f7d\uff09\uff1a using ANSIString = std::string; using UTF8String = std::string; using UTF16String = std::vector; void thisFuncAcceptsANSI(ANSIString msg); void thisFuncAcceptsUTF8(UTF8String msg); void thisFuncAcceptsUTF16(UTF16String msg); \u4e4b\u6240\u4ee5\u6211\u4f1a\u8bf4\uff0c std::string \u5e94\u8be5\u88c5 ANSI \u5b57\u7b26\u4e32\uff0c\u662f\u56e0\u4e3a\u6240\u6709\u6807\u51c6\u5e93\u5b98\u65b9\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u4f1a\u5047\u5b9a std::string \u7c7b\u578b\u662f ANSI \u7f16\u7801\u683c\u5f0f\uff08GBK\uff09\u3002\u5e76\u4e0d\u662f\u8bf4\uff0c\u4f60\u4e0d\u80fd\u7528 std::string \u5b58\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\u7684\u5185\u5bb9\u3002 \u5982\u679c\u4f60\u5c31\u662f\u60f3\u7528 std::string \u88c5 UTF-8 \u4e5f\u53ef\u4ee5\uff0c\u53ea\u4e0d\u8fc7\u4f60\u8981\u6ce8\u610f\u5728\u4f20\u5165\u6240\u6709\u4f7f\u7528\u4e86\u6587\u4ef6\u8def\u5f84\u7684\u51fd\u6570\uff0c\u5982 fopen \uff0c std::ifstream \u7684\u6784\u9020\u51fd\u6570\u524d\uff0c\u9700\u8981\u505a\u4e00\u4e2a\u8f6c\u6362\uff0c\u8f6c\u6210 GBK \u7684 std::string \u6216 UTF-16 \u7684 std::wstring \u540e\uff0c\u624d\u80fd\u4f7f\u7528\uff0c\u5f88\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u5982\u679c\u4f60\u59cb\u7ec8\u7528 std::u8string \u88c5 UTF-8\uff0c\u90a3\u4e48\u5f53\u4f60\u628a\u5b83\u8f93\u5165\u4e00\u4e2a\u63a5\u53d7 ANSI \u7684\u666e\u901a std::string \u53c2\u6570\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7c7b\u578b\u4e0d\u5339\u914d\u9519\u8bef\uff0c\u5f3a\u8feb\u4f60\u91cd\u65b0\u6e05\u9192\uff0c\u6216\u662f\u5f3a\u8feb\u4f60\u4f7f\u7528\u4e00\u4e2a\u8f6c\u6362\u51fd\u6570\uff0c\u7a0d\u540e\u4f1a\u4ecb\u7ecd\u8fd9\u4e2a\u8f6c\u6362\u51fd\u6570\u7684\u5199\u6cd5\u3002 \u4f8b\u5982\u5f53\u4f60\u4f7f\u7528 std::cout << u8string \u65f6\u4f1a\u62a5\u9519\uff0c\u8feb\u4f7f\u4f60\u6539\u4e3a std::cout << u8toansi(u8string) \u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff0c\u4ece\u800c\u907f\u514d\u4e86\u628a UTF-8 \u7684\u5b57\u7b26\u4e32\u6253\u5370\u5230\u4e86\u53ea\u652f\u6301 GBK \u7684\u63a7\u5236\u53f0\u4e0a\u3002 \u5176\u4e2d\u8f6c\u6362\u51fd\u6570\u7b7e\u540d\u4e3a std::string u8toansi(std::u8string s) \uff0c\u5f88\u53ef\u60dc\uff0c\u6807\u51c6\u5e93\u5e76\u6ca1\u6709\u63d0\u4f9b\u8fd9\u4e2a\u51fd\u6570\uff0c\u76f4\u5230 C++26 \u524d\uff0c\u6807\u51c6\u5e93\u5bf9\u5b57\u7b26\u7f16\u7801\u652f\u6301\u4e00\u76f4\u5f88\u5dee\uff0c\u4f60\u4e0d\u5f97\u4e0d\u81ea\u5df1\u5b9e\u73b0\u6216\u4f9d\u8d56\u7b2c\u4e09\u65b9\u5e93\u3002 \u603b\u4e4b\uff0c char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u5411\u8c03\u7528\u8005\u6697\u793a\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\u8fd9\u6837\u4e00\u4e2a\u51fd\u6570\uff1a thisFuncAcceptUTF8(std::u8string msg); \u5982\u679c\u8c03\u7528\u8005\u559c\u6b22\u7528 std::string \u88c5 UTF-8 \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528\uff1a std::string msg; // \u8c03\u7528\u8005\u786e\u4fe1\uff0c\u8fd9\u4e2a msg \u867d\u7136\u662f `std::string`\uff0c\u4f46\u91cc\u9762\u7684\u5185\u5bb9\u5c31\u662f UTF-8 // \u90a3\u4e48\u4ed6\u53ef\u4ee5\u5f3a\u5236\u8f6c\u6362\u4e3a u8string\uff0c\u6765\u8bc1\u660e\u81ea\u5df1\u5934\u8111\u6e05\u9192 thisFuncAcceptUTF8(std::u8string((char8_t *)msg.data(), msg.size())); \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 C++ \u5b98\u65b9\u5b9a\u4e49\u4e2d\uff0c\u5b58\u5728\u4e24\u79cd\u5b57\u7b26\u96c6\u3002\u4e00\u79cd\u662f \u6e90\u7801\u5b57\u7b26\u96c6 (source charset) \uff0c\u4e00\u79cd\u662f \u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u3002 \u8fd9\u771f\u662f\u7cdf\u7cd5\u7684\u672f\u8bed\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u8fd9\u4e2a\u540d\u5b57\u5177\u6709\u8bef\u5bfc\u6027\uff0c\u4ed6\u548c\u8fd0\u884c\u65f6\u6839\u672c\u6ca1\u6709\u5173\u7cfb\uff0c\u660e\u660e\u662f\u7f16\u8bd1\u671f\u5c31\u786e\u5b9a\u7684\u3002\u6240\u4ee5\u5c0f\u5f6d\u8001\u5e08\u66ff\u4ed6\u6539\u4e2a\u540d\u5b57\uff0c\u5b9e\u9645\u5e94\u8be5\u53eb\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u96c6\u201d\u3002 \u800c\u4e14\u4ed6\u4eec\u53eb\u5b57\u7b26\u96c6\u4e5f\u4e0d\u5408\u7406\uff0c\u5e94\u8be5\u53eb\u5b57\u7b26\u7f16\u7801\u624d\u5bf9\uff0cUTF-8 \u548c UTF-16 \u90fd\u662f Unicode \u5b57\u7b26\u96c6\u7684\u4e24\u79cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u4f46\u4ed6\u4eec\u660e\u663e\u662f\u4e0d\u540c\u7684\u3002 \u7136\u540e\uff0c\u518d\u5f15\u5165\u4e00\u4e2a\u771f\u6b63\u7684\uff0c\u8fd0\u884c\u65f6\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u8f6f\u4ef6\u5ba2\u6237\u7535\u8111\u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u6700\u7ec8\uff0c\u7ecf\u8fc7\u5c0f\u5f6d\u8001\u5e08\u6539\u826f\u7684\u672f\u8bed\u5982\u4e0b\uff1a \u6e90\u7801\u5b57\u7b26\u7f16\u7801: .cpp \u6e90\u7801\u6587\u4ef6\u65f6\u7528\u7684\u5b57\u7b26\u7f16\u7801\u3002\u4f8b\u5982\u7a0b\u5e8f\u5458\u7528\u8bb0\u4e8b\u672c\u4fdd\u5b58 .cpp \u6e90\u7801\u6587\u4ef6\u65f6\uff0c\u9009\u62e9 \u201cUTF-8\u201d \u4fdd\u5b58\u5c31\u662f UTF-8\uff0c\u9009\u62e9 \u201cANSI\u201d \u4fdd\u5b58\u5c31\u662f GBK\u3002 \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f char \u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u7684\u5b57\u7b26\u7f16\u7801\u3002\u9ed8\u8ba4\u662f\u6211\u4eec\u7a0b\u5e8f\u5458\uff08\u5f00\u53d1\u8005\uff09\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f\u6211\u4eec\u7684\u7a0b\u5e8f\u5728\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u8fd0\u884c\u65f6\uff0c\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf API \u7684 const char * \u671f\u671b\u63a5\u53d7\u600e\u6837\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002\u9ed8\u8ba4\u662f\u5ba2\u6237\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd9\u4e09\u4e2a\u53ef\u4ee5\u5404\u6709\u4e0d\u540c\u3002 \u5176\u4e2d \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801 \u548c \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801 \u7684\u4e0d\u5339\u914d\uff0c\u662f Windows \u8f6f\u4ef6\u51fa\u73b0\u4e71\u7801\u7684\u4e3b\u8981\u539f\u56e0\u3002 \u800c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u53ea\u4e8b\u5173\u4f60\u5982\u4f55\u4fdd\u5b58\u6e90\u7801\uff0c\u53ea\u662f\u8ba9\u7f16\u8bd1\u5668\u80fd\u591f\u6210\u529f\u8bfb\u53d6\u4f60\u7684\u6e90\u7801\uff0c\u5bf9\u8fd0\u884c\u65f6\u7684\u4e71\u7801\u95ee\u9898\u6ca1\u6709\u5f71\u54cd\u3002\u7f16\u8bd1\u5668\u8bfb\u5b8c\u6e90\u7801\u540e\uff0c\u8981\u5728\u5e38\u91cf\u533a\u751f\u6210\u5b57\u7b26\u4e32\u5e38\u91cf\u65f6\uff0c\u8fd8\u662f\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u7684\u3002 \u4f8b\u5982\u4e4b\u524d\u8bf4\u7684\u65e5\u672c galgame \u5728\u4e2d\u56fd\u7535\u8111\u4e0a\u6253\u5f00\u7206\u51fa\u4e71\u7801\uff0c\u5c31\u662f\u56e0\u4e3a\u662f\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u4e86 galgame\uff08\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u4e3a Shift-JIS\uff09\uff0c\u5728\u4e2d\u56fd\u5ba2\u6237\u7535\u8111\u4e0a\u6253\u5f00\uff08\u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801\u4e3a GBK\uff09\u5bfc\u81f4\u7684\u3002 \u65e5\u672c\u7a0b\u5e8f\u5458\u4f7f\u7528\u4ec0\u4e48\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u6839\u672c\u65e0\u5173\u7d27\u8981\u2026\u2026\u54ea\u6015\u4ed6\u4eec\u4f7f\u7528\u4e86 UTF-8 \u4fdd\u5b58\u6e90\u7801\uff0cMSVC \u7f16\u8bd1\u65f6\u4ecd\u7136\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a Shift-JIS \u7f16\u7801\u7684\u5b57\u9762\u91cf\u6765\u5b58\u50a8\u5728\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5e38\u91cf\u533a\u4e2d\u3002 \u4f60\u53ef\u80fd\u4f1a\u95ee\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u628a\u8fd9\u4e9b\u82b1\u91cc\u80e1\u54e8\u73a9\u5e94\u7edf\u4e00\u4e3a UTF-8\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u8f6c\u6362\u6765\u8f6c\u6362\u53bb\u4e86\uff1f\u8fd8\u4e0d\u662f\u56e0\u4e3a\u5386\u53f2\u9057\u7559\uff0c\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\u5458\u4e0d\u80af\u628a\u4ed6\u4eec GBK \u7f16\u7801\u7684\u6e90\u7801\u6539\u6210 UTF-8 \u4fdd\u5b58\uff0c\u800c\u4e14\uff0cWindows \u4e5f\u5b8c\u5168\u4e0d\u63d0\u4f9b\u57fa\u4e8e UTF-8 \u7684\u8de8\u5e73\u53f0 API\uff08\u53ea\u63d0\u4f9b GBK \u548c UTF-16 \u4e24\u79cd\uff0c\u5c31\u662f\u4e0d\u7ed9 UTF-8 \u7684\uff0c\u975e\u5e38\u6076\u5fc3\u4eba\uff09\u3002\u6240\u4ee5 MSVC \u81f3\u4eca\u4ecd\u7136\u9ed8\u8ba4\u662f GBK \u7f16\u7801\u7684\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f ANSI\uff0c\u8ddf\u968f\u4f60\u7cfb\u7edf\u7684\u533a\u57df\u8bbe\u7f6e\u800c\u53d8\uff0c\u5728\u4e2d\u56fd\u5c31 GBK\uff0c\u5728\u7f8e\u56fd\u5c31 UTF-8\uff0c\u5728\u6b27\u6d32\u5c31 Latin-1\uff0c\u975e\u5e38\u7684\u53cc\u6807\uff09\u3002\u5fae\u8f6f\u5404\u79cd\u626f\u76ae\u6548\u7387\u4f4e\u4e0b\uff0cAPI \u5f04\u4e86\u4e00\u5957\u53c8\u4e00\u5957\u4e92\u76f8\u6781\u9650\u62c9\u626f\uff0c\u800c\u6211\u4eec Linux \u548c GCC \u65e9\u5df2\u9ed8\u8ba4\u5c31\u662f UTF-8\u2026\u2026 \u6211\u7406\u89e3\u4f60\u73b0\u5728\u5927\u8111\u5e72\u70e7\u7684\u5fc3\u60c5\u3002\u4f3a\u5019\u8fd9\u4e9b\u5386\u53f2\u7b54\u8fa9\u5f88\u590d\u6742\uff0c\u4e5f\u5f88\u65e0\u804a\uff0c\u6beb\u65e0\u610f\u4e49\uff01\u53ea\u662f\u4e3a\u4e86\u64e6\u53cd Unicode \u52b3\u4fdd\u7684\u5c41\u80a1\u3002 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a \u5bf9\u4e8e\u8de8\u5e73\u53f0\u8f6f\u4ef6\u6765\u8bf4\uff0c\u6211\u63a8\u8350\u5927\u5bb6\u628a\u4e09\u4e2a\u5168\u90e8\u8bbe\u4e3a UTF-8\uff01\uff08\u8981\u505a\u5230\u8fd9\u4e00\u70b9\uff0c\u4e3b\u8981\u662f\u4f3a\u5019 MSVC\uff09 Linux + GCC \u7528\u6237\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u4f60\u4eec\u6240\u6709\u5b57\u7b26\u96c6\u9ed8\u8ba4\u7684\u8bbe\u5b9a\u5c31\u662f UTF-8\u3002 Windows + MSVC \u7528\u6237\u8bf7\u5f00\u542f /utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\uff0c\u73b0\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u90fd\u662f UTF-8 \u4e86\u3002 Windows + MinGW \u7528\u6237\u8bf7\u5f00\u542f -finput-charset=utf-8 \u548c -fexec-charset=utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\u3002 \u6240\u6709\u6e90\u7801\u6587\u4ef6\u7edf\u4e00\u4ee5 UTF-8 \u7f16\u7801\u4fdd\u5b58\uff0c\u4e14\u5c3d\u91cf\u5728\u6700\u524d\u9762\u52a0\u4e0a 0xFEFF \u8fd9\u4e2a BOM \u6807\u8bb0\uff0c\u9632\u6b62 MSVC \u8111\u62bd\u5f53\u4f5c GBK \u6765\u8bfb\u53d6\u3002 \u5728 main \u51fd\u6570\u524d\uff0c\u52a0\u4e24\u884c\uff1a // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 return 0; } \u8fd9\u6837\u4e00\u5957\u6253\u4e0b\u6765\uff0c\u5c31\u53ef\u4ee5\u4fdd\u8bc1\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u64cd\u4f5c\u7cfb\u7edf\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u6587\u672c\u7f16\u8f91\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u7801\uff0c\u4f60\u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u8bfb\u53d6\u6e90\u7801\uff0c\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u5b58\u50a8\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6b63\u786e\u7684\u628a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u8def\u5f84\u8f6c\u4e3a UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u3002 \u5728 CMake \u4e2d\uff0c\u53ea\u5bf9 MSVC \u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8fd9\u6837\u5199\uff1a if (MSVC) target_compile_options(\u4f60\u7684\u7a0b\u5e8f PRIVATE /utf-8) else() \u4e5f\u53ef\u4ee5\u5728\u6700\u524d\u9762 add_compile_options \uff0c\u5b9e\u73b0\u5bf9\u6240\u6709\u4e4b\u540e\u5b9a\u4e49\u7684\u7a0b\u5e8f\u5168\u5c40\u542f\u7528\u8be5\u9009\u9879\u3002 \u5728\u6211\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\uff0c\u6211\u90fd\u4f1a\u8fd9\u6837\u5f00\u542f\uff0c\u89e3\u51b3 MSVC \u4e0d\u8de8\u5e73\u53f0\u7684\u95ee\u9898\uff1a if (MSVC) add_compile_options(/Zc:preprocessor /utf-8 /DNOMINMAX /D_USE_MATH_DEFINES /EHsc /bigobj) else() if (WIN32) add_compile_options(-finput-charset=utf-8 -fexec-charset=utf-8) endif() add_compile_options(-Wall -Wextra -Werror=return-type) endif() add_executable(\u4f60\u7684\u7a0b\u5e8f \u4f60\u7684\u6587\u4ef6.cpp) # \u81ea\u52a8\u7ee7\u627f\u4e86\u4e0a\u9762\u6240\u6709\u7684\u7f16\u8bd1\u5668\u9009\u9879 .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 Windows \u5b98\u65b9\u63d0\u4f9b\u7684\u771f\u6b63 API \u662f _wfopen \u3002 fopen \u53ea\u662f\u4ed6\u4eec\u63d0\u4f9b\u7684\u201cPOSIX \u517c\u5bb9\u5c42\u201d \u5305\u88c5\uff0c\u5176\u4f1a\u628a\u8f93\u5165\u7684\u5b57\u7b26\u4e32\u53c2\u6570\u901a\u8fc7 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u540e\uff0c\u8f6c\u53d1\u7ed9 _wfopen \u3002 \u51fa\u4e8e\u8de8\u5e73\u53f0\u7684\u8981\u6c42\uff0c\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528 _wfopen \u8fd9\u79cd\u5176\u4ed6\u5e73\u53f0\u6ca1\u6709\u7684\u51fd\u6570\uff0c\u4e5f\u4e0d\u60f3\u7528\u90a3\u8fde 2 \u5b57\u8282 4 \u5b57\u8282\u90fd\u98d8\u5ffd\u4e0d\u5b9a\u7684 wchar_t \uff0c\u66f4\u4e0d\u60f3\u8ba9 std::string \u5b58\u6839\u672c\u4e0d\u80fd\u8de8\u5e73\u53f0\u7684 GBK\u3002 \u53ea\u8981\u8ba9 fopen \u7684 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u51fd\u6570\u66ff\u6362\u6210 \u201cUTF-8 \u5230 UTF-16\u201d \u5c31\u884c\u4e86\u3002\u8fc7\u53bb\uff0c\u6211\u4eec\u65e0\u6cd5\u66ff\u6362\uff0c\u6700\u65b0\u7684 Windows \u5728\u4e00\u6b21\u66f4\u65b0\u4e2d\uff0c\u652f\u6301\u4e86 \".utf-8\" locale \u8fd9\u4e00\u9ed1\u79d1\u6280\uff0c\u4e13\u95e8\u6ee1\u8db3\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u7684\u9700\u8981\u3002 // \u9ed8\u8ba4 locale fopen(\"\u4f60\u597d.txt\") == _wfopen(gbk_to_utf16(\"\u4f60\u597d.txt\")); // \u8bbe\u7f6e\u4e86 utf-8 locale \u540e fopen(\"\u4f60\u597d.txt\") == _wfopen(utf8_to_utf16(\"\u4f60\u597d.txt\")); \u82e5\u4e0d\u8bbe\u7f6e setlocale(LC_ALL, \".utf-8\") \uff0c\u5219 fopen \u548c ifstream \u9ed8\u8ba4\u4f1a\u628a\u4f60\u63d0\u4f9b\u7684 const char * \u6587\u4ef6\u8def\u5f84\uff0c\u5f53\u4f5c GBK \u7f16\u7801\u7684\uff0c\u800c\u6211\u4eec\u8bbe\u7f6e\u4e86 /utf-8 \u6216 -fexec-charset=utf-8 \u540e\uff0c\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u7f16\u7801\u5df2\u7ecf\u662f UTF-8 \u4e86\uff0c\u8fd9\u6837 UTF-8 \u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u8f93\u5165\u8fdb\u671f\u671b const char * \u7684 fopen \u53c2\u6570\uff0c\u5c31\u4f1a\u51fa\u4e71\u7801\u95ee\u9898\u4e86\u3002 \u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c .utf-8 locale \u53ea\u662f\u5f71\u54cd\u4e86\u6807\u51c6\u5e93\uff01\u5e76\u4e0d\u6539\u53d8\u7cfb\u7edf API\u3002 \u76f4\u63a5\u8c03\u7528\u7cfb\u7edf API \u65f6\uff0cA \u7cfb API \u4ecd\u7136\u6709\u95ee\u9898\u3002 MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u63d0\u793a\", MB_OK); // \u4e0d\u884c\uff0c.utf-8 \u53ea\u662f\u8ba9\u6807\u51c6\u5e93\u53d8\u6210 UTF-8 \u63a5\u53e3\u4e86\uff0cA \u7cfb Windows API \u4ecd\u7136\u662f GBK MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u63d0\u793a\", MB_OK); // \u6ca1\u95ee\u9898\uff01\u7528 UTF-16 \u7684 wchar_t \u5b57\u9762\u91cf\u6765\u8c03\u7528 W \u63a5\u53e3\u603b\u662f\u6ca1\u95ee\u9898\u7684 \u8fd8\u662f\u9700\u8981\u6211\u4eec\u624b\u52a8\u8f6c\u6362 UTF-8 \u5230 UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u2026\u2026\u4f46\u662f\u53cd\u6b63\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u5f88\u5c11\u9700\u8981\u76f4\u63a5\u8c03\u7528 Windows API\uff0c\u90fd\u662f\u901a\u8fc7\u901a\u7528\u7684 C/C++ \u6807\u51c6\u5e93\uff0c\u56e0\u6b64 .utf-8 locale \u53ef\u80fd\u662f\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u60f3\u8fdb\u519b UTF-8 \u7684\u6700\u4f73\u9009\u62e9\u3002 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e \u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\uff0c\u90fd\u662f\u9488\u5bf9 char \u7684\uff0c\u53ea\u6709 char \u88ab\u6545\u610f\u9488\u5bf9\u4e86\uff0c\u5b58\u5728\u5b57\u7b26\u7f16\u7801\u4e0d\u7edf\u4e00\u7684\u95ee\u9898\u3002 \u5982\u679c\u5168\u90e8\u7528 wchar_t \u7684\u8bdd\uff0c\u867d\u7136\u5728 Linux \u4e0a\u662f UTF-32\uff0c\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u4e0d\u7edf\u4e00\u4e86\u3002\u4f46\u81f3\u5c11\u5728\u540c\u4e00\u4e2a Windows \u64cd\u4f5c\u7cfb\u7edf\u4e0a\uff0c\u90fd\u662f\u7edf\u4e00\u7684 UTF-16\u3002 \u6240\u4ee5\u8fd8\u6709\u4e00\u79cd\u65b9\u5f0f\u662f\u5168\u9762\u91c7\u7528 wchar_t \u548c std::wstring \uff0c\u8fd9\u6837\u65e0\u8bba\u4f60\u7684\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\u5982\u4f55\uff0c\u90fd\u5bf9 wchar_t \u548c\u57fa\u4e8e const wchar_t * \u7684\u51fd\u6570\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\u3002 C \u8bed\u8a00\u6807\u51c6\u6ca1\u6709 _wfopen \uff0c\u4f46\u662f std::ifstream \u6709\u57fa\u4e8e std::wstring \u7684\u6784\u9020\u51fd\u6570\uff0c\u5c31 C++ \u6807\u51c6\u5e93\u6765\u770b std::wstring \u7684\u652f\u6301\u8fd8\u662f\u5f88\u4e30\u5bcc\u7684\uff0c\u57fa\u672c std::string \u6709\u7684 std::wstring \u90fd\u6709\uff0c\u4f8b\u5982 std::to_string \u548c std::to_wstring \uff0c std::cout \u548c std::wcout \u3002\u672c\u7ae0\u8282\u6700\u540e\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u5bbd\u5b57\u7b26\u6d41\u7684\u7528\u6cd5\u3002 \u7f3a\u70b9\u662f\uff0c\u9996\u5148\u6bcf\u6b21\u90fd\u9700\u8981\u5199 L\"\u4f60\u597d\" \u8fd9\u4e2a L \u524d\u7f00\u5f88\u9ebb\u70e6\uff0c\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u4e14\u5f88\u591a\u7b2c\u4e09\u65b9\u5e93\u90fd\u5728\u7528 std::string \uff0c\u5e76\u6ca1\u6709\u63d0\u4f9b std::wstring \u7684 API\u3002 \u4f8b\u5982 openvdb \u7684\u6587\u4ef6\u5199\u5165\u51fd\u6570\uff1a void openvdb::io::File::write(std::string const &filename); \u8fd9\u6837\u5c31\u5f88\u9ebb\u70e6\u4e86\uff0c\u5982\u679c\u4f60\u5185\u90e8\u5168\u662f UTF-16 \u7684 std::wstring \u6765\u8868\u793a\u5b57\u7b26\u4e32\uff0c\u8c03\u7528\u7b2c\u4e09\u65b9\u5e93\u524d\u5c31\u9700\u8981\u8f6c\u6210 GBK \u7684 std::string \u3002\u53ef\u4ee5\u7528 boost::locale::conv::to_utf \u8fd9\u4e2a\u51fd\u6570\u8f6c\u6362\uff0c\u4f46\u4e5f\u5f88\u9ebb\u70e6\uff0c\u800c\u4e14\u5982\u679c std::wstring \u542b\u6709 GBK \u8303\u56f4\u4e4b\u5916\u7684 \u201c\ud883\udede\u201d\uff0cGBK \u65e0\u6cd5\u8868\u793a\uff0c\u53c8\u4f1a\u6709\u7f16\u7801\u5931\u8d25\u7684\u95ee\u9898\u3002 \u8fd8\u6709 stbi_load \u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u662f\u53ea\u63d0\u4f9b\u4e86 const char * \u7684\u63a5\u53e3\uff0c\u591a\u4e86\u53bb\u4e86\u3002 setlocale(LC_ALL, \".utf-8\") \u7684\u597d\u5904\u662f\u53ef\u4ee5\u8ba9\u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u5168\u81ea\u52a8\u90fd\u4ece GBK \u65e0\u7f1d\u5207\u6362\u5230 UTF-8\uff0c\u800c\u4e0d\u7528\u5bf9\u4ed6\u4eec\u7684\u6e90\u7801\u505a\u4efb\u4f55\u66f4\u6539\u3002\u56e0\u4e3a\u4ed6\u4eec\u5185\u90e8\u90fd\u662f\u8c03\u7528\u7684 fopen \u548c ifstream \u3002 u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u4e2d\u56fd\u533a Windows\uff0cMSVC\uff0c\u7f16\u8bd1\u9009\u9879\uff1a /std:c++17 std::string s = \"\u4f60\u597d\"; hexdump(s); // C4 E3 BA C3 (GBK) std::string s = u8\"\u4f60\u597d\"; hexdump(s); // E4 BD A0 E5 A5 BD (UTF-8) u8 \u524d\u7f00\u544a\u8bc9\u7f16\u8bd1\u5668\uff0c\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u7f16\u7801\u5b58\u50a8\u3002\u65e0\u8bba\u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u662f\u4e0d\u662f UTF-8\u3002 \u7f16\u8bd1\u5668\u4fdd\u8bc1\u4f1a\u628a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u8f6c\u6362\u4e3a UTF-8 \u7f16\u7801\u7684 char \u5b57\u8282\u5e8f\u5217\uff0c\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u533a\u3002 \u8fd9\u5bf9\u4e8e\u5df2\u7ecf\u8bbe\u7f6e\u4e86 /utf-8 \u9009\u9879\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u5df2\u7ecf\u4fdd\u8bc1\u662f UTF-8 \u7684\u6211\u4eec\u6765\u8bf4\u6beb\u65e0\u4f5c\u7528\u3002\u53ea\u662f\u5bf9\u4e8e\u4e0d\u7528 /utf-8 \u7684\u540c\u5b66\uff0c\u4ed6\u4eec\u60f3\u8981\u4e34\u65f6\u521b\u5efa\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5c31\u53ef\u4ee5\u7528 u8 \u524d\u7f00\u3002 \u5728 C++17 \u548c\u4e4b\u524d\uff0c u8\"\u4f60\u597d\" \u4ea7\u751f\u7684\u662f const char [] \u7c7b\u578b\u7684\u5e38\u91cf\u3002 \u5728 C++20 \u4e2d\uff0c\u5f15\u5165\u4e86 char8_t \u3002\u7136\u540e\uff0c\u4ed6\u4eec\u89c4\u5b9a\uff0c u8\"\u4f60\u597d\" \u73b0\u5728\u4ea7\u751f\u7684\u662f const char8_t [] \u7c7b\u578b\u7684\u5e38\u91cf\u4e86\u3002 \u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u517c\u5bb9\u6027\u95ee\u9898\uff0c\u6bd4\u5982\u4ee5\u524d\u4f60\u5199\u7684\uff1a std::string s = u8\"\u4f60\u597d\"; \u73b0\u5728\u65e0\u6cd5\u7f16\u8bd1\u901a\u8fc7\u4e86\uff0c\u56e0\u4e3a const char8_t [] \u65e0\u6cd5\u7528\u4e8e\u6784\u9020\u53ea\u652f\u6301 const char [] \u7684 std::string \u3002 \u597d\u5728 C++23 \u53c8\u4fee\u590d\u4e86\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u4eec\u5141\u8bb8 const char8_t [] \u9690\u5f0f\u8f6c\u6362\u4e3a const char [] \uff0cC++17 \u4e4b\u524d\u7684\u8fd9\u79cd\u4ee3\u7801\u53c8\u80fd\u6b63\u5e38\u901a\u8fc7\u7f16\u8bd1\u3002\u6240\u4ee5\uff0c\u5982\u679c\u60f3\u5feb\u4e50\u5730\u7528 u8 \u5b57\u9762\u91cf\uff0c\u8981\u4e48 C++17\uff0c\u8981\u4e48 C++23\uff0c\u8df3\u8fc7 C++20 \u6bd4\u8f83\u597d\u3002 \u4f60\u53ef\u4ee5\u770b\u5230\uff0cC++ \u7248\u672c\u7684\u66f4\u65b0\u5e76\u4e0d\u662f 100% \u5b8c\u5168\u5411\u524d\u517c\u5bb9\u7684\uff0c\u6709\u65f6\u4e5f\u4f1a\u6709\u7834\u574f\u6027\u7684\u53d8\u66f4\uff0c\u4f46\u6bd4\u8f83\u5c11\uff0c\u5e73\u65f6\u611f\u89c9\u4e0d\u5230\u3002\u6bd4\u5982 C++11 \u4e4b\u524d auto \u5c31\u6709\u5176\u4ed6\u7684\u529f\u80fd\uff0c\u540e\u6765\u51b3\u5b9a\u8fd9\u4e2a\u529f\u80fd\u6ca1\u4ec0\u4e48\u7528\uff0c\u5c31\u628a auto \u6539\u6210\u53e6\u4e00\u4e2a\u610f\u601d\u4e86\u3002 \u9664\u4e86 u8 \u4ee5\u5916\uff0c\u8fd8\u6709\u8fd9\u4e9b\uff1a \u524d\u7f00 \u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u201c\u4f60\u597d\u201d \u8fd0\u884c\u5b57\u7b26\u96c6 (\u9ed8\u8ba4\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7684) const char [] L\u201d\u4f60\u597d\u201d Windows \u4e0a UTF-16\uff1bLinux \u4e0a UTF-32 const wchar_t [] u8\u201d\u4f60\u597d\u201d UTF-8 const char8_t [] u\u201d\u4f60\u597d\u201d UTF-16 const char16_t [] U\u201d\u4f60\u597d\u201d UTF-32 const char32_t [] \u53ea\u4e0d\u8fc7\u662f\u5f00\u53d1\u8005\u548c\u5ba2\u6237\u5f80\u5f80\u5904\u4e8e\u540c\u4e00\u4e2a\u5730\u533a\uff0c\u6240\u4ee5 \"\u4f60\u597d\" \u770b\u8d77\u6765\u597d\u50cf\u53ef\u4ee5\u76f4\u63a5\u8f93\u5165\u5230 std::cout \u4e2d\u4e00\u6837\u3002\u5b9e\u9645\u4e0a\u4ed6\u53ea\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684 ANSI\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7535\u8111\u7684 ANSI\uff0c\u5982\u679c\u76f4\u63a5\u62ff\u6765\u6253\u5370\uff0c\u4f1a\u5bfc\u81f4\u4ee5 \"\" \u5e38\u91cf\u5f62\u5f0f\u5199\u6b7b\u7684\u5b57\u7b26\u4e32\u4f1a\u5728\u5ba2\u6237\u7535\u8111\u4e0a\u51fa\u73b0\u4e71\u7801\u3002\u9664\u975e\u8fd9\u4e2a\u5b57\u7b26\u4e32\u53ea\u5305\u542b ASCII\uff0c\u56e0\u4e3a\u6240\u6709 ANSI \u90fd\u517c\u5bb9 ASCII\uff0c\u624d\u6070\u597d\u907f\u514d\u4e86\u4e71\u7801\u3002 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 \u628a\u5b57\u7b26\u4e32\u5f53\u4f5c\u7eaf\u7cb9\u7684\u201c\u5b57\u8282\u6d41\u201d\uff0c\u65e0\u89c6\u5b57\u7b26\u7f16\u7801\u3002\u6216\u8005\u8bf4\uff0c\u4f60\u4ece\u7cfb\u7edf\u8f93\u5165\u8fdb\u6765\u7684\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u6211\u5c31\u5b58\u50a8\u7684\u4ec0\u4e48\u7f16\u7801\u3002\u5bf9\u4e8e Unicode \u5219\u91c7\u53d6\u5b8c\u5168\u6446\u70c2\u7684\u6001\u5ea6\uff0c\u5b8c\u5168\u65e0\u89c6 Unicode \u7684\u5b58\u5728\u3002 \u9002\u7528\u573a\u666f\uff1a\u901a\u5e38\u4e0e\u6587\u5b57\u5904\u7406\u9886\u57df\u65e0\u5173\u7684\u8f6f\u4ef6\u4f1a\u91c7\u53d6\u8fd9\u79cd\u65b9\u6848\u3002 \u4f18\u70b9\uff1a\u65b9\u4fbf\uff0c\u4e14\u5185\u90e8\u5bf9\u5b57\u7b26\u4e32\u65e0\u4efb\u4f55\u8f6c\u6362\u548c\u5224\u65ad\uff0c\u6548\u7387\u6700\u9ad8\u3002 \u7f3a\u70b9\uff1a\u5728\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u8bfb\u5199\u5e26\u6709\u4e2d\u6587\u7684\u6587\u4ef6\u8def\u5f84\u65f6\uff0c\u4f1a\u9971\u53d7\u4e71\u7801\u548c\u627e\u4e0d\u5230\u6587\u4ef6\u7684\u56f0\u6270\u3002 \u65b9\u6cd5\uff1a\u5b8c\u5168\u4f7f\u7528 const char * \u548c std::string \u3002 \u4ee3\u8868\u4f5c\uff1aLinux \u6587\u4ef6\u7cfb\u7edf ext4\u3001Lua \u7f16\u7a0b\u8bed\u8a00\u3001\u73b0\u4ee3 Python \u4e2d\u7684 bytes \u7c7b\u578b\u3001HTTP \u7684 ? \u53c2\u6570\u3001\u65e9\u671f FAT32 \u6587\u4ef6\u7cfb\u7edf\u7b49\u3002 \u8fd9\u7c7b\u8f6f\u4ef6\u662f\u6700\u5e38\u89c1\u7684\u521d\u5b66\u8005\u5199\u6cd5\uff0c\u5982\u679c\u4f60\u4ece\u672a\u60f3\u8fc7\u5b57\u7b26\u7f16\u7801\u95ee\u9898\uff0c\u4ece\u4e0d\u4e86\u89e3 wchar_t \u3001 char32_t \u4e4b\u95f4\u7684\u6218\u4e89\uff0c\u53ea\u77e5\u9053 char \uff0c\u90a3\u4e48\u4f60\u5df2\u7ecf\u81ea\u52a8\u5728\u6b64\u9635\u8425\u91cc\u3002 \u6709\u4eba\u8bf4 Linux \u6587\u4ef6\u7cfb\u7edf\u662f UTF-8\uff1f\u5e76\u4e0d\u662f\uff01Linux \u6587\u4ef6\u7cfb\u7edf\u6839\u672c\u4e0d\u4f1a\u68c0\u9a8c\u4f60\u7684\u6587\u4ef6\u540d\u662f\u4e0d\u662f\u5408\u6cd5\u7684 UTF-8\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u4f60\u8bbe\u5b9a\u4e86 export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u4f1a\u4f7f\u6240\u6709\u7a0b\u5e8f\uff08\u5305\u62ec\u7ec8\u7aef\u6a21\u62df\u5668\uff09\u5047\u5b9a\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u5185\u5bb9\u90fd\u6309 UTF-8 \u7f16\u7801\uff0c\u4ece\u800c\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u5404\u7c7b API \u65f6\uff08\u5982 open\u3001write\uff09\u90fd\u4f1a\u4f7f\u7528 UTF-8 \u7f16\u7801\u7684 const char * \u8f93\u5165\uff0c\u5728 Linux \u7cfb\u7edf API \u770b\u6765\uff0c\u6240\u8c13\u201c\u6587\u4ef6\u540d\u201d\u53ea\u662f\u7eaf\u7cb9\u7684\u5b57\u8282\u6d41\uff0c\u53ea\u8981\u4fdd\u8bc1\u4e0d\u5305\u542b '/' \u548c '\\0' \uff0c\u65e0\u8bba\u4f60\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4ed6\u90fd\u4e0d\u5728\u4e4e\u3002\u800c\u6240\u6709\u7684 locale \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u7edd\u4e0d\u4f1a\u51fa\u73b0\u4e00\u4e2a\u4e2d\u6587\u6c49\u5b57\u7f16\u7801\u540e\u4ea7\u751f '/' \u7684\u60c5\u51b5\uff08\u4f8b\u5982 GB2312 \u4f1a\u628a\u4e00\u4e2a\u4e2d\u6587\u7f16\u7801\u6210\u4e24\u4e2a 0x80 \u5230 0xFF \u533a\u95f4\u7684\u5b57\u8282\uff0c\u548c ASCII \u7684\u8303\u56f4\u6ca1\u6709\u91cd\u53e0\uff0c\u66f4\u4e0d\u53ef\u80fd\u51fa\u73b0 '/' \uff09\uff0c\u5373\u4f7f\u6362\u6210 export LC_ALL=zh_CN.GB2312 \uff0cLinux \u6587\u4ef6\u7cfb\u7edf\u4e00\u6837\u80fd\u6b63\u5e38\u5de5\u4f5c\uff0c\u53ea\u4e0d\u8fc7\u8bfb\u53d6\u4f60\u4e4b\u524d\u4ee5 UTF-8 \u5199\u5165\u7684\u6587\u4ef6\u4f1a\u53d8\u6210\u4e71\u7801\u800c\u5df2\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a\u7684 Windows \u800c\u8a00\uff0c\u4ed6\u7684\u6240\u6709 A \u51fd\u6570\u53ea\u652f\u6301 GBK \u7f16\u7801\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u4f60 Lua \u4e2d\u628a\u5b57\u7b26\u4e32\u201c\u5f53\u4f5c\u201d UTF-8 \u6765\u7528\u3002\u90a3\u4e48\u5f53\u4f60\u5728\u8c03\u7528 Lua \u7684 io.open \u524d\uff0c\u9700\u8981\u5148\u505a\u4e00\u4e2a UTF-8 \u5230 GBK \u7684\u8f6c\u6362\uff0c\u8fd9\u8fd8\u4f1a\u5bfc\u81f4\u4e22\u5931\u90e8\u5206\u4e0d\u5728 GBK \u5185\u7684\u5b57\u7b26\uff0c\u6bd4\u5982\u5982\u679c\u4f60\u7684\u6587\u4ef6\u540d\u5305\u542b Emoji\uff0c\u90a3\u5c31\u4f1a\u53d8\u6210 ??? \u4e71\u7801\u3002\u800c\u4f7f\u7528 W \u51fd\u6570\u7684 UTF-16 \u5c31\u4e0d\u4f1a\uff0c\u56e0\u4e3a UTF-16 \u80fd\u5bb9\u7eb3\u5b8c\u6574\u7684 Unicode \u6620\u5c04\u3002\u800c\u5b8c\u5168\u6446\u70c2\u7684 Lua\uff0c\u5176 io.open \u53ea\u662f\u4f7f\u7528 C \u8bed\u8a00\u5e93\u51fd\u6570 fopen \uff0c fopen \u53c8\u662f\u57fa\u4e8e Windows \u7684 A \u7cfb\u5217\u51fd\u6570\uff0cLua \u53c8\u6ca1\u6709\u63d0\u4f9b\u5bf9 Windows C \u8fd0\u884c\u65f6\u5e93\u7279\u6709\u7684 _wfopen \u51fd\u6570\u7684\u5c01\u88c5\uff0c\u4ece\u800c\u6c38\u8fdc\u4e0d\u53ef\u80fd\u6253\u5f00\u4e00\u4e2a\u5e26\u6709 Emoji \u7684\u6587\u4ef6\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 ANSI \u9635\u8425\uff0c\u4f60\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0cchar \u6ee1\u5929\u98de\u6446\u70c2\u3002 UTF-8 \u9635\u8425 \u652f\u6301 Unicode\uff0c\u5b57\u7b26\u4e32\u7edf\u4e00\u4ee5 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u3001\u5904\u7406\u548c\u4f20\u8f93\u3002 \u5e94\u7528\u573a\u666f\uff1a\u5e38\u89c1\u4e8e\u6587\u5b57\u5904\u7406\u9700\u6c42\u4e0d\u5927\uff0c\u4f46\u6709\u5f3a\u70c8\u7684\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u7279\u522b\u662f\u4e92\u8054\u7f51\u65b9\u9762\u7684\u8f6f\u4ef6\u3002\u4ed6\u4eec\u901a\u5e38\u53ea\u7528\u5230\u5b57\u7b26\u4e32\u7684\u62fc\u63a5\u3001\u67e5\u627e\u3001\u5207\u7247\u901a\u5e38\u4e5f\u53ea\u662f\u5728\u56fa\u5b9a\u7684\u4f4d\u7f6e\uff08\u4f8b\u5982\u6587\u4ef6\u5206\u9694\u7b26 '/' \uff09\u3002\u4e5f\u975e\u5e38\u9002\u5408\u4e3b\u8981\u9762\u5bf9\u7684\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0cUTF-8 \u662f\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u6700\u9ad8\u7684\uff0c\u6240\u4ee5\u4e5f\u5e7f\u6cdb\u7528\u4e8e\u7f16\u8bd1\u5668\u3001\u6570\u636e\u5e93\u4e4b\u7c7b\u7684\u573a\u666f\u3002\u540c\u65f6\u56e0\u4e3a UTF-8 \u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u4f7f\u5f97\u4ed6\u80fd\u8f7b\u6613\u9002\u914d\u8fdc\u53e4\u7684 C \u8bed\u8a00\u7a0b\u5e8f\u548c\u5e93\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-8 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8de8\u5e73\u53f0\uff0c\u5728\u7f51\u7edc\u4f20\u8f93\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u7801\uff0cUTF-8 \u662f\u4e92\u8054\u7f51\u7684\u4e3b\u6d41\u7f16\u7801\u683c\u5f0f\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a\u8fd0\u884c\u7684 UTF-8 \u8f6f\u4ef6\u53ef\u4ee5\u968f\u610f\u5171\u4eab\u6587\u672c\u6570\u636e\u3002\u517c\u5bb9 ASCII\uff0c\u65b9\u4fbf\u590d\u7528\u73b0\u6709\u5e93\u548c\u751f\u6001\u3002\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u9ad8\uff0c\u5bf9\u4e2d\u6587\u6587\u672c\u4e5f\u4e0d\u7b97\u592a\u5dee\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e\u5e95\u5c42 API \u5747\u91c7\u7528 UTF-16 \u7684 Windows \u7cfb\u7edf\uff0c\u9700\u8981\u8fdb\u884c\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u635f\u5931\u3002\u4e14\u5b57\u7b26\u4e32\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4f1a\u53d8\u6210 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002 \u4ee3\u8868\u4f5c\uff1aRust \u8bed\u8a00\u3001Go \u8bed\u8a00\u3001CMake \u6784\u5efa\u7cfb\u7edf\u3001Julia \u8bed\u8a00\u7b49\u3002 \u5728 C++ \u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7 u8\"\u4f60\u597d\" \u521b\u5efa\u4e00\u4e2a\u4fdd\u8bc1\u5185\u90e8\u662f UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u7c7b\u578b\u4e3a char8_t [] \u3002 \u5982\u679c\u7528\u65e0\u524d\u7f00\u7684 \"\u4f60\u597d\" \u521b\u5efa\uff0c\u5219 MSVC \u9ed8\u8ba4\u4f1a\u4ee5\u7f16\u8bd1\u8005\u6240\u5728\u7cfb\u7edf\u7684\u201c\u533a\u57df\u8bbe\u7f6e (locale)\u201d \u4f5c\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7f16\u7801\u683c\u5f0f\uff08\u800c\u4e0d\u662f\u8fd0\u884c\u8005\u7684\u533a\u57df\u8bbe\u7f6e\uff01\uff09\uff0c\u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8ba9 MSVC \u7f16\u8bd1\u5668\u9ed8\u8ba4\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u5373\u8ba9 \"\u4f60\u597d\" \u548c u8\"\u4f60\u597d\" \u4e00\u6837\u91c7\u7528 UTF-8\u3002\u800c GCC \u9ed8\u8ba4\u5c31\u662f UTF-8\uff0c\u9664\u975e\u624b\u52a8\u6307\u5b9a -fexec-charset=GBK \u6765\u5207\u6362\u5230 GBK\u3002\u7a0d\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u7f16\u8bd1\u5668\u7684\u5b57\u7b26\u7f16\u7801\u95ee\u9898\u3002 \u5047\u8bbe\u4f60\u901a\u8fc7 /utf-8 \u6216 -fexec-charset=utf-8 \u641e\u5b9a\u4e86\u7f16\u8bd1\u671f\u5e38\u91cf\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u3002\u63a5\u4e0b\u6765\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u6587\u4ef6\u7cfb\u7edf\u3002 Linux \u6587\u4ef6\u7cfb\u7edf\u5185\u90e8\uff0c\u5747\u4f7f\u7528 8 \u4f4d\u7c7b\u578b char \u5b58\u50a8\uff0c\u5c06\u6587\u4ef6\u540d\u5f53\u4f5c\u5e73\u51e1\u7684\u5b57\u8282\u6d41\uff0c\u4e0d\u4f1a\u505a\u4efb\u4f55\u8f6c\u6362\u3002\u56e0\u6b64\u4f60\u7528 UTF-8 \u521b\u5efa\u548c\u6253\u5f00\u7684\u6587\u4ef6\uff0c\u5176\u4ed6\u4f7f\u7528 UTF-8 \u533a\u57df\u8bbe\u7f6e\u7684\u8f6f\u4ef6\u90fd\u53ef\u4ee5\u7167\u5e38\u6253\u5f00\uff0c\u4e0d\u4f1a\u6709\u4e71\u7801\u95ee\u9898\u3002 \u5176\u5b9e Windows \u4e0a\u4ee5 GBK \u7f16\u7801\u7684\u538b\u7f29\u6587\u4ef6\u6216\u6587\u672c\u6587\u4ef6\uff0c\u62f7\u8d1d\u5230 Linux \u4e0a\u6253\u5f00\u51fa\u73b0\u4e71\u7801\u95ee\u9898\uff0c\u5c31\u662f\u56e0\u4e3a Linux \u7684\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u90fd\u662f UTF-8 \u7684\u3002\u5b9e\u9645\u4e0a\u5982\u679c\u628a\u4f60\u7684\u6587\u4ef6\u62f7\u7ed9\u4e00\u4e2a\u7f8e\u56fd\u7684 Windows \u7528\u6237\uff0c\u4ed6\u4e5f\u4f1a\u770b\u5230\u4e71\u7801\uff0c\u56e0\u4e3a\u7f8e\u56fd\u5927\u533a\u7684 Windows \u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\uff0c\u800c\u4e2d\u56fd\u5927\u533a\u7684\u662f GBK\uff0c\u7a0d\u540e\u6211\u4eec\u4f1a\u8bb2\u5230\u89e3\u51b3\u65b9\u6848\u3002 \u800c Windows \u7684 NTFS \u6587\u4ef6\u7cfb\u7edf\uff0c\u91c7\u7528 16 \u4f4d\u7684 wchar_t \u5b58\u50a8\uff0cWindows \u7684\u6240\u6709 API\uff0c\u4e5f\u90fd\u662f\u57fa\u4e8e wchar_t \u7684\uff0cWindows \u5185\u6838\u5185\u90e8\u4e5f\u90fd\u7528 wchar_t \u50a8\u5b58\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u53ea\u6709\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6d41\u4f1a\u7528 char \u5b58\u50a8\u3002\u8fd9\u7c7b\u57fa\u4e8e wchar_t \u7684\u7cfb\u7edf API \u90fd\u6709\u4e00\u4e2a W \u540e\u7f00\uff0c\u4f8b\u5982\uff1a MessageBoxW(NULL, L\"\u4f60\u597d\", L\"\u6807\u9898\", MB_OK); \u8fd9\u4e2a MessageBoxW \u51fd\u6570\uff0c\u53ea\u63a5\u53d7 const wchar_t * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 L\"\u4f60\u597d\" \u662f\u4e00\u4e2a wchar_t [] \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5b83\u7684\u5185\u90e8\u7f16\u7801\u7c7b\u578b\u56fa\u5b9a\u662f UTF-16\uff0c\u4e0d\u4f1a\u968f\u7740\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002\u4e4b\u540e\u7684\u4e00\u8282\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3 W \u548c A \u51fd\u6570\u7684\u95ee\u9898\u3002 \u867d\u7136\u4e5f\u6709\u63d0\u4f9b A \u540e\u7f00\u7684\u7cfb\u5217\u51fd\u6570\uff0c\u4ed6\u4eec\u548c W \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u63a5\u53d7 const char * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002\u95ee\u9898\u5728\u4e8e\uff0c\u8fd9\u4e9b\u5b57\u7b26\u4e32\u90fd\u5fc5\u987b\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u4e5f\u5c31\u662f GBK \u7f16\u7801\uff01\u800c\u4e14\u65e0\u6cd5\u4fee\u6539\u3002 \u5f53\u8c03\u7528 A \u7cfb\u51fd\u6570\u65f6\uff0c\u4ed6\u4eec\u5185\u90e8\u4f1a\u628a GBK \u7f16\u7801\u8f6c\u6362\u4e3a UTF-16 \u7f16\u7801\uff0c\u7136\u540e\u8c03\u7528 Windows \u5185\u6838\u3002 \u8fd9\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\uff0c\u800c\u6240\u6709\u7684 C/C++ \u6807\u51c6\u5e93\u90fd\u662f\u57fa\u4e8e A \u51fd\u6570\u7684\uff01\u5982\u679c\u4f60\u7528 const char * \u5b57\u7b26\u4e32\u8c03\u7528 C \u6807\u51c6\u5e93\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u4e86 A \u51fd\u6570\u3002\u800c A \u51fd\u6570\u53ea\u63a5\u53d7 GBK\uff0c\u4f46\u4f60\u5374\u8f93\u5165\u4e86 UTF-8\uff01\u4ece\u800c UTF-8 \u4e2d\u6240\u6709\u9664 ASCII \u4ee5\u5916\u7684\uff0c\u5404\u79cd\u4e2d\u6587\u5b57\u7b26\u3001Emoji \u90fd\u4f1a\u53d8\u6210\u4e71\u7801\u3002 \u4f8b\u5982 fopen \u51fd\u6570\uff0c\u53ea\u6709 fopen(const char *path, const char *mode) \u8fd9\u4e00\u4e2a\u57fa\u4e8e char \u7684\u7248\u672c\uff0c\u91cc\u9762\u4e5f\u662f\u76f4\u63a5\u8c03\u7528\u7684 A \u51fd\u6570\uff0c\u5b8c\u5168\u4e0d\u7ed9\u6211\u9009\u62e9\u7684\u7a7a\u95f4\u3002\u867d\u7136 Windows \u4e5f\u63d0\u4f9b\u4e86 _wfopen(const wchar_t *path, const wchar_t *mode) \uff0c\u4f46\u90a3\u65e2\u4e0d\u662f POSIX \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f C \u8bed\u8a00\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f7f\u7528\u8fd9\u6837\u7684\u51fd\u6570\u5c31\u610f\u5473\u7740\u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 Windows \u5b98\u65b9\u8ba4\u4e3a\uff1a W \u51fd\u6570\u624d\u662f\u771f\u6b63\u7684 API\uff0c A \u51fd\u6570\u53ea\u662f\u5e94\u4ed8\u4e0d\u542c\u8bdd\u7684\u5b9d\u5b9d\u3002\u53ef\u4f60\u5c31\u6ca1\u53d1\u73b0\u4f60\u81ea\u5df1\u7684 C/C++ \u6807\u51c6\u5e93\u4e5f\u5168\u90e8\u5728\u8c03\u7528\u7684 A \u51fd\u6570\u4e48\uff1f \u603b\u4e4b\uff0c A \u51fd\u6570\u662f\u6b8b\u5e9f\u7684\uff0c\u6211\u4eec\u53ea\u80fd\u7528 W \u51fd\u6570\uff0c\u5c3d\u7ba1 UTF-16 \u662f\u5386\u53f2\u503a\uff0c\u4f46\u6211\u4eec\u522b\u65e0\u9009\u62e9\uff0c W \u51fd\u6570\u662f\u552f\u4e00\u80fd\u652f\u6301\u5b8c\u6574 Unicode \u5b57\u7b26\u8f93\u5165\u7684\u65b9\u5f0f\u3002 // \u5047\u8bbe\u8fd9\u6bb5 C++ \u4ee3\u7801\u4f7f\u7528 /utf-8 \u9009\u9879\u7f16\u8bd1\uff1a std::ifstream f(\"\u4f60\u597d.txt\"); // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5373\u4f7f\u201c\u4f60\u597d.txt\u201d\u5b58\u5728 std::ofstream f(\"\u4f60\u597d.txt\"); // \u4f1a\u521b\u5efa\u4e00\u4e2a\u4e71\u7801\u6587\u4ef6 \u6b63\u786e\u7684\u505a\u6cd5\u662f\u91c7\u7528 std::filesystem::u8path \u8fd9\u4e2a\u51fd\u6570\u505a UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\uff1a // C++17\uff0c\u9700\u8981\u7528 u8path \u8fd9\u4e2a\u51fd\u6570\u6784\u9020 path \u5bf9\u8c61\uff1a std::ifstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); // C++20 \u5f15\u5165 char8_t\uff0c\u533a\u5206\u4e8e\u666e\u901a char\uff0cpath \u7c7b\u4e5f\u6709\u4e86\u9488\u5bf9 const char8_t * \u7684\u6784\u9020\u51fd\u6570\u91cd\u8f7d\uff1a std::ifstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::filesystem::path \u7c7b\u7684 c_str() \u5728 Windows \u4e0a\u8fd4\u56de const wchar_t * \uff0c\u5728 Linux \u4e0a\u8fd4\u56de const char * \u3002\u8fd9\u5f88\u5408\u7406\uff0c\u56e0\u4e3a Windows \u6587\u4ef6\u7cfb\u7edf\u786e\u5b9e\u4ee5 wchar_t \u5b58\u50a8\u8def\u5f84\u540d\uff0c\u800c Linux \u6587\u4ef6\u7cfb\u7edf\u5b8c\u5168\u7528 char \u3002 \u6bcf\u6b21\u9700\u8981\u52a0 std::filesystem::u8path \u4e5f\u633a\u9ebb\u70e6\u7684\uff0c\u5bb9\u6613\u5fd8\u8bb0\uff0c\u4e00\u5fd8\u8bb0\u5c31\u65e0\u6cd5\u8bbf\u95ee\u4e2d\u6587\u76ee\u5f55\u3002 \u5f88\u591a\u8f6f\u4ef6\u5728 Windows \u4e0a\u65e0\u6cd5\u652f\u6301\u4e2d\u6587\u8def\u5f84\u540d\uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u4eec\u4e60\u60ef\u4e86 Linux \u6216 MacOS \u7684\u5168 UTF-8 \u73af\u5883\uff0c\u5bf9\u6587\u4ef6\u8def\u5f84\u6ca1\u6709\u4efb\u4f55\u8f6c\u6362\u3002\u800c Windows \u5e95\u5c42\u5168\u662f UTF-16\uff0c\u6839\u672c\u6ca1\u6709\u63d0\u4f9b UTF-8 \u7684 API\uff0c\u4f60 UTF-8 \u53ea\u80fd\u8f6c\u6362\u6210 UTF-16 \u624d\u80fd\u907f\u514d\u4e2d\u6587\u4e71\u7801\u3002\u4e2a\u4eba\u8ba4\u4e3a\uff0c\u6b7b\u6d3b\u4e0d\u80af\u63a5\u53d7\u660e\u6446\u7740\u5df2\u7ecf\u662f\u56fd\u9645\u901a\u7528\u6807\u51c6\u7684 UTF-8\uff0cA \u51fd\u6570\u7684\u7f16\u7801\u8fde\u5f53\u524d\u8fdb\u7a0b\u5207\u6362\u7684\u65b9\u6cd5\u90fd\u4e0d\u7ed9\u4e00\u4e2a\uff0c\u8fd9\u4e2a\u5e94\u8be5\u7531 Windows \u5168\u8d23\u627f\u62c5\u3002 \u597d\u6d88\u606f\u662f\uff0c\u6700\u8fd1 MSVC \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u4e00\u79cd\u65b9\u6848\uff0c\u5728\u4f60\u7684\u7a0b\u5e8f\u5f00\u5934\uff0c\u52a0\u4e0a setlocale(LC_ALL, \".utf-8\") \u5c31\u53ef\u4ee5\u8ba9 C \u548c C++ \u6807\u51c6\u5e93\u8fdb\u5165 UTF-8 \u6a21\u5f0f\uff1a\u4e0d\u518d\u8c03\u7528 A \u7cfb\u51fd\u6570\u64cd\u4f5c\u6587\u4ef6\uff0c\u800c\u662f\u4f1a\u628a\u6587\u4ef6\u540d\u4ece UTF-8 \u8f6c\u6362\u6210 UTF-16 \u540e\u518d\u8c03\u7528\u771f\u6b63\u7a33\u5b9a\u7684 W \u7cfb\u51fd\u6570\u3002 setlocale(LC_ALL, \".utf-8\"); // \u53ea\u9700\u8981\u8fd9\u4e00\u884c FILE *fp = fopen(u8\"\u4f60\u597d.txt\", \"r\"); // \u53ef\u4ee5\u4e86 std::ifstream fin(u8\"\u4f60\u597d.txt\"); // \u53ef\u4ee5\u4e86 setlocale(LC_ALL, \".utf-8\"); \u53ea\u662f\u628a C \u6807\u51c6\u5e93\u7684 const char * \u53c2\u6570\u53d8\u6210\u4e86\u63a5\u53d7 UTF-8\uff0c\u5e76\u4e0d\u4f1a\u8ba9\u7cfb\u7edf\u7684 A \u51fd\u6570\u4e5f\u53d8\u6210 UTF-8 \u54e6\uff0c\u8c03\u7528\u672c\u5730 API \u65f6\u4ecd\u9700 UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-8 \u9635\u8425\uff0c\u5f00\u542f /utf-8 \uff0c\u7a0b\u5e8f\u5f00\u5934\u5199 setlocale(LC_ALL, \".utf-8\") \u3002Linux \u7528\u6237\u5219\u4ec0\u4e48\u90fd\u4e0d\u7528\u505a\u3002 \u770b\u770b\u5404\u5927\u8f6f\u4ef6\u7ad9\u5728 UTF-8 \u9635\u8425\u7684\u7406\u7531\uff1a CMake\uff1a\u4f5c\u4e3a\u8de8\u5e73\u53f0\u7684\u6784\u5efa\u7cfb\u7edf\uff0c\u4e3a\u4e86\u8ba9\u9879\u76ee\u7684 CMakeLists.txt \u80fd\u8de8\u5e73\u53f0\u5171\u7528\u800c\u4e0d\u5fc5\u91cd\u5199\uff0c\u4ed6\u7406\u6240\u5f53\u7136\u5730\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\uff1a\u6240\u6709 CMakeLists.txt \u90fd\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u4e66\u5199\uff0c\u4e14\u7edf\u4e00\u4f7f\u7528\u6b63\u659c\u6760 '/' \u8def\u5f84\u5206\u9694\u7b26\u3002 CMake \u4f1a\u81ea\u52a8\u5728 Windows \u7cfb\u7edf\u4e0a\uff0c\u5c06 UTF-8 \u5b57\u7b26\u4e32\u8f6c\u6362\u6210 UTF-16 \u540e\uff0c\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u5728 Linux \u7cfb\u7edf\u4e0a\u5219\u4e0d\u505a\u8f6c\u6362\u3002\u5728 Windows \u7cfb\u7edf\u4e0a\u8fd8\u4f1a\u81ea\u52a8\u628a\u6587\u4ef6\u8def\u5f84\u4e2d\u7684\u6b63\u659c\u6760 '/' \u8f6c\u6362\u6210 Windows \u4e13\u5c5e\u7684\u53cd\u659c\u6760 '\\\\' \uff0c\u65e0\u9700\u7528\u6237\u64cd\u5fc3\u3002 \u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u8282\u70b9\u4eff\u771f\u8f6f\u4ef6\uff1a\u7531\u4e8e\u4fdd\u5b58\u7684\u9879\u76ee\u5de5\u7a0b\u6587\u4ef6\u9700\u8981\u5728 Linux \u548c Windows \u5e73\u53f0\u4e0a\u4e92\u901a\uff0c\u4e0d\u80fd\u91c7\u7528 Windows \u5404\u81ea\u4e3a\u653f\u7684 GBK \u683c\u5f0f\uff0c\u4e14\u5de5\u7a0b\u6587\u4ef6\u5185\u5bb9\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\u4e2d\u3002 Rust \u548c Go\uff1a\u4e25\u683c\u533a\u5206\u201c\u5b57\u7b26 (32 \u4f4d)\u201d\u548c\u201c\u5b57\u8282 (8 \u4f4d)\u201d\u7684\u6982\u5ff5\u3002\u5728\u5b57\u7b26\u4e32\u7c7b\u578b\u4e2d\u5b58\u50a8\u5b57\u8282\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u4ee5\u5b57\u8282\u65b9\u5f0f\u8bfb\u53d6\u6216\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-8 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5904\u7406\u5207\u7247\u548c\u7d22\u5f15\u65f6\u4e0d\u65b9\u4fbf\u3002 \u7f16\u7a0b\u8bed\u8a00 \u5b57\u7b26\u7c7b\u578b (32 \u4f4d) \u5b57\u8282\u7c7b\u578b (8 \u4f4d) Rust char u8 Go rune byte Julia Char UInt8 \u4e3a\u6b64\uff0c\u8fd9\u4e9b\u8bed\u8a00\u90fd\u4e3a\u5b57\u7b26\u4e32\u63d0\u4f9b\u4e86\u4e24\u5957 API\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u8282\u7d22\u5f15\u3002\u6309\u5b57\u7b26\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ece\u5934\u5f00\u59cb\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\uff0c\u76f4\u5230\u89e3\u6790\u5230\u60f3\u8981\u7684\u5b57\u7b26\u4e3a\u6b62\uff0c\u590d\u6742\u5ea6 O(N) O(N) \u3002\u6309\u5b57\u8282\u7d22\u5f15\u65f6\uff0c\u76f4\u63a5\u8df3\u5230\u6307\u5b9a\u5b57\u8282\uff0c\u65e0\u9700\u89e3\u6790\uff0c\u590d\u6742\u5ea6 O(1) O(1) \u3002 let s = \"\u4f60\u597d\"; // \u6309\u5b57\u7b26\u904d\u5386 for c in s.chars() { // c: char println!(\"{}\", c); } // \u6309\u5b57\u8282\u904d\u5386 for b in s.bytes() { // b: u8 println!(\"{:02x}\", b); } \u5728 C++ \u4e2d\uff0c\u82e5\u8981\u91c7\u7528\u8fd9\u79cd UTF-8 \u65b9\u6848\uff0c\u53ef\u4ee5\u4f7f\u7528 utfcpp \u8fd9\u4e2a\u5e93\uff1a https://github.com/nemtrif/utfcpp \u7a0d\u540e\u6211\u4eec\u4f1a\u4ee5\u6848\u4f8b\u8be6\u7ec6\u6f14\u793a\u8fd9\u4e2a\u5e93\u7684\u7528\u6cd5\uff0c\u4e5f\u4f1a\u5c1d\u8bd5\u81ea\u5df1\u624b\u6413\u3002 \u65b9\u6cd51\uff1a\u4f7f\u7528 utf8to32 \u4e00\u6b21\u6027\u5b8c\u6210\u8f6c\u6362\uff0c\u7528\u5b8c\u540e\u518d\u8f6c\u56de\u53bb\u3002 std::string s = \"\u4f60\u597d\"; std::u32string u32 = utf8::utf8to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\u574f'; s = utf8::utf32to8(u32); fmt::println(\"{}\", s); // \u4f60\u574f \u65b9\u6cd52\uff1a utfcpp \u4e5f\u5c01\u88c5\u4e86\u4e00\u4e2a utf8::iterator \u8fed\u4ee3\u5668\u9002\u914d\u5668\uff0c\u6548\u679c\u7c7b\u4f3c\u4e8e Rust \u7684 .chars() \uff0c\u53ef\u4ee5\u5b57\u7b26\u800c\u4e0d\u662f\u5b57\u8282\u904d\u5386\u5b57\u7b26\u4e32\u5bb9\u5668\u3002 char s[] = \"\u4f60\u597d\"; utf8::unchecked::iterator bit(s); utf8::unchecked::iterator eit(s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u5b89\u5168\uff08\u5e26\u8fb9\u754c\u68c0\u6d4b\uff09\u7684\u7248\u672c char s[] = \"\u4f60\u597d\"; utf8::iterator bit(s, s, s + strlen(s)); utf8::iterator eit(s + strlen(s), s, s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u57fa\u4e8e std::string \u7684\u7248\u672c std::string s = \"\u4f60\u597d\"; utf8::iterator bit(s.begin(), s.begin(), s.end()); utf8::iterator eit(s.end(), s.begin(), s.end()); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } \u7531\u4e8e\u8fed\u4ee3\u5668\u63a5\u53e3\u590d\u6742\u96be\u61c2\uff0c\u5efa\u8bae\u5148\u5c01\u88c5\u6210\u5e26\u6709 begin() \u548c end() \u7684 range \u5bf9\u8c61\uff0c\u65b9\u4fbf\u4f7f\u7528 C++17 range-based loop \u8bed\u6cd5\u76f4\u89c2\u904d\u5386\uff1a template struct Utf8Range { utf8::iterator bit; utf8::iterator eit; template Utf8Range(T &&t) : bit(std::begin(t), std::begin(t), std::end(t)) , eit(std::end(t), std::begin(t), std::end(t)) {} auto begin() const { return bit; } auto end() const { return eit; } }; template Utf8Range(T &&t) -> Utf8Range; // \u4ee5\u4e0b\u662f\u65b0\u7c7b\u7684\u4f7f\u7528\u65b9\u6cd5 std::string s = \"\u4f60\u597d\"; for (char32_t c : Utf8Range(s)) { fmt::println(\"U+{:04X}\", c); } UTF-16 \u9635\u8425 \u652f\u6301 Unicode \u8fc7\u65e9\uff0c\u8bef\u4ee5\u4e3a 0xFFFF \u5c31\u662f Unicode \u7684\u4e0a\u9650\u3002 \u4e00\u5f00\u59cb\uff0c\u4eba\u4eec\u9519\u8bef\u5730\u628a UTF-16 \u5f53\u6210\u6c38\u8fdc\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u89e3\u51b3\u4e71\u7801\u95ee\u9898\uff0c\u6240\u4ee5\u90a3\u6bb5\u65f6\u671f\u7684\u8f6f\u4ef6\u90fd\u5927\u4e3e\u4f7f\u7528 UTF-16 \u4f5c\u4e3a\u5185\u7801\u3002\u6ca1\u60f3\u5230\u540e\u6765 Unicode \u53c8\u5f15\u5165 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u800c\u73b0\u6709\u7684\u5df2\u7ecf\u91c7\u7528\u4e86 16 \u4f4d\u5185\u7801\u7684\u8f6f\u4ef6\u53c8\u5df2\u7ecf\u65e0\u6cd5\u6839\u9664\uff0c\u53ea\u597d\u4f7f\u7528\u201c\u4ee3\u7406\u5bf9\u201d\u673a\u5236\uff0c\u589e\u91cf\u66f4\u65b0\u4fee\u590d\u4e86\u73b0\u6709\u7684 16 \u4f4d\u5185\u7801\u8f6f\u4ef6\u3002UTF-16 \u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u597d\u5904\uff0c\u7559\u4e0b\u5386\u53f2\u503a\u3002 \u4e8b\u5b9e\u4e0a\uff0cUnicode \u5df2\u7ecf\u65e0\u6cd5\u7ee7\u7eed\u6269\u5bb9\u7a81\u7834 0x10FFFF\uff0c\u5c31\u662f\u56e0\u4e3a\u53cc uint16_t \u7f16\u7801\u7684\u4ee3\u7406\u5bf9\u6700\u591a\u53ea\u80fd\u5bb9\u7eb3\u989d\u5916 0x100000 \u4e2a\u5b57\u7b26\u7684\u7a7a\u95f4\u3002\u672c\u6765 UTF-8 \u4e00\u5f00\u59cb\u7684\u8349\u6848\u662f\u6253\u7b97\u6700\u591a\u652f\u6301 8 \u8282\u5217\u8f66\uff0c\u5b8c\u5168\u5bb9\u7eb3\u9ad8\u8fbe 0x7FFFFFFF \u8303\u56f4\u7684\u5b57\u7b26\u3002\u4e3a\u4e86\u8ba9 Windows \u8fd8\u80fd\u7ee7\u7eed\u7528\uff0cUnicode \u624d\u88ab\u8feb\u6b62\u6b65 0x10FFFF\uff0cUTF-8 \u4e5f\u7ec8\u7ed3\u4e8e 4 \u8282\u5217\u8f66\u3002 \u5e94\u7528\u573a\u666f\uff1a\u901a\u5e38\u8ba4\u4e3a\uff0cUTF-16 \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff0c\u65b0\u8f6f\u4ef6\u4e0d\u5e94\u8be5\u518d\u4f7f\u7528 UTF-16\u3002\u53ea\u6709\u5728\u548c\u8fd9\u4e9b\u7cdf\u7c95\u8f6f\u4ef6\u7684 API \u6253\u4ea4\u9053\u65f6\uff0c\u624d\u5fc5\u987b\u8f6c\u6362\u4e3a UTF-16\u3002\u4f46\u4e5f\u6709\u4eba\u6307\u51fa\uff1aUTF-16 \u662f\u7eaf\u4e2d\u6587\u538b\u7f29\u7387\u6700\u9ad8\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u6240\u4ee5 UTF-16 \u8fd8\u6bd4\u8f83\u9002\u5408\u7eaf\u4e2d\u6587\u6216\u4ee5\u4e2d\u6587\u5185\u5bb9\u4e3a\u4e3b\u7684\u6587\u672c\u6570\u636e\u538b\u7f29\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-16 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8c03\u7528 Windows \u7cfb\u7edf API \u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u76f4\u63a5\u5c31\u80fd\u8c03\u7528\uff0c\u6700\u9002\u5408 Windows \u672c\u5730\u5f00\u53d1\uff0c\u975e\u8de8\u5e73\u53f0\u3002\u4e14\u5bf9\u7eaf\u4e2d\u6587\u5185\u5bb9\u53ef\u6bd4 UTF-8 \u989d\u5916\u8282\u7701 33% \u7a7a\u95f4\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e Windows \u4ee5\u5916\u7684\u7cfb\u7edf\u5c31\u9700\u8981\u8f6c\u6362\u56de UTF-8\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u5f00\u9500\u3002\u4e14\u5982\u679c\u5b58\u50a8\u7684\u5185\u5bb9\u4e3b\u8981\u662f\u7eaf\u82f1\u6587\uff0c\u5982 XML \u4ee3\u7801\u7b49\uff0c\u5185\u5b58\u5360\u7528\u4f1a\u6bd4 UTF-8 \u7ffb\u500d\u3002\u800c\u4e14 UTF-16 \u4ecd\u7136\u662f\u53d8\u957f\u7f16\u7801\uff0c\u867d\u7136\u51fa\u73b0\u53d8\u957f\u7684\u6982\u7387\u8f83\u4f4e\uff0c\u4f46\u4e0d\u4e3a 0\uff0c\u4ecd\u9700\u8981\u5f00\u53d1\u8005\u505a\u7279\u6b8a\u5904\u7406\u3002\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u4f1a\u5bfc\u81f4\u751f\u50fb\u5b57\u7b26\u51fa\u9519\uff0c\u5b57\u7b26\u4e32\u4ee5\u7801\u70b9\u4e3a\u5355\u4f4d\u7684\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4ecd\u7136 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002\u5e76\u4e14 UTF-16 \u6709\u5927\u5c0f\u7aef\u8f6c\u6362\u7684\u95ee\u9898\u3002 \u4ee3\u8868\u4f5c\uff1aWindows \u7cfb\u7edf API\u3001Java \u8bed\u8a00\u3001Windows \u6587\u4ef6\u7cfb\u7edf (NTFS)\u3001Qt\u3001Word\u3001JSON\uff0c\u4ed6\u4eec\u90fd\u662f UTF-16 \u7684\u53d7\u5bb3\u8005\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-16 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-16 \u4f9d\u7136\u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5904\u7406\u6ca1\u95ee\u9898\uff0c\u751f\u50fb\u5b57\u5c31\u5bb9\u6613\u51fa\u95ee\u9898\uff0c\u4e14\u56e0\u4e3a\u51fa\u73b0\u6982\u7387\u4f4e\uff0c\u5f88\u5bb9\u6613\u4e0d\u53d1\u73b0\uff0c\u57cb\u4e0b\u9690\u60a3\u3002 Java \u5c31\u662f\u53d7\u5230\u4e86 UTF-16 \u5386\u53f2\u503a\u5f71\u54cd\uff0c char \u662f 16 \u4f4d\u7684\u7801\u4f4d\uff0c\u800c\u4e0d\u662f\u5b57\u7b26\uff0c\u771f\u6b63\u7684\u4e00\u4e2a\u5b57\u7b26\u662f 32 \u4f4d\u7684 Character \u7c7b\u578b\u3002 \u7f16\u7a0b\u8bed\u8a00 \u7801\u70b9\u7c7b\u578b (32 \u4f4d) \u7801\u4f4d\u7c7b\u578b (16 \u4f4d) Java Character char Java \u7684 Character \u7c7b\u578b\u662f\u4e00\u4e2a 32 \u4f4d\u7684\u503c\uff0c\u8fd9\u4e2a\u503c\u5305\u542b\u4e86\u4e00\u4e2a Unicode \u7801\u4f4d\u3002 char \u7c7b\u578b\u662f\u4e00\u4e2a 16 \u4f4d\u7684\u503c\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a UTF-16 \u7f16\u7801\u7684\u7801\u70b9\u3002 String \u7684 charAt() \u65b9\u6cd5\u8fd4\u56de\u7684\u662f char \u7c7b\u578b\u7684\u7801\u4f4d\uff08\u7c7b\u4f3c\u4e8e\u5b57\u8282\uff09\uff0c\u5982\u679c\u8981\u83b7\u53d6 Character \u7c7b\u578b\u7684\u5b8c\u6574\u5b57\u7b26\uff0c\u5fc5\u987b\u4f7f\u7528 codePointAt() \u65b9\u6cd5\u3002\u8fd9\u662f Java \u8bed\u8a00\u8bbe\u8ba1\u4e0a\u7684\u4e00\u4e2a\u5931\u8bef\uff0c\u5df2\u7ecf\u65e0\u6cd5\u6539\u53d8\u3002 \u800c\u540e\u7eed\u65b0\u51fa\u7684 Kotlin \u662f Java \u7684\u5408\u6cd5\u7ee7\u627f\u8005\uff0c\u4ed6\u679c\u65ad\u653e\u5f03 UTF-16\uff0c\u52a0\u5165\u4e86 UTF-32 \u9635\u8425\u3002\u53ef\u89c1\uff0c\u8001\u8f6f\u4ef6\u575a\u6301\u7528 UTF-16 \u662f\u56e0\u4e3a\u4ed6\u4eec\u79ef\u91cd\u96be\u8fd4\uff0c\u65b0\u8f6f\u4ef6\u518d\u7528 UTF-16 \u5c31\u662f\u81ea\u4f5c\u5b7d\u4e86\uff01 \u603b\u7ed3\uff1a\u4e0d\u8981\u652f\u6301 UTF-16 \u9635\u8425\uff0c\u9664\u975e\u4f60\u88ab\u8feb\u7ef4\u62a4\u53f2\u5c71\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u53d1\u5fae\u4fe1\u670b\u53cb\u5708\u65f6\uff0c\u8f93\u5165 Emoji \u8868\u60c5\u540e\u526a\u5207\uff0c\u518d\u7c98\u8d34\uff0c\u5c31\u548c\u53d1\u73b0\u4e00\u4e2a Emoji \u88ab\u5207\u65ad\u6210\u4e86\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4e71\u7801\u7684\u5f62\u5f0f\u663e\u73b0\u3002\u4f30\u8ba1\u662f\u56e0\u4e3a\u5fae\u4fe1\u57fa\u4e8e Java \u7f16\u5199\uff0c\u75bc\u900a\u7a0b\u5e8f\u5458\u5bf9 UTF-16 \u4ee3\u7406\u5bf9\u5904\u7406\u7684\u4e0d\u5229\u7d22\u3002 Java \u4e2d\u4ee5\u7801\u70b9\u904d\u5386\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5199\u6cd5\uff1a String s = \"\u4f60\u597d\"; // \u6309\u7801\u70b9\u904d\u5386 for (int i = 0; i < s.length();) { Character c = s.codePointAt(i); System.out.println(String.format(\"U+%04X\", c)); i += Character.charCount(c); } // \u6309\u7801\u4f4d\u904d\u5386 for (char c : s.toCharArray()) { System.out.println(String.format(\"U+%04X\", (int) c)); } \u7531\u4e8e JSON \u662f\u548c Java \u4e00\u5757\u53d1\u660e\u7684\u3002\u5bf9\u4e8e\u8d85\u51fa 0xFFFF \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u91c7\u7528\u7684\u8f6c\u4e49\uff0c\u4e5f\u662f\u57fa\u4e8e UTF-16 \u7f16\u7801\u3002\u5373\u540c\u4e00\u4e2a\u5b57\u4f1a\u53d8\u6210\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4fdd\u8bc1 JSON \u6587\u4ef6\u603b\u662f ASCII \u683c\u5f0f\uff0c\u907f\u514d Windows \u7684 GBK \u7f16\u7801\u4e71\u505a\u989d\u5916\u7684\u5e72\u6270\u3002 // \u4ee5\u4e0b\u4e24\u79cd\u5199\u6cd5\u7b49\u4ef7 {\"name\": \"\ud883\udede\"} {\"name\": \"\\ud883\\udfde\"} \u5728\u521a\u521a\u4ecb\u7ecd\u7684 C++ \u5e93 utfcpp \u4e2d\uff0c\u4e5f\u6709\u9488\u5bf9 UTF-16 \u7684\u8f6c\u6362\u51fd\u6570\uff0c\u5982 utf16to32 \uff1a std::u16string s = u\"\u4f60\u597d\"; std::u32string u32 = utf16::utf16to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\ud883\udede'; s = utf16::utf32to16(u32); fmt::println(\"{}\", s); // \u4f60\ud883\udede fmt::println(\"{}\", u32.size()); // 2 fmt::println(\"{}\", s.size()); // 3 UTF-32 \u9635\u8425 \u652f\u6301 Unicode\uff0c\u6bcf\u4e2a\u7801\u70b9\u90fd\u7528\u4e00\u4e2a uint32_t \u6216 char32_t \u8868\u793a\u3002 \u5e94\u7528\u573a\u666f\uff1a\u9002\u5408\u9700\u8981\u7ecf\u5e38\u5904\u7406\u6587\u5b57\u7684\u9886\u57df\uff0c\u5982\u6587\u672c\u7f16\u8f91\u5668\u3001\u6d4f\u89c8\u5668\u7b49\u3002\u4f46\u4e0d\u9002\u5408\u5b58\u50a8\u548c\u4f20\u8f93\uff0c\u56e0\u4e3a\u6d6a\u8d39\u786c\u76d8\u548c\u7f51\u7edc\u5e26\u5bbd\u3002\u5b57\u7b26\u4e32\u4e00\u822c\u90fd\u957f\u671f\u4ee5 UTF-8 \u5b58\u50a8\uff0c\u53ea\u6709\u5728\u9700\u8981\u9891\u7e41\u7d22\u5f15\u7801\u4f4d\u65f6\uff0c\u624d\u9700\u8981\u8f6c\u6362\u4e3a UTF-32\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-32 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u3001\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u90fd\u662f O(1) O(1) \u7684\u590d\u6742\u5ea6\uff0c\u53ef\u4ee5\u5f53\u4f5c\u666e\u901a\u6570\u7ec4\u4e00\u6837\uff0c\u968f\u610f\u5904\u7406\u3002\u4f8b\u5982\u4f60\u53ef\u4ee5\u8bbe\u60f3\u4e00\u4e2a\u6587\u672c\u7f16\u8f91\u6846\uff0c\u9700\u8981\u652f\u6301\u201c\u9000\u683c\u201d\u64cd\u4f5c\uff0c\u5982\u679c\u662f UTF-8 \u548c UTF-16 \u5c31\u9700\u8981\u7e41\u7410\u7684\u5224\u65ad\u4ee3\u7406\u5bf9\u3001\u5404\u79cd\u8f66\u53a2\uff0c\u800c UTF-32 \u7684\u5b57\u7b26\u4e32\u53ea\u9700\u8981\u4e00\u6b21 pop_back \u5c31\u641e\u5b9a\u4e86\u3002 \u7f3a\u70b9\uff1a\u6d6a\u8d39\u7a7a\u95f4\u5927\uff0c\u901a\u5e38\u5728\u4fdd\u5b58\u65f6\uff0c\u4ecd\u7136\u9700\u8981\u8f6c\u6362\u56de UTF-8 \u540e\u518d\u5199\u5165\u6587\u4ef6\uff0c\u6709\u4e00\u5b9a\u6027\u80fd\u5f00\u9500\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-32 \u9635\u8425\uff0c\u8bf7\u5168\u90e8\u4f7f\u7528 char32_t \u548c std::u32string \u3002\u5b57\u9762\u91cf\u5168\u7528 U\"\u4f60\u597d\" \u7684\u5f62\u5f0f\u4e66\u5199\uff0c\u8bfb\u6587\u4ef6\u65f6\u8f6c\u4e3a UTF-32\uff0c\u5199\u6587\u4ef6\u65f6\u8f6c\u56de UTF-8\u3002 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u7531\u4e8e C++26 \u524d\u6807\u51c6\u5e93\u5bf9\u7f16\u7801\u8f6c\u6362\u51e0\u4e4e\u6ca1\u6709\u652f\u6301\uff0c\u5728 C++ \u4e2d\u8f6c\u6362\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u5e38\u90fd\u9700\u8981\u7b2c\u4e09\u65b9\u5e93\u3002 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1a utfcpp \u5982\u679c\u4f60\u53ea\u662f\u9700\u8981\u4e0d\u540c UTF \u683c\u5f0f\u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u6ca1\u6709\u5904\u7406 GBK \u7b49\u7684\u9700\u6c42\uff1a\u90a3\u4e48\u4e4b\u524d\u5df2\u7ecf\u4ecb\u7ecd\u4e86 utfcpp \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5e93\uff0c\u5df2\u7ecf\u591f\u7528\u3002 #include \"utf8/cpp20.h\" std::u8string s8 = u8\"\u4f60\u597d\"; std::u16string s16 = utf8::utf8to16(s8); std::u32string s32 = utf8::utf8to32(s8); std::string s = utf8::utf16to8(s16); s8 = utf8::utf16tou8(s16); \u6700\u540e\u8fd9\u4e24\u4e2a\u533a\u522b\u5728\u4e8e\uff0c utf16to8 \u8fd4\u56de std::string \uff0c utf16tou8 \u8fd4\u56de std::u8string \uff0c\u91cc\u9762\u90fd\u662f UTF-8 \u7f16\u7801\u7684\uff0c\u4e0d\u8fc7\u6709\u7684\u4eba\u559c\u6b22\u7528 std::string \u6765\u5b58\u50a8 UTF-8\uff0c\u4e0d\u559c\u6b22 std::u8string \uff0c\u6216\u8005\u8bf4\u4ed6\u4eec\u6ca1\u6709 C++20\uff0c\u4e0d\u652f\u6301 std::u8string \uff0c\u56e0\u6b64\u8fd9\u4e2a\u5e93\u6ee1\u8db3\u4ed6\u4eec\u7684\u4e0d\u540c\u9700\u8981\u3002\u4f46\u662f std::u8string \u4f5c\u4e3a\u53c2\u6570\u65f6\u4e0d\u9700\u8981\uff0c\u56e0\u4e3a\u53c2\u6570\u53ef\u4ee5\u81ea\u52a8\u91cd\u8f7d\uff0c\u800c\u8fd4\u56de\u503c\u4e0d\u884c\u3002 \u7f3a\u70b9\u662f\u4ed6\u4e0d\u80fd\u5904\u7406 GBK\u3001Shift-JIS \u7b49\u975e Unicode \u7f16\u7801\uff0c\u4e5f\u4e0d\u80fd\u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u7684 ANSI \u533a\u57df\u8bbe\u7f6e\u3002 \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1a boost::locale \u5982\u679c\u4f60\u8fd8\u8981\u652f\u6301\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u6bd4\u5982 GBK\u3001Shift-JIS\u3001Latin-1\u3002 \u4e00\u79cd\u662f C \u8bed\u8a00\u7684 iconv \uff0c\u53e6\u4e00\u79cd\u662f\u73b0\u4ee3 C++ \u7684 boost::locale \u3002 \u867d\u7136\u529f\u80fd\u5dee\u4e0d\u591a\uff0c\u5e95\u5c42\u90fd\u662f\u8c03\u7528 icu \u7684\u3002 boost::locale \u7684 API \u66f4\u52a0\u53cb\u597d\uff0c\u800c\u4e14\u662f\u73b0\u4ee3 C++ \u98ce\u683c\u7684\u3002 # Ubuntu \u7528\u6237\u5b89\u88c5 Boost.locale \u65b9\u6cd5\uff1a $ sudo apt-get install libboost-locale-dev # Arch Linux \u7528\u6237\u5b89\u88c5 Boost \u5168\u5bb6\u6876\u65b9\u6cd5\uff1a $ sudo pacman -S boost \u4e0d\u559c\u6b22 Boost \u7684\u4eba\u6709\u96be\u4e86\u3002 UTF \u4e4b\u95f4\u4e92\u8f6c \u4f7f\u7528 boost::locale::conv::utf_to_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::utf_to_utf; int main() { std::string s8 = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c UTF-32\uff1a std::u32string s32 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-16\uff1a std::u16string s16 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-8\uff1a s8 = utf_to_utf(s32); std::cout << s8 << '\\n'; return 0; } \u6a21\u677f\u53c2\u6570\u4e2d\uff0c\u53ea\u9700\u6307\u5b9a\u8f6c\u6362\u5230\u7684\u662f\u4ec0\u4e48\u7c7b\u578b\u5c31\u884c\uff0c\u6765\u81ea\u4ec0\u4e48\u7c7b\u578b\uff0c\u4ed6\u81ea\u5df1\u4f1a\u91cd\u8f7d\u7684\u3002 \u6bd4\u5982\u4ece char32_t \u8f6c\u5230 char16_t \uff0c\u53ea\u9700\u8981 utf_to_utf \u5c31\u53ef\u4ee5\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7f16\u8bd1\uff1a $ g++ -std=c++17 -lboost_locale main.cpp \u8f93\u51fa\uff1a \u4f60\u597d \u5efa\u8bae\u7528\u540c\u6837\u8de8\u5e73\u53f0\u7684 CMake \u94fe\u63a5 Boost\uff0c\u5426\u5219 Windows \u7528\u6237\u8981\u6709\u96be\u4e86\u2026\u2026 find_package(Boost REQUIRED COMPONENTS locale) target_link_libraries(\u4f60\u7684\u7a0b\u5e8f Boost::locale) \u4e0d\u8fc7 boost::locale \u6709\u4e00\u4e2a\u7f3a\u70b9\uff0c\u90a3\u5c31\u662f\u4e0d\u652f\u6301 char8_t \u548c std::u8string \u3002 char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff01 \u7531\u4e8e Boost \u8f83\u8001\uff0c\u6ca1\u6709\u53ca\u65f6\u8ddf\u8fdb\uff0c\u6240\u4ee5\u4ed6\u5e76\u6ca1\u6709\u5b9e\u73b0\u9488\u5bf9 char8_t \u7684\u7279\u5316\uff0c\u5982\u679c\u4f7f\u7528\u4e86 utf_to_utf \u4f1a\u62a5 undefined reference \u9519\u8bef\uff0c\u5373\u627e\u4e0d\u5230\u7b26\u53f7\u3002\u6539\u6210 utf_to_utf \u5c31\u6ca1\u95ee\u9898\u4e86\u3002 GBK \u548c UTF \u4e92\u8f6c \u4f7f\u7528 boost::locale::conv::to/from_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::to_utf; using boost::locale::conv::from_utf; int main() { std::string s = \"\u4f60\u597d\"; // \u4ece GBK \u8f6c\u5230 UTF-16 std::wstring ws = to_utf(s, \"GBK\"); std::wcout << ws << '\\n'; // \u4ece UTF-16 \u8f6c\u56de GBK s = from_utf(ws, \"GBK\"); std::wcout << s << '\\n'; return 0; } \u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f GBK \u3001 Shift-JIS \u3001 Latin1 \u7b49\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u5b8c\u6574\u7684\u5217\u8868\u53ef\u4ee5\u5728\u770b\u5230\u3002 \u8fd9\u91cc to_utf \u4f1a\u81ea\u52a8\u5224\u65ad wchar_t \u7684\u5927\u5c0f\u3002\u5982\u679c\u662f 2 \u5b57\u8282\uff08Windows \u5e73\u53f0\u60c5\u51b5\uff09\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-16\uff0c\u5982\u679c\u662f 4 \u5b57\u8282\uff08Linux \u5e73\u53f0\u60c5\u51b5\uff09\uff0c\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-32\u3002 \u800c to_char \u5219\u662f\u65e0\u8bba\u4ec0\u4e48\u5e73\u53f0\uff0c\u90fd\u4f1a\u8f6c\u4e3a UTF-16\u3002 from_utf \u4e0d\u9700\u8981\u6307\u5b9a\u4efb\u4f55\u6a21\u677f\u53c2\u6570\uff0c\u56e0\u4e3a\u4ed6\u603b\u662f\u8fd4\u56de std::string \uff08ANSI \u6216 GBK \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff09\uff0c\u53c2\u6570\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4f1a\u81ea\u52a8\u901a\u8fc7\u91cd\u8f7d\u5224\u65ad\uff0c\u4f8b\u5982 from_utf(ws, \"GBK\") \u8fd9\u91cc\u7684\u53c2\u6570\u662f wchar_t \uff0c\u90a3\u4e48\u5728 Windows \u4e0a\uff0c\u4ed6\u4f1a\u68c0\u6d4b\u5230 wchar_t \u662f 2 \u5b57\u8282\uff0c\u5c31\u8ba4\u4e3a\u662f UTF-16 \u5230 GBK \u7684\u8f6c\u6362\u3002 UTF \u548c ANSI \u4e92\u8f6c \u6211\u4eec\u7a0b\u5e8f\u7684\u7528\u6237\u4e0d\u4e00\u5b9a\u662f\u4e2d\u56fd\u7528\u6237\uff08GBK\uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4fc4\u7f57\u65af\u7528\u6237\uff08CP1251\uff09\u3001\u65e5\u672c\u7528\u6237\uff08Shift-JIS\uff09\u3001\u897f\u73ed\u7259\u7528\u6237\uff08CP1252\uff09\u7b49\u3002 \u5982\u679c\u8981\u91c7\u7528\u7528\u6237\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u5373\u201cANSI\u201d\uff0c\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u7559\u7a7a\uff08 \"\" \uff09\u3002 \u7a7a\u5b57\u7b26\u4e32\u5c31\u8868\u793a\u91c7\u7528\u5f53\u524d\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e86\uff0c\u5728\u4e2d\u56fd\u5927\u533a\u7b49\u4ef7\u4e8e \"GBK\" \uff0c\u4fc4\u7f57\u65af\u5927\u533a\u7b49\u4ef7\u4e8e \"CP1251\" \u7b49\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::to_utf; int main() { setlocale(LC_ALL, \"\"); // \u5982\u679c\u4f60\u60f3\u7ed9 Boost \u7528\u7a7a\u5b57\u7b26\u4e32\uff0c\u9996\u5148\u9700\u8981\u8bbe\u7f6e\u4e00\u4e0b\u8fd9\u4e00\u884c std::string u8s = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c ANSI std::string s = from_utf(u8s, \"\"); // ANSI \u8f6c UTF-8 u8s = to_utf(s, \"\"); return 0; } setlocale(LC_ALL, \"\"); \u4e2d\u7684\u7a7a\u5b57\u7b26\u4e32\u8868\u793a \u5927\u603b\u7ed3 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-16 utf_to_utf UTF-x UTF-32 utf_to_utf UTF-x Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 UTF-x \u8868\u793a\u53d6\u51b3\u4e8e\u53c2\u6570\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u5982\u679c\u53c2\u6570\u662f char16_t \u7684\u5b57\u7b26\u4e32 std::u16string \uff0c\u90a3 x \u5c31\u662f 16\u3002 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-16 to_utf(\"GBK\", string) GBK UTF-32 to_utf(\"GBK\", string) GBK Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-32 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 from_utf(\"GBK\", string) UTF-8 GBK from_utf(\"GBK\", u16string) UTF-16 GBK from_utf(\"GBK\", u32string) UTF-32 GBK from_utf(\"GBK\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 GBK from_utf(\"\", string) UTF-8 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u16string) UTF-16 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u32string) UTF-32 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u533a\u57df\u8bbe\u7f6e GBK \u548c Shift-JIS \u4e92\u8f6c #include #include using boost::locale::conv::between; using boost::locale::conv::from_utf; int main() { // \u521b\u5efa\u4e00\u4e2a Shift-JIS \u5b57\u7b26\u4e32 std::string jis = from_utf(u8\"\u65e5\u672c\u8a9e\", \"Shift-JIS\"); // \u4ece Shift-JIS \u8f6c\u5230 GBK std::string gbk = between(jis, \"GBK\", \"Shift-JIS\"); std::cout << gbk << '\\n'; // \u4ece GBK \u8f6c\u56de Shift-JIS jis = between(gbk, \"Shift-JIS\", \"GBK\"); std::cout << jis << '\\n'; return 0; } \u6ce8\u610f\uff01\u662f\u76ee\u6807\u7f16\u7801\u5728\u524d\uff01\u5982\u679c\u4f60\u8981\u4ece Shift-JIS \u8f6c\u6210 GBK\uff0c\u90a3\u4e48\u9700\u8981 between(jis, \"GBK\", \"Shift-JIS\") \uff0c\u8fd9\u771f\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\u3002\u4e0d\u4ec5 GBK \u548c Shift-JIS \u53ef\u80fd\u4e0d\u5c0f\u5fc3\u5f04\u53cd\u4e86\uff0c\u7f16\u8bd1\u5668\uff0c\u4e00\u70b9\u63d0\u793a\u90fd\u6ca1\u6709\uff0c\u800c\u4e14 jis \u548c \u201cGBK\u201d \u90fd\u662f\u5b57\u7b26\u4e32\uff0c\u5f88\u5bb9\u6613\u5927\u8111\u641e\u6df7\u3002\u8ba9\u6211\u6765\u8bbe\u8ba1\u7684\u8bdd\uff0c\u6211\u4f1a\u8fd9\u6837\u63d0\u4f9b API\uff1a decode(jis, Encoding::ShiftJIS).encode(Encoding::GBK) \uff0c\u5176\u4e2d Encoding \u662f\u4e00\u4e2a\u679a\u4e3e\uff0c\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u4e0d\u4ec5\u907f\u514d\u72af\u9519\u7684\u673a\u4f1a\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u8f7b\u677e\u3002\u4e4b\u540e\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e13\u9898\u8bfe\u4e2d\uff0c\u4f1a\u518d\u8be6\u7ec6\u8bb2\u89e3\u4ec0\u4e48\u662f\u597d\u7684 API \u8bbe\u8ba1\u3002 \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u5982\u679c\u9047\u5230\u65e0\u6cd5\u7f16\u7801\u7684\u5b57\u7b26\uff0c\u8be5\u5982\u4f55\u5904\u7f6e\uff1f \u9ed8\u8ba4\u60c5\u51b5\u4e0b Boost \u4f1a\u5ffd\u89c6\u9519\u8bef\uff0c\u7f16\u7801\u5931\u8d25\u7684\u5b57\u7b26\u4f1a\u88ab\u4e22\u5f03\u3002 #include #include using boost::locale::conv::from_utf; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\"); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 std::cout << gbk << '\\n'; // \u5728 Windows \u7684 GBK \u7ec8\u7aef\u4e0a\uff0c\u53ea\u663e\u793a\u201c\u6211\u7231\u9762\u201d return 0; } \u53ef\u4ee5\u7528 method_type \u8fd9\u4e2a\u679a\u4e3e\u6765\u6307\u5b9a\u9519\u8bef\u5904\u7406\u7684\u65b9\u5f0f\u3002 \u9ed8\u8ba4\u662f skip \uff0c\u8df3\u8fc7\u6240\u6709\u89e3\u7801\u51fa\u9519\u7684\u5730\u65b9\uff08\u5bfc\u81f4\u201c\ud883\udede\u201d\u4e22\u5931\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230 stop \uff0c\u5f53\u9047\u5230\u89e3\u7801\u9519\u8bef\u65f6\uff0c\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\uff0c\u7ec8\u6b62\u7a0b\u5e8f\u6267\u884c\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\", method_type::stop); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 // from_utf \u4f1a\u629b\u51fa `conversion_error` \u5f02\u5e38 std::cout << gbk << '\\n'; return 0; } \u4e3e\u4f8b\uff1a\u5c1d\u8bd5\u4ee5 GBK \u4fdd\u5b58\uff0c\u5982\u679c\u5931\u8d25\uff0c\u5219\u6539\u4e3a\u5e26\u6709 BOM \u7684 UTF-8\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; using boost::locale::conv::conversion_error; void try_save(std::u32string content, std::wstring path) { std::string binary; try { // \u5c1d\u8bd5\u5c06 UTF-32 \u8f6c\u6210 GBK \u7f16\u7801 binary = from_utf(content, \"GBK\", method_type::stop); } catch (conversion_error const &e) { // \u82e5 GBK \u65e0\u6cd5\u8868\u793a // \u6539\u7528\u524d\u9762\u5e26\u6709 BOM \u7684 UTF-8 \u7f16\u7801 binary = \"\\xEF\\xBB\\xBF\" + utf_to_utf(content); } std::ofstream(path) << binary; } \u4e3e\u4f8b\uff1a\u652f\u6301 UTF-8 \u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f ANSI \u5b57\u7b26\u4e32\uff09\u7684\u6253\u5370\u51fd\u6570\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::utf_to_utf; static int dummy_init = (setlocale(LC_ALL, \"\"), 0); // \u9700\u8981\u8bbe\u7f6e\u8fc7 setlocale(LC_ALL, \"\") \u540e\uff0c\u624d\u80fd\u4f7f\u7528 Boost \u7684\u7a7a\u5b57\u7b26\u4e32\u5199\u6cd5 void u8print(std::string msg) { std::cout << from_utf(msg, \"\"); // \u6216\u8005\uff1a // std::wcout << utf_to_utf(msg); } \u6b64\u5904 static int dummy_init = \u662f\u4e00\u79cd\u9759\u6001\u521d\u59cb\u5316\u94a9\u5b50\u7684\u5c0f\u6280\u5de7\uff0c\u4e4b\u540e\u8bbe\u8ba1\u6a21\u5f0f\u8bfe\u7a0b\u7684\u5355\u4f8b\u6a21\u5f0f\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3\u3002 \u66f4\u591a\u529f\u80fd\uff1f\uff01 \u51fd\u6570 \u4ece \u5230 utf_to_utf UTF \u7cfb\u5217 UTF \u7cfb\u5217 from_utf UTF \u7cfb\u5217 \u6742\u724c\u5b57\u7b26\u7f16\u7801 to_utf \u6742\u724c\u5b57\u7b26\u7f16\u7801 UTF \u7cfb\u5217 between \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u66f4\u591a\u7ec6\u8282\u7528\u6cd5\u89c1\u5b98\u65b9\u6587\u6863\uff1ahttps://www.boost.org/doc/libs/1_81_0/libs/locale/doc/html/group__codepage.html \u4e0d\u53ef\u601d\u8bae\u7684\u662f\uff1a\u7f16\u7801\u8f6c\u6362\u53ea\u662f boost::locale::conv \u8fd9\u4e2a\u5b50\u6a21\u5757\u4e0b\u7684\u4e00\u4e2a\u5c0f\u529f\u80fd\u800c\u5df2\uff01 boost::locale \u8fd8\u63d0\u4f9b\u4e86\u66f4\u591a\u529f\u80fd\uff0c\u5982\u6309\u7167\u5730\u57df\u8bed\u8a00\u89c4\u8303\u683c\u5f0f\u5316\u6570\u5b57\u3001\u8d27\u5e01\u3001\u65e5\u671f\u3001\u65f6\u95f4\u7b49\uff0c\u4e0b\u4e00\u5c0f\u8282\u4e2d\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd\u3002\u5b8c\u5168\u662f std::locale \u7684\u4e0a\u4f4d\u66ff\u4ee3\u3002 Boost \u54ea\u91cc\u90fd\u597d\uff0c\u4f60\u60f3\u8981\u7684\u529f\u80fd\u5e94\u6709\u5c3d\u6709\u3002\u800c\u4e14\u4e0d\u9700\u8981 C++20\uff0c\u5f88\u4f4e\u7248\u672c\u7684 C++ \u4e5f\u80fd\u7528\u3002\u552f\u4e00\u7f3a\u70b9\u53ef\u80fd\u5c31\u662f\u592a\u80a5\u4e86\uff0c\u7f16\u8bd1\u6162\u3002 Windows \u7528\u6237\uff1aMultiByteToWideChar \u5982\u679c\u4f60\u662f Windows \u7a0b\u5e8f\u5458\uff0c\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u4e14\u9700\u8981\u5728 Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u89c4\u5b9a\u7684 ANSI\uff08\u5728\u4e2d\u56fd\u533a\u662f GBK\uff09\u7f16\u7801\u548c UTF-16 \u4e4b\u95f4\u8f6c\u6362\uff1a \u53ef\u4ee5\u7528 Windows \u5b98\u65b9\u63d0\u4f9b\u7684 MultiByteToWideChar \u548c WideCharToMultiByte \u51fd\u6570\u3002 \u8fd9\u4e24\u4e2a\u51fd\u6570\u56e0\u4e3a C \u8bed\u8a00\u7279\u8272\u7684\u7f18\u6545\uff0c\u53c2\u6570\u6bd4\u8f83\u591a\u800c\u6742\uff0c\u5efa\u8bae\u81ea\u5df1\u52a8\u624b\u5c01\u88c5\u6210\u66f4\u6613\u7528\u7684 C++ \u51fd\u6570\uff1a std::wstring ansi_to_wstring(const std::string &s) { // ACP = ANSI Code Page\uff0c\u544a\u8bc9\u4ed6\u5b57\u7b26\u4e32\u91cc\u7684\u662f\u5f53\u524d\u533a\u57df\u8bbe\u7f6e\u6307\u5b9a\u7684\u7f16\u7801\uff08\u5728\u4e2d\u56fd\u533a\uff0cANSI \u5c31\u662f GBK \u4e86\uff09 int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_ansi(const std::wstring &ws) { int len = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } std::wstring utf8_to_wstring(const std::string &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_utf8(const std::wstring &ws) { int len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } C \u8bed\u8a00\u7279\u8272\uff1a\u6240\u6709\u8981\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u90fd\u9700\u8981\u8c03\u7528\u4e24\u904d\uff0c\u7b2c\u4e00\u6ce2\u5148\u6c42\u51fa\u957f\u5ea6\uff0c\u7b2c\u4e8c\u6ce2\u624d\u5199\u5165\u3002\u8fd9\u662f\u4e3a\u4e86\u907f\u514d\u4e0e\u5185\u5b58\u5206\u914d\u5668\u8026\u5408\uff0c\u6240\u6709\u7684 C \u98ce\u683c API \u90fd\u662f\u8fd9\u6837\u3002 MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b \u590d\u73b0\u6761\u4ef6\uff1a Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e3a\u4e2d\u6587 (GBK)\u3002 \u4f7f\u7528 MSVC \u7684 /utf-8 \u9009\u9879\u7f16\u8bd1\u3002 #include int main() { MessageBoxA(nullptr, \"\u6211\u7231\ud883\udede\ud883\udede\u9762\", \"\u6807\u9898\", MB_OK); // \u4f1a\u53d8\u6210\u4e71\u7801 return 0; } Linux \u7528\u6237\uff1a iconv \u5982\u679c\u4f60\u662f Linux \u7528\u6237\uff0c\u4e14\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 iconv \u5e93\u3002 iconv \u4e5f\u6709 Windows \u7684\u7248\u672c\uff0c\u4f46\u5b89\u88c5\u6bd4\u8f83\u56f0\u96be\u3002\u5982\u679c\u4f60\u8fde iconv \u90fd\u641e\u5f97\u5b9a\uff0c\u6ca1\u7406\u7531 Boost \u641e\u4e0d\u5b9a\u3002 #include #include std::string convert(std::string const &s, char const *from, char const *to) { iconv_t cd = iconv_open(to, from); if (cd == (iconv_t)-1) { throw std::runtime_error(\"iconv_open failed\"); } auto in = s.data(); auto inbytesleft = s.size(); size_t outbytesleft = inbytesleft * 4; std::string buffer(outbytesleft, 0); auto out = buffer.data(); iconv(cd, &in, &inbytesleft, &out, &outbytesleft); iconv_close(cd); buffer.resize(buffer.size() - outbytesleft); return buffer; } // \u4e3e\u4f8b\uff1aUTF-8 \u8f6c GBK std::string utf8_to_gbk(std::string const &s) { return convert(s, \"UTF-8\", \"GBK\"); } // \u4e3e\u4f8b\uff1aGBK \u8f6c UTF-8 std::string gbk_to_utf8(std::string const &s) { return convert(s, \"GBK\", \"UTF-8\"); } iconv \u547d\u4ee4\u884c\u5de5\u5177 iconv \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u4e5f\u662f\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177\uff08\u5927\u591a Linux \u53d1\u884c\u7248\u90fd\u81ea\u5e26\u4e86\uff09\u3002\u7528\u6cd5\u5982\u4e0b\uff1a iconv -f \u6765\u81ea\u4ec0\u4e48\u7f16\u7801 -t \u5230\u4ec0\u4e48\u7f16\u7801 (\u8f93\u5165\u6587\u4ef6\u540d...) > \u8f93\u51fa\u6587\u4ef6\u540d \u5982\u4e0d\u6307\u5b9a\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u9ed8\u8ba4\u4ece\u7ec8\u7aef\u8f93\u5165\u6d41\u8bfb\u53d6\u3002 \u5982\u4e0d\u4f7f\u7528 > \u8f93\u51fa\u6587\u4ef6\u540d \u91cd\u5b9a\u5411\u8f93\u51fa\uff0c\u5219\u9ed8\u8ba4\u8f93\u51fa\u5230\u7ec8\u7aef\u3002 \u53ef\u4ee5\u7528 echo \u914d\u5408\u7ba1\u9053\u6765\u521b\u5efa\u8f93\u5165\u6d41\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 \u6b64\u5904\u663e\u793a\u4e71\u7801\u662f\u56e0\u4e3a\u6211\u7684\u7ec8\u7aef\u662f UTF-8 \u683c\u5f0f\uff0c\u65e0\u6cd5\u6b63\u786e\u89e3\u6790 iconv \u8f93\u51fa\u7684 GBK \u683c\u5f0f\u6570\u636e\u3002 \u628a\u201c\u6211\u7231\u5c0f\u5f6d\u8001\u5e08\u201d\u8f6c\u6362\u4e3a GBK \u683c\u5f0f\u5199\u5165 gbk.txt \uff0c\u7136\u540e\u518d\u91cd\u65b0\u8fd8\u539f\u56de UTF-8 \u683c\u5f0f\u67e5\u770b\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK > gbk.txt $ cat gbk.txt \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 $ iconv -f GBK -t UTF-8 gbk.txt \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 Windows \u53ef\u80fd\u4e5f\u6709\u7c7b\u4f3c\u7684\u5de5\u5177\uff0c\u6bd4\u5982 iconv.exe \uff0c\u4f46\u6211\u6ca1\u627e\u5230\u3002 \u672c\u5730\u5316 (locale) \u672c\u5730\u5316\u662f\u6307\u6839\u636e\u7528\u6237\u7684\u8bed\u8a00\u3001\u5730\u533a\u7b49\u73af\u5883\uff0c\u663e\u793a\u4e0d\u540c\u7684\u754c\u9762\u3002\u6bd4\u5982\u8bf4\uff0c\u540c\u6837\u662f\u6587\u4ef6\u83dc\u5355\uff0c\u4e2d\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201c\u6587\u4ef6\u201d\u3001\u82f1\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201cFile\u201d\u3002 \u533a\u5206\u5b57\u7b26\u7c7b\u578b C \u8bed\u8a00\u63d0\u4f9b\u4e86 \u5934\u6587\u4ef6\uff0c\u91cc\u9762\u5c01\u88c5\u4e86\u5927\u91cf\u5f62\u5982 isspace \u3001 isdigit \u8fd9\u6837\u7684\u5224\u65ad\u5b57\u7b26\u5206\u7c7b\u7684\u51fd\u6570\u3002 #include C++ \u5bf9\u5176\u5b9e\u65bd\u4e86\u518d\u5c01\u88c5\uff0c\u6539\u540d\u4e3a \u3002\u82e5\u4f60\u5bfc\u5165\u7684\u662f\u8be5\u5934\u6587\u4ef6\uff0c\u90a3\u4e48\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5e26\u6709 std \u540d\u5b57\u7a7a\u95f4\u524d\u7f00\u7684\u65b9\u5f0f std::isspace \uff0c std::isdigit \u8bbf\u95ee\u4e86\uff0c\u770b\u8d77\u6765\u66f4\u52a0\u4e13\u4e1a\uff08\u786e\u4fe1\uff09\u3002 #include \u51fd\u6570\u6e05\u5355\uff1a \u51fd\u6570\u540d\u79f0 \u5224\u65ad\u7684\u5b57\u7b26\u7c7b\u578b isascii 0 \u5230 0x7F \u7684\u6240\u6709 ASCII \u5b57\u7b26 isalpha \u5927\u5c0f\u5199\u5b57\u6bcd A-Z a-z isupper \u5927\u5199\u5b57\u6bcd A-Z islower \u5c0f\u5199\u5b57\u6bcd a-z isdigit \u6570\u5b57 0-9 isxdigit \u5341\u516d\u8fdb\u5236\u6570\u5b57 A-F a-f 0-9 isprint \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u5305\u62ec\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u6807\u70b9\u7b49 isgraph \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u4e0d\u5305\u62ec\u7a7a\u683c iscntrl \u63a7\u5236\u5b57\u7b26\uff0c\u9664\u53ef\u6253\u5370\u5b57\u7b26\u5916\u7684\u5168\u90e8 isspace \u7a7a\u767d\u5b57\u7b26\uff0c\u5982\u7a7a\u683c\u3001\u6362\u884c\u3001\u56de\u8f66\u3001\u5236\u8868\u7b26\u7b49 ispunct \u6807\u70b9\u7b26\u53f7 isalnum \u5b57\u6bcd\u6216\u6570\u5b57 \u66f4\u8be6\u7ec6\u7684\u8868\u683c\u53ef\u4ee5\u770b\uff1ahttps://en.cppreference.com/w/cpp/string/byte/isspace \u5bbd\u5b57\u7b26\u7c7b\u578b \u4e4b\u524d\u63d0\u5230\u7684\u5b57\u7b26\u90fd\u662f char \u7c7b\u578b\u7684 ASCII \u5b57\u7b26\uff0c\u8303\u56f4\u6700\u591a\u5728 0 \u5230 0x7F \u5185\u3002 \u5bf9\u53ea\u63a5\u53d7 char \u7684 isspace \uff0c ispunct \u7cfb\u5217\u51fd\u6570\uff0c\u53c2\u6570\u5982\u679c\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\uff0c\u7ed3\u679c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8981\u652f\u6301\u66f4\u5927\u8303\u56f4\u7684\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u7528 wchar_t \u7c7b\u578b\uff0c\u6216\u8005 char16_t \u548c char32_t \u3002 \u4e0e\u5b57\u7b26\u4e32\u5e38\u91cf\u4e00\u6837\uff0c\u5355\u4e2a\u5b57\u7b26\u4e5f\u53ef\u4ee5\u7528 L \u3001 u \u3001 U \u6765\u5206\u522b\u4ea7\u751f wchar_t \u3001 char16_t \u3001 char32_t \u7c7b\u578b\u7684\u5b57\u7b26\u3002 char c = '\u6211'; // \u7f16\u8bd1\u51fa\u9519\uff01char \u7c7b\u578b\u65e0\u6cd5\u5bb9\u7eb3\u6211 (0x6211) wchar_t wc = L'\u6211'; // \u7f16\u8bd1\u901a\u8fc7\uff0c\u7b49\u4ef7\u4e8e wc = 0x6211 \u548c const char * \u4e00\u6837\uff0c\u4e5f\u6709 const wchar_t \u8868\u793a\u8fd9\u79cd\u7531 Unicode \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff1a const wchar_t *ws = L\"\u4f60\u597d\uff0c\u4e16\u754c\"; assert(ws[2] == L'\uff0c'); wchar_t \u7684\u63d0\u51fa\u8d77\u521d\u662f\u4e3a\u4e86\u907f\u514d char \u7684\u533a\u57df\u8bbe\u7f6e\u5404\u81ea\u4e3a\u653f\uff0c\u7f16\u7801\u6df7\u4e71\u7684\u95ee\u9898\uff0c\u56e0\u4e3a wchar_t \u59cb\u7ec8\u662f UTF-16 (Windows) \u6216 UTF-32 (Linux)\u3002 wchar_t \u5e94\u7528\u6848\u4f8b std::string str = \"hello,world,universe\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, ',')) { std::cout << line << '\\n'; } \u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u5b57\u7b26\u4e32\u5206\u5272\u51fd\u6570\uff0c\u5b83\u4f1a\u628a hello \u6309\u7167\u9017\u53f7 \u201c,\u201d (0x2C) \u5206\u5272\uff0c\u7136\u540e\u8f93\u51fa\u3002 \u4f46\u662f\uff0c\u5b83\u65e0\u6cd5\u5904\u7406 Unicode \u5b57\u7b26 \u201c\uff0c\u201d (0xFF0C)\uff0c\u8fd9\u662f\u4e00\u4e2a\u5168\u89d2\u7684\u9017\u53f7\u3002\u56e0\u4e3a \u201c\uff0c\u201d \u4f1a\u88ab UTF-8 \u7f16\u7801\u6210\u4e09\u4e2a char \uff1a0xEF 0xBC 0x8C\u3002 std::string str = \"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, '\uff0c')) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u7b49\u4ef7\u4e8e '\\xEF\\xBC\\x8C'\uff0c\u4e00\u4e2a char \u5e38\u91cf\u91cc\u4e0d\u5f97\u5305\u542b\u4e09\u4e2a char\uff01 std::cout << line << '\\n'; } \u800c wchar_t \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a \u201c\uff0c\u201d \u5728 0xFFFF \u8303\u56f4\u5185\uff0c\u5373\u4f7f\u8003\u8651\u5230 Windows \u662f UTF-16 \u7f16\u7801\uff0c\u201c\uff0c\u201d \u53ea\u4f1a\u4ea7\u751f\u4e00\u4e2a wchar_t \u3002\u8fd9\u5bf9\u4ee5\u5355\u4e2a wchar_t \u4e3a\u5355\u4f4d\u7684 std::getline \u6765\u8bf4\u6ca1\u6709\u95ee\u9898\u3002 std::wstring str = L\"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::wstringstream ss(str); std::wstring line; while (std::getline(ss, line, L'\uff0c')) { // \u7f16\u8bd1\u901a\u8fc7\uff0c'\uff0c' \u662f\u5355\u4e2a UTF-16 \u7801\u4f4d std::wcout << line << L'\\n'; } \u533a\u57df\u8bbe\u7f6e\u4e0e locale \u8981\u8ba9 iswspace \u548c iswpunct \u8bc6\u522b\u4e2d\u6587\u9017\u53f7\u548c\u4e2d\u6587\u7a7a\u683c\uff0c\u6211\u4eec\u9700\u8981\u5148\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e00\u884c\u4ee3\u7801\uff1a setlocale(LC_ALL, \"C.utf-8\"); \u8fd9\u4f1a\u542f\u7528 Unicode \u5b57\u7b26\u96c6\uff0c\u4f7f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u80fd\u591f\u57fa\u4e8e Unicode \u5b57\u7b26\u96c6\u53bb\u5224\u65ad\u5b57\u7b26\u7c7b\u578b\uff0c\u800c\u4e0d\u662f\u9ed8\u8ba4\u7684 ASCII \u5b57\u7b26\u96c6\u3002 assert(ispunct(',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f ispunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L'\uff0c') == true);// 0xFF0C \u5bf9\u5e94\u7684\u5168\u89d2\u9017\u53f7\u4e5f\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 \u6bcf\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u4e00\u5f00\u59cb\uff0c\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \u3002\u9700\u8981\u8bbe\u7f6e\u4e3a \"C.UTF-8\" \u6216\u8005 \"zh_CN.UTF-8\" \uff0c\u603b\u4e4b\u662f\u652f\u6301 Unicode \u5b57\u7b26\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u624d\u80fd\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u8bc6\u522b\u8d85\u8fc7 ASCII \u8303\u56f4\u7684\u5b57\u7b26\u7684\u7c7b\u578b\u3002 fmt::println(\"\u9ed8\u8ba4: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C\"); fmt::println(\"C: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C.UTF-8\"); fmt::println(\"C.UTF-8: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"zh_CN.UTF-8\"); fmt::println(\"zh_CN.UTF-8: {}\", iswpunct(L'\uff0c')); \u8f93\u51fa\uff1a \u9ed8\u8ba4: 0 C: 0 C.UTF-8: 1 zh_CN.UTF-8: 1 \u603b\u4e4b\uff0c isw***** \u7cfb\u5217\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570 wchar_t \u8868\u793a\u8303\u56f4\u66f4\u5e7f\uff0c\u5728 Linux \u4e0a\u80fd\u8868\u793a\u6240\u6709 Unicode \u5b57\u7b26\uff0c\u5728 Windows \u4e0a\u80fd\u8868\u793a\u6240\u6709 0xFFFF \u4ee5\u5185\u7684\u5e38\u7528 Unicode \u5b57\u7b26\u3002 is***** \u7cfb\u5217\u51fd\u6570\u9047\u5230\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\u7684 char \u8fd8\u4f1a\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u975e\u5e38\u70e6\u4eba\u3002\u65e2\u7136 char \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a wchar_t \uff0c\u6240\u4ee5\u6211\u7684\u5efa\u8bae\u662f\u8bbe\u7f6e\u4e86 \".utf-8\" locale \u540e\uff0c\u5168\u90e8\u7528 isw***** \u53d6\u4ee3 is***** \u3002 locale \u7684\u547d\u540d\u89c4\u8303 \"zh_CN.UTF-8\" \u8fd9\u6837\u7684\u5b57\u7b26\u4e32\uff0c\u5c31\u662f locale \u7684\u540d\u5b57\uff0clocale \u540d\u5b57\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5206\u522b\u662f\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\u3002 \u8bed\u8a00.\u5b57\u7b26\u7f16\u7801 \"zh_CN.UTF-8\" \u5c31\u8868\u793a\uff0c\u4e00\u4e2a\u8bed\u8a00\u4e3a\u7b80\u4f53\u4e2d\u6587\uff0c\u7f16\u7801\u683c\u5f0f\u4e3a UTF-8 \u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u8981\u6ce8\u610f\u7684\u662f\uff0c\u7528\u6237\u5fc5\u987b\u5df2\u7ecf\u5b89\u88c5\u8fc7\u8be5\u533a\u57df\u8bbe\u7f6e\uff0c\u7a0b\u5e8f\u624d\u80fd\u4f7f\u7528 setlocale \u8bbe\u7f6e\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u627e\u4e0d\u5230 locale \u7684\u9519\u8bef\u3002 \u8fd9\u51e0\u4e4e\u5bfc\u81f4\u4f60\u6ca1\u6cd5\u7528\u9664\u9ed8\u8ba4\u5916\u7684\u4efb\u4f55 locale\uff0c\u6bd4\u5982 \"zh_CN.UTF-8\" \uff0c\u56e0\u4e3a\u4f60\u4e0d\u80fd\u786e\u5b9a\u7528\u6237\u6709\u6ca1\u6709\u5b89\u88c5\u4ed6\u3002\u4f46\u4f60\u53ef\u4ee5\u7528 boost::locale::generator \u51ed\u7a7a\u751f\u6210\u4e00\u4e2a\u7cfb\u7edf\u91cc\u6ca1\u6709\u5b89\u88c5\u8fc7\u7684 locale\uff0c\u7ed5\u5f00\u6807\u51c6\u5e93\u7684\u9650\u5236\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 Linux \u7528\u6237\u53ef\u4ee5\u901a\u8fc7 \u4fee\u6539 /etc/locale.gen \u53d6\u6d88\u6ce8\u91ca\u8981\u542f\u7528\u7684\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\uff0c\u4fdd\u5b58\u540e\uff0c\u8fd0\u884c locale-gen \u5373\u53ef\u5b89\u88c5\u6240\u6709\u6ca1\u6ce8\u91ca\u7684\u8bed\u8a00\u3002 sudo vim /etc/locale.gen sudo locale-gen \u53ef\u4ee5\u7528 locale -a \u547d\u4ee4\u67e5\u770b\u5df2\u7ecf\u5b89\u88c5\u4e86\u54ea\u4e9b locale\uff1a $ locale -a C C.utf8 POSIX en_US en_US.iso88591 en_US.utf8 zh_CN.gb18030 zh_CN.gbk zh_CN.utf8 \u6ce8\u610f\u5230\uff0clocale \u4e2d '.' \u53f7\u53f3\u8fb9\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u65e0\u89c6\u5927\u5c0f\u5199\u7684\uff0c\u800c\u4e14\u53ef\u4ee5\u7701\u7565\u6389 '-' \u3002\u6240\u4ee5 ISO-8859-1 \u53ef\u4ee5\u88ab\u7b80\u5199\u6210 iso88591 \uff0c UTF-8 \u88ab\u7b80\u5199\u6210 utf8 \u3002 \u5de6\u8fb9\u7684\u8bed\u8a00\u4e5f\u662f\u7528 '_' \u4e00\u5206\u4e3a\u4e8c\uff0c\u56fa\u5b9a\u662f '\u8bed\u8a00_\u5730\u533a' \u7684\u5199\u6cd5\u3002\u6bd4\u5982\u52a0\u62ff\u5927\u65e2\u6709\u82f1\u8bed\u7528\u6237\u53c8\u6709\u6cd5\u8bed\u7528\u6237\uff0c\u82f1\u8bed\u7684\u4ee3\u53f7\u662f 'en' \uff0c\u6cd5\u8bed\u7684\u4ee3\u53f7\u662f 'fr' \uff0c\u52a0\u62ff\u5927\u7684\u4ee3\u53f7\u662f 'CA' \uff0c\u6240\u4ee5\u5c31\u5b58\u5728\u7740 'en_CA' \u548c 'fr_CA' \u4e24\u79cd locale\u3002 \u4e5f\u6709\u4e00\u79cd\u8bed\u8a00\u88ab\u591a\u4e2a\u5730\u533a\u4f7f\u7528\u7684\u60c5\u51b5\uff0c\u4f8b\u5982\u4e2d\u6587\u7684\u4ee3\u53f7\u662f 'zh' \uff0c\u4ed6\u88ab\u4e2d\u56fd\u5927\u9646\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_CN' \uff0c\u88ab\u9999\u6e2f\u4f7f\u7528\u65f6\u53eb 'zh_HK' \uff0c\u88ab\u53f0\u6e7e\u7701\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_TW' \uff0c\u88ab\u65b0\u52a0\u5761\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_SG' \u3002 Windows \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b89\u88c5\u8bed\u8a00\u548c\u5730\u533a\u7684\u9009\u9879\uff0c\u4f46\u6bd4\u5c14\u76d6\u5b50\u5bf9 locale \u547d\u540d\u7684\u8bed\u6cd5\u7a0d\u6709\u4e0d\u540c\uff1a setlocale(LC_ALL, \"Chinese_China.936\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4ee3\u7801\u9875 936\uff08\u4e5f\u5c31\u662f GBK\uff09 \u4ed6\u7684\u8bed\u8a00\u540d\u4e0d\u662f\u6309\u7167\u56fd\u9645\u89c4\u8303\u7684 zh_CN \u8fd9\u6837\u7684\u7b80\u5199\uff0c\u800c\u662f Chinese_China \u3002 \u800c\u4e14\u540e\u9762\u7684 936 \u662f Windows \u79c1\u81ea\u5b9a\u4e49\u7684\u4e00\u5957\u6240\u8c13\u7684\u201c\u4ee3\u7801\u9875\u201d\uff0c\u8fd9\u91cc 936 \u5176\u5b9e\u5c31\u662f \u4e2d\u5b8f CP_GBK \u7684\u503c\uff0c\u8868\u793a GBK \u4ee3\u7801\u9875\u3002\u540c\u6837\u5730\u8fd8\u6709 65001 \u8868\u793a UTF-8 \u4ee3\u7801\u9875\u3002 setlocale(LC_ALL, \"Chinese_China.65001\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4f46\u662f\u542f\u7528 UTF-8 \u652f\u6301 setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 .65001 \u53ef\u4ee5\u7528\u522b\u540d .UTF-8 \u53d6\u4ee3\u3002\u4f46\u53ea\u6709 .UTF-8 \u652f\u6301\u8fd9\u4e2a\u522b\u540d\uff0c\u4f8b\u5982 .GBK \u4ed6\u5c31\u4e0d\u80fd\u8bc6\u522b\u3002 \u8bbe\u7f6e\u4e86 \"Chinese_China.utf-8\" \u6548\u679c\u548c\u4f60\u5728\u63a7\u5236\u9762\u677f\u5168\u5c40\u5f00\u4e86\u90a3\u4e2a \u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u5168\u7403\u8bed\u8a00\u5b9e\u9a8c\u652f\u6301\u201d \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u662f\u4ec5\u9650\u5f53\u524d\u8fdb\u7a0b\u7684 C/C++ \u6807\u51c6\u5e93\u3002 \u800c\u4e14\u7531\u4e8e argv \u5728\u4f60\u6765\u5f97\u53ca setlocale \u4e4b\u524d\u5c31\u5df2\u7ecf\u521d\u59cb\u5316\uff0c\u6240\u4ee5 main \u7684 argv \u53c2\u6570\u4f9d\u7136\u662f GBK \u7f16\u7801\u7684\uff0c\u9664\u975e\u4f60\u4f7f\u7528\u7684\u662f _wmain \uff0c\u90a3\u5c06\u80fd\u6536\u5230 UTF-16 \u7684 argv \uff0c\u7136\u540e\u4f60\u81ea\u5df1\u8f6c\u6362\u56de UTF-8\u3002 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u63a5\u53d7\u73af\u5883\u4e2d\u7684\u8bbe\u7f6e\uff0c\u5bf9\u4e8e Linux \u800c\u8a00\u662f $LC_ALL \u73af\u5883\u53d8\u91cf\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f\u63a7\u5236\u9762\u677f\u4e2d\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 setlocale(LC_ALL, \"\"); // \u662f\u7684\uff0c\u7a7a\u7684\u5b57\u7b26\u4e32 \u6ce8\u610f\u662f\u7a7a\u5b57\u7b26\u4e32 \"\" \u624d\u6709\u8fd9\u6837\u7684\u6548\u679c\uff0c\u800c\u4e0d\u662f NULL\uff01 setlocale(LC_ALL, NULL) \u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u4ed6\u7684\u6548\u679c\u662f\u8fd4\u56de\u5f53\u524d\u7684 locale\uff08\u6ca1\u60f3\u5230\u5427\uff1fsetlocale \u6709\u8fd4\u56de\u503c\uff09\u3002\u8fd9\u5c31\u662f C \u8bed\u8a00\u7684\u9b45\u529b\uff0c\u540c\u4e00\u4e2a\u51fd\u6570\u62c6\u6210\u597d\u51e0\u5206\u7528\uff0c\u53c8\u80fd set \u53c8\u80fd get\uff0c\u5c41\u80a1\u5341\u5206\u7075\u6d3b\u3002 \u4e5f\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u90e8\u5206\u4e3a\u7a7a\u7684 locale \u540d\u5b57\uff0c\u6bd4\u5982 \".utf-8\" \uff0c\u4ed6\u8868\u793a\u4fdd\u7559\u5f53\u524d\u73af\u5883\u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\uff0c\u4f46\u201c\u7f16\u7801\u201d\u90e8\u5206\u66ff\u6362\u4e3a\u201c.utf-8\u201d\u3002 setlocale(LC_ALL, \".utf-8\"); // \u5728\u4e2d\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u5728\u7f8e\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"English_United States.utf-8\"); \u7279\u6b8a locale\uff1a \"C\" \u4e0d\u559c\u6b22\u672c\u5730\u5316\u8fd9\u4e00\u5957\u8bbe\u5b9a\uff1f \u4f60\u53ef\u4ee5\u8bbe\u7f6e LC_ALL \u4e3a \"C\" \u6216 \"POSIX\" \uff0c\u8fd9\u662f\u6807\u51c6\u5e93\u9884\u5148\u5b9a\u4e49\u597d\u7684\u4e24\u4e2a locale\uff0c\u4ed6\u4eec\u7684\u7279\u70b9\u662f\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u672c\u5730\u5316\uff0c\u800c\u662f\u59cb\u7ec8\u4ee5\u82f1\u6587\u663e\u793a\u3002\u8fd9\u5728\u8c03\u8bd5\u7a0b\u5e8f\u65f6\u975e\u5e38\u6709\u7528\uff0c\u56e0\u4e3a\u8fd9\u6837\u4f60\u53ef\u4ee5\u786e\u5b9a\u8f93\u51fa\u7684\u683c\u5f0f\u662f\u56fa\u5b9a\u7684\uff0c\u4e0d\u4f1a\u88ab\u7528\u6237\u7684\u73af\u5883\u548c\u672c\u5730\u5316\u7684\u4fe1\u606f\u800c\u6539\u53d8\u3002 \u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u4f60\u6ca1\u6709 setlocale \u8fc7\uff0cC \u8bed\u8a00\u9ed8\u8ba4\u5c31\u662f \"C\" locale\uff0c\u4e0d\u4f1a\u53d7\u5230\u7528\u6237\u73af\u5883\u53d8\u91cf\u7684\u4efb\u4f55\u5f71\u54cd\uff08Windows \u7684\u6587\u4ef6\u7cfb\u7edf API \u9664\u5916\uff0c\u786e\u5b9e\u4f1a\u53d7\u5230 GBK \u5f71\u54cd\uff09\u3002 setlocale(LC_ALL, \"C\"); setlocale(LC_ALL, \"POSIX\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 \u4e0d\u8fc7\uff0c \"C\" \u610f\u5473\u7740\u4ed6\u5047\u5b9a\u5b57\u7b26\u4e32\u662f\u5b8c\u5168\u7684 ASCII\uff0c\u8d85\u8fc7 ASCII \u7684\u90e8\u5206\u662f\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff1a\u5bf9\u4e8e Linux \u800c\u8a00\u662f UTF-8\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u4e0d\u505a\u4efb\u4f55\u5904\u7406\uff0c\u56e0\u4e3a Linux \u7684 ext4 \u6587\u4ef6\u7cfb\u7edf\u6ca1\u6709\u5b57\u7b26\u7f16\u7801\u7684\u533a\u5206\uff09\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f GBK\uff08\u4e2d\u56fd\u533a\uff09\u3002 \u56e0\u6b64\uff0c\u4e5f\u6709 \"C.utf-8\" \u8fd9\u6837\u7684 locale\uff0c\u4ed6\u8868\u793a\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u53ef\u4ee5\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u652f\u6301 Unicode \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u4e5f\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6253\u5370 ASCII \u4ee5\u5916\u7684\u5b57\u7b26\u4e86\u3002\u53ea\u662f\u6ca1\u6709\u6307\u5b9a\u8bed\u8a00\uff0c\u901a\u5e38\u6765\u8bf4\u8fd9\u65f6 strerror \u4e00\u7c7b\u51fd\u6570\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u82f1\u8bed\u7684\u6d88\u606f\u3002 \u4f46\u4f3c\u4e4e\u53ea\u5728 Linux \u4e0a\u6709\u6548\uff0cWindows \u53ea\u652f\u6301 \"C\" \u800c\u4e0d\u652f\u6301 \"C.utf-8\" \u3002 LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf locale \u5206\u4e3a\u8bb8\u591a\u4e2a\u201c\u65b9\u9762 (facet)\u201d\uff0c\u4e0d\u540c\u7684\u65b9\u9762\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u53d6\u503c\uff08\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u662f\u4e00\u6837\u7684\uff09\uff0c\u53ef\u4ee5\u5ba2\u5236\u5316\u6807\u51c6\u5e93\u4e0d\u540c\u90e8\u5206\u6d89\u53ca\u8bed\u8a00\u548c\u7f16\u7801\u76f8\u5173\u7684\u884c\u4e3a\u3002\u8fd9\u4e9b\u65b9\u9762\u5728 C \u8bed\u8a00\u4e2d\u90fd\u6709\u4e00\u4e2a LC_ \u5f00\u5934\u7684\u679a\u4e3e\u6765\u8868\u793a\u3002 LC_CTYPE \u53ea\u5f71\u54cd ctype.h \u4e2d\u7684\u51fd\u6570\uff0c\u4e5f\u5c31\u662f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u8fd8\u6709 toupper \uff0c tolower \u7b49\uff0c\u4ed6\u8fd8\u5f71\u54cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\u65b9\u9762\u3002 LC_TIME \u5f71\u54cd\u65f6\u95f4\u548c\u65e5\u671f\u7684\u683c\u5f0f\u5316\uff0c\u4f8b\u5982 asctime \u7b49\u3002 LC_NUMERIC \u5f71\u54cd\u6570\u5b57\u7684\u683c\u5f0f\u5316\u3002 LC_MONETARY \u5f71\u54cd\u8d27\u5e01\u7684\u683c\u5f0f\u5316\u3002 LC_MESSAGES \u5f71\u54cd strerror \u7b49\u4fe1\u606f\u7c7b\u51fd\u6570\u8fd4\u56de\u7684\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\u5728\u4e2d\u6587 locale \u4e0b strerror(EPERM) \u4f1a\u8fd4\u56de \"\u6743\u9650\u4e0d\u591f\" \uff0c\u800c\u5728\u82f1\u6587 locale \u4e0b\u8fd4\u56de \"Permission denied.\" \u3002 LC_ALL \u662f\u5168\u5c40 locale\uff0c\u5b83\u4f1a\u5f71\u54cd\u4ee5\u4e0a\u6240\u6709\u6807\u51c6\u5e93\u51fd\u6570\u7684\u884c\u4e3a\u3002\u8bbe\u7f6e LC_ALL \u4e3a\u4e00\u4e2a\u503c\uff0c\u7b49\u540c\u4e8e\u4e3a\u4ee5\u4e0a\u6240\u6709\u90fd\u8d4b\u4e88\u7edf\u4e00\u7684\u503c\u3002 \u4f60\u53ef\u4ee5\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u8bbe\u7f6e $LC_ALL \u3001`$LC_CTYPE \u6240\u6709 GNU/Linux \u81ea\u5e26\u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u90fd\u5728 main \u51fd\u6570\u5f00\u5934\uff0c\u914d\u5907\u4e86 setlocale(LC_ALL, \"\"); \u3002\u8fd9\u4f1a\u8bfb\u53d6\u7528\u6237\u914d\u7f6e\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u533a\u57df\u504f\u597d\u8bbe\u7f6e\uff0c\u5e76\u8bbe\u4e3a\u5168\u5c40\u7684 locale\u3002 \u53ef\u4ee5\u7406\u89e3\u4e3a locale \u662f\u4e00\u4e2a\u9690\u85cf\u5728\u6807\u51c6\u5e93\u4e2d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u6240\u6709\u7684 iswpunct \u3001 asctime \u3001 strerror \u90fd\u4f1a\u8bfb\u53d6\u8be5\u5168\u5c40\u53d8\u91cf\u91cc\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u6765\u51b3\u5b9a\u81ea\u5df1\u7684\u8fd0\u884c\u65f6\u884c\u4e3a\u3002 LC_MESSAGES \uff1a\u62a5\u9519\u4fe1\u606f \u4f8b\u5982 touch \u8fd9\u4e9b\u547d\u4ee4\uff0c\u90fd\u662f\u57fa\u4e8e strerror \u6253\u5370\u62a5\u9519\u6d88\u606f\u7684\uff0c\u800c strerror \u53c8\u57fa\u4e8e\u533a\u57df\u8bbe\u7f6e\u7684 LC_MESSAGES \u65b9\u9762\u3002 \u8fd9\u4e9b\u547d\u4ee4\u884c\u7a0b\u5e8f\u7684\u4f5c\u8005\u65e0\u9700\u61c2\u5f97\u6240\u6709\u8bed\u8a00\uff0c\u4ed6\u4eec\u53ea\u9700\u8981\u8c03\u7528 strerror \u548c\u5404\u79cd messages \u67e5\u627e\u51fd\u6570\uff0c\u83b7\u5f97\u76f8\u5e94\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u540e\uff0c\u8f93\u51fa\u5373\u53ef\u81ea\u52a8\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7528\u6237\u7684\u9700\u6c42\u3002 \u53ea\u9700\u8981\u8bed\u8a00\u7684\u7528\u6237\uff0c\u5728\u4ed6\u7684\u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u8bbe\u7f6e LC_ALL=zh_CN.UTF-8 \u5c31\u53ef\u4ee5\u8ba9\u547d\u4ee4\u884c\u7a0b\u5e8f\u4eec\u59cb\u7ec8\u8f93\u51fa\u4e2d\u6587\u6d88\u606f\u4e86\u3002 $ export LC_MESSAGES=en_US.UTF-8 $ touch /root/a touch: cannot touch '/root/a': Permission denied $ export LC_MESSAGES=zh_CN.UTF-8 $ touch /root/a touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f \u4f8b\u5982 GCC \u7684\u62a5\u9519\u4fe1\u606f\uff0c\u5c31\u662f\u57fa\u4e8e\u4f60\u7684 $LC_MESSAGES \u73af\u5883\u53d8\u91cf\u6765\u51b3\u5b9a\u8f93\u51fa\u4f55\u79cd\u8bed\u8a00\u7684\u4fe1\u606f\u7684\u3002 \u4f60\u4e5f\u53ef\u4ee5\u53ea\u8bbe\u7f6e\u4e00\u4e2a export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u6837\u5c31\u65e0\u9700\u8bbe\u7f6e\u5176\u4ed6\u6240\u6709\u7684\u65b9\u9762 (facet)\uff0c\u5982\u65e0\u5355\u72ec\u8bbe\u7f6e\uff0c\u5176\u4ed6\u65b9\u9762\u4f1a\u81ea\u52a8\u53d8\u5f97\u548c $LC_ALL \u4e00\u6837\u3002 LC_CTYPE \uff1a\u5b57\u7b26\u7f16\u7801 \u8fd9\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\uff0c\u4ed6\u51b3\u5b9a\u4e86\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u683c\u5f0f\u3002 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u5185\u90e8\u90fd\u4ee5\u5185\u7801\uff08 const wchar_t * \u6216 std::wstring \uff09\u6765\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u5f53\u8f93\u51fa\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u7684\u5185\u7801\u5b57\u7b26\u4e32\uff08 wchar_t * \uff09\u4f1a\u4ee5 LC_CTYPE \u6307\u5b9a\u7684\u7f16\u7801\u683c\u5f0f\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6d41\uff08 const char * \u6216 std::string \uff09\u540e\u8f93\u51fa\u5230\u63a7\u5236\u53f0\u3002 \u56e0\u6b64\uff0c LC_CTYPE \u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\u662f\u65e0\u5173\u7d27\u8981\u7684\uff0c\u91cd\u8981\u7684\u662f\u540e\u534a\u6bb5\uff0c\u4f8b\u5982 \"zh_CN.UTF-8\" \uff0c\u90a3\u6709\u5f71\u54cd\u7684\u5c31\u53ea\u662f\u540e\u9762\u8fd9\u6bb5 \".UTF-8\" \u3002 \u52a1\u5fc5\u4f7f\u7528\u548c\u4f60\u7ec8\u7aef\u914d\u7f6e\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u4e71\u7801\u3002\u4f8b\u5982\u5f53\u6211\u6b3a\u9a97 touch \uff0c\u8ba9\u4ed6\u8bef\u4ee5\u4e3a\u6211\u7684\u7ec8\u7aef\u8f93\u51fa\u9700\u8981\u662f GBK \u7f16\u7801\uff1a $ export LC_MESSAGES=zh_CN.UTF-8 $ export LC_CTYPE=zh_CN.GBK # \u6b3a\u9a97 touch\uff01\u597d\u574f $ touch /root/a touch: \ufffd\u07b7\ufffd touch '/root/a': \u0228\ufffd\u07b2\ufffd\ufffd\ufffd \u4ed6\u5c31\u8f93\u51fa\u4e86\u8be1\u5f02\u7684\u4e71\u7801\u3002\u8fd9\u4e0d\u662f touch \u7684\u95ee\u9898\uff0ctouch \u53ea\u662f\u6309\u7167\u4f60\u73af\u5883\u53d8\u91cf $LC_CTYPE \u8bf4\u7684 GBK \u7f16\u7801\uff0c\u8f93\u51fa\u4e86 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u3002\u800c\u7ec8\u7aef\u7684\u8bbe\u7f6e\u5374\u662f UTF-8\uff0c\u7528 UTF-8 \u89e3\u7801 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u5f53\u7136\u51fa\u9519\u4e86\uff0c\u4e0d\u8fc7\u7531\u4e8e GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u8fd9\u91cc\u9762\u82f1\u6587\u90e8\u5206\u624d\u4fa5\u5e78\u6b63\u5e38\u663e\u793a\u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\u8981\u4e48\u4f60 $LC_CTYPE \u8bbe\u56de UTF-8\uff0c\u8981\u4e48\u628a\u7ec8\u7aef\u6539\u6210 GBK\uff0c\u603b\u4e4b $LC_CTYPE \u5fc5\u987b\u548c\u7ec8\u7aef\u5b57\u7b26\u7f16\u7801\u914d\u7f6e\u4e00\u6837\u3002\u4e5f\u53ef\u4ee5\u8c03\u7528 iconv \u628a touch \u7684 GBK \u8f93\u51fa\u8f6c\u6362\u56de UTF-8\uff0c\u4f9b UTF-8 \u7684\u7ec8\u7aef\u8bfb\u53d6\uff1a $ touch /root/a 2>&1 | iconv -f GBK -t UTF-8 touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f LC_TIME \uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 LC_TIME \u5f71\u54cd\u7684\u662f\u548c\u65f6\u95f4\u6709\u5173\u51fd\u6570\u7684\u8f93\u51fa\u683c\u5f0f\uff0c\u56e0\u4e3a\u4e0d\u540c\u7684\u5730\u533a\u6709\u4e0d\u540c\u7684\u65f6\u95f4\u663e\u793a\u4e60\u60ef\uff0c\u6bd4\u5982\u82f1\u6587\u662f Jan 1 00:00 \uff0c\u4e2d\u6587\u662f 1\u6708 1\u65e5 00\u65f600\u5206 \uff0c\u800c\u65e5\u672c\u4eba\u5219\u662f 1\u67081\u65e5 0\u66420\u5206 \u3002 $ export LC_TIME=en_US.UTF-8 $ date Fri Jul 19 04:01:49 PM CST 2024 $ export LC_TIME=zh_CN.UTF-8 $ date 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16:01:07 CST \u5728 C \u8bed\u8a00\u4e2d\uff0c\u4f60\u53ef\u4ee5\u7528\u8fd9\u6837\u683c\u5f0f\u5316\u65f6\u95f4\u548c\u65e5\u671f\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); struct tm *tm = localtime(&t); char buf[32]; strftime(buf, sizeof(buf), \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\", tm); puts(buf); } C++ \u63d0\u4f9b\u4e86\u57fa\u4e8e\u6d41\u7684\uff0c\u66f4\u201c\u65f6\u5c1a\u201d\u7684\u5199\u6cd5\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); tm *tm = localtime(&t); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 std::locale \u5bf9\u8c61 C \u8bed\u8a00\u7684 setlocale \u8bbe\u7f6e\u7684\u662f\u5168\u5c40 locale\uff0c\u5168\u5c40 locale \u53ea\u6709\u4e00\u4e2a\uff0c\u4e00\u8bbe\u5c31\u5f71\u54cd\u6240\u6709\u7ebf\u7a0b\uff0c\u975e\u5e38\u6c99\u96d5\u3002\u56e0\u6b64\u63d0\u5021\u201c\u4e0d\u8981\u72b6\u6001\u673a\u8981\u5bf9\u8c61\u201d\u7684 C++\uff0c\u5c01\u88c5\u4e86 std::locale \u5bf9\u8c61\u3002 std::locale \u7684\u6784\u9020\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u548c setlocale \u7684\u60c5\u51b5\u4e00\u6837\uff0c\u6709\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u73af\u5883 locale\uff0c \"C\" \u8868\u793a POSIX locale\uff0c\u8fd8\u6709\u81ea\u5b9a\u4e49\u5b57\u7b26\u4e32\u6bd4\u5982 \"zh_CN.UTF-8\" \u7684 locale\u3002 \u7136\u540e\uff0cC++ \u7684\u6d41\u7c7b\u578b\uff0c\u5982 std::cout \uff0c\u90fd\u6709\u4e00\u4e2a .imbue \u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u5c40\u90e8 locale\uff08\u53ea\u5bf9 std::cout \u751f\u6548\u7684\uff09\uff0c\u63a5\u53d7\u7684\u5c31\u662f\u8fd9\u4e2a std::locale \u5bf9\u8c61\u3002 #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 2024\u5e74 07\u6708 19\u65e5 Fri 16\u65f6 01\u5206 \u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\u53ea\u6709\u661f\u671f\u7684\u5b57\u7b26\u4e32\u53d7\u5230\u4e86\u5f71\u54cd\u3002\u5982\u679c\u8981\u4f7f\u6574\u4e2a\u65e5\u671f\u683c\u5f0f\u90fd\u8ddf\u968f LC_TIME \u7684\u8bbe\u5b9a\uff0c\u53ef\u7528 \"%c\" \uff1a #include #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%c\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%c\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e7407\u670819\u65e5 \u661f\u671f\u4e94 16\u65f633\u520639\u79d2 Fri 19 Jul 2024 04:33:39 PM CST \u5173\u4e8e \"%c\" \u3001 \"%Y\" \u8fd9\u4e9b\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u7684\u66f4\u591a\u8be6\u7ec6\u7528\u6cd5\uff0c\u53c2\u89c1 man strftime \u3002\u6211\u4eec\u4f5c\u4e3a\u5b57\u7b26\u7f16\u7801\u7684\u8bfe\u7a0b\u4e0d\u518d\u8d58\u8ff0\uff0c\u4e4b\u540e\u7684\u65f6\u95f4\u4e0e\u65e5\u671f\u4e13\u9898\u8bfe\u4e5f\u4f1a\u7a0d\u5fae\u8bb2\u4e00\u4e0b\u3002 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale boost::locale::generator gen; auto loc = gen(\"zh_CN.UTF-8\"); boost::locale::date_time dt = boost::locale::date_time::now(loc); std::cout << boost::locale::as::date(dt) << '\\n'; \u5bbd\u5b57\u7b26\u6d41 \u4e4b\u6240\u4ee5\u628a\u5bbd\u5b57\u7b26\u6d41\u653e\u5230\u6700\u540e\uff0c\u662f\u56e0\u4e3a\uff0c\u9996\u5148 iostream \u672c\u6765\u5c31\u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728\u672c\u4e66\u5f00\u5934\u5c31\u591a\u6b21\u5f3a\u8c03\u8fc7\u4ed6\u662f format \u5b5d\u5b50\u3002 \u800c\u5bbd\u5b57\u7b26 wchar_t \u672c\u8eab\u5c31\u5145\u65a5\u7740\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff08\u4f8b\u5982 Windows \u88ab UTF-16 \u80cc\u523a\uff09\u3002 \u73b0\u5728 iostream \u4e0e wchar_t \u4e00\u8d77\u51fa\u73b0\u5728\u6211\u9762\u524d\uff0c\u4e0d\u80fd\u8bf4\u662f\u68a6\u5e7b\u8054\u52a8\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u7b54\u8fa9\u8d85\u4eba\u4e86\u3002 \u603b\u4e4b\uff0c\u6211\u4e2a\u4eba\u8fd8\u662f\u63a8\u8350\u7a0b\u5e8f\u5185\u90e8\u4ee5 UTF-8\uff08 char8_t \uff09\u6216 UTF-32\uff08 char32_t \uff09\u7684\u5b57\u7b26\u4e32\u6765\u5904\u7406\u4e07\u7269\u3002 UTF-8 \u6216 UTF-32 \u7684\u9009\u62e9\u53d6\u51b3\u4e8e\u4f60\u7684\u4e2d\u6587\u5904\u7406\u9700\u6c42\u662f\u5426\u65fa\u76db\uff0c\u662f\u5426\u5728\u4e4e\u7a7a\u95f4\uff0c\u662f\u5426\u9700\u8981\u5207\u7247\u548c\u7d22\u5f15\u7b49\u3002 \u5f53\u9700\u8981\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u8bfb\u5199\u6587\u4ef6\u65f6\uff0c\u518d\u7528 boost::locale \u3001 utfcpp \u7b49\u5de5\u5177\u8f6c\u6362\u6210 ANSI\uff08 char \uff09\u6216 UTF-16\uff08 wchar_t \uff09\u3002 \u5bf9\u4e8e Linux \u7528\u6237\uff0c\u4e5f\u53ef\u4ee5\u68c0\u6d4b\u5982\u679c\u662f Linux \u7cfb\u7edf\uff0c\u5219\u4ec0\u4e48\u8f6c\u6362\u90fd\u4e0d\u505a\uff0c\u56e0\u4e3a Linux \u7528\u6237\u51e0\u4e4e\u90fd\u662f UTF-8\uff0c\u90a3\u4e48 const char8_t * \u53ef\u4ee5\u5f3a\u8f6c\u4e3a const char * \u800c\u4e0d\u7528\u4efb\u4f55\u989d\u5916\u5f00\u9500\u3002 std::string to_os_string(std::string const &u8s) { #if _WIN32 // UTF-8 \u5230 ANSI return boost::locale::conv::from_utf(u8s, \"\"); #elif __linux__ // \u4e0d\u8f6c\u6362 return u8s; #else #error \"Unsupported system.\" #endif } \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u5b9e\u5728\u8981\u5b66\u7cdf\u7cd5\u7684\u5bbd\u5b57\u7b26\u6d41\uff0c\u90a3\u6211\u4e5f\u5949\u966a\u5230\u5e95\u3002 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring \u5728\u4ed6\u4eec\u770b\u6765\uff0c std::string \u662f\u5df2\u7ecf\u5e9f\u5f03\u7684\u3002\u4ed6\u4eec\u8ba4\u4e3a std::wstring \u624d\u662f\u771f\u6b63\u8de8\u5e73\u53f0\u7684\u5b57\u7b26\u4e32\u3002 std::wstring : \u5b57\u7b26\u4e32 std::string : \u5b57\u8282\u6570\u7ec4 std::wifstream : \u6587\u672c\u6d41 std::ifstream : \u4e8c\u8fdb\u5236\u6d41 \u770b\u8d77\u6765\u53ea\u8981\u5168\u90e8\u7edf\u4e00 wchar_t \u5c31\u80fd\u5b9e\u73b0\u8de8\u5e73\u53f0\u4e86\uff1f\u662f\u7684\uff0c\u9664\u4e86 Windows\u2026\u2026 \u6807\u51c6\u8ba4\u4e3a wchar_t \u5e94\u8be5\u5305\u542b 0 \u5230 0x10FFFF \u7684\u6240\u6709\u7684 Unicode \u5b57\u7b26\u7801\u70b9\uff0c\u9700\u8981\u662f 32 \u4f4d\u7684\u3002\u7136\u800c Windows \u7684 wchar_t \u7531\u4e8e\u5386\u53f2\u539f\u56e0\uff0c\u662f 16 \u4f4d\u7684\uff0c\u9700\u8981\u7528\u4ee3\u7406\u5bf9\u624d\u80fd\u8868\u793a\u7a00\u6709\u5b57\u7b26\uff0c\u5e76\u4e0d\u80fd\u4e00\u4e2a wchar_t \u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002\u8fd9\u5bfc\u81f4\u5373\u4f7f\u7528\u4e86 wchar_t \u8fd8\u662f\u5b58\u5728\u8de8\u5e73\u53f0\u56f0\u96be\u7684\u95ee\u9898\uff1a\u4e00\u4e2a Linux \u7a0b\u5e8f\u7528 wchar_t \u53ef\u80fd\u4f1a\u5229\u7528 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u7279\u6027\uff0c\u65b9\u4fbf\u4e86\u6587\u672c\u5904\u7406\uff0c\u4f46\u79fb\u690d\u5230 Windows \u65f6\uff0c\u53d1\u73b0\u53d8\u6210\u4e86 UTF-16\uff0c\u9700\u8981\u5bf9\u4ee3\u7406\u5bf9\u505a\u7279\u6b8a\u5224\u65ad\u2026\u2026\u6ca1\u6709\u6ee1\u8db3\u8de8\u5e73\u53f0\u7684\u521d\u8877\uff0c\u4e5f\u505a\u4e0d\u5230\u5b9a\u957f\u7f16\u7801\u3002 char32_t \u505a\u5230\u4e86\u8de8\u5e73\u53f0\u7684 UTF-32\uff0c\u4e5f\u80fd\u5bb9\u7eb3\u5168\u90e8 Unicode \u7801\u70b9\uff0c\u53ef\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::to_wstring \uff0c\u5374\u6839\u672c\u6ca1\u6709 std::to_u32string \uff1b\u63d0\u4f9b\u4e86 std::wcout \uff0c\u5374\u6ca1\u6709\u63d0\u4f9b std::u32cout \u2026\u2026 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u5bbd\u5b57\u7b26\u6d41\u5f88\u7cdf\u7cd5\uff0c\u8bf4\u662f\u8de8\u5e73\u53f0\uff0c\u8de8\u4e86\u4e2a\u5bc2\u5bde\u3002 std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 \u8981\u4f7f\u7528 std::wcout \u4e4b\u524d\uff0c\u9700\u8981\u7528 .imbue \u8bbe\u7f6e\u5e26\u6709\u6b63\u786e LC_CTYPE \u65b9\u9762\u7684 locale\uff0c\u6216\u8005\u8bbe\u7f6e\u4e86 C \u8bed\u8a00\u7684\u5168\u5c40\u7684 setlocale \uff0c\u5426\u5219\u4e2d\u6587\u5b57\u7b26\u4f1a\u88ab\u4e22\u6389\u3002 int main() { std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u9519\u8bef\uff01\u4f60\u8fd8\u6ca1\u8bbe\u7f6e locale \u5462\uff01 return 0; } \u8f93\u51fa\uff1a Hello, ??! \u8fd9\u662f\u56e0\u4e3a\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \uff0c\u4ed6\u53ea\u652f\u6301 ASCII \u7684\u3002\u800c\u5f53 std::wcout \u9047\u5230\u8d85\u51fa\u5f53\u524d locale \u5b57\u7b26\u96c6\u8868\u793a\u8303\u56f4\u7684\u5b57\u7b26\u65f6\uff0c\u4f1a\u4e22\u5f03\uff0c\u66ff\u6362\u4e3a ? \u5b57\u7b26\uff0c\u8868\u793a\u51fa\u9519\u4e86\u3002 \u56e0\u6b64\uff0c std::wcout \u7684\u6b63\u786e\u7528\u6cd5\u5fc5\u987b\u662f\u5728\u4f60\u6253\u5370\u7b2c\u4e00\u6761\u8f93\u51fa\u524d\uff0c\u5c31 setlocale(LC_ALL, \"\") \uff0c\u9ed8\u8ba4\u7684 \"C\" \u80af\u5b9a\u662f\u4e0d\u884c\u7684\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u8f93\u51fa\uff1a Hello, \u4f60\u597d! \u6216\u8005\u7528 std::wcout \u7684 .imbue \u4e5f\u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u6837\u5bf9\u4e8e std::wcerr \u548c std::wclog \u4f60\u4e5f\u9700\u8981\u505a\u540c\u6837\u7684\u52a8\u4f5c\uff0c\u611f\u89c9\u4e0d\u5982\u7d22\u6027\u5168\u5c40\u8bbe\u7f6e\u4e86 setlocale \u65b9\u4fbf\u3002 int main() { std::wcout.imbue(std::locale(\"\")); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u5982\u679c\u4f60\u662f UTF-8 \u6d41\u6d3e\uff0c\u9009\u62e9 setlocale(LC_ALL, \".utf-8\") \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u53ea\u8981\u662f\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u7684 locale \u5c31\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6b63\u5e38\u8f93\u51fa\u4e2d\u6587\uff0c\u53ea\u8981\u4f60\u7ec8\u7aef\u7684\u8bbe\u7f6e\u4e5f\u662f\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\u7edd\u5bf9\u4e0d\u4f1a\u4e71\u7801\u3002 \u4f8b\u5982\u5f53\u4f60 setlocale(LC_ALL, \".utf-8\") \u540e\u5c31\u9700\u8981 system(\"chcp 65001\") \uff1b\u5f53\u4f60 setlocale(LC_ALL, \"Chinese_China.936\") \u540e\u5c31\u9700\u8981 system(\"chcp 936\") \u3002\u603b\u4e4b\uff0c\u59cb\u7ec8\u4fdd\u8bc1\u7ec8\u7aef\uff08 cmd \u6216 xfce4-terminal \uff09\u8bbe\u7f6e\u7684\u7f16\u7801\u548c\u4f60\u7a0b\u5e8f\u91cc setlocale(LC_CTYPE, ...) \u8bbe\u7f6e\u7684\u7f16\u7801\u4e00\u81f4\u3002 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u6709\u7684\u4eba\u4f1a\u7528 std::wcout \u4f3c\u4e4e\u4e5f\u80fd\u6253\u5370 char \u7684\u5b57\u7b26\u4e32\uff1f int main() { setlocale(LC_ALL, \"\"); std::wcout << \"Hello, \u4f60\u597d!\\n\"; // \u4e0d\u4e00\u5b9a\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587\uff01 std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // OK\uff0c\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587 return 0; } \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u7528\u6cd5\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u5e94\u8be5\u8981\u62a5\u9519\uff0c\u4f46\u662f\u7cdf\u7cd5\u7684\u6807\u51c6\u5e93\u5374\u6ca1\u6709\uff0c\u8bbe\u8ba1\u7684\u5931\u8bef\u3002 \u8bbe\u8ba1\u7684\u521d\u8877\u662f\uff0c\u53ef\u4ee5\u5728\u6253\u5370\u5e26\u4e2d\u6587\u7684\u5b57\u7b26\u4e32\u540e\uff0c\u65b9\u4fbf\u4f60\u4e34\u65f6\u6253\u5370\u4e00\u4e9b char \u7684\u5b57\u7b26\u4e32\u548c\u5b57\u7b26\uff0c\u4f8b\u5982 '\\n' \uff08\u56e0\u4e3a\u603b\u662f\u6709\u7684\u4eba\u60f3\u5077\u61d2\u4e0d\u5199 L\"\" \u524d\u7f00\uff09 std::wcout \u652f\u6301\u6253\u5370 char \u548c const char * \uff0c\u4ed6\u4f1a\u81ea\u52a8\u5e2e\u4f60\u628a\u8fd9\u90e8\u5206 char \u8f6c\u6210 wchar_t \u518d\u6253\u5370\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\" << L'\\n'; // \u6b63\u5e38\u5199\u6cd5 std::wcout << L\"Hello, \u4f60\u597d!\" << '\\n'; // \u61d2\u60f0\u72d7\u72d7\u5199\u6cd5 return 0; } \u4f46\u662f\uff0c\u8fd9\u90e8\u5206 char \u5e94\u5f53\u53ea\u5305\u542b ASCII \u5b57\u7b26\uff0c\u4e0d\u5e94\u8be5\u6709\u4e2d\u6587\u5b57\u7b26\uff0c\u5426\u5219\u53ef\u80fd\u53c8\u8981\u51fa\u73b0\u4e4b\u524d\u63d0\u5230\u7684 \u201cgalgame\u201d \u4e71\u7801\u95ee\u9898\u4e86\u3002 \u8d85\u7ea7\u5751\u70b9\uff1a std::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 \u975e\u5e38\u5751\u7684\u4e00\u4e2a\u70b9\uff1a\u4e00\u65e6\u4f60\u51b3\u5b9a\u7528 std::wcout \u540e\uff0c\u5c31\u4e0d\u80fd\u518d\u7528 std::cout \u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u5b9e\u6d4b\u7528\u8fc7 std::wcout \u540e\uff0c\u4f60\u7684 std::cout \u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4e0d\u51fa\u4efb\u4f55\u4e1c\u897f\u3002 \u4e0a\u4e86\u8d3c\u8239\u5c31\u4e0a\u5230\u5e95\u5427\uff01\u5982\u679c\u786e\u5b9e\u9700\u8981\u4e34\u65f6\u6253\u5370\u4e00\u4e9b std::string \uff0c\u5e76\u4e14\u786e\u4fdd\u91cc\u9762\u662f ASCII \u7684\u8bdd\uff0c\u53ef\u4ee5\u5229\u7528\u4e0a\u9762\u4e00\u8282\u8bf4\u7684\u201c\u61d2\u60f0\u72d7\u72d7\u5199\u6cd5\u201d\u7cca\u5f04\u4e0b\uff0c\u5982\u679c\u662f GBK \u6216 UTF-8 \u7684 std::string \u9700\u8981\u6253\u5370\u5230 std::wcout \uff0c\u5c31\u53ec\u5524\u4e00\u4e0b boost::locale \u5427\u3002 std::wprintf \u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5f53\u4f60\u7b2c\u4e00\u6b21\u4f7f\u7528 FILE * \u7684 wchar_t \u7cfb\u5217\u51fd\u6570\u540e\uff0c\u8fd9\u4e2a\u6587\u4ef6\u6d41\u4f1a\u88ab\u201c\u5bbd\u5316\u201d ( fwiden )\uff0c\u7528\u6211\u4eec\u7684\u8bdd\u8bf4\u53eb \u4e0a\u8d3c\u8239 \uff0c\u4e0a\u4e86\u5c31\u4e0b\u4e0d\u6765\uff0c\u518d\u4e5f\u65e0\u6cd5\u5f53\u4f5c\u201c\u7a84\u201d\u6d41\u7528\u4e86\u3002 \u53cd\u4e4b\u4ea6\u7136\uff0c\u4e00\u65e6\u4f60\u7528\u8fc7\u4e00\u6b21 std::cout \u540e\uff0c std::wcout \u5c31\u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4efb\u4f55\u4e1c\u897f\u90fd\u6253\u5370\u4e0d\u51fa\u6765\u3002\u53d6\u51b3\u4e8e\u4f60\u7b2c\u4e00\u6b21\u8c03\u7528\u8f93\u51fa\u6d41\u7528\u7684\u662f\u5bbd\u5b57\u7b26\u8fd8\u662f\u7a84\u5b57\u7b26\uff0c\u4e4b\u540e\u5c31\u53ea\u80fd\u4e00\u76f4\u7528\u90a3\u4e2a\u5bbd\u6216\u7a84\u4e86\uff0c\u4e0d\u8ba9\u8df3\u8239\u3002 \u4e0a\u8d3c\u8239\u4e0d\u884c\uff0c\u4e0a\u8b66\u8239\u4e5f\u4e0d\u884c\uff0c\u4e0a\u5b9a\u4e00\u4e2a\u5c31\u6ca1\u6cd5\u53d8\uff0c\u771f\u6076\u5fc3\u5440\uff01 // \u5148 wcout int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; std::cout << \"\u6211\u662f cout!\" << '\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f wcout! // \u5148 cout int main() { setlocale(LC_ALL, \"\"); std::cout << \"\u6211\u662f cout!\" << '\\n'; std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f cout! / wcout! \u8fd9\u91cc / wcout! \u597d\u50cf\u662f\u51fa BUG \u4e86\u2026\u2026\u4f30\u8ba1\u662f\u8d3c\u88ab\u8b66\u5bdf\u6253\u6389\u4e00\u534a\u8033\u6735\u53d8\u6210 / \u4e86\uff1f\u603b\u4e4b\u5404\u79cd\u6df7\u4e71\uff0c\u8bb0\u4f4f\u4e0d\u8981\u6df7\u7528\u8d3c\u8239\u548c\u8b66\u8239\u5c31\u884c\u4e86\u3002 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 \u6709\u540c\u5b66\u53cd\u6620\uff0cPython \u4e2d\u53ef\u4ee5\u901a\u8fc7 open('path.txt', encoding='gbk') \u6765\u7528\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u800c C++ \u4f3c\u4e4e\u6ca1\u6709\u7b49\u6548\u7684\u66ff\u4ee3\u54c1\u3002 \u5176\u5b9e\u4e00\u76f4\u90fd\u6709\uff0c\u4e0d\u8fc7\u4f60\u4e00\u76f4\u7528\u7684\u662f std::ifstream \u5b9e\u9645\u4e0a\u662f\u4e2a\u201c\u4e8c\u8fdb\u5236\u6d41\u201d\uff01\u8fd9\u79cd\u7eaf\u4e8c\u8fdb\u5236\u7684\u6d41\u6839\u672c\u5c31\u6ca1\u6253\u7b97\u652f\u6301\u5b57\u7b26\u7f16\u7801\u3002\u5373\u4f7f\u6307\u5b9a .imbue \u4e5f\u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u56e0\u4e3a .imbue \u7684\u524d\u63d0\u662f\u5b58\u5728\u201c\u5916\u7801 ( char ) \u5230\u5185\u7801 ( wchar_t ) \u7684\u8f6c\u6362\u201d\uff0c\u4f60\u4e8c\u8fdb\u5236\u6d41\u81f3\u59cb\u81f3\u7ec8\u90fd\u662f\u5916\u7801\uff0c\u54ea\u6765\u7684\u8f6c\u6362\uff1f\u53c8\u6ca1\u6709\u89c4\u5b9a char \u5fc5\u987b\u662f UTF-8\u3002 C++ \u771f\u6b63\u7684\u6587\u672c\u6d41\u5b9e\u9645\u4e0a\u662f\u5bbd\u5b57\u7b26\u6d41 std::wifstream \uff0c\u800c\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u7528 .imbue(std::locale(\"zh_CN.GBK\")) \u2026\u2026\u8bfb\u53d6\u65f6\u4f1a\u8c03\u7528 std::locale \u7c7b\u7684 std::codecvt \uff08\u662f LC_CTYPE \u7684\u4e00\u90e8\u5206\uff09\u65b9\u9762\uff0c\u8f6c\u6362\u4e3a wchar_t \uff0c\u7136\u540e\u8f93\u5165\u4f60\u7684 std::wstring \u3002 C \u548c C++ \u59d4\u5458\u4f1a\u5b98\u65b9\u5c31\u8ba4\u4e3a char * \u662f\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c wchar_t * \u624d\u662f\u6587\u672c\u6d41\uff01\u6240\u6709 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u91cc\u90fd\u662f\u7528 wchar_t \u6765\u5904\u7406\u6587\u672c\u6027\u8d28\u7684\u5b57\u7b26\u4e32\uff0c\u5305\u62ec GCC \u4e5f\u662f\u5927\u91cf\u4f7f\u7528 wchar_t \u4f5c\u4e3a\u5b57\u7b26\u5185\u90e8\u8868\u793a\u3002GCC \u8bfb\u53d6\u6e90\u7801\u6587\u4ef6\u5c31\u662f\u7528\u5bbd\u5b57\u7b26\u6d41\u8bfb\u53d6\u548c\u89e3\u7801\u5230\u5185\u5b58\u4e2d\u7684 UTF-32 \u5b57\u7b26\u4e32 std::wstring \u7684\u3002 \u7406\u8bba\u4e0a\u6240\u6709\u7684\u7a0b\u5e8f\u90fd\u5e94\u8be5\u50cf\u8fd9\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u52b3\u4fdd\u6559\u6750\u4ece\u6765\u4e0d\u63d0\uff0c\u4e00\u53e3\u4e00\u4e2a char [] \u5c31\u662f\u5b57\u7b26\u4e32\uff0c\u641e\u5f97 wchar_t \u5728\u9664\u4e86 GNU \u8fd9\u79cd\u201c\u4f53\u5236\u5185\u201d\u73af\u5883\u4e4b\u5916\uff0c\u6839\u672c\u6ca1\u4eba\u7528\u4e86\u3002\u73b0\u5728\u4e3a\u4e86\u5904\u7406\u4e2d\u6587\u5b57\u7b26\uff0c\u624d\u95f9\u51fa\u4e86 char \u5f53 UTF-8 \u4f7f\u8fd9\u79cd\u62db\u6570\uff0c\u4ee4\u4eba\u550f\u5618\u3002 \u603b\u4e4b\uff0c .imbue(std::locale(\"zh_CN.GBK\")) \u53ef\u4ee5\u628a GBK \u8bbe\u4e3a\u5f53\u524d\u6587\u672c\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5bbd\u6587\u4ef6\u6d41\u5c06\u4f1a\u6309\u7167\u8fd9\u4e2a\u7f16\u7801\u548c\u89e3\u7801\u6240\u6709\u7684\u5b57\u7b26\u4e32\u3002 std::locale \u7684\u5b57\u7b26\u4e32\u6784\u9020\u51fd\u6570\uff0c\u4ed6\u7684\u53c2\u6570\u5fc5\u987b\u662f\u7528\u6237\u7cfb\u7edf\u91cc\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684 locale\uff08\u901a\u8fc7\u4fee\u6539 /etc/locale.gen \u548c locale-gen \u547d\u4ee4\u5b89\u88c5\uff09\u3002\u4f46\u662f\uff0c\u4f60\u65e0\u6cd5\u786e\u4fdd\u7528\u6237\u7684\u7cfb\u7edf\u5b89\u88c5\u4e86 \"GBK\" locale\u3002 std::locale(\"zh_CN.GBK\") \u5728\u6ca1\u6709\u5b89\u88c5 GBK \u7684\u7528\u6237\u7535\u8111\u4e0a\u8fd0\u884c\u5c31\u4f1a\u629b\u51fa\u9519\u8bef\u8868\u793a\u627e\u4e0d\u5230\u8be5 locale\u3002\u56e0\u6b64\uff0c\u5982\u679c\u8981\u6307\u5b9a\u6309 GBK \u8bfb\u53d6\u6587\u4ef6\uff0c\u4e0d\u5efa\u8bae\u4f9d\u8d56\u7cfb\u7edf\u4e2d\u81ea\u5e26\u7684 std::locale(\"zh_CN.GBK\")) \uff0c\u800c\u662f\u8c03\u7528 boost::locale::generator \u5c31\u5730\u751f\u6210\u4e00\u4e2a locale\uff0c\u8fd9\u6837\u7a0b\u5e8f\u65e0\u8bba\u7cfb\u7edf\u6709\u6ca1\u6709\u5b89\u88c5\u90fd\u80fd\u8fd0\u884c\u4e86\uff1a #include #include int main() { std::wofstream fout; boost::locale::generator gen; std::locale loc = gen(\"zh_CN.GBK\"); fout.imbue(loc); fout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4ee5 GBK \u7f16\u7801\u5199\u51fa\u6587\u672c\u6587\u4ef6 } $ cat build/\u4f60\u597d.txt \ufffd\ufffd\u00e3\ufffd\ufffd\ufffd $ cat build/\u4f60\u597d.txt | iconv -f GBK -t UTF-8 \u4f60\u597d\uff0c\u4e16\u754c $ \u8fd9\u662f\u56e0\u4e3a boost_locale \u94fe\u63a5\u4e86 icu \uff0c\u5176\u5185\u90e8\u5305\u542b\u4e86\u6240\u6709\u7f16\u7801\u683c\u5f0f\u7684\u5b57\u7b26\u6620\u5c04\u8868\u3002 boost::locale::generator \u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a std::locale \uff0c\u7136\u540e\u901a\u8fc7\u865a\u51fd\u6570\u91cd\u8f7d\u7684\u65b9\u5f0f\u628a std::locale \u5bf9\u8c61\u4e2d\u7684 std::codecvt \u66ff\u6362\u6210 icu \u7684\u6620\u5c04\u8868\u3002\u4ece\u800c\u8ba9 std::wofstream \u8c03\u7528\u8fd9\u4e2a icu \u7684\u6620\u5c04\u51fd\u6570\uff0c\u5b9e\u73b0\u4e86 UTF-32 \u5230 GBK \u7684\u8f6c\u6362\u3002 \u6b64\u5916\uff0c\u4f60\u8fd8\u53ef\u4ee5\u9009\u62e9\u8986\u76d6 locale \u7684\u90e8\u5206\u65b9\u9762 (facet)\uff0c\u6bd4\u5982\u5728\u6587\u4ef6\u7f16\u7801\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u8981\u7528 \"zh_CN.GBK\" \u7684 LC_CTYPE \u65b9\u9762\u5c31\u53ef\u4ee5\u4e86\uff0c\u5176\u4ed6\u7684\u4f8b\u5982\u65f6\u95f4\u683c\u5f0f\u3001\u8bed\u8a00\u4fe1\u606f\u7b49\uff0c\u6211\u4eec\u8fd8\u662f\u60f3\u4fdd\u7559\u9ed8\u8ba4\u7684\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528 locale \u7684\u201c\u6742\u4ea4\u201d\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u4fdd\u7559\u8001 locale \u7684\u7edd\u5927\u90e8\u5206\u65b9\u9762\uff0c\u53ea\u66ff\u6362\u4e00\u4e2a\u65b9\u9762\u4e3a\u65b0 locale \u7684\uff1a std::locale old_loc = std::locale(\"\"); // \u73af\u5883 locale boost::locale::generator gen; std::locale new_loc = gen(\"zh_CN.GBK\"); // \u5168 GBK locale std::locale loc = std::locale(old_loc, new_loc, std::locale::ctype); // \u6742\u4ea4\uff1a\u7ee7\u627f old_loc \u7684\u5176\u4f59\u5168\u90e8\uff0c\u53ea\u66ff\u6362\u6389 LC_CTYPE \u90e8\u5206\u4e3a new_loc \u7684 fout.imbue(loc); locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5185\u7801\u7f16\u7801\u6210\u5916\u7801 std::string narrow(std::locale const &loc, std::wstring const &wstr) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::string str(wstr.size() * 4, '\\0'); // \u9884\u7559 4 \u500d\u7a7a\u95f4 wchar_t const *from_next; char *to_next; std::mbstate_t state{}; auto res = cvt.in(state, wstr.data(), wstr.data() + wstr.size(), from_next, str.data(), str.data() + str.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f str.resize(to_next - str.data()); return str; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f str.resize(to_next - str.data()); return str; } else { // \u8f6c\u6362\u5931\u8d25 return \"\"; } } // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5916\u7801\u89e3\u7801\u6210\u5185\u7801 std::wstring widen(std::locale const &loc, std::string const &str) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::wstring wstr(str.size(), L'\\0'); // \u9884\u7559\u7a7a\u95f4 char const *from_next; wchar_t *to_next; std::mbstate_t state{}; auto res = cvt.out(state, str.data(), str.data() + str.size(), from_next, wstr.data(), wstr.data() + wstr.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else { // \u8f6c\u6362\u5931\u8d25 return L\"\"; } } std::wstring wstr = L\"\u4f60\u597d\"; std::cout << narrow(std::locale(\"zh_CN.GBK\"), wstr); \u4e0d\u8fc7\uff0c\u6211\u4eec\u90fd\u6709\u66f4\u65b9\u4fbf\u7684 boost::locale::conv \u4e86\uff0c\u8fd8\u4f55\u5fc5\u8fd8\u7528\u8fd9\u4e48\u7e41\u7410\u7684 std::locale \u5462\uff1f\u6240\u4ee5\u6211\u662f\u4e0d\u63a8\u8350\u518d\u7528\u8fd9\u7834\u73a9\u610f\uff0c\u65e0\u8bba\u662f\u6613\u7528\u6027\u8fd8\u662f\u6269\u5c55\u6027\u90fd\u662f Boost \u5b8c\u80dc\u3002 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 \u5bf9\u4e8e\u6240\u6709\u7684 strcpy \u3001 strcmp \u3001 strlen \u8fd9\u7c7b str*** \u7cfb\u51fd\u6570\uff0c\u90fd\u6709\u4e00\u4e2a\u76f8\u5e94\u7684 wcs*** \u51fd\u6570\u3002 \u4f8b\u5982 wcscpy \u3001 wcscmp \u3001 wcslen \u3002 \u5b83\u4eec\u7684\u539f\u578b\u5982\u4e0b\uff1a wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); int wcscmp(const wchar_t *s1, const wchar_t *s2); size_t wcslen(const wchar_t *s); \u5b83\u4eec\u7684\u4f5c\u7528\u548c str*** \u7cfb\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u662f\u5b83\u4eec\u64cd\u4f5c\u7684\u662f wchar_t \u5b57\u7b26\u4e32\u3002 \u5bf9\u4e8e\u6240\u6709\u7684 fputc \u3001 printf \uff0c fprintf \uff0c fgets \u8fd9\u7c7b\u64cd\u4f5c\u6587\u4ef6\u7684\u51fd\u6570\uff0c\u4e5f\u90fd\u6709\u4e00\u4e2a\u914d\u5957\u7684 fw*** \u51fd\u6570\u3002 \u7b2c\u4e00\u6b21\u4f7f\u7528\u8fc7\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c FILE * \u5c06\u4f1a\u88ab\u201c\u5bbd\u5316\u201d\uff08 fwiden \uff09\u3002\u5bbd\u5316\u7684\u6587\u4ef6\u6d41\u4eca\u540e\u5c06\u53ea\u80fd\u8f93\u5165\u5bbd\u5b57\u7b26\u4e32\u3002 \u4f46\u662f\uff0c\u65e2\u7136 C++ \u5df2\u7ecf\u6709 std::wstring \uff0c\u5c31\u4e0d\u5efa\u8bae\u518d\u5b66 C \u8bed\u8a00 L'\\0' \u7ed3\u5c3e\u5b57\u7b26\u4e32\u4e86\u3002 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 TODO C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 wchar_t \u3001 char16_t \u3001 char32_t \u4e0e char \u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 std::mbrtoc16 \u3001 std::mbrtoc32 \u3001 std::c16rtomb \u3001 std::c32rtomb \u51fd\u6570\u3002 \u7136\u800c\uff0c\u53c8\u81ed\u53c8\u957f\uff0c\u7528\u5c01\u88c5\u597d\u7684 boost::locale::utf_to_utf/from_utf/to_utf/between \u4e0d\u9999\u5417\uff1f Windows \u4e13\u9898 \u9047\u5230\u5b57\u7b26\u7f16\u7801\u96be\u9898\u7684\uff0c\u4e3b\u8981\u662f Windows \u7a0b\u5e8f\u5458\u3002 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 \u4ece Windows NT \u7248\u672c\u5f00\u59cb\uff0c\u5bf9\u4e8e\u6240\u6709\u6d89\u53ca\u5b57\u7b26\u4e32\u7684\uff0c\u5176\u64cd\u4f5c\u7cfb\u7edf API \u63d0\u4f9b\u4e86\u4e24\u5957\u51fd\u6570\u3002 \u4e00\u5957\u662f A \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 A \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileA \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 ANSI\uff08\u5373 GBK\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u53e6\u4e00\u5957\u662f W \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 W \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileW \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 Unicode\uff08\u5373 UTF-16\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u5176\u4e2d CreateFileW \u624d\u662f Windows \u7cfb\u7edf\u771f\u6b63\u7684 API\u3002 \u800c CreateFileA \u662f\u4e3a\u4e86\u517c\u5bb9\u57fa\u4e8e ANSI \u7684\u8001\u7a0b\u5e8f. \u7531\u4e8e ANSI \u5728\u4e0d\u540c\u5730\u533a\u4f1a\u53d8\u5f97\u4e0d\u540c\uff0c\u4f7f\u7528\u8fd9\u7c7b\u51fd\u6570\u5199\u51fa\u7684\u7a0b\u5e8f\u4e0d\u5177\u6709\u56fd\u9645\u901a\u7528\u6027\u3002 \u5176\u5185\u90e8\u7684\u5b9e\u73b0\u53ea\u662f\u7b80\u7b80\u5355\u5355\u5730\u7ed9 const char * \u505a\u4e2a\u8f6c\u6362\uff0c\u4ece GBK \u8f6c\u5230 UTF-16\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528 CreateFileW\u3002 HANDLE CreateFileA(const char *lpFileName) { return CreateFileW(gbk_to_utf16(lpFileName)); } TCHAR \u6d41\u6d3e \u9664\u4e86\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5b8f\uff0c\u8fd9\u4e2a\u5b8f\u6ca1\u6709\u4efb\u4f55\u540e\u7f00\uff0c\u4f8b\u5982 CreateFile \u3002 \u5176\u5b9a\u4e49\u5982\u4e0b\uff1a #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif \u8fd9\u6837\u505a\u7684\u521d\u8877\u662f\uff0c\u7a0b\u5e8f\u5458\u53ea\u53ef\u4ee5\u5199\u51fa\u4e00\u5957\u9488\u5bf9 MessageBox \u7684\u4ee3\u7801\u3002 \u5f53\u8001\u677f\u60f3\u8981\u57fa\u4e8e Unicode \u65f6\uff0c\u4ed6\u5c31 #define UNICODE \uff0c\u8fd9\u6837 MessageBox \u5c31\u53d8\u6210\u4e86 MessageBoxW \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u5c31\u4f1a\u81ea\u52a8\u53d8\u6210 Unicode \u7684\uff0c\u56fd\u9645\u901a\u7528\u3002 \u5f53\u52b3\u4fdd\u8001\u677f\u60f3\u8981\u57fa\u4e8e ANSI \u65f6\uff0c\u4ed6\u5c31\u4e0d\u5b9a\u4e49 UNICODE \u5b8f\uff0c\u8fd9\u6837\u6240\u6709\u7684 MessageBox \u53c8\u53d8\u56de\u4e86 MessageBoxA \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u53c8\u53d8\u6210 ANSI \u7684\u4e86\u3002 \u6240\u6709\u6709 A/W \u533a\u5206\u7684\u7684 Windows API \u90fd\u6709\u8fd9\u6837\u4e00\u4e2a\u5b8f\uff0c\u6839\u636e UNICODE \u5b8f\u662f\u5426\u5b9a\u4e49\uff0c\u51b3\u5b9a\u91c7\u53d6\u54ea\u5957 API\u3002 \u6211\u4eec\u4f1f\u5927\u7684 Linux \u7cfb\u7edf\u5c31\u6ca1\u6709\u8fd9\u4e2a\u82e6\u607c\uff0c\u65e9\u5c31\u7edf\u4e00 UTF-8 \u4e86\u3002 \u9664\u6b64\u4e4b\u5916\uff0c \u4e2d\u8fd8\u5b9a\u4e49\u4e86 TEXT \u8fd9\u4e2a\u5b8f\u51fd\u6570\u3002 #ifdef UNICODE #define TEXT(s) L##s #else #define TEXT(s) s #endif \u7528\u6cd5\uff1a\u8981\u6c42\u7a0b\u5e8f\u5458\u628a\u6240\u6709\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u90fd\u7528 TEXT \u5b8f\u5305\u88f9\u3002 Qt \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b8f\u5305\u88f9\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u505a\u6cd5\uff0c tr \uff0c\u4f46\u5b83\u5e76\u4e0d\u662f\u4e3a\u4e86\u89e3\u51b3\u7f16\u7801\u95ee\u9898\uff0c\u800c\u662f\u4e3a\u4e86\u89e3\u51b3\u591a\u8bed\u8a00\u7ffb\u8bd1\u95ee\u9898\uff0c\u7a0d\u540e\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u4e00\u4e0b Qt \u4e2d\u7684\u5b57\u7b26\u4e32\u3002 \u5f53 UNICODE \u5b8f\u5b9a\u4e49\u65f6\uff0c TEXT \u4f1a\u81ea\u52a8\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u6dfb\u52a0 L \u524d\u7f00\uff0c\u4f7f\u5f97\u5b57\u7b26\u4e32\u53d8\u6210 Unicode \u7684\u3002\u5982\u679c\u6ca1\u6709\u5b9a\u4e49\uff0c\u5219\u53c8\u53d8\u56de ANSI \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff08\u8ddf\u968f\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\u7684\u8bbe\u5b9a\uff09\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff1a #include int main() { MessageBox(NULL, TEXT(\"\u4f60\u597d\uff0c\u4e16\u754c\"), TEXT(\"\u6807\u9898\"), MB_OK); } \u5f53\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u6807\u9898\", MB_OK); } \u5f53\u6ca1\u6709\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u6807\u9898\", MB_OK); } \u6b64\u5916\uff0c\u8fd8\u5b9a\u4e49\u4e86 TCHAR \u8fd9\u4e2a\u7c7b\u578b\u522b\u540d\uff0c\u540c\u6837\u662f\u9488\u5bf9\u662f\u5426\u5b9a\u4e49 UNICODE \u5b8f\u800c\u5b9a\u4e49\u4e86\u4e24\u5957\u7248\u672c\u3002 #ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif \u8fd8\u4e3a printf \u548c wprintf \u5b9a\u4e49\u4e86 TCHAR \u7248\u672c\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709 strlen \u548c wcslen \uff0c strcpy \u548c wcscpy \uff0c\u7b49\u7b49\u3002 #ifdef UNICODE #define _tprintf wprintf #define _tcscpy wcscpy #define _tcslen wcslen #else #define _tprintf printf #define _tcscpy strcpy #define _tcslen strlen #endif \u4e0d\u89c9\u5f97\u8fd9\u5f88\u9177\u5417\uff1f\u5f88\u7b26\u5408\u6211\u5bf9\u5f3a\u8feb\u75c7\u7684\u60f3\u8c61\uff0c\u79d1\u6280\u5e76\u4e14\u5e26\u7740\u81ed\u5473\u3002 int main() { TCHAR str[] = TEXT(\"\u6bd4\u5c14\u76d6\u5b50\u6211\u6d4b\u8bd5\u4f60\u7684\u7801\"); } (* \u54e6\uff0c\u6211\u662f\u8bf4\uff0c\u6211\u8981\u6d4b\u8bd5\u4f60\u7684\u7f16\u7801\u683c\u5f0f *) \u9700\u8981\u5207\u6362\u65f6\uff0c\u5728 MSVC \u4e2d\uff0c\u6253\u5f00\u6216\u5173\u95ed /DUNICODE \u7f16\u8bd1\u9009\u9879\u5373\u53ef\u3002 \u4e0d\u8981\u89c9\u5f97\u8fd9\u662f\u4ec0\u4e48\u597d\u4e3b\u610f\uff0c\u8fd9\u6837\u505a\u7684\u540e\u679c\u662f\uff0c\u4f60\u5199\u51fa\u7684\u4ee3\u7801\u53ea\u80fd\u5728 Windows \u4e0b\u7f16\u8bd1\u3002 \u5199\u8d77\u6765\u7d2f\u6b7b\u4eba\uff0c\u5b9e\u9645\u54ea\u6709\u90a3\u4e48\u591a\u4e00\u76f4\u5728 ANSI \u548c Unicode \u4e4b\u95f4\u6765\u56de\u5207\u6362\u7684\u9700\u6c42\uff1f \u6211\u7684\u5efa\u8bae\u662f\uff0c\u7edf\u4e00 wchar_t \uff0c\u7edf\u4e00\u5168\u7528 W \u51fd\u6570\uff0c\u618b\u62a0\u62a0\u7d22\u7d22\u7684\u534a\u8fdb\u534a\u9000\u3002 UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f \u4e4b\u524d\u8bf4\u8fc7\u4e86\uff0cWindows \u5e73\u53f0\u5230\u5904\u90fd\u9ed8\u8ba4 GBK \u975e\u5e38\u9ebb\u70e6\uff0c\u8981\u5207\u6362\u5230 UTF-8 \u5de5\u4f5c\u6d41\uff1a \u7f16\u8bd1\u5668\u5f00\u542f /utf-8 \u9009\u9879 \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c system(\"chcp 65001\") \u8bbe\u7f6e\u6587\u4ef6\u7cfb\u7edf\u5b57\u7b26\u4e32\u7f16\u7801\uff0c setlocale(LC_ALL, \".utf-8\") // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 SetConsoleCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u5165\u7f16\u7801\uff0c\u7528\u4e8e std::cin #elif __unix__ // \u53cd\u6b63 Unix \u7cfb\u7edf\u9ed8\u8ba4\u90fd\u662f UTF-8\uff0c\u4e0d\u8bbe\u7f6e\u4e5f\u884c\uff0c\u8fd9\u91cc\u8bbe\u7f6e\u5168\u5c40 locale \u662f\u4e3a\u4e86\u8ba9 iswspace \u63a5\u53d7\u5168\u89d2\u7a7a\u683c\u3001iswpunct \u63a5\u53d7\u5168\u89d2\u9017\u53f7 L'\uff0c' \u7b49 //setlocale(LC_ALL, \"zh_CN.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u4e2d\u6587\u672c\u5730\u5316\uff0c\u53ef\u4f7f strerror \u8f93\u51fa\u4e2d\u6587\uff08\u4f46\u7528\u6237\u5fc5\u987b locale-gen \u8fc7\u4e2d\u6587\uff01\uff09 //setlocale(LC_ALL, \"C.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u8bed\u8a00\u4e2d\u6027 locale\uff0c\u53ea\u5f71\u54cd iswspace\u3001iswpunct \u7b49\u51fd\u6570\uff0c\u4e0d\u4f1a\u4f7f strerror \u7b49\u8f93\u51fa\u4e2d\u6587 setlocale(LC_ALL, \".utf-8\"); // \u82e5\u4e0d\u5e26\u4efb\u4f55\u524d\u7f00\uff08\u63a8\u8350\uff09\uff0c\u5219\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u8bed\u8a00 $LANG\uff0c\u4f7f strerror \u81ea\u52a8\u9002\u5e94 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 std::wcout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4f60\u90fd\u7edf\u4e00 UTF-8 \u4e86\uff0c\u8fd9\u7834 UTF-16 \u548c UTF-32 \u4e4b\u95f4\u6765\u56de\u8df3\u7684\u7834 wchar_t \u5c31\u522b\u7528\u4e86\u5457\uff01 return 0; } WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == false \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::cout << char(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f GBK \u7f16\u7801\u7684 char \u5e8f\u5217 // \u5982\u679c\u662f\u4e2d\u6587\u5b57\u7b26\uff0cWndProc(WM_CHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u5b57\u8282\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u5df1\u5224\u65ad\u548c\u62fc\u63a5 GBK \u5b57\u7b26\u4e32 return 0; case WM_UNICHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == true \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::wcout << wchar_t(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f UTF-16 \u7f16\u7801\u7684 wchar_t \u5e8f\u5217 // \u5982\u679c\u662f\u4ee3\u7406\u5bf9\uff0cWndProc(WM_UNICHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u7801\u4f4d\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u884c\u628a\u4ee3\u7406\u5bf9\u7ec4\u88c5\u6210\u5b8c\u6574\u7684 Unicode \u7801\u70b9 return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } \u628a WndProc \u7684\u8f93\u5165\u5b58\u5165 std::u32string \u7684\u6848\u4f8b\uff1a std::u32string result; std::string ansi_buf; std::wstring utf16_buf; std::optional try_ansi_to_utf32(std::string const &s) { try { return boost::locale::conv::to_utf(s, \"\"); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } std::optional try_utf16_to_utf32(std::wstring const &s) { try { return boost::locale::conv::utf_to_utf(s); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: ansi_buf.push_back(char(wParam)); if (auto u = try_ansi_to_utf32(ansi_buf)) { result += u.value(); ansi_buf.clear(); } return 0; case WM_UNICHAR: utf16_buf.push_back(wchar_t(wParam)); if (auto u = try_utf16_to_utf32(utf16_buf)) { result += u.value(); utf16_buf.clear(); } return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); }; \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 \u6807\u51c6\u5e93\u7684 std::string \u6211\u4eec\u4e0d\u518d\u8d58\u8ff0\uff0c\u521a\u624d\u5728\u201c\u5bbd\u5b57\u7b26\u6d41\u201d\u4e2d\u4e5f\u4ecb\u7ecd\u4e86\u5b98\u65b9\u7684\u60f3\u6cd5\uff0c\u4e4b\u540e\u7684\u5b57\u7b26\u4e32\u4e13\u9898\u8bfe\u4f1a\u7ee7\u7eed\u8be6\u89e3\u3002 \u8fd9\u91cc\u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u5173\u4e8e\u5b57\u7b26\u7f16\u7801\u7684\u95ee\u9898\uff0c\u63a2\u7d22\u5404\u5927\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u5e93\uff0c\u662f\u5982\u4f55\u5c01\u88c5\u5b57\u7b26\u4e32\u7c7b\uff0c\u5982\u4f55\u89e3\u51b3 UTF-8 \u53d8\u957f\u7f16\u7801\uff0cUTF-32 \u538b\u7f29\u7387\u4f4e\u7684\u95ee\u9898\u7684\uff0c\u5e0c\u671b\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u63d0\u4f9b\u4e00\u70b9\u7075\u611f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u597d\u7684\u5e93\u6216\u8bed\u8a00\uff0c\u90fd\u8981\u660e\u786e\u533a\u5206\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u6982\u5ff5\uff0c\u524d\u8005\u662f\u6587\u672c\u5185\u5bb9\uff0c\u540e\u8005\u662f\u7eaf\u4e8c\u8fdb\u5236\u5185\u5bb9\u3002 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7\u201c\u7f16\u7801\u201d\u5f97\u5230\u7eaf\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6570\u7ec4\uff0c\u800c\u5b57\u8282\u6570\u7ec4\u53ef\u4ee5\u201c\u89e3\u7801\u201d\u5f97\u5230\u539f\u59cb\u5b57\u7b26\u4e32\u3002 \u65e9\u671f\u7684 C \u8bed\u8a00\u5c31\u662f\u56e0\u4e3a\u628a\u5b57\u7b26\u548c\u5b57\u8282\u6df7\u4e3a\u4e00\u8c08\uff0c\u90fd\u4f7f\u7528\u4e86 char \u7c7b\u578b\uff0c\u624d\u4ea7\u751f\u4e86\u540e\u6765\u8fd9\u4e48\u591a\u4e71\u8c61\u3002\u540e\u6765\u901a\u8fc7\u6253\u8865\u4e01\u6253\u4e0a\u771f\u6b63\u7684\u5b57\u7b26 wchar_t \uff0c\u5374\u6ca1\u4ec0\u4e48\u4eba\u7528\uff0c\u800c\u4e14\u8fd8\u88ab Windows \u641e\u6210 16 \u4f4d\uff0c\u53cd\u800c\u4e0d\u8de8\u5e73\u53f0\u4e86\u3002 \u6b64\u5904\u5148\u5217\u4e00\u4e2a\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u773c\u4e2d\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u8868\uff0c\u65b9\u4fbf\u4f60\u7406\u89e3\u3002 \u8bed\u8a00 \u5b57\u7b26 \u5b57\u7b26\u4e32 \u6587\u672c\u6d41 \u5b57\u8282\u6570\u7ec4 \u4e8c\u8fdb\u5236\u6d41 \u7f16\u7801/\u89e3\u7801 C char wchar_t * FILE * + fgetwc char * FILE * + fgetc wcstomb / mbstowc C++ wchar_t std::wstring std::wistream std::string / std::vector std::istream std::codecvt Qt QChar QString QTextStream QByteArray QDataStream QTextCodec Python3 str str open('r') bytes open('rb') str.encode() Python2 unicode unicode \u65e0 str open('r') unicode.encode() Java Character String Reader byte[] InputStream Charset.encode C# char string StreamReader byte[] Stream Encoding Rust char String BufRead u8 Read str::from_utf8 JS char String ReadableStream Uint8Array ReadableStream TextEncoder Go rune string Reader byte Reader utf8.DecodeRune PHP string string fopen string fopen mb_convert_encoding Swift Character String String.UnicodeScalarView UInt8 Data String.Encoding Kotlin Char String Reader ByteArray InputStream Charset.encode Obj-C unichar NSString NSInputStream uint8_t NSInputStream NSStringEncoding Lua integer table \u65e0 string io.open require'utf8' \u672c\u8bfe\u4e0d\u4f1a\u8bb2\u89e3\u8fd9\u4e9b\u8bed\u8a00\u7684\u5b57\u7b26\u4e32\u5177\u4f53\u7528\u6cd5\uff0c\u53ea\u63d0\u4f9b\u4e00\u4e9b\u6982\u5ff5\uff0c\u8ba9\u4f60\u77e5\u9053\u5927\u5bb6\u90fd\u662f\u600e\u4e48\u5b9e\u73b0\u7684\uff0c\u89e6\u7c7b\u65c1\u901a\u3002 Lua \u4e2d UTF-32 \u7684\u5b9a\u957f\u7f16\u7801\uff0c\u8981\u8fd9\u6837\u5b9e\u73b0\uff1a {80, 101, 110, 103} \u3002\u800c\u4ed6\u6240\u8c13\u7684 utf8 \u5e93\uff0c\u5c31\u662f\u8d1f\u8d23\u628a Lua \u81ea\u5df1\u7684 string \u5047\u8bbe\u4e3a utf8 \u7f16\u7801\uff0c\u89e3\u7801\u51fa\u4e00\u4e2a\u4e2a Unicode \u7801\u70b9\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fd9\u6837\u7684\u6570\u7ec4\u3002\u4ed6\u751a\u81f3\u4e0d\u662f Lua \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u662f\u4e2a\u7b2c\u4e09\u65b9\u7684\u5e93\uff0c\u8fd8\u662f\u9700\u8981\u7f16\u8bd1\u7684 C \u8bed\u8a00 .so \u6587\u4ef6\u3002\u8fd8\u6709 Lua \u5b5d\u5b50\u501f\u6b64\u786c\u8bf4\u6211\u4eec Lua \u662f\u5929\u751f UTF-8\uff01\u7136\u800c\u62ff\u7740\u4e2a UTF-8 \u7f16\u7801\u7684\u201c\u5b57\u8282\u6570\u7ec4\u201d string \u6765\u6253\u5f00 io.open \u6587\u4ef6\uff0c\u5c31\u4f1a\u62a5\u9519\u627e\u4e0d\u5230\u6587\u4ef6\uff08\u56e0\u4e3a\u4e2d\u56fd\u533a Windows \u7684 GBK\uff09\uff0c\u662f\u4e0d\u662f\u5f88\u597d\u7b11\u5462\uff1f Qt QString Qt \u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 Qt \u7684\u5b57\u8282\u6570\u7ec4\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 \u5b83\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u4e0a\u662f\u4e2a QChar \u6570\u7ec4\uff0c\u800c QChar \u662f unsigned short \uff0c\u5373 16 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\uff0c\u4e5f\u5c31\u662f UTF-16 \u7f16\u7801\u7684\u7801\u4f4d\u3002 QString str = \"\u4f60\u597d\uff0c\u4e16\u754c\"; // str.size() = 5 // str[0] = QChar(0x4f60) = u'\u4f60' // str[1] = QChar(0x597d) = u'\u597d' // str[2] = QChar(0xff0c) = u'\uff0c' // str[3] = QChar(0x4e16) = u'\u4e16' // str[4] = QChar(0x754c) = u'\u754c' \u53ef\u89c1\uff0c QString \u662f UTF-16 \u7f16\u7801\u7684\uff0c\u5c31\u548c Java \u4e00\u6837\uff0cQt \u4e5f\u662f UTF-16 \u6f6e\u7684\u53d7\u5bb3\u8005\u3002 \u6240\u4ee5\uff0cQString \u4e5f\u5b58\u5728\u7740\u4ee3\u7406\u5bf9\u53d8\u957f\u7f16\u7801\u7684\u95ee\u9898\u3002\u4f46\u81f3\u5c11\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5b57\u7b26\u6765\u8bf4\uff0c\u4e00\u4e2a 16 \u4f4d\u7684 QChar \u90fd\u5bb9\u7eb3\u7684\u4e0b\u4e86\u3002 QTextCodec Qt \u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u7684\u7f16\u7801\u8f6c\u6362\u51fd\u6570\uff0c\u7528\u4e8e\u5c06 QString \u8f6c\u6362\u6210 QByteArray \uff0c\u6216\u8005\u4ece QByteArray \u8f6c\u6362\u6210 QString \uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u90fd\u662f\u4ee5 to \u6216\u8005 from \u5f00\u5934\u7684\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u540d\uff0c\u4f8b\u5982 fromUtf8 \u3001 toUtf8 \u3001 toLocal8Bits \u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u5185\u90e8\uff0c\u90fd\u662f\u8c03\u7528 QTextCodec \u7c7b\u5b9e\u73b0\u7684\u8f6c\u6362\u3002 QTextCodec \u662f Qt \u7528\u4e8e\u5904\u7406\u5404\u79cd\u6587\u672c\u7f16\u7801\u4e4b\u95f4\u8f6c\u6362\u7684\u7c7b\u3002\u5b83\u7684\u9759\u6001\u65b9\u6cd5 codecForLocale \u8fd4\u56de\u4e86\u5f53\u524d\u7cfb\u7edf\u7684\u7f16\u7801\uff0c toUnicode \u548c fromUnicode \u5206\u522b\u662f\u5c06 QByteArray \u8f6c\u6362\u6210 QString \uff0c\u6216\u8005\u5c06 QString \u8f6c\u6362\u6210 QByteArray \u3002 QTextCodec *codec = QTextCodec::codecForLocale(); // \u8fd4\u56de\u5f53\u524d\u7cfb\u7edf\u7f16\u7801 QByteArray bytes = codec->fromUnicode(str); // \u5c06 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u5373 char[] QString str = codec->toUnicode(bytes); // \u5c06 QByteArray \u8f6c\u6362\u6210 QString QTextCodec \u8fd8\u63d0\u4f9b\u4e86\u4e00\u4e9b\u66f4\u52a0\u7ec6\u7c92\u5ea6\u7684\u8f6c\u6362\u63a5\u53e3\uff0c\u4f8b\u5982 fromUnicode \u9664\u4e86\u63a5\u53d7 QString \uff0c\u8fd8\u63a5\u53d7 QChar \u6570\u7ec4\uff0c\u53ef\u4ee5\u6307\u5b9a\u8f6c\u6362\u8303\u56f4\u3002 from/toLocal8Bits/Utf8/Latin1/Ascii \u4e3a\u4e86\u65b9\u4fbf\u4f7f\u7528\uff0cQt \u5c01\u88c5\u4e86\u4e00\u4e9b\u5e38\u7528\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362\u51fd\u6570\uff0c\u8fd9\u6837\u4f60\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u521b\u5efa\u4e00\u4e2a QTextCodec\u3002\u90fd\u662f to \u548c from \u5f00\u5934\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u7684\u540d\u79f0\u3002 Local8Bits \u8868\u793a\u8fd0\u884c\u65f6\u68c0\u6d4b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u5ba2\u6237\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 QByteArray bytes = str.toLocal8Bits(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801 QString::fromLocal8Bits(bytes); // \u518d\u4ece\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForLocale(); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Utf8 \u8868\u793a\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002 QByteArray bytes = str.toUtf8(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 UTF-8 \u7f16\u7801 QString::fromUtf8(bytes); // \u518d\u4ece UTF-8 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"UTF-8\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Latin1 \u8868\u793a ISO-8859-1 \u7f16\u7801\uff0c\u53c8\u79f0\u4e3a\u897f\u6b27\u7f16\u7801\uff0c\u5b83\u662f\u4e00\u4e2a\u5355\u5b57\u8282\u7f16\u7801\uff0c\u548c ASCII \u7f16\u7801\u76f8\u4f3c\uff0c\u4f46\u662f\u591a\u4e86 128-255 \u7684\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u6cd5\u8bed\u3001\u5fb7\u8bed\u3001\u897f\u73ed\u7259\u8bed\u3001\u8461\u8404\u7259\u8bed\u7b49\u5b57\u7b26\u3002 QByteArray bytes = str.toLatin1(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 Latin1 \u7f16\u7801 QString::fromLatin1(bytes); // \u518d\u4ece Latin1 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ISO-8859-1\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Ascii \u8868\u793a ASCII \u7f16\u7801\uff0c\u548c Latin1 \u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u4ed6\u65e0\u6cd5\u5904\u7406 128-255 \u8fd9\u4e00\u6bb5\u7684\u5b57\u7b26\u3002 QByteArray bytes = str.toAscii(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 ASCII \u7f16\u7801 QString::fromAscii(bytes); // \u518d\u4ece ASCII \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ASCII\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); \u5b57\u7b26\u4e32\u5e38\u91cf QString str = QStringLiterial(\"\u4f60\u597d\uff0c\u4e16\u754c\"); QStringLiterial \u53ef\u4ee5\u4fdd\u8bc1\uff0c\u8f6c\u6362\u65f6\u91c7\u7528\u7684\u662f\u6240\u8c13\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\uff08\u5b9e\u9645\u5e94\u8be5\u53eb\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\uff09\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u5f00\u53d1\u8005\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u662f\u7f16\u8bd1\u671f\u786e\u5b9a\u7684\u3002\u800c\u5982\u679c\u5199 QString::fromLocal8Bits(\"\") \u5c31\u53d8\u6210 \u201cANSI\u201d\uff0c\u5ba2\u6237\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u4e86\u3002\u8fd9\u4e24\u4e2a\u5b57\u7b26\u7f16\u7801\uff0c\u6bd4\u5982\u5728\u4e4b\u524d\u8de8\u56fd galgame \u7684\u6848\u4f8b\u4e2d\uff0c\u5c31\u662f\u4e0d\u540c\u7684\u3002 QTextStream QTextStream \u662f Qt \u63d0\u4f9b\u7684\u6587\u672c\u6d41\u7c7b\uff08\u5e26\u6709\u7f13\u51b2\uff09\uff0c\u5b83\u53ef\u4ee5\u5c06\u6587\u672c\u5199\u5165\u5230\u6587\u4ef6\u3001\u5957\u63a5\u5b57\u3001\u6807\u51c6\u8f93\u51fa\u7b49\u8bbe\u5907\u3002 \u6587\u672c\u6d41\u548c\u4e8c\u8fdb\u5236\u6d41\u4e0d\u540c\uff0c\u4ed6\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u8fc7 QTextStream \u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u3002 \u5f53\u4f60\u5f80 QTextStream \u5199\u5165 QString \u65f6\uff0c\u4f1a\u8c03\u7528\u8fd9\u4e2a\u7f16\u7801\u683c\u5f0f\u81ea\u52a8\u8f6c\u6362\u4e3a QByteArray \uff0c\u7136\u540e\u624d\u5199\u5165\u3002 \u8bfb\u53d6\u65f6\u4e5f\u540c\u7406\uff0c\u4f1a\u628a\u8bfb\u5230\u7684 QByteArray \u901a\u8fc7\u7f16\u7801\u683c\u5f0f\u89e3\u7801\uff0c\u5f97\u5230 QString \u5b57\u7b26\u4e32\u3002 Qt \u503c\u5f97\u79f0\u9053\u7684\u4e00\u70b9\u662f\uff1a\u4ed6\u628a\u6587\u4ef6\u548c\u6587\u4ef6\u6d41\u533a\u5206\u5f00\u6765\uff0c\u6587\u4ef6 QFile \u53ea\u9700\u8981\u8d1f\u8d23\u6253\u5f00\u6587\u4ef6\u5c31\u53ef\u4ee5\u4e86\uff1b\u800c\u6587\u672c\u6d41 QTextStream \u624d\u771f\u6b63\u8d1f\u8d23\u6570\u636e\u7684\u7f13\u51b2\uff0c\u89e3\u7801\u7b49\u64cd\u4f5c\u3002\u4f53\u73b0\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u804c\u8d23\u5355\u4e00\u539f\u5219\u3002 QFile file(\"hello.txt\"); file.open(QIODevice::ReadWrite); QTextStream stream(&file); stream.setCodec(\"UTF-8\"); // \u8bbe\u7f6e\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f stream << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u5199\u5165 QString\uff0cQTextStream \u4f1a\u81ea\u52a8\u5c06\u5176\u7528 UTF-8 \u7f16\u7801\u4e3a QByteArray \u540e\u5199\u5165 QFile \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u76f4\u63a5\u5199\u5165\u4e8c\u8fdb\u5236\u7684 QByteArray \uff0cQt \u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a QDataStream \u7c7b\uff0c\u65b9\u4fbf\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u8bfb\u5199\u3002 \u5982\u6b64\u628a\u4e8c\u8fdb\u5236\u548c\u6587\u672c\u4e25\u683c\u533a\u5206\uff0c\u800c\u4e0d\u662f\u50cf\u53e4\u4ee3 C \u8bed\u8a00\u90a3\u6837\u5b57\u8282\u4e0e\u5b57\u7b26\u6df7\u6dc6\u4e0d\u6e05\uff0c\u5168\u7528\u7cdf\u7cd5\u7684 char \u6765\u8868\u793a\uff0c\u5145\u5206\u4f53\u73b0\u4e86\u5f3a\u7c7b\u578b\u7684\u5b89\u5168\u3002 Python 3 str \u5982\u4f55\u89e3\u51b3 UTF-32 \u5360\u7528\u7a7a\u95f4\u5927\u7684\u75db\u70b9\uff1fPython \u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u7edd\u5bf9\u503c\u5f97\u4e00\u770b\uff01 \u4e3a\u4e86\u65b9\u4fbf\u6587\u672c\u5904\u7406\uff0c\u6700\u597d\u4ee5\u5b9a\u957f\u7f16\u7801\uff0c\u4e5f\u5c31\u662f UTF-32\uff0c\u5b58\u50a8\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7528 UTF-8 \u6216 UTF-16 \u6765\u5b58\u50a8\u7684\u8bdd\uff0c\u4f1a\u9047\u5230\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff1a \u4f8b\u5982\u50cf\u5b57\u7b26\u4e32\u7d22\u5f15\uff0c\u5b57\u7b26\u4e32\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\uff0c\u8981\u4e48\u7d22\u5f15\u51fa\u6765\u7684\u662f\u5b57\u8282\u800c\u4e0d\u662f\u5b57\u7b26\u4e86\uff1b\u8981\u4e48\u5c31\u9700\u8981 O(N) O(N) \u7684\u590d\u6742\u5ea6\uff0c\u9010\u4e00\u904d\u5386\u6bcf\u4e2a\u5b57\u8282\uff0c\u624d\u80fd\u786e\u5b9a\u771f\u6b63\u7684\u4f4d\u7f6e\uff1b\u54ea\u6015\u5168\u662f ASCII \u4e5f\u5f97\u8fd9\u4e48\u505a\uff0c\u56e0\u4e3a\u4e07\u4e00\u521a\u597d\u6709\u4e00\u4e2a\u662f\u4e2d\u6587\u5b57\u7b26\u5462\uff1f \u6240\u4ee5\uff0c\u5bf9\u4e8e\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684 Python \u6765\u8bf4\uff0cUTF-8 \u662f\u65e0\u6cd5\u63a5\u53d7\u7684\uff0c\u4f3c\u4e4e\u53ea\u80fd\u4ee5 UTF-32 \u6765\u5b58\u50a8\uff1f Python \u60f3\u5230\u4e86\u4e00\u4e2a\u5c0f\u5999\u62db\uff1a enum PyUnicodeType { PyUnicodeType_Latin1, PyUnicodeType_UCS2, PyUnicodeType_UCS4, }; struct PyUnicodeString { PyUnicodeType type; union { uint8_t *latin1; uint16_t *ucs2; uint32_t *ucs4; }; }; \u8fd9\u91cc\u7684 union \u662f\u4e00\u4e2a C \u8bed\u8a00\u7279\u6027\uff0c\u4ed6\u5141\u8bb8\u4f60\u628a\u591a\u4e2a\u6210\u5458\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u5e38\u6765\u8bf4\u9700\u8981\u914d\u5408\u4e00\u4e2a enum \u8868\u793a\u7c7b\u578b\uff0c\u624d\u80fd\u5b89\u5168\u4f7f\u7528\u3002\u73b0\u4ee3 C++ \u7684 std::variant \u66f4\u5b89\u5168\u7684\u53d6\u4ee3\u4e86\u4ed6\uff0c\u800c\u4e14\u4e0d\u9700\u8981\u5916\u6302\u4e00\u4e2a enum \u3002CPython \u89e3\u91ca\u5668\u56e0\u4e3a\u662f C \u8bed\u8a00\u5b9e\u73b0\uff0c\u53ea\u80fd\u7528 union \u6a21\u62df std::variant \u7684\u6548\u679c\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFF \u7684\u5b57\u7b26\uff08Latin-1 \u8303\u56f4\uff09\u65f6\uff0c\u5b9e\u9645\u4e0a\u6ca1\u5fc5\u8981\u5168\u7528\u8d85\u5927\u7684 uint32_t \u6765\u5b58\u50a8\u3002\u5b8c\u5168\u53ef\u4ee5\u53ea\u53d6\u51fa\u4f4e 8 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a\u66f4\u7d27\u51d1\u7684 uint8_t \u6570\u7ec4\uff0c\u5c31\u50cf Latin-1 \u7f16\u7801\u4e00\u6837\u3002 \u4f46\u662f\u5f53\u6309\u7d22\u5f15\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u4f1a\u5224\u65ad\u5f53\u524d union \u91cc\u88c5\u7684\u662f\u54ea\u79cd\u7c7b\u578b\uff0c\u5982\u679c\u662f Latin-1 \u7684\uff0c\u90a3\u5c31\u4f1a\u7528\u7ed3\u6784\u4f53\u91cc\u7684 uint8_t * \u6307\u9488\u6765\u7d22\u5f15\u3002 \u8fd9\u6837\uff0c\u5bf9\u4e8e\u5168 ASCII \u7684\u5b57\u7b26\u4e32\uff0c\u76f8\u6bd4\u8001\u8001\u5b9e\u5b9e\u5b58 UTF-32 \u5185\u5b58\u5360\u7528\u76f4\u63a5\u51cf\u5c11\u4e86 75%\uff01\u552f\u4e00\u7684\u4ee3\u4ef7\u662f\u6309\u7d22\u5f15\u8bfb\u5b57\u7b26\u5143\u7d20\u65f6\u9700\u8981\u505a\u4e2a if-else \u5224\u65ad\u3002\u540c\u65f6\u53c8\u4e0d\u5931\u53bb\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff08\u65e9\u671f Unicode \u8303\u56f4\uff09\u65f6\uff0c\u5219\u662f\u53d6\u51fa\u4f4e 16 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a uint16_t \u7684\u6570\u7ec4\uff0c\u8fd9\u79cd\u5b58\u50a8\u65b9\u6848\u4e5f\u79f0\u4e3a UCS-2\u3002 \u6ce8\u610f UCS-2 \u5e76\u4e0d\u7b49\u540c\u4e8e UTF-16\uff0cUTF-16 \u662f\u80fd\u591f\u8868\u793a\u5b8c\u6574\u7684 Unicode \u7684\u53d8\u957f\u7f16\u7801\uff08\u6709\u4ee3\u7406\u5bf9\uff09\uff1b\u800c UCS-2 \u662f\u6ca1\u6709\u4ee3\u7406\u5bf9\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u7f3a\u70b9\u662f\u53ea\u80fd\u8868\u793a 0xFFFF \u7684\u8303\u56f4\u3002 \u5bf9\u4e8e\u5927\u90e8\u5206\u4e2d\u6587\u5b57\u7b26\u4e32\uff0c\u5185\u5b58\u5360\u7528\u5c31\u51cf\u5c11\u4e86 50%\uff0c\u4e5f\u4e0d\u4e8f\u3002 \u5982\u679c\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0\u201c\ud883\udede\u201d\u8fd9\u6837\u7684\uff0c\u8d85\u8fc7 0xFFFF \u7684\u5b57\u7b26\uff0c\u624d\u4f1a\u91c7\u7528 uint32_t \u8001\u8001\u5b9e\u5b9e\u5b58\u50a8\u771f\u6b63\u7684 UTF-32\uff0c\u53c8\u79f0 UCS-4\u3002 \u8fd9\u4e24\u79cd\u53eb\u6cd5\u662f\u7b49\u4ef7\u7684\uff0c\u53cd\u6b63 Unicode \u4ece\u6765\u6ca1\u6709\u8d85\u8fc7 0xFFFFFFFF \u7684\uff0c\u73b0\u5728\u4ed6\u4eec\u90fd\u662f\u5b9a\u957f\u7f16\u7801\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u62df\u673a\u8bed\u8a00\u6765\u8bf4\uff0c\u53cd\u6b63\u672c\u6765\u5c31\u4e0d\u5728\u4e4e if-else \u5206\u652f\u8fd9\u70b9\u5c0f\u5f00\u9500\uff0c\u8fd9\u786e\u5b9e\u662f\u6700\u597d\u7684\u65b9\u6848\u3002 \u7f3a\u70b9\u5c31\u662f\uff0c\u5f53\u4f60\u5f80\u4e00\u4e2a\u5b8c\u5168\u662f ASCII \u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u7a81\u7136\u63d2\u5165\u4e00\u4e2a\u201c\ud883\udede\u201d\u65f6\uff0c\u4f1a\u4ea7\u751f\u5de8\u5927\u7684\u5185\u5b58\u91cd\u5206\u914d\u3002\u867d\u7136\u53ea\u6709\u4e00\u4e2a\u201c\ud883\udede\u201d\uff0c\u4f46\u4e3a\u6b64\uff0c\u5176\u4ed6\u6240\u6709 ASCII \u5b57\u7b26\u90fd\u5f97\u4e3a\u4ed6\u6269\u5f20\u5230 32 \u4f4d\u7684\u5927\u5c0f\u3002\u800c UTF-8 \u548c\u4f20\u7edf\u7684 UTF-32 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u6b64\u6211\u4e5f\u4e0d\u5efa\u8bae C++ \u7a0b\u5e8f\u5458\u81ea\u5df1\u624b\u6413\u4e2a\u8fd9\u6837\u7684 union \u5b57\u7b26\u4e32\u3002 Rust &str \u548c String \u800c Rust \u5219\u91c7\u7528\u4e86\u5b57\u7b26\u4e32\u5168\u5458 UTF-8 \u7684\u7b56\u7565\uff0c\u8fd9\u662f\u56e0\u4e3a Rust \u6700\u5e38\u7528\u4e8e\u4e92\u8054\u7f51\u65b9\u9762\u7684\u5e95\u5c42\u7cfb\u7edf\u8f6f\u4ef6\uff0c\u4e92\u8054\u7f51\u6700\u5e38\u7528\u7684\u6587\u672c\u7f16\u7801\u5c31\u662f UTF-8\uff0c\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\uff0c\u4e14\u56fd\u9645\u901a\u7528\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u4e92\u8054\u7f51\u57fa\u5efa\u6700\u5e38\u89c1\u7684\u5e73\u53f0\u5c31\u662f Linux\uff0c\u4f7f\u7528 UTF-8 \u5b58\u50a8\u5b57\u7b26\u4e32\uff0c\u8c03\u7528 Linux \u7cfb\u7edf API \u65e0\u9700\u4efb\u4f55\u8f6c\u6362\u3002\u4e14\u6587\u672c\u6587\u4ef6\u57fa\u672c\u90fd\u53ef\u4ee5\u5047\u5b9a\u662f UTF-8 \u7f16\u7801\uff0c\u5199\u5165\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u3002\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u8fd9\u5bfc\u81f4\u6587\u672c\u5904\u7406\u4e0a\u7684\u4e00\u4e9b\u56f0\u96be\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u7684\u7d22\u5f15\uff0c\u9700\u8981\u533a\u5206\u662f\u6309\u5b57\u8282\u7d22\u5f15\u8fd8\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u5982\u679c\u786e\u5b9e\u9700\u8981\u6309\u5b57\u7b26\u7d22\u5f15\u7684\u8bdd\uff0c\u590d\u6742\u5ea6\u5c31\u4f1a\u662f O(N) O(N) \u4e86\u3002 \u65e0\u8bba\u5982\u4f55\uff0c\u5982\u679c\u4f60\u9009\u62e9\u4e86 UTF-8 \u6d41\u6d3e\u7684\u8bdd\uff0cRust \u5b57\u7b26\u4e32\u7684\u201c\u8fed\u4ee3\u5668\u53cc\u8f68\u5236\u201d\u786e\u5b9e\u503c\u5f97\u79f0\u9053\uff1a let s = \"\u4f60\u597d\uff0c\u4e16\u754c\"; for c in s.chars() { // \u6309\u5b57\u7b26\u8fed\u4ee3 println!(\"{}\", c); } for b in s.bytes() { // \u6309\u5b57\u8282\u8fed\u4ee3 println!(\"{:02X}\", b); // \u6253\u5370\uff1aE4 BD A0 E5 A5 BD EF BC 8C E4 B8 96 E7 95 8C } Java String Java \u4e5f\u662f UTF-16 \u7684\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u4eae\u70b9\uff1a\u4ed6\u7684 String \u7c7b\u578b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u4f60\u65e0\u6cd5\u5c31\u5730\u4fee\u6539\u4e00\u4e2a String \u5bf9\u8c61\uff0c\u6bcf\u6b21\u4ea7\u751f\u4f60\u8c03\u7528 += \u7684\u90fd\u662f\u4e00\u4e2a\u65b0 String\uff0c\u800c\u4e0d\u4f1a\u8986\u76d6\u3002 \u4e5f\u5c31\u662f\u8bf4\uff1aJava \u7684 String \u867d\u7136\u662f\u201c\u5806\u201d\u4e2d\u7684\u5bf9\u8c61\uff0c\u5374\u65e0\u6cd5\u4ee5\u5f15\u7528\u4f20\u9012\u3002 \u8fd9\u907f\u514d\u4e86\u4ee5\u4e0b\u8fd9\u79cd\u60c5\u51b5\uff1a void registerStudent(String name) { name += \".txt\"; File file(name); file.write(...); } void myTransaction() { String name = \"\u5c0f\u5f6d\"; lib.registerStudent(name); office.registerStudent(name); // \u8fd9\u91cc name \u662f\u5426\u88ab\u4fee\u6539\uff1f } \u5982\u679c Java \u7684 String \u548c\u666e\u901a\u5bf9\u8c61\u4e00\u6837\uff0c\u88ab\u8c03\u7528\u8005\u7684\u4fee\u6539\u53ef\u4ee5\u5bf9\u5916\u90e8\u53ef\u89c1\uff0c\u90a3\u5c82\u4e0d\u662f\u6211\u6bcf\u6b21\u8c03\u7528\u4e00\u4e2a\u4ee5 String \u4e3a\u53c2\u6570\u7684\u51fd\u6570\u65f6\uff0c\u90fd\u9700\u8981\u64cd\u5fc3\uff1a\u8fd9\u4e2a\u51fd\u6570\u4f1a\u4e0d\u4f1a\u628a\u6211\u7684\u5b57\u7b26\u4e32\u4fee\u6539\u6389\uff1f \u6240\u4ee5\uff0cJava \u7ed9\u4ed6\u7684\u5bf9\u8c61\u6a21\u578b\u5f00\u4e86\u4e2a\u540e\u95e8\uff1a\u89c4\u5b9a\u6240\u6709\u5bf9\u8c61\u90fd\u662f\u6309\u5f15\u7528\u4f20\u9012\uff0c\u9664\u4e86 String \uff01\u5c31\u53ea\u6709 String \u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u8005\u5185\u90e8\u7684\u4fee\u6539\u5bf9\u5916\u4e0d\u53ef\u89c1\u3002 C++ \u548c Rust \u53ea\u9700\u8981\u52a0\u4e2a\u5e38\u5f15\u7528\u5c31\u884c\uff0c\u800c Java \u53d7\u5bb3\u8005\u8981\u8003\u8651\u7684\u5c31\u591a\u4e86\u3002 \u603b\u4e4b\uff0c\u8fd9\u5c31\u662f\u6ca1\u6709 const \u7684\u5783\u573e\u8bed\u8a00\u7684\u4e11\u6001\uff0c\u9700\u8981\u9760\u5404\u79cd\u8bed\u6cd5\u89c4\u5219\u4e0a\u5f00\u6d1e\u624d\u80fd\u5f25\u8865\u8bbe\u8ba1\u65f6\u8003\u8651\u4e0d\u5468\u7684\u7f3a\u9677\uff0c\u5c31\u4e3a\u4e86\u4f3a\u5019\u8fd9\u5e2e\u5f15\u7528\u90fd\u5f04\u4e0d\u660e\u767d\u7684\u5783\u573e\u5c0f\u767d\u3002 \u6211\u662f\u8bf4\u5783\u573e\u56de\u6536 (garbage-collect) \u8bed\u8a00\uff0c\u7b80\u79f0\u5783\u573e\u8bed\u8a00\u3002\u6ca1\u6709\u8bf4 Java \u5783\u573e\u7684\u610f\u601d\uff0c\u4f60\u8bf4\u5bf9\u5427\uff1f\u5783\u573e\u8bed\u8a00\u3002 COW \u5b57\u7b26\u4e32 \u62c5\u5fe7\uff1a\u90a3\u5c82\u4e0d\u662f\u6bcf\u6b21\u6211 += \u5b9e\u9645\u4e0a\u90fd\u767d\u767d\u6df1\u62f7\u8d1d\u4e86\u4e00\u4efd\u65b0\u7684 String \uff1f\u522b\u62c5\u5fc3\uff0c\u56e0\u4e3a\u5177\u4f53\u5b9e\u73b0\u4e0a\uff0cJava \u7684 String \u5728\u5e95\u5c42\u91c7\u7528\u4e86\u548c Qt \u7684 QString \u4e00\u6837\u7684 COW \u673a\u5236\uff1a \u5f53\u4e00\u4e2a QString \u88ab\u62f7\u8d1d\u6784\u9020\u65f6\uff0c\u5e76\u4e0d\u4f1a\u5bf9\u5176\u4e2d\u7684 QByteArray \u8fdb\u884c\u6df1\u62f7\u8d1d\uff0c\u800c\u662f\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u3002\u53ea\u6709\u5f53\u5176\u4e2d\u4e00\u4e2a QString \u88ab += \u7b49\u5e26\u6709\u526f\u4f5c\u7528\u64cd\u4f5c\u4fee\u6539\u65f6\uff0c\u624d\u4f1a\u6df1\u62f7\u8d1d\u4e00\u4efd\u65b0\u7684\uff0c\u8ba9\u4f60\u4fee\u6539\u3002\u8fd9\u6837\u5927\u5927\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\u548c\u6027\u80fd\u5f00\u9500\u3002 COW \u5b57\u7b26\u4e32\u7684\u7f3a\u70b9\u662f\uff1a\u5f53\u4f60\u5199\u591a\u7ebf\u7a0b\u5e76\u53d1\u65f6\uff0c\u672c\u6765\u591a\u7ebf\u7a0b\u53ea\u8bfb\u8bbf\u95ee\u540c\u4e00\u4e2a\u5b57\u7b26\u4e32\u662f\u5b89\u5168\u7684\uff0c\u4f46\u5982\u679c\u5b57\u7b26\u4e32\u6709 COW\uff0c\u8fde\u53ea\u8bfb\u8bbf\u95ee\u90fd\u4f1a\u4e0d\u5b89\u5168\u4e86\u3002\u4e4b\u540e\u6211\u4eec\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4f1a\u8be6\u7ec6\u5206\u6790\u8fd9\u662f\u4e3a\u4ec0\u4e48\u3002 \u5176\u5b9e\u65e9\u671f\u7684 C++98 \u4e2d\uff0c std::string \u4e5f\u91c7\u7528\u4e86 COW \u673a\u5236\uff0c\u4f46\u540e\u6765\u56e0\u4e3a\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u8981\u6c42\uff0c\u88ab\u8ffd\u6c42\u591a\u7ebf\u7a0b\u7684 C++11 \u8d23\u4ee4\u6539\u6b63\uff0c\u624d\u6709\u4e86\u540e\u6765 std::__cxx11::basic_string \u7684 ABI \u4e0d\u517c\u5bb9\u95ee\u9898\u3002\u6bd5\u7adf\u7ebf\u7a0b\u4e0d\u5b89\u5168\u5b9e\u5728\u592a\u4f24\u4e86\uff0c\u57fa\u672c\u610f\u5473\u7740\u591a\u7ebf\u7a0b\u5c31\u6ca1\u6cd5\u5171\u4eab std::string \u3002\u4e8b\u5b9e\u4e0a\uff0cQt \u6240\u6709\u7684\u5bf9\u8c61 QObject \uff0c\u5305\u62ec QString \u5728\u591a\u7ebf\u7a0b\u4e2d\u4f20\u9012\u65f6\uff0c\u5c31\u9700\u8981\u8c03\u7528 moveTo(QThread) \u8f6c\u79fb\u6240\u6709\u6743\uff0c\u624d\u80fd\u5b89\u5168\u5730\u4f20\u9012\u7ed9\u53e6\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u5c31\u662f\u56e0\u4e3a Qt \u5927\u91cf\u4f7f\u7528\u4e86 COW \u673a\u5236\u3002 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 TODO Grapheme TODO \u6b63\u89c4\u5316 TODO \u96f6\u5bbd\u7a7a\u683c TODO \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 TODO \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 \u201c\ud883\udede\u201d\u7684 Unicode \u7f16\u53f7\u662f 0x30EDE\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0c\u901a\u5e38\u53ef\u4ee5\u8f93\u5165 Ctrl+Shift+U \u7136\u540e\u8f93\u5165\u5341\u516d\u8fdb\u5236\u7f16\u53f7\uff0c3 0 E D E\uff0c\u7136\u540e Enter\uff0c\u5c31\u8f93\u5165\u4e86\u201c\ud883\udede\u201d\u3002 \u5728 Windows \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Win+R\uff0c\u7136\u540e\u8f93\u5165 charmap \uff0c\u6253\u5f00\u5b57\u7b26\u6620\u5c04\u8868\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u53cc\u51fb\u53ef\u4ee5\u590d\u5236\u5230\u526a\u8d34\u677f\u3002 \u5728 macOS \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Ctrl+Cmd+\u7a7a\u683c\uff0c\u6253\u5f00\u7279\u6b8a\u5b57\u7b26\u8f93\u5165\u9762\u677f\uff0c\u9009\u62e9\u201cUnicode\u201d\u5206\u7c7b\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u7136\u540e\u53cc\u51fb\u5c31\u8f93\u5165\u5230\u5149\u6807\u5904\u3002 UniFont \u5b57\u4f53 TODO \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f \u72ed\u4e49\u7684\u6c49\u5b57\uff1a0x4E00 \u5230 0x9FA5\uff08\u201c\u4e00\u201d\u5230\u201c\u9fa5\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\uff1a0x2E80 \u5230 0x9FFF\uff08\u201c\u2e80\u201d\u5230\u201c\u9fff\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\u5305\u542b\u4e86\u51e0\u4e4e\u6240\u6709\u4e2d\u65e5\u97e9\u4f7f\u7528\u7684\u6c49\u5b57\u5b57\u7b26\uff0c\u800c\u72ed\u4e49\u7684\u6c49\u5b57\u53ea\u662f\u4e2d\u6587\u91cc\u6700\u5e38\u7528\u7684\u4e00\u90e8\u5206\u3002 TODO Latin-1 \u7684\u8f6c\u6362 Latin-1 \u662f\u4e00\u4e2a 8 \u4f4d\u7f16\u7801\uff0c\u80fd\u8868\u793a 256 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u62c9\u4e01\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u3001\u5e38\u7528\u7684\u897f\u6b27\u5b57\u7b26\uff0c\u4ee5\u53ca\u4e00\u4e9b\u7279\u6b8a\u5b57\u7b26\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u4f60\u9700\u8981\u628a\u4e00\u4e2a Latin-1 \u7f16\u7801\u7684 char \u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a wchar_t \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fed\u4ee3\u5668\u63a5\u53e3\u6784\u9020 std::wstring \uff0c\u8fd9\u6837 char \u4f1a\u88ab\u9010\u4e2a\u8f6c\u6362\u4e3a wchar_t \u3002 std::string latin1 = \"I love P\\xE9ng\"; // 0xE9: \u00e9 std::wstring wstr(latin1.begin(), latin1.end()); std::wcout << wstr << '\\n'; \u8f93\u51fa\uff1a I love P\u00e9ng \u5e76\u4e0d\u6807\u51c6\u7684\u505a\u6cd5\uff0c\u8fd8\u662f\u5efa\u8bae\u7528 boost::locale::conv::to_utf(latin1, \"Latin-1\") \u3002 Latin-1 \u7684\u5999\u7528 \u7531\u4e8e Latin-1 \u8986\u76d6\u4e86\u6240\u6709\u7684 256 \u4e2a char \u7684\u53ef\u80fd\u503c\uff0c\u4efb\u4f55\u5b57\u8282\u6d41\u90fd\u53ef\u4ee5\u6210\u529f\u89e3\u7801\u3002 GBK \u548c UTF-8 \u6709\u81ea\u7ea0\u9519\u6027\uff0c\u6709\u4e9b\u8f93\u5165\u4f1a\u88ab\u584c\u7f29\u6210\u9519\u8bef\u201c\ufffd\u201d\u3002Latin-1 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u7167\u5355\u5168\u6536\uff01 \u56e0\u6b64\u6709\u65f6\uff0c\u4eba\u4eec\u53ef\u4ee5\u6b3a\u9a97\u4e00\u4e2a\u7f16\u7801\u5668\u8bf4\u201c\u6211\u91c7\u7528\u7684\u5b57\u7b26\u7f16\u7801\u662f Latin-1\u201d\uff01\u8fd9\u6837\u7f16\u7801\u5668\u5c31\u4e0d\u4f1a\u5bf9\u8f93\u5165\u7684\u5b57\u8282\u6d41\u505a\u4efb\u4f55\u8f6c\u6362\uff0c\u4ece\u800c\u53ef\u4ee5\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5f53\u6587\u672c\u6765\u4f20\uff0c\u89e3\u7801\u65f6\u4e5f\u6307\u5b9a Latin-1\uff0c\u539f\u539f\u672c\u672c\u7684\u53d6\u51fa\u6570\u636e\u3002 Base64 \u9632\u4e71\u7801 \u5982\u679c\u8981\u628a\u4e00\u4e32\u4e2d\u6587\u8f93\u5165\u4e00\u4e2a\u4e0d\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\uff0c\u53d1\u9001\u8ba9\u5bf9\u65b9\u6536\u5230\uff0c\u600e\u4e48\u529e\uff1f \u53ef\u4ee5\u7528 Latin-1 \u7f16\u7801\uff0c\u9a97\u8fd9\u4e2a\u8f6f\u4ef6\uff0c\u8ba9\u4ed6\u4ee5\u4e3a\u81ea\u5df1\u6536\u5230\u7684\u662f Latin-1 \u5b57\u7b26\u4e32\uff0c\u53cd\u6b63\u4ed6\u4e5f\u4e0d\u770b\u5185\u5bb9\uff0c\u4ece\u800c\u8ba9\u4ed6\u4e0d\u8981\u505a\u4efb\u4f55\u8f6c\u6362\u64cd\u4f5c\u3002 \u4e0d\u8fc7\u6709\u65f6\u5019\uff0c\u6587\u672c\u6846\u65e0\u6cd5\u8f93\u5165\u90e8\u5206\u7279\u6b8a\u7684\u63a7\u5236\u5b57\u7b26\uff0c\u800c UTF-8 \u5b57\u7b26\u4e32\u7f16\u7801\u51fa\u6765\u7684\u6587\u672c\uff0c\u8d85\u8fc7 0x80 \u7684\u90e8\u5206\uff0c\u53ef\u80fd\u843d\u5165 Latin-1 \u7684\u63a7\u5236\u5b57\u7b26\u4e2d\uff0c\u88ab\u8fd9\u4e2a\u8f6f\u4ef6\u9519\u8bef\u5730\u505a\u4e86\u7279\u6b8a\u5904\u7406\u3002 \u4e3a\u4e86\u907f\u514d\u53ea\u517c\u5bb9\u4e86 ASCII \u7684\u843d\u540e\u8f6f\u4ef6\u7834\u574f\u6211\u4eec\u7684\u5b57\u7b26\uff0c\u5bf9\u4e8e\u8fd9\u79cd\u53ea\u652f\u6301 ASCII \u6587\u672c\u7684\u7f16\u8f91\u6846\uff0c\u6211\u4eec\u53ef\u4ee5\u7528 Base64 \u7f16\u7801\u5148\u628a\u4efb\u610f\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u3002 Base64 \u662f\u4e00\u79cd\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u7684\u7b97\u6cd5\uff0c\u539f\u7406\u5f88\u7b80\u5355\uff0c\u5c31\u662f\u628a\u6bcf 6 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u8f6c\u6362\u4e3a\u4e00\u4e2a\u53ef\u6253\u5370\u7684 ASCII \u5b57\u7b26\uff08\u7528 A-Z a-z 0-9 - / \u8fd9 64 \u4e2a\u5b57\u7b26\u8868\u793a\uff09\u3002\u56e0\u6b64\uff0cBase64 \u7f16\u7801\u540e\u7684\u6587\u672c\uff0c\u6bcf 4 \u4e2a\u5b57\u7b26\u5c31\u6709 3 \u4e2a\u662f\u6709\u6548\u5b57\u7b26\uff0c\u5269\u4e0b\u7684 1 \u4e2a\u5b57\u7b26\u662f\u586b\u5145\u5b57\u7b26 = \u3002 \u4f8b\u5982\uff0c\u5b57\u7b26\u4e32 \"\u5c0f\u5f6d\u8001\u5e08\" \uff0c\u4f60\u53ef\u80fd\u60f3\u8981\u628a\u5b83\u901a\u8fc7\u90ae\u4ef6\u53d1\u51fa\u53bb\u3002\u800c\u8fd9\u4e2a\u90ae\u4ef6\u670d\u52a1\u5668\u4e0d\u652f\u6301 UTF-8 \u4e5f\u4e0d\u652f\u6301 GBK\uff0c\u53ea\u652f\u6301 ASCII\uff01 \u9996\u5148\u6211\u4eec\u7528 UTF-8 \u7f16\u7801\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff1a 0xE5 0xB0 0x8F 0xE5 0xBD 0xAD 0xE8 0x80 0x81 0xE5 0xB8 0x88 \u7136\u540e\u518d\u7528 Base64 \u4e8c\u6b21\u7f16\u7801\u6210\u666e\u901a\u7684\u53ef\u6253\u5370\u5b57\u6bcd\u548c\u6570\u5b57\u5e8f\u5217\uff1a 5bCP5b2t6ICB5biI \u5bf9\u65b9\u6536\u5230\u8fd9\u4e32\u795e\u79d8\u5b57\u7b26\u540e\uff0c\u518d\u7528 base64 \u89e3\u7801\uff0c\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c\u518d\u7528\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\u89e3\u7801\uff0c\u5c31\u80fd\u770b\u5230\u672c\u6765\u7684\u4e2d\u6587\u4e86\u3002 # \u53d1\u9001\u8005\uff1a import base64 secret = base64.b64encode(\"\u5c0f\u5f6d\u8001\u5e08\".encode()) # \u63a5\u6536\u8005\uff1a base64.b64decode(secret).decode() \u8fd9\u4e2a\u65b9\u6cd5\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u7801 UTF-8 \u5b57\u7b26\u4e32\uff0c\u8fd8\u53ef\u4ee5\u4f20\u8f93\u4efb\u610f\u975e\u6587\u672c\u7684\u6587\u4ef6\uff01\u4f8b\u5982\uff0c\u6709\u4eba\u5229\u7528 Base64 \u7f16\u7801\uff0c\u628a jpg \u56fe\u50cf\u6587\u4ef6\u76f4\u63a5\u5185\u5d4c\u5728 md \u6587\u4ef6\u91cc\uff01\uff08md \u6587\u4ef6\u53ea\u652f\u6301\u5305\u542b\u5408\u6cd5\u7684 UTF-8 \u6587\u672c\uff0c\u4e0d\u53ef\u80fd\u5305\u542b jpg \u7684\u4efb\u610f\u5b57\u8282\u6d41\uff0c\u56e0\u6b64\u53ea\u80fd\u7528 Base64 \u5148\u7f16\u7801\u6210 ASCII \u8303\u56f4\u5185\u7684\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u9632\u6b62 md \u7f16\u8bd1\u5668\u62a5 UTF-8 \u89e3\u7801\u9519\u8bef\uff09 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u8f93\u5165\u4e2d\u6587\u5b9e\u5728\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u8003\u8651\u5148 Base64 \u8f6c\u6362\u6210\u7eaf\u82f1\u6587\u8bd5\u8bd5\u770b\uff0c\u53cd\u6b63\u65e0\u8bba\u8c01\u90fd\u517c\u5bb9 ASCII\u3002\u5982\u679c\u8fd9\u4e2a\u6587\u672c\u6846\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff0c\u8fd8\u53ef\u4ee5\u8bd5\u8bd5\u770b\u53ea\u6709 A-Z 0-9 \u7684 Base32 \u7f16\u7801\u3002 UTF-7 TODO \u5b57\u7b26\u7f16\u7801\u731c\u6d4b TODO","title":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b"},{"location":"unicode/#_1","text":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u96c6 ASCII Latin-1 Unicode \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801 UTF-32 UTF-8 \u517c\u5bb9 ASCII \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d UTF-16 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 BOM \u6807\u8bb0 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u7684\u7f3a\u9677 GBK GB18030 \u603b\u7ed3 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 UTF-8 \u9635\u8425 UTF-16 \u9635\u8425 UTF-32 \u9635\u8425 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale UTF \u4e4b\u95f4\u4e92\u8f6c GBK \u548c UTF \u4e92\u8f6c UTF \u548c ANSI \u4e92\u8f6c \u5927\u603b\u7ed3 GBK \u548c Shift-JIS \u4e92\u8f6c \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u66f4\u591a\u529f\u80fd\uff1f\uff01 Windows \u7528\u6237\uff1aMultiByteToWideChar MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b Linux \u7528\u6237\uff1aiconv iconv \u547d\u4ee4\u884c\u5de5\u5177 \u672c\u5730\u5316 (locale) \u533a\u5206\u5b57\u7b26\u7c7b\u578b \u5bbd\u5b57\u7b26\u7c7b\u578b wchar_t \u5e94\u7528\u6848\u4f8b \u533a\u57df\u8bbe\u7f6e\u4e0e locale locale \u7684\u547d\u540d\u89c4\u8303 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7279\u6b8a locale\uff1a\"C\" LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801 LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 std::locale \u5bf9\u8c61 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale \u5bbd\u5b57\u7b26\u6d41 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 Windows \u4e13\u9898 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 TCHAR \u6d41\u6d3e UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 Qt QString QTextCodec from/toLocal8Bits/Utf8/Latin1/Ascii \u5b57\u7b26\u4e32\u5e38\u91cf QTextStream Python 3 str Rust &str \u548c String Java String COW \u5b57\u7b26\u4e32 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 Grapheme \u6b63\u89c4\u5316 \u96f6\u5bbd\u7a7a\u683c \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 UniFont \u5b57\u4f53 \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f Latin-1 \u7684\u8f6c\u6362 Latin-1 \u7684\u5999\u7528 Base64 \u9632\u4e71\u7801 UTF-7 \u5b57\u7b26\u7f16\u7801\u731c\u6d4b","title":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b"},{"location":"unicode/#_2","text":"\u8ba1\u7b97\u673a\u4e0d\u80fd\u76f4\u63a5\u5b58\u50a8\u5b57\u7b26\uff0c\u800c\u662f\u7528\u6570\u5b57\u6765\u4ee3\u66ff\uff0c\u8fd9\u5c31\u662f\u5b57\u7b26\u96c6\uff0c\u4e3a\u6bcf\u4e2a\u5b57\u7b26\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57\u3002","title":"\u5b57\u7b26\u96c6"},{"location":"unicode/#ascii","text":"ASCII \u4e3a\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u7ec4\u3001\u6807\u70b9\u7b26\u53f7\u7b49 128 \u4e2a\u5b57\u7b26\uff0c\u6bcf\u4e2a\u90fd\u7528\u4e00\u4e2a 0 \u5230 127 \u8303\u56f4\u5185\u7684\u6570\u5b57\u5bf9\u5e94\u3002 \u5982\u679c\u4f60\u60f3\u8981\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u5c31\u5728\u8fd9\u4e2a\u8868\u91cc\u5bfb\u627e\u5230\u76f8\u5e94\u7684\u6570\u5b57\u7f16\u53f7\uff0c\u7136\u540e\u5b58\u8fd9\u4e2a\u7f16\u53f7\u5373\u53ef\u3002 \u4f8b\u5982\u4e0b\u9762\u7684\u4e00\u4e32\u6570\u5b57\uff1a 80 101 110 103 \u5728 ASCII \u8868\u4e2d\u67e5\u627e\uff0c\u53d1\u73b0\u8fd9\u4e9b\u6570\u5b57\u5206\u522b\u5bf9\u5e94 P \u3001 e \u3001 n \u3001 g \u56db\u4e2a\u5b57\u6bcd\uff0c\u8fde\u8d77\u6765\u5c31\u8fd8\u539f\u5f97\u5230\u4e86\u539f\u672c\u7684\u5b57\u7b26\u4e32\u201cPeng\u201d\u3002","title":"ASCII"},{"location":"unicode/#latin-1","text":"Latin-1 \u6269\u5145\u4e86 ASCII \u5b57\u7b26\u96c6\uff0c\u4fdd\u6301 ASCII \u539f\u6709 0 \u5230 127 \u7684\u90e8\u5206\u6620\u5c04\u4e0d\u53d8\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 128 \u5230 255 \u7684\u6620\u5c04\u5173\u7cfb\u3002\u56e0\u6b64\u4e5f\u88ab\u79f0\u4e3a EASCII\uff08\u6269\u5c55 ASCII\uff09\u3002","title":"Latin-1"},{"location":"unicode/#unicode","text":"Unicode \u5b57\u7b26\u96c6\u4e3a\u5168\u4e16\u754c\u7684\u6240\u6709\u5b57\u7b26\u90fd\u5bf9\u5e94\u4e86\u4e00\u4e2a\u6574\u6570\u3002 \u5b57\u7b26 \u7f16\u53f7 \u6211 25105 \u6212 25106 \u6213 25107 \u6214 25108 \u6215 25109 \u6216 25110 \u6217 25111 \u6218 25112 \u6219 25113 \u621a 25114 \u51fa\u4e8e\u5386\u53f2\u517c\u5bb9\u6027\u8003\u8651\uff0cUnicode \u5728 0 \u5230 256 \u533a\u95f4\u5185\u7684\u6620\u5c04\u548c ASCII\u3001Latin-1 \u662f\u5b8c\u5168\u76f8\u540c\u7684\u3002 \u5b57\u7b26 \u7f16\u53f7 P 80 e 101 n 110 g 103 Unicode \u7ecf\u8fc7\u4e86\u8bb8\u591a\u7248\u672c\u7684\u53d1\u5c55\uff0c\u65e9\u671f\u7684 Unicode \u53ea\u6536\u5f55\u4e86 65536 (0x10000) \u4e2a\u5b57\u7b26\uff0c\u540e\u6765\u6269\u5145\u5230\u4e86 1114112 (0x110000) \u4e2a\u5b57\u7b26\u3002 \u603b\u4e4b\uff0c\u73b0\u5728 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u867d\u7136\u5360\u7528\u4e86 1114112 \u8fd9\u591a\u683c\u7801\u70b9\u7a7a\u95f4\uff0c\u4e0d\u8fc7\u5176\u4e2d\u5f88\u591a\u90fd\u662f\u7a7a\u53f7\uff0c\u7559\u5f85\u672a\u6765\u6269\u5145\u4f7f\u7528\u3002 Unicode \u5b57\u7b26\u6620\u5c04\u8868\u53ef\u4ee5\u5728\u7f51\u4e0a\u627e\u5230\uff1a https://symbl.cc/en/unicode-table/ https://www.compart.com/en/unicode/","title":"Unicode"},{"location":"unicode/#_3","text":"\u5b57\u7b26\u96c6: \u4ece\u5b57\u7b26\u5230\u6574\u6570\u7684\u4e00\u4e00\u6620\u5c04\u3002 ASCII: \u53ea\u6536\u5f55\u4e86\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 Latin-1: \u5728 ASCII \u57fa\u7840\u4e0a\u8ffd\u52a0\u4e86\u6ce8\u97f3\u5b57\u6bcd\uff0c\u6ee1\u8db3\u6b27\u6d32\u7528\u6237\u9700\u8981\u3002 Unicode: \u6536\u5f55\u4e86\u5168\u4e16\u754c\u6240\u6709\u6587\u5b57\u548c\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 \u8ba1\u7b97\u673a\u5b58\u50a8\u5b57\u7b26\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u5b58\u50a8\u4e86\u90a3\u4e2a\u5bf9\u5e94\u7684\u6574\u6570\u3002 \u8fd9\u4e9b\u6574\u6570\u5c31\u88ab\u79f0\u4e3a \u7801\u70b9 (code point) \uff0c\u6bcf\u4e2a\u5b57\u7b26\u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002 \u4e0d\u8fc7\uff0c\u7a0b\u5e8f\u5458\u901a\u5e38\u559c\u6b22\u7528\u5341\u516d\u8fdb\u5236\u4e66\u5199\u6570\u5b57\uff1a \u5b57\u7b26 \u7f16\u53f7 \u6211 0x6211 \u6212 0x6212 \u6213 0x6213 \u6214 0x6214 \u6215 0x6215 \u6216 0x6216 \u6217 0x6217 \u6218 0x6218 \u6219 0x6219 \u621a 0x621A \u4f8b\u5982\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\uff0c\u5728 Unicode \u8868\u4e2d\u7f16\u53f7\u4e3a 0x6211\u3002\u4e8e\u662f\u5f53\u8ba1\u7b97\u673a\u9700\u8981\u8868\u793a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\u65f6\uff0c\u5c31\u7528 0x6211 \u8fd9\u4e2a\u6574\u6570\u4ee3\u66ff\u3002 \u5982\u679c\u8981\u8868\u793a\u591a\u4e2a\u5b57\u7b26\uff0c\u90a3\u5c31\u7528\u4e00\u4e2a\u6574\u6570\u7684\u6570\u7ec4\u5427\uff01 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5904\u7406\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a 0x6211 0x7231 0x30EDE 0x30EDE 0x9762 0x21 \u8fd9\u4e00\u4e32\u6570\u5b57\u4ee3\u66ff\u3002 \u5982\u679c\u4f60\u8fd9\u91cc\u770b\u5230\u7684\u662f\u201c\u6211\u7231\u53e3\u53e3\u9762!\u201d\u8bf4\u660e\u4f60\u7684\u5b57\u4f53\u4e0d\u652f\u6301\u201cbi\u00e1ng\u201d\u8fd9\u4e2a\u5b57\u3002\u5f53\u6d4f\u89c8\u5668\u9047\u5230\u5f53\u524d\u5b57\u4f53\u4e0d\u652f\u6301\u7684 Unicode \u5b57\u7b26\u65f6\uff0c\u5c31\u4f1a\u66ff\u6362\u4e3a\u65b9\u5757\u3002\u5efa\u8bae\u5b89\u88c5\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u8f83\u591a\u7684 \u201cNoto Sans CJK SC\u201d \u5b57\u4f53\uff0c\u4e5f\u53ef\u4ee5\u5b89\u88c5\u652f\u6301\u4e00\u5207 Unicode \u5b57\u7b26\u7684 \u201cUniFonts\u201d\u3002 sudo apt-get install -y fonts-noto-cjk \u201c\ud883\udede(bi\u00e1ng)\ud883\udede(bi\u00e1ng)\u9762\u201d\u662f\u6d41\u884c\u4e8e\u4e2d\u56fd\u9655\u897f\u5173\u4e2d\u5730\u533a\u7684\u4e00\u79cd\u77e5\u540d\u4f20\u7edf\u98ce\u5473\u9762\u98df\uff0c\u5c5e\u4e8e\u626f\u9762\uff0c\u901a\u8fc7\u63c9\u3001\u62bb\u3001\u7529\u3001\u626f\u7b49\u6b65\u9aa4\u5236\u4f5c\uff0c\u9762\u5bbd\u800c\u539a\uff0c\u72b9\u5982\u201c\u88e4\u8170\u5e26\u201d\uff0c\u53e3\u611f\u52b2\u9053\uff0c\u98df\u7528\u524d\u52a0\u5165\u5404\u8272\u81ca\u5b50\u6216\u6cb9\u6cfc\u8fa3\u5b50\u3002\u4f46\u662f\uff0c\u5c0f\u5f6d\u8001\u5e08\u5176\u5b9e\u5e76\u6ca1\u6709\u5403\u8fc7\uff0c\u53ea\u662f\u56e0\u4e3a\u7a00\u6709\u5b57\u4f53\u770b\u8d77\u6765\u6bd4\u8f83\u597d\u73a9\u3002","title":"\u603b\u7ed3"},{"location":"unicode/#_4","text":"Unicode \u53ea\u662f\u6307\u5b9a\u4e86\u6574\u6570\uff0c\u6ca1\u6709\u89c4\u5b9a\u6574\u6570\u5982\u4f55\u5728\u5185\u5b58\u4e2d\u5b58\u5728\u3002 \u5b57\u7b26\u7f16\u7801: \u5c06\u5b57\u7b26\u7684\u6574\u6570\u7f16\u53f7\u5e8f\u5217\u5316\u4e3a\u8ba1\u7b97\u673a\u53ef\u76f4\u63a5\u5b58\u50a8\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u5b9e\u9645\u5b58\u5728\u7684\u6574\u6570\u7c7b\u578b\u3002 Unicode \u5b57\u7b26\u53ef\u4ee5\u9009\u7528\u4ee5\u4e0b\u8fd9\u4e9b\u5b57\u7b26\u7f16\u7801\u6765\u5e8f\u5217\u5316\uff1a UTF-32: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u4e2a uint32_t \u6574\u6570\u5b58\u50a8\u3002 UTF-16: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 2 \u4e2a uint16_t \u6574\u6570\u5b58\u50a8\u3002 UTF-8: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u5b58\u50a8\u3002 \u7ffb\u8bd1\u51fa\u6765\u7684\u8fd9\u4e9b\u5c0f\u6574\u6570\u53eb \u7801\u4f4d (code unit) \u3002\u4f8b\u5982\u5bf9\u4e8e UTF-8 \u800c\u8a00\uff0c\u6bcf\u4e2a uint8_t \u5c31\u662f\u4ed6\u7684\u7801\u4f4d\u3002","title":"\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#utf-32","text":"Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u6700\u5927\u503c 0x10FFFF \u6709 21 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0cC \u8bed\u8a00\u4e2d uint32_t \u80fd\u5bb9\u7eb3 32 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0c\u6240\u4ee5\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u662f\u76f4\u63a5\u7528 uint32_t \u6570\u7ec4\u6765\u4e00\u4e2a\u4e2a\u5bb9\u7eb3 Unicode \u5b57\u7b26\u7801\u70b9\u3002\u867d\u7136\u6d6a\u8d39\u4e86 11 \u4f4d\uff0c\u4f46\u81f3\u5c11\u6240\u6709 Unicode \u5b57\u7b26\u90fd\u80fd\u5b89\u5168\u5bb9\u7eb3\u3002 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a std::vector s = { 0x00006211, // \u6211 0x00007231, // \u7231 0x00030EDE, // \ud883\udede 0x00030EDE, // \ud883\udede 0x00009762, // \u9762 0x00000021, // ! }; \u8fd9\u4e2a\u6570\u7ec4\u8868\u793a\u3002 UTF-32 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u56fa\u5b9a\u5bf9\u5e94\u4e00\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-32 \u662f \u5b9a\u957f\u7f16\u7801 \u3002\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5c31\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002 \u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u6570\u7ec4\u7684\u7d22\u5f15\u64cd\u4f5c\u3002 \u65e0\u8bba\u5bf9\u6570\u7ec4\u5982\u4f55\u5207\u7247\uff0c\u90fd\u4e0d\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u7834\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u5c31\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u53cd\u8f6c\uff0c\u4e0d\u4f1a\u4ea7\u751f\u7834\u574f\u5b57\u7b26\u7684\u95ee\u9898\u3002 \u7f3a\u70b9\u662f\uff1a \u6d6a\u8d39\u5b58\u50a8\u7a7a\u95f4\u3002 \u5b9a\u957f\u7f16\u7801\u5f88\u65b9\u4fbf\uff0c\u6211\u4eec\u63a8\u8350\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\uff0c\u7edf\u4e00\u91c7\u7528 UTF-32 \u5f62\u5f0f\u5904\u7406\u6587\u5b57\u3002 UTF-32 \u4e5f\u88ab\u79f0\u4e3a UCS-4\uff0c\u4ed6\u4fe9\u662f\u540c\u4e49\u8bcd\u3002","title":"UTF-32"},{"location":"unicode/#utf-8","text":"UTF-32 \u867d\u7136\u65b9\u4fbf\u4e86\u6587\u5b57\u5904\u7406\uff0c\u7136\u800c\uff0c\u5374\u6d6a\u8d39\u4e86\u5927\u91cf\u7684\u5b58\u50a8\u7a7a\u95f4\uff0c\u4e0d\u5229\u4e8e\u6587\u5b57\u5b58\u50a8\uff01\u4e00\u4e2a\u5b57\u7b26\uff0c\u65e0\u8bba\u4ed6\u662f\u5e38\u7528\u8fd8\u662f\u4e0d\u5e38\u7528\uff0c\u90fd\u8981\u9738\u5360 4 \u4e2a\u5b57\u8282\u7684\u7a7a\u95f4\u3002 Unicode \u7f16\u7801\u5b57\u7b26\u65f6\uff0c\u7279\u610f\u628a\u5e38\u7528\u7684\u5b57\u7b26\u9760\u524d\u6392\u5217\u4e86\u3002 \u4e16\u754c\u4e0a\u5e38\u7528\u8bed\u8a00\u6587\u5b57\u90fd\u88ab\u523b\u610f\u7f16\u7801\u5728\u4e86 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u8d85\u8fc7 0x10000 \u7684\u57fa\u672c\u90fd\u662f\u4e0d\u5e38\u7528\u7684\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\uff0c\u5f88\u591a\u90fd\u662f\u5df2\u7ecf\u65e0\u4eba\u4f7f\u7528\u7684\u53e4\u4ee3\u6587\u5b57\u548c\u751f\u50fb\u5b57\uff0c\u4f8b\u5982\u201c\ud883\udede\u201d\u3002\u4ec5\u4ec5\u662f\u4e3a\u4e86\u8fd9\u4e9b\u5076\u5c14\u4f7f\u7528\u7684\u7f55\u89c1\u6587\u5b57\uff0c\u5c31\u8981\u6c42\u6240\u6709\u6587\u5b57\u90fd\u7528\u540c\u6837\u7684 4 \u5b57\u8282\u5bbd\u5ea6\u5b58\u50a8\uff0c\u5b9e\u5728\u662f\u6709\u70b9\u6d6a\u8d39\u3002 \u5728 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u540c\u6837\u6709\u6309\u7167\u5e38\u7528\u5ea6\u6392\u5e8f\uff1a 0 \u5230 0x7F \u662f\uff08\u6b27\u7f8e\u7528\u6237\uff09\u6700\u5e38\u7528\u7684\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u534a\u89d2\u6807\u70b9\u3002 0x80 \u5230 0x7FF \u662f\u8868\u97f3\u6587\u5b57\u533a\uff0c\u5e38\u7528\u7684\u6ce8\u97f3\u5b57\u6bcd\u3001\u62c9\u4e01\u5b57\u6bcd\u3001\u5e0c\u814a\u5b57\u6bcd\u3001\u897f\u91cc\u5c14\u5b57\u6bcd\u3001\u5e0c\u4f2f\u6765\u5b57\u6bcd\u7b49\u3002 0x800 \u5230 0xFFFF \u662f\u8868\u610f\u6587\u5b57\uff0c\u7b80\u7e41\u4e2d\u6587\u3001\u65e5\u6587\u3001\u97e9\u6587\u3001\u6cf0\u6587\u3001\u9a6c\u6765\u6587\u3001\u963f\u62c9\u4f2f\u6587\u7b49\u3002 0x10000 \u5230 0x10FFFF \u662f\u4e0d\u5e38\u7528\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\u3002 UTF-8 \u5c31\u662f\u4e3a\u4e86\u89e3\u51b3\u538b\u7f29\u95ee\u9898\u800c\u8bde\u751f\u7684\u3002 UTF-8 \u628a\u4e00\u4e2a\u7801\u70b9\u5e8f\u5217\u5316\u4e3a\u4e00\u4e2a\u6216\u591a\u4e2a\u7801\u4f4d\uff0c\u4e00\u4e2a\u7801\u4f4d\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u8868\u793a\u3002 0 \u5230 0x7F \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 1 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 2 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 3 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 4 \u4e2a\u5b57\u8282\u8868\u793a\u3002 \u5e8f\u5217\u5316\u89c4\u5219\u5982\u4e0b\uff1a","title":"UTF-8"},{"location":"unicode/#ascii_1","text":"\u5bf9\u4e8e 0 \u5230 0x7F \u7684\u5b57\u7b26\uff0c\u8fd9\u4e2a\u8303\u56f4\u7684\u5b57\u7b26\u9700\u8981 7 \u4f4d\u5b58\u50a8\u3002 \u6211\u4eec\u9009\u62e9\u76f4\u63a5\u5b58\u50a8\u5176\u503c\u3002 \u4f8b\u5982 \u2018P\u2019 \u4f1a\u88ab\u76f4\u63a5\u5b58\u50a8\u5176 Unicode \u503c\u7684 80\uff080x50\uff09\uff1a 01010000 \u7531\u4e8e Unicode \u5728 0 \u5230 0x7F \u8303\u56f4\u5185\u4e0e ASCII \u8868\u76f8\u540c\uff0c\u800c UTF-8 \u53c8\u628a 0 \u5230 0x7F \u7684\u503c\u76f4\u63a5\u5b58\u50a8\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u517c\u5bb9 ASCII\u3002\u8fd9\u4f7f\u5f97\u539f\u672c\u8bbe\u8ba1\u4e8e\u5904\u7406 ASCII \u7684 C \u8bed\u8a00\u51fd\u6570\uff0c\u4f8b\u5982 strlen\u3001strcat\u3001sprintf \u7b49\uff0c\u90fd\u53ef\u4ee5\u76f4\u63a5\u65e0\u7f1d\u5207\u6362\u5230 UTF-8\u3002\u53cd\u4e4b\u4ea6\u7136\uff0c\u4efb\u4f55\u8bbe\u8ba1\u7528\u4e8e UTF-8 \u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u5b8c\u5168\u63a5\u53d7 ASCII \u683c\u5f0f\u7684\u8f93\u5165\u6587\u672c\u3002 \u4f46\u90e8\u5206\u6d89\u53ca\u5b57\u7b26\u957f\u5ea6\u7684\u51fd\u6570\u4f1a\u6709\u4e9b\u8bb8\u4e0d\u517c\u5bb9\uff0c\u4f8b\u5982 strlen \u6c42\u51fa\u7684\u957f\u5ea6\u4f1a\u53d8\u6210\u5b57\u8282\u7684\u6570\u91cf\u800c\u4e0d\u662f\u5b57\u7b26\u7684\u6570\u91cf\u4e86\uff0c\u4f8b\u5982 strlen(\"\u6211\u4eec\") \u4f1a\u5f97\u5230 6 \u800c\u4e0d\u662f 2\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002","title":"\u517c\u5bb9 ASCII"},{"location":"unicode/#_5","text":"UTF-8 \u7684\u6784\u9020\u5c31\u50cf\u4e00\u5217\u5c0f\u706b\u8f66\u4e00\u6837\uff0c\u4e0d\u540c\u8303\u56f4\u5185\u7684\u7801\u4f4d\u4f1a\u88ab\u7f16\u7801\u6210\u4e0d\u540c\u957f\u5ea6\u7684\u5217\u8f66\uff0c\u4f46\u4ed6\u4eec\u90fd\u6709\u4e00\u4e2a\u8f66\u5934\u3002 \u6839\u636e\u706b\u8f66\u5934\u7684\u201c\u7b49\u7ea7\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u540e\u9762\u62c9\u7740\u51e0\u8282\u8f66\u53a2\u3002 \u706b\u8f66\u5934\u662f\u4ec0\u4e48\u7b49\u7ea7\u7531\u4ed6\u7684\u4e8c\u8fdb\u5236\u524d\u7f00\u51b3\u5b9a\uff1a \u5982\u679c\u662f 0 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u662f\u5355\u72ec\u4e00\u53f0\u706b\u8f66\u5934\uff0c\u540e\u9762\u6ca1\u6709\u8f66\u53a2\u4e86\uff0c\u8fd9\u8868\u793a\u8f66\u5934\u91cc\u9762\u76f4\u63a5\u88c5\u7740 0 \u5230 0x7F \u8303\u56f4\u7684\u666e\u901a ASCII \u5b57\u7b26\u3002 \u5982\u679c\u662f 110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e00\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u6b27\u6d32\u5b57\u7b26\u3002 \u5982\u679c\u662f 1110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e24\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u4e16\u754c\u5e38\u7528\u5b57\u7b26\u3002 \u5982\u679c\u662f 11110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e09\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u751f\u50fb\u5b57\u7b26\u3002 \u5982\u679c\u662f 10 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u8fd9\u662f\u4e00\u8282\u8f66\u53a2\uff0c\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002\u5982\u679c\u4f60\u770b\u5230\u4e00\u8282\u5355\u72ec\u7684\u8f66\u53a2\u5728\u524d\u9762\u65e0\u5934\u9a7e\u9a76\uff0c\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\u3002 \u5c0f\u670b\u53cb\u7528\u5c0f\u53f7\u5217\u8f66\u88c5\uff0c\u5927\u670b\u53cb\u7528\u5927\u53f7\u5217\u8f66\u88c5\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u4e32\u4e8c\u8fdb\u5236\uff1a 11100110 10000010 10000001 \u9996\u5148\uff0c\u770b\u5230\u7b2c\u4e00\u4e2a\u5b57\u8282\uff0c\u662f 1110 \u5f00\u5934\u7684\u4e09\u7ea7\u8f66\u5934\uff01\u8bf4\u660e\u540e\u9762\u8fd8\u6709\u4e24\u8282\u8f66\u53a2\u662f\u5c5e\u4e8e\u4ed6\u7684\u3002\u706b\u8f66\u5934\u4e2d 4 \u4f4d\u7528\u4e8e\u8868\u793a\u8f66\u5934\u7b49\u7ea7\u4e86\uff0c\u5269\u4e0b\u8fd8\u6709 4 \u4f4d\u7528\u4e8e\u88c5\u4e58\u5ba2\u3002 \u8f66\u53a2\u4e5f\u6709\u56fa\u5b9a\u7684\u524d\u7f00\uff0c\u6240\u6709\u7684\u8f66\u53a2\u90fd\u5fc5\u987b\u662f 10 \u5f00\u5934\u7684\u3002\u53bb\u9664\u8fd9\u5f00\u5934\u7684 2 \u4f4d\uff0c\u5269\u4e0b\u7684 6 \u4f4d\u5c31\u662f\u4e58\u5ba2\u3002 \u5bf9\u4e8e\u8fd9\u79cd\u4e09\u7ea7\u5217\u8f66\uff0c4 + 6 + 6 \u603b\u5171 16 \u4f4d\u4e8c\u8fdb\u5236\uff0c\u521a\u597d\u53ef\u4ee5\u88c5\u5f97\u4e0b 0xFFFF \u5185\u7684\u4e58\u5ba2\u3002 0110 000010 000001 \u7f16\u7801\u65f6\u5219\u662f\u53cd\u8fc7\u6765\u3002 \u4e58\u5ba2\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e09\u7247\uff0c\u4f8b\u5982\u5bf9\u4e8e\u201c\u6211\u201d\u8fd9\u4e2a\u4e58\u5ba2\uff0c\u201c\u6211\u201d\u7684\u7801\u70b9\u662f 0x6211\uff0c\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u662f\uff1a 110001000010001 \u628a\u4e58\u5ba2\u5207\u5206\u6210\u9ad8 4 \u4f4d\u3001\u4e2d 6 \u4f4d\u548c\u4f4e 6 \u4f4d\uff08\u4e0d\u8db3\u65f6\u5728\u524d\u9762\u8865\u96f6\uff09\uff1a 0110 001000 010001 \u52a0\u4e0a 1110 \u3001 10 \u548c 10 \u524d\u7f00\u540e\uff0c\u5f62\u6210\u4e00\u5217\u706b\u8f66\uff1a 11100110 10001000 10010001 \u8fd9\u6837\uff0c\u6211\u4eec\u5c31\u628a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\uff0c\u7f16\u7801\u6210\u4e86\u4e09\u8282\u5217\u8f66\uff0c\u585e\u8fdb\u5b57\u8282\u6d41\u7684\u7f51\u7edc\u96a7\u9053\u91cc\u4e86\u3002 \u603b\u7ed3\uff1a \u524d\u7f00\u662f 0 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 7 \u540d\u3002 \u524d\u7f00\u662f 10 \u7684\u662f\u8f66\u53a2\uff1a\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002 \u524d\u7f00\u662f 110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 5 \u540d + 1 \u8282\u8f66\u53a2\u8f7d\u5ba2 6 \u540d = \u5171 11 \u540d\u3002 \u524d\u7f00\u662f 1110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 4 \u540d + 2 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 16 \u540d\u3002 \u524d\u7f00\u662f 11110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 3 \u540d + 3 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 21 \u540d\u3002 \u9ad8\u7ea7\u8f66\u5934\u88c5\u4e86\u9632\u5f39\u94a2\u677f\uff0c\u8f7d\u5ba2\u7a7a\u95f4\u53d8\u5c11\uff0c\u53ea\u597d\u5300\u5230\u540e\u9762\u7684\u8f66\u53a2\u3002","title":"\u89e3\u7801\u89c4\u5219"},{"location":"unicode/#utf-8_1","text":"\u5982\u679c\u53d1\u73b0 10 \u5f00\u5934\u7684\u72ec\u7acb\u8f66\u53a2\uff0c\u5c31\u8bf4\u660e\u51fa\u95ee\u9898\u4e86\uff0c\u53ef\u80fd\u662f\u706b\u8f66\u88ab\u9519\u8bef\u62e6\u8170\u622a\u65ad\uff0c\u4e5f\u53ef\u80fd\u662f\u5b57\u7b26\u4e32\u88ab\u9519\u8bef\u5730\u53cd\u8f6c\u3002\u56e0\u4e3a 10 \u53ea\u53ef\u80fd\u662f\u706b\u8f66\u8f66\u53a2\uff0c\u4e0d\u53ef\u80fd\u51fa\u73b0\u5728\u706b\u8f66\u5934\u90e8\u3002\u6b64\u65f6\u89e3\u7801\u5668\u5e94\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u66ff\u6362\u3002 10000010 10000001 \u5728\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u5982\u679c\u4f60\u4e0d\u59a5\u5584\u5904\u7406 TCP \u7c98\u5305\u95ee\u9898\uff0c\u5c31\u53ef\u80fd\u706b\u8f66\u5934\u8fdb\u53bb\u4e86\uff0c\u706b\u8f66\u5c3e\u5df4\u8fd8\u9732\u5728\u96a7\u9053\u5916\u9762\uff0c\u4e00\u6bb5\u5b8c\u6574\u7684\u5217\u8f66\u88ab\u5207\u65ad\uff0c\u5bfc\u81f4 UTF-8 \u89e3\u8bfb\u7684\u65f6\u5019\u51fa\u9519\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u8bbe\u7acb\u4e00\u4e2a\u72b6\u6001\u673a\u6765\u89e3\u7801 UTF-8\u3002C \u8bed\u8a00\u7684 mbstate_t \u5c31\u662f\u8fd9\u79cd\u72b6\u6001\u673a\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u9664\u6b64\u4e4b\u5916\uff0c\u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\uff0c\u5374\u53d1\u73b0\u91cc\u9762\u88c5\u7740 0x394 (\u201c\u0394\u201d)\uff0c\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u5c31\u80fd\u88c5\u4e0b\u7684\u6b27\u6d32\u5b57\u7b26\uff0c\u5374\u7528\u4e86\u4e09\u7ea7\u706b\u8f66\u5934\u88c5\uff0c\u8bf4\u660e\u88c5\u7bb1\u90a3\u8fb9\u7684\u4eba\u5077\u61d2\u6ee5\u7528\u8d44\u6e90\u4e86\uff01\u8fd9\u79cd\u60c5\u51b5\u4e0b UTF-8 \u89e3\u7801\u5668\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u8981\u4fdd\u8bc1\u7f16\u7801\u7684\u552f\u4e00\u6027\uff0c0x394 \u662f 0x7F \u5230 0x7FF \u8303\u56f4\u7684\uff0c\u5c31\u5e94\u8be5\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u88c5\u3002 \u4ee5\u53ca\uff0c\u5982\u679c\u53d1\u73b0 11111 \u5f00\u5934\u7684\u4e94\u7ea7\u706b\u8f66\u5934\uff0c\u4e5f\u8981\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u6700\u591a\u53ea\u652f\u6301\u56db\u7ea7\u706b\u8f66\u5934\u3002 \u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u56db\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u7684\u5b57\u7b26\u8303\u56f4\u8d85\u8fc7\u4e86 0x10FFFF\uff0c\u8fd9\u8d85\u51fa\u4e86 Unicode \u7684\u8303\u56f4\uff0c\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\u3002\u5982\u679c\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u53d1\u73b0\u5b57\u7b26\u8303\u56f4\u5904\u5728\u4fdd\u7559\u533a 0xD800 \u5230 0xDFFF \u5185\uff0c\u8fd9\u662f Unicode \u627f\u8bfa\u6c38\u4e0d\u52a0\u5165\u5b57\u7b26\u7684\u533a\u95f4\uff08\u7a0d\u540e\u8bb2\u89e3 UTF-16 \u65f6\u4f1a\u89e3\u91ca\u4e3a\u4ec0\u4e48\uff09\uff0c\u4e5f\u8981\u62a5\u9519\u3002\u603b\u4e4b Unicode \u7801\u70b9\u7684\u5408\u6cd5\u8303\u56f4\u662f 0x0 \u5230 0xD7FF\uff0c0xE000 \u5230 0x10FFFF\u3002 \u603b\u4e4b\uff0cUTF-8 \u5177\u6709\u4e00\u5b9a\u7684\u5197\u4f59\u548c\u81ea\u7ea0\u9519\u80fd\u529b\uff0c\u5982\u679c\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u5dee\u9519\uff0c\u53ef\u80fd\u4f1a\u7206\u51fa\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u3002\u8fd9\u4e2a\u7279\u6b8a\u5b57\u7b26\u662f Unicode \u5b98\u65b9\u89c4\u5b9a\u7684\uff0c\u7801\u70b9\u4e3a 0xFFFD\uff0c\u51fa\u73b0\u4ed6\u5c31\u610f\u5473\u7740 UTF-8 \u89e3\u7801\u5931\u8d25\u4e86\u3002","title":"UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b"},{"location":"unicode/#_6","text":"\u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u4ee5 UTF-8 \u683c\u5f0f\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff1a std::vector s = { 0xE6, 0x88, 0x91, // \u6211\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xE7, 0x88, 0xB1, // \u7231\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xE9, 0x9D, 0xA2, // \u9762\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0x21, // !\uff0c\u8fd9\u662f\u4e2a ASCII \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u76f4\u63a5\u7528\u5355\u4e2a\u706b\u8f66\u5934\u88c5 }; UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u53ef\u80fd\u5bf9\u5e94\u591a\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u662f\u4e00\u79cd \u53d8\u957f\u7f16\u7801 \u3002\u53d8\u957f\u7f16\u7801\u7684\u7f3a\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4e0d\u4e00\u5b9a\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002\u56e0\u6b64\uff0c\u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\u3002 \u6570\u7ec4\u7684\u5355\u4e2a\u5143\u7d20\u7d22\u5f15\uff0c\u65e0\u6cd5\u4fdd\u8bc1\u53d6\u51fa\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u3002 \u5bf9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u53ef\u80fd\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u5207\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u4e0d\u4e00\u5b9a\u80fd\u628a\u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\uff0c\u56e0\u4e3a\u53ef\u80fd\u4e0d\u614e\u628a\u4e00\u4e2a\u5b57\u7b26\u7684\u591a\u4e2a\u7801\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u5b57\u7b26\u7834\u574f\u3002 \u4f18\u70b9\u662f\uff1a \u8282\u7ea6\u5b58\u50a8\u7a7a\u95f4\u3002 \u6211\u4eec\u63a8\u8350\u53ea\u5728\u7f51\u7edc\u901a\u4fe1\u3001\u786c\u76d8\u5b58\u50a8\u65f6\uff0c\u91c7\u7528 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u6587\u5b57\u3002 \u603b\u7ed3\uff1a UTF-8 \u9002\u5408\u5b58\u50a8\uff0cUTF-32 \u9002\u5408\u5904\u7406 \u3002 \u6211\u4eec\u5efa\u8bae\u8ba1\u7b97\u673a\u4ece\u786c\u76d8\u6216\u7f51\u7edc\u4e2d\u8bfb\u51fa UTF-8 \u5b57\u7b26\u4e32\u540e\uff0c\u7acb\u5373\u5c06\u5176\u8f6c\u6362\u4e3a UTF-32\uff0c\u4ee5\u65b9\u4fbf\u540e\u7eed\u6587\u5b57\u5904\u7406\u3002\u5f53\u9700\u8981\u5199\u5165\u786c\u76d8\u6216\u7f51\u7edc\u65f6\uff0c\u518d\u8f6c\u6362\u56de UTF-8\uff0c\u907f\u514d\u786c\u76d8\u5bb9\u91cf\u548c\u7f51\u7edc\u5e26\u5bbd\u7684\u6d6a\u8d39\u3002 \u8ba1\u7b97\u673a\u9700\u8981\u5916\u7801\u548c\u5185\u7801\u4e24\u79cd\uff1a \u5916\u7801=\u786c\u76d8\u4e2d\u7684\u6587\u672c=UTF-8 \u5185\u7801=\u5185\u5b58\u4e2d\u7684\u6587\u672c=UTF-32","title":"\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d"},{"location":"unicode/#utf-16","text":"UTF-16 \u7684\u7b56\u7565\u662f\uff1a\u65e2\u7136\u5927\u591a\u6570\u5e38\u7528\u5b57\u7b26\u7684\u7801\u70b9\u90fd\u5728 0x0 \u5230 0xFFFF \u5185\uff0c\u7528 uint32_t \u6765\u5b58\u50a8\u4e5f\u592a\u6d6a\u8d39\u4e86\u3002\u4ed6\u7684\u65b9\u6848\u5982\u4e0b\uff1a \u5bf9\u4e8e 0x0 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u5c31\u7528\u4e00\u4e2a uint16_t \u76f4\u63a5\u5b58\u3002 \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u53cd\u6b63\u4e0d\u5e38\u89c1\uff0c\u5c31\u62c6\u6210\u4e24\u4e2a uint16_t \u5b58\u3002\u8fd9\u4e2a\u62c6\u7684\u65b9\u6848\u5f88\u6709\u8bb2\u7a76\uff0c\u5982\u679c\u53ea\u662f\u666e\u901a\u7684\u62c6\uff0c\u7531\u4e8e\u89e3\u7801\u65f6\u6536\u5230\u7684\u662f\u4e2a\u6ca1\u5934\u6ca1\u5c3e\u7684\u5b57\u8282\u5e8f\u5217\uff0c\u65e0\u6cd5\u5206\u8fa8\u8fd9\u5230\u5e95\u662f\u4e24\u4e2a uint16_t \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u8fd8\u662f\u4e00\u4e2a uint16_t \u7684\u666e\u901a\u5b57\u7b26\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u628a\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u201c\ud883\udede\u201d\uff0c0x30EDE\u3002\u62c6\u6210\u4e24\u4e2a uint16_t \uff0c\u5f97\u5230 0x3 \u548c 0x0EDE\u3002\u5982\u679c\u76f4\u63a5\u5b58\u50a8\u8fd9\u4e24\u4e2a uint16_t \uff1a 0x0003 0x0EDE \u4e4b\u540e\u89e3\u7801\u65f6\uff0c\u5148\u8bfb\u5230 0x0003\uff0c\u8fd8\u4f1a\u4ee5\u4e3a\u4ed6\u662f\u5355\u72ec\u7684\u4e00\u4e2a uint16_t \uff0c\u8868\u793a 3 \u53f7\u5b57\u7b26\u201c\u201d\u3002\u540e\u9762\u7684 0x0EDE \u5c31\u53d8\u6210\u4e86\u4e00\u4e2a\u5355\u72ec\u7684 0x0EDE\uff0c\u53d8\u6210\u4e86 0x0EDE \u53f7\u5b57\u7b26 \u201c\u0ede\u201d\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u201c\ud883\udede\u201d\u5c31\u53d8\u6210\u4e86\u4e24\u4e2a\u6beb\u4e0d\u76f8\u5e72\u7684\u5b57\u7b26\uff0c\u201c\u0ede\u201d\u4e86\u3002 \u4e3a\u4e86\u907f\u514d\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u4e24\u4e2a uint16_t \u9700\u8981\u91c7\u7528\u4e00\u79cd\u7279\u6b8a\u7684\u65b9\u5f0f\u4ee5\u793a\u533a\u5206\u3002\u8ba9\u89e3\u7801\u5668\u4e00\u770b\u5230\uff0c\u5c31\u80fd\u786e\u5b9a\u8fd9\u4e24\u4e2a uint16_t \u9700\u8981\u7ec4\u88c5\u6210\u540c\u4e00\u4e2a\u5b57\u7b26\u3002 \u8fd9\u5c31\u7528\u5230\u4e86\u4e00\u4e2a\u201c\u6f0f\u6d1e\u201d\uff1aUnicode \u5e76\u6ca1\u6709\u628a\u7801\u70b9\u5206\u914d\u7684\u6ee1\u6ee1\u5f53\u5f53\uff0c\u6216\u8bb8\u662f\u51fa\u4e8e\u5148\u89c1\u4e4b\u660e\uff0c\u5728 0xD800 \u5230 0xDFFF \u4e4b\u95f4\u9884\u7559\u4e86\u4e00\u5927\u6bb5\u7a7a\u53f7\uff1a UTF-16 \u5c31\u662f\u5229\u7528\u4e86\u8fd9\u4e00\u6bb5\u7a7a\u95f4\uff0c\u4ed6\u89c4\u5b9a\uff1a0xD800 \u5230 0xDFFF \u4e4b\u95f4\u7684\u7801\u70b9\u5c06\u6c38\u8fdc\u4e0d\u7528\u6765\u8868\u793a\u5b57\u7b26\uff0c\u800c\u662f\u4f5c\u4e3a \u4ee3\u7406\u5bf9 (surrogate-pair) \u3002\u5176\u4e2d 0xD800 \u5230 0xDBFF \u662f \u9ad8\u4f4d\u4ee3\u7406 (high surrogate) \uff0c0xDC00 \u5230 0xDFFF \u662f \u4f4e\u4f4d\u4ee3\u7406 (low surrogate) \u3002\u9ad8\u4ee3\u7406\u5728\u524d\uff0c\u4f4e\u4ee3\u7406\u5728\u540e\u3002 \u4e00\u4e2a\u8d85\u8fc7 0xFFFF \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f1a\u88ab\u62c6\u6210\u4e24\u6bb5\uff0c\u4e00\u6bb5\u653e\u5728\u9ad8\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u6bb5\u653e\u5728\u4f4e\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u524d\u4e00\u540e\u653e\u5165 uint16_t \u5e8f\u5217\u4e2d\u3002 \u642d\u8f7d\u8d85\u5bbd\u8d85\u9650\u8d27\u7269\u7684\u8f66\u8f86\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e24\u6bb5\u518d\u8fdb\u5165\u96a7\u9053\u3002 \u5177\u4f53\u62c6\u5206\u65b9\u6cd5\u5982\u4e0b\uff1a \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7801\u70b9\uff0c\u9996\u5148\u5c06\u5176\u503c\u51cf\u53bb 0x10000\uff0c\u53d8\u6210\u4e00\u4e2a\u8303\u56f4 0x0 \u5230 0xFFFFF \u8303\u56f4\u5185\u7684\u6570\u5b57\uff0c\u8fd9\u80fd\u4fdd\u8bc1\u4ed6\u4eec\u53ea\u9700 20 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u53ef\u8868\u793a\u3002 \u4f8b\u5982\u201c\ud883\udede\u201d\u5bf9\u5e94\u7684\u7801\u70b9 0x30EDE\uff0c\u51cf\u53bb\u540e\u5c31\u53d8\u6210 0x20EDE\u3002 \u7136\u540e\uff0c\u5199\u51fa 0x20EDE \u7684\u4e8c\u8fdb\u5236\u8868\u793a\uff1a 00100000111011011110 \u603b\u5171 20 \u4f4d\uff0c\u6211\u4eec\u5c06\u5176\u62c6\u6210\u9ad8\u4f4e\u5404 10 \u4f4d\uff1a 0010000011 1011011110 \u5404\u81ea\u5199\u51fa\u76f8\u5e94\u7684\u5341\u516d\u8fdb\u5236\u6570\uff1a 0x083 0x2DE \u56e0\u4e3a\u6700\u591a\u53ea\u6709 10 \u4f4d\uff0c\u8fd9\u4e24\u4e2a\u6570\u90fd\u4f1a\u5728 0 \u5230 0x3FF \u7684\u8303\u56f4\u5185\u3002 \u800c 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u9884\u7559\u7684\u7a7a\u95f4\uff0c\u521a\u597d\u53ef\u4ee5\u5206\u522b\u5bb9\u7eb3 0x400 \u4e2a\u6570\uff01 \u6240\u4ee5\uff0c\u6211\u4eec\u5c06\u62c6\u5206\u51fa\u6765\u7684\u4e24\u4e2a 10 \u4f4d\u6570\uff0c\u5206\u522b\u52a0\u4e0a 0xD800 \u548c 0xDC00\uff1a 0xD800+0x083=0xD883 0xDC00+0x2DE=0xDFDE \u8fd9\u4e24\u4e2a\u6570\uff0c\u5fc5\u5b9a\u662f 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u6570\u3002\u800c\u8fd9\u4e24\u4e2a\u8303\u56f4\u90fd\u662f Unicode \u59d4\u5458\u4f1a\u9884\u7559\u7684\u4ee3\u7406\u5bf9\u533a\u95f4\uff0c\u7edd\u5bf9\u6ca1\u6709\u666e\u901a\u5b57\u7b26\u3002\u6240\u4ee5\uff0c\u751f\u6210\u7684\u4e24\u4e2a\u4ee3\u7406\u5bf9\u4e0d\u4f1a\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u53ef\u4ee5\u653e\u5fc3\u653e\u8fdb uint16_t \u6570\u7ec4\uff0c\u89e3\u7801\u5668\u5982\u679c\u68c0\u6d4b\u5230\u4ee3\u7406\u5bf9\uff0c\u5c31\u8bf4\u660e\u662f\u4e24\u8282\u8f66\u53a2\uff0c\u53ef\u4ee5\u653e\u5fc3\u8fde\u7eed\u8bfb\u53d6\u4e24\u4e2a uint16_t \u3002 \u6240\u4ee5\uff0c 0xD883 0xDFDE \u5c31\u662f\u201c\ud883\udede\u201d\u7528 UTF-16 \u7f16\u7801\u540e\u7684\u7ed3\u679c\u3002 \u4ee3\u7406\u5b57\u7b26\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\uff0c\u5f53\u89e3\u7801\u5668\u68c0\u6d4b\u5230\u4e00\u4e2a 0xD800 \u5230 0xDBFF \u8303\u56f4\u5185\u7684\u9ad8\u4ee3\u7406\u65f6\uff0c\u5c31\u9884\u793a\u7740\u8fd8\u9700\u8981\u518d\u8bfb\u53d6\u4e00\u4e2a\u4f4e\u4ee3\u7406\uff0c\u624d\u80fd\u62fc\u63a5\u6210\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u3002 \u5982\u679c\u63a5\u4e0b\u6765\u8bfb\u5230\u7684\u4e0d\u662f 0xDC00 \u5230 0xDFFF \u8303\u56f4\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u800c\u662f\u666e\u901a\u5b57\u7b26\u7684\u8bdd\uff0c\u90a3\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u53ef\u80fd\u662f\u4e2d\u95f4\u88ab\u4eba\u4e22\u5305\u4e86\uff0c\u9700\u8981\u62a5\u9519\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u9876\u66ff\u3002 \u53e6\u5916\uff0c\u5982\u679c\u8bfb\u5230\u4e86\u4e00\u4e2a\u5355\u72ec\u5b58\u5728\u7684 0xD800 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u90a3\u4e5f\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u56e0\u4e3a\u4ee3\u7406\u5b57\u7b26\u53ea\u6709\u6210\u5bf9\u51fa\u73b0\u624d\u6709\u610f\u4e49\uff0c\u4f4e\u4ee3\u7406\u5b57\u7b26\u4e0d\u53ef\u80fd\u5355\u72ec\u5728\u5f00\u5934\u51fa\u73b0\u3002 \u53ef\u89c1\uff0cUTF-16 \u548c UTF-8 \u4e00\u6837\uff0c\u90fd\u662f\u201c\u5c0f\u706b\u8f66\u201d\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0cUTF-16 \u540c\u6837\u4e5f\u6709\u7740\u7c7b\u4f3c\u4e8e UTF-8 \u7684\u6297\u5e72\u6270\u673a\u5236\u3002","title":"UTF-16"},{"location":"unicode/#_7","text":"\u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u591a\u5b57\u8282\u7684\u6574\u6570\u7c7b\u578b\uff08\u5982 uint16_t \u548c uint32_t \uff09\u9700\u8981\u88ab\u62c6\u6210\u591a\u4e2a\u5b57\u8282\u6765\u5b58\u50a8\u3002\u62c6\u5f00\u540e\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u6309\u4ec0\u4e48\u987a\u5e8f\u5b58\u5165\u5185\u5b58\uff1f\u4e0d\u540c\u7684\u786c\u4ef6\u67b6\u6784\u4ea7\u751f\u4e86\u4e89\u6267\uff1a \u5927\u7aef\u6d3e (bit endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u4e5f\u5c31\u662f\u5927\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5c0f\u7aef\u6d3e (little endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u4e5f\u5c31\u662f\u5c0f\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u8ba1\u7b97\u673a\u7535\u8def\u7684\u8ba1\u7b97\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x78 0x56 0x34 0x12 \u4f8b\u5982\uff0cIntel \u7684 x86 \u67b6\u6784\u548c ARM \u516c\u53f8\u7684 ARM \u67b6\u6784\u90fd\u662f\u5c0f\u7aef\u6d3e\uff0c\u800c Motorola \u516c\u53f8\u7684 68k \u67b6\u6784\u548c Sun \u516c\u53f8\u7684 SPARC \u67b6\u6784\u90fd\u662f\u5927\u7aef\u6d3e\u3002 \u8fd9\u5176\u5b9e\u662f\u5f88\u65e0\u804a\u7684\u4e89\u6267\uff0c\u4e3a\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u6539\u53d8\u8ba1\u7b97\u673a\u7684\u8bbe\u8ba1\u6beb\u65e0\u9053\u7406\uff0c\u6bd5\u7adf\u4e16\u754c\u4e0a\u4e5f\u6709\u4ece\u53f3\u5f80\u5de6\u4e66\u5199\u7684\u6587\u5b57\u548c\u4ece\u4e0a\u5f80\u4e0b\u4e66\u5199\u7684\u6587\u5b57\uff0c\u751a\u81f3\u6709\u5de6\u53f3\u6765\u56de\u4e66\u5199\u7684\u6587\u5b57\u2026\u2026\u5982\u679c\u8981\u4f3a\u5019\u4eba\u7c7b\uff0c\u4f60\u600e\u4e48\u4e0d\u6539\u6210\u5341\u8fdb\u5236\u5462\uff1f\u603b\u4e4b\uff0c\u6211\u8ba4\u4e3a\u5c0f\u7aef\u624d\u662f\u6700\u9002\u5408\u8ba1\u7b97\u673a\u7684\uff0c\u5e02\u9762\u4e0a\u5927\u591a\u6570\u4e3b\u6d41\u786c\u4ef6\u90fd\u662f\u5c0f\u7aef\u67b6\u6784\u3002 \u5728\u7f51\u7edc\u901a\u4fe1\u65f6\uff0c\u53d1\u6d88\u606f\u548c\u6536\u6d88\u606f\u7684\u53ef\u80fd\u662f\u4e0d\u540c\u7684\u67b6\u6784\uff0c\u5982\u679c\u53d1\u6d88\u606f\u7684\u662f\u5c0f\u7aef\u67b6\u6784\uff0c\u6536\u6d88\u606f\u7684\u662f\u5927\u7aef\u67b6\u6784\uff0c\u90a3\u4e48\u53d1\u51fa\u53bb\u7684\u662f 0x12345678\uff0c\u6536\u5230\u7684\u5c31\u4f1a\u53d8\u6210 0x78563421 \u4e86\u3002 \u56e0\u6b64\u4e92\u8054\u7f51\u4e00\u822c\u89c4\u5b9a\uff0c\u6240\u6709\u591a\u5b57\u8282\u7684\u6570\u636e\u5728\u7f51\u7edc\u5305\u4e2d\u7edf\u4e00\u91c7\u7528\u5927\u7aef\u3002\u5bf9\u4e8e\u5927\u7aef\u67b6\u6784\uff0c\u4ed6\u4eec\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u5bf9\u4e8e\u5c0f\u7aef\u67b6\u6784\uff0c\u5728\u53d1\u5305\u524d\u9700\u8981\u628a\u81ea\u5df1\u7684\u5c0f\u7aef\u6570\u636e\u505a\u5b57\u8282\u5e8f\u53cd\u8f6c\uff0c\u53d8\u6210\u5927\u7aef\u7684\u4ee5\u540e\uff0c\u518d\u53d1\u9001\u3002\u4e4b\u540e\u7684\u7f51\u7edc\u4e13\u9898\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u89e3\u8fd9\u4e00\u5757\u3002 \u57fa\u4e8e\u5b57\u8282\u7801\u7684\u865a\u62df\u673a\u8bed\u8a00\u901a\u5e38\u4f1a\u89c4\u5b9a\u4e00\u4e2a\u5b57\u8282\u5e8f\uff1a\u50cf Java \u8fd9\u79cd\u9762\u5411\u4e92\u8054\u7f51\u8bed\u8a00\uff0c\u7d22\u6027\u4e5f\u89c4\u5b9a\u4e86\u7edf\u4e00\u91c7\u7528\u5927\u7aef\uff0c\u65e0\u8bba JVM \u8fd0\u884c\u5728\u5927\u7aef\u673a\u5668\u8fd8\u662f\u5c0f\u7aef\u673a\u5668\u4e0a\u3002\u8fd9\u4f7f\u5f97\u4ed6\u4e0e\u4e92\u8054\u7f51\u901a\u4fe1\u6bd4\u8f83\u65b9\u4fbf\uff0c\u800c\u5728 x86 \u548c ARM \u67b6\u6784\u4e0a\uff0c\u4e0e\u672c\u5730\u53ea\u63a5\u53d7\u5c0f\u7aef\u6570\u636e\u7684 API\uff0c\u4f8b\u5982 OpenGL\uff0c\u6c9f\u901a\u8f83\u4e3a\u56f0\u96be\uff0c\u9700\u8981\u505a\u989d\u5916\u7684\u5b57\u8282\u5e8f\u8f6c\u6362\u3002\u800c C# \u4e3b\u6253\u6e38\u620f\u4e1a\u52a1\uff08\u4f8b\u5982 Unity\uff09\uff0c\u9700\u8981\u8003\u8651\u6027\u80fd\uff0c\u6240\u4ee5\u89c4\u5b9a\u5168\u90e8\u91c7\u7528\u5c0f\u7aef\u3002\u4f5c\u4e3a\u5e95\u5c42\u7f16\u7a0b\u8bed\u8a00\u7684 C++ \u5219\u662f\u5165\u4e61\u968f\u4fd7\uff0c\u4f60\u7684\u786c\u4ef6\u662f\u4ec0\u4e48\u7aef\uff0c\u4ed6\u5c31\u662f\u4ec0\u4e48\u7aef\uff0c\u4e0d\u4e3b\u52a8\u505a\u4efb\u4f55\u989d\u5916\u7684\u8f6c\u6362\u3002 UTF-16 \u548c UTF-32 \u7684\u7801\u4f4d\u90fd\u662f\u591a\u5b57\u8282\u7684\uff0c\u4e5f\u4f1a\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u3002\u4f8b\u5982\uff0cUTF-16 \u4e2d\u7684 uint16_t \u5e8f\u5217\uff1a 0x1234 0x5678 \u5728\u5927\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5728\u5c0f\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x34 0x12 0x78 0x56 \u8fd9\u6837\u4e00\u6765\uff0cUTF-16 \u548c UTF-32 \u7684\u5b57\u8282\u6d41\uff0c\u5728\u4e0d\u540c\u7684\u673a\u5668\u4e0a\uff0c\u53ef\u80fd\u4f1a\u6709\u4e0d\u540c\u7684\u987a\u5e8f\u3002\u8fd9\u7ed9\u8de8\u5e73\u53f0\u7684\u6587\u672c\u5904\u7406\u5e26\u6765\u4e86\u9ebb\u70e6\u3002 \u6240\u4ee5\u5f53\u4f60\u9700\u8981\u628a UTF-16 \u5b58\u5165\u786c\u76d8\u548c\u5728\u7f51\u7edc\u53d1\u9001\u65f6\uff0c\u8fd8\u9700\u8981\u989d\u5916\u6307\u660e\u4f60\u7528\u7684\u662f\u5927\u7aef\u7684 UTF-16 \u8fd8\u662f\u5c0f\u7aef\u7684 UTF-16\u3002 \u56e0\u6b64 UTF-16 \u548c UTF-32 \u8fdb\u4e00\u6b65\u5206\u88c2\u4e3a\uff1a UTF-16LE\uff1a\u5c0f\u7aef\u7684 UTF-16 UTF-16BE\uff1a\u5927\u7aef\u7684 UTF-16 UTF-32LE\uff1a\u5c0f\u7aef\u7684 UTF-32 UTF-32BE\uff1a\u5927\u7aef\u7684 UTF-32 \u5982\u679c\u53ea\u5728\u5185\u5b58\u7684 wchar_t \u4e2d\u4f7f\u7528\u5c31\u4e0d\u7528\u533a\u5206\uff0c\u9ed8\u8ba4\u8ddf\u968f\u5f53\u524d\u673a\u5668\u7684\u5927\u5c0f\u7aef\u3002\u6240\u4ee5 UTF-16 \u548c UTF-32 \u901a\u5e38\u53ea\u4f1a\u51fa\u73b0\u5728\u5185\u5b58\u4e2d\u7528\u4e8e\u5feb\u901f\u5904\u7406\u548c\u8ba1\u7b97\uff0c\u5f88\u5c11\u7528\u5728\u5b58\u50a8\u548c\u901a\u4fe1\u4e2d\u3002 UTF-8 \u662f\u57fa\u4e8e\u5355\u5b57\u8282\u7684\u7801\u4f4d\uff0c\u706b\u8f66\u5934\u7684\u987a\u5e8f\u4e5f\u6709\u4e25\u683c\u89c4\u5b9a\uff0c\u706b\u8f66\u5934\u603b\u662f\u5728\u6700\u524d\uff0c\u6839\u672c\u4e0d\u53d7\u5b57\u8282\u5e8f\u5927\u5c0f\u7aef\u5f71\u54cd\uff0c\u4e5f\u5c31\u6ca1\u6709\u5f71\u54cd\u3002 \u7531\u4e8e\u538b\u7f29\u7387\u4f4e\uff0c\u53c8\u5b58\u5728\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u800c\u4e92\u8054\u7f51\u6570\u636e\u9700\u8981\u4fdd\u8bc1\u76f8\u540c\u7684\u5927\u5c0f\u7aef\uff0c\u5728\u6536\u53d1\u5305\u65f6\u9700\u8981\u989d\u5916\u8f6c\u6362\uff0c\u56e0\u800c\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u7f51\u7edc\u3002\u800c UTF-8 \u7684\u5b58\u50a8\u5355\u4f4d\u662f\u5b57\u8282\uff0c\u5929\u751f\u6ca1\u6709\u5927\u5c0f\u7aef\u56f0\u6270\u3002\u66f4\u5999\u7684\u662f\uff0c\u4ed6\u4e14\u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u800c\u4e92\u8054\u7f51\u53c8\u662f\u53e4\u8463\u4e2d\u95f4\u4ef6\u6700\u591a\u7684\u5730\u65b9\u2026\u2026 \u603b\u4e4b\uff0c\u5b8c\u5168\u57fa\u4e8e\u5b57\u8282\u7684 UTF-8 \u662f\u6700\u9002\u5408\u7f51\u7edc\u901a\u4fe1\u548c\u786c\u76d8\u5b58\u50a8\u7684\u6587\u672c\u7f16\u7801\u683c\u5f0f\uff0c\u800c UTF-32 \u662f\u6700\u9002\u5408\u5728\u5185\u5b58\u4e2d\u5904\u7406\u7684\u683c\u5f0f\u3002","title":"\u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89"},{"location":"unicode/#bom","text":"0xFEFF \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u4e0d\u53ef\u89c1\u5b57\u7b26\u201c\ufeff\u201d\uff0c\u8fd9\u662f\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u6ca1\u6709\u4efb\u4f55\u6548\u679c\u3002 \u4f60\u53ef\u4ee5\u628a\u8fd9\u4e2a\u5b57\u7b26\u52a0\u5728\u6587\u672c\u6587\u4ef6\u7684\u5934\u90e8\uff0c\u544a\u8bc9\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\uff0c\u8fd9\u4e2a\u6587\u4ef6\u662f\u7528\u4ec0\u4e48\u7f16\u7801\u7684\u3002 \u5982\u679c\u662f UTF-16 \u548c UTF-32\uff0c\u56e0\u4e3a 0xFEFF \u4e0d\u5bf9\u79f0\uff0c\u4ed6\u8fd8\u80fd\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\u3002\u56e0\u6b64 0xFEFF \u88ab\u79f0\u4e3a\u5b57\u8282\u5e8f\u6807\u5fd7\uff08Byte-order-mark\uff0cBOM\uff09\u3002 \u5982\u679c\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u90a3\u4e48\u4ed6\u7167\u5e38\u8bfb\u51fa 0xFEFF\uff0c\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u5728\u6587\u672c\u4e2d\u4e0d\u663e\u793a\uff0c\u4e0d\u5f71\u54cd\u89c6\u89c9\u7ed3\u679c\u3002 \u4e00\u4e9b\u8001\u7684\u7f16\u8bd1\u5668\uff08\u8fdc\u53e4 MinGW\uff0c\u73b0\u5728\u5df2\u7ecf\u6ca1\u6709\u4e86\uff09\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u4f1a\u628a\u5e26\u6709 BOM \u7684 UTF-8 \u7684 .cpp \u6e90\u7801\u6587\u4ef6\uff0c\u5f53\u4f5c\u5934\u90e8\u5e26\u6709\u9519\u8bef\u5b57\u7b26\u7684\u4e71\u7801\u6587\u4ef6\uff0c\u4ece\u800c\u62a5\u9519\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u7684\u8bb0\u4e8b\u672c\u4fdd\u5b58\u4e3a UTF-8 \u65f6\uff0c\u603b\u662f\u4f1a\u52a0\u4e0a BOM\u3002\u5982\u679c\u8bb0\u4e8b\u672c\u53d1\u73b0\u4e00\u4e2a\u6587\u4ef6\u6ca1\u6709 BOM\uff0c\u4f1a\u5f53\u4f5c ANSI\uff08GBK\uff09\u6765\u8bfb\u53d6\u3002 0xFEFF \u5728\u4e0d\u540c\u7684\u7f16\u7801\u4e0b\u4f1a\u4ea7\u751f\u4e0d\u540c\u7684\u7ed3\u679c\uff1a UTF-8\uff1a 0xEF 0xBB 0xBF \uff0c\u4ed6\u4f1a\u5360\u7528 3 \u5b57\u8282\uff0c\u800c\u4e14\u4e0d\u4f1a\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\uff0c\u56e0\u4e3a UTF-8 \u662f\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u7684\u3002 UTF-16\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE \u3002 UTF-32\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0x00 0x00 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE 0x00 0x00 \u3002 \u56e0\u6b64\uff0c\u5728\u6587\u672c\u5934\u90e8\u52a0\u4e0a BOM \u6709\u52a9\u4e8e\u8f6f\u4ef6\u63a8\u6d4b\u8be5\u6587\u4ef6\u662f\u4ec0\u4e48\u7f16\u7801\u7684\uff08\u5982\u679c\u90a3\u8f6f\u4ef6\u652f\u6301\u89e3\u6790 BOM \u7684\u8bdd\uff09\u3002 \u4f8b\u5982 Windows \u73af\u5883\u4e2d\uff0c\u6240\u6709\u7684\u6587\u672c\u6587\u4ef6\u90fd\u88ab\u9ed8\u8ba4\u5047\u5b9a\u4e3a ANSI\uff08GBK\uff09\u7f16\u7801\uff0c\u5982\u679c\u4f60\u8981\u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u4e3a UTF-8 \u7f16\u7801\uff0c\u5c31\u9700\u8981\u52a0\u4e0a BOM \u6807\u5fd7\u3002\u5f53 MSVC \u8bfb\u53d6\u65f6\uff0c\u770b\u5230\u5f00\u5934\u662f 0xEF 0xBB 0xBF \uff0c\u5c31\u660e\u767d\u8fd9\u662f\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u6587\u4ef6\u3002\u8fd9\u6837\uff0cMSVC \u5c31\u80fd\u6b63\u786e\u5730\u5904\u7406\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4e86\u3002\u5982\u679c MSVC \u6ca1\u770b\u5230 BOM\uff0c\u4f1a\u9ed8\u8ba4\u4ee5\u4e3a\u662f ANSI\uff08GBK\uff09\u7f16\u7801\u7684\uff0c\u4ece\u800c\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4f1a\u4e71\u7801\u3002\u5f00\u542f /utf-8 \u9009\u9879\u4e5f\u80fd\u8ba9 MSVC \u628a\u6ca1\u6709 BOM \u7684\u6e90\u7801\u6587\u4ef6\u5f53\u4f5c UTF-8 \u6765\u89e3\u6790\uff0c\u9002\u5408\u8de8\u5e73\u53f0\u5b9d\u5b9d\u4f53\u8d28\u3002 \u5176\u5b9e Windows \u7528\u6237\u53ef\u4ee5\u5728\u63a7\u5236\u9762\u677f\u7684\u201c\u65f6\u949f\u548c\u533a\u57df\u201d\u91cc\uff0c\u627e\u5230\u201c\u533a\u57df\u201d\u9009\u9879\u3002\u5728\u201c\u533a\u57df\u201d\u9009\u9879\u5361\u91cc\uff0c\u70b9\u51fb\u201c\u66f4\u6539\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u7136\u540e\u5f39\u51fa\u7684\u5bf9\u8bdd\u6846\u91cc\uff0c\u52fe\u9009\u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u63d0\u4f9b\u5168\u7403\u8bed\u8a00\u652f\u6301\u201d\uff0c\u91cd\u542f\u540e\uff0c\u5c31\u53ef\u4ee5\u5728\u7a0b\u5e8f\u4e2d\u9ed8\u8ba4\u4f7f\u7528 UTF-8\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684 GBK \u4e86\u3002\u8fd9\u4f1a\u628a ANSI \u53d8\u6210 UTF-8\uff0c\u8ba9\u8bb0\u4e8b\u672c\u7b49\u8f6f\u4ef6\u628a\u65e0 BOM \u7684\u6587\u4ef6\u90fd\u5f53\u4f5c UTF-8\uff0c\u8ba9\u5404\u79cd\u8f6f\u4ef6\u90fd\u8ba4\u4e3a\u5b57\u7b26\u4e32\u662f UTF-8 \u7b49\u7b49\u3002\u8fd9\u53ef\u4ee5\u89e3\u51b3\u90e8\u5206\u7f8e\u56fd\u8f6f\u4ef6\u65e0\u6cd5\u5904\u7406\u4e2d\u6587\u3001\u4e71\u7801\u7b49\u95ee\u9898\uff0c\u56e0\u4e3a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u5e38\u5e38\u65e0\u610f\u8bc6\u5730\u7528 UTF-8 \u5b57\u7b26\u4e32\u672a\u7ecf\u5904\u7406\u76f4\u63a5\u8c03\u7528 A \u51fd\u6570\u3002\u4e0d\u8fc7\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4f60\u8fd0\u884c\u5176\u4ed6\u5047\u5b9a\u4e86 GBK \u7684\u4e2d\u56fd\u7279\u4f9b\u7a0b\u5e8f\u4e71\u7801\uff0c\u4e5f\u4f1a\u5bfc\u81f4\u4f60\u7684\u6bd5\u4e1a\u7b54\u8fa9\u5bfc\u5e08\u53d1\u6765\u7684 ZIP \u53d8\u6210\u4e71\u7801\u3002\u800c\u4e14\u6211\u4eec\u4f5c\u4e3a\u5ba2\u6237\u7aef\u7684\u5f00\u53d1\u8005\uff0c\u6211\u4eec\u603b\u4e0d\u80fd\u5f3a\u6c42\u6240\u6709\u5ba2\u6237\u7528\u6211\u4eec\u7684\u8f6f\u4ef6\u524d\uff0c\u6539\u53d8\u4ed6\u4eec\u7684\u63a7\u5236\u9762\u677f\u6765\u9002\u5e94\u6211\u4eec\u7684\u7a0b\u5e8f\u5427\uff1f\u6240\u4ee5\u8fd8\u662f\u9700\u8981\u7ed5\u5f00 GBK\uff0c\u76f4\u63a5\u8c03\u7528 UTF-16 \u7684 W \u7c7b API\u3002","title":"BOM \u6807\u8bb0"},{"location":"unicode/#gb2312gbkgb18030","text":"","title":"GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb"},{"location":"unicode/#gb2312","text":"GB2312 \u53d1\u5e03\u4e8e 1980 \u5e74\uff0c\u662f\u4e00\u4e2a\u53e4\u8001\u7684\u6c49\u5b57\u7f16\u7801\u6807\u51c6\uff0c\u517c\u5bb9 ASCII\u3002 \u201cGB\u201d \u8868\u793a Guo Biao\uff08\u56fd\u6807\uff09\u7684\u610f\u601d\u3002 GB2312 \u89c4\u5b9a\u4e86 6763 \u4e2a\u6c49\u5b57\u548c 682 \u4e2a\u7279\u6b8a\u7b26\u53f7\uff0c\u5171 7445 \u4e2a\u5b57\u7b26\u3002 GB2312 \u8ba9\u82f1\u6587\u548c\u6570\u5b57\u91c7\u7528\u548c ASCII \u76f8\u540c\u7684\u5355\u5b57\u8282\u7f16\u7801\uff0c\u800c\u5bf9\u4e8e\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u91c7\u7528\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u5176\u4e2d\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u7684\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u4e24\u4e2a\u5b57\u8282\u90fd\u5728 0xA1 \u5230 0xFE \u7684\u8303\u56f4\u5185\uff0c\u907f\u514d\u4e86\u4e0e\u5355\u5b57\u8282\u7684 ASCII \u7f16\u7801\u7a7a\u95f4\u51b2\u7a81\u3002 H i \u5f6d \u5b9d 0x48 0x69 0xC5 0xED 0xB1 0xA6 2 \u4e2a\u5b57\u8282\u5206\u522b\u88ab\u79f0\u4e3a\u201c\u533a\u7801\u201d\u548c\u201c\u4f4d\u7801\u201d\uff0c\u8303\u56f4\u90fd\u662f\u5728 0xA1 \u5230 0xFE \u533a\u95f4\u5185\u3002 \u201c\u7279\u6b8a\u7b26\u53f7\u201d\uff0c\u5171 682 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xA1A1 \u5230 0xA9FE\u3002 \u201c\u4e00\u7ea7\u6c49\u5b57\u201d\uff0c\u90fd\u662f\u6bd4\u8f83\u5e38\u7528\u7684\u6c49\u5b57\uff0c\u6309\u62fc\u97f3\u987a\u5e8f\u6392\u5e8f\uff0c\u5171 3755 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xB0A1 \u5230 0xF7FE\u3002 \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u662f\u4e00\u4e9b\u751f\u50fb\u5b57\uff0c\u6309\u90e8\u9996/\u7b14\u753b\u6392\u5e8f\uff0c\u5171 3008 \u4e2a\uff0c\u8fd9\u4e9b\u6c49\u5b57\u7684\u5b57\u7b26\u4ece 0x8140 \u5230 0xA0FE\u3002 GBK \u4e2d\u6c49\u5b57\u7684\u7f16\u53f7\u548c Unicode \u5e76\u4e0d\u662f\u76f8\u540c\u7684\uff0c\u8fd9\u4e5f\u662f GB2312 \u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6\u7528 UTF-8 \u6216 UTF-16 \u6253\u5f00\u4f1a\u4ea7\u751f\u4e71\u7801\u7684\u6839\u672c\u539f\u56e0\u3002 \u4f8b\u5982\u6c49\u5b57 \u201c\u5f6d\u201d \u5c31\u5c5e\u4e8e \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u5728 GB2312 \u4e2d\u7f16\u53f7\u4e3a 0xC5ED\uff0cUnicode \u4e2d\u7f16\u53f7\u4e3a 0x5F6D\u3002 \u5168\u89d2\u7a7a\u683c \u201c\u3000\u201d\uff0c\u5728 GB2312 \u4e2d\u7684\u7f16\u53f7\u4e3a 0xA1A1\uff0cUnicode \u4e2d\u7684\u7f16\u53f7\u4e3a 0x3000\u3002","title":"GB2312"},{"location":"unicode/#gb2312_1","text":"GBK \u548c UTF-8 \u7684\u5171\u540c\u70b9\u5728\u4e8e\uff0c\u4ed6\u4eec\u90fd\u907f\u5f00\u4e86 0 ~ 127 \u7684 ASCII \u7a7a\u95f4\uff0c\u6240\u4ee5\u5b8c\u5168\u517c\u5bb9 ASCII\u3002 \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u5982\u679c\u5728\u4e00\u4e2a GBK \u7f16\u7801\u7684\u4e2d\u6587\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u4e2d\u6587\uff0c\u53ef\u80fd\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\uff0c\u800c UTF-8 \u4e0d\u4f1a\u3002\u8fd9\u662f\u56e0\u4e3a GBK \u6ca1\u6709\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u4ed6\u524d\u540e\u4e24\u4e2a\u8f66\u53a2\u5e76\u6ca1\u6709\u4e0d\u540c\u3002 \u5f53 GBK \u88ab\u5207\u7247\u65f6\uff0c\u5c31\u5bb9\u6613\u51fa\u73b0\u8fde\u9501\u53cd\u5e94\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.substr(1); // \"\u64a9\u683d\u91c7\ufffd\" // \u590d\u73b0\u65b9\u5f0f: MSVC \u4e2d\u56fd\u533a Windows\uff0c/std:c++17\uff0c\u4e0d\u5f00\u542f /utf-8 \u53c2\u6570\uff08\u8fd9\u65f6\u5b57\u7b26\u4e32\u5e38\u91cf\u90fd\u662f GBK \u7f16\u7801\u7684\uff09 \u6838\u53cd\u5e94\u5806\uff0c\u542f\u52a8\uff01 \u7279\u522b\u662f\u5f53\u4f60\u8bd5\u56fe find \u4e00\u4e2a\u4e2d\u6587\u5b50\u5b57\u7b26\u4e32\u65f6\uff0cGBK \u7f16\u7801\u7684\u591a\u5b57\u8282\u5b57\u7b26\u4e32\u53ef\u80fd\u4ea7\u751f\u627e\u5230\u4e86\u7684\u5047\u8c61\u3002\u5b9e\u9645\u4e0a\u627e\u5230\u7684\u4f4d\u7f6e\u6839\u672c\u662f\u5207\u65ad\u4e86\u5355\u4e2a\u5b8c\u6574\u7684\u4e2d\u6587\u5b57\u7b26\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.find(\"\u91c7\"); // 5\uff0c\u628a\u201c\u5706\u201d\u7684\u540e\u534a\u6bb5 0xAD \u548c\u201c\u795e\u201d\u7684\u524d\u534a\u6bb5 0xC9 \u5f53\u6210\u4e00\u4e2a\u5b57\u201c\u91c7\u201d (0xAD 0xC9) \u4e86 \u800c UTF-8 \u5219\u80fd\u6709\u6548\u9650\u5236\u9519\u8bef\u7684\u4f20\u64ad\u3002 std::string u8s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xE6 0xB2 0x89 0xE8 0xBF 0xB7 0xE5 0x9C 0x86 0xE7 0xA5 0x9E std::cout << u8s.substr(1); // \"\ufffd\u8ff7\u5706\u795e\" std::cout << u8s.find(\"\u91c7\"); // \u627e\u4e0d\u5230\uff0c\u8fd4\u56de -1 \u56e0\u4e3a UTF-8 \u7684\u5934\u90e8\u5c0f\u706b\u8f66\u548c\u5c3e\u90e8\u8f66\u53a2\u91c7\u7528\u4e86\u72ec\u7acb\u7684\u7f16\u7801\uff0cfind \u4e0d\u53ef\u80fd\u901a\u8fc7\u4efb\u4f55\u5408\u6cd5\u7684 UTF-8 \u5b50\u5b57\u7b26\u4e32\u5b9a\u4f4d\u5230\u9519\u8bef\u7684\u4e2d\u95f4\u4f4d\u7f6e\u3002 GB2312 \u548c GBK \u7684\u7279\u6b8a\u6027\uff1a\u4ed6\u65e2\u662f\u5b57\u7b26\u96c6\uff0c\u53c8\u662f\u5b57\u7b26\u7f16\u7801\u3002\u9664 Unicode \u5916\u5927\u591a\u6570\u5b57\u7b26\u96c6\u90fd\u662f\u8fd9\u6837\uff0c\u81ea\u5df1\u5c31\u662f\u81ea\u5df1\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u6ca1\u6709\u5176\u4ed6\u7f16\u7801\u65b9\u5f0f\u3002\u53ea\u6709 Unicode \u628a\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u7684\u6982\u5ff5\u5206\u7684\u5f88\u6e05\u695a\uff0c\u56e0\u4e3a Unicode \u5b57\u7b26\u96c6\u6709 UTF-8\u3001UTF-\u3002","title":"GB2312 \u7684\u7f3a\u9677"},{"location":"unicode/#gbk","text":"GBK \u540c\u6837\u662f\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u662f\u5bf9 GB2312 \u7684\u6269\u5c55\u3002 GBK \u5728\u4fdd\u6301 GB2312 \u90e8\u5206\u4e0d\u53d8\u7684\u57fa\u7840\u4e0a\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u6536\u5f55\u7684\u6709\uff1a GB2312 \u4e2d\u7684\u5168\u90e8\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7 BIG-5\uff08\u7e41\u4f53\u4e2d\u6587\u7684\u7f16\u7801\uff09\u4e2d\u7684\u5168\u90e8\u6c49\u5b57 GB13000\uff08\u5373 Unicode\uff09\u4e2d\u7684\u5176\u4ed6\u4e2d\u65e5\u97e9\u6c49\u5b57 \u5176\u4ed6\u5c1a\u672a\u6536\u5f55\u7684\u7279\u6b8a\u6c49\u5b57\u3001\u90e8\u9996\u3001\u7b26\u53f7\u7b49 \u201cK\u201d \u8868\u793a Kuo\uff08\u6269\u5c55\uff09\u7684\u610f\u601d\u3002 GB2312\uff1a\u9996\u5b57\u8282 0xA1 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282 0xA1 \u5230 0xFE\u3002 GBK\uff1a\u9996\u5b57\u8282 0x81 \u5230 0xFE \uff0c\u5c3e\u5b57\u8282 0x40 \u5230 0xFE \u3002 \u6ce8\u610f\u5230 GBK \u7684\u5c3e\u5b57\u8282\u8fdb\u5165\u4e86 0x40\uff0cASCII \u7684\u8303\u56f4\u3002 \u8fd9\u4f7f\u5f97 GBK \u6bd4 GB2312 \u66f4\u5371\u9669\uff0c\u4f8b\u5982 \u201c\u4fb0\u201d \u8fd9\u4e2a\u5b57\uff0c\u4f1a\u88ab\u7f16\u7801\u6210 0x82 0x43\u3002 \u800c 0x43 \u521a\u597d\u662f ASCII \u5b57\u7b26 \u201cC\u201d \u7684\u7f16\u7801\u3002\u5982\u679c\u53d1\u751f\u5b57\u7b26\u4e32\u5207\u7247\uff0c\u53ef\u80fd\u5bfc\u81f4 \u201c\u4fb0\u201d \u53d8\u6210 \u201c\ufffdC\u201d\u3002\u5e76\u4e14\u5982\u679c\u521a\u597d\u7a0b\u5e8f\u5728 .find('C') \uff0c\u90a3\u4e48 \u201c\u4fb0\u201d \u7684\u540e\u534a\u4e2a\u5b57\u8282\u4f1a\u88ab\u5f53\u4f5c \u201cC\u201d \u800c\u627e\u5230\u3002 \u4e0d\u8fc7\uff0cGBK \u8bbe\u8ba1\u65f6\u7279\u610f\u907f\u5f00\u4e86 0x40 \u4ee5\u4e0b\u7684 ASCII \u5b57\u7b26\uff0c\u4f8b\u5982 0x2F \u662f \u201c/\u201d \u7684 ASCII \u7f16\u7801\uff0c\u5e38\u7528\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7684\u8def\u5f84\u5206\u9694\u7b26\u3002 \u7136\u800c\uff0cWindows \u6240\u7528\u7684\u8def\u5f84\u5206\u9694\u7b26\u662f\u53cd\u659c\u6760 \u201c\\\u201d\uff0c\u4ed6\u7684 ASCII \u7f16\u7801\u662f 0x5C\u3002 \u4f8b\u5982 \u201c\u4fd3\u201d\uff0cGBK \u7f16\u7801 0x82 0x5C\uff0c\u8fd9\u4e2a\u5b57\u5c31\u53ef\u80fd\u88ab\u9519\u8bef\u89e3\u8bfb\u6210 \u201c\ufffd\\\u201d\uff0c\u4f7f\u7a0b\u5e8f\u8bef\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u6587\u4ef6\u5939\u7684\u8def\u5f84\uff0c\u4ece\u800c\u5bfc\u81f4\u7a0b\u5e8f\u51fa\u9519\uff0c\u6216\u7559\u4e0b\u88ab\u9ed1\u5ba2\u653b\u51fb\u7684\u9690\u60a3\u3002 \u867d\u7136 Windows \u7cfb\u7edf\u5185\u90e8\u7edf\u4e00\u91c7\u7528 Unicode\uff08UTF-16\uff09\u6765\u5b58\u50a8\u548c\u5904\u7406\u8def\u5f84\uff0c\u4f46\u603b\u67b6\u4e0d\u4f4f\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\uff0c\u4f9d\u7136\u6267\u7740\u4e8e ANSI\uff08GBK\uff09\uff0c\u5982\u679c\u7528\u6237\u65e0\u610f\u6216\u6076\u610f\u8f93\u5165\u201c\u4fd3\u554a.txt\u201d\uff0c\u5c31\u6709\u53ef\u80fd\u4ea7\u751f\u9690\u60a3\u3002 \u800c UTF-8 \u540c\u6837\u517c\u5bb9 ASCII\uff0c\u5f97\u76ca\u4e8e\u5197\u4f59\u7684\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u5c31\u6ca1\u6709\u8fd9\u6837\u7684\u95ee\u9898\u3002 \u201cGBK\u201d \u867d\u7136\u51a0\u4ee5\u201c\u56fd\u6807\u201d\u4e4b\u540d\uff0c\u4f46\u5b9e\u9645\u4e0a\u662f\u5fae\u8f6f\u64c5\u81ea\u63a8\u51fa\u7684\uff01\u6839\u672c\u4e0d\u662f\u4ec0\u4e48\u56fd\u5bb6\u6807\u51c6\uff08\u4f60\u731c\u4ed6\u4e3a\u4ec0\u4e48\u6ca1\u6709\u56fd\u5bb6\u6587\u4ef6\u7f16\u53f7\uff09\u3002\u672c\u6765\u6211\u56fd\u5b98\u65b9\u90fd\u6253\u7b97\u63a8\u51fa GB13000 \u4e86\uff0c\u76f4\u63a5\u5b8c\u5168\u517c\u5bb9 Unicode \u5b57\u7b26\u96c6\u3002\u7136\u800c\u5fae\u8f6f\u81ea\u4f5c\u4e3b\u5f20\u628a\u4ed6 Wendous \u7684 GB2312 \u5347\u7ea7\u5230 GBK\uff08\u6bd4\u5c14\u76d6\u5b50\u4ee5\u4e3a\u81ea\u5df1\u517c\u5bb9\u538b\u5012\u4e00\u5207\uff0c\u62fd\u6b7b\u4e86\uff09\uff0c\u672c\u6765\u597d\u597d\u7684 GB13000 \u6807\u51c6\u53ea\u597d\u4f5c\u7f62\u3002\u4e3a\u4e86\u517c\u5bb9\u5df2\u7ecf\u5347\u7ea7\u6210 GBK \u7684 Wendous \u7cfb\u7edf\uff0c\u56fd\u5bb6\u53ea\u597d\u91cd\u65b0\u5236\u4f5c\u4e86\u4e00\u4efd GB18030 \u6807\u51c6\uff0c\u517c\u5bb9 GBK \u548c GB2312\u3002","title":"GBK"},{"location":"unicode/#gb18030","text":"\u4e8e 2000 \u5e74 3 \u6708\u53d1\u5e03\u7684\u6c49\u5b57\u7f16\u7801\u56fd\u5bb6\u6807\u51c6\uff0c\u5b8c\u5168\u517c\u5bb9 GBK \u548c GB2312\u3002 \u91c7\u7528\u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u53ef\u4ee5\u7f16\u7801\u4e3a 1 \u5b57\u8282\u30012 \u5b57\u8282\u3001\u6216 4 \u5b57\u8282\u3002 \u5176\u4e2d 1 \u5b57\u8282\u7684\u90e8\u5206\u53d6\u503c\u8303\u56f4\u662f 0 \u5230 0x7F\uff0c\u548c ASCII \u76f8\u540c\u3002 2 \u5b57\u8282\u7684\u90e8\u5206\u9996\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282\u8303\u56f4 0x40 \u5230 0xFE\uff0c\u548c GBK \u76f8\u540c\u3002 4 \u5b57\u8282\u7684\u90e8\u5206\u7b2c\u4e00\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u4e8c\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\uff0c\u7b2c\u4e09\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u56db\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\u3002 \u5b57\u7b26\u5904\u7406\u8f6f\u4ef6\u5728\u5904\u7406 GB18030 \u7684\u6587\u672c\u65f6\uff0c\u4ece\u5de6\u5f80\u53f3\u4f9d\u6b21\u626b\u63cf\u6bcf\u4e2a\u5b57\u8282\uff1a \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u53ea\u5360\u7528\u4e86\u4e00\u4e2a\u5b57\u8282 \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 1\uff0c\u90a3\u4e48\u8be5\u5b57\u7b26\u53ef\u80fd\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282\uff0c\u4e5f\u53ef\u80fd\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282\uff0c\u4e0d\u80fd\u5984\u4e0b\u65ad\u8bba\uff0c\u6240\u4ee5\u8fd8\u8981\u7ee7\u7eed\u5f80\u540e\u626b\u63cf\uff1a \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6709\u4e24\u4e2a\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282 \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6ca1\u6709\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282 \u5f53\u5b57\u7b26\u5360\u7528\u4e24\u4e2a\u6216\u8005\u56db\u4e2a\u5b57\u8282\u65f6\uff0cGB18030 \u7f16\u7801\u603b\u8981\u68c0\u6d4b\u4e24\u6b21\uff0c\u5904\u7406\u6548\u7387\u6bd4 GB2312 \u548c GBK \u90fd\u4f4e\u3002\u800c\u4e14\u548c GBK \u4e00\u6837\uff0c\u6709\u7740\u4e0d\u80fd\u81ea\u7ea0\u9519\uff0c\u5bb9\u6613\u4f7f\u7f16\u7801\u9519\u8bef\u8fde\u9501\u53cd\u5e94\u7684\u95ee\u9898\u3002 GB18030 \u7f16\u7801\u7a7a\u95f4\u5de8\u5927\uff0c\u4e0d\u4ec5\u56ca\u62ec\u4e86\u4e2d\u65e5\u97e9\u6c49\u5b57\uff0c\u6240\u6709 Unicode \u4e2d\u7684\u5b57\u7b26\u4e5f\u90fd\u88ab\u7eb3\u5165\u5176\u4e2d\uff01\u4e5f\u5c31\u662f\u8bf4\uff0cUnicode \u5b57\u7b26\u7528 GB18030 \u7f16\u7801\u662f\u65e0\u635f\u7684\uff0c\u548c UTF-8 \u4e00\u6837\uff0c\u800c\u4e14\u8fd8\u5b8c\u5168\u517c\u5bb9\u4e86 GBK\uff08\u4e2d\u56fd\u533a Windows \u7684\u9ed8\u8ba4\u7f16\u7801\uff09\u3002 \u6240\u4ee5\uff0cGB18030 \u5b57\u7b26\u7f16\u7801\u5bf9\u5e94\u7684\u5b57\u7b26\u96c6\u5b9e\u9645\u4e0a\u662f Unicode\u3002 \u5c3d\u7ba1\u5982\u6b64\uff0cWindows \u81f3\u4eca\uff08\u6211\u6d4b\u7684\u662f Win10\uff0c\u4e0d\u77e5\u9053 Win11 \u5b83\u4eec\u6539\u8fdb\u6ca1\u6709\uff09\u91c7\u7528\u7684\u4f9d\u7136\u662f GBK \u7f16\u7801\uff1a A \u7cfb API \u65e0\u6cd5\u6b63\u786e\u8bc6\u522b GB18030 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff0c\u6587\u4ef6\u8def\u5f84\u540d\u3002\u660e\u660e\u4e2d\u56fd\u653f\u5e9c\u90fd\u7ed9\u4f60\u505a\u5b8c\u5168\u517c\u5bb9\u4f60\u7684 GBK \u4e86\uff0c\u8fd8\u6536\u5f55\u6240\u6709 Unicode \u5b57\u7b26\u4e86\uff0c\u5b8c\u5168\u53ef\u4ee5\u65e0\u7f1d\u589e\u91cf\u5347\u7ea7\u7684\u4e1c\u897f\uff0c\u6ce5\u7801\u6c9f\u69fd\u7684\u6bd4\u5c14\u76d6\u5b50\u8fd8\u4e0d\u5feb\u70b9\u9ed8\u8ba4\u5207\u6362\u5230 GB18030\uff0c\u60f3\u4e0d\u901a\uff08\u81f4\u656c\u4f20\u5947\u9634\u4e95\u76d6\u6bd4\u5c14\u76d6\u5b50\uff09","title":"GB18030"},{"location":"unicode/#_8","text":"\u5b57\u7b26\u7f16\u7801\u517c\u5bb9\u6027\uff1aUTF-8 != GB18030 > GBK > GB2312 > ASCII \u5b57\u7b26\u96c6\u5927\u5c0f\uff1aUnicode = GB18030 > GBK > GB2312 > ASCII \u603b\u4e4b\uff0cGB \u7cfb\u5217\u7f16\u7801\u9762\u5bf9\u5207\u7247\u548c\u67e5\u627e\u5b58\u5728\u4e00\u5b9a\u7684\u95ee\u9898\uff0c\u6709\u6761\u4ef6\u7684\u8bdd\uff0c\u5efa\u8bae Windows \u7a0b\u5e8f\u5c3d\u5feb\u5347\u7ea7\u5230 UTF-8 \u5916\u7801\u3001UTF-16 \u5185\u7801\u7684\u5de5\u4f5c\u6d41\u4e0a\u6765\uff0c\u56de\u907f\u6389\u53f2\u5c71\u7684\u5f71\u54cd\u3002","title":"\u603b\u7ed3"},{"location":"unicode/#cc","text":"","title":"C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#_9","text":"\u7c7b\u578b \u5927\u5c0f \u7f16\u7801 \u5b57\u9762\u91cf Linux char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e $LC_ALL \u201chello\u201d Windows char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e \u201chello\u201d Linux wchar_t 4 \u5b57\u8282 UTF-32 L\u201dhello\u201d Windows wchar_t 2 \u5b57\u8282 UTF-16LE L\u201dhello\u201d char8_t 1 \u5b57\u8282 UTF-8 u8\u201dhello\u201d char16_t 2 \u5b57\u8282 UTF-16 u\u201dhello\u201d char32_t 4 \u5b57\u8282 UTF-32 U\u201dhello\u201d \u7531\u6b64\u53ef\u89c1\uff0c char \u548c wchar_t \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f GBK\u3002\u5bf9\u4e8e\u7f8e\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\u3002 \u5bf9\u4e8e Linux \u7528\u6237\u6765\u8bf4\uff0c\u5982\u679c\u4f60\u6ca1\u6709\u4e13\u95e8\u4fee\u6539\u8fc7\uff0c $LC_ALL \u9ed8\u8ba4\u662f en_US.UTF-8 \u6216 C.UTF-8 \u3002 \u8fd9\u5e26\u6765\u4e86\u5de8\u5927\u7684\u6df7\u6dc6\uff01\u5f88\u591a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u6f5c\u610f\u8bc6\u91cc\u4f1a\u60f3\u5f53\u7136\u5730\u628a char \u5f53\u4f5c UTF-8 \u6765\u7528\u3002\u5f88\u591a\u5f00\u6e90\u9879\u76ee\uff0c\u7b2c\u4e09\u65b9\u5e93\uff0c\u751a\u81f3\u5f88\u591a\u56fd\u4eba\u505a\u7684\u9879\u76ee\uff0c\u90fd\u88ab\u8fd9\u79cd\u201c\u60f3\u5f53\u7136\u201d\u4f20\u67d3\u4e86\u3002 \u597d\u6d88\u606f\u662f\u65e0\u8bba\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u662f\u4ec0\u4e48\uff0c\u80af\u5b9a\u517c\u5bb9 ASCII\u3002\u4f8b\u5982 GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u5426\u5219\u5c31\u548c\u6240\u6709\u7684 C \u8bed\u8a00\u7ecf\u5178\u51fd\u6570\u5982 strlen \uff0c\u6362\u884c\u7b26 '\\n' \uff0c\u8def\u5f84\u5206\u9694\u7b26 '/' \u548c '\\\\' \u51b2\u7a81\u4e86\u3002 wchar_t \u5c31\u597d\u4e00\u4e9b\uff0c\u867d\u7136\u5728 Windows \u7cfb\u7edf\u4e0a\u662f\u7cdf\u7cd5\u7684 UTF-16\uff0c\u4f46\u81f3\u5c11\u7a33\u5b9a\u4e86\uff0c\u4e0d\u4f1a\u968f\u7740\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u800c\u968f\u610f\u6539\u53d8\uff0c\u53ea\u8981\u4f60\u4e0d\u6253\u7b97\u8de8\u5e73\u53f0\uff0c wchar_t \u5c31\u662f Windows \u7a0b\u5e8f\u7684\u6807\u914d\u3002 \u6839\u636e Windows \u5b98\u65b9\u6587\u6863\u7684\u8bf4\u6cd5\uff0c wchar_t \u662f UTF-16LE\u3002","title":"\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#utf-8-ascii","text":"UTF-8 \u7684\u706b\u8f66\u5934\u548c\u8f66\u53a2\uff0c\u90fd\u662f 1 \u5f00\u5934\u7684\uff0c\u800c ASCII \u7684\u5355\u4f53\u706b\u8f66\u5934\u6c38\u8fdc\u662f 0 \u5f00\u5934\u3002\u8fd9\u5f88\u91cd\u8981\uff0c\u4e0d\u4ec5\u706b\u8f66\u5934\u9700\u8981\u548c ASCII \u533a\u5206\u5f00\u6765\uff0c\u8f66\u53a2\u4e5f\u9700\u8981\u3002\u8003\u8651\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff1a std::u32string path = \"\u4e00\u4e2a\u8001\u4f2f.txt\"; \u201c\u4e00\u4e2a\u8001\u4f2f\u201d \u8f6c\u6362\u4e3a Unicode \u7801\u70b9\u5206\u522b\u662f\uff1a 0x4E00 0x4E2A 0x8001 0x4F2F \u5982\u679c\u8ba9\u4ed6\u4eec\u539f\u5c01\u4e0d\u52a8\u76f4\u63a5\u5b58\u50a8\u8fdb char \u6570\u7ec4\u91cc\uff1a 0x4E 0x00 0x4E 0x2A 0x80 0x01 0x4F 0x2F \u5c31\u51fa\u95ee\u9898\u4e86\uff01\u9996\u5148\uff0c\u8fd9\u91cc 0x4E00 \u7684 0x00 \u90e8\u5206\uff0c\u4f1a\u88ab C \u8bed\u8a00\u5f53\u4f5c\u662f\u5b57\u7b26\u4e32\u7684\u7ed3\u5c3e\u3002\u5982\u679c\u62ff\u8fd9\u6837\u7684\u5b57\u7b26\u4e32\u53bb\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u7684 open \u51fd\u6570\uff0c\u4ed6\u4f1a\u4ee5\u4e3a\u4f60\u5728\u6253\u5f00 0x4E \u5355\u4e2a\u5b57\u7b26\u7684\u6587\u4ef6\u540d\uff0c\u4e5f\u5c31\u662f \"N\" \u3002 \u66f4\u7cdf\u7cd5\u7684\u662f\uff0c0x2F \u5bf9\u5e94\u7684 ASCII \u5b57\u7b26\u662f '/' \uff0c\u662f\u8def\u5f84\u5206\u9694\u7b26\u3002\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u4ee5\u4e3a\u4f60\u8981\u521b\u5efa\u4e00\u4e2a\u5b50\u6587\u4ef6\u5939\u4e0b\u7684\u6587\u4ef6 \"N\\x00N*\\x80\\x01O/.txt\" \uff0c\u6587\u4ef6\u5939\u540d\u5b57\u53eb \"N\\x00N*\\x80\\x01O\" \u800c\u6587\u4ef6\u53eb \".txt\" \u3002 \u4e3a\u4e86\u80fd\u8ba9\u9488\u5bf9 ASCII \u8bbe\u8ba1\u7684\u64cd\u4f5c\u7cfb\u7edf API \u652f\u6301\u4e2d\u6587\u6587\u4ef6\u540d\uff0c\u5c31\u53ea\u80fd\u7ed5\u5f00\u6240\u6709 0x7F \u4ee5\u4e0b\u7684\u503c\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 UTF-8 \u5bf9\u8f66\u53a2\u4e5f\u5168\u90e8\u62ac\u9ad8\u5230 0x80 \u4ee5\u4e0a\uff0c\u907f\u514d\u64cd\u4f5c\u7cfb\u7edf\u4e0d\u614e\u628a\u8f66\u53a2\u5f53\u4f5c\u662f '/' \u6216 '\\0' \u3002","title":"\u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII"},{"location":"unicode/#utf-8_2","text":"\u7531\u4e8e\u5de8\u5927\u7684\u60ef\u6027\uff0c\u5f88\u591a\u4eba\u90fd\u60f3\u5f53\u7136\u7684\u628a std::string \u5f53\u4f5c UTF-8 \u6765\u4f7f\u7528\u3002\u5bf9\u4e8e\u7b80\u5355\u7684\u6253\u5370\uff0c\u5e38\u89c4\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u5b57\u7b26\u4e32\u64cd\u4f5c\u6709\u4e0b\u9762\u8fd9\u51e0\u79cd\uff0c\u5f97\u76ca\u4e8e UTF-8 \u4f18\u79c0\u7684\u5e8f\u5217\u5316\u6d89\u53ca\u548c\u5197\u4f59\u6297\u5e72\u6270\u673a\u5236\uff0c\u7edd\u5927\u591a\u6570 ASCII \u652f\u6301\u7684\u64cd\u4f5c\uff0cUTF-8 \u5b57\u7b26\u4e32\u90fd\u80fd\u8f7b\u677e\u80dc\u4efb\uff0c\u552f\u72ec\u5176\u4e2d \u6d89\u53ca\u201c\u7d22\u5f15\u201d\u548c\u201c\u957f\u5ea6\u201d\u7684 \u4e00\u90e8\u5206\u64cd\u4f5c\u4e0d\u884c\u3002\u8fd9\u662f\u7531\u4e8e\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff0c\u5982\u679c\u9700\u8981\u505a\u201c\u7d22\u5f15\u201d\u7c7b\u64cd\u4f5c\uff0c\u8fd8\u662f\u5efa\u8bae\u5148\u8f6c\u6362\u6210\u5b9a\u957f\u7684 UTF-32 \u7f16\u7801\u3002 \u64cd\u4f5c UTF-8 UTF-32 GBK \u6c42\u5b57\u7b26\u4e32\u957f\u5ea6 \u00d7 \u221a \u00d7 \u5224\u65ad\u76f8\u7b49 \u221a \u221a \u221a \u5b57\u5178\u5e8f\u7684\u5927\u5c0f\u6bd4\u8f83 \u221a \u221a \u00d7 \u5b57\u7b26\u4e32\u62fc\u63a5 \u221a \u221a \u221a \u641c\u7d22\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u641c\u7d22\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u4e0b\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u83b7\u53d6\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u904d\u5386\u6240\u6709\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u5b50\u5b57\u7b26\u4e32\u5207\u7247 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u7247 \u00d7 \u221a \u00d7 \u67e5\u627e\u5e76\u66ff\u6362\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u67e5\u627e\u5e76\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u5220\u9664\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u4e3a\u4ec0\u4e48\uff1f\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u5b9e\u9a8c\uff1a std::string s = \"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \uff08\u4f7f\u7528 /utf-8 \u7f16\u8bd1\uff09\u8fd0\u884c\u540e\uff0c\u4f1a\u5f97\u5230 6\u3002 \u56e0\u4e3a std::string \u7684 size() \u8fd4\u56de\u7684\u662f char \u7684\u6570\u91cf\uff0c\u800c\u4e0d\u662f\u771f\u6b63\u5b57\u7b26\u7684\u6570\u91cf\u3002\u5728 UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u975e ASCII \u7684\u5b57\u7b26\u4f1a\u88ab\u7f16\u7801\u4e3a\u591a\u4e2a char \uff0c\u5bf9\u4e8e\u4e2d\u6587\u800c\u8a00\uff0c\u4e2d\u6587\u90fd\u5728 0x2E80 \u5230 0x9FFF \u8303\u56f4\u5185\uff0c\u5c5e\u4e8e\u4e09\u7ea7\u5217\u8f66\uff0c\u4e5f\u5c31\u662f\u6bcf\u4e2a\u6c49\u5b57\u4f1a\u88ab\u7f16\u7801\u6210 3 \u4e2a char \u3002 char \u662f\u5b57\u8282\uff08\u7801\u4f4d\uff09\u800c\u4e0d\u662f\u771f\u6b63\u7684\u5b57\u7b26\uff08\u7801\u70b9\uff09\u3002\u771f\u6b63\u7684 Unicode \u5b57\u7b26\u5e94\u8be5\u662f char32_t \u7c7b\u578b\u7684\u3002\u8c03\u7528 std::string \u7684 size() \u6216\u8005 strlen \u5f97\u5230\u7684\u53ea\u662f\u201c\u5b57\u8282\u6570\u91cf\u201d\u3002 \u800c UTF-32 \u4e2d\uff0c\u6bcf\u4e2a\u5b57\u7b26\uff08\u7801\u70b9\uff09\u90fd\u5bf9\u5e94\u4e00\u4e2a\u72ec\u7acb\u7684 char32_t \uff08\u7801\u4f4d\uff09\uff0c size() \u5c31\u662f\u771f\u6b63\u7684\u201c\u5b57\u7b26\u6570\u91cf\u201d\uff0c\u8fd9\u5c31\u662f\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 std::u32string s = U\"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \u5982\u679c\u4f60\u7684\u64cd\u4f5c\u53ea\u6d89\u53ca\u5b57\u7b26\u4e32\u67e5\u62fc\u63a5\u4e0e\u67e5\u627e\uff0c\u90a3\u5c31\u53ef\u4ee5\u7528 UTF-8\u3002\u5982\u679c\u5927\u91cf\u6d89\u53ca\u7d22\u5f15\uff0c\u5207\u7247\uff0c\u5355\u4e2a\u5b57\u7b26\u7684\u64cd\u4f5c\uff0c\u90a3\u5c31\u5fc5\u987b\u7528 UTF-32\uff08\u5426\u5219\u4e00\u9047\u5230\u6c49\u5b57\u5c31\u4f1a\u51fa\u9519\uff09\u3002 std::vector slogan = { \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\", \"\u5168\u4e16\u754c\u7a0b\u5e8f\u5458\u5927\u56e2\u7ed3\u4e07\u5c81\", }; std::string joined; for (auto const &s: slogan) { joined += s; // \u53ea\u662f\u62fc\u63a5\u800c\u5df2\uff0cUTF-8 \u6ca1\u95ee\u9898 } UTF-8 \u6309\u7d22\u5f15\u5207\u7247\u7684\u51fa\u9519\u6848\u4f8b\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-8 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u8282\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\ufffd\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-32 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u7b26\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u53ea\u6709\u5f53\u7d22\u5f15\u662f\u6765\u81ea find \u7684\u7ed3\u679c\u65f6\uff0cUTF-8 \u5b57\u7b26\u4e32\u7684\u5207\u7247\u624d\u80fd\u6b63\u5e38\u5de5\u4f5c\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(\"\u516c\"); // pos = 12 fmt::println(\"UTF-8 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u8282\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(U'\u516c'); // pos = 4 fmt::println(\"UTF-32 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u7b26\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u6ce8\u610f\u5230\u8fd9\u91cc UTF-8 \u7684 \"\u516c\" \u9700\u8981\u662f\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u5b57\u7b26\u3002 UTF-8 \u65e0\u6cd5\u53d6\u51fa\u5355\u4e2a\u975e ASCII \u5b57\u7b26\uff0c\u5bf9\u4e8e\u5355\u4e2a\u4e2d\u6587\u5b57\u7b26\uff0c\u4ecd\u7136\u53ea\u80fd\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u8868\u8fbe\uff08\u7531\u591a\u4e2a\u5b57\u8282\u7ec4\u6210\uff09\u3002 std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-8 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u8282\uff1a{}\", s[0]); // \u53ef\u80fd\u4f1a\u6253\u5370 \u2018\u00e5\u2019 (0xE5)\uff0c\u56e0\u4e3a\u201c\u5c0f\u201d\u7684 UTF-8 \u7f16\u7801\u662f 0xE5 0xB0 0x8F // \u4e5f\u53ef\u80fd\u662f\u4e71\u7801\u201c\ufffd\u201d\uff0c\u53d6\u51b3\u4e8e\u7ec8\u7aef\u7406\u89e3\u7684\u7f16\u7801\u683c\u5f0f std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-32 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u7b26\uff1a{}\", s[0]); // \u4f1a\u6253\u5370 \u2018\u5c0f\u2019 UTF-8 \u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\u4e5f\u4f1a\u51fa\u95ee\u9898\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u4e71\u7801 std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u628a\u6309\u5b57\u7b26\u6b63\u5e38\u53cd\u8f6c\uff0c\u5f97\u5230 \u201c\u5c81\u4e07\u8bfe\u5f00\u516c\u5e08\u8001\u5f6d\u5c0f\u201d \u603b\u7ed3\uff1aUTF-8 \u53ea\u80fd\u62fc\u63a5\u3001\u67e5\u627e\u3001\u6253\u5370\u3002\u4e0d\u80fd\u7d22\u5f15\u3001\u5207\u7247\u3001\u53cd\u8f6c\u3002 \u6309\u7d22\u5f15\u5207\u7247\u4e0d\u884c\uff0c\u4f46\u5982\u679c\u7d22\u5f15\u662f find \u51fa\u6765\u7684\u5c31\u6ca1\u95ee\u9898\u3002","title":"UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c"},{"location":"unicode/#ansi-unicode","text":"\u5728 Windows \u5b98\u65b9\u7684\u8bf4\u8f9e\u4e2d\uff0c\u6709\u201cUnicode \u7f16\u7801\u201d\u548c\u201cANSI \u7f16\u7801\u201d\u7684\u8bf4\u6cd5\u3002\u5f53\u4f60\u4f7f\u7528 Windows \u81ea\u5e26\u7684\u8bb0\u4e8b\u672c\u7a0b\u5e8f ( notepad.exe ) \u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u65f6\uff0c\u5c31\u4f1a\u770b\u5230\u8fd9\u6837\u7684\u9009\u5355\uff1a \u7ffb\u8bd1\u4e00\u4e0b\uff1a \u201cANSI\u201d\u6307\u7684\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u8bbe\u7f6e\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\u3002 \u6240\u8c13\u201cUnicode\u201d\u5176\u5b9e\u6307\u7684\u662f UTF-16\u3002 \u6240\u8c13\u201cUnicode big endian\u201d\u6307\u7684\u662f\u5927\u7aef UTF-16\u3002 \u201cUTF-8\u201d\u6307\u7684\u662f UTF-8 with BOM \u800c\u4e0d\u662f\u6b63\u5e38\u7684 UTF-8\u3002 \u5b9e\u9645\u4e0a Unicode \u53ea\u662f\u4e00\u4e2a\u5b57\u7b26\u96c6\uff0c\u53ea\u662f\u628a\u5b57\u7b26\u6620\u5c04\u5230\u6574\u6570\uff0c\u66f4\u6ca1\u6709\u4ec0\u4e48\u5927\u7aef\u5c0f\u7aef\uff0cUTF-16 \u624d\u662f\u7f16\u7801\u683c\u5f0f\u3002 \u800c ANSI \u672c\u6765\u5e94\u8be5\u662f ASCII \u7684\u610f\u601d\uff0c char \u672c\u6765\u5c31\u53ea\u652f\u6301 ASCII\u3002 \u4f46\u7531\u4e8e\u5f53\u65f6\u5404\u56fd\u8feb\u5207\u9700\u8981\u652f\u6301\u81ea\u5df1\u672c\u56fd\u7684\u6587\u5b57\uff0c\u5c31\u5728\u517c\u5bb9 ASCII \u7684\u57fa\u7840\u4e0a\uff0c\u53d1\u5c55\u51fa\u4e86\u81ea\u5df1\u7684\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u3002\u8fd9\u4e9b\u5f53\u5730\u7279\u4f9b\u7684\u5b57\u7b26\u96c6\u91cc\u53ea\u5305\u542b\u4e86\u672c\u56fd\u6587\u5b57\uff0c\u6240\u6709\u8fd9\u4e9b\u5404\u56fd\u7684\u5b57\u7b26\u7f16\u7801\u4e5f\u90fd\u548c UTF-8 \u7c7b\u4f3c\uff0c\u91c7\u7528\u706b\u8f66\u5934\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0c\u5bf9 0 \u5f00\u5934\u7684 ASCII \u90e8\u5206\u4e5f\u90fd\u662f\u517c\u5bb9\u3002\u6240\u4ee5 Windows \u7d22\u6027\u628a ANSI \u5f53\u4f5c\u201c\u5404\u56fd\u672c\u5730\u6587\u5b57\u7f16\u7801\u201d\u7684\u7b80\u79f0\u4e86\u3002\u4f46\u540e\u6765\u4e92\u8054\u7f51\u7684\u51fa\u73b0\uff0c\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u5e26\u6765\u4e86\u5de8\u5927\u7684\u4fe1\u606f\u4ea4\u6362\u56f0\u96be\u3002 \u4f8b\u5982\u4f60\u5728\u73a9\u4e00\u4e9b\u65e5\u672c\u7684 galgame \u65f6\uff0c\u4f1a\u53d1\u73b0\u91cc\u9762\u6587\u5b57\u5168\u90e8\u4e71\u7801\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u5728\u5404\u4e2a\u5730\u533a\u53d1\u884c\u7684\u662f\u201c\u7279\u4f9b\u7248\u201d\uff1a\u5728\u4e2d\u56fd\u5927\u9646\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 GBK \u5b57\u7b26\u96c6\uff0c\u5728\u65e5\u672c\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 Shift-JIS \u5b57\u7b26\u96c6\u3002\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u7a0b\u5e8f\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u5b58\u50a8\u7684\u662f Shift-JIS \u7684\u90a3\u4e9b\u201c\u6574\u6570\u201d\u3002\u8fd9\u5bfc\u81f4\u65e5\u672c\u7684 galgame \u5728\u4e2d\u56fd\u5927\u9646\u7279\u4f9b\u7684 Windows \u4e2d\uff0c\u628a Shift-JIS \u7684\u201c\u6574\u6570\u201d\u7528 GBK \u7684\u8868\u6765\u89e3\u8bfb\u4e86\uff0c\u4ece\u800c\u4e71\u7801\uff08GBK \u91cc\u7684\u65e5\u6587\u533a\u57df\u5e76\u6ca1\u6709\u548c Shift-JIS \u91cd\u53e0\uff09\u3002\u9700\u8981\u7528 Locale Emulator \u628a Shift-JIS \u7ffb\u8bd1\u6210 Unicode \u8bfb\u7ed9 Windows \u542c\u3002\u5982\u679c\u65e5\u672c\u7a0b\u5e8f\u5458\u4ece\u4e00\u5f00\u59cb\u5c31\u7edf\u4e00\u7528 Unicode \u6765\u5b58\u50a8\uff0c\u4e2d\u56fd\u533a\u73a9\u5bb6\u7684 Windows \u4e5f\u7edf\u4e00\u7528 Unicode \u89e3\u6790\uff0c\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cUnicode \u7ec4\u7ec7\u51fa\u73b0\u4e86\uff0c\u4ed6\u7684\u4f7f\u547d\u5c31\u662f\u7edf\u4e00\u5168\u4e16\u754c\u7684\u5b57\u7b26\u96c6\uff0c\u4fdd\u8bc1\u5168\u4e16\u754c\u6240\u6709\u7684\u6587\u5b57\u90fd\u80fd\u5728\u5168\u4e16\u754c\u6240\u6709\u7684\u8ba1\u7b97\u673a\u4e0a\u663e\u793a\u51fa\u6765\u3002\u9996\u5148\u521b\u529e\u4e86 Unicode \u5b57\u7b26\u96c6\uff0c\u7136\u540e\u89c4\u5b9a\u4e86 UTF-8\u3001UTF-16\u3001UTF-32 \u4e09\u79cd\u5b57\u7b26\u7f16\u7801\uff0c\u6700\u7ec8 UTF-8 \u6210\u4e3a\u5916\u7801\u7684\u4e3b\u6d41\uff0cUTF-32 \u6210\u4e3a\u5185\u7801\u7684\u4e3b\u6d41\u3002 \u63a5\u4e0b\u6765\u4e3a\u4e86\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u6211\u4eec\u7d22\u6027\u5c31\u987a\u7740\u5fae\u8f6f\u7684\u8fd9\u4e2a\u8bf4\u6cd5\uff1a \u7ba1 char \u53eb ANSI\uff1a\u968f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002 \u7ba1 wchar_t \u53eb Unicode\uff1a\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u5728 Linux \u4e0a\u662f UTF-32\u3002","title":"\u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48"},{"location":"unicode/#utf-16_1","text":"\u5fae\u8f6f\u7ba1 UTF-16 \u53eb Unicode \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u95ee\u9898\uff1a \u56e0\u4e3a\u5f53\u5e74 Unicode 5.0 \u7684\u65f6\u5019\u53ea\u6709 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff0c16 \u4f4d\u5c31\u88c5\u5f97\u4e0b\uff0c\u6240\u4ee5\u5f53\u65f6 UTF-16 \u8fd8\u662f\u4e00\u4e2a \u5b9a\u957f\u7f16\u7801 \u3002\u5fae\u8f6f\u4e8e\u662f\u51b3\u5b9a\u628a wchar_t \u5b9a\u4e49\u6210 2 \u5b57\u8282\uff0c\u5e76\u5728 NT \u5185\u6838\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u7cfb\u7edf\u8c03\u7528\u90fd\u5347\u7ea7\u6210\u4e86\u57fa\u4e8e wchar_t \u5b57\u7b26\u4e32\u7684 \u201cW \u7cfb\u201d API\u3002 \u6bd4\u5c14\u76d6\u5b50\u5f53\u65f6\u4ee5\u4e3a\u8fd9\u6837 UTF-16 \u5b9a\u957f\u5185\u7801\u5c31\u4e00\u52b3\u6c38\u9038\u4e86\uff0c\u5e76\u53f7\u53ec\u6240\u6709\u7a0b\u5e8f\u90fd\u6539\u7528 UTF-16 \u505a\u5185\u7801\uff0c\u522b\u7528 \u201cA \u7cfb\u201d API \u4e86\u3002 \u8d77\u521d\uff0c\u6240\u6709\u4eba\u90fd\u4ee5\u4e3a UTF-16 \u5c31\u662f\u6700\u7ec8\u7b54\u6848\u3002 \u6ca1\u60f3\u5230\u540e\u6765 Unicode \u59d4\u5458\u4f1a\u201c\u80cc\u523a\u201d\u4e86\u6bd4\u5c14\u76d6\u5b50\uff01\u5077\u5077\u628a\u8303\u56f4\u66f4\u65b0\u5230\u4e86 0x10FFFF\uff0c\u7a81\u7834\u4e86 16 \u4f4d\u6574\u6570\u7684\u5bb9\u91cf\u3002\u539f\u6765\u7684 UTF-16 \u5df2\u7ecf\u5bb9\u7eb3\u4e0d\u4e0b\uff0c\u53ea\u597d\u5229\u7528\u4e4b\u524d\u9884\u7559\u7684 0xD800 \u5230 0xDFFF \u7a7a\u53f7\u533a\u95f4\u4e11\u964b\u5730\u5b9e\u73b0\u4e86\u53d8\u957f\u7f16\u7801\u3002 \u76f4\u5230 UTF-16 \u4e00\u591c\u4e4b\u95f4\u6210\u4e86\u4e11\u964b\u7684 \u53d8\u957f\u7f16\u7801 \u3002 \u95f9\u4e86\u534a\u5929\uff0cWindows \u8d39\u5fc3\u8d39\u529b\u66ff Unicode \u59d4\u5458\u4f1a\u597d\u4e0d\u5bb9\u6613\u63a8\u5e7f\u7684 wchar_t \uff0c\u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801 \u7684\u597d\u5904\u3002\u53ef \u201cW \u7cfb\u201d API \u5374\u53c8\u710a\u6b7b\u5728\u4e86 NT \u5185\u6838\u6700\u5e95\u5c42\uff0c\u53cd\u590d\u6765\u5751\u7b2c\u4e00\u6b21\u7528 Windows \u7f16\u7a0b\u7684\u521d\u5b66\u8005\u3002 \u6bd4\u5c14\u76d6\u5b50\uff1a\u4f60\u8fd9\u6837\u663e\u5f97\u6211\u5f88\u5c0f\u4e11\u8bf6\uff1f \u9664 Windows \u5916\uff0cJava \u4e5f\u662f\u201cUTF-16 \u80cc\u523a\u201d\u7684\u53d7\u5bb3\u8005\uff0c\u4ed6\u4eec\u60f3\u5f53\u7136\u7684\u628a char \u5b9a\u4e49\u4e3a UTF-16\uff0c\u4ee5\u4e3a\u8fd9\u5c31\u662f\u672a\u6765\u6c38\u4e45\u7684\u5b9a\u957f\u5185\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u2026\u2026 \u76f4\u5230 Unicode \u52a0\u5165\u4e86 0x10FFFF\uff0cJava \u4e0d\u5f97\u4e0d\u91cd\u65b0\u5b9a\u4e49\u4e86\u4e2a Character \u4f5c\u4e3a UTF-32 \u5b57\u7b26\uff0c\u8fd8\u5f04\u4e2a char \u5230 Character \u7684\u8f6c\u6362\uff0c\u597d\u4e0d\u5c34\u5c2c\uff01 Linux \u6210\u7acb\u4e8e 1991 \u5e74\uff0c\u5f53\u65f6 Unicode \u4e5f\u624d\u521a\u521a\u51fa\u73b0\u3002Unicode \u5ba3\u5e03\u52a0\u5165 0x10FFFF \u540e\uff0cLinux \u624d\u5f00\u59cb\u5f15\u5165\u652f\u6301 Unicode\u3002\u5728\u77e5\u9053\u4e86 Unicode \u5305\u542b 0x10FFFF \u540e\uff0c\u4ed6\u4eec\u4e00\u5f00\u59cb\u5c31\u628a wchar_t \u5b9a\u4e49\u6210 4 \u5b57\u8282\uff0c\u9003\u8fc7\u4e86 UTF-16 \u7684\u80cc\u523a\u3002 \u540e\u6765\u65b0\u51fa\u7684\u8bed\u8a00\uff0c\u5982 Python 3\u3001Go\u3001Rust\u3001Swift\u3001Kotlin\uff0c\u628a\u5b57\u7b26\u94a6\u5b9a\u4e3a UTF-32 \u4e86\u3002\u4ed6\u4eec\u53ea\u6709\u5728\u8c03\u7528 Windows API \u65f6\uff0c\u624d\u4f1a\u4e34\u65f6\u8f6c\u6362\u4e3a UTF-16 \u6765\u8c03\u7528\uff0c\u9664\u6b64\u4e4b\u5916\u518d\u65e0 UTF-16 \u51fa\u73b0\u3002 \u8bb8\u591a\u7cdf\u7cd5\u7684\u535a\u5ba2\u58f0\u79f0\uff1a\u662f\u56e0\u4e3a\u201cUTF-16 \u6700\u6709\u5229\u4e8e\u4e2d\u6587\u538b\u7f29\u201d\uff0c\u6240\u4ee5 Java \u548c Windows \u624d\u91c7\u7528\u7684\uff1f\u7136\u800c\u5c31\u6211\u4e86\u89e3\u5230\u7684\u5b9e\u9645\u60c5\u51b5\u662f\u56e0\u4e3a\u4ed6\u4eec\u9519\u8bef\u7684\u4ee5\u4e3a 0xFFFF \u662f Unicode \u7684\u4e0a\u9650\u624d\u9519\u8bef\u91c7\u7528\u4e86\uff0c\u4e0d\u7136\u4e3a\u4ec0\u4e48\u540e\u6765\u7684\u65b0\u8bed\u8a00\u90fd\u91c7\u7528\u4e86 UTF-32 \u5185\u7801 + UTF-8 \u5916\u7801\u7684\u7ec4\u5408\uff1f\u800c\u4e14\u5728\u5916\u7801\u4e2d\u91c7\u7528 UTF-8 \u6216 UTF-16 \u538b\u7f29\u786e\u5b9e\u6ca1\u95ee\u9898\uff0c\u4f46\u662f Java \u548c Windows \u7684\u5931\u8bef\u5728\u4e8e\u628a UTF-16 \u5f53\u4f5c\u5185\u7801\u4e86\uff01\u5185\u7801\u5c31\u7406\u5e94\u662f\u5b9a\u957f\u7f16\u7801\u7684\u624d\u65b9\u4fbf\uff0c\u5982\u679c\u4f60\u6709\u4e0d\u540c\u60f3\u6cd5\uff0c\u6b22\u8fce\u7559\u8a00\u8ba8\u8bba\u3002 \u603b\u4e4b\uff0cUTF-16 \u662f\u7cdf\u7c95\uff0c\u4f46\u4ed6\u662f Windows \u552f\u4e00\u5b8c\u6574\u652f\u6301\u7684 Unicode \u63a5\u53e3\u3002\u4e0d\u5efa\u8bae\u8f6f\u4ef6\u5185\u90e8\u7528 UTF-16 \u5b58\u50a8\u6587\u5b57\uff0c\u4f60\u53ef\u4ee5\u7528\u66f4\u7d27\u51d1\u7684 UTF-8 \u6216\u66f4\u65b9\u4fbf\u5207\u7247\u7684 UTF-32\uff0c\u53ea\u9700\u5728\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u524d\u4e34\u65f6\u8f6c\u6362\u6210 UTF-16 \u5c31\u884c\u3002","title":"\u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a"},{"location":"unicode/#stdu8string","text":"\u5fc5\u987b\u6307\u51fa\uff1a\u5728 std::string \u4e2d\u88c5 UTF-8 \u5e76\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5728 std::u8string \u91cc\u540c\u6837\u53ef\u4ee5\u88c5 GBK\u3002\u8fd9\u5c31\u597d\u6bd4\u4e00\u4e2a\u540d\u53eb Age \u7684\u679a\u4e3e\u7c7b\u578b\uff0c\u5b9e\u9645\u5374\u88c5\u7740\u6027\u522b\u4e00\u6837\u3002 enum Age { // \u9519\u8bef\u793a\u8303 Male, Female, Custom, }; // \u9664\u4e86\u8ff7\u60d1\u540c\u4e8b\u5916\uff0c\u628a\u5e74\u9f84\u548c\u6027\u522b\u7684\u7c7b\u578b\u6df7\u7528\u6ca1\u6709\u597d\u5904 void registerStudent(Age age, Age sex); \u533a\u5206\u7c7b\u578b\u53ea\u662f\u5927\u591a\u6570\u4eba\u8bbe\u8ba1\u63a5\u53e3\u7684\u89c4\u8303\uff0c\u53ea\u662f\u65b9\u4fbf\u4f60\u901a\u8fc7\u770b\u51fd\u6570\u63a5\u53e3\u4e00\u773c\u533a\u5206\u8fd9\u4e2a\u51fd\u6570\u63a5\u53d7\u7684\u662f\u4ec0\u4e48\u683c\u5f0f\u7684\u5b57\u7b26\u4e32\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u6027\u3002\u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4e00\u770b\u5c31\u77e5\u9053\u8fd9\u4e9b\u51fd\u6570\u9700\u8981\u7684\u662f\u4ec0\u4e48\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 void thisFuncAcceptsANSI(std::string msg); void thisFuncAcceptsUTF8(std::u8string msg); void thisFuncAcceptsUTF16(std::u16string msg); void thisFuncAcceptsUnicode(std::wstring msg); void thisFuncAcceptsUTF32(std::u32string msg); \u6ca1\u6709 char8_t \u4e4b\u524d\uff0c\u7528\u7c7b\u578b\u522b\u540d\u540c\u6837\u53ef\u4ee5\u8d77\u5230\u5dee\u4e0d\u591a\u7684\u8bf4\u660e\u6548\u679c\uff08\u7f3a\u70b9\u662f\u65e0\u6cd5\u91cd\u8f7d\uff09\uff1a using ANSIString = std::string; using UTF8String = std::string; using UTF16String = std::vector; void thisFuncAcceptsANSI(ANSIString msg); void thisFuncAcceptsUTF8(UTF8String msg); void thisFuncAcceptsUTF16(UTF16String msg); \u4e4b\u6240\u4ee5\u6211\u4f1a\u8bf4\uff0c std::string \u5e94\u8be5\u88c5 ANSI \u5b57\u7b26\u4e32\uff0c\u662f\u56e0\u4e3a\u6240\u6709\u6807\u51c6\u5e93\u5b98\u65b9\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u4f1a\u5047\u5b9a std::string \u7c7b\u578b\u662f ANSI \u7f16\u7801\u683c\u5f0f\uff08GBK\uff09\u3002\u5e76\u4e0d\u662f\u8bf4\uff0c\u4f60\u4e0d\u80fd\u7528 std::string \u5b58\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\u7684\u5185\u5bb9\u3002 \u5982\u679c\u4f60\u5c31\u662f\u60f3\u7528 std::string \u88c5 UTF-8 \u4e5f\u53ef\u4ee5\uff0c\u53ea\u4e0d\u8fc7\u4f60\u8981\u6ce8\u610f\u5728\u4f20\u5165\u6240\u6709\u4f7f\u7528\u4e86\u6587\u4ef6\u8def\u5f84\u7684\u51fd\u6570\uff0c\u5982 fopen \uff0c std::ifstream \u7684\u6784\u9020\u51fd\u6570\u524d\uff0c\u9700\u8981\u505a\u4e00\u4e2a\u8f6c\u6362\uff0c\u8f6c\u6210 GBK \u7684 std::string \u6216 UTF-16 \u7684 std::wstring \u540e\uff0c\u624d\u80fd\u4f7f\u7528\uff0c\u5f88\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u5982\u679c\u4f60\u59cb\u7ec8\u7528 std::u8string \u88c5 UTF-8\uff0c\u90a3\u4e48\u5f53\u4f60\u628a\u5b83\u8f93\u5165\u4e00\u4e2a\u63a5\u53d7 ANSI \u7684\u666e\u901a std::string \u53c2\u6570\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7c7b\u578b\u4e0d\u5339\u914d\u9519\u8bef\uff0c\u5f3a\u8feb\u4f60\u91cd\u65b0\u6e05\u9192\uff0c\u6216\u662f\u5f3a\u8feb\u4f60\u4f7f\u7528\u4e00\u4e2a\u8f6c\u6362\u51fd\u6570\uff0c\u7a0d\u540e\u4f1a\u4ecb\u7ecd\u8fd9\u4e2a\u8f6c\u6362\u51fd\u6570\u7684\u5199\u6cd5\u3002 \u4f8b\u5982\u5f53\u4f60\u4f7f\u7528 std::cout << u8string \u65f6\u4f1a\u62a5\u9519\uff0c\u8feb\u4f7f\u4f60\u6539\u4e3a std::cout << u8toansi(u8string) \u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff0c\u4ece\u800c\u907f\u514d\u4e86\u628a UTF-8 \u7684\u5b57\u7b26\u4e32\u6253\u5370\u5230\u4e86\u53ea\u652f\u6301 GBK \u7684\u63a7\u5236\u53f0\u4e0a\u3002 \u5176\u4e2d\u8f6c\u6362\u51fd\u6570\u7b7e\u540d\u4e3a std::string u8toansi(std::u8string s) \uff0c\u5f88\u53ef\u60dc\uff0c\u6807\u51c6\u5e93\u5e76\u6ca1\u6709\u63d0\u4f9b\u8fd9\u4e2a\u51fd\u6570\uff0c\u76f4\u5230 C++26 \u524d\uff0c\u6807\u51c6\u5e93\u5bf9\u5b57\u7b26\u7f16\u7801\u652f\u6301\u4e00\u76f4\u5f88\u5dee\uff0c\u4f60\u4e0d\u5f97\u4e0d\u81ea\u5df1\u5b9e\u73b0\u6216\u4f9d\u8d56\u7b2c\u4e09\u65b9\u5e93\u3002 \u603b\u4e4b\uff0c char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u5411\u8c03\u7528\u8005\u6697\u793a\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\u8fd9\u6837\u4e00\u4e2a\u51fd\u6570\uff1a thisFuncAcceptUTF8(std::u8string msg); \u5982\u679c\u8c03\u7528\u8005\u559c\u6b22\u7528 std::string \u88c5 UTF-8 \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528\uff1a std::string msg; // \u8c03\u7528\u8005\u786e\u4fe1\uff0c\u8fd9\u4e2a msg \u867d\u7136\u662f `std::string`\uff0c\u4f46\u91cc\u9762\u7684\u5185\u5bb9\u5c31\u662f UTF-8 // \u90a3\u4e48\u4ed6\u53ef\u4ee5\u5f3a\u5236\u8f6c\u6362\u4e3a u8string\uff0c\u6765\u8bc1\u660e\u81ea\u5df1\u5934\u8111\u6e05\u9192 thisFuncAcceptUTF8(std::u8string((char8_t *)msg.data(), msg.size()));","title":"\u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae"},{"location":"unicode/#_10","text":"C++ \u5b98\u65b9\u5b9a\u4e49\u4e2d\uff0c\u5b58\u5728\u4e24\u79cd\u5b57\u7b26\u96c6\u3002\u4e00\u79cd\u662f \u6e90\u7801\u5b57\u7b26\u96c6 (source charset) \uff0c\u4e00\u79cd\u662f \u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u3002 \u8fd9\u771f\u662f\u7cdf\u7cd5\u7684\u672f\u8bed\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u8fd9\u4e2a\u540d\u5b57\u5177\u6709\u8bef\u5bfc\u6027\uff0c\u4ed6\u548c\u8fd0\u884c\u65f6\u6839\u672c\u6ca1\u6709\u5173\u7cfb\uff0c\u660e\u660e\u662f\u7f16\u8bd1\u671f\u5c31\u786e\u5b9a\u7684\u3002\u6240\u4ee5\u5c0f\u5f6d\u8001\u5e08\u66ff\u4ed6\u6539\u4e2a\u540d\u5b57\uff0c\u5b9e\u9645\u5e94\u8be5\u53eb\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u96c6\u201d\u3002 \u800c\u4e14\u4ed6\u4eec\u53eb\u5b57\u7b26\u96c6\u4e5f\u4e0d\u5408\u7406\uff0c\u5e94\u8be5\u53eb\u5b57\u7b26\u7f16\u7801\u624d\u5bf9\uff0cUTF-8 \u548c UTF-16 \u90fd\u662f Unicode \u5b57\u7b26\u96c6\u7684\u4e24\u79cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u4f46\u4ed6\u4eec\u660e\u663e\u662f\u4e0d\u540c\u7684\u3002 \u7136\u540e\uff0c\u518d\u5f15\u5165\u4e00\u4e2a\u771f\u6b63\u7684\uff0c\u8fd0\u884c\u65f6\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u8f6f\u4ef6\u5ba2\u6237\u7535\u8111\u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u6700\u7ec8\uff0c\u7ecf\u8fc7\u5c0f\u5f6d\u8001\u5e08\u6539\u826f\u7684\u672f\u8bed\u5982\u4e0b\uff1a \u6e90\u7801\u5b57\u7b26\u7f16\u7801: .cpp \u6e90\u7801\u6587\u4ef6\u65f6\u7528\u7684\u5b57\u7b26\u7f16\u7801\u3002\u4f8b\u5982\u7a0b\u5e8f\u5458\u7528\u8bb0\u4e8b\u672c\u4fdd\u5b58 .cpp \u6e90\u7801\u6587\u4ef6\u65f6\uff0c\u9009\u62e9 \u201cUTF-8\u201d \u4fdd\u5b58\u5c31\u662f UTF-8\uff0c\u9009\u62e9 \u201cANSI\u201d \u4fdd\u5b58\u5c31\u662f GBK\u3002 \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f char \u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u7684\u5b57\u7b26\u7f16\u7801\u3002\u9ed8\u8ba4\u662f\u6211\u4eec\u7a0b\u5e8f\u5458\uff08\u5f00\u53d1\u8005\uff09\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f\u6211\u4eec\u7684\u7a0b\u5e8f\u5728\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u8fd0\u884c\u65f6\uff0c\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf API \u7684 const char * \u671f\u671b\u63a5\u53d7\u600e\u6837\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002\u9ed8\u8ba4\u662f\u5ba2\u6237\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd9\u4e09\u4e2a\u53ef\u4ee5\u5404\u6709\u4e0d\u540c\u3002 \u5176\u4e2d \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801 \u548c \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801 \u7684\u4e0d\u5339\u914d\uff0c\u662f Windows \u8f6f\u4ef6\u51fa\u73b0\u4e71\u7801\u7684\u4e3b\u8981\u539f\u56e0\u3002 \u800c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u53ea\u4e8b\u5173\u4f60\u5982\u4f55\u4fdd\u5b58\u6e90\u7801\uff0c\u53ea\u662f\u8ba9\u7f16\u8bd1\u5668\u80fd\u591f\u6210\u529f\u8bfb\u53d6\u4f60\u7684\u6e90\u7801\uff0c\u5bf9\u8fd0\u884c\u65f6\u7684\u4e71\u7801\u95ee\u9898\u6ca1\u6709\u5f71\u54cd\u3002\u7f16\u8bd1\u5668\u8bfb\u5b8c\u6e90\u7801\u540e\uff0c\u8981\u5728\u5e38\u91cf\u533a\u751f\u6210\u5b57\u7b26\u4e32\u5e38\u91cf\u65f6\uff0c\u8fd8\u662f\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u7684\u3002 \u4f8b\u5982\u4e4b\u524d\u8bf4\u7684\u65e5\u672c galgame \u5728\u4e2d\u56fd\u7535\u8111\u4e0a\u6253\u5f00\u7206\u51fa\u4e71\u7801\uff0c\u5c31\u662f\u56e0\u4e3a\u662f\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u4e86 galgame\uff08\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u4e3a Shift-JIS\uff09\uff0c\u5728\u4e2d\u56fd\u5ba2\u6237\u7535\u8111\u4e0a\u6253\u5f00\uff08\u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801\u4e3a GBK\uff09\u5bfc\u81f4\u7684\u3002 \u65e5\u672c\u7a0b\u5e8f\u5458\u4f7f\u7528\u4ec0\u4e48\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u6839\u672c\u65e0\u5173\u7d27\u8981\u2026\u2026\u54ea\u6015\u4ed6\u4eec\u4f7f\u7528\u4e86 UTF-8 \u4fdd\u5b58\u6e90\u7801\uff0cMSVC \u7f16\u8bd1\u65f6\u4ecd\u7136\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a Shift-JIS \u7f16\u7801\u7684\u5b57\u9762\u91cf\u6765\u5b58\u50a8\u5728\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5e38\u91cf\u533a\u4e2d\u3002 \u4f60\u53ef\u80fd\u4f1a\u95ee\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u628a\u8fd9\u4e9b\u82b1\u91cc\u80e1\u54e8\u73a9\u5e94\u7edf\u4e00\u4e3a UTF-8\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u8f6c\u6362\u6765\u8f6c\u6362\u53bb\u4e86\uff1f\u8fd8\u4e0d\u662f\u56e0\u4e3a\u5386\u53f2\u9057\u7559\uff0c\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\u5458\u4e0d\u80af\u628a\u4ed6\u4eec GBK \u7f16\u7801\u7684\u6e90\u7801\u6539\u6210 UTF-8 \u4fdd\u5b58\uff0c\u800c\u4e14\uff0cWindows \u4e5f\u5b8c\u5168\u4e0d\u63d0\u4f9b\u57fa\u4e8e UTF-8 \u7684\u8de8\u5e73\u53f0 API\uff08\u53ea\u63d0\u4f9b GBK \u548c UTF-16 \u4e24\u79cd\uff0c\u5c31\u662f\u4e0d\u7ed9 UTF-8 \u7684\uff0c\u975e\u5e38\u6076\u5fc3\u4eba\uff09\u3002\u6240\u4ee5 MSVC \u81f3\u4eca\u4ecd\u7136\u9ed8\u8ba4\u662f GBK \u7f16\u7801\u7684\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f ANSI\uff0c\u8ddf\u968f\u4f60\u7cfb\u7edf\u7684\u533a\u57df\u8bbe\u7f6e\u800c\u53d8\uff0c\u5728\u4e2d\u56fd\u5c31 GBK\uff0c\u5728\u7f8e\u56fd\u5c31 UTF-8\uff0c\u5728\u6b27\u6d32\u5c31 Latin-1\uff0c\u975e\u5e38\u7684\u53cc\u6807\uff09\u3002\u5fae\u8f6f\u5404\u79cd\u626f\u76ae\u6548\u7387\u4f4e\u4e0b\uff0cAPI \u5f04\u4e86\u4e00\u5957\u53c8\u4e00\u5957\u4e92\u76f8\u6781\u9650\u62c9\u626f\uff0c\u800c\u6211\u4eec Linux \u548c GCC \u65e9\u5df2\u9ed8\u8ba4\u5c31\u662f UTF-8\u2026\u2026 \u6211\u7406\u89e3\u4f60\u73b0\u5728\u5927\u8111\u5e72\u70e7\u7684\u5fc3\u60c5\u3002\u4f3a\u5019\u8fd9\u4e9b\u5386\u53f2\u7b54\u8fa9\u5f88\u590d\u6742\uff0c\u4e5f\u5f88\u65e0\u804a\uff0c\u6beb\u65e0\u610f\u4e49\uff01\u53ea\u662f\u4e3a\u4e86\u64e6\u53cd Unicode \u52b3\u4fdd\u7684\u5c41\u80a1\u3002","title":"\u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6"},{"location":"unicode/#_11","text":"\u5bf9\u4e8e\u8de8\u5e73\u53f0\u8f6f\u4ef6\u6765\u8bf4\uff0c\u6211\u63a8\u8350\u5927\u5bb6\u628a\u4e09\u4e2a\u5168\u90e8\u8bbe\u4e3a UTF-8\uff01\uff08\u8981\u505a\u5230\u8fd9\u4e00\u70b9\uff0c\u4e3b\u8981\u662f\u4f3a\u5019 MSVC\uff09 Linux + GCC \u7528\u6237\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u4f60\u4eec\u6240\u6709\u5b57\u7b26\u96c6\u9ed8\u8ba4\u7684\u8bbe\u5b9a\u5c31\u662f UTF-8\u3002 Windows + MSVC \u7528\u6237\u8bf7\u5f00\u542f /utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\uff0c\u73b0\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u90fd\u662f UTF-8 \u4e86\u3002 Windows + MinGW \u7528\u6237\u8bf7\u5f00\u542f -finput-charset=utf-8 \u548c -fexec-charset=utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\u3002 \u6240\u6709\u6e90\u7801\u6587\u4ef6\u7edf\u4e00\u4ee5 UTF-8 \u7f16\u7801\u4fdd\u5b58\uff0c\u4e14\u5c3d\u91cf\u5728\u6700\u524d\u9762\u52a0\u4e0a 0xFEFF \u8fd9\u4e2a BOM \u6807\u8bb0\uff0c\u9632\u6b62 MSVC \u8111\u62bd\u5f53\u4f5c GBK \u6765\u8bfb\u53d6\u3002 \u5728 main \u51fd\u6570\u524d\uff0c\u52a0\u4e24\u884c\uff1a // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 return 0; } \u8fd9\u6837\u4e00\u5957\u6253\u4e0b\u6765\uff0c\u5c31\u53ef\u4ee5\u4fdd\u8bc1\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u64cd\u4f5c\u7cfb\u7edf\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u6587\u672c\u7f16\u8f91\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u7801\uff0c\u4f60\u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u8bfb\u53d6\u6e90\u7801\uff0c\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u5b58\u50a8\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6b63\u786e\u7684\u628a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u8def\u5f84\u8f6c\u4e3a UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u3002 \u5728 CMake \u4e2d\uff0c\u53ea\u5bf9 MSVC \u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8fd9\u6837\u5199\uff1a if (MSVC) target_compile_options(\u4f60\u7684\u7a0b\u5e8f PRIVATE /utf-8) else() \u4e5f\u53ef\u4ee5\u5728\u6700\u524d\u9762 add_compile_options \uff0c\u5b9e\u73b0\u5bf9\u6240\u6709\u4e4b\u540e\u5b9a\u4e49\u7684\u7a0b\u5e8f\u5168\u5c40\u542f\u7528\u8be5\u9009\u9879\u3002 \u5728\u6211\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\uff0c\u6211\u90fd\u4f1a\u8fd9\u6837\u5f00\u542f\uff0c\u89e3\u51b3 MSVC \u4e0d\u8de8\u5e73\u53f0\u7684\u95ee\u9898\uff1a if (MSVC) add_compile_options(/Zc:preprocessor /utf-8 /DNOMINMAX /D_USE_MATH_DEFINES /EHsc /bigobj) else() if (WIN32) add_compile_options(-finput-charset=utf-8 -fexec-charset=utf-8) endif() add_compile_options(-Wall -Wextra -Werror=return-type) endif() add_executable(\u4f60\u7684\u7a0b\u5e8f \u4f60\u7684\u6587\u4ef6.cpp) # \u81ea\u52a8\u7ee7\u627f\u4e86\u4e0a\u9762\u6240\u6709\u7684\u7f16\u8bd1\u5668\u9009\u9879","title":"\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a"},{"location":"unicode/#utf-8-locale","text":"Windows \u5b98\u65b9\u63d0\u4f9b\u7684\u771f\u6b63 API \u662f _wfopen \u3002 fopen \u53ea\u662f\u4ed6\u4eec\u63d0\u4f9b\u7684\u201cPOSIX \u517c\u5bb9\u5c42\u201d \u5305\u88c5\uff0c\u5176\u4f1a\u628a\u8f93\u5165\u7684\u5b57\u7b26\u4e32\u53c2\u6570\u901a\u8fc7 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u540e\uff0c\u8f6c\u53d1\u7ed9 _wfopen \u3002 \u51fa\u4e8e\u8de8\u5e73\u53f0\u7684\u8981\u6c42\uff0c\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528 _wfopen \u8fd9\u79cd\u5176\u4ed6\u5e73\u53f0\u6ca1\u6709\u7684\u51fd\u6570\uff0c\u4e5f\u4e0d\u60f3\u7528\u90a3\u8fde 2 \u5b57\u8282 4 \u5b57\u8282\u90fd\u98d8\u5ffd\u4e0d\u5b9a\u7684 wchar_t \uff0c\u66f4\u4e0d\u60f3\u8ba9 std::string \u5b58\u6839\u672c\u4e0d\u80fd\u8de8\u5e73\u53f0\u7684 GBK\u3002 \u53ea\u8981\u8ba9 fopen \u7684 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u51fd\u6570\u66ff\u6362\u6210 \u201cUTF-8 \u5230 UTF-16\u201d \u5c31\u884c\u4e86\u3002\u8fc7\u53bb\uff0c\u6211\u4eec\u65e0\u6cd5\u66ff\u6362\uff0c\u6700\u65b0\u7684 Windows \u5728\u4e00\u6b21\u66f4\u65b0\u4e2d\uff0c\u652f\u6301\u4e86 \".utf-8\" locale \u8fd9\u4e00\u9ed1\u79d1\u6280\uff0c\u4e13\u95e8\u6ee1\u8db3\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u7684\u9700\u8981\u3002 // \u9ed8\u8ba4 locale fopen(\"\u4f60\u597d.txt\") == _wfopen(gbk_to_utf16(\"\u4f60\u597d.txt\")); // \u8bbe\u7f6e\u4e86 utf-8 locale \u540e fopen(\"\u4f60\u597d.txt\") == _wfopen(utf8_to_utf16(\"\u4f60\u597d.txt\")); \u82e5\u4e0d\u8bbe\u7f6e setlocale(LC_ALL, \".utf-8\") \uff0c\u5219 fopen \u548c ifstream \u9ed8\u8ba4\u4f1a\u628a\u4f60\u63d0\u4f9b\u7684 const char * \u6587\u4ef6\u8def\u5f84\uff0c\u5f53\u4f5c GBK \u7f16\u7801\u7684\uff0c\u800c\u6211\u4eec\u8bbe\u7f6e\u4e86 /utf-8 \u6216 -fexec-charset=utf-8 \u540e\uff0c\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u7f16\u7801\u5df2\u7ecf\u662f UTF-8 \u4e86\uff0c\u8fd9\u6837 UTF-8 \u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u8f93\u5165\u8fdb\u671f\u671b const char * \u7684 fopen \u53c2\u6570\uff0c\u5c31\u4f1a\u51fa\u4e71\u7801\u95ee\u9898\u4e86\u3002 \u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c .utf-8 locale \u53ea\u662f\u5f71\u54cd\u4e86\u6807\u51c6\u5e93\uff01\u5e76\u4e0d\u6539\u53d8\u7cfb\u7edf API\u3002 \u76f4\u63a5\u8c03\u7528\u7cfb\u7edf API \u65f6\uff0cA \u7cfb API \u4ecd\u7136\u6709\u95ee\u9898\u3002 MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u63d0\u793a\", MB_OK); // \u4e0d\u884c\uff0c.utf-8 \u53ea\u662f\u8ba9\u6807\u51c6\u5e93\u53d8\u6210 UTF-8 \u63a5\u53e3\u4e86\uff0cA \u7cfb Windows API \u4ecd\u7136\u662f GBK MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u63d0\u793a\", MB_OK); // \u6ca1\u95ee\u9898\uff01\u7528 UTF-16 \u7684 wchar_t \u5b57\u9762\u91cf\u6765\u8c03\u7528 W \u63a5\u53e3\u603b\u662f\u6ca1\u95ee\u9898\u7684 \u8fd8\u662f\u9700\u8981\u6211\u4eec\u624b\u52a8\u8f6c\u6362 UTF-8 \u5230 UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u2026\u2026\u4f46\u662f\u53cd\u6b63\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u5f88\u5c11\u9700\u8981\u76f4\u63a5\u8c03\u7528 Windows API\uff0c\u90fd\u662f\u901a\u8fc7\u901a\u7528\u7684 C/C++ \u6807\u51c6\u5e93\uff0c\u56e0\u6b64 .utf-8 locale \u53ef\u80fd\u662f\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u60f3\u8fdb\u519b UTF-8 \u7684\u6700\u4f73\u9009\u62e9\u3002","title":".utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684"},{"location":"unicode/#b-wchar_t","text":"\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\uff0c\u90fd\u662f\u9488\u5bf9 char \u7684\uff0c\u53ea\u6709 char \u88ab\u6545\u610f\u9488\u5bf9\u4e86\uff0c\u5b58\u5728\u5b57\u7b26\u7f16\u7801\u4e0d\u7edf\u4e00\u7684\u95ee\u9898\u3002 \u5982\u679c\u5168\u90e8\u7528 wchar_t \u7684\u8bdd\uff0c\u867d\u7136\u5728 Linux \u4e0a\u662f UTF-32\uff0c\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u4e0d\u7edf\u4e00\u4e86\u3002\u4f46\u81f3\u5c11\u5728\u540c\u4e00\u4e2a Windows \u64cd\u4f5c\u7cfb\u7edf\u4e0a\uff0c\u90fd\u662f\u7edf\u4e00\u7684 UTF-16\u3002 \u6240\u4ee5\u8fd8\u6709\u4e00\u79cd\u65b9\u5f0f\u662f\u5168\u9762\u91c7\u7528 wchar_t \u548c std::wstring \uff0c\u8fd9\u6837\u65e0\u8bba\u4f60\u7684\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\u5982\u4f55\uff0c\u90fd\u5bf9 wchar_t \u548c\u57fa\u4e8e const wchar_t * \u7684\u51fd\u6570\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\u3002 C \u8bed\u8a00\u6807\u51c6\u6ca1\u6709 _wfopen \uff0c\u4f46\u662f std::ifstream \u6709\u57fa\u4e8e std::wstring \u7684\u6784\u9020\u51fd\u6570\uff0c\u5c31 C++ \u6807\u51c6\u5e93\u6765\u770b std::wstring \u7684\u652f\u6301\u8fd8\u662f\u5f88\u4e30\u5bcc\u7684\uff0c\u57fa\u672c std::string \u6709\u7684 std::wstring \u90fd\u6709\uff0c\u4f8b\u5982 std::to_string \u548c std::to_wstring \uff0c std::cout \u548c std::wcout \u3002\u672c\u7ae0\u8282\u6700\u540e\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u5bbd\u5b57\u7b26\u6d41\u7684\u7528\u6cd5\u3002 \u7f3a\u70b9\u662f\uff0c\u9996\u5148\u6bcf\u6b21\u90fd\u9700\u8981\u5199 L\"\u4f60\u597d\" \u8fd9\u4e2a L \u524d\u7f00\u5f88\u9ebb\u70e6\uff0c\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u4e14\u5f88\u591a\u7b2c\u4e09\u65b9\u5e93\u90fd\u5728\u7528 std::string \uff0c\u5e76\u6ca1\u6709\u63d0\u4f9b std::wstring \u7684 API\u3002 \u4f8b\u5982 openvdb \u7684\u6587\u4ef6\u5199\u5165\u51fd\u6570\uff1a void openvdb::io::File::write(std::string const &filename); \u8fd9\u6837\u5c31\u5f88\u9ebb\u70e6\u4e86\uff0c\u5982\u679c\u4f60\u5185\u90e8\u5168\u662f UTF-16 \u7684 std::wstring \u6765\u8868\u793a\u5b57\u7b26\u4e32\uff0c\u8c03\u7528\u7b2c\u4e09\u65b9\u5e93\u524d\u5c31\u9700\u8981\u8f6c\u6210 GBK \u7684 std::string \u3002\u53ef\u4ee5\u7528 boost::locale::conv::to_utf \u8fd9\u4e2a\u51fd\u6570\u8f6c\u6362\uff0c\u4f46\u4e5f\u5f88\u9ebb\u70e6\uff0c\u800c\u4e14\u5982\u679c std::wstring \u542b\u6709 GBK \u8303\u56f4\u4e4b\u5916\u7684 \u201c\ud883\udede\u201d\uff0cGBK \u65e0\u6cd5\u8868\u793a\uff0c\u53c8\u4f1a\u6709\u7f16\u7801\u5931\u8d25\u7684\u95ee\u9898\u3002 \u8fd8\u6709 stbi_load \u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u662f\u53ea\u63d0\u4f9b\u4e86 const char * \u7684\u63a5\u53e3\uff0c\u591a\u4e86\u53bb\u4e86\u3002 setlocale(LC_ALL, \".utf-8\") \u7684\u597d\u5904\u662f\u53ef\u4ee5\u8ba9\u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u5168\u81ea\u52a8\u90fd\u4ece GBK \u65e0\u7f1d\u5207\u6362\u5230 UTF-8\uff0c\u800c\u4e0d\u7528\u5bf9\u4ed6\u4eec\u7684\u6e90\u7801\u505a\u4efb\u4f55\u66f4\u6539\u3002\u56e0\u4e3a\u4ed6\u4eec\u5185\u90e8\u90fd\u662f\u8c03\u7528\u7684 fopen \u548c ifstream \u3002","title":"\u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e"},{"location":"unicode/#u8","text":"\u4e2d\u56fd\u533a Windows\uff0cMSVC\uff0c\u7f16\u8bd1\u9009\u9879\uff1a /std:c++17 std::string s = \"\u4f60\u597d\"; hexdump(s); // C4 E3 BA C3 (GBK) std::string s = u8\"\u4f60\u597d\"; hexdump(s); // E4 BD A0 E5 A5 BD (UTF-8) u8 \u524d\u7f00\u544a\u8bc9\u7f16\u8bd1\u5668\uff0c\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u7f16\u7801\u5b58\u50a8\u3002\u65e0\u8bba\u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u662f\u4e0d\u662f UTF-8\u3002 \u7f16\u8bd1\u5668\u4fdd\u8bc1\u4f1a\u628a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u8f6c\u6362\u4e3a UTF-8 \u7f16\u7801\u7684 char \u5b57\u8282\u5e8f\u5217\uff0c\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u533a\u3002 \u8fd9\u5bf9\u4e8e\u5df2\u7ecf\u8bbe\u7f6e\u4e86 /utf-8 \u9009\u9879\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u5df2\u7ecf\u4fdd\u8bc1\u662f UTF-8 \u7684\u6211\u4eec\u6765\u8bf4\u6beb\u65e0\u4f5c\u7528\u3002\u53ea\u662f\u5bf9\u4e8e\u4e0d\u7528 /utf-8 \u7684\u540c\u5b66\uff0c\u4ed6\u4eec\u60f3\u8981\u4e34\u65f6\u521b\u5efa\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5c31\u53ef\u4ee5\u7528 u8 \u524d\u7f00\u3002 \u5728 C++17 \u548c\u4e4b\u524d\uff0c u8\"\u4f60\u597d\" \u4ea7\u751f\u7684\u662f const char [] \u7c7b\u578b\u7684\u5e38\u91cf\u3002 \u5728 C++20 \u4e2d\uff0c\u5f15\u5165\u4e86 char8_t \u3002\u7136\u540e\uff0c\u4ed6\u4eec\u89c4\u5b9a\uff0c u8\"\u4f60\u597d\" \u73b0\u5728\u4ea7\u751f\u7684\u662f const char8_t [] \u7c7b\u578b\u7684\u5e38\u91cf\u4e86\u3002 \u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u517c\u5bb9\u6027\u95ee\u9898\uff0c\u6bd4\u5982\u4ee5\u524d\u4f60\u5199\u7684\uff1a std::string s = u8\"\u4f60\u597d\"; \u73b0\u5728\u65e0\u6cd5\u7f16\u8bd1\u901a\u8fc7\u4e86\uff0c\u56e0\u4e3a const char8_t [] \u65e0\u6cd5\u7528\u4e8e\u6784\u9020\u53ea\u652f\u6301 const char [] \u7684 std::string \u3002 \u597d\u5728 C++23 \u53c8\u4fee\u590d\u4e86\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u4eec\u5141\u8bb8 const char8_t [] \u9690\u5f0f\u8f6c\u6362\u4e3a const char [] \uff0cC++17 \u4e4b\u524d\u7684\u8fd9\u79cd\u4ee3\u7801\u53c8\u80fd\u6b63\u5e38\u901a\u8fc7\u7f16\u8bd1\u3002\u6240\u4ee5\uff0c\u5982\u679c\u60f3\u5feb\u4e50\u5730\u7528 u8 \u5b57\u9762\u91cf\uff0c\u8981\u4e48 C++17\uff0c\u8981\u4e48 C++23\uff0c\u8df3\u8fc7 C++20 \u6bd4\u8f83\u597d\u3002 \u4f60\u53ef\u4ee5\u770b\u5230\uff0cC++ \u7248\u672c\u7684\u66f4\u65b0\u5e76\u4e0d\u662f 100% \u5b8c\u5168\u5411\u524d\u517c\u5bb9\u7684\uff0c\u6709\u65f6\u4e5f\u4f1a\u6709\u7834\u574f\u6027\u7684\u53d8\u66f4\uff0c\u4f46\u6bd4\u8f83\u5c11\uff0c\u5e73\u65f6\u611f\u89c9\u4e0d\u5230\u3002\u6bd4\u5982 C++11 \u4e4b\u524d auto \u5c31\u6709\u5176\u4ed6\u7684\u529f\u80fd\uff0c\u540e\u6765\u51b3\u5b9a\u8fd9\u4e2a\u529f\u80fd\u6ca1\u4ec0\u4e48\u7528\uff0c\u5c31\u628a auto \u6539\u6210\u53e6\u4e00\u4e2a\u610f\u601d\u4e86\u3002 \u9664\u4e86 u8 \u4ee5\u5916\uff0c\u8fd8\u6709\u8fd9\u4e9b\uff1a \u524d\u7f00 \u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u201c\u4f60\u597d\u201d \u8fd0\u884c\u5b57\u7b26\u96c6 (\u9ed8\u8ba4\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7684) const char [] L\u201d\u4f60\u597d\u201d Windows \u4e0a UTF-16\uff1bLinux \u4e0a UTF-32 const wchar_t [] u8\u201d\u4f60\u597d\u201d UTF-8 const char8_t [] u\u201d\u4f60\u597d\u201d UTF-16 const char16_t [] U\u201d\u4f60\u597d\u201d UTF-32 const char32_t [] \u53ea\u4e0d\u8fc7\u662f\u5f00\u53d1\u8005\u548c\u5ba2\u6237\u5f80\u5f80\u5904\u4e8e\u540c\u4e00\u4e2a\u5730\u533a\uff0c\u6240\u4ee5 \"\u4f60\u597d\" \u770b\u8d77\u6765\u597d\u50cf\u53ef\u4ee5\u76f4\u63a5\u8f93\u5165\u5230 std::cout \u4e2d\u4e00\u6837\u3002\u5b9e\u9645\u4e0a\u4ed6\u53ea\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684 ANSI\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7535\u8111\u7684 ANSI\uff0c\u5982\u679c\u76f4\u63a5\u62ff\u6765\u6253\u5370\uff0c\u4f1a\u5bfc\u81f4\u4ee5 \"\" \u5e38\u91cf\u5f62\u5f0f\u5199\u6b7b\u7684\u5b57\u7b26\u4e32\u4f1a\u5728\u5ba2\u6237\u7535\u8111\u4e0a\u51fa\u73b0\u4e71\u7801\u3002\u9664\u975e\u8fd9\u4e2a\u5b57\u7b26\u4e32\u53ea\u5305\u542b ASCII\uff0c\u56e0\u4e3a\u6240\u6709 ANSI \u90fd\u517c\u5bb9 ASCII\uff0c\u624d\u6070\u597d\u907f\u514d\u4e86\u4e71\u7801\u3002","title":"u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528"},{"location":"unicode/#_12","text":"","title":"\u9009\u62e9\u4f60\u7684\u9635\u8425\uff01"},{"location":"unicode/#ansi","text":"\u628a\u5b57\u7b26\u4e32\u5f53\u4f5c\u7eaf\u7cb9\u7684\u201c\u5b57\u8282\u6d41\u201d\uff0c\u65e0\u89c6\u5b57\u7b26\u7f16\u7801\u3002\u6216\u8005\u8bf4\uff0c\u4f60\u4ece\u7cfb\u7edf\u8f93\u5165\u8fdb\u6765\u7684\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u6211\u5c31\u5b58\u50a8\u7684\u4ec0\u4e48\u7f16\u7801\u3002\u5bf9\u4e8e Unicode \u5219\u91c7\u53d6\u5b8c\u5168\u6446\u70c2\u7684\u6001\u5ea6\uff0c\u5b8c\u5168\u65e0\u89c6 Unicode \u7684\u5b58\u5728\u3002 \u9002\u7528\u573a\u666f\uff1a\u901a\u5e38\u4e0e\u6587\u5b57\u5904\u7406\u9886\u57df\u65e0\u5173\u7684\u8f6f\u4ef6\u4f1a\u91c7\u53d6\u8fd9\u79cd\u65b9\u6848\u3002 \u4f18\u70b9\uff1a\u65b9\u4fbf\uff0c\u4e14\u5185\u90e8\u5bf9\u5b57\u7b26\u4e32\u65e0\u4efb\u4f55\u8f6c\u6362\u548c\u5224\u65ad\uff0c\u6548\u7387\u6700\u9ad8\u3002 \u7f3a\u70b9\uff1a\u5728\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u8bfb\u5199\u5e26\u6709\u4e2d\u6587\u7684\u6587\u4ef6\u8def\u5f84\u65f6\uff0c\u4f1a\u9971\u53d7\u4e71\u7801\u548c\u627e\u4e0d\u5230\u6587\u4ef6\u7684\u56f0\u6270\u3002 \u65b9\u6cd5\uff1a\u5b8c\u5168\u4f7f\u7528 const char * \u548c std::string \u3002 \u4ee3\u8868\u4f5c\uff1aLinux \u6587\u4ef6\u7cfb\u7edf ext4\u3001Lua \u7f16\u7a0b\u8bed\u8a00\u3001\u73b0\u4ee3 Python \u4e2d\u7684 bytes \u7c7b\u578b\u3001HTTP \u7684 ? \u53c2\u6570\u3001\u65e9\u671f FAT32 \u6587\u4ef6\u7cfb\u7edf\u7b49\u3002 \u8fd9\u7c7b\u8f6f\u4ef6\u662f\u6700\u5e38\u89c1\u7684\u521d\u5b66\u8005\u5199\u6cd5\uff0c\u5982\u679c\u4f60\u4ece\u672a\u60f3\u8fc7\u5b57\u7b26\u7f16\u7801\u95ee\u9898\uff0c\u4ece\u4e0d\u4e86\u89e3 wchar_t \u3001 char32_t \u4e4b\u95f4\u7684\u6218\u4e89\uff0c\u53ea\u77e5\u9053 char \uff0c\u90a3\u4e48\u4f60\u5df2\u7ecf\u81ea\u52a8\u5728\u6b64\u9635\u8425\u91cc\u3002 \u6709\u4eba\u8bf4 Linux \u6587\u4ef6\u7cfb\u7edf\u662f UTF-8\uff1f\u5e76\u4e0d\u662f\uff01Linux \u6587\u4ef6\u7cfb\u7edf\u6839\u672c\u4e0d\u4f1a\u68c0\u9a8c\u4f60\u7684\u6587\u4ef6\u540d\u662f\u4e0d\u662f\u5408\u6cd5\u7684 UTF-8\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u4f60\u8bbe\u5b9a\u4e86 export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u4f1a\u4f7f\u6240\u6709\u7a0b\u5e8f\uff08\u5305\u62ec\u7ec8\u7aef\u6a21\u62df\u5668\uff09\u5047\u5b9a\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u5185\u5bb9\u90fd\u6309 UTF-8 \u7f16\u7801\uff0c\u4ece\u800c\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u5404\u7c7b API \u65f6\uff08\u5982 open\u3001write\uff09\u90fd\u4f1a\u4f7f\u7528 UTF-8 \u7f16\u7801\u7684 const char * \u8f93\u5165\uff0c\u5728 Linux \u7cfb\u7edf API \u770b\u6765\uff0c\u6240\u8c13\u201c\u6587\u4ef6\u540d\u201d\u53ea\u662f\u7eaf\u7cb9\u7684\u5b57\u8282\u6d41\uff0c\u53ea\u8981\u4fdd\u8bc1\u4e0d\u5305\u542b '/' \u548c '\\0' \uff0c\u65e0\u8bba\u4f60\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4ed6\u90fd\u4e0d\u5728\u4e4e\u3002\u800c\u6240\u6709\u7684 locale \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u7edd\u4e0d\u4f1a\u51fa\u73b0\u4e00\u4e2a\u4e2d\u6587\u6c49\u5b57\u7f16\u7801\u540e\u4ea7\u751f '/' \u7684\u60c5\u51b5\uff08\u4f8b\u5982 GB2312 \u4f1a\u628a\u4e00\u4e2a\u4e2d\u6587\u7f16\u7801\u6210\u4e24\u4e2a 0x80 \u5230 0xFF \u533a\u95f4\u7684\u5b57\u8282\uff0c\u548c ASCII \u7684\u8303\u56f4\u6ca1\u6709\u91cd\u53e0\uff0c\u66f4\u4e0d\u53ef\u80fd\u51fa\u73b0 '/' \uff09\uff0c\u5373\u4f7f\u6362\u6210 export LC_ALL=zh_CN.GB2312 \uff0cLinux \u6587\u4ef6\u7cfb\u7edf\u4e00\u6837\u80fd\u6b63\u5e38\u5de5\u4f5c\uff0c\u53ea\u4e0d\u8fc7\u8bfb\u53d6\u4f60\u4e4b\u524d\u4ee5 UTF-8 \u5199\u5165\u7684\u6587\u4ef6\u4f1a\u53d8\u6210\u4e71\u7801\u800c\u5df2\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a\u7684 Windows \u800c\u8a00\uff0c\u4ed6\u7684\u6240\u6709 A \u51fd\u6570\u53ea\u652f\u6301 GBK \u7f16\u7801\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u4f60 Lua \u4e2d\u628a\u5b57\u7b26\u4e32\u201c\u5f53\u4f5c\u201d UTF-8 \u6765\u7528\u3002\u90a3\u4e48\u5f53\u4f60\u5728\u8c03\u7528 Lua \u7684 io.open \u524d\uff0c\u9700\u8981\u5148\u505a\u4e00\u4e2a UTF-8 \u5230 GBK \u7684\u8f6c\u6362\uff0c\u8fd9\u8fd8\u4f1a\u5bfc\u81f4\u4e22\u5931\u90e8\u5206\u4e0d\u5728 GBK \u5185\u7684\u5b57\u7b26\uff0c\u6bd4\u5982\u5982\u679c\u4f60\u7684\u6587\u4ef6\u540d\u5305\u542b Emoji\uff0c\u90a3\u5c31\u4f1a\u53d8\u6210 ??? \u4e71\u7801\u3002\u800c\u4f7f\u7528 W \u51fd\u6570\u7684 UTF-16 \u5c31\u4e0d\u4f1a\uff0c\u56e0\u4e3a UTF-16 \u80fd\u5bb9\u7eb3\u5b8c\u6574\u7684 Unicode \u6620\u5c04\u3002\u800c\u5b8c\u5168\u6446\u70c2\u7684 Lua\uff0c\u5176 io.open \u53ea\u662f\u4f7f\u7528 C \u8bed\u8a00\u5e93\u51fd\u6570 fopen \uff0c fopen \u53c8\u662f\u57fa\u4e8e Windows \u7684 A \u7cfb\u5217\u51fd\u6570\uff0cLua \u53c8\u6ca1\u6709\u63d0\u4f9b\u5bf9 Windows C \u8fd0\u884c\u65f6\u5e93\u7279\u6709\u7684 _wfopen \u51fd\u6570\u7684\u5c01\u88c5\uff0c\u4ece\u800c\u6c38\u8fdc\u4e0d\u53ef\u80fd\u6253\u5f00\u4e00\u4e2a\u5e26\u6709 Emoji \u7684\u6587\u4ef6\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 ANSI \u9635\u8425\uff0c\u4f60\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0cchar \u6ee1\u5929\u98de\u6446\u70c2\u3002","title":"ANSI \u9635\u8425"},{"location":"unicode/#utf-8_3","text":"\u652f\u6301 Unicode\uff0c\u5b57\u7b26\u4e32\u7edf\u4e00\u4ee5 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u3001\u5904\u7406\u548c\u4f20\u8f93\u3002 \u5e94\u7528\u573a\u666f\uff1a\u5e38\u89c1\u4e8e\u6587\u5b57\u5904\u7406\u9700\u6c42\u4e0d\u5927\uff0c\u4f46\u6709\u5f3a\u70c8\u7684\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u7279\u522b\u662f\u4e92\u8054\u7f51\u65b9\u9762\u7684\u8f6f\u4ef6\u3002\u4ed6\u4eec\u901a\u5e38\u53ea\u7528\u5230\u5b57\u7b26\u4e32\u7684\u62fc\u63a5\u3001\u67e5\u627e\u3001\u5207\u7247\u901a\u5e38\u4e5f\u53ea\u662f\u5728\u56fa\u5b9a\u7684\u4f4d\u7f6e\uff08\u4f8b\u5982\u6587\u4ef6\u5206\u9694\u7b26 '/' \uff09\u3002\u4e5f\u975e\u5e38\u9002\u5408\u4e3b\u8981\u9762\u5bf9\u7684\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0cUTF-8 \u662f\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u6700\u9ad8\u7684\uff0c\u6240\u4ee5\u4e5f\u5e7f\u6cdb\u7528\u4e8e\u7f16\u8bd1\u5668\u3001\u6570\u636e\u5e93\u4e4b\u7c7b\u7684\u573a\u666f\u3002\u540c\u65f6\u56e0\u4e3a UTF-8 \u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u4f7f\u5f97\u4ed6\u80fd\u8f7b\u6613\u9002\u914d\u8fdc\u53e4\u7684 C \u8bed\u8a00\u7a0b\u5e8f\u548c\u5e93\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-8 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8de8\u5e73\u53f0\uff0c\u5728\u7f51\u7edc\u4f20\u8f93\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u7801\uff0cUTF-8 \u662f\u4e92\u8054\u7f51\u7684\u4e3b\u6d41\u7f16\u7801\u683c\u5f0f\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a\u8fd0\u884c\u7684 UTF-8 \u8f6f\u4ef6\u53ef\u4ee5\u968f\u610f\u5171\u4eab\u6587\u672c\u6570\u636e\u3002\u517c\u5bb9 ASCII\uff0c\u65b9\u4fbf\u590d\u7528\u73b0\u6709\u5e93\u548c\u751f\u6001\u3002\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u9ad8\uff0c\u5bf9\u4e2d\u6587\u6587\u672c\u4e5f\u4e0d\u7b97\u592a\u5dee\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e\u5e95\u5c42 API \u5747\u91c7\u7528 UTF-16 \u7684 Windows \u7cfb\u7edf\uff0c\u9700\u8981\u8fdb\u884c\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u635f\u5931\u3002\u4e14\u5b57\u7b26\u4e32\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4f1a\u53d8\u6210 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002 \u4ee3\u8868\u4f5c\uff1aRust \u8bed\u8a00\u3001Go \u8bed\u8a00\u3001CMake \u6784\u5efa\u7cfb\u7edf\u3001Julia \u8bed\u8a00\u7b49\u3002 \u5728 C++ \u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7 u8\"\u4f60\u597d\" \u521b\u5efa\u4e00\u4e2a\u4fdd\u8bc1\u5185\u90e8\u662f UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u7c7b\u578b\u4e3a char8_t [] \u3002 \u5982\u679c\u7528\u65e0\u524d\u7f00\u7684 \"\u4f60\u597d\" \u521b\u5efa\uff0c\u5219 MSVC \u9ed8\u8ba4\u4f1a\u4ee5\u7f16\u8bd1\u8005\u6240\u5728\u7cfb\u7edf\u7684\u201c\u533a\u57df\u8bbe\u7f6e (locale)\u201d \u4f5c\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7f16\u7801\u683c\u5f0f\uff08\u800c\u4e0d\u662f\u8fd0\u884c\u8005\u7684\u533a\u57df\u8bbe\u7f6e\uff01\uff09\uff0c\u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8ba9 MSVC \u7f16\u8bd1\u5668\u9ed8\u8ba4\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u5373\u8ba9 \"\u4f60\u597d\" \u548c u8\"\u4f60\u597d\" \u4e00\u6837\u91c7\u7528 UTF-8\u3002\u800c GCC \u9ed8\u8ba4\u5c31\u662f UTF-8\uff0c\u9664\u975e\u624b\u52a8\u6307\u5b9a -fexec-charset=GBK \u6765\u5207\u6362\u5230 GBK\u3002\u7a0d\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u7f16\u8bd1\u5668\u7684\u5b57\u7b26\u7f16\u7801\u95ee\u9898\u3002 \u5047\u8bbe\u4f60\u901a\u8fc7 /utf-8 \u6216 -fexec-charset=utf-8 \u641e\u5b9a\u4e86\u7f16\u8bd1\u671f\u5e38\u91cf\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u3002\u63a5\u4e0b\u6765\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u6587\u4ef6\u7cfb\u7edf\u3002 Linux \u6587\u4ef6\u7cfb\u7edf\u5185\u90e8\uff0c\u5747\u4f7f\u7528 8 \u4f4d\u7c7b\u578b char \u5b58\u50a8\uff0c\u5c06\u6587\u4ef6\u540d\u5f53\u4f5c\u5e73\u51e1\u7684\u5b57\u8282\u6d41\uff0c\u4e0d\u4f1a\u505a\u4efb\u4f55\u8f6c\u6362\u3002\u56e0\u6b64\u4f60\u7528 UTF-8 \u521b\u5efa\u548c\u6253\u5f00\u7684\u6587\u4ef6\uff0c\u5176\u4ed6\u4f7f\u7528 UTF-8 \u533a\u57df\u8bbe\u7f6e\u7684\u8f6f\u4ef6\u90fd\u53ef\u4ee5\u7167\u5e38\u6253\u5f00\uff0c\u4e0d\u4f1a\u6709\u4e71\u7801\u95ee\u9898\u3002 \u5176\u5b9e Windows \u4e0a\u4ee5 GBK \u7f16\u7801\u7684\u538b\u7f29\u6587\u4ef6\u6216\u6587\u672c\u6587\u4ef6\uff0c\u62f7\u8d1d\u5230 Linux \u4e0a\u6253\u5f00\u51fa\u73b0\u4e71\u7801\u95ee\u9898\uff0c\u5c31\u662f\u56e0\u4e3a Linux \u7684\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u90fd\u662f UTF-8 \u7684\u3002\u5b9e\u9645\u4e0a\u5982\u679c\u628a\u4f60\u7684\u6587\u4ef6\u62f7\u7ed9\u4e00\u4e2a\u7f8e\u56fd\u7684 Windows \u7528\u6237\uff0c\u4ed6\u4e5f\u4f1a\u770b\u5230\u4e71\u7801\uff0c\u56e0\u4e3a\u7f8e\u56fd\u5927\u533a\u7684 Windows \u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\uff0c\u800c\u4e2d\u56fd\u5927\u533a\u7684\u662f GBK\uff0c\u7a0d\u540e\u6211\u4eec\u4f1a\u8bb2\u5230\u89e3\u51b3\u65b9\u6848\u3002 \u800c Windows \u7684 NTFS \u6587\u4ef6\u7cfb\u7edf\uff0c\u91c7\u7528 16 \u4f4d\u7684 wchar_t \u5b58\u50a8\uff0cWindows \u7684\u6240\u6709 API\uff0c\u4e5f\u90fd\u662f\u57fa\u4e8e wchar_t \u7684\uff0cWindows \u5185\u6838\u5185\u90e8\u4e5f\u90fd\u7528 wchar_t \u50a8\u5b58\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u53ea\u6709\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6d41\u4f1a\u7528 char \u5b58\u50a8\u3002\u8fd9\u7c7b\u57fa\u4e8e wchar_t \u7684\u7cfb\u7edf API \u90fd\u6709\u4e00\u4e2a W \u540e\u7f00\uff0c\u4f8b\u5982\uff1a MessageBoxW(NULL, L\"\u4f60\u597d\", L\"\u6807\u9898\", MB_OK); \u8fd9\u4e2a MessageBoxW \u51fd\u6570\uff0c\u53ea\u63a5\u53d7 const wchar_t * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 L\"\u4f60\u597d\" \u662f\u4e00\u4e2a wchar_t [] \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5b83\u7684\u5185\u90e8\u7f16\u7801\u7c7b\u578b\u56fa\u5b9a\u662f UTF-16\uff0c\u4e0d\u4f1a\u968f\u7740\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002\u4e4b\u540e\u7684\u4e00\u8282\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3 W \u548c A \u51fd\u6570\u7684\u95ee\u9898\u3002 \u867d\u7136\u4e5f\u6709\u63d0\u4f9b A \u540e\u7f00\u7684\u7cfb\u5217\u51fd\u6570\uff0c\u4ed6\u4eec\u548c W \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u63a5\u53d7 const char * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002\u95ee\u9898\u5728\u4e8e\uff0c\u8fd9\u4e9b\u5b57\u7b26\u4e32\u90fd\u5fc5\u987b\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u4e5f\u5c31\u662f GBK \u7f16\u7801\uff01\u800c\u4e14\u65e0\u6cd5\u4fee\u6539\u3002 \u5f53\u8c03\u7528 A \u7cfb\u51fd\u6570\u65f6\uff0c\u4ed6\u4eec\u5185\u90e8\u4f1a\u628a GBK \u7f16\u7801\u8f6c\u6362\u4e3a UTF-16 \u7f16\u7801\uff0c\u7136\u540e\u8c03\u7528 Windows \u5185\u6838\u3002 \u8fd9\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\uff0c\u800c\u6240\u6709\u7684 C/C++ \u6807\u51c6\u5e93\u90fd\u662f\u57fa\u4e8e A \u51fd\u6570\u7684\uff01\u5982\u679c\u4f60\u7528 const char * \u5b57\u7b26\u4e32\u8c03\u7528 C \u6807\u51c6\u5e93\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u4e86 A \u51fd\u6570\u3002\u800c A \u51fd\u6570\u53ea\u63a5\u53d7 GBK\uff0c\u4f46\u4f60\u5374\u8f93\u5165\u4e86 UTF-8\uff01\u4ece\u800c UTF-8 \u4e2d\u6240\u6709\u9664 ASCII \u4ee5\u5916\u7684\uff0c\u5404\u79cd\u4e2d\u6587\u5b57\u7b26\u3001Emoji \u90fd\u4f1a\u53d8\u6210\u4e71\u7801\u3002 \u4f8b\u5982 fopen \u51fd\u6570\uff0c\u53ea\u6709 fopen(const char *path, const char *mode) \u8fd9\u4e00\u4e2a\u57fa\u4e8e char \u7684\u7248\u672c\uff0c\u91cc\u9762\u4e5f\u662f\u76f4\u63a5\u8c03\u7528\u7684 A \u51fd\u6570\uff0c\u5b8c\u5168\u4e0d\u7ed9\u6211\u9009\u62e9\u7684\u7a7a\u95f4\u3002\u867d\u7136 Windows \u4e5f\u63d0\u4f9b\u4e86 _wfopen(const wchar_t *path, const wchar_t *mode) \uff0c\u4f46\u90a3\u65e2\u4e0d\u662f POSIX \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f C \u8bed\u8a00\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f7f\u7528\u8fd9\u6837\u7684\u51fd\u6570\u5c31\u610f\u5473\u7740\u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 Windows \u5b98\u65b9\u8ba4\u4e3a\uff1a W \u51fd\u6570\u624d\u662f\u771f\u6b63\u7684 API\uff0c A \u51fd\u6570\u53ea\u662f\u5e94\u4ed8\u4e0d\u542c\u8bdd\u7684\u5b9d\u5b9d\u3002\u53ef\u4f60\u5c31\u6ca1\u53d1\u73b0\u4f60\u81ea\u5df1\u7684 C/C++ \u6807\u51c6\u5e93\u4e5f\u5168\u90e8\u5728\u8c03\u7528\u7684 A \u51fd\u6570\u4e48\uff1f \u603b\u4e4b\uff0c A \u51fd\u6570\u662f\u6b8b\u5e9f\u7684\uff0c\u6211\u4eec\u53ea\u80fd\u7528 W \u51fd\u6570\uff0c\u5c3d\u7ba1 UTF-16 \u662f\u5386\u53f2\u503a\uff0c\u4f46\u6211\u4eec\u522b\u65e0\u9009\u62e9\uff0c W \u51fd\u6570\u662f\u552f\u4e00\u80fd\u652f\u6301\u5b8c\u6574 Unicode \u5b57\u7b26\u8f93\u5165\u7684\u65b9\u5f0f\u3002 // \u5047\u8bbe\u8fd9\u6bb5 C++ \u4ee3\u7801\u4f7f\u7528 /utf-8 \u9009\u9879\u7f16\u8bd1\uff1a std::ifstream f(\"\u4f60\u597d.txt\"); // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5373\u4f7f\u201c\u4f60\u597d.txt\u201d\u5b58\u5728 std::ofstream f(\"\u4f60\u597d.txt\"); // \u4f1a\u521b\u5efa\u4e00\u4e2a\u4e71\u7801\u6587\u4ef6 \u6b63\u786e\u7684\u505a\u6cd5\u662f\u91c7\u7528 std::filesystem::u8path \u8fd9\u4e2a\u51fd\u6570\u505a UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\uff1a // C++17\uff0c\u9700\u8981\u7528 u8path \u8fd9\u4e2a\u51fd\u6570\u6784\u9020 path \u5bf9\u8c61\uff1a std::ifstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); // C++20 \u5f15\u5165 char8_t\uff0c\u533a\u5206\u4e8e\u666e\u901a char\uff0cpath \u7c7b\u4e5f\u6709\u4e86\u9488\u5bf9 const char8_t * \u7684\u6784\u9020\u51fd\u6570\u91cd\u8f7d\uff1a std::ifstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::filesystem::path \u7c7b\u7684 c_str() \u5728 Windows \u4e0a\u8fd4\u56de const wchar_t * \uff0c\u5728 Linux \u4e0a\u8fd4\u56de const char * \u3002\u8fd9\u5f88\u5408\u7406\uff0c\u56e0\u4e3a Windows \u6587\u4ef6\u7cfb\u7edf\u786e\u5b9e\u4ee5 wchar_t \u5b58\u50a8\u8def\u5f84\u540d\uff0c\u800c Linux \u6587\u4ef6\u7cfb\u7edf\u5b8c\u5168\u7528 char \u3002 \u6bcf\u6b21\u9700\u8981\u52a0 std::filesystem::u8path \u4e5f\u633a\u9ebb\u70e6\u7684\uff0c\u5bb9\u6613\u5fd8\u8bb0\uff0c\u4e00\u5fd8\u8bb0\u5c31\u65e0\u6cd5\u8bbf\u95ee\u4e2d\u6587\u76ee\u5f55\u3002 \u5f88\u591a\u8f6f\u4ef6\u5728 Windows \u4e0a\u65e0\u6cd5\u652f\u6301\u4e2d\u6587\u8def\u5f84\u540d\uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u4eec\u4e60\u60ef\u4e86 Linux \u6216 MacOS \u7684\u5168 UTF-8 \u73af\u5883\uff0c\u5bf9\u6587\u4ef6\u8def\u5f84\u6ca1\u6709\u4efb\u4f55\u8f6c\u6362\u3002\u800c Windows \u5e95\u5c42\u5168\u662f UTF-16\uff0c\u6839\u672c\u6ca1\u6709\u63d0\u4f9b UTF-8 \u7684 API\uff0c\u4f60 UTF-8 \u53ea\u80fd\u8f6c\u6362\u6210 UTF-16 \u624d\u80fd\u907f\u514d\u4e2d\u6587\u4e71\u7801\u3002\u4e2a\u4eba\u8ba4\u4e3a\uff0c\u6b7b\u6d3b\u4e0d\u80af\u63a5\u53d7\u660e\u6446\u7740\u5df2\u7ecf\u662f\u56fd\u9645\u901a\u7528\u6807\u51c6\u7684 UTF-8\uff0cA \u51fd\u6570\u7684\u7f16\u7801\u8fde\u5f53\u524d\u8fdb\u7a0b\u5207\u6362\u7684\u65b9\u6cd5\u90fd\u4e0d\u7ed9\u4e00\u4e2a\uff0c\u8fd9\u4e2a\u5e94\u8be5\u7531 Windows \u5168\u8d23\u627f\u62c5\u3002 \u597d\u6d88\u606f\u662f\uff0c\u6700\u8fd1 MSVC \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u4e00\u79cd\u65b9\u6848\uff0c\u5728\u4f60\u7684\u7a0b\u5e8f\u5f00\u5934\uff0c\u52a0\u4e0a setlocale(LC_ALL, \".utf-8\") \u5c31\u53ef\u4ee5\u8ba9 C \u548c C++ \u6807\u51c6\u5e93\u8fdb\u5165 UTF-8 \u6a21\u5f0f\uff1a\u4e0d\u518d\u8c03\u7528 A \u7cfb\u51fd\u6570\u64cd\u4f5c\u6587\u4ef6\uff0c\u800c\u662f\u4f1a\u628a\u6587\u4ef6\u540d\u4ece UTF-8 \u8f6c\u6362\u6210 UTF-16 \u540e\u518d\u8c03\u7528\u771f\u6b63\u7a33\u5b9a\u7684 W \u7cfb\u51fd\u6570\u3002 setlocale(LC_ALL, \".utf-8\"); // \u53ea\u9700\u8981\u8fd9\u4e00\u884c FILE *fp = fopen(u8\"\u4f60\u597d.txt\", \"r\"); // \u53ef\u4ee5\u4e86 std::ifstream fin(u8\"\u4f60\u597d.txt\"); // \u53ef\u4ee5\u4e86 setlocale(LC_ALL, \".utf-8\"); \u53ea\u662f\u628a C \u6807\u51c6\u5e93\u7684 const char * \u53c2\u6570\u53d8\u6210\u4e86\u63a5\u53d7 UTF-8\uff0c\u5e76\u4e0d\u4f1a\u8ba9\u7cfb\u7edf\u7684 A \u51fd\u6570\u4e5f\u53d8\u6210 UTF-8 \u54e6\uff0c\u8c03\u7528\u672c\u5730 API \u65f6\u4ecd\u9700 UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-8 \u9635\u8425\uff0c\u5f00\u542f /utf-8 \uff0c\u7a0b\u5e8f\u5f00\u5934\u5199 setlocale(LC_ALL, \".utf-8\") \u3002Linux \u7528\u6237\u5219\u4ec0\u4e48\u90fd\u4e0d\u7528\u505a\u3002 \u770b\u770b\u5404\u5927\u8f6f\u4ef6\u7ad9\u5728 UTF-8 \u9635\u8425\u7684\u7406\u7531\uff1a CMake\uff1a\u4f5c\u4e3a\u8de8\u5e73\u53f0\u7684\u6784\u5efa\u7cfb\u7edf\uff0c\u4e3a\u4e86\u8ba9\u9879\u76ee\u7684 CMakeLists.txt \u80fd\u8de8\u5e73\u53f0\u5171\u7528\u800c\u4e0d\u5fc5\u91cd\u5199\uff0c\u4ed6\u7406\u6240\u5f53\u7136\u5730\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\uff1a\u6240\u6709 CMakeLists.txt \u90fd\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u4e66\u5199\uff0c\u4e14\u7edf\u4e00\u4f7f\u7528\u6b63\u659c\u6760 '/' \u8def\u5f84\u5206\u9694\u7b26\u3002 CMake \u4f1a\u81ea\u52a8\u5728 Windows \u7cfb\u7edf\u4e0a\uff0c\u5c06 UTF-8 \u5b57\u7b26\u4e32\u8f6c\u6362\u6210 UTF-16 \u540e\uff0c\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u5728 Linux \u7cfb\u7edf\u4e0a\u5219\u4e0d\u505a\u8f6c\u6362\u3002\u5728 Windows \u7cfb\u7edf\u4e0a\u8fd8\u4f1a\u81ea\u52a8\u628a\u6587\u4ef6\u8def\u5f84\u4e2d\u7684\u6b63\u659c\u6760 '/' \u8f6c\u6362\u6210 Windows \u4e13\u5c5e\u7684\u53cd\u659c\u6760 '\\\\' \uff0c\u65e0\u9700\u7528\u6237\u64cd\u5fc3\u3002 \u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u8282\u70b9\u4eff\u771f\u8f6f\u4ef6\uff1a\u7531\u4e8e\u4fdd\u5b58\u7684\u9879\u76ee\u5de5\u7a0b\u6587\u4ef6\u9700\u8981\u5728 Linux \u548c Windows \u5e73\u53f0\u4e0a\u4e92\u901a\uff0c\u4e0d\u80fd\u91c7\u7528 Windows \u5404\u81ea\u4e3a\u653f\u7684 GBK \u683c\u5f0f\uff0c\u4e14\u5de5\u7a0b\u6587\u4ef6\u5185\u5bb9\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\u4e2d\u3002 Rust \u548c Go\uff1a\u4e25\u683c\u533a\u5206\u201c\u5b57\u7b26 (32 \u4f4d)\u201d\u548c\u201c\u5b57\u8282 (8 \u4f4d)\u201d\u7684\u6982\u5ff5\u3002\u5728\u5b57\u7b26\u4e32\u7c7b\u578b\u4e2d\u5b58\u50a8\u5b57\u8282\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u4ee5\u5b57\u8282\u65b9\u5f0f\u8bfb\u53d6\u6216\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-8 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5904\u7406\u5207\u7247\u548c\u7d22\u5f15\u65f6\u4e0d\u65b9\u4fbf\u3002 \u7f16\u7a0b\u8bed\u8a00 \u5b57\u7b26\u7c7b\u578b (32 \u4f4d) \u5b57\u8282\u7c7b\u578b (8 \u4f4d) Rust char u8 Go rune byte Julia Char UInt8 \u4e3a\u6b64\uff0c\u8fd9\u4e9b\u8bed\u8a00\u90fd\u4e3a\u5b57\u7b26\u4e32\u63d0\u4f9b\u4e86\u4e24\u5957 API\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u8282\u7d22\u5f15\u3002\u6309\u5b57\u7b26\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ece\u5934\u5f00\u59cb\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\uff0c\u76f4\u5230\u89e3\u6790\u5230\u60f3\u8981\u7684\u5b57\u7b26\u4e3a\u6b62\uff0c\u590d\u6742\u5ea6 O(N) O(N) \u3002\u6309\u5b57\u8282\u7d22\u5f15\u65f6\uff0c\u76f4\u63a5\u8df3\u5230\u6307\u5b9a\u5b57\u8282\uff0c\u65e0\u9700\u89e3\u6790\uff0c\u590d\u6742\u5ea6 O(1) O(1) \u3002 let s = \"\u4f60\u597d\"; // \u6309\u5b57\u7b26\u904d\u5386 for c in s.chars() { // c: char println!(\"{}\", c); } // \u6309\u5b57\u8282\u904d\u5386 for b in s.bytes() { // b: u8 println!(\"{:02x}\", b); } \u5728 C++ \u4e2d\uff0c\u82e5\u8981\u91c7\u7528\u8fd9\u79cd UTF-8 \u65b9\u6848\uff0c\u53ef\u4ee5\u4f7f\u7528 utfcpp \u8fd9\u4e2a\u5e93\uff1a https://github.com/nemtrif/utfcpp \u7a0d\u540e\u6211\u4eec\u4f1a\u4ee5\u6848\u4f8b\u8be6\u7ec6\u6f14\u793a\u8fd9\u4e2a\u5e93\u7684\u7528\u6cd5\uff0c\u4e5f\u4f1a\u5c1d\u8bd5\u81ea\u5df1\u624b\u6413\u3002 \u65b9\u6cd51\uff1a\u4f7f\u7528 utf8to32 \u4e00\u6b21\u6027\u5b8c\u6210\u8f6c\u6362\uff0c\u7528\u5b8c\u540e\u518d\u8f6c\u56de\u53bb\u3002 std::string s = \"\u4f60\u597d\"; std::u32string u32 = utf8::utf8to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\u574f'; s = utf8::utf32to8(u32); fmt::println(\"{}\", s); // \u4f60\u574f \u65b9\u6cd52\uff1a utfcpp \u4e5f\u5c01\u88c5\u4e86\u4e00\u4e2a utf8::iterator \u8fed\u4ee3\u5668\u9002\u914d\u5668\uff0c\u6548\u679c\u7c7b\u4f3c\u4e8e Rust \u7684 .chars() \uff0c\u53ef\u4ee5\u5b57\u7b26\u800c\u4e0d\u662f\u5b57\u8282\u904d\u5386\u5b57\u7b26\u4e32\u5bb9\u5668\u3002 char s[] = \"\u4f60\u597d\"; utf8::unchecked::iterator bit(s); utf8::unchecked::iterator eit(s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u5b89\u5168\uff08\u5e26\u8fb9\u754c\u68c0\u6d4b\uff09\u7684\u7248\u672c char s[] = \"\u4f60\u597d\"; utf8::iterator bit(s, s, s + strlen(s)); utf8::iterator eit(s + strlen(s), s, s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u57fa\u4e8e std::string \u7684\u7248\u672c std::string s = \"\u4f60\u597d\"; utf8::iterator bit(s.begin(), s.begin(), s.end()); utf8::iterator eit(s.end(), s.begin(), s.end()); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } \u7531\u4e8e\u8fed\u4ee3\u5668\u63a5\u53e3\u590d\u6742\u96be\u61c2\uff0c\u5efa\u8bae\u5148\u5c01\u88c5\u6210\u5e26\u6709 begin() \u548c end() \u7684 range \u5bf9\u8c61\uff0c\u65b9\u4fbf\u4f7f\u7528 C++17 range-based loop \u8bed\u6cd5\u76f4\u89c2\u904d\u5386\uff1a template struct Utf8Range { utf8::iterator bit; utf8::iterator eit; template Utf8Range(T &&t) : bit(std::begin(t), std::begin(t), std::end(t)) , eit(std::end(t), std::begin(t), std::end(t)) {} auto begin() const { return bit; } auto end() const { return eit; } }; template Utf8Range(T &&t) -> Utf8Range; // \u4ee5\u4e0b\u662f\u65b0\u7c7b\u7684\u4f7f\u7528\u65b9\u6cd5 std::string s = \"\u4f60\u597d\"; for (char32_t c : Utf8Range(s)) { fmt::println(\"U+{:04X}\", c); }","title":"UTF-8 \u9635\u8425"},{"location":"unicode/#utf-16_2","text":"\u652f\u6301 Unicode \u8fc7\u65e9\uff0c\u8bef\u4ee5\u4e3a 0xFFFF \u5c31\u662f Unicode \u7684\u4e0a\u9650\u3002 \u4e00\u5f00\u59cb\uff0c\u4eba\u4eec\u9519\u8bef\u5730\u628a UTF-16 \u5f53\u6210\u6c38\u8fdc\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u89e3\u51b3\u4e71\u7801\u95ee\u9898\uff0c\u6240\u4ee5\u90a3\u6bb5\u65f6\u671f\u7684\u8f6f\u4ef6\u90fd\u5927\u4e3e\u4f7f\u7528 UTF-16 \u4f5c\u4e3a\u5185\u7801\u3002\u6ca1\u60f3\u5230\u540e\u6765 Unicode \u53c8\u5f15\u5165 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u800c\u73b0\u6709\u7684\u5df2\u7ecf\u91c7\u7528\u4e86 16 \u4f4d\u5185\u7801\u7684\u8f6f\u4ef6\u53c8\u5df2\u7ecf\u65e0\u6cd5\u6839\u9664\uff0c\u53ea\u597d\u4f7f\u7528\u201c\u4ee3\u7406\u5bf9\u201d\u673a\u5236\uff0c\u589e\u91cf\u66f4\u65b0\u4fee\u590d\u4e86\u73b0\u6709\u7684 16 \u4f4d\u5185\u7801\u8f6f\u4ef6\u3002UTF-16 \u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u597d\u5904\uff0c\u7559\u4e0b\u5386\u53f2\u503a\u3002 \u4e8b\u5b9e\u4e0a\uff0cUnicode \u5df2\u7ecf\u65e0\u6cd5\u7ee7\u7eed\u6269\u5bb9\u7a81\u7834 0x10FFFF\uff0c\u5c31\u662f\u56e0\u4e3a\u53cc uint16_t \u7f16\u7801\u7684\u4ee3\u7406\u5bf9\u6700\u591a\u53ea\u80fd\u5bb9\u7eb3\u989d\u5916 0x100000 \u4e2a\u5b57\u7b26\u7684\u7a7a\u95f4\u3002\u672c\u6765 UTF-8 \u4e00\u5f00\u59cb\u7684\u8349\u6848\u662f\u6253\u7b97\u6700\u591a\u652f\u6301 8 \u8282\u5217\u8f66\uff0c\u5b8c\u5168\u5bb9\u7eb3\u9ad8\u8fbe 0x7FFFFFFF \u8303\u56f4\u7684\u5b57\u7b26\u3002\u4e3a\u4e86\u8ba9 Windows \u8fd8\u80fd\u7ee7\u7eed\u7528\uff0cUnicode \u624d\u88ab\u8feb\u6b62\u6b65 0x10FFFF\uff0cUTF-8 \u4e5f\u7ec8\u7ed3\u4e8e 4 \u8282\u5217\u8f66\u3002 \u5e94\u7528\u573a\u666f\uff1a\u901a\u5e38\u8ba4\u4e3a\uff0cUTF-16 \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff0c\u65b0\u8f6f\u4ef6\u4e0d\u5e94\u8be5\u518d\u4f7f\u7528 UTF-16\u3002\u53ea\u6709\u5728\u548c\u8fd9\u4e9b\u7cdf\u7c95\u8f6f\u4ef6\u7684 API \u6253\u4ea4\u9053\u65f6\uff0c\u624d\u5fc5\u987b\u8f6c\u6362\u4e3a UTF-16\u3002\u4f46\u4e5f\u6709\u4eba\u6307\u51fa\uff1aUTF-16 \u662f\u7eaf\u4e2d\u6587\u538b\u7f29\u7387\u6700\u9ad8\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u6240\u4ee5 UTF-16 \u8fd8\u6bd4\u8f83\u9002\u5408\u7eaf\u4e2d\u6587\u6216\u4ee5\u4e2d\u6587\u5185\u5bb9\u4e3a\u4e3b\u7684\u6587\u672c\u6570\u636e\u538b\u7f29\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-16 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8c03\u7528 Windows \u7cfb\u7edf API \u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u76f4\u63a5\u5c31\u80fd\u8c03\u7528\uff0c\u6700\u9002\u5408 Windows \u672c\u5730\u5f00\u53d1\uff0c\u975e\u8de8\u5e73\u53f0\u3002\u4e14\u5bf9\u7eaf\u4e2d\u6587\u5185\u5bb9\u53ef\u6bd4 UTF-8 \u989d\u5916\u8282\u7701 33% \u7a7a\u95f4\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e Windows \u4ee5\u5916\u7684\u7cfb\u7edf\u5c31\u9700\u8981\u8f6c\u6362\u56de UTF-8\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u5f00\u9500\u3002\u4e14\u5982\u679c\u5b58\u50a8\u7684\u5185\u5bb9\u4e3b\u8981\u662f\u7eaf\u82f1\u6587\uff0c\u5982 XML \u4ee3\u7801\u7b49\uff0c\u5185\u5b58\u5360\u7528\u4f1a\u6bd4 UTF-8 \u7ffb\u500d\u3002\u800c\u4e14 UTF-16 \u4ecd\u7136\u662f\u53d8\u957f\u7f16\u7801\uff0c\u867d\u7136\u51fa\u73b0\u53d8\u957f\u7684\u6982\u7387\u8f83\u4f4e\uff0c\u4f46\u4e0d\u4e3a 0\uff0c\u4ecd\u9700\u8981\u5f00\u53d1\u8005\u505a\u7279\u6b8a\u5904\u7406\u3002\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u4f1a\u5bfc\u81f4\u751f\u50fb\u5b57\u7b26\u51fa\u9519\uff0c\u5b57\u7b26\u4e32\u4ee5\u7801\u70b9\u4e3a\u5355\u4f4d\u7684\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4ecd\u7136 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002\u5e76\u4e14 UTF-16 \u6709\u5927\u5c0f\u7aef\u8f6c\u6362\u7684\u95ee\u9898\u3002 \u4ee3\u8868\u4f5c\uff1aWindows \u7cfb\u7edf API\u3001Java \u8bed\u8a00\u3001Windows \u6587\u4ef6\u7cfb\u7edf (NTFS)\u3001Qt\u3001Word\u3001JSON\uff0c\u4ed6\u4eec\u90fd\u662f UTF-16 \u7684\u53d7\u5bb3\u8005\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-16 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-16 \u4f9d\u7136\u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5904\u7406\u6ca1\u95ee\u9898\uff0c\u751f\u50fb\u5b57\u5c31\u5bb9\u6613\u51fa\u95ee\u9898\uff0c\u4e14\u56e0\u4e3a\u51fa\u73b0\u6982\u7387\u4f4e\uff0c\u5f88\u5bb9\u6613\u4e0d\u53d1\u73b0\uff0c\u57cb\u4e0b\u9690\u60a3\u3002 Java \u5c31\u662f\u53d7\u5230\u4e86 UTF-16 \u5386\u53f2\u503a\u5f71\u54cd\uff0c char \u662f 16 \u4f4d\u7684\u7801\u4f4d\uff0c\u800c\u4e0d\u662f\u5b57\u7b26\uff0c\u771f\u6b63\u7684\u4e00\u4e2a\u5b57\u7b26\u662f 32 \u4f4d\u7684 Character \u7c7b\u578b\u3002 \u7f16\u7a0b\u8bed\u8a00 \u7801\u70b9\u7c7b\u578b (32 \u4f4d) \u7801\u4f4d\u7c7b\u578b (16 \u4f4d) Java Character char Java \u7684 Character \u7c7b\u578b\u662f\u4e00\u4e2a 32 \u4f4d\u7684\u503c\uff0c\u8fd9\u4e2a\u503c\u5305\u542b\u4e86\u4e00\u4e2a Unicode \u7801\u4f4d\u3002 char \u7c7b\u578b\u662f\u4e00\u4e2a 16 \u4f4d\u7684\u503c\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a UTF-16 \u7f16\u7801\u7684\u7801\u70b9\u3002 String \u7684 charAt() \u65b9\u6cd5\u8fd4\u56de\u7684\u662f char \u7c7b\u578b\u7684\u7801\u4f4d\uff08\u7c7b\u4f3c\u4e8e\u5b57\u8282\uff09\uff0c\u5982\u679c\u8981\u83b7\u53d6 Character \u7c7b\u578b\u7684\u5b8c\u6574\u5b57\u7b26\uff0c\u5fc5\u987b\u4f7f\u7528 codePointAt() \u65b9\u6cd5\u3002\u8fd9\u662f Java \u8bed\u8a00\u8bbe\u8ba1\u4e0a\u7684\u4e00\u4e2a\u5931\u8bef\uff0c\u5df2\u7ecf\u65e0\u6cd5\u6539\u53d8\u3002 \u800c\u540e\u7eed\u65b0\u51fa\u7684 Kotlin \u662f Java \u7684\u5408\u6cd5\u7ee7\u627f\u8005\uff0c\u4ed6\u679c\u65ad\u653e\u5f03 UTF-16\uff0c\u52a0\u5165\u4e86 UTF-32 \u9635\u8425\u3002\u53ef\u89c1\uff0c\u8001\u8f6f\u4ef6\u575a\u6301\u7528 UTF-16 \u662f\u56e0\u4e3a\u4ed6\u4eec\u79ef\u91cd\u96be\u8fd4\uff0c\u65b0\u8f6f\u4ef6\u518d\u7528 UTF-16 \u5c31\u662f\u81ea\u4f5c\u5b7d\u4e86\uff01 \u603b\u7ed3\uff1a\u4e0d\u8981\u652f\u6301 UTF-16 \u9635\u8425\uff0c\u9664\u975e\u4f60\u88ab\u8feb\u7ef4\u62a4\u53f2\u5c71\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u53d1\u5fae\u4fe1\u670b\u53cb\u5708\u65f6\uff0c\u8f93\u5165 Emoji \u8868\u60c5\u540e\u526a\u5207\uff0c\u518d\u7c98\u8d34\uff0c\u5c31\u548c\u53d1\u73b0\u4e00\u4e2a Emoji \u88ab\u5207\u65ad\u6210\u4e86\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4e71\u7801\u7684\u5f62\u5f0f\u663e\u73b0\u3002\u4f30\u8ba1\u662f\u56e0\u4e3a\u5fae\u4fe1\u57fa\u4e8e Java \u7f16\u5199\uff0c\u75bc\u900a\u7a0b\u5e8f\u5458\u5bf9 UTF-16 \u4ee3\u7406\u5bf9\u5904\u7406\u7684\u4e0d\u5229\u7d22\u3002 Java \u4e2d\u4ee5\u7801\u70b9\u904d\u5386\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5199\u6cd5\uff1a String s = \"\u4f60\u597d\"; // \u6309\u7801\u70b9\u904d\u5386 for (int i = 0; i < s.length();) { Character c = s.codePointAt(i); System.out.println(String.format(\"U+%04X\", c)); i += Character.charCount(c); } // \u6309\u7801\u4f4d\u904d\u5386 for (char c : s.toCharArray()) { System.out.println(String.format(\"U+%04X\", (int) c)); } \u7531\u4e8e JSON \u662f\u548c Java \u4e00\u5757\u53d1\u660e\u7684\u3002\u5bf9\u4e8e\u8d85\u51fa 0xFFFF \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u91c7\u7528\u7684\u8f6c\u4e49\uff0c\u4e5f\u662f\u57fa\u4e8e UTF-16 \u7f16\u7801\u3002\u5373\u540c\u4e00\u4e2a\u5b57\u4f1a\u53d8\u6210\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4fdd\u8bc1 JSON \u6587\u4ef6\u603b\u662f ASCII \u683c\u5f0f\uff0c\u907f\u514d Windows \u7684 GBK \u7f16\u7801\u4e71\u505a\u989d\u5916\u7684\u5e72\u6270\u3002 // \u4ee5\u4e0b\u4e24\u79cd\u5199\u6cd5\u7b49\u4ef7 {\"name\": \"\ud883\udede\"} {\"name\": \"\\ud883\\udfde\"} \u5728\u521a\u521a\u4ecb\u7ecd\u7684 C++ \u5e93 utfcpp \u4e2d\uff0c\u4e5f\u6709\u9488\u5bf9 UTF-16 \u7684\u8f6c\u6362\u51fd\u6570\uff0c\u5982 utf16to32 \uff1a std::u16string s = u\"\u4f60\u597d\"; std::u32string u32 = utf16::utf16to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\ud883\udede'; s = utf16::utf32to16(u32); fmt::println(\"{}\", s); // \u4f60\ud883\udede fmt::println(\"{}\", u32.size()); // 2 fmt::println(\"{}\", s.size()); // 3","title":"UTF-16 \u9635\u8425"},{"location":"unicode/#utf-32_1","text":"\u652f\u6301 Unicode\uff0c\u6bcf\u4e2a\u7801\u70b9\u90fd\u7528\u4e00\u4e2a uint32_t \u6216 char32_t \u8868\u793a\u3002 \u5e94\u7528\u573a\u666f\uff1a\u9002\u5408\u9700\u8981\u7ecf\u5e38\u5904\u7406\u6587\u5b57\u7684\u9886\u57df\uff0c\u5982\u6587\u672c\u7f16\u8f91\u5668\u3001\u6d4f\u89c8\u5668\u7b49\u3002\u4f46\u4e0d\u9002\u5408\u5b58\u50a8\u548c\u4f20\u8f93\uff0c\u56e0\u4e3a\u6d6a\u8d39\u786c\u76d8\u548c\u7f51\u7edc\u5e26\u5bbd\u3002\u5b57\u7b26\u4e32\u4e00\u822c\u90fd\u957f\u671f\u4ee5 UTF-8 \u5b58\u50a8\uff0c\u53ea\u6709\u5728\u9700\u8981\u9891\u7e41\u7d22\u5f15\u7801\u4f4d\u65f6\uff0c\u624d\u9700\u8981\u8f6c\u6362\u4e3a UTF-32\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-32 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u3001\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u90fd\u662f O(1) O(1) \u7684\u590d\u6742\u5ea6\uff0c\u53ef\u4ee5\u5f53\u4f5c\u666e\u901a\u6570\u7ec4\u4e00\u6837\uff0c\u968f\u610f\u5904\u7406\u3002\u4f8b\u5982\u4f60\u53ef\u4ee5\u8bbe\u60f3\u4e00\u4e2a\u6587\u672c\u7f16\u8f91\u6846\uff0c\u9700\u8981\u652f\u6301\u201c\u9000\u683c\u201d\u64cd\u4f5c\uff0c\u5982\u679c\u662f UTF-8 \u548c UTF-16 \u5c31\u9700\u8981\u7e41\u7410\u7684\u5224\u65ad\u4ee3\u7406\u5bf9\u3001\u5404\u79cd\u8f66\u53a2\uff0c\u800c UTF-32 \u7684\u5b57\u7b26\u4e32\u53ea\u9700\u8981\u4e00\u6b21 pop_back \u5c31\u641e\u5b9a\u4e86\u3002 \u7f3a\u70b9\uff1a\u6d6a\u8d39\u7a7a\u95f4\u5927\uff0c\u901a\u5e38\u5728\u4fdd\u5b58\u65f6\uff0c\u4ecd\u7136\u9700\u8981\u8f6c\u6362\u56de UTF-8 \u540e\u518d\u5199\u5165\u6587\u4ef6\uff0c\u6709\u4e00\u5b9a\u6027\u80fd\u5f00\u9500\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-32 \u9635\u8425\uff0c\u8bf7\u5168\u90e8\u4f7f\u7528 char32_t \u548c std::u32string \u3002\u5b57\u9762\u91cf\u5168\u7528 U\"\u4f60\u597d\" \u7684\u5f62\u5f0f\u4e66\u5199\uff0c\u8bfb\u6587\u4ef6\u65f6\u8f6c\u4e3a UTF-32\uff0c\u5199\u6587\u4ef6\u65f6\u8f6c\u56de UTF-8\u3002","title":"UTF-32 \u9635\u8425"},{"location":"unicode/#_13","text":"\u7531\u4e8e C++26 \u524d\u6807\u51c6\u5e93\u5bf9\u7f16\u7801\u8f6c\u6362\u51e0\u4e4e\u6ca1\u6709\u652f\u6301\uff0c\u5728 C++ \u4e2d\u8f6c\u6362\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u5e38\u90fd\u9700\u8981\u7b2c\u4e09\u65b9\u5e93\u3002","title":"\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362"},{"location":"unicode/#utf-utfcpp","text":"\u5982\u679c\u4f60\u53ea\u662f\u9700\u8981\u4e0d\u540c UTF \u683c\u5f0f\u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u6ca1\u6709\u5904\u7406 GBK \u7b49\u7684\u9700\u6c42\uff1a\u90a3\u4e48\u4e4b\u524d\u5df2\u7ecf\u4ecb\u7ecd\u4e86 utfcpp \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5e93\uff0c\u5df2\u7ecf\u591f\u7528\u3002 #include \"utf8/cpp20.h\" std::u8string s8 = u8\"\u4f60\u597d\"; std::u16string s16 = utf8::utf8to16(s8); std::u32string s32 = utf8::utf8to32(s8); std::string s = utf8::utf16to8(s16); s8 = utf8::utf16tou8(s16); \u6700\u540e\u8fd9\u4e24\u4e2a\u533a\u522b\u5728\u4e8e\uff0c utf16to8 \u8fd4\u56de std::string \uff0c utf16tou8 \u8fd4\u56de std::u8string \uff0c\u91cc\u9762\u90fd\u662f UTF-8 \u7f16\u7801\u7684\uff0c\u4e0d\u8fc7\u6709\u7684\u4eba\u559c\u6b22\u7528 std::string \u6765\u5b58\u50a8 UTF-8\uff0c\u4e0d\u559c\u6b22 std::u8string \uff0c\u6216\u8005\u8bf4\u4ed6\u4eec\u6ca1\u6709 C++20\uff0c\u4e0d\u652f\u6301 std::u8string \uff0c\u56e0\u6b64\u8fd9\u4e2a\u5e93\u6ee1\u8db3\u4ed6\u4eec\u7684\u4e0d\u540c\u9700\u8981\u3002\u4f46\u662f std::u8string \u4f5c\u4e3a\u53c2\u6570\u65f6\u4e0d\u9700\u8981\uff0c\u56e0\u4e3a\u53c2\u6570\u53ef\u4ee5\u81ea\u52a8\u91cd\u8f7d\uff0c\u800c\u8fd4\u56de\u503c\u4e0d\u884c\u3002 \u7f3a\u70b9\u662f\u4ed6\u4e0d\u80fd\u5904\u7406 GBK\u3001Shift-JIS \u7b49\u975e Unicode \u7f16\u7801\uff0c\u4e5f\u4e0d\u80fd\u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u7684 ANSI \u533a\u57df\u8bbe\u7f6e\u3002","title":"\u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp"},{"location":"unicode/#boostlocale","text":"\u5982\u679c\u4f60\u8fd8\u8981\u652f\u6301\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u6bd4\u5982 GBK\u3001Shift-JIS\u3001Latin-1\u3002 \u4e00\u79cd\u662f C \u8bed\u8a00\u7684 iconv \uff0c\u53e6\u4e00\u79cd\u662f\u73b0\u4ee3 C++ \u7684 boost::locale \u3002 \u867d\u7136\u529f\u80fd\u5dee\u4e0d\u591a\uff0c\u5e95\u5c42\u90fd\u662f\u8c03\u7528 icu \u7684\u3002 boost::locale \u7684 API \u66f4\u52a0\u53cb\u597d\uff0c\u800c\u4e14\u662f\u73b0\u4ee3 C++ \u98ce\u683c\u7684\u3002 # Ubuntu \u7528\u6237\u5b89\u88c5 Boost.locale \u65b9\u6cd5\uff1a $ sudo apt-get install libboost-locale-dev # Arch Linux \u7528\u6237\u5b89\u88c5 Boost \u5168\u5bb6\u6876\u65b9\u6cd5\uff1a $ sudo pacman -S boost \u4e0d\u559c\u6b22 Boost \u7684\u4eba\u6709\u96be\u4e86\u3002","title":"\u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale"},{"location":"unicode/#utf","text":"\u4f7f\u7528 boost::locale::conv::utf_to_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::utf_to_utf; int main() { std::string s8 = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c UTF-32\uff1a std::u32string s32 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-16\uff1a std::u16string s16 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-8\uff1a s8 = utf_to_utf(s32); std::cout << s8 << '\\n'; return 0; } \u6a21\u677f\u53c2\u6570\u4e2d\uff0c\u53ea\u9700\u6307\u5b9a\u8f6c\u6362\u5230\u7684\u662f\u4ec0\u4e48\u7c7b\u578b\u5c31\u884c\uff0c\u6765\u81ea\u4ec0\u4e48\u7c7b\u578b\uff0c\u4ed6\u81ea\u5df1\u4f1a\u91cd\u8f7d\u7684\u3002 \u6bd4\u5982\u4ece char32_t \u8f6c\u5230 char16_t \uff0c\u53ea\u9700\u8981 utf_to_utf \u5c31\u53ef\u4ee5\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7f16\u8bd1\uff1a $ g++ -std=c++17 -lboost_locale main.cpp \u8f93\u51fa\uff1a \u4f60\u597d \u5efa\u8bae\u7528\u540c\u6837\u8de8\u5e73\u53f0\u7684 CMake \u94fe\u63a5 Boost\uff0c\u5426\u5219 Windows \u7528\u6237\u8981\u6709\u96be\u4e86\u2026\u2026 find_package(Boost REQUIRED COMPONENTS locale) target_link_libraries(\u4f60\u7684\u7a0b\u5e8f Boost::locale) \u4e0d\u8fc7 boost::locale \u6709\u4e00\u4e2a\u7f3a\u70b9\uff0c\u90a3\u5c31\u662f\u4e0d\u652f\u6301 char8_t \u548c std::u8string \u3002 char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff01 \u7531\u4e8e Boost \u8f83\u8001\uff0c\u6ca1\u6709\u53ca\u65f6\u8ddf\u8fdb\uff0c\u6240\u4ee5\u4ed6\u5e76\u6ca1\u6709\u5b9e\u73b0\u9488\u5bf9 char8_t \u7684\u7279\u5316\uff0c\u5982\u679c\u4f7f\u7528\u4e86 utf_to_utf \u4f1a\u62a5 undefined reference \u9519\u8bef\uff0c\u5373\u627e\u4e0d\u5230\u7b26\u53f7\u3002\u6539\u6210 utf_to_utf \u5c31\u6ca1\u95ee\u9898\u4e86\u3002","title":"UTF \u4e4b\u95f4\u4e92\u8f6c"},{"location":"unicode/#gbk-utf","text":"\u4f7f\u7528 boost::locale::conv::to/from_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::to_utf; using boost::locale::conv::from_utf; int main() { std::string s = \"\u4f60\u597d\"; // \u4ece GBK \u8f6c\u5230 UTF-16 std::wstring ws = to_utf(s, \"GBK\"); std::wcout << ws << '\\n'; // \u4ece UTF-16 \u8f6c\u56de GBK s = from_utf(ws, \"GBK\"); std::wcout << s << '\\n'; return 0; } \u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f GBK \u3001 Shift-JIS \u3001 Latin1 \u7b49\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u5b8c\u6574\u7684\u5217\u8868\u53ef\u4ee5\u5728\u770b\u5230\u3002 \u8fd9\u91cc to_utf \u4f1a\u81ea\u52a8\u5224\u65ad wchar_t \u7684\u5927\u5c0f\u3002\u5982\u679c\u662f 2 \u5b57\u8282\uff08Windows \u5e73\u53f0\u60c5\u51b5\uff09\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-16\uff0c\u5982\u679c\u662f 4 \u5b57\u8282\uff08Linux \u5e73\u53f0\u60c5\u51b5\uff09\uff0c\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-32\u3002 \u800c to_char \u5219\u662f\u65e0\u8bba\u4ec0\u4e48\u5e73\u53f0\uff0c\u90fd\u4f1a\u8f6c\u4e3a UTF-16\u3002 from_utf \u4e0d\u9700\u8981\u6307\u5b9a\u4efb\u4f55\u6a21\u677f\u53c2\u6570\uff0c\u56e0\u4e3a\u4ed6\u603b\u662f\u8fd4\u56de std::string \uff08ANSI \u6216 GBK \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff09\uff0c\u53c2\u6570\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4f1a\u81ea\u52a8\u901a\u8fc7\u91cd\u8f7d\u5224\u65ad\uff0c\u4f8b\u5982 from_utf(ws, \"GBK\") \u8fd9\u91cc\u7684\u53c2\u6570\u662f wchar_t \uff0c\u90a3\u4e48\u5728 Windows \u4e0a\uff0c\u4ed6\u4f1a\u68c0\u6d4b\u5230 wchar_t \u662f 2 \u5b57\u8282\uff0c\u5c31\u8ba4\u4e3a\u662f UTF-16 \u5230 GBK \u7684\u8f6c\u6362\u3002","title":"GBK \u548c UTF \u4e92\u8f6c"},{"location":"unicode/#utf-ansi","text":"\u6211\u4eec\u7a0b\u5e8f\u7684\u7528\u6237\u4e0d\u4e00\u5b9a\u662f\u4e2d\u56fd\u7528\u6237\uff08GBK\uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4fc4\u7f57\u65af\u7528\u6237\uff08CP1251\uff09\u3001\u65e5\u672c\u7528\u6237\uff08Shift-JIS\uff09\u3001\u897f\u73ed\u7259\u7528\u6237\uff08CP1252\uff09\u7b49\u3002 \u5982\u679c\u8981\u91c7\u7528\u7528\u6237\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u5373\u201cANSI\u201d\uff0c\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u7559\u7a7a\uff08 \"\" \uff09\u3002 \u7a7a\u5b57\u7b26\u4e32\u5c31\u8868\u793a\u91c7\u7528\u5f53\u524d\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e86\uff0c\u5728\u4e2d\u56fd\u5927\u533a\u7b49\u4ef7\u4e8e \"GBK\" \uff0c\u4fc4\u7f57\u65af\u5927\u533a\u7b49\u4ef7\u4e8e \"CP1251\" \u7b49\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::to_utf; int main() { setlocale(LC_ALL, \"\"); // \u5982\u679c\u4f60\u60f3\u7ed9 Boost \u7528\u7a7a\u5b57\u7b26\u4e32\uff0c\u9996\u5148\u9700\u8981\u8bbe\u7f6e\u4e00\u4e0b\u8fd9\u4e00\u884c std::string u8s = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c ANSI std::string s = from_utf(u8s, \"\"); // ANSI \u8f6c UTF-8 u8s = to_utf(s, \"\"); return 0; } setlocale(LC_ALL, \"\"); \u4e2d\u7684\u7a7a\u5b57\u7b26\u4e32\u8868\u793a","title":"UTF \u548c ANSI \u4e92\u8f6c"},{"location":"unicode/#_14","text":"\u51fd\u6570\u540d\u79f0 \u4ece \u5230 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-16 utf_to_utf UTF-x UTF-32 utf_to_utf UTF-x Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 UTF-x \u8868\u793a\u53d6\u51b3\u4e8e\u53c2\u6570\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u5982\u679c\u53c2\u6570\u662f char16_t \u7684\u5b57\u7b26\u4e32 std::u16string \uff0c\u90a3 x \u5c31\u662f 16\u3002 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-16 to_utf(\"GBK\", string) GBK UTF-32 to_utf(\"GBK\", string) GBK Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-32 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 from_utf(\"GBK\", string) UTF-8 GBK from_utf(\"GBK\", u16string) UTF-16 GBK from_utf(\"GBK\", u32string) UTF-32 GBK from_utf(\"GBK\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 GBK from_utf(\"\", string) UTF-8 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u16string) UTF-16 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u32string) UTF-32 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u533a\u57df\u8bbe\u7f6e","title":"\u5927\u603b\u7ed3"},{"location":"unicode/#gbk-shift-jis","text":"#include #include using boost::locale::conv::between; using boost::locale::conv::from_utf; int main() { // \u521b\u5efa\u4e00\u4e2a Shift-JIS \u5b57\u7b26\u4e32 std::string jis = from_utf(u8\"\u65e5\u672c\u8a9e\", \"Shift-JIS\"); // \u4ece Shift-JIS \u8f6c\u5230 GBK std::string gbk = between(jis, \"GBK\", \"Shift-JIS\"); std::cout << gbk << '\\n'; // \u4ece GBK \u8f6c\u56de Shift-JIS jis = between(gbk, \"Shift-JIS\", \"GBK\"); std::cout << jis << '\\n'; return 0; } \u6ce8\u610f\uff01\u662f\u76ee\u6807\u7f16\u7801\u5728\u524d\uff01\u5982\u679c\u4f60\u8981\u4ece Shift-JIS \u8f6c\u6210 GBK\uff0c\u90a3\u4e48\u9700\u8981 between(jis, \"GBK\", \"Shift-JIS\") \uff0c\u8fd9\u771f\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\u3002\u4e0d\u4ec5 GBK \u548c Shift-JIS \u53ef\u80fd\u4e0d\u5c0f\u5fc3\u5f04\u53cd\u4e86\uff0c\u7f16\u8bd1\u5668\uff0c\u4e00\u70b9\u63d0\u793a\u90fd\u6ca1\u6709\uff0c\u800c\u4e14 jis \u548c \u201cGBK\u201d \u90fd\u662f\u5b57\u7b26\u4e32\uff0c\u5f88\u5bb9\u6613\u5927\u8111\u641e\u6df7\u3002\u8ba9\u6211\u6765\u8bbe\u8ba1\u7684\u8bdd\uff0c\u6211\u4f1a\u8fd9\u6837\u63d0\u4f9b API\uff1a decode(jis, Encoding::ShiftJIS).encode(Encoding::GBK) \uff0c\u5176\u4e2d Encoding \u662f\u4e00\u4e2a\u679a\u4e3e\uff0c\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u4e0d\u4ec5\u907f\u514d\u72af\u9519\u7684\u673a\u4f1a\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u8f7b\u677e\u3002\u4e4b\u540e\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e13\u9898\u8bfe\u4e2d\uff0c\u4f1a\u518d\u8be6\u7ec6\u8bb2\u89e3\u4ec0\u4e48\u662f\u597d\u7684 API \u8bbe\u8ba1\u3002","title":"GBK \u548c Shift-JIS \u4e92\u8f6c"},{"location":"unicode/#_15","text":"\u5982\u679c\u9047\u5230\u65e0\u6cd5\u7f16\u7801\u7684\u5b57\u7b26\uff0c\u8be5\u5982\u4f55\u5904\u7f6e\uff1f \u9ed8\u8ba4\u60c5\u51b5\u4e0b Boost \u4f1a\u5ffd\u89c6\u9519\u8bef\uff0c\u7f16\u7801\u5931\u8d25\u7684\u5b57\u7b26\u4f1a\u88ab\u4e22\u5f03\u3002 #include #include using boost::locale::conv::from_utf; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\"); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 std::cout << gbk << '\\n'; // \u5728 Windows \u7684 GBK \u7ec8\u7aef\u4e0a\uff0c\u53ea\u663e\u793a\u201c\u6211\u7231\u9762\u201d return 0; } \u53ef\u4ee5\u7528 method_type \u8fd9\u4e2a\u679a\u4e3e\u6765\u6307\u5b9a\u9519\u8bef\u5904\u7406\u7684\u65b9\u5f0f\u3002 \u9ed8\u8ba4\u662f skip \uff0c\u8df3\u8fc7\u6240\u6709\u89e3\u7801\u51fa\u9519\u7684\u5730\u65b9\uff08\u5bfc\u81f4\u201c\ud883\udede\u201d\u4e22\u5931\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230 stop \uff0c\u5f53\u9047\u5230\u89e3\u7801\u9519\u8bef\u65f6\uff0c\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\uff0c\u7ec8\u6b62\u7a0b\u5e8f\u6267\u884c\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\", method_type::stop); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 // from_utf \u4f1a\u629b\u51fa `conversion_error` \u5f02\u5e38 std::cout << gbk << '\\n'; return 0; } \u4e3e\u4f8b\uff1a\u5c1d\u8bd5\u4ee5 GBK \u4fdd\u5b58\uff0c\u5982\u679c\u5931\u8d25\uff0c\u5219\u6539\u4e3a\u5e26\u6709 BOM \u7684 UTF-8\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; using boost::locale::conv::conversion_error; void try_save(std::u32string content, std::wstring path) { std::string binary; try { // \u5c1d\u8bd5\u5c06 UTF-32 \u8f6c\u6210 GBK \u7f16\u7801 binary = from_utf(content, \"GBK\", method_type::stop); } catch (conversion_error const &e) { // \u82e5 GBK \u65e0\u6cd5\u8868\u793a // \u6539\u7528\u524d\u9762\u5e26\u6709 BOM \u7684 UTF-8 \u7f16\u7801 binary = \"\\xEF\\xBB\\xBF\" + utf_to_utf(content); } std::ofstream(path) << binary; } \u4e3e\u4f8b\uff1a\u652f\u6301 UTF-8 \u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f ANSI \u5b57\u7b26\u4e32\uff09\u7684\u6253\u5370\u51fd\u6570\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::utf_to_utf; static int dummy_init = (setlocale(LC_ALL, \"\"), 0); // \u9700\u8981\u8bbe\u7f6e\u8fc7 setlocale(LC_ALL, \"\") \u540e\uff0c\u624d\u80fd\u4f7f\u7528 Boost \u7684\u7a7a\u5b57\u7b26\u4e32\u5199\u6cd5 void u8print(std::string msg) { std::cout << from_utf(msg, \"\"); // \u6216\u8005\uff1a // std::wcout << utf_to_utf(msg); } \u6b64\u5904 static int dummy_init = \u662f\u4e00\u79cd\u9759\u6001\u521d\u59cb\u5316\u94a9\u5b50\u7684\u5c0f\u6280\u5de7\uff0c\u4e4b\u540e\u8bbe\u8ba1\u6a21\u5f0f\u8bfe\u7a0b\u7684\u5355\u4f8b\u6a21\u5f0f\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3\u3002","title":"\u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5"},{"location":"unicode/#_16","text":"\u51fd\u6570 \u4ece \u5230 utf_to_utf UTF \u7cfb\u5217 UTF \u7cfb\u5217 from_utf UTF \u7cfb\u5217 \u6742\u724c\u5b57\u7b26\u7f16\u7801 to_utf \u6742\u724c\u5b57\u7b26\u7f16\u7801 UTF \u7cfb\u5217 between \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u66f4\u591a\u7ec6\u8282\u7528\u6cd5\u89c1\u5b98\u65b9\u6587\u6863\uff1ahttps://www.boost.org/doc/libs/1_81_0/libs/locale/doc/html/group__codepage.html \u4e0d\u53ef\u601d\u8bae\u7684\u662f\uff1a\u7f16\u7801\u8f6c\u6362\u53ea\u662f boost::locale::conv \u8fd9\u4e2a\u5b50\u6a21\u5757\u4e0b\u7684\u4e00\u4e2a\u5c0f\u529f\u80fd\u800c\u5df2\uff01 boost::locale \u8fd8\u63d0\u4f9b\u4e86\u66f4\u591a\u529f\u80fd\uff0c\u5982\u6309\u7167\u5730\u57df\u8bed\u8a00\u89c4\u8303\u683c\u5f0f\u5316\u6570\u5b57\u3001\u8d27\u5e01\u3001\u65e5\u671f\u3001\u65f6\u95f4\u7b49\uff0c\u4e0b\u4e00\u5c0f\u8282\u4e2d\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd\u3002\u5b8c\u5168\u662f std::locale \u7684\u4e0a\u4f4d\u66ff\u4ee3\u3002 Boost \u54ea\u91cc\u90fd\u597d\uff0c\u4f60\u60f3\u8981\u7684\u529f\u80fd\u5e94\u6709\u5c3d\u6709\u3002\u800c\u4e14\u4e0d\u9700\u8981 C++20\uff0c\u5f88\u4f4e\u7248\u672c\u7684 C++ \u4e5f\u80fd\u7528\u3002\u552f\u4e00\u7f3a\u70b9\u53ef\u80fd\u5c31\u662f\u592a\u80a5\u4e86\uff0c\u7f16\u8bd1\u6162\u3002","title":"\u66f4\u591a\u529f\u80fd\uff1f\uff01"},{"location":"unicode/#windows-multibytetowidechar","text":"\u5982\u679c\u4f60\u662f Windows \u7a0b\u5e8f\u5458\uff0c\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u4e14\u9700\u8981\u5728 Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u89c4\u5b9a\u7684 ANSI\uff08\u5728\u4e2d\u56fd\u533a\u662f GBK\uff09\u7f16\u7801\u548c UTF-16 \u4e4b\u95f4\u8f6c\u6362\uff1a \u53ef\u4ee5\u7528 Windows \u5b98\u65b9\u63d0\u4f9b\u7684 MultiByteToWideChar \u548c WideCharToMultiByte \u51fd\u6570\u3002 \u8fd9\u4e24\u4e2a\u51fd\u6570\u56e0\u4e3a C \u8bed\u8a00\u7279\u8272\u7684\u7f18\u6545\uff0c\u53c2\u6570\u6bd4\u8f83\u591a\u800c\u6742\uff0c\u5efa\u8bae\u81ea\u5df1\u52a8\u624b\u5c01\u88c5\u6210\u66f4\u6613\u7528\u7684 C++ \u51fd\u6570\uff1a std::wstring ansi_to_wstring(const std::string &s) { // ACP = ANSI Code Page\uff0c\u544a\u8bc9\u4ed6\u5b57\u7b26\u4e32\u91cc\u7684\u662f\u5f53\u524d\u533a\u57df\u8bbe\u7f6e\u6307\u5b9a\u7684\u7f16\u7801\uff08\u5728\u4e2d\u56fd\u533a\uff0cANSI \u5c31\u662f GBK \u4e86\uff09 int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_ansi(const std::wstring &ws) { int len = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } std::wstring utf8_to_wstring(const std::string &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_utf8(const std::wstring &ws) { int len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } C \u8bed\u8a00\u7279\u8272\uff1a\u6240\u6709\u8981\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u90fd\u9700\u8981\u8c03\u7528\u4e24\u904d\uff0c\u7b2c\u4e00\u6ce2\u5148\u6c42\u51fa\u957f\u5ea6\uff0c\u7b2c\u4e8c\u6ce2\u624d\u5199\u5165\u3002\u8fd9\u662f\u4e3a\u4e86\u907f\u514d\u4e0e\u5185\u5b58\u5206\u914d\u5668\u8026\u5408\uff0c\u6240\u6709\u7684 C \u98ce\u683c API \u90fd\u662f\u8fd9\u6837\u3002","title":"Windows \u7528\u6237\uff1aMultiByteToWideChar"},{"location":"unicode/#messageboxa","text":"\u590d\u73b0\u6761\u4ef6\uff1a Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e3a\u4e2d\u6587 (GBK)\u3002 \u4f7f\u7528 MSVC \u7684 /utf-8 \u9009\u9879\u7f16\u8bd1\u3002 #include int main() { MessageBoxA(nullptr, \"\u6211\u7231\ud883\udede\ud883\udede\u9762\", \"\u6807\u9898\", MB_OK); // \u4f1a\u53d8\u6210\u4e71\u7801 return 0; }","title":"MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b"},{"location":"unicode/#linux-iconv","text":"\u5982\u679c\u4f60\u662f Linux \u7528\u6237\uff0c\u4e14\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 iconv \u5e93\u3002 iconv \u4e5f\u6709 Windows \u7684\u7248\u672c\uff0c\u4f46\u5b89\u88c5\u6bd4\u8f83\u56f0\u96be\u3002\u5982\u679c\u4f60\u8fde iconv \u90fd\u641e\u5f97\u5b9a\uff0c\u6ca1\u7406\u7531 Boost \u641e\u4e0d\u5b9a\u3002 #include #include std::string convert(std::string const &s, char const *from, char const *to) { iconv_t cd = iconv_open(to, from); if (cd == (iconv_t)-1) { throw std::runtime_error(\"iconv_open failed\"); } auto in = s.data(); auto inbytesleft = s.size(); size_t outbytesleft = inbytesleft * 4; std::string buffer(outbytesleft, 0); auto out = buffer.data(); iconv(cd, &in, &inbytesleft, &out, &outbytesleft); iconv_close(cd); buffer.resize(buffer.size() - outbytesleft); return buffer; } // \u4e3e\u4f8b\uff1aUTF-8 \u8f6c GBK std::string utf8_to_gbk(std::string const &s) { return convert(s, \"UTF-8\", \"GBK\"); } // \u4e3e\u4f8b\uff1aGBK \u8f6c UTF-8 std::string gbk_to_utf8(std::string const &s) { return convert(s, \"GBK\", \"UTF-8\"); }","title":"Linux \u7528\u6237\uff1aiconv"},{"location":"unicode/#iconv","text":"iconv \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u4e5f\u662f\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177\uff08\u5927\u591a Linux \u53d1\u884c\u7248\u90fd\u81ea\u5e26\u4e86\uff09\u3002\u7528\u6cd5\u5982\u4e0b\uff1a iconv -f \u6765\u81ea\u4ec0\u4e48\u7f16\u7801 -t \u5230\u4ec0\u4e48\u7f16\u7801 (\u8f93\u5165\u6587\u4ef6\u540d...) > \u8f93\u51fa\u6587\u4ef6\u540d \u5982\u4e0d\u6307\u5b9a\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u9ed8\u8ba4\u4ece\u7ec8\u7aef\u8f93\u5165\u6d41\u8bfb\u53d6\u3002 \u5982\u4e0d\u4f7f\u7528 > \u8f93\u51fa\u6587\u4ef6\u540d \u91cd\u5b9a\u5411\u8f93\u51fa\uff0c\u5219\u9ed8\u8ba4\u8f93\u51fa\u5230\u7ec8\u7aef\u3002 \u53ef\u4ee5\u7528 echo \u914d\u5408\u7ba1\u9053\u6765\u521b\u5efa\u8f93\u5165\u6d41\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 \u6b64\u5904\u663e\u793a\u4e71\u7801\u662f\u56e0\u4e3a\u6211\u7684\u7ec8\u7aef\u662f UTF-8 \u683c\u5f0f\uff0c\u65e0\u6cd5\u6b63\u786e\u89e3\u6790 iconv \u8f93\u51fa\u7684 GBK \u683c\u5f0f\u6570\u636e\u3002 \u628a\u201c\u6211\u7231\u5c0f\u5f6d\u8001\u5e08\u201d\u8f6c\u6362\u4e3a GBK \u683c\u5f0f\u5199\u5165 gbk.txt \uff0c\u7136\u540e\u518d\u91cd\u65b0\u8fd8\u539f\u56de UTF-8 \u683c\u5f0f\u67e5\u770b\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK > gbk.txt $ cat gbk.txt \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 $ iconv -f GBK -t UTF-8 gbk.txt \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 Windows \u53ef\u80fd\u4e5f\u6709\u7c7b\u4f3c\u7684\u5de5\u5177\uff0c\u6bd4\u5982 iconv.exe \uff0c\u4f46\u6211\u6ca1\u627e\u5230\u3002","title":"iconv \u547d\u4ee4\u884c\u5de5\u5177"},{"location":"unicode/#locale","text":"\u672c\u5730\u5316\u662f\u6307\u6839\u636e\u7528\u6237\u7684\u8bed\u8a00\u3001\u5730\u533a\u7b49\u73af\u5883\uff0c\u663e\u793a\u4e0d\u540c\u7684\u754c\u9762\u3002\u6bd4\u5982\u8bf4\uff0c\u540c\u6837\u662f\u6587\u4ef6\u83dc\u5355\uff0c\u4e2d\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201c\u6587\u4ef6\u201d\u3001\u82f1\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201cFile\u201d\u3002","title":"\u672c\u5730\u5316 (locale)"},{"location":"unicode/#_17","text":"C \u8bed\u8a00\u63d0\u4f9b\u4e86 \u5934\u6587\u4ef6\uff0c\u91cc\u9762\u5c01\u88c5\u4e86\u5927\u91cf\u5f62\u5982 isspace \u3001 isdigit \u8fd9\u6837\u7684\u5224\u65ad\u5b57\u7b26\u5206\u7c7b\u7684\u51fd\u6570\u3002 #include C++ \u5bf9\u5176\u5b9e\u65bd\u4e86\u518d\u5c01\u88c5\uff0c\u6539\u540d\u4e3a \u3002\u82e5\u4f60\u5bfc\u5165\u7684\u662f\u8be5\u5934\u6587\u4ef6\uff0c\u90a3\u4e48\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5e26\u6709 std \u540d\u5b57\u7a7a\u95f4\u524d\u7f00\u7684\u65b9\u5f0f std::isspace \uff0c std::isdigit \u8bbf\u95ee\u4e86\uff0c\u770b\u8d77\u6765\u66f4\u52a0\u4e13\u4e1a\uff08\u786e\u4fe1\uff09\u3002 #include \u51fd\u6570\u6e05\u5355\uff1a \u51fd\u6570\u540d\u79f0 \u5224\u65ad\u7684\u5b57\u7b26\u7c7b\u578b isascii 0 \u5230 0x7F \u7684\u6240\u6709 ASCII \u5b57\u7b26 isalpha \u5927\u5c0f\u5199\u5b57\u6bcd A-Z a-z isupper \u5927\u5199\u5b57\u6bcd A-Z islower \u5c0f\u5199\u5b57\u6bcd a-z isdigit \u6570\u5b57 0-9 isxdigit \u5341\u516d\u8fdb\u5236\u6570\u5b57 A-F a-f 0-9 isprint \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u5305\u62ec\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u6807\u70b9\u7b49 isgraph \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u4e0d\u5305\u62ec\u7a7a\u683c iscntrl \u63a7\u5236\u5b57\u7b26\uff0c\u9664\u53ef\u6253\u5370\u5b57\u7b26\u5916\u7684\u5168\u90e8 isspace \u7a7a\u767d\u5b57\u7b26\uff0c\u5982\u7a7a\u683c\u3001\u6362\u884c\u3001\u56de\u8f66\u3001\u5236\u8868\u7b26\u7b49 ispunct \u6807\u70b9\u7b26\u53f7 isalnum \u5b57\u6bcd\u6216\u6570\u5b57 \u66f4\u8be6\u7ec6\u7684\u8868\u683c\u53ef\u4ee5\u770b\uff1ahttps://en.cppreference.com/w/cpp/string/byte/isspace","title":"\u533a\u5206\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#_18","text":"\u4e4b\u524d\u63d0\u5230\u7684\u5b57\u7b26\u90fd\u662f char \u7c7b\u578b\u7684 ASCII \u5b57\u7b26\uff0c\u8303\u56f4\u6700\u591a\u5728 0 \u5230 0x7F \u5185\u3002 \u5bf9\u53ea\u63a5\u53d7 char \u7684 isspace \uff0c ispunct \u7cfb\u5217\u51fd\u6570\uff0c\u53c2\u6570\u5982\u679c\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\uff0c\u7ed3\u679c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8981\u652f\u6301\u66f4\u5927\u8303\u56f4\u7684\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u7528 wchar_t \u7c7b\u578b\uff0c\u6216\u8005 char16_t \u548c char32_t \u3002 \u4e0e\u5b57\u7b26\u4e32\u5e38\u91cf\u4e00\u6837\uff0c\u5355\u4e2a\u5b57\u7b26\u4e5f\u53ef\u4ee5\u7528 L \u3001 u \u3001 U \u6765\u5206\u522b\u4ea7\u751f wchar_t \u3001 char16_t \u3001 char32_t \u7c7b\u578b\u7684\u5b57\u7b26\u3002 char c = '\u6211'; // \u7f16\u8bd1\u51fa\u9519\uff01char \u7c7b\u578b\u65e0\u6cd5\u5bb9\u7eb3\u6211 (0x6211) wchar_t wc = L'\u6211'; // \u7f16\u8bd1\u901a\u8fc7\uff0c\u7b49\u4ef7\u4e8e wc = 0x6211 \u548c const char * \u4e00\u6837\uff0c\u4e5f\u6709 const wchar_t \u8868\u793a\u8fd9\u79cd\u7531 Unicode \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff1a const wchar_t *ws = L\"\u4f60\u597d\uff0c\u4e16\u754c\"; assert(ws[2] == L'\uff0c'); wchar_t \u7684\u63d0\u51fa\u8d77\u521d\u662f\u4e3a\u4e86\u907f\u514d char \u7684\u533a\u57df\u8bbe\u7f6e\u5404\u81ea\u4e3a\u653f\uff0c\u7f16\u7801\u6df7\u4e71\u7684\u95ee\u9898\uff0c\u56e0\u4e3a wchar_t \u59cb\u7ec8\u662f UTF-16 (Windows) \u6216 UTF-32 (Linux)\u3002","title":"\u5bbd\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#wchar_t","text":"std::string str = \"hello,world,universe\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, ',')) { std::cout << line << '\\n'; } \u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u5b57\u7b26\u4e32\u5206\u5272\u51fd\u6570\uff0c\u5b83\u4f1a\u628a hello \u6309\u7167\u9017\u53f7 \u201c,\u201d (0x2C) \u5206\u5272\uff0c\u7136\u540e\u8f93\u51fa\u3002 \u4f46\u662f\uff0c\u5b83\u65e0\u6cd5\u5904\u7406 Unicode \u5b57\u7b26 \u201c\uff0c\u201d (0xFF0C)\uff0c\u8fd9\u662f\u4e00\u4e2a\u5168\u89d2\u7684\u9017\u53f7\u3002\u56e0\u4e3a \u201c\uff0c\u201d \u4f1a\u88ab UTF-8 \u7f16\u7801\u6210\u4e09\u4e2a char \uff1a0xEF 0xBC 0x8C\u3002 std::string str = \"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, '\uff0c')) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u7b49\u4ef7\u4e8e '\\xEF\\xBC\\x8C'\uff0c\u4e00\u4e2a char \u5e38\u91cf\u91cc\u4e0d\u5f97\u5305\u542b\u4e09\u4e2a char\uff01 std::cout << line << '\\n'; } \u800c wchar_t \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a \u201c\uff0c\u201d \u5728 0xFFFF \u8303\u56f4\u5185\uff0c\u5373\u4f7f\u8003\u8651\u5230 Windows \u662f UTF-16 \u7f16\u7801\uff0c\u201c\uff0c\u201d \u53ea\u4f1a\u4ea7\u751f\u4e00\u4e2a wchar_t \u3002\u8fd9\u5bf9\u4ee5\u5355\u4e2a wchar_t \u4e3a\u5355\u4f4d\u7684 std::getline \u6765\u8bf4\u6ca1\u6709\u95ee\u9898\u3002 std::wstring str = L\"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::wstringstream ss(str); std::wstring line; while (std::getline(ss, line, L'\uff0c')) { // \u7f16\u8bd1\u901a\u8fc7\uff0c'\uff0c' \u662f\u5355\u4e2a UTF-16 \u7801\u4f4d std::wcout << line << L'\\n'; }","title":"wchar_t \u5e94\u7528\u6848\u4f8b"},{"location":"unicode/#locale_1","text":"\u8981\u8ba9 iswspace \u548c iswpunct \u8bc6\u522b\u4e2d\u6587\u9017\u53f7\u548c\u4e2d\u6587\u7a7a\u683c\uff0c\u6211\u4eec\u9700\u8981\u5148\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e00\u884c\u4ee3\u7801\uff1a setlocale(LC_ALL, \"C.utf-8\"); \u8fd9\u4f1a\u542f\u7528 Unicode \u5b57\u7b26\u96c6\uff0c\u4f7f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u80fd\u591f\u57fa\u4e8e Unicode \u5b57\u7b26\u96c6\u53bb\u5224\u65ad\u5b57\u7b26\u7c7b\u578b\uff0c\u800c\u4e0d\u662f\u9ed8\u8ba4\u7684 ASCII \u5b57\u7b26\u96c6\u3002 assert(ispunct(',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f ispunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L'\uff0c') == true);// 0xFF0C \u5bf9\u5e94\u7684\u5168\u89d2\u9017\u53f7\u4e5f\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 \u6bcf\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u4e00\u5f00\u59cb\uff0c\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \u3002\u9700\u8981\u8bbe\u7f6e\u4e3a \"C.UTF-8\" \u6216\u8005 \"zh_CN.UTF-8\" \uff0c\u603b\u4e4b\u662f\u652f\u6301 Unicode \u5b57\u7b26\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u624d\u80fd\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u8bc6\u522b\u8d85\u8fc7 ASCII \u8303\u56f4\u7684\u5b57\u7b26\u7684\u7c7b\u578b\u3002 fmt::println(\"\u9ed8\u8ba4: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C\"); fmt::println(\"C: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C.UTF-8\"); fmt::println(\"C.UTF-8: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"zh_CN.UTF-8\"); fmt::println(\"zh_CN.UTF-8: {}\", iswpunct(L'\uff0c')); \u8f93\u51fa\uff1a \u9ed8\u8ba4: 0 C: 0 C.UTF-8: 1 zh_CN.UTF-8: 1 \u603b\u4e4b\uff0c isw***** \u7cfb\u5217\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570 wchar_t \u8868\u793a\u8303\u56f4\u66f4\u5e7f\uff0c\u5728 Linux \u4e0a\u80fd\u8868\u793a\u6240\u6709 Unicode \u5b57\u7b26\uff0c\u5728 Windows \u4e0a\u80fd\u8868\u793a\u6240\u6709 0xFFFF \u4ee5\u5185\u7684\u5e38\u7528 Unicode \u5b57\u7b26\u3002 is***** \u7cfb\u5217\u51fd\u6570\u9047\u5230\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\u7684 char \u8fd8\u4f1a\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u975e\u5e38\u70e6\u4eba\u3002\u65e2\u7136 char \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a wchar_t \uff0c\u6240\u4ee5\u6211\u7684\u5efa\u8bae\u662f\u8bbe\u7f6e\u4e86 \".utf-8\" locale \u540e\uff0c\u5168\u90e8\u7528 isw***** \u53d6\u4ee3 is***** \u3002","title":"\u533a\u57df\u8bbe\u7f6e\u4e0e locale"},{"location":"unicode/#locale_2","text":"\"zh_CN.UTF-8\" \u8fd9\u6837\u7684\u5b57\u7b26\u4e32\uff0c\u5c31\u662f locale \u7684\u540d\u5b57\uff0clocale \u540d\u5b57\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5206\u522b\u662f\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\u3002 \u8bed\u8a00.\u5b57\u7b26\u7f16\u7801 \"zh_CN.UTF-8\" \u5c31\u8868\u793a\uff0c\u4e00\u4e2a\u8bed\u8a00\u4e3a\u7b80\u4f53\u4e2d\u6587\uff0c\u7f16\u7801\u683c\u5f0f\u4e3a UTF-8 \u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u8981\u6ce8\u610f\u7684\u662f\uff0c\u7528\u6237\u5fc5\u987b\u5df2\u7ecf\u5b89\u88c5\u8fc7\u8be5\u533a\u57df\u8bbe\u7f6e\uff0c\u7a0b\u5e8f\u624d\u80fd\u4f7f\u7528 setlocale \u8bbe\u7f6e\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u627e\u4e0d\u5230 locale \u7684\u9519\u8bef\u3002 \u8fd9\u51e0\u4e4e\u5bfc\u81f4\u4f60\u6ca1\u6cd5\u7528\u9664\u9ed8\u8ba4\u5916\u7684\u4efb\u4f55 locale\uff0c\u6bd4\u5982 \"zh_CN.UTF-8\" \uff0c\u56e0\u4e3a\u4f60\u4e0d\u80fd\u786e\u5b9a\u7528\u6237\u6709\u6ca1\u6709\u5b89\u88c5\u4ed6\u3002\u4f46\u4f60\u53ef\u4ee5\u7528 boost::locale::generator \u51ed\u7a7a\u751f\u6210\u4e00\u4e2a\u7cfb\u7edf\u91cc\u6ca1\u6709\u5b89\u88c5\u8fc7\u7684 locale\uff0c\u7ed5\u5f00\u6807\u51c6\u5e93\u7684\u9650\u5236\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 Linux \u7528\u6237\u53ef\u4ee5\u901a\u8fc7 \u4fee\u6539 /etc/locale.gen \u53d6\u6d88\u6ce8\u91ca\u8981\u542f\u7528\u7684\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\uff0c\u4fdd\u5b58\u540e\uff0c\u8fd0\u884c locale-gen \u5373\u53ef\u5b89\u88c5\u6240\u6709\u6ca1\u6ce8\u91ca\u7684\u8bed\u8a00\u3002 sudo vim /etc/locale.gen sudo locale-gen \u53ef\u4ee5\u7528 locale -a \u547d\u4ee4\u67e5\u770b\u5df2\u7ecf\u5b89\u88c5\u4e86\u54ea\u4e9b locale\uff1a $ locale -a C C.utf8 POSIX en_US en_US.iso88591 en_US.utf8 zh_CN.gb18030 zh_CN.gbk zh_CN.utf8 \u6ce8\u610f\u5230\uff0clocale \u4e2d '.' \u53f7\u53f3\u8fb9\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u65e0\u89c6\u5927\u5c0f\u5199\u7684\uff0c\u800c\u4e14\u53ef\u4ee5\u7701\u7565\u6389 '-' \u3002\u6240\u4ee5 ISO-8859-1 \u53ef\u4ee5\u88ab\u7b80\u5199\u6210 iso88591 \uff0c UTF-8 \u88ab\u7b80\u5199\u6210 utf8 \u3002 \u5de6\u8fb9\u7684\u8bed\u8a00\u4e5f\u662f\u7528 '_' \u4e00\u5206\u4e3a\u4e8c\uff0c\u56fa\u5b9a\u662f '\u8bed\u8a00_\u5730\u533a' \u7684\u5199\u6cd5\u3002\u6bd4\u5982\u52a0\u62ff\u5927\u65e2\u6709\u82f1\u8bed\u7528\u6237\u53c8\u6709\u6cd5\u8bed\u7528\u6237\uff0c\u82f1\u8bed\u7684\u4ee3\u53f7\u662f 'en' \uff0c\u6cd5\u8bed\u7684\u4ee3\u53f7\u662f 'fr' \uff0c\u52a0\u62ff\u5927\u7684\u4ee3\u53f7\u662f 'CA' \uff0c\u6240\u4ee5\u5c31\u5b58\u5728\u7740 'en_CA' \u548c 'fr_CA' \u4e24\u79cd locale\u3002 \u4e5f\u6709\u4e00\u79cd\u8bed\u8a00\u88ab\u591a\u4e2a\u5730\u533a\u4f7f\u7528\u7684\u60c5\u51b5\uff0c\u4f8b\u5982\u4e2d\u6587\u7684\u4ee3\u53f7\u662f 'zh' \uff0c\u4ed6\u88ab\u4e2d\u56fd\u5927\u9646\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_CN' \uff0c\u88ab\u9999\u6e2f\u4f7f\u7528\u65f6\u53eb 'zh_HK' \uff0c\u88ab\u53f0\u6e7e\u7701\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_TW' \uff0c\u88ab\u65b0\u52a0\u5761\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_SG' \u3002 Windows \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b89\u88c5\u8bed\u8a00\u548c\u5730\u533a\u7684\u9009\u9879\uff0c\u4f46\u6bd4\u5c14\u76d6\u5b50\u5bf9 locale \u547d\u540d\u7684\u8bed\u6cd5\u7a0d\u6709\u4e0d\u540c\uff1a setlocale(LC_ALL, \"Chinese_China.936\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4ee3\u7801\u9875 936\uff08\u4e5f\u5c31\u662f GBK\uff09 \u4ed6\u7684\u8bed\u8a00\u540d\u4e0d\u662f\u6309\u7167\u56fd\u9645\u89c4\u8303\u7684 zh_CN \u8fd9\u6837\u7684\u7b80\u5199\uff0c\u800c\u662f Chinese_China \u3002 \u800c\u4e14\u540e\u9762\u7684 936 \u662f Windows \u79c1\u81ea\u5b9a\u4e49\u7684\u4e00\u5957\u6240\u8c13\u7684\u201c\u4ee3\u7801\u9875\u201d\uff0c\u8fd9\u91cc 936 \u5176\u5b9e\u5c31\u662f \u4e2d\u5b8f CP_GBK \u7684\u503c\uff0c\u8868\u793a GBK \u4ee3\u7801\u9875\u3002\u540c\u6837\u5730\u8fd8\u6709 65001 \u8868\u793a UTF-8 \u4ee3\u7801\u9875\u3002 setlocale(LC_ALL, \"Chinese_China.65001\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4f46\u662f\u542f\u7528 UTF-8 \u652f\u6301 setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 .65001 \u53ef\u4ee5\u7528\u522b\u540d .UTF-8 \u53d6\u4ee3\u3002\u4f46\u53ea\u6709 .UTF-8 \u652f\u6301\u8fd9\u4e2a\u522b\u540d\uff0c\u4f8b\u5982 .GBK \u4ed6\u5c31\u4e0d\u80fd\u8bc6\u522b\u3002 \u8bbe\u7f6e\u4e86 \"Chinese_China.utf-8\" \u6548\u679c\u548c\u4f60\u5728\u63a7\u5236\u9762\u677f\u5168\u5c40\u5f00\u4e86\u90a3\u4e2a \u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u5168\u7403\u8bed\u8a00\u5b9e\u9a8c\u652f\u6301\u201d \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u662f\u4ec5\u9650\u5f53\u524d\u8fdb\u7a0b\u7684 C/C++ \u6807\u51c6\u5e93\u3002 \u800c\u4e14\u7531\u4e8e argv \u5728\u4f60\u6765\u5f97\u53ca setlocale \u4e4b\u524d\u5c31\u5df2\u7ecf\u521d\u59cb\u5316\uff0c\u6240\u4ee5 main \u7684 argv \u53c2\u6570\u4f9d\u7136\u662f GBK \u7f16\u7801\u7684\uff0c\u9664\u975e\u4f60\u4f7f\u7528\u7684\u662f _wmain \uff0c\u90a3\u5c06\u80fd\u6536\u5230 UTF-16 \u7684 argv \uff0c\u7136\u540e\u4f60\u81ea\u5df1\u8f6c\u6362\u56de UTF-8\u3002","title":"locale \u7684\u547d\u540d\u89c4\u8303"},{"location":"unicode/#locale_3","text":"\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u63a5\u53d7\u73af\u5883\u4e2d\u7684\u8bbe\u7f6e\uff0c\u5bf9\u4e8e Linux \u800c\u8a00\u662f $LC_ALL \u73af\u5883\u53d8\u91cf\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f\u63a7\u5236\u9762\u677f\u4e2d\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 setlocale(LC_ALL, \"\"); // \u662f\u7684\uff0c\u7a7a\u7684\u5b57\u7b26\u4e32 \u6ce8\u610f\u662f\u7a7a\u5b57\u7b26\u4e32 \"\" \u624d\u6709\u8fd9\u6837\u7684\u6548\u679c\uff0c\u800c\u4e0d\u662f NULL\uff01 setlocale(LC_ALL, NULL) \u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u4ed6\u7684\u6548\u679c\u662f\u8fd4\u56de\u5f53\u524d\u7684 locale\uff08\u6ca1\u60f3\u5230\u5427\uff1fsetlocale \u6709\u8fd4\u56de\u503c\uff09\u3002\u8fd9\u5c31\u662f C \u8bed\u8a00\u7684\u9b45\u529b\uff0c\u540c\u4e00\u4e2a\u51fd\u6570\u62c6\u6210\u597d\u51e0\u5206\u7528\uff0c\u53c8\u80fd set \u53c8\u80fd get\uff0c\u5c41\u80a1\u5341\u5206\u7075\u6d3b\u3002 \u4e5f\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u90e8\u5206\u4e3a\u7a7a\u7684 locale \u540d\u5b57\uff0c\u6bd4\u5982 \".utf-8\" \uff0c\u4ed6\u8868\u793a\u4fdd\u7559\u5f53\u524d\u73af\u5883\u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\uff0c\u4f46\u201c\u7f16\u7801\u201d\u90e8\u5206\u66ff\u6362\u4e3a\u201c.utf-8\u201d\u3002 setlocale(LC_ALL, \".utf-8\"); // \u5728\u4e2d\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u5728\u7f8e\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"English_United States.utf-8\");","title":"\u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32"},{"location":"unicode/#localec","text":"\u4e0d\u559c\u6b22\u672c\u5730\u5316\u8fd9\u4e00\u5957\u8bbe\u5b9a\uff1f \u4f60\u53ef\u4ee5\u8bbe\u7f6e LC_ALL \u4e3a \"C\" \u6216 \"POSIX\" \uff0c\u8fd9\u662f\u6807\u51c6\u5e93\u9884\u5148\u5b9a\u4e49\u597d\u7684\u4e24\u4e2a locale\uff0c\u4ed6\u4eec\u7684\u7279\u70b9\u662f\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u672c\u5730\u5316\uff0c\u800c\u662f\u59cb\u7ec8\u4ee5\u82f1\u6587\u663e\u793a\u3002\u8fd9\u5728\u8c03\u8bd5\u7a0b\u5e8f\u65f6\u975e\u5e38\u6709\u7528\uff0c\u56e0\u4e3a\u8fd9\u6837\u4f60\u53ef\u4ee5\u786e\u5b9a\u8f93\u51fa\u7684\u683c\u5f0f\u662f\u56fa\u5b9a\u7684\uff0c\u4e0d\u4f1a\u88ab\u7528\u6237\u7684\u73af\u5883\u548c\u672c\u5730\u5316\u7684\u4fe1\u606f\u800c\u6539\u53d8\u3002 \u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u4f60\u6ca1\u6709 setlocale \u8fc7\uff0cC \u8bed\u8a00\u9ed8\u8ba4\u5c31\u662f \"C\" locale\uff0c\u4e0d\u4f1a\u53d7\u5230\u7528\u6237\u73af\u5883\u53d8\u91cf\u7684\u4efb\u4f55\u5f71\u54cd\uff08Windows \u7684\u6587\u4ef6\u7cfb\u7edf API \u9664\u5916\uff0c\u786e\u5b9e\u4f1a\u53d7\u5230 GBK \u5f71\u54cd\uff09\u3002 setlocale(LC_ALL, \"C\"); setlocale(LC_ALL, \"POSIX\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 \u4e0d\u8fc7\uff0c \"C\" \u610f\u5473\u7740\u4ed6\u5047\u5b9a\u5b57\u7b26\u4e32\u662f\u5b8c\u5168\u7684 ASCII\uff0c\u8d85\u8fc7 ASCII \u7684\u90e8\u5206\u662f\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff1a\u5bf9\u4e8e Linux \u800c\u8a00\u662f UTF-8\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u4e0d\u505a\u4efb\u4f55\u5904\u7406\uff0c\u56e0\u4e3a Linux \u7684 ext4 \u6587\u4ef6\u7cfb\u7edf\u6ca1\u6709\u5b57\u7b26\u7f16\u7801\u7684\u533a\u5206\uff09\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f GBK\uff08\u4e2d\u56fd\u533a\uff09\u3002 \u56e0\u6b64\uff0c\u4e5f\u6709 \"C.utf-8\" \u8fd9\u6837\u7684 locale\uff0c\u4ed6\u8868\u793a\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u53ef\u4ee5\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u652f\u6301 Unicode \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u4e5f\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6253\u5370 ASCII \u4ee5\u5916\u7684\u5b57\u7b26\u4e86\u3002\u53ea\u662f\u6ca1\u6709\u6307\u5b9a\u8bed\u8a00\uff0c\u901a\u5e38\u6765\u8bf4\u8fd9\u65f6 strerror \u4e00\u7c7b\u51fd\u6570\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u82f1\u8bed\u7684\u6d88\u606f\u3002 \u4f46\u4f3c\u4e4e\u53ea\u5728 Linux \u4e0a\u6709\u6548\uff0cWindows \u53ea\u652f\u6301 \"C\" \u800c\u4e0d\u652f\u6301 \"C.utf-8\" \u3002","title":"\u7279\u6b8a locale\uff1a\"C\""},{"location":"unicode/#lc_","text":"locale \u5206\u4e3a\u8bb8\u591a\u4e2a\u201c\u65b9\u9762 (facet)\u201d\uff0c\u4e0d\u540c\u7684\u65b9\u9762\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u53d6\u503c\uff08\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u662f\u4e00\u6837\u7684\uff09\uff0c\u53ef\u4ee5\u5ba2\u5236\u5316\u6807\u51c6\u5e93\u4e0d\u540c\u90e8\u5206\u6d89\u53ca\u8bed\u8a00\u548c\u7f16\u7801\u76f8\u5173\u7684\u884c\u4e3a\u3002\u8fd9\u4e9b\u65b9\u9762\u5728 C \u8bed\u8a00\u4e2d\u90fd\u6709\u4e00\u4e2a LC_ \u5f00\u5934\u7684\u679a\u4e3e\u6765\u8868\u793a\u3002 LC_CTYPE \u53ea\u5f71\u54cd ctype.h \u4e2d\u7684\u51fd\u6570\uff0c\u4e5f\u5c31\u662f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u8fd8\u6709 toupper \uff0c tolower \u7b49\uff0c\u4ed6\u8fd8\u5f71\u54cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\u65b9\u9762\u3002 LC_TIME \u5f71\u54cd\u65f6\u95f4\u548c\u65e5\u671f\u7684\u683c\u5f0f\u5316\uff0c\u4f8b\u5982 asctime \u7b49\u3002 LC_NUMERIC \u5f71\u54cd\u6570\u5b57\u7684\u683c\u5f0f\u5316\u3002 LC_MONETARY \u5f71\u54cd\u8d27\u5e01\u7684\u683c\u5f0f\u5316\u3002 LC_MESSAGES \u5f71\u54cd strerror \u7b49\u4fe1\u606f\u7c7b\u51fd\u6570\u8fd4\u56de\u7684\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\u5728\u4e2d\u6587 locale \u4e0b strerror(EPERM) \u4f1a\u8fd4\u56de \"\u6743\u9650\u4e0d\u591f\" \uff0c\u800c\u5728\u82f1\u6587 locale \u4e0b\u8fd4\u56de \"Permission denied.\" \u3002 LC_ALL \u662f\u5168\u5c40 locale\uff0c\u5b83\u4f1a\u5f71\u54cd\u4ee5\u4e0a\u6240\u6709\u6807\u51c6\u5e93\u51fd\u6570\u7684\u884c\u4e3a\u3002\u8bbe\u7f6e LC_ALL \u4e3a\u4e00\u4e2a\u503c\uff0c\u7b49\u540c\u4e8e\u4e3a\u4ee5\u4e0a\u6240\u6709\u90fd\u8d4b\u4e88\u7edf\u4e00\u7684\u503c\u3002 \u4f60\u53ef\u4ee5\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u8bbe\u7f6e $LC_ALL \u3001`$LC_CTYPE \u6240\u6709 GNU/Linux \u81ea\u5e26\u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u90fd\u5728 main \u51fd\u6570\u5f00\u5934\uff0c\u914d\u5907\u4e86 setlocale(LC_ALL, \"\"); \u3002\u8fd9\u4f1a\u8bfb\u53d6\u7528\u6237\u914d\u7f6e\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u533a\u57df\u504f\u597d\u8bbe\u7f6e\uff0c\u5e76\u8bbe\u4e3a\u5168\u5c40\u7684 locale\u3002 \u53ef\u4ee5\u7406\u89e3\u4e3a locale \u662f\u4e00\u4e2a\u9690\u85cf\u5728\u6807\u51c6\u5e93\u4e2d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u6240\u6709\u7684 iswpunct \u3001 asctime \u3001 strerror \u90fd\u4f1a\u8bfb\u53d6\u8be5\u5168\u5c40\u53d8\u91cf\u91cc\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u6765\u51b3\u5b9a\u81ea\u5df1\u7684\u8fd0\u884c\u65f6\u884c\u4e3a\u3002","title":"LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf"},{"location":"unicode/#lc_messages","text":"\u4f8b\u5982 touch \u8fd9\u4e9b\u547d\u4ee4\uff0c\u90fd\u662f\u57fa\u4e8e strerror \u6253\u5370\u62a5\u9519\u6d88\u606f\u7684\uff0c\u800c strerror \u53c8\u57fa\u4e8e\u533a\u57df\u8bbe\u7f6e\u7684 LC_MESSAGES \u65b9\u9762\u3002 \u8fd9\u4e9b\u547d\u4ee4\u884c\u7a0b\u5e8f\u7684\u4f5c\u8005\u65e0\u9700\u61c2\u5f97\u6240\u6709\u8bed\u8a00\uff0c\u4ed6\u4eec\u53ea\u9700\u8981\u8c03\u7528 strerror \u548c\u5404\u79cd messages \u67e5\u627e\u51fd\u6570\uff0c\u83b7\u5f97\u76f8\u5e94\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u540e\uff0c\u8f93\u51fa\u5373\u53ef\u81ea\u52a8\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7528\u6237\u7684\u9700\u6c42\u3002 \u53ea\u9700\u8981\u8bed\u8a00\u7684\u7528\u6237\uff0c\u5728\u4ed6\u7684\u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u8bbe\u7f6e LC_ALL=zh_CN.UTF-8 \u5c31\u53ef\u4ee5\u8ba9\u547d\u4ee4\u884c\u7a0b\u5e8f\u4eec\u59cb\u7ec8\u8f93\u51fa\u4e2d\u6587\u6d88\u606f\u4e86\u3002 $ export LC_MESSAGES=en_US.UTF-8 $ touch /root/a touch: cannot touch '/root/a': Permission denied $ export LC_MESSAGES=zh_CN.UTF-8 $ touch /root/a touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f \u4f8b\u5982 GCC \u7684\u62a5\u9519\u4fe1\u606f\uff0c\u5c31\u662f\u57fa\u4e8e\u4f60\u7684 $LC_MESSAGES \u73af\u5883\u53d8\u91cf\u6765\u51b3\u5b9a\u8f93\u51fa\u4f55\u79cd\u8bed\u8a00\u7684\u4fe1\u606f\u7684\u3002 \u4f60\u4e5f\u53ef\u4ee5\u53ea\u8bbe\u7f6e\u4e00\u4e2a export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u6837\u5c31\u65e0\u9700\u8bbe\u7f6e\u5176\u4ed6\u6240\u6709\u7684\u65b9\u9762 (facet)\uff0c\u5982\u65e0\u5355\u72ec\u8bbe\u7f6e\uff0c\u5176\u4ed6\u65b9\u9762\u4f1a\u81ea\u52a8\u53d8\u5f97\u548c $LC_ALL \u4e00\u6837\u3002","title":"LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f"},{"location":"unicode/#lc_ctype","text":"\u8fd9\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\uff0c\u4ed6\u51b3\u5b9a\u4e86\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u683c\u5f0f\u3002 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u5185\u90e8\u90fd\u4ee5\u5185\u7801\uff08 const wchar_t * \u6216 std::wstring \uff09\u6765\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u5f53\u8f93\u51fa\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u7684\u5185\u7801\u5b57\u7b26\u4e32\uff08 wchar_t * \uff09\u4f1a\u4ee5 LC_CTYPE \u6307\u5b9a\u7684\u7f16\u7801\u683c\u5f0f\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6d41\uff08 const char * \u6216 std::string \uff09\u540e\u8f93\u51fa\u5230\u63a7\u5236\u53f0\u3002 \u56e0\u6b64\uff0c LC_CTYPE \u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\u662f\u65e0\u5173\u7d27\u8981\u7684\uff0c\u91cd\u8981\u7684\u662f\u540e\u534a\u6bb5\uff0c\u4f8b\u5982 \"zh_CN.UTF-8\" \uff0c\u90a3\u6709\u5f71\u54cd\u7684\u5c31\u53ea\u662f\u540e\u9762\u8fd9\u6bb5 \".UTF-8\" \u3002 \u52a1\u5fc5\u4f7f\u7528\u548c\u4f60\u7ec8\u7aef\u914d\u7f6e\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u4e71\u7801\u3002\u4f8b\u5982\u5f53\u6211\u6b3a\u9a97 touch \uff0c\u8ba9\u4ed6\u8bef\u4ee5\u4e3a\u6211\u7684\u7ec8\u7aef\u8f93\u51fa\u9700\u8981\u662f GBK \u7f16\u7801\uff1a $ export LC_MESSAGES=zh_CN.UTF-8 $ export LC_CTYPE=zh_CN.GBK # \u6b3a\u9a97 touch\uff01\u597d\u574f $ touch /root/a touch: \ufffd\u07b7\ufffd touch '/root/a': \u0228\ufffd\u07b2\ufffd\ufffd\ufffd \u4ed6\u5c31\u8f93\u51fa\u4e86\u8be1\u5f02\u7684\u4e71\u7801\u3002\u8fd9\u4e0d\u662f touch \u7684\u95ee\u9898\uff0ctouch \u53ea\u662f\u6309\u7167\u4f60\u73af\u5883\u53d8\u91cf $LC_CTYPE \u8bf4\u7684 GBK \u7f16\u7801\uff0c\u8f93\u51fa\u4e86 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u3002\u800c\u7ec8\u7aef\u7684\u8bbe\u7f6e\u5374\u662f UTF-8\uff0c\u7528 UTF-8 \u89e3\u7801 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u5f53\u7136\u51fa\u9519\u4e86\uff0c\u4e0d\u8fc7\u7531\u4e8e GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u8fd9\u91cc\u9762\u82f1\u6587\u90e8\u5206\u624d\u4fa5\u5e78\u6b63\u5e38\u663e\u793a\u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\u8981\u4e48\u4f60 $LC_CTYPE \u8bbe\u56de UTF-8\uff0c\u8981\u4e48\u628a\u7ec8\u7aef\u6539\u6210 GBK\uff0c\u603b\u4e4b $LC_CTYPE \u5fc5\u987b\u548c\u7ec8\u7aef\u5b57\u7b26\u7f16\u7801\u914d\u7f6e\u4e00\u6837\u3002\u4e5f\u53ef\u4ee5\u8c03\u7528 iconv \u628a touch \u7684 GBK \u8f93\u51fa\u8f6c\u6362\u56de UTF-8\uff0c\u4f9b UTF-8 \u7684\u7ec8\u7aef\u8bfb\u53d6\uff1a $ touch /root/a 2>&1 | iconv -f GBK -t UTF-8 touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f","title":"LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#lc_time","text":"LC_TIME \u5f71\u54cd\u7684\u662f\u548c\u65f6\u95f4\u6709\u5173\u51fd\u6570\u7684\u8f93\u51fa\u683c\u5f0f\uff0c\u56e0\u4e3a\u4e0d\u540c\u7684\u5730\u533a\u6709\u4e0d\u540c\u7684\u65f6\u95f4\u663e\u793a\u4e60\u60ef\uff0c\u6bd4\u5982\u82f1\u6587\u662f Jan 1 00:00 \uff0c\u4e2d\u6587\u662f 1\u6708 1\u65e5 00\u65f600\u5206 \uff0c\u800c\u65e5\u672c\u4eba\u5219\u662f 1\u67081\u65e5 0\u66420\u5206 \u3002 $ export LC_TIME=en_US.UTF-8 $ date Fri Jul 19 04:01:49 PM CST 2024 $ export LC_TIME=zh_CN.UTF-8 $ date 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16:01:07 CST \u5728 C \u8bed\u8a00\u4e2d\uff0c\u4f60\u53ef\u4ee5\u7528\u8fd9\u6837\u683c\u5f0f\u5316\u65f6\u95f4\u548c\u65e5\u671f\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); struct tm *tm = localtime(&t); char buf[32]; strftime(buf, sizeof(buf), \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\", tm); puts(buf); } C++ \u63d0\u4f9b\u4e86\u57fa\u4e8e\u6d41\u7684\uff0c\u66f4\u201c\u65f6\u5c1a\u201d\u7684\u5199\u6cd5\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); tm *tm = localtime(&t); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206","title":"LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316"},{"location":"unicode/#stdlocale","text":"C \u8bed\u8a00\u7684 setlocale \u8bbe\u7f6e\u7684\u662f\u5168\u5c40 locale\uff0c\u5168\u5c40 locale \u53ea\u6709\u4e00\u4e2a\uff0c\u4e00\u8bbe\u5c31\u5f71\u54cd\u6240\u6709\u7ebf\u7a0b\uff0c\u975e\u5e38\u6c99\u96d5\u3002\u56e0\u6b64\u63d0\u5021\u201c\u4e0d\u8981\u72b6\u6001\u673a\u8981\u5bf9\u8c61\u201d\u7684 C++\uff0c\u5c01\u88c5\u4e86 std::locale \u5bf9\u8c61\u3002 std::locale \u7684\u6784\u9020\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u548c setlocale \u7684\u60c5\u51b5\u4e00\u6837\uff0c\u6709\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u73af\u5883 locale\uff0c \"C\" \u8868\u793a POSIX locale\uff0c\u8fd8\u6709\u81ea\u5b9a\u4e49\u5b57\u7b26\u4e32\u6bd4\u5982 \"zh_CN.UTF-8\" \u7684 locale\u3002 \u7136\u540e\uff0cC++ \u7684\u6d41\u7c7b\u578b\uff0c\u5982 std::cout \uff0c\u90fd\u6709\u4e00\u4e2a .imbue \u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u5c40\u90e8 locale\uff08\u53ea\u5bf9 std::cout \u751f\u6548\u7684\uff09\uff0c\u63a5\u53d7\u7684\u5c31\u662f\u8fd9\u4e2a std::locale \u5bf9\u8c61\u3002 #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 2024\u5e74 07\u6708 19\u65e5 Fri 16\u65f6 01\u5206 \u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\u53ea\u6709\u661f\u671f\u7684\u5b57\u7b26\u4e32\u53d7\u5230\u4e86\u5f71\u54cd\u3002\u5982\u679c\u8981\u4f7f\u6574\u4e2a\u65e5\u671f\u683c\u5f0f\u90fd\u8ddf\u968f LC_TIME \u7684\u8bbe\u5b9a\uff0c\u53ef\u7528 \"%c\" \uff1a #include #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%c\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%c\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e7407\u670819\u65e5 \u661f\u671f\u4e94 16\u65f633\u520639\u79d2 Fri 19 Jul 2024 04:33:39 PM CST \u5173\u4e8e \"%c\" \u3001 \"%Y\" \u8fd9\u4e9b\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u7684\u66f4\u591a\u8be6\u7ec6\u7528\u6cd5\uff0c\u53c2\u89c1 man strftime \u3002\u6211\u4eec\u4f5c\u4e3a\u5b57\u7b26\u7f16\u7801\u7684\u8bfe\u7a0b\u4e0d\u518d\u8d58\u8ff0\uff0c\u4e4b\u540e\u7684\u65f6\u95f4\u4e0e\u65e5\u671f\u4e13\u9898\u8bfe\u4e5f\u4f1a\u7a0d\u5fae\u8bb2\u4e00\u4e0b\u3002","title":"std::locale \u5bf9\u8c61"},{"location":"unicode/#boostlocalegenerator-locale","text":"boost::locale::generator gen; auto loc = gen(\"zh_CN.UTF-8\"); boost::locale::date_time dt = boost::locale::date_time::now(loc); std::cout << boost::locale::as::date(dt) << '\\n';","title":"boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale"},{"location":"unicode/#_19","text":"\u4e4b\u6240\u4ee5\u628a\u5bbd\u5b57\u7b26\u6d41\u653e\u5230\u6700\u540e\uff0c\u662f\u56e0\u4e3a\uff0c\u9996\u5148 iostream \u672c\u6765\u5c31\u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728\u672c\u4e66\u5f00\u5934\u5c31\u591a\u6b21\u5f3a\u8c03\u8fc7\u4ed6\u662f format \u5b5d\u5b50\u3002 \u800c\u5bbd\u5b57\u7b26 wchar_t \u672c\u8eab\u5c31\u5145\u65a5\u7740\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff08\u4f8b\u5982 Windows \u88ab UTF-16 \u80cc\u523a\uff09\u3002 \u73b0\u5728 iostream \u4e0e wchar_t \u4e00\u8d77\u51fa\u73b0\u5728\u6211\u9762\u524d\uff0c\u4e0d\u80fd\u8bf4\u662f\u68a6\u5e7b\u8054\u52a8\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u7b54\u8fa9\u8d85\u4eba\u4e86\u3002 \u603b\u4e4b\uff0c\u6211\u4e2a\u4eba\u8fd8\u662f\u63a8\u8350\u7a0b\u5e8f\u5185\u90e8\u4ee5 UTF-8\uff08 char8_t \uff09\u6216 UTF-32\uff08 char32_t \uff09\u7684\u5b57\u7b26\u4e32\u6765\u5904\u7406\u4e07\u7269\u3002 UTF-8 \u6216 UTF-32 \u7684\u9009\u62e9\u53d6\u51b3\u4e8e\u4f60\u7684\u4e2d\u6587\u5904\u7406\u9700\u6c42\u662f\u5426\u65fa\u76db\uff0c\u662f\u5426\u5728\u4e4e\u7a7a\u95f4\uff0c\u662f\u5426\u9700\u8981\u5207\u7247\u548c\u7d22\u5f15\u7b49\u3002 \u5f53\u9700\u8981\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u8bfb\u5199\u6587\u4ef6\u65f6\uff0c\u518d\u7528 boost::locale \u3001 utfcpp \u7b49\u5de5\u5177\u8f6c\u6362\u6210 ANSI\uff08 char \uff09\u6216 UTF-16\uff08 wchar_t \uff09\u3002 \u5bf9\u4e8e Linux \u7528\u6237\uff0c\u4e5f\u53ef\u4ee5\u68c0\u6d4b\u5982\u679c\u662f Linux \u7cfb\u7edf\uff0c\u5219\u4ec0\u4e48\u8f6c\u6362\u90fd\u4e0d\u505a\uff0c\u56e0\u4e3a Linux \u7528\u6237\u51e0\u4e4e\u90fd\u662f UTF-8\uff0c\u90a3\u4e48 const char8_t * \u53ef\u4ee5\u5f3a\u8f6c\u4e3a const char * \u800c\u4e0d\u7528\u4efb\u4f55\u989d\u5916\u5f00\u9500\u3002 std::string to_os_string(std::string const &u8s) { #if _WIN32 // UTF-8 \u5230 ANSI return boost::locale::conv::from_utf(u8s, \"\"); #elif __linux__ // \u4e0d\u8f6c\u6362 return u8s; #else #error \"Unsupported system.\" #endif } \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u5b9e\u5728\u8981\u5b66\u7cdf\u7cd5\u7684\u5bbd\u5b57\u7b26\u6d41\uff0c\u90a3\u6211\u4e5f\u5949\u966a\u5230\u5e95\u3002","title":"\u5bbd\u5b57\u7b26\u6d41"},{"location":"unicode/#stdwstring","text":"\u5728\u4ed6\u4eec\u770b\u6765\uff0c std::string \u662f\u5df2\u7ecf\u5e9f\u5f03\u7684\u3002\u4ed6\u4eec\u8ba4\u4e3a std::wstring \u624d\u662f\u771f\u6b63\u8de8\u5e73\u53f0\u7684\u5b57\u7b26\u4e32\u3002 std::wstring : \u5b57\u7b26\u4e32 std::string : \u5b57\u8282\u6570\u7ec4 std::wifstream : \u6587\u672c\u6d41 std::ifstream : \u4e8c\u8fdb\u5236\u6d41 \u770b\u8d77\u6765\u53ea\u8981\u5168\u90e8\u7edf\u4e00 wchar_t \u5c31\u80fd\u5b9e\u73b0\u8de8\u5e73\u53f0\u4e86\uff1f\u662f\u7684\uff0c\u9664\u4e86 Windows\u2026\u2026 \u6807\u51c6\u8ba4\u4e3a wchar_t \u5e94\u8be5\u5305\u542b 0 \u5230 0x10FFFF \u7684\u6240\u6709\u7684 Unicode \u5b57\u7b26\u7801\u70b9\uff0c\u9700\u8981\u662f 32 \u4f4d\u7684\u3002\u7136\u800c Windows \u7684 wchar_t \u7531\u4e8e\u5386\u53f2\u539f\u56e0\uff0c\u662f 16 \u4f4d\u7684\uff0c\u9700\u8981\u7528\u4ee3\u7406\u5bf9\u624d\u80fd\u8868\u793a\u7a00\u6709\u5b57\u7b26\uff0c\u5e76\u4e0d\u80fd\u4e00\u4e2a wchar_t \u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002\u8fd9\u5bfc\u81f4\u5373\u4f7f\u7528\u4e86 wchar_t \u8fd8\u662f\u5b58\u5728\u8de8\u5e73\u53f0\u56f0\u96be\u7684\u95ee\u9898\uff1a\u4e00\u4e2a Linux \u7a0b\u5e8f\u7528 wchar_t \u53ef\u80fd\u4f1a\u5229\u7528 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u7279\u6027\uff0c\u65b9\u4fbf\u4e86\u6587\u672c\u5904\u7406\uff0c\u4f46\u79fb\u690d\u5230 Windows \u65f6\uff0c\u53d1\u73b0\u53d8\u6210\u4e86 UTF-16\uff0c\u9700\u8981\u5bf9\u4ee3\u7406\u5bf9\u505a\u7279\u6b8a\u5224\u65ad\u2026\u2026\u6ca1\u6709\u6ee1\u8db3\u8de8\u5e73\u53f0\u7684\u521d\u8877\uff0c\u4e5f\u505a\u4e0d\u5230\u5b9a\u957f\u7f16\u7801\u3002 char32_t \u505a\u5230\u4e86\u8de8\u5e73\u53f0\u7684 UTF-32\uff0c\u4e5f\u80fd\u5bb9\u7eb3\u5168\u90e8 Unicode \u7801\u70b9\uff0c\u53ef\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::to_wstring \uff0c\u5374\u6839\u672c\u6ca1\u6709 std::to_u32string \uff1b\u63d0\u4f9b\u4e86 std::wcout \uff0c\u5374\u6ca1\u6709\u63d0\u4f9b std::u32cout \u2026\u2026 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u5bbd\u5b57\u7b26\u6d41\u5f88\u7cdf\u7cd5\uff0c\u8bf4\u662f\u8de8\u5e73\u53f0\uff0c\u8de8\u4e86\u4e2a\u5bc2\u5bde\u3002","title":"\u5b98\u65b9\u773c\u4e2d\u7684 std::wstring"},{"location":"unicode/#stdwcout","text":"","title":"std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e"},{"location":"unicode/#stdwcout-locale","text":"\u8981\u4f7f\u7528 std::wcout \u4e4b\u524d\uff0c\u9700\u8981\u7528 .imbue \u8bbe\u7f6e\u5e26\u6709\u6b63\u786e LC_CTYPE \u65b9\u9762\u7684 locale\uff0c\u6216\u8005\u8bbe\u7f6e\u4e86 C \u8bed\u8a00\u7684\u5168\u5c40\u7684 setlocale \uff0c\u5426\u5219\u4e2d\u6587\u5b57\u7b26\u4f1a\u88ab\u4e22\u6389\u3002 int main() { std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u9519\u8bef\uff01\u4f60\u8fd8\u6ca1\u8bbe\u7f6e locale \u5462\uff01 return 0; } \u8f93\u51fa\uff1a Hello, ??! \u8fd9\u662f\u56e0\u4e3a\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \uff0c\u4ed6\u53ea\u652f\u6301 ASCII \u7684\u3002\u800c\u5f53 std::wcout \u9047\u5230\u8d85\u51fa\u5f53\u524d locale \u5b57\u7b26\u96c6\u8868\u793a\u8303\u56f4\u7684\u5b57\u7b26\u65f6\uff0c\u4f1a\u4e22\u5f03\uff0c\u66ff\u6362\u4e3a ? \u5b57\u7b26\uff0c\u8868\u793a\u51fa\u9519\u4e86\u3002 \u56e0\u6b64\uff0c std::wcout \u7684\u6b63\u786e\u7528\u6cd5\u5fc5\u987b\u662f\u5728\u4f60\u6253\u5370\u7b2c\u4e00\u6761\u8f93\u51fa\u524d\uff0c\u5c31 setlocale(LC_ALL, \"\") \uff0c\u9ed8\u8ba4\u7684 \"C\" \u80af\u5b9a\u662f\u4e0d\u884c\u7684\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u8f93\u51fa\uff1a Hello, \u4f60\u597d! \u6216\u8005\u7528 std::wcout \u7684 .imbue \u4e5f\u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u6837\u5bf9\u4e8e std::wcerr \u548c std::wclog \u4f60\u4e5f\u9700\u8981\u505a\u540c\u6837\u7684\u52a8\u4f5c\uff0c\u611f\u89c9\u4e0d\u5982\u7d22\u6027\u5168\u5c40\u8bbe\u7f6e\u4e86 setlocale \u65b9\u4fbf\u3002 int main() { std::wcout.imbue(std::locale(\"\")); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u5982\u679c\u4f60\u662f UTF-8 \u6d41\u6d3e\uff0c\u9009\u62e9 setlocale(LC_ALL, \".utf-8\") \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u53ea\u8981\u662f\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u7684 locale \u5c31\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6b63\u5e38\u8f93\u51fa\u4e2d\u6587\uff0c\u53ea\u8981\u4f60\u7ec8\u7aef\u7684\u8bbe\u7f6e\u4e5f\u662f\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\u7edd\u5bf9\u4e0d\u4f1a\u4e71\u7801\u3002 \u4f8b\u5982\u5f53\u4f60 setlocale(LC_ALL, \".utf-8\") \u540e\u5c31\u9700\u8981 system(\"chcp 65001\") \uff1b\u5f53\u4f60 setlocale(LC_ALL, \"Chinese_China.936\") \u540e\u5c31\u9700\u8981 system(\"chcp 936\") \u3002\u603b\u4e4b\uff0c\u59cb\u7ec8\u4fdd\u8bc1\u7ec8\u7aef\uff08 cmd \u6216 xfce4-terminal \uff09\u8bbe\u7f6e\u7684\u7f16\u7801\u548c\u4f60\u7a0b\u5e8f\u91cc setlocale(LC_CTYPE, ...) \u8bbe\u7f6e\u7684\u7f16\u7801\u4e00\u81f4\u3002","title":"std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528"},{"location":"unicode/#stdwcout-stdstring","text":"\u6709\u7684\u4eba\u4f1a\u7528 std::wcout \u4f3c\u4e4e\u4e5f\u80fd\u6253\u5370 char \u7684\u5b57\u7b26\u4e32\uff1f int main() { setlocale(LC_ALL, \"\"); std::wcout << \"Hello, \u4f60\u597d!\\n\"; // \u4e0d\u4e00\u5b9a\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587\uff01 std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // OK\uff0c\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587 return 0; } \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u7528\u6cd5\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u5e94\u8be5\u8981\u62a5\u9519\uff0c\u4f46\u662f\u7cdf\u7cd5\u7684\u6807\u51c6\u5e93\u5374\u6ca1\u6709\uff0c\u8bbe\u8ba1\u7684\u5931\u8bef\u3002 \u8bbe\u8ba1\u7684\u521d\u8877\u662f\uff0c\u53ef\u4ee5\u5728\u6253\u5370\u5e26\u4e2d\u6587\u7684\u5b57\u7b26\u4e32\u540e\uff0c\u65b9\u4fbf\u4f60\u4e34\u65f6\u6253\u5370\u4e00\u4e9b char \u7684\u5b57\u7b26\u4e32\u548c\u5b57\u7b26\uff0c\u4f8b\u5982 '\\n' \uff08\u56e0\u4e3a\u603b\u662f\u6709\u7684\u4eba\u60f3\u5077\u61d2\u4e0d\u5199 L\"\" \u524d\u7f00\uff09 std::wcout \u652f\u6301\u6253\u5370 char \u548c const char * \uff0c\u4ed6\u4f1a\u81ea\u52a8\u5e2e\u4f60\u628a\u8fd9\u90e8\u5206 char \u8f6c\u6210 wchar_t \u518d\u6253\u5370\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\" << L'\\n'; // \u6b63\u5e38\u5199\u6cd5 std::wcout << L\"Hello, \u4f60\u597d!\" << '\\n'; // \u61d2\u60f0\u72d7\u72d7\u5199\u6cd5 return 0; } \u4f46\u662f\uff0c\u8fd9\u90e8\u5206 char \u5e94\u5f53\u53ea\u5305\u542b ASCII \u5b57\u7b26\uff0c\u4e0d\u5e94\u8be5\u6709\u4e2d\u6587\u5b57\u7b26\uff0c\u5426\u5219\u53ef\u80fd\u53c8\u8981\u51fa\u73b0\u4e4b\u524d\u63d0\u5230\u7684 \u201cgalgame\u201d \u4e71\u7801\u95ee\u9898\u4e86\u3002","title":"std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string"},{"location":"unicode/#stdwcout-stdcout","text":"\u975e\u5e38\u5751\u7684\u4e00\u4e2a\u70b9\uff1a\u4e00\u65e6\u4f60\u51b3\u5b9a\u7528 std::wcout \u540e\uff0c\u5c31\u4e0d\u80fd\u518d\u7528 std::cout \u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u5b9e\u6d4b\u7528\u8fc7 std::wcout \u540e\uff0c\u4f60\u7684 std::cout \u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4e0d\u51fa\u4efb\u4f55\u4e1c\u897f\u3002 \u4e0a\u4e86\u8d3c\u8239\u5c31\u4e0a\u5230\u5e95\u5427\uff01\u5982\u679c\u786e\u5b9e\u9700\u8981\u4e34\u65f6\u6253\u5370\u4e00\u4e9b std::string \uff0c\u5e76\u4e14\u786e\u4fdd\u91cc\u9762\u662f ASCII \u7684\u8bdd\uff0c\u53ef\u4ee5\u5229\u7528\u4e0a\u9762\u4e00\u8282\u8bf4\u7684\u201c\u61d2\u60f0\u72d7\u72d7\u5199\u6cd5\u201d\u7cca\u5f04\u4e0b\uff0c\u5982\u679c\u662f GBK \u6216 UTF-8 \u7684 std::string \u9700\u8981\u6253\u5370\u5230 std::wcout \uff0c\u5c31\u53ec\u5524\u4e00\u4e0b boost::locale \u5427\u3002 std::wprintf \u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5f53\u4f60\u7b2c\u4e00\u6b21\u4f7f\u7528 FILE * \u7684 wchar_t \u7cfb\u5217\u51fd\u6570\u540e\uff0c\u8fd9\u4e2a\u6587\u4ef6\u6d41\u4f1a\u88ab\u201c\u5bbd\u5316\u201d ( fwiden )\uff0c\u7528\u6211\u4eec\u7684\u8bdd\u8bf4\u53eb \u4e0a\u8d3c\u8239 \uff0c\u4e0a\u4e86\u5c31\u4e0b\u4e0d\u6765\uff0c\u518d\u4e5f\u65e0\u6cd5\u5f53\u4f5c\u201c\u7a84\u201d\u6d41\u7528\u4e86\u3002 \u53cd\u4e4b\u4ea6\u7136\uff0c\u4e00\u65e6\u4f60\u7528\u8fc7\u4e00\u6b21 std::cout \u540e\uff0c std::wcout \u5c31\u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4efb\u4f55\u4e1c\u897f\u90fd\u6253\u5370\u4e0d\u51fa\u6765\u3002\u53d6\u51b3\u4e8e\u4f60\u7b2c\u4e00\u6b21\u8c03\u7528\u8f93\u51fa\u6d41\u7528\u7684\u662f\u5bbd\u5b57\u7b26\u8fd8\u662f\u7a84\u5b57\u7b26\uff0c\u4e4b\u540e\u5c31\u53ea\u80fd\u4e00\u76f4\u7528\u90a3\u4e2a\u5bbd\u6216\u7a84\u4e86\uff0c\u4e0d\u8ba9\u8df3\u8239\u3002 \u4e0a\u8d3c\u8239\u4e0d\u884c\uff0c\u4e0a\u8b66\u8239\u4e5f\u4e0d\u884c\uff0c\u4e0a\u5b9a\u4e00\u4e2a\u5c31\u6ca1\u6cd5\u53d8\uff0c\u771f\u6076\u5fc3\u5440\uff01 // \u5148 wcout int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; std::cout << \"\u6211\u662f cout!\" << '\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f wcout! // \u5148 cout int main() { setlocale(LC_ALL, \"\"); std::cout << \"\u6211\u662f cout!\" << '\\n'; std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f cout! / wcout! \u8fd9\u91cc / wcout! \u597d\u50cf\u662f\u51fa BUG \u4e86\u2026\u2026\u4f30\u8ba1\u662f\u8d3c\u88ab\u8b66\u5bdf\u6253\u6389\u4e00\u534a\u8033\u6735\u53d8\u6210 / \u4e86\uff1f\u603b\u4e4b\u5404\u79cd\u6df7\u4e71\uff0c\u8bb0\u4f4f\u4e0d\u8981\u6df7\u7528\u8d3c\u8239\u548c\u8b66\u8239\u5c31\u884c\u4e86\u3002","title":"\u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01"},{"location":"unicode/#stdwfstream","text":"\u6709\u540c\u5b66\u53cd\u6620\uff0cPython \u4e2d\u53ef\u4ee5\u901a\u8fc7 open('path.txt', encoding='gbk') \u6765\u7528\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u800c C++ \u4f3c\u4e4e\u6ca1\u6709\u7b49\u6548\u7684\u66ff\u4ee3\u54c1\u3002 \u5176\u5b9e\u4e00\u76f4\u90fd\u6709\uff0c\u4e0d\u8fc7\u4f60\u4e00\u76f4\u7528\u7684\u662f std::ifstream \u5b9e\u9645\u4e0a\u662f\u4e2a\u201c\u4e8c\u8fdb\u5236\u6d41\u201d\uff01\u8fd9\u79cd\u7eaf\u4e8c\u8fdb\u5236\u7684\u6d41\u6839\u672c\u5c31\u6ca1\u6253\u7b97\u652f\u6301\u5b57\u7b26\u7f16\u7801\u3002\u5373\u4f7f\u6307\u5b9a .imbue \u4e5f\u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u56e0\u4e3a .imbue \u7684\u524d\u63d0\u662f\u5b58\u5728\u201c\u5916\u7801 ( char ) \u5230\u5185\u7801 ( wchar_t ) \u7684\u8f6c\u6362\u201d\uff0c\u4f60\u4e8c\u8fdb\u5236\u6d41\u81f3\u59cb\u81f3\u7ec8\u90fd\u662f\u5916\u7801\uff0c\u54ea\u6765\u7684\u8f6c\u6362\uff1f\u53c8\u6ca1\u6709\u89c4\u5b9a char \u5fc5\u987b\u662f UTF-8\u3002 C++ \u771f\u6b63\u7684\u6587\u672c\u6d41\u5b9e\u9645\u4e0a\u662f\u5bbd\u5b57\u7b26\u6d41 std::wifstream \uff0c\u800c\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u7528 .imbue(std::locale(\"zh_CN.GBK\")) \u2026\u2026\u8bfb\u53d6\u65f6\u4f1a\u8c03\u7528 std::locale \u7c7b\u7684 std::codecvt \uff08\u662f LC_CTYPE \u7684\u4e00\u90e8\u5206\uff09\u65b9\u9762\uff0c\u8f6c\u6362\u4e3a wchar_t \uff0c\u7136\u540e\u8f93\u5165\u4f60\u7684 std::wstring \u3002 C \u548c C++ \u59d4\u5458\u4f1a\u5b98\u65b9\u5c31\u8ba4\u4e3a char * \u662f\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c wchar_t * \u624d\u662f\u6587\u672c\u6d41\uff01\u6240\u6709 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u91cc\u90fd\u662f\u7528 wchar_t \u6765\u5904\u7406\u6587\u672c\u6027\u8d28\u7684\u5b57\u7b26\u4e32\uff0c\u5305\u62ec GCC \u4e5f\u662f\u5927\u91cf\u4f7f\u7528 wchar_t \u4f5c\u4e3a\u5b57\u7b26\u5185\u90e8\u8868\u793a\u3002GCC \u8bfb\u53d6\u6e90\u7801\u6587\u4ef6\u5c31\u662f\u7528\u5bbd\u5b57\u7b26\u6d41\u8bfb\u53d6\u548c\u89e3\u7801\u5230\u5185\u5b58\u4e2d\u7684 UTF-32 \u5b57\u7b26\u4e32 std::wstring \u7684\u3002 \u7406\u8bba\u4e0a\u6240\u6709\u7684\u7a0b\u5e8f\u90fd\u5e94\u8be5\u50cf\u8fd9\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u52b3\u4fdd\u6559\u6750\u4ece\u6765\u4e0d\u63d0\uff0c\u4e00\u53e3\u4e00\u4e2a char [] \u5c31\u662f\u5b57\u7b26\u4e32\uff0c\u641e\u5f97 wchar_t \u5728\u9664\u4e86 GNU \u8fd9\u79cd\u201c\u4f53\u5236\u5185\u201d\u73af\u5883\u4e4b\u5916\uff0c\u6839\u672c\u6ca1\u4eba\u7528\u4e86\u3002\u73b0\u5728\u4e3a\u4e86\u5904\u7406\u4e2d\u6587\u5b57\u7b26\uff0c\u624d\u95f9\u51fa\u4e86 char \u5f53 UTF-8 \u4f7f\u8fd9\u79cd\u62db\u6570\uff0c\u4ee4\u4eba\u550f\u5618\u3002 \u603b\u4e4b\uff0c .imbue(std::locale(\"zh_CN.GBK\")) \u53ef\u4ee5\u628a GBK \u8bbe\u4e3a\u5f53\u524d\u6587\u672c\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5bbd\u6587\u4ef6\u6d41\u5c06\u4f1a\u6309\u7167\u8fd9\u4e2a\u7f16\u7801\u548c\u89e3\u7801\u6240\u6709\u7684\u5b57\u7b26\u4e32\u3002 std::locale \u7684\u5b57\u7b26\u4e32\u6784\u9020\u51fd\u6570\uff0c\u4ed6\u7684\u53c2\u6570\u5fc5\u987b\u662f\u7528\u6237\u7cfb\u7edf\u91cc\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684 locale\uff08\u901a\u8fc7\u4fee\u6539 /etc/locale.gen \u548c locale-gen \u547d\u4ee4\u5b89\u88c5\uff09\u3002\u4f46\u662f\uff0c\u4f60\u65e0\u6cd5\u786e\u4fdd\u7528\u6237\u7684\u7cfb\u7edf\u5b89\u88c5\u4e86 \"GBK\" locale\u3002 std::locale(\"zh_CN.GBK\") \u5728\u6ca1\u6709\u5b89\u88c5 GBK \u7684\u7528\u6237\u7535\u8111\u4e0a\u8fd0\u884c\u5c31\u4f1a\u629b\u51fa\u9519\u8bef\u8868\u793a\u627e\u4e0d\u5230\u8be5 locale\u3002\u56e0\u6b64\uff0c\u5982\u679c\u8981\u6307\u5b9a\u6309 GBK \u8bfb\u53d6\u6587\u4ef6\uff0c\u4e0d\u5efa\u8bae\u4f9d\u8d56\u7cfb\u7edf\u4e2d\u81ea\u5e26\u7684 std::locale(\"zh_CN.GBK\")) \uff0c\u800c\u662f\u8c03\u7528 boost::locale::generator \u5c31\u5730\u751f\u6210\u4e00\u4e2a locale\uff0c\u8fd9\u6837\u7a0b\u5e8f\u65e0\u8bba\u7cfb\u7edf\u6709\u6ca1\u6709\u5b89\u88c5\u90fd\u80fd\u8fd0\u884c\u4e86\uff1a #include #include int main() { std::wofstream fout; boost::locale::generator gen; std::locale loc = gen(\"zh_CN.GBK\"); fout.imbue(loc); fout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4ee5 GBK \u7f16\u7801\u5199\u51fa\u6587\u672c\u6587\u4ef6 } $ cat build/\u4f60\u597d.txt \ufffd\ufffd\u00e3\ufffd\ufffd\ufffd $ cat build/\u4f60\u597d.txt | iconv -f GBK -t UTF-8 \u4f60\u597d\uff0c\u4e16\u754c $ \u8fd9\u662f\u56e0\u4e3a boost_locale \u94fe\u63a5\u4e86 icu \uff0c\u5176\u5185\u90e8\u5305\u542b\u4e86\u6240\u6709\u7f16\u7801\u683c\u5f0f\u7684\u5b57\u7b26\u6620\u5c04\u8868\u3002 boost::locale::generator \u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a std::locale \uff0c\u7136\u540e\u901a\u8fc7\u865a\u51fd\u6570\u91cd\u8f7d\u7684\u65b9\u5f0f\u628a std::locale \u5bf9\u8c61\u4e2d\u7684 std::codecvt \u66ff\u6362\u6210 icu \u7684\u6620\u5c04\u8868\u3002\u4ece\u800c\u8ba9 std::wofstream \u8c03\u7528\u8fd9\u4e2a icu \u7684\u6620\u5c04\u51fd\u6570\uff0c\u5b9e\u73b0\u4e86 UTF-32 \u5230 GBK \u7684\u8f6c\u6362\u3002 \u6b64\u5916\uff0c\u4f60\u8fd8\u53ef\u4ee5\u9009\u62e9\u8986\u76d6 locale \u7684\u90e8\u5206\u65b9\u9762 (facet)\uff0c\u6bd4\u5982\u5728\u6587\u4ef6\u7f16\u7801\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u8981\u7528 \"zh_CN.GBK\" \u7684 LC_CTYPE \u65b9\u9762\u5c31\u53ef\u4ee5\u4e86\uff0c\u5176\u4ed6\u7684\u4f8b\u5982\u65f6\u95f4\u683c\u5f0f\u3001\u8bed\u8a00\u4fe1\u606f\u7b49\uff0c\u6211\u4eec\u8fd8\u662f\u60f3\u4fdd\u7559\u9ed8\u8ba4\u7684\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528 locale \u7684\u201c\u6742\u4ea4\u201d\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u4fdd\u7559\u8001 locale \u7684\u7edd\u5927\u90e8\u5206\u65b9\u9762\uff0c\u53ea\u66ff\u6362\u4e00\u4e2a\u65b9\u9762\u4e3a\u65b0 locale \u7684\uff1a std::locale old_loc = std::locale(\"\"); // \u73af\u5883 locale boost::locale::generator gen; std::locale new_loc = gen(\"zh_CN.GBK\"); // \u5168 GBK locale std::locale loc = std::locale(old_loc, new_loc, std::locale::ctype); // \u6742\u4ea4\uff1a\u7ee7\u627f old_loc \u7684\u5176\u4f59\u5168\u90e8\uff0c\u53ea\u66ff\u6362\u6389 LC_CTYPE \u90e8\u5206\u4e3a new_loc \u7684 fout.imbue(loc);","title":"std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6"},{"location":"unicode/#locale_4","text":"// \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5185\u7801\u7f16\u7801\u6210\u5916\u7801 std::string narrow(std::locale const &loc, std::wstring const &wstr) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::string str(wstr.size() * 4, '\\0'); // \u9884\u7559 4 \u500d\u7a7a\u95f4 wchar_t const *from_next; char *to_next; std::mbstate_t state{}; auto res = cvt.in(state, wstr.data(), wstr.data() + wstr.size(), from_next, str.data(), str.data() + str.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f str.resize(to_next - str.data()); return str; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f str.resize(to_next - str.data()); return str; } else { // \u8f6c\u6362\u5931\u8d25 return \"\"; } } // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5916\u7801\u89e3\u7801\u6210\u5185\u7801 std::wstring widen(std::locale const &loc, std::string const &str) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::wstring wstr(str.size(), L'\\0'); // \u9884\u7559\u7a7a\u95f4 char const *from_next; wchar_t *to_next; std::mbstate_t state{}; auto res = cvt.out(state, str.data(), str.data() + str.size(), from_next, wstr.data(), wstr.data() + wstr.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else { // \u8f6c\u6362\u5931\u8d25 return L\"\"; } } std::wstring wstr = L\"\u4f60\u597d\"; std::cout << narrow(std::locale(\"zh_CN.GBK\"), wstr); \u4e0d\u8fc7\uff0c\u6211\u4eec\u90fd\u6709\u66f4\u65b9\u4fbf\u7684 boost::locale::conv \u4e86\uff0c\u8fd8\u4f55\u5fc5\u8fd8\u7528\u8fd9\u4e48\u7e41\u7410\u7684 std::locale \u5462\uff1f\u6240\u4ee5\u6211\u662f\u4e0d\u63a8\u8350\u518d\u7528\u8fd9\u7834\u73a9\u610f\uff0c\u65e0\u8bba\u662f\u6613\u7528\u6027\u8fd8\u662f\u6269\u5c55\u6027\u90fd\u662f Boost \u5b8c\u80dc\u3002","title":"locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362"},{"location":"unicode/#c-wchar_t","text":"\u5bf9\u4e8e\u6240\u6709\u7684 strcpy \u3001 strcmp \u3001 strlen \u8fd9\u7c7b str*** \u7cfb\u51fd\u6570\uff0c\u90fd\u6709\u4e00\u4e2a\u76f8\u5e94\u7684 wcs*** \u51fd\u6570\u3002 \u4f8b\u5982 wcscpy \u3001 wcscmp \u3001 wcslen \u3002 \u5b83\u4eec\u7684\u539f\u578b\u5982\u4e0b\uff1a wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); int wcscmp(const wchar_t *s1, const wchar_t *s2); size_t wcslen(const wchar_t *s); \u5b83\u4eec\u7684\u4f5c\u7528\u548c str*** \u7cfb\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u662f\u5b83\u4eec\u64cd\u4f5c\u7684\u662f wchar_t \u5b57\u7b26\u4e32\u3002 \u5bf9\u4e8e\u6240\u6709\u7684 fputc \u3001 printf \uff0c fprintf \uff0c fgets \u8fd9\u7c7b\u64cd\u4f5c\u6587\u4ef6\u7684\u51fd\u6570\uff0c\u4e5f\u90fd\u6709\u4e00\u4e2a\u914d\u5957\u7684 fw*** \u51fd\u6570\u3002 \u7b2c\u4e00\u6b21\u4f7f\u7528\u8fc7\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c FILE * \u5c06\u4f1a\u88ab\u201c\u5bbd\u5316\u201d\uff08 fwiden \uff09\u3002\u5bbd\u5316\u7684\u6587\u4ef6\u6d41\u4eca\u540e\u5c06\u53ea\u80fd\u8f93\u5165\u5bbd\u5b57\u7b26\u4e32\u3002 \u4f46\u662f\uff0c\u65e2\u7136 C++ \u5df2\u7ecf\u6709 std::wstring \uff0c\u5c31\u4e0d\u5efa\u8bae\u518d\u5b66 C \u8bed\u8a00 L'\\0' \u7ed3\u5c3e\u5b57\u7b26\u4e32\u4e86\u3002","title":"C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570"},{"location":"unicode/#c","text":"TODO","title":"C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362"},{"location":"unicode/#c-codecvt","text":"wchar_t \u3001 char16_t \u3001 char32_t \u4e0e char \u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 std::mbrtoc16 \u3001 std::mbrtoc32 \u3001 std::c16rtomb \u3001 std::c32rtomb \u51fd\u6570\u3002 \u7136\u800c\uff0c\u53c8\u81ed\u53c8\u957f\uff0c\u7528\u5c01\u88c5\u597d\u7684 boost::locale::utf_to_utf/from_utf/to_utf/between \u4e0d\u9999\u5417\uff1f","title":"C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 <codecvt>"},{"location":"unicode/#windows","text":"\u9047\u5230\u5b57\u7b26\u7f16\u7801\u96be\u9898\u7684\uff0c\u4e3b\u8981\u662f Windows \u7a0b\u5e8f\u5458\u3002","title":"Windows \u4e13\u9898"},{"location":"unicode/#windows-api-w","text":"\u4ece Windows NT \u7248\u672c\u5f00\u59cb\uff0c\u5bf9\u4e8e\u6240\u6709\u6d89\u53ca\u5b57\u7b26\u4e32\u7684\uff0c\u5176\u64cd\u4f5c\u7cfb\u7edf API \u63d0\u4f9b\u4e86\u4e24\u5957\u51fd\u6570\u3002 \u4e00\u5957\u662f A \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 A \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileA \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 ANSI\uff08\u5373 GBK\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u53e6\u4e00\u5957\u662f W \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 W \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileW \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 Unicode\uff08\u5373 UTF-16\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u5176\u4e2d CreateFileW \u624d\u662f Windows \u7cfb\u7edf\u771f\u6b63\u7684 API\u3002 \u800c CreateFileA \u662f\u4e3a\u4e86\u517c\u5bb9\u57fa\u4e8e ANSI \u7684\u8001\u7a0b\u5e8f. \u7531\u4e8e ANSI \u5728\u4e0d\u540c\u5730\u533a\u4f1a\u53d8\u5f97\u4e0d\u540c\uff0c\u4f7f\u7528\u8fd9\u7c7b\u51fd\u6570\u5199\u51fa\u7684\u7a0b\u5e8f\u4e0d\u5177\u6709\u56fd\u9645\u901a\u7528\u6027\u3002 \u5176\u5185\u90e8\u7684\u5b9e\u73b0\u53ea\u662f\u7b80\u7b80\u5355\u5355\u5730\u7ed9 const char * \u505a\u4e2a\u8f6c\u6362\uff0c\u4ece GBK \u8f6c\u5230 UTF-16\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528 CreateFileW\u3002 HANDLE CreateFileA(const char *lpFileName) { return CreateFileW(gbk_to_utf16(lpFileName)); }","title":"Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570"},{"location":"unicode/#tchar","text":"\u9664\u4e86\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5b8f\uff0c\u8fd9\u4e2a\u5b8f\u6ca1\u6709\u4efb\u4f55\u540e\u7f00\uff0c\u4f8b\u5982 CreateFile \u3002 \u5176\u5b9a\u4e49\u5982\u4e0b\uff1a #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif \u8fd9\u6837\u505a\u7684\u521d\u8877\u662f\uff0c\u7a0b\u5e8f\u5458\u53ea\u53ef\u4ee5\u5199\u51fa\u4e00\u5957\u9488\u5bf9 MessageBox \u7684\u4ee3\u7801\u3002 \u5f53\u8001\u677f\u60f3\u8981\u57fa\u4e8e Unicode \u65f6\uff0c\u4ed6\u5c31 #define UNICODE \uff0c\u8fd9\u6837 MessageBox \u5c31\u53d8\u6210\u4e86 MessageBoxW \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u5c31\u4f1a\u81ea\u52a8\u53d8\u6210 Unicode \u7684\uff0c\u56fd\u9645\u901a\u7528\u3002 \u5f53\u52b3\u4fdd\u8001\u677f\u60f3\u8981\u57fa\u4e8e ANSI \u65f6\uff0c\u4ed6\u5c31\u4e0d\u5b9a\u4e49 UNICODE \u5b8f\uff0c\u8fd9\u6837\u6240\u6709\u7684 MessageBox \u53c8\u53d8\u56de\u4e86 MessageBoxA \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u53c8\u53d8\u6210 ANSI \u7684\u4e86\u3002 \u6240\u6709\u6709 A/W \u533a\u5206\u7684\u7684 Windows API \u90fd\u6709\u8fd9\u6837\u4e00\u4e2a\u5b8f\uff0c\u6839\u636e UNICODE \u5b8f\u662f\u5426\u5b9a\u4e49\uff0c\u51b3\u5b9a\u91c7\u53d6\u54ea\u5957 API\u3002 \u6211\u4eec\u4f1f\u5927\u7684 Linux \u7cfb\u7edf\u5c31\u6ca1\u6709\u8fd9\u4e2a\u82e6\u607c\uff0c\u65e9\u5c31\u7edf\u4e00 UTF-8 \u4e86\u3002 \u9664\u6b64\u4e4b\u5916\uff0c \u4e2d\u8fd8\u5b9a\u4e49\u4e86 TEXT \u8fd9\u4e2a\u5b8f\u51fd\u6570\u3002 #ifdef UNICODE #define TEXT(s) L##s #else #define TEXT(s) s #endif \u7528\u6cd5\uff1a\u8981\u6c42\u7a0b\u5e8f\u5458\u628a\u6240\u6709\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u90fd\u7528 TEXT \u5b8f\u5305\u88f9\u3002 Qt \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b8f\u5305\u88f9\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u505a\u6cd5\uff0c tr \uff0c\u4f46\u5b83\u5e76\u4e0d\u662f\u4e3a\u4e86\u89e3\u51b3\u7f16\u7801\u95ee\u9898\uff0c\u800c\u662f\u4e3a\u4e86\u89e3\u51b3\u591a\u8bed\u8a00\u7ffb\u8bd1\u95ee\u9898\uff0c\u7a0d\u540e\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u4e00\u4e0b Qt \u4e2d\u7684\u5b57\u7b26\u4e32\u3002 \u5f53 UNICODE \u5b8f\u5b9a\u4e49\u65f6\uff0c TEXT \u4f1a\u81ea\u52a8\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u6dfb\u52a0 L \u524d\u7f00\uff0c\u4f7f\u5f97\u5b57\u7b26\u4e32\u53d8\u6210 Unicode \u7684\u3002\u5982\u679c\u6ca1\u6709\u5b9a\u4e49\uff0c\u5219\u53c8\u53d8\u56de ANSI \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff08\u8ddf\u968f\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\u7684\u8bbe\u5b9a\uff09\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff1a #include int main() { MessageBox(NULL, TEXT(\"\u4f60\u597d\uff0c\u4e16\u754c\"), TEXT(\"\u6807\u9898\"), MB_OK); } \u5f53\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u6807\u9898\", MB_OK); } \u5f53\u6ca1\u6709\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u6807\u9898\", MB_OK); } \u6b64\u5916\uff0c\u8fd8\u5b9a\u4e49\u4e86 TCHAR \u8fd9\u4e2a\u7c7b\u578b\u522b\u540d\uff0c\u540c\u6837\u662f\u9488\u5bf9\u662f\u5426\u5b9a\u4e49 UNICODE \u5b8f\u800c\u5b9a\u4e49\u4e86\u4e24\u5957\u7248\u672c\u3002 #ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif \u8fd8\u4e3a printf \u548c wprintf \u5b9a\u4e49\u4e86 TCHAR \u7248\u672c\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709 strlen \u548c wcslen \uff0c strcpy \u548c wcscpy \uff0c\u7b49\u7b49\u3002 #ifdef UNICODE #define _tprintf wprintf #define _tcscpy wcscpy #define _tcslen wcslen #else #define _tprintf printf #define _tcscpy strcpy #define _tcslen strlen #endif \u4e0d\u89c9\u5f97\u8fd9\u5f88\u9177\u5417\uff1f\u5f88\u7b26\u5408\u6211\u5bf9\u5f3a\u8feb\u75c7\u7684\u60f3\u8c61\uff0c\u79d1\u6280\u5e76\u4e14\u5e26\u7740\u81ed\u5473\u3002 int main() { TCHAR str[] = TEXT(\"\u6bd4\u5c14\u76d6\u5b50\u6211\u6d4b\u8bd5\u4f60\u7684\u7801\"); } (* \u54e6\uff0c\u6211\u662f\u8bf4\uff0c\u6211\u8981\u6d4b\u8bd5\u4f60\u7684\u7f16\u7801\u683c\u5f0f *) \u9700\u8981\u5207\u6362\u65f6\uff0c\u5728 MSVC \u4e2d\uff0c\u6253\u5f00\u6216\u5173\u95ed /DUNICODE \u7f16\u8bd1\u9009\u9879\u5373\u53ef\u3002 \u4e0d\u8981\u89c9\u5f97\u8fd9\u662f\u4ec0\u4e48\u597d\u4e3b\u610f\uff0c\u8fd9\u6837\u505a\u7684\u540e\u679c\u662f\uff0c\u4f60\u5199\u51fa\u7684\u4ee3\u7801\u53ea\u80fd\u5728 Windows \u4e0b\u7f16\u8bd1\u3002 \u5199\u8d77\u6765\u7d2f\u6b7b\u4eba\uff0c\u5b9e\u9645\u54ea\u6709\u90a3\u4e48\u591a\u4e00\u76f4\u5728 ANSI \u548c Unicode \u4e4b\u95f4\u6765\u56de\u5207\u6362\u7684\u9700\u6c42\uff1f \u6211\u7684\u5efa\u8bae\u662f\uff0c\u7edf\u4e00 wchar_t \uff0c\u7edf\u4e00\u5168\u7528 W \u51fd\u6570\uff0c\u618b\u62a0\u62a0\u7d22\u7d22\u7684\u534a\u8fdb\u534a\u9000\u3002","title":"TCHAR \u6d41\u6d3e"},{"location":"unicode/#utf-8_4","text":"\u4e4b\u524d\u8bf4\u8fc7\u4e86\uff0cWindows \u5e73\u53f0\u5230\u5904\u90fd\u9ed8\u8ba4 GBK \u975e\u5e38\u9ebb\u70e6\uff0c\u8981\u5207\u6362\u5230 UTF-8 \u5de5\u4f5c\u6d41\uff1a \u7f16\u8bd1\u5668\u5f00\u542f /utf-8 \u9009\u9879 \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c system(\"chcp 65001\") \u8bbe\u7f6e\u6587\u4ef6\u7cfb\u7edf\u5b57\u7b26\u4e32\u7f16\u7801\uff0c setlocale(LC_ALL, \".utf-8\") // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 SetConsoleCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u5165\u7f16\u7801\uff0c\u7528\u4e8e std::cin #elif __unix__ // \u53cd\u6b63 Unix \u7cfb\u7edf\u9ed8\u8ba4\u90fd\u662f UTF-8\uff0c\u4e0d\u8bbe\u7f6e\u4e5f\u884c\uff0c\u8fd9\u91cc\u8bbe\u7f6e\u5168\u5c40 locale \u662f\u4e3a\u4e86\u8ba9 iswspace \u63a5\u53d7\u5168\u89d2\u7a7a\u683c\u3001iswpunct \u63a5\u53d7\u5168\u89d2\u9017\u53f7 L'\uff0c' \u7b49 //setlocale(LC_ALL, \"zh_CN.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u4e2d\u6587\u672c\u5730\u5316\uff0c\u53ef\u4f7f strerror \u8f93\u51fa\u4e2d\u6587\uff08\u4f46\u7528\u6237\u5fc5\u987b locale-gen \u8fc7\u4e2d\u6587\uff01\uff09 //setlocale(LC_ALL, \"C.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u8bed\u8a00\u4e2d\u6027 locale\uff0c\u53ea\u5f71\u54cd iswspace\u3001iswpunct \u7b49\u51fd\u6570\uff0c\u4e0d\u4f1a\u4f7f strerror \u7b49\u8f93\u51fa\u4e2d\u6587 setlocale(LC_ALL, \".utf-8\"); // \u82e5\u4e0d\u5e26\u4efb\u4f55\u524d\u7f00\uff08\u63a8\u8350\uff09\uff0c\u5219\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u8bed\u8a00 $LANG\uff0c\u4f7f strerror \u81ea\u52a8\u9002\u5e94 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 std::wcout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4f60\u90fd\u7edf\u4e00 UTF-8 \u4e86\uff0c\u8fd9\u7834 UTF-16 \u548c UTF-32 \u4e4b\u95f4\u6765\u56de\u8df3\u7684\u7834 wchar_t \u5c31\u522b\u7528\u4e86\u5457\uff01 return 0; }","title":"UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f"},{"location":"unicode/#wndproc","text":"LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == false \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::cout << char(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f GBK \u7f16\u7801\u7684 char \u5e8f\u5217 // \u5982\u679c\u662f\u4e2d\u6587\u5b57\u7b26\uff0cWndProc(WM_CHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u5b57\u8282\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u5df1\u5224\u65ad\u548c\u62fc\u63a5 GBK \u5b57\u7b26\u4e32 return 0; case WM_UNICHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == true \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::wcout << wchar_t(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f UTF-16 \u7f16\u7801\u7684 wchar_t \u5e8f\u5217 // \u5982\u679c\u662f\u4ee3\u7406\u5bf9\uff0cWndProc(WM_UNICHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u7801\u4f4d\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u884c\u628a\u4ee3\u7406\u5bf9\u7ec4\u88c5\u6210\u5b8c\u6574\u7684 Unicode \u7801\u70b9 return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } \u628a WndProc \u7684\u8f93\u5165\u5b58\u5165 std::u32string \u7684\u6848\u4f8b\uff1a std::u32string result; std::string ansi_buf; std::wstring utf16_buf; std::optional try_ansi_to_utf32(std::string const &s) { try { return boost::locale::conv::to_utf(s, \"\"); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } std::optional try_utf16_to_utf32(std::wstring const &s) { try { return boost::locale::conv::utf_to_utf(s); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: ansi_buf.push_back(char(wParam)); if (auto u = try_ansi_to_utf32(ansi_buf)) { result += u.value(); ansi_buf.clear(); } return 0; case WM_UNICHAR: utf16_buf.push_back(wchar_t(wParam)); if (auto u = try_utf16_to_utf32(utf16_buf)) { result += u.value(); utf16_buf.clear(); } return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); };","title":"WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165"},{"location":"unicode/#_20","text":"\u6807\u51c6\u5e93\u7684 std::string \u6211\u4eec\u4e0d\u518d\u8d58\u8ff0\uff0c\u521a\u624d\u5728\u201c\u5bbd\u5b57\u7b26\u6d41\u201d\u4e2d\u4e5f\u4ecb\u7ecd\u4e86\u5b98\u65b9\u7684\u60f3\u6cd5\uff0c\u4e4b\u540e\u7684\u5b57\u7b26\u4e32\u4e13\u9898\u8bfe\u4f1a\u7ee7\u7eed\u8be6\u89e3\u3002 \u8fd9\u91cc\u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u5173\u4e8e\u5b57\u7b26\u7f16\u7801\u7684\u95ee\u9898\uff0c\u63a2\u7d22\u5404\u5927\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u5e93\uff0c\u662f\u5982\u4f55\u5c01\u88c5\u5b57\u7b26\u4e32\u7c7b\uff0c\u5982\u4f55\u89e3\u51b3 UTF-8 \u53d8\u957f\u7f16\u7801\uff0cUTF-32 \u538b\u7f29\u7387\u4f4e\u7684\u95ee\u9898\u7684\uff0c\u5e0c\u671b\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u63d0\u4f9b\u4e00\u70b9\u7075\u611f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u597d\u7684\u5e93\u6216\u8bed\u8a00\uff0c\u90fd\u8981\u660e\u786e\u533a\u5206\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u6982\u5ff5\uff0c\u524d\u8005\u662f\u6587\u672c\u5185\u5bb9\uff0c\u540e\u8005\u662f\u7eaf\u4e8c\u8fdb\u5236\u5185\u5bb9\u3002 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7\u201c\u7f16\u7801\u201d\u5f97\u5230\u7eaf\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6570\u7ec4\uff0c\u800c\u5b57\u8282\u6570\u7ec4\u53ef\u4ee5\u201c\u89e3\u7801\u201d\u5f97\u5230\u539f\u59cb\u5b57\u7b26\u4e32\u3002 \u65e9\u671f\u7684 C \u8bed\u8a00\u5c31\u662f\u56e0\u4e3a\u628a\u5b57\u7b26\u548c\u5b57\u8282\u6df7\u4e3a\u4e00\u8c08\uff0c\u90fd\u4f7f\u7528\u4e86 char \u7c7b\u578b\uff0c\u624d\u4ea7\u751f\u4e86\u540e\u6765\u8fd9\u4e48\u591a\u4e71\u8c61\u3002\u540e\u6765\u901a\u8fc7\u6253\u8865\u4e01\u6253\u4e0a\u771f\u6b63\u7684\u5b57\u7b26 wchar_t \uff0c\u5374\u6ca1\u4ec0\u4e48\u4eba\u7528\uff0c\u800c\u4e14\u8fd8\u88ab Windows \u641e\u6210 16 \u4f4d\uff0c\u53cd\u800c\u4e0d\u8de8\u5e73\u53f0\u4e86\u3002 \u6b64\u5904\u5148\u5217\u4e00\u4e2a\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u773c\u4e2d\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u8868\uff0c\u65b9\u4fbf\u4f60\u7406\u89e3\u3002 \u8bed\u8a00 \u5b57\u7b26 \u5b57\u7b26\u4e32 \u6587\u672c\u6d41 \u5b57\u8282\u6570\u7ec4 \u4e8c\u8fdb\u5236\u6d41 \u7f16\u7801/\u89e3\u7801 C char wchar_t * FILE * + fgetwc char * FILE * + fgetc wcstomb / mbstowc C++ wchar_t std::wstring std::wistream std::string / std::vector std::istream std::codecvt Qt QChar QString QTextStream QByteArray QDataStream QTextCodec Python3 str str open('r') bytes open('rb') str.encode() Python2 unicode unicode \u65e0 str open('r') unicode.encode() Java Character String Reader byte[] InputStream Charset.encode C# char string StreamReader byte[] Stream Encoding Rust char String BufRead u8 Read str::from_utf8 JS char String ReadableStream Uint8Array ReadableStream TextEncoder Go rune string Reader byte Reader utf8.DecodeRune PHP string string fopen string fopen mb_convert_encoding Swift Character String String.UnicodeScalarView UInt8 Data String.Encoding Kotlin Char String Reader ByteArray InputStream Charset.encode Obj-C unichar NSString NSInputStream uint8_t NSInputStream NSStringEncoding Lua integer table \u65e0 string io.open require'utf8' \u672c\u8bfe\u4e0d\u4f1a\u8bb2\u89e3\u8fd9\u4e9b\u8bed\u8a00\u7684\u5b57\u7b26\u4e32\u5177\u4f53\u7528\u6cd5\uff0c\u53ea\u63d0\u4f9b\u4e00\u4e9b\u6982\u5ff5\uff0c\u8ba9\u4f60\u77e5\u9053\u5927\u5bb6\u90fd\u662f\u600e\u4e48\u5b9e\u73b0\u7684\uff0c\u89e6\u7c7b\u65c1\u901a\u3002 Lua \u4e2d UTF-32 \u7684\u5b9a\u957f\u7f16\u7801\uff0c\u8981\u8fd9\u6837\u5b9e\u73b0\uff1a {80, 101, 110, 103} \u3002\u800c\u4ed6\u6240\u8c13\u7684 utf8 \u5e93\uff0c\u5c31\u662f\u8d1f\u8d23\u628a Lua \u81ea\u5df1\u7684 string \u5047\u8bbe\u4e3a utf8 \u7f16\u7801\uff0c\u89e3\u7801\u51fa\u4e00\u4e2a\u4e2a Unicode \u7801\u70b9\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fd9\u6837\u7684\u6570\u7ec4\u3002\u4ed6\u751a\u81f3\u4e0d\u662f Lua \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u662f\u4e2a\u7b2c\u4e09\u65b9\u7684\u5e93\uff0c\u8fd8\u662f\u9700\u8981\u7f16\u8bd1\u7684 C \u8bed\u8a00 .so \u6587\u4ef6\u3002\u8fd8\u6709 Lua \u5b5d\u5b50\u501f\u6b64\u786c\u8bf4\u6211\u4eec Lua \u662f\u5929\u751f UTF-8\uff01\u7136\u800c\u62ff\u7740\u4e2a UTF-8 \u7f16\u7801\u7684\u201c\u5b57\u8282\u6570\u7ec4\u201d string \u6765\u6253\u5f00 io.open \u6587\u4ef6\uff0c\u5c31\u4f1a\u62a5\u9519\u627e\u4e0d\u5230\u6587\u4ef6\uff08\u56e0\u4e3a\u4e2d\u56fd\u533a Windows \u7684 GBK\uff09\uff0c\u662f\u4e0d\u662f\u5f88\u597d\u7b11\u5462\uff1f","title":"\u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76"},{"location":"unicode/#qt-qstring","text":"Qt \u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 Qt \u7684\u5b57\u8282\u6570\u7ec4\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 \u5b83\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u4e0a\u662f\u4e2a QChar \u6570\u7ec4\uff0c\u800c QChar \u662f unsigned short \uff0c\u5373 16 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\uff0c\u4e5f\u5c31\u662f UTF-16 \u7f16\u7801\u7684\u7801\u4f4d\u3002 QString str = \"\u4f60\u597d\uff0c\u4e16\u754c\"; // str.size() = 5 // str[0] = QChar(0x4f60) = u'\u4f60' // str[1] = QChar(0x597d) = u'\u597d' // str[2] = QChar(0xff0c) = u'\uff0c' // str[3] = QChar(0x4e16) = u'\u4e16' // str[4] = QChar(0x754c) = u'\u754c' \u53ef\u89c1\uff0c QString \u662f UTF-16 \u7f16\u7801\u7684\uff0c\u5c31\u548c Java \u4e00\u6837\uff0cQt \u4e5f\u662f UTF-16 \u6f6e\u7684\u53d7\u5bb3\u8005\u3002 \u6240\u4ee5\uff0cQString \u4e5f\u5b58\u5728\u7740\u4ee3\u7406\u5bf9\u53d8\u957f\u7f16\u7801\u7684\u95ee\u9898\u3002\u4f46\u81f3\u5c11\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5b57\u7b26\u6765\u8bf4\uff0c\u4e00\u4e2a 16 \u4f4d\u7684 QChar \u90fd\u5bb9\u7eb3\u7684\u4e0b\u4e86\u3002","title":"Qt QString"},{"location":"unicode/#qtextcodec","text":"Qt \u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u7684\u7f16\u7801\u8f6c\u6362\u51fd\u6570\uff0c\u7528\u4e8e\u5c06 QString \u8f6c\u6362\u6210 QByteArray \uff0c\u6216\u8005\u4ece QByteArray \u8f6c\u6362\u6210 QString \uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u90fd\u662f\u4ee5 to \u6216\u8005 from \u5f00\u5934\u7684\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u540d\uff0c\u4f8b\u5982 fromUtf8 \u3001 toUtf8 \u3001 toLocal8Bits \u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u5185\u90e8\uff0c\u90fd\u662f\u8c03\u7528 QTextCodec \u7c7b\u5b9e\u73b0\u7684\u8f6c\u6362\u3002 QTextCodec \u662f Qt \u7528\u4e8e\u5904\u7406\u5404\u79cd\u6587\u672c\u7f16\u7801\u4e4b\u95f4\u8f6c\u6362\u7684\u7c7b\u3002\u5b83\u7684\u9759\u6001\u65b9\u6cd5 codecForLocale \u8fd4\u56de\u4e86\u5f53\u524d\u7cfb\u7edf\u7684\u7f16\u7801\uff0c toUnicode \u548c fromUnicode \u5206\u522b\u662f\u5c06 QByteArray \u8f6c\u6362\u6210 QString \uff0c\u6216\u8005\u5c06 QString \u8f6c\u6362\u6210 QByteArray \u3002 QTextCodec *codec = QTextCodec::codecForLocale(); // \u8fd4\u56de\u5f53\u524d\u7cfb\u7edf\u7f16\u7801 QByteArray bytes = codec->fromUnicode(str); // \u5c06 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u5373 char[] QString str = codec->toUnicode(bytes); // \u5c06 QByteArray \u8f6c\u6362\u6210 QString QTextCodec \u8fd8\u63d0\u4f9b\u4e86\u4e00\u4e9b\u66f4\u52a0\u7ec6\u7c92\u5ea6\u7684\u8f6c\u6362\u63a5\u53e3\uff0c\u4f8b\u5982 fromUnicode \u9664\u4e86\u63a5\u53d7 QString \uff0c\u8fd8\u63a5\u53d7 QChar \u6570\u7ec4\uff0c\u53ef\u4ee5\u6307\u5b9a\u8f6c\u6362\u8303\u56f4\u3002","title":"QTextCodec"},{"location":"unicode/#fromtolocal8bitsutf8latin1ascii","text":"\u4e3a\u4e86\u65b9\u4fbf\u4f7f\u7528\uff0cQt \u5c01\u88c5\u4e86\u4e00\u4e9b\u5e38\u7528\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362\u51fd\u6570\uff0c\u8fd9\u6837\u4f60\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u521b\u5efa\u4e00\u4e2a QTextCodec\u3002\u90fd\u662f to \u548c from \u5f00\u5934\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u7684\u540d\u79f0\u3002 Local8Bits \u8868\u793a\u8fd0\u884c\u65f6\u68c0\u6d4b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u5ba2\u6237\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 QByteArray bytes = str.toLocal8Bits(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801 QString::fromLocal8Bits(bytes); // \u518d\u4ece\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForLocale(); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Utf8 \u8868\u793a\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002 QByteArray bytes = str.toUtf8(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 UTF-8 \u7f16\u7801 QString::fromUtf8(bytes); // \u518d\u4ece UTF-8 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"UTF-8\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Latin1 \u8868\u793a ISO-8859-1 \u7f16\u7801\uff0c\u53c8\u79f0\u4e3a\u897f\u6b27\u7f16\u7801\uff0c\u5b83\u662f\u4e00\u4e2a\u5355\u5b57\u8282\u7f16\u7801\uff0c\u548c ASCII \u7f16\u7801\u76f8\u4f3c\uff0c\u4f46\u662f\u591a\u4e86 128-255 \u7684\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u6cd5\u8bed\u3001\u5fb7\u8bed\u3001\u897f\u73ed\u7259\u8bed\u3001\u8461\u8404\u7259\u8bed\u7b49\u5b57\u7b26\u3002 QByteArray bytes = str.toLatin1(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 Latin1 \u7f16\u7801 QString::fromLatin1(bytes); // \u518d\u4ece Latin1 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ISO-8859-1\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Ascii \u8868\u793a ASCII \u7f16\u7801\uff0c\u548c Latin1 \u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u4ed6\u65e0\u6cd5\u5904\u7406 128-255 \u8fd9\u4e00\u6bb5\u7684\u5b57\u7b26\u3002 QByteArray bytes = str.toAscii(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 ASCII \u7f16\u7801 QString::fromAscii(bytes); // \u518d\u4ece ASCII \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ASCII\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes);","title":"from/toLocal8Bits/Utf8/Latin1/Ascii"},{"location":"unicode/#_21","text":"QString str = QStringLiterial(\"\u4f60\u597d\uff0c\u4e16\u754c\"); QStringLiterial \u53ef\u4ee5\u4fdd\u8bc1\uff0c\u8f6c\u6362\u65f6\u91c7\u7528\u7684\u662f\u6240\u8c13\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\uff08\u5b9e\u9645\u5e94\u8be5\u53eb\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\uff09\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u5f00\u53d1\u8005\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u662f\u7f16\u8bd1\u671f\u786e\u5b9a\u7684\u3002\u800c\u5982\u679c\u5199 QString::fromLocal8Bits(\"\") \u5c31\u53d8\u6210 \u201cANSI\u201d\uff0c\u5ba2\u6237\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u4e86\u3002\u8fd9\u4e24\u4e2a\u5b57\u7b26\u7f16\u7801\uff0c\u6bd4\u5982\u5728\u4e4b\u524d\u8de8\u56fd galgame \u7684\u6848\u4f8b\u4e2d\uff0c\u5c31\u662f\u4e0d\u540c\u7684\u3002","title":"\u5b57\u7b26\u4e32\u5e38\u91cf"},{"location":"unicode/#qtextstream","text":"QTextStream \u662f Qt \u63d0\u4f9b\u7684\u6587\u672c\u6d41\u7c7b\uff08\u5e26\u6709\u7f13\u51b2\uff09\uff0c\u5b83\u53ef\u4ee5\u5c06\u6587\u672c\u5199\u5165\u5230\u6587\u4ef6\u3001\u5957\u63a5\u5b57\u3001\u6807\u51c6\u8f93\u51fa\u7b49\u8bbe\u5907\u3002 \u6587\u672c\u6d41\u548c\u4e8c\u8fdb\u5236\u6d41\u4e0d\u540c\uff0c\u4ed6\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u8fc7 QTextStream \u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u3002 \u5f53\u4f60\u5f80 QTextStream \u5199\u5165 QString \u65f6\uff0c\u4f1a\u8c03\u7528\u8fd9\u4e2a\u7f16\u7801\u683c\u5f0f\u81ea\u52a8\u8f6c\u6362\u4e3a QByteArray \uff0c\u7136\u540e\u624d\u5199\u5165\u3002 \u8bfb\u53d6\u65f6\u4e5f\u540c\u7406\uff0c\u4f1a\u628a\u8bfb\u5230\u7684 QByteArray \u901a\u8fc7\u7f16\u7801\u683c\u5f0f\u89e3\u7801\uff0c\u5f97\u5230 QString \u5b57\u7b26\u4e32\u3002 Qt \u503c\u5f97\u79f0\u9053\u7684\u4e00\u70b9\u662f\uff1a\u4ed6\u628a\u6587\u4ef6\u548c\u6587\u4ef6\u6d41\u533a\u5206\u5f00\u6765\uff0c\u6587\u4ef6 QFile \u53ea\u9700\u8981\u8d1f\u8d23\u6253\u5f00\u6587\u4ef6\u5c31\u53ef\u4ee5\u4e86\uff1b\u800c\u6587\u672c\u6d41 QTextStream \u624d\u771f\u6b63\u8d1f\u8d23\u6570\u636e\u7684\u7f13\u51b2\uff0c\u89e3\u7801\u7b49\u64cd\u4f5c\u3002\u4f53\u73b0\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u804c\u8d23\u5355\u4e00\u539f\u5219\u3002 QFile file(\"hello.txt\"); file.open(QIODevice::ReadWrite); QTextStream stream(&file); stream.setCodec(\"UTF-8\"); // \u8bbe\u7f6e\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f stream << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u5199\u5165 QString\uff0cQTextStream \u4f1a\u81ea\u52a8\u5c06\u5176\u7528 UTF-8 \u7f16\u7801\u4e3a QByteArray \u540e\u5199\u5165 QFile \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u76f4\u63a5\u5199\u5165\u4e8c\u8fdb\u5236\u7684 QByteArray \uff0cQt \u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a QDataStream \u7c7b\uff0c\u65b9\u4fbf\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u8bfb\u5199\u3002 \u5982\u6b64\u628a\u4e8c\u8fdb\u5236\u548c\u6587\u672c\u4e25\u683c\u533a\u5206\uff0c\u800c\u4e0d\u662f\u50cf\u53e4\u4ee3 C \u8bed\u8a00\u90a3\u6837\u5b57\u8282\u4e0e\u5b57\u7b26\u6df7\u6dc6\u4e0d\u6e05\uff0c\u5168\u7528\u7cdf\u7cd5\u7684 char \u6765\u8868\u793a\uff0c\u5145\u5206\u4f53\u73b0\u4e86\u5f3a\u7c7b\u578b\u7684\u5b89\u5168\u3002","title":"QTextStream"},{"location":"unicode/#python-3-str","text":"\u5982\u4f55\u89e3\u51b3 UTF-32 \u5360\u7528\u7a7a\u95f4\u5927\u7684\u75db\u70b9\uff1fPython \u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u7edd\u5bf9\u503c\u5f97\u4e00\u770b\uff01 \u4e3a\u4e86\u65b9\u4fbf\u6587\u672c\u5904\u7406\uff0c\u6700\u597d\u4ee5\u5b9a\u957f\u7f16\u7801\uff0c\u4e5f\u5c31\u662f UTF-32\uff0c\u5b58\u50a8\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7528 UTF-8 \u6216 UTF-16 \u6765\u5b58\u50a8\u7684\u8bdd\uff0c\u4f1a\u9047\u5230\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff1a \u4f8b\u5982\u50cf\u5b57\u7b26\u4e32\u7d22\u5f15\uff0c\u5b57\u7b26\u4e32\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\uff0c\u8981\u4e48\u7d22\u5f15\u51fa\u6765\u7684\u662f\u5b57\u8282\u800c\u4e0d\u662f\u5b57\u7b26\u4e86\uff1b\u8981\u4e48\u5c31\u9700\u8981 O(N) O(N) \u7684\u590d\u6742\u5ea6\uff0c\u9010\u4e00\u904d\u5386\u6bcf\u4e2a\u5b57\u8282\uff0c\u624d\u80fd\u786e\u5b9a\u771f\u6b63\u7684\u4f4d\u7f6e\uff1b\u54ea\u6015\u5168\u662f ASCII \u4e5f\u5f97\u8fd9\u4e48\u505a\uff0c\u56e0\u4e3a\u4e07\u4e00\u521a\u597d\u6709\u4e00\u4e2a\u662f\u4e2d\u6587\u5b57\u7b26\u5462\uff1f \u6240\u4ee5\uff0c\u5bf9\u4e8e\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684 Python \u6765\u8bf4\uff0cUTF-8 \u662f\u65e0\u6cd5\u63a5\u53d7\u7684\uff0c\u4f3c\u4e4e\u53ea\u80fd\u4ee5 UTF-32 \u6765\u5b58\u50a8\uff1f Python \u60f3\u5230\u4e86\u4e00\u4e2a\u5c0f\u5999\u62db\uff1a enum PyUnicodeType { PyUnicodeType_Latin1, PyUnicodeType_UCS2, PyUnicodeType_UCS4, }; struct PyUnicodeString { PyUnicodeType type; union { uint8_t *latin1; uint16_t *ucs2; uint32_t *ucs4; }; }; \u8fd9\u91cc\u7684 union \u662f\u4e00\u4e2a C \u8bed\u8a00\u7279\u6027\uff0c\u4ed6\u5141\u8bb8\u4f60\u628a\u591a\u4e2a\u6210\u5458\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u5e38\u6765\u8bf4\u9700\u8981\u914d\u5408\u4e00\u4e2a enum \u8868\u793a\u7c7b\u578b\uff0c\u624d\u80fd\u5b89\u5168\u4f7f\u7528\u3002\u73b0\u4ee3 C++ \u7684 std::variant \u66f4\u5b89\u5168\u7684\u53d6\u4ee3\u4e86\u4ed6\uff0c\u800c\u4e14\u4e0d\u9700\u8981\u5916\u6302\u4e00\u4e2a enum \u3002CPython \u89e3\u91ca\u5668\u56e0\u4e3a\u662f C \u8bed\u8a00\u5b9e\u73b0\uff0c\u53ea\u80fd\u7528 union \u6a21\u62df std::variant \u7684\u6548\u679c\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFF \u7684\u5b57\u7b26\uff08Latin-1 \u8303\u56f4\uff09\u65f6\uff0c\u5b9e\u9645\u4e0a\u6ca1\u5fc5\u8981\u5168\u7528\u8d85\u5927\u7684 uint32_t \u6765\u5b58\u50a8\u3002\u5b8c\u5168\u53ef\u4ee5\u53ea\u53d6\u51fa\u4f4e 8 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a\u66f4\u7d27\u51d1\u7684 uint8_t \u6570\u7ec4\uff0c\u5c31\u50cf Latin-1 \u7f16\u7801\u4e00\u6837\u3002 \u4f46\u662f\u5f53\u6309\u7d22\u5f15\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u4f1a\u5224\u65ad\u5f53\u524d union \u91cc\u88c5\u7684\u662f\u54ea\u79cd\u7c7b\u578b\uff0c\u5982\u679c\u662f Latin-1 \u7684\uff0c\u90a3\u5c31\u4f1a\u7528\u7ed3\u6784\u4f53\u91cc\u7684 uint8_t * \u6307\u9488\u6765\u7d22\u5f15\u3002 \u8fd9\u6837\uff0c\u5bf9\u4e8e\u5168 ASCII \u7684\u5b57\u7b26\u4e32\uff0c\u76f8\u6bd4\u8001\u8001\u5b9e\u5b9e\u5b58 UTF-32 \u5185\u5b58\u5360\u7528\u76f4\u63a5\u51cf\u5c11\u4e86 75%\uff01\u552f\u4e00\u7684\u4ee3\u4ef7\u662f\u6309\u7d22\u5f15\u8bfb\u5b57\u7b26\u5143\u7d20\u65f6\u9700\u8981\u505a\u4e2a if-else \u5224\u65ad\u3002\u540c\u65f6\u53c8\u4e0d\u5931\u53bb\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff08\u65e9\u671f Unicode \u8303\u56f4\uff09\u65f6\uff0c\u5219\u662f\u53d6\u51fa\u4f4e 16 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a uint16_t \u7684\u6570\u7ec4\uff0c\u8fd9\u79cd\u5b58\u50a8\u65b9\u6848\u4e5f\u79f0\u4e3a UCS-2\u3002 \u6ce8\u610f UCS-2 \u5e76\u4e0d\u7b49\u540c\u4e8e UTF-16\uff0cUTF-16 \u662f\u80fd\u591f\u8868\u793a\u5b8c\u6574\u7684 Unicode \u7684\u53d8\u957f\u7f16\u7801\uff08\u6709\u4ee3\u7406\u5bf9\uff09\uff1b\u800c UCS-2 \u662f\u6ca1\u6709\u4ee3\u7406\u5bf9\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u7f3a\u70b9\u662f\u53ea\u80fd\u8868\u793a 0xFFFF \u7684\u8303\u56f4\u3002 \u5bf9\u4e8e\u5927\u90e8\u5206\u4e2d\u6587\u5b57\u7b26\u4e32\uff0c\u5185\u5b58\u5360\u7528\u5c31\u51cf\u5c11\u4e86 50%\uff0c\u4e5f\u4e0d\u4e8f\u3002 \u5982\u679c\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0\u201c\ud883\udede\u201d\u8fd9\u6837\u7684\uff0c\u8d85\u8fc7 0xFFFF \u7684\u5b57\u7b26\uff0c\u624d\u4f1a\u91c7\u7528 uint32_t \u8001\u8001\u5b9e\u5b9e\u5b58\u50a8\u771f\u6b63\u7684 UTF-32\uff0c\u53c8\u79f0 UCS-4\u3002 \u8fd9\u4e24\u79cd\u53eb\u6cd5\u662f\u7b49\u4ef7\u7684\uff0c\u53cd\u6b63 Unicode \u4ece\u6765\u6ca1\u6709\u8d85\u8fc7 0xFFFFFFFF \u7684\uff0c\u73b0\u5728\u4ed6\u4eec\u90fd\u662f\u5b9a\u957f\u7f16\u7801\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u62df\u673a\u8bed\u8a00\u6765\u8bf4\uff0c\u53cd\u6b63\u672c\u6765\u5c31\u4e0d\u5728\u4e4e if-else \u5206\u652f\u8fd9\u70b9\u5c0f\u5f00\u9500\uff0c\u8fd9\u786e\u5b9e\u662f\u6700\u597d\u7684\u65b9\u6848\u3002 \u7f3a\u70b9\u5c31\u662f\uff0c\u5f53\u4f60\u5f80\u4e00\u4e2a\u5b8c\u5168\u662f ASCII \u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u7a81\u7136\u63d2\u5165\u4e00\u4e2a\u201c\ud883\udede\u201d\u65f6\uff0c\u4f1a\u4ea7\u751f\u5de8\u5927\u7684\u5185\u5b58\u91cd\u5206\u914d\u3002\u867d\u7136\u53ea\u6709\u4e00\u4e2a\u201c\ud883\udede\u201d\uff0c\u4f46\u4e3a\u6b64\uff0c\u5176\u4ed6\u6240\u6709 ASCII \u5b57\u7b26\u90fd\u5f97\u4e3a\u4ed6\u6269\u5f20\u5230 32 \u4f4d\u7684\u5927\u5c0f\u3002\u800c UTF-8 \u548c\u4f20\u7edf\u7684 UTF-32 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u6b64\u6211\u4e5f\u4e0d\u5efa\u8bae C++ \u7a0b\u5e8f\u5458\u81ea\u5df1\u624b\u6413\u4e2a\u8fd9\u6837\u7684 union \u5b57\u7b26\u4e32\u3002","title":"Python 3 str"},{"location":"unicode/#rust-str-string","text":"\u800c Rust \u5219\u91c7\u7528\u4e86\u5b57\u7b26\u4e32\u5168\u5458 UTF-8 \u7684\u7b56\u7565\uff0c\u8fd9\u662f\u56e0\u4e3a Rust \u6700\u5e38\u7528\u4e8e\u4e92\u8054\u7f51\u65b9\u9762\u7684\u5e95\u5c42\u7cfb\u7edf\u8f6f\u4ef6\uff0c\u4e92\u8054\u7f51\u6700\u5e38\u7528\u7684\u6587\u672c\u7f16\u7801\u5c31\u662f UTF-8\uff0c\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\uff0c\u4e14\u56fd\u9645\u901a\u7528\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u4e92\u8054\u7f51\u57fa\u5efa\u6700\u5e38\u89c1\u7684\u5e73\u53f0\u5c31\u662f Linux\uff0c\u4f7f\u7528 UTF-8 \u5b58\u50a8\u5b57\u7b26\u4e32\uff0c\u8c03\u7528 Linux \u7cfb\u7edf API \u65e0\u9700\u4efb\u4f55\u8f6c\u6362\u3002\u4e14\u6587\u672c\u6587\u4ef6\u57fa\u672c\u90fd\u53ef\u4ee5\u5047\u5b9a\u662f UTF-8 \u7f16\u7801\uff0c\u5199\u5165\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u3002\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u8fd9\u5bfc\u81f4\u6587\u672c\u5904\u7406\u4e0a\u7684\u4e00\u4e9b\u56f0\u96be\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u7684\u7d22\u5f15\uff0c\u9700\u8981\u533a\u5206\u662f\u6309\u5b57\u8282\u7d22\u5f15\u8fd8\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u5982\u679c\u786e\u5b9e\u9700\u8981\u6309\u5b57\u7b26\u7d22\u5f15\u7684\u8bdd\uff0c\u590d\u6742\u5ea6\u5c31\u4f1a\u662f O(N) O(N) \u4e86\u3002 \u65e0\u8bba\u5982\u4f55\uff0c\u5982\u679c\u4f60\u9009\u62e9\u4e86 UTF-8 \u6d41\u6d3e\u7684\u8bdd\uff0cRust \u5b57\u7b26\u4e32\u7684\u201c\u8fed\u4ee3\u5668\u53cc\u8f68\u5236\u201d\u786e\u5b9e\u503c\u5f97\u79f0\u9053\uff1a let s = \"\u4f60\u597d\uff0c\u4e16\u754c\"; for c in s.chars() { // \u6309\u5b57\u7b26\u8fed\u4ee3 println!(\"{}\", c); } for b in s.bytes() { // \u6309\u5b57\u8282\u8fed\u4ee3 println!(\"{:02X}\", b); // \u6253\u5370\uff1aE4 BD A0 E5 A5 BD EF BC 8C E4 B8 96 E7 95 8C }","title":"Rust &str \u548c String"},{"location":"unicode/#java-string","text":"Java \u4e5f\u662f UTF-16 \u7684\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u4eae\u70b9\uff1a\u4ed6\u7684 String \u7c7b\u578b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u4f60\u65e0\u6cd5\u5c31\u5730\u4fee\u6539\u4e00\u4e2a String \u5bf9\u8c61\uff0c\u6bcf\u6b21\u4ea7\u751f\u4f60\u8c03\u7528 += \u7684\u90fd\u662f\u4e00\u4e2a\u65b0 String\uff0c\u800c\u4e0d\u4f1a\u8986\u76d6\u3002 \u4e5f\u5c31\u662f\u8bf4\uff1aJava \u7684 String \u867d\u7136\u662f\u201c\u5806\u201d\u4e2d\u7684\u5bf9\u8c61\uff0c\u5374\u65e0\u6cd5\u4ee5\u5f15\u7528\u4f20\u9012\u3002 \u8fd9\u907f\u514d\u4e86\u4ee5\u4e0b\u8fd9\u79cd\u60c5\u51b5\uff1a void registerStudent(String name) { name += \".txt\"; File file(name); file.write(...); } void myTransaction() { String name = \"\u5c0f\u5f6d\"; lib.registerStudent(name); office.registerStudent(name); // \u8fd9\u91cc name \u662f\u5426\u88ab\u4fee\u6539\uff1f } \u5982\u679c Java \u7684 String \u548c\u666e\u901a\u5bf9\u8c61\u4e00\u6837\uff0c\u88ab\u8c03\u7528\u8005\u7684\u4fee\u6539\u53ef\u4ee5\u5bf9\u5916\u90e8\u53ef\u89c1\uff0c\u90a3\u5c82\u4e0d\u662f\u6211\u6bcf\u6b21\u8c03\u7528\u4e00\u4e2a\u4ee5 String \u4e3a\u53c2\u6570\u7684\u51fd\u6570\u65f6\uff0c\u90fd\u9700\u8981\u64cd\u5fc3\uff1a\u8fd9\u4e2a\u51fd\u6570\u4f1a\u4e0d\u4f1a\u628a\u6211\u7684\u5b57\u7b26\u4e32\u4fee\u6539\u6389\uff1f \u6240\u4ee5\uff0cJava \u7ed9\u4ed6\u7684\u5bf9\u8c61\u6a21\u578b\u5f00\u4e86\u4e2a\u540e\u95e8\uff1a\u89c4\u5b9a\u6240\u6709\u5bf9\u8c61\u90fd\u662f\u6309\u5f15\u7528\u4f20\u9012\uff0c\u9664\u4e86 String \uff01\u5c31\u53ea\u6709 String \u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u8005\u5185\u90e8\u7684\u4fee\u6539\u5bf9\u5916\u4e0d\u53ef\u89c1\u3002 C++ \u548c Rust \u53ea\u9700\u8981\u52a0\u4e2a\u5e38\u5f15\u7528\u5c31\u884c\uff0c\u800c Java \u53d7\u5bb3\u8005\u8981\u8003\u8651\u7684\u5c31\u591a\u4e86\u3002 \u603b\u4e4b\uff0c\u8fd9\u5c31\u662f\u6ca1\u6709 const \u7684\u5783\u573e\u8bed\u8a00\u7684\u4e11\u6001\uff0c\u9700\u8981\u9760\u5404\u79cd\u8bed\u6cd5\u89c4\u5219\u4e0a\u5f00\u6d1e\u624d\u80fd\u5f25\u8865\u8bbe\u8ba1\u65f6\u8003\u8651\u4e0d\u5468\u7684\u7f3a\u9677\uff0c\u5c31\u4e3a\u4e86\u4f3a\u5019\u8fd9\u5e2e\u5f15\u7528\u90fd\u5f04\u4e0d\u660e\u767d\u7684\u5783\u573e\u5c0f\u767d\u3002 \u6211\u662f\u8bf4\u5783\u573e\u56de\u6536 (garbage-collect) \u8bed\u8a00\uff0c\u7b80\u79f0\u5783\u573e\u8bed\u8a00\u3002\u6ca1\u6709\u8bf4 Java \u5783\u573e\u7684\u610f\u601d\uff0c\u4f60\u8bf4\u5bf9\u5427\uff1f\u5783\u573e\u8bed\u8a00\u3002","title":"Java String"},{"location":"unicode/#cow","text":"\u62c5\u5fe7\uff1a\u90a3\u5c82\u4e0d\u662f\u6bcf\u6b21\u6211 += \u5b9e\u9645\u4e0a\u90fd\u767d\u767d\u6df1\u62f7\u8d1d\u4e86\u4e00\u4efd\u65b0\u7684 String \uff1f\u522b\u62c5\u5fc3\uff0c\u56e0\u4e3a\u5177\u4f53\u5b9e\u73b0\u4e0a\uff0cJava \u7684 String \u5728\u5e95\u5c42\u91c7\u7528\u4e86\u548c Qt \u7684 QString \u4e00\u6837\u7684 COW \u673a\u5236\uff1a \u5f53\u4e00\u4e2a QString \u88ab\u62f7\u8d1d\u6784\u9020\u65f6\uff0c\u5e76\u4e0d\u4f1a\u5bf9\u5176\u4e2d\u7684 QByteArray \u8fdb\u884c\u6df1\u62f7\u8d1d\uff0c\u800c\u662f\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u3002\u53ea\u6709\u5f53\u5176\u4e2d\u4e00\u4e2a QString \u88ab += \u7b49\u5e26\u6709\u526f\u4f5c\u7528\u64cd\u4f5c\u4fee\u6539\u65f6\uff0c\u624d\u4f1a\u6df1\u62f7\u8d1d\u4e00\u4efd\u65b0\u7684\uff0c\u8ba9\u4f60\u4fee\u6539\u3002\u8fd9\u6837\u5927\u5927\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\u548c\u6027\u80fd\u5f00\u9500\u3002 COW \u5b57\u7b26\u4e32\u7684\u7f3a\u70b9\u662f\uff1a\u5f53\u4f60\u5199\u591a\u7ebf\u7a0b\u5e76\u53d1\u65f6\uff0c\u672c\u6765\u591a\u7ebf\u7a0b\u53ea\u8bfb\u8bbf\u95ee\u540c\u4e00\u4e2a\u5b57\u7b26\u4e32\u662f\u5b89\u5168\u7684\uff0c\u4f46\u5982\u679c\u5b57\u7b26\u4e32\u6709 COW\uff0c\u8fde\u53ea\u8bfb\u8bbf\u95ee\u90fd\u4f1a\u4e0d\u5b89\u5168\u4e86\u3002\u4e4b\u540e\u6211\u4eec\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4f1a\u8be6\u7ec6\u5206\u6790\u8fd9\u662f\u4e3a\u4ec0\u4e48\u3002 \u5176\u5b9e\u65e9\u671f\u7684 C++98 \u4e2d\uff0c std::string \u4e5f\u91c7\u7528\u4e86 COW \u673a\u5236\uff0c\u4f46\u540e\u6765\u56e0\u4e3a\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u8981\u6c42\uff0c\u88ab\u8ffd\u6c42\u591a\u7ebf\u7a0b\u7684 C++11 \u8d23\u4ee4\u6539\u6b63\uff0c\u624d\u6709\u4e86\u540e\u6765 std::__cxx11::basic_string \u7684 ABI \u4e0d\u517c\u5bb9\u95ee\u9898\u3002\u6bd5\u7adf\u7ebf\u7a0b\u4e0d\u5b89\u5168\u5b9e\u5728\u592a\u4f24\u4e86\uff0c\u57fa\u672c\u610f\u5473\u7740\u591a\u7ebf\u7a0b\u5c31\u6ca1\u6cd5\u5171\u4eab std::string \u3002\u4e8b\u5b9e\u4e0a\uff0cQt \u6240\u6709\u7684\u5bf9\u8c61 QObject \uff0c\u5305\u62ec QString \u5728\u591a\u7ebf\u7a0b\u4e2d\u4f20\u9012\u65f6\uff0c\u5c31\u9700\u8981\u8c03\u7528 moveTo(QThread) \u8f6c\u79fb\u6240\u6709\u6743\uff0c\u624d\u80fd\u5b89\u5168\u5730\u4f20\u9012\u7ed9\u53e6\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u5c31\u662f\u56e0\u4e3a Qt \u5927\u91cf\u4f7f\u7528\u4e86 COW \u673a\u5236\u3002","title":"COW \u5b57\u7b26\u4e32"},{"location":"unicode/#unicode_1","text":"","title":"Unicode \u77e5\u8bc6\u8fdb\u9636"},{"location":"unicode/#_22","text":"TODO","title":"\u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97"},{"location":"unicode/#grapheme","text":"TODO","title":"Grapheme"},{"location":"unicode/#_23","text":"TODO","title":"\u6b63\u89c4\u5316"},{"location":"unicode/#_24","text":"TODO","title":"\u96f6\u5bbd\u7a7a\u683c"},{"location":"unicode/#_25","text":"TODO","title":"\u7279\u6b8a\u63a7\u5236\u5b57\u7b26"},{"location":"unicode/#unicode_2","text":"\u201c\ud883\udede\u201d\u7684 Unicode \u7f16\u53f7\u662f 0x30EDE\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0c\u901a\u5e38\u53ef\u4ee5\u8f93\u5165 Ctrl+Shift+U \u7136\u540e\u8f93\u5165\u5341\u516d\u8fdb\u5236\u7f16\u53f7\uff0c3 0 E D E\uff0c\u7136\u540e Enter\uff0c\u5c31\u8f93\u5165\u4e86\u201c\ud883\udede\u201d\u3002 \u5728 Windows \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Win+R\uff0c\u7136\u540e\u8f93\u5165 charmap \uff0c\u6253\u5f00\u5b57\u7b26\u6620\u5c04\u8868\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u53cc\u51fb\u53ef\u4ee5\u590d\u5236\u5230\u526a\u8d34\u677f\u3002 \u5728 macOS \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Ctrl+Cmd+\u7a7a\u683c\uff0c\u6253\u5f00\u7279\u6b8a\u5b57\u7b26\u8f93\u5165\u9762\u677f\uff0c\u9009\u62e9\u201cUnicode\u201d\u5206\u7c7b\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u7136\u540e\u53cc\u51fb\u5c31\u8f93\u5165\u5230\u5149\u6807\u5904\u3002","title":"\u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26"},{"location":"unicode/#unifont","text":"TODO","title":"UniFont \u5b57\u4f53"},{"location":"unicode/#_26","text":"","title":"\u9ed1\u6697\u5c0f\u6280\u5de7"},{"location":"unicode/#_27","text":"\u72ed\u4e49\u7684\u6c49\u5b57\uff1a0x4E00 \u5230 0x9FA5\uff08\u201c\u4e00\u201d\u5230\u201c\u9fa5\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\uff1a0x2E80 \u5230 0x9FFF\uff08\u201c\u2e80\u201d\u5230\u201c\u9fff\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\u5305\u542b\u4e86\u51e0\u4e4e\u6240\u6709\u4e2d\u65e5\u97e9\u4f7f\u7528\u7684\u6c49\u5b57\u5b57\u7b26\uff0c\u800c\u72ed\u4e49\u7684\u6c49\u5b57\u53ea\u662f\u4e2d\u6587\u91cc\u6700\u5e38\u7528\u7684\u4e00\u90e8\u5206\u3002 TODO","title":"\u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f"},{"location":"unicode/#latin-1_1","text":"Latin-1 \u662f\u4e00\u4e2a 8 \u4f4d\u7f16\u7801\uff0c\u80fd\u8868\u793a 256 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u62c9\u4e01\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u3001\u5e38\u7528\u7684\u897f\u6b27\u5b57\u7b26\uff0c\u4ee5\u53ca\u4e00\u4e9b\u7279\u6b8a\u5b57\u7b26\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u4f60\u9700\u8981\u628a\u4e00\u4e2a Latin-1 \u7f16\u7801\u7684 char \u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a wchar_t \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fed\u4ee3\u5668\u63a5\u53e3\u6784\u9020 std::wstring \uff0c\u8fd9\u6837 char \u4f1a\u88ab\u9010\u4e2a\u8f6c\u6362\u4e3a wchar_t \u3002 std::string latin1 = \"I love P\\xE9ng\"; // 0xE9: \u00e9 std::wstring wstr(latin1.begin(), latin1.end()); std::wcout << wstr << '\\n'; \u8f93\u51fa\uff1a I love P\u00e9ng \u5e76\u4e0d\u6807\u51c6\u7684\u505a\u6cd5\uff0c\u8fd8\u662f\u5efa\u8bae\u7528 boost::locale::conv::to_utf(latin1, \"Latin-1\") \u3002","title":"Latin-1 \u7684\u8f6c\u6362"},{"location":"unicode/#latin-1_2","text":"\u7531\u4e8e Latin-1 \u8986\u76d6\u4e86\u6240\u6709\u7684 256 \u4e2a char \u7684\u53ef\u80fd\u503c\uff0c\u4efb\u4f55\u5b57\u8282\u6d41\u90fd\u53ef\u4ee5\u6210\u529f\u89e3\u7801\u3002 GBK \u548c UTF-8 \u6709\u81ea\u7ea0\u9519\u6027\uff0c\u6709\u4e9b\u8f93\u5165\u4f1a\u88ab\u584c\u7f29\u6210\u9519\u8bef\u201c\ufffd\u201d\u3002Latin-1 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u7167\u5355\u5168\u6536\uff01 \u56e0\u6b64\u6709\u65f6\uff0c\u4eba\u4eec\u53ef\u4ee5\u6b3a\u9a97\u4e00\u4e2a\u7f16\u7801\u5668\u8bf4\u201c\u6211\u91c7\u7528\u7684\u5b57\u7b26\u7f16\u7801\u662f Latin-1\u201d\uff01\u8fd9\u6837\u7f16\u7801\u5668\u5c31\u4e0d\u4f1a\u5bf9\u8f93\u5165\u7684\u5b57\u8282\u6d41\u505a\u4efb\u4f55\u8f6c\u6362\uff0c\u4ece\u800c\u53ef\u4ee5\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5f53\u6587\u672c\u6765\u4f20\uff0c\u89e3\u7801\u65f6\u4e5f\u6307\u5b9a Latin-1\uff0c\u539f\u539f\u672c\u672c\u7684\u53d6\u51fa\u6570\u636e\u3002","title":"Latin-1 \u7684\u5999\u7528"},{"location":"unicode/#base64","text":"\u5982\u679c\u8981\u628a\u4e00\u4e32\u4e2d\u6587\u8f93\u5165\u4e00\u4e2a\u4e0d\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\uff0c\u53d1\u9001\u8ba9\u5bf9\u65b9\u6536\u5230\uff0c\u600e\u4e48\u529e\uff1f \u53ef\u4ee5\u7528 Latin-1 \u7f16\u7801\uff0c\u9a97\u8fd9\u4e2a\u8f6f\u4ef6\uff0c\u8ba9\u4ed6\u4ee5\u4e3a\u81ea\u5df1\u6536\u5230\u7684\u662f Latin-1 \u5b57\u7b26\u4e32\uff0c\u53cd\u6b63\u4ed6\u4e5f\u4e0d\u770b\u5185\u5bb9\uff0c\u4ece\u800c\u8ba9\u4ed6\u4e0d\u8981\u505a\u4efb\u4f55\u8f6c\u6362\u64cd\u4f5c\u3002 \u4e0d\u8fc7\u6709\u65f6\u5019\uff0c\u6587\u672c\u6846\u65e0\u6cd5\u8f93\u5165\u90e8\u5206\u7279\u6b8a\u7684\u63a7\u5236\u5b57\u7b26\uff0c\u800c UTF-8 \u5b57\u7b26\u4e32\u7f16\u7801\u51fa\u6765\u7684\u6587\u672c\uff0c\u8d85\u8fc7 0x80 \u7684\u90e8\u5206\uff0c\u53ef\u80fd\u843d\u5165 Latin-1 \u7684\u63a7\u5236\u5b57\u7b26\u4e2d\uff0c\u88ab\u8fd9\u4e2a\u8f6f\u4ef6\u9519\u8bef\u5730\u505a\u4e86\u7279\u6b8a\u5904\u7406\u3002 \u4e3a\u4e86\u907f\u514d\u53ea\u517c\u5bb9\u4e86 ASCII \u7684\u843d\u540e\u8f6f\u4ef6\u7834\u574f\u6211\u4eec\u7684\u5b57\u7b26\uff0c\u5bf9\u4e8e\u8fd9\u79cd\u53ea\u652f\u6301 ASCII \u6587\u672c\u7684\u7f16\u8f91\u6846\uff0c\u6211\u4eec\u53ef\u4ee5\u7528 Base64 \u7f16\u7801\u5148\u628a\u4efb\u610f\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u3002 Base64 \u662f\u4e00\u79cd\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u7684\u7b97\u6cd5\uff0c\u539f\u7406\u5f88\u7b80\u5355\uff0c\u5c31\u662f\u628a\u6bcf 6 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u8f6c\u6362\u4e3a\u4e00\u4e2a\u53ef\u6253\u5370\u7684 ASCII \u5b57\u7b26\uff08\u7528 A-Z a-z 0-9 - / \u8fd9 64 \u4e2a\u5b57\u7b26\u8868\u793a\uff09\u3002\u56e0\u6b64\uff0cBase64 \u7f16\u7801\u540e\u7684\u6587\u672c\uff0c\u6bcf 4 \u4e2a\u5b57\u7b26\u5c31\u6709 3 \u4e2a\u662f\u6709\u6548\u5b57\u7b26\uff0c\u5269\u4e0b\u7684 1 \u4e2a\u5b57\u7b26\u662f\u586b\u5145\u5b57\u7b26 = \u3002 \u4f8b\u5982\uff0c\u5b57\u7b26\u4e32 \"\u5c0f\u5f6d\u8001\u5e08\" \uff0c\u4f60\u53ef\u80fd\u60f3\u8981\u628a\u5b83\u901a\u8fc7\u90ae\u4ef6\u53d1\u51fa\u53bb\u3002\u800c\u8fd9\u4e2a\u90ae\u4ef6\u670d\u52a1\u5668\u4e0d\u652f\u6301 UTF-8 \u4e5f\u4e0d\u652f\u6301 GBK\uff0c\u53ea\u652f\u6301 ASCII\uff01 \u9996\u5148\u6211\u4eec\u7528 UTF-8 \u7f16\u7801\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff1a 0xE5 0xB0 0x8F 0xE5 0xBD 0xAD 0xE8 0x80 0x81 0xE5 0xB8 0x88 \u7136\u540e\u518d\u7528 Base64 \u4e8c\u6b21\u7f16\u7801\u6210\u666e\u901a\u7684\u53ef\u6253\u5370\u5b57\u6bcd\u548c\u6570\u5b57\u5e8f\u5217\uff1a 5bCP5b2t6ICB5biI \u5bf9\u65b9\u6536\u5230\u8fd9\u4e32\u795e\u79d8\u5b57\u7b26\u540e\uff0c\u518d\u7528 base64 \u89e3\u7801\uff0c\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c\u518d\u7528\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\u89e3\u7801\uff0c\u5c31\u80fd\u770b\u5230\u672c\u6765\u7684\u4e2d\u6587\u4e86\u3002 # \u53d1\u9001\u8005\uff1a import base64 secret = base64.b64encode(\"\u5c0f\u5f6d\u8001\u5e08\".encode()) # \u63a5\u6536\u8005\uff1a base64.b64decode(secret).decode() \u8fd9\u4e2a\u65b9\u6cd5\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u7801 UTF-8 \u5b57\u7b26\u4e32\uff0c\u8fd8\u53ef\u4ee5\u4f20\u8f93\u4efb\u610f\u975e\u6587\u672c\u7684\u6587\u4ef6\uff01\u4f8b\u5982\uff0c\u6709\u4eba\u5229\u7528 Base64 \u7f16\u7801\uff0c\u628a jpg \u56fe\u50cf\u6587\u4ef6\u76f4\u63a5\u5185\u5d4c\u5728 md \u6587\u4ef6\u91cc\uff01\uff08md \u6587\u4ef6\u53ea\u652f\u6301\u5305\u542b\u5408\u6cd5\u7684 UTF-8 \u6587\u672c\uff0c\u4e0d\u53ef\u80fd\u5305\u542b jpg \u7684\u4efb\u610f\u5b57\u8282\u6d41\uff0c\u56e0\u6b64\u53ea\u80fd\u7528 Base64 \u5148\u7f16\u7801\u6210 ASCII \u8303\u56f4\u5185\u7684\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u9632\u6b62 md \u7f16\u8bd1\u5668\u62a5 UTF-8 \u89e3\u7801\u9519\u8bef\uff09 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u8f93\u5165\u4e2d\u6587\u5b9e\u5728\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u8003\u8651\u5148 Base64 \u8f6c\u6362\u6210\u7eaf\u82f1\u6587\u8bd5\u8bd5\u770b\uff0c\u53cd\u6b63\u65e0\u8bba\u8c01\u90fd\u517c\u5bb9 ASCII\u3002\u5982\u679c\u8fd9\u4e2a\u6587\u672c\u6846\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff0c\u8fd8\u53ef\u4ee5\u8bd5\u8bd5\u770b\u53ea\u6709 A-Z 0-9 \u7684 Base32 \u7f16\u7801\u3002","title":"Base64 \u9632\u4e71\u7801"},{"location":"unicode/#utf-7","text":"TODO","title":"UTF-7"},{"location":"unicode/#_28","text":"TODO","title":"\u5b57\u7b26\u7f16\u7801\u731c\u6d4b"},{"location":"variable_types/","text":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) \u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) TODO","title":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5)"},{"location":"variable_types/#_1","text":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) TODO","title":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5)"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"\u5c0f\u5f6d\u8001\u5e08\u73b0\u4ee3 C++ \u5927\u5178 \u5c0f\u5f6d\u5927\u5178\u662f\u4e00\u672c\u5173\u4e8e\u73b0\u4ee3 C++ \u7f16\u7a0b\u7684\u6743\u5a01\u6307\u5357\uff0c\u5b83\u6db5\u76d6\u4e86\u4ece\u57fa\u7840\u77e5\u8bc6\u5230\u9ad8\u7ea7\u6280\u5de7\u7684\u5185\u5bb9\uff0c\u9002\u5408\u521d\u5b66\u8005\u548c\u6709\u7ecf\u9a8c\u7684\u7a0b\u5e8f\u5458\u9605\u8bfb\u3002\u672c\u4e66\u7531\u5c0f\u5f6d\u8001\u5e08\u4eb2\u81ea\u7f16\u5199\uff0c\u901a\u8fc7\u7b80\u5355\u6613\u61c2\u7684\u8bed\u8a00\u548c\u4e30\u5bcc\u7684\u793a\u4f8b\uff0c\u5e2e\u52a9\u8bfb\u8005\u5feb\u901f\u638c\u63e1 C++ \u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8fd0\u7528\u5b83\u4eec\u6765\u89e3\u51b3\u5b9e\u9645\u95ee\u9898\u3002 \u6562\u627f\u8bfa\uff1a\u571f\u6728\u8001\u54e5\u4e5f\u80fd\u770b\u61c2\uff01 \u524d\u8a00 \u63a8\u8350\u7528\u624b\u673a\u6216\u5e73\u677f \u7ad6\u5c4f \u89c2\u770b\uff0c\u53ef\u4ee5\u5728\u5e8a\u6216\u6c99\u53d1\u4e0a\u8eba\u7740\u3002 \u7528\u7535\u8111\u770b\u7684\u8bdd\uff0c\u53ef\u4ee5\u6309 WIN + \u2190 \uff0c\u628a\u672c\u4e66\u7684\u6d4f\u89c8\u5668\u7a97\u53e3\u653e\u5728\u5c4f\u5e55\u5de6\u4fa7\uff0c\u53f3\u4fa7\u662f\u4f60\u7684 IDE\u3002\u4e00\u8fb9\u770b\u4e00\u8fb9\u81ea\u5df1\u52a8\u624b\u505a\u5b9e\u9a8c\u3002 \u8bf7\u5750\u548c\u653e\u5bbd\u3002 \u53ef\u4ee5\u6309\u987a\u5e8f\u9605\u8bfb\uff0c\u4e5f\u53ef\u4ee5\u5728\u672c\u9875\u9762\u4e0a\u65b9\u5bfc\u822a\u680f\u7684\u201c\u7ae0\u8282\u5217\u8868\u201d\u4e2d\uff0c\u9009\u62e9\u611f\u5174\u8da3\u7684\u7ae0\u8282\u9605\u8bfb\u3002 \u672c\u4e66\u5b8c\u5168\u5f00\u6e90\u548c\u514d\u8d39\uff0cGitHub \u4ed3\u5e93\uff1a https://github.com/parallel101/cppguidebook \u5982\u679c\u4f60\u662f\u5728\u4ed8\u8d39\u7fa4\u4e2d\u201c\u4e70\u201d\u5230\u672c\u4e66\uff0c\u6216\u8005\u6253\u7740\u5c0f\u5f6d\u8001\u5e08\u540d\u53f7\u5356\u8bfe\uff0c\u8bf4\u660e\u4f60\u53ef\u80fd\u662f\u79c1\u6709\u5236\u7684\u53d7\u5bb3\u8005\u3002\u56e0\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4ece\u6765\u6ca1\u6709\u4ed8\u8d39\u624d\u80fd\u770b\u7684\u8bfe\u7a0b\uff0c\u6240\u6709\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b\u90fd\u5bf9\u5168\u7403\u4e92\u8054\u7f51\u5f00\u653e\u3002 \u5982\u9700\u79bb\u7ebf\u67e5\u770b\uff0c\u53ef\u4ee5\u524d\u5f80 GitHub Release \u9875\u9762 \u4e0b\u8f7d PDF \u6587\u4ef6\u3002 \u5982\u679c\u4f60\u5728\u9605\u8bfb\u8fc7\u7a0b\u4e2d\u9047\u5230\u4efb\u4f55\u95ee\u9898\uff0c\u53ef\u4ee5\u5728 GitHub Issues \u4e2d\u63d0\u51fa\uff0c\u5c0f\u5f6d\u8001\u5e08\u4f1a\u5c3d\u529b\u89e3\u7b54\u3002 \u4e5f\u53ef\u4ee5\u5728 B \u7ad9 \u53d1\u79c1\u4fe1\u7ed9\u5c0f\u5f6d\u8001\u5e08\u54e6\u3002 \u672c\u4e66\u8fd8\u5728\u6301\u7eed\u66f4\u65b0\u4e2d\u2026\u2026\u8981\u8ffd\u756a\u7684\u8bdd\uff0c\u53ef\u4ee5\u5728 GitHub \u70b9\u4e00\u4e0b\u53f3\u4e0a\u89d2\u7684 \u201cWatch\u201d \u6309\u94ae\uff0c\u6bcf\u5f53\u5c0f\u5f6d\u8001\u5e08\u63d0\u4ea4\u65b0 commit\uff0cGitHub \u4f1a\u5411\u4f60\u53d1\u9001\u4e00\u5c01\u7535\u5b50\u90ae\u4ef6\uff0c\u63d0\u9192\u4f60\u5c0f\u5f6d\u8001\u5e08\u66f4\u65b0\u4e86\u3002 \u66f4\u65b0\u65f6\u95f4\uff1a2024\u5e7411\u670809\u65e5 11:39:40 (UTC+08:00) \u5728 GitHub Pages \u6d4f\u89c8\u672c\u4e66 | \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u5df1\u7ef4\u62a4\u7684\u955c\u50cf\u4e0a\u6d4f\u89c8\u672c\u4e66 \u683c\u5f0f\u7ea6\u5b9a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u6e29\u99a8\u63d0\u793a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u53ef\u80fd\u72af\u9519\u7684\u8b66\u544a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u7b11\u8bdd\u6216\u8da3\u5473\u5bd3\u8a00\u6545\u4e8b \u7528\u8fd9\u79cd\u989c\u8272\u4e66\u5199\u7684\u662f\u8865\u5145\u8bf4\u660e\u7684\u8bfe\u5916\u9605\u8bfb\uff0c\u770b\u4e0d\u61c2\u4e5f\u6ca1\u5173\u7cfb \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u662f\u521d\u5b66\u8005\u53ef\u6682\u65f6\u4e0d\u7528\u7406\u89e3\u7684\u7ec6\u8282 \u672f\u8bed\u540d\u79f0: \u8fd9\u91cc\u662f\u672f\u8bed\u7684\u5b9a\u4e49\u3002 \u89c2\u524d\u987b\u77e5 \u4e0e\u5927\u591a\u6570\u73b0\u6709\u6559\u6750\u4e0d\u540c\u7684\u662f\uff0c\u672c\u8bfe\u7a0b\u5c06\u4f1a\u91c7\u7528\u201c\u5012\u53d9\u201d\u7684\u5f62\u5f0f\uff0c\u4ece\u6700\u65b0\u7684 C++23 \u8bb2\u8d77\uff01\u7136\u540e\u8bb2 C++20\u3001C++17\u3001C++14\u3001C++11\uff0c\u6162\u6162\u8bb2\u5230\u6700\u539f\u59cb\u7684 C++98\u3002 \u4e0d\u7528\u62c5\u5fc3\uff0c\u8d8a\u662f\u73b0\u4ee3\u7684 C++\uff0c\u5b66\u8d77\u6765\u53cd\u800c\u66f4\u5bb9\u6613\uff01\u53cd\u800c\u53e4\u4ee3 C++ \u624d \u53c8\u81ed\u53c8\u957f \u3002 \u5f88\u591a\u540c\u5b66\u60f3\u5f53\u7136\u5730\u8bef\u4ee5\u4e3a C++98 \u6700\u7b80\u5355\uff0c\u54fc\u54e7\u54fc\u54e7\u8d39\u8001\u5927\u52b2\u4ece C++98 \u5f00\u59cb\u5b66\uff0c\u624d\u662f\u9519\u8bef\u7684\u3002 \u4e3a\u4e86\u5e94\u4ed8\u7f3a\u80f3\u818a\u5c11\u817f\u7684 C++98\uff0c\u4eba\u4eec\u53d1\u660e\u4e86\u5404\u79cd \u7e41\u7410\u65e0\u8c13 \u7684\u5199\u6cd5\uff0c\u5728\u73b0\u4ee3 C++ \u4e2d\uff0c\u65e9\u5c31\u5df2\u7ecf\u88ab\u66f4 \u7b80\u6d01\u76f4\u89c2 \u7684\u5199\u6cd5\u66ff\u4ee3\u4e86\u3002 \u4f8b\u5982\u6240\u8c13\u7684 safe-bool idiom\uff0c\u5199\u8d77\u6765\u53c8\u81ed\u53c8\u957f\uff0cC++11 \u5f15\u5165\u4e00\u4e2a explicit \u5173\u952e\u5b57\u76f4\u63a5\u5c31\u79d2\u4e86\u3002\u7ed3\u679c\u8fd8\u6709\u4e00\u6279\u52b3\u4fdd\u6559\u6750\u5927\u5439\u7279\u5439 safe-bool idiom\uff0c\u5439\u5f97\u597d\u50cf\u662f\u4e2a\u4ec0\u4e48\u9ad8\u5927\u4e0a\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e00\u6837\uff0c\u4e0d\u8fc7\u662f\u4e2a\u5e94\u4ed8 C++98 \u8bed\u8a00\u7f3a\u9677\u7684\u8e69\u811a\u73a9\u610f\u3002 \u5c31\u597d\u6bd4\u4e00\u4e2a \u8001\u5916 \u60f3\u8981\u5b66\u4e60\u6c49\u8bed\uff0c\u4ed6\u9996\u5148\u80af\u5b9a\u662f\u4ece \u73b0\u4ee3\u6c49\u8bed \u5b66\u8d77\uff01\u800c\u4e0d\u662f\u4e0a\u6765\u5c31\u6559\u4ed6 \u6587\u8a00\u6587 \u3002 \u5373\u4f7f\u8fd9\u4e2a\u8001\u5916\u7684\u804c\u4e1a\u5c31\u662f\u201c\u8003\u53e4\u201d\uff0c\u6216\u8005\u4ed6\u5bf9\u201c\u53e4\u4ee3\u6587\u5b66\u201d\u611f\u5174\u8da3\uff0c\u4e5f\u4e0d\u53ef\u80fd\u81ea\u5b66\u6587\u8a00\u6587\u7684\u540c\u65f6\u5b8c\u5168\u8df3\u8fc7\u73b0\u4ee3\u6c49\u8bed\u3002 \u5f53\u6211\u4eec\u5b66\u4e60\u4e2d\u6587\u65f6\uff0c\u4f60\u80af\u5b9a\u5e0c\u671b\u5148\u5b66\u73b0\u4ee3\u6c49\u8bed\uff0c\u518d\u5b66\u6587\u8a00\u6587\uff0c\u518d\u5b66\u7532\u9aa8\u6587\uff0c\u518d\u5b66 brainf* * k\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u5bf9\u4e8e C++ \u521d\u5b66\u8005\u4e5f\u662f\u5982\u6b64\uff1a\u6211\u4eec\u9996\u5148\u5b66\u4f1a\u7b80\u5355\u660e\u4e86\u7684\uff0c\u7b26\u5408\u73b0\u4ee3\u4eba\u601d\u7ef4\u7684 C++23\uff0c\u518d\u9010\u6e10\u56de\u5230\u4e13\u4e3a\u4f3a\u5019\u201c\u53e4\u4ee3\u5f00\u53d1\u73af\u5883\u201d\u7684 C++98\u3002 \u4f60\u7684\u751f\u4ea7\u73af\u5883\u53ef\u80fd\u4e0d\u5141\u8bb8\u7528\u4e0a C++20 \u751a\u81f3 C++23 \u7684\u65b0\u6807\u51c6\u3002 \u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u6559\u4f1a\u4f60 C++23 \u7684\u6b63\u5e38\u5199\u6cd5\u540e\uff0c\u4f1a\u8bb2\u89e3\u5982\u4f55\u5728 C++14\u3001C++98 \u4e2d\u5199\u51fa\u540c\u6837\u7684\u6548\u679c\u3002 \u8fd9\u6837\u4f60\u5b66\u4e60\u7684\u65f6\u5019\u601d\u8def\u6e05\u6670\uff0c\u4e0d\u7528\u88ab\u7e41\u7410\u7684 C++98 \u201c\u5947\u6280\u6deb\u5de7\u201d\u5e72\u6270\uff0c\u5b66\u8d77\u6765\u4e8b\u534a\u529f\u500d\uff1b\u4f46\u4e5f\u201c\u5403\u8fc7\u89c1\u8fc7\u201d\uff0c\u77e5\u9053\u53e4\u4ee3 C++98 \u7684\u5e94\u5bf9\u7b56\u7565\u3002 \u76ee\u524d\u4f01\u4e1a\u91cc\u4e3b\u6d41\u4f7f\u7528\u7684\u662f C++14 \u548c C++17\u3002\u4f8b\u5982\u8c37\u6b4c\u5c31\u660e\u786e\u89c4\u5b9a\u8981\u6c42 C++17\u3002 \u4e3e\u4e2a\u4f8b\u5b50 \u63a5\u4e0b\u6765\u7684\u4f8b\u5b50\u4f60\u53ef\u80fd\u770b\u4e0d\u61c2\uff0c\u4f46\u53ea\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e2a\u4f8b\u5b50\u662f\u5411\u4f60\u8bf4\u660e\uff1a\u8d8a\u662f\u65b0\u7684 C++ \u6807\u51c6\uff0c\u53cd\u800c\u8d8a\u5bb9\u6613\u5b66\uff01 \u4f8b\u5982\uff0c\u5728\u6a21\u677f\u5143\u7f16\u7a0b\u4e2d\uff0c\u8981\u68c0\u6d4b\u4e00\u4e2a\u7c7b\u578b T \u662f\u5426\u62e5\u6709 foo() \u8fd9\u4e00\u6210\u5458\u51fd\u6570\u3002\u5982\u679c\u5b58\u5728\uff0c\u624d\u4f1a\u8c03\u7528\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528\u5f88\u65b9\u4fbf\u7684 requires \u8bed\u6cd5\uff0c\u8f7b\u677e\u68c0\u6d4b\u4e00\u4e2a\u8868\u8fbe\u5f0f\u662f\u5426\u80fd\u5408\u6cd5\u901a\u8fc7\u7f16\u8bd1\u3002\u5982\u679c\u80fd\uff0c requires \u8bed\u53e5\u4f1a\u8fd4\u56de true \u3002\u7136\u540e\u7528\u4e00\u4e2a if constexpr \u8fdb\u884c\u7f16\u8bd1\u671f\u5206\u652f\u5224\u65ad\uff0c\u5373\u53ef\u5b9e\u73b0\u68c0\u6d4b\u5230\u5b58\u5728\u5219\u8c03\u7528\u3002 template void try_call_foo(T &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } \u4f46\u4ec5\u4ec5\u662f\u56de\u5230 C++17\uff0c\u6ca1\u6709 requires \u8bed\u6cd5\uff0c\u6211\u4eec\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a trait \u7c7b\uff0c\u5e76\u8fd0\u7528\u70e6\u4eba\u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u68c0\u6d4b\u8868\u8fbe\u5f0f\u662f\u5426\u7684\u5408\u6cd5\uff0c\u53c8\u81ed\u53c8\u957f\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template void try_call_foo(T &t) { if constexpr (has_foo::value) { t.foo(); } } \u5982\u679c\u56de\u5230 C++14\uff0c\u60c5\u51b5\u5c31\u66f4\u7cdf\u7cd5\u4e86\uff01 if constexpr \u662f C++17 \u7684\u7279\u6027\uff0c\u6ca1\u6709\u4ed6\uff0c\u8981\u5b9e\u73b0\u7f16\u8bd1\u671f\u5206\u652f\uff0c\u6211\u4eec\u5c31\u5f97\u7528 enable_if_t \u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u9700\u8981\u5b9a\u4e49\u4e24\u4e2a try_call_foo \u51fd\u6570\uff0c\u4e92\u76f8\u91cd\u8f7d\uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template ::value, int> = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int> = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++11\uff0c\u60c5\u51b5\u8fdb\u4e00\u6b65\u6076\u5316\uff01 enable_if_t \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5c0f\u52a9\u624b\u5df2\u7ecf\u4e0d\u5b58\u5728\uff0c\u9700\u8981\u4f7f\u7528\u6bd4\u4ed6\u66f4\u5e95\u5c42\u7684 enable_if \u6a21\u677f\u7c7b\uff0c\u624b\u52a8\u53d6\u51fa ::type \uff0c\u5e76\u4e14\u9700\u8981 typename \u4fee\u9970\uff0c\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff01\u5e76\u4e14 void_t \u4e5f\u4e0d\u80fd\u7528\u4e86\uff0c\u8981\u7528\u9017\u53f7\u8868\u8fbe\u5f0f\u5c0f\u6280\u5de7\u624d\u80fd\u8ba9 decltype \u56fa\u5b9a\u8fd4\u56de void\u2026\u2026 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo(), (void)0)> { static constexpr bool value = true; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++98\uff0c\u90a3\u53c8\u8981\u7f6a\u52a0\u4e00\u7b49\uff01 enable_if \u548c declval \u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u7684\u5e2e\u624b\u7c7b\u548c\u5e2e\u624b\u51fd\u6570\uff0c\u5728 C++98 \u4e2d\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5b9e\u73b0 enable_if \u2026\u2026 declval \u4e5f\u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u4e2d\u7684\u5e2e\u624b\u51fd\u6570\u2026\u2026\u5047\u8bbe\u4f60\u81ea\u5df1\u597d\u4e0d\u5bb9\u6613\u5b9e\u73b0\u51fa\u6765\u4e86 enable_if \u548c declval \uff0c\u8fd8\u6ca1\u5b8c\uff1a\u56e0\u4e3a constexpr \u5728 C++98 \u4e2d\u4e5f\u4e0d\u5b58\u5728\u4e86\uff01\u4f60\u65e0\u6cd5\u5b9a\u4e49 value \u6210\u5458\u53d8\u91cf\u4e3a\u7f16\u8bd1\u671f\u5e38\u91cf\uff0c\u6211\u4eec\u53ea\u597d\u53c8\u7528\u4e00\u4e2a\u62bd\u8c61\u7684\u679a\u4e3e\u5c0f\u6280\u5de7\u6765\u5b9e\u73b0\u5b9a\u4e49\u7c7b\u6210\u5458\u5e38\u91cf\u7684\u6548\u679c\u3002 template struct has_foo { enum { value = 0 }; }; template struct has_foo().foo(), (void)0)> { enum { value = 1 }; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u6b64\u5197\u957f\u96be\u61c2\u7684\u62bd\u8c61 C++98 \u4ee3\u7801\uff0c\u4eff\u4f5b\u662f\u201c\u52a0\u5bc6\u201d\u8fc7\u7684\u4ee3\u7801\u4e00\u6837\uff0c\u4ec5\u4ec5\u662f\u4e3a\u4e86\u5b9e\u73b0\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6210\u5458\u51fd\u6570 foo\u2026\u2026 \u5982\u679c\u56de\u5230 C \u8bed\u8a00\uff0c\u90a3\u4e48\u4f60\u751a\u81f3\u90fd\u4e0d\u7528\u68c0\u6d4b\u4e86\u3002\u56e0\u4e3a\u4f1f\u5927\u7684 C \u8bed\u8a00\u8fde\u6210\u5458\u51fd\u6570\u90fd\u6ca1\u6709\uff0c\u4f55\u8c08\u201c\u68c0\u6d4b\u6210\u5458\u51fd\u6570\u662f\u5426\u5b58\u5728\u201d\uff1f \u53cd\u89c2 C++20 \u7684\u5199\u6cd5\uff0c\u4e00\u773c\u5c31\u770b\u660e\u767d\u4ee3\u7801\u7684\u903b\u8f91\u662f\u4ec0\u4e48\uff0c\u8868\u8fbe\u4f60\u8be5\u8868\u8fbe\u7684\uff0c\u800c\u4e0d\u662f\u8ff7\u5931\u4e8e\u4f3a\u5019\u5404\u79cd\u8bed\u8a00\u7f3a\u9677\uff0c\u5e72\u6270\u6211\u4eec\u5b66\u4e60\u3002 void try_call_foo(auto &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } // \u4ece\u6b8b\u5e9f\u7684 C++98 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u5c31\u88ab\u8fd9\u4e9b\u65e0\u8c13\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u626d\u66f2\u4e86\uff0c\u800c\u4f7f\u5f97\u771f\u6b63\u5e94\u8be5\u8868\u8fbe\u7684\u4ee3\u7801\u903b\u8f91\uff0c\u6df9\u6ca1\u5728\u53c8\u81ed\u53c8\u957f\u7684\u53e4\u4ee3\u6280\u5de7\u4e2d\u3002 // \u4ece\u73b0\u4ee3\u7684 C++23 \u5b66\u8d77\uff0c\u5148\u77e5\u9053\u6b63\u5e38\u7684\u5199\u6cd5\u201c\u7406\u5e94\u201d\u662f\u4ec0\u4e48\u6837\u3002\u5de5\u4f5c\u4e2d\u7528\u4e0d\u4e0a C++23\uff1f\u6211\u4f1a\u5411\u4f60\u4ecb\u7ecd\uff0c\u5982\u679c\u8981\u5012\u9000\u56de C++14\uff0c\u53e4\u4ee3\u4eba\u90fd\u662f\u7528\u4ec0\u4e48\u201c\u5947\u6280\u6deb\u5de7\u201d\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 // \u8fd9\u6837\u4f60\u6700\u540e\u540c\u6837\u53ef\u4ee5\u9002\u5e94\u516c\u53f8\u8981\u6c42\u7684 C++14 \u73af\u5883\u3002\u4f46\u662f\u4ece C++23 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u53c8\u4e0d\u4f1a\u88ab\u5e94\u4ed8\u53e4\u4ee3\u8bed\u8a00\u7f3a\u9677\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u6270\u4e71\uff0c\u5b66\u8d77\u6765\u5c31\u4e8b\u534a\u529f\u500d\u3002 \u65e2\u7136\u73b0\u4ee3 C++ \u8fd9\u4e48\u597d\uff0c\u4e3a\u4ec0\u4e48\u5b66\u6821\u4e0d\u4ece\u73b0\u4ee3 C++ \u6559\u8d77\uff0c\u6559\u8d77\u6765\u8fd8\u8f7b\u677e\uff1f\u56e0\u4e3a\u52b3\u4fdd\u8001\u5e08\u4fdd\uff0c\u61d2\u5f97\u63a5\u89e6\u65b0\u77e5\u8bc6\uff0c\u8ba4\u4e3a\u201c\u7956\u5b97\u4e4b\u6cd5\u4e0d\u53ef\u53d8\u201d\uff0c\u201c\u7248\u53f7\u7a33\u5b9a\u538b\u5012\u4e00\u5207\u201d\u3002","title":"\u524d\u8a00"},{"location":"#c","text":"\u5c0f\u5f6d\u5927\u5178\u662f\u4e00\u672c\u5173\u4e8e\u73b0\u4ee3 C++ \u7f16\u7a0b\u7684\u6743\u5a01\u6307\u5357\uff0c\u5b83\u6db5\u76d6\u4e86\u4ece\u57fa\u7840\u77e5\u8bc6\u5230\u9ad8\u7ea7\u6280\u5de7\u7684\u5185\u5bb9\uff0c\u9002\u5408\u521d\u5b66\u8005\u548c\u6709\u7ecf\u9a8c\u7684\u7a0b\u5e8f\u5458\u9605\u8bfb\u3002\u672c\u4e66\u7531\u5c0f\u5f6d\u8001\u5e08\u4eb2\u81ea\u7f16\u5199\uff0c\u901a\u8fc7\u7b80\u5355\u6613\u61c2\u7684\u8bed\u8a00\u548c\u4e30\u5bcc\u7684\u793a\u4f8b\uff0c\u5e2e\u52a9\u8bfb\u8005\u5feb\u901f\u638c\u63e1 C++ \u7684\u6838\u5fc3\u6982\u5ff5\uff0c\u5e76\u5b66\u4f1a\u5982\u4f55\u8fd0\u7528\u5b83\u4eec\u6765\u89e3\u51b3\u5b9e\u9645\u95ee\u9898\u3002 \u6562\u627f\u8bfa\uff1a\u571f\u6728\u8001\u54e5\u4e5f\u80fd\u770b\u61c2\uff01","title":"\u5c0f\u5f6d\u8001\u5e08\u73b0\u4ee3 C++ \u5927\u5178"},{"location":"#_1","text":"\u63a8\u8350\u7528\u624b\u673a\u6216\u5e73\u677f \u7ad6\u5c4f \u89c2\u770b\uff0c\u53ef\u4ee5\u5728\u5e8a\u6216\u6c99\u53d1\u4e0a\u8eba\u7740\u3002 \u7528\u7535\u8111\u770b\u7684\u8bdd\uff0c\u53ef\u4ee5\u6309 WIN + \u2190 \uff0c\u628a\u672c\u4e66\u7684\u6d4f\u89c8\u5668\u7a97\u53e3\u653e\u5728\u5c4f\u5e55\u5de6\u4fa7\uff0c\u53f3\u4fa7\u662f\u4f60\u7684 IDE\u3002\u4e00\u8fb9\u770b\u4e00\u8fb9\u81ea\u5df1\u52a8\u624b\u505a\u5b9e\u9a8c\u3002 \u8bf7\u5750\u548c\u653e\u5bbd\u3002 \u53ef\u4ee5\u6309\u987a\u5e8f\u9605\u8bfb\uff0c\u4e5f\u53ef\u4ee5\u5728\u672c\u9875\u9762\u4e0a\u65b9\u5bfc\u822a\u680f\u7684\u201c\u7ae0\u8282\u5217\u8868\u201d\u4e2d\uff0c\u9009\u62e9\u611f\u5174\u8da3\u7684\u7ae0\u8282\u9605\u8bfb\u3002 \u672c\u4e66\u5b8c\u5168\u5f00\u6e90\u548c\u514d\u8d39\uff0cGitHub \u4ed3\u5e93\uff1a https://github.com/parallel101/cppguidebook \u5982\u679c\u4f60\u662f\u5728\u4ed8\u8d39\u7fa4\u4e2d\u201c\u4e70\u201d\u5230\u672c\u4e66\uff0c\u6216\u8005\u6253\u7740\u5c0f\u5f6d\u8001\u5e08\u540d\u53f7\u5356\u8bfe\uff0c\u8bf4\u660e\u4f60\u53ef\u80fd\u662f\u79c1\u6709\u5236\u7684\u53d7\u5bb3\u8005\u3002\u56e0\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4ece\u6765\u6ca1\u6709\u4ed8\u8d39\u624d\u80fd\u770b\u7684\u8bfe\u7a0b\uff0c\u6240\u6709\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b\u90fd\u5bf9\u5168\u7403\u4e92\u8054\u7f51\u5f00\u653e\u3002 \u5982\u9700\u79bb\u7ebf\u67e5\u770b\uff0c\u53ef\u4ee5\u524d\u5f80 GitHub Release \u9875\u9762 \u4e0b\u8f7d PDF \u6587\u4ef6\u3002 \u5982\u679c\u4f60\u5728\u9605\u8bfb\u8fc7\u7a0b\u4e2d\u9047\u5230\u4efb\u4f55\u95ee\u9898\uff0c\u53ef\u4ee5\u5728 GitHub Issues \u4e2d\u63d0\u51fa\uff0c\u5c0f\u5f6d\u8001\u5e08\u4f1a\u5c3d\u529b\u89e3\u7b54\u3002 \u4e5f\u53ef\u4ee5\u5728 B \u7ad9 \u53d1\u79c1\u4fe1\u7ed9\u5c0f\u5f6d\u8001\u5e08\u54e6\u3002 \u672c\u4e66\u8fd8\u5728\u6301\u7eed\u66f4\u65b0\u4e2d\u2026\u2026\u8981\u8ffd\u756a\u7684\u8bdd\uff0c\u53ef\u4ee5\u5728 GitHub \u70b9\u4e00\u4e0b\u53f3\u4e0a\u89d2\u7684 \u201cWatch\u201d \u6309\u94ae\uff0c\u6bcf\u5f53\u5c0f\u5f6d\u8001\u5e08\u63d0\u4ea4\u65b0 commit\uff0cGitHub \u4f1a\u5411\u4f60\u53d1\u9001\u4e00\u5c01\u7535\u5b50\u90ae\u4ef6\uff0c\u63d0\u9192\u4f60\u5c0f\u5f6d\u8001\u5e08\u66f4\u65b0\u4e86\u3002 \u66f4\u65b0\u65f6\u95f4\uff1a2024\u5e7411\u670809\u65e5 11:39:40 (UTC+08:00) \u5728 GitHub Pages \u6d4f\u89c8\u672c\u4e66 | \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u5df1\u7ef4\u62a4\u7684\u955c\u50cf\u4e0a\u6d4f\u89c8\u672c\u4e66","title":"\u524d\u8a00"},{"location":"#_2","text":"\u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u6e29\u99a8\u63d0\u793a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u53ef\u80fd\u72af\u9519\u7684\u8b66\u544a \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u5185\u5bb9\u662f\u7b11\u8bdd\u6216\u8da3\u5473\u5bd3\u8a00\u6545\u4e8b \u7528\u8fd9\u79cd\u989c\u8272\u4e66\u5199\u7684\u662f\u8865\u5145\u8bf4\u660e\u7684\u8bfe\u5916\u9605\u8bfb\uff0c\u770b\u4e0d\u61c2\u4e5f\u6ca1\u5173\u7cfb \u7528\u8fd9\u79cd\u989c\u8272\u5b57\u4f53\u4e66\u5199\u7684\u662f\u521d\u5b66\u8005\u53ef\u6682\u65f6\u4e0d\u7528\u7406\u89e3\u7684\u7ec6\u8282 \u672f\u8bed\u540d\u79f0: \u8fd9\u91cc\u662f\u672f\u8bed\u7684\u5b9a\u4e49\u3002","title":"\u683c\u5f0f\u7ea6\u5b9a"},{"location":"#_3","text":"\u4e0e\u5927\u591a\u6570\u73b0\u6709\u6559\u6750\u4e0d\u540c\u7684\u662f\uff0c\u672c\u8bfe\u7a0b\u5c06\u4f1a\u91c7\u7528\u201c\u5012\u53d9\u201d\u7684\u5f62\u5f0f\uff0c\u4ece\u6700\u65b0\u7684 C++23 \u8bb2\u8d77\uff01\u7136\u540e\u8bb2 C++20\u3001C++17\u3001C++14\u3001C++11\uff0c\u6162\u6162\u8bb2\u5230\u6700\u539f\u59cb\u7684 C++98\u3002 \u4e0d\u7528\u62c5\u5fc3\uff0c\u8d8a\u662f\u73b0\u4ee3\u7684 C++\uff0c\u5b66\u8d77\u6765\u53cd\u800c\u66f4\u5bb9\u6613\uff01\u53cd\u800c\u53e4\u4ee3 C++ \u624d \u53c8\u81ed\u53c8\u957f \u3002 \u5f88\u591a\u540c\u5b66\u60f3\u5f53\u7136\u5730\u8bef\u4ee5\u4e3a C++98 \u6700\u7b80\u5355\uff0c\u54fc\u54e7\u54fc\u54e7\u8d39\u8001\u5927\u52b2\u4ece C++98 \u5f00\u59cb\u5b66\uff0c\u624d\u662f\u9519\u8bef\u7684\u3002 \u4e3a\u4e86\u5e94\u4ed8\u7f3a\u80f3\u818a\u5c11\u817f\u7684 C++98\uff0c\u4eba\u4eec\u53d1\u660e\u4e86\u5404\u79cd \u7e41\u7410\u65e0\u8c13 \u7684\u5199\u6cd5\uff0c\u5728\u73b0\u4ee3 C++ \u4e2d\uff0c\u65e9\u5c31\u5df2\u7ecf\u88ab\u66f4 \u7b80\u6d01\u76f4\u89c2 \u7684\u5199\u6cd5\u66ff\u4ee3\u4e86\u3002 \u4f8b\u5982\u6240\u8c13\u7684 safe-bool idiom\uff0c\u5199\u8d77\u6765\u53c8\u81ed\u53c8\u957f\uff0cC++11 \u5f15\u5165\u4e00\u4e2a explicit \u5173\u952e\u5b57\u76f4\u63a5\u5c31\u79d2\u4e86\u3002\u7ed3\u679c\u8fd8\u6709\u4e00\u6279\u52b3\u4fdd\u6559\u6750\u5927\u5439\u7279\u5439 safe-bool idiom\uff0c\u5439\u5f97\u597d\u50cf\u662f\u4e2a\u4ec0\u4e48\u9ad8\u5927\u4e0a\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e00\u6837\uff0c\u4e0d\u8fc7\u662f\u4e2a\u5e94\u4ed8 C++98 \u8bed\u8a00\u7f3a\u9677\u7684\u8e69\u811a\u73a9\u610f\u3002 \u5c31\u597d\u6bd4\u4e00\u4e2a \u8001\u5916 \u60f3\u8981\u5b66\u4e60\u6c49\u8bed\uff0c\u4ed6\u9996\u5148\u80af\u5b9a\u662f\u4ece \u73b0\u4ee3\u6c49\u8bed \u5b66\u8d77\uff01\u800c\u4e0d\u662f\u4e0a\u6765\u5c31\u6559\u4ed6 \u6587\u8a00\u6587 \u3002 \u5373\u4f7f\u8fd9\u4e2a\u8001\u5916\u7684\u804c\u4e1a\u5c31\u662f\u201c\u8003\u53e4\u201d\uff0c\u6216\u8005\u4ed6\u5bf9\u201c\u53e4\u4ee3\u6587\u5b66\u201d\u611f\u5174\u8da3\uff0c\u4e5f\u4e0d\u53ef\u80fd\u81ea\u5b66\u6587\u8a00\u6587\u7684\u540c\u65f6\u5b8c\u5168\u8df3\u8fc7\u73b0\u4ee3\u6c49\u8bed\u3002 \u5f53\u6211\u4eec\u5b66\u4e60\u4e2d\u6587\u65f6\uff0c\u4f60\u80af\u5b9a\u5e0c\u671b\u5148\u5b66\u73b0\u4ee3\u6c49\u8bed\uff0c\u518d\u5b66\u6587\u8a00\u6587\uff0c\u518d\u5b66\u7532\u9aa8\u6587\uff0c\u518d\u5b66 brainf* * k\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u5bf9\u4e8e C++ \u521d\u5b66\u8005\u4e5f\u662f\u5982\u6b64\uff1a\u6211\u4eec\u9996\u5148\u5b66\u4f1a\u7b80\u5355\u660e\u4e86\u7684\uff0c\u7b26\u5408\u73b0\u4ee3\u4eba\u601d\u7ef4\u7684 C++23\uff0c\u518d\u9010\u6e10\u56de\u5230\u4e13\u4e3a\u4f3a\u5019\u201c\u53e4\u4ee3\u5f00\u53d1\u73af\u5883\u201d\u7684 C++98\u3002 \u4f60\u7684\u751f\u4ea7\u73af\u5883\u53ef\u80fd\u4e0d\u5141\u8bb8\u7528\u4e0a C++20 \u751a\u81f3 C++23 \u7684\u65b0\u6807\u51c6\u3002 \u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u6559\u4f1a\u4f60 C++23 \u7684\u6b63\u5e38\u5199\u6cd5\u540e\uff0c\u4f1a\u8bb2\u89e3\u5982\u4f55\u5728 C++14\u3001C++98 \u4e2d\u5199\u51fa\u540c\u6837\u7684\u6548\u679c\u3002 \u8fd9\u6837\u4f60\u5b66\u4e60\u7684\u65f6\u5019\u601d\u8def\u6e05\u6670\uff0c\u4e0d\u7528\u88ab\u7e41\u7410\u7684 C++98 \u201c\u5947\u6280\u6deb\u5de7\u201d\u5e72\u6270\uff0c\u5b66\u8d77\u6765\u4e8b\u534a\u529f\u500d\uff1b\u4f46\u4e5f\u201c\u5403\u8fc7\u89c1\u8fc7\u201d\uff0c\u77e5\u9053\u53e4\u4ee3 C++98 \u7684\u5e94\u5bf9\u7b56\u7565\u3002 \u76ee\u524d\u4f01\u4e1a\u91cc\u4e3b\u6d41\u4f7f\u7528\u7684\u662f C++14 \u548c C++17\u3002\u4f8b\u5982\u8c37\u6b4c\u5c31\u660e\u786e\u89c4\u5b9a\u8981\u6c42 C++17\u3002","title":"\u89c2\u524d\u987b\u77e5"},{"location":"#_4","text":"\u63a5\u4e0b\u6765\u7684\u4f8b\u5b50\u4f60\u53ef\u80fd\u770b\u4e0d\u61c2\uff0c\u4f46\u53ea\u9700\u8981\u8bb0\u4f4f\u8fd9\u4e2a\u4f8b\u5b50\u662f\u5411\u4f60\u8bf4\u660e\uff1a\u8d8a\u662f\u65b0\u7684 C++ \u6807\u51c6\uff0c\u53cd\u800c\u8d8a\u5bb9\u6613\u5b66\uff01 \u4f8b\u5982\uff0c\u5728\u6a21\u677f\u5143\u7f16\u7a0b\u4e2d\uff0c\u8981\u68c0\u6d4b\u4e00\u4e2a\u7c7b\u578b T \u662f\u5426\u62e5\u6709 foo() \u8fd9\u4e00\u6210\u5458\u51fd\u6570\u3002\u5982\u679c\u5b58\u5728\uff0c\u624d\u4f1a\u8c03\u7528\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528\u5f88\u65b9\u4fbf\u7684 requires \u8bed\u6cd5\uff0c\u8f7b\u677e\u68c0\u6d4b\u4e00\u4e2a\u8868\u8fbe\u5f0f\u662f\u5426\u80fd\u5408\u6cd5\u901a\u8fc7\u7f16\u8bd1\u3002\u5982\u679c\u80fd\uff0c requires \u8bed\u53e5\u4f1a\u8fd4\u56de true \u3002\u7136\u540e\u7528\u4e00\u4e2a if constexpr \u8fdb\u884c\u7f16\u8bd1\u671f\u5206\u652f\u5224\u65ad\uff0c\u5373\u53ef\u5b9e\u73b0\u68c0\u6d4b\u5230\u5b58\u5728\u5219\u8c03\u7528\u3002 template void try_call_foo(T &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } \u4f46\u4ec5\u4ec5\u662f\u56de\u5230 C++17\uff0c\u6ca1\u6709 requires \u8bed\u6cd5\uff0c\u6211\u4eec\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a trait \u7c7b\uff0c\u5e76\u8fd0\u7528\u70e6\u4eba\u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u68c0\u6d4b\u8868\u8fbe\u5f0f\u662f\u5426\u7684\u5408\u6cd5\uff0c\u53c8\u81ed\u53c8\u957f\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template void try_call_foo(T &t) { if constexpr (has_foo::value) { t.foo(); } } \u5982\u679c\u56de\u5230 C++14\uff0c\u60c5\u51b5\u5c31\u66f4\u7cdf\u7cd5\u4e86\uff01 if constexpr \u662f C++17 \u7684\u7279\u6027\uff0c\u6ca1\u6709\u4ed6\uff0c\u8981\u5b9e\u73b0\u7f16\u8bd1\u671f\u5206\u652f\uff0c\u6211\u4eec\u5c31\u5f97\u7528 enable_if_t \u7684 SFINAE \u5c0f\u6280\u5de7\uff0c\u9700\u8981\u5b9a\u4e49\u4e24\u4e2a try_call_foo \u51fd\u6570\uff0c\u4e92\u76f8\u91cd\u8f7d\uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo())>> { static constexpr bool value = true; }; template ::value, int> = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int> = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++11\uff0c\u60c5\u51b5\u8fdb\u4e00\u6b65\u6076\u5316\uff01 enable_if_t \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5c0f\u52a9\u624b\u5df2\u7ecf\u4e0d\u5b58\u5728\uff0c\u9700\u8981\u4f7f\u7528\u6bd4\u4ed6\u66f4\u5e95\u5c42\u7684 enable_if \u6a21\u677f\u7c7b\uff0c\u624b\u52a8\u53d6\u51fa ::type \uff0c\u5e76\u4e14\u9700\u8981 typename \u4fee\u9970\uff0c\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff01\u5e76\u4e14 void_t \u4e5f\u4e0d\u80fd\u7528\u4e86\uff0c\u8981\u7528\u9017\u53f7\u8868\u8fbe\u5f0f\u5c0f\u6280\u5de7\u624d\u80fd\u8ba9 decltype \u56fa\u5b9a\u8fd4\u56de void\u2026\u2026 template struct has_foo { static constexpr bool value = false; }; template struct has_foo().foo(), (void)0)> { static constexpr bool value = true; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u679c\u56de\u5230 C++98\uff0c\u90a3\u53c8\u8981\u7f6a\u52a0\u4e00\u7b49\uff01 enable_if \u548c declval \u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u7684\u5e2e\u624b\u7c7b\u548c\u5e2e\u624b\u51fd\u6570\uff0c\u5728 C++98 \u4e2d\uff0c\u6211\u4eec\u9700\u8981\u81ea\u5df1\u5b9e\u73b0 enable_if \u2026\u2026 declval \u4e5f\u662f C++11 \u5f15\u5165\u7684 \u5934\u6587\u4ef6\u4e2d\u7684\u5e2e\u624b\u51fd\u6570\u2026\u2026\u5047\u8bbe\u4f60\u81ea\u5df1\u597d\u4e0d\u5bb9\u6613\u5b9e\u73b0\u51fa\u6765\u4e86 enable_if \u548c declval \uff0c\u8fd8\u6ca1\u5b8c\uff1a\u56e0\u4e3a constexpr \u5728 C++98 \u4e2d\u4e5f\u4e0d\u5b58\u5728\u4e86\uff01\u4f60\u65e0\u6cd5\u5b9a\u4e49 value \u6210\u5458\u53d8\u91cf\u4e3a\u7f16\u8bd1\u671f\u5e38\u91cf\uff0c\u6211\u4eec\u53ea\u597d\u53c8\u7528\u4e00\u4e2a\u62bd\u8c61\u7684\u679a\u4e3e\u5c0f\u6280\u5de7\u6765\u5b9e\u73b0\u5b9a\u4e49\u7c7b\u6210\u5458\u5e38\u91cf\u7684\u6548\u679c\u3002 template struct has_foo { enum { value = 0 }; }; template struct has_foo().foo(), (void)0)> { enum { value = 1 }; }; template ::value, int>::type = 0> void try_call_foo(T &t) { t.foo(); } template ::value, int>::type = 0> void try_call_foo(T &) { } \u5982\u6b64\u5197\u957f\u96be\u61c2\u7684\u62bd\u8c61 C++98 \u4ee3\u7801\uff0c\u4eff\u4f5b\u662f\u201c\u52a0\u5bc6\u201d\u8fc7\u7684\u4ee3\u7801\u4e00\u6837\uff0c\u4ec5\u4ec5\u662f\u4e3a\u4e86\u5b9e\u73b0\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6210\u5458\u51fd\u6570 foo\u2026\u2026 \u5982\u679c\u56de\u5230 C \u8bed\u8a00\uff0c\u90a3\u4e48\u4f60\u751a\u81f3\u90fd\u4e0d\u7528\u68c0\u6d4b\u4e86\u3002\u56e0\u4e3a\u4f1f\u5927\u7684 C \u8bed\u8a00\u8fde\u6210\u5458\u51fd\u6570\u90fd\u6ca1\u6709\uff0c\u4f55\u8c08\u201c\u68c0\u6d4b\u6210\u5458\u51fd\u6570\u662f\u5426\u5b58\u5728\u201d\uff1f \u53cd\u89c2 C++20 \u7684\u5199\u6cd5\uff0c\u4e00\u773c\u5c31\u770b\u660e\u767d\u4ee3\u7801\u7684\u903b\u8f91\u662f\u4ec0\u4e48\uff0c\u8868\u8fbe\u4f60\u8be5\u8868\u8fbe\u7684\uff0c\u800c\u4e0d\u662f\u8ff7\u5931\u4e8e\u4f3a\u5019\u5404\u79cd\u8bed\u8a00\u7f3a\u9677\uff0c\u5e72\u6270\u6211\u4eec\u5b66\u4e60\u3002 void try_call_foo(auto &t) { if constexpr (requires { t.foo(); }) { t.foo(); } } // \u4ece\u6b8b\u5e9f\u7684 C++98 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u5c31\u88ab\u8fd9\u4e9b\u65e0\u8c13\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u626d\u66f2\u4e86\uff0c\u800c\u4f7f\u5f97\u771f\u6b63\u5e94\u8be5\u8868\u8fbe\u7684\u4ee3\u7801\u903b\u8f91\uff0c\u6df9\u6ca1\u5728\u53c8\u81ed\u53c8\u957f\u7684\u53e4\u4ee3\u6280\u5de7\u4e2d\u3002 // \u4ece\u73b0\u4ee3\u7684 C++23 \u5b66\u8d77\uff0c\u5148\u77e5\u9053\u6b63\u5e38\u7684\u5199\u6cd5\u201c\u7406\u5e94\u201d\u662f\u4ec0\u4e48\u6837\u3002\u5de5\u4f5c\u4e2d\u7528\u4e0d\u4e0a C++23\uff1f\u6211\u4f1a\u5411\u4f60\u4ecb\u7ecd\uff0c\u5982\u679c\u8981\u5012\u9000\u56de C++14\uff0c\u53e4\u4ee3\u4eba\u90fd\u662f\u7528\u4ec0\u4e48\u201c\u5947\u6280\u6deb\u5de7\u201d\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\u3002 // \u8fd9\u6837\u4f60\u6700\u540e\u540c\u6837\u53ef\u4ee5\u9002\u5e94\u516c\u53f8\u8981\u6c42\u7684 C++14 \u73af\u5883\u3002\u4f46\u662f\u4ece C++23 \u5b66\u8d77\uff0c\u4f60\u7684\u601d\u7ef4\u53c8\u4e0d\u4f1a\u88ab\u5e94\u4ed8\u53e4\u4ee3\u8bed\u8a00\u7f3a\u9677\u7684\u201c\u5947\u6280\u6deb\u5de7\u201d\u6270\u4e71\uff0c\u5b66\u8d77\u6765\u5c31\u4e8b\u534a\u529f\u500d\u3002 \u65e2\u7136\u73b0\u4ee3 C++ \u8fd9\u4e48\u597d\uff0c\u4e3a\u4ec0\u4e48\u5b66\u6821\u4e0d\u4ece\u73b0\u4ee3 C++ \u6559\u8d77\uff0c\u6559\u8d77\u6765\u8fd8\u8f7b\u677e\uff1f\u56e0\u4e3a\u52b3\u4fdd\u8001\u5e08\u4fdd\uff0c\u61d2\u5f97\u63a5\u89e6\u65b0\u77e5\u8bc6\uff0c\u8ba4\u4e3a\u201c\u7956\u5b97\u4e4b\u6cd5\u4e0d\u53ef\u53d8\u201d\uff0c\u201c\u7248\u53f7\u7a33\u5b9a\u538b\u5012\u4e00\u5207\u201d\u3002","title":"\u4e3e\u4e2a\u4f8b\u5b50"},{"location":"about/","text":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08 \u5c0f\u5f6d\u8001\u5e08\u662f\u4e00\u4f4d\u64c5\u957f\u9ad8\u6027\u80fd C++ \u7684\u7a0b\u5e8f\u5458\uff0c\u76ee\u524d\u4e3b\u8981\u4ece\u4e8b\u56fe\u5f62\u5b66\u9886\u57df\u7684\u5f15\u64ce\u5f00\u53d1\uff0c\u62e5\u6709\u591a\u5e74\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u4e30\u5bcc\u7684\u77e5\u8bc6\u50a8\u5907\uff0c\u7cbe\u901a\u7ebf\u6027\u4ee3\u6570\u3001\u5fae\u79ef\u5206\u3001\u6982\u7387\u8bba\u3001\u5fae\u5206\u51e0\u4f55\u3001\u56fe\u5f62\u5b66\u3001\u6e38\u620f\u5f15\u64ce\u3001\u4e92\u8054\u7f51\u3001\u7f16\u8bd1\u539f\u7406\u3001\u8bbe\u8ba1\u6a21\u5f0f\u3001\u79bb\u7ebf\u6e32\u67d3\u3001\u73b0\u4ee3 C++\u3001\u73b0\u4ee3 CMake\u3001\u73b0\u4ee3 CUDA\u3001\u73b0\u4ee3 OpenGL\u3001\u591a\u7ebf\u7a0b\u5e76\u53d1\u3001\u534f\u7a0b\u3001\u5f02\u6b65 I/O\u3001SIMD\u3001\u5e76\u884c\u7f16\u7a0b\u3001\u6027\u80fd\u8c03\u4f18\u7b49\u591a\u4e2a\u9886\u57df\uff0c\u90fd\u80fd\u5bf9\u7b54\u5982\u6d41\u3002 \u4ed6\u64c5\u957f\u5e76\u884c\u7f16\u7a0b\u548c\u4f18\u5316\u6280\u672f\uff0c\u5bf9\u4e8e\u73b0\u4ee3 C++ \u548c\u8bbe\u8ba1\u6a21\u5f0f\u4e5f\u6709\u81ea\u5df1\u72ec\u5230\u7684\u89c1\u89e3\uff0c\u6df1\u53d7\u201c\u7ae5\u978b\u201d\u559c\u7231\u548c\u5c0a\u656c\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 B \u7ad9 \u64ad\u51fa\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u7f16\u7a0b\u4e0e\u4f18\u5316\u300b\u7cfb\u5217\u516c\u5f00\u8bfe\uff0c\u4e00\u7ecf\u63a8\u51fa\uff0c\u7acb\u523b\u597d\u8bc4\u5982\u6f6e\uff01 \u5c0f\u5f6d\u8001\u5e08\u5c06\u81ea\u5df1\u4e30\u5bcc\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u77e5\u8bc6\u50a8\u5907\u8f6c\u5316\u4e3a\u7ae5\u978b\u4eec\u7684\u751f\u4ea7\u529b\uff0c\u642d\u4e0a\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u589e\u957f\u7684\u9ad8\u901f\u730e\u8f66\uff0c\u5f15\u9886\u7ae5\u978b\u9ad8\u5c31\u7684\u4f1f\u5927\u822a\u8def\u3002 \u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\u3002","title":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08"},{"location":"about/#_1","text":"\u5c0f\u5f6d\u8001\u5e08\u662f\u4e00\u4f4d\u64c5\u957f\u9ad8\u6027\u80fd C++ \u7684\u7a0b\u5e8f\u5458\uff0c\u76ee\u524d\u4e3b\u8981\u4ece\u4e8b\u56fe\u5f62\u5b66\u9886\u57df\u7684\u5f15\u64ce\u5f00\u53d1\uff0c\u62e5\u6709\u591a\u5e74\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u4e30\u5bcc\u7684\u77e5\u8bc6\u50a8\u5907\uff0c\u7cbe\u901a\u7ebf\u6027\u4ee3\u6570\u3001\u5fae\u79ef\u5206\u3001\u6982\u7387\u8bba\u3001\u5fae\u5206\u51e0\u4f55\u3001\u56fe\u5f62\u5b66\u3001\u6e38\u620f\u5f15\u64ce\u3001\u4e92\u8054\u7f51\u3001\u7f16\u8bd1\u539f\u7406\u3001\u8bbe\u8ba1\u6a21\u5f0f\u3001\u79bb\u7ebf\u6e32\u67d3\u3001\u73b0\u4ee3 C++\u3001\u73b0\u4ee3 CMake\u3001\u73b0\u4ee3 CUDA\u3001\u73b0\u4ee3 OpenGL\u3001\u591a\u7ebf\u7a0b\u5e76\u53d1\u3001\u534f\u7a0b\u3001\u5f02\u6b65 I/O\u3001SIMD\u3001\u5e76\u884c\u7f16\u7a0b\u3001\u6027\u80fd\u8c03\u4f18\u7b49\u591a\u4e2a\u9886\u57df\uff0c\u90fd\u80fd\u5bf9\u7b54\u5982\u6d41\u3002 \u4ed6\u64c5\u957f\u5e76\u884c\u7f16\u7a0b\u548c\u4f18\u5316\u6280\u672f\uff0c\u5bf9\u4e8e\u73b0\u4ee3 C++ \u548c\u8bbe\u8ba1\u6a21\u5f0f\u4e5f\u6709\u81ea\u5df1\u72ec\u5230\u7684\u89c1\u89e3\uff0c\u6df1\u53d7\u201c\u7ae5\u978b\u201d\u559c\u7231\u548c\u5c0a\u656c\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 B \u7ad9 \u64ad\u51fa\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u7f16\u7a0b\u4e0e\u4f18\u5316\u300b\u7cfb\u5217\u516c\u5f00\u8bfe\uff0c\u4e00\u7ecf\u63a8\u51fa\uff0c\u7acb\u523b\u597d\u8bc4\u5982\u6f6e\uff01 \u5c0f\u5f6d\u8001\u5e08\u5c06\u81ea\u5df1\u4e30\u5bcc\u7684\u5f00\u53d1\u7ecf\u9a8c\u548c\u77e5\u8bc6\u50a8\u5907\u8f6c\u5316\u4e3a\u7ae5\u978b\u4eec\u7684\u751f\u4ea7\u529b\uff0c\u642d\u4e0a\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u589e\u957f\u7684\u9ad8\u901f\u730e\u8f66\uff0c\u5f15\u9886\u7ae5\u978b\u9ad8\u5c31\u7684\u4f1f\u5927\u822a\u8def\u3002 \u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\u3002","title":"\u5173\u4e8e\u5c0f\u5f6d\u8001\u5e08"},{"location":"auto/","text":"auto \u795e\u6559 (\u672a\u5b8c\u5de5) \u53d8\u91cf auto \u8fd4\u56de\u7c7b\u578b auto C++11 \u5f15\u5165\u7684 auto \u5173\u952e\u5b57\u53ef\u4ee5\u7528\u4f5c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4f46\u5b83\u53ea\u662f\u4e00\u4e2a\u201c\u5360\u4f4d\u201d\uff0c\u8ba9\u6211\u4eec\u5f97\u4ee5\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\uff0c\u5e76\u6ca1\u6709\u591a\u5927\u4f5c\u7528\uff0c\u975e\u5e38\u6b8b\u5e9f\u3002 auto f() -> int; // \u7b49\u4ef7\u4e8e\uff1a int f(); \u95f9\u4e86\u534a\u5929\uff0c\u8fd8\u662f\u8981\u5199\u8fd4\u56de\u7c7b\u578b\uff0c\u5c31\u53ea\u662f\u632a\u5230\u540e\u9762\u53bb\u597d\u770b\u4e00\u70b9\u2026\u2026 \u5f53\u521d\u5f15\u5165\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\u5b9e\u9645\u7684\u7528\u9014\u662f auto f(int x) -> decltype(x * x) { return x * x; } \u8fd9\u79cd\u60c5\u51b5\uff0c\u4f46\u5f88\u5bb9\u6613\u88ab\u63a5\u4e0b\u6765 C++14 \u5f15\u5165\u7684\u771f\u6b63 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u5e73\u66ff\u4e86\u3002 \u4f46\u662f C++14 \u5f15\u5165\u4e86\u51fd\u6570 \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc \uff0c auto \u624d\u7b97\u771f\u6b63\u610f\u4e49\u4e0a\u80fd\u7528\u505a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff0c\u5b83\u4f1a\u81ea\u52a8\u6839\u636e\u51fd\u6570\u4e2d\u7684 return \u8868\u8fbe\u5f0f\u63a8\u5bfc\u51fa\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u3002 auto f(int x) { return x * x; // \u8868\u8fbe\u5f0f `x * x` \u7684\u7c7b\u578b\u4e3a int\uff0c\u6240\u4ee5 auto \u7c7b\u578b\u63a8\u5bfc\u4e3a int } // \u7b49\u4ef7\u4e8e\uff1a int f() { return x * x; } \u5982\u679c\u51fd\u6570\u4e2d\u6ca1\u6709 return \u8bed\u53e5\uff0c\u90a3\u4e48 auto \u4f1a\u88ab\u81ea\u52a8\u63a8\u5bfc\u4e3a void \uff0c\u975e\u5e38\u65b9\u4fbf\u3002 auto f() { std::println(\"hello\"); } // \u7b49\u4ef7\u4e8e\uff1a void f() { std::println(\"hello\"); } \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8fd4\u56de\u7c7b\u578b\u7528 auto \u6765\u63a8\u5bfc\u7684\u51fd\u6570\uff0c\u5982\u679c\u6709\u591a\u6761 return \u8bed\u53e5\uff0c\u90a3\u4e48\u4ed6\u4eec\u5fc5\u987b\u90fd\u8fd4\u56de\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u62a5\u9519\u3002 auto f(int x) { if (x > 0) { return 1; // int } else { return 3.14; // double } } // \u9519\u8bef\uff1a\u6709\u6b67\u4e49\uff0c\u65e0\u6cd5\u786e\u5b9a auto \u5e94\u8be5\u63a8\u5bfc\u4e3a int \u8fd8\u662f double auto \u8fd8\u6709\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u65e0\u6cd5\u7528\u4e8e\u201c\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u201d\u7684\u60c5\u51b5\u3002\u56e0\u4e3a\u63a8\u5bfc auto \u7c7b\u578b\u9700\u8981\u77e5\u9053\u51fd\u6570\u4f53\uff0c\u624d\u80fd\u770b\u5230\u91cc\u9762\u7684 return \u8868\u8fbe\u5f0f\u662f\u4ec0\u4e48\u7c7b\u578b\u3002\u6240\u4ee5\u5f53 auto \u8fd4\u56de\u7c7b\u578b\u88ab\u7528\u4e8e\u51fd\u6570\u7684\u975e\u5b9a\u4e49\u58f0\u660e\u65f6\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519\u3002 auto f(); // \u9519\u8bef\uff1a\u770b\u4e0d\u5230\u51fd\u6570\u4f53\uff0c\u65e0\u6cd5\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto f() { // \u7f16\u8bd1\u901a\u8fc7\uff1aauto \u63a8\u5bfc\u4e3a int return 1; // 1 \u662f int \u7c7b\u578b\u7684\u8868\u8fbe\u5f0f } \u56e0\u6b64\uff0c auto \u901a\u5e38\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u201c\u5c31\u5730\u5b9a\u4e49\u201d\u7684 inline \u51fd\u6570\uff0c\u4e0d\u9002\u5408\u9700\u8981\u201c\u5206\u79bb .cpp \u6587\u4ef6\u201d\u7684\u51fd\u6570\u3002 \u53c2\u6570\u7c7b\u578b auto C++20 \u5f15\u5165\u4e86 \u6a21\u677f\u53c2\u6570\u63a8\u5bfc \uff0c\u53ef\u4ee5\u8ba9\u6211\u4eec\u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u3002 \u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5c06\u8be5\u53c2\u6570\u58f0\u660e\u4e3a\u6a21\u677f\u53c2\u6570\uff0c\u4ec5\u4ec5\u662f\u4e00\u79cd\u66f4\u4fbf\u6377\u7684\u5199\u6cd5\u3002 void func(auto x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T x) { std::cout << x; } func(1); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(1) func(3.14); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(3.14) \u5982\u679c\u53c2\u6570\u7c7b\u578b\u7684 auto \u5e26\u6709\u5982 auto & \u8fd9\u6837\u7684\u4fee\u9970\uff0c\u5219\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u76f8\u5e94\u6a21\u677f\u51fd\u6570\u7684 T & \u3002 // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u5e38\u5f15\u7528 void func(auto const &x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T const &x) { std::cout << x; } // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u4e07\u80fd\u5f15\u7528 void func(auto &&x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T &&x) { std::cout << x; } auto \u5728\u591a\u6001\u4e2d\u7684\u5999\u7528 \u4f20\u7edf\u7684\uff0c\u57fa\u4e8e\u7c7b\u578b\u91cd\u8f7d\u7684\uff1a int square(int x) { return x * x; } double square(double x) { return x * x; } int main() { square(2); // 4\uff08\u8c03\u7528 int \u7248\u91cd\u8f7d\uff09 square(3.14); // 9.8596\uff08\u8c03\u7528 double \u7248\u91cd\u8f7d\uff09 // \u5982\u679c\u73b0\u5728\u53c8\u9700\u8981 float \u7248\u5462\uff1f\u53c8\u5f97\u5199\u4e00\u7248\u91cd\u8f7d\uff0c\u5185\u5bb9\u8fd8\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff0c\u6d6a\u8d39\u65f6\u95f4 } \u57fa\u4e8e auto \u6a21\u677f\u53c2\u6570\u63a8\u5bfc\u7684\uff1a auto square(auto x) { return x * x; } int main() { square(2); // 4\uff08auto \u63a8\u5bfc\u4e3a int\uff09 square(3.14); // 9.8596\uff08auto \u63a8\u5bfc\u4e3a double\uff09 // \u5373\u4f7f\u672a\u6765\u4ea7\u751f\u4e86 float \u7248\u7684\u9700\u6c42\uff0c\u4e5f\u4e0d\u7528\u6dfb\u52a0\u4efb\u4f55\u4ee3\u7801\uff0c\u56e0\u4e3a\u662f square \u662f\u5f88\u65b9\u4fbf\u7684\u6a21\u677f\u51fd\u6570 } auto \u63a8\u5bfc\u4e3a\u5f15\u7528 TODO: \u7ee7\u7eed\u4ecb\u7ecd auto , auto const , auto & , auto const & , auto && , decltype(auto) , auto * , auto const *","title":"auto \u795e\u6559 (\u672a\u5b8c\u5de5)"},{"location":"auto/#auto","text":"","title":"auto \u795e\u6559 (\u672a\u5b8c\u5de5)"},{"location":"auto/#auto_1","text":"","title":"\u53d8\u91cf auto"},{"location":"auto/#auto_2","text":"C++11 \u5f15\u5165\u7684 auto \u5173\u952e\u5b57\u53ef\u4ee5\u7528\u4f5c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4f46\u5b83\u53ea\u662f\u4e00\u4e2a\u201c\u5360\u4f4d\u201d\uff0c\u8ba9\u6211\u4eec\u5f97\u4ee5\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\uff0c\u5e76\u6ca1\u6709\u591a\u5927\u4f5c\u7528\uff0c\u975e\u5e38\u6b8b\u5e9f\u3002 auto f() -> int; // \u7b49\u4ef7\u4e8e\uff1a int f(); \u95f9\u4e86\u534a\u5929\uff0c\u8fd8\u662f\u8981\u5199\u8fd4\u56de\u7c7b\u578b\uff0c\u5c31\u53ea\u662f\u632a\u5230\u540e\u9762\u53bb\u597d\u770b\u4e00\u70b9\u2026\u2026 \u5f53\u521d\u5f15\u5165\u540e\u7f6e\u8fd4\u56de\u7c7b\u578b\u5b9e\u9645\u7684\u7528\u9014\u662f auto f(int x) -> decltype(x * x) { return x * x; } \u8fd9\u79cd\u60c5\u51b5\uff0c\u4f46\u5f88\u5bb9\u6613\u88ab\u63a5\u4e0b\u6765 C++14 \u5f15\u5165\u7684\u771f\u6b63 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u5e73\u66ff\u4e86\u3002 \u4f46\u662f C++14 \u5f15\u5165\u4e86\u51fd\u6570 \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc \uff0c auto \u624d\u7b97\u771f\u6b63\u610f\u4e49\u4e0a\u80fd\u7528\u505a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff0c\u5b83\u4f1a\u81ea\u52a8\u6839\u636e\u51fd\u6570\u4e2d\u7684 return \u8868\u8fbe\u5f0f\u63a8\u5bfc\u51fa\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u3002 auto f(int x) { return x * x; // \u8868\u8fbe\u5f0f `x * x` \u7684\u7c7b\u578b\u4e3a int\uff0c\u6240\u4ee5 auto \u7c7b\u578b\u63a8\u5bfc\u4e3a int } // \u7b49\u4ef7\u4e8e\uff1a int f() { return x * x; } \u5982\u679c\u51fd\u6570\u4e2d\u6ca1\u6709 return \u8bed\u53e5\uff0c\u90a3\u4e48 auto \u4f1a\u88ab\u81ea\u52a8\u63a8\u5bfc\u4e3a void \uff0c\u975e\u5e38\u65b9\u4fbf\u3002 auto f() { std::println(\"hello\"); } // \u7b49\u4ef7\u4e8e\uff1a void f() { std::println(\"hello\"); } \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u8fd4\u56de\u7c7b\u578b\u7528 auto \u6765\u63a8\u5bfc\u7684\u51fd\u6570\uff0c\u5982\u679c\u6709\u591a\u6761 return \u8bed\u53e5\uff0c\u90a3\u4e48\u4ed6\u4eec\u5fc5\u987b\u90fd\u8fd4\u56de\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u62a5\u9519\u3002 auto f(int x) { if (x > 0) { return 1; // int } else { return 3.14; // double } } // \u9519\u8bef\uff1a\u6709\u6b67\u4e49\uff0c\u65e0\u6cd5\u786e\u5b9a auto \u5e94\u8be5\u63a8\u5bfc\u4e3a int \u8fd8\u662f double auto \u8fd8\u6709\u4e00\u4e2a\u7f3a\u70b9\u662f\uff0c\u65e0\u6cd5\u7528\u4e8e\u201c\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u201d\u7684\u60c5\u51b5\u3002\u56e0\u4e3a\u63a8\u5bfc auto \u7c7b\u578b\u9700\u8981\u77e5\u9053\u51fd\u6570\u4f53\uff0c\u624d\u80fd\u770b\u5230\u91cc\u9762\u7684 return \u8868\u8fbe\u5f0f\u662f\u4ec0\u4e48\u7c7b\u578b\u3002\u6240\u4ee5\u5f53 auto \u8fd4\u56de\u7c7b\u578b\u88ab\u7528\u4e8e\u51fd\u6570\u7684\u975e\u5b9a\u4e49\u58f0\u660e\u65f6\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519\u3002 auto f(); // \u9519\u8bef\uff1a\u770b\u4e0d\u5230\u51fd\u6570\u4f53\uff0c\u65e0\u6cd5\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto f() { // \u7f16\u8bd1\u901a\u8fc7\uff1aauto \u63a8\u5bfc\u4e3a int return 1; // 1 \u662f int \u7c7b\u578b\u7684\u8868\u8fbe\u5f0f } \u56e0\u6b64\uff0c auto \u901a\u5e38\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u201c\u5c31\u5730\u5b9a\u4e49\u201d\u7684 inline \u51fd\u6570\uff0c\u4e0d\u9002\u5408\u9700\u8981\u201c\u5206\u79bb .cpp \u6587\u4ef6\u201d\u7684\u51fd\u6570\u3002","title":"\u8fd4\u56de\u7c7b\u578b auto"},{"location":"auto/#auto_3","text":"C++20 \u5f15\u5165\u4e86 \u6a21\u677f\u53c2\u6570\u63a8\u5bfc \uff0c\u53ef\u4ee5\u8ba9\u6211\u4eec\u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u3002 \u5728\u51fd\u6570\u53c2\u6570\u4e2d\u4e5f\u4f7f\u7528 auto \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5c06\u8be5\u53c2\u6570\u58f0\u660e\u4e3a\u6a21\u677f\u53c2\u6570\uff0c\u4ec5\u4ec5\u662f\u4e00\u79cd\u66f4\u4fbf\u6377\u7684\u5199\u6cd5\u3002 void func(auto x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T x) { std::cout << x; } func(1); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(1) func(3.14); // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u8c03\u7528 func(3.14) \u5982\u679c\u53c2\u6570\u7c7b\u578b\u7684 auto \u5e26\u6709\u5982 auto & \u8fd9\u6837\u7684\u4fee\u9970\uff0c\u5219\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u76f8\u5e94\u6a21\u677f\u51fd\u6570\u7684 T & \u3002 // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u5e38\u5f15\u7528 void func(auto const &x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T const &x) { std::cout << x; } // \u81ea\u52a8\u63a8\u5bfc\u4e3a\u4e07\u80fd\u5f15\u7528 void func(auto &&x) { std::cout << x; } // \u7b49\u4ef7\u4e8e: template void func(T &&x) { std::cout << x; }","title":"\u53c2\u6570\u7c7b\u578b auto"},{"location":"auto/#auto_4","text":"\u4f20\u7edf\u7684\uff0c\u57fa\u4e8e\u7c7b\u578b\u91cd\u8f7d\u7684\uff1a int square(int x) { return x * x; } double square(double x) { return x * x; } int main() { square(2); // 4\uff08\u8c03\u7528 int \u7248\u91cd\u8f7d\uff09 square(3.14); // 9.8596\uff08\u8c03\u7528 double \u7248\u91cd\u8f7d\uff09 // \u5982\u679c\u73b0\u5728\u53c8\u9700\u8981 float \u7248\u5462\uff1f\u53c8\u5f97\u5199\u4e00\u7248\u91cd\u8f7d\uff0c\u5185\u5bb9\u8fd8\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff0c\u6d6a\u8d39\u65f6\u95f4 } \u57fa\u4e8e auto \u6a21\u677f\u53c2\u6570\u63a8\u5bfc\u7684\uff1a auto square(auto x) { return x * x; } int main() { square(2); // 4\uff08auto \u63a8\u5bfc\u4e3a int\uff09 square(3.14); // 9.8596\uff08auto \u63a8\u5bfc\u4e3a double\uff09 // \u5373\u4f7f\u672a\u6765\u4ea7\u751f\u4e86 float \u7248\u7684\u9700\u6c42\uff0c\u4e5f\u4e0d\u7528\u6dfb\u52a0\u4efb\u4f55\u4ee3\u7801\uff0c\u56e0\u4e3a\u662f square \u662f\u5f88\u65b9\u4fbf\u7684\u6a21\u677f\u51fd\u6570 }","title":"auto \u5728\u591a\u6001\u4e2d\u7684\u5999\u7528"},{"location":"auto/#auto_5","text":"TODO: \u7ee7\u7eed\u4ecb\u7ecd auto , auto const , auto & , auto const & , auto && , decltype(auto) , auto * , auto const *","title":"auto \u63a8\u5bfc\u4e3a\u5f15\u7528"},{"location":"cmake_tutor/","text":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09 TODO","title":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"cmake_tutor/#c-cmake","text":"TODO","title":"\u5b66\u73b0\u4ee3 C++ \u4ece\u73b0\u4ee3 CMake \u5b66\u8d77\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"cpp_lifetime/","text":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f \u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f \u4e09\u5927\u5b58\u50a8\u5468\u671f \u603b\u7ed3 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u4e2d\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5177\u6709\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u3002 \u6784\u9020\u51fd\u6570\u56fa\u5b9a\u4e3a \u7c7b\u540d(\u6784\u9020\u51fd\u6570\u53c2\u6570\u5217\u8868) \u3002 \u6790\u6784\u51fd\u6570\u56fa\u5b9a\u4e3a ~\u7c7b\u540d() \u3002 \u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u90fd\u6ca1\u6709\u8fd4\u56de\u503c\u7c7b\u578b\u3002 \u6790\u6784\u51fd\u6570\u4e0d\u5f97\u62e5\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u4f46\u6784\u9020\u51fd\u6570\u53ef\u4ee5\u6709\u3002 struct Class { Class() { puts(\"\u6784\u9020\u51fd\u6570\"); } ~Class() { puts(\"\u6790\u6784\u51fd\u6570\"); } }; int main() { puts(\"\u8fdb\u5165 main\"); Class c; puts(\"\u79bb\u5f00 main\"); } \u8fd0\u884c\u7ed3\u679c\uff1a \u8fdb\u5165 main \u6784\u9020\u51fd\u6570 \u79bb\u5f00 main \u6790\u6784\u51fd\u6570 \u8fd9\u662f C++ \u4e2d\u6700\u57fa\u672c\u7684\u73b0\u8c61\u3002\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\uff0c\u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570\uff0c\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u79bb\u5f00\u5b9a\u4e49\u4e86\u4ed6\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u4f1a\u8c03\u7528\u6790\u6784\u51fd\u6570\u3002 \u51fd\u6570\u4f53\u6307\u7684\u662f\u4ece { \u5230 } \u4e4b\u95f4\u7684\u4ee3\u7801\u5757\u3002 \u5176\u4e2d\u6784\u9020\u51fd\u6570\u4e2d\u901a\u5e38\u8d1f\u8d23\u521b\u5efa\u8d44\u6e90\uff0c\u6790\u6784\u51fd\u6570\u4e2d\u901a\u5e38\u9500\u6bc1\u8d44\u6e90\u3002\u5bf9\u4e8e\u667a\u80fd\u6307\u9488\u548c vector \u800c\u8a00\uff0c\u8fd9\u4e2a\u8d44\u6e90\u5c31\u662f\u5185\u5b58\u3002 \u4e3a\u4ec0\u4e48\u8981\u53ca\u65f6\u9500\u6bc1\u4e0d\u7528\u7684\u8d44\u6e90\uff1f\u53ea\u5206\u914d\u4e0d\u91ca\u653e\uff0c\u4e00\u4e2a\u7a0b\u5e8f\u5360\u7528\u7684\u5185\u5b58\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u5c31\u4f1a\u8d8a\u6765\u8d8a\u591a\uff0c\u8fd9\u79cd\u7a0b\u5e8f\u5982\u679c\u957f\u671f\u8fd0\u884c\uff0c\u4f1a\u5403\u5149\u6574\u4e2a\u7cfb\u7edf\u7684\u6240\u6709\u8d44\u6e90\u7136\u540e\u88ab Linux \u5185\u6838\u89c6\u4e3a\u5371\u9669\u8fdb\u7a0b\u800c\u6740\u6b7b\u3002\u9664\u975e\u4f60\u7684\u7a0b\u5e8f\u53ea\u4f1a\u8fd0\u884c\u4e00\u4f1a\u4f1a\uff0c\u5982\u679c\u662f\u957f\u671f\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u4f8b\u5982\u670d\u52a1\u5668\uff0c\u5fc5\u987b\u4e25\u683c\u7ba1\u7406\u6240\u6709\u81ea\u5df1\u66fe\u7ecf\u5206\u914d\u8fc7\u7684\u5185\u5b58\uff0c\u4e0d\u7528\u65f6\u5c31\u7acb\u5373\u91ca\u653e\uff0c\u4e0d\u8981\u5360\u7740\u8305\u5751\u4e0d\u62c9\u53f2\u3002 } \u88ab\u8a89\u4e3a \u6700\u4f1f\u5927\u7684\u8fd0\u7b97\u7b26 \uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u53ef\u4ee5\u89e6\u53d1\u6790\u6784\u51fd\u6570\uff0c\u5e2e\u4f60\u81ea\u52a8\u91ca\u653e\u6389\u8d44\u6e90\uff0c\u4f60\u5c31\u4e0d\u7528\u81ea\u5df1\u8d39\u5fc3\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff0c\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u4e86\u3002 \u4e09\u5927\u5b58\u50a8\u5468\u671f \u5728\u8fdb\u4e00\u6b65\u6df1\u5165\u4e4b\u524d\uff0c\u6211\u4eec\u5fc5\u987b\u660e\u786e\u4ee5\u4e0b\u672f\u8bed\uff1a\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u3001\u52a8\u6001\u5b58\u50a8\u5468\u671f\u3001\u9759\u6001\u5b58\u50a8\u5468\u671f\u3002 \u53d8\u91cf\u5b9a\u4e49\u5728\u4e0d\u540c\u7684\u4f4d\u7f6e\uff0c\u5176\u751f\u547d\u5468\u671f\uff08\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\uff09\u4f1a\u6709\u6240\u4e0d\u540c\u3002 \u6bd4\u5982\u4e00\u4e2a\u53d8\u91cf\u5b9a\u4e49\u5728\u51fd\u6570\u4f53\u5185\u3001\u7c7b\u4f53\u5185\u3001\u901a\u8fc7 new \u521b\u5efa\uff0c\u4e4b\u7c7b\u7684\u3002 \u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u76f4\u63a5\u5b9a\u4e49\u5728 \u51fd\u6570\u4f53 \u5185\u3002\u4fd7\u79f0\u201c\u6808\u4e0a\u201d\u6216\u201c\u5c40\u90e8\u53d8\u91cf\u201d void func() { Class a; // a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u5b9a\u4e49\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u6240\u5728\u7684 {} \u4ee3\u7801\u5757\u6267\u884c\u5230 } \u5904\u65f6\u8c03\u7528\u3002 \u52a8\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u901a\u8fc7 new \u6765\u521b\u5efa\u3002\u4fd7\u79f0\u201c\u5806\u4e0a\u201d\u6216\u201c\u5806\u5bf9\u8c61\u201d void func() { Class *p = new Class; // *p \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f delete p; // \u91ca\u653e\u52a8\u6001\u5206\u914d\u7684\u5185\u5b58 } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u901a\u8fc7 new \u521b\u5efa\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 delete \u88ab\u8c03\u7528\u65f6\u88ab\u8c03\u7528\u3002 \u7279\u522b\u6ce8\u610f\uff0c p \u4f9d\u7136\u662f\u201c\u6808\u4e0a\u53d8\u91cf\u201d\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u201c\u5806\u4e0a\u53d8\u91cf\u201d\uff01 \u7528\u5f8b\u5e08\u8bed\u518d\u8bf4\u4e00\u904d\uff1a p \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f\uff01\uff08\u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\uff09 \u6307\u9488\u672c\u8eab\uff0c\u548c\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\uff0c\u662f\u4e24\u4e2a\u4e1c\u897f\uff0c\u4e0d\u8981\u6df7\u6dc6\u3002 p \u672c\u8eab\u4f1a\u968f\u7740 func \u7684 } \u800c\u6790\u6784\uff0c\u4f46\u662f *p \u7684\u7c7b\u578b\u662f Class * \uff0c\u662f\u4e00\u4e2a C \u8bed\u8a00\u539f\u59cb\u6307\u9488\uff0c\u539f\u59cb\u6307\u9488\u5c5e\u4e8e C \u8bed\u8a00\u539f\u59cb\u7c7b\u578b\uff0c\u6ca1\u6709\u6790\u6784\u51fd\u6570\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u62b5\u8fbe } \u65f6\uff0c p \u540d\u4e49\u4e0a\u4f1a\u6790\u6784\uff0c\u4f46\u662f\u4ed6\u6ca1\u6709\u6790\u6784\u51fd\u6570\uff0c\u5e76\u4e0d\u4f1a\u4ea7\u751f\u4efb\u4f55\u4f5c\u7528\u3002\u8fd9\u4e00\u5207\u548c p \u6307\u5411\u7684\u5bf9\u8c61 *p \u6ca1\u6709\u4efb\u4f55\u5173\u7cfb\uff0c\u4f60\u9700\u8981\u624b\u52a8 delete \u624d\u4f1a\u8c03\u7528\u5230 *p \u7684\u6790\u6784\u51fd\u6570\uff0c\u5e76\u91ca\u653e\u5206\u914d\u7684\u5185\u5b58\u3002 new \u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u5185\u5b58\u5206\u914d + \u5bf9\u8c61\u6784\u9020 delete \u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u5bf9\u8c61\u6790\u6784 + \u5185\u5b58\u91ca\u653e \u667a\u80fd\u6307\u9488\u7684\u4f18\u52bf\u5728\u4e8e\uff0c\u667a\u80fd\u6307\u9488\u662f\u4e2a C++ \u7c7b\uff0c\u5177\u6709\u5b9a\u5236\u7684\u6790\u6784\u51fd\u6570\u3002\u5f53 } \u62b5\u8fbe\uff0c \u667a\u80fd\u6307\u9488\u672c\u8eab \u7531\u4e8e\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\u6790\u6784\u65f6\uff0c\u5176\u4f1a delete p \uff0c\u5229\u7528\u52a8\u6001\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\uff0c\u89e6\u53d1 \u667a\u80fd\u6307\u9488\u6307\u5411\u5bf9\u8c61 \u7684\u6790\u6784\u51fd\u6570\uff0c\u4e5f\u5c31\u662f\u4ece\u800c\u8c03\u7528 *p \u7684\u6790\u6784\u51fd\u6570\u3002 \u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u53c8\u8981\u5177\u4f53\u5206\u4e09\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u6216\u201c\u9759\u6001\u53d8\u91cf\u201d (1) \u5b9a\u4e49\u5728 \u540d\u5b57\u7a7a\u95f4 \u5185\uff0c\u4e0d\u8bba\u662f\u4e0d\u662f static \u6216 inline\uff08\u5728\u540d\u5b57\u7a7a\u95f4\u4e2d\uff0cstatic \u548c inline \u5f71\u54cd\u7684\u53ea\u662f\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff0c\u800c\u4e0d\u662f\u5b58\u50a8\u5468\u671f\uff09 namespace hello { Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u542f\u52a8\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u524d\uff09\uff1b\u5bf9 DLL \u6765\u8bf4\u5219\u662f DLL \u9996\u6b21\u52a0\u8f7d\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u9000\u51fa\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u540e\uff09\u3002 (2) \u6ce8\u610f\uff0c \u5168\u5c40\u540d\u5b57\u7a7a\u95f4 \u662f\u4e00\u4e2a\u7279\u6b8a\u7684 \u540d\u5b57\u7a7a\u95f4 \uff0c\u5916\u9762\u6ca1\u6709\u5305\u88f9\u4efb\u4f55 namespace \u65f6\u5c31\u5c5e\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u3002\u6240\u4ee5\u4e0b\u9762\u8fd9\u79cd\u4e5f\u5c5e\u4e8e\u201c\u5728 (\u5168\u5c40) \u540d\u5b57\u7a7a\u95f4\u5185\u201d\uff1a Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f (3) \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u9759\u6001\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u5c31\u662f\u901a\u8fc7 static \u4fee\u9970\u8fc7\u7684\u6210\u5458\u53d8\u91cf\uff08\u5728\u7c7b\u5185\uff0cstatic \u5c31\u5f71\u54cd\u5b58\u50a8\u5468\u671f\u4e86\uff0cinline \u7ee7\u7eed\u53ea\u5f71\u54cd\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff09 struct Other { static Class s; }; Class Other::s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f struct Other { inline static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f }; struct Other { Class a; // a \u4e0d\u662f\u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u800c\u662f\u8ddf\u968f\u5176\u6240\u5c5e\u7684 Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u6210\u5458\u53d8\u91cf\uff08\u6ca1\u6709 static \u7684\uff09\uff0c\u8ddf\u968f\u6240\u5c5e\u7c7b\u7684\u5b58\u50a8\u5468\u671f struct Other { Class a; // a \u8ddf\u968f Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; Other o; // o.a \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f int main() { Other o; // o.a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f Other *p; // p->a \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6784\u9020\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6790\u6784\u65f6\u8c03\u7528\u3002 \u603b\u7ed3 \u81ea\u52a8\u5b58\u50a8\u5468\u671f - \u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u81ea\u52a8\u6790\u6784 \u52a8\u6001\u5b58\u50a8\u5468\u671f - \u901a\u8fc7 new \u521b\u5efa\u7684\uff0cdelete \u65f6\u6790\u6784 \u9759\u6001\u5b58\u50a8\u5468\u671f - \u5168\u5c40\u53d8\u91cf\uff0c\u7a0b\u5e8f\u7ed3\u675f\u65f6\u6790\u6784 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u539f\u56e0\u5f88\u590d\u6742\uff0c\u6574\u4e2a\u6545\u4e8b\u8981\u4ece boost \u5f53\u5e74\u5982\u4f55\u8bbe\u8ba1\u51fa\u53f3\u503c\u5f15\u7528\u5230\u56fe\u7075\u7684\u505c\u673a\u95ee\u9898\u8bb2\u8d77\uff0c\u8bb2\u4e86\u4f60\u4e5f\u8bb0\u4e0d\u4f4f\uff0c\u53ea\u9700\u8981\u8bb0\u4f4f\u7ed3\u8bba\uff1a \u5982\u679c\u4f60\u8981\u5b9a\u4e49\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 -Wnon-virtual-dtor -Wdelete-non-virtual-dtor TODO: \u4ecb\u7ecd \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c TODO int main() { std::string const &s = std::string(\"hello\"); std::cout << s; // OK } std::string const &identity(std::string const &s) { return s; } int main() { std::string const &s = identity(std::string(\"hello\")); std::cout << s; // BOOM! }","title":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#_1","text":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f \u4e09\u5927\u5b58\u50a8\u5468\u671f \u603b\u7ed3 \u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751 \u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c","title":"\u6df1\u5165\u7406\u89e3\u6790\u6784\u51fd\u6570\u4e0e\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#c","text":"C++ \u4e2d\u4e00\u4e2a\u7c7b\u53ef\u4ee5\u5177\u6709\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u3002 \u6784\u9020\u51fd\u6570\u56fa\u5b9a\u4e3a \u7c7b\u540d(\u6784\u9020\u51fd\u6570\u53c2\u6570\u5217\u8868) \u3002 \u6790\u6784\u51fd\u6570\u56fa\u5b9a\u4e3a ~\u7c7b\u540d() \u3002 \u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u90fd\u6ca1\u6709\u8fd4\u56de\u503c\u7c7b\u578b\u3002 \u6790\u6784\u51fd\u6570\u4e0d\u5f97\u62e5\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u4f46\u6784\u9020\u51fd\u6570\u53ef\u4ee5\u6709\u3002 struct Class { Class() { puts(\"\u6784\u9020\u51fd\u6570\"); } ~Class() { puts(\"\u6790\u6784\u51fd\u6570\"); } }; int main() { puts(\"\u8fdb\u5165 main\"); Class c; puts(\"\u79bb\u5f00 main\"); } \u8fd0\u884c\u7ed3\u679c\uff1a \u8fdb\u5165 main \u6784\u9020\u51fd\u6570 \u79bb\u5f00 main \u6790\u6784\u51fd\u6570 \u8fd9\u662f C++ \u4e2d\u6700\u57fa\u672c\u7684\u73b0\u8c61\u3002\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u88ab\u521b\u5efa\u65f6\uff0c\u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570\uff0c\u6bcf\u5f53\u4e00\u4e2a\u5bf9\u8c61\u79bb\u5f00\u5b9a\u4e49\u4e86\u4ed6\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u4f1a\u8c03\u7528\u6790\u6784\u51fd\u6570\u3002 \u51fd\u6570\u4f53\u6307\u7684\u662f\u4ece { \u5230 } \u4e4b\u95f4\u7684\u4ee3\u7801\u5757\u3002 \u5176\u4e2d\u6784\u9020\u51fd\u6570\u4e2d\u901a\u5e38\u8d1f\u8d23\u521b\u5efa\u8d44\u6e90\uff0c\u6790\u6784\u51fd\u6570\u4e2d\u901a\u5e38\u9500\u6bc1\u8d44\u6e90\u3002\u5bf9\u4e8e\u667a\u80fd\u6307\u9488\u548c vector \u800c\u8a00\uff0c\u8fd9\u4e2a\u8d44\u6e90\u5c31\u662f\u5185\u5b58\u3002 \u4e3a\u4ec0\u4e48\u8981\u53ca\u65f6\u9500\u6bc1\u4e0d\u7528\u7684\u8d44\u6e90\uff1f\u53ea\u5206\u914d\u4e0d\u91ca\u653e\uff0c\u4e00\u4e2a\u7a0b\u5e8f\u5360\u7528\u7684\u5185\u5b58\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u5c31\u4f1a\u8d8a\u6765\u8d8a\u591a\uff0c\u8fd9\u79cd\u7a0b\u5e8f\u5982\u679c\u957f\u671f\u8fd0\u884c\uff0c\u4f1a\u5403\u5149\u6574\u4e2a\u7cfb\u7edf\u7684\u6240\u6709\u8d44\u6e90\u7136\u540e\u88ab Linux \u5185\u6838\u89c6\u4e3a\u5371\u9669\u8fdb\u7a0b\u800c\u6740\u6b7b\u3002\u9664\u975e\u4f60\u7684\u7a0b\u5e8f\u53ea\u4f1a\u8fd0\u884c\u4e00\u4f1a\u4f1a\uff0c\u5982\u679c\u662f\u957f\u671f\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u4f8b\u5982\u670d\u52a1\u5668\uff0c\u5fc5\u987b\u4e25\u683c\u7ba1\u7406\u6240\u6709\u81ea\u5df1\u66fe\u7ecf\u5206\u914d\u8fc7\u7684\u5185\u5b58\uff0c\u4e0d\u7528\u65f6\u5c31\u7acb\u5373\u91ca\u653e\uff0c\u4e0d\u8981\u5360\u7740\u8305\u5751\u4e0d\u62c9\u53f2\u3002 } \u88ab\u8a89\u4e3a \u6700\u4f1f\u5927\u7684\u8fd0\u7b97\u7b26 \uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u53ef\u4ee5\u89e6\u53d1\u6790\u6784\u51fd\u6570\uff0c\u5e2e\u4f60\u81ea\u52a8\u91ca\u653e\u6389\u8d44\u6e90\uff0c\u4f60\u5c31\u4e0d\u7528\u81ea\u5df1\u8d39\u5fc3\u624b\u52a8\u91ca\u653e\u5185\u5b58\uff0c\u548c\u5176\u4ed6\u5404\u79cd\u8d44\u6e90\u4e86\u3002","title":"C++ \u5bf9\u8c61\u751f\u547d\u5468\u671f"},{"location":"cpp_lifetime/#_2","text":"\u5728\u8fdb\u4e00\u6b65\u6df1\u5165\u4e4b\u524d\uff0c\u6211\u4eec\u5fc5\u987b\u660e\u786e\u4ee5\u4e0b\u672f\u8bed\uff1a\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u3001\u52a8\u6001\u5b58\u50a8\u5468\u671f\u3001\u9759\u6001\u5b58\u50a8\u5468\u671f\u3002 \u53d8\u91cf\u5b9a\u4e49\u5728\u4e0d\u540c\u7684\u4f4d\u7f6e\uff0c\u5176\u751f\u547d\u5468\u671f\uff08\u6784\u9020\u51fd\u6570\u548c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\uff09\u4f1a\u6709\u6240\u4e0d\u540c\u3002 \u6bd4\u5982\u4e00\u4e2a\u53d8\u91cf\u5b9a\u4e49\u5728\u51fd\u6570\u4f53\u5185\u3001\u7c7b\u4f53\u5185\u3001\u901a\u8fc7 new \u521b\u5efa\uff0c\u4e4b\u7c7b\u7684\u3002 \u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u76f4\u63a5\u5b9a\u4e49\u5728 \u51fd\u6570\u4f53 \u5185\u3002\u4fd7\u79f0\u201c\u6808\u4e0a\u201d\u6216\u201c\u5c40\u90e8\u53d8\u91cf\u201d void func() { Class a; // a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u5b9a\u4e49\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u6240\u5728\u7684 {} \u4ee3\u7801\u5757\u6267\u884c\u5230 } \u5904\u65f6\u8c03\u7528\u3002 \u52a8\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u901a\u8fc7 new \u6765\u521b\u5efa\u3002\u4fd7\u79f0\u201c\u5806\u4e0a\u201d\u6216\u201c\u5806\u5bf9\u8c61\u201d void func() { Class *p = new Class; // *p \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f delete p; // \u91ca\u653e\u52a8\u6001\u5206\u914d\u7684\u5185\u5b58 } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u53d8\u91cf\u901a\u8fc7 new \u521b\u5efa\u65f6\u88ab\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 delete \u88ab\u8c03\u7528\u65f6\u88ab\u8c03\u7528\u3002 \u7279\u522b\u6ce8\u610f\uff0c p \u4f9d\u7136\u662f\u201c\u6808\u4e0a\u53d8\u91cf\u201d\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u201c\u5806\u4e0a\u53d8\u91cf\u201d\uff01 \u7528\u5f8b\u5e08\u8bed\u518d\u8bf4\u4e00\u904d\uff1a p \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f\uff0c p \u6307\u5411\u7684 *p \u624d\u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f\uff01\uff08\u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\uff09 \u6307\u9488\u672c\u8eab\uff0c\u548c\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\uff0c\u662f\u4e24\u4e2a\u4e1c\u897f\uff0c\u4e0d\u8981\u6df7\u6dc6\u3002 p \u672c\u8eab\u4f1a\u968f\u7740 func \u7684 } \u800c\u6790\u6784\uff0c\u4f46\u662f *p \u7684\u7c7b\u578b\u662f Class * \uff0c\u662f\u4e00\u4e2a C \u8bed\u8a00\u539f\u59cb\u6307\u9488\uff0c\u539f\u59cb\u6307\u9488\u5c5e\u4e8e C \u8bed\u8a00\u539f\u59cb\u7c7b\u578b\uff0c\u6ca1\u6709\u6790\u6784\u51fd\u6570\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u62b5\u8fbe } \u65f6\uff0c p \u540d\u4e49\u4e0a\u4f1a\u6790\u6784\uff0c\u4f46\u662f\u4ed6\u6ca1\u6709\u6790\u6784\u51fd\u6570\uff0c\u5e76\u4e0d\u4f1a\u4ea7\u751f\u4efb\u4f55\u4f5c\u7528\u3002\u8fd9\u4e00\u5207\u548c p \u6307\u5411\u7684\u5bf9\u8c61 *p \u6ca1\u6709\u4efb\u4f55\u5173\u7cfb\uff0c\u4f60\u9700\u8981\u624b\u52a8 delete \u624d\u4f1a\u8c03\u7528\u5230 *p \u7684\u6790\u6784\u51fd\u6570\uff0c\u5e76\u91ca\u653e\u5206\u914d\u7684\u5185\u5b58\u3002 new \u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u5185\u5b58\u5206\u914d + \u5bf9\u8c61\u6784\u9020 delete \u5206\u4e3a\u4e24\u90e8\u5206\uff1a \u5bf9\u8c61\u6790\u6784 + \u5185\u5b58\u91ca\u653e \u667a\u80fd\u6307\u9488\u7684\u4f18\u52bf\u5728\u4e8e\uff0c\u667a\u80fd\u6307\u9488\u662f\u4e2a C++ \u7c7b\uff0c\u5177\u6709\u5b9a\u5236\u7684\u6790\u6784\u51fd\u6570\u3002\u5f53 } \u62b5\u8fbe\uff0c \u667a\u80fd\u6307\u9488\u672c\u8eab \u7531\u4e8e\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\u6790\u6784\u65f6\uff0c\u5176\u4f1a delete p \uff0c\u5229\u7528\u52a8\u6001\u5b58\u50a8\u5468\u671f\u7684\u89c4\u5219\uff0c\u89e6\u53d1 \u667a\u80fd\u6307\u9488\u6307\u5411\u5bf9\u8c61 \u7684\u6790\u6784\u51fd\u6570\uff0c\u4e5f\u5c31\u662f\u4ece\u800c\u8c03\u7528 *p \u7684\u6790\u6784\u51fd\u6570\u3002 \u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u8fd9\u79cd\u53d8\u91cf\u53c8\u8981\u5177\u4f53\u5206\u4e09\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u6216\u201c\u9759\u6001\u53d8\u91cf\u201d (1) \u5b9a\u4e49\u5728 \u540d\u5b57\u7a7a\u95f4 \u5185\uff0c\u4e0d\u8bba\u662f\u4e0d\u662f static \u6216 inline\uff08\u5728\u540d\u5b57\u7a7a\u95f4\u4e2d\uff0cstatic \u548c inline \u5f71\u54cd\u7684\u53ea\u662f\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff0c\u800c\u4e0d\u662f\u5b58\u50a8\u5468\u671f\uff09 namespace hello { Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u542f\u52a8\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u524d\uff09\uff1b\u5bf9 DLL \u6765\u8bf4\u5219\u662f DLL \u9996\u6b21\u52a0\u8f7d\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53\u7a0b\u5e8f\u9000\u51fa\u65f6\u8c03\u7528\uff08main \u51fd\u6570\u4e4b\u540e\uff09\u3002 (2) \u6ce8\u610f\uff0c \u5168\u5c40\u540d\u5b57\u7a7a\u95f4 \u662f\u4e00\u4e2a\u7279\u6b8a\u7684 \u540d\u5b57\u7a7a\u95f4 \uff0c\u5916\u9762\u6ca1\u6709\u5305\u88f9\u4efb\u4f55 namespace \u65f6\u5c31\u5c5e\u4e8e\u8fd9\u79cd\u60c5\u51b5\uff0c\u4fd7\u79f0\u201c\u5168\u5c40\u53d8\u91cf\u201d\u3002\u6240\u4ee5\u4e0b\u9762\u8fd9\u79cd\u4e5f\u5c5e\u4e8e\u201c\u5728 (\u5168\u5c40) \u540d\u5b57\u7a7a\u95f4\u5185\u201d\uff1a Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f inline Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f (3) \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u9759\u6001\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u5c31\u662f\u901a\u8fc7 static \u4fee\u9970\u8fc7\u7684\u6210\u5458\u53d8\u91cf\uff08\u5728\u7c7b\u5185\uff0cstatic \u5c31\u5f71\u54cd\u5b58\u50a8\u5468\u671f\u4e86\uff0cinline \u7ee7\u7eed\u53ea\u5f71\u54cd\u201c\u7b26\u53f7\u53ef\u89c1\u6027\u201d\uff09 struct Other { static Class s; }; Class Other::s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f struct Other { inline static Class s; // s \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f }; struct Other { Class a; // a \u4e0d\u662f\u9759\u6001\u5b58\u50a8\u5468\u671f\uff0c\u800c\u662f\u8ddf\u968f\u5176\u6240\u5c5e\u7684 Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; \u5b9a\u4e49\u5728\u7c7b\u5185\u7684\u6210\u5458\u53d8\u91cf\uff08\u6ca1\u6709 static \u7684\uff09\uff0c\u8ddf\u968f\u6240\u5c5e\u7c7b\u7684\u5b58\u50a8\u5468\u671f struct Other { Class a; // a \u8ddf\u968f Other \u7ed3\u6784\u4f53\u7684\u5b58\u50a8\u5468\u671f }; Other o; // o.a \u662f\u9759\u6001\u5b58\u50a8\u5468\u671f int main() { Other o; // o.a \u662f\u81ea\u52a8\u5b58\u50a8\u5468\u671f Other *p; // p->a \u662f\u52a8\u6001\u5b58\u50a8\u5468\u671f } \u6784\u9020\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6784\u9020\u65f6\u8c03\u7528\u3002 \u6790\u6784\u65f6\u673a\uff1a\u5f53 Other \u7ed3\u6784\u4f53\u6790\u6784\u65f6\u8c03\u7528\u3002","title":"\u4e09\u5927\u5b58\u50a8\u5468\u671f"},{"location":"cpp_lifetime/#_3","text":"\u81ea\u52a8\u5b58\u50a8\u5468\u671f - \u51fd\u6570\u7684\u5c40\u90e8\u53d8\u91cf\uff0c\u81ea\u52a8\u6790\u6784 \u52a8\u6001\u5b58\u50a8\u5468\u671f - \u901a\u8fc7 new \u521b\u5efa\u7684\uff0cdelete \u65f6\u6790\u6784 \u9759\u6001\u5b58\u50a8\u5468\u671f - \u5168\u5c40\u53d8\u91cf\uff0c\u7a0b\u5e8f\u7ed3\u675f\u65f6\u6790\u6784","title":"\u603b\u7ed3"},{"location":"cpp_lifetime/#_4","text":"\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01 \u539f\u56e0\u5f88\u590d\u6742\uff0c\u6574\u4e2a\u6545\u4e8b\u8981\u4ece boost \u5f53\u5e74\u5982\u4f55\u8bbe\u8ba1\u51fa\u53f3\u503c\u5f15\u7528\u5230\u56fe\u7075\u7684\u505c\u673a\u95ee\u9898\u8bb2\u8d77\uff0c\u8bb2\u4e86\u4f60\u4e5f\u8bb0\u4e0d\u4f4f\uff0c\u53ea\u9700\u8981\u8bb0\u4f4f\u7ed3\u8bba\uff1a \u5982\u679c\u4f60\u8981\u5b9a\u4e49\u6790\u6784\u51fd\u6570\uff0c\u5c31 \u5fc5\u987b\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u3001\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570 \uff01","title":"\u6790\u6784\u51fd\u6570\u7684\u9006\u5929\u5927\u5751"},{"location":"cpp_lifetime/#_5","text":"-Wnon-virtual-dtor -Wdelete-non-virtual-dtor TODO: \u4ecb\u7ecd","title":"\u865a\u7c7b\u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u662f\u865a\u7684"},{"location":"cpp_lifetime/#_6","text":"TODO int main() { std::string const &s = std::string(\"hello\"); std::cout << s; // OK } std::string const &identity(std::string const &s) { return s; } int main() { std::string const &s = identity(std::string(\"hello\")); std::cout << s; // BOOM! }","title":"\u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c"},{"location":"cpp_memory/","text":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5) void modify(int *pa) { int *pb = pa + 1; *pb = 9; } int func() { int a = 4; int b = 5; modify(&a); return b; // 5 \u8fd8\u662f 9\uff1f }","title":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5)"},{"location":"cpp_memory/#c","text":"void modify(int *pa) { int *pb = pa + 1; *pb = 9; } int func() { int a = 4; int b = 5; modify(&a); return b; // 5 \u8fd8\u662f 9\uff1f }","title":"\u771f\u6b63\u7684 C++ \u5185\u5b58\u6a21\u578b\uff01 (\u672a\u5b8c\u5de5)"},{"location":"cpp_tricks/","text":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u522b\u518d [] \u5566\uff01 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u7ee7\u627f\u6784\u9020\u51fd\u6570 \u63d0\u524d\u8fd4\u56de \u7acb\u5373\u8c03\u7528\u7684 Lambda Lambda \u590d\u7528\u4ee3\u7801 \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u522b\u518d make_pair \u5566\uff01 insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 \u5b57\u7b26\u4e32\u5207\u7247 cout \u4e0d\u9700\u8981 endl \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f cerr \u4e0e cout \u7684\u6289\u62e9 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 if-auto \u4e0e while-auto bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f map + any \u5916\u6302\u5c5e\u6027 \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf int a = 42; int b = 58; \u73b0\u5728\u4f60\u60f3\u4ea4\u6362\u8fd9\u4e24\u4e2a\u53d8\u91cf\u3002 int tmp = a; a = b; b = tmp; \u4f46\u662f\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u65b9\u6cd5\uff1a std::swap(a, b); \u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4ea4\u6362\u4efb\u610f\u4e24\u4e2a\u540c\u7c7b\u578b\u7684\u503c\uff0c\u5305\u62ec\u7ed3\u6784\u4f53\u3001\u6570\u7ec4\u3001\u5bb9\u5668\u7b49\u3002 \u53ea\u9700\u8981 #include \u5c31\u53ef\u4ee5\u4f7f\u7528\uff01 \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5c0f\u5f6d\u8001\u5e08\uff1a\u4e0d\u8981\u51fa\u73b0 new \u548c delete\uff0c\u4e0d\u5b89\u5168\u3002 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; } \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u4f17\u6240\u5468\u77e5\uff0cC\u8bed\u8a00\u4e2d int \u76f8\u9664 / \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u4e5f\u662f int \uff0c\u5982\u679c\u9664\u6cd5\u4ea7\u751f\u4e86\u4f59\u6570\uff0c\u90a3\u4e48\u53ea\u4f1a\u4fdd\u7559\u6574\u6570\u90e8\u5206\u3002 \u4f8b\u5982 14 / 5 \uff0c\u672c\u6765\u5e94\u8be5\u5f97\u5230 2.8\u3002\u4f46\u662f\u56e0\u4e3a C \u8bed\u8a00\u7684\u9664\u6cd5\u8fd4\u56de int \uff0c\u7ed3\u679c\u4f1a\u81ea\u52a8\u5411\u4e0b\u53d6\u6574\uff0c\u5bfc\u81f4\u5f97\u5230 2\u3002 int a = 14, b = 5; int c = a / b; // c = 14 / 5 = 2 \u7b49\u4ef7\u4e8e int c = floor((float)a / b); // c = floor(2.8) = 2 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5c0f\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5730\u677f\u9664 (floor div) \u3002 C \u8bed\u8a00\u9ed8\u8ba4\u7684\u5c31\u662f\u5730\u677f\u9664\u3002 \u5982\u679c\u6211\u60f3\u8981\u7684\u662f\u5411\u4e0a\u53d6\u6574\uff0c\u8be5\u600e\u4e48\u5199\uff1f \u6700\u539f\u59cb\u7684\u5199\u6cd5\u662f\u5148\u8f6c\u6210\u6d6e\u70b9\u6570\u6765\u9664\uff0c\u7136\u540eceil\u51fd\u6570\u5411\u4e0a\u53d6\u6574\uff1a int c = ceil((float)a / b); \u4f46\u662f\u6d6e\u70b9\u6570\u4e0d\u4ec5\u4f4e\u6548\uff0c\u8fd8\u6709\u7cdf\u7cd5\u7684\u6d6e\u70b9\u6570\u7cbe\u5ea6\u8bef\u5dee\uff01\u5bf9\u4e8e\u5f88\u5927\u7684\u6574\u6570\uff08\u5927\u4e8e 2^{23} 2^{23} \uff09\u4f1a\u4ea7\u751f\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u66f4\u5408\u7406\u7684\u5199\u6cd5\u662f\u5148\u628a a \u52a0\u4e0a b - 1 \uff0c\u7136\u540e\u518d\u4e0b\u53d6\u6574\u5730\u9664\u4ee5 b \uff1a int c = (a + b - 1) / b; \u8fd9\u6837\u5c31\u80fd\u4ea7\u751f\u4e00\u4e2a\u5411\u4e0a\u53d6\u6574\u7684\u9664\u6cd5\u4e86\u3002 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5929\u82b1\u677f\u9664 (ceil div) \u3002 \u8bd5\u8bd5\u770b\uff1a14 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2.8\uff1b\u5982\u679c\u7528\u5730\u677f\u9664\uff0c\u4f1a\u5f97\u5230 2\uff1b\u5982\u679c\u7528\u5929\u82b1\u677f\u9664\uff0c\u4f1a\u5f97\u5230 3\u3002 14 / 5 = 2 (14 + 5 - 1) / 5 = (14 + 4) / 5 = 18 / 5 = 3 \u8bd5\u8bd5\u770b\uff1a10 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2\uff1b\u90a3\u4e48\u65e0\u8bba\u662f\u5730\u677f\u9664\u8fd8\u662f\u5929\u82b1\u677f\u9664\uff0c\u90fd\u5e94\u8be5\u5f97\u5230 2\u3002 10 / 5 = 2 (10 + 5 - 1) / 5 = (10 + 4) / 5 = 14 / 5 = 2 \u8fd9\u5c31\u662f C \u8bed\u8a00\u4e2d\u5b9e\u73b0\u5929\u82b1\u677f\u9664\u7684\u4e1a\u754c\u516c\u8ba4\u65b9\u5f0f\u3002 \u522b\u518d [] \u5566\uff01 \u4f60\u77e5\u9053\u5417\uff1f\u5728 map \u4e2d\u4f7f\u7528 [] \u67e5\u627e\u5143\u7d20\uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\u3002\u8fd9\u4e2a\u7279\u6027\u6709\u65f6\u5f88\u65b9\u4fbf\uff0c\u4f46\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u5199\u9519\u4e86\uff0c\u5c31\u4f1a\u5728 map \u4e2d\u521b\u5efa\u4e00\u4e2a\u591a\u4f59\u7684\u9ed8\u8ba4\u5143\u7d20\u3002 map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; cout << table[\"\u4faf\u6377\u8001\u5e08\"]; table \u4e2d\u660e\u660e\u6ca1\u6709 \u201c\u4faf\u6377\u8001\u5e08\u201d \u8fd9\u4e2a\u5143\u7d20\uff0c\u4f46\u7531\u4e8e [] \u7684\u7279\u6027\uff0c\u4ed6\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u4e00\u4e2a 0\uff0c\u4e0d\u4f1a\u7206\u4efb\u4f55\u9519\u8bef\uff01 \u6539\u7528\u66f4\u5b89\u5168\u7684 at() \u51fd\u6570\uff0c\u5f53\u67e5\u8be2\u7684\u5143\u7d20\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u4f60\u8c03\u8bd5\uff1a map table; table.at(\"\u5c0f\u5f6d\u8001\u5e08\") = 24; cout << table.at(\"\u4faf\u6377\u8001\u5e08\"); // \u629b\u51fa\u5f02\u5e38 [] \u771f\u6b63\u7684\u7528\u9014\u662f\u201c\u5199\u5165\u65b0\u5143\u7d20\u201d\u65f6\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u4ed6\u53ef\u4ee5\u81ea\u52a8\u5e2e\u4f60\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\uff0c\u4f9b\u4f60\u4ee5\u5f15\u7528\u7684\u65b9\u5f0f\u8d4b\u503c\u8fdb\u53bb\u3002 \u68c0\u6d4b\u5143\u7d20\u662f\u5426\u5b58\u5728\u53ef\u4ee5\u7528 count \uff1a if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } \u5373\u4f7f\u4f60\u60f3\u8981\u9ed8\u8ba4\u503c 0 \u8fd9\u4e00\u7279\u6027\uff0c count + at \u4e5f\u6bd4 [] \u66f4\u597d\uff0c\u56e0\u4e3a [] \u7684\u9ed8\u8ba4\u503c\u662f\u4f1a\u5bf9 table \u505a\u7834\u574f\u6027\u4fee\u6539\u7684\uff0c\u8fd9\u5bfc\u81f4 [] \u9700\u8981 map \u7684\u58f0\u660e\u4e0d\u4e3a const \uff1a map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u5982\u679c\"\u5c0f\u5f6d\u8001\u5e08\"\u8fd9\u4e00\u952e\u4e0d\u5b58\u5728\uff0c\u4f1a\u521b\u5efa\"\u5c0f\u5f6d\u8001\u5e08\"\u5e76\u8bbe\u4e3a\u9ed8\u8ba4\u503c 0 const map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u7f16\u8bd1\u5931\u8d25\uff01[] \u9700\u8981\u975e const \u7684 map \u5bf9\u8c61\uff0c\u56e0\u4e3a\u4ed6\u4f1a\u7834\u574f\u6027\u4fee\u6539 \u66f4\u591a map \u77e5\u8bc6\u8bf7\u770b\u6211\u4eec\u7684 map \u4e13\u9898\u8bfe \u3002 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 // C++98 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} }; Student stu(\"\u4faf\u6377\u8001\u5e08\", 42, 123); C++98 \u9700\u8981\u624b\u52a8\u4e66\u5199\u6784\u9020\u51fd\u6570\uff0c\u975e\u5e38\u9ebb\u70e6\uff01\u800c\u4e14\u51e0\u4e4e\u90fd\u662f\u91cd\u590d\u7684\u3002 C++11 \u4e2d\uff0c\u5e73\u51e1\u7684\u7ed3\u6784\u4f53\u7c7b\u578b\u4e0d\u9700\u8981\u518d\u5199\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u7528 {} \u5c31\u80fd\u5bf9\u6210\u5458\u4f9d\u6b21\u521d\u59cb\u5316\uff1a // C++11 struct Student { string name; int age; int id; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123}; \u8fd9\u88ab\u79f0\u4e3a \u805a\u5408\u521d\u59cb\u5316 (aggregate initialize)\u3002\u53ea\u8981\u4f60\u7684\u7c7b\u6ca1\u6709\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709 private \u6210\u5458\uff0c\u90fd\u53ef\u4ee5\u7528 {} \u805a\u5408\u521d\u59cb\u5316\u3002 \u597d\u6d88\u606f\uff1aC++20 \u4e2d\uff0c\u805a\u5408\u521d\u59cb\u5316\u4e5f\u652f\u6301 () \u4e86\uff0c\u7528\u8d77\u6765\u5c31\u548c\u4f20\u7edf\u7684 C++98 \u6784\u9020\u51fd\u6570\u4e00\u6837\uff01 // C++20 Student stu(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123); \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6307\u5b9a\u9ed8\u8ba4\u503c\uff1a // C++11 struct Student { string name; int age; int id = 9999; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; C++20 \u5f00\u59cb\uff0c {} \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6839\u636e\u6bcf\u4e2a\u6210\u5458\u7684\u540d\u5b57\u6765\u6307\u5b9a\u503c\uff1a Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; \u597d\u5904\u662f\uff0c\u5373\u4f7f\u4e0d\u614e\u5199\u9519\u53c2\u6570\u987a\u5e8f\u4e5f\u4e0d\u7528\u62c5\u5fc3\u3002 Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .id = 9999, .age = 24}; \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u53ea\u6709\u5f53\u4f60\u9700\u8981\u6709\u201c\u81ea\u5b9a\u4e49\u94a9\u5b50\u903b\u8f91\u201d\u7684\u65f6\u5019\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\u3002 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} Student(Student const &other) : name(other.name), age(other.age), id(other.id) { std::cout << \"\u62f7\u8d1d\u6784\u9020\\n\"; } Student &operator=(Student const &other) { name = other.name; age = other.age; id = other.id; std::cout << \"\u62f7\u8d1d\u8d4b\u503c\\n\"; return *this; } }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c \u5982\u679c\u4f60\u4e0d\u9700\u8981\u8fd9\u4e2a std::cout \uff0c\u53ea\u662f\u5e73\u51e1\u5730\u62f7\u8d1d\u6240\u6709\u6210\u5458\uff0c\u5b8c\u5168\u53ef\u4ee5\u4e0d\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\u3001\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff1a struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student(Student const &other) // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student &operator=(Student const &other) }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c assert(stu2.name == \"\u4faf\u6377\u8001\u5e08\"); \u603b\u4e4b\uff0c\u5f88\u591a C++ \u6559\u6750\u628a\u62f7\u8d1d/\u79fb\u52a8\u6784\u9020\u51fd\u6570\u8fc7\u4e8e\u5938\u5927\uff0c\u641e\u5f97\u597d\u50cf\u6bcf\u4e2a\u7c7b\u90fd\u9700\u8981\u81ea\u5df1\u5b9a\u4e49\u4e00\u6837\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u6709\u5728\u201c\u81ea\u5df1\u5b9e\u73b0\u5bb9\u5668\u201d\u7684\u60c5\u51b5\u4e0b\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3002\u53ef\u662f\u8c01\u4f1a\u6574\u5929\u624b\u6413\u5bb9\u5668\uff1f \u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u7c7b\u91cc\u9762\u5b58 vector\u3001string \u7b49\u5c01\u88c5\u597d\u7684\u5bb9\u5668\uff0c\u7f16\u8bd1\u5668\u9ed8\u8ba4\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4f1a\u81ea\u52a8\u8c03\u7528\u4ed6\u4eec\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u7528\u6237\u53ea\u9700\u4e13\u6ce8\u4e8e\u4e1a\u52a1\u903b\u8f91\u5373\u53ef\uff0c\u4e0d\u9700\u8981\u64cd\u5fc3\u5e95\u5c42\u7ec6\u8282\u3002 \u5bf9\u4e8e\u6301\u6709\u8d44\u6e90\u7684 RAII \u7c7b\uff0c\u6211\u4eec\u90fd\u4f1a\u76f4\u63a5\u5220\u9664\u5176\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff1a struct RAIIHandle { int handle; RAIIHandle() { handle = CreateObject(); } RAIIHandle(RAIIHandle const &) = delete; RAIIHandle &operator=(RAIIHandle const &) = delete; RAIIHandle() { DeleteObject(handle); } }; \u7ee7\u627f\u6784\u9020\u51fd\u6570 C++ \u7279\u8272\uff1a\u5b50\u7c7b\u4e0d\u4f1a\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff01\uff08\u9664\u975e\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\u662f\u6ca1\u6709\u53c2\u6570\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff09 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { void child_func() { ... } }; Child child(23, \"peng\"); // \u9519\u8bef\uff01Child \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff01 C++11 \u4e2d\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u9762\u5199 using \u7236\u7c7b::\u7236\u7c7b \uff0c\u5c31\u80fd\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u6240\u6709\u7684\u6784\u9020\u51fd\u6570\u4e86\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { using Parent::Parent; // \u52a0\u4e0a\u8fd9\u4e00\u884c\uff01 void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u81ea\u52a8\u8c03\u7528\u5230\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570 Parent(int, const char *) \u5728 C++98 \u4e2d\uff0c\u6ca1\u6709 using \u7684\u8fd9\u4e2a\u8bed\u6cd5\uff0c\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a\u6784\u9020\u51fd\u6570\uff0c\u7136\u540e\u4f7f\u7528\u201c\u59d4\u4efb\u6784\u9020\u201d\u7684\u8bed\u6cd5\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9\u7236\u7c7b\uff0c\u975e\u5e38\u7e41\u7410\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { Child(int age, const char *name) : Parent(age, name) { ... } void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6784\u9020\u51fd\u6570\u540e\u8f6c\u53d1\u5230\u7236\u7c7b \u63d0\u524d\u8fd4\u56de void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); } else { puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); } else { puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } } } \u8fd9\u4e2a\u51fd\u6570\u6709\u5f88\u591a\u5c42\u5d4c\u5957\uff0c\u5f88\u4e0d\u7f8e\u89c2\u3002\u7528 \u63d0\u524d\u8fd4\u56de \u7684\u5199\u6cd5\u6765\u4f18\u5316\uff1a void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); return; } puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); return; } puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } \u7acb\u5373\u8c03\u7528\u7684 Lambda \u6709\u65f6\uff0c\u9700\u8981\u5728\u4e00\u4e2a\u5217\u8868\u91cc\u5faa\u73af\u67e5\u627e\u67d0\u6837\u4e1c\u897f\uff0c\u4e5f\u53ef\u4ee5\u7528\u63d0\u524d\u8fd4\u56de\u7684\u5199\u6cd5\u4f18\u5316\uff1a bool find(const vector &v, int target) { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } \u53ef\u4ee5\u5305\u88f9\u4e00\u4e2a\u7acb\u5373\u8c03\u7528\u7684 Lambda \u5757 [&] { ... } () \uff0c\u9650\u5236\u63d0\u524d\u8fd4\u56de\u7684\u8303\u56f4\uff1a void find(const vector &v, int target) { bool found = [&] { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } (); if (found) { ... } } Lambda \u590d\u7528\u4ee3\u7801 vector spilt(string str) { vector list; string last; for (char c: str) { if (c == ' ') { list.push_back(last); last.clear(); } else { last.push_back(c); } } list.push_back(last); return list; } \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u7528 Lambda \u590d\u7528\uff1a vector spilt(string str) { vector list; string last; auto push = [&] { list.push_back(last); last.clear(); }; for (char c: str) { if (c == ' ') { push(); } else { last.push_back(c); } } push(); return list; } \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u5728\u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7ed3\u6784\u4f53\u7684 static \u6210\u5458\u65f6\uff1a struct Class { static int member; }; \u4f1a\u62a5\u9519 undefined reference to 'Class::member' \u3002\u8fd9\u662f\u8bf4\u7684\u4f60\u9700\u8981\u627e\u4e2a .cpp \u6587\u4ef6\uff0c\u5199\u51fa int Class::member \u624d\u80fd\u6d88\u9664\u8be5\u9519\u8bef\u3002 C++17 \u4e2d\uff0c\u53ea\u9700\u52a0\u4e2a inline \u5c31\u80fd\u89e3\u51b3\uff01 struct Class { inline static int member; }; \u522b\u518d make_pair \u5566\uff01 map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u4e3a\u907f\u514d\u5199\u51fa\u7c7b\u578b\u540d\u7684\u9ebb\u70e6\uff0c\u5f88\u591a\u8001\u5e08\u90fd\u4f1a\u8ba9\u4f60\u5199 make_pair\uff1a map table; table.insert(make_pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u7136\u800c C++11 \u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u5199\u6cd5\uff0c\u90a3\u5c31\u662f\u901a\u8fc7 {} \u9690\u5f0f\u6784\u9020\uff0c\u4e0d\u7528\u5199\u51fa\u7c7b\u578b\u540d\u6216 make_pair\uff1a map table; table.insert({\"\u4faf\u6377\u8001\u5e08\", 42}); \u5373\u4f7f\u4f60\u51fa\u4e8e\u67d0\u79cd\u201c\u6296m\u201d\u60c5\u8282\uff0c\u8fd8\u60f3\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u4e5f\u53ef\u4ee5\u7528 C++17 \u7684 CTAD \u8bed\u6cd5\uff0c\u514d\u53bb\u6a21\u677f\u53c2\u6570\uff1a map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); // tuple \u4e5f\u652f\u6301 CTAD\uff1a auto t = tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); // \u7b49\u4ef7\u4e8e\uff1a auto t = make_tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); println(\"{}\", typeid(t).name()); // tuple insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 map table; table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 24}); table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 42}); \u8fd9\u65f6\uff0c table[\"\u5c0f\u5f6d\u8001\u5e08\"] \u4ecd\u7136\u4f1a\u662f 24\uff0c\u800c\u4e0d\u662f 42\u3002\u56e0\u4e3a insert \u4e0d\u4f1a\u66ff\u6362 map \u91cc\u5df2\u7ecf\u5b58\u5728\u7684\u503c\u3002 \u5982\u679c\u5e0c\u671b\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u65f6\uff0c\u66ff\u6362\u73b0\u6709\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 [] \u8fd0\u7b97\u7b26\uff1a map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 42; C++17 \u63d0\u4f9b\u4e86\u6bd4 [] \u8fd0\u7b97\u7b26\u66f4\u9002\u5408\u8986\u76d6\u6027\u63d2\u5165\u7684 insert_or_assign \u51fd\u6570\uff1a map table; table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 24); table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 42); \u597d\u5904\uff1a insert_or_assign \u4e0d\u9700\u8981\u503c\u7c7b\u578b\u652f\u6301\u9ed8\u8ba4\u6784\u9020\uff0c\u53ef\u4ee5\u907f\u514d\u4e00\u6b21\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 + \u4e00\u6b21\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u7684\u5f00\u9500\u3002 \u5efa\u8bae\u628a insert_or_assign \u6539\u540d\u6210 set \uff0c at \u6539\u540d\u6210 get \uff1b\u53ea\u662f\u7531\u4e8e\u5386\u53f2\u539f\u56e0\u540d\u5b57\u8ff7\u60d1\u4e86\u3002 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f map table; for (auto it = table.begin(); it != table.end(); ++it) { if (it->second < 0) { table.erase(it); } } \u4f1a\u53d1\u751f\u5d29\u6e83\uff01\u770b\u6765 map \u4f3c\u4e4e\u4e0d\u5141\u8bb8\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u5220\u9664\uff1f\u4e0d\uff0c\u53ea\u662f\u4f60\u7684\u5199\u6cd5\u6709\u9519\u8bef\uff1a map table; for (auto it = table.begin(); it != table.end(); ) { if (it->second < 0) { it = table.erase(it); } else { ++it; } } C++20 \u5f15\u5165\u4e86\u66f4\u597d\u7684 erase_if \u5168\u5c40\u51fd\u6570\uff0c\u4e0d\u7528\u624b\u5199\u4e0a\u9762\u8fd9\u4e48\u9ebb\u70e6\u7684\u4ee3\u7801\uff1a map table; erase_if(table, [](pair it) { return it.second < 0; }); \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 vector v = {48, 23, 76, 11, 88, 63, 45, 28, 59}; \u4f17\u6240\u5468\u77e5\uff0c\u5728 vector \u4e2d\u5220\u9664\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u5341\u5206\u4f4e\u6548\u3002\u590d\u6742\u5ea6\uff1a O(n) O(n) // \u76f4\u63a5\u5220\u9664 v[3] v.erase(v.begin() + 3); \u5982\u679c\u4e0d\u5728\u4e4e\u5143\u7d20\u7684\u987a\u5e8f\uff0c\u53ef\u4ee5\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20 swap\uff0c\u7136\u540e pop_back\u3002\u590d\u6742\u5ea6\uff1a O(1) O(1) // \u628a v[3] \u548c v[v.size() - 1] \u4f4d\u7f6e\u5bf9\u8c03 swap(v[3], v[v.size() - 1]); // \u7136\u540e\u5220\u9664 v[v.size() - 1] v.pop_back(); \u8fd9\u6837\u5c31\u4e0d\u7528\u79fb\u52a8\u4e00\u5927\u5806\u5143\u7d20\u4e86\u3002\u8fd9\u88ab\u79f0\u4e3a back-swap-erase\u3002 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 vector \u4e2d\u53ea\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u9700\u8981 O(n) O(n) \u3002\u5982\u679c\u4e00\u8fb9\u904d\u5386\uff0c\u4e00\u8fb9\u5220\u9664\u591a\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u590d\u6742\u5ea6 O(n^2) O(n^2) \u4e86\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 remove \u548c remove_if \u51fd\u6570\uff0c\u5176\u5185\u90e8\u91c7\u7528\u7c7b\u4f3c back-swap-erase \u7684\u65b9\u6cd5\uff0c\u5148\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u79fb\u52a8\u5230\u672b\u5c3e\u3002\u7136\u540e\u4e00\u6b21\u6027 erase \u6389\u672b\u5c3e\u540c\u6837\u6570\u91cf\u7684\u5143\u7d20\u3002 \u4e14\u4ed6\u4eec\u90fd\u80fd\u4fdd\u6301\u987a\u5e8f\u4e0d\u53d8\u3002 \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove(v.begin(), v.end(), 42), v.end()); \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove_if(v.begin(), v.end(), [](int x) { return x > 0; }), v.end()); \u73b0\u5728 C++20 \u4e5f\u5f15\u5165\u4e86\u5168\u5c40\u51fd\u6570 erase \u548c erase_if\uff0c\u4f7f\u7528\u8d77\u6765\u66f4\u52a0\u76f4\u89c2\uff1a vector v; erase(v, 42); // \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20 erase_if(v, [](int x) { return x > 0; // \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20 }); \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 \u5982\u679c\u4f60\u60f3\u8981\u7ef4\u62a4\u4e00\u4e2a\u6709\u5e8f\u7684\u6570\u7ec4\uff0c\u7528 lower_bound \u6216 upper_bound \u6765\u63d2\u5165\u5143\u7d20\uff0c\u4fdd\u8bc1\u63d2\u5165\u540e\u4ecd\u4fdd\u6301\u6709\u5e8f\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 3), 3); // s = { 1, 2, 3, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 5), 5); // s = { 1, 2, 3, 4, 5, 6 } \u6709\u5e8f\u6570\u7ec4\u4e2d\uff0c\u53ef\u4ee5\u5229\u7528 lower_bound \u6216 upper_bound \u5feb\u901f\u4e8c\u5206\u67e5\u627e\u5230\u60f3\u8981\u7684\u503c\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } lower_bound(s.begin(), s.end(), 3); // s.begin() + 2; lower_bound(s.begin(), s.end(), 5); // s.begin() + 3; \u6709\u5e8f vector \u5e94\u7528\u6848\u4f8b\uff1a\u5229\u7528 CDF \u79ef\u5206 + \u4e8c\u5206\u6cd5\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u4efb\u610f\u6307\u5b9a\u5206\u5e03\u7684\u968f\u673a\u6570\u3002 \u4f8b\u5982\u6570\u503c\u7b56\u5212\u8981\u6c42\u7684\u62bd\u5361\u6982\u7387\u5206\u5e03\u662f\uff1a 2% \u51fa\u91d1\u5361 10% \u51fa\u84dd\u5361 80% \u51fa\u767d\u5361 8% \u51fa\u7b54\u8fa9 \u90a3\u4e48\u4f60\u8f6c\u6362\u4e00\u4e0b\u4efb\u52a1\u3002\u53d8\u6210\u968f\u673a\u751f\u6210\u4e00\u4e2a 0 \u5230 1 \u7684\u6d6e\u70b9\u6570\uff0c\u7136\u540e\u5224\u65ad\uff1a \u5c0f\u4e8e 0.02 \u65f6\uff0c\u51fa\u91d1\u5361 \u5c0f\u4e8e 0.12 \u65f6\uff0c\u51fa\u84dd\u5361 \u5c0f\u4e8e 0.92 \u65f6\uff0c\u51fa\u767d\u5361 \u5c0f\u4e8e 1.00 \u65f6\uff0c\u51fa\u7b54\u8fa9 \u8fd9\u4e2a\u8f6c\u6362\u8fc7\u7a0b\u5c31\u662f CDF \u79ef\u5206\u3002\u5982\u679c\u4f60\u628a\u8fd9 4 \u4e2a\u6570\u6309\u7167\u987a\u5e8f\u6392\u5217\uff0c\u5c31\u662f\u4e00\u4e2a\u6709\u5e8f vector\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::partial_sum \uff08\u4e0d\u7cbe\u51c6\uff09\u6216 std::inclusive_scan \uff08\u66f4\u7cbe\u51c6\uff0cC++17 \u5f15\u5165\uff09\u90fd\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684 CDF \u79bb\u6563\u79ef\u5206\u3002 vector probs = {0.02, 0.1, 0.8, 0.08}; vector cdf; // \u8ba1\u7b97 probs \u7684 CDF \u79ef\u5206\uff0c\u5b58\u5165 cdf \u6570\u7ec4 std::inclusive_scan(probs.begin(), probs.end(), std::back_inserter(cdf)); // cdf = {0.02, 0.12, 0.92, 1.00} \u662f\u4e00\u4e2a\u6709\u5e8f vector\uff0c\u53ef\u4ee5\u8fd0\u7528\u4e8c\u5206\u6cd5\u5b9a\u4f4d vector result = {\"\u91d1\u5361\", \"\u84dd\u5361\", \"\u767d\u5361\", \"\u7b54\u8fa9\"}; // \u751f\u6210 100 \u4e2a\u968f\u673a\u6570\uff1a for (int i = 0; i < 100; ++i) { double r = rand() / (RAND_MAX + 1.0); int index = lower_bound(cdf.begin(), cdf.end(), r) - cdf.begin(); cout << \"\u4f60\u62bd\u5230\u4e86\" << result[index] << endl; } \u987a\u4fbf\u4e00\u63d0\uff0cCDF \u79ef\u5206\u7684\u9006\u8fd0\u7b97\u662f\u79bb\u6563\u5fae\u5206\uff1a std::adjacent_difference \uff0c\u53ef\u4ee5\u4ece cdf \u6570\u7ec4\u590d\u539f\u51fa probs \u6570\u7ec4\u3002 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f // \u9519\u8bef\u7684\u5199\u6cd5\uff1a int r = rand() % 10; // \u8fd9\u6837\u5199\u662f\u9519\u8bef\u7684\uff01 rand() \u7684\u8fd4\u56de\u503c\u8303\u56f4\u662f [0, RAND_MAX]\uff0cRAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0b\u4e0d\u540c\uff0c\u5728 Windows \u5e73\u53f0\u7684\u662f 32767\uff0c\u5373 rand() \u53ea\u80fd\u751f\u6210 0\uff5e32767 \u4e4b\u95f4\u7684\u968f\u673a\u6570\u3002 \u5982\u679c\u60f3\u8981\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\uff1a int r = rand() % 10; \u7136\u800c\u8fd9\u79cd\u65b9\u6cd5\u6709\u4e2a\u81f4\u547d\u7684\u95ee\u9898\uff1a\u4e0d\u540c\u7684\u968f\u673a\u6570\u751f\u6210\u6982\u7387\u4e0d\u4e00\u6837\u3002 \u4f8b\u5982\u628a [0, RAND_MAX] \u5747\u5300\u5730\u5206\u6210 10 \u4efd\uff0c\u6bcf\u4efd 3276.7\u3002\u90a3\u4e48 0\uff5e6 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 10.0003%\uff0c\u800c 7\uff5e9 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 9.997%\u3002 \u8fd9\u6837\u5c31\u4e0d\u662f\u771f\u6b63\u7684\u5747\u5300\u5206\u5e03\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u786e\u6027\u3002 \u5f53\u6a21\u6570\u5927\u7684\u65f6\u5019\u4e0d\u5747\u5300\u6027\u4f1a\u53d8\u5f97\u7279\u522b\u660e\u663e\uff0c\u4f8b\u5982 rand() % 10000 \u3002 RAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0d\u540c\u7684\u7279\u6027\u4e5f\u8ba9\u8de8\u5e73\u53f0\u5f00\u53d1\u8005\u5f88\u5934\u5927\u3002 rand \u4f7f\u7528\u5168\u5c40\u53d8\u91cf\u5b58\u50a8\u79cd\u5b50\uff0c\u5bf9\u591a\u7ebf\u7a0b\u4e0d\u53cb\u597d\u3002 \u65e0\u6cd5\u72ec\u7acb\u7684\u4e3a\u591a\u4e2a\u751f\u6210\u5e8f\u5217\u8bbe\u5b9a\u72ec\u7acb\u7684\u79cd\u5b50\uff0c\u4e00\u4e9b\u6e38\u620f\u53ef\u80fd\u9700\u8981\u7528\u5230\u591a\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u5404\u81ea\u6709\u72ec\u7acb\u7684\u79cd\u5b50\u3002 \u53ea\u80fd\u751f\u6210\u5747\u5300\u5206\u5e03\u7684\u6574\u6570\uff0c\u4e0d\u80fd\u751f\u6210\u5e42\u7387\u5206\u5e03\u3001\u6b63\u592a\u5206\u5e03\u7b49\uff0c\u751f\u6210\u6d6e\u70b9\u6570\u4e5f\u6bd4\u8f83\u9ebb\u70e6\u3002 \u4f7f\u7528 srand(time(NULL)) \u65e0\u6cd5\u5b89\u5168\u5730\u751f\u6210\u968f\u673a\u6570\u7684\u521d\u59cb\u79cd\u5b50\uff0c\u5bb9\u6613\u88ab\u9ed1\u5ba2\u9884\u6d4b\u5e76\u653b\u51fb\u3002 rand \u7684\u7b97\u6cd5\u5b9e\u73b0\u6ca1\u6709\u5b98\u65b9\u89c4\u5b9a\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u5404\u6709\u4e0d\u540c\uff0c\u4ea7\u751f\u7684\u968f\u673a\u6570\u5e8f\u5217\u53ef\u80fd\u4e0d\u540c\u3002 \u4e3a\u6b64\uff0cC++ \u63d0\u51fa\u4e86\u66f4\u52a0\u4e13\u4e1a\u7684\u968f\u673a\u6570\u751f\u6210\u5668\uff1a \u5e93\u3002 // \u4f7f\u7528 \u5e93\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff1a #include #include int main() { uint64_t seed = std::random_device()(); std::mt19937 gen(seed); std::uniform_int_distribution dis(0, 9); for (int i = 0; i < 100; ++i) { int r = dis(gen); std::cout << r << \" \"; } } \u8fd9\u6837\u5c31\u53ef\u4ee5\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u4e86\u3002 std::random_device \u662f\u4e00\u4e2a\u968f\u673a\u6570\u79cd\u5b50\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u7cfb\u7edf\u7684\u968f\u673a\u8bbe\u5907\uff08\u5982\u679c\u6709\u7684\u8bdd\uff0c\u5426\u5219\u4f1a\u629b\u51fa\u5f02\u5e38\uff09\u751f\u6210\u4e00\u4e2a\u5b89\u5168\u7684\u968f\u673a\u6570\u79cd\u5b50\uff0c\u9ed1\u5ba2\u65e0\u6cd5\u9884\u6d4b\u3002 std::mt19937 \u662f\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u521d\u59cb\u79cd\u5b50\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u5e8f\u5217\u3002\u5e76\u4e14\u5fc5\u5b9a\u662f MT19937 \u8fd9\u4e2a\u9ad8\u5f3a\u5ea6\u7684\u968f\u673a\u7b97\u6cd5\uff0c\u6240\u6709\u5e73\u53f0\u90fd\u4e00\u6837\u3002 std::uniform_int_distribution \u662f\u4e00\u4e2a\u5206\u5e03\u5668\uff0c\u5b83\u53ef\u4ee5\u628a\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u6620\u5c04\u5230\u6211\u4eec\u60f3\u8981\u7684\u4e0a\u4e0b\u754c\u4e2d\u3002\u91cc\u9762\u7684\u5b9e\u73b0\u7c7b\u4f3c\u4e8e gen() % 10 \uff0c\u4f46\u901a\u8fc7\u6570\u5b66\u673a\u5236\u4fdd\u8bc1\u4e86\u7edd\u5bf9\u5747\u5300\u6027\u3002 \u7c7b\u4f3c\u7684\u8fd8\u6709 std::uniform_real_distribution \u7528\u4e8e\u751f\u6210\u6d6e\u70b9\u6570\uff0c std::normal_distribution \u7528\u4e8e\u751f\u6210\u6b63\u592a\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c std::poisson_distribution \u7528\u4e8e\u751f\u6210\u6cca\u677e\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u7b49\u7b49\u3002 \u5982\u679c\u559c\u6b22\u8001\u5f0f\u7684\u51fd\u6570\u8c03\u7528\u98ce\u683c\u63a5\u53e3\uff0c\u53ef\u4ee5\u5c01\u88c5\u4e00\u4e2a\u65b0\u7684 C++ \u91cd\u7f6e\u7248\u5b89\u5168 rand \uff1a thread_local std::mt19937 gen(std::random_device{}()); // \u6bcf\u7ebf\u7a0b\u4e00\u4e2a\uff0c\u4e92\u4e0d\u51b2\u7a81 int randint(int min, int max) { return std::uniform_int_distribution(min, max)(gen); } float randfloat(float min, float max) { return std::uniform_real_distribution(min, max)(gen); } const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u4f17\u6240\u5468\u77e5\uff0c const \u5728\u6307\u9488\u7b26\u53f7 * \u7684\u524d\u540e\uff0c\u6548\u679c\u662f\u4e0d\u540c\u7684\u3002 const int *p; int *const p; \u4f60\u80fd\u770b\u51fa\u6765\u4e0a\u9762\u8fd9\u4e2a const \u5206\u522b\u4fee\u9970\u7684\u662f\u8c01\u5417\uff1f const int *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u4e3a\u4e86\u770b\u8d77\u6765\u66f4\u52a0\u660e\u786e\uff0c\u6211\u901a\u5e38\u90fd\u4f1a\u540e\u7f6e\u6240\u6709\u7684 const \u4fee\u9970\u3002 int const *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\uff0cconst \u603b\u662f\u5728\u4fee\u9970\u4ed6\u524d\u9762\u7684\u4e1c\u897f\uff0c\u800c\u4e0d\u662f\u540e\u9762\u3002 \u4e3a\u4ec0\u4e48 int *const \u4fee\u9970\u7684\u662f int * \u4e5f\u5c31\u5f88\u5bb9\u6613\u7406\u89e3\u4e86\u3002 int const i; int const *p; int *const q; int const &r; \u4e3e\u4e2a\u4f8b\u5b50\uff1a int i, j; int *const p = &i; *p = 1; // OK\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int i, j; int const *p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // OK\uff1ap \u672c\u8eab\u53ef\u53d8\uff0c\u53ef\u4ee5\u6539\u53d8\u6307\u5411 int i, j; int const *const p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e5f\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int const * \u548c const int * \u7b49\u4ef7\uff01\u53ea\u6709 int *const \u662f\u4e0d\u540c\u7684\u3002 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u5927\u5bb6\u90fd\u77e5\u9053\uff0c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u58f0\u660e\u4e3a auto \uff0c\u8ba9\u5176\u81ea\u52a8\u63a8\u5bfc\u3002 auto square() { // int square(); return 1; } \u4f46\u4f60\u77e5\u9053\u4ece C++20 \u5f00\u59cb\uff0c\u53c2\u6570\u4e5f\u53ef\u4ee5\u58f0\u660e\u4e3a auto \u4e86\u5417\uff1f auto square(auto x) { // T square(T x); return x * x; } square(1); // square(int) square(3.14); // square(double) \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u201c\u6a21\u677f\u51fd\u6570\u201d\u7684\u4f20\u7edf\u5199\u6cd5\uff1a template T square(T x) { return x * x; } square(1); // square(int) square(3.14); // square(double) \u56e0\u4e3a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6240\u4ee5\u4e5f\u5f88\u96be\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u7684\u60c5\u51b5\u3002 auto \u53c2\u6570\u8fd8\u53ef\u4ee5\u5e26\u6709\u5f15\u7528\uff1a auto square(auto const &x) { // T square(T const &x); return x * x; } square(1); // square(int const &) square(3.14); // square(double const &) \u7b49\u4ef7\u4e8e\uff1a template T square(T const &x) { return x * x; } auto \u53c2\u6570\u6700\u597d\u7684\u914d\u5408\u83ab\u8fc7\u4e8e\u662f\u4e0e\u540c\u6837 C++20 \u5f15\u5165\u7684 concept\uff1a auto square(std::integral auto x) { // T square(T x) requires std::integral return x * x; } square(1); // square(int) square(3.14); // \u9519\u8bef\uff1adouble \u4e0d\u662f\u6574\u6570\u7c7b\u578b \u7b49\u4ef7\u4e8e\uff1a template requires std::integral T square(T x) { return x * x; } \u6216\u8005\uff1a template T square(T x) { return x * x; } \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 std::string file_get_content(std::string const &filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); std::istreambuf_iterator iit(ifs), iite; std::string content(iit, iite); return content; } void file_put_content(std::string const &filename, std::string const &content) { std::ofstream ofs(filename, std::ios::out | std::ios::binary); ofs << content; } \u8fd9\u6837\u5c31\u53ef\u4ee5\u628a\u6574\u4e2a\u6587\u4ef6\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u5f88\u65b9\u4fbf\u5730\u8fdb\u884c\u5904\u7406\u540e\u518d\u5199\u56de\u6587\u4ef6\u3002 \u63a8\u8350\u7528 std::ios::binary \u9009\u9879\u6253\u5f00\u4e8c\u8fdb\u5236\u6587\u4ef6\uff0c\u5426\u5219\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0 '\\n' \u65f6\uff0c\u4f1a\u88ab MSVC \u6807\u51c6\u5e93\u81ea\u52a8\u8f6c\u6362\u6210 '\\r\\n' \u6765\u5199\u5165\uff0c\u59a8\u788d\u6211\u4eec\u8de8\u5e73\u53f0\u3002 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 std::ifstream fin(\"test.txt\"); std::string line; while (std::getline(fin, line)) { std::cout << \"\u8bfb\u53d6\u5230\u4e00\u884c\uff1a\" << line << '\\n'; } \u5b57\u7b26\u4e32\u5207\u7247 #include #include #include std::vector split_str(std::string const &str, char ch) { std::stringstream ss(str); std::string line; std::vector res; while (std::getline(ss, line, ch)) { res.push_back(std::move(line)); } return res; } auto res = split_str(\"hello world\", ' '); // res = {\"hello\", \"world\"} cout \u4e0d\u9700\u8981 endl int a = 42; printf(\"%d\\n\", a); \u4e07\u4e00\u4f60\u5199\u9519\u4e86 % \u540e\u9762\u7684\u7c7b\u578b\uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u7559\u4e0b\u9690\u60a3\u3002 int a = 42; printf(\"%s\\n\", a); // \u7f16\u8bd1\u5668\u4e0d\u62a5\u9519\uff0c\u4f46\u662f\u8fd0\u884c\u65f6\u4f1a\u5d29\u6e83\uff01 C++ \u4e2d\u6709\u66f4\u5b89\u5168\u7684\u8f93\u51fa\u65b9\u5f0f cout \uff0c\u901a\u8fc7 C++ \u7684\u91cd\u8f7d\u673a\u5236\uff0c\u65e0\u9700\u624b\u52a8\u6307\u5b9a % \uff0c\u81ea\u52a8\u5c31\u80fd\u63a8\u5bfc\u7c7b\u578b\u3002 int a = 42; cout << a << endl; double d = 3.14; cout << d << endl; cout << \"Hello, World!\" << endl; endl \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6d41\u64cd\u4f5c\u7b26\uff0c\u4f5c\u7528\u7b49\u4ef7\u4e8e\u5148\u8f93\u51fa\u4e00\u4e2a '\\n' \u7136\u540e flush \u3002 cout << \"Hello, World!\" << '\\n'; cout.flush(); \u4f46\u5b9e\u9645\u4e0a\uff0c\u8f93\u51fa\u6d41 cout \u9ed8\u8ba4\u7684\u8bbe\u7f6e\u5c31\u662f\u201c\u884c\u5237\u65b0\u7f13\u5b58\u201d\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u68c0\u6d4b\u5230 '\\n' \u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u5237\u65b0\u4e00\u6b21\uff0c\u6839\u672c\u4e0d\u9700\u8981\u6211\u4eec\u624b\u52a8\u5237\u65b0\uff01 \u5982\u679c\u8fd8\u7528 endl \u7684\u8bdd\uff0c\u5c31\u76f8\u5f53\u4e8e\u5237\u65b0\u4e86\u4e24\u6b21\uff0c\u6d6a\u8d39\u6027\u80fd\u3002 \u53ef\u89c1\uff0cendl \u662f\u4e00\u4e2a\u88ab\u5f88\u591a\u65e0\u8111\u6559\u6750\u9519\u8bef\u5ba3\u4f20\uff0c\u5b9e\u9645\u4e0a\u6839\u672c\u591a\u6b64\u4e00\u4e3e\u7684\u4e1c\u897f\u3002 \u6211\u4eec\u53ea\u9700\u8981\u8f93\u51fa '\\n' \u5c31\u53ef\u4ee5\u4e86\uff0c\u6bcf\u6b21\u6362\u884c\u65f6 cout \u90fd\u4f1a\u81ea\u52a8\u5237\u65b0\u3002 cout << \"Hello, World!\" << '\\n'; endl \u662f\u4e00\u4e2a\u5178\u578b\u7684\u4ee5\u8bb9\u4f20\u8bb9\u9519\u8bef\u5199\u6cd5\uff0c\u53ea\u6709\u5f53\u4f60\u7684\u8f93\u51fa\u662f\u6307\u5411\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u7ba1\u9053\u65f6\uff0c\u5176\u9644\u5e26\u7684\u5237\u65b0\u529f\u80fd\u624d\u6709\u4f5c\u7528\u3002 \u5f53\u8f93\u51fa\u662f\u7ba1\u9053\u6216\u6587\u4ef6\u65f6\uff0c cout \u9700\u8981 endl \u624d\u80fd\u5237\u65b0\u3002 \u5f53\u8f93\u51fa\u662f\u666e\u901a\u63a7\u5236\u53f0\u65f6\uff0c cout \u53ea\u9700 '\\n' \u5c31\u80fd\u5237\u65b0\u4e86\uff0c\u6839\u672c\u7528\u4e0d\u7740 endl \u3002 \u800c\u4e14\uff0c\u7ba1\u9053\u6216\u6587\u4ef6\u5b9e\u9645\u4e0a\u4e5f\u4e0d\u5b58\u5728\u9891\u7e41\u5237\u65b0\u7684\u9700\u6c42\uff0c\u53cd\u6b63 ifstream \u6790\u6784\u65f6\u603b\u662f\u4f1a\u81ea\u52a8\u5237\u65b0\u5199\u5165\u78c1\u76d8\u3002 \u56e0\u6b64\uff0c endl \u64cd\u7eb5\u7b26\u5927\u591a\u65f6\u5019\u90fd\u662f\u5197\u4f59\u7684\uff1a\u63a7\u5236\u53f0\u8f93\u51fa\u7684 cout \u53ea\u9700\u8981\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u4e2d\u542b\u6709 '\\n' \u5c31\u5237\u65b0\u4e86\uff0c\u5373\u4f7f\u662f\u6587\u4ef6\u8bfb\u5199\u4e5f\u5f88\u5c11\u4f1a\u4f7f\u7528 endl \u3002 \u5982\u679c\u786e\u5b9e\u9700\u8981\u5f3a\u5236\u5237\u65b0\uff0c\u4e5f\u53ef\u4ee5\u7528 flush \u8fd9\u79cd\u66f4\u52a0\u53ef\u8bfb\u7684\u5199\u6cd5\uff1a int num; cout << \"please input the number: \" << flush; cin >> num; ofstream fout(\"log.txt\"); fout << \"immediate write 1\\n\" << flush; sleep(1); fout << \"immediate write 2\\n\" << flush; fout.close(); // \u5173\u95ed\u6587\u4ef6\u65f6\u603b\u662f\u81ea\u52a8 flush\uff0c\u4e0d\u4f1a\u6709\u6b8b\u7559\u672a\u5199\u5165\u7684\u5b57\u7b26 \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f \u540c\u5b66\uff1a\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u4f7f\u7528\uff1a cout << \"the answer is \" << 42 << '\\n'; \u53d1\u73b0\u8f93\u51fa\u4e71\u5957\u4e86\uff01\u8fd9\u662f\u4e0d\u662f\u8bf4\u660e cout \u4e0d\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\u5462\uff1f \u5c0f\u5f6d\u8001\u5e08\uff1acout \u662f\u4e00\u4e2a\u201c\u540c\u6b65\u6d41\u201d\uff0c\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\uff0c\u9519\u8bef\u7684\u662f\u4f60\u7684\u4f7f\u7528\u65b9\u5f0f\u3002 \u5982\u679c\u4ed6\u4e0d\u591a\u7ebf\u7a0b\u5b89\u5168\uff0c\u90a3\u591a\u7ebf\u7a0b\u5730\u8c03\u7528\u4ed6\u5c31\u4e0d\u662f\u8f93\u51fa\u4e71\u5e8f\uff0c\u800c\u662f\u7a0b\u5e8f\u5d29\u6e83\u4e86\u3002 \u4f46\u662f\uff0ccout \u7684\u7ebf\u7a0b\u5b89\u5168\uff0c\u53ea\u80fd\u4fdd\u8bc1\u6bcf\u4e00\u6b21 operator<< \u90fd\u662f\u539f\u5b50\u7684\uff0c\u6bcf\u4e00\u6b21\u5355\u72ec\u7684 operator<< \u4e0d\u4f1a\u88ab\u5176\u4ed6\u4eba\u6253\u65ad\u3002 \u4f46\u4f17\u6240\u5468\u77e5\uff0ccout \u4e3a\u4e86\u652f\u6301\u7ea7\u8054\u8c03\u7528\uff0c\u4ed6\u7684 operator<< \u90fd\u662f\u8fd4\u56de\u81ea\u5df1\u7684\uff0c\u4e0a\u9762\u7684\u4ee3\u7801\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5206\u522b\u4e09\u6b21\u8c03\u7528 cout \u7684 operator<< \u3002 cout << \"the answer is \" << 42 << '\\n'; // \u7b49\u4ef7\u4e8e\uff1a cout << \"the answer is \"; cout << 42; cout << '\\n'; \u53d8\u6210\u4e86\u4e09\u6b21 operator<< \uff0c\u6bcf\u4e00\u6b21\u90fd\u662f\u201c\u5404\u81ea\u201d\u539f\u5b50\u7684\uff0c\u4f46\u4e09\u4e2a\u539f\u5b50\u52a0\u5728\u4e00\u8d77\u5c31\u4e0d\u662f\u539f\u5b50\u4e86\u3002 \u800c\u662f\u5206\u5b50\u4e86 :) \u4ed6\u4eec\u4e2d\u95f4\u53ef\u80fd\u7a7f\u63d2\u4e86\u5176\u4ed6\u7ebf\u7a0b\u7684 cout\uff0c\u4ece\u800c\u5bfc\u81f4\u4f60 \"the answer is\" \u6253\u5370\u5b8c\u540e\uff0c\u88ab\u5176\u4ed6\u7ebf\u7a0b\u7684 '\\n' \u63d2\u5165\u8fdb\u6765\uff0c\u5bfc\u81f4\u6362\u884c\u6df7\u4e71\u3002 std::cout \u7684 operator<< \u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u4e0d\u4f1a\u88ab\u6253\u65ad\uff0c\u4f46\u591a\u4e2a operator<< \u7684\u8c03\u7528\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u53ef\u80fd\u4f1a \u4ea4\u9519 \uff0c\u5bfc\u81f4\u8f93\u51fa\u7ed3\u679c\u6df7\u4e71\u3002 \u66f4\u591a\u7ec6\u8282\u8bf7\u770b\u6211\u4eec\u7684 \u591a\u7ebf\u7a0b\u4e13\u9898 \u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\uff0c\u5148\u521b\u5efa\u4e00\u4e2a\u53ea\u5c5e\u4e8e\u5f53\u524d\u7ebf\u7a0b\u7684 ostringstream \uff0c\u6700\u540e\u4e00\u6b21\u6027\u8c03\u7528\u4e00\u6b21 cout \u7684 operator<< \uff0c\u8ba9\u201c\u539f\u5b50\u201d\u7684\u5355\u4f4d\u53d8\u6210\u201c\u4e00\u884c\u201d\u800c\u4e0d\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 ostringstream oss; oss << \"the answer is \" << 42 << '\\n'; cout << oss.str(); \u6216\u8005\uff0c\u4f7f\u7528 std::format \uff1a cout << std::format(\"the answer is {}\\n\", 42); \u603b\u4e4b\uff0c\u5c31\u662f\u8981\u8ba9 operator<< \u53ea\u6709\u4e00\u6b21\uff0c\u81ea\u7136\u5c31\u662f\u6ca1\u6709\u4ea4\u9519\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u6539\u7528 std::osyncstream(std::cout) \u4ee3\u66ff std::cout : std::osyncstream(std::cout) << \"the answer is \" << 42 << '\\n'; std::osyncstream \u53ef\u4ee5\u4fdd\u8bc1\uff1a1. \u4e0d\u4f1a\u4ea7\u751f\u6570\u636e\u7ade\u4e89\uff1b2. \u4e0d\u4f1a\u53d1\u751f\u7a7f\u63d2\u548c\u622a\u65ad\u3002\u53ef\u4ee5\u7406\u89e3\u4e3a std::osyncstream \u5728\u6784\u9020\u65f6\u5bf9\u7f13\u51b2\u533a\u4e0a\u9501\uff0c\u5728\u6790\u6784\u65f6\u89e3\u9501\u3002 \u5982\u679c\u4f60\u7684\u6807\u51c6\u5e93\u652f\u6301 C++23\uff0c\u8fd8\u53ef\u4ee5\u7528 std::println \uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8f93\u51fa\u4e5f\u662f\u539f\u5b50\u7684\uff08\u7b2c\u4e09\u65b9\u5e93\u5982 fmt::println \u4ea6\u53ef\uff09\uff1a std::println(\"the answer is {}\", 42); cerr \u4e0e cout \u7684\u6289\u62e9 \u5982\u679c\u4f60\u7684\u76ee\u7684\u662f\u8c03\u8bd5\u548c\u62a5\u9519\uff0c\u53ef\u4ee5\u8003\u8651\u7528 cerr \uff01 \u4ed6\u4f1a\u5728\u6bcf\u6b21 << \u65f6\u5237\u65b0\uff0c cerr \u624d\u662f\u6700\u9002\u5408\u6253\u5370\u9519\u8bef\u548c\u8c03\u8bd5\u4fe1\u606f\u7684\u6d41\u3002 cout \u7684\u4f18\u70b9\u662f\u4e0d\u9700\u8981\u65f6\u523b\u5237\u65b0\uff0c\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 cout << \"hello\\n\"; cout << \"the answer is \"; cout << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cout << \"!\\n\"; // \u56e0\u4e3a\u8fd8\u6ca1\u6709\u62b5\u8fbe \\n \u4ea7\u751f\u5237\u65b0\u5c31\u5d29\u6e83\uff0c\u5bfc\u81f4\u4e4b\u524d\u5c1a\u672a\u5237\u65b0\u7684 the answer is 42 \u4e22\u5931 \u53ef\u80fd\u7684\u8f93\u51fa\uff1a hello[\u6362\u884c] cerr << \"hello\\n\"; cerr << \"the answer is \"; cerr << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cerr << \"!\\n\"; \u8f93\u51fa\uff1a hello[\u6362\u884c] the answer is 42 \u8fd8\u6709\u4e00\u4e2a\u7279\u70b9\uff1a cout \u8f93\u51fa\u5230\u201c\u6807\u51c6\u8f93\u51fa\u6d41\u201d\uff0c\u53ef\u4ee5\u88ab\u8f93\u51fa\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u7ba1\u9053\u3002\u800c cerr \u8f93\u51fa\u5230\u201c\u6807\u51c6\u9519\u8bef\u6d41\u201d\uff0c\u901a\u5e38\u4e0d\u4f1a\u88ab\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u6216\u7ba1\u9053\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u628a\u7a0b\u5e8f\u9884\u8ba2\u7684\u8ba1\u7b97\u7ed3\u679c\u5199\u5230 cout \uff0c\u628a\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5199\u5230 cerr \uff0c\u8fd9\u6837\u7528\u6237\u5c31\u53ef\u4ee5\u901a\u8fc7 > \u91cd\u5b9a\u5411\u8ba1\u7b97\u7ed3\u679c\uff0c\u800c\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5219\u6b63\u5e38\u8f93\u51fa\u5230\u5c4f\u5e55\u4e0a\uff0c\u4e0d\u53d7\u91cd\u5b9a\u5411\u5f71\u54cd\u3002 cout << \"1 3 5 7\\n\"; cerr << \"ERROR: this is an error message!\\n\"; cout << \"11 13 17 19\\n\"; $ g++ prime.cpp -o prime $ ./prime 1 3 5 7 ERROR: this is an error message! 11 13 17 19 $ ./prime > output.txt ERROR: this is an error message! $ cat output.txt 1 3 5 7 11 13 17 19 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 \u6211\u4eec\u8bf4\u4e00\u4e2a\u7c7b\u578b\u5927\uff0c\u6709\u4e24\u79cd\u60c5\u51b5\u3002 \u7c7b\u672c\u8eab\u5f88\u5927\uff1a\u4f8b\u5982 array \u7c7b\u672c\u8eab\u4e0d\u5927\uff0c\u4f46\u5176\u6307\u5411\u7684\u5bf9\u8c61\u5927\uff0c\u4e14\u8be5\u7c7b\u662f\u6df1\u62f7\u8d1d\uff0c\u5bf9\u8be5\u7c7b\u7684\u62f7\u8d1d\u4f1a\u5f15\u8d77\u5176\u6307\u5411\u5bf9\u8c61\u7684\u62f7\u8d1d\uff1a\u4f8b\u5982 vector sizeof(array); // \u672c\u8eab 4000 \u5b57\u8282 sizeof(vector); // \u672c\u8eab 24 \u5b57\u8282\uff08\u6210\u5458\u662f 3 \u4e2a\u6307\u9488\uff09\uff0c\u6307\u5411\u7684\u6570\u7ec4\u53ef\u4ee5\u65e0\u9650\u589e\u5927 sizeof(vector) \u4e3a 24 \u5b57\u8282\u4ec5\u4e3a x86_64-pc-linux-gnu \u5e73\u53f0 libstdc++ \u5e93\u7684\u5b9e\u6d4b\u7ed3\u679c\uff0c\u5728 32 \u4f4d\u7cfb\u7edf\u4ee5\u53ca MSVC \u7684 Debug \u6a21\u5f0f STL \u4e0b\u53ef\u80fd\u5f97\u51fa\u4e0d\u540c\u7684\u7ed3\u679c\uff0c\u4e0d\u53ef\u4ee5\u4f9d\u8d56\u8fd9\u4e2a\u5e73\u53f0\u76f8\u5173\u7684\u7ed3\u679c\u6765\u7f16\u7a0b\u3002 \u5bf9\u4e8e vector\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 std::move \u79fb\u52a8\u8bed\u4e49\uff0c\u53ea\u62f7\u8d1d\u8be5\u7c7b\u672c\u8eab\u7684\u4e09\u4e2a\u6307\u9488\u6210\u5458\uff0c\u800c\u4e0d\u5bf9\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u6570\u7ec4\u8fdb\u884c\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e array\uff0c\u5219 std::move \u79fb\u52a8\u8bed\u4e49\u4e0e\u666e\u901a\u7684\u62f7\u8d1d\u6ca1\u6709\u533a\u522b\uff1aarray \u4f5c\u4e3a\u9759\u6001\u6570\u7ec4\u5bb9\u5668\uff0c\u4e0d\u662f\u901a\u8fc7\u201c\u6307\u9488\u6210\u5458\u201d\u6765\u4fdd\u5b58\u6570\u7ec4\u7684\uff0c\u800c\u662f\u76f4\u63a5\u628a\u6570\u7ec4\u5b58\u5728\u4ed6\u7684\u4f53\u5185\uff0c\u5bf9 array \u7684\u79fb\u52a8\u548c\u62f7\u8d1d\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff01 \u603b\u4e4b\uff0c\u79fb\u52a8\u8bed\u4e49\u7684\u52a0\u901f\u6548\u679c\uff0c\u53ea\u5bf9\u91c7\u7528\u4e86\u201c\u6307\u9488\u95f4\u63a5\u5b58\u50a8\u52a8\u6001\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08\u5982 vector\u3001map\u3001set\u3001string\uff09\u6709\u6548\u3002\u5bf9\u201c\u76f4\u63a5\u5b58\u50a8\u9759\u6001\u5927\u5c0f\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08array\u3001tuple\u3001variant\u3001\u6210\u529f\u201c\u5c0f\u5b57\u7b26\u4e32\u4f18\u5316\u201d\u7684 string\uff09\u65e0\u6548\u3002 \u6240\u4ee5\uff0c\u8ba9\u5f88\u591a\u201c\u79fb\u52a8\u8bed\u4e49\u201d\u5b5d\u5b50\u5931\u671b\u4e86\uff1a\u201c\u672c\u8eab\u5f88\u5927\u201d\u7684\u7c7b\uff0c\u79fb\u52a8\u548c\u62f7\u8d1d\u4e00\u6837\u6162\uff01 \u90a3\u4e48\u73b0\u5728\u6211\u4eec\u6709\u4e2a\u8d85\u5927\u7684\u7c7b\uff1a using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b vector arr; void func(BigType x) { arr.push_back(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } int main() { BigType x; func(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } \u5982\u4f55\u52a0\u901f\u8fd9\u79cd\u672c\u8eab\u8d85\u5927\u7684\u53d8\u91cf\u8f6c\u79fb\uff1f\u4f7f\u7528 const \u5f15\u7528\uff1a void func(BigType const &x) \u4f3c\u4e4e\u53ef\u4ee5\u907f\u514d\u4f20\u53c2\u65f6\u7684\u62f7\u8d1d\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u80fd\u907f\u514d push_back \u63a8\u5165 vector \u65f6\u6240\u4e0d\u5f97\u5df2\u7684\u62f7\u8d1d\u3002 \u5c0f\u6280\u5de7\uff1a\u6539\u7528 unique_ptr using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b using BigTypePtr = unique_ptr; vector arr; void func(BigTypePtr x) { arr.push_back(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488\uff0c\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u4e0d\u7528\u6df1\u62f7\u8d1d\u4e86\uff0c\u76f4\u63a5\u79fb\u52a8\u6240\u6709\u6743\u7ed9 vector \u91cc\u7684 BigTypePtr \u667a\u80fd\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } int main() { BigTypePtr x = make_unique(); // \u6ce8\u610f\uff1a\u7528\u667a\u80fd\u6307\u9488\u7684\u8bdd\uff0c\u9700\u8981\u7528 make_unique \u624d\u80fd\u521b\u5efa\u5bf9\u8c61\u4e86 func(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } \u4e0a\u9762\u6574\u4e2a\u7a0b\u5e8f\u4e2d\uff0c\u4e00\u5f00\u59cb\u901a\u8fc7 make_unique \u521b\u5efa\u7684\u8d85\u5927\u5bf9\u8c61\uff0c\u5168\u7a0b\u6ca1\u6709\u53d1\u751f\u4efb\u4f55\u79fb\u52a8\uff0c\u907f\u514d\u4e86\u65e0\u8c13\u7684\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u6765\u8bf4\uff0c\u4e5f\u53ef\u4ee5\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u5c31\u80fd\u5728\u51fd\u6570\u4e4b\u95f4\u7a7f\u68ad\u81ea\u5982\u4e86\u3002 // \u70ed\u77e5\u8bc6\uff1astd::mutex \u4e0d\u652f\u6301\u79fb\u52a8 void func(std::mutex lock); int main() { std::mutex lock; func(std::move(lock)); // \u9519\u8bef\uff1amutex(mutex &&) = delete } void func(std::unique_ptr lock); int main() { std::unique_ptr lock = std::make_unique(); func(std::move(lock)); // OK\uff1a\u8c03\u7528\u7684\u662f unique_ptr(unique_ptr &&)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b } \u66f4\u597d\u7684\u662f shared_ptr \uff0c\u8fde std::move \u90fd\u4e0d\u7528\u5199\uff0c\u66f4\u7701\u5fc3\u3002 void func(std::shared_ptr lock); int main() { std::shared_ptr lock = std::make_shared(); func(lock); // OK\uff1a\u8c03\u7528\u7684\u662f shared_ptr(shared_ptr const &)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b func(lock); // OK\uff1ashared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\uff0c\u5373\u4f7f\u6d45\u62f7\u8d1d\u53d1\u751f\u591a\u6b21\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4e5f\u4e0d\u4f1a\u88ab\u62f7\u8d1d\u6216\u79fb\u52a8 } optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 \u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u7c7b\uff0c\u5177\u6709\u81ea\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\uff0c\u4e14\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a struct SomeClass { int m_i; int m_j; SomeClass(int i, int j) : m_i(i), m_j(j) {} }; \u5f53\u6211\u4eec\u9700\u8981\u201c\u5ef6\u8fdf\u521d\u59cb\u5316\u201d\u65f6\u600e\u4e48\u529e\uff1f SomeClass c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c); \u53ef\u4ee5\u5229\u7528 optional \u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u201c\u7a7a\u201d\u7684\u7279\u6027\uff0c\u5b9e\u73b0\u5ef6\u8fdf\u8d4b\u503c\uff1a std::optional c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c.value()); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u5c31\u4f1a\u62a5\u9519\uff0c\u4ece\u800c\u628a\u7f16\u8bd1\u671f\u7684\u672a\u521d\u59cb\u5316\u8f6c\u6362\u4e3a\u8fd0\u884c\u65f6\u5f02\u5e38 \u5c31\u7c7b\u4f3c\u4e8e Python \u4e2d\u5148\u7ed9\u53d8\u91cf\u8d4b\u503c\u4e3a None\uff0c\u7136\u540e\u5728\u5faa\u73af\u6216 if \u91cc\u6761\u4ef6\u6027\u5730\u8d4b\u503c\u4e00\u6837\u3002 \u5982\u679c\u8981\u8fdb\u4e00\u6b65\u907f\u514d c = \u65f6\uff0c\u79fb\u52a8\u6784\u9020\u7684\u5f00\u9500\uff0c\u4e5f\u53ef\u4ee5\u7528 unique_ptr \u6216 shared_ptr \uff1a std::shared_ptr c; if (test()) { c = std::make_shared(1, 2); } else { c = std::make_shared(2, 3); } do_something(c); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u90a3\u4e48\u4f20\u5165\u7684\u5c31\u662f\u4e00\u4e2a nullptr\uff0cdo_something \u5185\u90e8\u9700\u8981\u8d1f\u8d23\u68c0\u6d4b\u6307\u9488\u662f\u5426\u4e3a nullptr \u5982\u679c do_something \u53c2\u6570\u9700\u8981\u7684\u662f\u539f\u59cb\u6307\u9488\uff0c\u53ef\u4ee5\u7528 .get() \u83b7\u53d6\u51fa\u6765\uff1a do_something(c.get()); // .get() \u53ef\u4ee5\u628a\u667a\u80fd\u6307\u9488\u8f6c\u6362\u56de\u539f\u59cb\u6307\u9488\uff0c\u4f46\u8bf7\u6ce8\u610f\u539f\u59cb\u6307\u9488\u4e0d\u6301\u6709\u5f15\u7528\uff0c\u4e0d\u4f1a\u5ef6\u4f38\u6307\u5411\u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5b9e\u9645\u4e0a\uff0cJava\u3001Python \u4e2d\u7684\u4e00\u5207\u5bf9\u8c61\uff08\u9664 int\u3001str \u7b49\u201c\u94a6\u5b9a\u201d\u7684\u57fa\u7840\u7c7b\u578b\u5916\uff09\u90fd\u662f\u5f15\u7528\u8ba1\u6570\u7684\u667a\u80fd\u6307\u9488 shared_ptr \uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u4e00\u5207\u7686\u6307\u9488\u4e86\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u597d\u50cf\u6ca1\u6709\u6307\u9488\u4e86\u3002 if-auto \u4e0e while-auto \u9700\u8981\u5148\u5b9a\u4e49\u4e00\u4e2a\u53d8\u91cf\uff0c\u7136\u540e\u5224\u65ad\u67d0\u4e9b\u6761\u4ef6\u7684\u60c5\u51b5\uff0c\u975e\u5e38\u5e38\u89c1\uff1a extern std::optional some_func(); auto opt = some_func(); if (opt.has_value()) { std::cout << opt.value(); } C++17 \u5f15\u5165\u7684 if-auto \u8bed\u6cd5\uff0c\u53ef\u4ee5\u5c31\u5730\u4e66\u5199\u53d8\u91cf\u5b9a\u4e49\u548c\u5224\u65ad\u6761\u4ef6\uff1a extern std::optional some_func(); if (auto opt = some_func(); opt.has_value()) { std::cout << opt.value(); } \u5bf9\u4e8e\u652f\u6301 (bool)opt \u7684 optional \u7c7b\u578b\u6765\u8bf4\uff0c\u540e\u9762\u7684\u6761\u4ef6\u4e5f\u53ef\u4ee5\u7701\u7565\uff1a extern std::optional some_func(); if (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a auto opt = some_func(); if (opt) { std::cout << opt.value(); } \u7c7b\u4f3c\u7684\u8fd8\u6709 while-auto\uff1a extern std::optional some_func(); while (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a while (true) { auto opt = some_func(); if (!opt) break; std::cout << opt.value(); } if-auto \u6700\u5e38\u89c1\u7684\u914d\u5408\u83ab\u8fc7\u4e8e map.find\uff1a std::map table; int key = 42; if (auto it = table.find(key); it != table.end()) { std::cout << it->second << '\\n'; } else { std::cout << \"not found\\n\"; } bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 \u4f17\u6240\u5468\u77e5\uff0c std::bind \u53ef\u4ee5\u4e3a\u51fd\u6570\u7ed1\u5b9a\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\uff08\u5bf9\u8c61\uff09\u3002 int func(int x, int y) { printf(\"func(%d, %d)\\n\", x, y); return x + y; } auto new_func = std::bind(func, 1, std::placeholders::_1); new_func(2); // \u8c03\u7528 new_func(2) \u65f6\uff0c\u5b9e\u9645\u4e0a\u8c03\u7528\u7684\u662f func(1, 2) } \u8f93\u51fa\uff1a func(1, 2) \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; }; bind \u7684\u5386\u53f2 \u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002 thread \u819d\u76d6\u4e2d\u7bad \u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42 \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand(); forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f \u4f17\u6240\u5468\u77e5\uff0c\u5f53\u4f60\u5728\u8f6c\u53d1\u4e00\u4e2a\u201c\u4e07\u80fd\u5f15\u7528\u201d\u53c2\u6570\u65f6\uff1a template void some_func(Arg &&arg) { other_func(arg); } \u5982\u679c\u6b64\u5904 arg \u4f20\u5165\u7684\u662f\u53f3\u503c\u5f15\u7528\uff0c\u90a3\u4e48\u4f20\u5165 other_func \u5c31\u4f1a\u53d8\u56de\u5de6\u503c\u5f15\u7528\u4e86\uff0c\u4e0d\u7b26\u5408\u5b8c\u7f8e\u8f6c\u53d1\u7684\u8981\u6c42\u3002 \u56e0\u6b64\u5f15\u5165\u4e86 forward \uff0c\u4ed6\u4f1a\u68c0\u6d4b arg \u662f\u5426\u4e3a\u201c\u53f3\u503c\u201d\uff1a\u5982\u679c\u662f\uff0c\u5219 forward \u7b49\u4ef7\u4e8e move \uff1b\u5982\u679c\u4e0d\u662f\uff0c\u5219 forward \u4ec0\u4e48\u90fd\u4e0d\u505a\uff08\u9ed8\u8ba4\u5c31\u662f\u5de6\u503c\u5f15\u7528\uff09\u3002 \u8fd9\u5f04\u5f97 forward \u7684\u5916\u89c2\u975e\u5e38\u5177\u6709\u8ff7\u60d1\u6027\uff0c\u53c8\u662f\u5c16\u62ec\u53f7\u53c8\u662f\u5706\u62ec\u53f7\u7684\u3002 template void some_func(Arg &&arg) { other_func(std::forward(arg)); } \u5b9e\u9645\u4e0a\uff0cforward \u7684\u7528\u6cd5\u975e\u5e38\u5355\u4e00\uff1a\u6c38\u8fdc\u662f forward(t) \u7684\u5f62\u5f0f\uff0c\u5176\u4e2d T \u662f t \u53d8\u91cf\u7684\u7c7b\u578b\u3002 \u53c8\u662f\u52b3\u4fdd\u7684\u9b45\u529b\uff0c\u5229\u7528\u540c\u6837\u662f C++11 \u7684 decltype \u5c31\u80fd\u83b7\u5f97 t \u5b9a\u4e49\u65f6\u7684 T \u3002 void some_func(auto &&arg) { other_func(std::forward(arg)); } \u6240\u4ee5 std::forward(arg) \u5b9e\u9645\u624d\u662f forward \u7684\u6b63\u786e\u7528\u6cd5\uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u5927\u591a\u6570\u65f6\u5019\u4f60\u662f\u6a21\u677f\u53c2\u6570 Arg && \uff0c\u6709\u7684\u4eba\u5077\u61d2\uff0c\u5c31\u628a decltype(arg) \u66ff\u6362\u6210\u5df2\u7ecf\u5339\u914d\u597d\u7684\u6a21\u677f\u53c2\u6570 Arg \u4e86\uff0c\u5b9e\u9645\u4e0a\u662f\u7b49\u4ef7\u7684\u3002 \u8fd9\u91cc\u9700\u8981\u590d\u8bfb arg \u592a\u7eb1\u5e01\u4e86\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5b8f\uff1a #define FWD(arg) std::forward(arg) \u8fd9\u6837\u5c31\u53ef\u4ee5\u7b80\u5316\u4e3a\uff1a void some_func(auto &&arg) { other_func(FWD(arg)); } \u5c11\u4e86\u70e6\u4eba\u7684\u5c16\u62ec\u53f7\uff0c\u770b\u8d77\u6765\u5bb9\u6613\u61c2\u591a\u4e86\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u540c\u5b66\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u4e3a\u4ec0\u4e48 std::forward \u8981\u5199\u6210 std::forward \u7684\u5f62\u5f0f\u5462\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u662f std::forward(t) \u5462\uff1f\u56e0\u4e3a\u8fd9\u6837\u5199\u7684\u8bdd\uff0c forward \u4e5f\u6ca1\u6cd5\u77e5\u9053\u4f60\u7684 t \u662f\u5de6\u662f\u53f3\u4e86\uff08\u51fd\u6570\u53c2\u6570\u59cb\u7ec8\u4f1a\u9ed8\u8ba4\u63a8\u5bfc\u4e3a\u5de6\uff0c\u5373\u4f7f\u5b9a\u4e49\u7684 t \u662f\u53f3\uff09\u56e0\u6b64\u5fc5\u987b\u544a\u8bc9 forward \uff0c t \u7684\u5b9a\u4e49\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f T \uff0c\u6216\u8005\u901a\u8fc7 decltype(t) \u6765\u83b7\u5f97 T \u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7528\u7684\u662f auto && \u53c2\u6570\uff0c\u90a3\u4e48 FWD \u4f1a\u5f88\u65b9\u4fbf\uff08\u81ea\u52a8\u5e2e\u4f60 decltype \uff09\u3002\u4f46\u662f\u5982\u679c\u4f60\u7528\u7684\u662f\u6a21\u677f\u53c2\u6570 T && \uff0c\u90a3\u4e48 FWD \u4e5f\u53ef\u4ee5\u7528\uff0c\u56e0\u4e3a decltype(t) \u603b\u662f\u5f97\u5230 T \u3002 bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408\u4e0a\u6587\u63d0\u5230\u7684 FWD \u5b8f\u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(FWD(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u540c\u6837\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u79f0\u624b\u7684\u5b8f\uff1a #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } \u8fd9\u91cc\u4f7f\u7528\u4e86\u5b8f\u53c2\u6570\u5305\uff0c\u6b64\u5904 __VA_ARGS__ \u5c31\u662f\u5b8f\u7684 ... \u4e2d\u7684\u5185\u5bb9\u3002\u6ce8\u610f\u533a\u5206\u5b8f\u7684 ... \u548c C++ \u53d8\u957f\u6a21\u677f\u7684 ... \u662f\u4e92\u76f8\u72ec\u7acb\u7684\u3002 struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = BIND(world, this); int x = 1; memfn(x, 2); memfn(3.14); } } int main() { // \u6355\u83b7\u975e this \u7684\u6210\u5458\u51fd\u6570\u4e5f OK\uff1a Class c; auto memfn = BIND(c.world, &c); // [&c] \u6309\u5f15\u7528\u6355\u83b7 c \u53d8\u91cf // \u5c55\u5f00\u4e3a\uff1a auto memfn = [&c] (auto &&..._args) { c.world(std::forward(_args)...); } memfn(3.14); } BIND \u8fd9\u4e2a\u540d\u5b57\u662f\u968f\u4fbf\u53d6\u7684\uff0c\u53d6\u8fd9\u4e2a\u540d\u5b57\u662f\u4e3a\u4e86\u8fb1 std::bind \u3002 \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u8fd8\u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f \u5f53\u4f60\u7684\u5168\u5c40\u51fd\u6570\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6216\u5e26\u6709\u91cd\u8f7d\u7684\u51fd\u6570\u65f6\uff1a template T square(T const t) { return t * t; } template void do_something(Fn &&fn) { fn(2); fn(3.14); } int main() { do_something(square); // \u7f16\u8bd1\u9519\u8bef\uff1a\u6709\u6b67\u4e49\u7684\u91cd\u8f7d } \u5c31\u4f1a\u51fa\u73b0\u8fd9\u6837\u607c\u4eba\u7684\u7f16\u8bd1\u9519\u8bef\uff1a test.cpp: In instantiation of 'void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]': test.cpp:18:21: required from here test.cpp:14:9: error: no matching function for call to 'do_something()' do_something(square); ^~~~~~~~~~~~~ test.cpp:7:3: note: candidate: 'template void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]' void do_something(Fn &&fn) { ^~~~~~~~~~~~~ test.cpp:7:3: note: template argument deduction/substitution failed: test.cpp:14:21: note: couldn't deduce template parameter 'Fn' do_something(square); ~~~~~~~~~~~~~^~~~~~ \u8fd9\u662f\u56e0\u4e3a\uff0c\u6a21\u677f\u51fd\u6570\u548c\u6709\u91cd\u8f7d\u7684\u51fd\u6570\uff0c\u662f\u201c\u591a\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u201c\u5e7b\u60f3\u8054\u5408\u4f53\u201d\uff0c\u800c do_something \u7684 Fn \u9700\u8981\u201c\u5355\u4e2a\u201d\u5177\u4f53\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u4e00\u822c\u6765\u8bf4\u662f\u9700\u8981 square \u548c square \u624d\u80fd\u53d8\u6210\u201c\u5177\u4f53\u201d\u7684\u201c\u5355\u4e2a\u201d\u51fd\u6570\u5bf9\u8c61\uff0c\u4f20\u5165 do_something \u7684 Fn \u6a21\u677f\u53c2\u6570\u3002 \u4f46\u662f\u5728\u201c\u51fd\u6570\u8c03\u7528\u201d\u7684\u8bed\u5883\u4e0b\uff0c\u56e0\u4e3a\u5df2\u77e5\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u5f97\u76ca\u4e8e C++ \u7684\u201c\u91cd\u8f7d\u201d\u673a\u5236\uff0c\u5e26\u6709\u6a21\u677f\u53c2\u6570\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u81ea\u52a8\u5339\u914d\u90a3\u4e2a\u6a21\u677f\u53c2\u6570\u4e3a\u4f60\u53c2\u6570\u7684\u7c7b\u578b\u3002 \u4f46\u73b0\u5728\u4f60\u5e76\u6ca1\u6709\u6307\u5b9a\u8c03\u7528\u53c2\u6570\uff0c\u800c\u53ea\u662f\u6307\u5b9a\u4e86\u4e00\u4e2a\u51fd\u6570\u540d square \uff0c\u90a3 C++ \u201c\u91cd\u8f7d\u201d\u673a\u5236\u65e0\u6cd5\u786e\u5b9a\u4f60\u9700\u8981\u7684\u662f square \u8fd8\u662f square \u4e2d\u7684\u54ea\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u4ed6\u4eec\u7684\u7c7b\u578b\u90fd\u4e0d\u540c\uff0c\u5c31\u65e0\u6cd5\u5177\u8c61\u82b1\u51fa\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b Fn \u6765\uff0c\u5bfc\u81f4 \u9519\u8bef\u3002 \u6709\u8da3\u7684\u662f\uff0c\u53ea\u9700\u8981\u5957\u4e00\u5c42 lambda \u5c31\u80fd\u89e3\u51b3\uff1a do_something([] (auto x) { return square(x); }); // \u7f16\u8bd1\u901a\u8fc7 \u6216\u8005\u7528\u6211\u4eec\u4e0a\u9762\u63a8\u8350\u7684 BIND \u5b8f\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } do_something(BIND(square)); // \u7f16\u8bd1\u901a\u8fc7 \u6709\u65f6\u5019\uff0c\u5982\u679c\u4f60\u60f3\u4f20\u9012 this \u7684\u6210\u5458\u51fd\u6570\u4e3a\u51fd\u6570\u5bf9\u8c61\uff0c\u4e5f\u4f1a\u51fa\u73b0\u8fd9\u79cd\u607c\u4eba\u7684\u9519\u8bef\uff1a struct Class { int func(int x) { return x + 1; } void test() { do_something(this->func); // \u8fd9\u91cc\u53c8\u4f1a\u4ea7\u751f\u70e6\u4eba\u7684 unresolved overload \u9519\u8bef\uff01 } }; \u540c\u6837\u53ef\u4ee5\u5305\u4e00\u5c42 lambda\uff0c\u6216\u8005\u7528\u5c0f\u5f6d\u8001\u5e08\u63d0\u4f9b\u7684 BIND \u5b8f\uff0c\u9ebb\u75f9\u7684\u7f16\u8bd1\u5668\u5c31\u4e0d\u72d7\u53eb\u4e86\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } void test() { do_something(BIND(func, this)); // \u641e\u5b9a } \u5efa\u8bae\u4fee\u6539\u6807\u51c6\u5e93\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u8fd9\u4e24\u4e2a\u771f\u6b63\u597d\u7528\u7684\u5b8f\u585e\u5230 \u548c \u91cc\uff0c\u4f5c\u4e3a C++26 \u6807\u51c6\u7684\u4e00\u90e8\u5206\u3002 map + any \u5916\u6302\u5c5e\u6027 TODO \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c C++ \u6709\u4e2a\u7279\u6027\uff1a\u652f\u6301\u7eaf\u53f3\u503c(prvalue)\u9690\u5f0f\u8f6c\u6362\u6210 const \u7684\u5de6\u503c\u5f15\u7528\u3002 \u7ffb\u8bd1\uff1a int && \u53ef\u4ee5\u81ea\u52a8\u8f6c\u6362\u6210 int const & \u3002 void func(int const &i); func(1); // OK\uff1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u53d8\u91cf\u4fdd\u5b58 1\uff0c\u7136\u540e\u4f5c\u4e3a int const & \u53c2\u6570\u4f20\u5165 \u5b9e\u9645\u4e0a\u5c31\u7b49\u4ef7\u4e8e\uff1a const int tmp = 1; func(tmp); \u4f46\u662f\uff0c int && \u5374\u4e0d\u80fd\u81ea\u52a8\u8f6c\u6362\u6210 int & \u3002 void func(int &i); func(1); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece int && \u81ea\u52a8\u8f6c\u6362\u6210 int & C++ \u5b98\u65b9\u8bbe\u7f6e\u8fd9\u4e2a\u9650\u5236\uff0c\u662f\u51fa\u4e8e\u8bed\u4e49\u5b89\u5168\u6027\u8003\u8651\uff0c\u56e0\u4e3a\u53c2\u6570\u63a5\u53d7 int & \u7684\uff0c\u4e00\u822c\u90fd\u610f\u5473\u7740\u8fd9\u4e2a\u662f\u7528\u4f5c\u8fd4\u56de\u503c\uff0c\u800c\u5982\u679c func \u7684\u53c2\u6570\u662f\uff0c func(1) \u3002 \u4e3a\u4e86\u7ed5\u5f00\u8fd9\u4e2a\u89c4\u5219\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5e2e\u624b\u51fd\u6570\uff1a T &temporary(T const &t) { return const_cast(t); } // \u6216\u8005\uff1a T &temporary(T &&t) { return const_cast(t); } \u7136\u540e\uff0c\u5c31\u53ef\u4ee5\u5feb\u4e50\u5730\u8f6c\u6362\u7eaf\u53f3\u503c\u4e3a\u975e const \u5de6\u503c\u4e86\uff1a void func(int &i); func(temporary(1)); \u5728 Libreoffice \u6e90\u7801\u4e2d\u5c31\u6709\u5e94\u7528\u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\u3002 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 std::string name = \"\u4f60\u597d\"; int answer = 42; auto str = std::format(\"\u4f60\u597d\uff0c{}\uff01\u7b54\u6848\u662f {}\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x{:02x}\\n\", name, answer, answer); \u6ca1\u6709 C++20 \u4e4b\u524d\uff0c\u8981\u4e48\u4f7f\u7528\u7b2c\u4e09\u65b9\u7684 fmt::format \uff0c\u8981\u4e48\u53ea\u80fd\u4f7f\u7528\u5b57\u7b26\u4e32\u7684 + \u8fd0\u7b97\u7b26\u62d9\u52a3\u5730\u62fc\u63a5\uff1a auto str = std::string(\"\u4f60\u597d\uff0c\") + name + \"\uff01\u7b54\u6848\u662f \" + std::to_string(answer) + \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" + std::to_string(answer) + \"\\n\"; \u8fd9\u6837\u505a\u6548\u7387\u4f4e\u4e0b\uff0c\u4e14\u4e0d\u6613\u9605\u8bfb\u3002\u800c\u4e14\u4e5f\u65e0\u6cd5\u5b9e\u73b0\u6570\u5b57\u6309\u201c\u5341\u516d\u8fdb\u5236\u201d\u8f6c\u5b57\u7b26\u4e32\u3002 \u53ef\u4ee5\u7528 std::ostringstream \uff0c\u5176\u7528\u6cd5\u4e0e std::cout \u76f8\u540c\u3002\u53ea\u4e0d\u8fc7\u4f1a\u628a\u7ed3\u679c\u5199\u5165\u4e00\u4e2a\u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f\u76f4\u63a5\u8f93\u51fa\uff09\uff0c\u53ef\u4ee5\u7528 .str() \u53d6\u51fa\u90a3\u4e2a\u5b57\u7b26\u4e32\u3002 #include std::ostringstream oss; oss << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\"; auto str = oss.str(); \u5229\u7528\u4e34\u65f6\u53d8\u91cf\u8bed\u6cd5\uff0c\u53ef\u4ee5\u6d53\u7f29\u5199\u5728\u4e00\u884c\u91cc\uff0c\u505a\u4e2a format \u62d9\u52a3\u7684\u6a21\u4eff\u8005\uff1a auto str = (std::ostringstream() << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\").str(); ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 TODO shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 system(\"chcp 65001\"); setlocale(\"LC_ALL\", \".utf-8\"); \u8be6\u89c1 Unicode \u4e13\u9898\u7ae0\u8282 \u3002 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 \u5728\u4e92\u8054\u7f51\u7f16\u7a0b\u548c\u5404\u79cd\u4e0e\u786c\u76d8\u3001\u5e8f\u5217\u5316\u6253\u4ea4\u9053\u7684\u573a\u666f\u4e2d\uff0c\u5e38\u5e38\u9700\u8981\u6309\u4f4d\u62c6\u5206\u5355\u4e2a\u5b57\u8282\u3002 C \u8bed\u8a00\u6709\u4e13\u95e8\u7167\u987e\u6b64\u7c7b\u5de5\u4f5c\u7684\u8bed\u6cd5\u7cd6\uff1a\u4f4d\u57df\u3002 \u4f4d\u57df\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u7ed3\u6784\u4f53\u6210\u5458\uff0c\u53ef\u4ee5\u5bf9\u4f4d\u8fdb\u884c\u5206\u7ec4\uff0c\u65b9\u4fbf\u8bfb\u53d6\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u4ece\u4e00\u4e2a\u5b57\u8282\u4e2d\u8bfb\u53d6\u4e09\u4e2a\u72b6\u6001\u4f4d\uff1a struct Flag { uint8_t a : 4; // \u4f4e 4 \u4f4d uint8_t b : 4; // \u9ad8 4 \u4f4d }; sizeof(Flag); // 1 \u5b57\u8282\u5927\u5c0f\uff08\u5171 8 \u4f4d\uff09 Flag f = std::bit_cast(0x21); f.a; // 0x1 f.b; // 0x2 \u4ee5\u4e0a\u7684\u4ee3\u7801\u7b49\u4ef7\u4e8e\uff1a uint8_t f = 0x21; int a = f & 0xF; // 0x1 int b = f >> 4; // 0x2 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d \u6709\u4e9b\u5d4c\u5957\u5f88\u6df1\u7684\u540d\u5b57\u7a7a\u95f4\u6bcf\u6b21\u90fd\u8981\u590d\u8bfb\u975e\u5e38\u5570\u55e6\u3002 #include int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u5982\u679c using namespace \u7684\u8bdd\uff0c\u53c8\u89c9\u5f97\u6c61\u67d3\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\u4e86\u3002 #include using namespace std::filesystem; int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u53ef\u4ee5\u7528 C++11 \u7684 namespace = \u8bed\u6cd5\uff0c\u7ed9\u540d\u5b57\u7a7a\u95f4\u53d6\u4e2a\u522b\u540d\u3002 #include namespace fs = std::filesystem; int main() { fs::path p = \"/var/www/html\"; ... } \u8fd9\u6837\u4ee5\u540e\u5c31\u53ef\u4ee5 fs \u8fd9\u4e2a\u7b80\u79f0\u8bbf\u95ee\u4e86\u3002","title":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7"},{"location":"cpp_tricks/#c","text":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7 \u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf \u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664 \u522b\u518d [] \u5566\uff01 \u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01 \u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01 \u7ee7\u627f\u6784\u9020\u51fd\u6570 \u63d0\u524d\u8fd4\u56de \u7acb\u5373\u8c03\u7528\u7684 Lambda Lambda \u590d\u7528\u4ee3\u7801 \u7c7b\u5185\u9759\u6001\u6210\u5458 inline \u522b\u518d make_pair \u5566\uff01 insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6 \u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f \u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20 \u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20 \u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5 C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e\u2026 \u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto \u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32 \u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6 \u5b57\u7b26\u4e32\u5207\u7247 cout \u4e0d\u9700\u8981 endl \u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f cerr \u4e0e cout \u7684\u6289\u62e9 \u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8 optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316 if-auto \u4e0e while-auto bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50 forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front \u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f map + any \u5916\u6302\u5c5e\u6027 \u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u8bbe\u7f6e locale \u4e3a .utf8 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f \u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005 \u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5 \u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32 ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001 shared_from_this requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570 \u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898 \u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d \u4f4d\u57df\uff08bit-field\uff09 vector + unordered_map = LRU cache Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e \u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf RAII \u7684 finally \u5e2e\u624b\u7c7b swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7 namespace \u522b\u540d","title":"\u5e94\u77e5\u5e94\u4f1a C++ \u5c0f\u6280\u5de7"},{"location":"cpp_tricks/#_1","text":"int a = 42; int b = 58; \u73b0\u5728\u4f60\u60f3\u4ea4\u6362\u8fd9\u4e24\u4e2a\u53d8\u91cf\u3002 int tmp = a; a = b; b = tmp; \u4f46\u662f\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u65b9\u6cd5\uff1a std::swap(a, b); \u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4ea4\u6362\u4efb\u610f\u4e24\u4e2a\u540c\u7c7b\u578b\u7684\u503c\uff0c\u5305\u62ec\u7ed3\u6784\u4f53\u3001\u6570\u7ec4\u3001\u5bb9\u5668\u7b49\u3002 \u53ea\u9700\u8981 #include \u5c31\u53ef\u4ee5\u4f7f\u7528\uff01","title":"\u4ea4\u6362\u4e24\u4e2a\u53d8\u91cf"},{"location":"cpp_tricks/#_2","text":"\u5c0f\u5f6d\u8001\u5e08\uff1a\u4e0d\u8981\u51fa\u73b0 new \u548c delete\uff0c\u4e0d\u5b89\u5168\u3002 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; }","title":"\u5b89\u5168\u5730\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4"},{"location":"cpp_tricks/#_3","text":"\u4f17\u6240\u5468\u77e5\uff0cC\u8bed\u8a00\u4e2d int \u76f8\u9664 / \uff0c\u5f97\u5230\u7684\u7ed3\u679c\u4e5f\u662f int \uff0c\u5982\u679c\u9664\u6cd5\u4ea7\u751f\u4e86\u4f59\u6570\uff0c\u90a3\u4e48\u53ea\u4f1a\u4fdd\u7559\u6574\u6570\u90e8\u5206\u3002 \u4f8b\u5982 14 / 5 \uff0c\u672c\u6765\u5e94\u8be5\u5f97\u5230 2.8\u3002\u4f46\u662f\u56e0\u4e3a C \u8bed\u8a00\u7684\u9664\u6cd5\u8fd4\u56de int \uff0c\u7ed3\u679c\u4f1a\u81ea\u52a8\u5411\u4e0b\u53d6\u6574\uff0c\u5bfc\u81f4\u5f97\u5230 2\u3002 int a = 14, b = 5; int c = a / b; // c = 14 / 5 = 2 \u7b49\u4ef7\u4e8e int c = floor((float)a / b); // c = floor(2.8) = 2 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5c0f\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5730\u677f\u9664 (floor div) \u3002 C \u8bed\u8a00\u9ed8\u8ba4\u7684\u5c31\u662f\u5730\u677f\u9664\u3002 \u5982\u679c\u6211\u60f3\u8981\u7684\u662f\u5411\u4e0a\u53d6\u6574\uff0c\u8be5\u600e\u4e48\u5199\uff1f \u6700\u539f\u59cb\u7684\u5199\u6cd5\u662f\u5148\u8f6c\u6210\u6d6e\u70b9\u6570\u6765\u9664\uff0c\u7136\u540eceil\u51fd\u6570\u5411\u4e0a\u53d6\u6574\uff1a int c = ceil((float)a / b); \u4f46\u662f\u6d6e\u70b9\u6570\u4e0d\u4ec5\u4f4e\u6548\uff0c\u8fd8\u6709\u7cdf\u7cd5\u7684\u6d6e\u70b9\u6570\u7cbe\u5ea6\u8bef\u5dee\uff01\u5bf9\u4e8e\u5f88\u5927\u7684\u6574\u6570\uff08\u5927\u4e8e 2^{23} 2^{23} \uff09\u4f1a\u4ea7\u751f\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u66f4\u5408\u7406\u7684\u5199\u6cd5\u662f\u5148\u628a a \u52a0\u4e0a b - 1 \uff0c\u7136\u540e\u518d\u4e0b\u53d6\u6574\u5730\u9664\u4ee5 b \uff1a int c = (a + b - 1) / b; \u8fd9\u6837\u5c31\u80fd\u4ea7\u751f\u4e00\u4e2a\u5411\u4e0a\u53d6\u6574\u7684\u9664\u6cd5\u4e86\u3002 \u5982\u679c a \u9664\u4ee5 b \u9664\u4e0d\u5c3d\uff0c\u90a3\u4e48\u4f1a\u627e\u5230\u6bd4\u4ed6\u5927\u7684\u7b2c\u4e00\u4e2a\u6574\u6570\u4f5c\u4e3a\u7ed3\u679c\uff0c\u8fd9\u5c31\u662f \u5929\u82b1\u677f\u9664 (ceil div) \u3002 \u8bd5\u8bd5\u770b\uff1a14 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2.8\uff1b\u5982\u679c\u7528\u5730\u677f\u9664\uff0c\u4f1a\u5f97\u5230 2\uff1b\u5982\u679c\u7528\u5929\u82b1\u677f\u9664\uff0c\u4f1a\u5f97\u5230 3\u3002 14 / 5 = 2 (14 + 5 - 1) / 5 = (14 + 4) / 5 = 18 / 5 = 3 \u8bd5\u8bd5\u770b\uff1a10 \u9664\u4ee5 5\uff0c\u5e94\u8be5\u5f97\u5230 2\uff1b\u90a3\u4e48\u65e0\u8bba\u662f\u5730\u677f\u9664\u8fd8\u662f\u5929\u82b1\u677f\u9664\uff0c\u90fd\u5e94\u8be5\u5f97\u5230 2\u3002 10 / 5 = 2 (10 + 5 - 1) / 5 = (10 + 4) / 5 = 14 / 5 = 2 \u8fd9\u5c31\u662f C \u8bed\u8a00\u4e2d\u5b9e\u73b0\u5929\u82b1\u677f\u9664\u7684\u4e1a\u754c\u516c\u8ba4\u65b9\u5f0f\u3002","title":"\u5730\u677f\u9664\u4e0e\u5929\u82b1\u677f\u9664"},{"location":"cpp_tricks/#_4","text":"\u4f60\u77e5\u9053\u5417\uff1f\u5728 map \u4e2d\u4f7f\u7528 [] \u67e5\u627e\u5143\u7d20\uff0c\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u4f1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\u3002\u8fd9\u4e2a\u7279\u6027\u6709\u65f6\u5f88\u65b9\u4fbf\uff0c\u4f46\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u5199\u9519\u4e86\uff0c\u5c31\u4f1a\u5728 map \u4e2d\u521b\u5efa\u4e00\u4e2a\u591a\u4f59\u7684\u9ed8\u8ba4\u5143\u7d20\u3002 map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; cout << table[\"\u4faf\u6377\u8001\u5e08\"]; table \u4e2d\u660e\u660e\u6ca1\u6709 \u201c\u4faf\u6377\u8001\u5e08\u201d \u8fd9\u4e2a\u5143\u7d20\uff0c\u4f46\u7531\u4e8e [] \u7684\u7279\u6027\uff0c\u4ed6\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u4e00\u4e2a 0\uff0c\u4e0d\u4f1a\u7206\u4efb\u4f55\u9519\u8bef\uff01 \u6539\u7528\u66f4\u5b89\u5168\u7684 at() \u51fd\u6570\uff0c\u5f53\u67e5\u8be2\u7684\u5143\u7d20\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u4f60\u8c03\u8bd5\uff1a map table; table.at(\"\u5c0f\u5f6d\u8001\u5e08\") = 24; cout << table.at(\"\u4faf\u6377\u8001\u5e08\"); // \u629b\u51fa\u5f02\u5e38 [] \u771f\u6b63\u7684\u7528\u9014\u662f\u201c\u5199\u5165\u65b0\u5143\u7d20\u201d\u65f6\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u5b58\u5728\uff0c\u4ed6\u53ef\u4ee5\u81ea\u52a8\u5e2e\u4f60\u521b\u5efa\u4e00\u4e2a\u9ed8\u8ba4\u503c\uff0c\u4f9b\u4f60\u4ee5\u5f15\u7528\u7684\u65b9\u5f0f\u8d4b\u503c\u8fdb\u53bb\u3002 \u68c0\u6d4b\u5143\u7d20\u662f\u5426\u5b58\u5728\u53ef\u4ee5\u7528 count \uff1a if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } \u5373\u4f7f\u4f60\u60f3\u8981\u9ed8\u8ba4\u503c 0 \u8fd9\u4e00\u7279\u6027\uff0c count + at \u4e5f\u6bd4 [] \u66f4\u597d\uff0c\u56e0\u4e3a [] \u7684\u9ed8\u8ba4\u503c\u662f\u4f1a\u5bf9 table \u505a\u7834\u574f\u6027\u4fee\u6539\u7684\uff0c\u8fd9\u5bfc\u81f4 [] \u9700\u8981 map \u7684\u58f0\u660e\u4e0d\u4e3a const \uff1a map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u5982\u679c\"\u5c0f\u5f6d\u8001\u5e08\"\u8fd9\u4e00\u952e\u4e0d\u5b58\u5728\uff0c\u4f1a\u521b\u5efa\"\u5c0f\u5f6d\u8001\u5e08\"\u5e76\u8bbe\u4e3a\u9ed8\u8ba4\u503c 0 const map table; return table[\"\u5c0f\u5f6d\u8001\u5e08\"]; // \u7f16\u8bd1\u5931\u8d25\uff01[] \u9700\u8981\u975e const \u7684 map \u5bf9\u8c61\uff0c\u56e0\u4e3a\u4ed6\u4f1a\u7834\u574f\u6027\u4fee\u6539 \u66f4\u591a map \u77e5\u8bc6\u8bf7\u770b\u6211\u4eec\u7684 map \u4e13\u9898\u8bfe \u3002","title":"\u522b\u518d [] \u5566\uff01"},{"location":"cpp_tricks/#_5","text":"// C++98 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} }; Student stu(\"\u4faf\u6377\u8001\u5e08\", 42, 123); C++98 \u9700\u8981\u624b\u52a8\u4e66\u5199\u6784\u9020\u51fd\u6570\uff0c\u975e\u5e38\u9ebb\u70e6\uff01\u800c\u4e14\u51e0\u4e4e\u90fd\u662f\u91cd\u590d\u7684\u3002 C++11 \u4e2d\uff0c\u5e73\u51e1\u7684\u7ed3\u6784\u4f53\u7c7b\u578b\u4e0d\u9700\u8981\u518d\u5199\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u7528 {} \u5c31\u80fd\u5bf9\u6210\u5458\u4f9d\u6b21\u521d\u59cb\u5316\uff1a // C++11 struct Student { string name; int age; int id; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123}; \u8fd9\u88ab\u79f0\u4e3a \u805a\u5408\u521d\u59cb\u5316 (aggregate initialize)\u3002\u53ea\u8981\u4f60\u7684\u7c7b\u6ca1\u6709\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709 private \u6210\u5458\uff0c\u90fd\u53ef\u4ee5\u7528 {} \u805a\u5408\u521d\u59cb\u5316\u3002 \u597d\u6d88\u606f\uff1aC++20 \u4e2d\uff0c\u805a\u5408\u521d\u59cb\u5316\u4e5f\u652f\u6301 () \u4e86\uff0c\u7528\u8d77\u6765\u5c31\u548c\u4f20\u7edf\u7684 C++98 \u6784\u9020\u51fd\u6570\u4e00\u6837\uff01 // C++20 Student stu(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 123); \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6307\u5b9a\u9ed8\u8ba4\u503c\uff1a // C++11 struct Student { string name; int age; int id = 9999; }; Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; C++20 \u5f00\u59cb\uff0c {} \u805a\u5408\u521d\u59cb\u5316\u8fd8\u53ef\u4ee5\u6839\u636e\u6bcf\u4e2a\u6210\u5458\u7684\u540d\u5b57\u6765\u6307\u5b9a\u503c\uff1a Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; // \u7b49\u4ef7\u4e8e\uff1a Student stu{\"\u5c0f\u5f6d\u8001\u5e08\", 24, 9999}; \u597d\u5904\u662f\uff0c\u5373\u4f7f\u4e0d\u614e\u5199\u9519\u53c2\u6570\u987a\u5e8f\u4e5f\u4e0d\u7528\u62c5\u5fc3\u3002 Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .id = 9999}; Student stu{.name = \"\u5c0f\u5f6d\u8001\u5e08\", .id = 9999, .age = 24};","title":"\u522b\u518d\u5199\u6784\u9020\u51fd\u6570\u5566\uff01"},{"location":"cpp_tricks/#_6","text":"\u53ea\u6709\u5f53\u4f60\u9700\u8981\u6709\u201c\u81ea\u5b9a\u4e49\u94a9\u5b50\u903b\u8f91\u201d\u7684\u65f6\u5019\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u6784\u9020\u51fd\u6570\u3002 struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} Student(Student const &other) : name(other.name), age(other.age), id(other.id) { std::cout << \"\u62f7\u8d1d\u6784\u9020\\n\"; } Student &operator=(Student const &other) { name = other.name; age = other.age; id = other.id; std::cout << \"\u62f7\u8d1d\u8d4b\u503c\\n\"; return *this; } }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c \u5982\u679c\u4f60\u4e0d\u9700\u8981\u8fd9\u4e2a std::cout \uff0c\u53ea\u662f\u5e73\u51e1\u5730\u62f7\u8d1d\u6240\u6709\u6210\u5458\uff0c\u5b8c\u5168\u53ef\u4ee5\u4e0d\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\u3001\u79fb\u52a8\u6784\u9020\u51fd\u6570\u3001\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff1a struct Student { string name; int age; int id; Student(string name_, int age_, int id_) : name(name_), age(age_), id(id_) {} // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student(Student const &other) // \u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210 Student &operator=(Student const &other) }; Student stu1(\"\u4faf\u6377\u8001\u5e08\", 42, 123); Student stu2 = stu1; // \u62f7\u8d1d\u6784\u9020 stu2 = stu1; // \u62f7\u8d1d\u8d4b\u503c assert(stu2.name == \"\u4faf\u6377\u8001\u5e08\"); \u603b\u4e4b\uff0c\u5f88\u591a C++ \u6559\u6750\u628a\u62f7\u8d1d/\u79fb\u52a8\u6784\u9020\u51fd\u6570\u8fc7\u4e8e\u5938\u5927\uff0c\u641e\u5f97\u597d\u50cf\u6bcf\u4e2a\u7c7b\u90fd\u9700\u8981\u81ea\u5df1\u5b9a\u4e49\u4e00\u6837\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u6709\u5728\u201c\u81ea\u5df1\u5b9e\u73b0\u5bb9\u5668\u201d\u7684\u60c5\u51b5\u4e0b\uff0c\u624d\u9700\u8981\u81ea\u5b9a\u4e49\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3002\u53ef\u662f\u8c01\u4f1a\u6574\u5929\u624b\u6413\u5bb9\u5668\uff1f \u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u7c7b\u91cc\u9762\u5b58 vector\u3001string \u7b49\u5c01\u88c5\u597d\u7684\u5bb9\u5668\uff0c\u7f16\u8bd1\u5668\u9ed8\u8ba4\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4f1a\u81ea\u52a8\u8c03\u7528\u4ed6\u4eec\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u7528\u6237\u53ea\u9700\u4e13\u6ce8\u4e8e\u4e1a\u52a1\u903b\u8f91\u5373\u53ef\uff0c\u4e0d\u9700\u8981\u64cd\u5fc3\u5e95\u5c42\u7ec6\u8282\u3002 \u5bf9\u4e8e\u6301\u6709\u8d44\u6e90\u7684 RAII \u7c7b\uff0c\u6211\u4eec\u90fd\u4f1a\u76f4\u63a5\u5220\u9664\u5176\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff1a struct RAIIHandle { int handle; RAIIHandle() { handle = CreateObject(); } RAIIHandle(RAIIHandle const &) = delete; RAIIHandle &operator=(RAIIHandle const &) = delete; RAIIHandle() { DeleteObject(handle); } };","title":"\u522b\u518d\u5199\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5566\uff01"},{"location":"cpp_tricks/#_7","text":"C++ \u7279\u8272\uff1a\u5b50\u7c7b\u4e0d\u4f1a\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff01\uff08\u9664\u975e\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570\u662f\u6ca1\u6709\u53c2\u6570\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff09 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { void child_func() { ... } }; Child child(23, \"peng\"); // \u9519\u8bef\uff01Child \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff01 C++11 \u4e2d\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u9762\u5199 using \u7236\u7c7b::\u7236\u7c7b \uff0c\u5c31\u80fd\u81ea\u52a8\u7ee7\u627f\u7236\u7c7b\u6240\u6709\u7684\u6784\u9020\u51fd\u6570\u4e86\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { using Parent::Parent; // \u52a0\u4e0a\u8fd9\u4e00\u884c\uff01 void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u81ea\u52a8\u8c03\u7528\u5230\u7236\u7c7b\u7684\u6784\u9020\u51fd\u6570 Parent(int, const char *) \u5728 C++98 \u4e2d\uff0c\u6ca1\u6709 using \u7684\u8fd9\u4e2a\u8bed\u6cd5\uff0c\u53ea\u80fd\u81ea\u5df1\u5b9a\u4e49\u4e00\u4e2a\u6784\u9020\u51fd\u6570\uff0c\u7136\u540e\u4f7f\u7528\u201c\u59d4\u4efb\u6784\u9020\u201d\u7684\u8bed\u6cd5\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9\u7236\u7c7b\uff0c\u975e\u5e38\u7e41\u7410\u3002 struct Parent { Parent(int age, const char *name) { ... } void parent_func() { ... } }; struct Child : Parent { Child(int age, const char *name) : Parent(age, name) { ... } void child_func() { ... } }; Child child(23, \"peng\"); // \u7f16\u8bd1\u901a\u8fc7\uff0c\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6784\u9020\u51fd\u6570\u540e\u8f6c\u53d1\u5230\u7236\u7c7b","title":"\u7ee7\u627f\u6784\u9020\u51fd\u6570"},{"location":"cpp_tricks/#_8","text":"void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); } else { puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); } else { puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); } } } \u8fd9\u4e2a\u51fd\u6570\u6709\u5f88\u591a\u5c42\u5d4c\u5957\uff0c\u5f88\u4e0d\u7f8e\u89c2\u3002\u7528 \u63d0\u524d\u8fd4\u56de \u7684\u5199\u6cd5\u6765\u4f18\u5316\uff1a void babysitter(Baby *baby) { if (!baby->is_alive()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u53bb\u4e16\u4e86\"); return; } puts(\"\u6b63\u5728\u68c0\u67e5\u5b9d\u5b9d\u5582\u98df\u60c5\u51b5...\"); if (baby->is_feeded()) { puts(\"\u5b9d\u5b9d\u5df2\u7ecf\u5582\u98df\u8fc7\u4e86\"); return; } puts(\"\u6b63\u5728\u5582\u98df\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u8c03\u6559\u5b9d\u5b9d...\"); puts(\"\u6b63\u5728\u5b89\u629a\u5b9d\u5b9d...\"); }","title":"\u63d0\u524d\u8fd4\u56de"},{"location":"cpp_tricks/#lambda","text":"\u6709\u65f6\uff0c\u9700\u8981\u5728\u4e00\u4e2a\u5217\u8868\u91cc\u5faa\u73af\u67e5\u627e\u67d0\u6837\u4e1c\u897f\uff0c\u4e5f\u53ef\u4ee5\u7528\u63d0\u524d\u8fd4\u56de\u7684\u5199\u6cd5\u4f18\u5316\uff1a bool find(const vector &v, int target) { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } \u53ef\u4ee5\u5305\u88f9\u4e00\u4e2a\u7acb\u5373\u8c03\u7528\u7684 Lambda \u5757 [&] { ... } () \uff0c\u9650\u5236\u63d0\u524d\u8fd4\u56de\u7684\u8303\u56f4\uff1a void find(const vector &v, int target) { bool found = [&] { for (int i = 0; i < v.size(); ++i) { if (v[i] == target) { return true; } } return false; } (); if (found) { ... } }","title":"\u7acb\u5373\u8c03\u7528\u7684 Lambda"},{"location":"cpp_tricks/#lambda_1","text":"vector spilt(string str) { vector list; string last; for (char c: str) { if (c == ' ') { list.push_back(last); last.clear(); } else { last.push_back(c); } } list.push_back(last); return list; } \u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u7528 Lambda \u590d\u7528\uff1a vector spilt(string str) { vector list; string last; auto push = [&] { list.push_back(last); last.clear(); }; for (char c: str) { if (c == ' ') { push(); } else { last.push_back(c); } } push(); return list; }","title":"Lambda \u590d\u7528\u4ee3\u7801"},{"location":"cpp_tricks/#inline","text":"\u5728\u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7ed3\u6784\u4f53\u7684 static \u6210\u5458\u65f6\uff1a struct Class { static int member; }; \u4f1a\u62a5\u9519 undefined reference to 'Class::member' \u3002\u8fd9\u662f\u8bf4\u7684\u4f60\u9700\u8981\u627e\u4e2a .cpp \u6587\u4ef6\uff0c\u5199\u51fa int Class::member \u624d\u80fd\u6d88\u9664\u8be5\u9519\u8bef\u3002 C++17 \u4e2d\uff0c\u53ea\u9700\u52a0\u4e2a inline \u5c31\u80fd\u89e3\u51b3\uff01 struct Class { inline static int member; };","title":"\u7c7b\u5185\u9759\u6001\u6210\u5458 inline"},{"location":"cpp_tricks/#make_pair","text":"map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u4e3a\u907f\u514d\u5199\u51fa\u7c7b\u578b\u540d\u7684\u9ebb\u70e6\uff0c\u5f88\u591a\u8001\u5e08\u90fd\u4f1a\u8ba9\u4f60\u5199 make_pair\uff1a map table; table.insert(make_pair(\"\u4faf\u6377\u8001\u5e08\", 42)); \u7136\u800c C++11 \u63d0\u4f9b\u4e86\u66f4\u597d\u7684\u5199\u6cd5\uff0c\u90a3\u5c31\u662f\u901a\u8fc7 {} \u9690\u5f0f\u6784\u9020\uff0c\u4e0d\u7528\u5199\u51fa\u7c7b\u578b\u540d\u6216 make_pair\uff1a map table; table.insert({\"\u4faf\u6377\u8001\u5e08\", 42}); \u5373\u4f7f\u4f60\u51fa\u4e8e\u67d0\u79cd\u201c\u6296m\u201d\u60c5\u8282\uff0c\u8fd8\u60f3\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u4e5f\u53ef\u4ee5\u7528 C++17 \u7684 CTAD \u8bed\u6cd5\uff0c\u514d\u53bb\u6a21\u677f\u53c2\u6570\uff1a map table; table.insert(pair(\"\u4faf\u6377\u8001\u5e08\", 42)); // tuple \u4e5f\u652f\u6301 CTAD\uff1a auto t = tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); // \u7b49\u4ef7\u4e8e\uff1a auto t = make_tuple(\"\u4faf\u6377\u8001\u5e08\", 42, string(\"\u5c0f\u5f6d\u8001\u5e08\")); println(\"{}\", typeid(t).name()); // tuple","title":"\u522b\u518d make_pair \u5566\uff01"},{"location":"cpp_tricks/#insert","text":"map table; table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 24}); table.insert({\"\u5c0f\u5f6d\u8001\u5e08\", 42}); \u8fd9\u65f6\uff0c table[\"\u5c0f\u5f6d\u8001\u5e08\"] \u4ecd\u7136\u4f1a\u662f 24\uff0c\u800c\u4e0d\u662f 42\u3002\u56e0\u4e3a insert \u4e0d\u4f1a\u66ff\u6362 map \u91cc\u5df2\u7ecf\u5b58\u5728\u7684\u503c\u3002 \u5982\u679c\u5e0c\u671b\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u65f6\uff0c\u66ff\u6362\u73b0\u6709\u5143\u7d20\uff0c\u53ef\u4ee5\u4f7f\u7528 [] \u8fd0\u7b97\u7b26\uff1a map table; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 24; table[\"\u5c0f\u5f6d\u8001\u5e08\"] = 42; C++17 \u63d0\u4f9b\u4e86\u6bd4 [] \u8fd0\u7b97\u7b26\u66f4\u9002\u5408\u8986\u76d6\u6027\u63d2\u5165\u7684 insert_or_assign \u51fd\u6570\uff1a map table; table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 24); table.insert_or_assign(\"\u5c0f\u5f6d\u8001\u5e08\", 42); \u597d\u5904\uff1a insert_or_assign \u4e0d\u9700\u8981\u503c\u7c7b\u578b\u652f\u6301\u9ed8\u8ba4\u6784\u9020\uff0c\u53ef\u4ee5\u907f\u514d\u4e00\u6b21\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 + \u4e00\u6b21\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u7684\u5f00\u9500\u3002 \u5efa\u8bae\u628a insert_or_assign \u6539\u540d\u6210 set \uff0c at \u6539\u540d\u6210 get \uff1b\u53ea\u662f\u7531\u4e8e\u5386\u53f2\u539f\u56e0\u540d\u5b57\u8ff7\u60d1\u4e86\u3002","title":"insert \u4e0d\u4f1a\u66ff\u6362\u73b0\u6709\u503c\u54e6"},{"location":"cpp_tricks/#map","text":"map table; for (auto it = table.begin(); it != table.end(); ++it) { if (it->second < 0) { table.erase(it); } } \u4f1a\u53d1\u751f\u5d29\u6e83\uff01\u770b\u6765 map \u4f3c\u4e4e\u4e0d\u5141\u8bb8\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u5220\u9664\uff1f\u4e0d\uff0c\u53ea\u662f\u4f60\u7684\u5199\u6cd5\u6709\u9519\u8bef\uff1a map table; for (auto it = table.begin(); it != table.end(); ) { if (it->second < 0) { it = table.erase(it); } else { ++it; } } C++20 \u5f15\u5165\u4e86\u66f4\u597d\u7684 erase_if \u5168\u5c40\u51fd\u6570\uff0c\u4e0d\u7528\u624b\u5199\u4e0a\u9762\u8fd9\u4e48\u9ebb\u70e6\u7684\u4ee3\u7801\uff1a map table; erase_if(table, [](pair it) { return it.second < 0; });","title":"\u4e00\u8fb9\u904d\u5386 map\uff0c\u4e00\u8fb9\u5220\u9664\uff1f"},{"location":"cpp_tricks/#vector","text":"vector v = {48, 23, 76, 11, 88, 63, 45, 28, 59}; \u4f17\u6240\u5468\u77e5\uff0c\u5728 vector \u4e2d\u5220\u9664\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u540e\u9762\u7684\u6240\u6709\u5143\u7d20\u5411\u524d\u79fb\u52a8\uff0c\u5341\u5206\u4f4e\u6548\u3002\u590d\u6742\u5ea6\uff1a O(n) O(n) // \u76f4\u63a5\u5220\u9664 v[3] v.erase(v.begin() + 3); \u5982\u679c\u4e0d\u5728\u4e4e\u5143\u7d20\u7684\u987a\u5e8f\uff0c\u53ef\u4ee5\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20 swap\uff0c\u7136\u540e pop_back\u3002\u590d\u6742\u5ea6\uff1a O(1) O(1) // \u628a v[3] \u548c v[v.size() - 1] \u4f4d\u7f6e\u5bf9\u8c03 swap(v[3], v[v.size() - 1]); // \u7136\u540e\u5220\u9664 v[v.size() - 1] v.pop_back(); \u8fd9\u6837\u5c31\u4e0d\u7528\u79fb\u52a8\u4e00\u5927\u5806\u5143\u7d20\u4e86\u3002\u8fd9\u88ab\u79f0\u4e3a back-swap-erase\u3002","title":"\u9ad8\u6548\u5220\u9664\u5355\u4e2a vector \u5143\u7d20"},{"location":"cpp_tricks/#vector_1","text":"vector \u4e2d\u53ea\u5220\u9664\u4e00\u4e2a\u5143\u7d20\u9700\u8981 O(n) O(n) \u3002\u5982\u679c\u4e00\u8fb9\u904d\u5386\uff0c\u4e00\u8fb9\u5220\u9664\u591a\u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff0c\u5c31\u9700\u8981\u590d\u6742\u5ea6 O(n^2) O(n^2) \u4e86\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 remove \u548c remove_if \u51fd\u6570\uff0c\u5176\u5185\u90e8\u91c7\u7528\u7c7b\u4f3c back-swap-erase \u7684\u65b9\u6cd5\uff0c\u5148\u628a\u8981\u5220\u9664\u7684\u5143\u7d20\u79fb\u52a8\u5230\u672b\u5c3e\u3002\u7136\u540e\u4e00\u6b21\u6027 erase \u6389\u672b\u5c3e\u540c\u6837\u6570\u91cf\u7684\u5143\u7d20\u3002 \u4e14\u4ed6\u4eec\u90fd\u80fd\u4fdd\u6301\u987a\u5e8f\u4e0d\u53d8\u3002 \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove(v.begin(), v.end(), 42), v.end()); \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20\uff1a vector v; v.erase(remove_if(v.begin(), v.end(), [](int x) { return x > 0; }), v.end()); \u73b0\u5728 C++20 \u4e5f\u5f15\u5165\u4e86\u5168\u5c40\u51fd\u6570 erase \u548c erase_if\uff0c\u4f7f\u7528\u8d77\u6765\u66f4\u52a0\u76f4\u89c2\uff1a vector v; erase(v, 42); // \u5220\u9664\u6240\u6709\u503c\u4e3a 42 \u7684\u5143\u7d20 erase_if(v, [](int x) { return x > 0; // \u5220\u9664\u6240\u6709\u503c\u5927\u4e8e 0 \u7684\u5143\u7d20 });","title":"\u6279\u91cf\u5220\u9664\u90e8\u5206 vector \u5143\u7d20"},{"location":"cpp_tricks/#vector_2","text":"\u5982\u679c\u4f60\u60f3\u8981\u7ef4\u62a4\u4e00\u4e2a\u6709\u5e8f\u7684\u6570\u7ec4\uff0c\u7528 lower_bound \u6216 upper_bound \u6765\u63d2\u5165\u5143\u7d20\uff0c\u4fdd\u8bc1\u63d2\u5165\u540e\u4ecd\u4fdd\u6301\u6709\u5e8f\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 3), 3); // s = { 1, 2, 3, 4, 6 } s.insert(lower_bound(s.begin(), s.end(), 5), 5); // s = { 1, 2, 3, 4, 5, 6 } \u6709\u5e8f\u6570\u7ec4\u4e2d\uff0c\u53ef\u4ee5\u5229\u7528 lower_bound \u6216 upper_bound \u5feb\u901f\u4e8c\u5206\u67e5\u627e\u5230\u60f3\u8981\u7684\u503c\uff1a vector s; s.push_back(1); s.push_back(2); s.push_back(4); s.push_back(6); // s = { 1, 2, 4, 6 } lower_bound(s.begin(), s.end(), 3); // s.begin() + 2; lower_bound(s.begin(), s.end(), 5); // s.begin() + 3; \u6709\u5e8f vector \u5e94\u7528\u6848\u4f8b\uff1a\u5229\u7528 CDF \u79ef\u5206 + \u4e8c\u5206\u6cd5\u53ef\u4ee5\u5b9e\u73b0\u751f\u6210\u4efb\u610f\u6307\u5b9a\u5206\u5e03\u7684\u968f\u673a\u6570\u3002 \u4f8b\u5982\u6570\u503c\u7b56\u5212\u8981\u6c42\u7684\u62bd\u5361\u6982\u7387\u5206\u5e03\u662f\uff1a 2% \u51fa\u91d1\u5361 10% \u51fa\u84dd\u5361 80% \u51fa\u767d\u5361 8% \u51fa\u7b54\u8fa9 \u90a3\u4e48\u4f60\u8f6c\u6362\u4e00\u4e0b\u4efb\u52a1\u3002\u53d8\u6210\u968f\u673a\u751f\u6210\u4e00\u4e2a 0 \u5230 1 \u7684\u6d6e\u70b9\u6570\uff0c\u7136\u540e\u5224\u65ad\uff1a \u5c0f\u4e8e 0.02 \u65f6\uff0c\u51fa\u91d1\u5361 \u5c0f\u4e8e 0.12 \u65f6\uff0c\u51fa\u84dd\u5361 \u5c0f\u4e8e 0.92 \u65f6\uff0c\u51fa\u767d\u5361 \u5c0f\u4e8e 1.00 \u65f6\uff0c\u51fa\u7b54\u8fa9 \u8fd9\u4e2a\u8f6c\u6362\u8fc7\u7a0b\u5c31\u662f CDF \u79ef\u5206\u3002\u5982\u679c\u4f60\u628a\u8fd9 4 \u4e2a\u6570\u6309\u7167\u987a\u5e8f\u6392\u5217\uff0c\u5c31\u662f\u4e00\u4e2a\u6709\u5e8f vector\u3002 \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::partial_sum \uff08\u4e0d\u7cbe\u51c6\uff09\u6216 std::inclusive_scan \uff08\u66f4\u7cbe\u51c6\uff0cC++17 \u5f15\u5165\uff09\u90fd\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684 CDF \u79bb\u6563\u79ef\u5206\u3002 vector probs = {0.02, 0.1, 0.8, 0.08}; vector cdf; // \u8ba1\u7b97 probs \u7684 CDF \u79ef\u5206\uff0c\u5b58\u5165 cdf \u6570\u7ec4 std::inclusive_scan(probs.begin(), probs.end(), std::back_inserter(cdf)); // cdf = {0.02, 0.12, 0.92, 1.00} \u662f\u4e00\u4e2a\u6709\u5e8f vector\uff0c\u53ef\u4ee5\u8fd0\u7528\u4e8c\u5206\u6cd5\u5b9a\u4f4d vector result = {\"\u91d1\u5361\", \"\u84dd\u5361\", \"\u767d\u5361\", \"\u7b54\u8fa9\"}; // \u751f\u6210 100 \u4e2a\u968f\u673a\u6570\uff1a for (int i = 0; i < 100; ++i) { double r = rand() / (RAND_MAX + 1.0); int index = lower_bound(cdf.begin(), cdf.end(), r) - cdf.begin(); cout << \"\u4f60\u62bd\u5230\u4e86\" << result[index] << endl; } \u987a\u4fbf\u4e00\u63d0\uff0cCDF \u79ef\u5206\u7684\u9006\u8fd0\u7b97\u662f\u79bb\u6563\u5fae\u5206\uff1a std::adjacent_difference \uff0c\u53ef\u4ee5\u4ece cdf \u6570\u7ec4\u590d\u539f\u51fa probs \u6570\u7ec4\u3002","title":"\u4fdd\u6301\u6709\u5e8f\u7684 vector \u7528\u4e8e\u4e8c\u5206\u6cd5"},{"location":"cpp_tricks/#c_1","text":"// \u9519\u8bef\u7684\u5199\u6cd5\uff1a int r = rand() % 10; // \u8fd9\u6837\u5199\u662f\u9519\u8bef\u7684\uff01 rand() \u7684\u8fd4\u56de\u503c\u8303\u56f4\u662f [0, RAND_MAX]\uff0cRAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0b\u4e0d\u540c\uff0c\u5728 Windows \u5e73\u53f0\u7684\u662f 32767\uff0c\u5373 rand() \u53ea\u80fd\u751f\u6210 0\uff5e32767 \u4e4b\u95f4\u7684\u968f\u673a\u6570\u3002 \u5982\u679c\u60f3\u8981\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff0c\u6700\u7b80\u5355\u7684\u529e\u6cd5\u662f\uff1a int r = rand() % 10; \u7136\u800c\u8fd9\u79cd\u65b9\u6cd5\u6709\u4e2a\u81f4\u547d\u7684\u95ee\u9898\uff1a\u4e0d\u540c\u7684\u968f\u673a\u6570\u751f\u6210\u6982\u7387\u4e0d\u4e00\u6837\u3002 \u4f8b\u5982\u628a [0, RAND_MAX] \u5747\u5300\u5730\u5206\u6210 10 \u4efd\uff0c\u6bcf\u4efd 3276.7\u3002\u90a3\u4e48 0\uff5e6 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 10.0003%\uff0c\u800c 7\uff5e9 \u4e4b\u95f4\u7684\u6570\u5b57\u51fa\u73b0\u7684\u6982\u7387\u662f 3276.7 / 32767 = 9.997%\u3002 \u8fd9\u6837\u5c31\u4e0d\u662f\u771f\u6b63\u7684\u5747\u5300\u5206\u5e03\uff0c\u8fd9\u53ef\u80fd\u4f1a\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u786e\u6027\u3002 \u5f53\u6a21\u6570\u5927\u7684\u65f6\u5019\u4e0d\u5747\u5300\u6027\u4f1a\u53d8\u5f97\u7279\u522b\u660e\u663e\uff0c\u4f8b\u5982 rand() % 10000 \u3002 RAND_MAX \u5728\u4e0d\u540c\u5e73\u53f0\u4e0d\u540c\u7684\u7279\u6027\u4e5f\u8ba9\u8de8\u5e73\u53f0\u5f00\u53d1\u8005\u5f88\u5934\u5927\u3002 rand \u4f7f\u7528\u5168\u5c40\u53d8\u91cf\u5b58\u50a8\u79cd\u5b50\uff0c\u5bf9\u591a\u7ebf\u7a0b\u4e0d\u53cb\u597d\u3002 \u65e0\u6cd5\u72ec\u7acb\u7684\u4e3a\u591a\u4e2a\u751f\u6210\u5e8f\u5217\u8bbe\u5b9a\u72ec\u7acb\u7684\u79cd\u5b50\uff0c\u4e00\u4e9b\u6e38\u620f\u53ef\u80fd\u9700\u8981\u7528\u5230\u591a\u4e2a\u968f\u673a\u5e8f\u5217\uff0c\u5404\u81ea\u6709\u72ec\u7acb\u7684\u79cd\u5b50\u3002 \u53ea\u80fd\u751f\u6210\u5747\u5300\u5206\u5e03\u7684\u6574\u6570\uff0c\u4e0d\u80fd\u751f\u6210\u5e42\u7387\u5206\u5e03\u3001\u6b63\u592a\u5206\u5e03\u7b49\uff0c\u751f\u6210\u6d6e\u70b9\u6570\u4e5f\u6bd4\u8f83\u9ebb\u70e6\u3002 \u4f7f\u7528 srand(time(NULL)) \u65e0\u6cd5\u5b89\u5168\u5730\u751f\u6210\u968f\u673a\u6570\u7684\u521d\u59cb\u79cd\u5b50\uff0c\u5bb9\u6613\u88ab\u9ed1\u5ba2\u9884\u6d4b\u5e76\u653b\u51fb\u3002 rand \u7684\u7b97\u6cd5\u5b9e\u73b0\u6ca1\u6709\u5b98\u65b9\u89c4\u5b9a\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u5404\u6709\u4e0d\u540c\uff0c\u4ea7\u751f\u7684\u968f\u673a\u6570\u5e8f\u5217\u53ef\u80fd\u4e0d\u540c\u3002 \u4e3a\u6b64\uff0cC++ \u63d0\u51fa\u4e86\u66f4\u52a0\u4e13\u4e1a\u7684\u968f\u673a\u6570\u751f\u6210\u5668\uff1a \u5e93\u3002 // \u4f7f\u7528 \u5e93\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u968f\u673a\u6570\uff1a #include #include int main() { uint64_t seed = std::random_device()(); std::mt19937 gen(seed); std::uniform_int_distribution dis(0, 9); for (int i = 0; i < 100; ++i) { int r = dis(gen); std::cout << r << \" \"; } } \u8fd9\u6837\u5c31\u53ef\u4ee5\u751f\u6210 0\uff5e9 \u4e4b\u95f4\u7684\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u4e86\u3002 std::random_device \u662f\u4e00\u4e2a\u968f\u673a\u6570\u79cd\u5b50\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u7cfb\u7edf\u7684\u968f\u673a\u8bbe\u5907\uff08\u5982\u679c\u6709\u7684\u8bdd\uff0c\u5426\u5219\u4f1a\u629b\u51fa\u5f02\u5e38\uff09\u751f\u6210\u4e00\u4e2a\u5b89\u5168\u7684\u968f\u673a\u6570\u79cd\u5b50\uff0c\u9ed1\u5ba2\u65e0\u6cd5\u9884\u6d4b\u3002 std::mt19937 \u662f\u4e00\u4e2a\u968f\u673a\u6570\u751f\u6210\u5668\uff0c\u5b83\u4f1a\u5229\u7528\u521d\u59cb\u79cd\u5b50\u751f\u6210\u4e00\u4e2a\u968f\u673a\u6570\u5e8f\u5217\u3002\u5e76\u4e14\u5fc5\u5b9a\u662f MT19937 \u8fd9\u4e2a\u9ad8\u5f3a\u5ea6\u7684\u968f\u673a\u7b97\u6cd5\uff0c\u6240\u6709\u5e73\u53f0\u90fd\u4e00\u6837\u3002 std::uniform_int_distribution \u662f\u4e00\u4e2a\u5206\u5e03\u5668\uff0c\u5b83\u53ef\u4ee5\u628a\u5747\u5300\u5206\u5e03\u7684\u968f\u673a\u6570\u6620\u5c04\u5230\u6211\u4eec\u60f3\u8981\u7684\u4e0a\u4e0b\u754c\u4e2d\u3002\u91cc\u9762\u7684\u5b9e\u73b0\u7c7b\u4f3c\u4e8e gen() % 10 \uff0c\u4f46\u901a\u8fc7\u6570\u5b66\u673a\u5236\u4fdd\u8bc1\u4e86\u7edd\u5bf9\u5747\u5300\u6027\u3002 \u7c7b\u4f3c\u7684\u8fd8\u6709 std::uniform_real_distribution \u7528\u4e8e\u751f\u6210\u6d6e\u70b9\u6570\uff0c std::normal_distribution \u7528\u4e8e\u751f\u6210\u6b63\u592a\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c std::poisson_distribution \u7528\u4e8e\u751f\u6210\u6cca\u677e\u5206\u5e03\u7684\u968f\u673a\u6570\uff0c\u7b49\u7b49\u3002 \u5982\u679c\u559c\u6b22\u8001\u5f0f\u7684\u51fd\u6570\u8c03\u7528\u98ce\u683c\u63a5\u53e3\uff0c\u53ef\u4ee5\u5c01\u88c5\u4e00\u4e2a\u65b0\u7684 C++ \u91cd\u7f6e\u7248\u5b89\u5168 rand \uff1a thread_local std::mt19937 gen(std::random_device{}()); // \u6bcf\u7ebf\u7a0b\u4e00\u4e2a\uff0c\u4e92\u4e0d\u51b2\u7a81 int randint(int min, int max) { return std::uniform_int_distribution(min, max)(gen); } float randfloat(float min, float max) { return std::uniform_real_distribution(min, max)(gen); }","title":"C++ \u968f\u673a\u6570\u7684\u6b63\u786e\u751f\u6210\u65b9\u5f0f"},{"location":"cpp_tricks/#const","text":"\u4f17\u6240\u5468\u77e5\uff0c const \u5728\u6307\u9488\u7b26\u53f7 * \u7684\u524d\u540e\uff0c\u6548\u679c\u662f\u4e0d\u540c\u7684\u3002 const int *p; int *const p; \u4f60\u80fd\u770b\u51fa\u6765\u4e0a\u9762\u8fd9\u4e2a const \u5206\u522b\u4fee\u9970\u7684\u662f\u8c01\u5417\uff1f const int *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u4e3a\u4e86\u770b\u8d77\u6765\u66f4\u52a0\u660e\u786e\uff0c\u6211\u901a\u5e38\u90fd\u4f1a\u540e\u7f6e\u6240\u6709\u7684 const \u4fee\u9970\u3002 int const *p; // \u6307\u9488\u6307\u5411\u7684 int \u4e0d\u53ef\u53d8 int *const p; // \u6307\u9488\u672c\u8eab\u4e0d\u53ef\u6539\u53d8\u6307\u5411 \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\uff0cconst \u603b\u662f\u5728\u4fee\u9970\u4ed6\u524d\u9762\u7684\u4e1c\u897f\uff0c\u800c\u4e0d\u662f\u540e\u9762\u3002 \u4e3a\u4ec0\u4e48 int *const \u4fee\u9970\u7684\u662f int * \u4e5f\u5c31\u5f88\u5bb9\u6613\u7406\u89e3\u4e86\u3002 int const i; int const *p; int *const q; int const &r; \u4e3e\u4e2a\u4f8b\u5b50\uff1a int i, j; int *const p = &i; *p = 1; // OK\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int i, j; int const *p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // OK\uff1ap \u672c\u8eab\u53ef\u53d8\uff0c\u53ef\u4ee5\u6539\u53d8\u6307\u5411 int i, j; int const *const p = &i; *p = 1; // \u9519\u8bef\uff1ap \u6307\u5411\u7684\u5bf9\u8c61\u4e0d\u53ef\u53d8 p = &j; // \u9519\u8bef\uff1ap \u672c\u8eab\u4e5f\u4e0d\u53ef\u53d8\uff0c\u4e0d\u80fd\u6539\u53d8\u6307\u5411 int const * \u548c const int * \u7b49\u4ef7\uff01\u53ea\u6709 int *const \u662f\u4e0d\u540c\u7684\u3002","title":"const \u5c45\u7136\u5e94\u8be5\u540e\u7f6e…"},{"location":"cpp_tricks/#auto","text":"\u5927\u5bb6\u90fd\u77e5\u9053\uff0c\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u58f0\u660e\u4e3a auto \uff0c\u8ba9\u5176\u81ea\u52a8\u63a8\u5bfc\u3002 auto square() { // int square(); return 1; } \u4f46\u4f60\u77e5\u9053\u4ece C++20 \u5f00\u59cb\uff0c\u53c2\u6570\u4e5f\u53ef\u4ee5\u58f0\u660e\u4e3a auto \u4e86\u5417\uff1f auto square(auto x) { // T square(T x); return x * x; } square(1); // square(int) square(3.14); // square(double) \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u201c\u6a21\u677f\u51fd\u6570\u201d\u7684\u4f20\u7edf\u5199\u6cd5\uff1a template T square(T x) { return x * x; } square(1); // square(int) square(3.14); // square(double) \u56e0\u4e3a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6240\u4ee5\u4e5f\u5f88\u96be\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u53ea\u9002\u7528\u4e8e\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u7684\u60c5\u51b5\u3002 auto \u53c2\u6570\u8fd8\u53ef\u4ee5\u5e26\u6709\u5f15\u7528\uff1a auto square(auto const &x) { // T square(T const &x); return x * x; } square(1); // square(int const &) square(3.14); // square(double const &) \u7b49\u4ef7\u4e8e\uff1a template T square(T const &x) { return x * x; } auto \u53c2\u6570\u6700\u597d\u7684\u914d\u5408\u83ab\u8fc7\u4e8e\u662f\u4e0e\u540c\u6837 C++20 \u5f15\u5165\u7684 concept\uff1a auto square(std::integral auto x) { // T square(T x) requires std::integral return x * x; } square(1); // square(int) square(3.14); // \u9519\u8bef\uff1adouble \u4e0d\u662f\u6574\u6570\u7c7b\u578b \u7b49\u4ef7\u4e8e\uff1a template requires std::integral T square(T x) { return x * x; } \u6216\u8005\uff1a template T square(T x) { return x * x; }","title":"\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5 auto"},{"location":"cpp_tricks/#_9","text":"std::string file_get_content(std::string const &filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); std::istreambuf_iterator iit(ifs), iite; std::string content(iit, iite); return content; } void file_put_content(std::string const &filename, std::string const &content) { std::ofstream ofs(filename, std::ios::out | std::ios::binary); ofs << content; } \u8fd9\u6837\u5c31\u53ef\u4ee5\u628a\u6574\u4e2a\u6587\u4ef6\u8bfb\u53d6\u5230\u5185\u5b58\u4e2d\uff0c\u5f88\u65b9\u4fbf\u5730\u8fdb\u884c\u5904\u7406\u540e\u518d\u5199\u56de\u6587\u4ef6\u3002 \u63a8\u8350\u7528 std::ios::binary \u9009\u9879\u6253\u5f00\u4e8c\u8fdb\u5236\u6587\u4ef6\uff0c\u5426\u5219\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0 '\\n' \u65f6\uff0c\u4f1a\u88ab MSVC \u6807\u51c6\u5e93\u81ea\u52a8\u8f6c\u6362\u6210 '\\r\\n' \u6765\u5199\u5165\uff0c\u59a8\u788d\u6211\u4eec\u8de8\u5e73\u53f0\u3002","title":"\u8bfb\u53d6\u6574\u4e2a\u6587\u4ef6\u5230\u5b57\u7b26\u4e32"},{"location":"cpp_tricks/#_10","text":"std::ifstream fin(\"test.txt\"); std::string line; while (std::getline(fin, line)) { std::cout << \"\u8bfb\u53d6\u5230\u4e00\u884c\uff1a\" << line << '\\n'; }","title":"\u9010\u884c\u8bfb\u53d6\u6587\u672c\u6587\u4ef6"},{"location":"cpp_tricks/#_11","text":"#include #include #include std::vector split_str(std::string const &str, char ch) { std::stringstream ss(str); std::string line; std::vector res; while (std::getline(ss, line, ch)) { res.push_back(std::move(line)); } return res; } auto res = split_str(\"hello world\", ' '); // res = {\"hello\", \"world\"}","title":"\u5b57\u7b26\u4e32\u5207\u7247"},{"location":"cpp_tricks/#cout-endl","text":"int a = 42; printf(\"%d\\n\", a); \u4e07\u4e00\u4f60\u5199\u9519\u4e86 % \u540e\u9762\u7684\u7c7b\u578b\uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u7559\u4e0b\u9690\u60a3\u3002 int a = 42; printf(\"%s\\n\", a); // \u7f16\u8bd1\u5668\u4e0d\u62a5\u9519\uff0c\u4f46\u662f\u8fd0\u884c\u65f6\u4f1a\u5d29\u6e83\uff01 C++ \u4e2d\u6709\u66f4\u5b89\u5168\u7684\u8f93\u51fa\u65b9\u5f0f cout \uff0c\u901a\u8fc7 C++ \u7684\u91cd\u8f7d\u673a\u5236\uff0c\u65e0\u9700\u624b\u52a8\u6307\u5b9a % \uff0c\u81ea\u52a8\u5c31\u80fd\u63a8\u5bfc\u7c7b\u578b\u3002 int a = 42; cout << a << endl; double d = 3.14; cout << d << endl; cout << \"Hello, World!\" << endl; endl \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6d41\u64cd\u4f5c\u7b26\uff0c\u4f5c\u7528\u7b49\u4ef7\u4e8e\u5148\u8f93\u51fa\u4e00\u4e2a '\\n' \u7136\u540e flush \u3002 cout << \"Hello, World!\" << '\\n'; cout.flush(); \u4f46\u5b9e\u9645\u4e0a\uff0c\u8f93\u51fa\u6d41 cout \u9ed8\u8ba4\u7684\u8bbe\u7f6e\u5c31\u662f\u201c\u884c\u5237\u65b0\u7f13\u5b58\u201d\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u68c0\u6d4b\u5230 '\\n' \u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u5237\u65b0\u4e00\u6b21\uff0c\u6839\u672c\u4e0d\u9700\u8981\u6211\u4eec\u624b\u52a8\u5237\u65b0\uff01 \u5982\u679c\u8fd8\u7528 endl \u7684\u8bdd\uff0c\u5c31\u76f8\u5f53\u4e8e\u5237\u65b0\u4e86\u4e24\u6b21\uff0c\u6d6a\u8d39\u6027\u80fd\u3002 \u53ef\u89c1\uff0cendl \u662f\u4e00\u4e2a\u88ab\u5f88\u591a\u65e0\u8111\u6559\u6750\u9519\u8bef\u5ba3\u4f20\uff0c\u5b9e\u9645\u4e0a\u6839\u672c\u591a\u6b64\u4e00\u4e3e\u7684\u4e1c\u897f\u3002 \u6211\u4eec\u53ea\u9700\u8981\u8f93\u51fa '\\n' \u5c31\u53ef\u4ee5\u4e86\uff0c\u6bcf\u6b21\u6362\u884c\u65f6 cout \u90fd\u4f1a\u81ea\u52a8\u5237\u65b0\u3002 cout << \"Hello, World!\" << '\\n'; endl \u662f\u4e00\u4e2a\u5178\u578b\u7684\u4ee5\u8bb9\u4f20\u8bb9\u9519\u8bef\u5199\u6cd5\uff0c\u53ea\u6709\u5f53\u4f60\u7684\u8f93\u51fa\u662f\u6307\u5411\u53e6\u4e00\u4e2a\u8fdb\u7a0b\u7684\u7ba1\u9053\u65f6\uff0c\u5176\u9644\u5e26\u7684\u5237\u65b0\u529f\u80fd\u624d\u6709\u4f5c\u7528\u3002 \u5f53\u8f93\u51fa\u662f\u7ba1\u9053\u6216\u6587\u4ef6\u65f6\uff0c cout \u9700\u8981 endl \u624d\u80fd\u5237\u65b0\u3002 \u5f53\u8f93\u51fa\u662f\u666e\u901a\u63a7\u5236\u53f0\u65f6\uff0c cout \u53ea\u9700 '\\n' \u5c31\u80fd\u5237\u65b0\u4e86\uff0c\u6839\u672c\u7528\u4e0d\u7740 endl \u3002 \u800c\u4e14\uff0c\u7ba1\u9053\u6216\u6587\u4ef6\u5b9e\u9645\u4e0a\u4e5f\u4e0d\u5b58\u5728\u9891\u7e41\u5237\u65b0\u7684\u9700\u6c42\uff0c\u53cd\u6b63 ifstream \u6790\u6784\u65f6\u603b\u662f\u4f1a\u81ea\u52a8\u5237\u65b0\u5199\u5165\u78c1\u76d8\u3002 \u56e0\u6b64\uff0c endl \u64cd\u7eb5\u7b26\u5927\u591a\u65f6\u5019\u90fd\u662f\u5197\u4f59\u7684\uff1a\u63a7\u5236\u53f0\u8f93\u51fa\u7684 cout \u53ea\u9700\u8981\u5b57\u7b26\u6216\u5b57\u7b26\u4e32\u4e2d\u542b\u6709 '\\n' \u5c31\u5237\u65b0\u4e86\uff0c\u5373\u4f7f\u662f\u6587\u4ef6\u8bfb\u5199\u4e5f\u5f88\u5c11\u4f1a\u4f7f\u7528 endl \u3002 \u5982\u679c\u786e\u5b9e\u9700\u8981\u5f3a\u5236\u5237\u65b0\uff0c\u4e5f\u53ef\u4ee5\u7528 flush \u8fd9\u79cd\u66f4\u52a0\u53ef\u8bfb\u7684\u5199\u6cd5\uff1a int num; cout << \"please input the number: \" << flush; cin >> num; ofstream fout(\"log.txt\"); fout << \"immediate write 1\\n\" << flush; sleep(1); fout << \"immediate write 2\\n\" << flush; fout.close(); // \u5173\u95ed\u6587\u4ef6\u65f6\u603b\u662f\u81ea\u52a8 flush\uff0c\u4e0d\u4f1a\u6709\u6b8b\u7559\u672a\u5199\u5165\u7684\u5b57\u7b26","title":"cout \u4e0d\u9700\u8981 endl"},{"location":"cpp_tricks/#cout","text":"\u540c\u5b66\uff1a\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u4f7f\u7528\uff1a cout << \"the answer is \" << 42 << '\\n'; \u53d1\u73b0\u8f93\u51fa\u4e71\u5957\u4e86\uff01\u8fd9\u662f\u4e0d\u662f\u8bf4\u660e cout \u4e0d\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\u5462\uff1f \u5c0f\u5f6d\u8001\u5e08\uff1acout \u662f\u4e00\u4e2a\u201c\u540c\u6b65\u6d41\u201d\uff0c\u662f \u591a\u7ebf\u7a0b\u5b89\u5168 \u7684\uff0c\u9519\u8bef\u7684\u662f\u4f60\u7684\u4f7f\u7528\u65b9\u5f0f\u3002 \u5982\u679c\u4ed6\u4e0d\u591a\u7ebf\u7a0b\u5b89\u5168\uff0c\u90a3\u591a\u7ebf\u7a0b\u5730\u8c03\u7528\u4ed6\u5c31\u4e0d\u662f\u8f93\u51fa\u4e71\u5e8f\uff0c\u800c\u662f\u7a0b\u5e8f\u5d29\u6e83\u4e86\u3002 \u4f46\u662f\uff0ccout \u7684\u7ebf\u7a0b\u5b89\u5168\uff0c\u53ea\u80fd\u4fdd\u8bc1\u6bcf\u4e00\u6b21 operator<< \u90fd\u662f\u539f\u5b50\u7684\uff0c\u6bcf\u4e00\u6b21\u5355\u72ec\u7684 operator<< \u4e0d\u4f1a\u88ab\u5176\u4ed6\u4eba\u6253\u65ad\u3002 \u4f46\u4f17\u6240\u5468\u77e5\uff0ccout \u4e3a\u4e86\u652f\u6301\u7ea7\u8054\u8c03\u7528\uff0c\u4ed6\u7684 operator<< \u90fd\u662f\u8fd4\u56de\u81ea\u5df1\u7684\uff0c\u4e0a\u9762\u7684\u4ee3\u7801\u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u5206\u522b\u4e09\u6b21\u8c03\u7528 cout \u7684 operator<< \u3002 cout << \"the answer is \" << 42 << '\\n'; // \u7b49\u4ef7\u4e8e\uff1a cout << \"the answer is \"; cout << 42; cout << '\\n'; \u53d8\u6210\u4e86\u4e09\u6b21 operator<< \uff0c\u6bcf\u4e00\u6b21\u90fd\u662f\u201c\u5404\u81ea\u201d\u539f\u5b50\u7684\uff0c\u4f46\u4e09\u4e2a\u539f\u5b50\u52a0\u5728\u4e00\u8d77\u5c31\u4e0d\u662f\u539f\u5b50\u4e86\u3002 \u800c\u662f\u5206\u5b50\u4e86 :) \u4ed6\u4eec\u4e2d\u95f4\u53ef\u80fd\u7a7f\u63d2\u4e86\u5176\u4ed6\u7ebf\u7a0b\u7684 cout\uff0c\u4ece\u800c\u5bfc\u81f4\u4f60 \"the answer is\" \u6253\u5370\u5b8c\u540e\uff0c\u88ab\u5176\u4ed6\u7ebf\u7a0b\u7684 '\\n' \u63d2\u5165\u8fdb\u6765\uff0c\u5bfc\u81f4\u6362\u884c\u6df7\u4e71\u3002 std::cout \u7684 operator<< \u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u4e0d\u4f1a\u88ab\u6253\u65ad\uff0c\u4f46\u591a\u4e2a operator<< \u7684\u8c03\u7528\u5728\u591a\u7ebf\u7a0b\u73af\u5883\u4e2d\u53ef\u80fd\u4f1a \u4ea4\u9519 \uff0c\u5bfc\u81f4\u8f93\u51fa\u7ed3\u679c\u6df7\u4e71\u3002 \u66f4\u591a\u7ec6\u8282\u8bf7\u770b\u6211\u4eec\u7684 \u591a\u7ebf\u7a0b\u4e13\u9898 \u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\uff0c\u5148\u521b\u5efa\u4e00\u4e2a\u53ea\u5c5e\u4e8e\u5f53\u524d\u7ebf\u7a0b\u7684 ostringstream \uff0c\u6700\u540e\u4e00\u6b21\u6027\u8c03\u7528\u4e00\u6b21 cout \u7684 operator<< \uff0c\u8ba9\u201c\u539f\u5b50\u201d\u7684\u5355\u4f4d\u53d8\u6210\u201c\u4e00\u884c\u201d\u800c\u4e0d\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 ostringstream oss; oss << \"the answer is \" << 42 << '\\n'; cout << oss.str(); \u6216\u8005\uff0c\u4f7f\u7528 std::format \uff1a cout << std::format(\"the answer is {}\\n\", 42); \u603b\u4e4b\uff0c\u5c31\u662f\u8981\u8ba9 operator<< \u53ea\u6709\u4e00\u6b21\uff0c\u81ea\u7136\u5c31\u662f\u6ca1\u6709\u4ea4\u9519\u3002 \u5728 C++20 \u4e2d\uff0c\u53ef\u4ee5\u6539\u7528 std::osyncstream(std::cout) \u4ee3\u66ff std::cout : std::osyncstream(std::cout) << \"the answer is \" << 42 << '\\n'; std::osyncstream \u53ef\u4ee5\u4fdd\u8bc1\uff1a1. \u4e0d\u4f1a\u4ea7\u751f\u6570\u636e\u7ade\u4e89\uff1b2. \u4e0d\u4f1a\u53d1\u751f\u7a7f\u63d2\u548c\u622a\u65ad\u3002\u53ef\u4ee5\u7406\u89e3\u4e3a std::osyncstream \u5728\u6784\u9020\u65f6\u5bf9\u7f13\u51b2\u533a\u4e0a\u9501\uff0c\u5728\u6790\u6784\u65f6\u89e3\u9501\u3002 \u5982\u679c\u4f60\u7684\u6807\u51c6\u5e93\u652f\u6301 C++23\uff0c\u8fd8\u53ef\u4ee5\u7528 std::println \uff0c\u8fd9\u4e2a\u51fd\u6570\u7684\u8f93\u51fa\u4e5f\u662f\u539f\u5b50\u7684\uff08\u7b2c\u4e09\u65b9\u5e93\u5982 fmt::println \u4ea6\u53ef\uff09\uff1a std::println(\"the answer is {}\", 42);","title":"\u591a\u7ebf\u7a0b\u4e2d cout \u51fa\u73b0\u4e71\u5e8f\uff1f"},{"location":"cpp_tricks/#cerr-cout","text":"\u5982\u679c\u4f60\u7684\u76ee\u7684\u662f\u8c03\u8bd5\u548c\u62a5\u9519\uff0c\u53ef\u4ee5\u8003\u8651\u7528 cerr \uff01 \u4ed6\u4f1a\u5728\u6bcf\u6b21 << \u65f6\u5237\u65b0\uff0c cerr \u624d\u662f\u6700\u9002\u5408\u6253\u5370\u9519\u8bef\u548c\u8c03\u8bd5\u4fe1\u606f\u7684\u6d41\u3002 cout \u7684\u4f18\u70b9\u662f\u4e0d\u9700\u8981\u65f6\u523b\u5237\u65b0\uff0c\u6709\u66f4\u597d\u7684\u6027\u80fd\u3002 cout << \"hello\\n\"; cout << \"the answer is \"; cout << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cout << \"!\\n\"; // \u56e0\u4e3a\u8fd8\u6ca1\u6709\u62b5\u8fbe \\n \u4ea7\u751f\u5237\u65b0\u5c31\u5d29\u6e83\uff0c\u5bfc\u81f4\u4e4b\u524d\u5c1a\u672a\u5237\u65b0\u7684 the answer is 42 \u4e22\u5931 \u53ef\u80fd\u7684\u8f93\u51fa\uff1a hello[\u6362\u884c] cerr << \"hello\\n\"; cerr << \"the answer is \"; cerr << 42; *(int *)1 = 1; // \u5d29\u6e83\uff01 cerr << \"!\\n\"; \u8f93\u51fa\uff1a hello[\u6362\u884c] the answer is 42 \u8fd8\u6709\u4e00\u4e2a\u7279\u70b9\uff1a cout \u8f93\u51fa\u5230\u201c\u6807\u51c6\u8f93\u51fa\u6d41\u201d\uff0c\u53ef\u4ee5\u88ab\u8f93\u51fa\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u7ba1\u9053\u3002\u800c cerr \u8f93\u51fa\u5230\u201c\u6807\u51c6\u9519\u8bef\u6d41\u201d\uff0c\u901a\u5e38\u4e0d\u4f1a\u88ab\u91cd\u5b9a\u5411\u5230\u6587\u4ef6\u6216\u7ba1\u9053\u3002 \u4f8b\u5982\uff0c\u53ef\u4ee5\u628a\u7a0b\u5e8f\u9884\u8ba2\u7684\u8ba1\u7b97\u7ed3\u679c\u5199\u5230 cout \uff0c\u628a\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5199\u5230 cerr \uff0c\u8fd9\u6837\u7528\u6237\u5c31\u53ef\u4ee5\u901a\u8fc7 > \u91cd\u5b9a\u5411\u8ba1\u7b97\u7ed3\u679c\uff0c\u800c\u8c03\u8bd5\u548c\u62a5\u9519\u4fe1\u606f\u5219\u6b63\u5e38\u8f93\u51fa\u5230\u5c4f\u5e55\u4e0a\uff0c\u4e0d\u53d7\u91cd\u5b9a\u5411\u5f71\u54cd\u3002 cout << \"1 3 5 7\\n\"; cerr << \"ERROR: this is an error message!\\n\"; cout << \"11 13 17 19\\n\"; $ g++ prime.cpp -o prime $ ./prime 1 3 5 7 ERROR: this is an error message! 11 13 17 19 $ ./prime > output.txt ERROR: this is an error message! $ cat output.txt 1 3 5 7 11 13 17 19","title":"cerr \u4e0e cout \u7684\u6289\u62e9"},{"location":"cpp_tricks/#_12","text":"\u6211\u4eec\u8bf4\u4e00\u4e2a\u7c7b\u578b\u5927\uff0c\u6709\u4e24\u79cd\u60c5\u51b5\u3002 \u7c7b\u672c\u8eab\u5f88\u5927\uff1a\u4f8b\u5982 array \u7c7b\u672c\u8eab\u4e0d\u5927\uff0c\u4f46\u5176\u6307\u5411\u7684\u5bf9\u8c61\u5927\uff0c\u4e14\u8be5\u7c7b\u662f\u6df1\u62f7\u8d1d\uff0c\u5bf9\u8be5\u7c7b\u7684\u62f7\u8d1d\u4f1a\u5f15\u8d77\u5176\u6307\u5411\u5bf9\u8c61\u7684\u62f7\u8d1d\uff1a\u4f8b\u5982 vector sizeof(array); // \u672c\u8eab 4000 \u5b57\u8282 sizeof(vector); // \u672c\u8eab 24 \u5b57\u8282\uff08\u6210\u5458\u662f 3 \u4e2a\u6307\u9488\uff09\uff0c\u6307\u5411\u7684\u6570\u7ec4\u53ef\u4ee5\u65e0\u9650\u589e\u5927 sizeof(vector) \u4e3a 24 \u5b57\u8282\u4ec5\u4e3a x86_64-pc-linux-gnu \u5e73\u53f0 libstdc++ \u5e93\u7684\u5b9e\u6d4b\u7ed3\u679c\uff0c\u5728 32 \u4f4d\u7cfb\u7edf\u4ee5\u53ca MSVC \u7684 Debug \u6a21\u5f0f STL \u4e0b\u53ef\u80fd\u5f97\u51fa\u4e0d\u540c\u7684\u7ed3\u679c\uff0c\u4e0d\u53ef\u4ee5\u4f9d\u8d56\u8fd9\u4e2a\u5e73\u53f0\u76f8\u5173\u7684\u7ed3\u679c\u6765\u7f16\u7a0b\u3002 \u5bf9\u4e8e vector\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 std::move \u79fb\u52a8\u8bed\u4e49\uff0c\u53ea\u62f7\u8d1d\u8be5\u7c7b\u672c\u8eab\u7684\u4e09\u4e2a\u6307\u9488\u6210\u5458\uff0c\u800c\u4e0d\u5bf9\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u6570\u7ec4\u8fdb\u884c\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e array\uff0c\u5219 std::move \u79fb\u52a8\u8bed\u4e49\u4e0e\u666e\u901a\u7684\u62f7\u8d1d\u6ca1\u6709\u533a\u522b\uff1aarray \u4f5c\u4e3a\u9759\u6001\u6570\u7ec4\u5bb9\u5668\uff0c\u4e0d\u662f\u901a\u8fc7\u201c\u6307\u9488\u6210\u5458\u201d\u6765\u4fdd\u5b58\u6570\u7ec4\u7684\uff0c\u800c\u662f\u76f4\u63a5\u628a\u6570\u7ec4\u5b58\u5728\u4ed6\u7684\u4f53\u5185\uff0c\u5bf9 array \u7684\u79fb\u52a8\u548c\u62f7\u8d1d\u662f\u5b8c\u5168\u4e00\u6837\u7684\uff01 \u603b\u4e4b\uff0c\u79fb\u52a8\u8bed\u4e49\u7684\u52a0\u901f\u6548\u679c\uff0c\u53ea\u5bf9\u91c7\u7528\u4e86\u201c\u6307\u9488\u95f4\u63a5\u5b58\u50a8\u52a8\u6001\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08\u5982 vector\u3001map\u3001set\u3001string\uff09\u6709\u6548\u3002\u5bf9\u201c\u76f4\u63a5\u5b58\u50a8\u9759\u6001\u5927\u5c0f\u6570\u636e\u201d\u7684\u7c7b\u578b\uff08array\u3001tuple\u3001variant\u3001\u6210\u529f\u201c\u5c0f\u5b57\u7b26\u4e32\u4f18\u5316\u201d\u7684 string\uff09\u65e0\u6548\u3002 \u6240\u4ee5\uff0c\u8ba9\u5f88\u591a\u201c\u79fb\u52a8\u8bed\u4e49\u201d\u5b5d\u5b50\u5931\u671b\u4e86\uff1a\u201c\u672c\u8eab\u5f88\u5927\u201d\u7684\u7c7b\uff0c\u79fb\u52a8\u548c\u62f7\u8d1d\u4e00\u6837\u6162\uff01 \u90a3\u4e48\u73b0\u5728\u6211\u4eec\u6709\u4e2a\u8d85\u5927\u7684\u7c7b\uff1a using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b vector arr; void func(BigType x) { arr.push_back(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } int main() { BigType x; func(std::move(x)); // \u62f7\u8d1d 4000 \u5b57\u8282\uff0c\u8d85\u6162\uff0cmove \u4e5f\u6ca1\u7528 } \u5982\u4f55\u52a0\u901f\u8fd9\u79cd\u672c\u8eab\u8d85\u5927\u7684\u53d8\u91cf\u8f6c\u79fb\uff1f\u4f7f\u7528 const \u5f15\u7528\uff1a void func(BigType const &x) \u4f3c\u4e4e\u53ef\u4ee5\u907f\u514d\u4f20\u53c2\u65f6\u7684\u62f7\u8d1d\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u80fd\u907f\u514d push_back \u63a8\u5165 vector \u65f6\u6240\u4e0d\u5f97\u5df2\u7684\u62f7\u8d1d\u3002 \u5c0f\u6280\u5de7\uff1a\u6539\u7528 unique_ptr using BigType = array; // 4000 \u5b57\u8282\u5927\u5c0f\u7684\u5e73\u5766\u7c7b\u578b using BigTypePtr = unique_ptr; vector arr; void func(BigTypePtr x) { arr.push_back(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488\uff0c\u5176\u6307\u5411\u7684 4000 \u5b57\u8282\u4e0d\u7528\u6df1\u62f7\u8d1d\u4e86\uff0c\u76f4\u63a5\u79fb\u52a8\u6240\u6709\u6743\u7ed9 vector \u91cc\u7684 BigTypePtr \u667a\u80fd\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } int main() { BigTypePtr x = make_unique(); // \u6ce8\u610f\uff1a\u7528\u667a\u80fd\u6307\u9488\u7684\u8bdd\uff0c\u9700\u8981\u7528 make_unique \u624d\u80fd\u521b\u5efa\u5bf9\u8c61\u4e86 func(std::move(x)); // \u53ea\u62f7\u8d1d 8 \u5b57\u8282\u7684\u6307\u9488 // \u7531\u4e8e\u79fb\u8d70\u4e86\u6240\u6709\u6743\uff0cx \u6b64\u65f6\u5df2\u7ecf\u4e3a nullptr } \u4e0a\u9762\u6574\u4e2a\u7a0b\u5e8f\u4e2d\uff0c\u4e00\u5f00\u59cb\u901a\u8fc7 make_unique \u521b\u5efa\u7684\u8d85\u5927\u5bf9\u8c61\uff0c\u5168\u7a0b\u6ca1\u6709\u53d1\u751f\u4efb\u4f55\u79fb\u52a8\uff0c\u907f\u514d\u4e86\u65e0\u8c13\u7684\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u6765\u8bf4\uff0c\u4e5f\u53ef\u4ee5\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u5c31\u80fd\u5728\u51fd\u6570\u4e4b\u95f4\u7a7f\u68ad\u81ea\u5982\u4e86\u3002 // \u70ed\u77e5\u8bc6\uff1astd::mutex \u4e0d\u652f\u6301\u79fb\u52a8 void func(std::mutex lock); int main() { std::mutex lock; func(std::move(lock)); // \u9519\u8bef\uff1amutex(mutex &&) = delete } void func(std::unique_ptr lock); int main() { std::unique_ptr lock = std::make_unique(); func(std::move(lock)); // OK\uff1a\u8c03\u7528\u7684\u662f unique_ptr(unique_ptr &&)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b } \u66f4\u597d\u7684\u662f shared_ptr \uff0c\u8fde std::move \u90fd\u4e0d\u7528\u5199\uff0c\u66f4\u7701\u5fc3\u3002 void func(std::shared_ptr lock); int main() { std::shared_ptr lock = std::make_shared(); func(lock); // OK\uff1a\u8c03\u7528\u7684\u662f shared_ptr(shared_ptr const &)\uff0c\u4e0d\u5173 mutex \u4ec0\u4e48\u4e8b func(lock); // OK\uff1ashared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\uff0c\u5373\u4f7f\u6d45\u62f7\u8d1d\u53d1\u751f\u591a\u6b21\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4e5f\u4e0d\u4f1a\u88ab\u62f7\u8d1d\u6216\u79fb\u52a8 }","title":"\u667a\u80fd\u6307\u9488\u9632\u6b62\u5927\u5bf9\u8c61\u79fb\u52a8"},{"location":"cpp_tricks/#optional","text":"\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u7c7b\uff0c\u5177\u6709\u81ea\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\uff0c\u4e14\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a struct SomeClass { int m_i; int m_j; SomeClass(int i, int j) : m_i(i), m_j(j) {} }; \u5f53\u6211\u4eec\u9700\u8981\u201c\u5ef6\u8fdf\u521d\u59cb\u5316\u201d\u65f6\u600e\u4e48\u529e\uff1f SomeClass c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c); \u53ef\u4ee5\u5229\u7528 optional \u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u201c\u7a7a\u201d\u7684\u7279\u6027\uff0c\u5b9e\u73b0\u5ef6\u8fdf\u8d4b\u503c\uff1a std::optional c; if (test()) { c = SomeClass(1, 2); } else { c = SomeClass(2, 3); } do_something(c.value()); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u5c31\u4f1a\u62a5\u9519\uff0c\u4ece\u800c\u628a\u7f16\u8bd1\u671f\u7684\u672a\u521d\u59cb\u5316\u8f6c\u6362\u4e3a\u8fd0\u884c\u65f6\u5f02\u5e38 \u5c31\u7c7b\u4f3c\u4e8e Python \u4e2d\u5148\u7ed9\u53d8\u91cf\u8d4b\u503c\u4e3a None\uff0c\u7136\u540e\u5728\u5faa\u73af\u6216 if \u91cc\u6761\u4ef6\u6027\u5730\u8d4b\u503c\u4e00\u6837\u3002 \u5982\u679c\u8981\u8fdb\u4e00\u6b65\u907f\u514d c = \u65f6\uff0c\u79fb\u52a8\u6784\u9020\u7684\u5f00\u9500\uff0c\u4e5f\u53ef\u4ee5\u7528 unique_ptr \u6216 shared_ptr \uff1a std::shared_ptr c; if (test()) { c = std::make_shared(1, 2); } else { c = std::make_shared(2, 3); } do_something(c); // \u5982\u679c\u62b5\u8fbe\u6b64\u5904\u524d\uff0cc \u6ca1\u6709\u521d\u59cb\u5316\uff0c\u90a3\u4e48\u4f20\u5165\u7684\u5c31\u662f\u4e00\u4e2a nullptr\uff0cdo_something \u5185\u90e8\u9700\u8981\u8d1f\u8d23\u68c0\u6d4b\u6307\u9488\u662f\u5426\u4e3a nullptr \u5982\u679c do_something \u53c2\u6570\u9700\u8981\u7684\u662f\u539f\u59cb\u6307\u9488\uff0c\u53ef\u4ee5\u7528 .get() \u83b7\u53d6\u51fa\u6765\uff1a do_something(c.get()); // .get() \u53ef\u4ee5\u628a\u667a\u80fd\u6307\u9488\u8f6c\u6362\u56de\u539f\u59cb\u6307\u9488\uff0c\u4f46\u8bf7\u6ce8\u610f\u539f\u59cb\u6307\u9488\u4e0d\u6301\u6709\u5f15\u7528\uff0c\u4e0d\u4f1a\u5ef6\u4f38\u6307\u5411\u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5b9e\u9645\u4e0a\uff0cJava\u3001Python \u4e2d\u7684\u4e00\u5207\u5bf9\u8c61\uff08\u9664 int\u3001str \u7b49\u201c\u94a6\u5b9a\u201d\u7684\u57fa\u7840\u7c7b\u578b\u5916\uff09\u90fd\u662f\u5f15\u7528\u8ba1\u6570\u7684\u667a\u80fd\u6307\u9488 shared_ptr \uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u4e00\u5207\u7686\u6307\u9488\u4e86\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u597d\u50cf\u6ca1\u6709\u6307\u9488\u4e86\u3002","title":"optional \u5b9e\u73b0\u5ef6\u8fdf\u521d\u59cb\u5316"},{"location":"cpp_tricks/#if-auto-while-auto","text":"\u9700\u8981\u5148\u5b9a\u4e49\u4e00\u4e2a\u53d8\u91cf\uff0c\u7136\u540e\u5224\u65ad\u67d0\u4e9b\u6761\u4ef6\u7684\u60c5\u51b5\uff0c\u975e\u5e38\u5e38\u89c1\uff1a extern std::optional some_func(); auto opt = some_func(); if (opt.has_value()) { std::cout << opt.value(); } C++17 \u5f15\u5165\u7684 if-auto \u8bed\u6cd5\uff0c\u53ef\u4ee5\u5c31\u5730\u4e66\u5199\u53d8\u91cf\u5b9a\u4e49\u548c\u5224\u65ad\u6761\u4ef6\uff1a extern std::optional some_func(); if (auto opt = some_func(); opt.has_value()) { std::cout << opt.value(); } \u5bf9\u4e8e\u652f\u6301 (bool)opt \u7684 optional \u7c7b\u578b\u6765\u8bf4\uff0c\u540e\u9762\u7684\u6761\u4ef6\u4e5f\u53ef\u4ee5\u7701\u7565\uff1a extern std::optional some_func(); if (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a auto opt = some_func(); if (opt) { std::cout << opt.value(); } \u7c7b\u4f3c\u7684\u8fd8\u6709 while-auto\uff1a extern std::optional some_func(); while (auto opt = some_func()) { std::cout << opt.value(); } // \u7b49\u4ef7\u4e8e\uff1a while (true) { auto opt = some_func(); if (!opt) break; std::cout << opt.value(); } if-auto \u6700\u5e38\u89c1\u7684\u914d\u5408\u83ab\u8fc7\u4e8e map.find\uff1a std::map table; int key = 42; if (auto it = table.find(key); it != table.end()) { std::cout << it->second << '\\n'; } else { std::cout << \"not found\\n\"; }","title":"if-auto \u4e0e while-auto"},{"location":"cpp_tricks/#bind-lambda","text":"\u4f17\u6240\u5468\u77e5\uff0c std::bind \u53ef\u4ee5\u4e3a\u51fd\u6570\u7ed1\u5b9a\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\uff08\u5bf9\u8c61\uff09\u3002 int func(int x, int y) { printf(\"func(%d, %d)\\n\", x, y); return x + y; } auto new_func = std::bind(func, 1, std::placeholders::_1); new_func(2); // \u8c03\u7528 new_func(2) \u65f6\uff0c\u5b9e\u9645\u4e0a\u8c03\u7528\u7684\u662f func(1, 2) } \u8f93\u51fa\uff1a func(1, 2) \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; };","title":"bind \u662f\u5386\u53f2\u7cdf\u7c95\uff0c\u5e94\u8be5\u7531 Lambda \u8868\u8fbe\u5f0f\u53d6\u4ee3"},{"location":"cpp_tricks/#bind","text":"\u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002","title":"bind \u7684\u5386\u53f2"},{"location":"cpp_tricks/#thread","text":"\u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42","title":"thread \u819d\u76d6\u4e2d\u7bad"},{"location":"cpp_tricks/#_13","text":"bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand();","title":"\u4e3e\u4e2a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668\u4f8b\u5b50"},{"location":"cpp_tricks/#forward-fwd","text":"\u4f17\u6240\u5468\u77e5\uff0c\u5f53\u4f60\u5728\u8f6c\u53d1\u4e00\u4e2a\u201c\u4e07\u80fd\u5f15\u7528\u201d\u53c2\u6570\u65f6\uff1a template void some_func(Arg &&arg) { other_func(arg); } \u5982\u679c\u6b64\u5904 arg \u4f20\u5165\u7684\u662f\u53f3\u503c\u5f15\u7528\uff0c\u90a3\u4e48\u4f20\u5165 other_func \u5c31\u4f1a\u53d8\u56de\u5de6\u503c\u5f15\u7528\u4e86\uff0c\u4e0d\u7b26\u5408\u5b8c\u7f8e\u8f6c\u53d1\u7684\u8981\u6c42\u3002 \u56e0\u6b64\u5f15\u5165\u4e86 forward \uff0c\u4ed6\u4f1a\u68c0\u6d4b arg \u662f\u5426\u4e3a\u201c\u53f3\u503c\u201d\uff1a\u5982\u679c\u662f\uff0c\u5219 forward \u7b49\u4ef7\u4e8e move \uff1b\u5982\u679c\u4e0d\u662f\uff0c\u5219 forward \u4ec0\u4e48\u90fd\u4e0d\u505a\uff08\u9ed8\u8ba4\u5c31\u662f\u5de6\u503c\u5f15\u7528\uff09\u3002 \u8fd9\u5f04\u5f97 forward \u7684\u5916\u89c2\u975e\u5e38\u5177\u6709\u8ff7\u60d1\u6027\uff0c\u53c8\u662f\u5c16\u62ec\u53f7\u53c8\u662f\u5706\u62ec\u53f7\u7684\u3002 template void some_func(Arg &&arg) { other_func(std::forward(arg)); } \u5b9e\u9645\u4e0a\uff0cforward \u7684\u7528\u6cd5\u975e\u5e38\u5355\u4e00\uff1a\u6c38\u8fdc\u662f forward(t) \u7684\u5f62\u5f0f\uff0c\u5176\u4e2d T \u662f t \u53d8\u91cf\u7684\u7c7b\u578b\u3002 \u53c8\u662f\u52b3\u4fdd\u7684\u9b45\u529b\uff0c\u5229\u7528\u540c\u6837\u662f C++11 \u7684 decltype \u5c31\u80fd\u83b7\u5f97 t \u5b9a\u4e49\u65f6\u7684 T \u3002 void some_func(auto &&arg) { other_func(std::forward(arg)); } \u6240\u4ee5 std::forward(arg) \u5b9e\u9645\u624d\u662f forward \u7684\u6b63\u786e\u7528\u6cd5\uff0c\u53ea\u4e0d\u8fc7\u56e0\u4e3a\u5927\u591a\u6570\u65f6\u5019\u4f60\u662f\u6a21\u677f\u53c2\u6570 Arg && \uff0c\u6709\u7684\u4eba\u5077\u61d2\uff0c\u5c31\u628a decltype(arg) \u66ff\u6362\u6210\u5df2\u7ecf\u5339\u914d\u597d\u7684\u6a21\u677f\u53c2\u6570 Arg \u4e86\uff0c\u5b9e\u9645\u4e0a\u662f\u7b49\u4ef7\u7684\u3002 \u8fd9\u91cc\u9700\u8981\u590d\u8bfb arg \u592a\u7eb1\u5e01\u4e86\u3002\u5b9e\u9645\u4e0a\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5b8f\uff1a #define FWD(arg) std::forward(arg) \u8fd9\u6837\u5c31\u53ef\u4ee5\u7b80\u5316\u4e3a\uff1a void some_func(auto &&arg) { other_func(FWD(arg)); } \u5c11\u4e86\u70e6\u4eba\u7684\u5c16\u62ec\u53f7\uff0c\u770b\u8d77\u6765\u5bb9\u6613\u61c2\u591a\u4e86\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u540c\u5b66\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u4e3a\u4ec0\u4e48 std::forward \u8981\u5199\u6210 std::forward \u7684\u5f62\u5f0f\u5462\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u662f std::forward(t) \u5462\uff1f\u56e0\u4e3a\u8fd9\u6837\u5199\u7684\u8bdd\uff0c forward \u4e5f\u6ca1\u6cd5\u77e5\u9053\u4f60\u7684 t \u662f\u5de6\u662f\u53f3\u4e86\uff08\u51fd\u6570\u53c2\u6570\u59cb\u7ec8\u4f1a\u9ed8\u8ba4\u63a8\u5bfc\u4e3a\u5de6\uff0c\u5373\u4f7f\u5b9a\u4e49\u7684 t \u662f\u53f3\uff09\u56e0\u6b64\u5fc5\u987b\u544a\u8bc9 forward \uff0c t \u7684\u5b9a\u4e49\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f T \uff0c\u6216\u8005\u901a\u8fc7 decltype(t) \u6765\u83b7\u5f97 T \u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7528\u7684\u662f auto && \u53c2\u6570\uff0c\u90a3\u4e48 FWD \u4f1a\u5f88\u65b9\u4fbf\uff08\u81ea\u52a8\u5e2e\u4f60 decltype \uff09\u3002\u4f46\u662f\u5982\u679c\u4f60\u7528\u7684\u662f\u6a21\u677f\u53c2\u6570 T && \uff0c\u90a3\u4e48 FWD \u4e5f\u53ef\u4ee5\u7528\uff0c\u56e0\u4e3a decltype(t) \u603b\u662f\u5f97\u5230 T \u3002","title":"forward \u8ff7\u60d1\u6027\u5730\u4e0d\u597d\u7528\uff0c\u5efa\u8bae\u6539\u7528 FWD \u5b8f"},{"location":"cpp_tricks/#bind-lambda-bind_front","text":"\u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408\u4e0a\u6587\u63d0\u5230\u7684 FWD \u5b8f\u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(FWD(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u540c\u6837\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u79f0\u624b\u7684\u5b8f\uff1a #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } \u8fd9\u91cc\u4f7f\u7528\u4e86\u5b8f\u53c2\u6570\u5305\uff0c\u6b64\u5904 __VA_ARGS__ \u5c31\u662f\u5b8f\u7684 ... \u4e2d\u7684\u5185\u5bb9\u3002\u6ce8\u610f\u533a\u5206\u5b8f\u7684 ... \u548c C++ \u53d8\u957f\u6a21\u677f\u7684 ... \u662f\u4e92\u76f8\u72ec\u7acb\u7684\u3002 struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = BIND(world, this); int x = 1; memfn(x, 2); memfn(3.14); } } int main() { // \u6355\u83b7\u975e this \u7684\u6210\u5458\u51fd\u6570\u4e5f OK\uff1a Class c; auto memfn = BIND(c.world, &c); // [&c] \u6309\u5f15\u7528\u6355\u83b7 c \u53d8\u91cf // \u5c55\u5f00\u4e3a\uff1a auto memfn = [&c] (auto &&..._args) { c.world(std::forward(_args)...); } memfn(3.14); } BIND \u8fd9\u4e2a\u540d\u5b57\u662f\u968f\u4fbf\u53d6\u7684\uff0c\u53d6\u8fd9\u4e2a\u540d\u5b57\u662f\u4e3a\u4e86\u8fb1 std::bind \u3002 \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u8fd8\u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f","title":"bind \u7ed1\u5b9a\u6210\u5458\u51fd\u6570\u662f\u964b\u4e60\uff0c\u6539\u7528 lambda \u6216 bind_front"},{"location":"cpp_tricks/#_14","text":"\u5f53\u4f60\u7684\u5168\u5c40\u51fd\u6570\u662f\u6a21\u677f\u51fd\u6570\uff0c\u6216\u5e26\u6709\u91cd\u8f7d\u7684\u51fd\u6570\u65f6\uff1a template T square(T const t) { return t * t; } template void do_something(Fn &&fn) { fn(2); fn(3.14); } int main() { do_something(square); // \u7f16\u8bd1\u9519\u8bef\uff1a\u6709\u6b67\u4e49\u7684\u91cd\u8f7d } \u5c31\u4f1a\u51fa\u73b0\u8fd9\u6837\u607c\u4eba\u7684\u7f16\u8bd1\u9519\u8bef\uff1a test.cpp: In instantiation of 'void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]': test.cpp:18:21: required from here test.cpp:14:9: error: no matching function for call to 'do_something()' do_something(square); ^~~~~~~~~~~~~ test.cpp:7:3: note: candidate: 'template void do_something(Fn&&) [with Fn = T (*)(T) [with T = double]]' void do_something(Fn &&fn) { ^~~~~~~~~~~~~ test.cpp:7:3: note: template argument deduction/substitution failed: test.cpp:14:21: note: couldn't deduce template parameter 'Fn' do_something(square); ~~~~~~~~~~~~~^~~~~~ \u8fd9\u662f\u56e0\u4e3a\uff0c\u6a21\u677f\u51fd\u6570\u548c\u6709\u91cd\u8f7d\u7684\u51fd\u6570\uff0c\u662f\u201c\u591a\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u201c\u5e7b\u60f3\u8054\u5408\u4f53\u201d\uff0c\u800c do_something \u7684 Fn \u9700\u8981\u201c\u5355\u4e2a\u201d\u5177\u4f53\u7684\u51fd\u6570\u5bf9\u8c61\u3002 \u4e00\u822c\u6765\u8bf4\u662f\u9700\u8981 square \u548c square \u624d\u80fd\u53d8\u6210\u201c\u5177\u4f53\u201d\u7684\u201c\u5355\u4e2a\u201d\u51fd\u6570\u5bf9\u8c61\uff0c\u4f20\u5165 do_something \u7684 Fn \u6a21\u677f\u53c2\u6570\u3002 \u4f46\u662f\u5728\u201c\u51fd\u6570\u8c03\u7528\u201d\u7684\u8bed\u5883\u4e0b\uff0c\u56e0\u4e3a\u5df2\u77e5\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u5f97\u76ca\u4e8e C++ \u7684\u201c\u91cd\u8f7d\u201d\u673a\u5236\uff0c\u5e26\u6709\u6a21\u677f\u53c2\u6570\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u81ea\u52a8\u5339\u914d\u90a3\u4e2a\u6a21\u677f\u53c2\u6570\u4e3a\u4f60\u53c2\u6570\u7684\u7c7b\u578b\u3002 \u4f46\u73b0\u5728\u4f60\u5e76\u6ca1\u6709\u6307\u5b9a\u8c03\u7528\u53c2\u6570\uff0c\u800c\u53ea\u662f\u6307\u5b9a\u4e86\u4e00\u4e2a\u51fd\u6570\u540d square \uff0c\u90a3 C++ \u201c\u91cd\u8f7d\u201d\u673a\u5236\u65e0\u6cd5\u786e\u5b9a\u4f60\u9700\u8981\u7684\u662f square \u8fd8\u662f square \u4e2d\u7684\u54ea\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u4ed6\u4eec\u7684\u7c7b\u578b\u90fd\u4e0d\u540c\uff0c\u5c31\u65e0\u6cd5\u5177\u8c61\u82b1\u51fa\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b Fn \u6765\uff0c\u5bfc\u81f4 \u9519\u8bef\u3002 \u6709\u8da3\u7684\u662f\uff0c\u53ea\u9700\u8981\u5957\u4e00\u5c42 lambda \u5c31\u80fd\u89e3\u51b3\uff1a do_something([] (auto x) { return square(x); }); // \u7f16\u8bd1\u901a\u8fc7 \u6216\u8005\u7528\u6211\u4eec\u4e0a\u9762\u63a8\u8350\u7684 BIND \u5b8f\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } do_something(BIND(square)); // \u7f16\u8bd1\u901a\u8fc7 \u6709\u65f6\u5019\uff0c\u5982\u679c\u4f60\u60f3\u4f20\u9012 this \u7684\u6210\u5458\u51fd\u6570\u4e3a\u51fd\u6570\u5bf9\u8c61\uff0c\u4e5f\u4f1a\u51fa\u73b0\u8fd9\u79cd\u607c\u4eba\u7684\u9519\u8bef\uff1a struct Class { int func(int x) { return x + 1; } void test() { do_something(this->func); // \u8fd9\u91cc\u53c8\u4f1a\u4ea7\u751f\u70e6\u4eba\u7684 unresolved overload \u9519\u8bef\uff01 } }; \u540c\u6837\u53ef\u4ee5\u5305\u4e00\u5c42 lambda\uff0c\u6216\u8005\u7528\u5c0f\u5f6d\u8001\u5e08\u63d0\u4f9b\u7684 BIND \u5b8f\uff0c\u9ebb\u75f9\u7684\u7f16\u8bd1\u5668\u5c31\u4e0d\u72d7\u53eb\u4e86\uff1a #define FWD(arg) std::forward(arg) #define BIND(func, ...) [__VA_ARGS__] (auto &&..._args) { func(FWD(_args)...); } void test() { do_something(BIND(func, this)); // \u641e\u5b9a } \u5efa\u8bae\u4fee\u6539\u6807\u51c6\u5e93\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u8fd9\u4e24\u4e2a\u771f\u6b63\u597d\u7528\u7684\u5b8f\u585e\u5230 \u548c \u91cc\uff0c\u4f5c\u4e3a C++26 \u6807\u51c6\u7684\u4e00\u90e8\u5206\u3002","title":"\u6551\u547d\uff01\u4e3a\u4ec0\u4e48\u6211\u7684\u5168\u5c40\u51fd\u6570\u4e0d\u80fd\u4f5c\u4e3a\u51fd\u6570\u5bf9\u8c61\uff1f"},{"location":"cpp_tricks/#map-any","text":"TODO","title":"map + any \u5916\u6302\u5c5e\u6027"},{"location":"cpp_tricks/#shared_ptr-deleter","text":"","title":"\u81ea\u5b9a\u4e49 shared_ptr \u7684 deleter"},{"location":"cpp_tricks/#check_cuda","text":"","title":"CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f"},{"location":"cpp_tricks/#_15","text":"","title":"\u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005"},{"location":"cpp_tricks/#locale-utf8","text":"","title":"\u8bbe\u7f6e locale \u4e3a .utf8"},{"location":"cpp_tricks/#_16","text":"","title":"\u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5"},{"location":"cpp_tricks/#this","text":"","title":"\u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d"},{"location":"cpp_tricks/#check_cuda_1","text":"","title":"CHECK_CUDA \u7c7b\u9519\u8bef\u68c0\u6d4b\u5b8f"},{"location":"cpp_tricks/#_17","text":"","title":"\u51fd\u6570\u9ed8\u8ba4\u53c2\u6570\u6c42\u503c\u7684\u4f4d\u7f6e\u662f\u8c03\u7528\u8005"},{"location":"cpp_tricks/#_18","text":"","title":"\u82b1\u62ec\u53f7\u5b9e\u73b0\u5b89\u5168\u7684\u7c7b\u578b\u8f6c\u6362\u68c0\u67e5"},{"location":"cpp_tricks/#_19","text":"C++ \u6709\u4e2a\u7279\u6027\uff1a\u652f\u6301\u7eaf\u53f3\u503c(prvalue)\u9690\u5f0f\u8f6c\u6362\u6210 const \u7684\u5de6\u503c\u5f15\u7528\u3002 \u7ffb\u8bd1\uff1a int && \u53ef\u4ee5\u81ea\u52a8\u8f6c\u6362\u6210 int const & \u3002 void func(int const &i); func(1); // OK\uff1a\u81ea\u52a8\u521b\u5efa\u4e00\u4e2a\u53d8\u91cf\u4fdd\u5b58 1\uff0c\u7136\u540e\u4f5c\u4e3a int const & \u53c2\u6570\u4f20\u5165 \u5b9e\u9645\u4e0a\u5c31\u7b49\u4ef7\u4e8e\uff1a const int tmp = 1; func(tmp); \u4f46\u662f\uff0c int && \u5374\u4e0d\u80fd\u81ea\u52a8\u8f6c\u6362\u6210 int & \u3002 void func(int &i); func(1); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece int && \u81ea\u52a8\u8f6c\u6362\u6210 int & C++ \u5b98\u65b9\u8bbe\u7f6e\u8fd9\u4e2a\u9650\u5236\uff0c\u662f\u51fa\u4e8e\u8bed\u4e49\u5b89\u5168\u6027\u8003\u8651\uff0c\u56e0\u4e3a\u53c2\u6570\u63a5\u53d7 int & \u7684\uff0c\u4e00\u822c\u90fd\u610f\u5473\u7740\u8fd9\u4e2a\u662f\u7528\u4f5c\u8fd4\u56de\u503c\uff0c\u800c\u5982\u679c func \u7684\u53c2\u6570\u662f\uff0c func(1) \u3002 \u4e3a\u4e86\u7ed5\u5f00\u8fd9\u4e2a\u89c4\u5219\uff0c\u6211\u4eec\u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u5e2e\u624b\u51fd\u6570\uff1a T &temporary(T const &t) { return const_cast(t); } // \u6216\u8005\uff1a T &temporary(T &&t) { return const_cast(t); } \u7136\u540e\uff0c\u5c31\u53ef\u4ee5\u5feb\u4e50\u5730\u8f6c\u6362\u7eaf\u53f3\u503c\u4e3a\u975e const \u5de6\u503c\u4e86\uff1a void func(int &i); func(temporary(1)); \u5728 Libreoffice \u6e90\u7801\u4e2d\u5c31\u6709\u5e94\u7528\u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\u3002 \u4e34\u65f6\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u662f\u4e00\u884c","title":"\u4e34\u65f6\u53f3\u503c\u8f6c\u5de6\u503c"},{"location":"cpp_tricks/#ostringstream","text":"std::string name = \"\u4f60\u597d\"; int answer = 42; auto str = std::format(\"\u4f60\u597d\uff0c{}\uff01\u7b54\u6848\u662f {}\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x{:02x}\\n\", name, answer, answer); \u6ca1\u6709 C++20 \u4e4b\u524d\uff0c\u8981\u4e48\u4f7f\u7528\u7b2c\u4e09\u65b9\u7684 fmt::format \uff0c\u8981\u4e48\u53ea\u80fd\u4f7f\u7528\u5b57\u7b26\u4e32\u7684 + \u8fd0\u7b97\u7b26\u62d9\u52a3\u5730\u62fc\u63a5\uff1a auto str = std::string(\"\u4f60\u597d\uff0c\") + name + \"\uff01\u7b54\u6848\u662f \" + std::to_string(answer) + \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" + std::to_string(answer) + \"\\n\"; \u8fd9\u6837\u505a\u6548\u7387\u4f4e\u4e0b\uff0c\u4e14\u4e0d\u6613\u9605\u8bfb\u3002\u800c\u4e14\u4e5f\u65e0\u6cd5\u5b9e\u73b0\u6570\u5b57\u6309\u201c\u5341\u516d\u8fdb\u5236\u201d\u8f6c\u5b57\u7b26\u4e32\u3002 \u53ef\u4ee5\u7528 std::ostringstream \uff0c\u5176\u7528\u6cd5\u4e0e std::cout \u76f8\u540c\u3002\u53ea\u4e0d\u8fc7\u4f1a\u628a\u7ed3\u679c\u5199\u5165\u4e00\u4e2a\u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f\u76f4\u63a5\u8f93\u51fa\uff09\uff0c\u53ef\u4ee5\u7528 .str() \u53d6\u51fa\u90a3\u4e2a\u5b57\u7b26\u4e32\u3002 #include std::ostringstream oss; oss << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\"; auto str = oss.str(); \u5229\u7528\u4e34\u65f6\u53d8\u91cf\u8bed\u6cd5\uff0c\u53ef\u4ee5\u6d53\u7f29\u5199\u5728\u4e00\u884c\u91cc\uff0c\u505a\u4e2a format \u62d9\u52a3\u7684\u6a21\u4eff\u8005\uff1a auto str = (std::ostringstream() << \"\u4f60\u597d\uff0c\" << name << \"\uff01\u7b54\u6848\u662f \" << answer << \"\uff0c\u5341\u516d\u8fdb\u5236\uff1a0x\" << std::hex << std::setfill('0') << std::setw(2) << answer << \"\\n\").str();","title":"ostringstream \u683c\u5f0f\u5316\u5b57\u7b26\u4e32"},{"location":"cpp_tricks/#adl","text":"TODO","title":"ADL \u673a\u5236\u5b9e\u73b0\u9759\u6001\u591a\u6001"},{"location":"cpp_tricks/#shared_from_this","text":"","title":"shared_from_this"},{"location":"cpp_tricks/#requires","text":"","title":"requires \u8bed\u6cd5\u68c0\u6d4b\u662f\u5426\u5b58\u5728\u6307\u5b9a\u6210\u5458\u51fd\u6570"},{"location":"cpp_tricks/#locale-utf8-windows","text":"system(\"chcp 65001\"); setlocale(\"LC_ALL\", \".utf-8\"); \u8be6\u89c1 Unicode \u4e13\u9898\u7ae0\u8282 \u3002","title":"\u8bbe\u7f6e locale \u4e3a .utf8 \u89e3\u51b3 Windows \u7f16\u7801\u96be\u95ee\u9898"},{"location":"cpp_tricks/#this_1","text":"","title":"\u6210\u5458\u51fd\u6570\u9488\u5bf9 this \u7684\u79fb\u52a8\u91cd\u8f7d"},{"location":"cpp_tricks/#bit-field","text":"\u5728\u4e92\u8054\u7f51\u7f16\u7a0b\u548c\u5404\u79cd\u4e0e\u786c\u76d8\u3001\u5e8f\u5217\u5316\u6253\u4ea4\u9053\u7684\u573a\u666f\u4e2d\uff0c\u5e38\u5e38\u9700\u8981\u6309\u4f4d\u62c6\u5206\u5355\u4e2a\u5b57\u8282\u3002 C \u8bed\u8a00\u6709\u4e13\u95e8\u7167\u987e\u6b64\u7c7b\u5de5\u4f5c\u7684\u8bed\u6cd5\u7cd6\uff1a\u4f4d\u57df\u3002 \u4f4d\u57df\u662f\u4e00\u79cd\u7279\u6b8a\u7684\u7ed3\u6784\u4f53\u6210\u5458\uff0c\u53ef\u4ee5\u5bf9\u4f4d\u8fdb\u884c\u5206\u7ec4\uff0c\u65b9\u4fbf\u8bfb\u53d6\u3002\u4f8b\u5982\uff0c\u6211\u4eec\u60f3\u8981\u4ece\u4e00\u4e2a\u5b57\u8282\u4e2d\u8bfb\u53d6\u4e09\u4e2a\u72b6\u6001\u4f4d\uff1a struct Flag { uint8_t a : 4; // \u4f4e 4 \u4f4d uint8_t b : 4; // \u9ad8 4 \u4f4d }; sizeof(Flag); // 1 \u5b57\u8282\u5927\u5c0f\uff08\u5171 8 \u4f4d\uff09 Flag f = std::bit_cast(0x21); f.a; // 0x1 f.b; // 0x2 \u4ee5\u4e0a\u7684\u4ee3\u7801\u7b49\u4ef7\u4e8e\uff1a uint8_t f = 0x21; int a = f & 0xF; // 0x1 int b = f >> 4; // 0x2","title":"\u4f4d\u57df\uff08bit-field\uff09"},{"location":"cpp_tricks/#vector-unordered_map-lru-cache","text":"","title":"vector + unordered_map = LRU cache"},{"location":"cpp_tricks/#lambda-unique_ptr-function","text":"","title":"Lambda \u6355\u83b7 unique_ptr \u5bfc\u81f4 function \u62a5\u9519\u600e\u4e48\u529e"},{"location":"cpp_tricks/#_20","text":"","title":"\u591a\u7ebf\u7a0b\u901a\u4fe1\u5e94\u57fa\u4e8e\u961f\u5217\uff0c\u800c\u4e0d\u662f\u5171\u4eab\u5168\u5c40\u53d8\u91cf"},{"location":"cpp_tricks/#raii-finally","text":"","title":"RAII \u7684 finally \u5e2e\u624b\u7c7b"},{"location":"cpp_tricks/#swap-mutex","text":"","title":"swap \u7f29\u5c0f mutex \u533a\u95f4\u4ee3\u4ef7"},{"location":"cpp_tricks/#namespace","text":"\u6709\u4e9b\u5d4c\u5957\u5f88\u6df1\u7684\u540d\u5b57\u7a7a\u95f4\u6bcf\u6b21\u90fd\u8981\u590d\u8bfb\u975e\u5e38\u5570\u55e6\u3002 #include int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u5982\u679c using namespace \u7684\u8bdd\uff0c\u53c8\u89c9\u5f97\u6c61\u67d3\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\u4e86\u3002 #include using namespace std::filesystem; int main() { std::filesystem::path p = \"/var/www/html\"; ... } \u53ef\u4ee5\u7528 C++11 \u7684 namespace = \u8bed\u6cd5\uff0c\u7ed9\u540d\u5b57\u7a7a\u95f4\u53d6\u4e2a\u522b\u540d\u3002 #include namespace fs = std::filesystem; int main() { fs::path p = \"/var/www/html\"; ... } \u8fd9\u6837\u4ee5\u540e\u5c31\u53ef\u4ee5 fs \u8fd9\u4e2a\u7b80\u79f0\u8bbf\u95ee\u4e86\u3002","title":"namespace \u522b\u540d"},{"location":"cuda_intro/","text":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u5b89\u88c5 CUDA \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 CUDA C++ \u7248\u672c \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u521b\u5efa CUDA \u9879\u76ee CMake \u914d\u7f6e\u603b\u7ed3 \u5f00\u59cb\u7f16\u5199 CUDA \u53c2\u8003\u8d44\u6599\uff1a https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html https://www.cs.sfu.ca/~ashriram/Courses/CS431/assets/lectures/Part8/GPU1.pdf \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u786c\u4ef6\u65b9\u9762\u5efa\u8bae\u4f7f\u7528\u81f3\u5c11 GTX 1060 \u4ee5\u4e0a\u663e\u5361\uff0c\u4f46\u662f\u66f4\u8001\u7684\u663e\u5361\u4e5f\u53ef\u4ee5\u8fd0\u884c\u3002 \u8f6f\u4ef6\u65b9\u9762\u5219\u53ef\u4ee5\u5c3d\u53ef\u80fd\u6700\u65b0\uff0c\u4ee5\u83b7\u5f97 CUDA C++20 \u652f\u6301\uff0c\u6211\u5b89\u88c5\u7684\u7248\u672c\u662f CUDA 12.5\u3002 \u4ee5\u4e0b\u4ec5\u6f14\u793a Arch Linux \u4e2d\u5b89\u88c5 CUDA \u7684\u65b9\u6cd5\uff0c\u56e0\u4e3a Arch Linux \u5b98\u65b9\u6e90\u4e2d\u5c31\u81ea\u5e26 nvidia \u9a71\u52a8\u548c cuda \u5305\uff0c\u800c\u4e14\u5f00\u7bb1\u5373\u7528\uff0c\u5176\u4ed6\u53d1\u884c\u7248\u8bf7\u81ea\u884c\u5982\u6cd5\u70ae\u5236\u3002 Wendous \u7528\u6237\u53ef\u80fd\u5728\u5b89\u88c5\u5b8c\u540e\u9047\u5230\u201c\u627e\u4e0d\u5230 cuxxx.dll\u201d\u62a5\u9519\uff0c\u8bf4\u660e\u4f60\u9700\u8981\u62f7\u8d1d CUDA \u5b89\u88c5\u76ee\u5f55\u4e0b\u7684\u6240\u6709 DLL \u5230 C:\\\\Windows\\\\System32 \u3002 WSL \u7528\u6237\u8981\u6ce8\u610f\uff0cWSL \u73af\u5883\u548c\u771f\u6b63\u7684 Linux \u76f8\u5dee\u751a\u8fdc\u3002\u5f88\u591a Linux \u4e0b\u7684\u6559\u7a0b\uff0c\u4f60\u4f1a\u53d1\u73b0\u5728 WSL \u91cc\u590d\u523b\u4e0d\u51fa\u6765\u3002\u8fd9\u662f WSL \u7684 bug\uff0c\u5e94\u8be5\u6c47\u62a5\u53bb\u8ba9\u5fae\u8f6f\u7edf\u4e00\u4fee\u590d\uff0c\u800c\u4e0d\u662f\u8ba9\u6559\u7a0b\u7684\u4f5c\u8005\u96f6\u96f6\u6563\u6563\u4e00\u4e2a\u4e2a\u4ee3\u5b83\u64e6\u5c41\u80a1\u3002\u5efa\u8bae\u76f4\u63a5\u5728 Wendous \u672c\u5730\u5b89\u88c5 CUDA \u53cd\u800c\u6bd4\u4f3a\u5019 WSL \u968f\u673a\u62c9\u7684 bug \u7701\u529b\u3002 Ubuntu \u7528\u6237\u53ef\u80fd\u8003\u8651\u5378\u8f7d Ubuntu\uff0c\u56e0\u4e3a Ubuntu \u6e90\u4e2d\u7684\u7248\u672c\u6c38\u4e0d\u66f4\u65b0\u3002\u60f3\u8981\u5b89\u88c5\u65b0\u51fa\u7684\u8f6f\u4ef6\u90fd\u975e\u5e38\u56f0\u96be\uff0c\u57fa\u672c\u53ea\u80fd\u5b89\u88c5\u5230\u4e94\u516d\u5e74\u524d\u7684\u53e4\u8463\u8f6f\u4ef6\uff0c\u8981\u4e48\u53ea\u80fd\u4ece\u7f51\u4e0a\u4e0b deb \u5305\uff0c\u548c Wendous \u4e00\u4e2a\u8f6f\u8038\u6837\u3002\u6240\u6709\u5b98\u65b9 apt \u6e90\u4e2d\u5305\u7684\u7248\u672c\u4ece Ubuntu \u53d1\u5e03\u90a3\u4e00\u5929\u5c31\u5b9a\u6b7b\u4e86\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u66f4\u65b0\u4e86\u3002\u8fd9\u662f\u4e3a\u4e86\u8d77\u591c\u7ea7\u670d\u52a1\u5668\u5b89\u5168\u7a33\u5b9a\u7684\u9700\u8981\uff0c\u5bf9\u4e8e\u4e2a\u4eba\u7535\u8111\u800c\u8a00\u5374\u53ea\u662f\u767d\u767d\u963b\u788d\u6211\u4eec\u5b66\u4e60\uff0cArch Linux \u8fd9\u6837\u7684\u6eda\u52a8\u66f4\u65b0\u7684\u53d1\u884c\u7248\u624d\u66f4\u9002\u5408\u4e2a\u4eba\u684c\u9762\u7528\u6237\u3002 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u9996\u5148\u786e\u4fdd\u4f60\u5b89\u88c5\u4e86 NVIDIA \u6700\u65b0\u9a71\u52a8\uff1a pacman -S nvidia \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u786e\u8ba4\u663e\u5361\u9a71\u52a8\u6b63\u5e38\u5de5\u4f5c\uff1a nvidia-smi \u5e94\u8be5\u80fd\u5f97\u5230\uff1a Mon Aug 26 14:09:15 2024 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 555.58.02 Driver Version: 555.58.02 CUDA Version: 12.5 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4070 ... Off | 00000000:01:00.0 On | N/A | | 0% 30C P8 17W / 285W | 576MiB / 16376MiB | 41% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 583 G /usr/lib/Xorg 370MiB | | 0 N/A N/A 740 G xfwm4 4MiB | | 0 N/A N/A 783 G /usr/lib/firefox/firefox 133MiB | | 0 N/A N/A 4435 G obs 37MiB | +-----------------------------------------------------------------------------------------+ \u5982\u679c\u4e0d\u884c\uff0c\u90a3\u5c31\u91cd\u542f\u3002 \u5b89\u88c5 CUDA \u7136\u540e\u5b89\u88c5 CUDA Toolkit\uff08\u5373 nvcc \u7f16\u8bd1\u5668\uff09\uff1a pacman -S cuda \u6253\u5f00 .bashrc \uff08\u5982\u679c\u4f60\u662f zsh \u7528\u6237\u5c31\u6253\u5f00 .zshrc \uff09\uff0c\u5728\u672b\u5c3e\u6dfb\u52a0\u4e24\u884c\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u662f\u9ed8\u8ba4\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # Arch Linux \u7528\u6237\u624d\u9700\u8981\u8fd9\u4e00\u884c \u7136\u540e\u91cd\u542f bash \uff0c\u6216\u8005\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u91cd\u8f7d\u73af\u5883\u53d8\u91cf\uff1a source .bashrc \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\u6d4b\u8bd5 CUDA \u7f16\u8bd1\u5668\u662f\u5426\u53ef\u7528\uff1a nvcc --version \u5e94\u8be5\u80fd\u5f97\u5230\uff1a nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2024 NVIDIA Corporation Built on Thu_Jun__6_02:18:23_PDT_2024 Cuda compilation tools, release 12.5, V12.5.82 Build cuda_12.5.r12.5/compiler.34385749_0 \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 CMake \u62a5\u9519\u627e\u4e0d\u5230 CUDA\uff1f\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # \u53ea\u6709 Arch Linux \u9700\u8981\u8fd9\u4e00\u884c IDE \u4f7f\u7528\u4e86 Clangd \u9759\u6001\u68c0\u67e5\u63d2\u4ef6\uff0c\u62a5\u9519\u4e0d\u8ba4\u8bc6 -forward-unknown-to-host-compiler \u9009\u9879\uff1f \u521b\u5efa\u6587\u4ef6 ~/.config/clangd/config.yaml \uff1a CompileFlags: Add: # \u8981\u989d\u5916\u6dfb\u52a0\u5230 Clang \u7684 NVCC \u6ca1\u6709\u7684\u53c2\u6570 - --no-cuda-version-check Remove: # \u79fb\u9664 Clang \u4e0d\u8ba4\u8bc6\u7684 NVCC \u53c2\u6570 - -forward-unknown-to-host-compiler - --expt-* - --generate-code=* - -arch=* - -rdc=* \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 \u5982\u679c\u4f60\u65e0\u6cd5\u641e\u5b9a\u73af\u5883\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 CMAKE_CUDA_COMPILER \u76f4\u63a5\u8bbe\u7f6e nvcc \u7f16\u8bd1\u5668\u7684\u8def\u5f84\uff1a set(CMAKE_CUDA_COMPILER \"/opt/cuda/bin/nvcc\") # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e \u4e0d\u5efa\u8bae\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a\u4f1a\u8ba9\u4f7f\u7528\u4f60\u9879\u76ee\u7684\u4eba\u4e5f\u88ab\u8feb\u628a CUDA \u5b89\u88c5\u5230\u8fd9\u4e2a\u8def\u5f84\u53bb\u3002 \u5efa\u8bae\u662f\u628a\u4f60\u7684 nvcc \u5b89\u88c5\u597d\u540e\uff0c\u901a\u8fc7 PATH \u73af\u5883\u53d8\u91cf\uff0c cmake \u5c31\u80fd\u627e\u5230\u4e86\uff0c\u4e0d\u9700\u8981\u8bbe\u7f6e\u8fd9\u4e2a\u53d8\u91cf\u3002 CUDA C++ \u7248\u672c CUDA \u662f\u4e00\u79cd\u57fa\u4e8e C++ \u7684\u9886\u57df\u7279\u5b9a\u8bed\u8a00\uff0cCUDA C++ \u7684\u7248\u672c\u548c\u6b63\u89c4 C++ \u4e00\u4e00\u5bf9\u5e94\u3002 \u76ee\u524d\u6700\u65b0\u7684\u662f CUDA C++20\uff0c\u53ef\u4ee5\u5b8c\u5168\u4f7f\u7528 C++20 \u7279\u6027\u7684\u540c\u65f6\u4e66\u5199 CUDA \u4ee3\u7801\u3002 \u5728 __host__ \u51fd\u6570\uff08\u672a\u7ecf\u7279\u6b8a\u4fee\u9970\u7684\u51fd\u6570\u9ed8\u8ba4\u5c31\u662f\u6b64\u7c7b\uff0c\u5728 CPU \u7aef\u6267\u884c\uff09\u4e2d\uff0cCUDA \u548c\u666e\u901a C++ \u6ca1\u6709\u533a\u522b\uff0c\u4efb\u4f55\u666e\u901a C++ \u4ee3\u7801\uff0c\u90fd\u53ef\u4ee5\u7528 CUDA \u7f16\u8bd1\u5668\u7f16\u8bd1\u3002 \u5728 __device__ \u51fd\u6570\uff08CUDA kernel\uff0c\u5728 GPU \u7aef\u6267\u884c\uff09\u4e2d\uff0c\u80fd\u4f7f\u7528\u7684\u51fd\u6570\u548c\u7c7b\u5c31\u6709\u4e00\u5b9a\u9650\u5236\u4e86\uff1a \u4f8b\u5982\u4f60\u4e0d\u80fd\u5728 __device__ \u51fd\u6570\u91cc\u4f7f\u7528\u4ec5\u9650 __host__ \u7528\u7684 std::cout \uff08\u4f46 printf \u53ef\u4ee5\uff0c\u56e0\u4e3a CUDA \u56e2\u961f\u4e3a\u4e86\u65b9\u4fbf\u7528\u6237\u8c03\u8bd5\uff0c\u4e3a\u4f60\u505a\u4e86 printf \u7684 __device__ \u7248\u7279\u5316\uff09\u3002 __device__ \u4e2d\u4e0d\u80fd\u4f7f\u7528\u7edd\u5927\u591a\u6570\u975e constexpr \u7684 STL \u5bb9\u5668\uff0c\u4f8b\u5982 std::map \u7b49\uff0c\u4f46\u662f\u5728 __host__ \u4fa7\u8fd8\u662f\u53ef\u4ee5\u7528\u7684\uff01 \u6240\u6709\u7684 constexpr \u51fd\u6570\u4e5f\u662f\u53ef\u4ee5\u4f7f\u7528\u7684\uff0c\u4f8b\u5982\u5404\u79cd C++ \u98ce\u683c\u7684\u6570\u5b66\u51fd\u6570\u5982 std::max \uff0c std::sin \uff0c\u8fd9\u4e9b\u51fd\u6570\u90fd\u662f constexpr \u7684\uff0c\u5728 __host__ \u548c __device__ \u90fd\u80fd\u7528\u3002 \u5982\u679c\u4e00\u4e2a\u5bb9\u5668\u7684\u6210\u5458\u5168\u662f constexpr \u7684\uff0c\u90a3\u4e48\u4ed6\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u3002\u4f8b\u5982 std::tuple \u3001 std::array \u7b49\u7b49\uff0c\u56e0\u4e3a\u4e0d\u6d89\u53ca I/O \u548c\u5185\u5b58\u5206\u914d\uff0c\u90fd\u662f\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528\u7684\u3002 \u4f8b\u5982 C++20 \u589e\u52a0\u4e86 constexpr-new \u7684\u652f\u6301\uff0c\u8ba9 std::vector \u548c std::string \u53d8\u6210\u4e86 constexpr \u7684\u5bb9\u5668\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528 std::vector \uff08\u4f1a\u7528\u5230 __device__ \u7248\u672c\u7684 malloc \u51fd\u6570\uff0c\u8fd9\u662f CUDA \u7684\u4e00\u5927\u7279\u8272\uff1a\u4f60\u53ef\u4ee5\u5728 kernel \u5185\u90e8\u7528 malloc \u52a8\u6001\u5206\u914d\u8bbe\u5907\u5185\u5b58\uff0c\u5e76\u4e14\u4ece CUDA C++20 \u5f00\u59cb new \u4e5f\u53ef\u4ee5\u4e86\uff09\u3002 std::variant \u73b0\u5728\u4e5f\u662f constexpr \u7684\u5bb9\u5668\uff0c\u4e5f\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u4e86\u3002 \u5f02\u5e38\u76ee\u524d\u8fd8\u4e0d\u662f constexpr \u7684\uff0c\u56e0\u6b64\u65e0\u6cd5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528 try/catch/throw \u7cfb\u5217\u5173\u952e\u5b57\u3002 \u603b\u4e4b\uff0c\u968f\u7740\uff0c\u6211\u4eec\u53ef\u4ee5\u671f\u5f85\u8d8a\u6765\u8d8a\u591a\u7eaf\u8ba1\u7b97\u7684\u51fd\u6570\u548c\u5bb9\u5668\u80fd\u5728 CUDA kernel\uff08 __device__ \u73af\u5883\uff09\u4e2d\u4f7f\u7528\u3002 \u6b63\u5982 CMAKE_CXX_STANDARD \u8bbe\u7f6e\u4e86 .cpp \u6587\u4ef6\u6240\u7528\u7684 C++ \u7248\u672c\uff0c\u4e5f\u53ef\u4ee5\u7528 CMAKE_CUDA_STANDARD \u8bbe\u7f6e .cu \u6587\u4ef6\u6240\u7528\u7684 CUDA C++ \u7248\u672c\u3002 set(CMAKE_CXX_STANDARD 20) # .cpp \u6587\u4ef6\u91c7\u7528\u7684 C++ \u7248\u672c\u662f C++20 set(CMAKE_CUDA_STANDARD 20) # .cu \u6587\u4ef6\u91c7\u7528\u7684 CUDA C++ \u7248\u672c\u662f C++20 \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") --expt-relaxed-constexpr : \u8ba9\u6240\u6709 constexpr \u51fd\u6570\u9ed8\u8ba4\u81ea\u52a8\u5e26\u6709 __host__ __device__ --expt-extended-lambda : \u5141\u8bb8\u4e3a lambda \u8868\u8fbe\u5f0f\u6307\u5b9a __host__ \u6216 __device__ \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u4e0d\u540c\u7684\u663e\u5361\u6709\u4e0d\u540c\u7684\u201c\u67b6\u6784\u7248\u672c\u53f7\u201d\uff0c\u67b6\u6784\u7248\u672c\u53f7\u5fc5\u987b\u4e0e\u4f60\u7684\u786c\u4ef6\u5339\u914d\u624d\u80fd\u6700\u4f73\u72b6\u6001\u8fd0\u884c\uff0c\u53ef\u4ee5\u7565\u4f4e\uff0c\u4f46\u5c06\u4e0d\u80fd\u53d1\u6325\u5b8c\u6574\u6027\u80fd\u3002 set(CMAKE_CUDA_ARCHITECTURES 86) # \u8868\u793a\u9488\u5bf9 RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\u751f\u6210 set(CMAKE_CUDA_ARCHITECTURES native) # \u5982\u679c CMake \u7248\u672c\u9ad8\u4e8e 3.24\uff0c\u8be5\u53d8\u91cf\u53ef\u4ee5\u8bbe\u4e3a \"native\"\uff0c\u8ba9 CMake \u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7 \u67b6\u6784\u7248\u672c\u53f7\uff1a\u4f8b\u5982 75 \u8868\u793a RTX 20xx \u7cfb\u5217\uff08Turing \u67b6\u6784\uff09\uff1b86 \u8868\u793a RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\uff1b89 \u8868\u793a RTX 40xx \u7cfb\u5217\uff08Ada \u67b6\u6784\uff09\u7b49\u3002 \u5b8c\u6574\u7684\u67b6\u6784\u7248\u672c\u53f7\u5217\u8868\u53ef\u4ee5\u5728 CUDA \u6587\u6863 \u4e2d\u627e\u5230\u3002 \u4e5f\u53ef\u4ee5\u8fd0\u884c\u5982\u4e0b\u547d\u4ee4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u67e5\u8be2\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7\uff1a __nvcc_device_query \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u9ed8\u8ba4\u53ea\u6709 __host__ \u51fd\u6570\u53ef\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002\u5982\u679c\u4f60\u9700\u8981\u5206\u79bb __device__ \u51fd\u6570\u7684\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u5c31\u8981\u5f00\u542f\u8fd9\u4e2a\u9009\u9879\uff1a set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) # \u53ef\u9009 \u521b\u5efa CUDA \u9879\u76ee \u5b8c\u6210\u4ee5\u4e0a\u9009\u9879\u7684\u8bbe\u5b9a\u540e\uff0c\u4f7f\u7528 project \u547d\u4ee4\u6b63\u5f0f\u521b\u5efa CUDA C++ \u9879\u76ee\u3002 project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) \u6211\u89c1\u8fc7\u6709\u4eba\u7167\u6284\u4ee3\u7801\u628a\u201c\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d\u201d\u6284\u8fdb\u53bb\u7684\u3002 \u5982\u9700\u5728\u7279\u5b9a\u6761\u4ef6\u4e0b\u624d\u5f00\u542f CUDA\uff0c\u53ef\u4ee5\u7528 enable_language() \u547d\u4ee4\u5ef6\u8fdf CUDA \u73af\u5883\u5728 CMake \u4e2d\u7684\u521d\u59cb\u5316\uff1a project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX) ... option(ENABLE_CUDA \"Enable CUDA\" ON) if (ENABLE_CUDA) enable_language(CUDA) endif() CMake \u914d\u7f6e\u603b\u7ed3 \u6ce8\u610f\uff01\u4ee5\u4e0a\u8fd9\u4e9b\u9009\u9879\u8bbe\u5b9a\u90fd\u5fc5\u987b\u5728 project() \u547d\u4ee4\u4e4b\u524d\uff01\u5426\u5219\u8bbe\u5b9a\u4e86\u4e5f\u65e0\u6548\u3002 \u56e0\u4e3a\u5b9e\u9645\u4e0a\u662f project() \u547d\u4ee4\u4f1a\u68c0\u6d4b\u8fd9\u4e9b\u9009\u9879\uff0c\u7528\u8fd9\u4e9b\u9009\u9879\u6765\u627e\u5230\u7f16\u8bd1\u5668\u548c CUDA \u7248\u672c\u7b49\u4fe1\u606f\u3002 \u603b\u4e4b\uff0c\u6211\u7684\u9009\u9879\u662f\uff1a cmake_minimum_required(VERSION 3.12) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CUDA_STANDARD 20) set(CMAKE_CUDA_SEPARABLE_COMPILATION OFF) set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) set(CMAKE_CUDA_ARCHITECTURES native) endif() project(\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) file(GLOB sources \"*.cpp\" \"*.cu\") add_executable(${PROJECT_NAME} ${sources}) target_link_libraries(${PROJECT_NAME} PRIVATE cusparse cublas) \u5f00\u59cb\u7f16\u5199 CUDA CUDA \u6709\u4e24\u5957 API\uff1a CUDA runtime API \uff1a\u66f4\u52a0\u7b80\u5355\uff0c\u517c\u987e\u6027\u80fd\uff0c\u65e0\u9700\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u90fd\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff0c\u4f46\u4e0d\u591f\u7075\u6d3b\u3002 CUDA driver API \uff1a\u66f4\u52a0\u7075\u6d3b\u591a\u53d8\uff0c\u4f46\u64cd\u4f5c\u7e41\u7410\uff0c\u9700\u8981\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u9002\u5408\u6709\u7279\u6b8a\u9700\u6c42\u7684\u7528\u6237\u3002 \u4ed6\u4eec\u90fd\u63d0\u4f9b\u4e86\u5927\u91cf\u7528\u4e8e\u7ba1\u7406 CUDA \u8d44\u6e90\u548c\u5185\u5b58\u7684\u51fd\u6570\u3002 \u6211\u4eec\u8981\u5b66\u4e60\u7684\u662f\u6bd4\u8f83\u6613\u61c2\u3001\u7528\u7684\u4e5f\u6700\u591a\u7684 CUDA runtime API\u3002 \u4f7f\u7528 \u5934\u6587\u4ef6\u5373\u53ef\u5bfc\u5165\u6240\u6709 CUDA runtime API \u7684\u51fd\u6570\u548c\u7c7b\u578b\uff1a #include \u867d\u7136 CUDA \u57fa\u4e8e C++\uff08\u800c\u4e0d\u662f C \u8bed\u8a00\uff09\uff0c\u652f\u6301\u6240\u6709 C++ \u8bed\u8a00\u7279\u6027\u3002\u4f46\u5176 CUDA runtime API \u4f9d\u7136\u662f\u4eff C \u98ce\u683c\u7684\u63a5\u53e3\uff0c\u53ef\u80fd\u662f\u7167\u987e\u4e86\u90e8\u5206\u4ece C \u8bed\u8a00\u8f6c\u8fc7\u6765\u7684\u571f\u6728\u8001\u54e5\uff0c\u4e5f\u53ef\u80fd\u662f\u4e3a\u4e86\u65b9\u4fbf\u88ab\u7b2c\u4e09\u65b9\u4e8c\u6b21\u5c01\u88c5\u3002 TODO: \u66f4\u591a\u8bdd\u9898","title":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b"},{"location":"cuda_intro/#c-cuda","text":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b \u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883 \u5b89\u88c5 NVIDIA \u9a71\u52a8 \u5b89\u88c5 CUDA \u5e38\u89c1\u95ee\u9898\u89e3\u7b54 \u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879 CUDA \u7f16\u8bd1\u5668\u8def\u5f84 CUDA C++ \u7248\u672c \u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6 \u663e\u5361\u67b6\u6784\u7248\u672c\u53f7 \u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49 \u521b\u5efa CUDA \u9879\u76ee CMake \u914d\u7f6e\u603b\u7ed3 \u5f00\u59cb\u7f16\u5199 CUDA \u53c2\u8003\u8d44\u6599\uff1a https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html https://www.cs.sfu.ca/~ashriram/Courses/CS431/assets/lectures/Part8/GPU1.pdf","title":"\u73b0\u4ee3 C++ \u7684 CUDA \u7f16\u7a0b"},{"location":"cuda_intro/#cuda","text":"\u786c\u4ef6\u65b9\u9762\u5efa\u8bae\u4f7f\u7528\u81f3\u5c11 GTX 1060 \u4ee5\u4e0a\u663e\u5361\uff0c\u4f46\u662f\u66f4\u8001\u7684\u663e\u5361\u4e5f\u53ef\u4ee5\u8fd0\u884c\u3002 \u8f6f\u4ef6\u65b9\u9762\u5219\u53ef\u4ee5\u5c3d\u53ef\u80fd\u6700\u65b0\uff0c\u4ee5\u83b7\u5f97 CUDA C++20 \u652f\u6301\uff0c\u6211\u5b89\u88c5\u7684\u7248\u672c\u662f CUDA 12.5\u3002 \u4ee5\u4e0b\u4ec5\u6f14\u793a Arch Linux \u4e2d\u5b89\u88c5 CUDA \u7684\u65b9\u6cd5\uff0c\u56e0\u4e3a Arch Linux \u5b98\u65b9\u6e90\u4e2d\u5c31\u81ea\u5e26 nvidia \u9a71\u52a8\u548c cuda \u5305\uff0c\u800c\u4e14\u5f00\u7bb1\u5373\u7528\uff0c\u5176\u4ed6\u53d1\u884c\u7248\u8bf7\u81ea\u884c\u5982\u6cd5\u70ae\u5236\u3002 Wendous \u7528\u6237\u53ef\u80fd\u5728\u5b89\u88c5\u5b8c\u540e\u9047\u5230\u201c\u627e\u4e0d\u5230 cuxxx.dll\u201d\u62a5\u9519\uff0c\u8bf4\u660e\u4f60\u9700\u8981\u62f7\u8d1d CUDA \u5b89\u88c5\u76ee\u5f55\u4e0b\u7684\u6240\u6709 DLL \u5230 C:\\\\Windows\\\\System32 \u3002 WSL \u7528\u6237\u8981\u6ce8\u610f\uff0cWSL \u73af\u5883\u548c\u771f\u6b63\u7684 Linux \u76f8\u5dee\u751a\u8fdc\u3002\u5f88\u591a Linux \u4e0b\u7684\u6559\u7a0b\uff0c\u4f60\u4f1a\u53d1\u73b0\u5728 WSL \u91cc\u590d\u523b\u4e0d\u51fa\u6765\u3002\u8fd9\u662f WSL \u7684 bug\uff0c\u5e94\u8be5\u6c47\u62a5\u53bb\u8ba9\u5fae\u8f6f\u7edf\u4e00\u4fee\u590d\uff0c\u800c\u4e0d\u662f\u8ba9\u6559\u7a0b\u7684\u4f5c\u8005\u96f6\u96f6\u6563\u6563\u4e00\u4e2a\u4e2a\u4ee3\u5b83\u64e6\u5c41\u80a1\u3002\u5efa\u8bae\u76f4\u63a5\u5728 Wendous \u672c\u5730\u5b89\u88c5 CUDA \u53cd\u800c\u6bd4\u4f3a\u5019 WSL \u968f\u673a\u62c9\u7684 bug \u7701\u529b\u3002 Ubuntu \u7528\u6237\u53ef\u80fd\u8003\u8651\u5378\u8f7d Ubuntu\uff0c\u56e0\u4e3a Ubuntu \u6e90\u4e2d\u7684\u7248\u672c\u6c38\u4e0d\u66f4\u65b0\u3002\u60f3\u8981\u5b89\u88c5\u65b0\u51fa\u7684\u8f6f\u4ef6\u90fd\u975e\u5e38\u56f0\u96be\uff0c\u57fa\u672c\u53ea\u80fd\u5b89\u88c5\u5230\u4e94\u516d\u5e74\u524d\u7684\u53e4\u8463\u8f6f\u4ef6\uff0c\u8981\u4e48\u53ea\u80fd\u4ece\u7f51\u4e0a\u4e0b deb \u5305\uff0c\u548c Wendous \u4e00\u4e2a\u8f6f\u8038\u6837\u3002\u6240\u6709\u5b98\u65b9 apt \u6e90\u4e2d\u5305\u7684\u7248\u672c\u4ece Ubuntu \u53d1\u5e03\u90a3\u4e00\u5929\u5c31\u5b9a\u6b7b\u4e86\uff0c\u6c38\u8fdc\u4e0d\u4f1a\u66f4\u65b0\u4e86\u3002\u8fd9\u662f\u4e3a\u4e86\u8d77\u591c\u7ea7\u670d\u52a1\u5668\u5b89\u5168\u7a33\u5b9a\u7684\u9700\u8981\uff0c\u5bf9\u4e8e\u4e2a\u4eba\u7535\u8111\u800c\u8a00\u5374\u53ea\u662f\u767d\u767d\u963b\u788d\u6211\u4eec\u5b66\u4e60\uff0cArch Linux \u8fd9\u6837\u7684\u6eda\u52a8\u66f4\u65b0\u7684\u53d1\u884c\u7248\u624d\u66f4\u9002\u5408\u4e2a\u4eba\u684c\u9762\u7528\u6237\u3002","title":"\u914d\u7f6e CUDA \u5f00\u53d1\u73af\u5883"},{"location":"cuda_intro/#nvidia","text":"\u9996\u5148\u786e\u4fdd\u4f60\u5b89\u88c5\u4e86 NVIDIA \u6700\u65b0\u9a71\u52a8\uff1a pacman -S nvidia \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u786e\u8ba4\u663e\u5361\u9a71\u52a8\u6b63\u5e38\u5de5\u4f5c\uff1a nvidia-smi \u5e94\u8be5\u80fd\u5f97\u5230\uff1a Mon Aug 26 14:09:15 2024 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 555.58.02 Driver Version: 555.58.02 CUDA Version: 12.5 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA GeForce RTX 4070 ... Off | 00000000:01:00.0 On | N/A | | 0% 30C P8 17W / 285W | 576MiB / 16376MiB | 41% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 583 G /usr/lib/Xorg 370MiB | | 0 N/A N/A 740 G xfwm4 4MiB | | 0 N/A N/A 783 G /usr/lib/firefox/firefox 133MiB | | 0 N/A N/A 4435 G obs 37MiB | +-----------------------------------------------------------------------------------------+ \u5982\u679c\u4e0d\u884c\uff0c\u90a3\u5c31\u91cd\u542f\u3002","title":"\u5b89\u88c5 NVIDIA \u9a71\u52a8"},{"location":"cuda_intro/#cuda_1","text":"\u7136\u540e\u5b89\u88c5 CUDA Toolkit\uff08\u5373 nvcc \u7f16\u8bd1\u5668\uff09\uff1a pacman -S cuda \u6253\u5f00 .bashrc \uff08\u5982\u679c\u4f60\u662f zsh \u7528\u6237\u5c31\u6253\u5f00 .zshrc \uff09\uff0c\u5728\u672b\u5c3e\u6dfb\u52a0\u4e24\u884c\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u662f\u9ed8\u8ba4\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # Arch Linux \u7528\u6237\u624d\u9700\u8981\u8fd9\u4e00\u884c \u7136\u540e\u91cd\u542f bash \uff0c\u6216\u8005\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\u91cd\u8f7d\u73af\u5883\u53d8\u91cf\uff1a source .bashrc \u8fd0\u884c\u4ee5\u4e0b\u547d\u4ee4\u6d4b\u8bd5 CUDA \u7f16\u8bd1\u5668\u662f\u5426\u53ef\u7528\uff1a nvcc --version \u5e94\u8be5\u80fd\u5f97\u5230\uff1a nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2024 NVIDIA Corporation Built on Thu_Jun__6_02:18:23_PDT_2024 Cuda compilation tools, release 12.5, V12.5.82 Build cuda_12.5.r12.5/compiler.34385749_0","title":"\u5b89\u88c5 CUDA"},{"location":"cuda_intro/#_1","text":"CMake \u62a5\u9519\u627e\u4e0d\u5230 CUDA\uff1f\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\uff1a export PATH=\"/opt/cuda/bin:$PATH\" # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e export NVCC_CCBIN=\"/usr/bin/g++-13\" # \u53ea\u6709 Arch Linux \u9700\u8981\u8fd9\u4e00\u884c IDE \u4f7f\u7528\u4e86 Clangd \u9759\u6001\u68c0\u67e5\u63d2\u4ef6\uff0c\u62a5\u9519\u4e0d\u8ba4\u8bc6 -forward-unknown-to-host-compiler \u9009\u9879\uff1f \u521b\u5efa\u6587\u4ef6 ~/.config/clangd/config.yaml \uff1a CompileFlags: Add: # \u8981\u989d\u5916\u6dfb\u52a0\u5230 Clang \u7684 NVCC \u6ca1\u6709\u7684\u53c2\u6570 - --no-cuda-version-check Remove: # \u79fb\u9664 Clang \u4e0d\u8ba4\u8bc6\u7684 NVCC \u53c2\u6570 - -forward-unknown-to-host-compiler - --expt-* - --generate-code=* - -arch=* - -rdc=*","title":"\u5e38\u89c1\u95ee\u9898\u89e3\u7b54"},{"location":"cuda_intro/#cmake","text":"","title":"\u5efa\u8bae\u5f00\u542f\u7684 CMake \u9009\u9879"},{"location":"cuda_intro/#cuda_2","text":"\u5982\u679c\u4f60\u65e0\u6cd5\u641e\u5b9a\u73af\u5883\u53d8\u91cf\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 CMAKE_CUDA_COMPILER \u76f4\u63a5\u8bbe\u7f6e nvcc \u7f16\u8bd1\u5668\u7684\u8def\u5f84\uff1a set(CMAKE_CUDA_COMPILER \"/opt/cuda/bin/nvcc\") # \u8fd9\u91cc\u6362\u6210\u4f60\u7684 cuda \u5b89\u88c5\u4f4d\u7f6e \u4e0d\u5efa\u8bae\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a\u4f1a\u8ba9\u4f7f\u7528\u4f60\u9879\u76ee\u7684\u4eba\u4e5f\u88ab\u8feb\u628a CUDA \u5b89\u88c5\u5230\u8fd9\u4e2a\u8def\u5f84\u53bb\u3002 \u5efa\u8bae\u662f\u628a\u4f60\u7684 nvcc \u5b89\u88c5\u597d\u540e\uff0c\u901a\u8fc7 PATH \u73af\u5883\u53d8\u91cf\uff0c cmake \u5c31\u80fd\u627e\u5230\u4e86\uff0c\u4e0d\u9700\u8981\u8bbe\u7f6e\u8fd9\u4e2a\u53d8\u91cf\u3002","title":"CUDA \u7f16\u8bd1\u5668\u8def\u5f84"},{"location":"cuda_intro/#cuda-c","text":"CUDA \u662f\u4e00\u79cd\u57fa\u4e8e C++ \u7684\u9886\u57df\u7279\u5b9a\u8bed\u8a00\uff0cCUDA C++ \u7684\u7248\u672c\u548c\u6b63\u89c4 C++ \u4e00\u4e00\u5bf9\u5e94\u3002 \u76ee\u524d\u6700\u65b0\u7684\u662f CUDA C++20\uff0c\u53ef\u4ee5\u5b8c\u5168\u4f7f\u7528 C++20 \u7279\u6027\u7684\u540c\u65f6\u4e66\u5199 CUDA \u4ee3\u7801\u3002 \u5728 __host__ \u51fd\u6570\uff08\u672a\u7ecf\u7279\u6b8a\u4fee\u9970\u7684\u51fd\u6570\u9ed8\u8ba4\u5c31\u662f\u6b64\u7c7b\uff0c\u5728 CPU \u7aef\u6267\u884c\uff09\u4e2d\uff0cCUDA \u548c\u666e\u901a C++ \u6ca1\u6709\u533a\u522b\uff0c\u4efb\u4f55\u666e\u901a C++ \u4ee3\u7801\uff0c\u90fd\u53ef\u4ee5\u7528 CUDA \u7f16\u8bd1\u5668\u7f16\u8bd1\u3002 \u5728 __device__ \u51fd\u6570\uff08CUDA kernel\uff0c\u5728 GPU \u7aef\u6267\u884c\uff09\u4e2d\uff0c\u80fd\u4f7f\u7528\u7684\u51fd\u6570\u548c\u7c7b\u5c31\u6709\u4e00\u5b9a\u9650\u5236\u4e86\uff1a \u4f8b\u5982\u4f60\u4e0d\u80fd\u5728 __device__ \u51fd\u6570\u91cc\u4f7f\u7528\u4ec5\u9650 __host__ \u7528\u7684 std::cout \uff08\u4f46 printf \u53ef\u4ee5\uff0c\u56e0\u4e3a CUDA \u56e2\u961f\u4e3a\u4e86\u65b9\u4fbf\u7528\u6237\u8c03\u8bd5\uff0c\u4e3a\u4f60\u505a\u4e86 printf \u7684 __device__ \u7248\u7279\u5316\uff09\u3002 __device__ \u4e2d\u4e0d\u80fd\u4f7f\u7528\u7edd\u5927\u591a\u6570\u975e constexpr \u7684 STL \u5bb9\u5668\uff0c\u4f8b\u5982 std::map \u7b49\uff0c\u4f46\u662f\u5728 __host__ \u4fa7\u8fd8\u662f\u53ef\u4ee5\u7528\u7684\uff01 \u6240\u6709\u7684 constexpr \u51fd\u6570\u4e5f\u662f\u53ef\u4ee5\u4f7f\u7528\u7684\uff0c\u4f8b\u5982\u5404\u79cd C++ \u98ce\u683c\u7684\u6570\u5b66\u51fd\u6570\u5982 std::max \uff0c std::sin \uff0c\u8fd9\u4e9b\u51fd\u6570\u90fd\u662f constexpr \u7684\uff0c\u5728 __host__ \u548c __device__ \u90fd\u80fd\u7528\u3002 \u5982\u679c\u4e00\u4e2a\u5bb9\u5668\u7684\u6210\u5458\u5168\u662f constexpr \u7684\uff0c\u90a3\u4e48\u4ed6\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u3002\u4f8b\u5982 std::tuple \u3001 std::array \u7b49\u7b49\uff0c\u56e0\u4e3a\u4e0d\u6d89\u53ca I/O \u548c\u5185\u5b58\u5206\u914d\uff0c\u90fd\u662f\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528\u7684\u3002 \u4f8b\u5982 C++20 \u589e\u52a0\u4e86 constexpr-new \u7684\u652f\u6301\uff0c\u8ba9 std::vector \u548c std::string \u53d8\u6210\u4e86 constexpr \u7684\u5bb9\u5668\uff0c\u56e0\u6b64\u53ef\u4ee5\u5728 __device__ \u4e2d\u4f7f\u7528 std::vector \uff08\u4f1a\u7528\u5230 __device__ \u7248\u672c\u7684 malloc \u51fd\u6570\uff0c\u8fd9\u662f CUDA \u7684\u4e00\u5927\u7279\u8272\uff1a\u4f60\u53ef\u4ee5\u5728 kernel \u5185\u90e8\u7528 malloc \u52a8\u6001\u5206\u914d\u8bbe\u5907\u5185\u5b58\uff0c\u5e76\u4e14\u4ece CUDA C++20 \u5f00\u59cb new \u4e5f\u53ef\u4ee5\u4e86\uff09\u3002 std::variant \u73b0\u5728\u4e5f\u662f constexpr \u7684\u5bb9\u5668\uff0c\u4e5f\u53ef\u4ee5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528\u4e86\u3002 \u5f02\u5e38\u76ee\u524d\u8fd8\u4e0d\u662f constexpr \u7684\uff0c\u56e0\u6b64\u65e0\u6cd5\u5728 __device__ \u51fd\u6570\u4e2d\u4f7f\u7528 try/catch/throw \u7cfb\u5217\u5173\u952e\u5b57\u3002 \u603b\u4e4b\uff0c\u968f\u7740\uff0c\u6211\u4eec\u53ef\u4ee5\u671f\u5f85\u8d8a\u6765\u8d8a\u591a\u7eaf\u8ba1\u7b97\u7684\u51fd\u6570\u548c\u5bb9\u5668\u80fd\u5728 CUDA kernel\uff08 __device__ \u73af\u5883\uff09\u4e2d\u4f7f\u7528\u3002 \u6b63\u5982 CMAKE_CXX_STANDARD \u8bbe\u7f6e\u4e86 .cpp \u6587\u4ef6\u6240\u7528\u7684 C++ \u7248\u672c\uff0c\u4e5f\u53ef\u4ee5\u7528 CMAKE_CUDA_STANDARD \u8bbe\u7f6e .cu \u6587\u4ef6\u6240\u7528\u7684 CUDA C++ \u7248\u672c\u3002 set(CMAKE_CXX_STANDARD 20) # .cpp \u6587\u4ef6\u91c7\u7528\u7684 C++ \u7248\u672c\u662f C++20 set(CMAKE_CUDA_STANDARD 20) # .cu \u6587\u4ef6\u91c7\u7528\u7684 CUDA C++ \u7248\u672c\u662f C++20","title":"CUDA C++ \u7248\u672c"},{"location":"cuda_intro/#c","text":"set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") --expt-relaxed-constexpr : \u8ba9\u6240\u6709 constexpr \u51fd\u6570\u9ed8\u8ba4\u81ea\u52a8\u5e26\u6709 __host__ __device__ --expt-extended-lambda : \u5141\u8bb8\u4e3a lambda \u8868\u8fbe\u5f0f\u6307\u5b9a __host__ \u6216 __device__","title":"\u8d4b\u80fd\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6"},{"location":"cuda_intro/#_2","text":"\u4e0d\u540c\u7684\u663e\u5361\u6709\u4e0d\u540c\u7684\u201c\u67b6\u6784\u7248\u672c\u53f7\u201d\uff0c\u67b6\u6784\u7248\u672c\u53f7\u5fc5\u987b\u4e0e\u4f60\u7684\u786c\u4ef6\u5339\u914d\u624d\u80fd\u6700\u4f73\u72b6\u6001\u8fd0\u884c\uff0c\u53ef\u4ee5\u7565\u4f4e\uff0c\u4f46\u5c06\u4e0d\u80fd\u53d1\u6325\u5b8c\u6574\u6027\u80fd\u3002 set(CMAKE_CUDA_ARCHITECTURES 86) # \u8868\u793a\u9488\u5bf9 RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\u751f\u6210 set(CMAKE_CUDA_ARCHITECTURES native) # \u5982\u679c CMake \u7248\u672c\u9ad8\u4e8e 3.24\uff0c\u8be5\u53d8\u91cf\u53ef\u4ee5\u8bbe\u4e3a \"native\"\uff0c\u8ba9 CMake \u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7 \u67b6\u6784\u7248\u672c\u53f7\uff1a\u4f8b\u5982 75 \u8868\u793a RTX 20xx \u7cfb\u5217\uff08Turing \u67b6\u6784\uff09\uff1b86 \u8868\u793a RTX 30xx \u7cfb\u5217\uff08Ampere \u67b6\u6784\uff09\uff1b89 \u8868\u793a RTX 40xx \u7cfb\u5217\uff08Ada \u67b6\u6784\uff09\u7b49\u3002 \u5b8c\u6574\u7684\u67b6\u6784\u7248\u672c\u53f7\u5217\u8868\u53ef\u4ee5\u5728 CUDA \u6587\u6863 \u4e2d\u627e\u5230\u3002 \u4e5f\u53ef\u4ee5\u8fd0\u884c\u5982\u4e0b\u547d\u4ee4\uff08\u5982\u679c\u6709\u7684\u8bdd\uff09\u67e5\u8be2\u5f53\u524d\u663e\u5361\u7684\u67b6\u6784\u7248\u672c\u53f7\uff1a __nvcc_device_query","title":"\u663e\u5361\u67b6\u6784\u7248\u672c\u53f7"},{"location":"cuda_intro/#_3","text":"\u9ed8\u8ba4\u53ea\u6709 __host__ \u51fd\u6570\u53ef\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002\u5982\u679c\u4f60\u9700\u8981\u5206\u79bb __device__ \u51fd\u6570\u7684\u58f0\u660e\u548c\u5b9a\u4e49\uff0c\u5c31\u8981\u5f00\u542f\u8fd9\u4e2a\u9009\u9879\uff1a set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) # \u53ef\u9009","title":"\u8bbe\u5907\u51fd\u6570\u5206\u79bb\u5b9a\u4e49"},{"location":"cuda_intro/#cuda_3","text":"\u5b8c\u6210\u4ee5\u4e0a\u9009\u9879\u7684\u8bbe\u5b9a\u540e\uff0c\u4f7f\u7528 project \u547d\u4ee4\u6b63\u5f0f\u521b\u5efa CUDA C++ \u9879\u76ee\u3002 project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) \u6211\u89c1\u8fc7\u6709\u4eba\u7167\u6284\u4ee3\u7801\u628a\u201c\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d\u201d\u6284\u8fdb\u53bb\u7684\u3002 \u5982\u9700\u5728\u7279\u5b9a\u6761\u4ef6\u4e0b\u624d\u5f00\u542f CUDA\uff0c\u53ef\u4ee5\u7528 enable_language() \u547d\u4ee4\u5ef6\u8fdf CUDA \u73af\u5883\u5728 CMake \u4e2d\u7684\u521d\u59cb\u5316\uff1a project(\u8fd9\u91cc\u586b\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX) ... option(ENABLE_CUDA \"Enable CUDA\" ON) if (ENABLE_CUDA) enable_language(CUDA) endif()","title":"\u521b\u5efa CUDA \u9879\u76ee"},{"location":"cuda_intro/#cmake_1","text":"\u6ce8\u610f\uff01\u4ee5\u4e0a\u8fd9\u4e9b\u9009\u9879\u8bbe\u5b9a\u90fd\u5fc5\u987b\u5728 project() \u547d\u4ee4\u4e4b\u524d\uff01\u5426\u5219\u8bbe\u5b9a\u4e86\u4e5f\u65e0\u6548\u3002 \u56e0\u4e3a\u5b9e\u9645\u4e0a\u662f project() \u547d\u4ee4\u4f1a\u68c0\u6d4b\u8fd9\u4e9b\u9009\u9879\uff0c\u7528\u8fd9\u4e9b\u9009\u9879\u6765\u627e\u5230\u7f16\u8bd1\u5668\u548c CUDA \u7248\u672c\u7b49\u4fe1\u606f\u3002 \u603b\u4e4b\uff0c\u6211\u7684\u9009\u9879\u662f\uff1a cmake_minimum_required(VERSION 3.12) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CUDA_STANDARD 20) set(CMAKE_CUDA_SEPARABLE_COMPILATION OFF) set(CMAKE_CUDA_FLAGS \"${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr --expt-extended-lambda\") if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) set(CMAKE_CUDA_ARCHITECTURES native) endif() project(\u4f60\u7684\u9879\u76ee\u540d LANGUAGES CXX CUDA) file(GLOB sources \"*.cpp\" \"*.cu\") add_executable(${PROJECT_NAME} ${sources}) target_link_libraries(${PROJECT_NAME} PRIVATE cusparse cublas)","title":"CMake \u914d\u7f6e\u603b\u7ed3"},{"location":"cuda_intro/#cuda_4","text":"CUDA \u6709\u4e24\u5957 API\uff1a CUDA runtime API \uff1a\u66f4\u52a0\u7b80\u5355\uff0c\u517c\u987e\u6027\u80fd\uff0c\u65e0\u9700\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u90fd\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff0c\u4f46\u4e0d\u591f\u7075\u6d3b\u3002 CUDA driver API \uff1a\u66f4\u52a0\u7075\u6d3b\u591a\u53d8\uff0c\u4f46\u64cd\u4f5c\u7e41\u7410\uff0c\u9700\u8981\u624b\u52a8\u7f16\u8bd1 kernel\uff0c\u9002\u5408\u6709\u7279\u6b8a\u9700\u6c42\u7684\u7528\u6237\u3002 \u4ed6\u4eec\u90fd\u63d0\u4f9b\u4e86\u5927\u91cf\u7528\u4e8e\u7ba1\u7406 CUDA \u8d44\u6e90\u548c\u5185\u5b58\u7684\u51fd\u6570\u3002 \u6211\u4eec\u8981\u5b66\u4e60\u7684\u662f\u6bd4\u8f83\u6613\u61c2\u3001\u7528\u7684\u4e5f\u6700\u591a\u7684 CUDA runtime API\u3002 \u4f7f\u7528 \u5934\u6587\u4ef6\u5373\u53ef\u5bfc\u5165\u6240\u6709 CUDA runtime API \u7684\u51fd\u6570\u548c\u7c7b\u578b\uff1a #include \u867d\u7136 CUDA \u57fa\u4e8e C++\uff08\u800c\u4e0d\u662f C \u8bed\u8a00\uff09\uff0c\u652f\u6301\u6240\u6709 C++ \u8bed\u8a00\u7279\u6027\u3002\u4f46\u5176 CUDA runtime API \u4f9d\u7136\u662f\u4eff C \u98ce\u683c\u7684\u63a5\u53e3\uff0c\u53ef\u80fd\u662f\u7167\u987e\u4e86\u90e8\u5206\u4ece C \u8bed\u8a00\u8f6c\u8fc7\u6765\u7684\u571f\u6728\u8001\u54e5\uff0c\u4e5f\u53ef\u80fd\u662f\u4e3a\u4e86\u65b9\u4fbf\u88ab\u7b2c\u4e09\u65b9\u4e8c\u6b21\u5c01\u88c5\u3002 TODO: \u66f4\u591a\u8bdd\u9898","title":"\u5f00\u59cb\u7f16\u5199 CUDA"},{"location":"design_concept/","text":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u5982\u679c\u4e00\u4e2a\u4e1c\u897f\u53eb\u8d77\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u8d70\u8d77\u8def\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u90a3\u4e48\u4e0d\u59a8\u8ba4\u4e3a\u4ed6\u5c31\u662f\u4e00\u53ea\u9e2d\u3002 \u6211\u4eec\u6709\u4e09\u79cd\u7c7b\u578b\u7684\u72d7\uff1a\u62c9\u5e03\u62c9\u591a\u72ac\uff0c\u85cf\u7352\uff0c\u5f20\u5fc3\u6b23\u3002 \u8bf7\u52ff\u4fae\u8fb1\u62c9\u5e03\u62c9\u591a\u548c\u85cf\u7352\uff01 \u4ed6\u4eec\u6709\u4e00\u4e2a\u5171\u540c\u70b9\uff0c\u90a3\u5c31\u662f\u5b83\u4eec\u90fd\u4f1a\u72d7\u53eb\uff08bark\uff09\u4ee5\u53ca\u81ea\u6211\u4ecb\u7ecd\uff08intro\uff09\u3002 struct Labrador { void intro() { puts(\"\u6211\u80fd\u5e2e\u4f60\u6361\u56de\u68cd\u68cd\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Mastiff { void intro() { puts(\"\u6211\u80fd\u4fdd\u536b\u56fd\u738b\u8363\u8000\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Xinxin { void intro() { puts(\"\u6211\u80fd\u795d\u60a8\u88c1\u5458\u6eda\u6eda\uff01\"); } void bark() { puts(\"\u4ece\u672a\u8d21\u732e\u4efb\u4f55\u6838\u5fc3\u529f\u80fd\uff01\"); } }; \u73b0\u5728\uff0c\u6211\u4eec\u9700\u8981\u8bbe\u8ba1\u4e00\u4e2a\u201c\u9972\u517b\u5458\u201d\u51fd\u6570\uff0c\u4ed6\u4f1a\u8ba9\u72d7\u72d7\u5148\u81ea\u6211\u4ecb\u7ecd\uff0c\u7136\u540e\u53eb\u4e24\u58f0\u3002 \u4f20\u7edf\u7684\u57fa\u4e8e\u91cd\u8f7d\u7684\u5199\u6cd5\uff0c\u9700\u8981\u8fde\u7eed\u5199\u4e09\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u51fd\u6570\u4f53\uff0c\u975e\u5e38\u9ebb\u70e6\uff0c\u8fdd\u53cd\u201c\u907f\u514d\u91cd\u590d\u201d\u539f\u5219\uff0c\u4e0d\u5229\u4e8e\u4ee3\u7801\u672a\u6765\u7684\u7ef4\u62a4\u3002 void feeder(Labrador dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Mastiff dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Xinxin dog) { dog.intro(); dog.bark(); dog.bark(); } \u65b9\u68481\uff1a\u6a21\u677f\u51fd\u6570 template void feeder(Dog dog) { dog.intro(); dog.bark(); dog.bark(); } \u6b64\u5904\u628a Dog \u5b9a\u4e49\u4e3a\u6a21\u677f\u51fd\u6570 TODO","title":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5)"},{"location":"design_concept/#c20-concept","text":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5) \u5982\u679c\u4e00\u4e2a\u4e1c\u897f\u53eb\u8d77\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u8d70\u8d77\u8def\u6765\u50cf\u4e00\u53ea\u9e2d\uff0c\u90a3\u4e48\u4e0d\u59a8\u8ba4\u4e3a\u4ed6\u5c31\u662f\u4e00\u53ea\u9e2d\u3002 \u6211\u4eec\u6709\u4e09\u79cd\u7c7b\u578b\u7684\u72d7\uff1a\u62c9\u5e03\u62c9\u591a\u72ac\uff0c\u85cf\u7352\uff0c\u5f20\u5fc3\u6b23\u3002 \u8bf7\u52ff\u4fae\u8fb1\u62c9\u5e03\u62c9\u591a\u548c\u85cf\u7352\uff01 \u4ed6\u4eec\u6709\u4e00\u4e2a\u5171\u540c\u70b9\uff0c\u90a3\u5c31\u662f\u5b83\u4eec\u90fd\u4f1a\u72d7\u53eb\uff08bark\uff09\u4ee5\u53ca\u81ea\u6211\u4ecb\u7ecd\uff08intro\uff09\u3002 struct Labrador { void intro() { puts(\"\u6211\u80fd\u5e2e\u4f60\u6361\u56de\u68cd\u68cd\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Mastiff { void intro() { puts(\"\u6211\u80fd\u4fdd\u536b\u56fd\u738b\u8363\u8000\uff01\"); } void bark() { puts(\"\u6c6a\u6c6a\uff01\"); } }; struct Xinxin { void intro() { puts(\"\u6211\u80fd\u795d\u60a8\u88c1\u5458\u6eda\u6eda\uff01\"); } void bark() { puts(\"\u4ece\u672a\u8d21\u732e\u4efb\u4f55\u6838\u5fc3\u529f\u80fd\uff01\"); } }; \u73b0\u5728\uff0c\u6211\u4eec\u9700\u8981\u8bbe\u8ba1\u4e00\u4e2a\u201c\u9972\u517b\u5458\u201d\u51fd\u6570\uff0c\u4ed6\u4f1a\u8ba9\u72d7\u72d7\u5148\u81ea\u6211\u4ecb\u7ecd\uff0c\u7136\u540e\u53eb\u4e24\u58f0\u3002 \u4f20\u7edf\u7684\u57fa\u4e8e\u91cd\u8f7d\u7684\u5199\u6cd5\uff0c\u9700\u8981\u8fde\u7eed\u5199\u4e09\u4e2a\u4e00\u6a21\u4e00\u6837\u7684\u51fd\u6570\u4f53\uff0c\u975e\u5e38\u9ebb\u70e6\uff0c\u8fdd\u53cd\u201c\u907f\u514d\u91cd\u590d\u201d\u539f\u5219\uff0c\u4e0d\u5229\u4e8e\u4ee3\u7801\u672a\u6765\u7684\u7ef4\u62a4\u3002 void feeder(Labrador dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Mastiff dog) { dog.intro(); dog.bark(); dog.bark(); } void feeder(Xinxin dog) { dog.intro(); dog.bark(); dog.bark(); } \u65b9\u68481\uff1a\u6a21\u677f\u51fd\u6570 template void feeder(Dog dog) { dog.intro(); dog.bark(); dog.bark(); } \u6b64\u5904\u628a Dog \u5b9a\u4e49\u4e3a\u6a21\u677f\u51fd\u6570 TODO","title":"\u9e2d\u5b50\u7c7b\u578b\u4e0e C++20 concept (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/","text":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u865a\u51fd\u6570\u7684\u7f3a\u70b9 \u865a\u51fd\u6570\u7684\u7f3a\u70b9 TODO","title":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/#_1","text":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5) \u865a\u51fd\u6570\u7684\u7f3a\u70b9","title":"\u7c7b\u578b\u64e6\u9664\u795e\u6559\u53ca\u5176\u5b9e\u73b0 (\u672a\u5b8c\u5de5)"},{"location":"design_erasure/#_2","text":"TODO","title":"\u865a\u51fd\u6570\u7684\u7f3a\u70b9"},{"location":"design_functor/","text":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f \u51fd\u6570\u6307\u9488 \u9996\u5148\u9700\u8981\u5b9a\u4e49\u51fd\u6570\u6307\u9488\u7c7b\u578b\uff1a using func_t = int (*)(int i); // \u7b49\u4ef7\u4e8e typedef int (*func_t)(int i); \u51fd\u6570\u6307\u9488\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u7b56\u7565\u6a21\u5f0f\uff1a void test(func_t func) { cout << func(2); cout << func(3); } int twice(int i) { return i * 2; } int main() { test(twice); // 4 6 } \u51fd\u6570\u6307\u9488\u5b9e\u73b0\u591a\u6001 int twice(int i) { return i * 2; } int triple(int i) { return i * 3; } int main() { test(twice); // 4 6 test(triple); // 6 9 } \u51fd\u6570\u6307\u9488\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u51fd\u6570\u6307\u9488\u53ea\u80fd\u6307\u5411\u5168\u5c40\u51fd\u6570\uff0c\u65e0\u6cd5\u4fdd\u5b58\u72b6\u6001\u3002 int ntimes(int scale, int i) { return i * scale; } int main() { test(ntimes(2)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 test(ntimes(3)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 } \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 struct myclass { void run(string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc.run(\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc. operator() (\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc(\"\u5c0f\u5207\"); \u91cd\u8f7d\u4e86 operator() \u540e\u7684 myclass \u5bf9\u8c61\uff0c\u8c03\u7528\u8d77\u6765\u5c31\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\u3002 \u4eff\u51fd\u6570 \u4eff\u51fd\u6570\u662f\u4e00\u79cd\u91cd\u8f7d\u4e86 \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 \u7684\u7c7b\uff0c\u53ef\u4ee5\u50cf\u51fd\u6570\u4e00\u6837\u4f7f\u7528\uff1a struct twice_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; int main() { test(twice); // 4 6 } \u4eff\u51fd\u6570\u7684\u4f18\u52bf\u662f\u53ef\u4ee5\u4fdd\u5b58 \u72b6\u6001 \uff1a struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; void test(ntimes_t func) { cout << func(2); cout << func(3); } int main() { ntimes_t twice(2); ntimes_t triple(3); ntimes_t quadric(4); test(twice); // 4 6 test(triple); // 6 9 test(quadric); // 8 12 } \u4eff\u51fd\u6570\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u9700\u8981\u5728 test \u4e2d\u5199\u660e\u4eff\u51fd\u6570\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u65e0\u6cd5\u5b9e\u73b0\u591a\u6001\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; struct triple_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // \u9519\u8bef\uff1atest \u53ea\u517c\u5bb9\u4e86 twice_t \u505a\u53c2\u6570 } \u5982\u4f55\u89e3\u51b3\uff1f \u5229\u7528\u6a21\u677f template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // 6 9 } \u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86 \u7f16\u8bd1\u671f\u591a\u6001 \uff0c\u56e0\u4e3a test \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u53ef\u4ee5\u6839\u636e\u4f20\u5165\u7684\u5177\u4f53\u51fd\u6570\u7c7b\u578b\u8fdb\u884c\u63a8\u5bfc\u3002 \u6a21\u677f\u4f20\u4eff\u51fd\u6570\u7684\u7f3a\u9677 \u7f3a\u70b9\uff1a\u5fc5\u987b\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u65e0\u6cd5\u52a8\u6001\u51b3\u5b9a\u7c7b\u578b\u3002 template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { bool ok; cin >> ok; test(ok ? twice : triple); // \u9519\u8bef\uff1a\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u4e4b\u95f4\u4e0d\u80fd\u4e09\u76ee } \u4e07\u80fd\u7684 function \u5bb9\u5668 std::function \u91c7\u7528\u4e86 \u7c7b\u578b\u64e6\u9664\u6280\u672f \uff0c\u65e0\u9700\u5199\u660e\u4eff\u51fd\u6570\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u80fd\u5bb9\u7eb3\u4efb\u4f55\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u3002 \u53ea\u9700\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u5199\u660e\u51fd\u6570\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u5373\u53ef\uff0c\u6240\u6709\u5177\u6709\u540c\u6837\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u7684\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u90fd\u53ef\u4ee5\u4f20\u5165\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; function twice = twice_t(); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u4eff\u51fd\u6570 int triple(int i) { return i * 3; } function function_triple = triple; // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u51fd\u6570\u6307\u9488 struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; function quadric = ntimes_t(4); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u5e26\u72b6\u6001\u7684\u4eff\u51fd\u6570 \u53ef\u4ee5\u7528 function \u5bb9\u5668\u4f5c\u4e3a\u53c2\u6570\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u4f7f\u7528\u6a21\u677f\u3002 // \u6a21\u677f\uff1a\u6027\u80fd\u4f18\u5148 template void test(Func func) { cout << func(2); cout << func(3); } // \u5bb9\u5668\uff1a\u7075\u6d3b\u6027\u4f18\u5148 void test(function func) { cout << func(2); cout << func(3); } \u51fd\u6570\u5f0f\u4e3a\u4ec0\u4e48\u597d\uff1f \u6709\u4eba\u8bf4\uff0cfunction \u5e95\u5c42\u4f9d\u7136\u662f\u57fa\u4e8e\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u7684\uff0c\u4e0d\u662f\u548c\u865a\u51fd\u6570\u4e00\u6837\u4f4e\u6548\u5417\uff1f\u51fd\u6570\u5f0f\u76f8\u6bd4\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u597d\u5728\u54ea\u91cc\u5462\uff1f \u6027\u80fd\u4e0e\u7075\u6d3b\u6027\u7684\u9009\u62e9\u6743 \u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u5f80\u5f80\u662f 20% \u7684\u4ee3\u7801\u8017\u8d39\u4e86 80% \u7684\u8ba1\u7b97\u673a\u65f6\u95f4\u3002\u6211\u4eec\u53ea\u8981\u4f18\u5316\u8fd9 20% \u7684\u74f6\u9888\u4ee3\u7801\u5c31\u53ef\u4ee5\u3002 \u865a\u51fd\u6570\u5b9e\u73b0\u7684\u591a\u6001\uff0c\u662f\u5f3a\u5236\u7684\uff0c\u4e00\u65e6\u7528\u4e86\u865a\u51fd\u6570\uff0c\u5c31\u6ca1\u6cd5\u628a\u865a\u8868\u53bb\u6389\u4e86\uff0c\u6c38\u8fdc\u5361\u5728\u4f60\u7684\u5bf9\u8c61\u7c7b\u578b\u91cc\u5360 8 \u5b57\u8282\u7a7a\u95f4\uff0c\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u6001\u4f7f\u7528\u3002 \u5982\u679c\u9009\u62e9\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\uff0c\u4f60\u53ef\u4ee5\u5728\u6b21\u8981\u7684\u4e1a\u52a1\u903b\u8f91\u4ee3\u7801\u4e2d\u9009\u62e9\u66f4\u7075\u6d3b\u7684 function \u5bb9\u5668\u3002 \u800c\u5728\u9700\u8981\u6027\u80fd\u7684\u74f6\u9888\u4ee3\u7801\u5904\uff0c\u53ef\u4ee5\u968f\u65f6\u5207\u6362\u5230\u57fa\u4e8e\u6a21\u677f\u7684\uff0c\u66f4\u9ad8\u6027\u80fd\u7684\u7f16\u8bd1\u671f\u591a\u6001\u3002\u51fd\u6570\u5f0f\u7ed9\u4e86\u4f60\u6839\u636e\u60c5\u51b5\u9009\u62e9\u7684\u81ea\u7531\u5ea6\u3002 function \u6709\u5c0f\u5bf9\u8c61\u4f18\u5316 \u800c\u4e14 function \u5185\u90e8\u5177\u6709\u7c7b\u4f3c\u4e8e string \u5c0f\u5bf9\u8c61\u4f18\u5316\u673a\u5236\uff0c\u5bf9\u4e8e\u8f83\u5c0f\u7684\u72b6\u6001\u6216\u6ca1\u6709\u72b6\u6001\u7684\u4eff\u51fd\u6570\uff0c\u5c31\u65e0\u9700\u6307\u9488\uff01\u65e0\u9700\u5806\u5185\u5b58\u5206\u914d\uff01 \u800c\u865a\u51fd\u6570\u54ea\u6015\u6ca1\u6709\u72b6\u6001\uff0c\u7531\u4e8e\u865a\u8868\u6307\u9488\u7684\u5b58\u5728\uff0c\u4e5f\u603b\u662f\u9700\u8981\u7528 new \u521b\u5efa\uff0c\u603b\u662f\u4f1a\u9020\u6210\u5927\u91cf\u7684\u788e\u7247\u5316\u5185\u5b58\uff0c\u56e0\u6b64\u5373\u4f7f\u540c\u6837\u9009\u62e9\u4e86\u7075\u6d3b\u6027\uff0cfunction \u4f9d\u7136\u6bd4\u865a\u51fd\u6570\u9ad8\u6548\u4e00\u70b9\u3002 \u800c\u4e14\u5373\u4f7f\u4f60\u7684\u72b6\u6001\u975e\u5e38\u591a\uff0c\u5bfc\u81f4 function \u4e0d\u5f97\u4e0d\u9700\u8981\u5806\u5185\u5b58\u5206\u914d\u4e86\uff0c\u8fd9\u4e00\u5206\u914d\u4e5f\u4e0d\u7528\u4f60\u81ea\u5df1\u64cd\u5fc3\uff0c\u4e0d\u7528\u624b\u52a8 new\uff0c\u4e5f\u4e0d\u7528\u624b\u52a8 make_shared\uff0cfunction \u5185\u90e8\u81ea\u52a8\u5e2e\u4f60\u5b8c\u6210\u4e00\u5207\u3002 lambda \u8868\u8fbe\u5f0f\u5f88\u65b9\u4fbf \u6700\u91cd\u8981\u7684\u662f\uff0c\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u53ef\u4ee5\u4fbf\u6377\u5730\u5229\u7528 lambda \u8868\u8fbe\u5f0f\u5c31\u5730\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u800c\u9762\u5411\u5bf9\u8c61\u9700\u8981\u5927\u8d39\u5468\u7ae0\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u63a5\u53e3\uff0c\u7136\u540e\u518d\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u865a\u51fd\u6570\uff0c\u6709\u65f6\u8fd8\u9700\u8981\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u7ed5\u4e86\u4e2a\u5927\u5708\u5b50\uff0c\u4e0d\u4ec5\u5199\u8d77\u6765\u75db\u82e6\uff0c\u9700\u8981\u8d77\u540d\u5f3a\u8feb\u75c7\uff0c\u800c\u4e14\u770b\u5f97\u4eba\u4e5f\u5934\u75bc\u3002lambda \u8868\u8fbe\u5f0f\uff0c\u5c31\u5730\u521b\u5efa\uff0c\u65e0\u9700\u540d\u5b57\uff0c\u66f4\u9002\u5408\u654f\u6377\u5f00\u53d1\u3002","title":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_functor/#_1","text":"","title":"\u51fd\u6570\u5f0f\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_functor/#_2","text":"\u9996\u5148\u9700\u8981\u5b9a\u4e49\u51fd\u6570\u6307\u9488\u7c7b\u578b\uff1a using func_t = int (*)(int i); // \u7b49\u4ef7\u4e8e typedef int (*func_t)(int i); \u51fd\u6570\u6307\u9488\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0\u7b56\u7565\u6a21\u5f0f\uff1a void test(func_t func) { cout << func(2); cout << func(3); } int twice(int i) { return i * 2; } int main() { test(twice); // 4 6 }","title":"\u51fd\u6570\u6307\u9488"},{"location":"design_functor/#_3","text":"int twice(int i) { return i * 2; } int triple(int i) { return i * 3; } int main() { test(twice); // 4 6 test(triple); // 6 9 }","title":"\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u591a\u6001"},{"location":"design_functor/#_4","text":"\u7f3a\u70b9\uff1a\u51fd\u6570\u6307\u9488\u53ea\u80fd\u6307\u5411\u5168\u5c40\u51fd\u6570\uff0c\u65e0\u6cd5\u4fdd\u5b58\u72b6\u6001\u3002 int ntimes(int scale, int i) { return i * scale; } int main() { test(ntimes(2)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 test(ntimes(3)); // \u9519\u8bef\uff1a\u6ca1\u6709\u8fd9\u79cd\u8bed\u6cd5 }","title":"\u51fd\u6570\u6307\u9488\u7684\u7f3a\u9677"},{"location":"design_functor/#_5","text":"struct myclass { void run(string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc.run(\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc. operator() (\"\u5c0f\u5207\"); struct myclass { void operator() (string name) { cout << name << \"\uff0c\u4f60\u597d\\n\"; } }; myclass mc; mc(\"\u5c0f\u5207\"); \u91cd\u8f7d\u4e86 operator() \u540e\u7684 myclass \u5bf9\u8c61\uff0c\u8c03\u7528\u8d77\u6765\u5c31\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\u3002","title":"\u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26"},{"location":"design_functor/#_6","text":"\u4eff\u51fd\u6570\u662f\u4e00\u79cd\u91cd\u8f7d\u4e86 \u51fd\u6570\u8c03\u7528\u8fd0\u7b97\u7b26 \u7684\u7c7b\uff0c\u53ef\u4ee5\u50cf\u51fd\u6570\u4e00\u6837\u4f7f\u7528\uff1a struct twice_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; int main() { test(twice); // 4 6 } \u4eff\u51fd\u6570\u7684\u4f18\u52bf\u662f\u53ef\u4ee5\u4fdd\u5b58 \u72b6\u6001 \uff1a struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; void test(ntimes_t func) { cout << func(2); cout << func(3); } int main() { ntimes_t twice(2); ntimes_t triple(3); ntimes_t quadric(4); test(twice); // 4 6 test(triple); // 6 9 test(quadric); // 8 12 }","title":"\u4eff\u51fd\u6570"},{"location":"design_functor/#_7","text":"\u7f3a\u70b9\uff1a\u9700\u8981\u5728 test \u4e2d\u5199\u660e\u4eff\u51fd\u6570\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u65e0\u6cd5\u5b9e\u73b0\u591a\u6001\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; struct triple_t { int operator() (int i) { return i * 2; } }; void test(twice_t func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // \u9519\u8bef\uff1atest \u53ea\u517c\u5bb9\u4e86 twice_t \u505a\u53c2\u6570 } \u5982\u4f55\u89e3\u51b3\uff1f","title":"\u4eff\u51fd\u6570\u7684\u7f3a\u9677"},{"location":"design_functor/#_8","text":"template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { test(twice); // 4 6 test(triple); // 6 9 } \u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86 \u7f16\u8bd1\u671f\u591a\u6001 \uff0c\u56e0\u4e3a test \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u53ef\u4ee5\u6839\u636e\u4f20\u5165\u7684\u5177\u4f53\u51fd\u6570\u7c7b\u578b\u8fdb\u884c\u63a8\u5bfc\u3002","title":"\u5229\u7528\u6a21\u677f"},{"location":"design_functor/#_9","text":"\u7f3a\u70b9\uff1a\u5fc5\u987b\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u65e0\u6cd5\u52a8\u6001\u51b3\u5b9a\u7c7b\u578b\u3002 template void test(Func func) { cout << func(2); cout << func(3); } twice_t twice; triple_t triple; int main() { bool ok; cin >> ok; test(ok ? twice : triple); // \u9519\u8bef\uff1a\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u4e4b\u95f4\u4e0d\u80fd\u4e09\u76ee }","title":"\u6a21\u677f\u4f20\u4eff\u51fd\u6570\u7684\u7f3a\u9677"},{"location":"design_functor/#function","text":"std::function \u91c7\u7528\u4e86 \u7c7b\u578b\u64e6\u9664\u6280\u672f \uff0c\u65e0\u9700\u5199\u660e\u4eff\u51fd\u6570\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\uff0c\u80fd\u5bb9\u7eb3\u4efb\u4f55\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u3002 \u53ea\u9700\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u5199\u660e\u51fd\u6570\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u5373\u53ef\uff0c\u6240\u6709\u5177\u6709\u540c\u6837\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u7684\u4eff\u51fd\u6570\u6216\u51fd\u6570\u6307\u9488\u90fd\u53ef\u4ee5\u4f20\u5165\u3002 struct twice_t { int operator() (int i) { return i * 2; } }; function twice = twice_t(); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u4eff\u51fd\u6570 int triple(int i) { return i * 3; } function function_triple = triple; // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u51fd\u6570\u6307\u9488 struct ntimes_t { int scale; ntimes_t(int scale) : scale(scale) {} int operator() (int i) { return i * scale; } }; function quadric = ntimes_t(4); // \u6ca1\u95ee\u9898\uff0c\u80fd\u63a5\u53d7\u5e26\u72b6\u6001\u7684\u4eff\u51fd\u6570 \u53ef\u4ee5\u7528 function \u5bb9\u5668\u4f5c\u4e3a\u53c2\u6570\uff0c\u5c31\u53ef\u4ee5\u907f\u514d\u4f7f\u7528\u6a21\u677f\u3002 // \u6a21\u677f\uff1a\u6027\u80fd\u4f18\u5148 template void test(Func func) { cout << func(2); cout << func(3); } // \u5bb9\u5668\uff1a\u7075\u6d3b\u6027\u4f18\u5148 void test(function func) { cout << func(2); cout << func(3); }","title":"\u4e07\u80fd\u7684 function \u5bb9\u5668"},{"location":"design_functor/#_10","text":"\u6709\u4eba\u8bf4\uff0cfunction \u5e95\u5c42\u4f9d\u7136\u662f\u57fa\u4e8e\u51fd\u6570\u6307\u9488\u5b9e\u73b0\u7684\uff0c\u4e0d\u662f\u548c\u865a\u51fd\u6570\u4e00\u6837\u4f4e\u6548\u5417\uff1f\u51fd\u6570\u5f0f\u76f8\u6bd4\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u597d\u5728\u54ea\u91cc\u5462\uff1f \u6027\u80fd\u4e0e\u7075\u6d3b\u6027\u7684\u9009\u62e9\u6743 \u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u5f80\u5f80\u662f 20% \u7684\u4ee3\u7801\u8017\u8d39\u4e86 80% \u7684\u8ba1\u7b97\u673a\u65f6\u95f4\u3002\u6211\u4eec\u53ea\u8981\u4f18\u5316\u8fd9 20% \u7684\u74f6\u9888\u4ee3\u7801\u5c31\u53ef\u4ee5\u3002 \u865a\u51fd\u6570\u5b9e\u73b0\u7684\u591a\u6001\uff0c\u662f\u5f3a\u5236\u7684\uff0c\u4e00\u65e6\u7528\u4e86\u865a\u51fd\u6570\uff0c\u5c31\u6ca1\u6cd5\u628a\u865a\u8868\u53bb\u6389\u4e86\uff0c\u6c38\u8fdc\u5361\u5728\u4f60\u7684\u5bf9\u8c61\u7c7b\u578b\u91cc\u5360 8 \u5b57\u8282\u7a7a\u95f4\uff0c\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u6001\u4f7f\u7528\u3002 \u5982\u679c\u9009\u62e9\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\uff0c\u4f60\u53ef\u4ee5\u5728\u6b21\u8981\u7684\u4e1a\u52a1\u903b\u8f91\u4ee3\u7801\u4e2d\u9009\u62e9\u66f4\u7075\u6d3b\u7684 function \u5bb9\u5668\u3002 \u800c\u5728\u9700\u8981\u6027\u80fd\u7684\u74f6\u9888\u4ee3\u7801\u5904\uff0c\u53ef\u4ee5\u968f\u65f6\u5207\u6362\u5230\u57fa\u4e8e\u6a21\u677f\u7684\uff0c\u66f4\u9ad8\u6027\u80fd\u7684\u7f16\u8bd1\u671f\u591a\u6001\u3002\u51fd\u6570\u5f0f\u7ed9\u4e86\u4f60\u6839\u636e\u60c5\u51b5\u9009\u62e9\u7684\u81ea\u7531\u5ea6\u3002 function \u6709\u5c0f\u5bf9\u8c61\u4f18\u5316 \u800c\u4e14 function \u5185\u90e8\u5177\u6709\u7c7b\u4f3c\u4e8e string \u5c0f\u5bf9\u8c61\u4f18\u5316\u673a\u5236\uff0c\u5bf9\u4e8e\u8f83\u5c0f\u7684\u72b6\u6001\u6216\u6ca1\u6709\u72b6\u6001\u7684\u4eff\u51fd\u6570\uff0c\u5c31\u65e0\u9700\u6307\u9488\uff01\u65e0\u9700\u5806\u5185\u5b58\u5206\u914d\uff01 \u800c\u865a\u51fd\u6570\u54ea\u6015\u6ca1\u6709\u72b6\u6001\uff0c\u7531\u4e8e\u865a\u8868\u6307\u9488\u7684\u5b58\u5728\uff0c\u4e5f\u603b\u662f\u9700\u8981\u7528 new \u521b\u5efa\uff0c\u603b\u662f\u4f1a\u9020\u6210\u5927\u91cf\u7684\u788e\u7247\u5316\u5185\u5b58\uff0c\u56e0\u6b64\u5373\u4f7f\u540c\u6837\u9009\u62e9\u4e86\u7075\u6d3b\u6027\uff0cfunction \u4f9d\u7136\u6bd4\u865a\u51fd\u6570\u9ad8\u6548\u4e00\u70b9\u3002 \u800c\u4e14\u5373\u4f7f\u4f60\u7684\u72b6\u6001\u975e\u5e38\u591a\uff0c\u5bfc\u81f4 function \u4e0d\u5f97\u4e0d\u9700\u8981\u5806\u5185\u5b58\u5206\u914d\u4e86\uff0c\u8fd9\u4e00\u5206\u914d\u4e5f\u4e0d\u7528\u4f60\u81ea\u5df1\u64cd\u5fc3\uff0c\u4e0d\u7528\u624b\u52a8 new\uff0c\u4e5f\u4e0d\u7528\u624b\u52a8 make_shared\uff0cfunction \u5185\u90e8\u81ea\u52a8\u5e2e\u4f60\u5b8c\u6210\u4e00\u5207\u3002 lambda \u8868\u8fbe\u5f0f\u5f88\u65b9\u4fbf \u6700\u91cd\u8981\u7684\u662f\uff0c\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u53ef\u4ee5\u4fbf\u6377\u5730\u5229\u7528 lambda \u8868\u8fbe\u5f0f\u5c31\u5730\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u800c\u9762\u5411\u5bf9\u8c61\u9700\u8981\u5927\u8d39\u5468\u7ae0\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u63a5\u53e3\uff0c\u7136\u540e\u518d\u5b9a\u4e49\u4e00\u4e2a\u7c7b\u5b9e\u73b0\u865a\u51fd\u6570\uff0c\u6709\u65f6\u8fd8\u9700\u8981\u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u7ed5\u4e86\u4e2a\u5927\u5708\u5b50\uff0c\u4e0d\u4ec5\u5199\u8d77\u6765\u75db\u82e6\uff0c\u9700\u8981\u8d77\u540d\u5f3a\u8feb\u75c7\uff0c\u800c\u4e14\u770b\u5f97\u4eba\u4e5f\u5934\u75bc\u3002lambda \u8868\u8fbe\u5f0f\uff0c\u5c31\u5730\u521b\u5efa\uff0c\u65e0\u9700\u540d\u5b57\uff0c\u66f4\u9002\u5408\u654f\u6377\u5f00\u53d1\u3002","title":"\u51fd\u6570\u5f0f\u4e3a\u4ec0\u4e48\u597d\uff1f"},{"location":"design_gamedev/","text":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f \u5355\u4f8b\u6a21\u5f0f \u6a21\u677f\u6a21\u5f0f \u72b6\u6001\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f CRTP \u6a21\u5f0f \u7ec4\u4ef6\u6a21\u5f0f \u89c2\u5bdf\u8005\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u8bbf\u95ee\u8005\u6a21\u5f0f \u5355\u4f8b\u6a21\u5f0f \u901a\u5e38\u7528\u4e8e\u6e38\u620f\u4e2d\u7684\u5168\u5c40\u7ba1\u7406\u7c7b\uff0c\u4fdd\u8bc1\u6574\u4e2a\u7a0b\u5e8f\uff08\u8fdb\u7a0b\uff09\u4e2d\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u5bf9\u8c61\u5b58\u5728\u3002\u6709\u5f88\u591a\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\uff1a \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 Game game; \u6548\u679c\uff1a\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u5c31\u4f1a\u521b\u5efa game \u5bf9\u8c61\uff0c\u4e4b\u540e\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 Game &getGame() { static Game game; return game; } getGame().updatePlayers(); \u6548\u679c\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 getGame() \u65f6\u4f1a\u521d\u59cb\u5316\uff0c\u4e4b\u540e\u7684\u8c03\u7528\u4f1a\u76f4\u63a5\u8fd4\u56de\u4e0a\u6b21\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 \u6839\u636e\u4f60\u7684\u9700\u8981\uff0c\u5982\u679c\u4f60\u9700\u8981\u5728\u7a0b\u5e8f\u4e00\u542f\u52a8\u65f6 game \u5bf9\u8c61\u5c31\u53ef\u7528\uff0c\u5c31\u7528\u997f\u6c57\u6a21\u5f0f\u3002 \u5982\u679c game \u7684\u521d\u59cb\u5316\u9700\u8981\u67d0\u4e9b\u6761\u4ef6\uff0c\u4f8b\u5982\u521b\u5efa Game \u7c7b\u524d\u9700\u8981 OpenGL \u521d\u59cb\u5316\uff0c\u90a3\u4e48\u53ef\u7528\u61d2\u6c57\u6a21\u5f0f\uff1a int main() { glfwInit(); // \u521d\u59cb\u5316 OpenGL getGame().initialize(); // \u7b2c\u4e00\u6b21\u8c03\u7528 getGame \u4f1a\u521d\u59cb\u5316 game \u5355\u4f8b getGame().updatePlayers(); // \u4e4b\u540e\u7684\u8c03\u7528\u603b\u662f\u8fd4\u56de\u5bf9\u540c\u4e00\u4e2a game \u5355\u4f8b\u7684\u5f15\u7528 } \u63d0\u793a\uff1a\u5982\u679c\u8981\u628a\u5355\u4f8b\u5bf9\u8c61\u7684\u5b9a\u4e49\u653e\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u52a1\u5fc5\u6dfb\u52a0 inline \u4fee\u9970\u7b26\uff0c\u800c\u4e0d\u662f static\uff0c\u5426\u5219\u4f1a\u5bfc\u81f4\u591a\u4e2a cpp \u6587\u4ef6\u5404\u81ea\u6709\u4e00\u4e2a Game \u5bf9\u8c61\u3002 // Game.hpp inline Game game; inline Game &getGame() { static Game game; return game; } \u5c01\u88c5\u5728\u7c7b\u5185\u90e8 \u7531\u4e8e\u6240\u6709\u5355\u4f8b\u5168\u90e8\u66b4\u9732\u5728\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\uff0c\u5bb9\u6613\u4ea7\u751f\u6df7\u4e71\u3002 \u4e00\u822c\u4f1a\u628a\u5355\u4f8b\u5bf9\u8c61\u6216\u51fd\u6570\u5c01\u88c5\u5728\u7c7b\u5185\u90e8\uff0c\u5e76\u4e14\u628a Game \u7684\u6784\u9020\u51fd\u6570\u8bbe\u4e3a private\uff0c\u907f\u514d\u7528\u6237\u4e0d\u614e\u76f4\u63a5\u521b\u5efa\u51fa\u672c\u5e94\u53ea\u6709\u5355\u4e2a\u5b9e\u4f8b\u7684 Game \u7c7b\u3002 \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: // inline static Game instance; // \u867d\u7136\u5f88\u723d\uff0c\u4f46\u4e0d\u80fd\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a Game \u5728\u4ed6\u7684 }; \u7ed3\u675f\u524d\u90fd\u662f\u4e0d\u5b8c\u6574\u7c7b\u578b static Game instance; // \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u5c31\u597d\u6bd4\u5168\u5c40\u53d8\u91cf\u7684 extern Game instance \u4e00\u6837\uff0c\u4e0d\u9700\u8981\u662f\u5b8c\u6574\u7c7b\u578b }; inline Game Game::instance; // \u5982\u679c\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u9700\u8981 inline\uff01 Game::instance.updatePlayers(); \u8b66\u544a\uff1a\u53ea\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\u5e76\u4f7f\u7528 inline \u8fd9\u79cd\u5199\u6cd5\uff0c\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u8fd9\u4f1a\u4f7f DLL \u548c EXE \u5404\u81ea\u6301\u6709\u4e00\u4efd\u4e92\u4e0d\u5171\u901a\u7684 instance \u3002\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\u8fd9\u79cd\u997f\u6c57\u6a21\u5f0f\u5355\u4f8b\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \uff0c\u522b\u7528 inline \u4e86\u3002 \u8fd9\u662f\u56e0\u4e3a Windows \u4e2d\u7684\u6bcf\u4e2a DLL \u548c EXE \u90fd\u662f\u4e00\u5ea7\u5b64\u5c9b\uff0c\u4e92\u76f8\u4e0d\u77e5\u9053\u5bf9\u65b9\u6709\u6ca1\u6709\u8fd9\u4e2a\u7b26\u53f7\uff0c\u6240\u4ee5 inline \u7684\u6548\u679c\u4ece\u201c\u5168\u5c40\u53ea\u4fdd\u7559\u4e00\u4efd\u5b9a\u4e49\u201d\u53d8\u6210\u5728\u6bcf\u4e2a\u201c\u5b64\u5c9b\u201d\u5185\u5404\u81ea\u5728\u5185\u90e8\u53ea\u4fdd\u7559\u4e00\u4efd\uff0c\u4ece\u800c DLL \u548c EXE \u5404\u81ea\u4e00\u4efd\uff0c\u603b\u5171\u6709\u4e24\u4efd\u4e86\uff0c\u4e92\u76f8\u5185\u5bb9\u4e0d\u4e92\u901a\uff0c\u4ece\u800c\u4e0d\u662f\u5355\u4f8b\u6a21\u5f0f\u3002\u800c Linux \u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a SO \u52a8\u6001\u5e93\u662f\u8fd0\u884c\u65f6\u624d\u7531 ld-linux.so \u5b8c\u6210\u94fe\u63a5\u7684\uff0cSO \u5185\u90e8\u4ecd\u4fdd\u6709\u7f16\u8bd1\u65f6\u4ea7\u751f\u7684\u51fd\u6570\u7b26\u53f7\u4fe1\u606f\uff0c\u4e3a\u7684\u662f\u88ab\u53ef\u6267\u884c ELF \u52a0\u8f7d\u8fdb\u6765\u4ee5\u540e\uff0c ld-linux.so \u53ef\u4ee5\u81ea\u52a8\u6839\u636e\u628a\u53ef\u6267\u884c ELF \u548c SO \u5185\u90e8\u7684 call \u6307\u4ee4\u540e\u7684\u5730\u5740\u66f4\u65b0\u4e3a\u52a0\u8f7d\u540e\u7684\u7b26\u53f7\u7684\u52a8\u6001\u5730\u5740\u3002\u800c Windows \u7684 DLL \u4e2d\u6240\u6709\u7b26\u53f7\u5728\u7f16\u8bd1\u65f6\u5c31\u5df2\u7ecf\u88ab ld \u5df2\u7ecf\u710a\u6b7b\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 Windows \u7684\u6bcf\u4e2a DLL \u90fd\u4f1a\u81ea\u52a8\u989d\u5916\u751f\u6210\u4e00\u4e2a\u540c\u540d LIB \u6587\u4ef6\uff0c\u8fd9\u4e2a LIB \u91cc\u9762\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e2a\u201c\u63d2\u6869\u201d\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u5b57\u548c DLL \u4e2d\u7684\u76f8\u540c\uff0c\u4f46\u662f\u51fd\u6570\u7684\u5185\u5bb9\uff0c\u662f\u4f1a\u52a8\u6001 LoadLibrary \u52a0\u8f7d\u540c\u540d DLL\uff0c\u5e76\u901a\u8fc7 GetProcAddress \u52a8\u6001\u83b7\u53d6\u6240\u6709 dllexport \u7684\u51fd\u6570\uff0c\u800c\u94fe\u63a5\u65f6\u5019\u6307\u5b9a\u7684\u5b9e\u9645\u4e0a\u662f\u539f DLL \u5bf9\u5e94\u7684\u8fd9\u4e2a\u63d2\u6869 LIB\uff0cDLL \u672c\u8eab\u662f\u65e0\u6cd5\u88ab\u94fe\u63a5\u5668\u94fe\u63a5\u7684\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: inline static Game &instance() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9e\u73b0\u7684\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c static Game game; return game; } }; Game::instance().updatePlayers(); \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \u3002 \u901a\u7528\u7684\u5355\u4f8b\u6a21\u5f0f\u6a21\u677f template inline T &singleton() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u5c31\u5730\u5b9e\u73b0\u7684\u6a21\u677f\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c // \u53ea\u6709\u7b2c\u4e00\u6b21\u8fdb\u5165\u65f6\u4f1a\u6784\u9020\u4e00\u904d T\uff0c\u4e4b\u540e\u4e0d\u4f1a\u518d\u6784\u9020 // \u4e0d\u540c\u7684 T \u4f1a\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684 singleton \u5b9e\u4f8b\uff0c\u5404\u81ea\u4f53\u5185\u7684 static \u53d8\u91cf\u72ec\u7acb\u8ba1\u7b97\uff0c\u4e92\u4e0d\u5e72\u6270 static T inst; return inst; } singleton().updatePlayers(); singleton().someMethod(); \u4efb\u4f55\u7c7b\u578b T\uff0c\u53ea\u8981\u4ee5 singleton() \u5f62\u5f0f\u83b7\u53d6\uff0c\u90fd\u80fd\u4fdd\u8bc1\u6bcf\u4e2a T \u90fd\u53ea\u6709\u4e00\u4efd\u5bf9\u8c61\u3002\uff08\u524d\u63d0\u662f\u4f60\u4e0d\u8981\u518d T() \u521b\u5efa\u5bf9\u8c61\uff09 \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u6a21\u677f\u7684\u58f0\u660e\u548c\u5b9a\u4e49 \u3002 \u6a21\u677f\u6a21\u5f0f \u6ce8\u610f\uff1a\u6a21\u677f\u6a21\u5f0f\u548c C++ \u7684\u6a21\u677f\u5e76\u6ca1\u6709\u5fc5\u7136\u5173\u7cfb\uff01\u6a21\u677f\u6a21\u5f0f\u53ea\u662f\u4e00\u79cd\u601d\u60f3\uff0c\u53ef\u4ee5\u7528\u6a21\u677f\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u7528\u865a\u51fd\u6570\u5b9e\u73b0\uff08\u5927\u591a\u53cd\u800c\u662f\u7528\u865a\u51fd\u6570\u5b9e\u73b0\u7684\uff09 \u6a21\u677f\u6a21\u5f0f\u7528\u4e8e\u5c01\u88c5\u6e38\u620f\u4e2d\u4e00\u4e9b\u76f8\u4f3c\u7684\u5904\u7406\u903b\u8f91\uff0c\u628a\u5171\u540c\u7684\u90e8\u5206\u96c6\u4e2d\u5230\u4e00\u4e2a\u57fa\u7c7b\uff0c\u628a\u4e0d\u540c\u7684\u7ec6\u8282\u90e8\u5206\u7559\u7ed9\u5b50\u7c7b\u5b9e\u73b0\u3002 \u548c\u7b56\u7565\u6a21\u5f0f\u5f88\u50cf\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u63a5\u6536\u7b56\u7565\u7684\u76f4\u63a5\u5c31\u662f\u57fa\u7c7b\u81ea\u5df1\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u56fa\u5b9a\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21\uff0c\u7136\u540e\u7ed8\u5236 1 \u6b21\u3002\u663e\u7136\u9700\u8981\u628a\u201c\u79fb\u52a8\u201d\u548c\u201c\u7ed8\u5236\u201d\u4f5c\u4e3a\u4e24\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u6765\u5b9e\u73b0\u3002 struct Character { virtual void draw() = 0; virtual void move() = 0; }; struct Player : Character { void draw() override { drawPlayer(); } void move() override { movePlayer(); } }; struct Enemy : Character { void draw() override { drawEnemy(); } void move() override { moveEnemy(); } }; \u5982\u679c\u8ba9\u8d1f\u8d23\u8c03\u7528 Character \u7684\u4eba\u6765\u5b9e\u73b0\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u7684\u8bdd\uff0c\u5c31\u7834\u574f\u4e86\u5f00\u95ed\u539f\u5219\u3002 struct Game { vector chars; void update() { for (auto &&c: chars) { c->move(); c->move(); c->move(); c->draw(); } } } \u6539\u4e3a\u628a\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u5c01\u88c5\u4e3a\u4e00\u4e2a Character \u7684\u666e\u901a\u51fd\u6570 update\u3002 struct Character { protected: virtual void draw() = 0; virtual void move() = 0; public: void update() { move(); move(); move(); draw(); } }; struct Game { vector chars; void update() { for (auto &&c: chars) { c->update(); } } } \u8fd9\u6837\u8c03\u7528\u8005\u5c31\u5f88\u8f7b\u677e\u4e86\uff0c\u4e0d\u5fc5\u5173\u5fc3\u5e95\u5c42\u7ec6\u8282\uff0c\u800c update \u4e5f\u53ea\u901a\u8fc7\u63a5\u53e3\u548c\u5b50\u7c7b\u901a\u4fe1\uff0c\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u548c\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\u3002 \u6a21\u677f\u6a21\u5f0f\u8fd8\u662f\u7b56\u7565\u6a21\u5f0f\uff1a\u5982\u4f55\u9009\u62e9\uff1f \u5f53\u4e00\u4e2a\u5bf9\u8c61\u6d89\u53ca\u5f88\u591a\u7b56\u7565\u65f6\uff0c\u7528\u7b56\u7565\u6a21\u5f0f\uff1b\u5f53\u53ea\u9700\u8981\u4e00\u4e2a\u7b56\u7565\uff0c\u4e14\u9700\u8981\u7528\u5230\u57fa\u7c7b\u7684\u6210\u5458\u65f6\uff0c\u7528\u6a21\u677f\u6a21\u5f0f\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u7684\u7b56\u7565\u6709\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\uff0c\u79fb\u52a8\u65b9\u5f0f\u6709\u201c\u8d70\u8def\u201d\u3001\u201c\u8dd1\u6b65\u201d\u4e24\u79cd\uff0c\u653b\u51fb\u7b56\u7565\u53c8\u6709\u201c\u5e73A\u201d\u3001\u201c\u66b4\u51fb\u201d\u4e24\u79cd\u3002 \u90a3\u4e48\u5c31\u7528\u7b56\u7565\u6a21\u5f0f\uff0c\u8ba9\u89d2\u8272\u5206\u522b\u6307\u5411\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\u7684\u6307\u9488\u3002 struct Character { MoveStrategy *moveStrategy; AttackStrategy *attackStrategy; void update() { if (isKeyPressed(GLFW_KEY_S) { moveStrategy->move(); } else if (isKeyPressed(GLFW_KEY_W)) { moveStrategy->run(); } while (auto enemy = Game::instance().findEnemy(range)) { attackStrategy->attack(enemy); } } }; \u800c\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u7b56\u7565\uff0c\u6bd4\u5982\u6b66\u5668\u7c7b\uff0c\u53ea\u9700\u8981\u653b\u51fb\u7b56\u7565\uff0c\u5e76\u4e14\u653b\u51fb\u7b56\u7565\u9700\u8981\u77e5\u9053\u6b66\u5668\u7684\u4f24\u5bb3\u503c\u3001\u5c04\u7a0b\u3001\u9644\u9b54\u5c5e\u6027\u7b49\u4fe1\u606f\uff0c\u90a3\u5c31\u9002\u5408\u6a21\u677f\u6a21\u5f0f\u3002 struct Weapon { protected: double damage; double charge; MagicFlag magicFlags; double range; virtual void attack(Enemy *enemy); public: void update() { while (auto enemy = Game::instance().findEnemy(range)) { attack(enemy); } } }; \u6700\u5e38\u89c1\u7684\u662f do_xxx \u5c01\u88c5 \u4f8b\u5982\uff0c\u4e00\u4e2a\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u63a5\u53e3\u7c7b\uff1a struct Converter { virtual void process(const char *s, size_t len) = 0; }; \u8fd9\u4e2a\u63a5\u53e3\u662f\u8003\u8651 \u5b9e\u73b0 Converter \u5b50\u7c7b\u7684\u65b9\u4fbf \uff0c\u5bf9\u4e8e \u8c03\u7528 Converter \u7684\u7528\u6237 \u4f7f\u7528\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u65b9\u4fbf\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u8fd0\u7528\u6a21\u677f\u6a21\u5f0f\uff0c\u628a\u539f\u6765\u7684\u865a\u51fd\u6570\u63a5\u53e3\u6539\u4e3a protected \u7684\u51fd\u6570\uff0c\u4e14\u540d\u5b57\u6539\u4e3a do_process\u3002 struct Converter { protected: virtual void do_process(const char *s, size_t len) = 0; public: void process(string_view str) { return do_process(str.data(), str.size()); } void process(string str) { return do_process(str.data(), str.size()); } void process(const char *cstr) { return do_process(cstr, strlen(cstr)); } }; \u5b9e\u73b0 Converter \u7684\u5b50\u7c7b\u65f6\uff0c\u91cd\u5199\u4ed6\u7684 do_process \u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u662f protected \u7684\uff0c\u53ea\u80fd\u88ab\u7ee7\u627f\u4e86 Converter \u7684\u5b50\u7c7b\u8bbf\u95ee\u548c\u91cd\u5199\u3002 \u5916\u5c42\u7528\u6237\u53ea\u80fd\u901a\u8fc7 Converter \u57fa\u7c7b\u5c01\u88c5\u597d\u7684 process \u51fd\u6570\uff0c\u907f\u514d\u5916\u5c42\u7528\u6237\u76f4\u63a5\u5e72\u6d89\u5e95\u5c42\u7ec6\u8282\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 std::pmr::memory_resource \u3001 std::codecvt \u7b49\u90fd\u8fd0\u7528\u4e86 do_xxx \u5f0f\u7684\u6a21\u677f\u6a21\u5f0f\u5c01\u88c5\u3002 \u72b6\u6001\u6a21\u5f0f \u6e38\u620f\u4e2d\u7684\u89d2\u8272\u901a\u5e38\u6709\u591a\u79cd\u72b6\u6001\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u602a\u7269\u53ef\u80fd\u6709\u201c\u5f85\u673a\u201d\u3001\u201c\u5de1\u903b\u201d\u3001\u201c\u8ffd\u51fb\u201d\u3001\u201c\u653b\u51fb\u201d\u7b49\u591a\u79cd\u72b6\u6001\uff0c\u800c\u6bcf\u79cd\u72b6\u6001\u4e0b\u7684\u884c\u4e3a\u90fd\u4e0d\u4e00\u6837\u3002 \u5982\u679c\u7528\u4e00\u4e2a\u679a\u4e3e\u53d8\u91cf\u6765\u8868\u793a\u5f53\u524d\u72b6\u6001\uff0c\u90a3\u6bcf\u6b21\u5c31\u90fd\u9700\u8981\u7528 switch \u6765\u5904\u7406\u4e0d\u540c\u7684\u72b6\u6001\u3002 enum MonsterState { Idle, Chase, Attack, }; struct Monster { MonsterState state = Idle; void update() { switch (state) { case Idle: if (seesPlayer()) state = Chase; break; case Chase: if (canAttack()) state = Attack; else if (!seesPlayer()) state = Idle; break; case Attack: if (!seesPlayer()) state = Idle; break; } } }; \u8fd9\u6216\u8bb8\u6027\u80fd\u4e0a\u6709\u4e00\u5b9a\u4f18\u52bf\uff0c\u7f3a\u70b9\u662f\uff0c\u6240\u6709\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5806\u79ef\u5728\u540c\u4e00\u4e2a\u51fd\u6570\u4e2d\uff0c\u5982\u679c\u6709\u591a\u4e2a\u51fd\u6570\uff08\u4e0d\u53ea\u662f update\uff09\uff0c\u90a3\u4e48\u6bcf\u6dfb\u52a0\u4e00\u4e2a\u65b0\u72b6\u6001\u5c31\u9700\u8981\u4fee\u6539\u6240\u6709\u51fd\u6570\uff0c\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u800c\u4e14\u5982\u679c\u4e0d\u540c\u7684\u72b6\u6001\u542b\u6709\u4e0d\u540c\u7684\u989d\u5916\u6570\u503c\u9700\u8981\u5b58\u50a8\uff0c\u6bd4\u5982 Chase \u72b6\u6001\u9700\u8981\u5b58\u50a8\u5f53\u524d\u901f\u5ea6\uff0c\u90a3\u5c31\u9700\u8981\u5728 Monster \u7c7b\u4e2d\u6dfb\u52a0 speed \u6210\u5458\uff0c\u800c state \u4e0d\u4e3a Chase \u65f6\u53c8\u7528\u4e0d\u5230\u8fd9\u4e2a\u6210\u5458\uff0c\u975e\u5e38\u5bb9\u6613\u6270\u4e71\u601d\u7ef4\u3002 \u72b6\u6001\u4e0d\u662f\u679a\u4e3e\uff0c\u800c\u662f\u7c7b \u4e3a\u6b64\uff0c\u63d0\u51fa\u4e86\u72b6\u6001\u6a21\u5f0f\uff0c\u5c06\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5206\u79bb\u5230\u4e0d\u540c\u7684\u7c7b\u4e2d\u3002\u4ed6\u628a\u6bcf\u79cd\u72b6\u6001\u62bd\u8c61\u4e3a\u4e00\u4e2a\u7c7b\uff0c\u72b6\u6001\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u89d2\u8272\u6301\u6709\u8868\u793a\u5f53\u524d\u72b6\u6001\u7684\u5bf9\u8c61\uff0c\u7528\u72b6\u6001\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u6765\u8868\u793a\u5904\u7406\u903b\u8f91\uff0c\u800c\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u901a\u8fc7 if \u5224\u65ad\u6765\u6267\u884c\u4e0d\u540c\u7684\u884c\u4e3a\u3002 struct Monster; struct State { virtual void update(Monster *monster) = 0; }; struct Idle : State { void update(Monster *monster) override { if (monster->seesPlayer()) { monster->setState(new Chase()); } } }; struct Chase : State { void update(Monster *monster) override { if (monster->canAttack()) { monster->setState(new Attack()); } else if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Attack : State { void update(Monster *monster) override { if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Monster { State *state = new Idle(); void update() { state->update(this); } void setState(State *newState) { delete state; state = newState; } }; \u539f\u578b\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f\u7528\u4e8e\u590d\u5236\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u4e14\u65b0\u5bf9\u8c61\u7684 \u5c5e\u6027 \u548c \u7c7b\u578b \u4e0e\u539f\u6765\u76f8\u540c\u3002\u5982\u4f55\u5b9e\u73b0\uff1f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4e0d\u884c\uff1f \u62f7\u8d1d\u6784\u9020\u51fd\u6570\u53ea\u80fd\u7528\u4e8e\u7c7b\u578b\u786e\u5b9a\u7684\u60c5\u51b5\uff0c\u5bf9\u4e8e\u5177\u6709\u865a\u51fd\u6570\uff0c\u53ef\u80fd\u5177\u6709\u989d\u5916\u6210\u5458\u7684\u591a\u6001\u7c7b\u578b\uff0c\u4f1a\u53d1\u751f object-slicing\uff0c\u5bfc\u81f4\u62f7\u8d1d\u51fa\u6765\u7684\u7c7b\u578b\u53ea\u662f\u57fa\u7c7b\u7684\u90e8\u5206\uff0c\u800c\u4e0d\u662f\u5b8c\u6574\u7684\u5b50\u7c7b\u5bf9\u8c61\u3002 RedBall ball; Ball newball = ball; // \u9519\u8bef\uff1a\u53d1\u751f\u4e86 object-slicing\uff01\u73b0\u5728 newball \u7684\u7c7b\u578b\u53ea\u662f Ball \u4e86\uff0c\u4e22\u5931\u4e86 RedBall \u7684\u4fe1\u606f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6307\u9488\u4e0d\u884c\uff1f \u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff0c\u800c\u6211\u4eec\u9700\u8981\u7684\u662f\u6df1\u62f7\u8d1d\u3002 Ball *ball = new RedBall(); Ball *newball = ball; // \u9519\u8bef\uff1a\u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff01newball \u548c ball \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u5bf9\u8c61 \u9700\u8981\u8c03\u7528\u5230\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u540c\u65f6\u53c8\u57fa\u4e8e\u6307\u9488 Ball *ball = new RedBall(); Ball *newball = new RedBall(*dynamic_cast(ball)); // \u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u91cc\u663e\u5f0f\u5199\u51fa\u4e86 ball \u5185\u90e8\u7684\u771f\u6b63\u7c7b\u578b\uff0c\u8fdd\u80cc\u4e86\u5f00\u95ed\u539f\u5219 \u5c06\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5c01\u88c5\u4e3a\u865a\u51fd\u6570 \u539f\u578b\u6a21\u5f0f\u5c06\u5bf9\u8c61\u7684\u62f7\u8d1d\u65b9\u6cd5\u4f5c\u4e3a\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u4e00\u4e2a\u865a\u63a5\u53e3\u7684\u6307\u9488\uff0c\u907f\u514d\u4e86\u76f4\u63a5\u62f7\u8d1d\u7c7b\u578b\u3002\u4f46\u865a\u51fd\u6570\u5185\u90e8\u4f1a\u8c03\u7528\u5b50\u7c7b\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u5b9e\u73b0\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u719f\u6089\u5de5\u5382\u6a21\u5f0f\u7684\u540c\u5b66\uff1a\u539f\u578b\u6a21\u5f0f\u76f8\u5f53\u4e8e\u628a\u6bcf\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e86\u81ea\u5df1\u7684\u5de5\u5382\uff0c\u53ea\u9700\u8981\u6709\u4e00\u4e2a\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u5c31\u80fd\u4e0d\u65ad\u590d\u5236\u51fa\u548c\u4ed6\u76f8\u540c\u7c7b\u578b\u7684\u5bf9\u8c61\u6765\u3002 struct Ball { virtual Ball *clone() = 0; }; struct RedBall : Ball { Ball *clone() override { return new RedBall(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { Ball *clone() override { return new BlueBall(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230 }; \u597d\u5904\u662f\uff0c\u8c03\u7528\u8005\u65e0\u9700\u77e5\u9053\u5177\u4f53\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u4ed6\u662f Ball \u7684\u5b50\u7c7b\uff0c\u5c31\u53ef\u4ee5\u514b\u9686\u51fa\u4e00\u4efd\u5b8c\u5168\u4e00\u6837\u7684\u5b50\u7c7b\u5bf9\u8c61\u6765\uff0c\u4e14\u8fd4\u56de\u7684\u4e5f\u662f\u6307\u9488\uff0c\u4e0d\u4f1a\u53d1\u751f object-slicing\u3002 Ball *ball = new RedBall(); ... Ball *newball = ball->clone(); // newball \u7684\u7c7b\u578b\u4ecd\u7136\u662f RedBall clone \u8fd4\u56de\u4e3a\u667a\u80fd\u6307\u9488 struct Ball { virtual unique_ptr clone() = 0; }; struct RedBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230\u65b0\u5bf9\u8c61\u4e2d }; \u8fd9\u6837\u5c31\u4fdd\u8bc1\u4e86\u5185\u5b58\u4e0d\u4f1a\u6cc4\u6f0f\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f shared_ptr\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a shared_ptr\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f\u624b\u52a8 delete \u7684\u539f\u59cb\u6307\u9488\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u901a\u8fc7 release\uff0c\u6545\u610f\u9020\u6210\u4e00\u6b21\u5185\u5b58\u6cc4\u6f0f\uff0c\u6210\u4e3a\u9700\u8981\u624b\u52a8\u7ba1\u7406\u7684\u539f\u59cb\u6307\u9488\u3002 CRTP \u6a21\u5f0f\u81ea\u52a8\u5b9e\u73b0 clone CRTP\uff08Curiously Recurring Template Pattern\uff09\u662f\u4e00\u79cd\u6a21\u677f\u5143\u7f16\u7a0b\u6280\u672f\uff0c\u5b83\u53ef\u4ee5\u5728\u7f16\u8bd1\u671f\u95f4\u628a\u6d3e\u751f\u7c7b\u7684\u7c7b\u578b\u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u4f20\u9012\u7ed9\u57fa\u7c7b\uff0c\u4ece\u800c\u5b9e\u73b0\u4e00\u4e9b\u81ea\u52a8\u5316\u7684\u529f\u80fd\u3002 \u7279\u70b9\u662f\uff0c\u7ee7\u627f\u4e00\u4e2a CRTP \u7c7b\u65f6\uff0c\u9700\u8981\u628a\u5b50\u7c7b\u672c\u8eab\u4f5c\u4e3a\u57fa\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u3002 \u5e76\u4e0d\u4f1a\u51fa\u73b0\u5faa\u73af\u5f15\u7528\u662f\u56e0\u4e3a\uff0c\u7528\u5230\u5b50\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\u662f\u5728\u57fa\u7c7b\u7684\u6210\u5458\u51fd\u6570\u5185\u90e8\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5728\u57fa\u7c7b\u5185\u90e8\uff0c\u800c\u6a21\u677f\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\u7684\u5b9e\u4f8b\u5316\u662f\u60f0\u6027\u7684\uff0c\u7528\u5230\u4e86\u624d\u4f1a\u5b9e\u4f8b\u5316\u3002 template struct Pet { void feed() { Derived *that = static_cast(this); that->speak(); that->speak(); } }; struct CatPet : Pet { void speak() { puts(\"Meow!\"); } }; struct DogPet : Pet { void speak() { puts(\"Bark!\"); } }; \u4e00\u822c\u7684\u8c61\u7259\u5854\u7406\u8bba\u5bb6\u6559\u6750\u4e2d\u90fd\u4f1a\u544a\u8bc9\u4f60\uff0cCRTP \u662f\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u66f4\u9ad8\u6548\u5730\u5b9e\u73b0\u6a21\u677f\u6a21\u5f0f\uff0c\u597d\u50cf CRTP \u5c31\u548c\u865a\u51fd\u6570\u52bf\u4e0d\u4e24\u7acb\u3002 \u4f46\u5c0f\u5f6d\u8001\u5e08\u7684\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0cCRTP \u5e38\u5e38\u662f\u548c\u865a\u51fd\u6570\u4e00\u8d77\u51fa\u73b0\u7684\u597d\u642d\u6863\u3002 \u4f8b\u5982 CRTP \u53ef\u4ee5\u5e2e\u52a9\u539f\u578b\u6a21\u5f0f\u5b9e\u73b0\u81ea\u52a8\u5316\u5b9a\u4e49 clone \u865a\u51fd\u6570\uff0c\u7a0d\u540e\u4ecb\u7ecd\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u4e2d\u4e5f\u4f1a\u7528\u5230 CRTP\u3002 struct Ball { virtual unique_ptr clone() = 0; }; template struct BallImpl : Ball { // \u81ea\u52a8\u5b9e\u73b0 clone \u7684\u8f85\u52a9\u5de5\u5177\u7c7b unique_ptr clone() override { Derived *that = static_cast(this); return make_unique(*that); } }; struct RedBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; struct BlueBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0c\u5bf9\u8c61\u7c7b\u578b zeno::IObject \u7684\u6df1\u62f7\u8d1d\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u539f\u578b\u6a21\u5f0f\u3002 \u7ec4\u4ef6\u6a21\u5f0f \u6e38\u620f\u4e2d\u7684\u7269\u4f53\uff08\u6e38\u620f\u5bf9\u8c61\uff09\u901a\u5e38\u7531\u591a\u4e2a\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u53ef\u80fd\u7531\u201c\u89d2\u8272\u63a7\u5236\u5668\u201d\u3001\u201c\u89d2\u8272\u5916\u89c2\u201d\u3001\u201c\u89d2\u8272\u52a8\u753b\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4e00\u4e2a\u5b50\u5f39\u53ef\u80fd\u7531\u201c\u5b50\u5f39\u7269\u7406\u201d\u3001\u201c\u5b50\u5f39\u5916\u89c2\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\u3002 \u7ec4\u4ef6\u6a21\u5f0f\u662f \u6e38\u620f\u5f00\u53d1\u9886\u57df\u6700\u91cd\u8981\u7684\u8bbe\u8ba1\u6a21\u5f0f \uff0c\u5b83\u5c06\u6e38\u620f\u5bf9\u8c61\u5206\u4e3a\u591a\u4e2a\u7ec4\u4ef6\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u53ea\u5173\u5fc3\u81ea\u5df1\u7684\u903b\u8f91\uff0c\u800c\u4e0d\u5173\u5fc3\u5176\u4ed6\u7ec4\u4ef6\u7684\u903b\u8f91\u3002 \u8e69\u811a\u7684\u6e38\u620f\u5f00\u53d1\u8005\uff08\u901a\u5e38\u662f 985 \u91cf\u4ea7\u51fa\u6765\u7684\u8c61\u7259\u5854\u5de8\u5a74\uff09\u4f1a\u628a\u6bcf\u4e2a\u7ec4\u4ef6\u5199\u6210\u4e00\u4e2a\u7c7b\uff0c\u7136\u540e\u4f7f\u7528\u201c\u591a\u91cd\u7ee7\u627f\u201d\u7ee7\u627f\u51fa\u4e00\u4e2a\u73a9\u5bb6\u7c7b\u6765\uff0c\u5e76\u606c\u4e0d\u77e5\u803b\u5730\u58f0\u79f0\u201c\u6211\u4e5f\u4f1a\u7ec4\u4ef6\u6a21\u5f0f\u4e86\u201d\u3002 \u7136\u800c\uff0c\u8fd9\u6837\u7684\u7f3a\u70b9\u6709\uff1a \u6e38\u620f\u5f00\u53d1\u4e2d\u666e\u904d\u6d89\u53ca\u5230 update \u51fd\u6570\uff0c\u800c\u73a9\u5bb6\u7c7b\u7684 update \u9700\u8981\u8f6e\u6d41\u8c03\u7528\u6bcf\u4e2a\u7ec4\u4ef6\u7684 update \u51fd\u6570\u3002 \u800c\u591a\u91cd\u7ee7\u627f\u4e00\u65e6\u9047\u5230\u91cd\u540d\u7684 update \u51fd\u6570\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519 \u201c\u6709\u6b67\u4e49\u7684\u51fd\u6570\u540d\u201d \u6446\u70c2\u4e0d\u5e72\u4e86\uff0c\u9700\u8981\u4f60\u624b\u5199\u65b0\u7684 update \u51fd\u6570\u3002 struct Player : PlayerController, PlayerAppearance, PlayerAnimation { void update() { PlayerController::update(); PlayerAppearance::update(); PlayerAnimation::update(); } }; C++\uff08\u548c\u5927\u591a\u6570\u975e\u811a\u672c\u8bed\u8a00\u90fd\uff09\u4e0d\u652f\u6301\u8fd0\u884c\u65f6\u6dfb\u52a0\u6216\u5220\u9664\u57fa\u7c7b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u8981\u6dfb\u52a0\u4e00\u4e2a\u65b0\u89d2\u8272\uff0c\u6216\u662f\u4fee\u6539\u73b0\u6709\u89d2\u8272\u7684\u903b\u8f91\uff0c\u5c31\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u4e00\u904d\u6574\u4e2a\u6e38\u620f\u7684\u6e90\u7801\u3002 \u5728\u7f51\u7edc\u6e38\u620f\u4e2d\uff0c\u66f4\u65b0 DLL \u548c\u66f4\u65b0\u8d44\u4ea7\uff08\u56fe\u7247\u3001\u97f3\u9891\u3001\u6a21\u578b\u7b49\uff09\u662f\u5b8c\u5168\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u670d\u52a1\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u505c\u673a\u66f4\u65b0\uff0c\u66f4\u65b0\u8d44\u4ea7\u4e0d\u9700\u8981\uff0cDLL \u53ef\u4ee5\u88ab\u7f16\u7a0b\u5141\u8bb8\u52a8\u6001\u52a0\u8f7d\u65b0\u7684\u8d34\u56fe\u3002 \u5bf9\u4e8e\u5ba2\u6237\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u91cd\u65b0\u8d70\u4e00\u904d\u5f88\u957f\u7684 App \u5ba1\u6838\u6d41\u7a0b\uff08\u56e0\u4e3a\u76f4\u63a5\u8fd0\u884c\u4e8e\u624b\u673a\u4e0a\u7684 C++ \u53ef\u4ee5\u8f7b\u677e\u690d\u5165\u75c5\u6bd2\uff09\uff0c\u800c\u66f4\u65b0\u8d44\u4ea7\u7684\u5ba1\u6838\u6d41\u7a0b\u77ed\u5f97\u591a\uff0c\u751a\u81f3\u5e72\u8106\u65e0\u9700\u5ba1\u6838\u3002 \u56e0\u6b64\uff0c\u6e38\u620f\u5f00\u53d1\u8005\u5f88\u5c11\u4f1a\u628a\u6e38\u620f\u903b\u8f91\u76f4\u63a5\u5199\u6b7b\u5728 C++ \u4e2d\uff0c\u8fd9\u4f1a\u8ba9\u66f4\u65b0\u6e38\u620f\u903b\u8f91\uff08\u4f8b\u5982\u4fee\u590d BUG\uff09\u9700\u8981\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6bcf\u6b21\u505c\u673a\u66f4\u65b0\u90fd\u4f1a\u7ed9\u73a9\u5bb6\u53d1 200 \u5408\u6210\u7389\uff09 \u4f60\u7ecf\u5e38\u770b\u5230\u6e38\u620f\u9886\u57df\u7684 \u201cC++ \u5f00\u53d1\u5c97\u201d \u5b9e\u9645\u4e0a\u662f \u201c\u89e3\u91ca\u5668\u5f00\u53d1\u201d\u3002 \u6e38\u620f\u5f00\u53d1\u8005\u4f1a\u628a\u7ecf\u5e38\u9700\u8981\u7ef4\u62a4\u548c\u66f4\u65b0\u7684\u6e38\u620f\u903b\u8f91\u5199\u5728\u5982 Lua\u3001Python \u7b49\u811a\u672c\u8bed\u8a00\u4e2d\uff0c\u7136\u540e\u5728 C++ \u4e2d\u96c6\u6210\u4e00\u4e2a Lua\u3001Python \u89e3\u91ca\u5668\uff0c\u6839\u636e\u89e3\u91ca\u5668\u7684\u8c03\u7528\u7ed3\u679c\uff0c\u52a8\u6001\u521b\u5efa\u51fa C++ \u5bf9\u8c61\uff0c\u7136\u540e\u628a\u8fd9\u4e9b C++ \u5bf9\u8c61\u5f53\u4f5c\u7ec4\u4ef6\u6dfb\u52a0\u5230\u6e38\u620f\u5bf9\u8c61\u4e0a\u3002 \u5f53\u51fa\u73b0 BUG \u65f6\uff0c\u53ea\u9700\u8981\u4fee\u6539\u8fd9\u4e9b\u811a\u672c\u8bed\u8a00\u7684\u4ee3\u7801\uff0c\u7136\u540e\u4ee5\u201c\u8d44\u4ea7\u201d\u7684\u5f62\u5f0f\uff0c\u5feb\u901f\u8d70\u4e00\u904d\u5ba1\u6838\u6d41\u7a0b\uff0c\u5c31\u53ef\u4ee5\u4fee\u590d BUG\uff0c\u65e0\u9700\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6709\u65f6\u5019\u4f1a\u201c\u8d44\u6e90\u5df2\u8fc7\u671f\u201d\u201c\u6b63\u5728\u4e0b\u8f7d\u8d44\u6e90\u201d\uff0c\u6709\u65f6\u662f\u66f4\u65b0\u4e86\u56fe\u7247\u8d44\u6e90\uff0c\u4e5f\u53ef\u80fd\u662f\u5728\u811a\u672c\u8bed\u8a00\u91cc\u52a8\u6001\u4fee\u590d\u4e86 BUG\uff09 Java \u548c C# \u90fd\u6ca1\u6709\u591a\u91cd\u7ee7\u627f\u3002\u4f60\u8ba9\u4eba\u5bb6\u57fa\u4e8e C# \u7684 Unity \u600e\u4e48\u6d3b\uff1f \u56e0\u6b64\uff0c\u771f\u6b63\u7684\u7ec4\u4ef6\u6a21\u5f0f\u90fd\u4f1a\u5141\u8bb8\u52a8\u6001\u63d2\u5165\u7ec4\u4ef6\uff0c\u800c\u4e0d\u662f\u7f16\u8bd1\u671f\u5199\u6b7b\u3002\u9664\u975e\u4f60\u662f\u67d0\u4e9b\u8c61\u7259\u5854\u7684\u4e00\u6b21\u6027\u6c99\u96d5\u5927\u4f5c\u4e1a\u3002 \u6e38\u620f\u5bf9\u8c61\u7ec4\u4ef6\u5316\u540e\uff0c\u53ef\u4ee5\u7075\u6d3b\u5730\u7ec4\u5408\u51fa\u4e0d\u540c\u7684\u6e38\u620f\u5bf9\u8c61\uff0c\u800c\u4e0d\u5fc5\u4e3a\u6bcf\u4e00\u79cd\u7ec4\u5408\u90fd\u5199\u4e00\u4e2a\u7c7b\u3002 struct Component { virtual void update(GameObject *go) = 0; virtual ~Component() = default; // \u6ce8\u610f\uff01 }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } }; \u6ce8\u610f\uff1aComponent \u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u4e3a\u865a\u51fd\u6570\u3002\u5426\u5219\uff0c\u5f53 Component \u88ab delete \u65f6\uff0c\u53ea\u4f1a\u8c03\u7528\u5230 Component \u8fd9\u4e2a\u57fa\u7c7b\u7684\u6790\u6784\u51fd\u6570\uff0c\u800c\u4e0d\u4f1a\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6790\u6784\u51fd\u6570\u3002 \u5426\u5219\uff0c\u5982\u679c\u4f60\u7684\u5b50\u7c7b\u6709 string\u3001vector \u8fd9\u79cd\u6301\u6709\u5185\u5b58\u8d44\u6e90\u7684\u5bb9\u5668\u7c7b\uff0c\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f\uff0c\u5bfc\u81f4\u6e38\u620f\u8fd0\u884c\u8d8a\u4e45\u5185\u5b58\u5360\u7528\u8d8a\u5927\u3002 \u795e\u5947\u7684\u662f\uff0c\u5982\u679c\u4f60\u7684 Component \u5168\u90e8\u90fd\u662f\u7528 make_shared \u521b\u5efa\u7684\uff0c\u90a3\u5c31\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\u4e86\uff0c\u8fd9\u5f97\u76ca\u4e8e shared_ptr \u4f1a\u5bf9 deleter \u505a\u7c7b\u578b\u64e6\u9664\u3002 make_unique \u548c new \u521b\u5efa\u7684\u5c31\u4f1a\u6cc4\u6f0f\uff0c\u56e0\u4e3a\u4ed6\u4eec delete \u65f6\u662f\u4ee5\u57fa\u7c7b\u6307\u9488\u53bb delete \u7684\uff0c\u800c shared_ptr \u4f1a\u5728\u6784\u9020\u65f6\u5c31\u8bb0\u4f4f\u5b50\u7c7b\u7684 deleter\u3002 \u6240\u6709\u7ec4\u4ef6\uff0c\u90fd\u652f\u6301 update\uff08\u6bcf\u5e27\u66f4\u65b0\uff09\u64cd\u4f5c\uff1a struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void update(GameObject *go) override { position += velocity * dt; } }; struct LivingBeing : Component { int ageLeft; void update(GameObject *go) override { if (ageLeft < 0) go->kill(); else ageLeft -= 1; } }; \u7ec4\u4ef6\u7684\u521b\u5efa \u7ec4\u4ef6\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a \u7ec4\u4ef6\u4f5c\u4e3a\u4e00\u4e2a\u666e\u901a\u5bf9\u8c61\uff0c\u7531 GameObject \u7684\u6784\u9020\u51fd\u6570\u521b\u5efa\u3002 struct Player : GameObject { Movable *movable; LivingBeing *livingBeing; PlayerController *playerController; PlayerAppearance *playerAppearance; Player() { movable = new Movable(); livingBeing = new LivingBeing(42); playerController = new PlayerController(); playerAppearance = new PlayerAppearance(); add(movable); add(livingBeing); add(playerController); add(playerAppearance); } }; \u4e0d\u518d\u9700\u8981\u5b9a\u4e49 Player \u7c7b\u53ca\u5176\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u521b\u5efa\u5177\u6709 Player \u6240\u9700\u6240\u6709\u7ec4\u4ef6\u7684 GameObject \u5bf9\u8c61\u5373\u53ef\u3002 GameObject *makePlayer() { GameObject *go = new GameObject(); go->add(new Movable()); go->add(new LivingBeing(42)); go->add(new PlayerController()); go->add(new PlayerAppearance()); return go; } \u6b63\u7ecf\u6e38\u620f\u5f15\u64ce\u90fd\u91c7\u7528\u540e\u8005\uff0c\u4e0d\u7528\u6dfb\u52a0 C++ \u6e90\u7801\uff0c\u53ea\u662f\u4ece xml \u7b49\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u6bcf\u4e2a\u7c7b\u6240\u4f9d\u8d56\u7684\u7ec4\u4ef6\uff0c\u5c31\u80fd\u521b\u5efa\u65b0\u7684\u73a9\u5bb6\u7c7b\uff0c\u65b9\u4fbf\u52a8\u6001\u66f4\u65b0\u6e38\u620f\u903b\u8f91\u800c\u65e0\u9700\u91cd\u65b0\u53d1\u5e03 dll\u3002 \u7ec4\u4ef6\u4e4b\u95f4\u5982\u4f55\u901a\u4fe1 \u7f3a\u70b9\u662f\uff0c\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u9700\u8981\u901a\u8fc7 GameObject \u6765\u5b9e\u73b0\uff0c\u800c GameObject \u5e76\u4e0d\u77e5\u9053\u5b83\u7684\u7ec4\u4ef6\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u5c31\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u7ec4\u4ef6\u7684\u6210\u5458\u3002 \u4f8b\u5982\uff0cPlayerController \u7ec4\u4ef6\u60f3\u8981\u6539\u53d8 Movable \u7ec4\u4ef6\u7684 velocity\uff0c\u5c31\u65e0\u6cd5\u76f4\u63a5\u6539\u3002 struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { go->velocity.y += 1; // \u9519\u8bef\uff01velocity \u662f Movable \u7ec4\u4ef6\u7684\u6210\u5458\uff0c\u800c\u4e0d\u662f GameObject \u91cc\u76f4\u63a5\u6709\u7684 } if (isKeyPressed(GLFW_KEY_S)) { go->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { go->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { go->velocity.x += 1; } } }; \u5982\u4f55\u89e3\u51b3\u7ec4\u4ef6\u4e4b\u95f4\u901a\u4fe1\u96be\u7684\u95ee\u9898\uff1f \u628a\u5e38\u7528\u7684\u5b57\u6bb5\uff0c\u4f8b\u5982 position \u548c velocity \u76f4\u63a5\u653e\u5728 GameObject \u91cc\uff0c\u4f9b\u6240\u6709\u7ec4\u4ef6\u76f4\u63a5\u8bbf\u95ee\u3002 struct GameObject { glm::vec3 position; glm::vec3 velocity; ... }; \u5141\u8bb8\u7528\u6237\u6839\u636e\u5176\u4ed6\u7ec4\u4ef6\u7684\u7c7b\u578b\uff0c\u76f4\u63a5\u83b7\u53d6\u51fa\u5176\u4ed6\u7ec4\u4ef6\u7684\u6307\u9488\uff0c\u5373\u53ef\u8bbf\u95ee\u5176\u6210\u5458\u3002 struct PlayerController : Component { void update(GameObject *go) override { Movable *movable = go->getComponent(); if (!movable) { throw runtime_error(\"\u8fd9\u4e2a\u5bf9\u8c61\u4f3c\u4e4e\u4e0d\u652f\u6301\u79fb\u52a8\"); } if (isKeyPressed(GLFW_KEY_W)) { movable->velocity.y += 1; } if (isKeyPressed(GLFW_KEY_S)) { movable->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { movable->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { movable->velocity.x += 1; } } }; \u7136\u800c\uff0cgetComponent \u5982\u4f55\u5b9e\u73b0\uff1f struct GameObject { template T *getComponent() { for (auto &&c: components) { if (T *t = dynamic_cast(c)) { return t; } } return nullptr; } }; \u7528\u5230\u4e86 dynamic_cast \uff0c\u8fd9\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\u4e00\u79cd\u5b9e\u73b0\u65b9\u5f0f\uff0c\u800c\u4e14\u4e5f\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u66f4\u597d\u7684\u5b9e\u73b0\u65b9\u5f0f\u662f\u5229\u7528 typeid \u505a map \u7684\u952e\uff0c\u52a0\u901f\u67e5\u627e\u3002\u6ca1\u6709\u6027\u80fd\u95ee\u9898\uff0c\u4f46\u4f9d\u7136\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 struct GameObject { unordered_map components; template T *getComponent() { if (auto it = components.find(typeid(T)); it != components.end()) { return dynamic_cast(it->second); } else { return nullptr; } } void add(Component *component) { components[typeid(*component)] = component; } }; \u8ba9 PlayerController \u53d1\u51fa\u6307\u5b9a\u7c7b\u578b\u7684\u6d88\u606f\u5bf9\u8c61\uff0c\u7531 Movable \u68c0\u67e5\u5e76\u5904\u7406\u3002 \u6d88\u606f\u7c7b\u578b\u4e5f\u662f\u591a\u6001\u7684\uff0c\u521d\u5b66\u8005\u53ef\u4ee5\u5148\u901a\u8fc7 dynamic_cast \u5b9e\u73b0\u7c7b\u578b\u68c0\u67e5\u3002\u7a0d\u540e\u6211\u4eec\u4f1a\u4ecb\u7ecd\u66f4\u4e13\u4e1a\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u628a\u5b50\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u57fa\u7c7b\u6307\u9488\u3002 \u800c dynamic_cast \u53ef\u4ee5\u628a\u57fa\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u5b50\u7c7b\u6307\u9488\u3002 \u5982\u679c\u4ed6\u6307\u5411\u7684\u5bf9\u8c61\u786e\u5b9e\u5c31\u662f\u90a3\u4e2a\u5b50\u7c7b\u7c7b\u578b\u7684\u8bdd\uff0c\u5c31\u6b63\u5e38\u8fd4\u56de\u5b50\u7c7b\u6307\u9488\u4e86\u3002 \u5426\u5219\uff0c\u5982\u679c\u7c7b\u578b\u4e0d\u5339\u914d\uff0c dynamic_cast \u4f1a\u8fd4\u56de nullptr\u3002\u53ea\u9700\u5224\u65ad\u8fd4\u56de\u7684\u6307\u9488\u662f\u4e0d\u662f nullptr \u5c31\u77e5\u9053\u662f\u5426\u7c7b\u578b\u5339\u914d\u4e86\u3002 \u89c2\u5bdf\u8005\u6a21\u5f0f struct Message { virtual ~Message() = default; // C++ \u89c4\u5b9a\uff1a\u53ea\u6709\u591a\u6001\u7c7b\u578b\u624d\u80fd dynamic_cast\uff0c\u8fd9\u91cc\u6211\u4eec\u7528\u4e0d\u5230\u865a\u51fd\u6570\uff0c\u90a3\u5c31\u53ea\u8ba9\u6790\u6784\u51fd\u6570\u4e3a\u865a\u51fd\u6570\uff0c\u5373\u53ef\u4f7f Message \u53d8\u4e3a\u591a\u6001\u7c7b\u578b }; struct MoveMessage : Message { glm::vec3 velocityChange; }; struct Component { virtual void update(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) override { // \u6240\u6709\u4e0d\u540c\u7684\u6d88\u606f\u7c7b\u578b\u90fd\u4f1a\u8fdb\u5165\u6b64\u51fd\u6570 if (MoveMessage *mm = dynamic_cast(msg)) { // \u4f46\u53ea\u6709\u771f\u6b63\u7c7b\u578b\u4e3a MoveMessage \u7684\u6d88\u606f\u4f1a\u88ab\u5904\u7406 velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } } }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } void send(Message *msg) { for (auto &&c: components) { c->handleMessage(msg); } } }; \u8fd9\u5c31\u662f\u6240\u8c13\u7684\u89c2\u5bdf\u8005\u6a21\u5f0f\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u53ef\u4ee5\u6536\u5230\u6240\u6709\u6d88\u606f\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u3002 \u4f46\u8fd9\u6837\u505a\u7684\u7f3a\u70b9\u662f\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u9700\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u4e0d\u8bba\u662f\u5426\u662f\u81ea\u5df1\u9700\u8981\u7684\uff0c\u5982\u679c\u7ec4\u4ef6\u6570\u91cf\u591a\uff0c\u6d88\u606f\u7c7b\u578b\u53c8\u591a\uff0c\u5c31\u4f1a\u51fa\u73b0\u6027\u80fd\u95ee\u9898\u3002 \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f\u662f\u89c2\u5bdf\u8005\u6a21\u5f0f\u7684\u5347\u7ea7\u7248\uff0c\u7531\u4e00\u4e2a\u4e2d\u5fc3\u7684\u4e8b\u4ef6\u603b\u7ebf\u6765\u7ba1\u7406\u6d88\u606f\u7684\u5206\u53d1\u3002\u4e8b\u4ef6\u603b\u7ebf\u901a\u5e38\u4f5c\u4e3a GameObject \u7684\u6210\u5458\u51fa\u73b0\u3002 \u6bcf\u4e2a\u7ec4\u4ef6\u53ef\u4ee5\u8ba2\u9605\u81ea\u5df1\u611f\u5174\u8da3\u7684\u6d88\u606f\u7c7b\u578b\uff0c\u5f53\u4e8b\u4ef6\u603b\u7ebf\u6536\u5230\u6d88\u606f\u65f6\uff0c\u53ea\u628a\u6d88\u606f\u5206\u53d1\u7ed9\u8ba2\u9605\u8005\uff0c\u800c\u4e0d\u662f\u6240\u6709\u7ec4\u4ef6\u3002 struct GameObject { vector components; unordered_map> subscribers; // \u4e8b\u4ef6\u603b\u7ebf template void subscribe(Component *component) { subscribers[type_index(typeid(EventType))].push_back(component); } template void send(EventType *msg) { for (auto &&c: subscribers[type_index(typeid(EventType))]) { c->handleMessage(msg); } } void add(Component *component) { components.push_back(component); component->subscribeMessages(this); } void update() { for (auto &&c: components) { c->update(this); } } }; struct Component { virtual void update(GameObject *go) = 0; virtual void subscribeMessages(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void subscribeMessages(GameObject *go) { go->subscribe(this); } void handleMessage(Message *msg) override { if (MoveMessage *mm = dynamic_cast(msg)) { velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_SPACE)) { JumpMessage jm; go->send(&jm); } } }; \u8fd9\u6837\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u6309\u9700\u901a\u4fe1\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f struct Message { virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; }; struct JumpMessage { double jumpHeight; }; \u5982\u4f55\u5b9a\u4e49\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u7684\u5904\u7406\u65b9\u5f0f\uff1f struct MessageVisitor; // \u524d\u5411\u58f0\u660e struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(MoveMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct JumpMessage { double jumpHeight; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(JumpMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct MessageVisitor { virtual void visit(MoveMessage *mm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 virtual void visit(JumpMessage *jm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 }; struct Movable : MessageVisitor { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) { msg->accept(this); } void visit(MoveMessage *mm) override { velocity += mm->velocityChange; } void visit(JumpMessage *jm) override { velocity.y += sqrt(2 * 9.8 * jm->jumpHeight); } }; \u8fd9\u5c31\u662f\u8bbf\u95ee\u8005\u6a21\u5f0f\uff0c\u540c\u65f6\u7528\u5230\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u548c\u91cd\u8f7d\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u90fd\u80fd\u5b9a\u5236\u4e00\u4e2a\u5904\u7406\u65b9\u5f0f\uff0c\u800c\u4e0d\u7528\u901a\u8fc7\u4f4e\u6548\u7684 dynamic_cast \u5224\u65ad\u6d88\u606f\u7c7b\u578b\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u662f\u5426\u7b26\u5408\u5f00\u95ed\u539f\u5219\u5462\uff1f \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u6d88\u606f\u7c7b\u578b \u5728 MessageVisitor \u4e2d\u6dfb\u52a0\u4e00\u4e2a visit \u7684\u91cd\u8f7d \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u7ec4\u4ef6\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u7ec4\u4ef6\u7c7b\u578b \u8fd9\u4e09\u9879\u4fee\u6539\u90fd\u662f\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\uff0c\u5e76\u4e0d\u4f1a\u51fa\u73b0\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u7684\u60c5\u51b5\u3002 \u4f46\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\u8bbe\u8ba1\uff0c\u56e0\u6b64\u6211\u4eec\u8ba9\u6240\u6709\u7684 visit \u865a\u51fd\u6570\u6709\u4e00\u4e2a\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u4ec0\u4e48\u90fd\u4e0d\u505a\u3002\u8fd9\u6837\u5f53\u65b0\u589e\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u867d\u7136\u9700\u8981\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u91cd\u65b0\u7f16\u8bd1\u4e86\uff0c\u4f46\u662f\u7a0b\u5e8f\u5458\u65e0\u9700\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\uff0c\u6e90\u7801\u7ea7\u522b\u4e0a\uff0c\u662f\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u7684\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u901a\u5e38\u7528\u4e8e acceptor \u6570\u91cf\u6709\u9650\uff0c\u4f46 visitor \u7684\u7ec4\u4ef6\u7c7b\u578b\u5343\u53d8\u4e07\u5316\u7684\u60c5\u51b5\u3002 \u5982\u679c\u6d88\u606f\u7c7b\u578b\u6709\u9650\uff0c\u7ec4\u4ef6\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5982\u679c\u7ec4\u4ef6\u7c7b\u578b\u6709\u9650\uff0c\u6d88\u606f\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5e38\u4f5c\u4e3a acceptor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684 IR \u8282\u70b9\uff08\u4ee3\u7801\u4e2d\u95f4\u8868\u793a\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u6d88\u606f\u7c7b\u578b\u3002 \u5e38\u4f5c\u4e3a visitor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684\u4f18\u5316 pass\uff08\u4f1a\u4fee\u6539 IR \u8282\u70b9\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u63a5\u53d7\u6d88\u606f\u7ec4\u4ef6\u7c7b\u578b\u3002 \u4f46\u662f\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5b9e\u73b0 accept \u7684\u91cd\u8f7d\uff0c\u5185\u5bb9\u5b8c\u5168\u4e00\u6837\uff0c\u51fa\u73b0\u4e86\u4ee3\u7801\u91cd\u590d\u3002 Java \u7684\u6a21\u677f\u662f type-erasure \u7684\uff0c\u5bf9\u6b64\u675f\u624b\u65e0\u7b56\u3002\u800c C++ \u7684\u6a21\u677f\u662f refined-generic\uff0c\u53ef\u4ee5\u5229\u7528 CRTP \u81ea\u52a8\u5b9e\u73b0\u8fd9\u90e8\u5206\uff1a struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; template struct MessageImpl : Message { void accept(MessageVisitor *visitor) override { static_assert(std::is_base_of_v); visitor->visit(static_cast(this)); } }; struct MoveMessage : MessageImpl { glm::vec3 velocityChange; // \u81ea\u52a8\u5b9e\u73b0\u4e86 accept \u51fd\u6570 }; struct JumpMessage : MessageImpl { double jumpHeight; }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0cZFX \u7f16\u8bd1\u5668\u7684 IR \u4f18\u5316\u7cfb\u7edf\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 MVC \u6a21\u5f0f \u8bbe\u8ba1\u6a21\u5f0f\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u8bdd\u9898\uff0c\u672c\u671f\u5148\u8bb2\u5230\u8fd9\u91cc\uff0c\u4e0b\u96c6\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd UI \u5f00\u53d1\u4e2d\u5927\u540d\u9f0e\u9f0e\u7684 MVC \u6a21\u5f0f\u3002 MVC \u6a21\u5f0f\u662f\u4e00\u79cd\u67b6\u6784\u6a21\u5f0f\uff0c\u5b83\u5c06\u5e94\u7528\u7a0b\u5e8f\u5206\u4e3a\u4e09\u4e2a\u6838\u5fc3\u90e8\u5206\uff1a\u6a21\u578b\uff08Model\uff09\u3001\u89c6\u56fe\uff08View\uff09\u548c\u63a7\u5236\u5668\uff08Controller\uff09\uff0c\u901a\u8fc7\u5206\u79bb\u5e94\u7528\u7a0b\u5e8f\u7684\u8f93\u5165\u3001\u5904\u7406\u548c\u8f93\u51fa\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u6a21\u578b\uff08Model\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u6570\u636e\u548c\u4e1a\u52a1\u903b\u8f91\uff0c\u901a\u5e38\u7531\u6570\u636e\u7ed3\u6784\u548c\u6570\u636e\u5e93\u7ec4\u6210\u3002 \u89c6\u56fe\uff08View\uff09\uff1a\u8d1f\u8d23\u5c55\u793a\u6570\u636e\u548c\u7528\u6237\u754c\u9762\uff0c\u901a\u5e38\u7531 HTML\u3001CSS \u548c JavaScript \u7ec4\u6210\u3002 \u63a7\u5236\u5668\uff08Controller\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u7528\u6237\u4ea4\u4e92\u548c\u8c03\u5ea6\u6a21\u578b\u548c\u89c6\u56fe\uff0c\u901a\u5e38\u7531\u540e\u7aef\u8bed\u8a00\uff08\u5982 PHP\u3001Java \u7b49\uff09\u5b9e\u73b0\u3002 MVC \u6a21\u5f0f\u7684\u4f18\u70b9\uff1a \u4f4e\u8026\u5408\uff1a\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u804c\u8d23\u6e05\u6670\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u8fdb\u884c\u5355\u72ec\u7684\u4fee\u6539\u548c\u7ef4\u62a4\u3002 \u53ef\u6269\u5c55\u6027\uff1a\u7531\u4e8e\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u4f4e\u8026\u5408\u6027\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u6dfb\u52a0\u65b0\u7684\u529f\u80fd\u548c\u7ec4\u4ef6\u3002 \u53ef\u7ef4\u62a4\u6027\uff1a\u5206\u79bb\u4e86\u4e0d\u540c\u7684\u804c\u8d23\uff0c\u4f7f\u5f97\u4ee3\u7801\u66f4\u5bb9\u6613\u7406\u89e3\u548c\u7ef4\u62a4\u3002","title":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_gamedev/#_1","text":"\u5355\u4f8b\u6a21\u5f0f \u6a21\u677f\u6a21\u5f0f \u72b6\u6001\u6a21\u5f0f \u539f\u578b\u6a21\u5f0f CRTP \u6a21\u5f0f \u7ec4\u4ef6\u6a21\u5f0f \u89c2\u5bdf\u8005\u6a21\u5f0f \u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f \u8bbf\u95ee\u8005\u6a21\u5f0f","title":"\u6e38\u620f\u5f00\u53d1\u4e2d\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f"},{"location":"design_gamedev/#_2","text":"\u901a\u5e38\u7528\u4e8e\u6e38\u620f\u4e2d\u7684\u5168\u5c40\u7ba1\u7406\u7c7b\uff0c\u4fdd\u8bc1\u6574\u4e2a\u7a0b\u5e8f\uff08\u8fdb\u7a0b\uff09\u4e2d\u53ea\u6709\u4e00\u4e2a\u5b9e\u4f8b\u5bf9\u8c61\u5b58\u5728\u3002\u6709\u5f88\u591a\u79cd\u5e38\u89c1\u7684\u5199\u6cd5\uff1a \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 Game game; \u6548\u679c\uff1a\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u5c31\u4f1a\u521b\u5efa game \u5bf9\u8c61\uff0c\u4e4b\u540e\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 Game &getGame() { static Game game; return game; } getGame().updatePlayers(); \u6548\u679c\uff1a\u7b2c\u4e00\u6b21\u8c03\u7528 getGame() \u65f6\u4f1a\u521d\u59cb\u5316\uff0c\u4e4b\u540e\u7684\u8c03\u7528\u4f1a\u76f4\u63a5\u8fd4\u56de\u4e0a\u6b21\u521b\u5efa\u7684\u5b9e\u4f8b\u3002 \u6839\u636e\u4f60\u7684\u9700\u8981\uff0c\u5982\u679c\u4f60\u9700\u8981\u5728\u7a0b\u5e8f\u4e00\u542f\u52a8\u65f6 game \u5bf9\u8c61\u5c31\u53ef\u7528\uff0c\u5c31\u7528\u997f\u6c57\u6a21\u5f0f\u3002 \u5982\u679c game \u7684\u521d\u59cb\u5316\u9700\u8981\u67d0\u4e9b\u6761\u4ef6\uff0c\u4f8b\u5982\u521b\u5efa Game \u7c7b\u524d\u9700\u8981 OpenGL \u521d\u59cb\u5316\uff0c\u90a3\u4e48\u53ef\u7528\u61d2\u6c57\u6a21\u5f0f\uff1a int main() { glfwInit(); // \u521d\u59cb\u5316 OpenGL getGame().initialize(); // \u7b2c\u4e00\u6b21\u8c03\u7528 getGame \u4f1a\u521d\u59cb\u5316 game \u5355\u4f8b getGame().updatePlayers(); // \u4e4b\u540e\u7684\u8c03\u7528\u603b\u662f\u8fd4\u56de\u5bf9\u540c\u4e00\u4e2a game \u5355\u4f8b\u7684\u5f15\u7528 } \u63d0\u793a\uff1a\u5982\u679c\u8981\u628a\u5355\u4f8b\u5bf9\u8c61\u7684\u5b9a\u4e49\u653e\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u52a1\u5fc5\u6dfb\u52a0 inline \u4fee\u9970\u7b26\uff0c\u800c\u4e0d\u662f static\uff0c\u5426\u5219\u4f1a\u5bfc\u81f4\u591a\u4e2a cpp \u6587\u4ef6\u5404\u81ea\u6709\u4e00\u4e2a Game \u5bf9\u8c61\u3002 // Game.hpp inline Game game; inline Game &getGame() { static Game game; return game; }","title":"\u5355\u4f8b\u6a21\u5f0f"},{"location":"design_gamedev/#_3","text":"\u7531\u4e8e\u6240\u6709\u5355\u4f8b\u5168\u90e8\u66b4\u9732\u5728\u5168\u5c40\u540d\u5b57\u7a7a\u95f4\uff0c\u5bb9\u6613\u4ea7\u751f\u6df7\u4e71\u3002 \u4e00\u822c\u4f1a\u628a\u5355\u4f8b\u5bf9\u8c61\u6216\u51fd\u6570\u5c01\u88c5\u5728\u7c7b\u5185\u90e8\uff0c\u5e76\u4e14\u628a Game \u7684\u6784\u9020\u51fd\u6570\u8bbe\u4e3a private\uff0c\u907f\u514d\u7528\u6237\u4e0d\u614e\u76f4\u63a5\u521b\u5efa\u51fa\u672c\u5e94\u53ea\u6709\u5355\u4e2a\u5b9e\u4f8b\u7684 Game \u7c7b\u3002 \u4f5c\u4e3a\u5168\u5c40\u53d8\u91cf\uff08\u997f\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: // inline static Game instance; // \u867d\u7136\u5f88\u723d\uff0c\u4f46\u4e0d\u80fd\u8fd9\u6837\u5199\uff0c\u56e0\u4e3a Game \u5728\u4ed6\u7684 }; \u7ed3\u675f\u524d\u90fd\u662f\u4e0d\u5b8c\u6574\u7c7b\u578b static Game instance; // \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u5c31\u597d\u6bd4\u5168\u5c40\u53d8\u91cf\u7684 extern Game instance \u4e00\u6837\uff0c\u4e0d\u9700\u8981\u662f\u5b8c\u6574\u7c7b\u578b }; inline Game Game::instance; // \u5982\u679c\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\uff0c\u9700\u8981 inline\uff01 Game::instance.updatePlayers(); \u8b66\u544a\uff1a\u53ea\u5b9a\u4e49\u5728\u5934\u6587\u4ef6\u4e2d\u5e76\u4f7f\u7528 inline \u8fd9\u79cd\u5199\u6cd5\uff0c\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u8fd9\u4f1a\u4f7f DLL \u548c EXE \u5404\u81ea\u6301\u6709\u4e00\u4efd\u4e92\u4e0d\u5171\u901a\u7684 instance \u3002\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\u8fd9\u79cd\u997f\u6c57\u6a21\u5f0f\u5355\u4f8b\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \uff0c\u522b\u7528 inline \u4e86\u3002 \u8fd9\u662f\u56e0\u4e3a Windows \u4e2d\u7684\u6bcf\u4e2a DLL \u548c EXE \u90fd\u662f\u4e00\u5ea7\u5b64\u5c9b\uff0c\u4e92\u76f8\u4e0d\u77e5\u9053\u5bf9\u65b9\u6709\u6ca1\u6709\u8fd9\u4e2a\u7b26\u53f7\uff0c\u6240\u4ee5 inline \u7684\u6548\u679c\u4ece\u201c\u5168\u5c40\u53ea\u4fdd\u7559\u4e00\u4efd\u5b9a\u4e49\u201d\u53d8\u6210\u5728\u6bcf\u4e2a\u201c\u5b64\u5c9b\u201d\u5185\u5404\u81ea\u5728\u5185\u90e8\u53ea\u4fdd\u7559\u4e00\u4efd\uff0c\u4ece\u800c DLL \u548c EXE \u5404\u81ea\u4e00\u4efd\uff0c\u603b\u5171\u6709\u4e24\u4efd\u4e86\uff0c\u4e92\u76f8\u5185\u5bb9\u4e0d\u4e92\u901a\uff0c\u4ece\u800c\u4e0d\u662f\u5355\u4f8b\u6a21\u5f0f\u3002\u800c Linux \u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a SO \u52a8\u6001\u5e93\u662f\u8fd0\u884c\u65f6\u624d\u7531 ld-linux.so \u5b8c\u6210\u94fe\u63a5\u7684\uff0cSO \u5185\u90e8\u4ecd\u4fdd\u6709\u7f16\u8bd1\u65f6\u4ea7\u751f\u7684\u51fd\u6570\u7b26\u53f7\u4fe1\u606f\uff0c\u4e3a\u7684\u662f\u88ab\u53ef\u6267\u884c ELF \u52a0\u8f7d\u8fdb\u6765\u4ee5\u540e\uff0c ld-linux.so \u53ef\u4ee5\u81ea\u52a8\u6839\u636e\u628a\u53ef\u6267\u884c ELF \u548c SO \u5185\u90e8\u7684 call \u6307\u4ee4\u540e\u7684\u5730\u5740\u66f4\u65b0\u4e3a\u52a0\u8f7d\u540e\u7684\u7b26\u53f7\u7684\u52a8\u6001\u5730\u5740\u3002\u800c Windows \u7684 DLL \u4e2d\u6240\u6709\u7b26\u53f7\u5728\u7f16\u8bd1\u65f6\u5c31\u5df2\u7ecf\u88ab ld \u5df2\u7ecf\u710a\u6b7b\uff0c\u65e0\u6cd5\u4fee\u6539\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 Windows \u7684\u6bcf\u4e2a DLL \u90fd\u4f1a\u81ea\u52a8\u989d\u5916\u751f\u6210\u4e00\u4e2a\u540c\u540d LIB \u6587\u4ef6\uff0c\u8fd9\u4e2a LIB \u91cc\u9762\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u4e2a\u201c\u63d2\u6869\u201d\u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u5b57\u548c DLL \u4e2d\u7684\u76f8\u540c\uff0c\u4f46\u662f\u51fd\u6570\u7684\u5185\u5bb9\uff0c\u662f\u4f1a\u52a8\u6001 LoadLibrary \u52a0\u8f7d\u540c\u540d DLL\uff0c\u5e76\u901a\u8fc7 GetProcAddress \u52a8\u6001\u83b7\u53d6\u6240\u6709 dllexport \u7684\u51fd\u6570\uff0c\u800c\u94fe\u63a5\u65f6\u5019\u6307\u5b9a\u7684\u5b9e\u9645\u4e0a\u662f\u539f DLL \u5bf9\u5e94\u7684\u8fd9\u4e2a\u63d2\u6869 LIB\uff0cDLL \u672c\u8eab\u662f\u65e0\u6cd5\u88ab\u94fe\u63a5\u5668\u94fe\u63a5\u7684\u3002 \u4f5c\u4e3a\u51fd\u6570\u5185\u90e8\u7684 static \u53d8\u91cf\uff08\u61d2\u6c57\u6a21\u5f0f\uff09 struct Game { ... Game(Game &&) = delete; private: Game() { ... } public: inline static Game &instance() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9e\u73b0\u7684\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c static Game game; return game; } }; Game::instance().updatePlayers(); \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u58f0\u660e\u548c\u5b9a\u4e49 \u3002","title":"\u5c01\u88c5\u5728\u7c7b\u5185\u90e8"},{"location":"design_gamedev/#_4","text":"template inline T &singleton() { // \u8fd9\u91cc\u7684 inline \u53ef\u4ee5\u7701\u7565\uff0c\u56e0\u4e3a\u5c31\u5730\u5b9e\u73b0\u7684\u6a21\u677f\u51fd\u6570\u81ea\u5e26 inline \u6548\u679c // \u53ea\u6709\u7b2c\u4e00\u6b21\u8fdb\u5165\u65f6\u4f1a\u6784\u9020\u4e00\u904d T\uff0c\u4e4b\u540e\u4e0d\u4f1a\u518d\u6784\u9020 // \u4e0d\u540c\u7684 T \u4f1a\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684 singleton \u5b9e\u4f8b\uff0c\u5404\u81ea\u4f53\u5185\u7684 static \u53d8\u91cf\u72ec\u7acb\u8ba1\u7b97\uff0c\u4e92\u4e0d\u5e72\u6270 static T inst; return inst; } singleton().updatePlayers(); singleton().someMethod(); \u4efb\u4f55\u7c7b\u578b T\uff0c\u53ea\u8981\u4ee5 singleton() \u5f62\u5f0f\u83b7\u53d6\uff0c\u90fd\u80fd\u4fdd\u8bc1\u6bcf\u4e2a T \u90fd\u53ea\u6709\u4e00\u4efd\u5bf9\u8c61\u3002\uff08\u524d\u63d0\u662f\u4f60\u4e0d\u8981\u518d T() \u521b\u5efa\u5bf9\u8c61\uff09 \u8b66\u544a\uff1a\u8fd9\u79cd\u5199\u6cd5\u540c\u6837\u4e0d\u9002\u7528\u4e8e\u591a DLL \u7684\u60c5\u51b5\uff01\u5982\u679c\u9700\u8981\u5728\u591a DLL \u73af\u5883\u4e2d\u4f7f\u7528\uff0c\u8bf7\u4e56\u4e56 \u5206\u79bb\u6a21\u677f\u7684\u58f0\u660e\u548c\u5b9a\u4e49 \u3002","title":"\u901a\u7528\u7684\u5355\u4f8b\u6a21\u5f0f\u6a21\u677f"},{"location":"design_gamedev/#_5","text":"\u6ce8\u610f\uff1a\u6a21\u677f\u6a21\u5f0f\u548c C++ \u7684\u6a21\u677f\u5e76\u6ca1\u6709\u5fc5\u7136\u5173\u7cfb\uff01\u6a21\u677f\u6a21\u5f0f\u53ea\u662f\u4e00\u79cd\u601d\u60f3\uff0c\u53ef\u4ee5\u7528\u6a21\u677f\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u7528\u865a\u51fd\u6570\u5b9e\u73b0\uff08\u5927\u591a\u53cd\u800c\u662f\u7528\u865a\u51fd\u6570\u5b9e\u73b0\u7684\uff09 \u6a21\u677f\u6a21\u5f0f\u7528\u4e8e\u5c01\u88c5\u6e38\u620f\u4e2d\u4e00\u4e9b\u76f8\u4f3c\u7684\u5904\u7406\u903b\u8f91\uff0c\u628a\u5171\u540c\u7684\u90e8\u5206\u96c6\u4e2d\u5230\u4e00\u4e2a\u57fa\u7c7b\uff0c\u628a\u4e0d\u540c\u7684\u7ec6\u8282\u90e8\u5206\u7559\u7ed9\u5b50\u7c7b\u5b9e\u73b0\u3002 \u548c\u7b56\u7565\u6a21\u5f0f\u5f88\u50cf\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u63a5\u6536\u7b56\u7565\u7684\u76f4\u63a5\u5c31\u662f\u57fa\u7c7b\u81ea\u5df1\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u56fa\u5b9a\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21\uff0c\u7136\u540e\u7ed8\u5236 1 \u6b21\u3002\u663e\u7136\u9700\u8981\u628a\u201c\u79fb\u52a8\u201d\u548c\u201c\u7ed8\u5236\u201d\u4f5c\u4e3a\u4e24\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u6765\u5b9e\u73b0\u3002 struct Character { virtual void draw() = 0; virtual void move() = 0; }; struct Player : Character { void draw() override { drawPlayer(); } void move() override { movePlayer(); } }; struct Enemy : Character { void draw() override { drawEnemy(); } void move() override { moveEnemy(); } }; \u5982\u679c\u8ba9\u8d1f\u8d23\u8c03\u7528 Character \u7684\u4eba\u6765\u5b9e\u73b0\u6bcf\u4e00\u5e27\u9700\u8981\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u7684\u8bdd\uff0c\u5c31\u7834\u574f\u4e86\u5f00\u95ed\u539f\u5219\u3002 struct Game { vector chars; void update() { for (auto &&c: chars) { c->move(); c->move(); c->move(); c->draw(); } } } \u6539\u4e3a\u628a\u79fb\u52a8 3 \u6b21 + \u7ed8\u5236 1 \u6b21\u5c01\u88c5\u4e3a\u4e00\u4e2a Character \u7684\u666e\u901a\u51fd\u6570 update\u3002 struct Character { protected: virtual void draw() = 0; virtual void move() = 0; public: void update() { move(); move(); move(); draw(); } }; struct Game { vector chars; void update() { for (auto &&c: chars) { c->update(); } } } \u8fd9\u6837\u8c03\u7528\u8005\u5c31\u5f88\u8f7b\u677e\u4e86\uff0c\u4e0d\u5fc5\u5173\u5fc3\u5e95\u5c42\u7ec6\u8282\uff0c\u800c update \u4e5f\u53ea\u901a\u8fc7\u63a5\u53e3\u548c\u5b50\u7c7b\u901a\u4fe1\uff0c\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u548c\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\u3002","title":"\u6a21\u677f\u6a21\u5f0f"},{"location":"design_gamedev/#_6","text":"\u5f53\u4e00\u4e2a\u5bf9\u8c61\u6d89\u53ca\u5f88\u591a\u7b56\u7565\u65f6\uff0c\u7528\u7b56\u7565\u6a21\u5f0f\uff1b\u5f53\u53ea\u9700\u8981\u4e00\u4e2a\u7b56\u7565\uff0c\u4e14\u9700\u8981\u7528\u5230\u57fa\u7c7b\u7684\u6210\u5458\u65f6\uff0c\u7528\u6a21\u677f\u6a21\u5f0f\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u7684\u7b56\u7565\u6709\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\uff0c\u79fb\u52a8\u65b9\u5f0f\u6709\u201c\u8d70\u8def\u201d\u3001\u201c\u8dd1\u6b65\u201d\u4e24\u79cd\uff0c\u653b\u51fb\u7b56\u7565\u53c8\u6709\u201c\u5e73A\u201d\u3001\u201c\u66b4\u51fb\u201d\u4e24\u79cd\u3002 \u90a3\u4e48\u5c31\u7528\u7b56\u7565\u6a21\u5f0f\uff0c\u8ba9\u89d2\u8272\u5206\u522b\u6307\u5411\u79fb\u52a8\u7b56\u7565\u548c\u653b\u51fb\u7b56\u7565\u7684\u6307\u9488\u3002 struct Character { MoveStrategy *moveStrategy; AttackStrategy *attackStrategy; void update() { if (isKeyPressed(GLFW_KEY_S) { moveStrategy->move(); } else if (isKeyPressed(GLFW_KEY_W)) { moveStrategy->run(); } while (auto enemy = Game::instance().findEnemy(range)) { attackStrategy->attack(enemy); } } }; \u800c\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u7b56\u7565\uff0c\u6bd4\u5982\u6b66\u5668\u7c7b\uff0c\u53ea\u9700\u8981\u653b\u51fb\u7b56\u7565\uff0c\u5e76\u4e14\u653b\u51fb\u7b56\u7565\u9700\u8981\u77e5\u9053\u6b66\u5668\u7684\u4f24\u5bb3\u503c\u3001\u5c04\u7a0b\u3001\u9644\u9b54\u5c5e\u6027\u7b49\u4fe1\u606f\uff0c\u90a3\u5c31\u9002\u5408\u6a21\u677f\u6a21\u5f0f\u3002 struct Weapon { protected: double damage; double charge; MagicFlag magicFlags; double range; virtual void attack(Enemy *enemy); public: void update() { while (auto enemy = Game::instance().findEnemy(range)) { attack(enemy); } } };","title":"\u6a21\u677f\u6a21\u5f0f\u8fd8\u662f\u7b56\u7565\u6a21\u5f0f\uff1a\u5982\u4f55\u9009\u62e9\uff1f"},{"location":"design_gamedev/#do_xxx","text":"\u4f8b\u5982\uff0c\u4e00\u4e2a\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u63a5\u53e3\u7c7b\uff1a struct Converter { virtual void process(const char *s, size_t len) = 0; }; \u8fd9\u4e2a\u63a5\u53e3\u662f\u8003\u8651 \u5b9e\u73b0 Converter \u5b50\u7c7b\u7684\u65b9\u4fbf \uff0c\u5bf9\u4e8e \u8c03\u7528 Converter \u7684\u7528\u6237 \u4f7f\u7528\u8d77\u6765\u53ef\u80fd\u5e76\u4e0d\u65b9\u4fbf\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u8fd0\u7528\u6a21\u677f\u6a21\u5f0f\uff0c\u628a\u539f\u6765\u7684\u865a\u51fd\u6570\u63a5\u53e3\u6539\u4e3a protected \u7684\u51fd\u6570\uff0c\u4e14\u540d\u5b57\u6539\u4e3a do_process\u3002 struct Converter { protected: virtual void do_process(const char *s, size_t len) = 0; public: void process(string_view str) { return do_process(str.data(), str.size()); } void process(string str) { return do_process(str.data(), str.size()); } void process(const char *cstr) { return do_process(cstr, strlen(cstr)); } }; \u5b9e\u73b0 Converter \u7684\u5b50\u7c7b\u65f6\uff0c\u91cd\u5199\u4ed6\u7684 do_process \u51fd\u6570\uff0c\u8fd9\u4e9b\u51fd\u6570\u662f protected \u7684\uff0c\u53ea\u80fd\u88ab\u7ee7\u627f\u4e86 Converter \u7684\u5b50\u7c7b\u8bbf\u95ee\u548c\u91cd\u5199\u3002 \u5916\u5c42\u7528\u6237\u53ea\u80fd\u901a\u8fc7 Converter \u57fa\u7c7b\u5c01\u88c5\u597d\u7684 process \u51fd\u6570\uff0c\u907f\u514d\u5916\u5c42\u7528\u6237\u76f4\u63a5\u5e72\u6d89\u5e95\u5c42\u7ec6\u8282\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 std::pmr::memory_resource \u3001 std::codecvt \u7b49\u90fd\u8fd0\u7528\u4e86 do_xxx \u5f0f\u7684\u6a21\u677f\u6a21\u5f0f\u5c01\u88c5\u3002","title":"\u6700\u5e38\u89c1\u7684\u662f do_xxx \u5c01\u88c5"},{"location":"design_gamedev/#_7","text":"\u6e38\u620f\u4e2d\u7684\u89d2\u8272\u901a\u5e38\u6709\u591a\u79cd\u72b6\u6001\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u602a\u7269\u53ef\u80fd\u6709\u201c\u5f85\u673a\u201d\u3001\u201c\u5de1\u903b\u201d\u3001\u201c\u8ffd\u51fb\u201d\u3001\u201c\u653b\u51fb\u201d\u7b49\u591a\u79cd\u72b6\u6001\uff0c\u800c\u6bcf\u79cd\u72b6\u6001\u4e0b\u7684\u884c\u4e3a\u90fd\u4e0d\u4e00\u6837\u3002 \u5982\u679c\u7528\u4e00\u4e2a\u679a\u4e3e\u53d8\u91cf\u6765\u8868\u793a\u5f53\u524d\u72b6\u6001\uff0c\u90a3\u6bcf\u6b21\u5c31\u90fd\u9700\u8981\u7528 switch \u6765\u5904\u7406\u4e0d\u540c\u7684\u72b6\u6001\u3002 enum MonsterState { Idle, Chase, Attack, }; struct Monster { MonsterState state = Idle; void update() { switch (state) { case Idle: if (seesPlayer()) state = Chase; break; case Chase: if (canAttack()) state = Attack; else if (!seesPlayer()) state = Idle; break; case Attack: if (!seesPlayer()) state = Idle; break; } } }; \u8fd9\u6216\u8bb8\u6027\u80fd\u4e0a\u6709\u4e00\u5b9a\u4f18\u52bf\uff0c\u7f3a\u70b9\u662f\uff0c\u6240\u6709\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5806\u79ef\u5728\u540c\u4e00\u4e2a\u51fd\u6570\u4e2d\uff0c\u5982\u679c\u6709\u591a\u4e2a\u51fd\u6570\uff08\u4e0d\u53ea\u662f update\uff09\uff0c\u90a3\u4e48\u6bcf\u6dfb\u52a0\u4e00\u4e2a\u65b0\u72b6\u6001\u5c31\u9700\u8981\u4fee\u6539\u6240\u6709\u51fd\u6570\uff0c\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u800c\u4e14\u5982\u679c\u4e0d\u540c\u7684\u72b6\u6001\u542b\u6709\u4e0d\u540c\u7684\u989d\u5916\u6570\u503c\u9700\u8981\u5b58\u50a8\uff0c\u6bd4\u5982 Chase \u72b6\u6001\u9700\u8981\u5b58\u50a8\u5f53\u524d\u901f\u5ea6\uff0c\u90a3\u5c31\u9700\u8981\u5728 Monster \u7c7b\u4e2d\u6dfb\u52a0 speed \u6210\u5458\uff0c\u800c state \u4e0d\u4e3a Chase \u65f6\u53c8\u7528\u4e0d\u5230\u8fd9\u4e2a\u6210\u5458\uff0c\u975e\u5e38\u5bb9\u6613\u6270\u4e71\u601d\u7ef4\u3002","title":"\u72b6\u6001\u6a21\u5f0f"},{"location":"design_gamedev/#_8","text":"\u4e3a\u6b64\uff0c\u63d0\u51fa\u4e86\u72b6\u6001\u6a21\u5f0f\uff0c\u5c06\u4e0d\u540c\u72b6\u6001\u7684\u5904\u7406\u903b\u8f91\u5206\u79bb\u5230\u4e0d\u540c\u7684\u7c7b\u4e2d\u3002\u4ed6\u628a\u6bcf\u79cd\u72b6\u6001\u62bd\u8c61\u4e3a\u4e00\u4e2a\u7c7b\uff0c\u72b6\u6001\u662f\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u89d2\u8272\u6301\u6709\u8868\u793a\u5f53\u524d\u72b6\u6001\u7684\u5bf9\u8c61\uff0c\u7528\u72b6\u6001\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u6765\u8868\u793a\u5904\u7406\u903b\u8f91\uff0c\u800c\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u901a\u8fc7 if \u5224\u65ad\u6765\u6267\u884c\u4e0d\u540c\u7684\u884c\u4e3a\u3002 struct Monster; struct State { virtual void update(Monster *monster) = 0; }; struct Idle : State { void update(Monster *monster) override { if (monster->seesPlayer()) { monster->setState(new Chase()); } } }; struct Chase : State { void update(Monster *monster) override { if (monster->canAttack()) { monster->setState(new Attack()); } else if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Attack : State { void update(Monster *monster) override { if (!monster->seesPlayer()) { monster->setState(new Idle()); } } }; struct Monster { State *state = new Idle(); void update() { state->update(this); } void setState(State *newState) { delete state; state = newState; } };","title":"\u72b6\u6001\u4e0d\u662f\u679a\u4e3e\uff0c\u800c\u662f\u7c7b"},{"location":"design_gamedev/#_9","text":"\u539f\u578b\u6a21\u5f0f\u7528\u4e8e\u590d\u5236\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u4e14\u65b0\u5bf9\u8c61\u7684 \u5c5e\u6027 \u548c \u7c7b\u578b \u4e0e\u539f\u6765\u76f8\u540c\u3002\u5982\u4f55\u5b9e\u73b0\uff1f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u4e0d\u884c\uff1f \u62f7\u8d1d\u6784\u9020\u51fd\u6570\u53ea\u80fd\u7528\u4e8e\u7c7b\u578b\u786e\u5b9a\u7684\u60c5\u51b5\uff0c\u5bf9\u4e8e\u5177\u6709\u865a\u51fd\u6570\uff0c\u53ef\u80fd\u5177\u6709\u989d\u5916\u6210\u5458\u7684\u591a\u6001\u7c7b\u578b\uff0c\u4f1a\u53d1\u751f object-slicing\uff0c\u5bfc\u81f4\u62f7\u8d1d\u51fa\u6765\u7684\u7c7b\u578b\u53ea\u662f\u57fa\u7c7b\u7684\u90e8\u5206\uff0c\u800c\u4e0d\u662f\u5b8c\u6574\u7684\u5b50\u7c7b\u5bf9\u8c61\u3002 RedBall ball; Ball newball = ball; // \u9519\u8bef\uff1a\u53d1\u751f\u4e86 object-slicing\uff01\u73b0\u5728 newball \u7684\u7c7b\u578b\u53ea\u662f Ball \u4e86\uff0c\u4e22\u5931\u4e86 RedBall \u7684\u4fe1\u606f \u4e3a\u4ec0\u4e48\u62f7\u8d1d\u6307\u9488\u4e0d\u884c\uff1f \u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff0c\u800c\u6211\u4eec\u9700\u8981\u7684\u662f\u6df1\u62f7\u8d1d\u3002 Ball *ball = new RedBall(); Ball *newball = ball; // \u9519\u8bef\uff1a\u6307\u9488\u7684\u62f7\u8d1d\u662f\u6d45\u62f7\u8d1d\uff01newball \u548c ball \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u5bf9\u8c61 \u9700\u8981\u8c03\u7528\u5230\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u540c\u65f6\u53c8\u57fa\u4e8e\u6307\u9488 Ball *ball = new RedBall(); Ball *newball = new RedBall(*dynamic_cast(ball)); // \u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u91cc\u663e\u5f0f\u5199\u51fa\u4e86 ball \u5185\u90e8\u7684\u771f\u6b63\u7c7b\u578b\uff0c\u8fdd\u80cc\u4e86\u5f00\u95ed\u539f\u5219 \u5c06\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u5c01\u88c5\u4e3a\u865a\u51fd\u6570 \u539f\u578b\u6a21\u5f0f\u5c06\u5bf9\u8c61\u7684\u62f7\u8d1d\u65b9\u6cd5\u4f5c\u4e3a\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u4e00\u4e2a\u865a\u63a5\u53e3\u7684\u6307\u9488\uff0c\u907f\u514d\u4e86\u76f4\u63a5\u62f7\u8d1d\u7c7b\u578b\u3002\u4f46\u865a\u51fd\u6570\u5185\u90e8\u4f1a\u8c03\u7528\u5b50\u7c7b\u771f\u6b63\u7684\u6784\u9020\u51fd\u6570\uff0c\u5b9e\u73b0\u6df1\u62f7\u8d1d\u3002 \u5bf9\u4e8e\u719f\u6089\u5de5\u5382\u6a21\u5f0f\u7684\u540c\u5b66\uff1a\u539f\u578b\u6a21\u5f0f\u76f8\u5f53\u4e8e\u628a\u6bcf\u4e2a\u5bf9\u8c61\u53d8\u6210\u4e86\u81ea\u5df1\u7684\u5de5\u5382\uff0c\u53ea\u9700\u8981\u6709\u4e00\u4e2a\u73b0\u6709\u7684\u5bf9\u8c61\uff0c\u5c31\u80fd\u4e0d\u65ad\u590d\u5236\u51fa\u548c\u4ed6\u76f8\u540c\u7c7b\u578b\u7684\u5bf9\u8c61\u6765\u3002 struct Ball { virtual Ball *clone() = 0; }; struct RedBall : Ball { Ball *clone() override { return new RedBall(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { Ball *clone() override { return new BlueBall(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230 }; \u597d\u5904\u662f\uff0c\u8c03\u7528\u8005\u65e0\u9700\u77e5\u9053\u5177\u4f53\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u4ed6\u662f Ball \u7684\u5b50\u7c7b\uff0c\u5c31\u53ef\u4ee5\u514b\u9686\u51fa\u4e00\u4efd\u5b8c\u5168\u4e00\u6837\u7684\u5b50\u7c7b\u5bf9\u8c61\u6765\uff0c\u4e14\u8fd4\u56de\u7684\u4e5f\u662f\u6307\u9488\uff0c\u4e0d\u4f1a\u53d1\u751f object-slicing\u3002 Ball *ball = new RedBall(); ... Ball *newball = ball->clone(); // newball \u7684\u7c7b\u578b\u4ecd\u7136\u662f RedBall","title":"\u539f\u578b\u6a21\u5f0f"},{"location":"design_gamedev/#clone","text":"struct Ball { virtual unique_ptr clone() = 0; }; struct RedBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } }; struct BlueBall : Ball { unique_ptr clone() override { return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 } int someData; // \u5982\u679c\u6709\u6210\u5458\u53d8\u91cf\uff0c\u4e5f\u4f1a\u4e00\u5e76\u88ab\u62f7\u8d1d\u5230\u65b0\u5bf9\u8c61\u4e2d }; \u8fd9\u6837\u5c31\u4fdd\u8bc1\u4e86\u5185\u5b58\u4e0d\u4f1a\u6cc4\u6f0f\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f shared_ptr\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a shared_ptr\u3002 \u5982\u679c\u8c03\u7528\u8005\u9700\u8981\u7684\u662f\u624b\u52a8 delete \u7684\u539f\u59cb\u6307\u9488\uff0c\u600e\u4e48\u529e\uff1f \u7b54\uff1aunique_ptr \u53ef\u4ee5\u901a\u8fc7 release\uff0c\u6545\u610f\u9020\u6210\u4e00\u6b21\u5185\u5b58\u6cc4\u6f0f\uff0c\u6210\u4e3a\u9700\u8981\u624b\u52a8\u7ba1\u7406\u7684\u539f\u59cb\u6307\u9488\u3002","title":"clone \u8fd4\u56de\u4e3a\u667a\u80fd\u6307\u9488"},{"location":"design_gamedev/#crtp-clone","text":"CRTP\uff08Curiously Recurring Template Pattern\uff09\u662f\u4e00\u79cd\u6a21\u677f\u5143\u7f16\u7a0b\u6280\u672f\uff0c\u5b83\u53ef\u4ee5\u5728\u7f16\u8bd1\u671f\u95f4\u628a\u6d3e\u751f\u7c7b\u7684\u7c7b\u578b\u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u4f20\u9012\u7ed9\u57fa\u7c7b\uff0c\u4ece\u800c\u5b9e\u73b0\u4e00\u4e9b\u81ea\u52a8\u5316\u7684\u529f\u80fd\u3002 \u7279\u70b9\u662f\uff0c\u7ee7\u627f\u4e00\u4e2a CRTP \u7c7b\u65f6\uff0c\u9700\u8981\u628a\u5b50\u7c7b\u672c\u8eab\u4f5c\u4e3a\u57fa\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u3002 \u5e76\u4e0d\u4f1a\u51fa\u73b0\u5faa\u73af\u5f15\u7528\u662f\u56e0\u4e3a\uff0c\u7528\u5230\u5b50\u7c7b\u7684\u5177\u4f53\u7c7b\u578b\u662f\u5728\u57fa\u7c7b\u7684\u6210\u5458\u51fd\u6570\u5185\u90e8\uff0c\u800c\u4e0d\u662f\u76f4\u63a5\u5728\u57fa\u7c7b\u5185\u90e8\uff0c\u800c\u6a21\u677f\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\u7684\u5b9e\u4f8b\u5316\u662f\u60f0\u6027\u7684\uff0c\u7528\u5230\u4e86\u624d\u4f1a\u5b9e\u4f8b\u5316\u3002 template struct Pet { void feed() { Derived *that = static_cast(this); that->speak(); that->speak(); } }; struct CatPet : Pet { void speak() { puts(\"Meow!\"); } }; struct DogPet : Pet { void speak() { puts(\"Bark!\"); } }; \u4e00\u822c\u7684\u8c61\u7259\u5854\u7406\u8bba\u5bb6\u6559\u6750\u4e2d\u90fd\u4f1a\u544a\u8bc9\u4f60\uff0cCRTP \u662f\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u66f4\u9ad8\u6548\u5730\u5b9e\u73b0\u6a21\u677f\u6a21\u5f0f\uff0c\u597d\u50cf CRTP \u5c31\u548c\u865a\u51fd\u6570\u52bf\u4e0d\u4e24\u7acb\u3002 \u4f46\u5c0f\u5f6d\u8001\u5e08\u7684\u7f16\u7a0b\u5b9e\u8df5\u4e2d\uff0cCRTP \u5e38\u5e38\u662f\u548c\u865a\u51fd\u6570\u4e00\u8d77\u51fa\u73b0\u7684\u597d\u642d\u6863\u3002 \u4f8b\u5982 CRTP \u53ef\u4ee5\u5e2e\u52a9\u539f\u578b\u6a21\u5f0f\u5b9e\u73b0\u81ea\u52a8\u5316\u5b9a\u4e49 clone \u865a\u51fd\u6570\uff0c\u7a0d\u540e\u4ecb\u7ecd\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u4e2d\u4e5f\u4f1a\u7528\u5230 CRTP\u3002 struct Ball { virtual unique_ptr clone() = 0; }; template struct BallImpl : Ball { // \u81ea\u52a8\u5b9e\u73b0 clone \u7684\u8f85\u52a9\u5de5\u5177\u7c7b unique_ptr clone() override { Derived *that = static_cast(this); return make_unique(*that); } }; struct RedBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 RedBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; struct BlueBall : BallImpl { // unique_ptr clone() override { // BallImpl \u81ea\u52a8\u5b9e\u73b0\u7684 clone \u7b49\u4ef7\u4e8e // return make_unique(*this); // \u8c03\u7528 BlueBall \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570 // } }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0c\u5bf9\u8c61\u7c7b\u578b zeno::IObject \u7684\u6df1\u62f7\u8d1d\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u539f\u578b\u6a21\u5f0f\u3002","title":"CRTP \u6a21\u5f0f\u81ea\u52a8\u5b9e\u73b0 clone"},{"location":"design_gamedev/#_10","text":"\u6e38\u620f\u4e2d\u7684\u7269\u4f53\uff08\u6e38\u620f\u5bf9\u8c61\uff09\u901a\u5e38\u7531\u591a\u4e2a\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4f8b\u5982\uff0c\u4e00\u4e2a\u89d2\u8272\u53ef\u80fd\u7531\u201c\u89d2\u8272\u63a7\u5236\u5668\u201d\u3001\u201c\u89d2\u8272\u5916\u89c2\u201d\u3001\u201c\u89d2\u8272\u52a8\u753b\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\uff0c\u4e00\u4e2a\u5b50\u5f39\u53ef\u80fd\u7531\u201c\u5b50\u5f39\u7269\u7406\u201d\u3001\u201c\u5b50\u5f39\u5916\u89c2\u201d\u7b49\u7ec4\u4ef6\u7ec4\u6210\u3002 \u7ec4\u4ef6\u6a21\u5f0f\u662f \u6e38\u620f\u5f00\u53d1\u9886\u57df\u6700\u91cd\u8981\u7684\u8bbe\u8ba1\u6a21\u5f0f \uff0c\u5b83\u5c06\u6e38\u620f\u5bf9\u8c61\u5206\u4e3a\u591a\u4e2a\u7ec4\u4ef6\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u53ea\u5173\u5fc3\u81ea\u5df1\u7684\u903b\u8f91\uff0c\u800c\u4e0d\u5173\u5fc3\u5176\u4ed6\u7ec4\u4ef6\u7684\u903b\u8f91\u3002 \u8e69\u811a\u7684\u6e38\u620f\u5f00\u53d1\u8005\uff08\u901a\u5e38\u662f 985 \u91cf\u4ea7\u51fa\u6765\u7684\u8c61\u7259\u5854\u5de8\u5a74\uff09\u4f1a\u628a\u6bcf\u4e2a\u7ec4\u4ef6\u5199\u6210\u4e00\u4e2a\u7c7b\uff0c\u7136\u540e\u4f7f\u7528\u201c\u591a\u91cd\u7ee7\u627f\u201d\u7ee7\u627f\u51fa\u4e00\u4e2a\u73a9\u5bb6\u7c7b\u6765\uff0c\u5e76\u606c\u4e0d\u77e5\u803b\u5730\u58f0\u79f0\u201c\u6211\u4e5f\u4f1a\u7ec4\u4ef6\u6a21\u5f0f\u4e86\u201d\u3002 \u7136\u800c\uff0c\u8fd9\u6837\u7684\u7f3a\u70b9\u6709\uff1a \u6e38\u620f\u5f00\u53d1\u4e2d\u666e\u904d\u6d89\u53ca\u5230 update \u51fd\u6570\uff0c\u800c\u73a9\u5bb6\u7c7b\u7684 update \u9700\u8981\u8f6e\u6d41\u8c03\u7528\u6bcf\u4e2a\u7ec4\u4ef6\u7684 update \u51fd\u6570\u3002 \u800c\u591a\u91cd\u7ee7\u627f\u4e00\u65e6\u9047\u5230\u91cd\u540d\u7684 update \u51fd\u6570\uff0c\u4f1a\u76f4\u63a5\u62a5\u9519 \u201c\u6709\u6b67\u4e49\u7684\u51fd\u6570\u540d\u201d \u6446\u70c2\u4e0d\u5e72\u4e86\uff0c\u9700\u8981\u4f60\u624b\u5199\u65b0\u7684 update \u51fd\u6570\u3002 struct Player : PlayerController, PlayerAppearance, PlayerAnimation { void update() { PlayerController::update(); PlayerAppearance::update(); PlayerAnimation::update(); } }; C++\uff08\u548c\u5927\u591a\u6570\u975e\u811a\u672c\u8bed\u8a00\u90fd\uff09\u4e0d\u652f\u6301\u8fd0\u884c\u65f6\u6dfb\u52a0\u6216\u5220\u9664\u57fa\u7c7b\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u8981\u6dfb\u52a0\u4e00\u4e2a\u65b0\u89d2\u8272\uff0c\u6216\u662f\u4fee\u6539\u73b0\u6709\u89d2\u8272\u7684\u903b\u8f91\uff0c\u5c31\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u4e00\u904d\u6574\u4e2a\u6e38\u620f\u7684\u6e90\u7801\u3002 \u5728\u7f51\u7edc\u6e38\u620f\u4e2d\uff0c\u66f4\u65b0 DLL \u548c\u66f4\u65b0\u8d44\u4ea7\uff08\u56fe\u7247\u3001\u97f3\u9891\u3001\u6a21\u578b\u7b49\uff09\u662f\u5b8c\u5168\u4e0d\u540c\u7684\u3002 \u5bf9\u4e8e\u670d\u52a1\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u505c\u673a\u66f4\u65b0\uff0c\u66f4\u65b0\u8d44\u4ea7\u4e0d\u9700\u8981\uff0cDLL \u53ef\u4ee5\u88ab\u7f16\u7a0b\u5141\u8bb8\u52a8\u6001\u52a0\u8f7d\u65b0\u7684\u8d34\u56fe\u3002 \u5bf9\u4e8e\u5ba2\u6237\u7aef\u800c\u8a00\uff0c\u66f4\u65b0 DLL \u9700\u8981\u91cd\u65b0\u8d70\u4e00\u904d\u5f88\u957f\u7684 App \u5ba1\u6838\u6d41\u7a0b\uff08\u56e0\u4e3a\u76f4\u63a5\u8fd0\u884c\u4e8e\u624b\u673a\u4e0a\u7684 C++ \u53ef\u4ee5\u8f7b\u677e\u690d\u5165\u75c5\u6bd2\uff09\uff0c\u800c\u66f4\u65b0\u8d44\u4ea7\u7684\u5ba1\u6838\u6d41\u7a0b\u77ed\u5f97\u591a\uff0c\u751a\u81f3\u5e72\u8106\u65e0\u9700\u5ba1\u6838\u3002 \u56e0\u6b64\uff0c\u6e38\u620f\u5f00\u53d1\u8005\u5f88\u5c11\u4f1a\u628a\u6e38\u620f\u903b\u8f91\u76f4\u63a5\u5199\u6b7b\u5728 C++ \u4e2d\uff0c\u8fd9\u4f1a\u8ba9\u66f4\u65b0\u6e38\u620f\u903b\u8f91\uff08\u4f8b\u5982\u4fee\u590d BUG\uff09\u9700\u8981\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6bcf\u6b21\u505c\u673a\u66f4\u65b0\u90fd\u4f1a\u7ed9\u73a9\u5bb6\u53d1 200 \u5408\u6210\u7389\uff09 \u4f60\u7ecf\u5e38\u770b\u5230\u6e38\u620f\u9886\u57df\u7684 \u201cC++ \u5f00\u53d1\u5c97\u201d \u5b9e\u9645\u4e0a\u662f \u201c\u89e3\u91ca\u5668\u5f00\u53d1\u201d\u3002 \u6e38\u620f\u5f00\u53d1\u8005\u4f1a\u628a\u7ecf\u5e38\u9700\u8981\u7ef4\u62a4\u548c\u66f4\u65b0\u7684\u6e38\u620f\u903b\u8f91\u5199\u5728\u5982 Lua\u3001Python \u7b49\u811a\u672c\u8bed\u8a00\u4e2d\uff0c\u7136\u540e\u5728 C++ \u4e2d\u96c6\u6210\u4e00\u4e2a Lua\u3001Python \u89e3\u91ca\u5668\uff0c\u6839\u636e\u89e3\u91ca\u5668\u7684\u8c03\u7528\u7ed3\u679c\uff0c\u52a8\u6001\u521b\u5efa\u51fa C++ \u5bf9\u8c61\uff0c\u7136\u540e\u628a\u8fd9\u4e9b C++ \u5bf9\u8c61\u5f53\u4f5c\u7ec4\u4ef6\u6dfb\u52a0\u5230\u6e38\u620f\u5bf9\u8c61\u4e0a\u3002 \u5f53\u51fa\u73b0 BUG \u65f6\uff0c\u53ea\u9700\u8981\u4fee\u6539\u8fd9\u4e9b\u811a\u672c\u8bed\u8a00\u7684\u4ee3\u7801\uff0c\u7136\u540e\u4ee5\u201c\u8d44\u4ea7\u201d\u7684\u5f62\u5f0f\uff0c\u5feb\u901f\u8d70\u4e00\u904d\u5ba1\u6838\u6d41\u7a0b\uff0c\u5c31\u53ef\u4ee5\u4fee\u590d BUG\uff0c\u65e0\u9700\u505c\u673a\u66f4\u65b0\u3002\uff08\u4f8b\u5982\u660e\u65e5\u65b9\u821f\u6709\u65f6\u5019\u4f1a\u201c\u8d44\u6e90\u5df2\u8fc7\u671f\u201d\u201c\u6b63\u5728\u4e0b\u8f7d\u8d44\u6e90\u201d\uff0c\u6709\u65f6\u662f\u66f4\u65b0\u4e86\u56fe\u7247\u8d44\u6e90\uff0c\u4e5f\u53ef\u80fd\u662f\u5728\u811a\u672c\u8bed\u8a00\u91cc\u52a8\u6001\u4fee\u590d\u4e86 BUG\uff09 Java \u548c C# \u90fd\u6ca1\u6709\u591a\u91cd\u7ee7\u627f\u3002\u4f60\u8ba9\u4eba\u5bb6\u57fa\u4e8e C# \u7684 Unity \u600e\u4e48\u6d3b\uff1f \u56e0\u6b64\uff0c\u771f\u6b63\u7684\u7ec4\u4ef6\u6a21\u5f0f\u90fd\u4f1a\u5141\u8bb8\u52a8\u6001\u63d2\u5165\u7ec4\u4ef6\uff0c\u800c\u4e0d\u662f\u7f16\u8bd1\u671f\u5199\u6b7b\u3002\u9664\u975e\u4f60\u662f\u67d0\u4e9b\u8c61\u7259\u5854\u7684\u4e00\u6b21\u6027\u6c99\u96d5\u5927\u4f5c\u4e1a\u3002 \u6e38\u620f\u5bf9\u8c61\u7ec4\u4ef6\u5316\u540e\uff0c\u53ef\u4ee5\u7075\u6d3b\u5730\u7ec4\u5408\u51fa\u4e0d\u540c\u7684\u6e38\u620f\u5bf9\u8c61\uff0c\u800c\u4e0d\u5fc5\u4e3a\u6bcf\u4e00\u79cd\u7ec4\u5408\u90fd\u5199\u4e00\u4e2a\u7c7b\u3002 struct Component { virtual void update(GameObject *go) = 0; virtual ~Component() = default; // \u6ce8\u610f\uff01 }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } }; \u6ce8\u610f\uff1aComponent \u7684\u6790\u6784\u51fd\u6570\u5fc5\u987b\u4e3a\u865a\u51fd\u6570\u3002\u5426\u5219\uff0c\u5f53 Component \u88ab delete \u65f6\uff0c\u53ea\u4f1a\u8c03\u7528\u5230 Component \u8fd9\u4e2a\u57fa\u7c7b\u7684\u6790\u6784\u51fd\u6570\uff0c\u800c\u4e0d\u4f1a\u8c03\u7528\u5230\u5b50\u7c7b\u7684\u6790\u6784\u51fd\u6570\u3002 \u5426\u5219\uff0c\u5982\u679c\u4f60\u7684\u5b50\u7c7b\u6709 string\u3001vector \u8fd9\u79cd\u6301\u6709\u5185\u5b58\u8d44\u6e90\u7684\u5bb9\u5668\u7c7b\uff0c\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f\uff0c\u5bfc\u81f4\u6e38\u620f\u8fd0\u884c\u8d8a\u4e45\u5185\u5b58\u5360\u7528\u8d8a\u5927\u3002 \u795e\u5947\u7684\u662f\uff0c\u5982\u679c\u4f60\u7684 Component \u5168\u90e8\u90fd\u662f\u7528 make_shared \u521b\u5efa\u7684\uff0c\u90a3\u5c31\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\u4e86\uff0c\u8fd9\u5f97\u76ca\u4e8e shared_ptr \u4f1a\u5bf9 deleter \u505a\u7c7b\u578b\u64e6\u9664\u3002 make_unique \u548c new \u521b\u5efa\u7684\u5c31\u4f1a\u6cc4\u6f0f\uff0c\u56e0\u4e3a\u4ed6\u4eec delete \u65f6\u662f\u4ee5\u57fa\u7c7b\u6307\u9488\u53bb delete \u7684\uff0c\u800c shared_ptr \u4f1a\u5728\u6784\u9020\u65f6\u5c31\u8bb0\u4f4f\u5b50\u7c7b\u7684 deleter\u3002 \u6240\u6709\u7ec4\u4ef6\uff0c\u90fd\u652f\u6301 update\uff08\u6bcf\u5e27\u66f4\u65b0\uff09\u64cd\u4f5c\uff1a struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void update(GameObject *go) override { position += velocity * dt; } }; struct LivingBeing : Component { int ageLeft; void update(GameObject *go) override { if (ageLeft < 0) go->kill(); else ageLeft -= 1; } };","title":"\u7ec4\u4ef6\u6a21\u5f0f"},{"location":"design_gamedev/#_11","text":"\u7ec4\u4ef6\u6709\u4e24\u79cd\u521b\u5efa\u65b9\u5f0f\uff1a \u7ec4\u4ef6\u4f5c\u4e3a\u4e00\u4e2a\u666e\u901a\u5bf9\u8c61\uff0c\u7531 GameObject \u7684\u6784\u9020\u51fd\u6570\u521b\u5efa\u3002 struct Player : GameObject { Movable *movable; LivingBeing *livingBeing; PlayerController *playerController; PlayerAppearance *playerAppearance; Player() { movable = new Movable(); livingBeing = new LivingBeing(42); playerController = new PlayerController(); playerAppearance = new PlayerAppearance(); add(movable); add(livingBeing); add(playerController); add(playerAppearance); } }; \u4e0d\u518d\u9700\u8981\u5b9a\u4e49 Player \u7c7b\u53ca\u5176\u6784\u9020\u51fd\u6570\u4e86\uff0c\u53ea\u9700\u4e00\u4e2a\u666e\u901a\u51fd\u6570\u521b\u5efa\u5177\u6709 Player \u6240\u9700\u6240\u6709\u7ec4\u4ef6\u7684 GameObject \u5bf9\u8c61\u5373\u53ef\u3002 GameObject *makePlayer() { GameObject *go = new GameObject(); go->add(new Movable()); go->add(new LivingBeing(42)); go->add(new PlayerController()); go->add(new PlayerAppearance()); return go; } \u6b63\u7ecf\u6e38\u620f\u5f15\u64ce\u90fd\u91c7\u7528\u540e\u8005\uff0c\u4e0d\u7528\u6dfb\u52a0 C++ \u6e90\u7801\uff0c\u53ea\u662f\u4ece xml \u7b49\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u6bcf\u4e2a\u7c7b\u6240\u4f9d\u8d56\u7684\u7ec4\u4ef6\uff0c\u5c31\u80fd\u521b\u5efa\u65b0\u7684\u73a9\u5bb6\u7c7b\uff0c\u65b9\u4fbf\u52a8\u6001\u66f4\u65b0\u6e38\u620f\u903b\u8f91\u800c\u65e0\u9700\u91cd\u65b0\u53d1\u5e03 dll\u3002","title":"\u7ec4\u4ef6\u7684\u521b\u5efa"},{"location":"design_gamedev/#_12","text":"\u7f3a\u70b9\u662f\uff0c\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u9700\u8981\u901a\u8fc7 GameObject \u6765\u5b9e\u73b0\uff0c\u800c GameObject \u5e76\u4e0d\u77e5\u9053\u5b83\u7684\u7ec4\u4ef6\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u5c31\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95ee\u7ec4\u4ef6\u7684\u6210\u5458\u3002 \u4f8b\u5982\uff0cPlayerController \u7ec4\u4ef6\u60f3\u8981\u6539\u53d8 Movable \u7ec4\u4ef6\u7684 velocity\uff0c\u5c31\u65e0\u6cd5\u76f4\u63a5\u6539\u3002 struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { go->velocity.y += 1; // \u9519\u8bef\uff01velocity \u662f Movable \u7ec4\u4ef6\u7684\u6210\u5458\uff0c\u800c\u4e0d\u662f GameObject \u91cc\u76f4\u63a5\u6709\u7684 } if (isKeyPressed(GLFW_KEY_S)) { go->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { go->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { go->velocity.x += 1; } } }; \u5982\u4f55\u89e3\u51b3\u7ec4\u4ef6\u4e4b\u95f4\u901a\u4fe1\u96be\u7684\u95ee\u9898\uff1f \u628a\u5e38\u7528\u7684\u5b57\u6bb5\uff0c\u4f8b\u5982 position \u548c velocity \u76f4\u63a5\u653e\u5728 GameObject \u91cc\uff0c\u4f9b\u6240\u6709\u7ec4\u4ef6\u76f4\u63a5\u8bbf\u95ee\u3002 struct GameObject { glm::vec3 position; glm::vec3 velocity; ... }; \u5141\u8bb8\u7528\u6237\u6839\u636e\u5176\u4ed6\u7ec4\u4ef6\u7684\u7c7b\u578b\uff0c\u76f4\u63a5\u83b7\u53d6\u51fa\u5176\u4ed6\u7ec4\u4ef6\u7684\u6307\u9488\uff0c\u5373\u53ef\u8bbf\u95ee\u5176\u6210\u5458\u3002 struct PlayerController : Component { void update(GameObject *go) override { Movable *movable = go->getComponent(); if (!movable) { throw runtime_error(\"\u8fd9\u4e2a\u5bf9\u8c61\u4f3c\u4e4e\u4e0d\u652f\u6301\u79fb\u52a8\"); } if (isKeyPressed(GLFW_KEY_W)) { movable->velocity.y += 1; } if (isKeyPressed(GLFW_KEY_S)) { movable->velocity.y -= 1; } if (isKeyPressed(GLFW_KEY_A)) { movable->velocity.x -= 1; } if (isKeyPressed(GLFW_KEY_D)) { movable->velocity.x += 1; } } }; \u7136\u800c\uff0cgetComponent \u5982\u4f55\u5b9e\u73b0\uff1f struct GameObject { template T *getComponent() { for (auto &&c: components) { if (T *t = dynamic_cast(c)) { return t; } } return nullptr; } }; \u7528\u5230\u4e86 dynamic_cast \uff0c\u8fd9\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\u4e00\u79cd\u5b9e\u73b0\u65b9\u5f0f\uff0c\u800c\u4e14\u4e5f\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 \u66f4\u597d\u7684\u5b9e\u73b0\u65b9\u5f0f\u662f\u5229\u7528 typeid \u505a map \u7684\u952e\uff0c\u52a0\u901f\u67e5\u627e\u3002\u6ca1\u6709\u6027\u80fd\u95ee\u9898\uff0c\u4f46\u4f9d\u7136\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u3002 struct GameObject { unordered_map components; template T *getComponent() { if (auto it = components.find(typeid(T)); it != components.end()) { return dynamic_cast(it->second); } else { return nullptr; } } void add(Component *component) { components[typeid(*component)] = component; } }; \u8ba9 PlayerController \u53d1\u51fa\u6307\u5b9a\u7c7b\u578b\u7684\u6d88\u606f\u5bf9\u8c61\uff0c\u7531 Movable \u68c0\u67e5\u5e76\u5904\u7406\u3002 \u6d88\u606f\u7c7b\u578b\u4e5f\u662f\u591a\u6001\u7684\uff0c\u521d\u5b66\u8005\u53ef\u4ee5\u5148\u901a\u8fc7 dynamic_cast \u5b9e\u73b0\u7c7b\u578b\u68c0\u67e5\u3002\u7a0d\u540e\u6211\u4eec\u4f1a\u4ecb\u7ecd\u66f4\u4e13\u4e1a\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u6211\u4eec\u53ea\u80fd\u628a\u5b50\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u57fa\u7c7b\u6307\u9488\u3002 \u800c dynamic_cast \u53ef\u4ee5\u628a\u57fa\u7c7b\u6307\u9488\u8f6c\u6362\u4e3a\u5b50\u7c7b\u6307\u9488\u3002 \u5982\u679c\u4ed6\u6307\u5411\u7684\u5bf9\u8c61\u786e\u5b9e\u5c31\u662f\u90a3\u4e2a\u5b50\u7c7b\u7c7b\u578b\u7684\u8bdd\uff0c\u5c31\u6b63\u5e38\u8fd4\u56de\u5b50\u7c7b\u6307\u9488\u4e86\u3002 \u5426\u5219\uff0c\u5982\u679c\u7c7b\u578b\u4e0d\u5339\u914d\uff0c dynamic_cast \u4f1a\u8fd4\u56de nullptr\u3002\u53ea\u9700\u5224\u65ad\u8fd4\u56de\u7684\u6307\u9488\u662f\u4e0d\u662f nullptr \u5c31\u77e5\u9053\u662f\u5426\u7c7b\u578b\u5339\u914d\u4e86\u3002","title":"\u7ec4\u4ef6\u4e4b\u95f4\u5982\u4f55\u901a\u4fe1"},{"location":"design_gamedev/#_13","text":"struct Message { virtual ~Message() = default; // C++ \u89c4\u5b9a\uff1a\u53ea\u6709\u591a\u6001\u7c7b\u578b\u624d\u80fd dynamic_cast\uff0c\u8fd9\u91cc\u6211\u4eec\u7528\u4e0d\u5230\u865a\u51fd\u6570\uff0c\u90a3\u5c31\u53ea\u8ba9\u6790\u6784\u51fd\u6570\u4e3a\u865a\u51fd\u6570\uff0c\u5373\u53ef\u4f7f Message \u53d8\u4e3a\u591a\u6001\u7c7b\u578b }; struct MoveMessage : Message { glm::vec3 velocityChange; }; struct Component { virtual void update(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) override { // \u6240\u6709\u4e0d\u540c\u7684\u6d88\u606f\u7c7b\u578b\u90fd\u4f1a\u8fdb\u5165\u6b64\u51fd\u6570 if (MoveMessage *mm = dynamic_cast(msg)) { // \u4f46\u53ea\u6709\u771f\u6b63\u7c7b\u578b\u4e3a MoveMessage \u7684\u6d88\u606f\u4f1a\u88ab\u5904\u7406 velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } } }; struct GameObject { vector components; void add(Component *component) { components.push_back(component); } void update() { for (auto &&c: components) { c->update(this); } } void send(Message *msg) { for (auto &&c: components) { c->handleMessage(msg); } } }; \u8fd9\u5c31\u662f\u6240\u8c13\u7684\u89c2\u5bdf\u8005\u6a21\u5f0f\uff0c\u7531\u4e8e\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u53ef\u4ee5\u6536\u5230\u6240\u6709\u6d88\u606f\uff0c\u56e0\u6b64\uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u901a\u4fe1\u3002 \u4f46\u8fd9\u6837\u505a\u7684\u7f3a\u70b9\u662f\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u9700\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u4e0d\u8bba\u662f\u5426\u662f\u81ea\u5df1\u9700\u8981\u7684\uff0c\u5982\u679c\u7ec4\u4ef6\u6570\u91cf\u591a\uff0c\u6d88\u606f\u7c7b\u578b\u53c8\u591a\uff0c\u5c31\u4f1a\u51fa\u73b0\u6027\u80fd\u95ee\u9898\u3002","title":"\u89c2\u5bdf\u8005\u6a21\u5f0f"},{"location":"design_gamedev/#-","text":"\u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f\u662f\u89c2\u5bdf\u8005\u6a21\u5f0f\u7684\u5347\u7ea7\u7248\uff0c\u7531\u4e00\u4e2a\u4e2d\u5fc3\u7684\u4e8b\u4ef6\u603b\u7ebf\u6765\u7ba1\u7406\u6d88\u606f\u7684\u5206\u53d1\u3002\u4e8b\u4ef6\u603b\u7ebf\u901a\u5e38\u4f5c\u4e3a GameObject \u7684\u6210\u5458\u51fa\u73b0\u3002 \u6bcf\u4e2a\u7ec4\u4ef6\u53ef\u4ee5\u8ba2\u9605\u81ea\u5df1\u611f\u5174\u8da3\u7684\u6d88\u606f\u7c7b\u578b\uff0c\u5f53\u4e8b\u4ef6\u603b\u7ebf\u6536\u5230\u6d88\u606f\u65f6\uff0c\u53ea\u628a\u6d88\u606f\u5206\u53d1\u7ed9\u8ba2\u9605\u8005\uff0c\u800c\u4e0d\u662f\u6240\u6709\u7ec4\u4ef6\u3002 struct GameObject { vector components; unordered_map> subscribers; // \u4e8b\u4ef6\u603b\u7ebf template void subscribe(Component *component) { subscribers[type_index(typeid(EventType))].push_back(component); } template void send(EventType *msg) { for (auto &&c: subscribers[type_index(typeid(EventType))]) { c->handleMessage(msg); } } void add(Component *component) { components.push_back(component); component->subscribeMessages(this); } void update() { for (auto &&c: components) { c->update(this); } } }; struct Component { virtual void update(GameObject *go) = 0; virtual void subscribeMessages(GameObject *go) = 0; virtual void handleMessage(Message *msg) = 0; virtual ~Component() = default; }; struct Movable : Component { glm::vec3 position; glm::vec3 velocity; void subscribeMessages(GameObject *go) { go->subscribe(this); } void handleMessage(Message *msg) override { if (MoveMessage *mm = dynamic_cast(msg)) { velocity += mm->velocityChange; } } }; struct PlayerController : Component { void update(GameObject *go) override { if (isKeyPressed(GLFW_KEY_W)) { MoveMessage mm; mm.velocityChange.y += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_S)) { MoveMessage mm; mm.velocityChange.y -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_A)) { MoveMessage mm; mm.velocityChange.x -= 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_D)) { MoveMessage mm; mm.velocityChange.x += 1; go->send(&mm); } if (isKeyPressed(GLFW_KEY_SPACE)) { JumpMessage jm; go->send(&jm); } } }; \u8fd9\u6837\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u7ec4\u4ef6\u4e4b\u95f4\u7684\u6309\u9700\u901a\u4fe1\u3002","title":"\u53d1\u5e03-\u8ba2\u9605\u6a21\u5f0f"},{"location":"design_gamedev/#_14","text":"struct Message { virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; }; struct JumpMessage { double jumpHeight; }; \u5982\u4f55\u5b9a\u4e49\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u7684\u5904\u7406\u65b9\u5f0f\uff1f struct MessageVisitor; // \u524d\u5411\u58f0\u660e struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; struct MoveMessage { glm::vec3 velocityChange; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(MoveMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct JumpMessage { double jumpHeight; void accept(MessageVisitor *visitor) override { visitor->visit(this); // \u4f1a\u8c03\u7528\u5230 visit(JumpMessage *mm) \u8fd9\u4e2a\u91cd\u8f7d } }; struct MessageVisitor { virtual void visit(MoveMessage *mm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 virtual void visit(JumpMessage *jm) {} // \u9ed8\u8ba4\u4e0d\u505a\u4efb\u4f55\u5904\u7406 }; struct Movable : MessageVisitor { glm::vec3 position; glm::vec3 velocity; void handleMessage(Message *msg) { msg->accept(this); } void visit(MoveMessage *mm) override { velocity += mm->velocityChange; } void visit(JumpMessage *jm) override { velocity.y += sqrt(2 * 9.8 * jm->jumpHeight); } }; \u8fd9\u5c31\u662f\u8bbf\u95ee\u8005\u6a21\u5f0f\uff0c\u540c\u65f6\u7528\u5230\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u865a\u51fd\u6570\u548c\u91cd\u8f7d\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u5bf9\u6240\u6709\u4e0d\u540c\u7c7b\u578b\u6d88\u606f\u90fd\u80fd\u5b9a\u5236\u4e00\u4e2a\u5904\u7406\u65b9\u5f0f\uff0c\u800c\u4e0d\u7528\u901a\u8fc7\u4f4e\u6548\u7684 dynamic_cast \u5224\u65ad\u6d88\u606f\u7c7b\u578b\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u662f\u5426\u7b26\u5408\u5f00\u95ed\u539f\u5219\u5462\uff1f \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u6d88\u606f\u7c7b\u578b \u5728 MessageVisitor \u4e2d\u6dfb\u52a0\u4e00\u4e2a visit \u7684\u91cd\u8f7d \u5f53\u6211\u4eec\u65b0\u589e\u4e00\u79cd\u7ec4\u4ef6\u7c7b\u578b\u65f6\uff0c\u9700\u8981\u4fee\u6539\u7684\u5730\u65b9\u6709\uff1a \u65b0\u589e\u7ec4\u4ef6\u7c7b\u578b \u8fd9\u4e09\u9879\u4fee\u6539\u90fd\u662f\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\uff0c\u5e76\u4e0d\u4f1a\u51fa\u73b0\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u7684\u60c5\u51b5\u3002 \u4f46\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5904\u7406\u6240\u6709\u6d88\u606f\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u4e0d\u7b26\u5408\u5f00\u95ed\u539f\u5219\u7684\u8bbe\u8ba1\uff0c\u56e0\u6b64\u6211\u4eec\u8ba9\u6240\u6709\u7684 visit \u865a\u51fd\u6570\u6709\u4e00\u4e2a\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u4ec0\u4e48\u90fd\u4e0d\u505a\u3002\u8fd9\u6837\u5f53\u65b0\u589e\u6d88\u606f\u7c7b\u578b\u65f6\uff0c\u867d\u7136\u9700\u8981\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u91cd\u65b0\u7f16\u8bd1\u4e86\uff0c\u4f46\u662f\u7a0b\u5e8f\u5458\u65e0\u9700\u4fee\u6539\u4efb\u4f55\u4ee3\u7801\uff0c\u6e90\u7801\u7ea7\u522b\u4e0a\uff0c\u662f\u6ee1\u8db3\u5f00\u95ed\u539f\u5219\u7684\u3002 \u8bbf\u95ee\u8005\u6a21\u5f0f\u901a\u5e38\u7528\u4e8e acceptor \u6570\u91cf\u6709\u9650\uff0c\u4f46 visitor \u7684\u7ec4\u4ef6\u7c7b\u578b\u5343\u53d8\u4e07\u5316\u7684\u60c5\u51b5\u3002 \u5982\u679c\u6d88\u606f\u7c7b\u578b\u6709\u9650\uff0c\u7ec4\u4ef6\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5982\u679c\u7ec4\u4ef6\u7c7b\u578b\u6709\u9650\uff0c\u6d88\u606f\u7c7b\u578b\u53ef\u80fd\u7ecf\u5e38\u589e\u52a0\uff0c\u90a3\u9700\u8981\u628a\u6d88\u606f\u7c7b\u578b\u4f5c\u4e3a visitor\uff0c\u7ec4\u4ef6\u7c7b\u578b\u4f5c\u4e3a acceptor\u3002 \u5e38\u4f5c\u4e3a acceptor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684 IR \u8282\u70b9\uff08\u4ee3\u7801\u4e2d\u95f4\u8868\u793a\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u6d88\u606f\u7c7b\u578b\u3002 \u5e38\u4f5c\u4e3a visitor \u7684\u6709\uff1a\u7f16\u8bd1\u5668\u5f00\u53d1\u4e2d\u7684\u4f18\u5316 pass\uff08\u4f1a\u4fee\u6539 IR \u8282\u70b9\uff09\uff0c\u6e38\u620f\u4e0e UI \u5f00\u53d1\u4e2d\u7684\u63a5\u53d7\u6d88\u606f\u7ec4\u4ef6\u7c7b\u578b\u3002 \u4f46\u662f\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u8981\u5b9e\u73b0 accept \u7684\u91cd\u8f7d\uff0c\u5185\u5bb9\u5b8c\u5168\u4e00\u6837\uff0c\u51fa\u73b0\u4e86\u4ee3\u7801\u91cd\u590d\u3002 Java \u7684\u6a21\u677f\u662f type-erasure \u7684\uff0c\u5bf9\u6b64\u675f\u624b\u65e0\u7b56\u3002\u800c C++ \u7684\u6a21\u677f\u662f refined-generic\uff0c\u53ef\u4ee5\u5229\u7528 CRTP \u81ea\u52a8\u5b9e\u73b0\u8fd9\u90e8\u5206\uff1a struct Message { virtual void accept(MessageVisitor *visitor) = 0; virtual ~Message() = default; }; template struct MessageImpl : Message { void accept(MessageVisitor *visitor) override { static_assert(std::is_base_of_v); visitor->visit(static_cast(this)); } }; struct MoveMessage : MessageImpl { glm::vec3 velocityChange; // \u81ea\u52a8\u5b9e\u73b0\u4e86 accept \u51fd\u6570 }; struct JumpMessage : MessageImpl { double jumpHeight; }; \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u4e2d\uff0cZFX \u7f16\u8bd1\u5668\u7684 IR \u4f18\u5316\u7cfb\u7edf\u5c31\u8fd0\u7528\u4e86 CRTP \u52a0\u6301\u7684\u8bbf\u95ee\u8005\u6a21\u5f0f\u3002","title":"\u8bbf\u95ee\u8005\u6a21\u5f0f"},{"location":"design_gamedev/#mvc","text":"\u8bbe\u8ba1\u6a21\u5f0f\u662f\u4e00\u4e2a\u5de8\u5927\u7684\u8bdd\u9898\uff0c\u672c\u671f\u5148\u8bb2\u5230\u8fd9\u91cc\uff0c\u4e0b\u96c6\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd UI \u5f00\u53d1\u4e2d\u5927\u540d\u9f0e\u9f0e\u7684 MVC \u6a21\u5f0f\u3002 MVC \u6a21\u5f0f\u662f\u4e00\u79cd\u67b6\u6784\u6a21\u5f0f\uff0c\u5b83\u5c06\u5e94\u7528\u7a0b\u5e8f\u5206\u4e3a\u4e09\u4e2a\u6838\u5fc3\u90e8\u5206\uff1a\u6a21\u578b\uff08Model\uff09\u3001\u89c6\u56fe\uff08View\uff09\u548c\u63a7\u5236\u5668\uff08Controller\uff09\uff0c\u901a\u8fc7\u5206\u79bb\u5e94\u7528\u7a0b\u5e8f\u7684\u8f93\u5165\u3001\u5904\u7406\u548c\u8f93\u51fa\u6765\u63d0\u9ad8\u5e94\u7528\u7a0b\u5e8f\u7684\u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u6a21\u578b\uff08Model\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u6570\u636e\u548c\u4e1a\u52a1\u903b\u8f91\uff0c\u901a\u5e38\u7531\u6570\u636e\u7ed3\u6784\u548c\u6570\u636e\u5e93\u7ec4\u6210\u3002 \u89c6\u56fe\uff08View\uff09\uff1a\u8d1f\u8d23\u5c55\u793a\u6570\u636e\u548c\u7528\u6237\u754c\u9762\uff0c\u901a\u5e38\u7531 HTML\u3001CSS \u548c JavaScript \u7ec4\u6210\u3002 \u63a7\u5236\u5668\uff08Controller\uff09\uff1a\u8d1f\u8d23\u5904\u7406\u7528\u6237\u4ea4\u4e92\u548c\u8c03\u5ea6\u6a21\u578b\u548c\u89c6\u56fe\uff0c\u901a\u5e38\u7531\u540e\u7aef\u8bed\u8a00\uff08\u5982 PHP\u3001Java \u7b49\uff09\u5b9e\u73b0\u3002 MVC \u6a21\u5f0f\u7684\u4f18\u70b9\uff1a \u4f4e\u8026\u5408\uff1a\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u804c\u8d23\u6e05\u6670\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u8fdb\u884c\u5355\u72ec\u7684\u4fee\u6539\u548c\u7ef4\u62a4\u3002 \u53ef\u6269\u5c55\u6027\uff1a\u7531\u4e8e\u6a21\u578b\u3001\u89c6\u56fe\u548c\u63a7\u5236\u5668\u4e4b\u95f4\u7684\u4f4e\u8026\u5408\u6027\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u5730\u6dfb\u52a0\u65b0\u7684\u529f\u80fd\u548c\u7ec4\u4ef6\u3002 \u53ef\u7ef4\u62a4\u6027\uff1a\u5206\u79bb\u4e86\u4e0d\u540c\u7684\u804c\u8d23\uff0c\u4f7f\u5f97\u4ee3\u7801\u66f4\u5bb9\u6613\u7406\u89e3\u548c\u7ef4\u62a4\u3002","title":"MVC \u6a21\u5f0f"},{"location":"design_overview/","text":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 \u4e0d\u8981\u53bb\u6307\u6325\u4e0b\u9762\u600e\u4e48\u505a\uff01 \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. \u4f60\u597d O(N) O(N) \u554a\uff01","title":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5)"},{"location":"design_overview/#_1","text":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5) \u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9 \u4e0d\u8981\u53bb\u6307\u6325\u4e0b\u9762\u600e\u4e48\u505a\uff01","title":"\u8bbe\u8ba1\u6a21\u5f0f\u603b\u89c8 (\u672a\u5b8c\u5de5)"},{"location":"design_overview/#_2","text":"x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}. \u4f60\u597d O(N) O(N) \u554a\uff01","title":"\u52a8\u6001\u7c7b\u578b\u7684\u7f3a\u70b9"},{"location":"design_variant/","text":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 visitor \u6a21\u5f0f \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 TODO visitor \u6a21\u5f0f","title":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5)"},{"location":"design_variant/#_1","text":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5) \u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9 visitor \u6a21\u5f0f","title":"\u9759\u6001\u591a\u6001\u4e0e\u9762\u5411\u6570\u636e\u7f16\u7a0b (\u672a\u5b8c\u5de5)"},{"location":"design_variant/#_2","text":"TODO","title":"\u52a8\u6001\u591a\u6001\u7684\u7f3a\u70b9"},{"location":"design_variant/#visitor","text":"","title":"visitor \u6a21\u5f0f"},{"location":"design_virtual/","text":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01 \u8bb8\u591a\u8bbe\u8ba1\u6a21\u5f0f\u90fd\u4e0e\u865a\u51fd\u6570\u606f\u606f\u76f8\u5173\uff0c\u4eca\u5929\u6211\u4eec\u6765\u5b66\u4e60\u4e00\u4e9b\u5e38\u7528\u7684\u3002 \u7b56\u7565\u6a21\u5f0f \u8fed\u4ee3\u5668\u6a21\u5f0f \u9002\u914d\u5668\u6a21\u5f0f \u5de5\u5382\u6a21\u5f0f \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f \u4eab\u5143\u6a21\u5f0f \u4ee3\u7406\u6a21\u5f0f \u5f88\u591a\u6559\u6750\u4e2d\u90fd\u4f1a\u4e3e\u51fa\u8fd9\u79cd\u770b\u8d77\u6765\u597d\u50cf\u5f88\u6709\u8bf4\u670d\u529b\u7684\u4f8b\u5b50\uff1a struct Pet { virtual void speak() = 0; }; struct CatPet \uff1aPet { void speak() override { puts(\"\u55b5\"); } }; struct DogPet \uff1aPet { void speak() override { puts(\"\u6c6a\"); } }; int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); cat->speak(); dog->speak(); } \u7136\u800c\uff0c\u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2d\uff0c\u865a\u51fd\u6570\u53ef\u6709\u53ef\u65e0\uff0c\u5e76\u6ca1\u6709\u53d1\u6325\u4efb\u4f55\u4ef7\u503c\uff0c\u56e0\u4e3a\u666e\u901a\u6210\u5458\u51fd\u6570\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 \u865a\u51fd\u6570\u771f\u6b63\u7684\u4ef7\u503c\u5728\u4e8e\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u5165\u5176\u4ed6\u51fd\u6570\u65f6\uff01\u53ef\u4ee5\u590d\u7528\u90a3\u4e2a\u51fd\u6570\u91cc\u7684\u4ee3\u7801\u3002 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); puts(\"\u5582\u98df\u5b8c\u6bd5\"); } int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); feed(cat); feed(dog); } \u4f18\u70b9\u5728\u4e8e\uff0cfeed \u51fd\u6570\u53ea\u7528\u5b9e\u73b0\u4e00\u904d\u4e86\u3002\u5982\u679c\u6ca1\u6709\u865a\u51fd\u6570\uff1a void feed(DogPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u6c6a\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u55b5\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u5582\u98df \u548c \u5582\u98df\u5b8c\u6bd5 \u91cd\u590d\u4e24\u904d\uff01\u5982\u679c\u6211\u4eec\u53c8\u8981\u5f15\u5165\u4e00\u79cd\u65b0\u52a8\u7269 PigPet \u5462\uff1f\u4f60\u53c8\u8981\u624b\u5fd9\u811a\u4e71\u590d\u5236\u7c98\u8d34\u4e00\u4efd\u65b0\u7684 feed \u51fd\u6570\uff01 void feed(PigPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u62f1\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u6539\u4e86\u9700\u6c42\uff0c\u4ed6\u8bf4\u52a8\u7269\u73b0\u5728\u8981\u53eb\u4e24\u6b21\u3002 \u91c7\u7528\u4e86\u865a\u51fd\u6570\u7684\u4f60\uff0c\u53ea\u9700\u8981\u5728 feed \u51fd\u6570\u5185\u589e\u52a0\u4e00\u6b21 speak \u5373\u53ef\uff0c\u8f7b\u677e\uff01 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); pet->speak(); // \u52a0\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u5982\u679c\u4e00\u5f00\u59cb\u6ca1\u7528\u865a\u51fd\u6570\uff0c\u5c31\u5f97\u8fde\u6539 3 \u4e2a\u5730\u65b9\uff01 void feed(DogPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u4e14\u4e07\u4e00\u590d\u5236\u7c98\u8d34\u7684\u65f6\u5019\u6709\u4e2a\u5730\u65b9\u5199\u9519\u4e86\uff0c\u975e\u5e38\u9690\u853d\uff0c\u5f88\u5bb9\u6613\u53d1\u73b0\u4e0d\u4e86\uff1a void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); puts(\"\u55b5\"); // \u628a\u732b\u7684\u4ee3\u7801\u590d\u5236\u8fc7\u6765\u7684\u65f6\u5019\u6f0f\u6539\u4e86 \ud83e\udd2f puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u865a\u51fd\u6570\u5b9e\u6218\u6848\u4f8b \u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8bf4\u7684\u8fd9\u4e9b\u6211\u90fd\u4f1a\uff0c\u8fd9\u6709\u4ec0\u4e48\u7a00\u5947\u7684\u3002\u90a3\u6211\u4eec\u6765\u4e3e\u4e2a\u5b9e\u9645\u5f00\u53d1\u4e2d\u4f1a\u9047\u5230\u7684\u4f8b\u5b50\u3002 \u8fd9\u91cc\u6709\u4e00\u4e2a\u6c42\u548c\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u548c\u3002 \u8fd8\u6709\u4e00\u4e2a\u6c42\u79ef\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u79ef\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u4ee3\u7801\u91cd\u590d\uff01 \u6211\u4eec\u89c2\u5bdf\u4e00\u4e0b sum \u548c product \u4e4b\u95f4\u6709\u54ea\u4e9b\u76f8\u4f3c\u7684\u90e8\u5206\uff0c\u628a\u4e24\u8005\u4ea7\u751f\u4e0d\u540c\u7684\u90e8\u5206\u7528 ??? \u4ee3\u66ff\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * } return res; } \u628a ??? \u90e8\u5206\u7528\u4e00\u4e2a\u865a\u51fd\u6570\u9876\u66ff\uff1a struct Reducer { virtual int init() = 0; virtual int add(int a, int b) = 0; }; int reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u8fd9\u6837\u4e0d\u8bba\u6211\u4eec\u60f3\u8981\u6c42\u548c\uff0c\u8fd8\u662f\u6c42\u79ef\uff0c\u53ea\u9700\u8981\u5b9e\u73b0\u5176\u4e2d\u4e0d\u540c\u7684\u90e8\u5206\u5c31\u53ef\u4ee5\u4e86\uff0c\u516c\u5171\u90e8\u5206\u5df2\u7ecf\u5728 reduce \u91cc\u5b9e\u73b0\u597d\uff0c\u5c31\u5b9e\u73b0\u4e86\u4ee3\u7801\u590d\u7528\u3002 struct SumReducer : Reducer { int init() override { return 0; } int add(int a, int b) override { return a + b; } }; struct ProductReducer : Reducer { int init() override { return 1; } int add(int a, int b) override { return a * b; } }; reduce(v, new SumReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 sum(v) reduce(v, new ProductReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 product(v) \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 \u5f88\u5bb9\u6613\u6dfb\u52a0\u65b0\u7684\u7b56\u7565\u8fdb\u6765\uff1a struct MinReducer : Reducer { int init() override { return numeric_limits::max(); } int add(int a, int b) override { return min(a, b); } }; struct MaxReducer : Reducer { int init() override { return numeric_limits::min(); } int add(int a, int b) override { return max(a, b); } }; \u591a\u91cd\u7b56\u7565 \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 sum \u548c product \u51fd\u6570\u4ece\u8f93\u5165\u6570\u636e\u76f4\u63a5\u8ba1\u7b97\uff08\u800c\u4e0d\u7528\u5148\u8bfb\u53d6\u5230\u4e00\u4e2a vector\uff09\uff01 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u62bd\u51fa\u516c\u5171\u90e8\u5206\uff0c\u73b0\u5728\u53ea\u9700\u8981\u4fee\u6539 reduce \u51fd\u6570\u672c\u8eab\u5c31\u53ef\u4ee5\u4e86\u3002 SumReducer \u548c ProductReducer \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u4f53\u73b0\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 int reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u53c8\u6539\u56de\u6765\uff0c\u4ed6\u7a81\u7136\u53c8\u60f3\u8981\u4ece vector \u91cc\u8bfb\u53d6\u6570\u636e\u4e86\u3002 \u5728\u7834\u53e3\u5927\u9a82\u8001\u677f\u51fa\u5c14\u53cd\u5c14\u7684\u540c\u65f6\uff0c\u4f60\u5f00\u59cb\u601d\u8003\uff0c\u8fd9\u4e24\u4e2a\u51fd\u6570\u4f3c\u4e4e\u8fd8\u662f\u6709\u4e00\u4e9b\u91cd\u590d\u53ef\u4ee5\u62bd\u53d6\u51fa\u6765\uff1f int cin_reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } int vector_reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u73b0\u5728\u6211\u4eec\u53ea\u6709\u8868\u793a\u5982\u4f55\u8ba1\u7b97\u7684\u7c7b Reducer \u505a\u53c2\u6570\u3002 \u4f60\u51b3\u5b9a\uff0c\u518d\u5b9a\u4e49\u4e00\u4e2a\u8868\u793a\u5982\u4f55\u8bfb\u53d6\u7684\u865a\u7c7b Inputer\u3002 struct Inputer { virtual optional fetch() = 0; }; int reduce(Inputer *inputer, Reducer *reducer) { int res = reducer->init(); while (auto tmp = inputer->fetch()) { res = reducer->add(res, tmp.value()); } return res; } \u8fd9\u6837\uff0c\u6211\u4eec\u6ee1\u8db3\u4e86 \u5355\u4e00\u804c\u8d23\u539f\u5219 \uff1a\u6bcf\u4e2a\u7c7b\u53ea\u8d1f\u8d23\u4e00\u4ef6\u4e8b\u3002 \u8fd9\u91cc\u7684 Inputer \u5b9e\u9645\u4e0a\u8fd0\u7528\u4e86 \u8fed\u4ee3\u5668\u6a21\u5f0f \uff1a\u63d0\u4f9b\u4e00\u4e2a\u62bd\u8c61\u63a5\u53e3\u6765 \u987a\u5e8f\u8bbf\u95ee \u4e00\u4e2a\u96c6\u5408\u4e2d\u5404\u4e2a\u5143\u7d20\uff0c\u800c\u53c8\u65e0\u987b\u66b4\u9732\u8be5\u96c6\u5408\u7684\u5185\u90e8\u8868\u793a\u3002 \u5e95\u5c42\u662f cin \u8fd8\u662f vector\uff1f\u6211\u4e0d\u5728\u4e4e\uff01\u6211\u53ea\u77e5\u9053\u4ed6\u53ef\u4ee5\u4f9d\u6b21\u987a\u5e8f\u53d6\u51fa\u6570\u636e\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; reduce(new CinInputer(), new SumReducer()); reduce(new VectorInputer(v), new SumReducer()); reduce(new CinInputer(), new ProductReducer()); reduce(new VectorInputer(v), new ProductReducer()); Inputer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8bfb\u53d6\u6570\u636e\uff0cReducer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8ba1\u7b97\u6570\u636e\u3002 \u8fd9\u5c31\u662f \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \uff1a\u9ad8\u5c42\u6a21\u5757\uff08reduce \u51fd\u6570\uff09\u4e0d\u8981\u76f4\u63a5\u4f9d\u8d56\u4e8e\u4f4e\u5c42\u6a21\u5757\uff0c\u4e8c\u8005\u90fd\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff08Inputer \u548c Reducer \u7c7b\uff09\u6765\u6c9f\u901a\u3002 \u4e0d\u8981\u4ec0\u4e48\u4e1c\u897f\u90fd\u585e\u4e00\u5757 \u6709\u4e9b\u7cdf\u7cd5\u7684\u5b9e\u73b0\u4f1a\u628a\u5206\u660e\u4e0d\u5c5e\u4e8e\u540c\u4e00\u5c42\u6b21\u7684\u4e1c\u897f\u5f3a\u884c\u653e\u5728\u4e00\u8d77\uff0c\u6bd4\u5982\u6ca1\u80fd\u5206\u6e05 Inputer \u548c Reducer \u7c7b\uff0c\u9519\u8bef\u5730\u628a\u4ed6\u4eec\u8bbe\u8ba1\u6210\u4e86\u4e00\u4e2a\u7c7b\uff01 int reduce(Reducer *reducer) { int res = reducer->init(); while (auto tmp = reducer->fetch()) { // fetch \u51ed\u4ec0\u4e48\u548c init\u3001add \u653e\u5728\u4e00\u8d77\uff1f res = reducer->add(res, tmp.value()); } return res; } fetch \u660e\u660e\u5c5e\u4e8e IO \u64cd\u4f5c\uff01\u4f46\u4ed6\u88ab\u9519\u8bef\u5730\u653e\u5728\u4e86\u672c\u5e94\u53ea\u8d1f\u8d23\u8ba1\u7b97\u7684 Reducer \u91cc\uff01 \u8fd9\u5bfc\u81f4\u4f60\u5fc5\u987b\u5b9e\u73b0\u56db\u4e2a\u7c7b\uff0c\u7f57\u5217\u6240\u6709\u7684\u6392\u5217\u7ec4\u5408\uff1a struct CinSumReducer : Reducer { ... }; struct VectorSumReducer : Reducer { ... }; struct CinProductReducer : Reducer { ... }; struct VectorProductReducer : Reducer { ... }; \u8fd9\u663e\u7136\u662f\u4e0d\u7b26\u5408 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u7684\u3002 \u6ee1\u8db3 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3001 \u5f00\u95ed\u539f\u5219 \u3001 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u7684\u4ee3\u7801\u66f4\u52a0\u7075\u6d3b\u3001\u6613\u4e8e\u6269\u5c55\u3001\u6613\u4e8e\u7ef4\u62a4\u3002\u8bf7\u52a1\u5fc5\u8bb0\u4f4f\u5e76\u843d\u5b9e\u8d77\u6765\uff01 \u5426\u5219\u5373\u4f60\u88c5\u6a21\u4f5c\u6837\u5730\u7528\u4e86\u865a\u51fd\u6570\uff0c\u4e5f\u4e00\u6837\u4f1a\u5bfc\u81f4\u4ee3\u7801\u91cd\u590d\u3001\u96be\u4ee5\u7ef4\u62a4\uff01 \u8001\u677f\u514b\u6263\u5de5\u8d44\u65f6\u5c31\u4e0d\u7528\u9075\u5b88\u8fd9\u4e9b\u539f\u5219 \u9002\u914d\u5668\u6a21\u5f0f \u521a\u624d\u7684\u4f8b\u5b50\u4e2d\u6211\u4eec\u7528\u5230\u4e86 Inputer \u865a\u63a5\u53e3\u7c7b\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; \u5982\u679c\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\uff1a\u8bfb\u53d6\u5230 0 \u622a\u6b62\uff0c\u800c\u4e0d\u662f -1 \u5462\uff1f\u96be\u9053\u8fd8\u5f97\u7ed9 CinInputer \u52a0\u4e2a\u53c2\u6570\uff1f \u4f46\u662f vector \u6709\u65f6\u5019\u4e5f\u53ef\u80fd\u6709\u8bfb\u5230 -1 \u5c31\u63d0\u524d\u622a\u65ad\u7684\u9700\u6c42\u5440\uff1f \u8fd9\u660e\u663e\u8fdd\u80cc\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 \u66f4\u597d\u7684\u8bbe\u8ba1\u662f\uff0c\u8ba9 CinInputer \u65e0\u9650\u8bfb\u53d6\uff0c\u6c38\u8fdc\u6210\u529f\u3002 \u7136\u540e\u53e6\u5916\u5f04\u4e00\u4e2a StopInputerAdapter\uff0c\u5176\u63a5\u53d7\u4e00\u4e2a CinInputer \u4f5c\u4e3a\u6784\u9020\u53c2\u6570\u3002 \u5f53 StopInputerAdapter \u88ab\u8bfb\u53d6\u65f6\uff0c\u4ed6\u4f1a\u68c0\u67e5\u662f\u5426\u4e3a -1\uff0c\u5982\u679c\u5df2\u7ecf\u5f97\u5230 -1\uff0c\u90a3\u4e48\u5c31\u8fd4\u56de nullopt\uff0c\u4e0d\u4f1a\u8fdb\u4e00\u6b65\u8c03\u7528 CinInputer \u4e86\u3002 StopInputerAdapter \u8d1f\u8d23\u5904\u7406\u622a\u65ad\u95ee\u9898\uff0cCinInputer \u53ea\u662f\u8d1f\u8d23\u8bfb\u53d6 cin \u8f93\u5165\u3002\u6ee1\u8db3\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 struct StopInputerAdapter : Inputer { Inputer *inputer; int stopMark; StopInputerAdapter(Inputer *inputer, int stopMark) : inputer(inputer) , stopMark(stopMark) {} optional fetch() override { auto tmp = inputer->fetch(); if (tmp == stopMark) return nullopt; return tmp; } }; \u8fd9\u91cc\u7684 StopInputerAdapter \u5c31\u662f\u4e00\u4e2a\u9002\u914d\u5668\uff0c\u4ed6\u628a CinInputer \u7684\u63a5\u53e3\uff08\u65e0\u9650\u8bfb\u53d6\uff09\u53e0\u52a0\u4e0a\u4e86\u4e00\u4e2a\u989d\u5916\u529f\u80fd\uff0c\u8bfb\u5230\u6307\u5b9a\u7684 stopMark \u503c\u5c31\u505c\u6b62\uff0c\u4ea7\u751f\u4e86\u4e00\u4e2a\u65b0\u7684 Inputer\u3002 reduce(new StopInputerAdapter(new CinInputer(), -1), new SumReducer()); // \u4ece cin \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new StopInputerAdapter(new VectorInputer(v), -1), new SumReducer()); // \u4ece vector \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new VectorInputer(), new SumReducer()); // \u4ece vector \u8bfb\uff0c\u4f46\u65e0\u9700\u622a\u65ad \u8fd9\u5c31\u662f \u9002\u914d\u5668\u6a21\u5f0f \uff1a\u5c06\u4e00\u4e2a\u7c7b\u7684\u63a5\u53e3\u6dfb\u6cb9\u52a0\u918b\uff0c\u8f6c\u6362\u6210\u5ba2\u6237\u5e0c\u671b\u7684\u53e6\u4e00\u4e2a\u63a5\u53e3\u3002 StopInputerAdapter \u8fd9\u4e2a\u9002\u914d\u5668\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a Inputer\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f5c\u4e3a reduce \u7684\u53c2\u6570\uff0c\u9002\u5e94\u4e86\u73b0\u6709\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 StopInputerAdapter \u5e76\u4e0d\u4f9d\u8d56\u4e8e\u53c2\u6570 Inputer \u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u53ef\u4ee5\u662f CinInputer\u3001\u4e5f\u53ef\u4ee5\u662f VectorInputer\uff0c\u6ee1\u8db3\u4e86 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u3002 \u672a\u6765\u5373\u4f7f\u65b0\u589e\u4e86\u4e0d\u540c\u7c7b\u578b\u7684 Inputer\uff0c\u751a\u81f3\u662f\u5176\u4ed6 InputerAdapter\uff0c\u4e00\u6837\u53ef\u4ee5\u914d\u5408 StopInputerAdapter \u4e00\u8d77\u4f7f\u7528\u800c\u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u6ee1\u8db3\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u5982\u679c\u6211\u4eec\u8fd8\u60f3\u5b9e\u73b0\uff0c\u8fc7\u6ee4\u51fa\u6240\u6709\u6b63\u6570\u548c\u96f6\uff0c\u8d1f\u6570\u76f4\u63a5\u4e22\u5f03\u5462\uff1f struct FilterInputerAdapter { Inputer *inputer; FilterInputerAdapter(Inputer *inputer) : inputer(inputer) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (tmp >= 0) { return tmp; } } } }; \u6539\u8fdb\uff1aFilter \u7684\u6761\u4ef6\u4e0d\u5e94\u4e3a\u5199\u6b7b\u7684 tmp >= 0 \uff0c\u800c\u5e94\u8be5\u662f\u4f20\u5165\u4e00\u4e2a FilterStrategy\uff0c\u5141\u8bb8\u7528\u6237\u6269\u5c55\u3002 struct FilterStrategy { virtual bool shouldPass(int value) = 0; // \u8fd4\u56de true \u8868\u793a\u8be5\u503c\u5e94\u8be5\u88ab\u4fdd\u7559 }; struct FilterStrategyAbove : FilterStrategy { // \u5927\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyAbove(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value > threshold; } }; struct FilterStrategyBelow : FilterStrategy { // \u5c0f\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyBelow(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value < threshold; } }; struct FilterInputerAdapter : Inputer { Inputer *inputer; FilterStrategy *strategy; FilterInputerAdapter(Inputer *inputer, FilterStrategy *strategy) : inputer(inputer), strategy(strategy) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (strategy->shouldPass(tmp)) { return tmp; } } } }; FilterStrategy \u53c8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u8fd0\u7528\u9002\u914d\u5668\u6a21\u5f0f\uff1a\u4f8b\u5982\u6211\u4eec\u53ef\u4ee5\u628a FilterStrategyAbove(0) \u548c FilterStrategyBelow(100) \u7ec4\u5408\u8d77\u6765\uff0c\u5b9e\u73b0\u8fc7\u6ee4\u51fa 0\uff5e100 \u8303\u56f4\u5185\u7684\u6574\u6570\u3002 struct FilterStrategyAnd : FilterStrategy { // \u8981\u6c42 a \u548c b \u4e24\u4e2a\u8fc7\u6ee4\u7b56\u7565\u90fd\u4e3a true\uff0c\u624d\u80fd\u901a\u8fc7 FilterStrategy *a; FilterStrategy *b; FilterStrategyAnd(FilterStrategy *a, FilterStrategy *b) : a(a), b(b) {} bool shouldPass(int value) override { return a->shouldPass(value) && b->shouldPass(value); } }; reduce( new FilterInputerAdapter( new StopInputerAdapter( new CinInputer(), -1 ), new FilterStrategyAnd( new FilterStrategyAbove(0), new FilterStrategyBelow(100) ) ), new SumReducer()); \u662f\u4e0d\u662f\u903b\u8f91\u975e\u5e38\u6e05\u6670\uff0c\u800c\u4e14\u5bb9\u6613\u6269\u5c55\u5462\uff1f \u5b9e\u9645\u4e0a\u51fd\u6570\u5f0f\u548c\u6a21\u677f\u5143\u7f16\u7a0b\u66f4\u64c5\u957f\u505a\u8fd9\u79cd\u5de5\u4f5c\uff0c\u4f46\u4eca\u5929\u5148\u4ecb\u7ecd\u5b8c\u539f\u6c41\u539f\u5473\u7684 Java \u98ce\u683c\u9762\u5411\u5bf9\u8c61\uff0c\u4ed6\u4eec\u590d\u7528\u4ee3\u7801\u7684\u601d\u8def\u662f\u5171\u901a\u7684\u3002 \u4f60\u5148\u5b66\u4f1a\u8d70\u8def\uff0c\u660e\u5929\u6211\u4eec\u518d\u6765\u5b66\u4e60\u8dd1\u6b65\uff0c\u597d\u5427\uff1f \u8de8\u63a5\u53e3\u7684\u9002\u914d\u5668 \u9002\u914d\u5668\u6a21\u5f0f\u8fd8\u53ef\u4ee5\u4f7f\u539f\u672c\u7531\u4e8e\u63a5\u53e3\u4e0d\u517c\u5bb9\u800c\u4e0d\u80fd\u4e00\u8d77\u5de5\u4f5c\u7684\u90a3\u4e9b\u7c7b\u53ef\u4ee5\u4e00\u8d77\u5de5\u4f5c\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u4e86\u7c7b\u4f3c\u4e8e\u6211\u4eec Inputer \u7684\u8f93\u5165\u6d41\u63a5\u53e3\uff0c\u4e5f\u662f\u57fa\u4e8e\u865a\u51fd\u6570\u7684\u3002\u4f46\u662f\u4ed6\u7684\u63a5\u53e3\u663e\u7136\u4e0d\u80fd\u76f4\u63a5\u4f20\u5165\u6211\u4eec\u7684 reduce \u51fd\u6570\uff0c\u6211\u4eec\u7684 reduce \u51fd\u6570\u53ea\u63a5\u53d7\u6211\u4eec\u81ea\u5df1\u7684 Inputer \u63a5\u53e3\u3002\u8fd9\u65f6\u5c31\u53ef\u4ee5\u7528\u9002\u914d\u5668\uff0c\u628a\u63a5\u53e3\u7ffb\u8bd1\u6210\u6211\u4eec\u7684 reducer \u80fd\u591f\u7406\u89e3\u7684\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e2a\u81ea\u79f0 \u201cPoost\u201d \u7684\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u63a5\u53e3\uff1a struct PoostInputer { virtual bool hasNext() = 0; virtual int getNext() = 0; }; \u4ed6\u4eec\u8981\u6c42\u7684\u7528\u6cd5\u662f\u5148\u5224\u65ad hasNext()\uff0c\u7136\u540e\u624d\u80fd\u8c03\u7528 getNext \u8bfb\u53d6\u51fa\u771f\u6b63\u7684\u503c\u3002\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u4e86\u4e00\u4e2a Poost \u9002\u914d\u5668\uff0c\u628a PoostInputer \u7ffb\u8bd1\u6210\u6211\u4eec\u7684 Inputer\uff1a struct PoostInputerAdapter : Inputer { PoostInputer *poostIn; PoostInputerAdapter(PoostInputer *poostIn) : poostIn(poostIn) {} optional fetch() override { if (poostIn->hasNext()) { return poostIn->getNext(); } else { return nullopt; } } }; \u5f53\u6211\u4eec\u5f97\u5230\u4e00\u4e2a PoostInputer \u65f6\uff0c\u5982\u679c\u60f3\u8981\u8c03\u7528\u6211\u4eec\u81ea\u5df1\u7684 reducer\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u4e2a PoostInputerAdapter \u5957\u4e00\u5c42\uff1a auto poostStdIn = poost::getStandardInput(); reduce(new PoostInputerAdapter(poostStdIn), new SumReducer()); \u8fd9\u6837\u5c31\u53ef\u4ee5\u65e0\u7f1d\u5730\u628a PoostInputer \u4f5c\u4e3a reduce \u7684\u53c2\u6570\u4e86\u3002 \u5de5\u5382\u6a21\u5f0f \u73b0\u5728\u4f60\u662f\u4e00\u4e2a\u6e38\u620f\u5f00\u53d1\u8005\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u88c5\u5907\u6b66\u5668\uff0c\u4e0d\u540c\u7684\u6b66\u5668\u53ef\u4ee5\u53d1\u51fa\u4e0d\u540c\u7684\u5b50\u5f39\uff01 \u4f60\u4f7f\u7528\u5c0f\u5f6d\u8001\u5e08\u6559\u7684 \u7b56\u7565\u6a21\u5f0f \uff0c\u628a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u4f5c\u4e3a\u4e0d\u540c\u7684\u7b56\u7565\u4f20\u5165 player \u51fd\u6570\uff0c\u9020\u6210\u4e0d\u540c\u7c7b\u578b\u7684\u4f24\u5bb3\u3002 struct Bullet { virtual void explode() = 0; }; struct AK47Bullet : Bullet { void explode() override { puts(\"\u7269\u7406\u4f24\u5bb3\"); } }; struct MagicBullet : Bullet { void explode() override { puts(\"\u9b54\u6cd5\u4f24\u5bb3\"); } }; void player(Bullet *bullet) { bullet->explode(); } player(new AK47Bullet()); player(new MagicBullet()); \u4f46\u662f\u8fd9\u6837\u5c31\u76f8\u5f53\u4e8e\u6bcf\u4e2a\u73a9\u5bb6\u53ea\u6709\u4e00\u53d1\u5b50\u5f39\uff0c\u542c\u4e2a\u54cd\u5c31\u6ca1\u4e86\u2026 \u5982\u4f55\u5141\u8bb8\u73a9\u5bb6\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u9020\u65b0\u5b50\u5f39\u51fa\u6765\uff1f\u6211\u4eec\u53ef\u4ee5\u628a\u201c\u521b\u5efa\u5b50\u5f39\u201d\u8fd9\u4e00\u8fc7\u7a0b\u62bd\u8c61\u51fa\u6765\uff0c\u653e\u5728\u4e00\u4e2a\u201c\u67aa\u201d\u7c7b\u91cc\u3002 struct Gun { virtual Bullet *shoot() = 0; }; struct AK47Gun : Gun { Bullet *shoot() override { return new AK47Bullet(); } }; struct MagicGun : Gun { Bullet *shoot() override { return new MagicBullet(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new AK47Gun()); player(new MagicGun()); \u73b0\u5728\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u76f4\u63a5\u9009\u62e9\u4e0d\u540c\u7684\u67aa\u4e86\uff01 \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u5de5\u5382\u6a21\u5f0f \uff1a\u201c\u67aa\u201d\u5c31\u662f\u201c\u5b50\u5f39\u201d\u5bf9\u8c61\u7684\u5de5\u5382\u3002 \u4f20\u7ed9\u73a9\u5bb6\u7684\u662f\u5b50\u5f39\u7684\u5de5\u5382\u2014\u2014\u67aa\uff0c\u800c\u4e0d\u662f\u5b50\u5f39\u672c\u8eab\u3002 \u53ea\u8981\u8c03\u7528\u5de5\u5382\u7684 shoot \u51fd\u6570\uff0c\u73a9\u5bb6\u53ef\u4ee5\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u5efa\u65b0\u5b50\u5f39\u51fa\u6765\u3002 \u6b63\u6240\u8c13\u6388\u4eba\u4ee5\u9c7c\u4e0d\u5982\u6388\u4eba\u4ee5\u6e14\uff0c\u4f60\u7684\u73a9\u5bb6\u4e0d\u518d\u662f\u88ab\u52a8\u63a5\u53d7\u5b50\u5f39\uff0c\u800c\u662f\u53ef\u4ee5\u81ea\u5df1\u521b\u9020\u5b50\u5f39\u4e86\uff01 \u5de5\u5382\u8fd8\u53ef\u4ee5\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u6570\uff0c\u4f8b\u5982\u6211\u4eec\u9700\u8981\u6a21\u62df AK47 \u53ef\u80fd\u201c\u53d7\u6f6e\u201d\uff0c\u5bfc\u81f4\u4ea7\u751f\u7684\u5b50\u5f39\u5a01\u529b\u964d\u4f4e\u3002 \u5c31\u53ef\u4ee5\u7ed9\u67aa\u52a0\u4e00\u4e2a isWet \u53c2\u6570\uff0c\u7ed9\u5b50\u5f39\u52a0\u4e00\u4e2a damage \u53c2\u6570\uff0c\u8ba9 AK47 \u751f\u6210\u5b50\u5f39\u7684\u65f6\u5019\uff0c\u6839\u636e isWet \u4e3a\u5b50\u5f39\u6784\u9020\u51fd\u6570\u8bbe\u7f6e\u4e0d\u540c\u7684 damage\u3002 struct AK47Bullet { int damage; AK47Bullet(int damage) : damage(damage) {} void explode() { printf(\"\u9020\u6210 %d \u70b9\u7269\u7406\u4f24\u5bb3\\n\", damage); } }; struct AK47Gun : Gun { bool isWet; AK47Gun(bool isWet) : isWet(isWet) {} Bullet *shoot() override { if (isWet) return new AK47Bullet(5); // \u53d7\u6f6e\u4e86\uff0c\u4f24\u5bb3\u964d\u4f4e\u4e3a 5 else return new AK47Bullet(10); // \u6b63\u5e38\u60c5\u51b5\u4e0b\u4f24\u5bb3\u4e3a 10 } }; \u6211\u4eec\u8fd8\u53ef\u4ee5\u5229\u7528\u6a21\u677f\u81ea\u52a8\u4e3a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u6279\u91cf\u5b9a\u4e49\u5de5\u5382\uff1a template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new GunWithBullet()); player(new GunWithBullet()); \u8fd9\u6837\u5c31\u4e0d\u5fc5\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5b50\u5f39\u7c7b\u578b\u65f6\uff0c\u90fd\u5f97\u65b0\u5efa\u4e00\u4e2a\u76f8\u5e94\u7684\u67aa\u7c7b\u578b\u4e86\uff0c\u8fdb\u4e00\u6b65\u907f\u514d\u4e86\u4ee3\u7801\u91cd\u590d\u3002\u53ef\u89c1\u6a21\u677f\u5143\u7f16\u7a0b\u5b8c\u5168\u53ef\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u5f3a\u5f3a\u8054\u624b\u3002 \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f Gun *getGun(string name) { if (name == \"AK47\") { return new GunWithBullet(); } else if (name == \"Magic\") { return new GunWithBullet(); } else { throw runtime_error(\"\u6ca1\u6709\u8fd9\u79cd\u67aa\"); } } player(getGun(\"AK47\")); player(getGun(\"Magic\")); RAII \u81ea\u52a8\u7ba1\u7406\u5185\u5b58 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); delete bullet; // \u521a\u624d\u6ca1\u6709 delete\uff01\u4f1a\u4ea7\u751f\u5185\u5b58\u6cc4\u6f0f\uff01 } } player(new GunWithBullet()); player(new GunWithBullet()); \u73b0\u5728\u7684\u5de5\u5382\u4e00\u822c\u90fd\u4f1a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u5177\u4f53\u6765\u8bf4\u5c31\u662f\u7528 unique_ptr \u4ee3\u66ff T * \uff0c\u7528 make_unique(xxx) \u4ee3\u66ff new T(xxx) \u3002 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); unique_ptr shoot() override { return make_unique(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { auto bullet = gun->shoot(); bullet->explode(); // unique_ptr \u5728\u9000\u51fa\u5f53\u524d {} \u65f6\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u4e0d\u7528\u4f60\u60e6\u8bb0\u7740\u4e86 } } player(make_unique>().get()); player(make_unique>().get()); \u8fd9\u91cc C++ \u6807\u51c6\u4fdd\u8bc1\u4e86 unique_ptr \u7684\u751f\u547d\u5468\u671f\u662f\u8fd9\u4e00\u6574\u884c\uff08; \u7ed3\u675f\u524d\uff09\uff0c\u6574\u4e2a player \u6267\u884c\u671f\u95f4\u90fd\u6d3b\u7740\uff0c\u4e0d\u4f1a\u63d0\u524d\u91ca\u653e \u6b63\u5982 func(string().c_str()) \u4e0d\u4f1a\u6709\u4efb\u4f55\u95ee\u9898\uff0cstring \u8981\u5230 func \u8fd4\u56de\u540e\u624d\u91ca\u653e\u5462\uff01 \u53ea\u8981\u628a\u6240\u6709 make_unique \u770b\u4f5c new T \uff0c\u628a\u6240\u6709\u7684 unique_ptr \u770b\u4f5c T * \uff0c\u7528\u6cd5\u51e0\u4e4e\u4e00\u6837\uff0c\u4f46\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\uff0c\u65e0\u9700\u624b\u52a8 delete\u3002 \u5de5\u5382\u6a21\u5f0f\u5b9e\u6218 \u56de\u5230\u6570\u7ec4\u6c42\u548c\u95ee\u9898\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } int average(vector v) { int res = 0; int count = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; count = count + 1; } return res / count; } \u6211\u4eec\u60f3\u8981\u52a0\u4e00\u4e2a\u6c42\u5e73\u5747\u503c\u7684\u51fd\u6570 average\uff0c\u8fd9\u8be5\u5982\u4f55\u4e0e sum \u5408\u8d77\u6765\uff1f \u6ce8\u610f\u56e0\u4e3a\u6211\u4eec\u8981\u652f\u6301\u4ece CinInputer \u8bfb\u5165\u6570\u636e\uff0c\u5e76\u4e0d\u4e00\u5b9a\u50cf\u4e00\u6837 VectorInputer \u80fd\u591f\u63d0\u524d\u5f97\u5230\u6570\u7ec4\u5927\u5c0f\uff0c\u4e0d\u7136\u4e5f\u4e0d\u9700\u8981 count \u4e86\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 int count? = ???; // sum \u548c product \u7528\u4e0d\u5230\u8be5\u53d8\u91cf\uff0c\u53ea\u6709 average \u9700\u8981 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * count? = count? ???; // average \u65f6\u8fd9\u91cc\u8fd8\u9700\u8981\u989d\u5916\u4fee\u6539 count \u53d8\u91cf\uff01 } return res; } \u770b\u6765\u6211\u4eec\u9700\u8981\u5141\u8bb8 Reducer \u7684 init() \u8fd4\u56de \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d\uff01 \u4ee5\u524d\u7684\u8bbe\u8ba1\u8ba9 init() \u53ea\u80fd\u8fd4\u56de\u5355\u4e2a int \u662f\u4e2a\u9519\u8bef\u7684\u51b3\u5b9a\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u628a \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d \u5c01\u88c5\u6210\u4e00\u4e2a\u65b0\u7684\u7c7b\u3002 \u7136\u540e\u6539\u4e3a\u7531\u8fd9\u4e2a\u7c7b\u8d1f\u8d23\u63d0\u4f9b\u865a\u51fd\u6570 add()\u3002 \u4e14\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u53f3\u4fa7\u53c2\u6570\u4e86\uff0c\u5de6\u4fa7\u7684 res \u53d8\u91cf\u5df2\u7ecf\u5b58\u5728 ReducerState \u4f53\u5185\u4e86\u3002 struct ReducerState { virtual void add(int val) = 0; virtual int result() = 0; }; struct Reducer { virtual unique_ptr init() = 0; }; struct SumReducerState : ReducerState { int res; SumReducerState() : res(0) {} void add(int val) override { res = res + val; } int result() override { return res; } }; struct ProductReducerState : ReducerState { int res; ProductReducerState() : res(1) {} void add(int val) override { res = res * val; } int result() override { return res; } }; struct AverageReducerState : ReducerState { int res; int count; AverageReducerState() : res(0), count(0) {} void add(int val) override { res = res + val; count = count + 1; } int result() override { return res / count; } }; struct SumReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct ProductReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct AverageReducer : Reducer { unique_ptr init() override { return make_unique(); } }; \u8fd9\u91cc Reducer \u5c31\u6210\u4e86 ReducerState \u7684\u5de5\u5382\u3002 int reduce(Inputer *inputer, Reducer *reducer) { unique_ptr state = reducer->init(); while (auto val = inputer->fetch()) { state->add(val); } return state->result(); } int main() { vector v; reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 \u5e76\u884c \u7684 sum \u548c product \u51fd\u6570\uff01 \u5e76\u884c\u7248\u9700\u8981\u521b\u5efa\u5f88\u591a\u4e2a\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u9700\u8981\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u4e2d\u95f4\u7ed3\u679c\u53d8\u91cf\uff0c\u6700\u540e\u7684\u7ed3\u679c\u8ba1\u7b97\u53c8\u9700\u8981\u4e00\u4e2a\u4e2d\u95f4\u53d8\u91cf\u3002 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u91c7\u7528\u5de5\u5382\u6a21\u5f0f\uff0c\u5141\u8bb8\u51fd\u6570\u4f53\u5185\u591a\u6b21\u521b\u5efa ReducerState \u5bf9\u8c61\u3002 int reduce(Inputer *inputer, Reducer *reducer) { tbb::task_group g; list> local_states; vector chunk; auto enqueue_chunk = [&]() { local_chunks.emplace_back(); g.run([chunk = move(chunk), &back = local_chunks.back()]() { auto local_state = reducer->init(); for (auto &&c: chunk) { local_state->add(c); } back = move(local_state); // list \u4fdd\u8bc1\u5df2\u7ecf\u63d2\u5165\u5143\u7d20\u7684\u5f15\u7528\u4e0d\u4f1a\u5931\u6548\uff0c\u6240\u4ee5\u53ef\u4ee5\u6682\u5b58 back \u5f15\u7528 }); chunk.clear(); }; while (auto tmp = inputer->fetch()) { if (chunk.size() < 64) { // \u8fd8\u6ca1\u586b\u6ee1 64 \u4e2a chunk.push_back(tmp); } else { // \u586b\u6ee1\u4e86 64 \u4e2a\uff0c\u53ef\u4ee5\u63d0\u4ea4\u6210\u4e00\u4e2a\u5355\u72ec\u4efb\u52a1\u4e86 enqueue_chunk(); } } if (chunk.size() > 0) { enqueue_chunk(); // \u63d0\u4ea4\u4e0d\u8db3 64 \u4e2a\u7684\u6b8b\u4f59\u9879 } g.wait(); auto final_state = reducer->init(); for (auto &&local_state: local_states) { res = final_state->add(local_state->result()); } return final_state->result(); } \u53ea\u9700\u8981\u628a reducer \u53c2\u6570\u66ff\u6362\u4e3a MinReducer\u3001AverageReducer\u2026\u2026\u5c31\u81ea\u52a8\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u4efb\u52a1\uff0c\u800c\u4e0d\u7528\u4e3a\u4ed6\u4eec\u6bcf\u4e2a\u5355\u72ec\u7f16\u5199\u5e76\u884c\u7248\u672c\u7684\u4ee3\u7801\u3002 \u8bfe\u540e\u4f5c\u4e1a\uff1a\u4f7f\u7528\u6a21\u677f\u6279\u91cf\u5b9a\u4e49\u6240\u6709\u7684 Reducer\uff01\u4f8b\u5982\uff1a using MinReducer = ReducerWithState; ... \u4eab\u5143\u6a21\u5f0f \u5728\u4e8c\u7ef4\u6e38\u620f\u5f00\u53d1\u4e2d\uff0c\u5e38\u5e38\u4f1a\u63d0\u5230\u4e00\u79cd\u79f0\u4e3a Sprite\uff08\u7cbe\u7075\u8d34\u56fe\uff09\u7684\u9ed1\u8bdd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6bcf\u4e2a\u5bf9\u8c61\u81ea\u5df1\u6709\u4e00\u5f20\u8d34\u56fe\uff0c\u8d34\u56fe\u8ddf\u7740\u7269\u4f53\u7684\u4f4d\u7f6e\u8d70\u3002 struct Bullet { glm::vec3 position; glm::vec3 velocity; vector texture; void draw() { glDrawPixels(position, texture); } }; texture \u91cc\u9762\u5b58\u50a8\u7740\u8d34\u56fe\u7684 RGB \u6570\u636e\uff0c\u4ed6\u76f4\u63a5\u5c31\u662f Bullet \u7684\u6210\u5458\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u6253\u51fa\u4e86 100 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 100 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u540c\u65f6\u6253\u51fa\u4e86 1000 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 1000 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5185\u5b58\u6d88\u8017\u5c06\u4f1a\u975e\u5e38\u5927\u3002\u7136\u800c\u6240\u6709\u540c\u7c7b\u578b\u7684 Bullet\uff0c\u5176\u8d34\u56fe\u6570\u7ec4\u5176\u5b9e\u662f\u5b8c\u5168\u76f8\u540c\u7684\uff0c\u5b8c\u5168\u6ca1\u5fc5\u8981\u5404\u81ea\u5b58\u90a3\u4e48\u591a\u4efd\u62f7\u8d1d\u3002 \u4e3a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 \u4eab\u5143\u6a21\u5f0f \uff1a\u5171\u4eab\u591a\u4e2a\u5bf9\u8c61\u4e4b\u95f4 \u76f8\u540c \u7684\u90e8\u5206\uff0c\u8282\u7701\u5185\u5b58\u5f00\u9500\u3002 \u8fd9\u91cc\u6bcf\u9897\u5b50\u5f39\u7684 position\u3001velocity \u663e\u7136\u90fd\u662f\u5404\u6709\u4e0d\u540c\u7684\uff0c\u4e0d\u53ef\u80fd\u6240\u6709\u5b50\u5f39\u90fd\u5728\u540c\u4e00\u4e2a\u4f4d\u7f6e\u4e0a\u3002 \u4f46\u662f\u5f88\u591a\u5b50\u5f39\u90fd\u4f1a\u6709\u7740\u76f8\u540c\u7684\u8d34\u56fe\uff0c\u53ea\u6709\u4e0d\u540c\u7c7b\u578b\u7684\u5b50\u5f39\u8d34\u56fe\u4f1a\u4e0d\u4e00\u6837\u3002 \u6bd4\u5982\u706b\u7130\u5f39\u548c\u5bd2\u51b0\u5f39\u4f1a\u6709\u4e0d\u540c\u7684\u8d34\u56fe\uff0c\u4f46\u662f\u5f53\u573a\u4e0a\u51fa\u73b0 100 \u9897\u706b\u7130\u5f39\u65f6\uff0c\u663e\u7136\u4e0d\u9700\u8981\u62f7\u8d1d 100 \u4efd\u5b8c\u5168\u76f8\u540c\u7684\u706b\u7130\u5f39\u8d34\u56fe\u3002 struct Sprite { // Sprite \u624d\u662f\u771f\u6b63\u6301\u6709\uff08\u5f88\u5927\u7684\uff09\u8d34\u56fe\u6570\u636e\u7684 vector texture; void draw(glm::vec3 position) { glDrawPixels(position, texture); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // \u5141\u8bb8\u591a\u4e2a\u5b50\u5f39\u5bf9\u8c61\u5171\u4eab\u540c\u4e00\u4e2a\u7cbe\u7075\u8d34\u56fe\u7684\u6240\u6709\u6743 void draw() { sprite->draw(position); // \u8f6c\u53d1\u7ed9 Sprite \u8ba9\u4ed6\u5e2e\u5fd9\u5728\u6211\u7684\u4f4d\u7f6e\u7ed8\u5236\u8d34\u56fe } }; \u9700\u8981\u7ed8\u5236\u5b50\u5f39\u65f6\uff0cBullet \u7684 draw \u53ea\u662f\u7b80\u5355\u5730\u8f6c\u53d1\u7ed9 Sprite \u7c7b\u7684 draw\u3002 \u53ea\u8981\u544a\u8bc9 Sprite \u5b50\u5f39\u7684\u4f4d\u7f6e\u5c31\u884c\uff0c\u8d34\u56fe\u6570\u636e\u5df2\u7ecf\u5b58\u5728 Sprite \u5185\u90e8\uff0c\u8ba9\u4ed6\u6765\u8d1f\u8d23\u771f\u6b63\u7ed8\u5236\u3002 Bullet \u7c7b\u53ea\u9700\u8981\u4e13\u6ce8\u4e8e\u4f4d\u7f6e\u3001\u901f\u5ea6\u7684\u66f4\u65b0\u5373\u53ef\uff0c\u4e0d\u5fc5\u53bb\u64cd\u5fc3\u7740\u8d34\u56fe\u7ed8\u5236\u7684\u7ec6\u8282\uff0c\u5b9e\u73b0\u4e86\u89e3\u8026\u3002 \u8fd9\u79cd\u51fd\u6570\u8c03\u7528\u7684\u8f6c\u53d1\u4e5f\u88ab\u79f0\u4e3a \u4ee3\u7406\u6a21\u5f0f \u3002 \u4ee3\u7406\u6a21\u5f0f \u8fd9\u6837\u8fd8\u6709\u4e00\u4e2a\u597d\u5904\u90a3\u5c31\u662f\uff0cSprite \u53ef\u4ee5\u8bbe\u8ba1\u6210\u4e00\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\u7c7b\uff1a struct Sprite { virtual void draw(glm::vec3 position) = 0; }; struct FireSprite : Sprite { vector fireTexture; FireSprite() : fireTexture(loadTexture(\"fire.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, fireTexture); } }; struct IceSprite : Sprite { // \u5047\u5982\u5bd2\u51b0\u5f39\u9700\u8981\u4e24\u5f20\u8d34\u56fe\uff0c\u4e5f\u6ca1\u95ee\u9898\uff01\u56e0\u4e3a\u865a\u63a5\u53e3\u7c7b\u5141\u8bb8\u5b50\u7c7b\u6709\u4e0d\u540c\u7684\u6210\u5458\uff0c\u4e0d\u540c\u7684\u7ed3\u6784\u4f53\u5927\u5c0f vector iceTexture1; vector iceTexture2; IceSprite() : iceTexture1(loadTexture(\"ice1.jpg\")) , iceTexture2(loadTexture(\"ice2.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, iceTexture1); glDrawPixels(position, iceTexture2); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // Sprite \u8d1f\u8d23\u542b\u6709\u865a\u51fd\u6570 void draw() { // Bullet \u7684 draw \u5c31\u4e0d\u7528\u662f\u865a\u51fd\u6570\u4e86\uff01 sprite->draw(position); } }; \u7ec4\u4ef6\u6a21\u5f0f \u865a\u51fd\u6570\u5e38\u89c1\u95ee\u9898\u8fa8\u6790 \u8fd4\u56de bool \u7684\u865a\u51fd\u6570 \u8bfe\u540e\u4f5c\u4e1a \u4f60\u62ff\u5230\u4e86\u4e00\u4e2a\u5927\u5b66\u751f\u8ba1\u7b97\u5668\u7684\u5927\u4f5c\u4e1a\uff1a int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; if (c == '+') { cout << a + b; } else if (c == '-') { cout << a - b; } else if (c == '*') { cout << a * b; } else if (c == '/') { cout << a / b; } else { cout << \"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"; } } \u4f60\u5f00\u59cb\u7528\u7b56\u7565\u6a21\u5f0f\u6539\u9020\u5b83\uff1a struct Calculator { virtual int calculate(int a, int b) = 0; }; struct AddCalculator : Calculator { int calculate(int a, int b) override { return a + b; } }; struct SubCalculator : Calculator { int calculate(int a, int b) override { return a - b; } }; struct MulCalculator : Calculator { int calculate(int a, int b) override { return a * b; } }; struct DivCalculator : Calculator { int calculate(int a, int b) override { return a / b; } }; Calculator *getCalculator(char c) { if (c == '+') { calculator = new AddCalculator(); } else if (c == '-') { calculator = new SubCalculator(); } else if (c == '*') { calculator = new MulCalculator(); } else if (c == '/') { calculator = new DivCalculator(); } else { throw runtime_error(\"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"); } }; int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; Calculator *calculator = getCalculator(c); cout << calculator->calculate(a, b); }","title":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01"},{"location":"design_virtual/#_1","text":"\u8bb8\u591a\u8bbe\u8ba1\u6a21\u5f0f\u90fd\u4e0e\u865a\u51fd\u6570\u606f\u606f\u76f8\u5173\uff0c\u4eca\u5929\u6211\u4eec\u6765\u5b66\u4e60\u4e00\u4e9b\u5e38\u7528\u7684\u3002 \u7b56\u7565\u6a21\u5f0f \u8fed\u4ee3\u5668\u6a21\u5f0f \u9002\u914d\u5668\u6a21\u5f0f \u5de5\u5382\u6a21\u5f0f \u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f \u4eab\u5143\u6a21\u5f0f \u4ee3\u7406\u6a21\u5f0f \u5f88\u591a\u6559\u6750\u4e2d\u90fd\u4f1a\u4e3e\u51fa\u8fd9\u79cd\u770b\u8d77\u6765\u597d\u50cf\u5f88\u6709\u8bf4\u670d\u529b\u7684\u4f8b\u5b50\uff1a struct Pet { virtual void speak() = 0; }; struct CatPet \uff1aPet { void speak() override { puts(\"\u55b5\"); } }; struct DogPet \uff1aPet { void speak() override { puts(\"\u6c6a\"); } }; int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); cat->speak(); dog->speak(); } \u7136\u800c\uff0c\u5728\u8fd9\u4e2a\u6848\u4f8b\u4e2d\uff0c\u865a\u51fd\u6570\u53ef\u6709\u53ef\u65e0\uff0c\u5e76\u6ca1\u6709\u53d1\u6325\u4efb\u4f55\u4ef7\u503c\uff0c\u56e0\u4e3a\u666e\u901a\u6210\u5458\u51fd\u6570\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u540c\u6837\u6548\u679c\u3002 \u865a\u51fd\u6570\u771f\u6b63\u7684\u4ef7\u503c\u5728\u4e8e\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u53c2\u6570\u4f20\u5165\u5176\u4ed6\u51fd\u6570\u65f6\uff01\u53ef\u4ee5\u590d\u7528\u90a3\u4e2a\u51fd\u6570\u91cc\u7684\u4ee3\u7801\u3002 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); puts(\"\u5582\u98df\u5b8c\u6bd5\"); } int main() { Pet *cat = new CatPet(); Pet *dog = new DogPet(); feed(cat); feed(dog); } \u4f18\u70b9\u5728\u4e8e\uff0cfeed \u51fd\u6570\u53ea\u7528\u5b9e\u73b0\u4e00\u904d\u4e86\u3002\u5982\u679c\u6ca1\u6709\u865a\u51fd\u6570\uff1a void feed(DogPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u6c6a\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u55b5\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u5582\u98df \u548c \u5582\u98df\u5b8c\u6bd5 \u91cd\u590d\u4e24\u904d\uff01\u5982\u679c\u6211\u4eec\u53c8\u8981\u5f15\u5165\u4e00\u79cd\u65b0\u52a8\u7269 PigPet \u5462\uff1f\u4f60\u53c8\u8981\u624b\u5fd9\u811a\u4e71\u590d\u5236\u7c98\u8d34\u4e00\u4efd\u65b0\u7684 feed \u51fd\u6570\uff01 void feed(PigPet *pet) { puts(\"\u5582\u98df\"); // \u91cd\u590d\u7684\u4ee3\u7801 puts(\"\u62f1\"); puts(\"\u5582\u98df\u5b8c\u6bd5\"); // \u91cd\u590d\u7684\u4ee3\u7801 } \u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u6539\u4e86\u9700\u6c42\uff0c\u4ed6\u8bf4\u52a8\u7269\u73b0\u5728\u8981\u53eb\u4e24\u6b21\u3002 \u91c7\u7528\u4e86\u865a\u51fd\u6570\u7684\u4f60\uff0c\u53ea\u9700\u8981\u5728 feed \u51fd\u6570\u5185\u589e\u52a0\u4e00\u6b21 speak \u5373\u53ef\uff0c\u8f7b\u677e\uff01 void feed(Pet *pet) { puts(\"\u5582\u98df\"); pet->speak(); pet->speak(); // \u52a0\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u5982\u679c\u4e00\u5f00\u59cb\u6ca1\u7528\u865a\u51fd\u6570\uff0c\u5c31\u5f97\u8fde\u6539 3 \u4e2a\u5730\u65b9\uff01 void feed(DogPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u6c6a\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(CatPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u55b5\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u62f1\"); // \u6539\u8fd9\u91cc puts(\"\u5582\u98df\u5b8c\u6bd5\"); } \u800c\u4e14\u4e07\u4e00\u590d\u5236\u7c98\u8d34\u7684\u65f6\u5019\u6709\u4e2a\u5730\u65b9\u5199\u9519\u4e86\uff0c\u975e\u5e38\u9690\u853d\uff0c\u5f88\u5bb9\u6613\u53d1\u73b0\u4e0d\u4e86\uff1a void feed(PigPet *pet) { puts(\"\u5582\u98df\"); puts(\"\u62f1\"); puts(\"\u55b5\"); // \u628a\u732b\u7684\u4ee3\u7801\u590d\u5236\u8fc7\u6765\u7684\u65f6\u5019\u6f0f\u6539\u4e86 \ud83e\udd2f puts(\"\u5582\u98df\u5b8c\u6bd5\"); }","title":"\u8ba9\u865a\u51fd\u6570\u518d\u6b21\u4f1f\u5927\uff01"},{"location":"design_virtual/#_2","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8bf4\u7684\u8fd9\u4e9b\u6211\u90fd\u4f1a\uff0c\u8fd9\u6709\u4ec0\u4e48\u7a00\u5947\u7684\u3002\u90a3\u6211\u4eec\u6765\u4e3e\u4e2a\u5b9e\u9645\u5f00\u53d1\u4e2d\u4f1a\u9047\u5230\u7684\u4f8b\u5b50\u3002 \u8fd9\u91cc\u6709\u4e00\u4e2a\u6c42\u548c\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u548c\u3002 \u8fd8\u6709\u4e00\u4e2a\u6c42\u79ef\u51fd\u6570\uff0c\u53ef\u4ee5\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u4e2d\u6240\u6709\u6570\u5b57\u7684\u79ef\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u4ee3\u7801\u91cd\u590d\uff01 \u6211\u4eec\u89c2\u5bdf\u4e00\u4e0b sum \u548c product \u4e4b\u95f4\u6709\u54ea\u4e9b\u76f8\u4f3c\u7684\u90e8\u5206\uff0c\u628a\u4e24\u8005\u4ea7\u751f\u4e0d\u540c\u7684\u90e8\u5206\u7528 ??? \u4ee3\u66ff\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * } return res; } \u628a ??? \u90e8\u5206\u7528\u4e00\u4e2a\u865a\u51fd\u6570\u9876\u66ff\uff1a struct Reducer { virtual int init() = 0; virtual int add(int a, int b) = 0; }; int reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u8fd9\u6837\u4e0d\u8bba\u6211\u4eec\u60f3\u8981\u6c42\u548c\uff0c\u8fd8\u662f\u6c42\u79ef\uff0c\u53ea\u9700\u8981\u5b9e\u73b0\u5176\u4e2d\u4e0d\u540c\u7684\u90e8\u5206\u5c31\u53ef\u4ee5\u4e86\uff0c\u516c\u5171\u90e8\u5206\u5df2\u7ecf\u5728 reduce \u91cc\u5b9e\u73b0\u597d\uff0c\u5c31\u5b9e\u73b0\u4e86\u4ee3\u7801\u590d\u7528\u3002 struct SumReducer : Reducer { int init() override { return 0; } int add(int a, int b) override { return a + b; } }; struct ProductReducer : Reducer { int init() override { return 1; } int add(int a, int b) override { return a * b; } }; reduce(v, new SumReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 sum(v) reduce(v, new ProductReducer()); // \u7b49\u4ef7\u4e8e\u4e4b\u524d\u7684 product(v) \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 \u5f88\u5bb9\u6613\u6dfb\u52a0\u65b0\u7684\u7b56\u7565\u8fdb\u6765\uff1a struct MinReducer : Reducer { int init() override { return numeric_limits::max(); } int add(int a, int b) override { return min(a, b); } }; struct MaxReducer : Reducer { int init() override { return numeric_limits::min(); } int add(int a, int b) override { return max(a, b); } };","title":"\u865a\u51fd\u6570\u5b9e\u6218\u6848\u4f8b"},{"location":"design_virtual/#_3","text":"\u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 sum \u548c product \u51fd\u6570\u4ece\u8f93\u5165\u6570\u636e\u76f4\u63a5\u8ba1\u7b97\uff08\u800c\u4e0d\u7528\u5148\u8bfb\u53d6\u5230\u4e00\u4e2a vector\uff09\uff01 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u62bd\u51fa\u516c\u5171\u90e8\u5206\uff0c\u73b0\u5728\u53ea\u9700\u8981\u4fee\u6539 reduce \u51fd\u6570\u672c\u8eab\u5c31\u53ef\u4ee5\u4e86\u3002 SumReducer \u548c ProductReducer \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u4f53\u73b0\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 int reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u53c8\u6539\u56de\u6765\uff0c\u4ed6\u7a81\u7136\u53c8\u60f3\u8981\u4ece vector \u91cc\u8bfb\u53d6\u6570\u636e\u4e86\u3002 \u5728\u7834\u53e3\u5927\u9a82\u8001\u677f\u51fa\u5c14\u53cd\u5c14\u7684\u540c\u65f6\uff0c\u4f60\u5f00\u59cb\u601d\u8003\uff0c\u8fd9\u4e24\u4e2a\u51fd\u6570\u4f3c\u4e4e\u8fd8\u662f\u6709\u4e00\u4e9b\u91cd\u590d\u53ef\u4ee5\u62bd\u53d6\u51fa\u6765\uff1f int cin_reduce(Reducer *reducer) { int res = reducer->init(); while (true) { int tmp; cin >> tmp; if (tmp == -1) break; res = reducer->add(res, tmp); } return res; } int vector_reduce(vector v, Reducer *reducer) { int res = reducer->init(); for (int i = 0; i < v.size(); i++) { res = reducer->add(res, v[i]); } return res; } \u73b0\u5728\u6211\u4eec\u53ea\u6709\u8868\u793a\u5982\u4f55\u8ba1\u7b97\u7684\u7c7b Reducer \u505a\u53c2\u6570\u3002 \u4f60\u51b3\u5b9a\uff0c\u518d\u5b9a\u4e49\u4e00\u4e2a\u8868\u793a\u5982\u4f55\u8bfb\u53d6\u7684\u865a\u7c7b Inputer\u3002 struct Inputer { virtual optional fetch() = 0; }; int reduce(Inputer *inputer, Reducer *reducer) { int res = reducer->init(); while (auto tmp = inputer->fetch()) { res = reducer->add(res, tmp.value()); } return res; } \u8fd9\u6837\uff0c\u6211\u4eec\u6ee1\u8db3\u4e86 \u5355\u4e00\u804c\u8d23\u539f\u5219 \uff1a\u6bcf\u4e2a\u7c7b\u53ea\u8d1f\u8d23\u4e00\u4ef6\u4e8b\u3002 \u8fd9\u91cc\u7684 Inputer \u5b9e\u9645\u4e0a\u8fd0\u7528\u4e86 \u8fed\u4ee3\u5668\u6a21\u5f0f \uff1a\u63d0\u4f9b\u4e00\u4e2a\u62bd\u8c61\u63a5\u53e3\u6765 \u987a\u5e8f\u8bbf\u95ee \u4e00\u4e2a\u96c6\u5408\u4e2d\u5404\u4e2a\u5143\u7d20\uff0c\u800c\u53c8\u65e0\u987b\u66b4\u9732\u8be5\u96c6\u5408\u7684\u5185\u90e8\u8868\u793a\u3002 \u5e95\u5c42\u662f cin \u8fd8\u662f vector\uff1f\u6211\u4e0d\u5728\u4e4e\uff01\u6211\u53ea\u77e5\u9053\u4ed6\u53ef\u4ee5\u4f9d\u6b21\u987a\u5e8f\u53d6\u51fa\u6570\u636e\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; reduce(new CinInputer(), new SumReducer()); reduce(new VectorInputer(v), new SumReducer()); reduce(new CinInputer(), new ProductReducer()); reduce(new VectorInputer(v), new ProductReducer()); Inputer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8bfb\u53d6\u6570\u636e\uff0cReducer \u8d1f\u8d23\u544a\u8bc9 reduce \u51fd\u6570\u5982\u4f55\u8ba1\u7b97\u6570\u636e\u3002 \u8fd9\u5c31\u662f \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \uff1a\u9ad8\u5c42\u6a21\u5757\uff08reduce \u51fd\u6570\uff09\u4e0d\u8981\u76f4\u63a5\u4f9d\u8d56\u4e8e\u4f4e\u5c42\u6a21\u5757\uff0c\u4e8c\u8005\u90fd\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff08Inputer \u548c Reducer \u7c7b\uff09\u6765\u6c9f\u901a\u3002","title":"\u591a\u91cd\u7b56\u7565"},{"location":"design_virtual/#_4","text":"\u6709\u4e9b\u7cdf\u7cd5\u7684\u5b9e\u73b0\u4f1a\u628a\u5206\u660e\u4e0d\u5c5e\u4e8e\u540c\u4e00\u5c42\u6b21\u7684\u4e1c\u897f\u5f3a\u884c\u653e\u5728\u4e00\u8d77\uff0c\u6bd4\u5982\u6ca1\u80fd\u5206\u6e05 Inputer \u548c Reducer \u7c7b\uff0c\u9519\u8bef\u5730\u628a\u4ed6\u4eec\u8bbe\u8ba1\u6210\u4e86\u4e00\u4e2a\u7c7b\uff01 int reduce(Reducer *reducer) { int res = reducer->init(); while (auto tmp = reducer->fetch()) { // fetch \u51ed\u4ec0\u4e48\u548c init\u3001add \u653e\u5728\u4e00\u8d77\uff1f res = reducer->add(res, tmp.value()); } return res; } fetch \u660e\u660e\u5c5e\u4e8e IO \u64cd\u4f5c\uff01\u4f46\u4ed6\u88ab\u9519\u8bef\u5730\u653e\u5728\u4e86\u672c\u5e94\u53ea\u8d1f\u8d23\u8ba1\u7b97\u7684 Reducer \u91cc\uff01 \u8fd9\u5bfc\u81f4\u4f60\u5fc5\u987b\u5b9e\u73b0\u56db\u4e2a\u7c7b\uff0c\u7f57\u5217\u6240\u6709\u7684\u6392\u5217\u7ec4\u5408\uff1a struct CinSumReducer : Reducer { ... }; struct VectorSumReducer : Reducer { ... }; struct CinProductReducer : Reducer { ... }; struct VectorProductReducer : Reducer { ... }; \u8fd9\u663e\u7136\u662f\u4e0d\u7b26\u5408 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u7684\u3002 \u6ee1\u8db3 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3001 \u5f00\u95ed\u539f\u5219 \u3001 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u7684\u4ee3\u7801\u66f4\u52a0\u7075\u6d3b\u3001\u6613\u4e8e\u6269\u5c55\u3001\u6613\u4e8e\u7ef4\u62a4\u3002\u8bf7\u52a1\u5fc5\u8bb0\u4f4f\u5e76\u843d\u5b9e\u8d77\u6765\uff01 \u5426\u5219\u5373\u4f60\u88c5\u6a21\u4f5c\u6837\u5730\u7528\u4e86\u865a\u51fd\u6570\uff0c\u4e5f\u4e00\u6837\u4f1a\u5bfc\u81f4\u4ee3\u7801\u91cd\u590d\u3001\u96be\u4ee5\u7ef4\u62a4\uff01 \u8001\u677f\u514b\u6263\u5de5\u8d44\u65f6\u5c31\u4e0d\u7528\u9075\u5b88\u8fd9\u4e9b\u539f\u5219","title":"\u4e0d\u8981\u4ec0\u4e48\u4e1c\u897f\u90fd\u585e\u4e00\u5757"},{"location":"design_virtual/#_5","text":"\u521a\u624d\u7684\u4f8b\u5b50\u4e2d\u6211\u4eec\u7528\u5230\u4e86 Inputer \u865a\u63a5\u53e3\u7c7b\u3002 struct CinInputer : Inputer { optional fetch() override { int tmp; cin >> tmp; if (tmp == -1) return nullopt; return tmp; } }; struct VectorInputer : Inputer { vector v; int pos = 0; VectorInputer(vector v) : v(v) {} optional fetch() override { if (pos == v.size()) return nullopt; return v[pos++]; } }; \u5982\u679c\u6211\u4eec\u60f3\u8981\u5b9e\u73b0\uff1a\u8bfb\u53d6\u5230 0 \u622a\u6b62\uff0c\u800c\u4e0d\u662f -1 \u5462\uff1f\u96be\u9053\u8fd8\u5f97\u7ed9 CinInputer \u52a0\u4e2a\u53c2\u6570\uff1f \u4f46\u662f vector \u6709\u65f6\u5019\u4e5f\u53ef\u80fd\u6709\u8bfb\u5230 -1 \u5c31\u63d0\u524d\u622a\u65ad\u7684\u9700\u6c42\u5440\uff1f \u8fd9\u660e\u663e\u8fdd\u80cc\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 \u66f4\u597d\u7684\u8bbe\u8ba1\u662f\uff0c\u8ba9 CinInputer \u65e0\u9650\u8bfb\u53d6\uff0c\u6c38\u8fdc\u6210\u529f\u3002 \u7136\u540e\u53e6\u5916\u5f04\u4e00\u4e2a StopInputerAdapter\uff0c\u5176\u63a5\u53d7\u4e00\u4e2a CinInputer \u4f5c\u4e3a\u6784\u9020\u53c2\u6570\u3002 \u5f53 StopInputerAdapter \u88ab\u8bfb\u53d6\u65f6\uff0c\u4ed6\u4f1a\u68c0\u67e5\u662f\u5426\u4e3a -1\uff0c\u5982\u679c\u5df2\u7ecf\u5f97\u5230 -1\uff0c\u90a3\u4e48\u5c31\u8fd4\u56de nullopt\uff0c\u4e0d\u4f1a\u8fdb\u4e00\u6b65\u8c03\u7528 CinInputer \u4e86\u3002 StopInputerAdapter \u8d1f\u8d23\u5904\u7406\u622a\u65ad\u95ee\u9898\uff0cCinInputer \u53ea\u662f\u8d1f\u8d23\u8bfb\u53d6 cin \u8f93\u5165\u3002\u6ee1\u8db3\u4e86 \u5355\u4e00\u8d23\u4efb\u539f\u5219 \u3002 struct StopInputerAdapter : Inputer { Inputer *inputer; int stopMark; StopInputerAdapter(Inputer *inputer, int stopMark) : inputer(inputer) , stopMark(stopMark) {} optional fetch() override { auto tmp = inputer->fetch(); if (tmp == stopMark) return nullopt; return tmp; } }; \u8fd9\u91cc\u7684 StopInputerAdapter \u5c31\u662f\u4e00\u4e2a\u9002\u914d\u5668\uff0c\u4ed6\u628a CinInputer \u7684\u63a5\u53e3\uff08\u65e0\u9650\u8bfb\u53d6\uff09\u53e0\u52a0\u4e0a\u4e86\u4e00\u4e2a\u989d\u5916\u529f\u80fd\uff0c\u8bfb\u5230\u6307\u5b9a\u7684 stopMark \u503c\u5c31\u505c\u6b62\uff0c\u4ea7\u751f\u4e86\u4e00\u4e2a\u65b0\u7684 Inputer\u3002 reduce(new StopInputerAdapter(new CinInputer(), -1), new SumReducer()); // \u4ece cin \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new StopInputerAdapter(new VectorInputer(v), -1), new SumReducer()); // \u4ece vector \u8bfb\u5230 -1 \u4e3a\u6b62 reduce(new VectorInputer(), new SumReducer()); // \u4ece vector \u8bfb\uff0c\u4f46\u65e0\u9700\u622a\u65ad \u8fd9\u5c31\u662f \u9002\u914d\u5668\u6a21\u5f0f \uff1a\u5c06\u4e00\u4e2a\u7c7b\u7684\u63a5\u53e3\u6dfb\u6cb9\u52a0\u918b\uff0c\u8f6c\u6362\u6210\u5ba2\u6237\u5e0c\u671b\u7684\u53e6\u4e00\u4e2a\u63a5\u53e3\u3002 StopInputerAdapter \u8fd9\u4e2a\u9002\u914d\u5668\u672c\u8eab\u4e5f\u662f\u4e00\u4e2a Inputer\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f5c\u4e3a reduce \u7684\u53c2\u6570\uff0c\u9002\u5e94\u4e86\u73b0\u6709\u7684 \u7b56\u7565\u6a21\u5f0f \u3002 StopInputerAdapter \u5e76\u4e0d\u4f9d\u8d56\u4e8e\u53c2\u6570 Inputer \u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u53ef\u4ee5\u662f CinInputer\u3001\u4e5f\u53ef\u4ee5\u662f VectorInputer\uff0c\u6ee1\u8db3\u4e86 \u4f9d\u8d56\u5012\u7f6e\u539f\u5219 \u3002 \u672a\u6765\u5373\u4f7f\u65b0\u589e\u4e86\u4e0d\u540c\u7c7b\u578b\u7684 Inputer\uff0c\u751a\u81f3\u662f\u5176\u4ed6 InputerAdapter\uff0c\u4e00\u6837\u53ef\u4ee5\u914d\u5408 StopInputerAdapter \u4e00\u8d77\u4f7f\u7528\u800c\u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u6ee1\u8db3\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u5982\u679c\u6211\u4eec\u8fd8\u60f3\u5b9e\u73b0\uff0c\u8fc7\u6ee4\u51fa\u6240\u6709\u6b63\u6570\u548c\u96f6\uff0c\u8d1f\u6570\u76f4\u63a5\u4e22\u5f03\u5462\uff1f struct FilterInputerAdapter { Inputer *inputer; FilterInputerAdapter(Inputer *inputer) : inputer(inputer) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (tmp >= 0) { return tmp; } } } }; \u6539\u8fdb\uff1aFilter \u7684\u6761\u4ef6\u4e0d\u5e94\u4e3a\u5199\u6b7b\u7684 tmp >= 0 \uff0c\u800c\u5e94\u8be5\u662f\u4f20\u5165\u4e00\u4e2a FilterStrategy\uff0c\u5141\u8bb8\u7528\u6237\u6269\u5c55\u3002 struct FilterStrategy { virtual bool shouldPass(int value) = 0; // \u8fd4\u56de true \u8868\u793a\u8be5\u503c\u5e94\u8be5\u88ab\u4fdd\u7559 }; struct FilterStrategyAbove : FilterStrategy { // \u5927\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyAbove(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value > threshold; } }; struct FilterStrategyBelow : FilterStrategy { // \u5c0f\u4e8e\u4e00\u5b9a\u503c\uff08threshold\uff09\u624d\u80fd\u901a\u8fc7 int threshold; FilterStrategyBelow(int threshold) : threshold(threshold) {} bool shouldPass(int value) override { return value < threshold; } }; struct FilterInputerAdapter : Inputer { Inputer *inputer; FilterStrategy *strategy; FilterInputerAdapter(Inputer *inputer, FilterStrategy *strategy) : inputer(inputer), strategy(strategy) {} optional fetch() override { while (true) { auto tmp = inputer->fetch(); if (!tmp.has_value()) { return nullopt; } if (strategy->shouldPass(tmp)) { return tmp; } } } }; FilterStrategy \u53c8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u8fd0\u7528\u9002\u914d\u5668\u6a21\u5f0f\uff1a\u4f8b\u5982\u6211\u4eec\u53ef\u4ee5\u628a FilterStrategyAbove(0) \u548c FilterStrategyBelow(100) \u7ec4\u5408\u8d77\u6765\uff0c\u5b9e\u73b0\u8fc7\u6ee4\u51fa 0\uff5e100 \u8303\u56f4\u5185\u7684\u6574\u6570\u3002 struct FilterStrategyAnd : FilterStrategy { // \u8981\u6c42 a \u548c b \u4e24\u4e2a\u8fc7\u6ee4\u7b56\u7565\u90fd\u4e3a true\uff0c\u624d\u80fd\u901a\u8fc7 FilterStrategy *a; FilterStrategy *b; FilterStrategyAnd(FilterStrategy *a, FilterStrategy *b) : a(a), b(b) {} bool shouldPass(int value) override { return a->shouldPass(value) && b->shouldPass(value); } }; reduce( new FilterInputerAdapter( new StopInputerAdapter( new CinInputer(), -1 ), new FilterStrategyAnd( new FilterStrategyAbove(0), new FilterStrategyBelow(100) ) ), new SumReducer()); \u662f\u4e0d\u662f\u903b\u8f91\u975e\u5e38\u6e05\u6670\uff0c\u800c\u4e14\u5bb9\u6613\u6269\u5c55\u5462\uff1f \u5b9e\u9645\u4e0a\u51fd\u6570\u5f0f\u548c\u6a21\u677f\u5143\u7f16\u7a0b\u66f4\u64c5\u957f\u505a\u8fd9\u79cd\u5de5\u4f5c\uff0c\u4f46\u4eca\u5929\u5148\u4ecb\u7ecd\u5b8c\u539f\u6c41\u539f\u5473\u7684 Java \u98ce\u683c\u9762\u5411\u5bf9\u8c61\uff0c\u4ed6\u4eec\u590d\u7528\u4ee3\u7801\u7684\u601d\u8def\u662f\u5171\u901a\u7684\u3002 \u4f60\u5148\u5b66\u4f1a\u8d70\u8def\uff0c\u660e\u5929\u6211\u4eec\u518d\u6765\u5b66\u4e60\u8dd1\u6b65\uff0c\u597d\u5427\uff1f","title":"\u9002\u914d\u5668\u6a21\u5f0f"},{"location":"design_virtual/#_6","text":"\u9002\u914d\u5668\u6a21\u5f0f\u8fd8\u53ef\u4ee5\u4f7f\u539f\u672c\u7531\u4e8e\u63a5\u53e3\u4e0d\u517c\u5bb9\u800c\u4e0d\u80fd\u4e00\u8d77\u5de5\u4f5c\u7684\u90a3\u4e9b\u7c7b\u53ef\u4ee5\u4e00\u8d77\u5de5\u4f5c\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u4e86\u7c7b\u4f3c\u4e8e\u6211\u4eec Inputer \u7684\u8f93\u5165\u6d41\u63a5\u53e3\uff0c\u4e5f\u662f\u57fa\u4e8e\u865a\u51fd\u6570\u7684\u3002\u4f46\u662f\u4ed6\u7684\u63a5\u53e3\u663e\u7136\u4e0d\u80fd\u76f4\u63a5\u4f20\u5165\u6211\u4eec\u7684 reduce \u51fd\u6570\uff0c\u6211\u4eec\u7684 reduce \u51fd\u6570\u53ea\u63a5\u53d7\u6211\u4eec\u81ea\u5df1\u7684 Inputer \u63a5\u53e3\u3002\u8fd9\u65f6\u5c31\u53ef\u4ee5\u7528\u9002\u914d\u5668\uff0c\u628a\u63a5\u53e3\u7ffb\u8bd1\u6210\u6211\u4eec\u7684 reducer \u80fd\u591f\u7406\u89e3\u7684\u3002 \u4ee5\u4e0b\u662f\u4e00\u4e2a\u81ea\u79f0 \u201cPoost\u201d \u7684\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u63a5\u53e3\uff1a struct PoostInputer { virtual bool hasNext() = 0; virtual int getNext() = 0; }; \u4ed6\u4eec\u8981\u6c42\u7684\u7528\u6cd5\u662f\u5148\u5224\u65ad hasNext()\uff0c\u7136\u540e\u624d\u80fd\u8c03\u7528 getNext \u8bfb\u53d6\u51fa\u771f\u6b63\u7684\u503c\u3002\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u4e86\u4e00\u4e2a Poost \u9002\u914d\u5668\uff0c\u628a PoostInputer \u7ffb\u8bd1\u6210\u6211\u4eec\u7684 Inputer\uff1a struct PoostInputerAdapter : Inputer { PoostInputer *poostIn; PoostInputerAdapter(PoostInputer *poostIn) : poostIn(poostIn) {} optional fetch() override { if (poostIn->hasNext()) { return poostIn->getNext(); } else { return nullopt; } } }; \u5f53\u6211\u4eec\u5f97\u5230\u4e00\u4e2a PoostInputer \u65f6\uff0c\u5982\u679c\u60f3\u8981\u8c03\u7528\u6211\u4eec\u81ea\u5df1\u7684 reducer\uff0c\u5c31\u53ef\u4ee5\u7528\u8fd9\u4e2a PoostInputerAdapter \u5957\u4e00\u5c42\uff1a auto poostStdIn = poost::getStandardInput(); reduce(new PoostInputerAdapter(poostStdIn), new SumReducer()); \u8fd9\u6837\u5c31\u53ef\u4ee5\u65e0\u7f1d\u5730\u628a PoostInputer \u4f5c\u4e3a reduce \u7684\u53c2\u6570\u4e86\u3002","title":"\u8de8\u63a5\u53e3\u7684\u9002\u914d\u5668"},{"location":"design_virtual/#_7","text":"\u73b0\u5728\u4f60\u662f\u4e00\u4e2a\u6e38\u620f\u5f00\u53d1\u8005\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u88c5\u5907\u6b66\u5668\uff0c\u4e0d\u540c\u7684\u6b66\u5668\u53ef\u4ee5\u53d1\u51fa\u4e0d\u540c\u7684\u5b50\u5f39\uff01 \u4f60\u4f7f\u7528\u5c0f\u5f6d\u8001\u5e08\u6559\u7684 \u7b56\u7565\u6a21\u5f0f \uff0c\u628a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u4f5c\u4e3a\u4e0d\u540c\u7684\u7b56\u7565\u4f20\u5165 player \u51fd\u6570\uff0c\u9020\u6210\u4e0d\u540c\u7c7b\u578b\u7684\u4f24\u5bb3\u3002 struct Bullet { virtual void explode() = 0; }; struct AK47Bullet : Bullet { void explode() override { puts(\"\u7269\u7406\u4f24\u5bb3\"); } }; struct MagicBullet : Bullet { void explode() override { puts(\"\u9b54\u6cd5\u4f24\u5bb3\"); } }; void player(Bullet *bullet) { bullet->explode(); } player(new AK47Bullet()); player(new MagicBullet()); \u4f46\u662f\u8fd9\u6837\u5c31\u76f8\u5f53\u4e8e\u6bcf\u4e2a\u73a9\u5bb6\u53ea\u6709\u4e00\u53d1\u5b50\u5f39\uff0c\u542c\u4e2a\u54cd\u5c31\u6ca1\u4e86\u2026 \u5982\u4f55\u5141\u8bb8\u73a9\u5bb6\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u9020\u65b0\u5b50\u5f39\u51fa\u6765\uff1f\u6211\u4eec\u53ef\u4ee5\u628a\u201c\u521b\u5efa\u5b50\u5f39\u201d\u8fd9\u4e00\u8fc7\u7a0b\u62bd\u8c61\u51fa\u6765\uff0c\u653e\u5728\u4e00\u4e2a\u201c\u67aa\u201d\u7c7b\u91cc\u3002 struct Gun { virtual Bullet *shoot() = 0; }; struct AK47Gun : Gun { Bullet *shoot() override { return new AK47Bullet(); } }; struct MagicGun : Gun { Bullet *shoot() override { return new MagicBullet(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new AK47Gun()); player(new MagicGun()); \u73b0\u5728\uff0c\u4f60\u7684\u73a9\u5bb6\u53ef\u4ee5\u76f4\u63a5\u9009\u62e9\u4e0d\u540c\u7684\u67aa\u4e86\uff01 \u8fd9\u5c31\u662f\u6240\u8c13\u7684 \u5de5\u5382\u6a21\u5f0f \uff1a\u201c\u67aa\u201d\u5c31\u662f\u201c\u5b50\u5f39\u201d\u5bf9\u8c61\u7684\u5de5\u5382\u3002 \u4f20\u7ed9\u73a9\u5bb6\u7684\u662f\u5b50\u5f39\u7684\u5de5\u5382\u2014\u2014\u67aa\uff0c\u800c\u4e0d\u662f\u5b50\u5f39\u672c\u8eab\u3002 \u53ea\u8981\u8c03\u7528\u5de5\u5382\u7684 shoot \u51fd\u6570\uff0c\u73a9\u5bb6\u53ef\u4ee5\u6e90\u6e90\u4e0d\u65ad\u5730\u521b\u5efa\u65b0\u5b50\u5f39\u51fa\u6765\u3002 \u6b63\u6240\u8c13\u6388\u4eba\u4ee5\u9c7c\u4e0d\u5982\u6388\u4eba\u4ee5\u6e14\uff0c\u4f60\u7684\u73a9\u5bb6\u4e0d\u518d\u662f\u88ab\u52a8\u63a5\u53d7\u5b50\u5f39\uff0c\u800c\u662f\u53ef\u4ee5\u81ea\u5df1\u521b\u9020\u5b50\u5f39\u4e86\uff01 \u5de5\u5382\u8fd8\u53ef\u4ee5\u5177\u6709\u4e00\u5b9a\u7684\u53c2\u6570\uff0c\u4f8b\u5982\u6211\u4eec\u9700\u8981\u6a21\u62df AK47 \u53ef\u80fd\u201c\u53d7\u6f6e\u201d\uff0c\u5bfc\u81f4\u4ea7\u751f\u7684\u5b50\u5f39\u5a01\u529b\u964d\u4f4e\u3002 \u5c31\u53ef\u4ee5\u7ed9\u67aa\u52a0\u4e00\u4e2a isWet \u53c2\u6570\uff0c\u7ed9\u5b50\u5f39\u52a0\u4e00\u4e2a damage \u53c2\u6570\uff0c\u8ba9 AK47 \u751f\u6210\u5b50\u5f39\u7684\u65f6\u5019\uff0c\u6839\u636e isWet \u4e3a\u5b50\u5f39\u6784\u9020\u51fd\u6570\u8bbe\u7f6e\u4e0d\u540c\u7684 damage\u3002 struct AK47Bullet { int damage; AK47Bullet(int damage) : damage(damage) {} void explode() { printf(\"\u9020\u6210 %d \u70b9\u7269\u7406\u4f24\u5bb3\\n\", damage); } }; struct AK47Gun : Gun { bool isWet; AK47Gun(bool isWet) : isWet(isWet) {} Bullet *shoot() override { if (isWet) return new AK47Bullet(5); // \u53d7\u6f6e\u4e86\uff0c\u4f24\u5bb3\u964d\u4f4e\u4e3a 5 else return new AK47Bullet(10); // \u6b63\u5e38\u60c5\u51b5\u4e0b\u4f24\u5bb3\u4e3a 10 } }; \u6211\u4eec\u8fd8\u53ef\u4ee5\u5229\u7528\u6a21\u677f\u81ea\u52a8\u4e3a\u4e0d\u540c\u7684\u5b50\u5f39\u7c7b\u578b\u6279\u91cf\u5b9a\u4e49\u5de5\u5382\uff1a template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); } } player(new GunWithBullet()); player(new GunWithBullet()); \u8fd9\u6837\u5c31\u4e0d\u5fc5\u6bcf\u6b21\u6dfb\u52a0\u65b0\u5b50\u5f39\u7c7b\u578b\u65f6\uff0c\u90fd\u5f97\u65b0\u5efa\u4e00\u4e2a\u76f8\u5e94\u7684\u67aa\u7c7b\u578b\u4e86\uff0c\u8fdb\u4e00\u6b65\u907f\u514d\u4e86\u4ee3\u7801\u91cd\u590d\u3002\u53ef\u89c1\u6a21\u677f\u5143\u7f16\u7a0b\u5b8c\u5168\u53ef\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u5f3a\u5f3a\u8054\u624b\u3002","title":"\u5de5\u5382\u6a21\u5f0f"},{"location":"design_virtual/#_8","text":"Gun *getGun(string name) { if (name == \"AK47\") { return new GunWithBullet(); } else if (name == \"Magic\") { return new GunWithBullet(); } else { throw runtime_error(\"\u6ca1\u6709\u8fd9\u79cd\u67aa\"); } } player(getGun(\"AK47\")); player(getGun(\"Magic\"));","title":"\u8d85\u7ea7\u5de5\u5382\u6a21\u5f0f"},{"location":"design_virtual/#raii","text":"template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); Bullet *shoot() override { return new B(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { Bullet *bullet = gun->shoot(); bullet->explode(); delete bullet; // \u521a\u624d\u6ca1\u6709 delete\uff01\u4f1a\u4ea7\u751f\u5185\u5b58\u6cc4\u6f0f\uff01 } } player(new GunWithBullet()); player(new GunWithBullet()); \u73b0\u5728\u7684\u5de5\u5382\u4e00\u822c\u90fd\u4f1a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u5177\u4f53\u6765\u8bf4\u5c31\u662f\u7528 unique_ptr \u4ee3\u66ff T * \uff0c\u7528 make_unique(xxx) \u4ee3\u66ff new T(xxx) \u3002 template struct GunWithBullet : Gun { static_assert(is_base_of::value, \"B \u5fc5\u987b\u662f Bullet \u7684\u5b50\u7c7b\"); unique_ptr shoot() override { return make_unique(); } }; void player(Gun *gun) { for (int i = 0; i < 100; i++) { auto bullet = gun->shoot(); bullet->explode(); // unique_ptr \u5728\u9000\u51fa\u5f53\u524d {} \u65f6\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u4e0d\u7528\u4f60\u60e6\u8bb0\u7740\u4e86 } } player(make_unique>().get()); player(make_unique>().get()); \u8fd9\u91cc C++ \u6807\u51c6\u4fdd\u8bc1\u4e86 unique_ptr \u7684\u751f\u547d\u5468\u671f\u662f\u8fd9\u4e00\u6574\u884c\uff08; \u7ed3\u675f\u524d\uff09\uff0c\u6574\u4e2a player \u6267\u884c\u671f\u95f4\u90fd\u6d3b\u7740\uff0c\u4e0d\u4f1a\u63d0\u524d\u91ca\u653e \u6b63\u5982 func(string().c_str()) \u4e0d\u4f1a\u6709\u4efb\u4f55\u95ee\u9898\uff0cstring \u8981\u5230 func \u8fd4\u56de\u540e\u624d\u91ca\u653e\u5462\uff01 \u53ea\u8981\u628a\u6240\u6709 make_unique \u770b\u4f5c new T \uff0c\u628a\u6240\u6709\u7684 unique_ptr \u770b\u4f5c T * \uff0c\u7528\u6cd5\u51e0\u4e4e\u4e00\u6837\uff0c\u4f46\u6ca1\u6709\u5185\u5b58\u6cc4\u6f0f\uff0c\u65e0\u9700\u624b\u52a8 delete\u3002","title":"RAII \u81ea\u52a8\u7ba1\u7406\u5185\u5b58"},{"location":"design_virtual/#_9","text":"\u56de\u5230\u6570\u7ec4\u6c42\u548c\u95ee\u9898\u3002 int sum(vector v) { int res = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; } return res; } int product(vector v) { int res = 1; for (int i = 0; i < v.size(); i++) { res = res * v[i]; } return res; } int average(vector v) { int res = 0; int count = 0; for (int i = 0; i < v.size(); i++) { res = res + v[i]; count = count + 1; } return res / count; } \u6211\u4eec\u60f3\u8981\u52a0\u4e00\u4e2a\u6c42\u5e73\u5747\u503c\u7684\u51fd\u6570 average\uff0c\u8fd9\u8be5\u5982\u4f55\u4e0e sum \u5408\u8d77\u6765\uff1f \u6ce8\u610f\u56e0\u4e3a\u6211\u4eec\u8981\u652f\u6301\u4ece CinInputer \u8bfb\u5165\u6570\u636e\uff0c\u5e76\u4e0d\u4e00\u5b9a\u50cf\u4e00\u6837 VectorInputer \u80fd\u591f\u63d0\u524d\u5f97\u5230\u6570\u7ec4\u5927\u5c0f\uff0c\u4e0d\u7136\u4e5f\u4e0d\u9700\u8981 count \u4e86\u3002 int reduce(vector v) { int res = ???; // sum \u65f6\u8fd9\u91cc\u662f 0\uff0cproduct \u65f6\u8fd9\u91cc\u662f 1 int count? = ???; // sum \u548c product \u7528\u4e0d\u5230\u8be5\u53d8\u91cf\uff0c\u53ea\u6709 average \u9700\u8981 for (int i = 0; i < v.size(); i++) { res = res ??? v[i]; // sum \u65f6\u8fd9\u91cc\u662f +\uff0cproduct \u65f6\u8fd9\u91cc\u662f * count? = count? ???; // average \u65f6\u8fd9\u91cc\u8fd8\u9700\u8981\u989d\u5916\u4fee\u6539 count \u53d8\u91cf\uff01 } return res; } \u770b\u6765\u6211\u4eec\u9700\u8981\u5141\u8bb8 Reducer \u7684 init() \u8fd4\u56de \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d\uff01 \u4ee5\u524d\u7684\u8bbe\u8ba1\u8ba9 init() \u53ea\u80fd\u8fd4\u56de\u5355\u4e2a int \u662f\u4e2a\u9519\u8bef\u7684\u51b3\u5b9a\u3002 \u8fd9\u65f6\u5019\u5c31\u53ef\u4ee5\u628a \u201c\u4efb\u610f\u6570\u91cf\u7684\u72b6\u6001\u53d8\u91cf\u201d \u5c01\u88c5\u6210\u4e00\u4e2a\u65b0\u7684\u7c7b\u3002 \u7136\u540e\u6539\u4e3a\u7531\u8fd9\u4e2a\u7c7b\u8d1f\u8d23\u63d0\u4f9b\u865a\u51fd\u6570 add()\u3002 \u4e14\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u53f3\u4fa7\u53c2\u6570\u4e86\uff0c\u5de6\u4fa7\u7684 res \u53d8\u91cf\u5df2\u7ecf\u5b58\u5728 ReducerState \u4f53\u5185\u4e86\u3002 struct ReducerState { virtual void add(int val) = 0; virtual int result() = 0; }; struct Reducer { virtual unique_ptr init() = 0; }; struct SumReducerState : ReducerState { int res; SumReducerState() : res(0) {} void add(int val) override { res = res + val; } int result() override { return res; } }; struct ProductReducerState : ReducerState { int res; ProductReducerState() : res(1) {} void add(int val) override { res = res * val; } int result() override { return res; } }; struct AverageReducerState : ReducerState { int res; int count; AverageReducerState() : res(0), count(0) {} void add(int val) override { res = res + val; count = count + 1; } int result() override { return res / count; } }; struct SumReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct ProductReducer : Reducer { unique_ptr init() override { return make_unique(); } }; struct AverageReducer : Reducer { unique_ptr init() override { return make_unique(); } }; \u8fd9\u91cc Reducer \u5c31\u6210\u4e86 ReducerState \u7684\u5de5\u5382\u3002 int reduce(Inputer *inputer, Reducer *reducer) { unique_ptr state = reducer->init(); while (auto val = inputer->fetch()) { state->add(val); } return state->result(); } int main() { vector v; reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); reduce(make_unique(v).get(), make_unique().get()); } \u73b0\u5728\uff0c\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u4ed6\u60f3\u8981 \u5e76\u884c \u7684 sum \u548c product \u51fd\u6570\uff01 \u5e76\u884c\u7248\u9700\u8981\u521b\u5efa\u5f88\u591a\u4e2a\u4efb\u52a1\uff0c\u6bcf\u4e2a\u4efb\u52a1\u9700\u8981\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u4e2d\u95f4\u7ed3\u679c\u53d8\u91cf\uff0c\u6700\u540e\u7684\u7ed3\u679c\u8ba1\u7b97\u53c8\u9700\u8981\u4e00\u4e2a\u4e2d\u95f4\u53d8\u91cf\u3002 \u8fd8\u597d\u4f60\u65e9\u5df2\u63d0\u524d\u91c7\u7528\u5de5\u5382\u6a21\u5f0f\uff0c\u5141\u8bb8\u51fd\u6570\u4f53\u5185\u591a\u6b21\u521b\u5efa ReducerState \u5bf9\u8c61\u3002 int reduce(Inputer *inputer, Reducer *reducer) { tbb::task_group g; list> local_states; vector chunk; auto enqueue_chunk = [&]() { local_chunks.emplace_back(); g.run([chunk = move(chunk), &back = local_chunks.back()]() { auto local_state = reducer->init(); for (auto &&c: chunk) { local_state->add(c); } back = move(local_state); // list \u4fdd\u8bc1\u5df2\u7ecf\u63d2\u5165\u5143\u7d20\u7684\u5f15\u7528\u4e0d\u4f1a\u5931\u6548\uff0c\u6240\u4ee5\u53ef\u4ee5\u6682\u5b58 back \u5f15\u7528 }); chunk.clear(); }; while (auto tmp = inputer->fetch()) { if (chunk.size() < 64) { // \u8fd8\u6ca1\u586b\u6ee1 64 \u4e2a chunk.push_back(tmp); } else { // \u586b\u6ee1\u4e86 64 \u4e2a\uff0c\u53ef\u4ee5\u63d0\u4ea4\u6210\u4e00\u4e2a\u5355\u72ec\u4efb\u52a1\u4e86 enqueue_chunk(); } } if (chunk.size() > 0) { enqueue_chunk(); // \u63d0\u4ea4\u4e0d\u8db3 64 \u4e2a\u7684\u6b8b\u4f59\u9879 } g.wait(); auto final_state = reducer->init(); for (auto &&local_state: local_states) { res = final_state->add(local_state->result()); } return final_state->result(); } \u53ea\u9700\u8981\u628a reducer \u53c2\u6570\u66ff\u6362\u4e3a MinReducer\u3001AverageReducer\u2026\u2026\u5c31\u81ea\u52a8\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u8ba1\u7b97\u4efb\u52a1\uff0c\u800c\u4e0d\u7528\u4e3a\u4ed6\u4eec\u6bcf\u4e2a\u5355\u72ec\u7f16\u5199\u5e76\u884c\u7248\u672c\u7684\u4ee3\u7801\u3002 \u8bfe\u540e\u4f5c\u4e1a\uff1a\u4f7f\u7528\u6a21\u677f\u6279\u91cf\u5b9a\u4e49\u6240\u6709\u7684 Reducer\uff01\u4f8b\u5982\uff1a using MinReducer = ReducerWithState; ...","title":"\u5de5\u5382\u6a21\u5f0f\u5b9e\u6218"},{"location":"design_virtual/#_10","text":"\u5728\u4e8c\u7ef4\u6e38\u620f\u5f00\u53d1\u4e2d\uff0c\u5e38\u5e38\u4f1a\u63d0\u5230\u4e00\u79cd\u79f0\u4e3a Sprite\uff08\u7cbe\u7075\u8d34\u56fe\uff09\u7684\u9ed1\u8bdd\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u6bcf\u4e2a\u5bf9\u8c61\u81ea\u5df1\u6709\u4e00\u5f20\u8d34\u56fe\uff0c\u8d34\u56fe\u8ddf\u7740\u7269\u4f53\u7684\u4f4d\u7f6e\u8d70\u3002 struct Bullet { glm::vec3 position; glm::vec3 velocity; vector texture; void draw() { glDrawPixels(position, texture); } }; texture \u91cc\u9762\u5b58\u50a8\u7740\u8d34\u56fe\u7684 RGB \u6570\u636e\uff0c\u4ed6\u76f4\u63a5\u5c31\u662f Bullet \u7684\u6210\u5458\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u6253\u51fa\u4e86 100 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 100 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u5982\u679c\u6211\u4eec\u7684\u73a9\u5bb6\u540c\u65f6\u6253\u51fa\u4e86 1000 \u9897\u5b50\u5f39\uff0c\u5c31\u9700\u8981\u5b58\u50a8 1000 \u4e2a\u8d34\u56fe\u6570\u7ec4\u3002 \u8fd9\u6837\u7684\u8bdd\uff0c\u5185\u5b58\u6d88\u8017\u5c06\u4f1a\u975e\u5e38\u5927\u3002\u7136\u800c\u6240\u6709\u540c\u7c7b\u578b\u7684 Bullet\uff0c\u5176\u8d34\u56fe\u6570\u7ec4\u5176\u5b9e\u662f\u5b8c\u5168\u76f8\u540c\u7684\uff0c\u5b8c\u5168\u6ca1\u5fc5\u8981\u5404\u81ea\u5b58\u90a3\u4e48\u591a\u4efd\u62f7\u8d1d\u3002 \u4e3a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 \u4eab\u5143\u6a21\u5f0f \uff1a\u5171\u4eab\u591a\u4e2a\u5bf9\u8c61\u4e4b\u95f4 \u76f8\u540c \u7684\u90e8\u5206\uff0c\u8282\u7701\u5185\u5b58\u5f00\u9500\u3002 \u8fd9\u91cc\u6bcf\u9897\u5b50\u5f39\u7684 position\u3001velocity \u663e\u7136\u90fd\u662f\u5404\u6709\u4e0d\u540c\u7684\uff0c\u4e0d\u53ef\u80fd\u6240\u6709\u5b50\u5f39\u90fd\u5728\u540c\u4e00\u4e2a\u4f4d\u7f6e\u4e0a\u3002 \u4f46\u662f\u5f88\u591a\u5b50\u5f39\u90fd\u4f1a\u6709\u7740\u76f8\u540c\u7684\u8d34\u56fe\uff0c\u53ea\u6709\u4e0d\u540c\u7c7b\u578b\u7684\u5b50\u5f39\u8d34\u56fe\u4f1a\u4e0d\u4e00\u6837\u3002 \u6bd4\u5982\u706b\u7130\u5f39\u548c\u5bd2\u51b0\u5f39\u4f1a\u6709\u4e0d\u540c\u7684\u8d34\u56fe\uff0c\u4f46\u662f\u5f53\u573a\u4e0a\u51fa\u73b0 100 \u9897\u706b\u7130\u5f39\u65f6\uff0c\u663e\u7136\u4e0d\u9700\u8981\u62f7\u8d1d 100 \u4efd\u5b8c\u5168\u76f8\u540c\u7684\u706b\u7130\u5f39\u8d34\u56fe\u3002 struct Sprite { // Sprite \u624d\u662f\u771f\u6b63\u6301\u6709\uff08\u5f88\u5927\u7684\uff09\u8d34\u56fe\u6570\u636e\u7684 vector texture; void draw(glm::vec3 position) { glDrawPixels(position, texture); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // \u5141\u8bb8\u591a\u4e2a\u5b50\u5f39\u5bf9\u8c61\u5171\u4eab\u540c\u4e00\u4e2a\u7cbe\u7075\u8d34\u56fe\u7684\u6240\u6709\u6743 void draw() { sprite->draw(position); // \u8f6c\u53d1\u7ed9 Sprite \u8ba9\u4ed6\u5e2e\u5fd9\u5728\u6211\u7684\u4f4d\u7f6e\u7ed8\u5236\u8d34\u56fe } }; \u9700\u8981\u7ed8\u5236\u5b50\u5f39\u65f6\uff0cBullet \u7684 draw \u53ea\u662f\u7b80\u5355\u5730\u8f6c\u53d1\u7ed9 Sprite \u7c7b\u7684 draw\u3002 \u53ea\u8981\u544a\u8bc9 Sprite \u5b50\u5f39\u7684\u4f4d\u7f6e\u5c31\u884c\uff0c\u8d34\u56fe\u6570\u636e\u5df2\u7ecf\u5b58\u5728 Sprite \u5185\u90e8\uff0c\u8ba9\u4ed6\u6765\u8d1f\u8d23\u771f\u6b63\u7ed8\u5236\u3002 Bullet \u7c7b\u53ea\u9700\u8981\u4e13\u6ce8\u4e8e\u4f4d\u7f6e\u3001\u901f\u5ea6\u7684\u66f4\u65b0\u5373\u53ef\uff0c\u4e0d\u5fc5\u53bb\u64cd\u5fc3\u7740\u8d34\u56fe\u7ed8\u5236\u7684\u7ec6\u8282\uff0c\u5b9e\u73b0\u4e86\u89e3\u8026\u3002 \u8fd9\u79cd\u51fd\u6570\u8c03\u7528\u7684\u8f6c\u53d1\u4e5f\u88ab\u79f0\u4e3a \u4ee3\u7406\u6a21\u5f0f \u3002","title":"\u4eab\u5143\u6a21\u5f0f"},{"location":"design_virtual/#_11","text":"\u8fd9\u6837\u8fd8\u6709\u4e00\u4e2a\u597d\u5904\u90a3\u5c31\u662f\uff0cSprite \u53ef\u4ee5\u8bbe\u8ba1\u6210\u4e00\u4e2a\u865a\u51fd\u6570\u63a5\u53e3\u7c7b\uff1a struct Sprite { virtual void draw(glm::vec3 position) = 0; }; struct FireSprite : Sprite { vector fireTexture; FireSprite() : fireTexture(loadTexture(\"fire.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, fireTexture); } }; struct IceSprite : Sprite { // \u5047\u5982\u5bd2\u51b0\u5f39\u9700\u8981\u4e24\u5f20\u8d34\u56fe\uff0c\u4e5f\u6ca1\u95ee\u9898\uff01\u56e0\u4e3a\u865a\u63a5\u53e3\u7c7b\u5141\u8bb8\u5b50\u7c7b\u6709\u4e0d\u540c\u7684\u6210\u5458\uff0c\u4e0d\u540c\u7684\u7ed3\u6784\u4f53\u5927\u5c0f vector iceTexture1; vector iceTexture2; IceSprite() : iceTexture1(loadTexture(\"ice1.jpg\")) , iceTexture2(loadTexture(\"ice2.jpg\")) {} void draw(glm::vec3 position) override { glDrawPixels(position, iceTexture1); glDrawPixels(position, iceTexture2); } }; struct Bullet { glm::vec3 position; glm::vec3 velocity; shared_ptr sprite; // Sprite \u8d1f\u8d23\u542b\u6709\u865a\u51fd\u6570 void draw() { // Bullet \u7684 draw \u5c31\u4e0d\u7528\u662f\u865a\u51fd\u6570\u4e86\uff01 sprite->draw(position); } };","title":"\u4ee3\u7406\u6a21\u5f0f"},{"location":"design_virtual/#_12","text":"","title":"\u7ec4\u4ef6\u6a21\u5f0f"},{"location":"design_virtual/#_13","text":"","title":"\u865a\u51fd\u6570\u5e38\u89c1\u95ee\u9898\u8fa8\u6790"},{"location":"design_virtual/#bool","text":"","title":"\u8fd4\u56de bool \u7684\u865a\u51fd\u6570"},{"location":"design_virtual/#_14","text":"\u4f60\u62ff\u5230\u4e86\u4e00\u4e2a\u5927\u5b66\u751f\u8ba1\u7b97\u5668\u7684\u5927\u4f5c\u4e1a\uff1a int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; if (c == '+') { cout << a + b; } else if (c == '-') { cout << a - b; } else if (c == '*') { cout << a * b; } else if (c == '/') { cout << a / b; } else { cout << \"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"; } } \u4f60\u5f00\u59cb\u7528\u7b56\u7565\u6a21\u5f0f\u6539\u9020\u5b83\uff1a struct Calculator { virtual int calculate(int a, int b) = 0; }; struct AddCalculator : Calculator { int calculate(int a, int b) override { return a + b; } }; struct SubCalculator : Calculator { int calculate(int a, int b) override { return a - b; } }; struct MulCalculator : Calculator { int calculate(int a, int b) override { return a * b; } }; struct DivCalculator : Calculator { int calculate(int a, int b) override { return a / b; } }; Calculator *getCalculator(char c) { if (c == '+') { calculator = new AddCalculator(); } else if (c == '-') { calculator = new SubCalculator(); } else if (c == '*') { calculator = new MulCalculator(); } else if (c == '/') { calculator = new DivCalculator(); } else { throw runtime_error(\"\u4e0d\u652f\u6301\u7684\u8fd0\u7b97\u7b26\"); } }; int main() { char c; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e00\u4e2a\u6570\uff1a\"; cin >> a; cout << \"\u8bf7\u8f93\u5165\u7b2c\u4e8c\u4e2a\u6570\uff1a\"; cin >> b; cout << \"\u8bf7\u8f93\u5165\u8fd0\u7b97\u7b26\uff1a\"; cin >> c; Calculator *calculator = getCalculator(c); cout << calculator->calculate(a, b); }","title":"\u8bfe\u540e\u4f5c\u4e1a"},{"location":"donate/","text":"\u8d5e\u52a9\u540d\u5355 \u5c0f\u5f6d\u5927\u5178\u7684\u6301\u7eed\u7f16\u5199\u79bb\u4e0d\u5f00\u4ee5\u4e0b\u5c0f\u5f6d\u53cb\u7684\u8d5e\u52a9\uff01 \u5c0f\u5f6d\u8001\u5e08\u7684\u5927\u5178\u662f\u514d\u8d39\u4e0b\u8f7d\u7684\uff0c\u4e0d\u7528\u8d5e\u52a9\u4e5f\u53ef\u4ee5\u67e5\u770b\u54e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u906d\u5230 \u201c\u767d\u773c\u72fc\u201d\u8111\u677f \u5f00\u9664\uff0c\u76ee\u524d\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\u3002\u53ea\u597d\u5bfb\u6c42\u5404\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9\uff0c\u4fdd\u969c\u5c0f\u5f6d\u8001\u5e08\u7684\u57fa\u672c\u751f\u547d\u4f53\u5f81\u8fd0\u884c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9886\u8854\u5f00\u53d1\u7684 Zeno \u8f6f\u4ef6\uff0c\u66fe\u53c2\u4e0e \u6d41\u91cf\u5730\u7403 2 \u3001\u676d\u5dde\u4e9a\u8fd0\u4f1a\u7b49\u5927\u578b\u9879\u76ee\u7684\u7279\u6548\u5236\u4f5c\uff0c\u9b45\u60d1\u65e0\u6570\u897f\u88c5\u5927\u8111\u6295\u8d44\u4eba\uff0c\u4e3a\u201c\u767d\u773c\u72fc\u201d\u535a\u5f97\u98ce\u5149\u65e0\u9650\u3002\u73b0\u5728\u5374\u5c06\u5982\u6b64\u8d21\u732e\u5de8\u5927\u7684 Zeno \u201c\u5f00\u56fd\u529f\u52cb\u201d\uff0c\u4ee5\u201c\u8d44\u91d1\u56f0\u96be\u201d\u4e3a\u7531\u201c\u5378\u8f7d\u201d\u4e86\uff0c\u8db3\u4ee5\u89c1\u8fd9\u4f4d\u201c\u767d\u773c\u72fc\u201d\u7684\u201c\u77e5\u6069\u56fe\u62a5\u201d\u3002 \u5982\u679c\u4f60\u89c9\u5f97\u672c\u4e66\u5bf9\u4f60\u6709\u6240\u5e2e\u52a9\uff0c\u53ef\u4ee5\u901a\u8fc7 \u7231\u53d1\u7535 \u8d5e\u52a9\u5c0f\u5f6d\u8001\u5e08\uff0c\u4ee5\u4fbf\u5c0f\u5f6d\u8001\u5e08\u6709\u66f4\u591a\u7684\u7cbe\u529b\u7ee7\u7eed\u7f16\u5199\u548c\u7ef4\u62a4\u672c\u4e66\u3002 \u6bcf\u6709\u4e00\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9 26.90 \uff0c\u5c0f\u5f6d\u8001\u5e08\u4e00\u5929\u7684\u98df\u54c1\u5b89\u5168\u5c31\u6709\u4e86\u7740\u843d\u3002 \u6551\u547d\u2026\u2026\u7231\u53d1\u7535\u4f3c\u4e4e\u5173\u505c\u4e86\uff01\uff1f\u5c0f\u5f6d\u8001\u5e08\u8d76\u7d27\u8d34\u51fa\u652f\u4ed8\u5b9d\u6536\u6b3e\u7801\u4f5c\u4e3a\u66ff\u4ee3\u2026\u2026 \u5982\u679c\u4f60\u4e5f\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\uff0c\u5c31\u4e0d\u7528\u52c9\u5f3a\u8d5e\u52a9\u4e86\u2026\u2026\u4e5f\u53ef\u4ee5\u5148\u7ed9\u5c0f\u5f6d\u8001\u5e08\u70b9\u4e00\u9897 \u2b50Star\u2b50 \u8868\u793a\u5fc3\u610f\u3002","title":"\u8d5e\u52a9\u540d\u5355"},{"location":"donate/#_1","text":"\u5c0f\u5f6d\u5927\u5178\u7684\u6301\u7eed\u7f16\u5199\u79bb\u4e0d\u5f00\u4ee5\u4e0b\u5c0f\u5f6d\u53cb\u7684\u8d5e\u52a9\uff01 \u5c0f\u5f6d\u8001\u5e08\u7684\u5927\u5178\u662f\u514d\u8d39\u4e0b\u8f7d\u7684\uff0c\u4e0d\u7528\u8d5e\u52a9\u4e5f\u53ef\u4ee5\u67e5\u770b\u54e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u906d\u5230 \u201c\u767d\u773c\u72fc\u201d\u8111\u677f \u5f00\u9664\uff0c\u76ee\u524d\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\u3002\u53ea\u597d\u5bfb\u6c42\u5404\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9\uff0c\u4fdd\u969c\u5c0f\u5f6d\u8001\u5e08\u7684\u57fa\u672c\u751f\u547d\u4f53\u5f81\u8fd0\u884c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9886\u8854\u5f00\u53d1\u7684 Zeno \u8f6f\u4ef6\uff0c\u66fe\u53c2\u4e0e \u6d41\u91cf\u5730\u7403 2 \u3001\u676d\u5dde\u4e9a\u8fd0\u4f1a\u7b49\u5927\u578b\u9879\u76ee\u7684\u7279\u6548\u5236\u4f5c\uff0c\u9b45\u60d1\u65e0\u6570\u897f\u88c5\u5927\u8111\u6295\u8d44\u4eba\uff0c\u4e3a\u201c\u767d\u773c\u72fc\u201d\u535a\u5f97\u98ce\u5149\u65e0\u9650\u3002\u73b0\u5728\u5374\u5c06\u5982\u6b64\u8d21\u732e\u5de8\u5927\u7684 Zeno \u201c\u5f00\u56fd\u529f\u52cb\u201d\uff0c\u4ee5\u201c\u8d44\u91d1\u56f0\u96be\u201d\u4e3a\u7531\u201c\u5378\u8f7d\u201d\u4e86\uff0c\u8db3\u4ee5\u89c1\u8fd9\u4f4d\u201c\u767d\u773c\u72fc\u201d\u7684\u201c\u77e5\u6069\u56fe\u62a5\u201d\u3002 \u5982\u679c\u4f60\u89c9\u5f97\u672c\u4e66\u5bf9\u4f60\u6709\u6240\u5e2e\u52a9\uff0c\u53ef\u4ee5\u901a\u8fc7 \u7231\u53d1\u7535 \u8d5e\u52a9\u5c0f\u5f6d\u8001\u5e08\uff0c\u4ee5\u4fbf\u5c0f\u5f6d\u8001\u5e08\u6709\u66f4\u591a\u7684\u7cbe\u529b\u7ee7\u7eed\u7f16\u5199\u548c\u7ef4\u62a4\u672c\u4e66\u3002 \u6bcf\u6709\u4e00\u4f4d\u5c0f\u5f6d\u53cb\u8d5e\u52a9 26.90 \uff0c\u5c0f\u5f6d\u8001\u5e08\u4e00\u5929\u7684\u98df\u54c1\u5b89\u5168\u5c31\u6709\u4e86\u7740\u843d\u3002 \u6551\u547d\u2026\u2026\u7231\u53d1\u7535\u4f3c\u4e4e\u5173\u505c\u4e86\uff01\uff1f\u5c0f\u5f6d\u8001\u5e08\u8d76\u7d27\u8d34\u51fa\u652f\u4ed8\u5b9d\u6536\u6b3e\u7801\u4f5c\u4e3a\u66ff\u4ee3\u2026\u2026 \u5982\u679c\u4f60\u4e5f\u5904\u4e8e\u5931\u4e1a\u72b6\u6001\uff0c\u5c31\u4e0d\u7528\u52c9\u5f3a\u8d5e\u52a9\u4e86\u2026\u2026\u4e5f\u53ef\u4ee5\u5148\u7ed9\u5c0f\u5f6d\u8001\u5e08\u70b9\u4e00\u9897 \u2b50Star\u2b50 \u8868\u793a\u5fc3\u610f\u3002","title":"\u8d5e\u52a9\u540d\u5355"},{"location":"error_code/","text":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u914d\u5957\u89c6\u9891\uff1a BV1QpWSekEJY \u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u9519\u8bef\u7684\u5206\u7c7b \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u53ef\u6062\u590d\u9519\u8bef \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected \u9519\u8bef\u7684\u5206\u7c7b \u5047\u8bbe\u4e00\u4e2a\u51fd\u6570 open \u7684\u529f\u80fd\u662f\u6253\u5f00\u6587\u4ef6\u3002 int open(const char *path) { if (!file_exists(path)) { // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\u600e\u4e48\u529e\uff1f } // \u6210\u529f\u627e\u5230\u6587\u4ef6\uff1a return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u51fd\u6570\u90fd\u80fd\u6210\u529f\u6267\u884c\uff0c\u90fd\u80fd\u6b63\u5e38\u8fd4\u56de\u7ed3\u679c\u2026\u2026 \u53ef\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u8bbe\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u6c38\u8fdc\u6b63\u786e\u6267\u884c\uff08\u4f8b\u5982\u6587\u4ef6\u53ef\u80fd\u88ab\u7528\u6237\u8bef\u5220\u9664\uff0c\u6216\u8005\u5185\u5b58\u4e0d\u591f\u7528\u7b49\uff09\u3002 \u66f4\u6709\u751a\u8005\uff0c\u6709\u65f6\u9519\u8bef\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff08\u4f8b\u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u4e00\u4e2a\u65b0\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5c06\u5176\u89c6\u4e3a\u4e0d\u53ef\u4fee\u590d\u7684\u9519\u8bef\uff09\u3002 \u7279\u522b\u662f\u6d89\u53ca IO \u64cd\u4f5c\u7684\u4efb\u52a1\uff0c\u51fa\u73b0\u4e00\u4e9b\u7ec6\u5c0f\u9519\u8bef\u7684\u60c5\u51b5\u662f\u5f88\u591a\u7684\u3002\u8981\u533a\u5206\u54ea\u4e9b\u662f\u53ef\u4ee5\u4fee\u590d\u7684\u9519\u8bef\uff0c\u54ea\u4e9b\u662f\u4e0d\u53ef\u633d\u56de\u7684\u9519\u8bef\u3002 \u4f8b\u5982\u5f53\u7f51\u7edc\u8fde\u63a5\u5931\u8d25\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u5c1d\u8bd5\u8fde\u63a5\u4e24\u4e09\u6b21\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u884c\uff0c\u90a3\u624d\u8ba4\u4e3a\u662f\u771f\u7684\u5931\u8d25\u4e86\u3002 \u56e0\u6b64\uff0c\u6211\u4eec\u628a\u9519\u8bef\u5206\u4e3a\u4e24\u5927\u7c7b\uff1a \u53ef\u6062\u590d\u9519\u8bef\uff1a\u4e0d\u662f\u7279\u522b\u4e25\u91cd\u7684\uff0c\u751a\u81f3\u662f\u8ba1\u5212\u4e4b\u4e2d\u7684\uff0c\u7ecf\u5e38\u53d1\u751f\u7684\u9519\u8bef\u3002\u53ef\u4ee5\u901a\u8fc7\u4e00\u5b9a\u64cd\u4f5c\u6765\u5f25\u8865\u8fd9\u7c7b\u9519\u8bef\uff0c\u6216\u5c06\u5176\u8f6c\u5316\u4e3a\u5176\u4ed6\u4e0d\u540c\u7c7b\u578b\u7684\u9519\u8bef\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef\uff1a\u975e\u5e38\u4e25\u91cd\u7684\u9519\u8bef\uff0c\u6216\u8005\u662f\u53d1\u751f\u6982\u7387\u5f88\u4f4e\u5e73\u65f6\u6ca1\u5fc5\u8981\u7279\u6b8a\u5904\u7406\u7684\u9519\u8bef\u3002\u4e00\u65e6\u53d1\u751f\uff0c\u6574\u4e2a\u7a0b\u5e8f\u90fd\u65e0\u6cd5\u7ee7\u7eed\u6267\u884c\u4e0b\u53bb\uff0c\u5fc5\u987b\u5168\u8eab\u800c\u9000\uff0c\u6574\u4e2a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u90fd\u5c06\u7ec8\u6b62\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u4e0d\u53ef\u6062\u590d\u9519\u8bef\u7684\u5904\u7406\u6700\u7b80\u5355\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u88ab\u8c03\u7528\u8005\u68c0\u6d4b\u5230\u9519\u8bef\u7684\u5206\u652f\u4e2d\uff0c\u76f4\u63a5\u8c03\u7528 exit \u51fd\u6570\u201c\u7ec8\u6b62\u7a0b\u5e8f\u201d\u5373\u53ef\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\u6211\u5c31\u81ea\u6740\uff01 exit(1); // \u7a0b\u5e8f\u4e0d\u4f1a\u6267\u884c\u5230\u6b64 } return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7f3a\u70b9\uff1a exit \u4f1a\u76f4\u63a5\u9000\u51fa\u6574\u4e2a\u8fdb\u7a0b\uff01\u6ca1\u6709\u4efb\u4f55\u7ed9\u8c03\u7528\u8005\u633d\u56de\u7684\u673a\u4f1a\uff0c\u56e0\u6b64\u53ea\u80fd\u7528\u4e8e\u201c\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u201d\u8fd9\u4e2a\u7c7b\u578b\u3002 \u4f18\u70b9\uff1a\u8c03\u7528\u8005\u65e0\u9700\u505a\u4efb\u4f55\u5224\u65ad\u5904\u7406\uff0c\u5199\u8d77\u6765\u5c31\u597d\u50cf\u88ab\u8c03\u7528\u51fd\u6570\u201c\u603b\u662f\u6210\u529f\u201d\u4e00\u6837\uff0c\u603b\u80fd\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u4e3a\u5982\u679c\u88ab\u8c03\u7528\u8005\u5931\u8d25\u7684\u8bdd\uff0c\u4ed6\u4f1a\u8c03\u7528 exit \u81ea\u6740\uff0c\u5c31\u4e0d\u4f1a\u8fd4\u56de\u5230\u8c03\u7528\u8005\u4e2d\u4e86\u3002 \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6\u53d8\u6210\u201c\u7801\u7801\u7684\u8424\u706b\u866b\u201d\u4e86\u3002 \u53ef\u6062\u590d\u9519\u8bef \u6709\u65f6\u5019\uff0c\u6211\u4eec\u5bf9\u4e8e\u90e8\u5206\u9519\u8bef\uff0c\u662f\u6709\u633d\u56de\u673a\u4f1a\u7684\uff0c\u4e0d\u5e0c\u671b\u56e0\u4e3a\u4e00\u70b9\u53ef\u4ee5\u4fee\u590d\u7684\u5c0f\u9519\u8bef\u5c31\u628a\u6574\u4e2a\u7a0b\u5e8f\u7ec8\u6b62\u6389\u3002 \u8981\u4e0d\u8981\u633d\u56de\u5e94\u8be5\u7531\u8c03\u7528\u8005\u7684\u5177\u4f53\u4e1a\u52a1\u51b3\u5b9a\uff0c\u800c\u5c01\u88c5\u826f\u597d\u7684 API\uff08 open \uff09\u5e94\u8be5\u5fe0\u5b9e\u5730\u628a\u9519\u8bef\u62a5\u544a\u7ed9\u8c03\u7528\u8005\uff08 main \uff09\u3002 \u8ba9\u8c03\u7528\u8005\u6765\u51b3\u5b9a\u8981\u6740\u4e86\u8fd8\u662f\u62a2\u6551\uff0c\u800c\u4e0d\u662f\u81ea\u4f5c\u4e3b\u5f20\u5730\u76f4\u63a5\u81ea\u6740\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c31\u8fd4\u56de -1 \u8fd9\u4e2a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d\u4ee3\u66ff return -1; } return get_handle(path); } int main() { int file = open(\"file.txt\"); if (file == -1) { // \u7f3a\u70b9\u662f main \u91cc\u9762\u5fc5\u987b\u5224\u65ad\u8fd4\u56de\u503c\u662f\u5426\u4e3a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c1d\u8bd5\u8fdb\u884c\u5904\u7406 create_empty_file(\"file.txt\"); // \u91cd\u65b0\u5c1d\u8bd5\u6253\u5f00 file = open(\"file.txt\"); if (file == -1) { // \u5982\u679c\u8fd8\u662f\u51fa\u9519\uff0c\u90a3\u5c31\u6ca1\u6551\u4e86 exit(-1); // \u76f4\u63a5\u81ea\u6740 } } char buf[64]; read(file, buf, sizeof buf); ... } \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 main \u662f\u8c03\u7528\u8005\uff0c open \u662f\u88ab\u8c03\u7528\u8005\u3002 \u88ab\u8c03\u7528\u8005\u51fd\u6570\u53ef\u80fd\u4ea7\u751f\u9519\u8bef\uff0c\u4e5f\u53ef\u80fd\u6b63\u5e38\u6267\u884c\u3002 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected \u4e5f\u53ef\u4ee5 boost::expected \u66ff\u4ee3\u3002","title":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"error_code/#c","text":"\u914d\u5957\u89c6\u9891\uff1a BV1QpWSekEJY \u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09 \u9519\u8bef\u7684\u5206\u7c7b \u4e0d\u53ef\u6062\u590d\u9519\u8bef \u53ef\u6062\u590d\u9519\u8bef \u6211\u8be5\u5982\u4f55\u6289\u62e9 \u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005 \u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01 \u5f02\u5e38 \u9519\u8bef\u7801 std::error_code std::expected","title":"\u73b0\u4ee3 C++ \u9519\u8bef\u5904\u7406\u77e5\u591a\u5c11\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"error_code/#_1","text":"\u5047\u8bbe\u4e00\u4e2a\u51fd\u6570 open \u7684\u529f\u80fd\u662f\u6253\u5f00\u6587\u4ef6\u3002 int open(const char *path) { if (!file_exists(path)) { // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\u600e\u4e48\u529e\uff1f } // \u6210\u529f\u627e\u5230\u6587\u4ef6\uff1a return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7406\u60f3\u60c5\u51b5\u4e0b\uff0c\u6240\u6709\u7684\u51fd\u6570\u90fd\u80fd\u6210\u529f\u6267\u884c\uff0c\u90fd\u80fd\u6b63\u5e38\u8fd4\u56de\u7ed3\u679c\u2026\u2026 \u53ef\u73b0\u5b9e\u4e2d\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u8bbe\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u6c38\u8fdc\u6b63\u786e\u6267\u884c\uff08\u4f8b\u5982\u6587\u4ef6\u53ef\u80fd\u88ab\u7528\u6237\u8bef\u5220\u9664\uff0c\u6216\u8005\u5185\u5b58\u4e0d\u591f\u7528\u7b49\uff09\u3002 \u66f4\u6709\u751a\u8005\uff0c\u6709\u65f6\u9519\u8bef\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff08\u4f8b\u5982\u6587\u4ef6\u4e0d\u5b58\u5728\uff0c\u5219\u521b\u5efa\u4e00\u4e2a\u65b0\u6587\u4ef6\uff0c\u800c\u4e0d\u662f\u5c06\u5176\u89c6\u4e3a\u4e0d\u53ef\u4fee\u590d\u7684\u9519\u8bef\uff09\u3002 \u7279\u522b\u662f\u6d89\u53ca IO \u64cd\u4f5c\u7684\u4efb\u52a1\uff0c\u51fa\u73b0\u4e00\u4e9b\u7ec6\u5c0f\u9519\u8bef\u7684\u60c5\u51b5\u662f\u5f88\u591a\u7684\u3002\u8981\u533a\u5206\u54ea\u4e9b\u662f\u53ef\u4ee5\u4fee\u590d\u7684\u9519\u8bef\uff0c\u54ea\u4e9b\u662f\u4e0d\u53ef\u633d\u56de\u7684\u9519\u8bef\u3002 \u4f8b\u5982\u5f53\u7f51\u7edc\u8fde\u63a5\u5931\u8d25\u65f6\uff0c\u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u5c1d\u8bd5\u8fde\u63a5\u4e24\u4e09\u6b21\uff0c\u5982\u679c\u8fd8\u662f\u4e0d\u884c\uff0c\u90a3\u624d\u8ba4\u4e3a\u662f\u771f\u7684\u5931\u8d25\u4e86\u3002 \u56e0\u6b64\uff0c\u6211\u4eec\u628a\u9519\u8bef\u5206\u4e3a\u4e24\u5927\u7c7b\uff1a \u53ef\u6062\u590d\u9519\u8bef\uff1a\u4e0d\u662f\u7279\u522b\u4e25\u91cd\u7684\uff0c\u751a\u81f3\u662f\u8ba1\u5212\u4e4b\u4e2d\u7684\uff0c\u7ecf\u5e38\u53d1\u751f\u7684\u9519\u8bef\u3002\u53ef\u4ee5\u901a\u8fc7\u4e00\u5b9a\u64cd\u4f5c\u6765\u5f25\u8865\u8fd9\u7c7b\u9519\u8bef\uff0c\u6216\u5c06\u5176\u8f6c\u5316\u4e3a\u5176\u4ed6\u4e0d\u540c\u7c7b\u578b\u7684\u9519\u8bef\u3002 \u4e0d\u53ef\u6062\u590d\u9519\u8bef\uff1a\u975e\u5e38\u4e25\u91cd\u7684\u9519\u8bef\uff0c\u6216\u8005\u662f\u53d1\u751f\u6982\u7387\u5f88\u4f4e\u5e73\u65f6\u6ca1\u5fc5\u8981\u7279\u6b8a\u5904\u7406\u7684\u9519\u8bef\u3002\u4e00\u65e6\u53d1\u751f\uff0c\u6574\u4e2a\u7a0b\u5e8f\u90fd\u65e0\u6cd5\u7ee7\u7eed\u6267\u884c\u4e0b\u53bb\uff0c\u5fc5\u987b\u5168\u8eab\u800c\u9000\uff0c\u6574\u4e2a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u90fd\u5c06\u7ec8\u6b62\u3002","title":"\u9519\u8bef\u7684\u5206\u7c7b"},{"location":"error_code/#_2","text":"\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u7684\u5904\u7406\u6700\u7b80\u5355\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728\u88ab\u8c03\u7528\u8005\u68c0\u6d4b\u5230\u9519\u8bef\u7684\u5206\u652f\u4e2d\uff0c\u76f4\u63a5\u8c03\u7528 exit \u51fd\u6570\u201c\u7ec8\u6b62\u7a0b\u5e8f\u201d\u5373\u53ef\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\u6211\u5c31\u81ea\u6740\uff01 exit(1); // \u7a0b\u5e8f\u4e0d\u4f1a\u6267\u884c\u5230\u6b64 } return get_handle(path); } int main() { int file = open(\"file.txt\"); char buf[64]; read(file, buf, sizeof buf); ... } \u7f3a\u70b9\uff1a exit \u4f1a\u76f4\u63a5\u9000\u51fa\u6574\u4e2a\u8fdb\u7a0b\uff01\u6ca1\u6709\u4efb\u4f55\u7ed9\u8c03\u7528\u8005\u633d\u56de\u7684\u673a\u4f1a\uff0c\u56e0\u6b64\u53ea\u80fd\u7528\u4e8e\u201c\u4e0d\u53ef\u6062\u590d\u9519\u8bef\u201d\u8fd9\u4e2a\u7c7b\u578b\u3002 \u4f18\u70b9\uff1a\u8c03\u7528\u8005\u65e0\u9700\u505a\u4efb\u4f55\u5224\u65ad\u5904\u7406\uff0c\u5199\u8d77\u6765\u5c31\u597d\u50cf\u88ab\u8c03\u7528\u51fd\u6570\u201c\u603b\u662f\u6210\u529f\u201d\u4e00\u6837\uff0c\u603b\u80fd\u8fd4\u56de\u7ed3\u679c\u3002\u56e0\u4e3a\u5982\u679c\u88ab\u8c03\u7528\u8005\u5931\u8d25\u7684\u8bdd\uff0c\u4ed6\u4f1a\u8c03\u7528 exit \u81ea\u6740\uff0c\u5c31\u4e0d\u4f1a\u8fd4\u56de\u5230\u8c03\u7528\u8005\u4e2d\u4e86\u3002 \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6\u53d8\u6210\u201c\u7801\u7801\u7684\u8424\u706b\u866b\u201d\u4e86\u3002","title":"\u4e0d\u53ef\u6062\u590d\u9519\u8bef"},{"location":"error_code/#_3","text":"\u6709\u65f6\u5019\uff0c\u6211\u4eec\u5bf9\u4e8e\u90e8\u5206\u9519\u8bef\uff0c\u662f\u6709\u633d\u56de\u673a\u4f1a\u7684\uff0c\u4e0d\u5e0c\u671b\u56e0\u4e3a\u4e00\u70b9\u53ef\u4ee5\u4fee\u590d\u7684\u5c0f\u9519\u8bef\u5c31\u628a\u6574\u4e2a\u7a0b\u5e8f\u7ec8\u6b62\u6389\u3002 \u8981\u4e0d\u8981\u633d\u56de\u5e94\u8be5\u7531\u8c03\u7528\u8005\u7684\u5177\u4f53\u4e1a\u52a1\u51b3\u5b9a\uff0c\u800c\u5c01\u88c5\u826f\u597d\u7684 API\uff08 open \uff09\u5e94\u8be5\u5fe0\u5b9e\u5730\u628a\u9519\u8bef\u62a5\u544a\u7ed9\u8c03\u7528\u8005\uff08 main \uff09\u3002 \u8ba9\u8c03\u7528\u8005\u6765\u51b3\u5b9a\u8981\u6740\u4e86\u8fd8\u662f\u62a2\u6551\uff0c\u800c\u4e0d\u662f\u81ea\u4f5c\u4e3b\u5f20\u5730\u76f4\u63a5\u81ea\u6740\u3002 int open(const char *path) { if (!file_exists(path)) { // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c31\u8fd4\u56de -1 \u8fd9\u4e2a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d\u4ee3\u66ff return -1; } return get_handle(path); } int main() { int file = open(\"file.txt\"); if (file == -1) { // \u7f3a\u70b9\u662f main \u91cc\u9762\u5fc5\u987b\u5224\u65ad\u8fd4\u56de\u503c\u662f\u5426\u4e3a\u201c\u51fa\u9519\u7279\u6b8a\u503c\u201d // \u5982\u679c\u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5c1d\u8bd5\u8fdb\u884c\u5904\u7406 create_empty_file(\"file.txt\"); // \u91cd\u65b0\u5c1d\u8bd5\u6253\u5f00 file = open(\"file.txt\"); if (file == -1) { // \u5982\u679c\u8fd8\u662f\u51fa\u9519\uff0c\u90a3\u5c31\u6ca1\u6551\u4e86 exit(-1); // \u76f4\u63a5\u81ea\u6740 } } char buf[64]; read(file, buf, sizeof buf); ... }","title":"\u53ef\u6062\u590d\u9519\u8bef"},{"location":"error_code/#_4","text":"","title":"\u6211\u8be5\u5982\u4f55\u6289\u62e9"},{"location":"error_code/#_5","text":"main \u662f\u8c03\u7528\u8005\uff0c open \u662f\u88ab\u8c03\u7528\u8005\u3002 \u88ab\u8c03\u7528\u8005\u51fd\u6570\u53ef\u80fd\u4ea7\u751f\u9519\u8bef\uff0c\u4e5f\u53ef\u80fd\u6b63\u5e38\u6267\u884c\u3002","title":"\u8c03\u7528\u8005\u4e0e\u88ab\u8c03\u7528\u8005"},{"location":"error_code/#_6","text":"","title":"\u63d0\u524d\u8fd4\u56de\u662f\u597d\u4e60\u60ef\uff01"},{"location":"error_code/#_7","text":"","title":"\u5f02\u5e38"},{"location":"error_code/#_8","text":"","title":"\u9519\u8bef\u7801"},{"location":"error_code/#stderror_code","text":"","title":"std::error_code"},{"location":"error_code/#stdexpected","text":"\u4e5f\u53ef\u4ee5 boost::expected \u66ff\u4ee3\u3002","title":"std::expected"},{"location":"functions/","text":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u81ea\u5b9a\u4e49\u51fd\u6570 \u8c03\u7528\u51fd\u6570 \u51fd\u6570\u7684\u8fd4\u56de\u503c \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570 \u81ea\u5b9a\u4e49\u51fd\u6570 int square(int x) { } \u8c03\u7528\u51fd\u6570 TODO: println \u53c2\u6570\u6f14\u793a \u51fd\u6570\u7684\u8fd4\u56de\u503c \u51fd\u6570\u53ef\u4ee5\u6ca1\u6709\u8fd4\u56de\u503c\uff0c\u53ea\u9700\u8981\u58f0\u660e\u51fd\u6570\u65f6\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a void \u5373\u53ef\uff0c\u8c03\u7528\u8fd9\u6837\u7684\u51fd\u6570\u53ea\u662f\u4e3a\u4e86\u4ed6\u7684\u526f\u4f5c\u7528\uff08\u5982\u4fee\u6539\u5168\u5c40\u53d8\u91cf\uff0c\u8f93\u51fa\u6587\u672c\u5230\u63a7\u5236\u53f0\uff0c\u4fee\u6539\u5f15\u7528\u53c2\u6570\u7b49\uff09\u3002 void compute() { return; } \u5bf9\u4e8e\u6ca1\u6709\u8fd4\u56de\u503c\uff08\u8fd4\u56de\u7c7b\u578b\u4e3a void \uff09\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7701\u7565 return \u4e0d\u5199\u3002 void compute() { // \u6ca1\u95ee\u9898 } \u5bf9\u4e8e\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6f0f\u5199\uff0c\u4f1a\u51fa\u73b0\u53ef\u6015\u7684\u672a\u5b9a\u4e49\u884c\u4e3a (undefined behaviour)\u3002\u7f16\u8bd1\u5668\u4e0d\u4e00\u5b9a\u4f1a\u62a5\u9519\uff0c\u800c\u662f\u5230\u8fd0\u884c\u65f6\u624d\u51fa\u73b0\u5d29\u6e83\u7b49\u73b0\u8c61\u3002\u5efa\u8bae GCC \u7528\u6237\u5f00\u542f -Werror=return-type \u8ba9\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u65f6\u5c31\u68c0\u6d4b\u6b64\u7c7b\u9519\u8bef\uff0cMSVC \u5219\u662f\u5f00\u542f /we4716 \u3002\u66f4\u591a\u672a\u5b9a\u4e49\u884c\u4e3a\u53ef\u4ee5\u770b\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5217\u8868 \u7ae0\u8282\u3002 \u4f46\u6709\u4e24\u4e2a\u4f8b\u5916\uff1a1. main \u51fd\u6570\u662f\u7279\u6b8a\u7684\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u4f1a\u81ea\u52a8\u5e2e\u4f60 return 0; \u30022. \u5177\u6709 co_return \u6216 co_await \u7684\u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\u3002 \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 TODO\uff1a\u548c Python\u3001Java \u5bf9\u6bd4 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 TODO\uff1a\u66f4\u591a\u4ecb\u7ecd\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570 TODO","title":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5)"},{"location":"functions/#_1","text":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5) \u81ea\u5b9a\u4e49\u51fd\u6570 \u8c03\u7528\u51fd\u6570 \u51fd\u6570\u7684\u8fd4\u56de\u503c \u63a5\u4f4f\u8fd4\u56de\u503c \u51fd\u6570\u7684\u53c2\u6570 \u5f62\u53c2 vs \u5b9e\u53c2 \u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2 C \u98ce\u683c\u53d8\u957f\u53c2\u6570 \u6a21\u677f\u51fd\u6570 main \u51fd\u6570\u7684\u53c2\u6570","title":"\u8ba4\u8bc6\u51fd\u6570 (\u672a\u5b8c\u5de5)"},{"location":"functions/#_2","text":"int square(int x) { }","title":"\u81ea\u5b9a\u4e49\u51fd\u6570"},{"location":"functions/#_3","text":"TODO: println \u53c2\u6570\u6f14\u793a","title":"\u8c03\u7528\u51fd\u6570"},{"location":"functions/#_4","text":"\u51fd\u6570\u53ef\u4ee5\u6ca1\u6709\u8fd4\u56de\u503c\uff0c\u53ea\u9700\u8981\u58f0\u660e\u51fd\u6570\u65f6\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a void \u5373\u53ef\uff0c\u8c03\u7528\u8fd9\u6837\u7684\u51fd\u6570\u53ea\u662f\u4e3a\u4e86\u4ed6\u7684\u526f\u4f5c\u7528\uff08\u5982\u4fee\u6539\u5168\u5c40\u53d8\u91cf\uff0c\u8f93\u51fa\u6587\u672c\u5230\u63a7\u5236\u53f0\uff0c\u4fee\u6539\u5f15\u7528\u53c2\u6570\u7b49\uff09\u3002 void compute() { return; } \u5bf9\u4e8e\u6ca1\u6709\u8fd4\u56de\u503c\uff08\u8fd4\u56de\u7c7b\u578b\u4e3a void \uff09\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7701\u7565 return \u4e0d\u5199\u3002 void compute() { // \u6ca1\u95ee\u9898 } \u5bf9\u4e8e\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6f0f\u5199\uff0c\u4f1a\u51fa\u73b0\u53ef\u6015\u7684\u672a\u5b9a\u4e49\u884c\u4e3a (undefined behaviour)\u3002\u7f16\u8bd1\u5668\u4e0d\u4e00\u5b9a\u4f1a\u62a5\u9519\uff0c\u800c\u662f\u5230\u8fd0\u884c\u65f6\u624d\u51fa\u73b0\u5d29\u6e83\u7b49\u73b0\u8c61\u3002\u5efa\u8bae GCC \u7528\u6237\u5f00\u542f -Werror=return-type \u8ba9\u7f16\u8bd1\u5668\u5728\u7f16\u8bd1\u65f6\u5c31\u68c0\u6d4b\u6b64\u7c7b\u9519\u8bef\uff0cMSVC \u5219\u662f\u5f00\u542f /we4716 \u3002\u66f4\u591a\u672a\u5b9a\u4e49\u884c\u4e3a\u53ef\u4ee5\u770b\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5217\u8868 \u7ae0\u8282\u3002 \u4f46\u6709\u4e24\u4e2a\u4f8b\u5916\uff1a1. main \u51fd\u6570\u662f\u7279\u6b8a\u7684\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u4f1a\u81ea\u52a8\u5e2e\u4f60 return 0; \u30022. \u5177\u6709 co_return \u6216 co_await \u7684\u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\u3002","title":"\u51fd\u6570\u7684\u8fd4\u56de\u503c"},{"location":"functions/#_5","text":"","title":"\u63a5\u4f4f\u8fd4\u56de\u503c"},{"location":"functions/#_6","text":"","title":"\u51fd\u6570\u7684\u53c2\u6570"},{"location":"functions/#vs","text":"","title":"\u5f62\u53c2 vs \u5b9e\u53c2"},{"location":"functions/#vs_1","text":"TODO\uff1a\u548c Python\u3001Java \u5bf9\u6bd4","title":"\u6309\u5f15\u7528\u4f20\u53c2 vs \u6309\u503c\u4f20\u53c2"},{"location":"functions/#c","text":"","title":"C \u98ce\u683c\u53d8\u957f\u53c2\u6570"},{"location":"functions/#_7","text":"TODO\uff1a\u66f4\u591a\u4ecb\u7ecd\u51fd\u6570","title":"\u6a21\u677f\u51fd\u6570"},{"location":"functions/#main","text":"TODO","title":"main \u51fd\u6570\u7684\u53c2\u6570"},{"location":"hello_world/","text":"\u4f60\u597d\uff0c\u4e16\u754c \u4f60\u597d\uff0c\u4e16\u754c \u4ec0\u4e48\u662f\u51fd\u6570 \u4ece main \u51fd\u6570\u8bf4\u8d77 main \u51fd\u6570\u7684\u8fd4\u56de\u503c \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f \u6253\u5370\u4e00\u4e9b\u4fe1\u606f \u6ce8\u91ca \u4ec0\u4e48\u662f\u51fd\u6570 \u51fd\u6570: \u4e00\u6bb5\u7528 {} \u5305\u88f9\u7684\u4ee3\u7801\u5757\uff0c\u6709\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u540d\u5b57\u505a\u6807\u8bc6\u3002\u51fd\u6570\u53ef\u4ee5\u88ab\u5176\u4ed6\u51fd\u6570\u8c03\u7528\u3002\u51fd\u6570\u53ef\u4ee5\u6709\u8fd4\u56de\u503c\u548c\u53c2\u6570\u3002\u51fd\u6570\u7684 {} \u4ee3\u7801\u5757\u5185\u7684\u7a0b\u5e8f\u4ee3\u7801\uff0c\u6bcf\u6b21\u8be5\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u90fd\u4f1a\u6267\u884c\u3002 int compute() { return 42; } \u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c compute \u5c31\u662f\u51fd\u6570\u7684\u540d\u5b57\uff0c int \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u2014\u2014\u6574\u6570\u3002 \u4e43\u53d6\u6574\u6570\u4e4b\u82f1\u6587\u201cinteger\u201d\u7684\u201cint\u201d\u800c\u5f97\u540d\uff08\u6a21\u4eff\u4faf\u6377\u8001\u5e08\u8bf4\u8bdd\uff09 \u800c {} \u5305\u88f9\u7684\u662f\u51fd\u6570\u4f53\uff0c\u662f\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u4f1a\u6267\u884c\u7684\u4ee3\u7801\u3002 \u6b64\u5904 return 42 \u5c31\u662f\u51fd\u6570\u4f53\u5185\u7684\u552f\u4e00\u4e00\u6761\u8bed\u53e5\uff0c\u8868\u793a\u51fd\u6570\u7acb\u5373\u6267\u884c\u5b8c\u6bd5\uff0c\u8fd4\u56de 42\u3002 \u8fd4\u56de\u503c: \u5f53\u4e00\u4e2a\u51fd\u6570\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f1a\u5411\u8c03\u7528\u8be5\u51fd\u6570\u7684\u8c03\u7528\u8005\u8fd4\u56de\u4e00\u4e2a\u503c\uff0c\u8fd9\u4e2a\u503c\u5c31\u662f return \u540e\u9762\u7684\u8868\u8fbe\u5f0f\u7684\u503c\u3002\u8fd4\u56de\u503c\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u7c7b\u578b\uff0c\u6b64\u5904 compute \u7684\u8fd4\u56de\u7c7b\u578b\u662f int \uff0c\u4e5f\u5c31\u662f\u8bf4 compute \u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u3002 \u5173\u4e8e\u51fd\u6570\u7684\u53c2\u6570\uff0c\u6211\u4eec\u7a0d\u540e\u518d\u505a\u8bf4\u660e\u3002 \u4ece main \u51fd\u6570\u8bf4\u8d77 C++ \u7a0b\u5e8f\u901a\u5e38\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u7ec4\u6210\uff0c\u5176\u4e2d\u5fc5\u987b\u6709\u4e00\u4e2a\u540d\u4e3a main \u7684\u51fd\u6570\u4f5c\u4e3a\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002 main \u51fd\u6570\u7684\u5b9a\u4e49\u5982\u4e0b\uff1a int main() { } \u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u8c03\u7528 main \u51fd\u6570\u3002 \u4e25\u683c\u6765\u8bf4\uff0c\u662f C++ \u8fd0\u884c\u65f6\u8c03\u7528\u4e86 main \u51fd\u6570\uff0c\u4f46\u76ee\u524d\u5148\u7406\u89e3\u4e3a\u201c\u64cd\u4f5c\u7cfb\u7edf\u8c03\u7528\u4e86 main \u51fd\u6570\u201d\u4e5f\u65e0\u59a8\u3002 \u8981\u628a\u7a0b\u5e8f\u53d1\u5c55\u58ee\u5927\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba9 main \u51fd\u6570\u7ee7\u7eed\u8c03\u7528\u5176\u4ed6\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u5728 main \u51fd\u6570\u4e2d\u7f16\u5199\u6574\u4e2a\u7a0b\u5e8f\u7684\u903b\u8f91\uff08\u4e0d\u63a8\u8350\uff09\u3002 \u56e0\u6b64\uff0c main \u53ef\u4ee5\u88ab\u770b\u4f5c\u662f\u201c\u5b87\u5b99\u5927\u7206\u70b8\u201d\u3002 main \u51fd\u6570\u7684\u8fd4\u56de\u503c int main() { return 0; } return \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\uff0cmain \u51fd\u6570\u8fd4\u56de\uff0c\u5373\u610f\u5473\u7740\u7a0b\u5e8f\u7684\u7ed3\u675f\u3002 main \u51fd\u6570\u603b\u662f\u8fd4\u56de\u4e00\u4e2a\u6574\u6570 ( int \u7c7b\u578b)\uff0c\u7528\u8fd9\u4e2a\u6574\u6570\u5411\u64cd\u4f5c\u7cfb\u7edf\u8868\u793a\u7a0b\u5e8f\u9000\u51fa\u7684\u539f\u56e0\u3002 \u5982\u679c\u7a0b\u5e8f\u6b63\u5e38\u6267\u884c\u5b8c\u6bd5\uff0c\u6b63\u5e38\u7ed3\u675f\u9000\u51fa\uff0c\u90a3\u5c31\u8bf7\u8fd4\u56de 0\u3002 \u901a\u5e38\u6765\u8bf4\u6709\u8fd4\u56de\u7c7b\u578b\u7684\u51fd\u6570\u90fd\u9700\u8981\u5728\u6240\u6709\u5206\u652f\u90fd\u6709 return \u8bed\u53e5\uff0c\u4f46\u6709\u8da3\u7684\u662f\uff0cC++ \u6807\u51c6\u5bf9 main \u51fd\u6570\u505a\u4e86\u7279\u6b8a\u7684\u201c\u5bbd\u5927\u5904\u7406\u201d\uff1a\u5728\u63a7\u5236\u6d41\u8fbe\u5230 main \u51fd\u6570\u7684\u7ed3\u5c3e\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u9047\u5230 return \u8bed\u53e5\uff0c\u5219\u7b49\u4ef7\u4e8e\u6267\u884c return 0; \u3002\u6240\u4ee5\u5bf9\u4e8e\u4f60\u672c\u6765\u5c31\u6253\u7b97\u8fd4\u56de 0 \u7684\u60c5\u51b5\uff0c\u4e5f\u53ef\u4ee5\u5077\u61d2\u4e0d\u5199 return \u8bed\u53e5\uff0c\u7f16\u8bd1\u5668\u81ea\u52a8\u4f1a\u5e2e\u4f60\u52a0\u4e0a\u3002\u4ee5\u53ca\uff0cmain \u51fd\u6570\u5fc5\u987b\u8fd4\u56de int \u7c7b\u578b\uff0c\u4e0d\u80fd\u8fd4\u56de void \u7c7b\u578b\u3002 \u8fd4\u56de\u4e00\u4e2a\u4e0d\u4e3a 0 \u7684\u6574\u6570\u53ef\u4ee5\u8868\u793a\u7a0b\u5e8f\u51fa\u73b0\u4e86\u5f02\u5e38\uff0c\u662f\u56e0\u4e3a\u51fa\u9519\u4e86\u624d\u9000\u51fa\u7684\uff0c\u503c\u7684\u591a\u5c11\u53ef\u4ee5\u7528\u4e8e\u8868\u660e\u9519\u8bef\u7684\u5177\u4f53\u539f\u56e0\u3002 \u64cd\u4f5c\u7cfb\u7edf\uff1a\u6211\u8c03\u7528\u4e86\u4f60\u8fd9\u4e2a\u7a0b\u5e8f\u7684 main \u51fd\u6570\uff0c\u6211\u597d\u5947\u7a0b\u5e8f\u662f\u5426\u6b63\u786e\u6267\u884c\u4e86\uff1f\u8ba9\u6211\u4eec\u7ea6\u5b9a\u597d\uff1a\u5982\u679c\u4f60\u8fd0\u8f6c\u6b63\u5e38\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de0\u8868\u793a\u6210\u529f\u54e6\uff01\u5982\u679c\u6709\u9519\u8bef\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de\u4e00\u4e2a\u9519\u8bef\u4ee3\u7801\uff0c\u6bd4\u5982\u8fd4\u56de1\u8868\u793a\u65e0\u6743\u9650\uff0c2\u8868\u793a\u627e\u4e0d\u5230\u6587\u4ef6\u2026\u2026\u4e4b\u7c7b\u7684\u3002\u5f53\u7136\uff0c\u9519\u8bef\u4ee3\u7801\u90fd\u662f\u4e0d\u4e3a0\u7684\u3002 \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f TODO: \u4ecb\u7ecd\u63a7\u5236\u53f0 \u6253\u5370\u4e00\u4e9b\u4fe1\u606f int main() { std::println(\"Hello, World!\"); } \u4ee5\u4e0a\u4ee3\u7801\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa Hello, World! \u3002 \u6ce8\u91ca int main() { // \u5c0f\u5f6d\u8001\u5e08\uff0c\u8bf7\u4f60\u5728\u8fd9\u91cc\u63d2\u5165\u7a0b\u5e8f\u7684\u903b\u8f91\u54e6\uff01 } \u8fd9\u91cc\u7684 // \u662f\u6ce8\u91ca\uff0c\u6ce8\u91ca\u4f1a\u88ab\u7f16\u8bd1\u5668\u5ffd\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u7a0b\u5e8f\u6e90\u7801\u4e2d\u690d\u5165\u63cf\u8ff0\u6027\u7684\u6587\u672c\u3002\u6709\u65f6\u4e5f\u4f1a\u7528\u4e8e\u591a\u4eba\u534f\u4f5c\u9879\u76ee\u4e2d\u7a0b\u5e8f\u5458\u4e4b\u95f4\u4e92\u76f8\u6c9f\u901a\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u8bf6\u563f\u4f60\u770b\u4e0d\u89c1\u6211 } \u5728\u7f16\u8bd1\u5668\u770b\u6765\u5c31\u53ea\u662f\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); } (* \u7f16\u8bd1\u5668\u8138\u7ea2\u4e2d* ) C++ \u652f\u6301\u884c\u6ce8\u91ca // xx \u548c\u5757\u6ce8\u91ca /* xx */ \u4e24\u79cd\u8bed\u6cd5\u3002 int main() { // \u6211\u662f\u884c\u6ce8\u91ca /* \u6211\u662f\u5757\u6ce8\u91ca */ /* \u5757\u6ce8\u91ca \u53ef\u4ee5 \u6709 \u5f88\u591a\u884c */ std::println(/* \u5757\u6ce8\u91ca\u4e5f\u53ef\u4ee5\u5939\u5728\u4ee3\u7801\u4e2d\u95f4 */\"\u4f60\u597d\"); std::println(\"\u4e16\u754c\"); // \u884c\u6ce8\u91ca\u53ea\u80fd\u8ffd\u52a0\u5728\u4e00\u884c\u7684\u672b\u5c3e std::println(\"\u65e9\u5b89\"); } \u5728\u6211\u4eec\u4ee5\u540e\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\uff0c\u90fd\u4f1a\u50cf\u8fd9\u6837\u6ce8\u91ca\u8bf4\u660e\uff0c\u5145\u5f53 \u5c31\u5730\u8bb2\u89e3\u5458 \u7684\u6548\u679c\u3002\u53bb\u9664\u8fd9\u4e9b\u6ce8\u91ca\u5e76\u4e0d\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u5e38\u8fd0\u884c\uff0c\u6dfb\u52a0\u6587\u5b57\u6ce8\u91ca\u53ea\u662f\u5c0f\u5f6d\u8001\u5e08\u4e3a\u4e86\u63d0\u9192\u4f60\u6bcf\u4e00\u884c\u7684\u4ee3\u7801\u4f5c\u7528\u3002","title":"\u4f60\u597d\uff0c\u4e16\u754c"},{"location":"hello_world/#_1","text":"\u4f60\u597d\uff0c\u4e16\u754c \u4ec0\u4e48\u662f\u51fd\u6570 \u4ece main \u51fd\u6570\u8bf4\u8d77 main \u51fd\u6570\u7684\u8fd4\u56de\u503c \u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f \u6253\u5370\u4e00\u4e9b\u4fe1\u606f \u6ce8\u91ca","title":"\u4f60\u597d\uff0c\u4e16\u754c"},{"location":"hello_world/#_2","text":"\u51fd\u6570: \u4e00\u6bb5\u7528 {} \u5305\u88f9\u7684\u4ee3\u7801\u5757\uff0c\u6709\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u540d\u5b57\u505a\u6807\u8bc6\u3002\u51fd\u6570\u53ef\u4ee5\u88ab\u5176\u4ed6\u51fd\u6570\u8c03\u7528\u3002\u51fd\u6570\u53ef\u4ee5\u6709\u8fd4\u56de\u503c\u548c\u53c2\u6570\u3002\u51fd\u6570\u7684 {} \u4ee3\u7801\u5757\u5185\u7684\u7a0b\u5e8f\u4ee3\u7801\uff0c\u6bcf\u6b21\u8be5\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u90fd\u4f1a\u6267\u884c\u3002 int compute() { return 42; } \u4e0a\u9762\u7684\u4ee3\u7801\u4e2d\uff0c compute \u5c31\u662f\u51fd\u6570\u7684\u540d\u5b57\uff0c int \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u2014\u2014\u6574\u6570\u3002 \u4e43\u53d6\u6574\u6570\u4e4b\u82f1\u6587\u201cinteger\u201d\u7684\u201cint\u201d\u800c\u5f97\u540d\uff08\u6a21\u4eff\u4faf\u6377\u8001\u5e08\u8bf4\u8bdd\uff09 \u800c {} \u5305\u88f9\u7684\u662f\u51fd\u6570\u4f53\uff0c\u662f\u51fd\u6570\u88ab\u8c03\u7528\u65f6\u4f1a\u6267\u884c\u7684\u4ee3\u7801\u3002 \u6b64\u5904 return 42 \u5c31\u662f\u51fd\u6570\u4f53\u5185\u7684\u552f\u4e00\u4e00\u6761\u8bed\u53e5\uff0c\u8868\u793a\u51fd\u6570\u7acb\u5373\u6267\u884c\u5b8c\u6bd5\uff0c\u8fd4\u56de 42\u3002 \u8fd4\u56de\u503c: \u5f53\u4e00\u4e2a\u51fd\u6570\u6267\u884c\u5b8c\u6bd5\u65f6\uff0c\u4f1a\u5411\u8c03\u7528\u8be5\u51fd\u6570\u7684\u8c03\u7528\u8005\u8fd4\u56de\u4e00\u4e2a\u503c\uff0c\u8fd9\u4e2a\u503c\u5c31\u662f return \u540e\u9762\u7684\u8868\u8fbe\u5f0f\u7684\u503c\u3002\u8fd4\u56de\u503c\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u7c7b\u578b\uff0c\u6b64\u5904 compute \u7684\u8fd4\u56de\u7c7b\u578b\u662f int \uff0c\u4e5f\u5c31\u662f\u8bf4 compute \u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u3002 \u5173\u4e8e\u51fd\u6570\u7684\u53c2\u6570\uff0c\u6211\u4eec\u7a0d\u540e\u518d\u505a\u8bf4\u660e\u3002","title":"\u4ec0\u4e48\u662f\u51fd\u6570"},{"location":"hello_world/#main","text":"C++ \u7a0b\u5e8f\u901a\u5e38\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u7ec4\u6210\uff0c\u5176\u4e2d\u5fc5\u987b\u6709\u4e00\u4e2a\u540d\u4e3a main \u7684\u51fd\u6570\u4f5c\u4e3a\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002 main \u51fd\u6570\u7684\u5b9a\u4e49\u5982\u4e0b\uff1a int main() { } \u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u8c03\u7528 main \u51fd\u6570\u3002 \u4e25\u683c\u6765\u8bf4\uff0c\u662f C++ \u8fd0\u884c\u65f6\u8c03\u7528\u4e86 main \u51fd\u6570\uff0c\u4f46\u76ee\u524d\u5148\u7406\u89e3\u4e3a\u201c\u64cd\u4f5c\u7cfb\u7edf\u8c03\u7528\u4e86 main \u51fd\u6570\u201d\u4e5f\u65e0\u59a8\u3002 \u8981\u628a\u7a0b\u5e8f\u53d1\u5c55\u58ee\u5927\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba9 main \u51fd\u6570\u7ee7\u7eed\u8c03\u7528\u5176\u4ed6\u51fd\u6570\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u5728 main \u51fd\u6570\u4e2d\u7f16\u5199\u6574\u4e2a\u7a0b\u5e8f\u7684\u903b\u8f91\uff08\u4e0d\u63a8\u8350\uff09\u3002 \u56e0\u6b64\uff0c main \u53ef\u4ee5\u88ab\u770b\u4f5c\u662f\u201c\u5b87\u5b99\u5927\u7206\u70b8\u201d\u3002","title":"\u4ece main \u51fd\u6570\u8bf4\u8d77"},{"location":"hello_world/#main_1","text":"int main() { return 0; } return \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\uff0cmain \u51fd\u6570\u8fd4\u56de\uff0c\u5373\u610f\u5473\u7740\u7a0b\u5e8f\u7684\u7ed3\u675f\u3002 main \u51fd\u6570\u603b\u662f\u8fd4\u56de\u4e00\u4e2a\u6574\u6570 ( int \u7c7b\u578b)\uff0c\u7528\u8fd9\u4e2a\u6574\u6570\u5411\u64cd\u4f5c\u7cfb\u7edf\u8868\u793a\u7a0b\u5e8f\u9000\u51fa\u7684\u539f\u56e0\u3002 \u5982\u679c\u7a0b\u5e8f\u6b63\u5e38\u6267\u884c\u5b8c\u6bd5\uff0c\u6b63\u5e38\u7ed3\u675f\u9000\u51fa\uff0c\u90a3\u5c31\u8bf7\u8fd4\u56de 0\u3002 \u901a\u5e38\u6765\u8bf4\u6709\u8fd4\u56de\u7c7b\u578b\u7684\u51fd\u6570\u90fd\u9700\u8981\u5728\u6240\u6709\u5206\u652f\u90fd\u6709 return \u8bed\u53e5\uff0c\u4f46\u6709\u8da3\u7684\u662f\uff0cC++ \u6807\u51c6\u5bf9 main \u51fd\u6570\u505a\u4e86\u7279\u6b8a\u7684\u201c\u5bbd\u5927\u5904\u7406\u201d\uff1a\u5728\u63a7\u5236\u6d41\u8fbe\u5230 main \u51fd\u6570\u7684\u7ed3\u5c3e\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u9047\u5230 return \u8bed\u53e5\uff0c\u5219\u7b49\u4ef7\u4e8e\u6267\u884c return 0; \u3002\u6240\u4ee5\u5bf9\u4e8e\u4f60\u672c\u6765\u5c31\u6253\u7b97\u8fd4\u56de 0 \u7684\u60c5\u51b5\uff0c\u4e5f\u53ef\u4ee5\u5077\u61d2\u4e0d\u5199 return \u8bed\u53e5\uff0c\u7f16\u8bd1\u5668\u81ea\u52a8\u4f1a\u5e2e\u4f60\u52a0\u4e0a\u3002\u4ee5\u53ca\uff0cmain \u51fd\u6570\u5fc5\u987b\u8fd4\u56de int \u7c7b\u578b\uff0c\u4e0d\u80fd\u8fd4\u56de void \u7c7b\u578b\u3002 \u8fd4\u56de\u4e00\u4e2a\u4e0d\u4e3a 0 \u7684\u6574\u6570\u53ef\u4ee5\u8868\u793a\u7a0b\u5e8f\u51fa\u73b0\u4e86\u5f02\u5e38\uff0c\u662f\u56e0\u4e3a\u51fa\u9519\u4e86\u624d\u9000\u51fa\u7684\uff0c\u503c\u7684\u591a\u5c11\u53ef\u4ee5\u7528\u4e8e\u8868\u660e\u9519\u8bef\u7684\u5177\u4f53\u539f\u56e0\u3002 \u64cd\u4f5c\u7cfb\u7edf\uff1a\u6211\u8c03\u7528\u4e86\u4f60\u8fd9\u4e2a\u7a0b\u5e8f\u7684 main \u51fd\u6570\uff0c\u6211\u597d\u5947\u7a0b\u5e8f\u662f\u5426\u6b63\u786e\u6267\u884c\u4e86\uff1f\u8ba9\u6211\u4eec\u7ea6\u5b9a\u597d\uff1a\u5982\u679c\u4f60\u8fd0\u8f6c\u6b63\u5e38\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de0\u8868\u793a\u6210\u529f\u54e6\uff01\u5982\u679c\u6709\u9519\u8bef\u7684\u8bdd\uff0c\u5c31\u8fd4\u56de\u4e00\u4e2a\u9519\u8bef\u4ee3\u7801\uff0c\u6bd4\u5982\u8fd4\u56de1\u8868\u793a\u65e0\u6743\u9650\uff0c2\u8868\u793a\u627e\u4e0d\u5230\u6587\u4ef6\u2026\u2026\u4e4b\u7c7b\u7684\u3002\u5f53\u7136\uff0c\u9519\u8bef\u4ee3\u7801\u90fd\u662f\u4e0d\u4e3a0\u7684\u3002","title":"main \u51fd\u6570\u7684\u8fd4\u56de\u503c"},{"location":"hello_world/#_3","text":"TODO: \u4ecb\u7ecd\u63a7\u5236\u53f0","title":"\u8fd9\u4e2a\u9ed1\u8272\u7684\u7a97\u53e3\u662f\uff1f"},{"location":"hello_world/#_4","text":"int main() { std::println(\"Hello, World!\"); } \u4ee5\u4e0a\u4ee3\u7801\u4f1a\u5728\u63a7\u5236\u53f0\u8f93\u51fa Hello, World! \u3002","title":"\u6253\u5370\u4e00\u4e9b\u4fe1\u606f"},{"location":"hello_world/#_5","text":"int main() { // \u5c0f\u5f6d\u8001\u5e08\uff0c\u8bf7\u4f60\u5728\u8fd9\u91cc\u63d2\u5165\u7a0b\u5e8f\u7684\u903b\u8f91\u54e6\uff01 } \u8fd9\u91cc\u7684 // \u662f\u6ce8\u91ca\uff0c\u6ce8\u91ca\u4f1a\u88ab\u7f16\u8bd1\u5668\u5ffd\u7565\uff0c\u901a\u5e38\u7528\u4e8e\u5728\u7a0b\u5e8f\u6e90\u7801\u4e2d\u690d\u5165\u63cf\u8ff0\u6027\u7684\u6587\u672c\u3002\u6709\u65f6\u4e5f\u4f1a\u7528\u4e8e\u591a\u4eba\u534f\u4f5c\u9879\u76ee\u4e2d\u7a0b\u5e8f\u5458\u4e4b\u95f4\u4e92\u76f8\u6c9f\u901a\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u7f16\u8bd1\u5668\u662f\u715e\u7b14 // \u8bf6\u563f\u4f60\u770b\u4e0d\u89c1\u6211 } \u5728\u7f16\u8bd1\u5668\u770b\u6765\u5c31\u53ea\u662f\uff1a int main() { std::println(\"\u7f16\u8bd1\u5668\u4f1f\u5927\uff0c\u65e0\u9700\u591a\u8a00\"); } (* \u7f16\u8bd1\u5668\u8138\u7ea2\u4e2d* ) C++ \u652f\u6301\u884c\u6ce8\u91ca // xx \u548c\u5757\u6ce8\u91ca /* xx */ \u4e24\u79cd\u8bed\u6cd5\u3002 int main() { // \u6211\u662f\u884c\u6ce8\u91ca /* \u6211\u662f\u5757\u6ce8\u91ca */ /* \u5757\u6ce8\u91ca \u53ef\u4ee5 \u6709 \u5f88\u591a\u884c */ std::println(/* \u5757\u6ce8\u91ca\u4e5f\u53ef\u4ee5\u5939\u5728\u4ee3\u7801\u4e2d\u95f4 */\"\u4f60\u597d\"); std::println(\"\u4e16\u754c\"); // \u884c\u6ce8\u91ca\u53ea\u80fd\u8ffd\u52a0\u5728\u4e00\u884c\u7684\u672b\u5c3e std::println(\"\u65e9\u5b89\"); } \u5728\u6211\u4eec\u4ee5\u540e\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\uff0c\u90fd\u4f1a\u50cf\u8fd9\u6837\u6ce8\u91ca\u8bf4\u660e\uff0c\u5145\u5f53 \u5c31\u5730\u8bb2\u89e3\u5458 \u7684\u6548\u679c\u3002\u53bb\u9664\u8fd9\u4e9b\u6ce8\u91ca\u5e76\u4e0d\u5f71\u54cd\u7a0b\u5e8f\u7684\u6b63\u5e38\u8fd0\u884c\uff0c\u6dfb\u52a0\u6587\u5b57\u6ce8\u91ca\u53ea\u662f\u5c0f\u5f6d\u8001\u5e08\u4e3a\u4e86\u63d0\u9192\u4f60\u6bcf\u4e00\u884c\u7684\u4ee3\u7801\u4f5c\u7528\u3002","title":"\u6ce8\u91ca"},{"location":"interview/","text":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c \u6700\u8fd1\u597d\u50cf\u5f88\u6d41\u884c\u9762\u7ecf\u2026\u2026\u5c0f\u5f6d\u8001\u5e08\u4e5f\u6765\u5199\u4e00\u4e0b\u3002 \u6cfd\u68ee\u79d1\u5de5 (2021.12.07) \u5f20\u5265\u58eb\u5728taichi\u8bba\u575b\u91cc\u4e3b\u52a8\u627e\u4e0a\u6765\u8054\u7cfb\uff0c\u8868\u793a\u6211\u4eec\u5f88\u6b23\u8d4f\u4f60\u5728\u592a\u6781\u7684\u4f1f\u5927\u8d21\u732e\uff0c\u5e0c\u671b\u548c\u6211\u4eec\u6cfd\u68ee\u4e00\u8d77\u521b\u9020\u66f4\u597d\u7684\u65b0\u4ea7\u54c1(\u4ec0\u4e48\u6316\u5899\u89d2) \u5f20\u5265\u58eb\u5728\u5fae\u4fe1\u7535\u8bdd\u91cc\u5f00\u59cb\u8bed\u97f3\u9762\u8bd5\u4e86\uff0c\u4e0a\u6765\u5c31\u8981\u6c42\u5b9e\u73b0sqrt\u51fd\u6570(\u725b\u987f\u8fed\u4ee3\u6cd5\u5373\u53ef\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e0d\u5c0f\u5fc3\u5199\u9519\uff0c\u6709\u6b7b\u5faa\u73af\uff0c\u5f20\u5265\u58eb\u8868\u793a\u4e0d\u8981\u7d27\uff0c\u8fd9\u4e2a\u4f60\u80af\u5b9a\u73b0\u5b9e\u4e2d\u5f88\u5bb9\u6613\u8c03\u8bd5\u6539\u6b63\u7684\uff0c\u4e3b\u8981\u662f\u725b\u987f\u8fed\u4ee3\u9700\u8981\u5bfc\u6570\u7684\u89e3\u6790\u5f0f\uff0c\u5bb9\u6613\u5199\u9519\uff0cnaive\u7684\u521d\u5b66\u8005\u4e5f\u53ef\u4ee5\u9009\u62e9\u5199\u4e8c\u5206\u6cd5\uff0c\u4f59\u5207\u6cd5\u7b49) \u6709\u6ca1\u6709\u4e86\u89e3\u8fc7\u96f7\u795e3\u7684\u5feb\u901fsqrt\u51fd\u6570\uff1f(\u77e5\u9053\uff0c\u4f46\u597d\u50cf\u662f\u795e\u5947\u7684\u4e8c\u8fdb\u5236\u8fd0\u7b97\uff0c\u6ca1\u6709\u6df1\u5165\u4e86\u89e3\u8fc7\u4e3a\u4ec0\u4e48\u8fd9\u6837\u505a) \u77e5\u9053float\u7684\u5e03\u5c40\u5427(23\u4f4d\u5e95\u6570mantissa\uff0c8\u4f4d\u6307\u6570exponent\uff0c1\u4f4d\u7b26\u53f7sign) \u800c\u725b\u987f\u8fed\u4ee3\u6cd5\u9700\u8981\u8fd1\u4f3c\uff0csqrt\u6700\u597d\u7684\u8fd1\u4f3c\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u628aexponent\u4f4d\u9664\u4ee52\uff0c\u5bf9\u4e0d\u5bf9\uff1f(\u5c0f\u5f6d\u8001\u5e08\u604d\u7136\u5927\u609f\uff0c\u602a\u4e0d\u5f97\u9700\u8981\u53f3\u79fb1\u4f4d\uff0c\u539f\u6765\u662f\u8ba9exponent\u96642\uff0c\u96f7\u795e\u7684sqrt\u56e0\u4e3a\u6709\u826f\u597d\u7684\u8fd1\u4f3c\u521d\u503c\uff0c\u63a5\u4e0b\u6765\u5c31\u53ea\u9700\u8981\u4e00\u4e24\u6b65\u5c31\u80fd\u6536\u655b) \u63a5\u4e0b\u6765\u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u6211\u6709\u4ece 1 \u5230 100 \u8fd9 100 \u4e2a\u6570\uff0c\u7ec4\u6210\u8d85\u957f\u7684\u6570\u7ec4\uff0c\u968f\u673a\u6392\u5217\uff0c\u73b0\u5728\u8fd9\u91cc\u9762\u7f3a\u5c11\u4e86\u4e00\u4f4d(\u6bd4\u5982 1 2 3 4 5 7 8 9 10 \u5c31\u662f\u7f3a\u5c11\u4e86 6) \u73b0\u5728\uff0c\u6211\u4e00\u8fb9\u62a5\u6570\u4f60\u4e00\u8fb9\u64cd\u4f5c\uff0c\u6211\u62a5\u5b8c\u7684\u90a3\u4e00\u523b\uff0c\u4f60\u5fc5\u987b\u7acb\u5373\u544a\u8bc9\u6211\uff0c\u7f3a\u5931\u7684\u90a3\u4e00\u4e2a\u6570\u662f\u4ec0\u4e48\uff0c\u5e76\u4e14\u4e0d\u5141\u8bb8\u4f7f\u7528\u8bb0\u4e8b\u672c(\u4e5f\u5c31\u662f\u8981\u6c42\u5e38\u6570\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5f88\u7b80\u5355\uff0c\u4f60\u62a5\u7684\u540c\u65f6\u6211\u5f80\u4e00\u4e2a\u8ba1\u6570\u5668\u91cc\u7d2f\u52a0\u6c42\u548c\uff0c\u7136\u540e\u7b97\u51fa\u6765\u7684\u603b\u6c42\u548c\u548c 5050 \u76f8\u51cf\uff0c\u5f97\u5230\u7684\u5c31\u662f\u7f3a\u5931\u7684\u90a3\u4e2a\u6570\u4e86\uff0c\u6bd4\u5982 1+2+3+4+5+7+8+9+10 - 55 = -6\uff0c\u90a3\u4e48\u5c31\u77e5\u9053\u7f3a\u7684\u662f 6) \u5982\u679c\u6211\u662f\u7f3a\u4e86\u4e24\u4e2a\u6570\u5462\uff1f(\u90a3\u6211\u5f04\u4e24\u4e2a\u8ba1\u6570\u5668\uff0c\u4e00\u4e2a\u6c42\u548c\uff0c\u4e00\u4e2a\u6c42\u79ef\uff0c\u7136\u540e\u8054\u7acb\u4e8c\u5143\u4e8c\u6b21\u65b9\u7a0b) \u6211\u63d0\u4f9b\u4e00\u4e2a\u751f\u62100\u52301\u533a\u95f4\u5747\u5300\u968f\u673a\u6570\u7684\u51fd\u6570frand\uff0c\u5982\u679c\u6211\u6307\u5b9a\u4e00\u4e2a\u5206\u5e03\uff0c\u6bd4\u5982\u8981\u6c42\u9ad8\u65af\u5206\u5e03\uff0c\u5982\u4f55\u751f\u6210\u7b26\u5408\u8fd9\u4e2a\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff1f(frand\u662f\u5747\u5300\u968f\u673a\u6570\u51fd\u6570\uff0c\u8981\u6620\u5c04\u5230\u6307\u5b9a\u5bc6\u5ea6\u5206\u5e03\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u5148\u5bf9\u8be5\u6982\u7387\u5bc6\u5ea6\u51fd\u6570pdf\u6c42\u79ef\u5206\uff0c\u5f97\u5230\u7d2f\u79ef\u6982\u7387\u51fd\u6570cdf\uff0c\u6c42\u5176\u53cd\u51fd\u6570icdf\uff0c\u7136\u540e\u4f7f\u7528icdf(frand())\u5373\u4e3a\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff0c\u4f8b\u5982\u5bf9\u4e8e\u9ad8\u65af\u5206\u5e03\u6765\u8bf4\uff0c\u4ed6\u7684cdf\u51fd\u6570\u662ferf\uff0c\u4e5f\u5c31\u662ferfinv(frand())\u53ef\u4ee5\u751f\u6210\u9ad8\u65af\u5206\u5e03\u7684\u968f\u673a\u6570\uff09 \u5199\u4e00\u4e2a\u51fd\u6570\uff0c\u751f\u6210\u4e00\u4e2a\u5706\u5f62\u5185\u5747\u5300\u5206\u5e03\u7684\u70b9(\u521d\u5b66\u8005naive\u7684\u5199\u6cd5\uff1a\u5148\u751f\u6210\u4e00\u4e2a\u6b63\u65b9\u5f62\u7684\u5747\u5300\u5206\u5e03\u70b9\uff0c\u7136\u540e\u5224\u5b9a\u662f\u5426\u5728\u534a\u5f841\u5185\uff0c\u5982\u679c\u5728\u5219\u4fdd\u7559\uff0c\u5426\u5219\u91cd\u65b0\u751f\u6210\uff0c\u76f4\u5230\u751f\u6210\u5728\u534a\u5f84\u5185\uff1b\u5c0f\u5f6d\u8001\u5e08\u7684\u5199\u6cd5\uff1a\u9996\u5148\u6c42\u5706\u5f62\u5468\u957fS=2pir\u7684icdf\uff0c\u7136\u540eblahblah\uff0c\u6700\u7ec8\u662fr=icdf(frand())\uff0c\u7136\u540e\u518d\u968f\u673a\u4e00\u4e2atheta=frand()*2pi\uff0cx=rcostheta\uff0cy=rsintheta) \u5047\u5982\u6211\u6307\u5b9a\u7684\u51fd\u6570\u4e0d\u662f\u4e00\u4e2a\u89e3\u6790\u5f0f\uff0c\u800c\u662f\u4e00\u4e2a\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u600e\u4e48\u751f\u6210\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\uff1f(\u9996\u5148\u6c42\u8be5\u5bc6\u5ea6\u6570\u7ec4\u7684\u524d\u7f00\u548cprefix sum\uff0c\u7136\u540er=frand()\uff0c\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e0b\u6807\u4f4d\u7f6e\uff0c\u8be5\u4e0b\u6807\u5373\u4e3a\u8981\u751f\u6210\u7684\u968f\u673a\u6570\uff0c\u5982\u679c\u6709\u4e00\u4e2a\u503c\u5217\u8868\uff0c\u5219\u7528\u4e0b\u6807\u8bbf\u95ee\u8fd9\u4e2a\u503c\u5217\u8868\uff0c\u5982\u679c\u9700\u8981\u8fde\u7eed\u53d8\u5316\uff0c\u53ef\u4ee5\u5728\u7b2c\u4e00\u4e2a\u5927\u4e8e\u7b49\u4e8er\u548c\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e24\u4e2a\u5143\u7d20\u4e4b\u95f4\u6309r\u591a\u51fa\u7684\u4f59\u6570\u63d2\u503c) \u53ef\u662f\u904d\u5386\u53bb\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4f4d\u7f6e\u53ef\u80fd\u4f1a\u5f88\u6162\uff0c\u600e\u4e48\u52a0\u901f\uff1f(\u4e8c\u5206\u6cd5\u641c\u7d22\u8be5\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u53ef\u4ee5\u7528\u6807\u51c6\u5e93\u7684lower_bound) \u4e8b\u540e \u540e\u6765\u5c0f\u5f6d\u8001\u5e08\u5728\u804c\u671f\u95f4\uff0c\u5f20\u5265\u58eb\u4e00\u987f\u5439\u6367\uff1a\u4f60\u662f\u6211\u4eec\u8fd9\u91cc\u552f\u4e00\u4e00\u4e2a\u901a\u8fc7\u7845\u8c37\u7ea7\u4eba\u624d\u6d4b\u8bd5\u7684\u5458\u5de5\uff0c\u4e00\u89c1\u5230\u65b0\u5458\u5de5\u5c31\u5439\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u770b\u770b\u4eba\u5bb6\u5c0f\u5f6d\u8001\u5e08\u3002 \u5f20\u5265\u58eb\u8fd8\u753b\u51fa\u4e86\u671f\u6743\u5927\u997c\uff0c\u8bb2\u4e86\u4e00\u7cfb\u5217\u6211\u542c\u4e0d\u61c2\u7684\u865a\u62df\u671f\u6743\u6982\u5ff5\u91d1\u6eb6\u672f\u8bed\u540e\uff0c\u603b\u4e4b\u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\u9f13\u52b1\u5c0f\u5f6d\u8001\u5e08\u594b\u6597\uff0c\u594b\u6597\u7684\u516c\u53f8\u80a1\u4ef7\u6da8\u4e86\u5c31\u80fd\u5206\u7ea2\uff0c\u4f46\u76f4\u5230\u6700\u540e\u90fd\u6ca1\u6709\u5151\u73b0\uff0c\u800c\u4e14\u636e\u4e86\u89e3\u4e0a\u5e02\u516c\u53f8\u624d\u6709\u671f\u6743\u2026\u2026 \u5c0f\u5f6d\u8001\u5e08\u770b\u5230\u5f20\u5265\u58eb\u8fd9\u4e48\u91cd\u7528\uff0c\u4ee5\u4e3a\u6bd5\u4e1a\u4ee5\u540e\u80af\u5b9a\u7ed9\u8f6c\u6b63\u4e86\uff0c\u6240\u4ee5\u5c31\u6ca1\u6709\u8003\u7814\uff0c\u6ca1\u6709\u53bb\u770b\u6821\u62db\uff0c\u4e5f\u6ca1\u6709\u63a5\u53d7\u5b66\u6821\u7684\u5bf9\u63a5\uff0c\u5fd8\u6211\u5730\u4f3a\u5019zeno\u5de5\u4f5c\uff0c\u6253\u7b97\u4e00\u6bd5\u4e1a\u5c31\u76f4\u63a5\u53bb\u6df1\u5733\u4f3a\u5019\u5f20\u5265\u58eb\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 zeno \u7684\u5de5\u4f5c\u57fa\u672c\u5b8c\u6210\u4e86\uff0c\u627e\u4e0d\u5230\u6709\u4ec0\u4e48\u9700\u8981\u505a\u7684\uff0c\u5f20\u5265\u58eb\u7a81\u7136\u5f00\u59cb\u53cd\u590d\u7c97\u9119\u8bed\u8a00\u7f9e\u8fb1\u5c0f\u5f6d\u8001\u5e08\uff0cpua\u5c0f\u5f6d\u8001\u5e08\uff0c\u66f0\u201c\u4f60\u662f\u7a0b\u5e8f\u5458\u9493\u4e1d\u601d\u7ef4\u201d\u201c\u6839\u672c\u4e0d\u61c2\u6211\u4eec\u7684\u5b9e\u9645\u9700\u6c42\u201d\u201c\u4f60\u4eec\u9493\u4e1d\u7a0b\u5e8f\u5458\u662f\u6700\u4e0d\u61c2\u7f8e\u672f\u7d20\u517b\u7684\u201d\uff0c\u770b\u5728\u5265\u58eb\u8fd8\u5728\u53d1\u5de5\u8d44\u7684\u4efd\u4e0a\uff0c\u5c31\u6ca1\u6709\u7406\u5b83\u3002 \u5c0f\u5f6d\u8001\u5e08\u7ec8\u4e8e\u6bd5\u4e1a\u4e86\uff0c\u8868\u793a\u53ef\u4ee5\u8f6c\u6b63\uff0c\u8fd9\u65f6\u5f20\u5265\u58eb\u5374\u51fa\u5c14\u53cd\u5c14\uff0c\u5404\u79cd\u63a8\u8131\uff0c\u66f0\u201c\u8d44\u91d1\u56f0\u96be\u201d\u201c\u8bf7\u4e0d\u52a8\u5c0f\u5f6d\u8001\u5e08\u201d\u201c\u7b49\u62119\u6708\u62c9\u5230\u6295\u8d44\u597d\u4e0d\u597d\u201d\uff0c\u7136\u800c\u81f3\u4eca\u6ca1\u6709\u53cd\u5e94\uff0c\u8f6c\u5934\u5c31\u770b\u5230\u670b\u53cb\u5708\u5728\u53d1\u5e03\u5916\u5305jd\u3002 \u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u201c\u54c0\u6c42\u201d\u5f20\u5265\u58eb\u201c\u5f00\u773c\u201d\uff0c\u5f20\u5265\u58eb\u53cd\u590d\u63a8\u8131\u540e\uff0c\u7ec8\u4e8e\u8868\u793a\uff1a\u770b\u5728\u4f60\u5bf9zeno\u4e5f\u6709\u201c\u611f\u60c5\u201d\u4e86\uff0c\u5982\u679c\u4f60\u8fd8\u60f3\u4e3a\u6211\u4eeczeno\u7ee7\u7eed\u201c\u8d21\u732e\u201d\u7684\u8bdd\uff0c\u53ef\u4ee5\u5f00\u51fa5k\u4f4e\u4ef7\u91cd\u65b0\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\uff0c\u7b49\u201c\u62c9\u5230\u6295\u8d44\u201d\u201c\u8d44\u91d1\u4e0d\u56f0\u96be\u201d\u65f6\uff0c\u518d\u7ed9\u5c0f\u5f6d\u8001\u5e08\u201c\u8865\u8d34\u201d\u56de\u539f\u6765\u768416k\u5de5\u8d44\uff0c\u540c\u65f6\u770b\u5230\u5f20\u5265\u58eb\u5728\u7fa4\u91cc\u70ab\u8000\u4ed6\u8239\u65b0\u7684\u7b49\u8eab\u624b\u529e(\u5c04)\u3002 \u5f20\u5265\u58eb\u81ea\u6211\u611f\u52a8\u6f14\u7684\u60df\u5999\u60df\u8096\uff0c\u5c0f\u5f6d\u8001\u5e08\u8003\u8651\u5230\u5f20\u5265\u58eb\u671f\u6743\u5927\u997c\u7684\u524d\u8f66\u4e4b\u9274\uff0c\u5c31\u6ca1\u6709\u76f8\u4fe1\u5265\u58eb\u7684\u201c\u597d\u610f\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\u53ea\u597d\u4ee5\u672c\u79d1\u5e94\u5c4a\u751f\u8eab\u4efd\u5f00\u59cb\u5bfb\u627e\u5de5\u4f5c\uff0c\u5176\u4e2dhr\u7ecf\u5e38\u62f7\u95ee\u201c\u6211\u770b\u4f601\u6708\u5230\u73b0\u5728\u90fd\u662f\u6ca1\u6709\u5de5\u4f5c\u7684\u72b6\u6001\uff1f\u201d\u201c\u8bf4\u4e00\u4e0b\u79bb\u804c\u539f\u56e0\u201d\u9020\u6210\u5f88\u5927\u7684\u9ebb\u70e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u5c55\u793a\u201c\u5de5\u4f5c\u7ecf\u9a8c\u201d\u65f6\uff0chr\u603b\u662f\u53cd\u590d\u5f3a\u8c03\u201c\u6211\u770b\u4f60\u624d\u521a\u6bd5\u4e1a\u5440\uff1f\u201d\uff0c\u8ba4\u4e3a\u201c\u5b9e\u4e60\u7ecf\u9a8c\u201d\u4e0d\u7b97\uff0c\u5bfc\u81f4\u5c0f\u5f6d\u8001\u5e08\u5728\u5f20\u5265\u58eb\u7684\u7ecf\u9a8c\u51e0\u4e4e\u4f5c\u5e9f\uff0c\u800c\u5e94\u5c4a\u751f\u4f18\u60e0\u53c8\u88ab\u5f20\u5265\u58eb\u8017\u6389\uff0c\u7136\u800c\uff0c\u5b83\u53ea\u8981\u770b\u4e00\u4e0bzeno\u8d21\u732e\u6392\u884c\u699c\u5c31\u77e5\u9053\uff0c\u5c0f\u5f6d\u8001\u5e08\u7684\u8d21\u732e\u662f\u7b2c\u4e00\u7684\u3002 \u6240\u6709\u6cfd\u68ee\u5458\u5de5\u90fd\u9700\u8981\u719f\u6089\u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u8fed\u4ee3\u8fc7\u7684\u8282\u70b9\u7cfb\u7edf\uff0c\u624d\u80fd\u5f00\u59cb\u4ed6\u7684zeno\u5f00\u53d1\uff0c\u66f4\u4f55\u51b5\u5c0f\u5f6d\u8001\u5e08\u8fd8\u8d21\u732e\u4e86\u5305\u62ec\u8282\u70b9\u7f16\u8f91\u5668\u3001Python bindings\u3001\u5b9e\u65f6\u4e09\u7ef4\u89c6\u7a97\u3001\u591a\u8fdb\u7a0b\u901a\u4fe1\u3001\u78c1\u76d8\u7f13\u5b58\u3001\u5bf9\u8c61\u5e8f\u5217\u5316\u3001\u5b9e\u65f6optix\u3001shader\u8282\u70b9\u3001GLSL codegen\u3001\u521a\u4f53\u4eff\u771f\u3001Prim\u5c5e\u6027\u7cfb\u7edf\u3001ZFX\u7f16\u8bd1\u5668\u3001PrimPrim \u90bb\u5c45\u67e5\u627e\u3001\u63d2\u4ef6\u7cfb\u7edf\u3001ABC \u52a0\u8f7d\u5668\u3001\u51e0\u4f55\u8282\u70b9\u3001VDB \u8282\u70b9\u3001\u6d41\u4f53\u5b50\u56fe\u3001Blender \u63d2\u4ef6\u3001OpenSubdiv \u96c6\u6210\u3001libigl \u96c6\u6210\u3001CI/CD \u5de5\u4f5c\u6d41\u7b49\u8bf8\u591a\u529f\u80fd\u3002 \u5f20\u5265\u58eb\u53d1\u77e5\u4e4e\u6587\u7ae0\u7206\u8bba\uff1a\u6211\u4eec\u4e0d\u9700\u8981\u7a0b\u5e8f\u5458\uff01\u53ea\u9700\u8981\u5076\u5c14\u62db\u4e24\u4e2a\u5389\u5bb3\u4e00\u70b9\u7684\u5b9e\u4e60\u751f\uff0c\u505a\u4e2a\u4e00\u4e24\u5e74\uff0c\u628a\u8f6f\u4ef6\u505a\u5b8c\u4ee5\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u4ed6\u4eec\u4e86\uff0c\u663e\u7136\u5c0f\u5f6d\u8001\u5e08\u5c31\u662f\u8fd9\u6837\u4e00\u4e2a\u4e00\u6b21\u6027\u53c8\u7279\u522b\u597d\u7528\u7684\u5b9e\u4e60\u751f\u3002 \u67d0 Unity \u5c0f\u5382 (2024.08.12) \u4e00\u4e2a\u770b\u8d77\u6765\u53ef\u80fd\u662f\u8001\u677f\u7684\u4eba\u7269\u51fa\u9762\u8fce\u63a5\uff0c\u8fdb\u5165\u4e00\u4e2a\u72ec\u7acb\u7684\u4f1a\u8bae\u5ba4\u5f00\u59cb\u9762\u8c08\u3002 \u4e4b\u524d\u73a9\u8fc7\u54ea\u4e9b\u6e38\u620f\uff1f(\u4e3b\u8981\u662f\u8089\u9e3d\u548c\u6a21\u62df\u7ecf\u8425\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u6740\u622e\u5c16\u5854\u548cKSP\uff0c\u56e0\u4e3a\u4ed6\u4eec\u662fUnity\u6e38\u620f\uff0c\u8fd8\u4ecb\u7ecd\u4e86\u5236\u4f5c\u4ee5\u6492\u7684\u7ed3\u5408\u6a21\u7ec4\u7684\u7ecf\u5386\uff0c\u57fa\u4e8eLua API\u7684) \u9762\u8bd5\u5b98\u8bf4\u73b0\u5728 KSP2 \u6ca1\u6709\u5361\u987f\u4e86\uff0c\u56e0\u4e3a GC \u4f18\u5316\u4e86 \u95ee\u5b66\u8fc7Unity\u5417\uff1f(\u4e86\u89e3\u4e00\u70b98\uff0c\u4e4b\u524d\u505a\u8fc7KSP\u6a21\u7ec4) \u95ee\u90a3\u4e48\u4f60\u7684Unity\u7248\u672c\uff1f(\u7cdf\u7cd5\uff0c\u53ea\u80fd\u88c5\u50bb\u4e86\uff0c\u56e0\u4e3a\u5176\u5b9e\u5f88\u4e45\u6ca1\u6253\u5f00\u8fc7\u4e86\uff0c\u800c\u4e14\u65b0\u7535\u8111\u91cc\u4e5f\u6ca1\u6709\u4e0bUnity) \u8868\u793a\u4f60\u5e94\u8be5\u591a\u770b\u770bUnity\u5b98\u65b9\u6587\u6863\uff0c\u7279\u522b\u662f\u82f1\u6587\u7684\u6587\u6863 \u95eePBR\u6d41\u7a0b\uff1f(\u5206\u4e3aLambert\u548cCook-Torrance\u4e24\u4e2a\u6a21\u578b\uff0c\u5408\u5e76\u8d77\u6765\uff0clambert\u5f88\u7b80\u5355\u7684\u5168\u65b9\u5411\u968f\u673a\u6f2b\u53cd\u5c04\uff0c\u4ecb\u7ecd\u4e86NDF, GDF, FDF\u4e09\u4e2a\u51fd\u6570\u7684\u7269\u7406\u610f\u4e49) \u95eeCg\u7740\u8272\u8bed\u8a00\uff1f(Unity\u81ea\u5df1\u7684\u7740\u8272\u5668\u8bed\u8a00\uff0c\u4e0d\u719f\u6089\uff0c\u8868\u793a\u4e4b\u524d\u5199\u7684\u90fd\u662fGLSL\uff0c\u4f46\u6211\u77e5\u9053\u6240\u6709\u5f15\u64ce\u90fd\u6709\u4e00\u4e2a\u94a6\u5b9a\u8bed\u8a00\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u4f1a\u7ffb\u8bd1\u751f\u6210\u4e0d\u540c\u7684\u76ee\u6807\u8bed\u8a00\u6bd4\u5982GLSL\uff0cUnity\u4e5f\u652f\u6301\u5199GLSL\uff0c\u4f46\u90e8\u5206\u529f\u80fd\u7279\u6027API\u6709\u6240\u7f3a\u5931\uff0c\u6240\u4ee5\u4e3b\u8981\u8fd8\u662f\u5199Cg\uff0c\u5728GL\u540e\u7aef\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u751f\u6210GLSL\u7684) \u5c0f\u5f6d\u8001\u5e08\u63d0\u8d77\u4e3a\u4e86\u652f\u6301UE\uff0c\u7279\u522b\u505a\u4e86HLSL\u540e\u7aef(\u9762\u8bd5\u5b98\u9510\u8bc4\u4e86\u715e\u7b14DX\u4e0d\u8de8\u5e73\u53f0\uff0c\u73b0\u5728\u6e38\u620f\u4e3b\u8981\u8fd8\u662f\u57fa\u4e8eOpenGL\u5728\u505a\uff0cUE\u662f\u56e0\u4e3a\u5fae\u8f6f\u7ed9\u94b1\u4e86\u624d\u94a6\u5b9aHLSL\u4e3a\u4e3b\u8bed\u8a00\uff0c\u4f46\u5b9e\u9645\u4e0a\u4e5f\u6709\u7ffb\u8bd1\u5230GLSL\u7684OpenGL\u540e\u7aef) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u8868\u793a\u6211\u4eec\u505a\u7684\u662fUnity\u7684\u5fae\u4fe1\u5c0f\u6e38\u620f\uff0c\u56e0\u4e3a\u6700\u8fd1\u63a8\u51fa\u7684WebGL\u540e\u7aef(\u5c0f\u5f6d\u8001\u5e08\uff1a\u602a\u4e0d\u5f97\u53ef\u4ee5\u770b\u5230\u6700\u8fd1\u8fd9\u4e48\u591a\u5fae\u4fe1\u5c0f\u6e38\u620f) \u95ee\u4e86 Lua(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u5199\u7684 Lua \u811a\u672c\u5b9e\u73b0\u4ee5\u6492\u6a21\u7ec4) \u6211\u4eec\u4e0d\u662f\u8981\u5199 Lua\uff0c\u800c\u662f\u8981\u8c03\u7528 Lua \u7684 C \u63a5\u53e3\u54e6\uff01(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e5f\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u53c2\u4e0e\u7684\u4e00\u4e2a\u4ee5\u6492\u6a21\u7ec4\u9879\u76ee IsaacSocket \u5c31\u662f\u57fa\u4e8e C# \u5ba2\u6237\u7aef\uff0c\u52a8\u6001\u5f80\u4ee5\u6492\u8fdb\u7a0b\u6ce8\u5165 C++ DLL\uff0c\u52ab\u6301\u4ee5\u6492\u7684\u5404\u79cd\u56de\u8c03\uff0c\u7136\u540e\u66b4\u9732\u51fa Lua \u63a5\u53e3\uff0c\u521b\u5efa\u4e86\u4e00\u7cfb\u5217\u5bf9\u6e38\u620f\u5185 Lua \u811a\u672c\u53ef\u89c1\u7684 C++ \u51fd\u6570\uff0c\u5b9e\u73b0\u4ee5\u6492 API \u7684\u6269\u5c55\uff0c\u9700\u8981 lua_tonumber \u6765\u83b7\u53d6\u53c2\u6570\uff0clua_pushnumber \u6765\u8fd4\u56de\u503c\u7b49) \u95ee\u4e86 lua_State \u662f\u4ec0\u4e48(\u5c0f\u5f6d\u8001\u5e08\uff1a\u542b\u6709 lua \u7684\u5806\u6808\u5168\u5c40\u53d8\u91cf\u7b49\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u5404\u81ea\u72ec\u7acb) \u95ee\u5982\u4f55\u521b\u5efa\u4e00\u4e2a UI \u754c\u9762\uff1f\u9009\u62e9\u4e0d\u540c\u7684\u670d\u52a1\u5668\uff0c\u767b\u5f55(\u4f7f\u7528json+http\u5b9e\u73b0rpc\uff0c\u83b7\u5f97\u4e00\u4e2a\u5217\u8868\uff0c\u7136\u540e\u8bbe\u7f6e\u5217\u8868\uff0c\u5373\u53ef\u5229\u7528MVC\u521b\u5efa\u51fa\u754c\u9762) Unity \u7684 UI \u7cfb\u7edf\u4f1a\u5199\u5417\uff1f(\u4e0d\u4f1a\uff0c\u53ea\u77e5\u9053Qt\u6709QListView\u63a7\u4ef6\uff0cUnity\u53ef\u80fd\u4e5f\u6709\u5427\uff1f) \u851a\u6765\u5c0f\u6c7d\u8f66 (2024.08.15) 1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 2\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 \u6ca1\u67093\u9762\u4e86\uff0c\u539f\u56e0\u4e0d\u660e\u3002 \u5176\u57df\u79d1\u6280 (2024.09.03) 1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 \u8981\u6c42\u81ea\u6211\u4ecb\u7ecd(\u4e3b\u8981\u4ecb\u7ecd\u4e86\u6cfd\u68ee\u5728\u6e32\u67d3\u7684\u5de5\u4f5c\uff0cshader\u8282\u70b9\u7b49\uff0c\u4e0d\u4ec5\u8d1f\u8d23\u4e86Qt+OpenGL\u5b9e\u65f6\u53ef\u89c6\u5316\uff0c\u540e\u6765\u8fd8\u52a0\u5165\u4e86OptiX\u5b9e\u65f6\u5149\u8ffd\u652f\u6301) \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecdzeno\u7684shader\u8282\u70b9\u652f\u6301\u8f93\u51fa\u4e3aGLSL\u3001HLSL\u3001CUDA\u4e09\u79cd\u540e\u7aef\u683c\u5f0f\uff0c\u90fd\u662fcodegen\uff0c\u5176\u4e2dCUDA\u540e\u7aef\u91c7\u7528NVPTX\u7f16\u8bd1\uff0c\u4f9bOptiX\u4f7f\u7528 \u4ecb\u7ecdPBR\u6d41\u7a0b(albedo, metallic, roughness \u7b49\uff0c\u8fd8\u6709\u6cd5\u7ebf\u8d34\u56fe\u7684\u70d8\u70e4\uff0cIBL \u5149\u7167\u7b49) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u4ecb\u7ecd\u4e86\u516c\u53f8\u5185\u90e8\u662f\u6709\u5d4c\u5165\u5f0f(\u4e09\u7ef4\u6355\u83b7\u8bbe\u5907)\u548c\u7535\u8111\u7aef(\u7528\u4e8e\u67e5\u770b\u4e09\u7ef4\u6355\u83b7\u7ed3\u679c\u7684App)\uff0c\u5d4c\u5165\u5f0f\u8bbe\u5907\u53ea\u9700\u8981\u505a\u521d\u6b65\u7684\u6570\u636e\u5904\u7406\uff0c\u57fa\u4e8e\u56fd\u4ea7GPU(\u4f46\u662fCUDA\u63a5\u53e3)\uff0c\u521d\u6b65\u5904\u7406\u540e\u56de\u4f20\u7528\u6237\u7535\u8111\uff0c\u7535\u8111\u7aef\u53ef\u4ee5\u5047\u5b9a\u7528\u6237\u662fNVIDIA\u663e\u5361(\u4e5f\u662fCUDA\u63a5\u53e3)\u7528\u4e8e\u66f4massive\u7684\u540e\u5904\u7406\u548c\u6e32\u67d3\u53ef\u89c6\u5316 \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecd\u5728taichi three\u4e2d\u624b\u6413\u8f6f\u5149\u6805\u6e32\u67d3\u5668\u7684\u7ecf\u5386(\u652f\u6301ssr, ssgi, taa\u7b49) 2\u9762\uff08LeetCode\u5728\u7ebf\u9762\u8bd5\uff0c\u6709\u5171\u4eab\u4ee3\u7801\u7f16\u8f91\u5668\uff09 \u8981\u6c42\u5c0f\u5f6d\u8001\u5e08\u81ea\u6211\u4ecb\u7ecd(\u7b80\u5386\u4ed6\u5df2\u7ecf\u62ff\u5230\u770b\u7740\u4e86\uff0c\u5c31\u4e0d\u590d\u8bfb\u540d\u5b57\u548c\u5b66\u5386\u4e86\uff0c\u6240\u4ee5\u4e3b\u8981\u4ecb\u7ecd\u9879\u76ee\uff0c\u5728zeno\u4e2d\uff0c\u5c0f\u5f6d\u8001\u5e08\u62c5\u4efb\u6e32\u67d3\u548c\u8282\u70b9\u7cfb\u7edf\u7684\u5f00\u53d1\uff0c\u4ecb\u7ecdQt+OpenGL\u89c6\u7a97\u53ef\u89c6\u5316\uff0c\u4ecb\u7ecd\u8282\u70b9\u7cfb\u7edf\u7c7b\u4f3c\u4e8e\u4f4e\u4ee3\u7801\u7684\u4f18\u52bf\uff0c\u7b80\u8981\u4ecb\u7ecdtaichi, nbodysolver, co_async\u2026\u2026\u70ab\u8000\u9ad8\u6548\u7684\u534f\u7a0b\uff0c\u5e76\u5b89\u5229\u5c0f\u5f6d\u8001\u5e08\u6bd4\u7ad9\u9891\u9053\uff0ccpp\u516c\u5f00\u8bfe) \u9762\u8bd5\u5b98\u8868\u793a\u4e0d\u719fcpp20\uff0c\u63d0\u51fa\u8981\u4ee5cpp17\u4e3a\u57fa\u7840(\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u5728zeno\u548ctaichi\u4e5f\u90fd\u662f\u7528cpp17) cpp\u6709\u54ea\u56db\u5927cast(static_cast, dynamic_cast, const_cast, reinterpret_cast) static_cast vs dynamic_cast\u9002\u7528\u573a\u666f(\u5b50\u7c7b\u8f6c\u57fa\u7c7b\u603b\u662fstatic_cast\uff0c\u4e00\u4e2a\u57fa\u7c7b\u6307\u9488\uff0c\u5982\u679c\u4e0d\u80fd\u786e\u5b9a\u662f\u4e0d\u662f\u5b50\u7c7b\uff0c\u90a3\u5c31\u9700\u8981dynamic_cast\uff0c\u5982\u679c\u5931\u8d25\u4f1a\u8fd4\u56denullptr\uff0c\u8bb0\u5f97\u68c0\u67e5\uff01\u5982\u679cdynamic_cast\u5f15\u7528\u5219\u5931\u8d25\u629b\u51fabad_cast\u5f02\u5e38) dynamic_cast\u80cc\u540eRTTI\u539f\u7406(\u5b9e\u9645\u4e0a\u662f\u6bd4\u8f83typeid\u662f\u5426\u517c\u5bb9\uff0ctypeid\u6307\u9488\u5b58\u5728\u865a\u51fd\u6570\u8868\u91cc\uff0c\u53ea\u6709\u5e26\u6709\u81f3\u5c111\u4e2a\u865a\u51fd\u6570\u7684\u79f0\u4e3a\u201c\u591a\u6001\u7c7b\u201d\u7684\u7c7b\u578b\u4f1a\u751f\u6210RTTI\u4fe1\u606f\uff0c\u987a\u4fbf\u63a8\u9500\u4e86\u4e3a\u4ec0\u4e48llvm\u9009\u62e9\u5f00\u542f-fno-rtti\u548c-fno-exception\uff0c\u662f\u907f\u514d\u4e8c\u8fdb\u5236\u81a8\u80c0) llvm\u5173\u95ed\u4e86RTTI\uff0c\u90a3\u4ed6\u662f\u5982\u4f55\u53d8\u76f8\u5b9e\u73b0dynamic_cast\u7684\uff1f(\u6211\u77e5\u9053\uff0c\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff01\u5b9a\u4e49\u4e86getType\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u679a\u4e3e\uff0c\u7528\u4e8e\u6bd4\u8f83) \u53ef\u662f\u5982\u679cD2\u7ee7\u627fD1\u7ee7\u627fB\uff0c\u5982\u4f55\u4fdd\u8bc1D2\u4e5f\u53ef\u4ee5cast\u4e3aD1\uff1f(\u5b8c\u4e86\uff0cllvm\u6e90\u7801\u770b\u7684\u4e0d\u4ed4\u7ec6\uff0c\u53ea\u80fd\u7528\u4ee5\u6492\u7684\u505a\u6cd5\u76f2\u731c\u4e00\u4e2a\uff1a\u662fB\u6709getD1\u548cgetD2\u4e24\u4e2a\u865a\u51fd\u6570\uff01\u4ed6\u4eec\u9ed8\u8ba4\u8fd4\u56denullptr\uff0c\u53ea\u6709D1\u4f1a\u91cd\u5199getD1\uff0cD2\u4f1a\u91cd\u5199getD2\uff0c\u5185\u90e8\u90fd\u662f\u7b80\u5355\u7684\u8fd4\u56dethis) const_cast\u672a\u5b9a\u4e49\u884c\u4e3a(\u672c\u6765\u662fconst\u7684\u4e0d\u80fd\u53bb\u6389const\u540e\u8bbf\u95ee\uff0c\u5c55\u793a\u4e86\u6210\u5458\u51fd\u6570\u590d\u7528\u4e24\u4e2adata\u7684\u7528\u6cd5) const_cast\u540e\u8fd4\u56de\u6307\u9488\u6ca1\u95ee\u9898\uff0c\u9762\u8bd5\u5b98\u6539\u6210\u8fd4\u56de\u5f15\u7528\uff0c\u6d89\u53ca\u89e3\u5f15\u7528\uff0c\u95ee\u8fd9\u6837\u8fd8\u5b89\u5168\u5417\uff1f(\u8ff7\u60d1\u6027\u5f88\u5f3a\u7684\u95ee\u9898\uff0c\u88ab\u5c0f\u5f6d\u8001\u5e08\u8bc6\u7834\uff1a\u975econst\u5730\u89e3\u5f15\u7528const\u53d8\u91cf\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u53d6\uff0c\u5c31\u548cend\u8fed\u4ee3\u5668\u4e0d\u80fd\u89e3\u5f15\u7528\u4e00\u6837\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u5199\u8bbf\u95ee) const vs constexpr\u53d8\u91cf\u533a\u522b(const\u53ef\u4ee5\u6709\u5730\u5740\uff0c\u800cconstexpr\u4e0d\u4e00\u5b9a\u6709) reinterpret_cast\u7528\u6cd5\uff0c\u4ec0\u4e48\u60c5\u51b5\u4e0b\u5b89\u5168(\u5c0f\u5f6d\u8001\u5e08\u5199\u7ecf\u5178\u4e3e\u51faint\u548cfloat\u4e4b\u95f4bit-cast\u7684\u6848\u4f8b\uff0c\u4ecb\u7ecd\u503c\u8f6c\u6362\u548c\u6309\u4f4d\u8f6c\u6362\u7684\u533a\u522b\uff0c\u52fe\u5f15\u9762\u8bd5\u5b98\u4e0a\u94a9\uff0c\u4ed6\u80af\u5b9a\u8ba4\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4e0d\u77e5\u9053reinterpret_cast\u4e0d\u80fd\u505aint\u548cfloat\u7684\u6307\u9488\u8f6c\u6362\uff0c\u4e8e\u662f\u53d1\u95ee\uff1a) \u9762\u8bd5\u5b98\u5199\u51faint\u548cfloat\u6307\u9488\u5f3a\u8f6c\u5e76\u89e3\u5f15\u7528\u7684\u4ee3\u7801\uff0c\u95ee\u8fd9\u4e2a\u5b89\u5168\u5417\uff1f(\u4e0a\u94a9\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u5373\u7b54\uff1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e0d\u80fd\u7528reinterpret_cast\u8f6cint\u548cfloat\u6307\u9488\uff0c\u662f\u56e0\u4e3astrict-aliasing\u8ba4\u4e3aint\u548cfloat\u4e0d\u517c\u5bb9\uff0c\u8f6c\u6362\u540e\u89e3\u5f15\u7528\u5373UB\uff0c\u9762\u8bd5\u5b98\u8bf4\u4f3c\u4e4e\u53ea\u6709GCC\u4f1a\u7528\u8fd9\u4e2a\uff0c\u5c0f\u5f6d\u8001\u5e08\u7b54\uff1aGCC\u9ed8\u8ba4\u5f00\u542f\uff0c\u53ef\u4ee5\u7528-fno-strict-aliasing\u5173\u95ed\uff0cMSVC\u4e0d\u5229\u7528\u6b64\u89c4\u5219\u4f18\u5316\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u4ecb\u7ecd\u6307\u9488\u522b\u540d\u4e0e\u4f18\u5316\u7684\u5173\u7cfb\uff0c\u5373\u4e3a\u4ec0\u4e48\u63d0\u51fastrict-aliasing\u89c4\u5219\u7684\u539f\u56e0) \u5c0f\u5f6d\u8001\u5e08\u5f3a\u8c03int\u548cunsigned int\u662f\u517c\u5bb9\uff0c\u9762\u8bd5\u5b98\u5c31\u95ee\u4e3a\u4ec0\u4e48char\u53ef\u4ee5\uff1f(reinterpret_cast\u6709\u7834\u683c\u5141\u8bb8\u7684\u7279\u4f8b\uff0cchar,unsigned char,std::byte\u4e0e\u6240\u6709\u7c7b\u578b\u90fd\u517c\u5bb9\uff0c\u8f6c\u4e3achar\u6307\u9488\u540e\u53ef\u4ee5\u968f\u610f\u8bbf\u95ee\u4efb\u610f\u7c7b\u578b\u7684\u5185\u5b58\uff0c\u6307\u51fa\u662fcpp\u6807\u51c6\u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u89e3\u5e8f\u5217\u5316\u7684\u65b9\u4fbf\u6027) \u5982\u4f55\u5b9e\u73b0\u771f\u6b63\u5b89\u5168\u7684int\u548cfloat\u8f6c\u6362\uff1f(\u4f7f\u7528memcpy\u6216cpp20\u7684bit_cast\u662f\u5b89\u5168\u7684\uff0c\u5e76\u63a8\u9500memcpy vs bit_cast\u533a\u522b\uff1a\u867d\u7136cppref\u4e0abit_cast\u7684\u201c\u53c2\u8003\u5b9e\u73b0\u201d\u662fmemcpy\uff0c\u4f46\u5f97\u76ca\u4e8e\u5176\u57fa\u4e8e\u7f16\u8bd1\u5668\u5f00\u6d1e__builtin_bit_cast\uff0c\u8ba9bit_cast\u662fconstexpr\u51fd\u6570\u53ef\u7f16\u8bd1\u671f\u786e\u5b9a) inline\u5173\u952e\u5b57\u4f5c\u7528(non-odr external linkage\uff0c\u5efa\u8bae\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u7684\u51fd\u6570\u90fd\u52a0inline\uff0c\u5426\u5219\u591a\u4e2a.cpp\u6587\u4ef6\u4e2d\u4ea7\u751f\u591a\u4e2a\u5b9a\u4e49\uff0c\u89e6\u53d1\u94fe\u63a5\u5668odr\u62a5\u9519\uff0c\u800cinline\u5219\u662f\u975endr\u7684\u5916\u90e8\u94fe\u63a5) \u9762\u8bd5\u5b98\u95eeinline\u51fd\u6570\u591a\u4e2a\u6587\u4ef6\u4e2d\u770b\u5230\u7684\u51fd\u6570\u4f53\u5b9a\u4e49\u4e0d\u540c\uff0c\u4f46\u51fd\u6570\u53c2\u6570\u5217\u8868\u76f8\u540c\uff0c\u4f1a\u600e\u4e48\u6837\uff1f(\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6807\u51c6\u8981\u6c42\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709.cpp\u7ffb\u8bd1\u5355\u5143\u770b\u5230\u7684inline\u51fd\u6570\u5b9a\u4e49\u4e00\u81f4\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u5f80\u5f80\u5e76\u4e0d\u62a5\u9519) \u5c0f\u5f6d\u8001\u5e08\u63a8\u9500\uff1a\u8fd9\u5bfc\u81f4\u4f60\u5728cpp\u6587\u4ef6\u4e2d\u5b9a\u4e49\u975ePOD\u7c7b\u4f1a\u88ab\u5751\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9a\u4e49\u7684\u6210\u5458\u51fd\u6570\uff0c\u9ed8\u8ba4\u662finline\u7684\uff0c\u5305\u62ec\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5f53\u65f6\u5bfc\u81f4zeno\u8c03\u8bd5\u4e86\u534a\u5929(\u9762\u8bd5\u5b98\u8868\u793a\u4ed6\u4e4b\u524d\u96c6\u6210\u4e00\u4e2a\u5f00\u6e90\u5e93\u4e5f\u9047\u5230\u8fd9\u4e2a\u5751\uff0c\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u53ef\u4ee5\u5957\u533f\u540dnamespace\u89e3\u51b3) push_back vs emplace_back(2\u91cd\u8f7dvs\u4e07\u80fd\u5f15\u7528+\u53d8\u957f\u53c2\u6570\uff0cemplace\u53ef\u4ee5\u5c31\u5730\u5e26\u4efb\u610f\u53c2\u6570\u6784\u9020\u4f60\u7684\u5143\u7d20\u7c7b\u578b\uff0cemplace\u7684\u989d\u5916\u597d\u5904\u662f\u89e6\u53d1explicit\u7684\u6784\u9020\u51fd\u6570\u800c\u65e0\u9700\u663e\u5f0f\u5199\u51fa\u7c7b\u540d\uff0c\u4e5f\u5e26\u6765\u4e86\u5371\u9669\uff0c\u6240\u4ee5\u6211\u5728\u8bfe\u7a0b\u4e2d\u90fd\u4e0d\u63a8\u8350\u4f7f\u7528\uff0c\u5982\u9700\u907f\u514d\u79fb\u52a8\u53ef\u4ee5 vector> \uff0c\u8fd9\u8fd8\u80fd\u4f7f\u6269\u5bb9\u65f6\u4e5f\u4e0d\u89e6\u53d1\u79fb\u52a8) \u4ec0\u4e48\u60c5\u51b5\u4e0b\u4e0d\u4f1a\u79fb\u52a8\uff1f\u9762\u8bd5\u5b98\u4f3c\u4e4e\u5728\u8bd5\u63a2\u6211\u662f\u5426\u4e86\u89e3 vector \u6269\u5bb9\u539f\u7406(\u53ea\u6709\u5f53size>capacity\u65f6\u624d\u4f1a\u89e6\u53d1\uff0c\u6bcf\u6b21\u89e6\u53d1\u6269\u5bb9\u65f6gcc\u589e\u52a0\u52302 x size\uff0cmsvc\u5219\u662f1.5 x size\uff0c\u603b\u51712n\u6b21\u64cd\u4f5c\uff0c\u597d\u5904\u662f\u4fdd\u8bc1\u4e86\u603b\u4f53O(n)\u590d\u6742\u5ea6\uff0c\u6211\u4eec\u5efa\u8bae\u77e5\u9053\u957f\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528reserve\u63d0\u524d\u9884\u8ba2100\u7684capacity\uff0c\u8fd9\u6837\u53ea\u6709\u63a8\u5165\u7b2c101\u4e2a\u5143\u7d20\u624d\u4f1a\u6269\u5bb9\u5230200\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u63a8\u9500\u4e86vector, deque, list\u7684\u533a\u522b\uff0c\u8fed\u4ee3\u5668\u5931\u6548\u539f\u56e0) \u8fd8\u95ee\u4e86\u4e07\u80fd\u5f15\u7528\u548c\u5b8c\u7f8e\u8f6c\u53d1\u7684\u539f\u7406(\u5f15\u7528\u6298\u53e0) \u4ec0\u4e48\u662fPOD(\u57fa\u7840\u7c7b\u578b\u3001\u6307\u9488\u3001\u65e0\u7528\u6237\u6784\u9020\u51fd\u6570\u7684\u7eaf\u57fa\u7840\u7c7b\u578b\u7ec4\u6210\u7684\u7ed3\u6784\u4f53) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1avector\u8d85\u7f13\u5b58\u5927resize\u5bfc\u81f4memset\u6027\u80fd\u5f71\u54cd\uff1f(\u62ff\u51fa\u6211\u7684tbb\u8bfe\u7a0b\u7684parallel_filter\u6848\u4f8b\uff0c\u5229\u7528pod\u6a21\u677f\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u719f\u6089\u7f13\u5b58\uff0c\u4e0d\u7528\u63d0\u95ee\u4e86) \u9762\u8bd5\u5b98\u63d0\u95eePIMPL\u6a21\u5f0f(\u5199C::Impl\u7ed9\u4ed6\u770b\uff0c\u53c8\u95eePIMPL\u7684\u76ee\u7684\u662f\u4ec0\u4e48\uff0c\u4e00\u5f00\u59cb\u7b54\uff1a\u5206\u79bb\u5b9a\u4e49\uff0c\u52a0\u901f\u7f16\u8bd1\uff0c\u95ee\u8fd8\u6709\u4ec0\u4e48\u4f5c\u7528\u5417\uff1f\u4fdd\u6301abi\u7a33\u5b9a\uff0c\u4e0d\u7528\u91cd\u65b0\u7f16\u8bd1\u4f9d\u8d56\u8005\uff0c\u53ef\u7528\u4e8e\u63d2\u4ef6\u70ed\u88c5\u8f7d) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48C\u7684\u6784\u9020\u51fd\u6570\u91cc\u4f1a\u9700\u8981unique_ptr\u7c7b\u578b\u6790\u6784\u51fd\u6570\u7684\u4fe1\u606f\u5417\uff1f(\u9762\u8bd5\u5b98\uff1a\u56e0\u4e3a\u6790\u6784\u51fd\u6570\u9700\u8981\u77e5\u9053sizeof!=0\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u4f46\u662f\uff0cC\u7684\u6790\u6784\u51fd\u6570\u88ab\u8f6c\u79fb\u5230\u4e86C.cpp\uff0c\u4e3a\u4ec0\u4e48\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521d\u59cbunique_ptr\u4e3anullptr\uff0c\u4ecd\u7136\u7f16\u8bd1\u51fa\u9519\uff1f\u9762\u8bd5\u5b98\u652f\u652f\u543e\u543e\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u56e0\u4e3a\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u5f02\u5e38\uff0c\u5bfc\u81f4\u4e4b\u524d\u521d\u59cb\u5316\u8fc7\u7684\u6210\u5458\u6790\u6784\uff0c\u518d\u6b21\u5411\u4ed6\u515c\u552ecpp\u5f02\u5e38\u9b45\u529b\u65f6\u523b) q\u6307\u9488 vs d\u6307\u9488(Qt\u5b9e\u73b0cow\u548cpimpl\u7684\u7ec6\u8282\uff0c\u56e0\u4e3a\u5e73\u65f6\u6ca1\u6ce8\u610f\u770bqt\u5934\u6587\u4ef6\u6e90\u7801\uff0c\u5c0f\u5f6d\u8001\u5e08\u552f\u4e00\u683d\u8ddf\u5934\u7684\u9898\uff0c\u8bf4\u662f\u770b\u5230\u7b80\u5386\u5199\u7684Qt\u5c31\u95ee\u4e86\uff0c\u5e76\u8868\u793a\u4e4b\u524dzeno\u91cc\u4e3b\u8981\u662f\u7528PyQt) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1ac++11 string\u4e3a\u4ec0\u4e48\u6253\u7834abi(\u56e0\u4e3ac++98 string\u91c7\u7528cow\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u6a21\u578b\u5e38\u8bc6\u201c\u5171\u4eab\u8bfb\u5b89\u5168\u201d) make_shared vs shared_ptr new\u7684\u533a\u522b(\u53ea\u9700\u4e00\u6b21\u6027\u5206\u914d\uff0c\u65e0\u9700\u518dnew SpCounter\uff0c\u539f\u7406\u662foperator new+placement new) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48shared_ptr\u7684\u6784\u9020\u51fd\u6570\u6ca1\u6709noexcept\u5417\uff1f(\u5c31\u662f\u56e0\u4e3a\u8981new SpCounter) \u662foperator new\u8fd8\u662fnew_allocator\uff1f(\u9ed8\u8ba4\u662fnew_allocator\uff0c\u53ef\u7528allocate_shared\u66ff\u6362\u6389) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053make_shared_for_overwrite\u7684\u533a\u522b\u5417(\u91c7\u7528default-init\uff0cnew\u8868\u8fbe\u5f0f\u540e\u6ca1\u6709\u4e86\u62ec\u53f7\uff0c\u53ef\u907f\u514dPOD\u7c7b\u578b0\u521d\u59cb\u5316\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u8fd9\u4e2a\u6211\u90fd\u6ca1\u4e86\u89e3\u8fc7) CRTP(\u5947\u5f02\u9012\u5f52\u6a21\u677f\u6a21\u5f0f\uff0c\u6700\u521d\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u8981\u5b9e\u73b0\u83b7\u53d6\u5b50\u7c7b\u6307\u9488self\uff0c\u63a8\u9500\u4e86cpp\u6a21\u677f\u7c7b\u5ef6\u8fdf\u5b9e\u4f8b\u5316\u6210\u5458\u51fd\u6570\u7684\u673a\u5236\uff0c\u5176\u5b9eCRTP\u8fd8\u80fd\u7528\u4e8e\u5b9e\u73b0\u539f\u578b\u6a21\u5f0f\u548cvisitor\u6a21\u5f0f\uff0c\u56e0\u4e3a\u65f6\u95f4\u5173\u7cfb\u6ca1\u6765\u5f97\u53ca\u8bf4) \u865a\u51fd\u6570\u4e3a\u4ec0\u4e48\u4f4e\u6548\uff1f\u865a\u51fd\u6570\u5982\u4f55\u4f18\u5316(\u56e0\u4e3a\u9700\u8981call\u4e00\u4e2a\u6307\u9488\uff0ccpu\u65e0\u6cd5\u9884\u77e5\uff0c\u4f7f\u7528final\uff0c\u4e0d\u7528\u8bfb\u53d6\u865a\u51fd\u6570\u6307\u9488\u8868\uff0c\u7136\u540e\u8bf4\u660e\u4e86vecB\u62c6\u6210vecD1\u548cvecD2\u66f4\u9ad8\u6548) shared_from_this\u5b9e\u73b0(\u672c\u6765\u8981\u6211\u5199\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6765\u4e0d\u53ca\u5199\uff0c\u4f46\u662f\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u51fa\u8fc7\u624b\u6413shared\u5168\u5bb6\u6876\u7684\u89c6\u9891\uff0c\u9762\u8bd5\u5b98\u53ea\u597d\u653e\u5fc3) \u4f60\u5bf9\u54ea\u4e2a\u9886\u57df\u611f\u5174\u8da3\uff1f(\u5f53\u7136\u662f\u6e32\u67d3\uff0c\u6211\u4ece\u5c0f\u505a\u5230\u5927\uff0c\u5e76\u8868\u793a\u6027\u80fd\u4f18\u5316\u8fd9\u4e00\u5757\u4e5f\u5c3d\u7ba1\u8bf7\u6559\u5c0f\u5f6d\u8001\u5e08\uff0c\u6709cuda\u548csimd\u4f18\u5316\u5ba2\u6237\u7ecf\u9a8c) \u8fd8\u6709\u4ec0\u4e48\u95ee\u9898\u5bf9\u672c\u516c\u53f8\u5417\uff1f(\u65f6\u95f4\u4e0d\u591a\u4e86\uff0c\u5c31\u95ee\u8981\u4e0d\u8981\u73b0\u5728\u5f00\u59cb\u5b66\u4e60\u4e09\u7ef4\u91cd\u5efa\uff0c\u6216\u8005\u53ef\u4ee5\u8bd5\u8bd5\u770b\u5ba2\u6237\u7aef\uff0c\u8bf4\u5c97\u4f4d\u9009\u62e9\u53ef\u4ee5\u4e4b\u540e\u548chr\u6c9f\u901a\uff0c\u5e76\u5411\u6211\u63a8\u9500\u4e863dgs\uff0c\u7403\u978b\u51fd\u6570\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u597d\u591apaper\u5440\uff1f\u770b\u4e86\u51e0\u4e2a\u6548\u679c\u56fe\uff0c\u5178\u4e2d\u5178\u4e4bOurs\u6c38\u8fdc\u662f\u6700\u597d\u7684) 3\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\uff09 \u53c8\u4ecb\u7ecd\u4e86zeno\u548ctaichi\uff0c\u95ee\u4e86\u70b9\u4e91\u76f8\u5173\u95ee\u9898\uff0c\u5f88\u5feb\u7ed3\u675f\u4e86\u3002 4\u9762\uff08\u62c9\u6295\u8d44\u7684\u5408\u4f19\u4eba\u4eb2\u81ea\u7ebf\u4e0b\u89c1\u9762\uff09 \u5546\u573a\u5168\u90e8\u5173\u95ed\u4e86\uff0c\u661f\u5df4\u514b\u8fd8\u5f00\u7740 \u4ecb\u7ecd\u4e00\u4e0b\u4f60\u81ea\u5df18\uff08\u53c8\u662f zeno\uff09 \u95ee\u4e86\u4e0a\u6b21\u7684\u9762\u8bd5\u5b98\u600e\u4e48\u6837\u5440\uff08\u6211\u770b\u4e86\u63a8\u8350\u7684 3dgs\uff0c\u53d1\u73b0\u662f\u628a\u626b\u63cf\u51fa\u6765\u7684\u70b9\u4e91\uff0c\u9010\u6b65\u8f6c\u6362\u4e3a\u692d\u5706\u7403\u6e32\u67d3\uff09 \u4f60\u77e5\u9053\uff0c\u73b0\u5728\u4e3b\u6d41\u56fe\u5f62\u5b66\u90fd\u662f\u4e09\u89d2\u5f62\u7f51\u683c\uff0c\u90a3\u4e48\u8fd9\u79cd\u70b9\u4e91\u8981\u5982\u4f55\u6e32\u67d3\u5462\uff1f\uff08\u70b9\u4e91\u7684\u8bdd\u53ef\u4ee5\u5148\u7528 marching cube \u8f6c\u4e09\u89d2\u5f62\u9762\uff0czeno \u7684\u6d41\u4f53\u5c31\u662f\u8fd9\u6837\u7684\uff09 \u4f46\u662f\u6027\u80fd\u4e0d\u591f\uff0c\u4e0d\u80fd\u4fdd\u8bc1\u5b9e\u65f6\uff08\u53ef\u4ee5\u7528\u5c4f\u5e55\u7a7a\u95f4\u6d41\u4f53\uff0c\u4f46\u662f\u6548\u679c\u4e00\u822c\uff0c\u6211\u4eec\u505a\u7535\u5f71\u7684\u9700\u8981\u9ad8\u8d28\u91cf\u7684\u79bb\u7ebf\u6e32\u67d3\uff0c\u4e0d\u592a\u6ce8\u91cd\u5b9e\u65f6\u6027\uff0c\u5b9e\u65f6\u692d\u7403\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u7528\u5149\u8ffd\uff0c\u7b97\u5c04\u7ebf\u4e0e\u692d\u7403\u8868\u9762\u6c42\u4ea4\u5373\u53ef\uff0c\u4e0d\u8fc7\u82f1\u4f1f\u8fbe\u7684\u786c\u4ef6\u52a0\u901f\u53ea\u6709\u4e09\u89d2\u5f62\u7684\uff0c\u4f46\u662f GPU Gems \u4e0a\u7684 BVH \u52a0\u901f\u6c42\u4ea4\u4ee3\u7801\u7528\u4e8e\u692d\u7403\u4e5f\u662f\u53ef\u4ee5\u62ff\u6765\u53c2\u8003\u7684\uff09 \u62ff\u51fa\u4e00\u53f0 3D \u626b\u63cf\u673a\u5668\uff0c\u8bf4\u4f60\u77e5\u9053\u6211\u4eec\u8fd9\u4e2a\u6d4b\u7ed8\u673a\u5668\u662f\u5982\u4f55\u5b9a\u4f4d\u7684\u5417\uff08\u60ef\u6027\u5236\u5bfc\uff0c\u91cc\u9762\u6709\u52a0\u901f\u5ea6\u8ba1\uff0c\u6c42\u4e8c\u9636\u79ef\u5206\u5c31\u53ef\u4ee5\u5f97\u5230\u4f4d\u7f6e\uff09 \u4f46\u662f\u8fd9\u6837\u65f6\u95f4\u957f\u4f1a\u6709\u7d2f\u8ba1\u8bef\u5dee\uff0c\u5982\u4f55\u6d88\u9664\u8bef\u5dee\uff1f\uff08\u53ef\u4ee5\u7528 GPS \u5b9a\u4f4d\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5149\u5b66\u6444\u50cf\u5934\u626b\u63cf\u7684\u7ed3\u679c\uff0c\u786e\u5b9a\u81ea\u5df1\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u5fc5\u8981\u65f6\u53ef\u4ee5\u8d34\u51e0\u4e2a\u8bc6\u522b\u7eb8\u7247\u5728\u5899\u4e0a\u65b9\u4fbf\u7a0b\u5e8f\u68c0\u6d4b\uff09 \u662f\u7684\uff0c\u5b9e\u9645\u4e0a\u6211\u4eec\u5728\u6237\u5916\u4f1a\u7528 GPS \u5b9a\u4f4d\uff0c\u77ff\u6d1e\u91cc\u5c31\u4f1a\u7528\u5149\u5b66\u7684\u5b9a\u4f4d\u65b9\u6cd5\uff0c\u6d88\u9664\u60ef\u6027\u5236\u5bfc\u7684\u7d2f\u8ba1\u8bef\u5dee\u3002 \u90a3\u4e48 GPS \u536b\u661f\u5b9a\u4f4d\u7684\u539f\u7406\u4f60\u77e5\u9053\u5417\uff1f\uff08\u4e09\u9897 GPS \u536b\u661f\u53d1\u51fa\u4e0d\u540c\u76f8\u4f4d\u7684\u7535\u78c1\u6ce2\uff0c\u56e0\u4e3a\u5149\u901f\u6709\u9650\uff0c\u79fb\u52a8\u8bbe\u5907\u901a\u8fc7\u68c0\u6d4b\u76f8\u4f4d\u5dee\uff0c\u5c31\u77e5\u9053\u81ea\u5df1\u8ddd\u79bb\u4e09\u9897\u536b\u661f\u7684\u8ddd\u79bb\uff0c\u7136\u540e\u4e09\u4e2a\u8ddd\u79bb\u5c31\u80fd\u552f\u4e00\u786e\u5b9a\u4e00\u4e2a\u70b9\uff09 \u96c5\u79d1\u8d1d\u601d (2024.09.03) \u4ecb\u7ecd\u4e00\u4e0b\u81ea\u5df1\uff08\u53c8\u4ecb\u7ecdzeno\u662f\u4e00\u6b3eCAD\u7c7b\u7684\u9879\u76ee\uff09 \u54c8\u5e0c\u8868\uff08\u4ecb\u7ecdunordered_map\u57fa\u4e8e\u94fe\u8868\u6cd5\uff0c\u6807\u51c6\u5e93\u7684hashint\u662f\u6052\u7b49\u51fd\u6570\uff0cabsl\u7684\u5b9e\u73b0\u57fa\u4e8e\u5f00\u653e\u5730\u5740\u6cd5\u66f4\u9ad8\u6548\uff0cjava\u4e5f\u662f\u94fe\u8868\u6cd5\uff0c\u4f46\u94fe\u8868\u8fc7\u957f\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u7b49\uff09 \u7ea2\u9ed1\u6811\uff08\u4e94\u5927\u89c4\u5219\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u4e94\u4e2a\u89c4\u5219\u80fd\u4fdd\u8bc1\u4e0d\u8d85\u8fc72\u500d\u6df1\u5ea6\uff0c\u540c\u65f6\u6bd4\u4e8c\u53c9\u5e73\u8861\u6811\u9ad8\u6548\uff09 \u7ea2\u9ed1\u6811\u5de6\u65cb\u53f3\u65cb\u64cd\u4f5c\uff08\u53f3\u513f\u5b50\u66ff\u6362\u7236\u4eb2\uff0c\u7236\u4eb2\u53d8\u6210\u5de6\u513f\u5b50\uff09 \u9762\u8bd5\u5b98\u900f\u9732\uff1a\u5b9e\u9645\u4e0a\u7ea2\u9ed1\u6811\u5c31\u662f\u4e00\u4e2a4\u9636\u6811\uff0c\u4f60\u60f3\u60f3\u770b\uff08\u786e\u5b9e\uff0c\u5982\u679c\u628a\u7ea2\u9ed1\u4e24\u5c42\u770b\u4f5c\u4e00\u5c42\u7684\u8bdd\uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a4\u9636\u5e73\u8861\u6811\uff09 OpenGL \u6e32\u67d3\u7ba1\u7ebf\uff083d\u9876\u70b9\u6570\u636e -> vert shader (\u77e9\u9635\u53d8\u6362) -> \u5149\u6805\u5316+\u63d2\u503c+\u6df1\u5ea6\u6d4b\u8bd5 -> frag shader (\u524d\u5411\u7740\u8272) -> G-buffer -> \u5ef6\u8fdf\u6e32\u67d3 (\u540e\u5411\u7740\u8272) -> \u540e\u5904\u7406 -> \u5c4f\u5e55\uff09 \u6765\u9762\u8bd5\u7684\u4eba\u4e2d\uff0c\u4f60\u662f\u6211\u89c1\u8fc7\u6280\u672f\u6700\u597d\u7684\u4e00\u4e2a\uff0c\u4e4b\u524d\u4e00\u4e2a\u7855\u58eb\uff0c\u4e0a\u6765\u54c8\u5e0c\u8868\u5c31\u652f\u652f\u543e\u543e\u6302\u6389\u3002 \u4e8b\u540e\uff1a\u5df2\u5f55\u53d6\uff0c\u6b63\u5728\u4e0a\u73eding\u2026\u2026\u53c8\u662f\u505a Qt + OpenGL \u7684\u9879\u76ee","title":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c"},{"location":"interview/#_1","text":"\u6700\u8fd1\u597d\u50cf\u5f88\u6d41\u884c\u9762\u7ecf\u2026\u2026\u5c0f\u5f6d\u8001\u5e08\u4e5f\u6765\u5199\u4e00\u4e0b\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u9762\u8bd5\u7ecf\u9a8c"},{"location":"interview/#20211207","text":"\u5f20\u5265\u58eb\u5728taichi\u8bba\u575b\u91cc\u4e3b\u52a8\u627e\u4e0a\u6765\u8054\u7cfb\uff0c\u8868\u793a\u6211\u4eec\u5f88\u6b23\u8d4f\u4f60\u5728\u592a\u6781\u7684\u4f1f\u5927\u8d21\u732e\uff0c\u5e0c\u671b\u548c\u6211\u4eec\u6cfd\u68ee\u4e00\u8d77\u521b\u9020\u66f4\u597d\u7684\u65b0\u4ea7\u54c1(\u4ec0\u4e48\u6316\u5899\u89d2) \u5f20\u5265\u58eb\u5728\u5fae\u4fe1\u7535\u8bdd\u91cc\u5f00\u59cb\u8bed\u97f3\u9762\u8bd5\u4e86\uff0c\u4e0a\u6765\u5c31\u8981\u6c42\u5b9e\u73b0sqrt\u51fd\u6570(\u725b\u987f\u8fed\u4ee3\u6cd5\u5373\u53ef\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e0d\u5c0f\u5fc3\u5199\u9519\uff0c\u6709\u6b7b\u5faa\u73af\uff0c\u5f20\u5265\u58eb\u8868\u793a\u4e0d\u8981\u7d27\uff0c\u8fd9\u4e2a\u4f60\u80af\u5b9a\u73b0\u5b9e\u4e2d\u5f88\u5bb9\u6613\u8c03\u8bd5\u6539\u6b63\u7684\uff0c\u4e3b\u8981\u662f\u725b\u987f\u8fed\u4ee3\u9700\u8981\u5bfc\u6570\u7684\u89e3\u6790\u5f0f\uff0c\u5bb9\u6613\u5199\u9519\uff0cnaive\u7684\u521d\u5b66\u8005\u4e5f\u53ef\u4ee5\u9009\u62e9\u5199\u4e8c\u5206\u6cd5\uff0c\u4f59\u5207\u6cd5\u7b49) \u6709\u6ca1\u6709\u4e86\u89e3\u8fc7\u96f7\u795e3\u7684\u5feb\u901fsqrt\u51fd\u6570\uff1f(\u77e5\u9053\uff0c\u4f46\u597d\u50cf\u662f\u795e\u5947\u7684\u4e8c\u8fdb\u5236\u8fd0\u7b97\uff0c\u6ca1\u6709\u6df1\u5165\u4e86\u89e3\u8fc7\u4e3a\u4ec0\u4e48\u8fd9\u6837\u505a) \u77e5\u9053float\u7684\u5e03\u5c40\u5427(23\u4f4d\u5e95\u6570mantissa\uff0c8\u4f4d\u6307\u6570exponent\uff0c1\u4f4d\u7b26\u53f7sign) \u800c\u725b\u987f\u8fed\u4ee3\u6cd5\u9700\u8981\u8fd1\u4f3c\uff0csqrt\u6700\u597d\u7684\u8fd1\u4f3c\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u628aexponent\u4f4d\u9664\u4ee52\uff0c\u5bf9\u4e0d\u5bf9\uff1f(\u5c0f\u5f6d\u8001\u5e08\u604d\u7136\u5927\u609f\uff0c\u602a\u4e0d\u5f97\u9700\u8981\u53f3\u79fb1\u4f4d\uff0c\u539f\u6765\u662f\u8ba9exponent\u96642\uff0c\u96f7\u795e\u7684sqrt\u56e0\u4e3a\u6709\u826f\u597d\u7684\u8fd1\u4f3c\u521d\u503c\uff0c\u63a5\u4e0b\u6765\u5c31\u53ea\u9700\u8981\u4e00\u4e24\u6b65\u5c31\u80fd\u6536\u655b) \u63a5\u4e0b\u6765\u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u6211\u6709\u4ece 1 \u5230 100 \u8fd9 100 \u4e2a\u6570\uff0c\u7ec4\u6210\u8d85\u957f\u7684\u6570\u7ec4\uff0c\u968f\u673a\u6392\u5217\uff0c\u73b0\u5728\u8fd9\u91cc\u9762\u7f3a\u5c11\u4e86\u4e00\u4f4d(\u6bd4\u5982 1 2 3 4 5 7 8 9 10 \u5c31\u662f\u7f3a\u5c11\u4e86 6) \u73b0\u5728\uff0c\u6211\u4e00\u8fb9\u62a5\u6570\u4f60\u4e00\u8fb9\u64cd\u4f5c\uff0c\u6211\u62a5\u5b8c\u7684\u90a3\u4e00\u523b\uff0c\u4f60\u5fc5\u987b\u7acb\u5373\u544a\u8bc9\u6211\uff0c\u7f3a\u5931\u7684\u90a3\u4e00\u4e2a\u6570\u662f\u4ec0\u4e48\uff0c\u5e76\u4e14\u4e0d\u5141\u8bb8\u4f7f\u7528\u8bb0\u4e8b\u672c(\u4e5f\u5c31\u662f\u8981\u6c42\u5e38\u6570\u7a7a\u95f4\u590d\u6742\u5ea6\uff0c\u5f88\u7b80\u5355\uff0c\u4f60\u62a5\u7684\u540c\u65f6\u6211\u5f80\u4e00\u4e2a\u8ba1\u6570\u5668\u91cc\u7d2f\u52a0\u6c42\u548c\uff0c\u7136\u540e\u7b97\u51fa\u6765\u7684\u603b\u6c42\u548c\u548c 5050 \u76f8\u51cf\uff0c\u5f97\u5230\u7684\u5c31\u662f\u7f3a\u5931\u7684\u90a3\u4e2a\u6570\u4e86\uff0c\u6bd4\u5982 1+2+3+4+5+7+8+9+10 - 55 = -6\uff0c\u90a3\u4e48\u5c31\u77e5\u9053\u7f3a\u7684\u662f 6) \u5982\u679c\u6211\u662f\u7f3a\u4e86\u4e24\u4e2a\u6570\u5462\uff1f(\u90a3\u6211\u5f04\u4e24\u4e2a\u8ba1\u6570\u5668\uff0c\u4e00\u4e2a\u6c42\u548c\uff0c\u4e00\u4e2a\u6c42\u79ef\uff0c\u7136\u540e\u8054\u7acb\u4e8c\u5143\u4e8c\u6b21\u65b9\u7a0b) \u6211\u63d0\u4f9b\u4e00\u4e2a\u751f\u62100\u52301\u533a\u95f4\u5747\u5300\u968f\u673a\u6570\u7684\u51fd\u6570frand\uff0c\u5982\u679c\u6211\u6307\u5b9a\u4e00\u4e2a\u5206\u5e03\uff0c\u6bd4\u5982\u8981\u6c42\u9ad8\u65af\u5206\u5e03\uff0c\u5982\u4f55\u751f\u6210\u7b26\u5408\u8fd9\u4e2a\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff1f(frand\u662f\u5747\u5300\u968f\u673a\u6570\u51fd\u6570\uff0c\u8981\u6620\u5c04\u5230\u6307\u5b9a\u5bc6\u5ea6\u5206\u5e03\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u5148\u5bf9\u8be5\u6982\u7387\u5bc6\u5ea6\u51fd\u6570pdf\u6c42\u79ef\u5206\uff0c\u5f97\u5230\u7d2f\u79ef\u6982\u7387\u51fd\u6570cdf\uff0c\u6c42\u5176\u53cd\u51fd\u6570icdf\uff0c\u7136\u540e\u4f7f\u7528icdf(frand())\u5373\u4e3a\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\u751f\u6210\u51fd\u6570\uff0c\u4f8b\u5982\u5bf9\u4e8e\u9ad8\u65af\u5206\u5e03\u6765\u8bf4\uff0c\u4ed6\u7684cdf\u51fd\u6570\u662ferf\uff0c\u4e5f\u5c31\u662ferfinv(frand())\u53ef\u4ee5\u751f\u6210\u9ad8\u65af\u5206\u5e03\u7684\u968f\u673a\u6570\uff09 \u5199\u4e00\u4e2a\u51fd\u6570\uff0c\u751f\u6210\u4e00\u4e2a\u5706\u5f62\u5185\u5747\u5300\u5206\u5e03\u7684\u70b9(\u521d\u5b66\u8005naive\u7684\u5199\u6cd5\uff1a\u5148\u751f\u6210\u4e00\u4e2a\u6b63\u65b9\u5f62\u7684\u5747\u5300\u5206\u5e03\u70b9\uff0c\u7136\u540e\u5224\u5b9a\u662f\u5426\u5728\u534a\u5f841\u5185\uff0c\u5982\u679c\u5728\u5219\u4fdd\u7559\uff0c\u5426\u5219\u91cd\u65b0\u751f\u6210\uff0c\u76f4\u5230\u751f\u6210\u5728\u534a\u5f84\u5185\uff1b\u5c0f\u5f6d\u8001\u5e08\u7684\u5199\u6cd5\uff1a\u9996\u5148\u6c42\u5706\u5f62\u5468\u957fS=2pir\u7684icdf\uff0c\u7136\u540eblahblah\uff0c\u6700\u7ec8\u662fr=icdf(frand())\uff0c\u7136\u540e\u518d\u968f\u673a\u4e00\u4e2atheta=frand()*2pi\uff0cx=rcostheta\uff0cy=rsintheta) \u5047\u5982\u6211\u6307\u5b9a\u7684\u51fd\u6570\u4e0d\u662f\u4e00\u4e2a\u89e3\u6790\u5f0f\uff0c\u800c\u662f\u4e00\u4e2a\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u600e\u4e48\u751f\u6210\u7b26\u5408\u8be5\u5206\u5e03\u7684\u968f\u673a\u6570\uff1f(\u9996\u5148\u6c42\u8be5\u5bc6\u5ea6\u6570\u7ec4\u7684\u524d\u7f00\u548cprefix sum\uff0c\u7136\u540er=frand()\uff0c\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e0b\u6807\u4f4d\u7f6e\uff0c\u8be5\u4e0b\u6807\u5373\u4e3a\u8981\u751f\u6210\u7684\u968f\u673a\u6570\uff0c\u5982\u679c\u6709\u4e00\u4e2a\u503c\u5217\u8868\uff0c\u5219\u7528\u4e0b\u6807\u8bbf\u95ee\u8fd9\u4e2a\u503c\u5217\u8868\uff0c\u5982\u679c\u9700\u8981\u8fde\u7eed\u53d8\u5316\uff0c\u53ef\u4ee5\u5728\u7b2c\u4e00\u4e2a\u5927\u4e8e\u7b49\u4e8er\u548c\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4e24\u4e2a\u5143\u7d20\u4e4b\u95f4\u6309r\u591a\u51fa\u7684\u4f59\u6570\u63d2\u503c) \u53ef\u662f\u904d\u5386\u53bb\u67e5\u627e\u7b2c\u4e00\u4e2a\u5927\u4e8er\u7684\u4f4d\u7f6e\u53ef\u80fd\u4f1a\u5f88\u6162\uff0c\u600e\u4e48\u52a0\u901f\uff1f(\u4e8c\u5206\u6cd5\u641c\u7d22\u8be5\u79bb\u6563\u7684\u5bc6\u5ea6\u6570\u7ec4\uff0c\u53ef\u4ee5\u7528\u6807\u51c6\u5e93\u7684lower_bound) \u4e8b\u540e \u540e\u6765\u5c0f\u5f6d\u8001\u5e08\u5728\u804c\u671f\u95f4\uff0c\u5f20\u5265\u58eb\u4e00\u987f\u5439\u6367\uff1a\u4f60\u662f\u6211\u4eec\u8fd9\u91cc\u552f\u4e00\u4e00\u4e2a\u901a\u8fc7\u7845\u8c37\u7ea7\u4eba\u624d\u6d4b\u8bd5\u7684\u5458\u5de5\uff0c\u4e00\u89c1\u5230\u65b0\u5458\u5de5\u5c31\u5439\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u770b\u770b\u4eba\u5bb6\u5c0f\u5f6d\u8001\u5e08\u3002 \u5f20\u5265\u58eb\u8fd8\u753b\u51fa\u4e86\u671f\u6743\u5927\u997c\uff0c\u8bb2\u4e86\u4e00\u7cfb\u5217\u6211\u542c\u4e0d\u61c2\u7684\u865a\u62df\u671f\u6743\u6982\u5ff5\u91d1\u6eb6\u672f\u8bed\u540e\uff0c\u603b\u4e4b\u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\u9f13\u52b1\u5c0f\u5f6d\u8001\u5e08\u594b\u6597\uff0c\u594b\u6597\u7684\u516c\u53f8\u80a1\u4ef7\u6da8\u4e86\u5c31\u80fd\u5206\u7ea2\uff0c\u4f46\u76f4\u5230\u6700\u540e\u90fd\u6ca1\u6709\u5151\u73b0\uff0c\u800c\u4e14\u636e\u4e86\u89e3\u4e0a\u5e02\u516c\u53f8\u624d\u6709\u671f\u6743\u2026\u2026 \u5c0f\u5f6d\u8001\u5e08\u770b\u5230\u5f20\u5265\u58eb\u8fd9\u4e48\u91cd\u7528\uff0c\u4ee5\u4e3a\u6bd5\u4e1a\u4ee5\u540e\u80af\u5b9a\u7ed9\u8f6c\u6b63\u4e86\uff0c\u6240\u4ee5\u5c31\u6ca1\u6709\u8003\u7814\uff0c\u6ca1\u6709\u53bb\u770b\u6821\u62db\uff0c\u4e5f\u6ca1\u6709\u63a5\u53d7\u5b66\u6821\u7684\u5bf9\u63a5\uff0c\u5fd8\u6211\u5730\u4f3a\u5019zeno\u5de5\u4f5c\uff0c\u6253\u7b97\u4e00\u6bd5\u4e1a\u5c31\u76f4\u63a5\u53bb\u6df1\u5733\u4f3a\u5019\u5f20\u5265\u58eb\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728 zeno \u7684\u5de5\u4f5c\u57fa\u672c\u5b8c\u6210\u4e86\uff0c\u627e\u4e0d\u5230\u6709\u4ec0\u4e48\u9700\u8981\u505a\u7684\uff0c\u5f20\u5265\u58eb\u7a81\u7136\u5f00\u59cb\u53cd\u590d\u7c97\u9119\u8bed\u8a00\u7f9e\u8fb1\u5c0f\u5f6d\u8001\u5e08\uff0cpua\u5c0f\u5f6d\u8001\u5e08\uff0c\u66f0\u201c\u4f60\u662f\u7a0b\u5e8f\u5458\u9493\u4e1d\u601d\u7ef4\u201d\u201c\u6839\u672c\u4e0d\u61c2\u6211\u4eec\u7684\u5b9e\u9645\u9700\u6c42\u201d\u201c\u4f60\u4eec\u9493\u4e1d\u7a0b\u5e8f\u5458\u662f\u6700\u4e0d\u61c2\u7f8e\u672f\u7d20\u517b\u7684\u201d\uff0c\u770b\u5728\u5265\u58eb\u8fd8\u5728\u53d1\u5de5\u8d44\u7684\u4efd\u4e0a\uff0c\u5c31\u6ca1\u6709\u7406\u5b83\u3002 \u5c0f\u5f6d\u8001\u5e08\u7ec8\u4e8e\u6bd5\u4e1a\u4e86\uff0c\u8868\u793a\u53ef\u4ee5\u8f6c\u6b63\uff0c\u8fd9\u65f6\u5f20\u5265\u58eb\u5374\u51fa\u5c14\u53cd\u5c14\uff0c\u5404\u79cd\u63a8\u8131\uff0c\u66f0\u201c\u8d44\u91d1\u56f0\u96be\u201d\u201c\u8bf7\u4e0d\u52a8\u5c0f\u5f6d\u8001\u5e08\u201d\u201c\u7b49\u62119\u6708\u62c9\u5230\u6295\u8d44\u597d\u4e0d\u597d\u201d\uff0c\u7136\u800c\u81f3\u4eca\u6ca1\u6709\u53cd\u5e94\uff0c\u8f6c\u5934\u5c31\u770b\u5230\u670b\u53cb\u5708\u5728\u53d1\u5e03\u5916\u5305jd\u3002 \u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u201c\u54c0\u6c42\u201d\u5f20\u5265\u58eb\u201c\u5f00\u773c\u201d\uff0c\u5f20\u5265\u58eb\u53cd\u590d\u63a8\u8131\u540e\uff0c\u7ec8\u4e8e\u8868\u793a\uff1a\u770b\u5728\u4f60\u5bf9zeno\u4e5f\u6709\u201c\u611f\u60c5\u201d\u4e86\uff0c\u5982\u679c\u4f60\u8fd8\u60f3\u4e3a\u6211\u4eeczeno\u7ee7\u7eed\u201c\u8d21\u732e\u201d\u7684\u8bdd\uff0c\u53ef\u4ee5\u5f00\u51fa5k\u4f4e\u4ef7\u91cd\u65b0\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\uff0c\u7b49\u201c\u62c9\u5230\u6295\u8d44\u201d\u201c\u8d44\u91d1\u4e0d\u56f0\u96be\u201d\u65f6\uff0c\u518d\u7ed9\u5c0f\u5f6d\u8001\u5e08\u201c\u8865\u8d34\u201d\u56de\u539f\u6765\u768416k\u5de5\u8d44\uff0c\u540c\u65f6\u770b\u5230\u5f20\u5265\u58eb\u5728\u7fa4\u91cc\u70ab\u8000\u4ed6\u8239\u65b0\u7684\u7b49\u8eab\u624b\u529e(\u5c04)\u3002 \u5f20\u5265\u58eb\u81ea\u6211\u611f\u52a8\u6f14\u7684\u60df\u5999\u60df\u8096\uff0c\u5c0f\u5f6d\u8001\u5e08\u8003\u8651\u5230\u5f20\u5265\u58eb\u671f\u6743\u5927\u997c\u7684\u524d\u8f66\u4e4b\u9274\uff0c\u5c31\u6ca1\u6709\u76f8\u4fe1\u5265\u58eb\u7684\u201c\u597d\u610f\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\u53ea\u597d\u4ee5\u672c\u79d1\u5e94\u5c4a\u751f\u8eab\u4efd\u5f00\u59cb\u5bfb\u627e\u5de5\u4f5c\uff0c\u5176\u4e2dhr\u7ecf\u5e38\u62f7\u95ee\u201c\u6211\u770b\u4f601\u6708\u5230\u73b0\u5728\u90fd\u662f\u6ca1\u6709\u5de5\u4f5c\u7684\u72b6\u6001\uff1f\u201d\u201c\u8bf4\u4e00\u4e0b\u79bb\u804c\u539f\u56e0\u201d\u9020\u6210\u5f88\u5927\u7684\u9ebb\u70e6\u3002 \u5c0f\u5f6d\u8001\u5e08\u5c55\u793a\u201c\u5de5\u4f5c\u7ecf\u9a8c\u201d\u65f6\uff0chr\u603b\u662f\u53cd\u590d\u5f3a\u8c03\u201c\u6211\u770b\u4f60\u624d\u521a\u6bd5\u4e1a\u5440\uff1f\u201d\uff0c\u8ba4\u4e3a\u201c\u5b9e\u4e60\u7ecf\u9a8c\u201d\u4e0d\u7b97\uff0c\u5bfc\u81f4\u5c0f\u5f6d\u8001\u5e08\u5728\u5f20\u5265\u58eb\u7684\u7ecf\u9a8c\u51e0\u4e4e\u4f5c\u5e9f\uff0c\u800c\u5e94\u5c4a\u751f\u4f18\u60e0\u53c8\u88ab\u5f20\u5265\u58eb\u8017\u6389\uff0c\u7136\u800c\uff0c\u5b83\u53ea\u8981\u770b\u4e00\u4e0bzeno\u8d21\u732e\u6392\u884c\u699c\u5c31\u77e5\u9053\uff0c\u5c0f\u5f6d\u8001\u5e08\u7684\u8d21\u732e\u662f\u7b2c\u4e00\u7684\u3002 \u6240\u6709\u6cfd\u68ee\u5458\u5de5\u90fd\u9700\u8981\u719f\u6089\u5c0f\u5f6d\u8001\u5e08\u53cd\u590d\u8fed\u4ee3\u8fc7\u7684\u8282\u70b9\u7cfb\u7edf\uff0c\u624d\u80fd\u5f00\u59cb\u4ed6\u7684zeno\u5f00\u53d1\uff0c\u66f4\u4f55\u51b5\u5c0f\u5f6d\u8001\u5e08\u8fd8\u8d21\u732e\u4e86\u5305\u62ec\u8282\u70b9\u7f16\u8f91\u5668\u3001Python bindings\u3001\u5b9e\u65f6\u4e09\u7ef4\u89c6\u7a97\u3001\u591a\u8fdb\u7a0b\u901a\u4fe1\u3001\u78c1\u76d8\u7f13\u5b58\u3001\u5bf9\u8c61\u5e8f\u5217\u5316\u3001\u5b9e\u65f6optix\u3001shader\u8282\u70b9\u3001GLSL codegen\u3001\u521a\u4f53\u4eff\u771f\u3001Prim\u5c5e\u6027\u7cfb\u7edf\u3001ZFX\u7f16\u8bd1\u5668\u3001PrimPrim \u90bb\u5c45\u67e5\u627e\u3001\u63d2\u4ef6\u7cfb\u7edf\u3001ABC \u52a0\u8f7d\u5668\u3001\u51e0\u4f55\u8282\u70b9\u3001VDB \u8282\u70b9\u3001\u6d41\u4f53\u5b50\u56fe\u3001Blender \u63d2\u4ef6\u3001OpenSubdiv \u96c6\u6210\u3001libigl \u96c6\u6210\u3001CI/CD \u5de5\u4f5c\u6d41\u7b49\u8bf8\u591a\u529f\u80fd\u3002 \u5f20\u5265\u58eb\u53d1\u77e5\u4e4e\u6587\u7ae0\u7206\u8bba\uff1a\u6211\u4eec\u4e0d\u9700\u8981\u7a0b\u5e8f\u5458\uff01\u53ea\u9700\u8981\u5076\u5c14\u62db\u4e24\u4e2a\u5389\u5bb3\u4e00\u70b9\u7684\u5b9e\u4e60\u751f\uff0c\u505a\u4e2a\u4e00\u4e24\u5e74\uff0c\u628a\u8f6f\u4ef6\u505a\u5b8c\u4ee5\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u4ed6\u4eec\u4e86\uff0c\u663e\u7136\u5c0f\u5f6d\u8001\u5e08\u5c31\u662f\u8fd9\u6837\u4e00\u4e2a\u4e00\u6b21\u6027\u53c8\u7279\u522b\u597d\u7528\u7684\u5b9e\u4e60\u751f\u3002","title":"\u6cfd\u68ee\u79d1\u5de5 (2021.12.07)"},{"location":"interview/#unity-20240812","text":"\u4e00\u4e2a\u770b\u8d77\u6765\u53ef\u80fd\u662f\u8001\u677f\u7684\u4eba\u7269\u51fa\u9762\u8fce\u63a5\uff0c\u8fdb\u5165\u4e00\u4e2a\u72ec\u7acb\u7684\u4f1a\u8bae\u5ba4\u5f00\u59cb\u9762\u8c08\u3002 \u4e4b\u524d\u73a9\u8fc7\u54ea\u4e9b\u6e38\u620f\uff1f(\u4e3b\u8981\u662f\u8089\u9e3d\u548c\u6a21\u62df\u7ecf\u8425\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u6740\u622e\u5c16\u5854\u548cKSP\uff0c\u56e0\u4e3a\u4ed6\u4eec\u662fUnity\u6e38\u620f\uff0c\u8fd8\u4ecb\u7ecd\u4e86\u5236\u4f5c\u4ee5\u6492\u7684\u7ed3\u5408\u6a21\u7ec4\u7684\u7ecf\u5386\uff0c\u57fa\u4e8eLua API\u7684) \u9762\u8bd5\u5b98\u8bf4\u73b0\u5728 KSP2 \u6ca1\u6709\u5361\u987f\u4e86\uff0c\u56e0\u4e3a GC \u4f18\u5316\u4e86 \u95ee\u5b66\u8fc7Unity\u5417\uff1f(\u4e86\u89e3\u4e00\u70b98\uff0c\u4e4b\u524d\u505a\u8fc7KSP\u6a21\u7ec4) \u95ee\u90a3\u4e48\u4f60\u7684Unity\u7248\u672c\uff1f(\u7cdf\u7cd5\uff0c\u53ea\u80fd\u88c5\u50bb\u4e86\uff0c\u56e0\u4e3a\u5176\u5b9e\u5f88\u4e45\u6ca1\u6253\u5f00\u8fc7\u4e86\uff0c\u800c\u4e14\u65b0\u7535\u8111\u91cc\u4e5f\u6ca1\u6709\u4e0bUnity) \u8868\u793a\u4f60\u5e94\u8be5\u591a\u770b\u770bUnity\u5b98\u65b9\u6587\u6863\uff0c\u7279\u522b\u662f\u82f1\u6587\u7684\u6587\u6863 \u95eePBR\u6d41\u7a0b\uff1f(\u5206\u4e3aLambert\u548cCook-Torrance\u4e24\u4e2a\u6a21\u578b\uff0c\u5408\u5e76\u8d77\u6765\uff0clambert\u5f88\u7b80\u5355\u7684\u5168\u65b9\u5411\u968f\u673a\u6f2b\u53cd\u5c04\uff0c\u4ecb\u7ecd\u4e86NDF, GDF, FDF\u4e09\u4e2a\u51fd\u6570\u7684\u7269\u7406\u610f\u4e49) \u95eeCg\u7740\u8272\u8bed\u8a00\uff1f(Unity\u81ea\u5df1\u7684\u7740\u8272\u5668\u8bed\u8a00\uff0c\u4e0d\u719f\u6089\uff0c\u8868\u793a\u4e4b\u524d\u5199\u7684\u90fd\u662fGLSL\uff0c\u4f46\u6211\u77e5\u9053\u6240\u6709\u5f15\u64ce\u90fd\u6709\u4e00\u4e2a\u94a6\u5b9a\u8bed\u8a00\uff0c\u5728\u4e0d\u540c\u5e73\u53f0\u4f1a\u7ffb\u8bd1\u751f\u6210\u4e0d\u540c\u7684\u76ee\u6807\u8bed\u8a00\u6bd4\u5982GLSL\uff0cUnity\u4e5f\u652f\u6301\u5199GLSL\uff0c\u4f46\u90e8\u5206\u529f\u80fd\u7279\u6027API\u6709\u6240\u7f3a\u5931\uff0c\u6240\u4ee5\u4e3b\u8981\u8fd8\u662f\u5199Cg\uff0c\u5728GL\u540e\u7aef\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u751f\u6210GLSL\u7684) \u5c0f\u5f6d\u8001\u5e08\u63d0\u8d77\u4e3a\u4e86\u652f\u6301UE\uff0c\u7279\u522b\u505a\u4e86HLSL\u540e\u7aef(\u9762\u8bd5\u5b98\u9510\u8bc4\u4e86\u715e\u7b14DX\u4e0d\u8de8\u5e73\u53f0\uff0c\u73b0\u5728\u6e38\u620f\u4e3b\u8981\u8fd8\u662f\u57fa\u4e8eOpenGL\u5728\u505a\uff0cUE\u662f\u56e0\u4e3a\u5fae\u8f6f\u7ed9\u94b1\u4e86\u624d\u94a6\u5b9aHLSL\u4e3a\u4e3b\u8bed\u8a00\uff0c\u4f46\u5b9e\u9645\u4e0a\u4e5f\u6709\u7ffb\u8bd1\u5230GLSL\u7684OpenGL\u540e\u7aef) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u8868\u793a\u6211\u4eec\u505a\u7684\u662fUnity\u7684\u5fae\u4fe1\u5c0f\u6e38\u620f\uff0c\u56e0\u4e3a\u6700\u8fd1\u63a8\u51fa\u7684WebGL\u540e\u7aef(\u5c0f\u5f6d\u8001\u5e08\uff1a\u602a\u4e0d\u5f97\u53ef\u4ee5\u770b\u5230\u6700\u8fd1\u8fd9\u4e48\u591a\u5fae\u4fe1\u5c0f\u6e38\u620f) \u95ee\u4e86 Lua(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u5199\u7684 Lua \u811a\u672c\u5b9e\u73b0\u4ee5\u6492\u6a21\u7ec4) \u6211\u4eec\u4e0d\u662f\u8981\u5199 Lua\uff0c\u800c\u662f\u8981\u8c03\u7528 Lua \u7684 C \u63a5\u53e3\u54e6\uff01(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e5f\u719f\u6089\uff0c\u56e0\u4e3a\u4e4b\u524d\u53c2\u4e0e\u7684\u4e00\u4e2a\u4ee5\u6492\u6a21\u7ec4\u9879\u76ee IsaacSocket \u5c31\u662f\u57fa\u4e8e C# \u5ba2\u6237\u7aef\uff0c\u52a8\u6001\u5f80\u4ee5\u6492\u8fdb\u7a0b\u6ce8\u5165 C++ DLL\uff0c\u52ab\u6301\u4ee5\u6492\u7684\u5404\u79cd\u56de\u8c03\uff0c\u7136\u540e\u66b4\u9732\u51fa Lua \u63a5\u53e3\uff0c\u521b\u5efa\u4e86\u4e00\u7cfb\u5217\u5bf9\u6e38\u620f\u5185 Lua \u811a\u672c\u53ef\u89c1\u7684 C++ \u51fd\u6570\uff0c\u5b9e\u73b0\u4ee5\u6492 API \u7684\u6269\u5c55\uff0c\u9700\u8981 lua_tonumber \u6765\u83b7\u53d6\u53c2\u6570\uff0clua_pushnumber \u6765\u8fd4\u56de\u503c\u7b49) \u95ee\u4e86 lua_State \u662f\u4ec0\u4e48(\u5c0f\u5f6d\u8001\u5e08\uff1a\u542b\u6709 lua \u7684\u5806\u6808\u5168\u5c40\u53d8\u91cf\u7b49\u4e0a\u4e0b\u6587\u4fe1\u606f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u5404\u81ea\u72ec\u7acb) \u95ee\u5982\u4f55\u521b\u5efa\u4e00\u4e2a UI \u754c\u9762\uff1f\u9009\u62e9\u4e0d\u540c\u7684\u670d\u52a1\u5668\uff0c\u767b\u5f55(\u4f7f\u7528json+http\u5b9e\u73b0rpc\uff0c\u83b7\u5f97\u4e00\u4e2a\u5217\u8868\uff0c\u7136\u540e\u8bbe\u7f6e\u5217\u8868\uff0c\u5373\u53ef\u5229\u7528MVC\u521b\u5efa\u51fa\u754c\u9762) Unity \u7684 UI \u7cfb\u7edf\u4f1a\u5199\u5417\uff1f(\u4e0d\u4f1a\uff0c\u53ea\u77e5\u9053Qt\u6709QListView\u63a7\u4ef6\uff0cUnity\u53ef\u80fd\u4e5f\u6709\u5427\uff1f)","title":"\u67d0 Unity \u5c0f\u5382 (2024.08.12)"},{"location":"interview/#20240815","text":"1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 2\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 TODO \u8fd8\u5728\u5199 \u6ca1\u67093\u9762\u4e86\uff0c\u539f\u56e0\u4e0d\u660e\u3002","title":"\u851a\u6765\u5c0f\u6c7d\u8f66 (2024.08.15)"},{"location":"interview/#20240903","text":"1\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\u6c9f\u901a\uff09 \u8981\u6c42\u81ea\u6211\u4ecb\u7ecd(\u4e3b\u8981\u4ecb\u7ecd\u4e86\u6cfd\u68ee\u5728\u6e32\u67d3\u7684\u5de5\u4f5c\uff0cshader\u8282\u70b9\u7b49\uff0c\u4e0d\u4ec5\u8d1f\u8d23\u4e86Qt+OpenGL\u5b9e\u65f6\u53ef\u89c6\u5316\uff0c\u540e\u6765\u8fd8\u52a0\u5165\u4e86OptiX\u5b9e\u65f6\u5149\u8ffd\u652f\u6301) \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecdzeno\u7684shader\u8282\u70b9\u652f\u6301\u8f93\u51fa\u4e3aGLSL\u3001HLSL\u3001CUDA\u4e09\u79cd\u540e\u7aef\u683c\u5f0f\uff0c\u90fd\u662fcodegen\uff0c\u5176\u4e2dCUDA\u540e\u7aef\u91c7\u7528NVPTX\u7f16\u8bd1\uff0c\u4f9bOptiX\u4f7f\u7528 \u4ecb\u7ecdPBR\u6d41\u7a0b(albedo, metallic, roughness \u7b49\uff0c\u8fd8\u6709\u6cd5\u7ebf\u8d34\u56fe\u7684\u70d8\u70e4\uff0cIBL \u5149\u7167\u7b49) \u95ee\u5230\u4e86PBR\u8ba1\u7b97\u91cf\u5927\uff0c\u79fb\u52a8\u7aef\u5982\u4f55\u89e3\u51b3\u6027\u80fd\u95ee\u9898(\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u4e0d\u719f\u6089\uff0c\u4e4b\u524d\u505a\u7684\u90fd\u662f\u684c\u9762\u7aef\u7684\u6e32\u67d3\uff0c\u53ea\u77e5\u9053\u79fb\u52a8\u7aef\u597d\u50cf\u662ftile-based rendering\u7684) \u4ecb\u7ecd\u4e86\u516c\u53f8\u5185\u90e8\u662f\u6709\u5d4c\u5165\u5f0f(\u4e09\u7ef4\u6355\u83b7\u8bbe\u5907)\u548c\u7535\u8111\u7aef(\u7528\u4e8e\u67e5\u770b\u4e09\u7ef4\u6355\u83b7\u7ed3\u679c\u7684App)\uff0c\u5d4c\u5165\u5f0f\u8bbe\u5907\u53ea\u9700\u8981\u505a\u521d\u6b65\u7684\u6570\u636e\u5904\u7406\uff0c\u57fa\u4e8e\u56fd\u4ea7GPU(\u4f46\u662fCUDA\u63a5\u53e3)\uff0c\u521d\u6b65\u5904\u7406\u540e\u56de\u4f20\u7528\u6237\u7535\u8111\uff0c\u7535\u8111\u7aef\u53ef\u4ee5\u5047\u5b9a\u7528\u6237\u662fNVIDIA\u663e\u5361(\u4e5f\u662fCUDA\u63a5\u53e3)\u7528\u4e8e\u66f4massive\u7684\u540e\u5904\u7406\u548c\u6e32\u67d3\u53ef\u89c6\u5316 \u5c0f\u5f6d\u8001\u5e08\u4e3b\u52a8\u4ecb\u7ecd\u5728taichi three\u4e2d\u624b\u6413\u8f6f\u5149\u6805\u6e32\u67d3\u5668\u7684\u7ecf\u5386(\u652f\u6301ssr, ssgi, taa\u7b49) 2\u9762\uff08LeetCode\u5728\u7ebf\u9762\u8bd5\uff0c\u6709\u5171\u4eab\u4ee3\u7801\u7f16\u8f91\u5668\uff09 \u8981\u6c42\u5c0f\u5f6d\u8001\u5e08\u81ea\u6211\u4ecb\u7ecd(\u7b80\u5386\u4ed6\u5df2\u7ecf\u62ff\u5230\u770b\u7740\u4e86\uff0c\u5c31\u4e0d\u590d\u8bfb\u540d\u5b57\u548c\u5b66\u5386\u4e86\uff0c\u6240\u4ee5\u4e3b\u8981\u4ecb\u7ecd\u9879\u76ee\uff0c\u5728zeno\u4e2d\uff0c\u5c0f\u5f6d\u8001\u5e08\u62c5\u4efb\u6e32\u67d3\u548c\u8282\u70b9\u7cfb\u7edf\u7684\u5f00\u53d1\uff0c\u4ecb\u7ecdQt+OpenGL\u89c6\u7a97\u53ef\u89c6\u5316\uff0c\u4ecb\u7ecd\u8282\u70b9\u7cfb\u7edf\u7c7b\u4f3c\u4e8e\u4f4e\u4ee3\u7801\u7684\u4f18\u52bf\uff0c\u7b80\u8981\u4ecb\u7ecdtaichi, nbodysolver, co_async\u2026\u2026\u70ab\u8000\u9ad8\u6548\u7684\u534f\u7a0b\uff0c\u5e76\u5b89\u5229\u5c0f\u5f6d\u8001\u5e08\u6bd4\u7ad9\u9891\u9053\uff0ccpp\u516c\u5f00\u8bfe) \u9762\u8bd5\u5b98\u8868\u793a\u4e0d\u719fcpp20\uff0c\u63d0\u51fa\u8981\u4ee5cpp17\u4e3a\u57fa\u7840(\u6ca1\u5173\u7cfb\uff0c\u6211\u4eec\u5728zeno\u548ctaichi\u4e5f\u90fd\u662f\u7528cpp17) cpp\u6709\u54ea\u56db\u5927cast(static_cast, dynamic_cast, const_cast, reinterpret_cast) static_cast vs dynamic_cast\u9002\u7528\u573a\u666f(\u5b50\u7c7b\u8f6c\u57fa\u7c7b\u603b\u662fstatic_cast\uff0c\u4e00\u4e2a\u57fa\u7c7b\u6307\u9488\uff0c\u5982\u679c\u4e0d\u80fd\u786e\u5b9a\u662f\u4e0d\u662f\u5b50\u7c7b\uff0c\u90a3\u5c31\u9700\u8981dynamic_cast\uff0c\u5982\u679c\u5931\u8d25\u4f1a\u8fd4\u56denullptr\uff0c\u8bb0\u5f97\u68c0\u67e5\uff01\u5982\u679cdynamic_cast\u5f15\u7528\u5219\u5931\u8d25\u629b\u51fabad_cast\u5f02\u5e38) dynamic_cast\u80cc\u540eRTTI\u539f\u7406(\u5b9e\u9645\u4e0a\u662f\u6bd4\u8f83typeid\u662f\u5426\u517c\u5bb9\uff0ctypeid\u6307\u9488\u5b58\u5728\u865a\u51fd\u6570\u8868\u91cc\uff0c\u53ea\u6709\u5e26\u6709\u81f3\u5c111\u4e2a\u865a\u51fd\u6570\u7684\u79f0\u4e3a\u201c\u591a\u6001\u7c7b\u201d\u7684\u7c7b\u578b\u4f1a\u751f\u6210RTTI\u4fe1\u606f\uff0c\u987a\u4fbf\u63a8\u9500\u4e86\u4e3a\u4ec0\u4e48llvm\u9009\u62e9\u5f00\u542f-fno-rtti\u548c-fno-exception\uff0c\u662f\u907f\u514d\u4e8c\u8fdb\u5236\u81a8\u80c0) llvm\u5173\u95ed\u4e86RTTI\uff0c\u90a3\u4ed6\u662f\u5982\u4f55\u53d8\u76f8\u5b9e\u73b0dynamic_cast\u7684\uff1f(\u6211\u77e5\u9053\uff0c\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff01\u5b9a\u4e49\u4e86getType\u865a\u51fd\u6570\uff0c\u8fd4\u56de\u679a\u4e3e\uff0c\u7528\u4e8e\u6bd4\u8f83) \u53ef\u662f\u5982\u679cD2\u7ee7\u627fD1\u7ee7\u627fB\uff0c\u5982\u4f55\u4fdd\u8bc1D2\u4e5f\u53ef\u4ee5cast\u4e3aD1\uff1f(\u5b8c\u4e86\uff0cllvm\u6e90\u7801\u770b\u7684\u4e0d\u4ed4\u7ec6\uff0c\u53ea\u80fd\u7528\u4ee5\u6492\u7684\u505a\u6cd5\u76f2\u731c\u4e00\u4e2a\uff1a\u662fB\u6709getD1\u548cgetD2\u4e24\u4e2a\u865a\u51fd\u6570\uff01\u4ed6\u4eec\u9ed8\u8ba4\u8fd4\u56denullptr\uff0c\u53ea\u6709D1\u4f1a\u91cd\u5199getD1\uff0cD2\u4f1a\u91cd\u5199getD2\uff0c\u5185\u90e8\u90fd\u662f\u7b80\u5355\u7684\u8fd4\u56dethis) const_cast\u672a\u5b9a\u4e49\u884c\u4e3a(\u672c\u6765\u662fconst\u7684\u4e0d\u80fd\u53bb\u6389const\u540e\u8bbf\u95ee\uff0c\u5c55\u793a\u4e86\u6210\u5458\u51fd\u6570\u590d\u7528\u4e24\u4e2adata\u7684\u7528\u6cd5) const_cast\u540e\u8fd4\u56de\u6307\u9488\u6ca1\u95ee\u9898\uff0c\u9762\u8bd5\u5b98\u6539\u6210\u8fd4\u56de\u5f15\u7528\uff0c\u6d89\u53ca\u89e3\u5f15\u7528\uff0c\u95ee\u8fd9\u6837\u8fd8\u5b89\u5168\u5417\uff1f(\u8ff7\u60d1\u6027\u5f88\u5f3a\u7684\u95ee\u9898\uff0c\u88ab\u5c0f\u5f6d\u8001\u5e08\u8bc6\u7834\uff1a\u975econst\u5730\u89e3\u5f15\u7528const\u53d8\u91cf\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u53d6\uff0c\u5c31\u548cend\u8fed\u4ee3\u5668\u4e0d\u80fd\u89e3\u5f15\u7528\u4e00\u6837\uff0c\u5373\u4f7f\u6ca1\u6709\u8bfb\u5199\u8bbf\u95ee) const vs constexpr\u53d8\u91cf\u533a\u522b(const\u53ef\u4ee5\u6709\u5730\u5740\uff0c\u800cconstexpr\u4e0d\u4e00\u5b9a\u6709) reinterpret_cast\u7528\u6cd5\uff0c\u4ec0\u4e48\u60c5\u51b5\u4e0b\u5b89\u5168(\u5c0f\u5f6d\u8001\u5e08\u5199\u7ecf\u5178\u4e3e\u51faint\u548cfloat\u4e4b\u95f4bit-cast\u7684\u6848\u4f8b\uff0c\u4ecb\u7ecd\u503c\u8f6c\u6362\u548c\u6309\u4f4d\u8f6c\u6362\u7684\u533a\u522b\uff0c\u52fe\u5f15\u9762\u8bd5\u5b98\u4e0a\u94a9\uff0c\u4ed6\u80af\u5b9a\u8ba4\u4e3a\u5c0f\u5f6d\u8001\u5e08\u4e0d\u77e5\u9053reinterpret_cast\u4e0d\u80fd\u505aint\u548cfloat\u7684\u6307\u9488\u8f6c\u6362\uff0c\u4e8e\u662f\u53d1\u95ee\uff1a) \u9762\u8bd5\u5b98\u5199\u51faint\u548cfloat\u6307\u9488\u5f3a\u8f6c\u5e76\u89e3\u5f15\u7528\u7684\u4ee3\u7801\uff0c\u95ee\u8fd9\u4e2a\u5b89\u5168\u5417\uff1f(\u4e0a\u94a9\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u5373\u7b54\uff1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e0d\u80fd\u7528reinterpret_cast\u8f6cint\u548cfloat\u6307\u9488\uff0c\u662f\u56e0\u4e3astrict-aliasing\u8ba4\u4e3aint\u548cfloat\u4e0d\u517c\u5bb9\uff0c\u8f6c\u6362\u540e\u89e3\u5f15\u7528\u5373UB\uff0c\u9762\u8bd5\u5b98\u8bf4\u4f3c\u4e4e\u53ea\u6709GCC\u4f1a\u7528\u8fd9\u4e2a\uff0c\u5c0f\u5f6d\u8001\u5e08\u7b54\uff1aGCC\u9ed8\u8ba4\u5f00\u542f\uff0c\u53ef\u4ee5\u7528-fno-strict-aliasing\u5173\u95ed\uff0cMSVC\u4e0d\u5229\u7528\u6b64\u89c4\u5219\u4f18\u5316\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u4ecb\u7ecd\u6307\u9488\u522b\u540d\u4e0e\u4f18\u5316\u7684\u5173\u7cfb\uff0c\u5373\u4e3a\u4ec0\u4e48\u63d0\u51fastrict-aliasing\u89c4\u5219\u7684\u539f\u56e0) \u5c0f\u5f6d\u8001\u5e08\u5f3a\u8c03int\u548cunsigned int\u662f\u517c\u5bb9\uff0c\u9762\u8bd5\u5b98\u5c31\u95ee\u4e3a\u4ec0\u4e48char\u53ef\u4ee5\uff1f(reinterpret_cast\u6709\u7834\u683c\u5141\u8bb8\u7684\u7279\u4f8b\uff0cchar,unsigned char,std::byte\u4e0e\u6240\u6709\u7c7b\u578b\u90fd\u517c\u5bb9\uff0c\u8f6c\u4e3achar\u6307\u9488\u540e\u53ef\u4ee5\u968f\u610f\u8bbf\u95ee\u4efb\u610f\u7c7b\u578b\u7684\u5185\u5b58\uff0c\u6307\u51fa\u662fcpp\u6807\u51c6\u4e3a\u4e86\u65b9\u4fbf\u6211\u4eec\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u89e3\u5e8f\u5217\u5316\u7684\u65b9\u4fbf\u6027) \u5982\u4f55\u5b9e\u73b0\u771f\u6b63\u5b89\u5168\u7684int\u548cfloat\u8f6c\u6362\uff1f(\u4f7f\u7528memcpy\u6216cpp20\u7684bit_cast\u662f\u5b89\u5168\u7684\uff0c\u5e76\u63a8\u9500memcpy vs bit_cast\u533a\u522b\uff1a\u867d\u7136cppref\u4e0abit_cast\u7684\u201c\u53c2\u8003\u5b9e\u73b0\u201d\u662fmemcpy\uff0c\u4f46\u5f97\u76ca\u4e8e\u5176\u57fa\u4e8e\u7f16\u8bd1\u5668\u5f00\u6d1e__builtin_bit_cast\uff0c\u8ba9bit_cast\u662fconstexpr\u51fd\u6570\u53ef\u7f16\u8bd1\u671f\u786e\u5b9a) inline\u5173\u952e\u5b57\u4f5c\u7528(non-odr external linkage\uff0c\u5efa\u8bae\u5934\u6587\u4ef6\u4e2d\u5c31\u5730\u5b9a\u4e49\u7684\u51fd\u6570\u90fd\u52a0inline\uff0c\u5426\u5219\u591a\u4e2a.cpp\u6587\u4ef6\u4e2d\u4ea7\u751f\u591a\u4e2a\u5b9a\u4e49\uff0c\u89e6\u53d1\u94fe\u63a5\u5668odr\u62a5\u9519\uff0c\u800cinline\u5219\u662f\u975endr\u7684\u5916\u90e8\u94fe\u63a5) \u9762\u8bd5\u5b98\u95eeinline\u51fd\u6570\u591a\u4e2a\u6587\u4ef6\u4e2d\u770b\u5230\u7684\u51fd\u6570\u4f53\u5b9a\u4e49\u4e0d\u540c\uff0c\u4f46\u51fd\u6570\u53c2\u6570\u5217\u8868\u76f8\u540c\uff0c\u4f1a\u600e\u4e48\u6837\uff1f(\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6807\u51c6\u8981\u6c42\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709.cpp\u7ffb\u8bd1\u5355\u5143\u770b\u5230\u7684inline\u51fd\u6570\u5b9a\u4e49\u4e00\u81f4\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u5f80\u5f80\u5e76\u4e0d\u62a5\u9519) \u5c0f\u5f6d\u8001\u5e08\u63a8\u9500\uff1a\u8fd9\u5bfc\u81f4\u4f60\u5728cpp\u6587\u4ef6\u4e2d\u5b9a\u4e49\u975ePOD\u7c7b\u4f1a\u88ab\u5751\uff0c\u56e0\u4e3a\u7c7b\u4f53\u5185\u5c31\u5730\u5b9a\u4e49\u7684\u6210\u5458\u51fd\u6570\uff0c\u9ed8\u8ba4\u662finline\u7684\uff0c\u5305\u62ec\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5f53\u65f6\u5bfc\u81f4zeno\u8c03\u8bd5\u4e86\u534a\u5929(\u9762\u8bd5\u5b98\u8868\u793a\u4ed6\u4e4b\u524d\u96c6\u6210\u4e00\u4e2a\u5f00\u6e90\u5e93\u4e5f\u9047\u5230\u8fd9\u4e2a\u5751\uff0c\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u53ef\u4ee5\u5957\u533f\u540dnamespace\u89e3\u51b3) push_back vs emplace_back(2\u91cd\u8f7dvs\u4e07\u80fd\u5f15\u7528+\u53d8\u957f\u53c2\u6570\uff0cemplace\u53ef\u4ee5\u5c31\u5730\u5e26\u4efb\u610f\u53c2\u6570\u6784\u9020\u4f60\u7684\u5143\u7d20\u7c7b\u578b\uff0cemplace\u7684\u989d\u5916\u597d\u5904\u662f\u89e6\u53d1explicit\u7684\u6784\u9020\u51fd\u6570\u800c\u65e0\u9700\u663e\u5f0f\u5199\u51fa\u7c7b\u540d\uff0c\u4e5f\u5e26\u6765\u4e86\u5371\u9669\uff0c\u6240\u4ee5\u6211\u5728\u8bfe\u7a0b\u4e2d\u90fd\u4e0d\u63a8\u8350\u4f7f\u7528\uff0c\u5982\u9700\u907f\u514d\u79fb\u52a8\u53ef\u4ee5 vector> \uff0c\u8fd9\u8fd8\u80fd\u4f7f\u6269\u5bb9\u65f6\u4e5f\u4e0d\u89e6\u53d1\u79fb\u52a8) \u4ec0\u4e48\u60c5\u51b5\u4e0b\u4e0d\u4f1a\u79fb\u52a8\uff1f\u9762\u8bd5\u5b98\u4f3c\u4e4e\u5728\u8bd5\u63a2\u6211\u662f\u5426\u4e86\u89e3 vector \u6269\u5bb9\u539f\u7406(\u53ea\u6709\u5f53size>capacity\u65f6\u624d\u4f1a\u89e6\u53d1\uff0c\u6bcf\u6b21\u89e6\u53d1\u6269\u5bb9\u65f6gcc\u589e\u52a0\u52302 x size\uff0cmsvc\u5219\u662f1.5 x size\uff0c\u603b\u51712n\u6b21\u64cd\u4f5c\uff0c\u597d\u5904\u662f\u4fdd\u8bc1\u4e86\u603b\u4f53O(n)\u590d\u6742\u5ea6\uff0c\u6211\u4eec\u5efa\u8bae\u77e5\u9053\u957f\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u8c03\u7528reserve\u63d0\u524d\u9884\u8ba2100\u7684capacity\uff0c\u8fd9\u6837\u53ea\u6709\u63a8\u5165\u7b2c101\u4e2a\u5143\u7d20\u624d\u4f1a\u6269\u5bb9\u5230200\uff0c\u5c0f\u5f6d\u8001\u5e08\u987a\u4fbf\u63a8\u9500\u4e86vector, deque, list\u7684\u533a\u522b\uff0c\u8fed\u4ee3\u5668\u5931\u6548\u539f\u56e0) \u8fd8\u95ee\u4e86\u4e07\u80fd\u5f15\u7528\u548c\u5b8c\u7f8e\u8f6c\u53d1\u7684\u539f\u7406(\u5f15\u7528\u6298\u53e0) \u4ec0\u4e48\u662fPOD(\u57fa\u7840\u7c7b\u578b\u3001\u6307\u9488\u3001\u65e0\u7528\u6237\u6784\u9020\u51fd\u6570\u7684\u7eaf\u57fa\u7840\u7c7b\u578b\u7ec4\u6210\u7684\u7ed3\u6784\u4f53) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1avector\u8d85\u7f13\u5b58\u5927resize\u5bfc\u81f4memset\u6027\u80fd\u5f71\u54cd\uff1f(\u62ff\u51fa\u6211\u7684tbb\u8bfe\u7a0b\u7684parallel_filter\u6848\u4f8b\uff0c\u5229\u7528pod\u6a21\u677f\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u719f\u6089\u7f13\u5b58\uff0c\u4e0d\u7528\u63d0\u95ee\u4e86) \u9762\u8bd5\u5b98\u63d0\u95eePIMPL\u6a21\u5f0f(\u5199C::Impl\u7ed9\u4ed6\u770b\uff0c\u53c8\u95eePIMPL\u7684\u76ee\u7684\u662f\u4ec0\u4e48\uff0c\u4e00\u5f00\u59cb\u7b54\uff1a\u5206\u79bb\u5b9a\u4e49\uff0c\u52a0\u901f\u7f16\u8bd1\uff0c\u95ee\u8fd8\u6709\u4ec0\u4e48\u4f5c\u7528\u5417\uff1f\u4fdd\u6301abi\u7a33\u5b9a\uff0c\u4e0d\u7528\u91cd\u65b0\u7f16\u8bd1\u4f9d\u8d56\u8005\uff0c\u53ef\u7528\u4e8e\u63d2\u4ef6\u70ed\u88c5\u8f7d) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48C\u7684\u6784\u9020\u51fd\u6570\u91cc\u4f1a\u9700\u8981unique_ptr\u7c7b\u578b\u6790\u6784\u51fd\u6570\u7684\u4fe1\u606f\u5417\uff1f(\u9762\u8bd5\u5b98\uff1a\u56e0\u4e3a\u6790\u6784\u51fd\u6570\u9700\u8981\u77e5\u9053sizeof!=0\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u4f46\u662f\uff0cC\u7684\u6790\u6784\u51fd\u6570\u88ab\u8f6c\u79fb\u5230\u4e86C.cpp\uff0c\u4e3a\u4ec0\u4e48\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521d\u59cbunique_ptr\u4e3anullptr\uff0c\u4ecd\u7136\u7f16\u8bd1\u51fa\u9519\uff1f\u9762\u8bd5\u5b98\u652f\u652f\u543e\u543e\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u56e0\u4e3a\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u5f02\u5e38\uff0c\u5bfc\u81f4\u4e4b\u524d\u521d\u59cb\u5316\u8fc7\u7684\u6210\u5458\u6790\u6784\uff0c\u518d\u6b21\u5411\u4ed6\u515c\u552ecpp\u5f02\u5e38\u9b45\u529b\u65f6\u523b) q\u6307\u9488 vs d\u6307\u9488(Qt\u5b9e\u73b0cow\u548cpimpl\u7684\u7ec6\u8282\uff0c\u56e0\u4e3a\u5e73\u65f6\u6ca1\u6ce8\u610f\u770bqt\u5934\u6587\u4ef6\u6e90\u7801\uff0c\u5c0f\u5f6d\u8001\u5e08\u552f\u4e00\u683d\u8ddf\u5934\u7684\u9898\uff0c\u8bf4\u662f\u770b\u5230\u7b80\u5386\u5199\u7684Qt\u5c31\u95ee\u4e86\uff0c\u5e76\u8868\u793a\u4e4b\u524dzeno\u91cc\u4e3b\u8981\u662f\u7528PyQt) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1ac++11 string\u4e3a\u4ec0\u4e48\u6253\u7834abi(\u56e0\u4e3ac++98 string\u91c7\u7528cow\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u6a21\u578b\u5e38\u8bc6\u201c\u5171\u4eab\u8bfb\u5b89\u5168\u201d) make_shared vs shared_ptr new\u7684\u533a\u522b(\u53ea\u9700\u4e00\u6b21\u6027\u5206\u914d\uff0c\u65e0\u9700\u518dnew SpCounter\uff0c\u539f\u7406\u662foperator new+placement new) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053\u4e3a\u4ec0\u4e48shared_ptr\u7684\u6784\u9020\u51fd\u6570\u6ca1\u6709noexcept\u5417\uff1f(\u5c31\u662f\u56e0\u4e3a\u8981new SpCounter) \u662foperator new\u8fd8\u662fnew_allocator\uff1f(\u9ed8\u8ba4\u662fnew_allocator\uff0c\u53ef\u7528allocate_shared\u66ff\u6362\u6389) \u5c0f\u5f6d\u8001\u5e08\u53cd\u5411\u63d0\u95ee\uff1a\u77e5\u9053make_shared_for_overwrite\u7684\u533a\u522b\u5417(\u91c7\u7528default-init\uff0cnew\u8868\u8fbe\u5f0f\u540e\u6ca1\u6709\u4e86\u62ec\u53f7\uff0c\u53ef\u907f\u514dPOD\u7c7b\u578b0\u521d\u59cb\u5316\uff0c\u9762\u8bd5\u5b98\u8868\u793a\u8fd9\u4e2a\u6211\u90fd\u6ca1\u4e86\u89e3\u8fc7) CRTP(\u5947\u5f02\u9012\u5f52\u6a21\u677f\u6a21\u5f0f\uff0c\u6700\u521d\u7528\u4e8e\u53d6\u4ee3\u865a\u51fd\u6570\uff0c\u8981\u5b9e\u73b0\u83b7\u53d6\u5b50\u7c7b\u6307\u9488self\uff0c\u63a8\u9500\u4e86cpp\u6a21\u677f\u7c7b\u5ef6\u8fdf\u5b9e\u4f8b\u5316\u6210\u5458\u51fd\u6570\u7684\u673a\u5236\uff0c\u5176\u5b9eCRTP\u8fd8\u80fd\u7528\u4e8e\u5b9e\u73b0\u539f\u578b\u6a21\u5f0f\u548cvisitor\u6a21\u5f0f\uff0c\u56e0\u4e3a\u65f6\u95f4\u5173\u7cfb\u6ca1\u6765\u5f97\u53ca\u8bf4) \u865a\u51fd\u6570\u4e3a\u4ec0\u4e48\u4f4e\u6548\uff1f\u865a\u51fd\u6570\u5982\u4f55\u4f18\u5316(\u56e0\u4e3a\u9700\u8981call\u4e00\u4e2a\u6307\u9488\uff0ccpu\u65e0\u6cd5\u9884\u77e5\uff0c\u4f7f\u7528final\uff0c\u4e0d\u7528\u8bfb\u53d6\u865a\u51fd\u6570\u6307\u9488\u8868\uff0c\u7136\u540e\u8bf4\u660e\u4e86vecB\u62c6\u6210vecD1\u548cvecD2\u66f4\u9ad8\u6548) shared_from_this\u5b9e\u73b0(\u672c\u6765\u8981\u6211\u5199\u7684\uff0c\u56e0\u4e3a\u65f6\u95f4\u6765\u4e0d\u53ca\u5199\uff0c\u4f46\u662f\u5c0f\u5f6d\u8001\u5e08\u8868\u793a\u51fa\u8fc7\u624b\u6413shared\u5168\u5bb6\u6876\u7684\u89c6\u9891\uff0c\u9762\u8bd5\u5b98\u53ea\u597d\u653e\u5fc3) \u4f60\u5bf9\u54ea\u4e2a\u9886\u57df\u611f\u5174\u8da3\uff1f(\u5f53\u7136\u662f\u6e32\u67d3\uff0c\u6211\u4ece\u5c0f\u505a\u5230\u5927\uff0c\u5e76\u8868\u793a\u6027\u80fd\u4f18\u5316\u8fd9\u4e00\u5757\u4e5f\u5c3d\u7ba1\u8bf7\u6559\u5c0f\u5f6d\u8001\u5e08\uff0c\u6709cuda\u548csimd\u4f18\u5316\u5ba2\u6237\u7ecf\u9a8c) \u8fd8\u6709\u4ec0\u4e48\u95ee\u9898\u5bf9\u672c\u516c\u53f8\u5417\uff1f(\u65f6\u95f4\u4e0d\u591a\u4e86\uff0c\u5c31\u95ee\u8981\u4e0d\u8981\u73b0\u5728\u5f00\u59cb\u5b66\u4e60\u4e09\u7ef4\u91cd\u5efa\uff0c\u6216\u8005\u53ef\u4ee5\u8bd5\u8bd5\u770b\u5ba2\u6237\u7aef\uff0c\u8bf4\u5c97\u4f4d\u9009\u62e9\u53ef\u4ee5\u4e4b\u540e\u548chr\u6c9f\u901a\uff0c\u5e76\u5411\u6211\u63a8\u9500\u4e863dgs\uff0c\u7403\u978b\u51fd\u6570\uff0c\u5c0f\u5f6d\u8001\u5e08\uff1a\u597d\u591apaper\u5440\uff1f\u770b\u4e86\u51e0\u4e2a\u6548\u679c\u56fe\uff0c\u5178\u4e2d\u5178\u4e4bOurs\u6c38\u8fdc\u662f\u6700\u597d\u7684) 3\u9762\uff08\u75bc\u900a\u4f1a\u8bae\u8bed\u97f3\uff09 \u53c8\u4ecb\u7ecd\u4e86zeno\u548ctaichi\uff0c\u95ee\u4e86\u70b9\u4e91\u76f8\u5173\u95ee\u9898\uff0c\u5f88\u5feb\u7ed3\u675f\u4e86\u3002 4\u9762\uff08\u62c9\u6295\u8d44\u7684\u5408\u4f19\u4eba\u4eb2\u81ea\u7ebf\u4e0b\u89c1\u9762\uff09 \u5546\u573a\u5168\u90e8\u5173\u95ed\u4e86\uff0c\u661f\u5df4\u514b\u8fd8\u5f00\u7740 \u4ecb\u7ecd\u4e00\u4e0b\u4f60\u81ea\u5df18\uff08\u53c8\u662f zeno\uff09 \u95ee\u4e86\u4e0a\u6b21\u7684\u9762\u8bd5\u5b98\u600e\u4e48\u6837\u5440\uff08\u6211\u770b\u4e86\u63a8\u8350\u7684 3dgs\uff0c\u53d1\u73b0\u662f\u628a\u626b\u63cf\u51fa\u6765\u7684\u70b9\u4e91\uff0c\u9010\u6b65\u8f6c\u6362\u4e3a\u692d\u5706\u7403\u6e32\u67d3\uff09 \u4f60\u77e5\u9053\uff0c\u73b0\u5728\u4e3b\u6d41\u56fe\u5f62\u5b66\u90fd\u662f\u4e09\u89d2\u5f62\u7f51\u683c\uff0c\u90a3\u4e48\u8fd9\u79cd\u70b9\u4e91\u8981\u5982\u4f55\u6e32\u67d3\u5462\uff1f\uff08\u70b9\u4e91\u7684\u8bdd\u53ef\u4ee5\u5148\u7528 marching cube \u8f6c\u4e09\u89d2\u5f62\u9762\uff0czeno \u7684\u6d41\u4f53\u5c31\u662f\u8fd9\u6837\u7684\uff09 \u4f46\u662f\u6027\u80fd\u4e0d\u591f\uff0c\u4e0d\u80fd\u4fdd\u8bc1\u5b9e\u65f6\uff08\u53ef\u4ee5\u7528\u5c4f\u5e55\u7a7a\u95f4\u6d41\u4f53\uff0c\u4f46\u662f\u6548\u679c\u4e00\u822c\uff0c\u6211\u4eec\u505a\u7535\u5f71\u7684\u9700\u8981\u9ad8\u8d28\u91cf\u7684\u79bb\u7ebf\u6e32\u67d3\uff0c\u4e0d\u592a\u6ce8\u91cd\u5b9e\u65f6\u6027\uff0c\u5b9e\u65f6\u692d\u7403\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u7528\u5149\u8ffd\uff0c\u7b97\u5c04\u7ebf\u4e0e\u692d\u7403\u8868\u9762\u6c42\u4ea4\u5373\u53ef\uff0c\u4e0d\u8fc7\u82f1\u4f1f\u8fbe\u7684\u786c\u4ef6\u52a0\u901f\u53ea\u6709\u4e09\u89d2\u5f62\u7684\uff0c\u4f46\u662f GPU Gems \u4e0a\u7684 BVH \u52a0\u901f\u6c42\u4ea4\u4ee3\u7801\u7528\u4e8e\u692d\u7403\u4e5f\u662f\u53ef\u4ee5\u62ff\u6765\u53c2\u8003\u7684\uff09 \u62ff\u51fa\u4e00\u53f0 3D \u626b\u63cf\u673a\u5668\uff0c\u8bf4\u4f60\u77e5\u9053\u6211\u4eec\u8fd9\u4e2a\u6d4b\u7ed8\u673a\u5668\u662f\u5982\u4f55\u5b9a\u4f4d\u7684\u5417\uff08\u60ef\u6027\u5236\u5bfc\uff0c\u91cc\u9762\u6709\u52a0\u901f\u5ea6\u8ba1\uff0c\u6c42\u4e8c\u9636\u79ef\u5206\u5c31\u53ef\u4ee5\u5f97\u5230\u4f4d\u7f6e\uff09 \u4f46\u662f\u8fd9\u6837\u65f6\u95f4\u957f\u4f1a\u6709\u7d2f\u8ba1\u8bef\u5dee\uff0c\u5982\u4f55\u6d88\u9664\u8bef\u5dee\uff1f\uff08\u53ef\u4ee5\u7528 GPS \u5b9a\u4f4d\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u5149\u5b66\u6444\u50cf\u5934\u626b\u63cf\u7684\u7ed3\u679c\uff0c\u786e\u5b9a\u81ea\u5df1\u7684\u76f8\u5bf9\u4f4d\u7f6e\uff0c\u5fc5\u8981\u65f6\u53ef\u4ee5\u8d34\u51e0\u4e2a\u8bc6\u522b\u7eb8\u7247\u5728\u5899\u4e0a\u65b9\u4fbf\u7a0b\u5e8f\u68c0\u6d4b\uff09 \u662f\u7684\uff0c\u5b9e\u9645\u4e0a\u6211\u4eec\u5728\u6237\u5916\u4f1a\u7528 GPS \u5b9a\u4f4d\uff0c\u77ff\u6d1e\u91cc\u5c31\u4f1a\u7528\u5149\u5b66\u7684\u5b9a\u4f4d\u65b9\u6cd5\uff0c\u6d88\u9664\u60ef\u6027\u5236\u5bfc\u7684\u7d2f\u8ba1\u8bef\u5dee\u3002 \u90a3\u4e48 GPS \u536b\u661f\u5b9a\u4f4d\u7684\u539f\u7406\u4f60\u77e5\u9053\u5417\uff1f\uff08\u4e09\u9897 GPS \u536b\u661f\u53d1\u51fa\u4e0d\u540c\u76f8\u4f4d\u7684\u7535\u78c1\u6ce2\uff0c\u56e0\u4e3a\u5149\u901f\u6709\u9650\uff0c\u79fb\u52a8\u8bbe\u5907\u901a\u8fc7\u68c0\u6d4b\u76f8\u4f4d\u5dee\uff0c\u5c31\u77e5\u9053\u81ea\u5df1\u8ddd\u79bb\u4e09\u9897\u536b\u661f\u7684\u8ddd\u79bb\uff0c\u7136\u540e\u4e09\u4e2a\u8ddd\u79bb\u5c31\u80fd\u552f\u4e00\u786e\u5b9a\u4e00\u4e2a\u70b9\uff09","title":"\u5176\u57df\u79d1\u6280 (2024.09.03)"},{"location":"interview/#20240903_1","text":"\u4ecb\u7ecd\u4e00\u4e0b\u81ea\u5df1\uff08\u53c8\u4ecb\u7ecdzeno\u662f\u4e00\u6b3eCAD\u7c7b\u7684\u9879\u76ee\uff09 \u54c8\u5e0c\u8868\uff08\u4ecb\u7ecdunordered_map\u57fa\u4e8e\u94fe\u8868\u6cd5\uff0c\u6807\u51c6\u5e93\u7684hashint\u662f\u6052\u7b49\u51fd\u6570\uff0cabsl\u7684\u5b9e\u73b0\u57fa\u4e8e\u5f00\u653e\u5730\u5740\u6cd5\u66f4\u9ad8\u6548\uff0cjava\u4e5f\u662f\u94fe\u8868\u6cd5\uff0c\u4f46\u94fe\u8868\u8fc7\u957f\u4f1a\u8f6c\u6362\u4e3a\u7ea2\u9ed1\u6811\u7b49\uff09 \u7ea2\u9ed1\u6811\uff08\u4e94\u5927\u89c4\u5219\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u4e94\u4e2a\u89c4\u5219\u80fd\u4fdd\u8bc1\u4e0d\u8d85\u8fc72\u500d\u6df1\u5ea6\uff0c\u540c\u65f6\u6bd4\u4e8c\u53c9\u5e73\u8861\u6811\u9ad8\u6548\uff09 \u7ea2\u9ed1\u6811\u5de6\u65cb\u53f3\u65cb\u64cd\u4f5c\uff08\u53f3\u513f\u5b50\u66ff\u6362\u7236\u4eb2\uff0c\u7236\u4eb2\u53d8\u6210\u5de6\u513f\u5b50\uff09 \u9762\u8bd5\u5b98\u900f\u9732\uff1a\u5b9e\u9645\u4e0a\u7ea2\u9ed1\u6811\u5c31\u662f\u4e00\u4e2a4\u9636\u6811\uff0c\u4f60\u60f3\u60f3\u770b\uff08\u786e\u5b9e\uff0c\u5982\u679c\u628a\u7ea2\u9ed1\u4e24\u5c42\u770b\u4f5c\u4e00\u5c42\u7684\u8bdd\uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a4\u9636\u5e73\u8861\u6811\uff09 OpenGL \u6e32\u67d3\u7ba1\u7ebf\uff083d\u9876\u70b9\u6570\u636e -> vert shader (\u77e9\u9635\u53d8\u6362) -> \u5149\u6805\u5316+\u63d2\u503c+\u6df1\u5ea6\u6d4b\u8bd5 -> frag shader (\u524d\u5411\u7740\u8272) -> G-buffer -> \u5ef6\u8fdf\u6e32\u67d3 (\u540e\u5411\u7740\u8272) -> \u540e\u5904\u7406 -> \u5c4f\u5e55\uff09 \u6765\u9762\u8bd5\u7684\u4eba\u4e2d\uff0c\u4f60\u662f\u6211\u89c1\u8fc7\u6280\u672f\u6700\u597d\u7684\u4e00\u4e2a\uff0c\u4e4b\u524d\u4e00\u4e2a\u7855\u58eb\uff0c\u4e0a\u6765\u54c8\u5e0c\u8868\u5c31\u652f\u652f\u543e\u543e\u6302\u6389\u3002 \u4e8b\u540e\uff1a\u5df2\u5f55\u53d6\uff0c\u6b63\u5728\u4e0a\u73eding\u2026\u2026\u53c8\u662f\u505a Qt + OpenGL \u7684\u9879\u76ee","title":"\u96c5\u79d1\u8d1d\u601d (2024.09.03)"},{"location":"lambda/","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u7528\u51fd\u6570\u5c01\u88c5 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u4e8c\u6b21\u5c01\u88c5 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 mutable \u7684\u51fd\u6570\u5bf9\u8c61 \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u6309\u5f15\u7528\u6355\u83b7 \u6309\u503c\u79fb\u52a8\u6355\u83b7 \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u7c7b lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 std::bind_front \u548c std::bind_back \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4f7f\u7528 lambda \u4ee3\u66ff bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5 \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum = {}\", s); return 0; } \u8fd9\u662f\u4e00\u4e2a\u8ba1\u7b97\u6570\u7ec4\u6c42\u548c\u7684\u7b80\u5355\u7a0b\u5e8f\u3002 \u4f46\u662f\uff0c\u4ed6\u53ea\u80fd\u8ba1\u7b97\u6570\u7ec4 a \u7684\u6c42\u548c\uff0c\u65e0\u6cd5\u590d\u7528\u3002 \u5982\u679c\u6211\u4eec\u6709\u53e6\u4e00\u4e2a\u6570\u7ec4 b \u4e5f\u9700\u8981\u6c42\u548c\u7684\u8bdd\uff0c\u5c31\u5f97\u628a\u6574\u4e2a\u6c42\u548c\u7684 for \u5faa\u73af\u91cd\u65b0\u5199\u4e00\u904d\uff1a int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum of a = {}\", s); std::vector b = {5, 6, 7, 8}; s = 0; for (int i = 0; i < a.size(); i++) { s += b[i]; } fmt::println(\"sum of b = {}\", s); return 0; } \u8fd9\u5c31\u51fa\u73b0\u4e86\u7a0b\u5e8f\u8bbe\u8ba1\u7684\u5927\u5fcc\uff1a\u4ee3\u7801\u91cd\u590d\u3002 \u4f8b\u5982\uff0c\u4f60\u6709\u5439\u7a7a\u8c03\u7684\u9700\u6c42\uff0c\u548c\u5145\u624b\u673a\u7684\u9700\u6c42\u3002\u4f60\u4e3a\u4e86\u6ee1\u8db3\u8fd9\u4e24\u4e2a\u9700\u6c42\uff0c\u8d2d\u4e70\u4e86\u4e24\u53f0\u53d1\u7535\u673a\uff0c\u5206\u522b\u4e3a\u7a7a\u8c03\u548c\u624b\u673a\u4f9b\u7535\u3002\u7b2c\u4e8c\u5929\uff0c\u4f60\u53c8\u4ea7\u751f\u4e86\u73a9\u7535\u8111\u9700\u6c42\uff0c\u4e8e\u662f\u4f60\u53c8\u8d2d\u4e70\u4e00\u53f0\u53d1\u7535\u673a\uff0c\u4e13\u4e3a\u7535\u8111\u4f9b\u7535\u2026\u2026\u771f\u662f\u6d6a\u8d39\uff01 \u91cd\u590d\u7684\u4ee3\u7801\u4e0d\u4ec5\u5f71\u54cd\u4ee3\u7801\u7684 \u53ef\u8bfb\u6027 \uff0c\u4e5f\u589e\u52a0\u4e86 \u7ef4\u62a4 \u4ee3\u7801\u7684\u6210\u672c\u3002 \u770b\u8d77\u6765\u4e71\u7cdf\u7cdf\u7684\uff0c\u4fe1\u606f\u5bc6\u5ea6\u4f4e\uff0c\u8ba9\u4eba\u4e00\u773c\u770b\u4e0d\u51fa\u4ee3\u7801\u5728\u5e72\u4ec0\u4e48\u7684\u529f\u80fd \u5f88\u5bb9\u6613\u5199\u9519\uff0c\u770b\u8d70\u773c\uff0c\u96be\u8c03\u8bd5 \u590d\u5236\u7c98\u8d34\u8fc7\u7a0b\u4e2d\uff0c\u5bb9\u6613\u6f0f\u6539\uff0c\u6bd4\u5982\u8fd9\u91cc\u7684 s += b[i] \u53ef\u80fd\u5199\u6210 s += a[i] \u800c\u81ea\u5df1\u4e0d\u53d1\u73b0 \u6539\u8d77\u6765\u4e0d\u65b9\u4fbf\uff0c\u5f53\u6211\u4eec\u7684\u9700\u6c42\u53d8\u66f4\u65f6\uff0c\u9700\u8981\u591a\u5904\u4fee\u6539\uff0c\u6bd4\u5982\u5f53\u6211\u9700\u8981\u6539\u4e3a\u8ba1\u7b97\u4e58\u79ef\u65f6\uff0c\u9700\u8981\u628a\u4e24\u4e2a\u5730\u65b9\u90fd\u6539\u6210 s *= \u6539\u4e86\u4ee5\u540e\u53ef\u80fd\u6f0f\u6539\u4e00\u90e8\u5206\uff0c\u7559\u4e0b Bug \u9690\u60a3 \u654f\u6377\u5f00\u53d1\u9700\u8981\u53cd\u590d\u4fee\u6539\u4ee3\u7801\uff0c\u6bd4\u5982\u4f60\u6b63\u5728\u8c03\u8bd5 += \u548c -= \u7684\u533a\u522b\uff0c\u770b\u7ed3\u679c\u53d8\u5316\uff0c\u5982\u679c\u4e00\u6b21\u5207\u6362\u9700\u8981\u6539\u591a\u5904\uff0c\u5c31\u5f71\u54cd\u4e86\u8c03\u8bd5\u901f\u5ea6 \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u5982\u679c\u4f60\u8fd8\u662f\u559c\u6b22\u201c\u4e00\u672c\u9053\u201d\u5199\u6cd5\u7684\u8bdd\uff0c\u4e0d\u59a8\u60f3\u60f3\u770b\uff0c\u5b8c\u5168\u4e0d\u7528\u4efb\u4f55\u6807\u51c6\u5e93\u548c\u7b2c\u4e09\u65b9\u5e93\u7684\u51fd\u6570\u548c\u7c7b\uff0c\u628a fmt::println \u548c std::vector \u8fd9\u4e9b\u51fd\u6570\u5168\u90e8\u62c6\u89e3\u6210\u4e00\u4e2a\u4e2a\u7cfb\u7edf\u8c03\u7528\u3002\u90a3\u8fd9\u6574\u4e2a\u7a0b\u5e8f\u4f1a\u6709\u591a\u96be\u5199\uff1f int main() { #ifdef _WIN32 int *a = (int *)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else int *a = (int *)mmap(NULL, 4 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); #endif a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; int s = 0; for (int i = 0; i < 4; i++) { s += a[i]; } char buffer[64]; buffer[0] = 's'; buffer[1] = 'u'; buffer[2] = 'm'; buffer[3] = ' '; buffer[4] = '='; buffer[5] = ' '; // \u4f8b\u5982\uff0c\u5982\u679c\u8981\u4fee\u6539\u6b64\u5904\u7684\u63d0\u793a\u6587\u672c\uff0c\u751a\u81f3\u9700\u8981\u4fee\u6539\u540e\u9762\u7684 len \u53d8\u91cf... int len = 6; int x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif int *b = (int *)a; b[0] = 4; b[1] = 5; b[2] = 6; b[3] = 7; int s = 0; for (int i = 0; i < 4; i++) { s += b[i]; } len = 6; x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif #ifdef _WIN32 VirtualFree(a, 0, MEM_RELEASE); #else munmap(a); #endif return 0; } \u4e0d\u4ec5\u5b8c\u5168\u6ca1\u6709\u53ef\u8bfb\u6027\u3001\u53ef\u7ef4\u62a4\u6027\uff0c\u751a\u81f3\u90fd\u6ca1\u6709\u53ef\u79fb\u690d\u6027\u3002 \u9664\u975e\u4f60\u53ea\u5199\u5e94\u4ed8\u5bfc\u5e08\u7684\u201c\u4e00\u6b21\u6027\u201d\u7a0b\u5e8f\uff0c\u4e00\u65e6\u8981\u5b9e\u73b0\u590d\u6742\u7684\u4e1a\u52a1\u9700\u6c42\uff0c\u4e0d\u53ef\u907f\u514d\u7684\u8981\u81ea\u5df1\u5c01\u88c5\u51fd\u6570\u6216\u7c7b\u3002\u7f51\u4e0a\u6240\u6709\u9f13\u5439\u201c\u4e0d\u5c01\u88c5\u201d\u201c\u8bbe\u8ba1\u6a21\u5f0f\u662f\u9762\u5b50\u5de5\u7a0b\u201d\u7684\u53cd\u667a\u8a00\u8bba\uff0c\u90fd\u662f\u6ca1\u6709\u505a\u8fc7\u5927\u578b\u9879\u76ee\u7684\u3002 \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u5f88\u591a\u8bbe\u8ba1\u6a21\u5f0f\u6559\u6750\u7247\u9762\u5f3a\u8c03 \u53ef\u8bfb\u6027 \uff0c\u4eff\u4f5b\u8bbe\u8ba1\u6a21\u5f0f\u5c31\u662f\u4e3a\u4e86\u201c\u4f18\u96c5\u201d\u201c\u9ad8\u5927\u4e0a\u201d\u201c\u7f8e\u5b66\u201d\uff1f\u4f7f\u5f97\u5f88\u591a\u4eba\u8ba4\u4e3a\uff0c\u201c\u6211\u8fd9\u4e2a\u662f\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u4e0d\u7528\u7f8e\u5316\u7ed9\u9886\u5bfc\u770b\u201d\u800c\u62d2\u7edd\u8bbe\u8ba1\u6a21\u5f0f\u3002\u5b9e\u9645\u4e0a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e \u65b9\u4fbf\u540e\u7eed\u4fee\u6539 \uff01 \u4f8b\u5982 B \u7ad9\u4ee5\u524d\u53ea\u652f\u6301\u4e0a\u4f20\u666e\u901a\u89c6\u9891\uff0c\u73b0\u5728\u53d4\u53d4\u7a81\u7136\u63d0\u51fa\uff1a\u8981\u652f\u6301\u4e92\u52a8\u89c6\u9891\uff0c\u5145\u7535\u89c6\u9891\uff0c\u89c6\u9891\u5408\u96c6\uff0c\u8fd8\u5e9f\u9664\u4e86\u89c6\u9891\u5206 p\uff0c\u8fd8\u8981\u652f\u6301\u4e0a\u4f20\u77ed\u89c6\u9891\uff0c\u7ad6\u5c4f\u5f00\u5173\u7b49\u2026\u2026\u6bcf\u4e00\u4e2a\u53d4\u53d4\u7684\u8981\u6c42\uff0c\u90fd\u9700\u8981\u5927\u91cf\u7a0b\u5e8f\u5458\u4fee\u6539\u4ee3\u7801\uff0c\u65e0\u8bba\u6d89\u53ca\u524d\u7aef\u8fd8\u662f\u540e\u7aef\u3002 \u4e0e\u5efa\u7b51\u3001\u7ed8\u753b\u7b49\u9886\u57df\u4e0d\u540c\uff0c\u4e00\u6b21\u4ea4\u4ed8\u5b8c\u6bd5\u5c31\u53ef\u4ee5\u51e0\u4e4e\u6c38\u4e45\u4f7f\u7528\u3002\u800c\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u66f4\uff0c\u90fd\u5bfc\u81f4\u4ee3\u7801\u9700\u8981\u4fee\u6539\u3002\u5f00\u53d1\u4eba\u5458\u51e0\u4e4e\u9700\u8981\u4e00\u76f4\u56f4\u7ed5\u7740\u8f6f\u4ef6\u4ee3\u7801\uff0c\u4e0d\u65ad\u7684\u4fee\u6539\u3002\u8c03\u67e5\u8868\u660e\uff0c\u7a0b\u5e8f\u5458 90% \u7684\u65f6\u95f4\u82b1\u5728 \u6539\u4ee3\u7801 \u4e0a\uff0c \u5199\u4ee3\u7801 \u53ea\u5360 10%\u3002 \u8f6f\u4ef6\u5c31\u50cf\u751f\u7269\uff0c\u8981\u4e0d\u65ad\u8fdb\u5316\uff0c\u8f6f\u4ef6\u4e0d\u66f4\u65b0\u4e0d\u7ef4\u62a4\u4e86\u7b49\u4e8e\u6b7b\u3002\u5982\u679c\u4e00\u4e2a\u8f6f\u4ef6\u9010\u6e10\u53d8\u5f97\u81c3\u80bf\u96be\u4ee5\u4fee\u6539\uff0c\u65e0\u6cd5\u9002\u5e94\u65b0\u9700\u6c42\uff0c\u90a3\u4ed6\u5c31\u50cf\u5df2\u7ecf\u5931\u53bb\u8fdb\u5316\u80fd\u529b\u7684\u751f\u7269\u79cd\u7fa4\uff0c\u5982\u300a\u4e09\u4f53\u300b\u4e16\u754c\u89c2\u4e2d\u201c\u5b89\u987f\u201d\u5230\u6fb3\u5927\u5229\u4e9a\u4fdd\u7559\u533a\u91cc\u201c\u7edd\u80b2\u201d\u7684\u4eba\u7c7b\uff0c\u88ab\u6dd8\u6c70\u53ea\u662f\u65f6\u95f4\u95ee\u9898\u3002 \u5982\u679c\u6211\u4eec\u80fd\u5728 \u5199\u4ee3\u7801 \u9636\u6bb5\uff0c\u5c31\u628a\u7a0b\u5e8f\u51c6\u5907\u5f97 \u6613\u4e8e\u540e\u7eed\u4fee\u6539 \uff0c\u90a3\u5c31\u53ef\u4ee5\u5728\u540e\u7eed 90% \u7684 \u6539\u4ee3\u7801 \u9636\u6bb5\u7701\u4e0b\u65e0\u6570\u65f6\u95f4\u3002 \u5982\u4f55\u8ba9\u4ee3\u7801\u6613\u4e8e\u4fee\u6539\uff1f\u524d\u4eba\u603b\u7ed3\u51fa\u4e00\u7cfb\u5217\u5e38\u7528\u7684\u5199\u6cd5\uff0c\u8fd9\u7c7b\u5199\u6cd5\u6709\u52a9\u4e8e\u8ba9\u540e\u7eed\u4fee\u6539\u66f4\u5bb9\u6613\uff0c\u5404\u81ea\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u5408\uff0c\u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u3002 \u63d0\u5347\u53ef\u7ef4\u62a4\u6027\u6700\u57fa\u7840\u7684\u4e00\u70b9\uff0c\u5c31\u662f\u907f\u514d\u91cd\u590d\uff01 \u5f53\u4f60\u6709\u5f88\u591a\u5730\u65b9\u51fa\u73b0\u91cd\u590d\u7684\u4ee3\u7801\u65f6\uff0c\u4e00\u65e6\u9700\u8981\u6d89\u53ca\u4fee\u6539\u8fd9\u90e8\u5206\u903b\u8f91\u65f6\uff0c\u5c31\u9700\u8981\u5230\u6bcf\u4e00\u4e2a\u51fa\u73b0\u4e86\u8fd9\u4e2a\u903b\u8f91\u7684\u4ee3\u7801\u4e2d\uff0c\u53bb\u9010\u4e00\u4fee\u6539\u3002 \u4f8b\u5982\u4f60\u7684\u540d\u5b57\uff0c\u5728\u51fa\u751f\u8bc1\uff0c\u8eab\u4efd\u8bc1\uff0c\u5b66\u751f\u8bc1\uff0c\u6bd5\u4e1a\u8bc1\uff0c\u623f\u4ea7\u8bc1\uff0c\u9a7e\u9a76\u8bc1\uff0c\u5404\u79cd\u5730\u65b9\u90fd\u51fa\u73b0\u4e86\u3002\u90a3\u4e48\u4f60\u8981\u6539\u540d\u7684\u8bdd\uff0c\u6240\u6709\u8fd9\u4e9b\u8bc1\u4ef6\u90fd\u9700\u8981\u91cd\u65b0\u5370\u5237\uff01\u5982\u679c\u80fd\u628a\u4ed6\u4eec\u5408\u5e76\u6210\u4e00\u4e2a\u201c\u7edf\u4e00\u8bc1\u201d\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4fee\u6539\u201c\u7edf\u4e00\u8bc1\u201d\u4e0a\u7684\u540d\u5b57\u5c31\u884c\u4e86\u3002 \u4e0d\u8fc7\uff0c\u73b0\u5b9e\u4e2d\u5e76\u6ca1\u6709\u9891\u7e41\u6539\u540d\u5b57\u7684\u9700\u6c42\uff0c\u8fd9\u8bf4\u660e\uff1a \u5bf9\u4e8e\u4e0d\u5e38\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u53ef\u4ee5\u5bb9\u5fcd\u4e00\u5b9a\u7684\u91cd\u590d\u3002 \u8d8a\u662f\u672a\u6765\u6709\u53ef\u80fd\u4fee\u6539\u7684\uff0c\u5c31\u8d8a\u9700\u8981\u8bbe\u8ba1\u6a21\u5f0f\u964d\u91cd\uff01 \u4f8b\u5982\u6570\u5b66\u5e38\u6570 PI = 3.1415926535897\uff0c\u8fd9\u8f88\u5b50\u90fd\u4e0d\u53ef\u80fd\u51fa\u73b0\u4fee\u6539\u7684\u9700\u6c42\uff0c\u90a3\u5199\u6b7b\u4e5f\u6ca1\u5173\u7cfb\u3002\u5982\u679c\u8981\u628a PI \u5b9a\u4e49\u6210\u5b8f\uff0c\u53ea\u662f\u51fa\u4e8e\u201c\u8bb0\u4e0d\u4f4f\u201d\u201c\u5199\u8d77\u6765\u592a\u957f\u4e86\u201d\u201c\u590d\u5236\u7c98\u8d34\u9ebb\u70e6\u201d\u3002\u6240\u4ee5\u5bf9\u4e8e PI \u8fd9\u79cd\u4e0d\u4f1a\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u964d\u91cd\u53ea\u662f\u589e\u52a0 \u53ef\u8bfb\u6027 \uff0c\u800c\u4e0d\u662f \u53ef\u4fee\u6539\u6027 \u3002 \u4f46\u662f\uff0c\u4e0d\u8981\u60f3\u5f53\u7136\uff01\u9700\u6c42\u7684\u5343\u53d8\u4e07\u5316\u603b\u662f\u8d85\u51fa\u4f60\u7684\u60f3\u8c61\u3002 \u4f8b\u5982\u4f60\u505a\u4e86\u4e00\u4e2a\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u6e38\u620f\uff0c\u9700\u8981\u7528\u5230\u91cd\u529b\u52a0\u901f\u5ea6 g = 9.8\uff0c\u4f60\u60f3\u5f53\u7136\u8ba4\u4e3a g \u4ee5\u540e\u4e0d\u53ef\u80fd\u4fee\u6539\u3002\u8001\u677f\u4e5f\u4fe1\u8a93\u65e6\u65e6\u5411\u4f60\u4fdd\u8bc1\uff1a\u201c\u6ca1\u4e8b\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u4e0d\u4f1a\u6539\u53d8\u3002\u201d\u4f60\u5c31\u5199\u6b7b\u5728\u4ee3\u7801\u91cc\u4e86\u3002 \u6ca1\u60f3\u5230\uff0c\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u8001\u677f\u7a81\u7136\u8981\u6c42\u4f60\u52a0\u5165\u201c\u6708\u7403\u7ae0\u201d\u5173\u5361\uff0c\u5728\u8fd9\u4e9b\u5173\u5361\u4e2d\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u662f g = 1.6\u3002 \u5982\u679c\u4f60\u4e00\u5f00\u59cb\u5c31\u5df2\u7ecf\u628a g \u63d0\u53d6\u51fa\u6765\uff0c\u5b9a\u4e49\u4e3a\u5e38\u91cf\uff1a struct Level { const double g = 9.8; void physics_sim() { bird.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f pig.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f } }; \u90a3\u4e48\u8981\u652f\u6301\u6708\u7403\u5173\u5361\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5c31\u53ef\u4ee5\u4e86\u3002 struct Level { double g; Level(Chapter chapter) { if (chapter == ChapterMoon) { g = 1.6; } else { g = 9.8; } } void physics_sim() { bird.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g pig.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g } }; \u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u505a zeno \u65f6\uff0c\u8be2\u95ee\u8981\u4e0d\u8981\u628a\u6e32\u67d3\u7ba1\u7ebf\u8282\u70b9\u5316\uff0c\u65b9\u4fbf\u7528\u6237\u52a8\u6001\u7f16\u7a0b\uff1f\u5f20\u7329\u7329\u5c31\u662f\u4fe1\u8a93\u65e6\u65e6\u9053\uff1a\u201c\u6e32\u67d3\u662f\u4e00\u4e2a\u9ad8\u5ea6\u6210\u719f\u9886\u57df\uff0c\u4e0d\u4f1a\u6709\u591a\u5c11\u4fee\u6539\u9700\u6c42\u7684\u3002\u201d\u5c0f\u5f6d\u8001\u5e08\u9042\u5199\u6b7b\u4e86\u6e32\u67d3\u7ba1\u7ebf\uff0c\u4e13\u4e3a\u6027\u80fd\u6781\u5ea6\u4f18\u5316\uff0c\u51e0\u4e2a\u6708\u540e\uff0c\u5f20\u7329\u7329\u7f9e\u7b54\u7b54\u627e\u5230\u5c0f\u5f6d\u8001\u5e08\uff1a\u201c\u5c0f\u5f6d\u8001\u5e08\uff0c\u90a3\u4e2a\uff0c\u6e32\u67d3\uff0c\u80fd\u4e0d\u80fd\u6539\u6210\u8282\u70b9\u554a\u2026\u2026\u201d\u3002\u8fd9\u4e2a\u6545\u4e8b\u544a\u8bc9\u6211\u4eec\uff0c\u7532\u65b9\u7684\u4fe1\u8a93\u65e6\u65e6\u653e\u7684\u4e00\u4e2a\u5c41\u90fd\u4e0d\u80fd\u4fe1\u3002 \u7528\u51fd\u6570\u5c01\u88c5 \u51fd\u6570\u5c31\u662f\u6765\u5e2e\u4f60\u89e3\u51b3\u4ee3\u7801\u91cd\u590d\u95ee\u9898\u7684\uff01\u8981\u9886\uff1a \u628a\u5171\u540c\u7684\u90e8\u5206\u63d0\u53d6\u51fa\u6765\uff0c\u628a\u4e0d\u540c\u7684\u90e8\u5206\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u3002 void sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } fmt::println(\"sum of v = {}\", s); } int main() { std::vector a = {1, 2, 3, 4}; sum(a); std::vector b = {5, 6, 7, 8}; sum(b); return 0; } \u8fd9\u6837 main \u51fd\u6570\u91cc\u5c31\u53ef\u4ee5\u53ea\u5173\u5fc3\u8981\u6c42\u548c\u7684\u6570\u7ec4\uff0c\u800c\u4e0d\u7528\u5173\u5fc3\u6c42\u548c\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\u4e86\u3002\u4e8b\u540e\u6211\u4eec\u53ef\u4ee5\u968f\u65f6\u628a sum \u7684\u5185\u5bb9\u5077\u5077\u6362\u6389\uff0c\u6362\u6210\u5e76\u884c\u7684\u7b97\u6cd5\uff0cmain \u4e5f\u4e0d\u7528\u77e5\u9053\u3002\u8fd9\u5c31\u662f \u5c01\u88c5 \uff0c\u53ef\u4ee5\u628a\u91cd\u590d\u7684\u516c\u5171\u90e8\u5206\u62bd\u53d6\u51fa\u6765\uff0c\u65b9\u4fbf\u4ee5\u540e\u4fee\u6539\u4ee3\u7801\u3002 sum \u51fd\u6570\u76f8\u5f53\u4e8e\uff0c\u5f53\u9700\u8981\u5439\u7a7a\u8c03\u65f6\uff0c\u63d2\u4e0a\u7a7a\u8c03\u63d2\u5ea7\u3002\u5f53\u9700\u8981\u7ed9\u624b\u673a\u5145\u7535\u65f6\uff0c\u63d2\u4e0a\u624b\u673a\u5145\u7535\u5668\u3002\u4f60\u4e0d\u9700\u8981\u5173\u5fc3\u63d2\u5ea7\u91cc\u7684\u7535\u54ea\u91cc\u6765\uff0c\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4f1a\u66ff\u4f60\u60f3\u529e\u6cd5\u89e3\u51b3\uff0c\u60f3\u529e\u6cd5\u4f18\u5316\uff0c\u60f3\u529e\u6cd5\u5347\u7ea7\u5230\u7eff\u8272\u80fd\u6e90\u3002\u4f60\u53ea\u9700\u8981\u5439\u7740\u7a7a\u8c03\u7ed9\u4f60\u6b63\u5728\u5f00\u53d1\u7684\u624b\u673a App \u4f18\u5316\u5c31\u884c\u4e86\uff0c\u5927\u5927\u51cf\u8f7b\u7a0b\u5e8f\u5458\u5fc3\u667a\u8d1f\u62c5\u3002 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u4f46\u662f\uff01\u8fd9\u6bb5\u4ee3\u7801\u4ecd\u7136\u6709\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u628a sum \u6c42\u548c\u7684\u7ed3\u679c\uff0c\u76f4\u63a5\u5728 sum \u91cc\u6253\u5370\u4e86\u51fa\u6765\u3002sum \u91cc\u5199\u6b7b\u4e86\uff0c\u6c42\u5b8c\u548c\u4e4b\u540e\u53ea\u80fd\u76f4\u63a5\u6253\u5370\uff0c\u8c03\u7528\u8005 main \u6839\u672c\u65e0\u6cd5\u63a7\u5236\u3002 \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u5c01\u88c5\uff0c\u6216\u8005\u8bf4\uff0c\u5c01\u88c5\u8fc7\u5934\u4e86\u3002 \u4f60\u628a\u624b\u673a\u5145\u7535\u5668 (fmt::println) \u710a\u6b7b\u5728\u4e86\u63d2\u5ea7 (sum) \u4e0a\uff0c\u73b0\u5728\u8fd9\u4e2a\u63d2\u5ea7\u53ea\u80fd\u7ed9\u624b\u673a\u5145\u7535 (\u7528\u4e8e\u76f4\u63a5\u6253\u5370) \u4e86\uff0c\u4e0d\u80fd\u7ed9\u7b14\u8bb0\u672c\u7535\u8111\u5145\u7535 (\u6c42\u548c\u7ed3\u679c\u4e0d\u76f4\u63a5\u7528\u4e8e\u6253\u5370) \u4e86\uff01\u5c3d\u7ba1\u901a\u8fc7\u66f4\u6362\u5145\u7535\u7ebf (\u53c2\u6570 v)\uff0c\u8fd8\u53ef\u4ee5\u652f\u6301\u652f\u6301\u5b89\u5353 (a) \u548c\u82f9\u679c (b) \u4e24\u79cd\u624b\u673a\u7684\u5145\u7535\uff0c\u4f46\u8fd9\u6837\u710a\u6b7b\u7684\u63d2\u5ea7\u5df2\u7ecf\u548c\u7b14\u8bb0\u672c\u7535\u8111\u65e0\u7f18\u4e86\u3002 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u5f88\u660e\u663e\uff0c\u201c\u6253\u5370\u201d\u548c\u201c\u6c42\u548c\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u64cd\u4f5c\uff0c\u4e0d\u5e94\u8be5\u710a\u6b7b\u5728\u4e00\u5757\u3002 sum \u51fd\u6570\u7684\u672c\u804c\u5de5\u4f5c\u662f\u201c\u6570\u7ec4\u6c42\u548c\u201d\uff0c\u4e0d\u5e94\u8be5\u9644\u8d60\u6253\u5370\u529f\u80fd\u3002 sum \u8ba1\u7b97\u51fa\u6c42\u548c\u7ed3\u679c\u540e\uff0c\u76f4\u63a5 return \u5373\u53ef\u3002 \u5982\u4f55\u5904\u7406\u8fd9\u4e2a\u7ed3\u679c\uff0c\u662f\u8c03\u7528\u8005 main \u7684\u4e8b\uff0c\u6b63\u5982\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4e0d\u4f1a\u7ba1\u4f60\u7528\u4ed6\u63d0\u4f9b\u7684\u7535\u6765\u5439\u7a7a\u8c03\u8fd8\u662f\u73a9\u6e38\u620f\u4e00\u6837\uff0c\u53ea\u8981\u4e0d\u59a8\u788d\u5230\u5176\u4ed6\u5c45\u6c11\u7684\u6b63\u5e38\u7528\u7535\u3002 int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum of a = {}\", sum(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"sum of b = {}\", sum(b)); return 0; } \u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8bf4\u7684 \u804c\u8d23\u5355\u4e00\u539f\u5219 \u3002 \u4e8c\u6b21\u5c01\u88c5 \u5047\u8bbe\u6211\u4eec\u8981\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff0c\u53ef\u4ee5\u518d\u5b9a\u4e49\u4e2a\u51fd\u6570 average\uff0c\u4ed6\u53ef\u4ee5\u57fa\u4e8e sum \u5b9e\u73b0\uff1a int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } double average(std::vector const &v) { return (double)sum(v) / v.size(); } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"average of a = {}\", average(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"average of b = {}\", average(b)); return 0; } \u8fdb\u4e00\u6b65\u5c01\u88c5\u4e00\u4e2a\u6253\u5370\u6570\u7ec4\u6240\u6709\u7edf\u8ba1\u5b66\u4fe1\u606f\u7684\u51fd\u6570\uff1a void print_statistics(std::vector const &v) { if (v.empty()) { fmt::println(\"this is empty...\"); } else { fmt::println(\"sum: {}\", sum(v)); fmt::println(\"average: {}\", average(v)); fmt::println(\"min: {}\", min(v)); fmt::println(\"max: {}\", max(v)); } } int main() { std::vector a = {1, 2, 3, 4}; print_statistics(a); std::vector b = {5, 6, 7, 8}; print_statistics(b); return 0; } \u66b4\u9732 API \u65f6\uff0c\u8981\u540c\u65f6\u63d0\u4f9b\u5e95\u5c42\u7684 API \u548c\u9ad8\u5c42\u5c01\u88c5\u7684 API\u3002\u7528\u6237\u5982\u679c\u60f3\u8981\u63a7\u5236\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u8c03\u7528\u5e95\u5c42 API\uff0c\u60f3\u8981\u7701\u4e8b\u7684\u7528\u6237\u53ef\u4ee5\u8c03\u7528\u9ad8\u5c42\u5c01\u88c5\u597d\u7684 API\u3002 \u9ad8\u5c42\u5c01\u88c5 API \u5e94\u5f53\u53ef\u4ee5\u5b8c\u5168\u901a\u8fc7\u8c03\u7528\u5e95\u5c42 API \u5b9e\u73b0\uff0c\u63d0\u4f9b\u9ad8\u5c42 API \u53ea\u662f\u65b9\u4fbf\u521d\u7ea7\u7528\u6237\u4f7f\u7528\u548c\u7406\u89e3\u3002 \u4f8b\u5982 libcurl \u5c31\u63d0\u4f9b\u4e86 curl_easy \u548c curl_multi \u4e24\u5957 API\u3002 - `curl_multi` \u63d0\u4f9b\u4e86\u8d85\u8be6\u7ec6\u7684\u53c2\u6570\uff0c\u628a\u6bcf\u4e2a\u64cd\u4f5c\u5206\u62c6\u6210\u591a\u6b65\uff0c\u65b9\u4fbf\u7528\u6237\u63d2\u624b\u7ec6\u8282\uff0c\u6ee1\u8db3\u9ad8\u7ea7\u7528\u6237\u7684\u5b9a\u5236\u5316\u9700\u6c42\uff0c\u4f46\u592a\u8fc7\u590d\u6742\uff0c\u96be\u4ee5\u5b66\u4e60\u3002 - `curl_easy` \u662f\u5bf9 `curl_multi` \u7684\u518d\u5c01\u88c5\uff0c\u63d0\u4f9b\u4e86\u66f4\u7b80\u5355\u7684 API\uff0c\u4f46\u662f\u5bf9\u5177\u4f53\u7ec6\u8282\u5c31\u96be\u4ee5\u64cd\u63a7\u4e86\uff0c\u9002\u5408\u521d\u5b66\u8005\u4e0a\u624b\u3002 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c Linux \u5185\u6838\u4e3a\u4ec0\u4e48\u575a\u6301\u4f7f\u7528 8 \u7f29\u8fdb\u4e3a\u4ee3\u7801\u98ce\u683c\uff1f \u56e0\u4e3a\u9ad8\u7f29\u8fdb\u53ef\u4ee5\u907f\u514d\u7a0b\u5e8f\u5458\u5199\u51fa\u5d4c\u5957\u5c42\u6570\u592a\u6df1\u7684\u4ee3\u7801\uff0c\u5f53\u4ed6\u5199\u51fa\u592a\u6df1\u5d4c\u5957\u65f6\uff0c\u5de8\u5927\u7684 8 \u7f29\u8fdb\u4f1a\u8ba9\u4ee3\u7801\u53d8\u5f97\u975e\u5e38\u504f\u53f3\uff0c\u5199\u4e0d\u4e0b\u591a\u5c11\u7a7a\u95f4\u3002\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u81ea\u5df1\u7ea2\u7740\u8138\u201c\u5bf9\u4e0d\u8d77\uff0c\u6211\u628a\u5355\u4e2a\u51fd\u6570\u5199\u592a\u6df1\u4e86\u201d\u7136\u540e\u8d76\u7d27\u62c6\u5206\u51fa\u591a\u4e2a\u51fd\u6570\u6765\u3002 \u6b64\u5916\uff0c\u4ed6\u8fd8\u89c4\u5b9a\u4e86\u5355\u4e00\u4e00\u4e2a\u51fd\u6570\u5fc5\u987b\u5728\u7ec8\u7aef\u5bbd\u5ea6 80 x 24 \u4e2d\u663e\u793a\u5f97\u4e0b\uff0c\u5426\u5219\u5c31\u9700\u8981\u62c6\u5206\u6210\u591a\u4e2a\u51fd\u6570\u91cd\u5199\uff0c\u8fd9\u914d\u5408 8 \u7f29\u8fdb\uff0c\u6709\u6548\u7684\u9650\u5236\u4e86\u5d4c\u5957\u7684\u5c42\u6570\uff0c\u8feb\u4f7f\u7a0b\u5e8f\u5458\u4e0d\u5f97\u4e0d\u91cd\u65b0\u601d\u8003\uff0c\u66f4\u89e3\u8026\u7684\u5199\u6cd5\u51fa\u6765\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u4f60\u4ea7\u751f\u4e86\u4e24\u4e2a\u9700\u6c42\uff0c\u5206\u522b\u5c01\u88c5\u4e86\u4e24\u4e2a\u51fd\u6570\uff1a sum \u6c42\u6240\u6709\u5143\u7d20\u7684\u548c product \u6c42\u6240\u6709\u5143\u7d20\u7684\u79ef int sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret += v[i]; } return ret; } int product(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret *= v[i]; } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", sum(a)); fmt::println(\"product: {}\", product(a)); return 0; } \u6ce8\u610f\u5230 sum \u548c product \u7684\u5185\u5bb9\u51e0\u4e4e\u5982\u51fa\u4e00\u8f99\uff0c\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff1a sum \u7684\u5faa\u73af\u4f53\u4e3a += \uff1b product \u7684\u5faa\u73af\u4f53\u4e3a *= \u3002 \u8fd9\u79cd\u51fd\u6570\u4f53\u5185\u6709\u90e8\u5206\u4ee3\u7801\u91cd\u590d\uff0c\u4f46\u53c8\u6709\u7279\u5b9a\u90e8\u5206\u4e0d\u540c\uff0c\u96be\u4ee5\u62bd\u79bb\u3002 \u8be5\u600e\u4e48\u590d\u7528\u8fd9\u91cd\u590d\u7684\u90e8\u5206\u4ee3\u7801\u5462\uff1f \u6211\u4eec\u8981\u628a sum \u548c product \u5408\u5e76\u6210\u4e00\u4e2a\u51fd\u6570 generic_sum \u3002\u7136\u540e\u901a\u8fc7\u51fd\u6570\u53c2\u6570\uff0c\u628a\u5dee\u5f02\u90e8\u5206\uff080\u3001 += \uff09\u201c\u6ce8\u5165\u201d\u5230\u4e24\u4e2a\u51fd\u6570\u539f\u672c\u4e0d\u540c\u5730\u65b9\u3002 \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u5982\u4f55\u8868\u793a\u6211\u8fd9\u4e2a\u51fd\u6570\u662f\u8981\u505a\u6c42\u548c += \u8fd8\u662f\u6c42\u79ef *= \uff1f \u8ba9\u6211\u4eec\u5b9a\u4e49\u679a\u4e3e\uff1a enum Mode { ADD, // \u6c42\u548c\u64cd\u4f5c MUL, // \u6c42\u79ef\u64cd\u4f5c }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { // \u51fd\u6570\u5185\u5224\u65ad\u679a\u4e3e\uff0c\u51b3\u5b9a\u8981\u505a\u4ec0\u4e48\u64cd\u4f5c ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", generic_sum(a, ADD)); // \u7528\u6237\u6307\u5b9a\u4ed6\u60f3\u8981\u7684\u64cd\u4f5c fmt::println(\"product: {}\", generic_sum(a, MUL)); return 0; } \u7136\u800c\uff0c\u5982\u679c\u7528\u6237\u73b0\u5728\u60f3\u8981\u6c42\u6570\u7ec4\u7684 \u6700\u5927\u503c \u5462\uff1f \u679a\u4e3e\u4e2d\u8fd8\u6ca1\u6709\u5b9e\u73b0\u6700\u5927\u503c\u7684\u64cd\u4f5c\u2026\u2026\u8981\u652f\u6301\uff0c\u5c31\u5f97\u624b\u5fd9\u811a\u4e71\u5730\u53bb\u4fee\u6539 generic_sum \u51fd\u6570\u548c Mode \u679a\u4e3e\u539f\u672c\u7684\u5b9a\u4e49\uff0c\u771f\u9ebb\u70e6\uff01 enum Mode { ADD, MUL, MAX, // ***\u6539*** }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } else if (mode == MAX) { // ***\u6539*** ret = std::max(ret, v[i]); // ***\u6539*** } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, MAX); // ***\u6539*** return 0; } \u6211\u7528 // ***\u6539*** \u6307\u793a\u4e86\u6240\u6709\u9700\u8981\u6539\u52a8\u7684\u5730\u65b9\u3002 \u4e3a\u4e86\u589e\u52a0\u4e00\u4e2a\u6c42\u6700\u5927\u503c\u7684\u64cd\u4f5c\uff0c\u5c31\u9700\u8981\u4e09\u5904\u5206\u6563\u5728\u5404\u5730\u7684\u6539\u52a8\uff01 \u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u5bb9\u6613\u6284\u6f0f\uff0c\u6284\u9519\uff0c\u6bd4\u5982 MAX \u4e0d\u5c0f\u5fc3\u6253\u9519\u6210 MUL \u4e86\uff0c\u81ea\u5df1\u5374\u6ca1\u53d1\u73b0\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u8fd9\u6837\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\uff0c\u5fc3\u667a\u8d1f\u62c5\u6781\u5927\uff0c\u6574\u5929\u5c31\u63d0\u5fc3\u540a\u80c6\u7740\u4e1c\u4e00\u5757\uff0c\u897f\u4e00\u5757\u7684\u6563\u88c5\u4ee3\u7801\uff0c\u62c5\u5fc3\u7740\u6709\u6ca1\u6709\u54ea\u4e2a\u5730\u65b9\u5199\u9519\u5199\u6f0f\uff0c\u4e25\u91cd\u59a8\u788d\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u5e76\u4e14\u5199\u51fa\u6765\u7684\u4ee3\u7801\u4e5f\u4e0d\u80fd\u9002\u5e94\u9700\u6c42\u7684\u53d8\u5316\uff1a\u5047\u5982\u6211\u9700\u8981\u652f\u6301 MIN \u5462\uff1f\u53c8\u5f97\u6539\u4e09\u4e2a\u5730\u65b9\uff01\u8fd9\u8fdd\u80cc\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u7684 \u5f00\u95ed\u539f\u5219 \u3002 \u5f00\u95ed\u539f\u5219: \u5bf9\u6269\u5c55\u5f00\u653e\uff0c\u5bf9\u4fee\u6539\u5c01\u95ed\u3002\u6307\u7684\u662f\u8f6f\u4ef6\u5728\u9002\u5e94\u9700\u6c42\u53d8\u5316\u65f6\uff0c\u5e94\u5c3d\u91cf\u901a\u8fc7 \u6269\u5c55\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\uff0c\u800c\u4e0d\u662f\u901a\u8fc7 \u4fee\u6539\u5df2\u6709\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\u3002 \u4f7f\u7528\u679a\u4e3e\u548c if-else \u5b9e\u73b0\u591a\u6001\uff0c\u96be\u4ee5\u6269\u5c55\uff0c\u8fd8\u8981\u4e00\u76f4\u53bb\u4fee\u6539\u539f\u51fd\u6570\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5c31\u8fdd\u80cc\u4e86 \u5f00\u95ed\u539f\u5219 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u5982\u679c\u6211\u4eec\u53ef\u4ee5\u201c\u6ce8\u5165\u201d\u4ee3\u7801\u5c31\u597d\u4e86\uff01\u80fd\u5426\u628a\u4e00\u6bb5\u201c\u4ee3\u7801\u201d\u4f5c\u4e3a generic_sum \u51fd\u6570\u7684\u53c2\u6570\u5462\uff1f \u4ee3\u7801\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\uff0c\u6ce8\u5165\u4ee3\u7801\u5c31\u662f\u6ce8\u5165\u51fd\u6570\u3002\u6211\u4eec\u5148\u5b9a\u4e49\u51fa\u4e09\u4e2a\u4e0d\u540c\u64cd\u4f5c\u5bf9\u5e94\u7684\u51fd\u6570\uff1a int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } \u7136\u540e\uff0c\u628a\u8fd9\u4e09\u4e2a\u5c0f\u51fd\u6570\uff0c\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u5927\u51fd\u6570 generic_sum \u7684\u53c2\u6570\u5c31\u884c\uff01 int generic_sum(std::vector const &v, auto op) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { // \u51fd\u6570\u4f5c\u8005\u65e0\u9700\u4e86\u89e3\u7528\u6237\u6307\u5b9a\u7684\u201c\u64cd\u4f5c\u201d\u5177\u4f53\u662f\u4ec0\u4e48 // \u53ea\u9700\u8981\u8c03\u7528\u8fd9\u4e00\u201c\u64cd\u4f5c\u201d\uff0c\u5f97\u5230\u7ed3\u679c\u5c31\u884c ret = op(ret, v[i]); } return ret; } int main() { std::vector a = {1, 2, 3, 4}; // \u7528\u6237\u65e0\u9700\u5173\u5fc3\u51fd\u6570\u7684\u5177\u4f53\u5b9e\u73b0\u662f\u4ec0\u4e48 // \u53ea\u9700\u968f\u5fc3\u6240\u6b32\u6307\u5b9a\u4ed6\u7684\u201c\u64cd\u4f5c\u201d\u4f5c\u4e3a\u53c2\u6570 generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u8d23\u4efb\u660e\u786e\u4e86\uff0c\u6211\u4eec\u6210\u529f\u628a\u4e00\u90e8\u5206\u7ec6\u8282\u4ece generic_sum \u4e2d\u8fdb\u4e00\u6b65\u62bd\u79bb\u3002 \u5e93\u4f5c\u8005 generic_sum \u4e0d\u5fc5\u4e86\u89e3 main \u7684\u64cd\u4f5c\u5177\u4f53\u662f\u4ec0\u4e48\uff0c\u4ed6\u53ea\u8d1f\u8d23\u5229\u7528\u8fd9\u4e2a\u64cd\u4f5c\u6c42\u201c\u548c\u201d\u3002 \u5e93\u7528\u6237 main \u4e0d\u5fc5\u4e86\u89e3 generic_sum \u5982\u4f55\u5b9e\u73b0\u64cd\u4f5c\u7d2f\u52a0\uff0c\u4ed6\u53ea\u7ba1\u6ce8\u5165\u201c\u5982\u4f55\u64cd\u4f5c\u201d\u7684\u4ee3\u7801\uff0c\u4ee5\u51fd\u6570\u7684\u5f62\u5f0f\u3002 \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 int generic_sum(std::vector const &v, auto op) { } \u8fd9\u91cc\u7684\u53c2\u6570 op \u7c7b\u578b\u58f0\u660e\u4e3a auto\uff0c\u6548\u679c\u5c31\u662f\uff0cop \u8fd9\u4e2a\u53c2\u6570\u73b0\u5728\u80fd\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u7684\u5bf9\u8c61\u4e86\uff08\u5305\u62ec\u51fd\u6570\uff01\uff09 int generic_sum(std::vector const &v, auto op) { ... } \u51c6\u786e\u7684\u8bf4\uff0c auto op \u53c2\u6570\u7684\u6548\u679c\u662f\u4f7f generic_sum \u53d8\u4e3a\u4e00\u4e2a \u6a21\u677f\u51fd\u6570 \uff0c\u5176\u4e2d op \u53c2\u6570\u53d8\u6210\u4e86\u6a21\u677f\u53c2\u6570\uff0c\u80fd\u591f\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u4e86\u3002\u800c\u5199\u660e\u7c7b\u578b\u7684\u53c2\u6570 std::vector const &v \u5c31\u6ca1\u6709\u4efb\u4f55\u989d\u5916\u6548\u679c\uff0c\u5c31\u53ea\u80fd\u63a5\u53d7 vector \u800c\u5df2\u3002 \u5982\u679c\u4f60\u4e0d\u652f\u6301 C++20 \u7684\u8bdd\uff0c\u9700\u8981\u663e\u5f0f\u5199\u51fa template \uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\uff1a template int generic_sum(std::vector const &v, Op op) { ... } C++11\uff1aauto \u53ea\u80fd\u7528\u4e8e\u5b9a\u4e49\u53d8\u91cf\uff1bC++14\uff1a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u662f auto\uff1bC++17\uff1a\u6a21\u677f\u53c2\u6570\u4e5f\u53ef\u4ee5 auto\uff1bC++20\uff1a\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5\u662f auto \u4e86\uff1b\uff08\u72c2\u60f3\uff09C++47\uff1aauto \u73b0\u5728\u662f C++47 \u7684\u552f\u4e00\u5173\u952e\u5b57\uff0c\u7528\u6237\u53ea\u9700\u4e0d\u65ad\u8f93\u5165 auto-auto-auto\uff0c\u7f16\u8bd1\u5668\u5185\u5efa\u4eba\u5de5\u667a\u80fd\u81ea\u52a8\u8bc6\u522b\u4f60\u7684\u610f\u56fe\u751f\u6210\u673a\u5668\u7801\u3002 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 \u5728\u8fc7\u53bb\u7684 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f \u4e2d\uff0c\u51fd\u6570\uff08\u4ee3\u7801\uff09\u548c\u5bf9\u8c61\uff08\u6570\u636e\uff09\u88ab \u5272\u88c2 \u5f00\u6765\uff0c\u4ed6\u4eec\u611a\u6627\u5730\u8ba4\u4e3a \u51fd\u6570\u4e0d\u662f\u5bf9\u8c61 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f \u5219\u8ba4\u4e3a\uff1a \u51fd\u6570\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u51fd\u6570\u53ef\u4ee5\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u51fd\u6570\u7684\u53c2\u6570\uff01 Function lives matter! \u9762\u5411\u5bf9\u8c61\u5c31\u597d\u6bd4\u8ba1\u7b97\u673a\u7684\u201c\u54c8\u4f5b\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u548c\u6570\u636e\u5272\u88c2\uff0c\u4ee3\u7801\u53ea\u80fd\u5355\u65b9\u9762\u64cd\u4f5c\u6570\u636e\u3002\u51fd\u6570\u5f0f\u5c31\u597d\u6bd4\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u4e5f\u662f\u6570\u636e\u3002\u770b\u4f3c\u4f1a\u5bfc\u81f4\u4f4e\u6548\uff0c\u5b9e\u5219\u5927\u5927\u65b9\u4fbf\u4e86\u52a8\u6001\u52a0\u8f7d\u65b0\u7a0b\u5e8f\uff0c\u56e0\u800c\u73b0\u5728\u7684\u8ba1\u7b97\u673a\u57fa\u672c\u90fd\u91c7\u7528\u4e86\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff0c\u88ab\u4eb2\u5207\u5730\u5c0a\u79f0\u4e3a \u51fd\u6570\u5bf9\u8c61 \u3002 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 C++98 \u65f6\u4ee3\uff0c\u4eba\u4eec\u8fd8\u9700\u8981\u5355\u72ec\u8dd1\u5230 main \u5916\u9762\uff0c\u4e13\u95e8\u5b9a\u4e49 add \u3001 mul \u3001 max \u51fd\u6570\u3002\u5f04\u5f97\u6574\u4e2a\u4ee3\u7801\u4e71\u54c4\u54c4\u7684\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } C++11 \u5f15\u5165\u4e86 Lambda \u8868\u8fbe\u5f0f \u8bed\u6cd5\uff0c\u5141\u8bb8\u4f60\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002 int main() { std::vector a = {1, 2, 3, 4}; auto add = [](int a, int b) { return a + b; }; auto mul = [](int a, int b) { return a * b; }; auto max = [](int a, int b) { return std::max(a, b); }; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u4e0d\u7528\u5f80 main \u5916\u9762\u585e\u5783\u573e\u4e86\uff0c\u4e00\u6e05\u723d\u3002 \u66f4\u8fdb\u4e00\u6b65\uff0c\u6211\u4eec\u751a\u81f3\u4e0d\u7528\u5b9a\u4e49\u53d8\u91cf\uff0c\u76f4\u63a5\u628a Lambda \u8868\u8fbe\u5f0f\u5199\u5728 generic_sum \u7684\u53c2\u6570\u91cc\u5c31\u884c\u4e86\uff01 int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); // ***\u6539*** return 0; } \u4ee5\u4e0a\u5199\u6cd5\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u8981\u652f\u6301\u4e00\u4e2a\u65b0\u64cd\u4f5c\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5730\u65b9\uff1a\u5728\u8c03\u7528 generic_sum \u65f6\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002\u968f\u53eb\u968f\u5230\uff0c\u4e0d\u7528\u7ea0\u7ed3\u4e8e\u201c\u8d77\u540d\u5f3a\u8feb\u75c7\u201d\uff0c\u662f\u4e0d\u662f\u5f88\u65b9\u4fbf\u5462\uff1f \u51c6\u786e\u7684\u8bf4\uff0cLambda \u521b\u5efa\u7684\u662f\u51fd\u6570\u5bf9\u8c61 (function object) \u6216\u79f0\u4eff\u51fd\u6570 (functor) \u800c\u4e0d\u662f\u4f20\u7edf\u610f\u4e49\u4e0a\u7684\u51fd\u6570\u3002 \u5176\u5b9e C++98 \u65f6\u4ee3\u4eba\u4eec\u5c31\u5df2\u7ecf\u5927\u91cf\u5728\u7528 operator()() \u6a21\u62df\u51fd\u6570\u5bf9\u8c61\u4e86\uff0c\u8457\u540d\u7684\u7b2c\u4e09\u65b9\u5e93 Boost \u4e5f\u5c01\u88c5\u4e86\u5404\u79cd\u51fd\u6570\u5f0f\u5e38\u7528\u7684\u5bb9\u5668\u548c\u5de5\u5177\u3002C++11 \u624d\u7ec8\u4e8e\u628a \u51fd\u6570\u5bf9\u8c61 \u8fd9\u4e2a\u6982\u5ff5\u8f6c\u6b63\uff0c\u5e76\u5f15\u5165\u4e86\u66f4\u65b9\u4fbf\u7684 Lambda \u8bed\u6cd5\u7cd6\u3002 \u5373\u4f7f\u662f\u9762\u5411\u5bf9\u8c61\u7684\u5934\u53f7\u5b5d\u5b50 Java\uff0c\u4e5f\u5df2\u7ecf\u5f00\u59cb\u5f15\u5165\u51fd\u6570\u5f0f\u7684 Lambda \u8bed\u6cd5\u7cd6\uff0cC# \u7684 LINQ \u66f4\u662f\u660e\u76ee\u5f20\u80c6\u7684\u81f4\u656c map-reduce \u5168\u5bb6\u6876\uff0c\u751a\u81f3 C \u8bed\u8a00\u7528\u6237\u4e5f\u5f00\u59cb\u73a9\u5404\u79cd\u51fd\u6570\u6307\u9488\u56de\u8c03\u2026\u2026\u6ca1\u529e\u6cd5\uff0c\u51fd\u6570\u5f0f\u786e\u5b9e\u65b9\u4fbf\u5440\uff01 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u51fd\u6570\u5bf9\u8c61 op \u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\uff0c\u8ba9 generic_sum \u5185\u90e8\u53bb\u8c03\u7528\uff0c\u5c31\u50cf\u5f80 generic_sum \u4f53\u5185\u201c\u6ce8\u5165\u201d\u4e86\u4e00\u6bb5\u81ea\u5b9a\u4e49\u4ee3\u7801\u4e00\u6837\u3002 \u8fd9\u53ef\u4ee5\u8ba9 generic_sum \u5728\u4e0d\u4fee\u6539\u672c\u4f53\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7\u4fee\u6539\u201c\u6ce8\u5165\u201d\u90e8\u5206\uff0c\u8f7b\u677e\u6269\u5c55\uff0c\u6ee1\u8db3 \u5f00\u95ed\u539f\u5219 \u3002 \u66f4\u51c6\u786e\u7684\u8bf4\uff0c\u8fd9\u4f53\u73b0\u7684\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8981\u6c42\u7684 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u3002 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219: \u4e00\u4e2a\u5c01\u88c5\u597d\u7684\u51fd\u6570\u6216\u7c7b\uff0c\u5e94\u8be5\u5c3d\u91cf\u4f9d\u8d56\u4e8e\u62bd\u8c61\u63a5\u53e3\uff0c\u800c\u4e0d\u662f\u4f9d\u8d56\u4e8e\u5177\u4f53\u5b9e\u73b0\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u56db\u5927\u7f16\u7a0b\u8303\u5f0f\u90fd\u5404\u81ea\u53d1\u5c55\u51fa\u4e86 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u7684\u89e3\u51b3\u65b9\u6848\uff1a \u9762\u5411\u8fc7\u7a0b\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u6307\u9488 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u865a\u51fd\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u5bf9\u8c61 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u6a21\u677f\u5143\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u6a21\u677f\u53c2\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u540c\u6837\u662f\u628a\u62bd\u8c61\u63a5\u53e3\u4f5c\u4e3a\u53c2\u6570\uff0c\u540c\u6837\u89e3\u51b3\u53ef\u6269\u5c55\u95ee\u9898\u3002 \u51fd\u6570\u6307\u9488\u8d34\u8fd1\u5e95\u5c42\u786c\u4ef6\uff0c\u865a\u51fd\u6570\u65b9\u4fbf\u6574\u5408\u591a\u4e2a\u63a5\u53e3\uff0c\u51fd\u6570\u5bf9\u8c61\u8f7b\u91cf\u7ea7\u3001\u968f\u5730\u53d6\u7528\uff0c\u6a21\u677f\u5143\u6709\u52a9\u9ad8\u6027\u80fd\u4f18\u5316\uff0c\u4e0d\u540c\u7684\u7f16\u7a0b\u8303\u5f0f\u6b8a\u9014\u540c\u5f52\u3002 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4f9d\u8d56\u6ce8\u5165\u539f\u5219\u53ef\u4ee5\u51cf\u5c11\u4ee3\u7801\u4e4b\u95f4\u7684\u8026\u5408\u5ea6\uff0c\u5927\u5927\u63d0\u9ad8\u4ee3\u7801\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u8026\u5408\u5ea6: \u6307\u7684\u662f\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u548c\u5176\u4ed6\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u8026\u5408\u5ea6\u8d8a\u4f4e\uff0c\u8d8a\u5bb9\u6613\u8fdb\u884c\u5355\u5143\u6d4b\u8bd5\u3001\u91cd\u6784\u3001\u590d\u7528\u548c\u6269\u5c55\u3002 \u9ad8\u8026\u5408\u5ea6\u7684\u5178\u578b\u662f\u201c\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u201d\u3002\u4f4e\u8026\u5408\u7684\u5178\u8303\u662f\u86af\u8693\uff0c\u56e0\u4e3a\u86af\u8693\u53ef\u4ee5\u5728\u4efb\u610f\u65ad\u9762\u5207\u5f00\uff0c\u8fd8\u80fd\u6d3b\u4e0b\u6765\uff0c\u770b\u6765\u86af\u8693\u7684\u8eab\u4f53\u8bbe\u8ba1\u975e\u5e38\u201c\u6a21\u5757\u5316\u201d\u5462\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8f6f\u4ef6\u5e94\u5f53\u8ffd\u6c42\u4f4e\u8026\u5408\u5ea6\uff0c\u9002\u5ea6\u89e3\u8026\u7684\u8f6f\u4ef6\u80fd\u66f4\u5feb\u9002\u5e94\u9700\u6c42\u53d8\u5316\u3002\u4f46\u8fc7\u5ea6\u7684\u4f4e\u8026\u5408\u4e5f\u4f1a\u5bfc\u81f4\u4ee3\u7801\u8fc7\u4e8e\u5206\u6563\uff0c\u4e0d\u6613\u9605\u8bfb\u548c\u4fee\u6539\uff0c\u751a\u81f3\u53ef\u80fd\u8d77\u5230\u53cd\u6548\u679c\u3002 \u82e5\u4f60\u89e3\u8026\u540e\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u5316\u8981\u6539\u52a8\u7684\u5730\u65b9\u53d8\u5c11\u4e86\uff0c\u90a3\u5c31\u662f\u5408\u7406\u7684\u89e3\u8026\u3002\u82e5\u4f60\u8fc7\u5206\u89e3\u8026\uff0c\u4ee3\u7801\u4e1c\u4e00\u5757\u897f\u4e00\u5757\uff0c\u4ee5\u81f3\u4e8e\u9700\u6c42\u53d8\u5316\u65f6\u9700\u8981\u5230\u5904\u6539\uff0c\u6bd4\u4e0d\u89e3\u8026\u65f6\u6d6a\u8d39\u7684\u65f6\u95f4\u8fd8\u8981\u591a\uff0c\u90a3\u5c31\u662f\u89e3\u8026\u8fc7\u5ea6\u3002 \u5b8c\u5168\u96f6\u8026\u5408\u7684\u7a0b\u5e8f\u6bcf\u4e2a\u51fd\u6570\u4e92\u4e0d\u8054\u7cfb\uff0c\u5c31\u50cf\u628a\u86af\u8693\u62c6\u6563\u6210\u4e00\u4e2a\u4e2a\u72ec\u7acb\u7684\u7ec6\u80de\u4e00\u6837\u3002\u8fde\u521d\u59cb\u9700\u6c42\u201c\u6d3b\u7740\u201d\u90fd\u5b9e\u73b0\u4e0d\u4e86\uff0c\u8c08\u4f55\u9002\u5e94\u9700\u6c42\u53d8\u5316\uff1f\u6240\u4ee5\u89e3\u8026\u4e5f\u5207\u52ff\u77eb\u6789\u8fc7\u6b63\u3002 \u4e3a\u4e86\u907f\u514d\u89e3\u8026\u77eb\u6789\u8fc7\u6b63\uff0c\u4eba\u4eec\u53c8\u63d0\u51fa\u4e86\u5185\u805a\u7684\u6982\u5ff5\uff0c\u5e76\u89c4\u5b9a\u89e3\u8026\u7684\u524d\u63d0\u662f\uff1a\u4e0d\u803d\u8bef\u5185\u805a\u3002\u803d\u8bef\u5230\u5185\u805a\u7684\u89e3\u8026\uff0c\u5c31\u53ea\u4f1a\u8d77\u5230\u964d\u4f4e\u53ef\u7ef4\u62a4\u6027\u7684\u53cd\u6548\u679c\u4e86\u3002 \u5185\u805a: \u6307\u7684\u662f\u540c\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u5185\u90e8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u5185\u805a\u5ea6\u8d8a\u9ad8\uff0c\u529f\u80fd\u8d8a\u72ec\u7acb\uff0c\u8d8a\u65b9\u4fbf\u96c6\u4e2d\u7ef4\u62a4\u3002 \u4f8b\u5982\uff0c\u4eba\u7684\u5fc3\u810f\u4e13\u95e8\u8d1f\u8d23\u6cf5\u8840\uff0c\u809d\u810f\u53ea\u8d1f\u8d23\u89e3\u6bd2\uff0c\u8fd9\u5c31\u662f\u9ad8\u5185\u805a\u7684\u4eba\u4f53\u5668\u5b98\u3002\u82e5\u4eba\u7684\u5fc3\u810f\u8fd8\u8981\u517c\u804c\u89e3\u6bd2\uff0c\u809d\u810f\u8fd8\u517c\u804c\u6cf5\u8840\uff0c\u770b\u4f3c\u597d\u50cf\u662f\u589e\u52a0\u4e86\u201c\u4e07\u4e00\u5fc3\u810f\u574f\u6389\u201d\u7684\u5197\u4f59\u6027\uff0c\u5b9e\u9645\u4e0a\u628a\u201c\u6cf5\u8840\u201d\u8fd9\u4e00\u529f\u80fd\u62c6\u6563\u5230\u5404\u5730\uff0c\u65e0\u6cd5\u201c\u96c6\u4e2d\u529b\u91cf\u6cf5\u5927\u8840\u201d\u4e86\u3002 \u4eba\u7c7b\u7684\u5927\u8111\u548c CPU \u4e00\u6837\uff0c\u4e5f\u6709\u201c\u7f13\u5b58\u5c40\u57df\u6027 (cache-locality)\u201d\u7684\u9650\u5236\uff1a\u4e0d\u80fd\u540c\u65f6\u5728\u5f88\u591a\u4e2a\u4e3b\u9898\u4e4b\u95f4\u5feb\u901f\u5207\u6362\uff0c\u65e0\u8bba\u662f\u65f6\u95f4\u4e0a\u7684\u8fd8\u662f\u7a7a\u95f4\u4e0a\u7684\u5272\u88c2 (cache-miss)\uff0c\u90fd\u4f1a\u5e72\u6270\u7a0b\u5e8f\u5458\u601d\u7ef4\u7684\u8fde\u8d2f\u6027\uff0c\u4ece\u800c\u589e\u5927\u5fc3\u667a\u8d1f\u62c5\u3002 \u597d\u7684\u8f6f\u4ef6\u8981\u4fdd\u6301\u4f4e\u8026\u5408\uff0c\u540c\u65f6\u9ad8\u5185\u805a\u3002 \u5c31\u50cf\u201c\u6c11\u4e3b\u96c6\u4e2d\u5236\u201d\u4e00\u6837\uff0c\u65e2\u8981\u76d1\u7763\u9632\u6b62\u5927\u6743\u72ec\u63fd\uff0c\u53c8\u8981\u96c6\u4e2d\u529b\u91cf\u529e\u4e00\u4e2a\u4eba\u529e\u4e0d\u6210\u7684\u5927\u4e8b\u3002 \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u4f20\u7edf\u7684\u9762\u5411\u5bf9\u8c61\u540c\u6837\u53ef\u4ee5\u7528 \u865a\u51fd\u6570\u63a5\u53e3\u7c7b \u6a21\u62df \u51fd\u6570\u5bf9\u8c61 \u4e00\u6837\u7684\u529f\u80fd\uff0c\u53ea\u4e0d\u8fc7\u6ca1\u6709 lambda \u548c\u95ed\u5305\u7684\u8bed\u6cd5\u52a0\u6301\uff0c\u5199\u8d77\u6765\u975e\u5e38\u7e41\u7410\uff0c\u5c31\u548c\u5728 C \u8bed\u8a00\u91cc\u201c\u6a21\u62df\u201d\u9762\u5411\u5bf9\u8c61\u4e00\u6837\u3002 \u4e3a\u4e86\u8fd9\u4e48\u5c0f\u7684\u4e00\u4e2a\u4ee3\u7801\u5757\uff0c\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u5c31\u50cf\u5988\u5988\u5f00\u4e00\u67b6\u201c\u7a7a\u4e2d\u6218\u8f66\u201d A380 \u53ea\u662f\u4e3a\u4e86\u63a5\u4f60\u653e\u5b66\u4e00\u6837\uff0c\u7b49\u4f60\u503c\u597d\u673a\u7684\u65f6\u95f4\u6211\u81ea\u5df1\u8d70\u90fd\u8d70\u5230\u4e86\u3002\u800c\u51fd\u6570\u5f0f\u4e2d\uff0c\u7528 lambda \u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u76f8\u5f53\u4e8e\u968f\u5730\u6293\u6765\u4e00\u53f0\u5171\u4eab\u5355\u8f66\u5f00\u8d70\u3002 struct OpBase { // \u9762\u5411\u5bf9\u8c61\uff1a\u9047\u4e8b\u4e0d\u51b3\u5148\u5b9a\u4e49\u63a5\u53e3\u2026\u2026 virtual int compute(int a, int b) = 0; virtual ~OpBase() = default; }; struct OpAdd : OpBase { int compute(int a, int b) override { return a + b; } }; struct OpMul : OpBase { int compute(int a, int b) override { return a * b; } }; struct OpMax : OpBase { int compute(int a, int b) override { return std::max(a, b); } }; int generic_sum(std::vector const &v, OpBase *op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op->compute(ret, v[i]); // \u5199\u8d77\u6765\u4e5f\u9ebb\u70e6\uff0c\u9700\u8981\u8c03\u7528\u4ed6\u7684\u6210\u5458\u51fd\u6570\uff0c\u6210\u5458\u51fd\u6570\u53c8\u8981\u8d77\u540d\u2026\u2026 } delete op; return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, new OpAdd()); generic_sum(a, new OpMul()); generic_sum(a, new OpMax()); return 0; } \u4e0d\u4ec5\u9700\u8981\u5b9a\u4e49\u4e00\u5806\u7c7b\uff0c\u63a5\u53e3\u7c7b\uff0c\u5b9e\u73b0\u7c7b\uff0c\u7ee7\u627f\u6765\u7ee7\u627f\u53bb\uff0c\u8fd8\u9700\u8981\u7ba1\u7406\u8ba8\u538c\u7684\u6307\u9488\uff0c\u4ee3\u7801\u91cf\u7ffb\u500d\uff0c\u6ca1\u4ec0\u4e48\u53ef\u8bfb\u6027\uff0c\u53c8\u5f71\u54cd\u8fd0\u884c\u6548\u7387\u3002 3 \u5e74 2 \u73ed\u5c0f\u5f6d\u540c\u5b66\uff0c\u4f60\u7684\u5988\u5988\u5f00\u7740 A380 \u6765\u63a5\u4f60\u4e86\u3002 \u800c\u73b0\u4ee3 C++ \u53ea\u9700 Lambda \u8bed\u6cd5\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u723d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u521a\u521a\uff0c\u6211\u4eec\u7684\u5b9e\u73b0\u7528\u4e86 auto op \u505a\u53c2\u6570\uff0c\u8fd9\u7b49\u4ef7\u4e8e\u8ba9 generic_sum \u53d8\u6210\u4e00\u4e2a\u6a21\u677f\u51fd\u6570\u3002 int generic_sum(std::vector const &v, auto op); // \u4e0d\u652f\u6301 C++20 \u65f6\u7684\u66ff\u4ee3\u5199\u6cd5\uff1a template int generic_sum(std::vector const &v, Op op); \u8fd9\u610f\u5473\u7740\u6bcf\u5f53\u7528\u6237\u6307\u5b9a\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff08lambda\uff09\u65f6\uff0c generic_sum \u90fd\u4f1a\u91cd\u65b0\u5b9e\u4f8b\u5316\u4e00\u904d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u7f16\u8bd1\u540e\uff0c\u4f1a\u53d8\u6210\u7c7b\u4f3c\u4e8e\u8fd9\u6837\uff1a generic_sum(a); generic_sum(a); generic_sum(a); \u4f1a\u751f\u6210\u4e09\u4efd\u51fd\u6570\uff0c\u6bcf\u4e2a\u90fd\u662f\u72ec\u7acb\u7f16\u8bd1\u7684\uff1a int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = add(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = mul(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = max(ret, v[i]); } return ret; } \u8fd9\u5141\u8bb8\u7f16\u8bd1\u5668\u4e3a\u6bcf\u4e2a\u7248\u672c\u7684 generic_sum \u5355\u72ec\u505a\u4f18\u5316\uff0c\u91cf\u8eab\u5b9a\u5236\u6700\u4f18\u7684\u4ee3\u7801\u3002 \u4f8b\u5982 add \u8fd9\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u56e0\u4e3a\u53ea\u5728 generic_sum \u4e2d\u4f7f\u7528\u4e86\uff0c\u4f1a\u88ab\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u5185\u8054\uff0c\u4e0d\u4f1a\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u548c\u8df3\u8f6c\u7684\u6307\u4ee4\uff0c\u5404\u81ea\u4f18\u5316\u6210\u5355\u72ec\u4e00\u6761\u52a0\u6cd5 / \u4e58\u6cd5 / \u6700\u5927\u503c\u6307\u4ee4\u7b49\u3002 \u6bd4\u5982\uff0c\u7f16\u8bd1\u5668\u4f1a\u68c0\u6d4b\u5230 += \u53ef\u4ee5\u77e2\u91cf\u5316\uff0c\u4e8e\u662f\u7528 _mm_add_epi32 \u66ff\u4ee3\u4e86\u3002\u540c\u7406\uff0cmul \u5219\u7528 _mm_mullo_epi32 \u66ff\u4ee3\uff0cmax \u5219\u7528 _mm_max_epi32 \u66ff\u4ee3\u7b49\uff0c\u5404\u81ea\u5206\u522b\u751f\u6210\u4e86\u5404\u81ea\u7248\u672c\u6700\u4f18\u7684\u4ee3\u7801\u3002\u800c\u5982\u679c\u662f\u666e\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u4e0d\u4f1a\u751f\u6210\u4e09\u4efd\u91cf\u8eab\u5b9a\u505a\u7684\u5b9e\u4f8b\uff0c\u65e0\u6cd5\u77e2\u91cf\u5316\uff08\u6709\u4e00\u79cd\u4f8b\u5916\uff0c\u5c31\u662f\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u4e86 generic_sum \u4f3c\u4e4e\u53ea\u6709\u8fd9\u4e09\u79cd\u53ef\u80fd\u53c2\u6570\uff0c\u7136\u540e\u505a\u4e86 IPO \u4f18\u5316\uff0c\u4f46\u5e76\u4e0d\u5982\u6a21\u677f\u5b9e\u4f8b\u5316\u4e00\u6837\u7a33\u5b9a\u5f3a\u5236\uff09\u3002 \u4e3a\u4e09\u79cd\u4e0d\u540c\u7684 op \u53c2\u6570\u5206\u522b\u5b9a\u505a\u4e09\u4efd\u3002\u867d\u7136\u589e\u52a0\u4e86\u7f16\u8bd1\u65f6\u95f4\uff0c\u81a8\u80c0\u4e86\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u4f53\u79ef\uff1b\u4f46\u751f\u6210\u7684\u673a\u5668\u7801\u662f\u5206\u522b\u9488\u5bf9\u6bcf\u79cd\u7279\u4f8b\u4e00\u5bf9\u4e00\u6df1\u5ea6\u4f18\u5316\u7684\uff0c\u66f4\u9ad8\u6548\u3002 \u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\uff08gemm\uff09\u7684\u6700\u4f18\u7b97\u6cd5\uff0c\u5bf9\u4e8e\u4e0d\u540c\u7684\u77e9\u9635\u5927\u5c0f\u548c\u5f62\u72b6\u662f\u4e0d\u540c\u7684\u3002\u8457\u540d\u7684\u7ebf\u6027\u4ee3\u6570\u5e93 CUBLAS \u548c MKL \u4e2d\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u7528\u6237\u8f93\u5165\u7684\u77e9\u9635\u5f62\u72b6\uff0c\u9009\u53d6\u6700\u4f18\u7684\u7b97\u6cd5\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cCUBLAS \u5e93\u91cc\u5176\u5b9e\u5b58\u7740\u9002\u5408\u5404\u79cd\u77e9\u9635\u5927\u5c0f\u6392\u5217\u7ec4\u5408\u7684\u7b97\u6cd5\u4ee3\u7801\uff08\u4ee5 fatbin \u683c\u5f0f\u5b58\u50a8\u5728\u4e8c\u8fdb\u5236\u4e2d\uff09\u3002\u5f53\u8c03\u7528\u77e9\u9635\u4e58\u6cd5\u65f6\uff0c\u81ea\u52a8\u67e5\u5230\u6700\u9002\u5408\u7684\u4e00\u7248\u6765\u8c03\u7528\u7ed9\u4f60\u3002\u7c7b\u4f3c gemm\uff0c\u8fd8\u6709 gemv\u3001spmv\u2026\u2026\u6240\u6709\u7684\u77e9\u9635\u8fd0\u7b97 API \u90fd\u7ecf\u5386\u4e86\u8fd9\u6837\u7684\u201c\u7f16\u8bd1\u671f\u201d\u66b4\u529b\u6392\u5217\u7ec4\u5408\uff0c\u53ea\u4e3a\u201c\u8fd0\u884c\u65f6\u201d\u91ca\u653e\u6700\u5927\u6027\u80fd\uff01\u8fd9\u4e5f\u5bfc\u81f4\u7f16\u8bd1\u597d\u7684 cublas.dll \u6587\u4ef6\u6765\u5230\u4e86\u6050\u6016\u7684 20 MB \u5de6\u53f3\uff0c\u800c\u6211\u4eec\u79f0\u4e4b\u4e3a\u9ad8\u6548\u3002 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u6bcf\u4e2a Lambda \u8868\u8fbe\u5f0f\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b\uff0c\u8fd9\u4f7f\u5f97 generic_sum \u5bf9\u4e8e\u6bcf\u4e2a\u4e0d\u540c\u7684 Lambda \u90fd\u4f1a\u5b9e\u4f8b\u5316\u4e00\u904d\u3002\u867d\u7136\u6709\u5229\u4e8e\u6027\u80fd\u4f18\u5316\uff0c\u4f46\u4e5f\u5f71\u54cd\u4e86\u7f16\u8bd1\u901f\u5ea6\u548c\u7075\u6d3b\u6027\u3002 \u901a\u5e38\uff0c\u6211\u4eec\u53ea\u80fd\u901a\u8fc7 decltype(add) \u83b7\u53d6 add \u8fd9\u4e2a Lambda \u5bf9\u8c61\u7684\u7c7b\u578b\u3002\u4e5f\u53ea\u80fd\u901a\u8fc7 auto \u6765\u6355\u83b7 Lambda \u5bf9\u8c61\u4e3a\u53d8\u91cf\u3002 \u4e3a\u6b64\uff0c\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::function \u5bb9\u5668\uff0c\u4ed6\u80fd\u5bb9\u7eb3\u4efb\u4f55\u51fd\u6570\u5bf9\u8c61\uff01\u65e0\u8bba\u662f\u533f\u540d\u7684 Lambda \u51fd\u6570\u5bf9\u8c61\uff0c\u8fd8\u662f\u666e\u666e\u901a\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u90fd\u80fd\u7eb3\u5165 std::function \u7684\u4f53\u5185\u3002 \u552f\u4e00\u7684\u4ee3\u4ef7\u662f\uff0c\u4f60\u9700\u8981\u6307\u5b9a\u51fa\u6240\u6709\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u53c2\u6570\u4e3a\u4e24\u4e2a int \uff0c\u8fd4\u56de int \u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7528 std::function \u5bb9\u5668\u5b58\u50a8\u3002 auto add_lambda = [](int a, int b) { // Lambda \u51fd\u6570\u5bf9\u8c61 return a + b; }; struct AddClass { int operator()(int a, int b) { // \u81ea\u5b9a\u4e49\u7c7b\u6a21\u62df\u51fd\u6570\u5bf9\u8c61 return a + b; } }; AddClass add_object; int add_regular_func(int a, int b) { // \u666e\u901a\u51fd\u6570 return a + b; } std::function add; // \u6240\u6709\u5e7f\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u7edf\u7edf\u63a5\u7eb3 add = add_lambda; // OK add = add_object; // OK add = add_regular_func; // OK int generic_sum(std::vector const &v, std::function op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op(ret, v[i]); // \u5199\u8d77\u6765\u548c\u6a21\u677f\u4f20\u53c2\u65f6\u4e00\u6837\u65e0\u611f } // \u65e0\u9700\u6307\u9488\uff0c\u65e0\u9700 delete\uff0cfunction \u80fd\u81ea\u52a8\u7ba1\u7406\u51fd\u6570\u5bf9\u8c61\u751f\u547d\u5468\u671f return ret; } \u5982\u679c\u8fd8\u60f3\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b std::function \u3002\u8fd9\u91cc std::any \u662f\u4e2a\u8d85\u7ea7\u4e07\u80fd\u5bb9\u5668\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u4f55\u5bf9\u8c61\uff0c\u4ed6\u548c std::function \u4e00\u6837\u90fd\u91c7\u7528\u4e86\u201c\u7c7b\u578b\u64e6\u9664 (type-erasure)\u201d\u6280\u672f\uff0c\u7f3a\u70b9\u662f\u5fc5\u987b\u914d\u5408 std::any_cast \u624d\u80fd\u53d6\u51fa\u4f7f\u7528\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u8fdb\u9636\u4e13\u9898\u4e2d\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u4ed6\u4eec\u7684\u539f\u7406\uff0c\u5e76\u5e26\u4f60\u81ea\u5df1\u505a\u4e00\u4e2a\u64e6\u52a0\u6cd5\u7684\u7c7b\u578b\u64e6\u9664\u5bb9\u5668\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\uff0c\u80fd\u5728\u9759\u6001\u4e0e\u52a8\u6001\u4e4b\u95f4\u8f7b\u677e\u5207\u6362\uff0c \u9ad8\u6027\u80fd \u4e0e \u7075\u6d3b\u6027 \u4efb\u541b\u9009\u62e9\u3002 \u5728\u9700\u8981\u6027\u80fd\u7684 \u74f6\u9888\u4ee3\u7801 \u4e2d\u7528\u6a21\u677f\u4f20\u53c2\uff0c\u7f16\u8bd1\u671f\u9759\u6001\u5206\u53d1\uff0c\u591a\u6b21\u91cf\u8eab\u5b9a\u505a\uff0c\u63d0\u9ad8\u8fd0\u884c\u65f6\u6027\u80fd\u3002 \u74f6\u9888\u4ee3\u7801: \u5f80\u5f80\u4e00\u4e2a\u7a0b\u5e8f 80% \u7684\u65f6\u95f4\u82b1\u5728 20% \u7684\u4ee3\u7801\u4e0a\u3002\u8fd9 20% \u662f\u5728\u7a0b\u5e8f\u4e2d\u9891\u7e41\u6267\u884c\u7684\u3001\u8ba1\u7b97\u91cf\u5927\u7684\u3001\u6216\u8005\u8c03\u7528\u7279\u522b\u8017\u65f6\u7684\u51fd\u6570\u3002\u9488\u5bf9\u8fd9\u90e8\u5206\u74f6\u9888\u4ee3\u7801\u4f18\u5316\u5373\u53ef\uff0c\u800c\u5269\u4f59\u7684 80% \u6253\u9171\u6cb9\u4ee3\u7801\uff0c\u5927\u53ef\u4ee5\u600e\u4e48\u65b9\u4fbf\u600e\u4e48\u5199\u3002 \u5728\u6027\u80fd\u65e0\u5173\u7d27\u8981\u7684\u9876\u5c42\u4e1a\u52a1\u903b\u8f91\u4e2d\u7528 function \u5bb9\u5668\u4f20\u53c2\uff0c\u8fd0\u884c\u65f6\u52a8\u6001\u5206\u53d1\uff0c\u8282\u7701\u7f16\u8bd1\u4f53\u79ef\uff0c\u65b9\u4fbf\u6301\u4e45\u5b58\u50a8\uff0c\u7075\u6d3b\u6613\u7528\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 generic_sum \u51fd\u6570\uff0c\u5982\u679c\u6211\u4eec\u7a81\u7136\u60f3\u8981\u9ad8\u6027\u80fd\u4e86\uff0c\u53ea\u9700\u628a std::function op \u8f7b\u8f7b\u6539\u4e3a auto op \u5c31\u8f7b\u677e\u5207\u6362\u5230\u9759\u6001\u5206\u53d1\u6a21\u5f0f\u4e86\u3002 \u800c\u865a\u51fd\u6570\u4e00\u65e6\u7528\u4e86\uff0c\u57fa\u672c\u5c31\u53ea\u80fd\u52a8\u6001\u5206\u53d1\u4e86\uff0c\u5373\u4f7f\u80fd\u88ab IPO \u4f18\u5316\u6389\uff0c\u865a\u8868\u6307\u9488\u4e5f\u6c38\u8fdc\u5360\u636e\u7740\u4e00\u4e2a 8 \u5b57\u8282\u7684\u7a7a\u95f4\uff0c\u4e14\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u5f0f\u4f20\u6765\u4f20\u53bb\u3002 \u4e00\u79cd\u9759\u6001\u5206\u53d1\u7248\u7684\u865a\u51fd\u6570\u66ff\u4ee3\u54c1\u662f CRTP\uff0c\u4ed6\u57fa\u4e8e\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u4f46\u4e0e\u865a\u51fd\u6570\u4e4b\u95f4\u5207\u6362\u56f0\u96be\uff0c\u4e0d\u50cf\u51fd\u6570\u5bf9\u8c61\u90a3\u4e48\u65e0\u611f\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u3002 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u4e3b\u7ebf\u7a0b\u4e0d\u65ad\u5730\u5411\u5de5\u4f5c\u8005\u7ebf\u7a0b\u53d1\u9001\u51fd\u6570\u5bf9\u8c61\uff0c\u4ee4\u5176\u4ee3\u4e3a\u6267\u884c\uff1a mt_queue> task_queue; void main_thread() { task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a11\"); }); task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a12\"); }); } void worker_thread() { while (true) { auto task = task_queue.pop(); task(); } } mt_queue \u662f\u5c0f\u5f6d\u8001\u5e08\u5c01\u88c5\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u7684\u6d88\u606f\u961f\u5217\uff0c\u5b9e\u73b0\u539f\u7406\u4f1a\u5728\u7a0d\u540e\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4e2d\u8be6\u7ec6\u8bb2\u89e3\u3002 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u662f\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff0c\u4ed6\u5141\u8bb8\u51fd\u6570\u5bf9\u8c61\u6355\u83b7\u5916\u90e8\u53d8\u91cf\uff0c\u5e76\u5728\u51fd\u6570\u5bf9\u8c61\u5185\u90e8\u4f7f\u7528\u8fd9\u4e9b\u53d8\u91cf\u3002 int x = 10; auto add_x = [x](int a) { return a + x; }; fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 \u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u52a0\u4e0a mutable \u4fee\u9970\uff0c\u89c1\u540e\u6587\u3002 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u95ed\u5305\u8bed\u6cd5\uff1a int x = 10; auto add_x = [x](int a) { return a + x; }; \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u4e00\u4e2a\u5e26\u6709 operator() \u6210\u5458\u51fd\u6570\u7684\u7ed3\u6784\u4f53\uff1a struct Lambda { int x; Lambda(int val) : x(val) {} int operator() (int a) const { return a + x; } }; int main() { int x = 10; Lambda add_x(x); fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 return 0; } \u76f8\u5f53\u4e8e\u6211\u4eec\u5199\u7684 lambda \u51fd\u6570\u4f53\uff0c\u5b9e\u9645\u4e0a\u88ab\u7f16\u8bd1\u5668\u79fb\u5230\u4e86 Lambda \u7c7b\u7684 operator() \u6210\u5458\u51fd\u6570\u4f53\u5185\u3002 \u800c\u4e14\u8fd9\u7ed3\u6784\u4f53\u662f\u533f\u540d\u7684\uff0c\u6ca1\u6709\u786e\u5b9a\u7684\u540d\u5b57\uff0c\u6b64\u5904\u7c7b\u540d Lambda \u53ea\u662f\u793a\u610f\uff0c\u56e0\u800c\u5e73\u65f6\u53ea\u80fd\u901a\u8fc7 auto \u4fdd\u5b58\u5373\u65f6\u521b\u5efa\u7684 lambda \u5bf9\u8c61\u3002 \u800c\u6240\u8c13\u7684\u95ed\u5305\u6355\u83b7\u53d8\u91cf\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8fd9\u4e2a\u7ed3\u6784\u4f53\u7684\u6210\u5458\uff01 \u6309\u503c\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u91cc\u62f7\u8d1d\u4e86\u4e00\u4efd\u540c\u540d\u7684\u6210\u5458\uff1b\u5982\u679c\u662f\u5f15\u7528\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u91cc\u7684\u6210\u5458\u662f\u4e2a\u5f15\u7528\u3002 \u53ef\u4ee5\u5728 https://cppinsights.io \u8fd9\u4e2a\u7f51\u7ad9\uff0c\u81ea\u52a8\u62c6\u89e3\u5305\u62ec Lambda \u5728\u5185\u7684\u6240\u6709\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6\u4e3a\u539f\u59cb\u7684\u7ed3\u6784\u4f53\u548c\u51fd\u6570\u3002\u66f4\u591a\u597d\u7528\u7684\u5de5\u5177\u7f51\u7ad9\u53ef\u4ee5\u770b\u6211\u4eec \u5de5\u5177\u548c\u9879\u76ee\u63a8\u8350 \u4e13\u9898\u7ae0\u8282\u3002 \u5bf9\u4e8e\u5f15\u7528\uff0c\u5219\u662f\u7b49\u4ef7\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u4e2d\u542b\u6709\u4e00\u4efd\u5f15\u7528\u4f5c\u4e3a\u6210\u5458\uff1a int x = 10; auto inc_x = [&x](int a) { return x++; }; struct Lambda { int &x; Lambda(int &val) : x(val) {} int operator() () const { return x++; } }; int main() { int x = 10; Lambda inc_x(x); fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 10 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 11 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 12 fmt::println(\"{}\", x); // \u8f93\u51fa 13 return 0; } operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u533f\u540d lambda \u5bf9\u8c61\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u7684\u7c7b\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); \u5f88\u591a\u540c\u5b66\u90fd\u5206\u4e0d\u6e05 operator operator() opeartor()() \uff0c\u8fd9\u4e2a\u62ec\u53f7\u786e\u5b9e\u5f88\u6709\u8ff7\u60d1\u6027\uff0c\u4eca\u5929\u6211\u6765\u89e3\u91ca\u4e00\u4e0b\u3002 \u4f60\u73b0\u5728\uff0c\u628a\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6539\u6210\u8fd9\u6837\uff1a struct Lambda { int call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.call(2); \u662f\u4e0d\u662f\u5f88\u5bb9\u6613\u770b\u61c2\uff1f\u8fd9\u5c31\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6210\u5458\u51fd\u6570 call \uff0c\u7136\u540e\u8c03\u7528\u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u73b0\u5728\uff0c\u8fdb\u4e00\u6b65\u6539\u6210\uff1a struct Lambda { int operator_call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator_call(2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f\u8fd9\u5c31\u662f\u628a\u51fd\u6570\u540d\u6539\u6210\u4e86 operator_call \uff0c\u4f9d\u7136\u662f\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u91cd\u70b9\u6765\u4e86\uff0c\u6211\u4eec\u628a\u51fd\u6570\u540d\uff0c\u6ce8\u610f\u662f\u51fd\u6570\u540d\u53eb operator() \uff0c\u8fd9\u4e2a\u7a7a\u7684\u5706\u62ec\u53f7\u662f\u51fd\u6570\u540d\u7684\u4e00\u90e8\u5206\uff01 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f operator \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u5173\u952e\u5b57\uff0c\u6548\u679c\u662f\u548c\u540e\u9762\u7684\u4e00\u4e2a\u8fd0\u7b97\u7b26\u7ed3\u5408\uff0c\u5f62\u6210\u4e00\u4e2a\u7279\u6b8a\u7684\u201c\u6807\u8bc6\u7b26\u201d\uff0c\u8fd9\u4e2a\u201c\u6807\u8bc6\u7b26\u201d\u548c\u666e\u901a\u51fd\u6570\u540d\u4e00\u6837\uff0c\u90fd\u662f\u201c\u5355\u4e2a\u5355\u8bcd\u201d\uff0c\u4e0d\u53ef\u5206\u5272\u3002 \u4f8b\u5982 operator+ \u5c31\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c operator[] \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6211\u4eec\u8fd9\u91cc\u7684 operator() \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6ca1\u6709\u4ec0\u4e48\u7a00\u5947\u7684\uff0c\u53ea\u4e0d\u8fc7\u540e\u9762\u8fde\u7684\u8fd0\u7b97\u7b26\u521a\u597d\u662f\u62ec\u53f7\u800c\u5df2\u3002 \u8fd9\u91cc\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 lambda . operator() \u6765\u8bbf\u95ee\u8fd9\u4e2a\u6210\u5458\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\uff0c operator() \u5c31\u548c\u4e00\u4e2a\u666e\u901a\u6210\u5458\u540d\u5b57\u4e00\u6837\uff0c\u6ca1\u6709\u533a\u522b\uff0c\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7 . \u8bbf\u95ee\u3002 \u4f8b\u5982\uff0c\u5bf9\u4e8e\u8fd0\u7b97\u7b26 + \u6765\u8bf4\uff0c\u5f53\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230 lambda + 2 \u8fd9\u6837\u7684\u8868\u8fbe\u5f0f\u65f6\uff0c\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u6210 lambda.operator+ (2) \uff0c\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 struct Lambda { int operator+ (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda + 2; // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator+ (2); \u540c\u6837\u7684\uff0c\u5bf9\u4e8e () \u8fd0\u7b97\u7b26\uff0c\u4e5f\u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210 operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\uff0c\u7531\u4e8e\u5bf9 operator() \u51fd\u6570\u672c\u8eab\u7684\u8c03\u7528\u4e5f\u9700\u8981\u4e00\u4e2a\u62ec\u53f7\uff08\u53c2\u6570\u5217\u8868\uff09\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u5c31\u6709\u4e24\u4e2a\u62ec\u53f7\u4e86\u3002\u5b9e\u9645\u4e0a\u6839\u672c\u4e0d\u642d\u754c\uff0c\u4e00\u4e2a\u662f\u51fd\u6570\u540d\u6807\u8bc6\u7b26\u7684\u4e00\u90e8\u5206\uff0c\u4e00\u4e2a\u662f\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u3002 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (2); \u8fd9\u65f6\u5019\uff0c\u53bb\u6389 (2) \u91cc\u7684\u53c2\u6570 2 \uff0c\u5c31\u53d8\u6210\u4e86\u8ba9\u4f60\u5f88\u56f0\u60d1\u7684\u53cc\u62ec\u53f7\u3002\u800c\u5f88\u591a\u4eba\u559c\u6b22\u7d27\u6328\u8005\u8fde\u5199\uff0c\u770b\u8d77\u6765\u5c31\u5f88\u8ff7\u60d1\u3002 \u5b9e\u9645\u4e0a\uff0c\u7b2c\u4e00\u4e2a () \u662f\u51fd\u6570\u540d\u5b57\u7684\u4e00\u90e8\u5206\uff0c\u548c operator \u662f\u8fde\u5728\u4e00\u8d77\u7684\uff0c\u4e0d\u53ef\u5206\u5272\uff0c\u4e2d\u95f4\u4e5f\u4e0d\u80fd\u6709\u5176\u4ed6\u53c2\u6570\u3002\u7b2c\u4e8c\u4e2a () \u662f\u51fd\u6570\u53c2\u6570\u5217\u8868\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u521a\u597d\u662f\u6ca1\u6709\u53c2\u6570\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u4e5f\u662f\u4e2a\u7a7a\u62ec\u53f7\uff0c\u5f88\u591a\u521d\u5b66\u8005\u770b\u5230\u5c31\u8ff7\u7cca\u4e86\uff0c\u8fd8\u770b\u4e0d\u61c2\u5efa\u8bae\u4ece\u4e0a\u9762\u6709\u4e00\u4e2a\u53c2\u6570\u7684 operator() (int a) \u770b\u3002 struct Lambda { int operator() () const { return 1; } }; Lambda lambda; int ret = lambda(); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (); \u6240\u4ee5\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u8bf4\u5b9a\u4e49\u4e86 operator() \u6210\u5458\u51fd\u6570\u7684\u7c7b\uff0c\u662f\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u6216\u8005\u8bf4\u201c\u4eff\u51fd\u6570\u201d\uff0c\u56e0\u4e3a\u5f53\u4f60\u4f7f\u7528\u51fd\u6570\u7684\u8bed\u6cd5 lambda(2) \u8c03\u7528\u4ed6\u4eec\u65f6\uff0c\u4f1a\u89e6\u53d1\u4ed6\u4eec\u7684\u6210\u5458\u51fd\u6570 operator()(2) \u4ece\u800c\u7528\u6cd5\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u5176\u5b9e\u9645\u53c8\u662f\u5bf9\u8c61\uff0c\u4e5f\u5c31\u5f97\u540d\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u548c\u201c\u4eff\u51fd\u6570\u201d\u4e86\u3002 \u6211\u5efa\u8bae\u4f60\u81ea\u5df1\u53bb https://cppinsights.io \u8fd9\u4e2a\u89e3\u6784\u8bed\u6cd5\u7cd6\u7684\u5de5\u5177\u7f51\u7ad9\u52a8\u52a8\u624b\u8bd5\u8bd5\u770b\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u800c\u6355\u83b7\u4e86\u53d8\u91cf\u7684\uff1a int x = 4; auto lambda = [&x] (int a) { return a + x; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int &x; Lambda(int &x_) : x(x_) {} int operator() (int a) const { return a + x; } }; int x = 4; Lambda lambda(x); int ret = lambda.operator() (2); \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 \u6b63\u56e0\u5982\u6b64\uff0c\u95ed\u5305\u6309\u503c\u6355\u83b7\uff08 [=] \uff09\u7684\u53d8\u91cf\uff0c\u5176\u751f\u547d\u5468\u671f\u548c Lambda \u5bf9\u8c61\u76f8\u540c\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u62f7\u8d1d\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u88ab\u91cd\u65b0\u62f7\u8d1d\u4e00\u4efd\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u79fb\u52a8\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u968f\u4e4b\u4e00\u8d77\u79fb\u52a8\u3002 struct C { C() { fmt::println(\"C \u9ed8\u8ba4\u6784\u9020\"); } C(C const &) { fmt::println(\"C \u62f7\u8d1d\u6784\u9020\"); } C(C &&) { fmt::println(\"C \u79fb\u52a8\u6784\u9020\"); } C &operator=(C const &) { fmt::println(\"C \u62f7\u8d1d\u8d4b\u503c\"); } C &operator=(C &&) { fmt::println(\"C \u79fb\u52a8\u8d4b\u503c\"); } ~C() { fmt::println(\"C \u6790\u6784\"); } }; C c; fmt::println(\"\u6784\u9020 lambda\"); auto lambda = [c] {}; fmt::println(\"\u62f7\u8d1d lambda \u5230 lambda2\"); auto lambda2 = lambda; fmt::println(\"\u79fb\u52a8 lambda \u5230 lambda3\"); auto lambda3 = lambda; \u8f93\u51fa\uff1a C \u9ed8\u8ba4\u6784\u9020 \u6784\u9020 lambda C \u62f7\u8d1d\u6784\u9020 \u62f7\u8d1d lambda \u5230 lambda2 C \u62f7\u8d1d\u6784\u9020 \u79fb\u52a8 lambda \u5230 lambda3 C \u79fb\u52a8\u6784\u9020 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 \u5982\u679c\u6309\u503c\u6355\u83b7\u4e86\u4e0d\u80fd\u62f7\u8d1d\u7684\u5bf9\u8c61\uff08\u6bd4\u5982 std::unique_ptr \uff09\uff0c\u90a3\u4e48 Lambda \u5bf9\u8c61\u4e5f\u4f1a\u65e0\u6cd5\u62f7\u8d1d\uff0c\u53ea\u80fd\u79fb\u52a8\u3002 std::unique_ptr p = std::make_unique(10); auto lambda = [p] {}; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u56e0\u4e3a\u8fd9\u91cc\u7b49\u4ef7\u4e8e [p' = p]\uff0c\u662f\u5bf9 p' \u7684\u62f7\u8d1d\u6784\u9020 auto lambda = [p = std::move(p)] {}; // \u7f16\u8bd1\u901a\u8fc7\u2705unique_ptr \u652f\u6301\u79fb\u52a8\u6784\u9020 auto lambda2 = lambda; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3std::unique_ptr \u53ea\u652f\u6301\u79fb\u52a8\uff0c\u4e0d\u652f\u6301\u62f7\u8d1d auto lambda2 = std::move(lambda); // \u7f16\u8bd1\u901a\u8fc7\u2705 \u7528\u6211\u4eec\u4e4b\u524d\u7684\u65b9\u6cd5\u89e3\u6784\u8bed\u6cd5\u7cd6\u540e\uff1a struct Lambda { std::unique_ptr p; Lambda(std::unique_ptr ptr) : p(std::move(ptr)) {} // Lambda(Lambda const &) = delete; // \u56e0\u4e3a\u6709 unique_ptr \u6210\u5458\uff0c\u5bfc\u81f4 Lambda \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u88ab\u9690\u5f0f\u5220\u9664 void operator()() const { } }; int main() { std::unique_ptr p = std::make_unique(10); Lambda lambda(p); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3 Lambda lambda(std::move(p)); // \u7f16\u8bd1\u901a\u8fc7\u2705 return 0; } mutable \u7684\u51fd\u6570\u5bf9\u8c61 int x = 10; auto lambda = [x] () { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3lambda \u6355\u83b7\u7684 x \u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684 }; int ret = lambda(); \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int x; int operator() () const { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3const \u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u6210\u5458\u53d8\u91cf } }; int x = 10; Lambda lambda{x}; int ret = lambda.operator() (); \u6ce8\u610f\u5230\uff0c\u8fd9\u91cc\u7684 operator() \u6210\u5458\u51fd\u6570\u6709\u4e00\u4e2a const \u4fee\u9970\uff0c\u610f\u5473\u7740\u8be5\u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5176\u4f53\u5185\u7684\u53d8\u91cf\u3002 \u6240\u6709 lambda \u51fd\u6570\u5bf9\u8c61\u751f\u6210\u65f6\u9ed8\u8ba4\uff0c\u5c31\u4f1a\u7ed9\u4ed6\u7684 operator() \u6210\u5458\u51fd\u6570\u52a0\u4e0a const \u4fee\u9970\u3002 \u4e5f\u5c31\u662f\u8bf4\u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u7ed9 lambda \u52a0\u4e0a mutable \u4fee\u9970\uff0c\u5c31\u52a0\u5728 () \u540e\u9762\u3002 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"lambda() = {}\", lambda()); // 10 fmt::println(\"lambda() = {}\", lambda()); // 11 fmt::println(\"lambda() = {}\", lambda()); // 12 \u7f16\u8bd1\u5668\u7ffb\u8bd1\u4ea7\u751f\u7684 Lambda \u7c7b\u7684\u6210\u5458\u51fd\u6570\uff0c\u5c31\u4e0d\u4f1a\u5e26 const \u4fee\u9970\u4e86\uff0c\u4ece\u800c\u5141\u8bb8\u6211\u4eec\u7684\u51fd\u6570\u4f53\u4fee\u6539\u6355\u83b7\u7684\u975e\u5f15\u7528\u53d8\u91cf\u3002 struct Lambda { int x; int operator() () { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 } }; int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 \u6ce8\u610f\uff1a\u7531\u4e8e\u4f7f\u7528\u4e86\u503c\u6355\u83b7\uff0clambda \u4fee\u6539\u7684\u662f\u5728\u4ed6\u521b\u5efa\u65f6\u5bf9 x \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u5916\u9762\u7684 x \u4e0d\u4f1a\u6539\u53d8\uff01 int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // 13 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"ret = {}\", lambda()); // 10 fmt::println(\"ret = {}\", lambda()); // 11 fmt::println(\"ret = {}\", lambda()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u7f16\u8bd1\u5668\u4ea7\u751f\u7684\u533f\u540d lambda \u5bf9\u8c61\u4e2d\u6355\u83b7\u4ea7\u751f\u7684 x \u6210\u5458\u53d8\u91cf\u662f\u533f\u540d\u7684\uff0c\u65e0\u6cd5\u8bbf\u95ee \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u4e00\u4e2a\u53d8\u91cf\u7684\u4e09\u79cd\u6355\u83b7\u65b9\u5f0f\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7 [x] \u6309\u5f15\u7528\u6355\u83b7 [&x] \u6309\u503c\u79fb\u52a8\u6355\u83b7 [x = std::move(x)] \u6309\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 [x = ...] \u6279\u91cf\u6355\u83b7\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [=] \u6309\u5f15\u7528\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [&] \u591a\u4e2a\u6355\u83b7 + \u9ed8\u8ba4\u6355\u83b7\u65b9\u5f0f [x, y, &] \u6216 [&x, &y, =] \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u8bed\u6cd5\uff1a [\u53d8\u91cf\u540d] \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u62f7\u8d1d\u4e00\u4efd\u6355\u83b7\u7684\u53d8\u91cf\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u5df2\u7ecf\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4e0d\u4f1a\u5f71\u54cd lambda \u6355\u83b7 x \u7684\u503c\u3002 main \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 985 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) mutable { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u7531\u4e8e lambda \u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u9ed8\u8ba4\u90fd\u662f\u4e0d\u53ef\u4fee\u6539\uff08 const \uff09\uff0c\u9700\u8981 mutable \u624d\u80fd\u4fee\u6539\u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u3002\u800c\u6309\u5f15\u7528\u6355\u83b7\u5c31\u4e0d\u9700\u8981 mutable \uff0c\u56e0\u4e3a\u867d\u7136 lambda \u672c\u8eab\u4e0d\u53ef\u4fee\u6539\uff0c\u4f46\u4ed6\u6307\u5411\u7684\u4e1c\u897f\u53ef\u4ee5\u4fee\u6539\u5440\uff01 \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 985 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u4f9d\u7136\u6709\u6548\u3002 int main() { std::function lambda; { int x = 985; lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = 985 \u6309\u5f15\u7528\u6355\u83b7 \u8bed\u6cd5\uff1a [&\u53d8\u91cf\u540d] \u6309\u5f15\u7528\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u521b\u5efa\u4e00\u4efd\u6307\u5411\u53d8\u91cf\u7684\u5f15\u7528\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf\u5f15\u7528 &x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u662f\u540c\u4e00\u4e2a\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4f1a\u76f4\u63a5\u5f71\u54cd lambda \u6355\u83b7\u4e2d x \u7684\u503c\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 \u6f14\u793a\uff1amain \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e5f\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u5c06\u6210\u4e3a\u5371\u9669\u7684\u201c\u7a7a\u60ac\u5f15\u7528\uff08dangling-reference\uff09\u201d\uff01\u6b64\u65f6\u518d\u5c1d\u8bd5\u8bbf\u95ee x\uff0c\u5c06\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int main() { std::function lambda; { int x = 985; lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = -858993460 -858993460 \u4e3a\u5185\u5b58\u4e2d\u7684\u5783\u573e\u503c\uff0c\u4f60\u8bfb\u5230\u7684\u7ed3\u679c\u53ef\u80fd\u968f\u5e73\u53f0\uff0c\u7f16\u8bd1\u5668\u7248\u672c\uff0c\u4f18\u5316\u9009\u9879\u7684\u4e0d\u540c\u800c\u4e0d\u540c\uff0c\u6b63\u5e38\u8bfb\u5230 985 \u4e5f\u662f\u6709\u53ef\u80fd\u7684\uff0c\u5f00\u53d1\u8005\u4e0d\u80fd\u4f9d\u8d56\u6b64\u7c7b\u968f\u673a\u6027\u7684\u7ed3\u679c\u3002 \u6b63\u5e38\u8bfb\u5230 985\uff08\u5927\u5b66\uff09\u4e5f\u662f\u6709\u53ef\u80fd\u7684\u3002 -858993460 \u662f\u5728 Windows \u5e73\u53f0\u7684\u8c03\u8bd5\u6a21\u5f0f\u4e0b\u53ef\u80fd\u7684\u8f93\u51fa\uff0c\u56e0\u4e3a Windows \u503e\u5411\u4e8e\u628a\u6808\u5185\u5b58\u586b\u6ee1 0xcccccccc \u4ee5\u65b9\u4fbf\u8c03\u8bd5\uff0c\u5176\u4e2d 0xcc \u521a\u597d\u4e5f\u662f int3 \u8fd9\u6761 x86 \u8c03\u8bd5\u6307\u4ee4\u7684\u4e8c\u8fdb\u5236\u7801\uff0c\u53ef\u80fd\u662f\u4e3a\u4e86\u907f\u514d\u6307\u4ee4\u6307\u9488\u6267\u884c\u5230\u5806\u6808\u91cc\u53bb\u3002 \u6309\u503c\u79fb\u52a8\u6355\u83b7 TODO \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 TODO lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b lambda \u51fd\u6570\u53ef\u4ee5\u901a\u8fc7\u5728\u53c2\u6570\u5217\u8868\u540e\u4f7f\u7528 -> \u6307\u5b9a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) -> int { return a; }; int i = lambda(); \u5982\u679c\u8fd4\u56de\u7c7b\u578b\u7701\u7565\u4e0d\u5199\uff0c\u9ed8\u8ba4\u662f -> auto \uff0c\u4e5f\u5c31\u662f\u6839\u636e\u4f60\u7684 return \u8bed\u53e5\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 auto lambda = [] (int a) { return a; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> auto { return a; }; \u548c\u666e\u901a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a auto \u4e00\u6837\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u8868\u8fbe\u5f0f\u4e3a\u4f60\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) { return a; // \u6b64\u8868\u8fbe\u5f0f\u7c7b\u578b\u4e3a int }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> int { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f int return a; }; auto lambda2 = [] (int a) { return a * 2.0; // \u6b64\u8fd4\u56de\u8868\u8fbe\u5f0f\u7684\u7c7b\u578b\u4e3a double }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda2 = [] (int a) -> double { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f double return a * 2.0; }; \u5982\u679c\u6ca1\u6709\u8fd4\u56de\u8bed\u53e5\uff0c\u90a3\u4e48\u4f1a\u63a8\u5bfc\u4e3a\u8fd4\u56de void \u7c7b\u578b\u7684 lambda\u3002 auto lambda = [] (int a) { fmt::println(\"a = {}\", a); }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { fmt::println(\"a = {}\", a); }; auto lambda = [] (int a) { return; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { return; }; \u548c\u51fd\u6570\u7684 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u4e00\u6837\uff0c\u5f53\u8fd4\u56de\u7c7b\u578b\u4e3a auto \u7684 lambda \u5177\u6709\u591a\u4e2a\u8fd4\u56de\u8bed\u53e5\u65f6\uff0c\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709\u5206\u652f\u4e0a\u7684\u8fd4\u56de\u503c\u5177\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u62a5\u9519\uff0c\u9700\u8981\u624b\u52a8\u5199\u51fa\u8fd4\u56de\u7c7b\u578b\uff0c\u6216\u8005\u628a\u6240\u6709\u5206\u652f\u7684\u8fd4\u56de\u503c\u6539\u6210\u76f8\u540c\u7684\u3002 auto lambda_error = [] (double x) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u4e24\u4e2a\u5206\u652f\u7684\u8fd4\u56de\u7c7b\u578b\u4e0d\u540c\uff0c\u65e0\u6cd5\u81ea\u52a8\u63a8\u5bfc if (x > 0) { return x; // double } else { return 0; // int } }; auto lambda_ok = [] (double x) { // \u7f16\u8bd1\u901a\u8fc7 if (x > 0) { return x; // double } else { return (double)0; // double } }; auto lambda_also_ok = [] (double x) -> double { // \u624b\u52a8\u660e\u786e\u8fd4\u56de\u7c7b\u578b\uff0c\u7f16\u8bd1\u4e5f\u80fd\u901a\u8fc7 if (x > 0) { return x; // double } else { return 0; // int\uff0c\u4f46\u4f1a\u9690\u5f0f\u8f6c\u6362\u4e3a double } }; auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b TODO auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u6211\u4eec\u603b\u662f\u7528 auto \u6765\u4fdd\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u4f5c\u4e3a\u5c40\u90e8\u53d8\u91cf\uff0c\u8fd9\u4f1a\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\u3002 \u4e3a\u4ec0\u4e48\u4e0d\u80fd\u663e\u5f0f\u5199\u51fa\u7c7b\u578b\u540d\u5b57\uff1f\u56e0\u4e3a lambda \u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f60\u65e0\u6cd5\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u53ea\u80fd\u901a\u8fc7 auto \u63a8\u5bfc\u3002 int b = 2; auto lambda = [b] (int a) { return a + b; }; \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 C++11 \u540c\u65f6\u5f15\u5165 auto \u548c lambda \u8bed\u6cd5\u7684\u539f\u56e0\u3002 \u5982\u679c\u4f60\u5b9e\u5728\u9700\u8981\u663e\u5f0f\u7684\u7c7b\u540d\uff0c\u90a3\u5c31\u9700\u8981\u4f7f\u7528 std::function \u5bb9\u5668\u3002\u867d\u7136 lambda \u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f46\u662f\u8be5\u7c7b\u578b\u7b26\u5408\u201c\u53ef\u8c03\u7528\u201d\u7684\u7ea6\u675f\uff0c\u53ef\u4ee5\u88ab std::function \u5bb9\u5668\u63a5\u7eb3\u3002 \u5373 lambda \u7c7b\u578b\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u76f8\u5e94\u53c2\u6570\u5217\u8868\u7684 std::function \u5bb9\u5668\u3002\u56e0\u4e3a std::function \u5bb9\u5668\u53ef\u4ee5\u63a5\u7eb3\u4efb\u4f55\u201c\u53ef\u63a5\u53d7 (Args...) \u53c2\u6570\u8c03\u7528\u5e76\u8fd4\u56de Ret \u7c7b\u578b\u201d\u7684\u4efb\u610f\u51fd\u6570\u5bf9\u8c61\u3002 int b = 2; std::function lambda = [b] (int a) { return a + b; }; \u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u628a lambda \u5bf9\u8c61\u63a8\u5165 vector \u7b49\u5bb9\u5668\u4e2d\u65f6\uff0c\u5c31\u9700\u8981\u663e\u5f0f\u5199\u51fa\u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\uff0c\u6b64\u65f6\u4e07\u80fd\u51fd\u6570\u5bf9\u8c61\u5bb9\u5668 std::function \u5c31\u80fd\u6d3e\u4e0a\u7528\u573a\u4e86\uff1a // vector lambda_list; // \u9519\u8bef\uff1a\u4e0d\u652f\u6301\u7684\u8bed\u6cd5 vector> lambda_list; // OK int b = 2; lambda_list.push_back([b] (int a) { return a + b; }; lambda_list.push_back([b] (int a) { return a * b; }; for (auto lambda: lambda_list) { int ret = lambda(2); fmt::println(\"{}\", ret); } \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 TODO \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom TODO \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u65b0\u624b\u7528 lambda \u5e38\u89c1\u7684\u9519\u8bef\u5c31\u662f\u641e\u4e0d\u6e05\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\uff0c\u603b\u662f\u60f3\u5f53\u7136\u5730\u65e0\u8111\u7528 [&] \uff0c\u975e\u5e38\u5371\u9669\u3002 \u5982\u679c\u4f60\u6709\u201c\u81ea\u77e5\u4e4b\u660e\u201d\uff0c\u81ea\u77e5\u4e0d\u719f\u6089\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u90a3\u5c31\u5168\u90e8 [=] \u3002 \u7b49\u6211\u4eec\u7a0d\u540e\u7684 \u751f\u547d\u5468\u671f\u4e13\u9898\u8bfe\u7a0b \u4e2d\u4ecb\u7ecd\u3002 \u5b9e\u9645\u4e0a\uff0c [=] \u5e94\u8be5\u662f\u4f60\u9ed8\u8ba4\u7684\u6355\u83b7\u65b9\u5f0f\u3002 \u53ea\u6709\u5f53\u7c7b\u578b\u65e0\u6cd5\u62f7\u8d1d\u4f1a\u6df1\u62f7\u8d1d\u6210\u672c\u8fc7\u9ad8\u65f6\uff0c\u624d\u4f1a\u9009\u62e9\u6027\u5730\u628a\u4e00\u4e9b\u53ef\u4ee5\u6539\u6210\u5f15\u7528\u6355\u83b7\u7684\u90e8\u5206 lambda\uff0c\u4f7f\u7528 [&] \u6765\u6355\u83b7\u90e8\u5206\u9700\u8981\u907f\u514d\u62f7\u8d1d\u7684\u53d8\u91cf\uff0c\u6216\u8005\u4f7f\u7528 shared_ptr \u914d\u5408 [=] \u5c06\u6df1\u62f7\u8d1d\u5316\u4e3a\u6d45\u62f7\u8d1d\u3002 \u4e00\u4e9b\u4e60\u60ef\u4e86 Python\u3001JS \u7b49\u5168\u5458 shared_ptr \u7684\u5783\u573e\u56de\u6536\u8bed\u8a00\u5de8\u5a74\uff0c\u4e00\u4e0a\u6765\u5c31\u5168\u90e8\u65e0\u8111 [&] \uff0c\u7528\u5b9e\u9645\u884c\u52a8\u8bc1\u660e\u4e86\u667a\u5546\u548c\u52c7\u6c14\u6210\u53cd\u6bd4\u5b9a\u5f8b\u3002 \u597d\u6d88\u606f\u662f\uff0c\u5bf9\u4e8e\u4ee3\u7801\u590d\u7528\u548c\u5c31\u5730\u8c03\u7528\u7684\u60c5\u51b5\uff0clambda \u5bf9\u8c61\u7684\u751f\u547d\u90fd\u4e0d\u4f1a\u51fa\u51fd\u6570\u4f53\uff0c\u53ef\u4ee5\u5b89\u5168\u5730\u6539\u6210\u6309\u5f15\u7528\u6355\u83b7 [&] \u3002 \u4f46\u662f\u5bf9\u4e8e\u4e0b\u9762\u4e24\u79cd\u60c5\u51b5\uff08\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u548c\u4f5c\u4e3a\u8fd4\u56de\u503c\uff09\uff0c\u5c31\u4e0d\u4e00\u5b9a\u6709\u8fd9\u4e48\u5e78\u8fd0\u4e86\u3002 \u603b\u4e4b\uff0c\u65e0\u8bba\u5982\u4f55\u8981\u4fdd\u8bc1 lambda \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5c0f\u4e8e\u7b49\u4e8e \u6309\u5f15\u7528\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u3002\u5982\u679c\u505a\u4e0d\u5230\uff0c\u90a3\u5c31\u5f97\u628a\u8fd9\u4e9b\u53ef\u80fd\u8d85\u51fa\u7684\u53d8\u91cf\u6539\u6210\u6309\u503c\u6355\u83b7 [=] \u3002 \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5982\u679c\u4f60\u60f3\u8ba9\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5c31\u5730\u5b9a\u4e49\uff08\u58f0\u660e\u4e0e\u5b9a\u4e49\u5408\u4f53\uff09\u7684\u51fd\u6570\uff0c\u5efa\u8bae\u586b\u5199 auto \u4e3a\u8fd4\u56de\u503c\u7c7b\u578b\uff0c\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\uff08\u56e0\u4e3a\u4f60\u65e0\u6cd5\u5199\u51fa\u5177\u4f53\u7c7b\u578b\u540d\uff09\u3002 \u7136\u540e\uff0c\u5728 return \u8bed\u53e5\u4e2d\u5c31\u5730\u5199\u51fa lambda \u8868\u8fbe\u5f0f\u5373\u53ef\uff1a auto make_adder(int x) { return [x] (int y) { return x + y; }; } \u5206\u79bb\u58f0\u660e\u4e0e\u5b9a\u4e49\u7684\u51fd\u6570\uff0c\u65e0\u6cd5\u4f7f\u7528 auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff0c\u4e0d\u5f97\u4e0d\u4f7f\u7528\u4e07\u80fd\u7684\u51fd\u6570\u5bb9\u5668 std::function \u6765\u64e6\u5c41\u80a1\uff1a // adder.h std::function make_adder(int x); // adder.cpp std::function make_adder(int x) { return [x] (int y) { return x + y; }; } \u201c\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\uff0c\u8fd9\u79cd\u7528\u6cd5\u5728\u51fd\u6570\u5f0f\u7f16\u7a0b\u975e\u5e38\u5e38\u89c1\u3002 \u5e94\u7528\u6848\u4f8b \u4f8b\u5982\u4e0a\u8ff0\u7684 make_adder \u7b49\u4e8e\u7ed1\u5b9a\u4e86\u4e00\u4e2a\u56fa\u5b9a\u53c2\u6570 x \u7684\u52a0\u6cd5\u51fd\u6570\uff0c\u4e4b\u540e\u6bcf\u6b21\u8c03\u7528\u8fd9\u4e2a\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5c31\u56fa\u5b9a\u589e\u52a0\u4e4b\u524d\u5728 make_adder \u53c2\u6570\u4e2d x \u7684\u589e\u91cf\u4e86\u3002 TODO \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u6b64\u7c7b\u201c\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u5199\u6cd5\uff0c\u5176 lambda \u6355\u83b7\u5fc5\u987b\u662f\u6309\u503c\u6355\u83b7\u7684\uff01 \u5426\u5219\uff0c\u56e0\u4e3a\u8c03\u7528\u8005\u8c03\u7528\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\u65f6\uff0c\u5c40\u90e8\u53d8\u91cf\u548c\u5b9e\u53c2\u6240\u5bf9\u5e94\u7684\u51fd\u6570\u5c40\u90e8\u6808\u7a7a\u95f4\u5df2\u7ecf\u91ca\u653e\uff0c\u76f8\u5f53\u4e8e\u5728 lambda \u4f53\u5185\u5b58\u6709\u7a7a\u60ac\u5f15\u7528\uff0c\u5bfc\u81f4\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u8981\u4e48\u76f4\u63a5\u5d29\u6e83\uff0c\u8981\u4e48\u975e\u5e38\u9690\u853d\u5730\u7559\u4e0b\u5185\u5b58\u975e\u6cd5\u8bbf\u95ee\u7684\u9690\u60a3\uff09\u3002 auto make_adder(int x) { return [x] (int y) { return x + y; }; } int main() { // \u6211\u662f\u8c03\u7528\u8005 auto adder = make_adder(2); adder(3); // 2 + 3 = 5 } \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 TODO\uff1a\u4ee3\u7801 \u5e94\u7528\u6848\u4f8b TODO\uff1a\u7b56\u7565\u6a21\u5f0f TODO\uff1a\u5ef6\u8fdf\u56de\u8c03 \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570\u7684\u751f\u547d\u5468\u671f\u95ee\u9898\uff0c\u9700\u8981\u5206\u5c31\u5730\u8c03\u7528\u548c\u5ef6\u8fdf\u8c03\u7528\u4e24\u79cd\u60c5\u51b5\u8ba8\u8bba\u3002 \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] \u5982\u679c\u4f60\u7684\u667a\u529b\u6682\u4e0d\u8db3\u4ee5\u641e\u61c2\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u6ca1\u5173\u7cfb\uff0c\u59cb\u7ec8\u4f7f\u7528 [=] \u80af\u5b9a\u6ca1\u9519\u3002 \u4e00\u4e2a\u540c\u5b66\u8be2\u95ee\uff1a\u6211\u53e3\u6e34\uff01\u5728\u4e0d\u77e5\u9053\u4ed6\u7684\u8010\u53d7\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u80af\u5b9a\u662f\u76f4\u63a5\u7ed9\u4ed6\u5403\u6c34\uff0c\u800c\u4e0d\u662f\u7ed9\u4ed6\u5403\u9152\u7cbe\u3002\u867d\u7136\u4e00\u4e9b\u5b5d\u5b50\u66f0\u201c\u9002\u91cf\u201d\u201c\u9002\u5ea6\u201d\u201c\u8ba1\u91cf\u201d\u5404\u79cd\u4e00\u8fde\u4e32\u9644\u52a0\u6761\u4ef6\u4e0b\uff0c\u5ba3\u79f0\u201c\u9152\u7cbe\u4e5f\u662f\u5b89\u5168\u7684\u201d\u3002\u4f46\u662f\u201c\u6c34\u6c38\u8fdc\u662f\u5b89\u5168\u7684\u201d\uff0c\u201c\u6c38\u8fdc\u201d\uff0c\u90a3\u6211\u76f4\u63a5\u7ed9\u4ed6\u559d\u6c34\uff0c\u662f\u80af\u5b9a\u4e0d\u4f1a\u9519\u7684\u3002\u7b49\u4f60\u957f\u5927\u6210\u5e74\u4e86\uff0c\u6709\u8fa8\u522b\u80fd\u529b\u4e86\uff0c\u518d\u53bb\u6839\u636e\u81ea\u5df1\u7684\u5c0f\u8ba1\u673a\u7619\u75d2\u7a0b\u5ea6\uff0c\u9009\u62e9\u6027\u5730\u559d\u6709\u673a\u6eb6\u5242\u3002\u6b64\u5904 [=] \u5c31\u662f\u8fd9\u4e2a\u4e07\u80fd\u7684\u6c34\uff0c\u867d\u7136\u4e0d\u4e00\u5b9a\u9ad8\u6548\uff0c\u4f46\u662f\u80af\u5b9a\u6ca1\u9519\u3002\u521d\u5b66\u8005\u603b\u662f\u4ece [=] \u7528\u8d77\uff0c\u7b49\u5b66\u660e\u767d\u4e86\uff0c\u518d\u6765\u5c1d\u8bd5\u7a81\u7834\u201c\u5c0f\u8ba1\u673a\u6027\u80fd\u7126\u8651\u4f18\u5316\u201d\u4e5f\u4e0d\u8fdf\u3002 \u5982\u679c\u4f60\u81ea\u8ba4\u4e3a\u80fd\u5206\u5f97\u6e05\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u521b\u5efa\uff0c\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u8fd4\u56de\u4e00\u4e2a lambda\uff0c\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u63a5\u53d7\u4e00\u4e2a lambda \u505a\u53c2\u6570\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u4f5c\u4e3a\u56de\u8c03\u51fd\u6570\uff0c\u5ef6\u8fdf\u8c03\u7528\uff0c\u90a3\u5c31\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u4ee5\u4e0a\u56db\u79cd\u60c5\u51b5\uff0c\u5206\u522b\u4ee3\u7801\u6f14\u793a\uff1a void func() { int i = 1; auto lambda = [&] () { return i; }; lambda(); } int main() { func(); } auto func() { int i = 1; return [=] () { return i; }; } int main() { auto lambda = func(); lambda(); } auto func(auto lambda) { lambda(); } int main() { int i = 1; func([&] () { return i; }); } vector> g_callbacks; auto func(auto lambda) { g_callbacks.push_back(lambda); } void init() { int i = 1; func([=] () { return i; }); } int main() { init(); for (auto cb: g_callbacks) { cb(); } } lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u51fd\u6570\u6bd4\u8f83\u7b80\u5355\uff0c\u76f4\u63a5\u5f80\u51fd\u6570\u53c2\u6570\u4e2d\u4f20\u5165 lambda \u5bf9\u8c61\u5373\u53ef\u3002 sort \uff1a std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::sort(a.begin(), a.end(), comp); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 shared_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::shared_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u7684\u5f15\u7528\u8ba1\u6570\u5f52\u96f6\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002 \u6a21\u677f\u7c7b \u800c\u6a21\u677f\u7c7b\u5219\u9700\u8981\u5148\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u6307\u5b9a\u7c7b\u578b\uff0c\u7136\u540e\u5728\u6784\u9020\u51fd\u6570\u4e2d\u4f20\u5165\u53c2\u6570\u3002 std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::set sorted(comp); sorted.assign(a.begin(), a.end()); a.assign(sorted.begin(), sorted.end()); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5229\u7528 set \u5bb9\u5668\u6709\u5e8f\u7684\u7279\u70b9\uff0c\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 unique_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::unique_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u6790\u6784\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002 lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b TODO: count_if, erase_if, argsort \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 \u4e8c\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b a < b std::less a > b std::greater a <= b std::less_equal a >= b std::greater_equal a == b std::equal_to a != b std::not_equal_to a <=> b std::compare_three_way (C++20) a && b std::logical_and a \\|\\| b std::logical_or a & b std::bit_and a \\| b std::bit_or a ^ b std::bit_xor a + b std::plus a - b std::minus a * b std::multiplies a / b std::divides a % b std::modulus \u4e00\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b !a std::logical_not ~a std::bit_not -a std::negate a std::identity bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 \u539f\u59cb\u51fd\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { hello(2, 3); hello(2, 4); hello(2, 5); return 0; } \u7ed1\u5b9a\u90e8\u5206\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello2 = std::bind(hello, 2, std::placeholders::_1); hello2(3); // hello(2, 3) hello2(4); // hello(2, 4) hello2(5); // hello(2, 5) return 0; } std::placeholders::_1 \u8868\u793a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\u3002 std::placeholders::_1 \u5728 bind \u8868\u8fbe\u5f0f\u4e2d\u4f4d\u4e8e hello \u7684\u7684\u7b2c\u4e8c\u53c2\u6570\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\uff1a\u628a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\uff0c\u4f20\u9012\u5230 hello \u7684\u7b2c\u4e8c\u53c2\u6570\u4e0a\u53bb\u3002 \u7ed1\u5b9a\u5168\u90e8\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello23 = std::bind(hello, 2, 3); hello23(); // hello(2, 3) return 0; } \u7ed1\u5b9a\u5f15\u7528\u53c2\u6570\uff1a int inc(int &x) { x += 1; } int main() { int x = 0; auto incx = std::bind(inc, std::ref(x)); incx(); fmt::println(\"x = {}\", x); // x = 1 incx(); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u5982\u679c\u4e0d\u4f7f\u7528 std::ref \uff0c\u90a3\u4e48 main \u91cc\u7684\u5c40\u90e8\u53d8\u91cf x \u4e0d\u4f1a\u6539\u53d8\uff01\u56e0\u4e3a std::bind \u6709\u4e00\u4e2a\u607c\u4eba\u7684\u8bbe\u8ba1\uff1a\u9ed8\u8ba4\u6309\u62f7\u8d1d\u6355\u83b7\uff0c\u4f1a\u628a\u53c2\u6570\u62f7\u8d1d\u4e00\u4efd\uff0c\u800c\u4e0d\u662f\u4fdd\u7559\u5f15\u7528\u3002 \u6709\u8da3\u7684\u662f\uff0cplaceholder \u6307\u5b9a\u7684\u53c2\u6570\uff0c\u5374\u4e0d\u9700\u8981 std::ref \u624d\u80fd\u4fdd\u6301\u5f15\u7528\uff1a int inc(int &x, int y) { x += y; } int main() { int x = 0; auto inc1 = std::bind(inc, std::placeholders::_1, 1); inc1(x); // \u6b64\u5904 x \u662f\u6309\u5f15\u7528\u4f20\u9012\u7684 fmt::println(\"x = {}\", x); // x = 1 inc1(x); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u90a3\u662f\u56e0\u4e3a\uff0c std::placeholders::_1 \u6307\u5b9a\u7684\u53c2\u6570\u4f1a\u88ab\u76f4\u63a5\u5b8c\u7f8e\u8f6c\u53d1\u7ed9 inc \u91cc\u7684 x \uff0c\u76f8\u5f53\u4e8e inc(x, 2); \u3002\u53ea\u6709\u6355\u83b7\u7684\u53c2\u6570\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e0d\u4f1a\u5b8c\u7f8e\u8f6c\u53d1\u3002 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 \u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; }; bind \u7684\u5386\u53f2 \u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002 thread \u819d\u76d6\u4e2d\u7bad \u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42 \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand(); std::bind_front \u548c std::bind_back C++17 \u5f15\u5165\u4e86\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\uff1a std::bind_front \uff1a\u7ed1\u5b9a\u6700\u524d\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u540e\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\uff1b std::bind_back \uff1a\u7ed1\u5b9a\u672b\u5c3e\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u524d\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\u3002 \u548c\u666e\u901a\u7684 std::bind \u76f8\u6bd4\u6709\u4ec0\u4e48\u597d\u5904\u5462\uff1f \u5bf9\u4e8e\u51fd\u6570\u53c2\u6570\u975e\u5e38\u591a\uff0c\u4f46\u5b9e\u9645\u53ea\u9700\u8981\u7ed1\u5b9a\u4e00\u4e24\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\uff0c\u7528 std::bind \u4f1a\u9700\u8981\u6dfb\u52a0\u975e\u5e38\u591a\u7684 placeholder\uff0c\u6570\u91cf\u548c\u51fd\u6570\u7684\u5269\u4f59\u53c2\u6570\u6570\u91cf\u4e00\u6837\u591a\u3002\u800c std::bind_front \u5219\u76f8\u5f53\u4e8e\u4e00\u4e2a\u7b80\u5199\uff0c\u540e\u9762\u7684\u5360\u4f4d\u7b26\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\u4e86\u3002 \u4f8b\u5982\u7ed1\u5b9a x = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, 42, std::placeholders::_1, std::placeholders::_2); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_front(func, 42); \u7ed1\u5b9a z = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, std::placeholders::_1, std::placeholders::_2, 42); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_back(func, 42); \u53ef\u4ee5\u770b\u5230\uff0c\u4f7f\u7528\u8fd9\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\u660e\u663e\u5199\u7684\u4ee3\u7801\u5c11\u4e86\u3002 \u5176\u4e2d\u6700\u5e38\u7528\u7684\u662f std::bind_front \uff0c\u7528\u4e8e\u7ed1\u5b9a\u7c7b\u6210\u5458\u7684 this \u6307\u9488\u3002 \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } } \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f \u4f7f\u7528 lambda \u4ee3\u66ff \u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408 forward \u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(std::forward(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 TODO\uff1a std::less \u548c std::bind \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u901a\u8fc7\u6309\u503c\u79fb\u52a8\u6355\u83b7 [p = std::move(p)] \uff0clambda \u53ef\u4ee5\u6301\u6709\u4e00\u4e2a unique_ptr \u4f5c\u4e3a\u6355\u83b7\u53d8\u91cf\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u8fd9\u6837\u521b\u5efa\u51fa\u6765\u7684 lambda\uff0c\u5b58\u5165 std::function \u65f6\u4f1a\u62a5\u9519\uff1a TODO: \u4ee3\u7801 \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 TODO: \u4ee3\u7801\u6848\u4f8b \u5728\u4e4b\u540e\u7684 std::variant \u4e13\u9898\u7ae0\u8282 \u4e2d\u4f1a\u8fdb\u4e00\u6b65\u4ecb\u7ecd\u3002 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b"},{"location":"lambda/#_1","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f \u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f \u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01 \u7528\u51fd\u6570\u5c01\u88c5 \u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408 \u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528 \u4e8c\u6b21\u5c01\u88c5 Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c \u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f \u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5 \u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a \u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6 \u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01 C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a \u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4 \u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1 \u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1 \u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217 \u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305 \u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6 operator() \u5f88\u6709\u8ff7\u60d1\u6027 \u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898 mutable \u7684\u51fd\u6570\u5bf9\u8c61 \u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5 \u6355\u83b7\u5217\u8868\u8bed\u6cd5 \u6309\u503c\u62f7\u8d1d\u6355\u83b7 \u6309\u5f15\u7528\u6355\u83b7 \u6309\u503c\u79fb\u52a8\u6355\u83b7 \u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528 auto & \u4e0e auto const & \u7684\u5e94\u7528 auto && \u4e07\u80fd\u5f15\u7528 decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5 \u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf \u5e94\u7528\u6848\u4f8b \u4ee3\u7801\u590d\u7528 \u5c31\u5730\u8c03\u7528\u7684 lambda-idiom \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570 \u5e94\u7528\u6848\u4f8b \u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f \u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&] lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570 \u6a21\u677f\u51fd\u6570 \u6a21\u677f\u7c7b lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b \u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570 bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570 bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1 bind \u7684\u5386\u53f2 thread \u819d\u76d6\u4e2d\u7bad \u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668 std::bind_front \u548c std::bind_back \u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570 \u4f7f\u7528 std::bind_front \u4ee3\u66ff \u4f7f\u7528 lambda \u4ee3\u66ff bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408 \u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389 lambda \u8fdb\u9636\u6848\u4f8b lambda \u5b9e\u73b0\u9012\u5f52 lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26 \u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function \u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488 \u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001 \u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668 C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66\u51fd\u6570\u5f0f\u7f16\u7a0b"},{"location":"lambda/#_2","text":"int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum = {}\", s); return 0; } \u8fd9\u662f\u4e00\u4e2a\u8ba1\u7b97\u6570\u7ec4\u6c42\u548c\u7684\u7b80\u5355\u7a0b\u5e8f\u3002 \u4f46\u662f\uff0c\u4ed6\u53ea\u80fd\u8ba1\u7b97\u6570\u7ec4 a \u7684\u6c42\u548c\uff0c\u65e0\u6cd5\u590d\u7528\u3002 \u5982\u679c\u6211\u4eec\u6709\u53e6\u4e00\u4e2a\u6570\u7ec4 b \u4e5f\u9700\u8981\u6c42\u548c\u7684\u8bdd\uff0c\u5c31\u5f97\u628a\u6574\u4e2a\u6c42\u548c\u7684 for \u5faa\u73af\u91cd\u65b0\u5199\u4e00\u904d\uff1a int main() { std::vector a = {1, 2, 3, 4}; int s = 0; for (int i = 0; i < a.size(); i++) { s += a[i]; } fmt::println(\"sum of a = {}\", s); std::vector b = {5, 6, 7, 8}; s = 0; for (int i = 0; i < a.size(); i++) { s += b[i]; } fmt::println(\"sum of b = {}\", s); return 0; } \u8fd9\u5c31\u51fa\u73b0\u4e86\u7a0b\u5e8f\u8bbe\u8ba1\u7684\u5927\u5fcc\uff1a\u4ee3\u7801\u91cd\u590d\u3002 \u4f8b\u5982\uff0c\u4f60\u6709\u5439\u7a7a\u8c03\u7684\u9700\u6c42\uff0c\u548c\u5145\u624b\u673a\u7684\u9700\u6c42\u3002\u4f60\u4e3a\u4e86\u6ee1\u8db3\u8fd9\u4e24\u4e2a\u9700\u6c42\uff0c\u8d2d\u4e70\u4e86\u4e24\u53f0\u53d1\u7535\u673a\uff0c\u5206\u522b\u4e3a\u7a7a\u8c03\u548c\u624b\u673a\u4f9b\u7535\u3002\u7b2c\u4e8c\u5929\uff0c\u4f60\u53c8\u4ea7\u751f\u4e86\u73a9\u7535\u8111\u9700\u6c42\uff0c\u4e8e\u662f\u4f60\u53c8\u8d2d\u4e70\u4e00\u53f0\u53d1\u7535\u673a\uff0c\u4e13\u4e3a\u7535\u8111\u4f9b\u7535\u2026\u2026\u771f\u662f\u6d6a\u8d39\uff01 \u91cd\u590d\u7684\u4ee3\u7801\u4e0d\u4ec5\u5f71\u54cd\u4ee3\u7801\u7684 \u53ef\u8bfb\u6027 \uff0c\u4e5f\u589e\u52a0\u4e86 \u7ef4\u62a4 \u4ee3\u7801\u7684\u6210\u672c\u3002 \u770b\u8d77\u6765\u4e71\u7cdf\u7cdf\u7684\uff0c\u4fe1\u606f\u5bc6\u5ea6\u4f4e\uff0c\u8ba9\u4eba\u4e00\u773c\u770b\u4e0d\u51fa\u4ee3\u7801\u5728\u5e72\u4ec0\u4e48\u7684\u529f\u80fd \u5f88\u5bb9\u6613\u5199\u9519\uff0c\u770b\u8d70\u773c\uff0c\u96be\u8c03\u8bd5 \u590d\u5236\u7c98\u8d34\u8fc7\u7a0b\u4e2d\uff0c\u5bb9\u6613\u6f0f\u6539\uff0c\u6bd4\u5982\u8fd9\u91cc\u7684 s += b[i] \u53ef\u80fd\u5199\u6210 s += a[i] \u800c\u81ea\u5df1\u4e0d\u53d1\u73b0 \u6539\u8d77\u6765\u4e0d\u65b9\u4fbf\uff0c\u5f53\u6211\u4eec\u7684\u9700\u6c42\u53d8\u66f4\u65f6\uff0c\u9700\u8981\u591a\u5904\u4fee\u6539\uff0c\u6bd4\u5982\u5f53\u6211\u9700\u8981\u6539\u4e3a\u8ba1\u7b97\u4e58\u79ef\u65f6\uff0c\u9700\u8981\u628a\u4e24\u4e2a\u5730\u65b9\u90fd\u6539\u6210 s *= \u6539\u4e86\u4ee5\u540e\u53ef\u80fd\u6f0f\u6539\u4e00\u90e8\u5206\uff0c\u7559\u4e0b Bug \u9690\u60a3 \u654f\u6377\u5f00\u53d1\u9700\u8981\u53cd\u590d\u4fee\u6539\u4ee3\u7801\uff0c\u6bd4\u5982\u4f60\u6b63\u5728\u8c03\u8bd5 += \u548c -= \u7684\u533a\u522b\uff0c\u770b\u7ed3\u679c\u53d8\u5316\uff0c\u5982\u679c\u4e00\u6b21\u5207\u6362\u9700\u8981\u6539\u591a\u5904\uff0c\u5c31\u5f71\u54cd\u4e86\u8c03\u8bd5\u901f\u5ea6","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\uff1f"},{"location":"lambda/#_3","text":"\u5982\u679c\u4f60\u8fd8\u662f\u559c\u6b22\u201c\u4e00\u672c\u9053\u201d\u5199\u6cd5\u7684\u8bdd\uff0c\u4e0d\u59a8\u60f3\u60f3\u770b\uff0c\u5b8c\u5168\u4e0d\u7528\u4efb\u4f55\u6807\u51c6\u5e93\u548c\u7b2c\u4e09\u65b9\u5e93\u7684\u51fd\u6570\u548c\u7c7b\uff0c\u628a fmt::println \u548c std::vector \u8fd9\u4e9b\u51fd\u6570\u5168\u90e8\u62c6\u89e3\u6210\u4e00\u4e2a\u4e2a\u7cfb\u7edf\u8c03\u7528\u3002\u90a3\u8fd9\u6574\u4e2a\u7a0b\u5e8f\u4f1a\u6709\u591a\u96be\u5199\uff1f int main() { #ifdef _WIN32 int *a = (int *)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else int *a = (int *)mmap(NULL, 4 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); #endif a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; int s = 0; for (int i = 0; i < 4; i++) { s += a[i]; } char buffer[64]; buffer[0] = 's'; buffer[1] = 'u'; buffer[2] = 'm'; buffer[3] = ' '; buffer[4] = '='; buffer[5] = ' '; // \u4f8b\u5982\uff0c\u5982\u679c\u8981\u4fee\u6539\u6b64\u5904\u7684\u63d0\u793a\u6587\u672c\uff0c\u751a\u81f3\u9700\u8981\u4fee\u6539\u540e\u9762\u7684 len \u53d8\u91cf... int len = 6; int x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif int *b = (int *)a; b[0] = 4; b[1] = 5; b[2] = 6; b[3] = 7; int s = 0; for (int i = 0; i < 4; i++) { s += b[i]; } len = 6; x = s; do { buffer[len++] = '0' + x % 10; x /= 10; } while (x); buffer[len++] = '\\n'; #ifdef _WIN32 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL); #else write(1, buffer, len); #endif #ifdef _WIN32 VirtualFree(a, 0, MEM_RELEASE); #else munmap(a); #endif return 0; } \u4e0d\u4ec5\u5b8c\u5168\u6ca1\u6709\u53ef\u8bfb\u6027\u3001\u53ef\u7ef4\u62a4\u6027\uff0c\u751a\u81f3\u90fd\u6ca1\u6709\u53ef\u79fb\u690d\u6027\u3002 \u9664\u975e\u4f60\u53ea\u5199\u5e94\u4ed8\u5bfc\u5e08\u7684\u201c\u4e00\u6b21\u6027\u201d\u7a0b\u5e8f\uff0c\u4e00\u65e6\u8981\u5b9e\u73b0\u590d\u6742\u7684\u4e1a\u52a1\u9700\u6c42\uff0c\u4e0d\u53ef\u907f\u514d\u7684\u8981\u81ea\u5df1\u5c01\u88c5\u51fd\u6570\u6216\u7c7b\u3002\u7f51\u4e0a\u6240\u6709\u9f13\u5439\u201c\u4e0d\u5c01\u88c5\u201d\u201c\u8bbe\u8ba1\u6a21\u5f0f\u662f\u9762\u5b50\u5de5\u7a0b\u201d\u7684\u53cd\u667a\u8a00\u8bba\uff0c\u90fd\u662f\u6ca1\u6709\u505a\u8fc7\u5927\u578b\u9879\u76ee\u7684\u3002","title":"\u72c2\u60f3\uff1a\u6ca1\u6709\u51fd\u6570\u7684\u4e16\u754c\uff1f"},{"location":"lambda/#_4","text":"\u5f88\u591a\u8bbe\u8ba1\u6a21\u5f0f\u6559\u6750\u7247\u9762\u5f3a\u8c03 \u53ef\u8bfb\u6027 \uff0c\u4eff\u4f5b\u8bbe\u8ba1\u6a21\u5f0f\u5c31\u662f\u4e3a\u4e86\u201c\u4f18\u96c5\u201d\u201c\u9ad8\u5927\u4e0a\u201d\u201c\u7f8e\u5b66\u201d\uff1f\u4f7f\u5f97\u5f88\u591a\u4eba\u8ba4\u4e3a\uff0c\u201c\u6211\u8fd9\u4e2a\u662f\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u4e0d\u7528\u7f8e\u5316\u7ed9\u9886\u5bfc\u770b\u201d\u800c\u62d2\u7edd\u8bbe\u8ba1\u6a21\u5f0f\u3002\u5b9e\u9645\u4e0a\u8bbe\u8ba1\u6a21\u5f0f\u7684\u4e3b\u8981\u4ef7\u503c\u5728\u4e8e \u65b9\u4fbf\u540e\u7eed\u4fee\u6539 \uff01 \u4f8b\u5982 B \u7ad9\u4ee5\u524d\u53ea\u652f\u6301\u4e0a\u4f20\u666e\u901a\u89c6\u9891\uff0c\u73b0\u5728\u53d4\u53d4\u7a81\u7136\u63d0\u51fa\uff1a\u8981\u652f\u6301\u4e92\u52a8\u89c6\u9891\uff0c\u5145\u7535\u89c6\u9891\uff0c\u89c6\u9891\u5408\u96c6\uff0c\u8fd8\u5e9f\u9664\u4e86\u89c6\u9891\u5206 p\uff0c\u8fd8\u8981\u652f\u6301\u4e0a\u4f20\u77ed\u89c6\u9891\uff0c\u7ad6\u5c4f\u5f00\u5173\u7b49\u2026\u2026\u6bcf\u4e00\u4e2a\u53d4\u53d4\u7684\u8981\u6c42\uff0c\u90fd\u9700\u8981\u5927\u91cf\u7a0b\u5e8f\u5458\u4fee\u6539\u4ee3\u7801\uff0c\u65e0\u8bba\u6d89\u53ca\u524d\u7aef\u8fd8\u662f\u540e\u7aef\u3002 \u4e0e\u5efa\u7b51\u3001\u7ed8\u753b\u7b49\u9886\u57df\u4e0d\u540c\uff0c\u4e00\u6b21\u4ea4\u4ed8\u5b8c\u6bd5\u5c31\u53ef\u4ee5\u51e0\u4e4e\u6c38\u4e45\u4f7f\u7528\u3002\u800c\u8f6f\u4ef6\u5f00\u53d1\u662f\u4e00\u4e2a\u6301\u7eed\u7684\u8fc7\u7a0b\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u66f4\uff0c\u90fd\u5bfc\u81f4\u4ee3\u7801\u9700\u8981\u4fee\u6539\u3002\u5f00\u53d1\u4eba\u5458\u51e0\u4e4e\u9700\u8981\u4e00\u76f4\u56f4\u7ed5\u7740\u8f6f\u4ef6\u4ee3\u7801\uff0c\u4e0d\u65ad\u7684\u4fee\u6539\u3002\u8c03\u67e5\u8868\u660e\uff0c\u7a0b\u5e8f\u5458 90% \u7684\u65f6\u95f4\u82b1\u5728 \u6539\u4ee3\u7801 \u4e0a\uff0c \u5199\u4ee3\u7801 \u53ea\u5360 10%\u3002 \u8f6f\u4ef6\u5c31\u50cf\u751f\u7269\uff0c\u8981\u4e0d\u65ad\u8fdb\u5316\uff0c\u8f6f\u4ef6\u4e0d\u66f4\u65b0\u4e0d\u7ef4\u62a4\u4e86\u7b49\u4e8e\u6b7b\u3002\u5982\u679c\u4e00\u4e2a\u8f6f\u4ef6\u9010\u6e10\u53d8\u5f97\u81c3\u80bf\u96be\u4ee5\u4fee\u6539\uff0c\u65e0\u6cd5\u9002\u5e94\u65b0\u9700\u6c42\uff0c\u90a3\u4ed6\u5c31\u50cf\u5df2\u7ecf\u5931\u53bb\u8fdb\u5316\u80fd\u529b\u7684\u751f\u7269\u79cd\u7fa4\uff0c\u5982\u300a\u4e09\u4f53\u300b\u4e16\u754c\u89c2\u4e2d\u201c\u5b89\u987f\u201d\u5230\u6fb3\u5927\u5229\u4e9a\u4fdd\u7559\u533a\u91cc\u201c\u7edd\u80b2\u201d\u7684\u4eba\u7c7b\uff0c\u88ab\u6dd8\u6c70\u53ea\u662f\u65f6\u95f4\u95ee\u9898\u3002 \u5982\u679c\u6211\u4eec\u80fd\u5728 \u5199\u4ee3\u7801 \u9636\u6bb5\uff0c\u5c31\u628a\u7a0b\u5e8f\u51c6\u5907\u5f97 \u6613\u4e8e\u540e\u7eed\u4fee\u6539 \uff0c\u90a3\u5c31\u53ef\u4ee5\u5728\u540e\u7eed 90% \u7684 \u6539\u4ee3\u7801 \u9636\u6bb5\u7701\u4e0b\u65e0\u6570\u65f6\u95f4\u3002 \u5982\u4f55\u8ba9\u4ee3\u7801\u6613\u4e8e\u4fee\u6539\uff1f\u524d\u4eba\u603b\u7ed3\u51fa\u4e00\u7cfb\u5217\u5e38\u7528\u7684\u5199\u6cd5\uff0c\u8fd9\u7c7b\u5199\u6cd5\u6709\u52a9\u4e8e\u8ba9\u540e\u7eed\u4fee\u6539\u66f4\u5bb9\u6613\uff0c\u5404\u81ea\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u5408\uff0c\u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u3002 \u63d0\u5347\u53ef\u7ef4\u62a4\u6027\u6700\u57fa\u7840\u7684\u4e00\u70b9\uff0c\u5c31\u662f\u907f\u514d\u91cd\u590d\uff01 \u5f53\u4f60\u6709\u5f88\u591a\u5730\u65b9\u51fa\u73b0\u91cd\u590d\u7684\u4ee3\u7801\u65f6\uff0c\u4e00\u65e6\u9700\u8981\u6d89\u53ca\u4fee\u6539\u8fd9\u90e8\u5206\u903b\u8f91\u65f6\uff0c\u5c31\u9700\u8981\u5230\u6bcf\u4e00\u4e2a\u51fa\u73b0\u4e86\u8fd9\u4e2a\u903b\u8f91\u7684\u4ee3\u7801\u4e2d\uff0c\u53bb\u9010\u4e00\u4fee\u6539\u3002 \u4f8b\u5982\u4f60\u7684\u540d\u5b57\uff0c\u5728\u51fa\u751f\u8bc1\uff0c\u8eab\u4efd\u8bc1\uff0c\u5b66\u751f\u8bc1\uff0c\u6bd5\u4e1a\u8bc1\uff0c\u623f\u4ea7\u8bc1\uff0c\u9a7e\u9a76\u8bc1\uff0c\u5404\u79cd\u5730\u65b9\u90fd\u51fa\u73b0\u4e86\u3002\u90a3\u4e48\u4f60\u8981\u6539\u540d\u7684\u8bdd\uff0c\u6240\u6709\u8fd9\u4e9b\u8bc1\u4ef6\u90fd\u9700\u8981\u91cd\u65b0\u5370\u5237\uff01\u5982\u679c\u80fd\u628a\u4ed6\u4eec\u5408\u5e76\u6210\u4e00\u4e2a\u201c\u7edf\u4e00\u8bc1\u201d\uff0c\u90a3\u4e48\u53ea\u9700\u8981\u4fee\u6539\u201c\u7edf\u4e00\u8bc1\u201d\u4e0a\u7684\u540d\u5b57\u5c31\u884c\u4e86\u3002 \u4e0d\u8fc7\uff0c\u73b0\u5b9e\u4e2d\u5e76\u6ca1\u6709\u9891\u7e41\u6539\u540d\u5b57\u7684\u9700\u6c42\uff0c\u8fd9\u8bf4\u660e\uff1a \u5bf9\u4e8e\u4e0d\u5e38\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u53ef\u4ee5\u5bb9\u5fcd\u4e00\u5b9a\u7684\u91cd\u590d\u3002 \u8d8a\u662f\u672a\u6765\u6709\u53ef\u80fd\u4fee\u6539\u7684\uff0c\u5c31\u8d8a\u9700\u8981\u8bbe\u8ba1\u6a21\u5f0f\u964d\u91cd\uff01 \u4f8b\u5982\u6570\u5b66\u5e38\u6570 PI = 3.1415926535897\uff0c\u8fd9\u8f88\u5b50\u90fd\u4e0d\u53ef\u80fd\u51fa\u73b0\u4fee\u6539\u7684\u9700\u6c42\uff0c\u90a3\u5199\u6b7b\u4e5f\u6ca1\u5173\u7cfb\u3002\u5982\u679c\u8981\u628a PI \u5b9a\u4e49\u6210\u5b8f\uff0c\u53ea\u662f\u51fa\u4e8e\u201c\u8bb0\u4e0d\u4f4f\u201d\u201c\u5199\u8d77\u6765\u592a\u957f\u4e86\u201d\u201c\u590d\u5236\u7c98\u8d34\u9ebb\u70e6\u201d\u3002\u6240\u4ee5\u5bf9\u4e8e PI \u8fd9\u79cd\u4e0d\u4f1a\u4fee\u6539\u7684\u4e1c\u897f\uff0c\u964d\u91cd\u53ea\u662f\u589e\u52a0 \u53ef\u8bfb\u6027 \uff0c\u800c\u4e0d\u662f \u53ef\u4fee\u6539\u6027 \u3002 \u4f46\u662f\uff0c\u4e0d\u8981\u60f3\u5f53\u7136\uff01\u9700\u6c42\u7684\u5343\u53d8\u4e07\u5316\u603b\u662f\u8d85\u51fa\u4f60\u7684\u60f3\u8c61\u3002 \u4f8b\u5982\u4f60\u505a\u4e86\u4e00\u4e2a\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u6e38\u620f\uff0c\u9700\u8981\u7528\u5230\u91cd\u529b\u52a0\u901f\u5ea6 g = 9.8\uff0c\u4f60\u60f3\u5f53\u7136\u8ba4\u4e3a g \u4ee5\u540e\u4e0d\u53ef\u80fd\u4fee\u6539\u3002\u8001\u677f\u4e5f\u4fe1\u8a93\u65e6\u65e6\u5411\u4f60\u4fdd\u8bc1\uff1a\u201c\u6ca1\u4e8b\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u4e0d\u4f1a\u6539\u53d8\u3002\u201d\u4f60\u5c31\u5199\u6b7b\u5728\u4ee3\u7801\u91cc\u4e86\u3002 \u6ca1\u60f3\u5230\uff0c\u201c\u6124\u6012\u7684\u5c0f\u9e1f\u201d\u8001\u677f\u7a81\u7136\u8981\u6c42\u4f60\u52a0\u5165\u201c\u6708\u7403\u7ae0\u201d\u5173\u5361\uff0c\u5728\u8fd9\u4e9b\u5173\u5361\u4e2d\uff0c\u91cd\u529b\u52a0\u901f\u5ea6\u662f g = 1.6\u3002 \u5982\u679c\u4f60\u4e00\u5f00\u59cb\u5c31\u5df2\u7ecf\u628a g \u63d0\u53d6\u51fa\u6765\uff0c\u5b9a\u4e49\u4e3a\u5e38\u91cf\uff1a struct Level { const double g = 9.8; void physics_sim() { bird.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f pig.v = g * t; // \u5047\u88c5\u8fd9\u91cc\u662f\u7269\u7406\u4eff\u771f\u7a0b\u5e8f } }; \u90a3\u4e48\u8981\u652f\u6301\u6708\u7403\u5173\u5361\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5c31\u53ef\u4ee5\u4e86\u3002 struct Level { double g; Level(Chapter chapter) { if (chapter == ChapterMoon) { g = 1.6; } else { g = 9.8; } } void physics_sim() { bird.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g pig.v = g * t; // \u65e0\u9700\u4efb\u4f55\u4fee\u6539\uff0c\u81ea\u52a8\u9002\u5e94\u4e86\u65b0\u7684\u975e\u5e38\u6570 g } }; \u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u505a zeno \u65f6\uff0c\u8be2\u95ee\u8981\u4e0d\u8981\u628a\u6e32\u67d3\u7ba1\u7ebf\u8282\u70b9\u5316\uff0c\u65b9\u4fbf\u7528\u6237\u52a8\u6001\u7f16\u7a0b\uff1f\u5f20\u7329\u7329\u5c31\u662f\u4fe1\u8a93\u65e6\u65e6\u9053\uff1a\u201c\u6e32\u67d3\u662f\u4e00\u4e2a\u9ad8\u5ea6\u6210\u719f\u9886\u57df\uff0c\u4e0d\u4f1a\u6709\u591a\u5c11\u4fee\u6539\u9700\u6c42\u7684\u3002\u201d\u5c0f\u5f6d\u8001\u5e08\u9042\u5199\u6b7b\u4e86\u6e32\u67d3\u7ba1\u7ebf\uff0c\u4e13\u4e3a\u6027\u80fd\u6781\u5ea6\u4f18\u5316\uff0c\u51e0\u4e2a\u6708\u540e\uff0c\u5f20\u7329\u7329\u7f9e\u7b54\u7b54\u627e\u5230\u5c0f\u5f6d\u8001\u5e08\uff1a\u201c\u5c0f\u5f6d\u8001\u5e08\uff0c\u90a3\u4e2a\uff0c\u6e32\u67d3\uff0c\u80fd\u4e0d\u80fd\u6539\u6210\u8282\u70b9\u554a\u2026\u2026\u201d\u3002\u8fd9\u4e2a\u6545\u4e8b\u544a\u8bc9\u6211\u4eec\uff0c\u7532\u65b9\u7684\u4fe1\u8a93\u65e6\u65e6\u653e\u7684\u4e00\u4e2a\u5c41\u90fd\u4e0d\u80fd\u4fe1\u3002","title":"\u8bbe\u8ba1\u6a21\u5f0f\u8ffd\u6c42\u7684\u662f\u201c\u53ef\u6539\u201d\u800c\u4e0d\u662f\u201c\u53ef\u8bfb\u201d\uff01"},{"location":"lambda/#_5","text":"\u51fd\u6570\u5c31\u662f\u6765\u5e2e\u4f60\u89e3\u51b3\u4ee3\u7801\u91cd\u590d\u95ee\u9898\u7684\uff01\u8981\u9886\uff1a \u628a\u5171\u540c\u7684\u90e8\u5206\u63d0\u53d6\u51fa\u6765\uff0c\u628a\u4e0d\u540c\u7684\u90e8\u5206\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u3002 void sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } fmt::println(\"sum of v = {}\", s); } int main() { std::vector a = {1, 2, 3, 4}; sum(a); std::vector b = {5, 6, 7, 8}; sum(b); return 0; } \u8fd9\u6837 main \u51fd\u6570\u91cc\u5c31\u53ef\u4ee5\u53ea\u5173\u5fc3\u8981\u6c42\u548c\u7684\u6570\u7ec4\uff0c\u800c\u4e0d\u7528\u5173\u5fc3\u6c42\u548c\u5177\u4f53\u662f\u5982\u4f55\u5b9e\u73b0\u7684\u4e86\u3002\u4e8b\u540e\u6211\u4eec\u53ef\u4ee5\u968f\u65f6\u628a sum \u7684\u5185\u5bb9\u5077\u5077\u6362\u6389\uff0c\u6362\u6210\u5e76\u884c\u7684\u7b97\u6cd5\uff0cmain \u4e5f\u4e0d\u7528\u77e5\u9053\u3002\u8fd9\u5c31\u662f \u5c01\u88c5 \uff0c\u53ef\u4ee5\u628a\u91cd\u590d\u7684\u516c\u5171\u90e8\u5206\u62bd\u53d6\u51fa\u6765\uff0c\u65b9\u4fbf\u4ee5\u540e\u4fee\u6539\u4ee3\u7801\u3002 sum \u51fd\u6570\u76f8\u5f53\u4e8e\uff0c\u5f53\u9700\u8981\u5439\u7a7a\u8c03\u65f6\uff0c\u63d2\u4e0a\u7a7a\u8c03\u63d2\u5ea7\u3002\u5f53\u9700\u8981\u7ed9\u624b\u673a\u5145\u7535\u65f6\uff0c\u63d2\u4e0a\u624b\u673a\u5145\u7535\u5668\u3002\u4f60\u4e0d\u9700\u8981\u5173\u5fc3\u63d2\u5ea7\u91cc\u7684\u7535\u54ea\u91cc\u6765\uff0c\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4f1a\u66ff\u4f60\u60f3\u529e\u6cd5\u89e3\u51b3\uff0c\u60f3\u529e\u6cd5\u4f18\u5316\uff0c\u60f3\u529e\u6cd5\u5347\u7ea7\u5230\u7eff\u8272\u80fd\u6e90\u3002\u4f60\u53ea\u9700\u8981\u5439\u7740\u7a7a\u8c03\u7ed9\u4f60\u6b63\u5728\u5f00\u53d1\u7684\u624b\u673a App \u4f18\u5316\u5c31\u884c\u4e86\uff0c\u5927\u5927\u51cf\u8f7b\u7a0b\u5e8f\u5458\u5fc3\u667a\u8d1f\u62c5\u3002","title":"\u7528\u51fd\u6570\u5c01\u88c5"},{"location":"lambda/#_6","text":"\u4f46\u662f\uff01\u8fd9\u6bb5\u4ee3\u7801\u4ecd\u7136\u6709\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u628a sum \u6c42\u548c\u7684\u7ed3\u679c\uff0c\u76f4\u63a5\u5728 sum \u91cc\u6253\u5370\u4e86\u51fa\u6765\u3002sum \u91cc\u5199\u6b7b\u4e86\uff0c\u6c42\u5b8c\u548c\u4e4b\u540e\u53ea\u80fd\u76f4\u63a5\u6253\u5370\uff0c\u8c03\u7528\u8005 main \u6839\u672c\u65e0\u6cd5\u63a7\u5236\u3002 \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u5c01\u88c5\uff0c\u6216\u8005\u8bf4\uff0c\u5c01\u88c5\u8fc7\u5934\u4e86\u3002 \u4f60\u628a\u624b\u673a\u5145\u7535\u5668 (fmt::println) \u710a\u6b7b\u5728\u4e86\u63d2\u5ea7 (sum) \u4e0a\uff0c\u73b0\u5728\u8fd9\u4e2a\u63d2\u5ea7\u53ea\u80fd\u7ed9\u624b\u673a\u5145\u7535 (\u7528\u4e8e\u76f4\u63a5\u6253\u5370) \u4e86\uff0c\u4e0d\u80fd\u7ed9\u7b14\u8bb0\u672c\u7535\u8111\u5145\u7535 (\u6c42\u548c\u7ed3\u679c\u4e0d\u76f4\u63a5\u7528\u4e8e\u6253\u5370) \u4e86\uff01\u5c3d\u7ba1\u901a\u8fc7\u66f4\u6362\u5145\u7535\u7ebf (\u53c2\u6570 v)\uff0c\u8fd8\u53ef\u4ee5\u652f\u6301\u652f\u6301\u5b89\u5353 (a) \u548c\u82f9\u679c (b) \u4e24\u79cd\u624b\u673a\u7684\u5145\u7535\uff0c\u4f46\u8fd9\u6837\u710a\u6b7b\u7684\u63d2\u5ea7\u5df2\u7ecf\u548c\u7b14\u8bb0\u672c\u7535\u8111\u65e0\u7f18\u4e86\u3002","title":"\u8981\u5c01\u88c5\uff0c\u4f46\u4e0d\u8981\u8026\u5408"},{"location":"lambda/#_7","text":"\u5f88\u660e\u663e\uff0c\u201c\u6253\u5370\u201d\u548c\u201c\u6c42\u548c\u201d\u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u64cd\u4f5c\uff0c\u4e0d\u5e94\u8be5\u710a\u6b7b\u5728\u4e00\u5757\u3002 sum \u51fd\u6570\u7684\u672c\u804c\u5de5\u4f5c\u662f\u201c\u6570\u7ec4\u6c42\u548c\u201d\uff0c\u4e0d\u5e94\u8be5\u9644\u8d60\u6253\u5370\u529f\u80fd\u3002 sum \u8ba1\u7b97\u51fa\u6c42\u548c\u7ed3\u679c\u540e\uff0c\u76f4\u63a5 return \u5373\u53ef\u3002 \u5982\u4f55\u5904\u7406\u8fd9\u4e2a\u7ed3\u679c\uff0c\u662f\u8c03\u7528\u8005 main \u7684\u4e8b\uff0c\u6b63\u5982\u201c\u56fd\u5bb6\u7535\u7f51\u201d\u4e0d\u4f1a\u7ba1\u4f60\u7528\u4ed6\u63d0\u4f9b\u7684\u7535\u6765\u5439\u7a7a\u8c03\u8fd8\u662f\u73a9\u6e38\u620f\u4e00\u6837\uff0c\u53ea\u8981\u4e0d\u59a8\u788d\u5230\u5176\u4ed6\u5c45\u6c11\u7684\u6b63\u5e38\u7528\u7535\u3002 int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum of a = {}\", sum(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"sum of b = {}\", sum(b)); return 0; } \u8fd9\u5c31\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8bf4\u7684 \u804c\u8d23\u5355\u4e00\u539f\u5219 \u3002","title":"\u6bcf\u4e2a\u51fd\u6570\u5e94\u8be5\u804c\u8d23\u5355\u4e00\uff0c\u522b\u4e00\u5fc3\u591a\u7528"},{"location":"lambda/#_8","text":"\u5047\u8bbe\u6211\u4eec\u8981\u8ba1\u7b97\u4e00\u4e2a\u6570\u7ec4\u7684\u5e73\u5747\u503c\uff0c\u53ef\u4ee5\u518d\u5b9a\u4e49\u4e2a\u51fd\u6570 average\uff0c\u4ed6\u53ef\u4ee5\u57fa\u4e8e sum \u5b9e\u73b0\uff1a int sum(std::vector const &v) { int s = 0; for (int i = 0; i < v.size(); i++) { s += v[i]; } return s; } double average(std::vector const &v) { return (double)sum(v) / v.size(); } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"average of a = {}\", average(a)); std::vector b = {5, 6, 7, 8}; fmt::println(\"average of b = {}\", average(b)); return 0; } \u8fdb\u4e00\u6b65\u5c01\u88c5\u4e00\u4e2a\u6253\u5370\u6570\u7ec4\u6240\u6709\u7edf\u8ba1\u5b66\u4fe1\u606f\u7684\u51fd\u6570\uff1a void print_statistics(std::vector const &v) { if (v.empty()) { fmt::println(\"this is empty...\"); } else { fmt::println(\"sum: {}\", sum(v)); fmt::println(\"average: {}\", average(v)); fmt::println(\"min: {}\", min(v)); fmt::println(\"max: {}\", max(v)); } } int main() { std::vector a = {1, 2, 3, 4}; print_statistics(a); std::vector b = {5, 6, 7, 8}; print_statistics(b); return 0; } \u66b4\u9732 API \u65f6\uff0c\u8981\u540c\u65f6\u63d0\u4f9b\u5e95\u5c42\u7684 API \u548c\u9ad8\u5c42\u5c01\u88c5\u7684 API\u3002\u7528\u6237\u5982\u679c\u60f3\u8981\u63a7\u5236\u66f4\u591a\u7ec6\u8282\u53ef\u4ee5\u8c03\u7528\u5e95\u5c42 API\uff0c\u60f3\u8981\u7701\u4e8b\u7684\u7528\u6237\u53ef\u4ee5\u8c03\u7528\u9ad8\u5c42\u5c01\u88c5\u597d\u7684 API\u3002 \u9ad8\u5c42\u5c01\u88c5 API \u5e94\u5f53\u53ef\u4ee5\u5b8c\u5168\u901a\u8fc7\u8c03\u7528\u5e95\u5c42 API \u5b9e\u73b0\uff0c\u63d0\u4f9b\u9ad8\u5c42 API \u53ea\u662f\u65b9\u4fbf\u521d\u7ea7\u7528\u6237\u4f7f\u7528\u548c\u7406\u89e3\u3002 \u4f8b\u5982 libcurl \u5c31\u63d0\u4f9b\u4e86 curl_easy \u548c curl_multi \u4e24\u5957 API\u3002 - `curl_multi` \u63d0\u4f9b\u4e86\u8d85\u8be6\u7ec6\u7684\u53c2\u6570\uff0c\u628a\u6bcf\u4e2a\u64cd\u4f5c\u5206\u62c6\u6210\u591a\u6b65\uff0c\u65b9\u4fbf\u7528\u6237\u63d2\u624b\u7ec6\u8282\uff0c\u6ee1\u8db3\u9ad8\u7ea7\u7528\u6237\u7684\u5b9a\u5236\u5316\u9700\u6c42\uff0c\u4f46\u592a\u8fc7\u590d\u6742\uff0c\u96be\u4ee5\u5b66\u4e60\u3002 - `curl_easy` \u662f\u5bf9 `curl_multi` \u7684\u518d\u5c01\u88c5\uff0c\u63d0\u4f9b\u4e86\u66f4\u7b80\u5355\u7684 API\uff0c\u4f46\u662f\u5bf9\u5177\u4f53\u7ec6\u8282\u5c31\u96be\u4ee5\u64cd\u63a7\u4e86\uff0c\u9002\u5408\u521d\u5b66\u8005\u4e0a\u624b\u3002","title":"\u4e8c\u6b21\u5c01\u88c5"},{"location":"lambda/#linus-3-80-24","text":"Linux \u5185\u6838\u4e3a\u4ec0\u4e48\u575a\u6301\u4f7f\u7528 8 \u7f29\u8fdb\u4e3a\u4ee3\u7801\u98ce\u683c\uff1f \u56e0\u4e3a\u9ad8\u7f29\u8fdb\u53ef\u4ee5\u907f\u514d\u7a0b\u5e8f\u5458\u5199\u51fa\u5d4c\u5957\u5c42\u6570\u592a\u6df1\u7684\u4ee3\u7801\uff0c\u5f53\u4ed6\u5199\u51fa\u592a\u6df1\u5d4c\u5957\u65f6\uff0c\u5de8\u5927\u7684 8 \u7f29\u8fdb\u4f1a\u8ba9\u4ee3\u7801\u53d8\u5f97\u975e\u5e38\u504f\u53f3\uff0c\u5199\u4e0d\u4e0b\u591a\u5c11\u7a7a\u95f4\u3002\u4ece\u800c\u8ba9\u7a0b\u5e8f\u5458\u81ea\u5df1\u7ea2\u7740\u8138\u201c\u5bf9\u4e0d\u8d77\uff0c\u6211\u628a\u5355\u4e2a\u51fd\u6570\u5199\u592a\u6df1\u4e86\u201d\u7136\u540e\u8d76\u7d27\u62c6\u5206\u51fa\u591a\u4e2a\u51fd\u6570\u6765\u3002 \u6b64\u5916\uff0c\u4ed6\u8fd8\u89c4\u5b9a\u4e86\u5355\u4e00\u4e00\u4e2a\u51fd\u6570\u5fc5\u987b\u5728\u7ec8\u7aef\u5bbd\u5ea6 80 x 24 \u4e2d\u663e\u793a\u5f97\u4e0b\uff0c\u5426\u5219\u5c31\u9700\u8981\u62c6\u5206\u6210\u591a\u4e2a\u51fd\u6570\u91cd\u5199\uff0c\u8fd9\u914d\u5408 8 \u7f29\u8fdb\uff0c\u6709\u6548\u7684\u9650\u5236\u4e86\u5d4c\u5957\u7684\u5c42\u6570\uff0c\u8feb\u4f7f\u7a0b\u5e8f\u5458\u4e0d\u5f97\u4e0d\u91cd\u65b0\u601d\u8003\uff0c\u66f4\u89e3\u8026\u7684\u5199\u6cd5\u51fa\u6765\u3002","title":"Linus \u7684\u6700\u4f73\u5b9e\u8df5\uff1a\u6bcf\u4e2a\u51fd\u6570\u4e0d\u8981\u8d85\u8fc7 3 \u5c42\u5d4c\u5957\uff0c\u4e00\u884c\u4e0d\u8981\u8d85\u8fc7 80 \u5b57\u7b26\uff0c\u6bcf\u4e2a\u51fd\u6570\u4f53\u4e0d\u8981\u8d85\u8fc7 24 \u884c"},{"location":"lambda/#_9","text":"\u4f60\u4ea7\u751f\u4e86\u4e24\u4e2a\u9700\u6c42\uff0c\u5206\u522b\u5c01\u88c5\u4e86\u4e24\u4e2a\u51fd\u6570\uff1a sum \u6c42\u6240\u6709\u5143\u7d20\u7684\u548c product \u6c42\u6240\u6709\u5143\u7d20\u7684\u79ef int sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret += v[i]; } return ret; } int product(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { ret *= v[i]; } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", sum(a)); fmt::println(\"product: {}\", product(a)); return 0; } \u6ce8\u610f\u5230 sum \u548c product \u7684\u5185\u5bb9\u51e0\u4e4e\u5982\u51fa\u4e00\u8f99\uff0c\u552f\u4e00\u7684\u533a\u522b\u5728\u4e8e\uff1a sum \u7684\u5faa\u73af\u4f53\u4e3a += \uff1b product \u7684\u5faa\u73af\u4f53\u4e3a *= \u3002 \u8fd9\u79cd\u51fd\u6570\u4f53\u5185\u6709\u90e8\u5206\u4ee3\u7801\u91cd\u590d\uff0c\u4f46\u53c8\u6709\u7279\u5b9a\u90e8\u5206\u4e0d\u540c\uff0c\u96be\u4ee5\u62bd\u79bb\u3002 \u8be5\u600e\u4e48\u590d\u7528\u8fd9\u91cd\u590d\u7684\u90e8\u5206\u4ee3\u7801\u5462\uff1f \u6211\u4eec\u8981\u628a sum \u548c product \u5408\u5e76\u6210\u4e00\u4e2a\u51fd\u6570 generic_sum \u3002\u7136\u540e\u901a\u8fc7\u51fd\u6570\u53c2\u6570\uff0c\u628a\u5dee\u5f02\u90e8\u5206\uff080\u3001 += \uff09\u201c\u6ce8\u5165\u201d\u5230\u4e24\u4e2a\u51fd\u6570\u539f\u672c\u4e0d\u540c\u5730\u65b9\u3002","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u51fd\u6570\u5f0f\uff1f"},{"location":"lambda/#_10","text":"\u5982\u4f55\u8868\u793a\u6211\u8fd9\u4e2a\u51fd\u6570\u662f\u8981\u505a\u6c42\u548c += \u8fd8\u662f\u6c42\u79ef *= \uff1f \u8ba9\u6211\u4eec\u5b9a\u4e49\u679a\u4e3e\uff1a enum Mode { ADD, // \u6c42\u548c\u64cd\u4f5c MUL, // \u6c42\u79ef\u64cd\u4f5c }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { // \u51fd\u6570\u5185\u5224\u65ad\u679a\u4e3e\uff0c\u51b3\u5b9a\u8981\u505a\u4ec0\u4e48\u64cd\u4f5c ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; fmt::println(\"sum: {}\", generic_sum(a, ADD)); // \u7528\u6237\u6307\u5b9a\u4ed6\u60f3\u8981\u7684\u64cd\u4f5c fmt::println(\"product: {}\", generic_sum(a, MUL)); return 0; } \u7136\u800c\uff0c\u5982\u679c\u7528\u6237\u73b0\u5728\u60f3\u8981\u6c42\u6570\u7ec4\u7684 \u6700\u5927\u503c \u5462\uff1f \u679a\u4e3e\u4e2d\u8fd8\u6ca1\u6709\u5b9e\u73b0\u6700\u5927\u503c\u7684\u64cd\u4f5c\u2026\u2026\u8981\u652f\u6301\uff0c\u5c31\u5f97\u624b\u5fd9\u811a\u4e71\u5730\u53bb\u4fee\u6539 generic_sum \u51fd\u6570\u548c Mode \u679a\u4e3e\u539f\u672c\u7684\u5b9a\u4e49\uff0c\u771f\u9ebb\u70e6\uff01 enum Mode { ADD, MUL, MAX, // ***\u6539*** }; int generic_sum(std::vector const &v, Mode mode) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { if (mode == ADD) { ret += v[i]; } else if (mode == MUL) { ret *= v[i]; } else if (mode == MAX) { // ***\u6539*** ret = std::max(ret, v[i]); // ***\u6539*** } } return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, MAX); // ***\u6539*** return 0; } \u6211\u7528 // ***\u6539*** \u6307\u793a\u4e86\u6240\u6709\u9700\u8981\u6539\u52a8\u7684\u5730\u65b9\u3002 \u4e3a\u4e86\u589e\u52a0\u4e00\u4e2a\u6c42\u6700\u5927\u503c\u7684\u64cd\u4f5c\uff0c\u5c31\u9700\u8981\u4e09\u5904\u5206\u6563\u5728\u5404\u5730\u7684\u6539\u52a8\uff01 \u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u5bb9\u6613\u6284\u6f0f\uff0c\u6284\u9519\uff0c\u6bd4\u5982 MAX \u4e0d\u5c0f\u5fc3\u6253\u9519\u6210 MUL \u4e86\uff0c\u81ea\u5df1\u5374\u6ca1\u53d1\u73b0\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u8fd9\u6837\u5199\u4ee3\u7801\u7684\u65b9\u5f0f\uff0c\u5fc3\u667a\u8d1f\u62c5\u6781\u5927\uff0c\u6574\u5929\u5c31\u63d0\u5fc3\u540a\u80c6\u7740\u4e1c\u4e00\u5757\uff0c\u897f\u4e00\u5757\u7684\u6563\u88c5\u4ee3\u7801\uff0c\u62c5\u5fc3\u7740\u6709\u6ca1\u6709\u54ea\u4e2a\u5730\u65b9\u5199\u9519\u5199\u6f0f\uff0c\u4e25\u91cd\u59a8\u788d\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u5e76\u4e14\u5199\u51fa\u6765\u7684\u4ee3\u7801\u4e5f\u4e0d\u80fd\u9002\u5e94\u9700\u6c42\u7684\u53d8\u5316\uff1a\u5047\u5982\u6211\u9700\u8981\u652f\u6301 MIN \u5462\uff1f\u53c8\u5f97\u6539\u4e09\u4e2a\u5730\u65b9\uff01\u8fd9\u8fdd\u80cc\u4e86\u8bbe\u8ba1\u6a21\u5f0f\u7684 \u5f00\u95ed\u539f\u5219 \u3002 \u5f00\u95ed\u539f\u5219: \u5bf9\u6269\u5c55\u5f00\u653e\uff0c\u5bf9\u4fee\u6539\u5c01\u95ed\u3002\u6307\u7684\u662f\u8f6f\u4ef6\u5728\u9002\u5e94\u9700\u6c42\u53d8\u5316\u65f6\uff0c\u5e94\u5c3d\u91cf\u901a\u8fc7 \u6269\u5c55\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\uff0c\u800c\u4e0d\u662f\u901a\u8fc7 \u4fee\u6539\u5df2\u6709\u4ee3\u7801 \u6765\u5b9e\u73b0\u53d8\u5316\u3002 \u4f7f\u7528\u679a\u4e3e\u548c if-else \u5b9e\u73b0\u591a\u6001\uff0c\u96be\u4ee5\u6269\u5c55\uff0c\u8fd8\u8981\u4e00\u76f4\u53bb\u4fee\u6539\u539f\u51fd\u6570\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5c31\u8fdd\u80cc\u4e86 \u5f00\u95ed\u539f\u5219 \u3002","title":"\u679a\u4e3e\u7684\u7cdf\u7cd5\u7528\u6cd5"},{"location":"lambda/#_11","text":"\u5982\u679c\u6211\u4eec\u53ef\u4ee5\u201c\u6ce8\u5165\u201d\u4ee3\u7801\u5c31\u597d\u4e86\uff01\u80fd\u5426\u628a\u4e00\u6bb5\u201c\u4ee3\u7801\u201d\u4f5c\u4e3a generic_sum \u51fd\u6570\u7684\u53c2\u6570\u5462\uff1f \u4ee3\u7801\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\uff0c\u6ce8\u5165\u4ee3\u7801\u5c31\u662f\u6ce8\u5165\u51fd\u6570\u3002\u6211\u4eec\u5148\u5b9a\u4e49\u51fa\u4e09\u4e2a\u4e0d\u540c\u64cd\u4f5c\u5bf9\u5e94\u7684\u51fd\u6570\uff1a int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } \u7136\u540e\uff0c\u628a\u8fd9\u4e09\u4e2a\u5c0f\u51fd\u6570\uff0c\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u5927\u51fd\u6570 generic_sum \u7684\u53c2\u6570\u5c31\u884c\uff01 int generic_sum(std::vector const &v, auto op) { int ret = v[0]; for (int i = 1; i < v.size(); i++) { // \u51fd\u6570\u4f5c\u8005\u65e0\u9700\u4e86\u89e3\u7528\u6237\u6307\u5b9a\u7684\u201c\u64cd\u4f5c\u201d\u5177\u4f53\u662f\u4ec0\u4e48 // \u53ea\u9700\u8981\u8c03\u7528\u8fd9\u4e00\u201c\u64cd\u4f5c\u201d\uff0c\u5f97\u5230\u7ed3\u679c\u5c31\u884c ret = op(ret, v[i]); } return ret; } int main() { std::vector a = {1, 2, 3, 4}; // \u7528\u6237\u65e0\u9700\u5173\u5fc3\u51fd\u6570\u7684\u5177\u4f53\u5b9e\u73b0\u662f\u4ec0\u4e48 // \u53ea\u9700\u968f\u5fc3\u6240\u6b32\u6307\u5b9a\u4ed6\u7684\u201c\u64cd\u4f5c\u201d\u4f5c\u4e3a\u53c2\u6570 generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u8d23\u4efb\u660e\u786e\u4e86\uff0c\u6211\u4eec\u6210\u529f\u628a\u4e00\u90e8\u5206\u7ec6\u8282\u4ece generic_sum \u4e2d\u8fdb\u4e00\u6b65\u62bd\u79bb\u3002 \u5e93\u4f5c\u8005 generic_sum \u4e0d\u5fc5\u4e86\u89e3 main \u7684\u64cd\u4f5c\u5177\u4f53\u662f\u4ec0\u4e48\uff0c\u4ed6\u53ea\u8d1f\u8d23\u5229\u7528\u8fd9\u4e2a\u64cd\u4f5c\u6c42\u201c\u548c\u201d\u3002 \u5e93\u7528\u6237 main \u4e0d\u5fc5\u4e86\u89e3 generic_sum \u5982\u4f55\u5b9e\u73b0\u64cd\u4f5c\u7d2f\u52a0\uff0c\u4ed6\u53ea\u7ba1\u6ce8\u5165\u201c\u5982\u4f55\u64cd\u4f5c\u201d\u7684\u4ee3\u7801\uff0c\u4ee5\u51fd\u6570\u7684\u5f62\u5f0f\u3002","title":"\u51fd\u6570\u5f0f\u7f16\u7a0b\u5149\u8363\u6551\u573a"},{"location":"lambda/#c20-auto","text":"int generic_sum(std::vector const &v, auto op) { } \u8fd9\u91cc\u7684\u53c2\u6570 op \u7c7b\u578b\u58f0\u660e\u4e3a auto\uff0c\u6548\u679c\u5c31\u662f\uff0cop \u8fd9\u4e2a\u53c2\u6570\u73b0\u5728\u80fd\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u7684\u5bf9\u8c61\u4e86\uff08\u5305\u62ec\u51fd\u6570\uff01\uff09 int generic_sum(std::vector const &v, auto op) { ... } \u51c6\u786e\u7684\u8bf4\uff0c auto op \u53c2\u6570\u7684\u6548\u679c\u662f\u4f7f generic_sum \u53d8\u4e3a\u4e00\u4e2a \u6a21\u677f\u51fd\u6570 \uff0c\u5176\u4e2d op \u53c2\u6570\u53d8\u6210\u4e86\u6a21\u677f\u53c2\u6570\uff0c\u80fd\u591f\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u4e86\u3002\u800c\u5199\u660e\u7c7b\u578b\u7684\u53c2\u6570 std::vector const &v \u5c31\u6ca1\u6709\u4efb\u4f55\u989d\u5916\u6548\u679c\uff0c\u5c31\u53ea\u80fd\u63a5\u53d7 vector \u800c\u5df2\u3002 \u5982\u679c\u4f60\u4e0d\u652f\u6301 C++20 \u7684\u8bdd\uff0c\u9700\u8981\u663e\u5f0f\u5199\u51fa template \uff0c\u624d\u80fd\u5b9e\u73b0\u540c\u6837\u7684\u6548\u679c\uff1a template int generic_sum(std::vector const &v, Op op) { ... } C++11\uff1aauto \u53ea\u80fd\u7528\u4e8e\u5b9a\u4e49\u53d8\u91cf\uff1bC++14\uff1a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u53ef\u4ee5\u662f auto\uff1bC++17\uff1a\u6a21\u677f\u53c2\u6570\u4e5f\u53ef\u4ee5 auto\uff1bC++20\uff1a\u51fd\u6570\u53c2\u6570\u4e5f\u53ef\u4ee5\u662f auto \u4e86\uff1b\uff08\u72c2\u60f3\uff09C++47\uff1aauto \u73b0\u5728\u662f C++47 \u7684\u552f\u4e00\u5173\u952e\u5b57\uff0c\u7528\u6237\u53ea\u9700\u4e0d\u65ad\u8f93\u5165 auto-auto-auto\uff0c\u7f16\u8bd1\u5668\u5185\u5efa\u4eba\u5de5\u667a\u80fd\u81ea\u52a8\u8bc6\u522b\u4f60\u7684\u610f\u56fe\u751f\u6210\u673a\u5668\u7801\u3002","title":"\u6211\u7528\u4e86 C++20 \u7684\u51fd\u6570\u53c2\u6570 auto \u8bed\u6cd5\u7cd6"},{"location":"lambda/#_12","text":"\u5728\u8fc7\u53bb\u7684 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f \u4e2d\uff0c\u51fd\u6570\uff08\u4ee3\u7801\uff09\u548c\u5bf9\u8c61\uff08\u6570\u636e\uff09\u88ab \u5272\u88c2 \u5f00\u6765\uff0c\u4ed6\u4eec\u611a\u6627\u5730\u8ba4\u4e3a \u51fd\u6570\u4e0d\u662f\u5bf9\u8c61 \u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f \u5219\u8ba4\u4e3a\uff1a \u51fd\u6570\u4e5f\u662f\u4e00\u79cd\u53d8\u91cf\uff0c\u51fd\u6570\u53ef\u4ee5\u4f5c\u4e3a\u53e6\u4e00\u4e2a\u51fd\u6570\u7684\u53c2\u6570\uff01 Function lives matter! \u9762\u5411\u5bf9\u8c61\u5c31\u597d\u6bd4\u8ba1\u7b97\u673a\u7684\u201c\u54c8\u4f5b\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u548c\u6570\u636e\u5272\u88c2\uff0c\u4ee3\u7801\u53ea\u80fd\u5355\u65b9\u9762\u64cd\u4f5c\u6570\u636e\u3002\u51fd\u6570\u5f0f\u5c31\u597d\u6bd4\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\uff0c\u4ee3\u7801\u4e5f\u662f\u6570\u636e\u3002\u770b\u4f3c\u4f1a\u5bfc\u81f4\u4f4e\u6548\uff0c\u5b9e\u5219\u5927\u5927\u65b9\u4fbf\u4e86\u52a8\u6001\u52a0\u8f7d\u65b0\u7a0b\u5e8f\uff0c\u56e0\u800c\u73b0\u5728\u7684\u8ba1\u7b97\u673a\u57fa\u672c\u90fd\u91c7\u7528\u4e86\u201c\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\u201d\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff0c\u88ab\u4eb2\u5207\u5730\u5c0a\u79f0\u4e3a \u51fd\u6570\u5bf9\u8c61 \u3002","title":"\u51fd\u6570\u4e5f\u662f\u5bf9\u8c61\uff01"},{"location":"lambda/#c11-lambda","text":"C++98 \u65f6\u4ee3\uff0c\u4eba\u4eec\u8fd8\u9700\u8981\u5355\u72ec\u8dd1\u5230 main \u5916\u9762\uff0c\u4e13\u95e8\u5b9a\u4e49 add \u3001 mul \u3001 max \u51fd\u6570\u3002\u5f04\u5f97\u6574\u4e2a\u4ee3\u7801\u4e71\u54c4\u54c4\u7684\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int max(int a, int b) { return std::max(a, b); } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } C++11 \u5f15\u5165\u4e86 Lambda \u8868\u8fbe\u5f0f \u8bed\u6cd5\uff0c\u5141\u8bb8\u4f60\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002 int main() { std::vector a = {1, 2, 3, 4}; auto add = [](int a, int b) { return a + b; }; auto mul = [](int a, int b) { return a * b; }; auto max = [](int a, int b) { return std::max(a, b); }; generic_sum(a, add); generic_sum(a, product); generic_sum(a, max); return 0; } \u4e0d\u7528\u5f80 main \u5916\u9762\u585e\u5783\u573e\u4e86\uff0c\u4e00\u6e05\u723d\u3002 \u66f4\u8fdb\u4e00\u6b65\uff0c\u6211\u4eec\u751a\u81f3\u4e0d\u7528\u5b9a\u4e49\u53d8\u91cf\uff0c\u76f4\u63a5\u628a Lambda \u8868\u8fbe\u5f0f\u5199\u5728 generic_sum \u7684\u53c2\u6570\u91cc\u5c31\u884c\u4e86\uff01 int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); // ***\u6539*** return 0; } \u4ee5\u4e0a\u5199\u6cd5\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u8981\u652f\u6301\u4e00\u4e2a\u65b0\u64cd\u4f5c\uff0c\u53ea\u9700\u4fee\u6539\u4e00\u5904\u5730\u65b9\uff1a\u5728\u8c03\u7528 generic_sum \u65f6\u5c31\u5730\u521b\u5efa\u4e00\u4e2a\u51fd\u6570\u3002\u968f\u53eb\u968f\u5230\uff0c\u4e0d\u7528\u7ea0\u7ed3\u4e8e\u201c\u8d77\u540d\u5f3a\u8feb\u75c7\u201d\uff0c\u662f\u4e0d\u662f\u5f88\u65b9\u4fbf\u5462\uff1f \u51c6\u786e\u7684\u8bf4\uff0cLambda \u521b\u5efa\u7684\u662f\u51fd\u6570\u5bf9\u8c61 (function object) \u6216\u79f0\u4eff\u51fd\u6570 (functor) \u800c\u4e0d\u662f\u4f20\u7edf\u610f\u4e49\u4e0a\u7684\u51fd\u6570\u3002 \u5176\u5b9e C++98 \u65f6\u4ee3\u4eba\u4eec\u5c31\u5df2\u7ecf\u5927\u91cf\u5728\u7528 operator()() \u6a21\u62df\u51fd\u6570\u5bf9\u8c61\u4e86\uff0c\u8457\u540d\u7684\u7b2c\u4e09\u65b9\u5e93 Boost \u4e5f\u5c01\u88c5\u4e86\u5404\u79cd\u51fd\u6570\u5f0f\u5e38\u7528\u7684\u5bb9\u5668\u548c\u5de5\u5177\u3002C++11 \u624d\u7ec8\u4e8e\u628a \u51fd\u6570\u5bf9\u8c61 \u8fd9\u4e2a\u6982\u5ff5\u8f6c\u6b63\uff0c\u5e76\u5f15\u5165\u4e86\u66f4\u65b9\u4fbf\u7684 Lambda \u8bed\u6cd5\u7cd6\u3002 \u5373\u4f7f\u662f\u9762\u5411\u5bf9\u8c61\u7684\u5934\u53f7\u5b5d\u5b50 Java\uff0c\u4e5f\u5df2\u7ecf\u5f00\u59cb\u5f15\u5165\u51fd\u6570\u5f0f\u7684 Lambda \u8bed\u6cd5\u7cd6\uff0cC# \u7684 LINQ \u66f4\u662f\u660e\u76ee\u5f20\u80c6\u7684\u81f4\u656c map-reduce \u5168\u5bb6\u6876\uff0c\u751a\u81f3 C \u8bed\u8a00\u7528\u6237\u4e5f\u5f00\u59cb\u73a9\u5404\u79cd\u51fd\u6570\u6307\u9488\u56de\u8c03\u2026\u2026\u6ca1\u529e\u6cd5\uff0c\u51fd\u6570\u5f0f\u786e\u5b9e\u65b9\u4fbf\u5440\uff01","title":"C++11 \u5f15\u5165 Lambda \u8bed\u6cd5\u7cd6"},{"location":"lambda/#_13","text":"\u51fd\u6570\u5bf9\u8c61 op \u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\uff0c\u8ba9 generic_sum \u5185\u90e8\u53bb\u8c03\u7528\uff0c\u5c31\u50cf\u5f80 generic_sum \u4f53\u5185\u201c\u6ce8\u5165\u201d\u4e86\u4e00\u6bb5\u81ea\u5b9a\u4e49\u4ee3\u7801\u4e00\u6837\u3002 \u8fd9\u53ef\u4ee5\u8ba9 generic_sum \u5728\u4e0d\u4fee\u6539\u672c\u4f53\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7\u4fee\u6539\u201c\u6ce8\u5165\u201d\u90e8\u5206\uff0c\u8f7b\u677e\u6269\u5c55\uff0c\u6ee1\u8db3 \u5f00\u95ed\u539f\u5219 \u3002 \u66f4\u51c6\u786e\u7684\u8bf4\uff0c\u8fd9\u4f53\u73b0\u7684\u662f\u8bbe\u8ba1\u6a21\u5f0f\u6240\u8981\u6c42\u7684 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u3002 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219: \u4e00\u4e2a\u5c01\u88c5\u597d\u7684\u51fd\u6570\u6216\u7c7b\uff0c\u5e94\u8be5\u5c3d\u91cf\u4f9d\u8d56\u4e8e\u62bd\u8c61\u63a5\u53e3\uff0c\u800c\u4e0d\u662f\u4f9d\u8d56\u4e8e\u5177\u4f53\u5b9e\u73b0\u3002\u8fd9\u53ef\u4ee5\u63d0\u9ad8\u7a0b\u5e8f\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u56db\u5927\u7f16\u7a0b\u8303\u5f0f\u90fd\u5404\u81ea\u53d1\u5c55\u51fa\u4e86 \u4f9d\u8d56\u6ce8\u5165\u539f\u5219 \u7684\u89e3\u51b3\u65b9\u6848\uff1a \u9762\u5411\u8fc7\u7a0b\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u6307\u9488 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u865a\u51fd\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u51fd\u6570\u5bf9\u8c61 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u6a21\u677f\u5143\u7f16\u7a0b\u8303\u5f0f\u4e2d\uff0c \u6a21\u677f\u53c2\u6570 \u5c31\u662f\u90a3\u4e2a\u62bd\u8c61\u63a5\u53e3\u3002 \u540c\u6837\u662f\u628a\u62bd\u8c61\u63a5\u53e3\u4f5c\u4e3a\u53c2\u6570\uff0c\u540c\u6837\u89e3\u51b3\u53ef\u6269\u5c55\u95ee\u9898\u3002 \u51fd\u6570\u6307\u9488\u8d34\u8fd1\u5e95\u5c42\u786c\u4ef6\uff0c\u865a\u51fd\u6570\u65b9\u4fbf\u6574\u5408\u591a\u4e2a\u63a5\u53e3\uff0c\u51fd\u6570\u5bf9\u8c61\u8f7b\u91cf\u7ea7\u3001\u968f\u5730\u53d6\u7528\uff0c\u6a21\u677f\u5143\u6709\u52a9\u9ad8\u6027\u80fd\u4f18\u5316\uff0c\u4e0d\u540c\u7684\u7f16\u7a0b\u8303\u5f0f\u6b8a\u9014\u540c\u5f52\u3002","title":"\u4f9d\u8d56\u6ce8\u5165\u539f\u5219"},{"location":"lambda/#_14","text":"\u4f9d\u8d56\u6ce8\u5165\u539f\u5219\u53ef\u4ee5\u51cf\u5c11\u4ee3\u7801\u4e4b\u95f4\u7684\u8026\u5408\u5ea6\uff0c\u5927\u5927\u63d0\u9ad8\u4ee3\u7801\u7684\u7075\u6d3b\u6027\u548c\u53ef\u6269\u5c55\u6027\u3002 \u8026\u5408\u5ea6: \u6307\u7684\u662f\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u548c\u5176\u4ed6\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u8026\u5408\u5ea6\u8d8a\u4f4e\uff0c\u8d8a\u5bb9\u6613\u8fdb\u884c\u5355\u5143\u6d4b\u8bd5\u3001\u91cd\u6784\u3001\u590d\u7528\u548c\u6269\u5c55\u3002 \u9ad8\u8026\u5408\u5ea6\u7684\u5178\u578b\u662f\u201c\u7275\u4e00\u53d1\u800c\u52a8\u5168\u8eab\u201d\u3002\u4f4e\u8026\u5408\u7684\u5178\u8303\u662f\u86af\u8693\uff0c\u56e0\u4e3a\u86af\u8693\u53ef\u4ee5\u5728\u4efb\u610f\u65ad\u9762\u5207\u5f00\uff0c\u8fd8\u80fd\u6d3b\u4e0b\u6765\uff0c\u770b\u6765\u86af\u8693\u7684\u8eab\u4f53\u8bbe\u8ba1\u975e\u5e38\u201c\u6a21\u5757\u5316\u201d\u5462\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u8f6f\u4ef6\u5e94\u5f53\u8ffd\u6c42\u4f4e\u8026\u5408\u5ea6\uff0c\u9002\u5ea6\u89e3\u8026\u7684\u8f6f\u4ef6\u80fd\u66f4\u5feb\u9002\u5e94\u9700\u6c42\u53d8\u5316\u3002\u4f46\u8fc7\u5ea6\u7684\u4f4e\u8026\u5408\u4e5f\u4f1a\u5bfc\u81f4\u4ee3\u7801\u8fc7\u4e8e\u5206\u6563\uff0c\u4e0d\u6613\u9605\u8bfb\u548c\u4fee\u6539\uff0c\u751a\u81f3\u53ef\u80fd\u8d77\u5230\u53cd\u6548\u679c\u3002 \u82e5\u4f60\u89e3\u8026\u540e\uff0c\u6bcf\u6b21\u9700\u6c42\u53d8\u5316\u8981\u6539\u52a8\u7684\u5730\u65b9\u53d8\u5c11\u4e86\uff0c\u90a3\u5c31\u662f\u5408\u7406\u7684\u89e3\u8026\u3002\u82e5\u4f60\u8fc7\u5206\u89e3\u8026\uff0c\u4ee3\u7801\u4e1c\u4e00\u5757\u897f\u4e00\u5757\uff0c\u4ee5\u81f3\u4e8e\u9700\u6c42\u53d8\u5316\u65f6\u9700\u8981\u5230\u5904\u6539\uff0c\u6bd4\u4e0d\u89e3\u8026\u65f6\u6d6a\u8d39\u7684\u65f6\u95f4\u8fd8\u8981\u591a\uff0c\u90a3\u5c31\u662f\u89e3\u8026\u8fc7\u5ea6\u3002 \u5b8c\u5168\u96f6\u8026\u5408\u7684\u7a0b\u5e8f\u6bcf\u4e2a\u51fd\u6570\u4e92\u4e0d\u8054\u7cfb\uff0c\u5c31\u50cf\u628a\u86af\u8693\u62c6\u6563\u6210\u4e00\u4e2a\u4e2a\u72ec\u7acb\u7684\u7ec6\u80de\u4e00\u6837\u3002\u8fde\u521d\u59cb\u9700\u6c42\u201c\u6d3b\u7740\u201d\u90fd\u5b9e\u73b0\u4e0d\u4e86\uff0c\u8c08\u4f55\u9002\u5e94\u9700\u6c42\u53d8\u5316\uff1f\u6240\u4ee5\u89e3\u8026\u4e5f\u5207\u52ff\u77eb\u6789\u8fc7\u6b63\u3002 \u4e3a\u4e86\u907f\u514d\u89e3\u8026\u77eb\u6789\u8fc7\u6b63\uff0c\u4eba\u4eec\u53c8\u63d0\u51fa\u4e86\u5185\u805a\u7684\u6982\u5ff5\uff0c\u5e76\u89c4\u5b9a\u89e3\u8026\u7684\u524d\u63d0\u662f\uff1a\u4e0d\u803d\u8bef\u5185\u805a\u3002\u803d\u8bef\u5230\u5185\u805a\u7684\u89e3\u8026\uff0c\u5c31\u53ea\u4f1a\u8d77\u5230\u964d\u4f4e\u53ef\u7ef4\u62a4\u6027\u7684\u53cd\u6548\u679c\u4e86\u3002 \u5185\u805a: \u6307\u7684\u662f\u540c\u4e00\u4e2a\u6a21\u5757\u3001\u7c7b\u3001\u51fd\u6570\u5185\u90e8\u5404\u4e2a\u5143\u7d20\u4e4b\u95f4\u7684\u5173\u8054\u7a0b\u5ea6\u3002\u5185\u805a\u5ea6\u8d8a\u9ad8\uff0c\u529f\u80fd\u8d8a\u72ec\u7acb\uff0c\u8d8a\u65b9\u4fbf\u96c6\u4e2d\u7ef4\u62a4\u3002 \u4f8b\u5982\uff0c\u4eba\u7684\u5fc3\u810f\u4e13\u95e8\u8d1f\u8d23\u6cf5\u8840\uff0c\u809d\u810f\u53ea\u8d1f\u8d23\u89e3\u6bd2\uff0c\u8fd9\u5c31\u662f\u9ad8\u5185\u805a\u7684\u4eba\u4f53\u5668\u5b98\u3002\u82e5\u4eba\u7684\u5fc3\u810f\u8fd8\u8981\u517c\u804c\u89e3\u6bd2\uff0c\u809d\u810f\u8fd8\u517c\u804c\u6cf5\u8840\uff0c\u770b\u4f3c\u597d\u50cf\u662f\u589e\u52a0\u4e86\u201c\u4e07\u4e00\u5fc3\u810f\u574f\u6389\u201d\u7684\u5197\u4f59\u6027\uff0c\u5b9e\u9645\u4e0a\u628a\u201c\u6cf5\u8840\u201d\u8fd9\u4e00\u529f\u80fd\u62c6\u6563\u5230\u5404\u5730\uff0c\u65e0\u6cd5\u201c\u96c6\u4e2d\u529b\u91cf\u6cf5\u5927\u8840\u201d\u4e86\u3002 \u4eba\u7c7b\u7684\u5927\u8111\u548c CPU \u4e00\u6837\uff0c\u4e5f\u6709\u201c\u7f13\u5b58\u5c40\u57df\u6027 (cache-locality)\u201d\u7684\u9650\u5236\uff1a\u4e0d\u80fd\u540c\u65f6\u5728\u5f88\u591a\u4e2a\u4e3b\u9898\u4e4b\u95f4\u5feb\u901f\u5207\u6362\uff0c\u65e0\u8bba\u662f\u65f6\u95f4\u4e0a\u7684\u8fd8\u662f\u7a7a\u95f4\u4e0a\u7684\u5272\u88c2 (cache-miss)\uff0c\u90fd\u4f1a\u5e72\u6270\u7a0b\u5e8f\u5458\u601d\u7ef4\u7684\u8fde\u8d2f\u6027\uff0c\u4ece\u800c\u589e\u5927\u5fc3\u667a\u8d1f\u62c5\u3002 \u597d\u7684\u8f6f\u4ef6\u8981\u4fdd\u6301\u4f4e\u8026\u5408\uff0c\u540c\u65f6\u9ad8\u5185\u805a\u3002 \u5c31\u50cf\u201c\u6c11\u4e3b\u96c6\u4e2d\u5236\u201d\u4e00\u6837\uff0c\u65e2\u8981\u76d1\u7763\u9632\u6b62\u5927\u6743\u72ec\u63fd\uff0c\u53c8\u8981\u96c6\u4e2d\u529b\u91cf\u529e\u4e00\u4e2a\u4eba\u529e\u4e0d\u6210\u7684\u5927\u4e8b\u3002","title":"\u4f4e\u8026\u5408\uff0c\u9ad8\u5185\u805a"},{"location":"lambda/#_15","text":"\u4f20\u7edf\u7684\u9762\u5411\u5bf9\u8c61\u540c\u6837\u53ef\u4ee5\u7528 \u865a\u51fd\u6570\u63a5\u53e3\u7c7b \u6a21\u62df \u51fd\u6570\u5bf9\u8c61 \u4e00\u6837\u7684\u529f\u80fd\uff0c\u53ea\u4e0d\u8fc7\u6ca1\u6709 lambda \u548c\u95ed\u5305\u7684\u8bed\u6cd5\u52a0\u6301\uff0c\u5199\u8d77\u6765\u975e\u5e38\u7e41\u7410\uff0c\u5c31\u548c\u5728 C \u8bed\u8a00\u91cc\u201c\u6a21\u62df\u201d\u9762\u5411\u5bf9\u8c61\u4e00\u6837\u3002 \u4e3a\u4e86\u8fd9\u4e48\u5c0f\u7684\u4e00\u4e2a\u4ee3\u7801\u5757\uff0c\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u7c7b\uff0c\u5c31\u50cf\u5988\u5988\u5f00\u4e00\u67b6\u201c\u7a7a\u4e2d\u6218\u8f66\u201d A380 \u53ea\u662f\u4e3a\u4e86\u63a5\u4f60\u653e\u5b66\u4e00\u6837\uff0c\u7b49\u4f60\u503c\u597d\u673a\u7684\u65f6\u95f4\u6211\u81ea\u5df1\u8d70\u90fd\u8d70\u5230\u4e86\u3002\u800c\u51fd\u6570\u5f0f\u4e2d\uff0c\u7528 lambda \u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u76f8\u5f53\u4e8e\u968f\u5730\u6293\u6765\u4e00\u53f0\u5171\u4eab\u5355\u8f66\u5f00\u8d70\u3002 struct OpBase { // \u9762\u5411\u5bf9\u8c61\uff1a\u9047\u4e8b\u4e0d\u51b3\u5148\u5b9a\u4e49\u63a5\u53e3\u2026\u2026 virtual int compute(int a, int b) = 0; virtual ~OpBase() = default; }; struct OpAdd : OpBase { int compute(int a, int b) override { return a + b; } }; struct OpMul : OpBase { int compute(int a, int b) override { return a * b; } }; struct OpMax : OpBase { int compute(int a, int b) override { return std::max(a, b); } }; int generic_sum(std::vector const &v, OpBase *op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op->compute(ret, v[i]); // \u5199\u8d77\u6765\u4e5f\u9ebb\u70e6\uff0c\u9700\u8981\u8c03\u7528\u4ed6\u7684\u6210\u5458\u51fd\u6570\uff0c\u6210\u5458\u51fd\u6570\u53c8\u8981\u8d77\u540d\u2026\u2026 } delete op; return ret; } int main() { std::vector a = {1, 2, 3, 4}; generic_sum(a, new OpAdd()); generic_sum(a, new OpMul()); generic_sum(a, new OpMax()); return 0; } \u4e0d\u4ec5\u9700\u8981\u5b9a\u4e49\u4e00\u5806\u7c7b\uff0c\u63a5\u53e3\u7c7b\uff0c\u5b9e\u73b0\u7c7b\uff0c\u7ee7\u627f\u6765\u7ee7\u627f\u53bb\uff0c\u8fd8\u9700\u8981\u7ba1\u7406\u8ba8\u538c\u7684\u6307\u9488\uff0c\u4ee3\u7801\u91cf\u7ffb\u500d\uff0c\u6ca1\u4ec0\u4e48\u53ef\u8bfb\u6027\uff0c\u53c8\u5f71\u54cd\u8fd0\u884c\u6548\u7387\u3002 3 \u5e74 2 \u73ed\u5c0f\u5f6d\u540c\u5b66\uff0c\u4f60\u7684\u5988\u5988\u5f00\u7740 A380 \u6765\u63a5\u4f60\u4e86\u3002 \u800c\u73b0\u4ee3 C++ \u53ea\u9700 Lambda \u8bed\u6cd5\u5c31\u5730\u5b9a\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u723d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); });","title":"\u4e0e\u4f20\u7edf\u9762\u5411\u5bf9\u8c61\u7684\u5bf9\u6bd4"},{"location":"lambda/#_16","text":"\u521a\u521a\uff0c\u6211\u4eec\u7684\u5b9e\u73b0\u7528\u4e86 auto op \u505a\u53c2\u6570\uff0c\u8fd9\u7b49\u4ef7\u4e8e\u8ba9 generic_sum \u53d8\u6210\u4e00\u4e2a\u6a21\u677f\u51fd\u6570\u3002 int generic_sum(std::vector const &v, auto op); // \u4e0d\u652f\u6301 C++20 \u65f6\u7684\u66ff\u4ee3\u5199\u6cd5\uff1a template int generic_sum(std::vector const &v, Op op); \u8fd9\u610f\u5473\u7740\u6bcf\u5f53\u7528\u6237\u6307\u5b9a\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff08lambda\uff09\u65f6\uff0c generic_sum \u90fd\u4f1a\u91cd\u65b0\u5b9e\u4f8b\u5316\u4e00\u904d\u3002 generic_sum(a, [](int a, int b) { return a + b; }); generic_sum(a, [](int a, int b) { return a * b; }); generic_sum(a, [](int a, int b) { return std::max(a, b); }); \u7f16\u8bd1\u540e\uff0c\u4f1a\u53d8\u6210\u7c7b\u4f3c\u4e8e\u8fd9\u6837\uff1a generic_sum(a); generic_sum(a); generic_sum(a); \u4f1a\u751f\u6210\u4e09\u4efd\u51fd\u6570\uff0c\u6bcf\u4e2a\u90fd\u662f\u72ec\u7acb\u7f16\u8bd1\u7684\uff1a int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = add(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = mul(ret, v[i]); } return ret; } int generic_sum(std::vector const &v) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = max(ret, v[i]); } return ret; } \u8fd9\u5141\u8bb8\u7f16\u8bd1\u5668\u4e3a\u6bcf\u4e2a\u7248\u672c\u7684 generic_sum \u5355\u72ec\u505a\u4f18\u5316\uff0c\u91cf\u8eab\u5b9a\u5236\u6700\u4f18\u7684\u4ee3\u7801\u3002 \u4f8b\u5982 add \u8fd9\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u56e0\u4e3a\u53ea\u5728 generic_sum \u4e2d\u4f7f\u7528\u4e86\uff0c\u4f1a\u88ab\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u5185\u8054\uff0c\u4e0d\u4f1a\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u548c\u8df3\u8f6c\u7684\u6307\u4ee4\uff0c\u5404\u81ea\u4f18\u5316\u6210\u5355\u72ec\u4e00\u6761\u52a0\u6cd5 / \u4e58\u6cd5 / \u6700\u5927\u503c\u6307\u4ee4\u7b49\u3002 \u6bd4\u5982\uff0c\u7f16\u8bd1\u5668\u4f1a\u68c0\u6d4b\u5230 += \u53ef\u4ee5\u77e2\u91cf\u5316\uff0c\u4e8e\u662f\u7528 _mm_add_epi32 \u66ff\u4ee3\u4e86\u3002\u540c\u7406\uff0cmul \u5219\u7528 _mm_mullo_epi32 \u66ff\u4ee3\uff0cmax \u5219\u7528 _mm_max_epi32 \u66ff\u4ee3\u7b49\uff0c\u5404\u81ea\u5206\u522b\u751f\u6210\u4e86\u5404\u81ea\u7248\u672c\u6700\u4f18\u7684\u4ee3\u7801\u3002\u800c\u5982\u679c\u662f\u666e\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u4e0d\u4f1a\u751f\u6210\u4e09\u4efd\u91cf\u8eab\u5b9a\u505a\u7684\u5b9e\u4f8b\uff0c\u65e0\u6cd5\u77e2\u91cf\u5316\uff08\u6709\u4e00\u79cd\u4f8b\u5916\uff0c\u5c31\u662f\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u4e86 generic_sum \u4f3c\u4e4e\u53ea\u6709\u8fd9\u4e09\u79cd\u53ef\u80fd\u53c2\u6570\uff0c\u7136\u540e\u505a\u4e86 IPO \u4f18\u5316\uff0c\u4f46\u5e76\u4e0d\u5982\u6a21\u677f\u5b9e\u4f8b\u5316\u4e00\u6837\u7a33\u5b9a\u5f3a\u5236\uff09\u3002 \u4e3a\u4e09\u79cd\u4e0d\u540c\u7684 op \u53c2\u6570\u5206\u522b\u5b9a\u505a\u4e09\u4efd\u3002\u867d\u7136\u589e\u52a0\u4e86\u7f16\u8bd1\u65f6\u95f4\uff0c\u81a8\u80c0\u4e86\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u4f53\u79ef\uff1b\u4f46\u751f\u6210\u7684\u673a\u5668\u7801\u662f\u5206\u522b\u9488\u5bf9\u6bcf\u79cd\u7279\u4f8b\u4e00\u5bf9\u4e00\u6df1\u5ea6\u4f18\u5316\u7684\uff0c\u66f4\u9ad8\u6548\u3002 \u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\uff08gemm\uff09\u7684\u6700\u4f18\u7b97\u6cd5\uff0c\u5bf9\u4e8e\u4e0d\u540c\u7684\u77e9\u9635\u5927\u5c0f\u548c\u5f62\u72b6\u662f\u4e0d\u540c\u7684\u3002\u8457\u540d\u7684\u7ebf\u6027\u4ee3\u6570\u5e93 CUBLAS \u548c MKL \u4e2d\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u7528\u6237\u8f93\u5165\u7684\u77e9\u9635\u5f62\u72b6\uff0c\u9009\u53d6\u6700\u4f18\u7684\u7b97\u6cd5\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cCUBLAS \u5e93\u91cc\u5176\u5b9e\u5b58\u7740\u9002\u5408\u5404\u79cd\u77e9\u9635\u5927\u5c0f\u6392\u5217\u7ec4\u5408\u7684\u7b97\u6cd5\u4ee3\u7801\uff08\u4ee5 fatbin \u683c\u5f0f\u5b58\u50a8\u5728\u4e8c\u8fdb\u5236\u4e2d\uff09\u3002\u5f53\u8c03\u7528\u77e9\u9635\u4e58\u6cd5\u65f6\uff0c\u81ea\u52a8\u67e5\u5230\u6700\u9002\u5408\u7684\u4e00\u7248\u6765\u8c03\u7528\u7ed9\u4f60\u3002\u7c7b\u4f3c gemm\uff0c\u8fd8\u6709 gemv\u3001spmv\u2026\u2026\u6240\u6709\u7684\u77e9\u9635\u8fd0\u7b97 API \u90fd\u7ecf\u5386\u4e86\u8fd9\u6837\u7684\u201c\u7f16\u8bd1\u671f\u201d\u66b4\u529b\u6392\u5217\u7ec4\u5408\uff0c\u53ea\u4e3a\u201c\u8fd0\u884c\u65f6\u201d\u91ca\u653e\u6700\u5927\u6027\u80fd\uff01\u8fd9\u4e5f\u5bfc\u81f4\u7f16\u8bd1\u597d\u7684 cublas.dll \u6587\u4ef6\u6765\u5230\u4e86\u6050\u6016\u7684 20 MB \u5de6\u53f3\uff0c\u800c\u6211\u4eec\u79f0\u4e4b\u4e3a\u9ad8\u6548\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u5728\u6a21\u677f\u52a0\u6301\u4e0b\u9759\u6001\u5206\u53d1"},{"location":"lambda/#function","text":"Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u6bcf\u4e2a Lambda \u8868\u8fbe\u5f0f\u90fd\u4f1a\u521b\u5efa\u4e00\u4e2a\u5168\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\u7c7b\u578b\uff0c\u8fd9\u4f7f\u5f97 generic_sum \u5bf9\u4e8e\u6bcf\u4e2a\u4e0d\u540c\u7684 Lambda \u90fd\u4f1a\u5b9e\u4f8b\u5316\u4e00\u904d\u3002\u867d\u7136\u6709\u5229\u4e8e\u6027\u80fd\u4f18\u5316\uff0c\u4f46\u4e5f\u5f71\u54cd\u4e86\u7f16\u8bd1\u901f\u5ea6\u548c\u7075\u6d3b\u6027\u3002 \u901a\u5e38\uff0c\u6211\u4eec\u53ea\u80fd\u901a\u8fc7 decltype(add) \u83b7\u53d6 add \u8fd9\u4e2a Lambda \u5bf9\u8c61\u7684\u7c7b\u578b\u3002\u4e5f\u53ea\u80fd\u901a\u8fc7 auto \u6765\u6355\u83b7 Lambda \u5bf9\u8c61\u4e3a\u53d8\u91cf\u3002 \u4e3a\u6b64\uff0c\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::function \u5bb9\u5668\uff0c\u4ed6\u80fd\u5bb9\u7eb3\u4efb\u4f55\u51fd\u6570\u5bf9\u8c61\uff01\u65e0\u8bba\u662f\u533f\u540d\u7684 Lambda \u51fd\u6570\u5bf9\u8c61\uff0c\u8fd8\u662f\u666e\u666e\u901a\u901a\u7684\u51fd\u6570\u6307\u9488\uff0c\u90fd\u80fd\u7eb3\u5165 std::function \u7684\u4f53\u5185\u3002 \u552f\u4e00\u7684\u4ee3\u4ef7\u662f\uff0c\u4f60\u9700\u8981\u6307\u5b9a\u51fa\u6240\u6709\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u53c2\u6570\u4e3a\u4e24\u4e2a int \uff0c\u8fd4\u56de int \u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u7528 std::function \u5bb9\u5668\u5b58\u50a8\u3002 auto add_lambda = [](int a, int b) { // Lambda \u51fd\u6570\u5bf9\u8c61 return a + b; }; struct AddClass { int operator()(int a, int b) { // \u81ea\u5b9a\u4e49\u7c7b\u6a21\u62df\u51fd\u6570\u5bf9\u8c61 return a + b; } }; AddClass add_object; int add_regular_func(int a, int b) { // \u666e\u901a\u51fd\u6570 return a + b; } std::function add; // \u6240\u6709\u5e7f\u4e49\u51fd\u6570\u5bf9\u8c61\uff0c\u7edf\u7edf\u63a5\u7eb3 add = add_lambda; // OK add = add_object; // OK add = add_regular_func; // OK int generic_sum(std::vector const &v, std::function op) { int ret = v[0]; for (int i = 1; i < v.size(); ++i) { ret = op(ret, v[i]); // \u5199\u8d77\u6765\u548c\u6a21\u677f\u4f20\u53c2\u65f6\u4e00\u6837\u65e0\u611f } // \u65e0\u9700\u6307\u9488\uff0c\u65e0\u9700 delete\uff0cfunction \u80fd\u81ea\u52a8\u7ba1\u7406\u51fd\u6570\u5bf9\u8c61\u751f\u547d\u5468\u671f return ret; } \u5982\u679c\u8fd8\u60f3\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u53c2\u6570\u548c\u8fd4\u56de\u503c\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b std::function \u3002\u8fd9\u91cc std::any \u662f\u4e2a\u8d85\u7ea7\u4e07\u80fd\u5bb9\u5668\uff0c\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u4f55\u5bf9\u8c61\uff0c\u4ed6\u548c std::function \u4e00\u6837\u90fd\u91c7\u7528\u4e86\u201c\u7c7b\u578b\u64e6\u9664 (type-erasure)\u201d\u6280\u672f\uff0c\u7f3a\u70b9\u662f\u5fc5\u987b\u914d\u5408 std::any_cast \u624d\u80fd\u53d6\u51fa\u4f7f\u7528\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u8fdb\u9636\u4e13\u9898\u4e2d\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u4ed6\u4eec\u7684\u539f\u7406\uff0c\u5e76\u5e26\u4f60\u81ea\u5df1\u505a\u4e00\u4e2a\u64e6\u52a0\u6cd5\u7684\u7c7b\u578b\u64e6\u9664\u5bb9\u5668\u3002 \u51fd\u6570\u5f0f\u7f16\u7a0b\uff0c\u80fd\u5728\u9759\u6001\u4e0e\u52a8\u6001\u4e4b\u95f4\u8f7b\u677e\u5207\u6362\uff0c \u9ad8\u6027\u80fd \u4e0e \u7075\u6d3b\u6027 \u4efb\u541b\u9009\u62e9\u3002 \u5728\u9700\u8981\u6027\u80fd\u7684 \u74f6\u9888\u4ee3\u7801 \u4e2d\u7528\u6a21\u677f\u4f20\u53c2\uff0c\u7f16\u8bd1\u671f\u9759\u6001\u5206\u53d1\uff0c\u591a\u6b21\u91cf\u8eab\u5b9a\u505a\uff0c\u63d0\u9ad8\u8fd0\u884c\u65f6\u6027\u80fd\u3002 \u74f6\u9888\u4ee3\u7801: \u5f80\u5f80\u4e00\u4e2a\u7a0b\u5e8f 80% \u7684\u65f6\u95f4\u82b1\u5728 20% \u7684\u4ee3\u7801\u4e0a\u3002\u8fd9 20% \u662f\u5728\u7a0b\u5e8f\u4e2d\u9891\u7e41\u6267\u884c\u7684\u3001\u8ba1\u7b97\u91cf\u5927\u7684\u3001\u6216\u8005\u8c03\u7528\u7279\u522b\u8017\u65f6\u7684\u51fd\u6570\u3002\u9488\u5bf9\u8fd9\u90e8\u5206\u74f6\u9888\u4ee3\u7801\u4f18\u5316\u5373\u53ef\uff0c\u800c\u5269\u4f59\u7684 80% \u6253\u9171\u6cb9\u4ee3\u7801\uff0c\u5927\u53ef\u4ee5\u600e\u4e48\u65b9\u4fbf\u600e\u4e48\u5199\u3002 \u5728\u6027\u80fd\u65e0\u5173\u7d27\u8981\u7684\u9876\u5c42\u4e1a\u52a1\u903b\u8f91\u4e2d\u7528 function \u5bb9\u5668\u4f20\u53c2\uff0c\u8fd0\u884c\u65f6\u52a8\u6001\u5206\u53d1\uff0c\u8282\u7701\u7f16\u8bd1\u4f53\u79ef\uff0c\u65b9\u4fbf\u6301\u4e45\u5b58\u50a8\uff0c\u7075\u6d3b\u6613\u7528\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 generic_sum \u51fd\u6570\uff0c\u5982\u679c\u6211\u4eec\u7a81\u7136\u60f3\u8981\u9ad8\u6027\u80fd\u4e86\uff0c\u53ea\u9700\u628a std::function op \u8f7b\u8f7b\u6539\u4e3a auto op \u5c31\u8f7b\u677e\u5207\u6362\u5230\u9759\u6001\u5206\u53d1\u6a21\u5f0f\u4e86\u3002 \u800c\u865a\u51fd\u6570\u4e00\u65e6\u7528\u4e86\uff0c\u57fa\u672c\u5c31\u53ea\u80fd\u52a8\u6001\u5206\u53d1\u4e86\uff0c\u5373\u4f7f\u80fd\u88ab IPO \u4f18\u5316\u6389\uff0c\u865a\u8868\u6307\u9488\u4e5f\u6c38\u8fdc\u5360\u636e\u7740\u4e00\u4e2a 8 \u5b57\u8282\u7684\u7a7a\u95f4\uff0c\u4e14\u6c38\u8fdc\u53ea\u80fd\u4ee5\u6307\u9488\u5f62\u5f0f\u4f20\u6765\u4f20\u53bb\u3002 \u4e00\u79cd\u9759\u6001\u5206\u53d1\u7248\u7684\u865a\u51fd\u6570\u66ff\u4ee3\u54c1\u662f CRTP\uff0c\u4ed6\u57fa\u4e8e\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u4f46\u4e0e\u865a\u51fd\u6570\u4e4b\u95f4\u5207\u6362\u56f0\u96be\uff0c\u4e0d\u50cf\u51fd\u6570\u5bf9\u8c61\u90a3\u4e48\u65e0\u611f\uff0c\u4e4b\u540e\u7684\u6a21\u677f\u5143\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u4e5f\u53ef\u5728 function \u5bb9\u5668\u4e2d\u52a8\u6001\u5206\u53d1"},{"location":"lambda/#_17","text":"\u4e3b\u7ebf\u7a0b\u4e0d\u65ad\u5730\u5411\u5de5\u4f5c\u8005\u7ebf\u7a0b\u53d1\u9001\u51fd\u6570\u5bf9\u8c61\uff0c\u4ee4\u5176\u4ee3\u4e3a\u6267\u884c\uff1a mt_queue> task_queue; void main_thread() { task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a11\"); }); task_queue.push([] { fmt::println(\"\u6b63\u5728\u6267\u884c\u4efb\u52a12\"); }); } void worker_thread() { while (true) { auto task = task_queue.pop(); task(); } } mt_queue \u662f\u5c0f\u5f6d\u8001\u5e08\u5c01\u88c5\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u7684\u6d88\u606f\u961f\u5217\uff0c\u5b9e\u73b0\u539f\u7406\u4f1a\u5728\u7a0d\u540e\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4e2d\u8be6\u7ec6\u8bb2\u89e3\u3002","title":"\u6848\u4f8b\uff1a\u51fd\u6570\u5bf9\u8c61\u7684\u52a8\u6001\u5206\u53d1\u7528\u4e8e\u591a\u7ebf\u7a0b\u4efb\u52a1\u961f\u5217"},{"location":"lambda/#_18","text":"\u95ed\u5305\u662f\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff0c\u4ed6\u5141\u8bb8\u51fd\u6570\u5bf9\u8c61\u6355\u83b7\u5916\u90e8\u53d8\u91cf\uff0c\u5e76\u5728\u51fd\u6570\u5bf9\u8c61\u5185\u90e8\u4f7f\u7528\u8fd9\u4e9b\u53d8\u91cf\u3002 int x = 10; auto add_x = [x](int a) { return a + x; }; fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 \u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u52a0\u4e0a mutable \u4fee\u9970\uff0c\u89c1\u540e\u6587\u3002","title":"\u51fd\u6570\u5bf9\u8c61\u7684\u91cd\u8981\u673a\u5236\uff1a\u95ed\u5305"},{"location":"lambda/#_19","text":"Lambda \u51fd\u6570\u5bf9\u8c61\u7684\u95ed\u5305\u8bed\u6cd5\uff1a int x = 10; auto add_x = [x](int a) { return a + x; }; \u5b9e\u9645\u4e0a\u7b49\u4ef7\u4e8e\u4e00\u4e2a\u5e26\u6709 operator() \u6210\u5458\u51fd\u6570\u7684\u7ed3\u6784\u4f53\uff1a struct Lambda { int x; Lambda(int val) : x(val) {} int operator() (int a) const { return a + x; } }; int main() { int x = 10; Lambda add_x(x); fmt::println(\"{}\", add_x(5)); // \u8f93\u51fa 15 return 0; } \u76f8\u5f53\u4e8e\u6211\u4eec\u5199\u7684 lambda \u51fd\u6570\u4f53\uff0c\u5b9e\u9645\u4e0a\u88ab\u7f16\u8bd1\u5668\u79fb\u5230\u4e86 Lambda \u7c7b\u7684 operator() \u6210\u5458\u51fd\u6570\u4f53\u5185\u3002 \u800c\u4e14\u8fd9\u7ed3\u6784\u4f53\u662f\u533f\u540d\u7684\uff0c\u6ca1\u6709\u786e\u5b9a\u7684\u540d\u5b57\uff0c\u6b64\u5904\u7c7b\u540d Lambda \u53ea\u662f\u793a\u610f\uff0c\u56e0\u800c\u5e73\u65f6\u53ea\u80fd\u901a\u8fc7 auto \u4fdd\u5b58\u5373\u65f6\u521b\u5efa\u7684 lambda \u5bf9\u8c61\u3002 \u800c\u6240\u8c13\u7684\u95ed\u5305\u6355\u83b7\u53d8\u91cf\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u8fd9\u4e2a\u7ed3\u6784\u4f53\u7684\u6210\u5458\uff01 \u6309\u503c\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u91cc\u62f7\u8d1d\u4e86\u4e00\u4efd\u540c\u540d\u7684\u6210\u5458\uff1b\u5982\u679c\u662f\u5f15\u7528\u6355\u83b7\uff0c\u5c31\u76f8\u5f53\u4e8e\u7ed3\u6784\u4f53\u91cc\u7684\u6210\u5458\u662f\u4e2a\u5f15\u7528\u3002 \u53ef\u4ee5\u5728 https://cppinsights.io \u8fd9\u4e2a\u7f51\u7ad9\uff0c\u81ea\u52a8\u62c6\u89e3\u5305\u62ec Lambda \u5728\u5185\u7684\u6240\u6709\u73b0\u4ee3 C++ \u8bed\u6cd5\u7cd6\u4e3a\u539f\u59cb\u7684\u7ed3\u6784\u4f53\u548c\u51fd\u6570\u3002\u66f4\u591a\u597d\u7528\u7684\u5de5\u5177\u7f51\u7ad9\u53ef\u4ee5\u770b\u6211\u4eec \u5de5\u5177\u548c\u9879\u76ee\u63a8\u8350 \u4e13\u9898\u7ae0\u8282\u3002 \u5bf9\u4e8e\u5f15\u7528\uff0c\u5219\u662f\u7b49\u4ef7\u4e8e\u7ed3\u6784\u4f53\u6210\u5458\u4e2d\u542b\u6709\u4e00\u4efd\u5f15\u7528\u4f5c\u4e3a\u6210\u5458\uff1a int x = 10; auto inc_x = [&x](int a) { return x++; }; struct Lambda { int &x; Lambda(int &val) : x(val) {} int operator() () const { return x++; } }; int main() { int x = 10; Lambda inc_x(x); fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 10 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 11 fmt::println(\"{}\", inc_x()); // \u8f93\u51fa 12 fmt::println(\"{}\", x); // \u8f93\u51fa 13 return 0; }","title":"\u95ed\u5305\u7684\u672c\u8d28\u662f\u8bed\u6cd5\u7cd6"},{"location":"lambda/#operator","text":"\u533f\u540d lambda \u5bf9\u8c61\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u7684\u7c7b\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); \u5f88\u591a\u540c\u5b66\u90fd\u5206\u4e0d\u6e05 operator operator() opeartor()() \uff0c\u8fd9\u4e2a\u62ec\u53f7\u786e\u5b9e\u5f88\u6709\u8ff7\u60d1\u6027\uff0c\u4eca\u5929\u6211\u6765\u89e3\u91ca\u4e00\u4e0b\u3002 \u4f60\u73b0\u5728\uff0c\u628a\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\uff0c\u6539\u6210\u8fd9\u6837\uff1a struct Lambda { int call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.call(2); \u662f\u4e0d\u662f\u5f88\u5bb9\u6613\u770b\u61c2\uff1f\u8fd9\u5c31\u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u6210\u5458\u51fd\u6570 call \uff0c\u7136\u540e\u8c03\u7528\u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u73b0\u5728\uff0c\u8fdb\u4e00\u6b65\u6539\u6210\uff1a struct Lambda { int operator_call (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator_call(2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f\u8fd9\u5c31\u662f\u628a\u51fd\u6570\u540d\u6539\u6210\u4e86 operator_call \uff0c\u4f9d\u7136\u662f\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u3002 \u91cd\u70b9\u6765\u4e86\uff0c\u6211\u4eec\u628a\u51fd\u6570\u540d\uff0c\u6ce8\u610f\u662f\u51fd\u6570\u540d\u53eb operator() \uff0c\u8fd9\u4e2a\u7a7a\u7684\u5706\u62ec\u53f7\u662f\u51fd\u6570\u540d\u7684\u4e00\u90e8\u5206\uff01 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u80fd\u4e0d\u80fd\u7406\u89e3\uff1f operator \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u5173\u952e\u5b57\uff0c\u6548\u679c\u662f\u548c\u540e\u9762\u7684\u4e00\u4e2a\u8fd0\u7b97\u7b26\u7ed3\u5408\uff0c\u5f62\u6210\u4e00\u4e2a\u7279\u6b8a\u7684\u201c\u6807\u8bc6\u7b26\u201d\uff0c\u8fd9\u4e2a\u201c\u6807\u8bc6\u7b26\u201d\u548c\u666e\u901a\u51fd\u6570\u540d\u4e00\u6837\uff0c\u90fd\u662f\u201c\u5355\u4e2a\u5355\u8bcd\u201d\uff0c\u4e0d\u53ef\u5206\u5272\u3002 \u4f8b\u5982 operator+ \u5c31\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c operator[] \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6211\u4eec\u8fd9\u91cc\u7684 operator() \u4e5f\u662f\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6ca1\u6709\u4ec0\u4e48\u7a00\u5947\u7684\uff0c\u53ea\u4e0d\u8fc7\u540e\u9762\u8fde\u7684\u8fd0\u7b97\u7b26\u521a\u597d\u662f\u62ec\u53f7\u800c\u5df2\u3002 \u8fd9\u91cc\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 lambda . operator() \u6765\u8bbf\u95ee\u8fd9\u4e2a\u6210\u5458\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\uff0c operator() \u5c31\u548c\u4e00\u4e2a\u666e\u901a\u6210\u5458\u540d\u5b57\u4e00\u6837\uff0c\u6ca1\u6709\u533a\u522b\uff0c\u4e00\u6837\u53ef\u4ee5\u901a\u8fc7 . \u8bbf\u95ee\u3002 \u4f8b\u5982\uff0c\u5bf9\u4e8e\u8fd0\u7b97\u7b26 + \u6765\u8bf4\uff0c\u5f53\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230 lambda + 2 \u8fd9\u6837\u7684\u8868\u8fbe\u5f0f\u65f6\uff0c\u4f1a\u81ea\u52a8\u7ffb\u8bd1\u6210 lambda.operator+ (2) \uff0c\u8fd9\u5c31\u662f\u6240\u8c13\u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 struct Lambda { int operator+ (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda + 2; // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator+ (2); \u540c\u6837\u7684\uff0c\u5bf9\u4e8e () \u8fd0\u7b97\u7b26\uff0c\u4e5f\u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210 operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\uff0c\u7531\u4e8e\u5bf9 operator() \u51fd\u6570\u672c\u8eab\u7684\u8c03\u7528\u4e5f\u9700\u8981\u4e00\u4e2a\u62ec\u53f7\uff08\u53c2\u6570\u5217\u8868\uff09\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u5c31\u6709\u4e24\u4e2a\u62ec\u53f7\u4e86\u3002\u5b9e\u9645\u4e0a\u6839\u672c\u4e0d\u642d\u754c\uff0c\u4e00\u4e2a\u662f\u51fd\u6570\u540d\u6807\u8bc6\u7b26\u7684\u4e00\u90e8\u5206\uff0c\u4e00\u4e2a\u662f\u4ea7\u751f\u51fd\u6570\u8c03\u7528\u3002 struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda(2); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (2); \u8fd9\u65f6\u5019\uff0c\u53bb\u6389 (2) \u91cc\u7684\u53c2\u6570 2 \uff0c\u5c31\u53d8\u6210\u4e86\u8ba9\u4f60\u5f88\u56f0\u60d1\u7684\u53cc\u62ec\u53f7\u3002\u800c\u5f88\u591a\u4eba\u559c\u6b22\u7d27\u6328\u8005\u8fde\u5199\uff0c\u770b\u8d77\u6765\u5c31\u5f88\u8ff7\u60d1\u3002 \u5b9e\u9645\u4e0a\uff0c\u7b2c\u4e00\u4e2a () \u662f\u51fd\u6570\u540d\u5b57\u7684\u4e00\u90e8\u5206\uff0c\u548c operator \u662f\u8fde\u5728\u4e00\u8d77\u7684\uff0c\u4e0d\u53ef\u5206\u5272\uff0c\u4e2d\u95f4\u4e5f\u4e0d\u80fd\u6709\u5176\u4ed6\u53c2\u6570\u3002\u7b2c\u4e8c\u4e2a () \u662f\u51fd\u6570\u53c2\u6570\u5217\u8868\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u91cc\u521a\u597d\u662f\u6ca1\u6709\u53c2\u6570\uff0c\u6240\u4ee5\u770b\u8d77\u6765\u4e5f\u662f\u4e2a\u7a7a\u62ec\u53f7\uff0c\u5f88\u591a\u521d\u5b66\u8005\u770b\u5230\u5c31\u8ff7\u7cca\u4e86\uff0c\u8fd8\u770b\u4e0d\u61c2\u5efa\u8bae\u4ece\u4e0a\u9762\u6709\u4e00\u4e2a\u53c2\u6570\u7684 operator() (int a) \u770b\u3002 struct Lambda { int operator() () const { return 1; } }; Lambda lambda; int ret = lambda(); // \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a int ret = lambda.operator() (); \u6240\u4ee5\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u8bf4\u5b9a\u4e49\u4e86 operator() \u6210\u5458\u51fd\u6570\u7684\u7c7b\uff0c\u662f\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u6216\u8005\u8bf4\u201c\u4eff\u51fd\u6570\u201d\uff0c\u56e0\u4e3a\u5f53\u4f60\u4f7f\u7528\u51fd\u6570\u7684\u8bed\u6cd5 lambda(2) \u8c03\u7528\u4ed6\u4eec\u65f6\uff0c\u4f1a\u89e6\u53d1\u4ed6\u4eec\u7684\u6210\u5458\u51fd\u6570 operator()(2) \u4ece\u800c\u7528\u6cd5\u548c\u666e\u901a\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u5176\u5b9e\u9645\u53c8\u662f\u5bf9\u8c61\uff0c\u4e5f\u5c31\u5f97\u540d\u201c\u51fd\u6570\u5bf9\u8c61\u201d\u548c\u201c\u4eff\u51fd\u6570\u201d\u4e86\u3002 \u6211\u5efa\u8bae\u4f60\u81ea\u5df1\u53bb https://cppinsights.io \u8fd9\u4e2a\u89e3\u6784\u8bed\u6cd5\u7cd6\u7684\u5de5\u5177\u7f51\u7ad9\u52a8\u52a8\u624b\u8bd5\u8bd5\u770b\uff1a auto lambda = [] (int a) { return a + 1; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int operator() (int a) const { return a + 1; } }; Lambda lambda; int ret = lambda.operator() (2); \u800c\u6355\u83b7\u4e86\u53d8\u91cf\u7684\uff1a int x = 4; auto lambda = [&x] (int a) { return a + x; }; int ret = lambda(2); \u5b9e\u9645\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int &x; Lambda(int &x_) : x(x_) {} int operator() (int a) const { return a + x; } }; int x = 4; Lambda lambda(x); int ret = lambda.operator() (2);","title":"operator() \u5f88\u6709\u8ff7\u60d1\u6027"},{"location":"lambda/#_20","text":"\u6b63\u56e0\u5982\u6b64\uff0c\u95ed\u5305\u6309\u503c\u6355\u83b7\uff08 [=] \uff09\u7684\u53d8\u91cf\uff0c\u5176\u751f\u547d\u5468\u671f\u548c Lambda \u5bf9\u8c61\u76f8\u540c\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u62f7\u8d1d\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u88ab\u91cd\u65b0\u62f7\u8d1d\u4e00\u4efd\u3002 \u5f53 Lambda \u5bf9\u8c61\u88ab\u79fb\u52a8\u65f6\uff0c\u5176\u6309\u503c\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u4e5f\u4f1a\u968f\u4e4b\u4e00\u8d77\u79fb\u52a8\u3002 struct C { C() { fmt::println(\"C \u9ed8\u8ba4\u6784\u9020\"); } C(C const &) { fmt::println(\"C \u62f7\u8d1d\u6784\u9020\"); } C(C &&) { fmt::println(\"C \u79fb\u52a8\u6784\u9020\"); } C &operator=(C const &) { fmt::println(\"C \u62f7\u8d1d\u8d4b\u503c\"); } C &operator=(C &&) { fmt::println(\"C \u79fb\u52a8\u8d4b\u503c\"); } ~C() { fmt::println(\"C \u6790\u6784\"); } }; C c; fmt::println(\"\u6784\u9020 lambda\"); auto lambda = [c] {}; fmt::println(\"\u62f7\u8d1d lambda \u5230 lambda2\"); auto lambda2 = lambda; fmt::println(\"\u79fb\u52a8 lambda \u5230 lambda3\"); auto lambda3 = lambda; \u8f93\u51fa\uff1a C \u9ed8\u8ba4\u6784\u9020 \u6784\u9020 lambda C \u62f7\u8d1d\u6784\u9020 \u62f7\u8d1d lambda \u5230 lambda2 C \u62f7\u8d1d\u6784\u9020 \u79fb\u52a8 lambda \u5230 lambda3 C \u79fb\u52a8\u6784\u9020 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 C \u6790\u6784 \u5982\u679c\u6309\u503c\u6355\u83b7\u4e86\u4e0d\u80fd\u62f7\u8d1d\u7684\u5bf9\u8c61\uff08\u6bd4\u5982 std::unique_ptr \uff09\uff0c\u90a3\u4e48 Lambda \u5bf9\u8c61\u4e5f\u4f1a\u65e0\u6cd5\u62f7\u8d1d\uff0c\u53ea\u80fd\u79fb\u52a8\u3002 std::unique_ptr p = std::make_unique(10); auto lambda = [p] {}; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u56e0\u4e3a\u8fd9\u91cc\u7b49\u4ef7\u4e8e [p' = p]\uff0c\u662f\u5bf9 p' \u7684\u62f7\u8d1d\u6784\u9020 auto lambda = [p = std::move(p)] {}; // \u7f16\u8bd1\u901a\u8fc7\u2705unique_ptr \u652f\u6301\u79fb\u52a8\u6784\u9020 auto lambda2 = lambda; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3std::unique_ptr \u53ea\u652f\u6301\u79fb\u52a8\uff0c\u4e0d\u652f\u6301\u62f7\u8d1d auto lambda2 = std::move(lambda); // \u7f16\u8bd1\u901a\u8fc7\u2705 \u7528\u6211\u4eec\u4e4b\u524d\u7684\u65b9\u6cd5\u89e3\u6784\u8bed\u6cd5\u7cd6\u540e\uff1a struct Lambda { std::unique_ptr p; Lambda(std::unique_ptr ptr) : p(std::move(ptr)) {} // Lambda(Lambda const &) = delete; // \u56e0\u4e3a\u6709 unique_ptr \u6210\u5458\uff0c\u5bfc\u81f4 Lambda \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u88ab\u9690\u5f0f\u5220\u9664 void operator()() const { } }; int main() { std::unique_ptr p = std::make_unique(10); Lambda lambda(p); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3 Lambda lambda(std::move(p)); // \u7f16\u8bd1\u901a\u8fc7\u2705 return 0; }","title":"\u95ed\u5305\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u95ee\u9898"},{"location":"lambda/#mutable","text":"int x = 10; auto lambda = [x] () { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3lambda \u6355\u83b7\u7684 x \u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684 }; int ret = lambda(); \u4f1a\u88ab\u7f16\u8bd1\u5668\u7ffb\u8bd1\u6210\uff1a struct Lambda { int x; int operator() () const { return x++; // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3const \u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u6210\u5458\u53d8\u91cf } }; int x = 10; Lambda lambda{x}; int ret = lambda.operator() (); \u6ce8\u610f\u5230\uff0c\u8fd9\u91cc\u7684 operator() \u6210\u5458\u51fd\u6570\u6709\u4e00\u4e2a const \u4fee\u9970\uff0c\u610f\u5473\u7740\u8be5\u6210\u5458\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\u5176\u4f53\u5185\u7684\u53d8\u91cf\u3002 \u6240\u6709 lambda \u51fd\u6570\u5bf9\u8c61\u751f\u6210\u65f6\u9ed8\u8ba4\uff0c\u5c31\u4f1a\u7ed9\u4ed6\u7684 operator() \u6210\u5458\u51fd\u6570\u52a0\u4e0a const \u4fee\u9970\u3002 \u4e5f\u5c31\u662f\u8bf4\u95ed\u5305\u6355\u83b7\u7684\u53d8\u91cf\u9ed8\u8ba4\u662f\u53ea\u8bfb\u7684\uff0c\u5982\u679c\u9700\u8981\u4fee\u6539\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u53ef\u4ee5\u7ed9 lambda \u52a0\u4e0a mutable \u4fee\u9970\uff0c\u5c31\u52a0\u5728 () \u540e\u9762\u3002 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"lambda() = {}\", lambda()); // 10 fmt::println(\"lambda() = {}\", lambda()); // 11 fmt::println(\"lambda() = {}\", lambda()); // 12 \u7f16\u8bd1\u5668\u7ffb\u8bd1\u4ea7\u751f\u7684 Lambda \u7c7b\u7684\u6210\u5458\u51fd\u6570\uff0c\u5c31\u4e0d\u4f1a\u5e26 const \u4fee\u9970\u4e86\uff0c\u4ece\u800c\u5141\u8bb8\u6211\u4eec\u7684\u51fd\u6570\u4f53\u4fee\u6539\u6355\u83b7\u7684\u975e\u5f15\u7528\u53d8\u91cf\u3002 struct Lambda { int x; int operator() () { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 } }; int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 \u6ce8\u610f\uff1a\u7531\u4e8e\u4f7f\u7528\u4e86\u503c\u6355\u83b7\uff0clambda \u4fee\u6539\u7684\u662f\u5728\u4ed6\u521b\u5efa\u65f6\u5bf9 x \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u5916\u9762\u7684 x \u4e0d\u4f1a\u6539\u53d8\uff01 int x = 10; Lambda lambda{x}; fmt::println(\"lambda() = {}\", lambda.operator() ()); // 10 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 11 fmt::println(\"lambda() = {}\", lambda.operator() ()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // 13 int x = 10; auto lambda = [x] () mutable { return x++; // \u7f16\u8bd1\u901a\u8fc7\u2705 }; fmt::println(\"ret = {}\", lambda()); // 10 fmt::println(\"ret = {}\", lambda()); // 11 fmt::println(\"ret = {}\", lambda()); // 12 fmt::println(\"x = {}\", x); // 10 fmt::println(\"lambda.x = {}\", lambda.x); // \u7f16\u8bd1\u9519\u8bef\ud83d\udca3\u7f16\u8bd1\u5668\u4ea7\u751f\u7684\u533f\u540d lambda \u5bf9\u8c61\u4e2d\u6355\u83b7\u4ea7\u751f\u7684 x \u6210\u5458\u53d8\u91cf\u662f\u533f\u540d\u7684\uff0c\u65e0\u6cd5\u8bbf\u95ee","title":"mutable \u7684\u51fd\u6570\u5bf9\u8c61"},{"location":"lambda/#lambda","text":"","title":"\u6df1\u5165\u8ba4\u8bc6 lambda \u8bed\u6cd5"},{"location":"lambda/#_21","text":"\u4e00\u4e2a\u53d8\u91cf\u7684\u4e09\u79cd\u6355\u83b7\u65b9\u5f0f\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7 [x] \u6309\u5f15\u7528\u6355\u83b7 [&x] \u6309\u503c\u79fb\u52a8\u6355\u83b7 [x = std::move(x)] \u6309\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7 [x = ...] \u6279\u91cf\u6355\u83b7\uff1a \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [=] \u6309\u5f15\u7528\u6355\u83b7\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf [&] \u591a\u4e2a\u6355\u83b7 + \u9ed8\u8ba4\u6355\u83b7\u65b9\u5f0f [x, y, &] \u6216 [&x, &y, =]","title":"\u6355\u83b7\u5217\u8868\u8bed\u6cd5"},{"location":"lambda/#_22","text":"\u8bed\u6cd5\uff1a [\u53d8\u91cf\u540d] \u6309\u503c\u62f7\u8d1d\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u62f7\u8d1d\u4e00\u4efd\u6355\u83b7\u7684\u53d8\u91cf\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u5df2\u7ecf\u662f\u4e24\u4e2a\u4e0d\u540c\u7684\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4e0d\u4f1a\u5f71\u54cd lambda \u6355\u83b7 x \u7684\u503c\u3002 main \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 985 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e0d\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [x] (int i) mutable { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u7531\u4e8e lambda \u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u9ed8\u8ba4\u90fd\u662f\u4e0d\u53ef\u4fee\u6539\uff08 const \uff09\uff0c\u9700\u8981 mutable \u624d\u80fd\u4fee\u6539\u6309\u503c\u6355\u83b7\u7684\u6210\u5458\u3002\u800c\u6309\u5f15\u7528\u6355\u83b7\u5c31\u4e0d\u9700\u8981 mutable \uff0c\u56e0\u4e3a\u867d\u7136 lambda \u672c\u8eab\u4e0d\u53ef\u4fee\u6539\uff0c\u4f46\u4ed6\u6307\u5411\u7684\u4e1c\u897f\u53ef\u4ee5\u4fee\u6539\u5440\uff01 \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 985 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u4f9d\u7136\u6709\u6548\u3002 int main() { std::function lambda; { int x = 985; lambda = [x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = 985","title":"\u6309\u503c\u62f7\u8d1d\u6355\u83b7"},{"location":"lambda/#_23","text":"\u8bed\u6cd5\uff1a [&\u53d8\u91cf\u540d] \u6309\u5f15\u7528\u6355\u83b7\u7684\u53d8\u91cf\uff0c\u5728 lambda \u5bf9\u8c61\u521b\u5efa\u65f6\uff0c\u4f1a\u521b\u5efa\u4e00\u4efd\u6307\u5411\u53d8\u91cf\u7684\u5f15\u7528\u3002 lambda \u6355\u83b7\u7684\u53d8\u91cf\u5f15\u7528 &x \u4e0e\u539f\u5148 main \u51fd\u6570\u4e2d\u7684 x \u662f\u540c\u4e00\u4e2a\u53d8\u91cf\uff0c\u5bf9 main \u51fd\u6570\u4e2d x \u7684\u4fee\u6539\u4f1a\u76f4\u63a5\u5f71\u54cd lambda \u6355\u83b7\u4e2d x \u7684\u503c\uff0c\u53cd\u4e4b\u4ea6\u7136\u3002 \u6f14\u793a\uff1amain \u4e2d\u7684\u4fee\u6539\u5bf9 lambda \u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); x = 211; fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1alambda \u4e2d\u7684\u4fee\u6539\u5bf9 main \u4e5f\u53ef\u89c1\u3002 int main() { int x = 985; auto lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); x = 211; }; fmt::println(\"in main: x = {}\", x); lambda(); fmt::println(\"in main: x = {}\", x); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x = 211 in lambda: x = 211 \u6f14\u793a\uff1amain \u4e2d x \u751f\u547d\u5468\u671f\u7ed3\u675f\u540e\uff0clambda \u4e2d\u7684 x \u5c06\u6210\u4e3a\u5371\u9669\u7684\u201c\u7a7a\u60ac\u5f15\u7528\uff08dangling-reference\uff09\u201d\uff01\u6b64\u65f6\u518d\u5c1d\u8bd5\u8bbf\u95ee x\uff0c\u5c06\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int main() { std::function lambda; { int x = 985; lambda = [&x] (int i) { fmt::println(\"in lambda: x = {}\", x); }; fmt::println(\"in main: x = {}\", x); lambda(); } fmt::println(\"in main: x \u5df2\u7ecf\u6790\u6784\"); lambda(); } \u8f93\u51fa\uff1a in main: x = 985 in lambda: x = 985 in main: x \u5df2\u7ecf\u6790\u6784 in lambda: x = -858993460 -858993460 \u4e3a\u5185\u5b58\u4e2d\u7684\u5783\u573e\u503c\uff0c\u4f60\u8bfb\u5230\u7684\u7ed3\u679c\u53ef\u80fd\u968f\u5e73\u53f0\uff0c\u7f16\u8bd1\u5668\u7248\u672c\uff0c\u4f18\u5316\u9009\u9879\u7684\u4e0d\u540c\u800c\u4e0d\u540c\uff0c\u6b63\u5e38\u8bfb\u5230 985 \u4e5f\u662f\u6709\u53ef\u80fd\u7684\uff0c\u5f00\u53d1\u8005\u4e0d\u80fd\u4f9d\u8d56\u6b64\u7c7b\u968f\u673a\u6027\u7684\u7ed3\u679c\u3002 \u6b63\u5e38\u8bfb\u5230 985\uff08\u5927\u5b66\uff09\u4e5f\u662f\u6709\u53ef\u80fd\u7684\u3002 -858993460 \u662f\u5728 Windows \u5e73\u53f0\u7684\u8c03\u8bd5\u6a21\u5f0f\u4e0b\u53ef\u80fd\u7684\u8f93\u51fa\uff0c\u56e0\u4e3a Windows \u503e\u5411\u4e8e\u628a\u6808\u5185\u5b58\u586b\u6ee1 0xcccccccc \u4ee5\u65b9\u4fbf\u8c03\u8bd5\uff0c\u5176\u4e2d 0xcc \u521a\u597d\u4e5f\u662f int3 \u8fd9\u6761 x86 \u8c03\u8bd5\u6307\u4ee4\u7684\u4e8c\u8fdb\u5236\u7801\uff0c\u53ef\u80fd\u662f\u4e3a\u4e86\u907f\u514d\u6307\u4ee4\u6307\u9488\u6267\u884c\u5230\u5806\u6808\u91cc\u53bb\u3002","title":"\u6309\u5f15\u7528\u6355\u83b7"},{"location":"lambda/#_24","text":"TODO","title":"\u6309\u503c\u79fb\u52a8\u6355\u83b7"},{"location":"lambda/#_25","text":"TODO","title":"\u81ea\u5b9a\u4e49\u8868\u8fbe\u5f0f\u6355\u83b7"},{"location":"lambda/#lambda-auto","text":"","title":"lambda \u4e2d\u7684 auto \u7c7b\u578b\u63a8\u5bfc"},{"location":"lambda/#auto","text":"lambda \u51fd\u6570\u53ef\u4ee5\u901a\u8fc7\u5728\u53c2\u6570\u5217\u8868\u540e\u4f7f\u7528 -> \u6307\u5b9a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) -> int { return a; }; int i = lambda(); \u5982\u679c\u8fd4\u56de\u7c7b\u578b\u7701\u7565\u4e0d\u5199\uff0c\u9ed8\u8ba4\u662f -> auto \uff0c\u4e5f\u5c31\u662f\u6839\u636e\u4f60\u7684 return \u8bed\u53e5\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 auto lambda = [] (int a) { return a; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> auto { return a; }; \u548c\u666e\u901a\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u58f0\u660e\u4e3a auto \u4e00\u6837\uff0c\u4f1a\u81ea\u52a8\u6839\u636e\u8868\u8fbe\u5f0f\u4e3a\u4f60\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff1a auto lambda = [] (int a) { return a; // \u6b64\u8868\u8fbe\u5f0f\u7c7b\u578b\u4e3a int }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> int { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f int return a; }; auto lambda2 = [] (int a) { return a * 2.0; // \u6b64\u8fd4\u56de\u8868\u8fbe\u5f0f\u7684\u7c7b\u578b\u4e3a double }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda2 = [] (int a) -> double { // \u6240\u4ee5 auto \u63a8\u5bfc\u51fa\u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u662f double return a * 2.0; }; \u5982\u679c\u6ca1\u6709\u8fd4\u56de\u8bed\u53e5\uff0c\u90a3\u4e48\u4f1a\u63a8\u5bfc\u4e3a\u8fd4\u56de void \u7c7b\u578b\u7684 lambda\u3002 auto lambda = [] (int a) { fmt::println(\"a = {}\", a); }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { fmt::println(\"a = {}\", a); }; auto lambda = [] (int a) { return; }; // \u7b49\u4ef7\u4e8e\uff1a auto lambda = [] (int a) -> void { return; }; \u548c\u51fd\u6570\u7684 auto \u8fd4\u56de\u7c7b\u578b\u63a8\u5bfc\u4e00\u6837\uff0c\u5f53\u8fd4\u56de\u7c7b\u578b\u4e3a auto \u7684 lambda \u5177\u6709\u591a\u4e2a\u8fd4\u56de\u8bed\u53e5\u65f6\uff0c\u5fc5\u987b\u4fdd\u8bc1\u6240\u6709\u5206\u652f\u4e0a\u7684\u8fd4\u56de\u503c\u5177\u6709\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u7f16\u8bd1\u5668\u62a5\u9519\uff0c\u9700\u8981\u624b\u52a8\u5199\u51fa\u8fd4\u56de\u7c7b\u578b\uff0c\u6216\u8005\u628a\u6240\u6709\u5206\u652f\u7684\u8fd4\u56de\u503c\u6539\u6210\u76f8\u540c\u7684\u3002 auto lambda_error = [] (double x) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u4e24\u4e2a\u5206\u652f\u7684\u8fd4\u56de\u7c7b\u578b\u4e0d\u540c\uff0c\u65e0\u6cd5\u81ea\u52a8\u63a8\u5bfc if (x > 0) { return x; // double } else { return 0; // int } }; auto lambda_ok = [] (double x) { // \u7f16\u8bd1\u901a\u8fc7 if (x > 0) { return x; // double } else { return (double)0; // double } }; auto lambda_also_ok = [] (double x) -> double { // \u624b\u52a8\u660e\u786e\u8fd4\u56de\u7c7b\u578b\uff0c\u7f16\u8bd1\u4e5f\u80fd\u901a\u8fc7 if (x > 0) { return x; // double } else { return 0; // int\uff0c\u4f46\u4f1a\u9690\u5f0f\u8f6c\u6362\u4e3a double } };","title":"auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b"},{"location":"lambda/#auto_1","text":"TODO","title":"auto \u63a8\u5bfc\u53c2\u6570\u7c7b\u578b"},{"location":"lambda/#auto_2","text":"","title":"auto \u53c2\u6570\u5b9e\u73b0\u591a\u6b21\u5b9e\u4f8b\u5316\u7684\u5e94\u7528"},{"location":"lambda/#auto-auto-const","text":"","title":"auto & \u4e0e auto const & \u7684\u5e94\u7528"},{"location":"lambda/#auto_3","text":"","title":"auto && \u4e07\u80fd\u5f15\u7528"},{"location":"lambda/#decltypeauto","text":"","title":"decltype(auto) \u4fdd\u7559\u771f\u6b63\u7684\u539f\u59cb\u8fd4\u56de\u7c7b\u578b"},{"location":"lambda/#lambda_1","text":"","title":"lambda \u5e38\u89c1\u7684\u4e09\u5927\u7528\u6cd5"},{"location":"lambda/#_26","text":"\u6211\u4eec\u603b\u662f\u7528 auto \u6765\u4fdd\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u4f5c\u4e3a\u5c40\u90e8\u53d8\u91cf\uff0c\u8fd9\u4f1a\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\u3002 \u4e3a\u4ec0\u4e48\u4e0d\u80fd\u663e\u5f0f\u5199\u51fa\u7c7b\u578b\u540d\u5b57\uff1f\u56e0\u4e3a lambda \u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f60\u65e0\u6cd5\u5199\u51fa\u7c7b\u578b\u540d\uff0c\u53ea\u80fd\u901a\u8fc7 auto \u63a8\u5bfc\u3002 int b = 2; auto lambda = [b] (int a) { return a + b; }; \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 C++11 \u540c\u65f6\u5f15\u5165 auto \u548c lambda \u8bed\u6cd5\u7684\u539f\u56e0\u3002 \u5982\u679c\u4f60\u5b9e\u5728\u9700\u8981\u663e\u5f0f\u7684\u7c7b\u540d\uff0c\u90a3\u5c31\u9700\u8981\u4f7f\u7528 std::function \u5bb9\u5668\u3002\u867d\u7136 lambda \u8868\u8fbe\u5f0f\u4ea7\u751f\u7684\u7c7b\u578b\u662f\u533f\u540d\u7684\uff0c\u4f46\u662f\u8be5\u7c7b\u578b\u7b26\u5408\u201c\u53ef\u8c03\u7528\u201d\u7684\u7ea6\u675f\uff0c\u53ef\u4ee5\u88ab std::function \u5bb9\u5668\u63a5\u7eb3\u3002 \u5373 lambda \u7c7b\u578b\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u76f8\u5e94\u53c2\u6570\u5217\u8868\u7684 std::function \u5bb9\u5668\u3002\u56e0\u4e3a std::function \u5bb9\u5668\u53ef\u4ee5\u63a5\u7eb3\u4efb\u4f55\u201c\u53ef\u63a5\u53d7 (Args...) \u53c2\u6570\u8c03\u7528\u5e76\u8fd4\u56de Ret \u7c7b\u578b\u201d\u7684\u4efb\u610f\u51fd\u6570\u5bf9\u8c61\u3002 int b = 2; std::function lambda = [b] (int a) { return a + b; }; \u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u628a lambda \u5bf9\u8c61\u63a8\u5165 vector \u7b49\u5bb9\u5668\u4e2d\u65f6\uff0c\u5c31\u9700\u8981\u663e\u5f0f\u5199\u51fa\u51fd\u6570\u5bf9\u8c61\u7684\u7c7b\u578b\uff0c\u6b64\u65f6\u4e07\u80fd\u51fd\u6570\u5bf9\u8c61\u5bb9\u5668 std::function \u5c31\u80fd\u6d3e\u4e0a\u7528\u573a\u4e86\uff1a // vector lambda_list; // \u9519\u8bef\uff1a\u4e0d\u652f\u6301\u7684\u8bed\u6cd5 vector> lambda_list; // OK int b = 2; lambda_list.push_back([b] (int a) { return a + b; }; lambda_list.push_back([b] (int a) { return a * b; }; for (auto lambda: lambda_list) { int ret = lambda(2); fmt::println(\"{}\", ret); }","title":"\u50a8\u5b58\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u5c40\u90e8\u53d8\u91cf"},{"location":"lambda/#_27","text":"","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_28","text":"TODO","title":"\u4ee3\u7801\u590d\u7528"},{"location":"lambda/#lambda-idiom","text":"TODO","title":"\u5c31\u5730\u8c03\u7528\u7684 lambda-idiom"},{"location":"lambda/#_29","text":"\u65b0\u624b\u7528 lambda \u5e38\u89c1\u7684\u9519\u8bef\u5c31\u662f\u641e\u4e0d\u6e05\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\uff0c\u603b\u662f\u60f3\u5f53\u7136\u5730\u65e0\u8111\u7528 [&] \uff0c\u975e\u5e38\u5371\u9669\u3002 \u5982\u679c\u4f60\u6709\u201c\u81ea\u77e5\u4e4b\u660e\u201d\uff0c\u81ea\u77e5\u4e0d\u719f\u6089\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u90a3\u5c31\u5168\u90e8 [=] \u3002 \u7b49\u6211\u4eec\u7a0d\u540e\u7684 \u751f\u547d\u5468\u671f\u4e13\u9898\u8bfe\u7a0b \u4e2d\u4ecb\u7ecd\u3002 \u5b9e\u9645\u4e0a\uff0c [=] \u5e94\u8be5\u662f\u4f60\u9ed8\u8ba4\u7684\u6355\u83b7\u65b9\u5f0f\u3002 \u53ea\u6709\u5f53\u7c7b\u578b\u65e0\u6cd5\u62f7\u8d1d\u4f1a\u6df1\u62f7\u8d1d\u6210\u672c\u8fc7\u9ad8\u65f6\uff0c\u624d\u4f1a\u9009\u62e9\u6027\u5730\u628a\u4e00\u4e9b\u53ef\u4ee5\u6539\u6210\u5f15\u7528\u6355\u83b7\u7684\u90e8\u5206 lambda\uff0c\u4f7f\u7528 [&] \u6765\u6355\u83b7\u90e8\u5206\u9700\u8981\u907f\u514d\u62f7\u8d1d\u7684\u53d8\u91cf\uff0c\u6216\u8005\u4f7f\u7528 shared_ptr \u914d\u5408 [=] \u5c06\u6df1\u62f7\u8d1d\u5316\u4e3a\u6d45\u62f7\u8d1d\u3002 \u4e00\u4e9b\u4e60\u60ef\u4e86 Python\u3001JS \u7b49\u5168\u5458 shared_ptr \u7684\u5783\u573e\u56de\u6536\u8bed\u8a00\u5de8\u5a74\uff0c\u4e00\u4e0a\u6765\u5c31\u5168\u90e8\u65e0\u8111 [&] \uff0c\u7528\u5b9e\u9645\u884c\u52a8\u8bc1\u660e\u4e86\u667a\u5546\u548c\u52c7\u6c14\u6210\u53cd\u6bd4\u5b9a\u5f8b\u3002 \u597d\u6d88\u606f\u662f\uff0c\u5bf9\u4e8e\u4ee3\u7801\u590d\u7528\u548c\u5c31\u5730\u8c03\u7528\u7684\u60c5\u51b5\uff0clambda \u5bf9\u8c61\u7684\u751f\u547d\u90fd\u4e0d\u4f1a\u51fa\u51fd\u6570\u4f53\uff0c\u53ef\u4ee5\u5b89\u5168\u5730\u6539\u6210\u6309\u5f15\u7528\u6355\u83b7 [&] \u3002 \u4f46\u662f\u5bf9\u4e8e\u4e0b\u9762\u4e24\u79cd\u60c5\u51b5\uff08\u4f5c\u4e3a\u53c2\u6570\u4f20\u5165\u548c\u4f5c\u4e3a\u8fd4\u56de\u503c\uff09\uff0c\u5c31\u4e0d\u4e00\u5b9a\u6709\u8fd9\u4e48\u5e78\u8fd0\u4e86\u3002 \u603b\u4e4b\uff0c\u65e0\u8bba\u5982\u4f55\u8981\u4fdd\u8bc1 lambda \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f \u5c0f\u4e8e\u7b49\u4e8e \u6309\u5f15\u7528\u6355\u83b7\u7684\u6240\u6709\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u3002\u5982\u679c\u505a\u4e0d\u5230\uff0c\u90a3\u5c31\u5f97\u628a\u8fd9\u4e9b\u53ef\u80fd\u8d85\u51fa\u7684\u53d8\u91cf\u6539\u6210\u6309\u503c\u6355\u83b7 [=] \u3002","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_30","text":"\u5982\u679c\u4f60\u60f3\u8ba9\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\uff0c\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5c31\u5730\u5b9a\u4e49\uff08\u58f0\u660e\u4e0e\u5b9a\u4e49\u5408\u4f53\uff09\u7684\u51fd\u6570\uff0c\u5efa\u8bae\u586b\u5199 auto \u4e3a\u8fd4\u56de\u503c\u7c7b\u578b\uff0c\u81ea\u52a8\u63a8\u5bfc lambda \u7684\u533f\u540d\u7c7b\u578b\uff08\u56e0\u4e3a\u4f60\u65e0\u6cd5\u5199\u51fa\u5177\u4f53\u7c7b\u578b\u540d\uff09\u3002 \u7136\u540e\uff0c\u5728 return \u8bed\u53e5\u4e2d\u5c31\u5730\u5199\u51fa lambda \u8868\u8fbe\u5f0f\u5373\u53ef\uff1a auto make_adder(int x) { return [x] (int y) { return x + y; }; } \u5206\u79bb\u58f0\u660e\u4e0e\u5b9a\u4e49\u7684\u51fd\u6570\uff0c\u65e0\u6cd5\u4f7f\u7528 auto \u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\uff0c\u4e0d\u5f97\u4e0d\u4f7f\u7528\u4e07\u80fd\u7684\u51fd\u6570\u5bb9\u5668 std::function \u6765\u64e6\u5c41\u80a1\uff1a // adder.h std::function make_adder(int x); // adder.cpp std::function make_adder(int x) { return [x] (int y) { return x + y; }; } \u201c\u51fd\u6570\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\uff0c\u8fd9\u79cd\u7528\u6cd5\u5728\u51fd\u6570\u5f0f\u7f16\u7a0b\u975e\u5e38\u5e38\u89c1\u3002","title":"\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u8fd4\u56de\u503c"},{"location":"lambda/#_31","text":"\u4f8b\u5982\u4e0a\u8ff0\u7684 make_adder \u7b49\u4e8e\u7ed1\u5b9a\u4e86\u4e00\u4e2a\u56fa\u5b9a\u53c2\u6570 x \u7684\u52a0\u6cd5\u51fd\u6570\uff0c\u4e4b\u540e\u6bcf\u6b21\u8c03\u7528\u8fd9\u4e2a\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u5c31\u56fa\u5b9a\u589e\u52a0\u4e4b\u524d\u5728 make_adder \u53c2\u6570\u4e2d x \u7684\u589e\u91cf\u4e86\u3002 TODO","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_32","text":"\u6b64\u7c7b\u201c\u8fd4\u56de\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u201d\u7684\u5199\u6cd5\uff0c\u5176 lambda \u6355\u83b7\u5fc5\u987b\u662f\u6309\u503c\u6355\u83b7\u7684\uff01 \u5426\u5219\uff0c\u56e0\u4e3a\u8c03\u7528\u8005\u8c03\u7528\u8fd4\u56de\u7684\u51fd\u6570\u5bf9\u8c61\u65f6\uff0c\u5c40\u90e8\u53d8\u91cf\u548c\u5b9e\u53c2\u6240\u5bf9\u5e94\u7684\u51fd\u6570\u5c40\u90e8\u6808\u7a7a\u95f4\u5df2\u7ecf\u91ca\u653e\uff0c\u76f8\u5f53\u4e8e\u5728 lambda \u4f53\u5185\u5b58\u6709\u7a7a\u60ac\u5f15\u7528\uff0c\u5bfc\u81f4\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u8981\u4e48\u76f4\u63a5\u5d29\u6e83\uff0c\u8981\u4e48\u975e\u5e38\u9690\u853d\u5730\u7559\u4e0b\u5185\u5b58\u975e\u6cd5\u8bbf\u95ee\u7684\u9690\u60a3\uff09\u3002 auto make_adder(int x) { return [x] (int y) { return x + y; }; } int main() { // \u6211\u662f\u8c03\u7528\u8005 auto adder = make_adder(2); adder(3); // 2 + 3 = 5 }","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_33","text":"TODO\uff1a\u4ee3\u7801","title":"\u63a5\u53d7\u4e00\u4e2a\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570"},{"location":"lambda/#_34","text":"TODO\uff1a\u7b56\u7565\u6a21\u5f0f TODO\uff1a\u5ef6\u8fdf\u56de\u8c03","title":"\u5e94\u7528\u6848\u4f8b"},{"location":"lambda/#_35","text":"\u51fd\u6570\u5bf9\u8c61\u505a\u53c2\u6570\u7684\u751f\u547d\u5468\u671f\u95ee\u9898\uff0c\u9700\u8981\u5206\u5c31\u5730\u8c03\u7528\u548c\u5ef6\u8fdf\u8c03\u7528\u4e24\u79cd\u60c5\u51b5\u8ba8\u8bba\u3002","title":"\u6ce8\u610f\u6355\u83b7\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f"},{"location":"lambda/#_36","text":"\u5982\u679c\u4f60\u7684\u667a\u529b\u6682\u4e0d\u8db3\u4ee5\u641e\u61c2\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u6ca1\u5173\u7cfb\uff0c\u59cb\u7ec8\u4f7f\u7528 [=] \u80af\u5b9a\u6ca1\u9519\u3002 \u4e00\u4e2a\u540c\u5b66\u8be2\u95ee\uff1a\u6211\u53e3\u6e34\uff01\u5728\u4e0d\u77e5\u9053\u4ed6\u7684\u8010\u53d7\u5ea6\u7684\u60c5\u51b5\u4e0b\uff0c\u6211\u80af\u5b9a\u662f\u76f4\u63a5\u7ed9\u4ed6\u5403\u6c34\uff0c\u800c\u4e0d\u662f\u7ed9\u4ed6\u5403\u9152\u7cbe\u3002\u867d\u7136\u4e00\u4e9b\u5b5d\u5b50\u66f0\u201c\u9002\u91cf\u201d\u201c\u9002\u5ea6\u201d\u201c\u8ba1\u91cf\u201d\u5404\u79cd\u4e00\u8fde\u4e32\u9644\u52a0\u6761\u4ef6\u4e0b\uff0c\u5ba3\u79f0\u201c\u9152\u7cbe\u4e5f\u662f\u5b89\u5168\u7684\u201d\u3002\u4f46\u662f\u201c\u6c34\u6c38\u8fdc\u662f\u5b89\u5168\u7684\u201d\uff0c\u201c\u6c38\u8fdc\u201d\uff0c\u90a3\u6211\u76f4\u63a5\u7ed9\u4ed6\u559d\u6c34\uff0c\u662f\u80af\u5b9a\u4e0d\u4f1a\u9519\u7684\u3002\u7b49\u4f60\u957f\u5927\u6210\u5e74\u4e86\uff0c\u6709\u8fa8\u522b\u80fd\u529b\u4e86\uff0c\u518d\u53bb\u6839\u636e\u81ea\u5df1\u7684\u5c0f\u8ba1\u673a\u7619\u75d2\u7a0b\u5ea6\uff0c\u9009\u62e9\u6027\u5730\u559d\u6709\u673a\u6eb6\u5242\u3002\u6b64\u5904 [=] \u5c31\u662f\u8fd9\u4e2a\u4e07\u80fd\u7684\u6c34\uff0c\u867d\u7136\u4e0d\u4e00\u5b9a\u9ad8\u6548\uff0c\u4f46\u662f\u80af\u5b9a\u6ca1\u9519\u3002\u521d\u5b66\u8005\u603b\u662f\u4ece [=] \u7528\u8d77\uff0c\u7b49\u5b66\u660e\u767d\u4e86\uff0c\u518d\u6765\u5c1d\u8bd5\u7a81\u7834\u201c\u5c0f\u8ba1\u673a\u6027\u80fd\u7126\u8651\u4f18\u5316\u201d\u4e5f\u4e0d\u8fdf\u3002 \u5982\u679c\u4f60\u81ea\u8ba4\u4e3a\u80fd\u5206\u5f97\u6e05\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u521b\u5efa\uff0c\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u8fd4\u56de\u4e00\u4e2a lambda\uff0c\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u63a5\u53d7\u4e00\u4e2a lambda \u505a\u53c2\u6570\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a \u5728\u5f53\u524d\u51fd\u6570\u4f53\u5185\u7acb\u5373\u8c03\u7528\uff0c\u53ef\u4ee5\u5f15\u7528\u6355\u83b7 [&] \uff0c\u4f46\u503c\u6355\u83b7 [=] \u4e5f\u6ca1\u9519\u3002 \u4f5c\u4e3a\u56de\u8c03\u51fd\u6570\uff0c\u5ef6\u8fdf\u8c03\u7528\uff0c\u90a3\u5c31\u5fc5\u987b\u503c\u6355\u83b7 [=] \u3002 \u4ee5\u4e0a\u56db\u79cd\u60c5\u51b5\uff0c\u5206\u522b\u4ee3\u7801\u6f14\u793a\uff1a void func() { int i = 1; auto lambda = [&] () { return i; }; lambda(); } int main() { func(); } auto func() { int i = 1; return [=] () { return i; }; } int main() { auto lambda = func(); lambda(); } auto func(auto lambda) { lambda(); } int main() { int i = 1; func([&] () { return i; }); } vector> g_callbacks; auto func(auto lambda) { g_callbacks.push_back(lambda); } void init() { int i = 1; func([=] () { return i; }); } int main() { init(); for (auto cb: g_callbacks) { cb(); } }","title":"\u751f\u547d\u5468\u671f\u95ee\u9898\u603b\u7ed3\uff1a\u4f55\u65f6\u4f7f\u7528 [=] \u6216 [&]"},{"location":"lambda/#lambda-stl","text":"\u5206\u4e3a\u4e24\u79cd\u60c5\u51b5\uff1a","title":"lambda \u7528\u4e8e STL \u6a21\u677f\u7684\u4eff\u51fd\u6570\u53c2\u6570"},{"location":"lambda/#_37","text":"\u6a21\u677f\u51fd\u6570\u6bd4\u8f83\u7b80\u5355\uff0c\u76f4\u63a5\u5f80\u51fd\u6570\u53c2\u6570\u4e2d\u4f20\u5165 lambda \u5bf9\u8c61\u5373\u53ef\u3002 sort \uff1a std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::sort(a.begin(), a.end(), comp); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 shared_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::shared_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u7684\u5f15\u7528\u8ba1\u6570\u5f52\u96f6\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002","title":"\u6a21\u677f\u51fd\u6570"},{"location":"lambda/#_38","text":"\u800c\u6a21\u677f\u7c7b\u5219\u9700\u8981\u5148\u5728\u6a21\u677f\u53c2\u6570\u4e2d\u6307\u5b9a\u7c7b\u578b\uff0c\u7136\u540e\u5728\u6784\u9020\u51fd\u6570\u4e2d\u4f20\u5165\u53c2\u6570\u3002 std::vector a = {1, 4, 2, 8, 5, 7}; auto comp = [] (int i, int j) { return i < j; }; std::set sorted(comp); sorted.assign(a.begin(), a.end()); a.assign(sorted.begin(), sorted.end()); fmt::println(\"a = {}\", a); \u6548\u679c\uff1a\u5229\u7528 set \u5bb9\u5668\u6709\u5e8f\u7684\u7279\u70b9\uff0c\u5c06 a \u6570\u7ec4\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\u540e\u6253\u5370\u3002 unique_ptr \uff1a auto deleter = [] (FILE *fp) { fclose(fp); }; std::unique_ptr p(fopen(\"hello.txt\", \"r\"), deleter); \u6548\u679c\uff1a\u5f53 p \u6790\u6784\u65f6\uff0c\u8c03\u7528 fclose(p.get()) \u3002","title":"\u6a21\u677f\u7c7b"},{"location":"lambda/#lambda-stl_1","text":"TODO: count_if, erase_if, argsort","title":"lambda \u5728 STL \u4e2d\u7684\u4f7f\u7528\u6848\u4f8b"},{"location":"lambda/#_39","text":"\u4e8c\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b a < b std::less a > b std::greater a <= b std::less_equal a >= b std::greater_equal a == b std::equal_to a != b std::not_equal_to a <=> b std::compare_three_way (C++20) a && b std::logical_and a \\|\\| b std::logical_or a & b std::bit_and a \\| b std::bit_or a ^ b std::bit_xor a + b std::plus a - b std::minus a * b std::multiplies a / b std::divides a % b std::modulus \u4e00\u5143\u8fd0\u7b97\u7b26 \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b\u578b !a std::logical_not ~a std::bit_not -a std::negate a std::identity","title":"\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570"},{"location":"lambda/#bind","text":"\u539f\u59cb\u51fd\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { hello(2, 3); hello(2, 4); hello(2, 5); return 0; } \u7ed1\u5b9a\u90e8\u5206\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello2 = std::bind(hello, 2, std::placeholders::_1); hello2(3); // hello(2, 3) hello2(4); // hello(2, 4) hello2(5); // hello(2, 5) return 0; } std::placeholders::_1 \u8868\u793a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\u3002 std::placeholders::_1 \u5728 bind \u8868\u8fbe\u5f0f\u4e2d\u4f4d\u4e8e hello \u7684\u7684\u7b2c\u4e8c\u53c2\u6570\u4f4d\u7f6e\uff0c\u8fd9\u610f\u5473\u7740\uff1a\u628a hello2 \u7684\u7b2c\u4e00\u53c2\u6570\uff0c\u4f20\u9012\u5230 hello \u7684\u7b2c\u4e8c\u53c2\u6570\u4e0a\u53bb\u3002 \u7ed1\u5b9a\u5168\u90e8\u53c2\u6570\uff1a int hello(int x, int y) { fmt::println(\"hello({}, {})\", x, y); return x + y; } int main() { auto hello23 = std::bind(hello, 2, 3); hello23(); // hello(2, 3) return 0; } \u7ed1\u5b9a\u5f15\u7528\u53c2\u6570\uff1a int inc(int &x) { x += 1; } int main() { int x = 0; auto incx = std::bind(inc, std::ref(x)); incx(); fmt::println(\"x = {}\", x); // x = 1 incx(); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u5982\u679c\u4e0d\u4f7f\u7528 std::ref \uff0c\u90a3\u4e48 main \u91cc\u7684\u5c40\u90e8\u53d8\u91cf x \u4e0d\u4f1a\u6539\u53d8\uff01\u56e0\u4e3a std::bind \u6709\u4e00\u4e2a\u607c\u4eba\u7684\u8bbe\u8ba1\uff1a\u9ed8\u8ba4\u6309\u62f7\u8d1d\u6355\u83b7\uff0c\u4f1a\u628a\u53c2\u6570\u62f7\u8d1d\u4e00\u4efd\uff0c\u800c\u4e0d\u662f\u4fdd\u7559\u5f15\u7528\u3002 \u6709\u8da3\u7684\u662f\uff0cplaceholder \u6307\u5b9a\u7684\u53c2\u6570\uff0c\u5374\u4e0d\u9700\u8981 std::ref \u624d\u80fd\u4fdd\u6301\u5f15\u7528\uff1a int inc(int &x, int y) { x += y; } int main() { int x = 0; auto inc1 = std::bind(inc, std::placeholders::_1, 1); inc1(x); // \u6b64\u5904 x \u662f\u6309\u5f15\u7528\u4f20\u9012\u7684 fmt::println(\"x = {}\", x); // x = 1 inc1(x); fmt::println(\"x = {}\", x); // x = 2 return 0; } \u90a3\u662f\u56e0\u4e3a\uff0c std::placeholders::_1 \u6307\u5b9a\u7684\u53c2\u6570\u4f1a\u88ab\u76f4\u63a5\u5b8c\u7f8e\u8f6c\u53d1\u7ed9 inc \u91cc\u7684 x \uff0c\u76f8\u5f53\u4e8e inc(x, 2); \u3002\u53ea\u6709\u6355\u83b7\u7684\u53c2\u6570\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e0d\u4f1a\u5b8c\u7f8e\u8f6c\u53d1\u3002","title":"bind \u4e3a\u51fd\u6570\u5bf9\u8c61\u7ed1\u5b9a\u53c2\u6570"},{"location":"lambda/#bind_1","text":"\u5f53\u6211\u4eec\u7ed1\u5b9a\u51fa\u6765\u7684\u51fd\u6570\u5bf9\u8c61\u8fd8\u9700\u8981\u63a5\u53d7\u53c2\u6570\u65f6\uff0c\u5c31\u53d8\u5f97\u5c24\u4e3a\u590d\u6742\uff1a\u9700\u8981\u4f7f\u7528\u5360\u4f4d\u7b26\uff08placeholder\uff09\u3002 int func(int x, int y, int z, int &w); int w = rand(); auto bound = std::bind(func, std::placeholders::_2, 1, std::placeholders::_1, std::ref(w)); // int res = bound(5, 6); // \u7b49\u4ef7\u4e8e func(6, 1, 5, w); \u8fd9\u662f\u4e00\u4e2a\u7ed1\u5b9a\u5668\uff0c\u628a func \u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u548c\u7b2c\u56db\u4e2a\u53c2\u6570\u56fa\u5b9a\u4e0b\u6765\uff0c\u5f62\u6210\u4e00\u4e2a\u65b0\u7684\u51fd\u6570\u5bf9\u8c61\uff0c\u7136\u540e\u53ea\u9700\u8981\u4f20\u5165\u524d\u9762\u4e24\u4e2a\u53c2\u6570\u5c31\u53ef\u4ee5\u8c03\u7528\u539f\u6765\u7684\u51fd\u6570\u4e86\u3002 \u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u65e7\u7684\u6280\u672f\uff0cC++98 \u65f6\u4ee3\u5c31\u6709\u4e86\u3002\u4f46\u662f\uff0c\u73b0\u5728\u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u53ef\u4ee5\u66f4\u7b80\u6d01\u5730\u5b9e\u73b0\uff1a int func(int x, int y, int z, int &w); int w = rand(); auto lambda = [&w](int x, int y) { return func(y, 1, x, w); }; int res = lambda(5, 6); Lambda \u8868\u8fbe\u5f0f\u6709\u8bb8\u591a\u4f18\u52bf\uff1a \u7b80\u6d01\uff1a\u4e0d\u9700\u8981\u5199\u4e00\u5927\u5806\u770b\u4e0d\u61c2\u7684 std::placeholders::_1 \uff0c\u76f4\u63a5\u5199\u53d8\u91cf\u540d\u5c31\u53ef\u4ee5\u4e86\u3002 \u7075\u6d3b\uff1a\u53ef\u4ee5\u5728 Lambda \u4e2d\u4f7f\u7528\u4efb\u610f\u591a\u7684\u53d8\u91cf\uff0c\u8c03\u6574\u987a\u5e8f\uff0c\u800c\u4e0d\u4ec5\u4ec5\u662f std::placeholders::_1 \u3002 \u6613\u61c2\uff1a\u5199\u8d77\u6765\u548c\u666e\u901a\u51fd\u6570\u8c03\u7528\u4e00\u6837\uff0c\u6240\u6709\u4eba\u90fd\u5bb9\u6613\u770b\u61c2\u3002 \u6355\u83b7\u5f15\u7528\uff1a std::bind \u4e0d\u652f\u6301\u6355\u83b7\u5f15\u7528\uff0c\u603b\u662f\u62f7\u8d1d\u53c2\u6570\uff0c\u5fc5\u987b\u914d\u5408 std::ref \u624d\u80fd\u6355\u83b7\u5230\u5f15\u7528\u3002\u800c Lambda \u53ef\u4ee5\u968f\u610f\u6355\u83b7\u4e0d\u540c\u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309\u503c\uff08 [x] \uff09\u6216\u6309\u5f15\u7528\uff08 [&x] \uff09\uff0c\u8fd8\u53ef\u4ee5\u79fb\u52a8\u6355\u83b7\uff08 [x = move(x)] \uff09\uff0c\u751a\u81f3\u6355\u83b7 this\uff08 [this] \uff09\u3002 \u5939\u5e26\u79c1\u8d27\uff1a\u53ef\u4ee5\u5728 lambda \u4f53\u5185\u5f88\u65b9\u4fbf\u5730\u5939\u5e26\u5176\u4ed6\u989d\u5916\u8f6c\u6362\u64cd\u4f5c\uff0c\u6bd4\u5982\uff1a auto lambda = [&w](int x, int y) { return func(y + 8, 1, x * x, ++w) * 2; };","title":"bind \u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1"},{"location":"lambda/#bind_2","text":"\u4e3a\u4ec0\u4e48 C++11 \u6709\u4e86 Lambda \u8868\u8fbe\u5f0f\uff0c\u8fd8\u8981\u63d0\u51fa std::bind \u5462\uff1f \u867d\u7136 bind \u548c lambda \u770b\u4f3c\u90fd\u662f\u5728 C++11 \u5f15\u5165\u7684\uff0c\u5b9e\u9645\u4e0a bind \u7684\u63d0\u51fa\u8fdc\u8fdc\u65e9\u4e8e lambda\u3002 \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u6211\u4eec\u4e0d\u751f\u4ea7\u5e93\uff0c\u6211\u4eec\u53ea\u662f boost \u7684\u642c\u8fd0\u5de5\u3002 \u5f53\u65f6\u8fd8\u662f C++98\uff0c\u7531\u4e8e\u6ca1\u6709 lambda\uff0c\u96be\u4ee5\u521b\u5efa\u51fd\u6570\u5bf9\u8c61\uff0c\u201c\u6355\u83b7\u53c2\u6570\u201d\u975e\u5e38\u56f0\u96be\u3002 \u4e3a\u4e86\u89e3\u51b3\u201c\u6355\u83b7\u96be\u201d\u95ee\u9898\uff0c\u5728\u7b2c\u4e09\u65b9\u5e93 boost \u4e2d\u63d0\u51fa\u4e86 boost::bind \uff0c\u7531\u4e8e\u5f53\u65f6\u53ea\u6709 C++98\uff0c\u5f88\u591a\u6709\u76ca\u4e8e\u51fd\u6570\u5f0f\u7f16\u7a0b\u7684\u7279\u6027\u90fd\u6ca1\u6709\uff0c\u6240\u4ee5\u5b9e\u73b0\u7684\u975e\u5e38\u4e11\u964b\u3002 \u4f8b\u5982\uff0c\u56e0\u4e3a C++98 \u6ca1\u6709\u53d8\u957f\u6a21\u677f\u53c2\u6570\uff0c\u65e0\u6cd5\u5b9e\u73b0 \u3002\u6240\u4ee5\u5b9e\u9645\u4e0a\u5f53\u65f6 boost \u6240\u6709\u652f\u6301\u591a\u53c2\u6570\u7684\u51fd\u6570\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u901a\u8fc7\uff1a void some_func(); void some_func(int i1); void some_func(int i1, int i2); void some_func(int i1, int i2, int i3); void some_func(int i1, int i2, int i3, int i4); // ... \u8fd9\u6837\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u51fd\u6570\u6765\u5b9e\u73b0\u7684\uff0c\u800c\u4e14\u53c2\u6570\u6570\u91cf\u6709\u4e0a\u9650\u3002\u901a\u5e38\u4f1a\u5b9e\u73b0 0 \u5230 20 \u4e2a\u53c2\u6570\u7684\u91cd\u8f7d\uff0c\u66f4\u591a\u5c31\u4e0d\u652f\u6301\u4e86\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u77e5\u9053\u73b0\u5728 bind \u9700\u8981\u914d\u5408\u5404\u79cd std::placeholders::_1 \u4f7f\u7528\uff0c\u6709\u6ca1\u6709\u60f3\u8fc7\u8fd9\u5957\u4e11\u964b\u7684\u5360\u4f4d\u7b26\u662f\u4e3a\u4ec0\u4e48\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u7528 std::placeholder<1> \uff0c\u8fd9\u6837\u4e0d\u662f\u66f4\u53ef\u6269\u5c55\u5417\uff1f \u6ca1\u9519\uff0c\u5f53\u65f6 boost::bind \u5c31\u662f\u7528\u66b4\u529b\u91cd\u8f7d\u51e0\u5341\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u7b49\u7684\u51fd\u6570\uff0c\u6392\u5217\u7ec4\u5408\uff0c\u55ef\u662f\u6392\u51fa\u6765\u7684\uff0c\u6240\u4ee5\u6211\u4eec\u4f1a\u770b\u5230 boost::placeholders \u53ea\u6709\u6709\u9650\u4e2a\u6570\u7684\u5360\u4f4d\u7b26\u6570\u91cf\u3002 \u7cdf\u7cd5\u7684\u662f\uff0c\u6807\u51c6\u5e93\u7684 std::bind \u628a boost::bind \u539f\u5c01\u4e0d\u52a8\u642c\u4e86\u8fc7\u6765\uff0c\u751a\u81f3 placeholders \u7684\u66b4\u529b\u7ec4\u5408\u4e5f\u6ca1\u6709\u53d8\uff0c\u9020\u6210\u4e86 std::bind \u5982\u4eca\u4e11\u964b\u7684\u63a5\u53e3\u3002 \u4eba\u5bb6 boost::bind \u662f\u56e0\u4e3a\u4e0d\u80fd\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\uff0c\u624d\u53ea\u80fd\u90a3\u6837\u618b\u5c48\u7684\u554a\uff1f\u53ef\u73b0\u5728\u4f60\u7801\u662f\u6807\u51c6\u59d4\u5458\u4f1a\u554a\uff0c\u4f60\u53ef\u4ee5\u4fee\u6539\u8bed\u8a00\u8bed\u6cd5\u554a\uff1f \u7136\u800c\uff0cC++ \u6807\u51c6\u7684\u66f4\u65b0\u662f\u4ee5\u201c\u63d0\u6848\u201d\u7684\u65b9\u5f0f\uff0c\u9010\u6b65\u201c\u589e\u91cf\u201d\u66f4\u65b0\u8fdb\u5165\u8bed\u8a00\u6807\u51c6\u7684\u3002\u5373\u4f7f\u662f\u5728 C++98 \u5230 C++11 \u8fd9\u6bb5\u65f6\u95f4\u5185\uff0c\u5185\u90e8\u4e5f\u662f\u6709\u4e00\u4e2a\u5f88\u957f\u7684\u6d88\u5316\u6d41\u7a0b\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\u6709\u5f88\u591a\u5b50\u7248\u672c\uff0c\u53ea\u662f\u5bf9\u5916\u770b\u8d77\u6765\u597d\u50cf\u53ea\u6709\u4e00\u4e2a C++11\u3002 \u6bd4\u65b9\u8bf4\uff0c\u6211 2001 \u5e74\u63d0\u51fa std::bind \u63d0\u6848\uff0c2005 \u5e74\u88ab\u6279\u51c6\u8fdb\u5165\u672a\u6765\u5c06\u8981\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u7136\u540e\u53c8\u4e00\u4e2a\u4eba\u5728 2006 \u5e74\u63d0\u51fa\u5176\u5b9e\u4e0d\u9700\u8981 bind\uff0c\u5b8c\u5168\u53ef\u4ee5\u7528\u66f4\u597d\u7684 lambda \u8bed\u6cd5\u6765\u4ee3\u66ff bind\uff0c\u7136\u540e\u7b49\u5230\u4e86 2008 \u5e74\u624d\u6279\u51c6\u8fdb\u5165\u5373\u5c06\u53d1\u5e03\u7684 C++11 \u6807\u51c6\u3002\u4f46\u662f\u5df2\u7ecf\u8fdb\u5165\u6807\u51c6\u7684\u4e1c\u897f\u5c31\u4e0d\u4f1a\u518d\u9000\u51fa\u4e86\uff0c\u54ea\u6015\u8fd8\u6ca1\u6709\u53d1\u5e03\u3002\u5c31\u8fd9\u6837 bind \u548c lambda \u540c\u65f6\u8fdb\u5165\u4e86\u6807\u51c6\u3002 \u6240\u4ee5\u95f9\u4e86\u534a\u5929\uff0clambda \u5b9e\u9645\u4e0a\u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\uff0c\u6709\u4e86 lambda \u6839\u672c\u4e0d\u9700\u8981 bind \u7684\u3002\u53ea\u4e0d\u8fc7\u662f\u7531\u4e8e C++ \u59d4\u5458\u4f1a\u524d\u540e\u626f\u76ae\u7684\u201c\u5236\u5ea6\u4f18\u52bf\u201d\uff0c\u5bfc\u81f4 bind \u548c\u4ed6\u7684\u4e0a\u4f4d\u66ff\u4ee3 lambda \u540c\u65f6\u8fdb\u5165\u4e86 C++11 \u6807\u51c6\u4e00\u8d77\u53d1\u5e03\u3002 \u8fd9\u4e0b\u770b\u61c2\u4e86\u3002 \u5f88\u591a\u540c\u5b66\u5c31\u4e0d\u7406\u89e3\uff0c\u5c0f\u5f6d\u8001\u5e08\u8bf4\u201clambda \u662f bind \u7684\u4e0a\u4f4d\u66ff\u4ee3\u201d\uff0c\u4ed6\u5c31\u8d28\u7591\u201c\u53ef\u4ed6\u4eec\u4e0d\u90fd\u662f C++11 \u63d0\u51fa\u7684\u5417\uff1f\u201d \u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cC++11 \u548c C++98 \u4e4b\u95f4\u4e3a\u4ec0\u4e48\u5e74\u4ee3\u5dee\u4e86\u90a3\u4e48\u4e45\u8fdc\uff0c\u5c31\u662f\u56e0\u4e3a\u4e00\u4e2a\u6807\u51c6\u4e00\u62d6\u518d\u62d6\uff0c\u5185\u90e8\u5b9e\u9645\u4e0a\u5df2\u7ecf\u8fed\u4ee3\u4e86\u597d\u51e0\u4e2a\u5c0f\u7248\u672c\u4e86\uff0c\u624d\u53d1\u5e03\u51fa\u6765\u3002 \u518d\u4e3e\u4e2a\u4f8b\u5b50\uff0cCTAD \u548c optional \u90fd\u662f C++17 \u5f15\u5165\u7684\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981 make_optional \u8fd9\u4e2a\u5e2e\u624b\u51fd\u6570\uff1f\u4e0d\u662f\u8bf4 CTAD \u662f make_xxx \u7684\u4e0a\u4f4d\u66ff\u4ee3\u5417\uff1f\u53ef\u89c1\uff0cC++ \u6807\u51c6\u4e2d\u8fd9\u79cd\u201c\u540c\u4e00\u4e2a\u7248\u672c\u5185\u201d\u81ea\u5df1\u6253\u81ea\u5df1\u8033\u5149\u7684\u73b0\u8c61\u6bd4\u6bd4\u7686\u662f\u3002 \u6240\u4ee5\uff0c\u73b0\u5728\u8fd8\u575a\u6301\u7528 bind \u7684\uff0c\u90fd\u662f\u4e9b 2005 \u5e74\u524d\u540e\u5728\u8c61\u7259\u5854\u63a5\u53d7 C++ \u6559\u80b2\uff0c\u4f46\u53c8\u4e0d\u80af\u201c\u7ec8\u8eab\u5b66\u4e60\u201d\u7684\u52b3\u4fdd\u3002\u8fd9\u6279\u52b3\u4fdd\u53c8\u53bb\u201c\u4e0a\u5cb8\u201d\u5f53\u201c\u6559\u5e08\u201d\uff0c\u7ee7\u7eed\u590d\u5236 2005 \u5e74\u7684\u9519\u8bef\u6bd2\u5bb3\u9752\u5c11\u5e74\uff0c\u5b9e\u73b0\u4e86\u52b3\u4fdd\u7684\u518d\u751f\u4ea7\u3002","title":"bind \u7684\u5386\u53f2"},{"location":"lambda/#thread","text":"\u7cdf\u7cd5\u7684\u662f\uff0cbind \u7684\u8fd9\u79cd\u837c\u6bd2\uff0c\u751a\u81f3\u5f71\u54cd\u5230\u4e86\u7ebf\u7a0b\u5e93\uff1a std::thread \u7684\u6784\u9020\u51fd\u6570\u5c31\u662f\u57fa\u4e8e std::bind \u7684\uff01 \u8fd9\u5bfc\u81f4\u4e86 std::thread \u548c std::bind \u4e00\u6837\uff0c\u65e0\u6cd5\u6355\u83b7\u5f15\u7528\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t(thread_func, x); t.join(); printf(\"%d\\n\", x); // 0 \u4e3a\u4e86\u907f\u514d\u8e29\u5230 bind \u7684\u5751\uff0c\u6211\u5efa\u8bae\u6240\u6709\u540c\u5b66\uff0c\u6784\u9020 std::thread \u65f6\uff0c\u7edf\u4e00\u53ea\u6307\u5b9a\u201c\u5355\u4e2a\u53c2\u6570\u201d\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u672c\u8eab\u3002\u5982\u679c\u9700\u8981\u6355\u83b7\u53c2\u6570\uff0c\u8bf7\u4f7f\u7528 lambda\u3002\u56e0\u4e3a lambda \u4e2d\uff0c\u6355\u83b7\u4e86\u54ea\u4e9b\u53d8\u91cf\uff0c\u53c2\u6570\u7684\u987a\u5e8f\u662f\u4ec0\u4e48\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u5f15\u7528\uff0c\u54ea\u4e9b\u6355\u83b7\u662f\u62f7\u8d1d\uff0c\u975e\u5e38\u6e05\u6670\u3002 void thread_func(int &x) { x = 42; } int x = 0; std::thread t([&x] { // [&x] \u8868\u793a\u6309\u5f15\u7528\u6355\u83b7 x\uff1b\u5982\u679c\u5199\u4f5c [x]\uff0c\u90a3\u5c31\u662f\u62f7\u8d1d\u6355\u83b7 thread_func(x); }); t.join(); printf(\"%d\\n\", x); // 42","title":"thread \u819d\u76d6\u4e2d\u7bad"},{"location":"lambda/#_40","text":"bind \u5199\u6cd5\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = std::bind(uni, std::ref(gen)); double x = frand(); double y = frand(); \u6539\u7528 lambda\uff1a std::mt19937 gen(seed); std::uniform_real_distribution uni(0, 1); auto frand = [uni, &gen] { return uni(gen); }; double x = frand(); double y = frand();","title":"\u6848\u4f8b\uff1a\u7ed1\u5b9a\u968f\u673a\u6570\u751f\u6210\u5668"},{"location":"lambda/#stdbind_front-stdbind_back","text":"C++17 \u5f15\u5165\u4e86\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\uff1a std::bind_front \uff1a\u7ed1\u5b9a\u6700\u524d\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u540e\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\uff1b std::bind_back \uff1a\u7ed1\u5b9a\u672b\u5c3e\u7684\u82e5\u5e72\u4e2a\u53c2\u6570\uff0c\u524d\u9762\u7684\u53c2\u6570\u81ea\u52a8\u6dfb\u52a0\u5360\u4f4d\u7b26\u3002 \u548c\u666e\u901a\u7684 std::bind \u76f8\u6bd4\u6709\u4ec0\u4e48\u597d\u5904\u5462\uff1f \u5bf9\u4e8e\u51fd\u6570\u53c2\u6570\u975e\u5e38\u591a\uff0c\u4f46\u5b9e\u9645\u53ea\u9700\u8981\u7ed1\u5b9a\u4e00\u4e24\u4e2a\u53c2\u6570\u7684\u60c5\u51b5\uff0c\u7528 std::bind \u4f1a\u9700\u8981\u6dfb\u52a0\u975e\u5e38\u591a\u7684 placeholder\uff0c\u6570\u91cf\u548c\u51fd\u6570\u7684\u5269\u4f59\u53c2\u6570\u6570\u91cf\u4e00\u6837\u591a\u3002\u800c std::bind_front \u5219\u76f8\u5f53\u4e8e\u4e00\u4e2a\u7b80\u5199\uff0c\u540e\u9762\u7684\u5360\u4f4d\u7b26\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\u4e86\u3002 \u4f8b\u5982\u7ed1\u5b9a x = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, 42, std::placeholders::_1, std::placeholders::_2); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_front(func, 42); \u7ed1\u5b9a z = 42\uff1a int func(int x, int y, int z); auto bound = std::bind(func, std::placeholders::_1, std::placeholders::_2, 42); // \u7b49\u4ef7\u4e8e\uff1a auto bound = std::bind_back(func, 42); \u53ef\u4ee5\u770b\u5230\uff0c\u4f7f\u7528\u8fd9\u4e24\u4e2a\u65b0\u7ed1\u5b9a\u51fd\u6570\u660e\u663e\u5199\u7684\u4ee3\u7801\u5c11\u4e86\u3002 \u5176\u4e2d\u6700\u5e38\u7528\u7684\u662f std::bind_front \uff0c\u7528\u4e8e\u7ed1\u5b9a\u7c7b\u6210\u5458\u7684 this \u6307\u9488\u3002","title":"std::bind_front \u548c std::bind_back"},{"location":"lambda/#_41","text":"\u4f7f\u7528\u201c\u6210\u5458\u51fd\u6570\u6307\u9488\u201d\u8bed\u6cd5\uff08\u8fd9\u4e00\u5947\u8469\u8bed\u6cd5\u5728 C++98 \u5c31\u6709\uff09\u914d\u5408 std::bind \uff0c\u53ef\u4ee5\u5b9e\u73b0\u7ed1\u5b9a\u4e00\u4e2a\u7c7b\u578b\u7684\u6210\u5458\u51fd\u6570\uff1a struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = std::bind(&Class::world, this); // \u5c06 this->world \u7ed1\u5b9a\u6210\u4e00\u4e2a\u53ef\u4ee5\u5ef6\u540e\u8c03\u7528\u7684\u51fd\u6570\u5bf9\u8c61 memfn(); memfn(); } } \u4e0d\u5c31\u662f\u6355\u83b7 this \u5417\uff1f\u6211\u4eec lambda \u4e5f\u53ef\u4ee5\u8f7b\u6613\u505a\u5230\uff01\u4e14\u65e0\u9700\u7e41\u7410\u5730\u5199\u51fa this \u7c7b\u7684\u5b8c\u6574\u7c7b\u540d\uff0c\u8fd8\u5199\u4e2a\u8111\u762b &:: \u5f3a\u78b1\u4f60\u7684\u952e\u76d8\u3002 struct Class { void world() { puts(\"world!\"); } void hello() { auto memfn = [this] { world(); // \u7b49\u4ef7\u4e8e this->world() }; memfn(); memfn(); } } bind \u7684\u7f3a\u70b9\u662f\uff0c\u5f53\u6211\u4eec\u7684\u6210\u5458\u51fd\u6570\u542b\u6709\u591a\u4e2a\u53c2\u6570\u65f6\uff0cbind \u5c31\u975e\u5e38\u9ebb\u70e6\u4e86\uff1a\u9700\u8981\u4e00\u4e2a\u4e2a\u5199\u51fa placeholder\uff0c\u800c\u4e14\u6570\u91cf\u5fc5\u987b\u548c world \u7684\u53c2\u6570\u6570\u91cf\u4e00\u81f4\u3002\u6bcf\u6b21 world \u8981\u65b0\u589e\u53c2\u6570\u65f6\uff0c\u6240\u6709 bind \u7684\u5730\u65b9\u90fd\u9700\u8981\u52a0\u4e00\u4e0b placeholder\uff0c\u975e\u5e38\u6c99\u96d5\u3002 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3, 4); } } \u800c\u4e14\uff0c\u5982\u679c\u6709\u8981\u7ed1\u5b9a\u7684\u76ee\u6807\u51fd\u6570\u6709\u591a\u4e2a\u53c2\u6570\u6570\u91cf\u4e0d\u540c\u7684\u91cd\u8f7d\uff0c\u90a3 bind \u5c31\u5b8c\u5168\u4e0d\u80fd\u5de5\u4f5c\u4e86\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind(&Class::world, this, std::placeholders::_1, std::placeholders::_2); memfn(1, 2); memfn(3.14); // \u7f16\u8bd1\u51fa\u9519\uff01\u6b7b\u6263\u5360\u4f4d\u7b26\u7684 bind \u5fc5\u987b\u8981\u6c42\u4e24\u4e2a\u53c2\u6570\uff0c\u5373\u4f7f world \u660e\u660e\u6709\u5355\u53c2\u6570\u7684\u91cd\u8f7d auto memfn_1arg = std::bind(&Class::world, this, std::placeholders::_1); memfn_1arg(3.14); // \u5fc5\u987b\u91cd\u65b0\u7ed1\u5b9a\u4e00\u4e2a\u201c\u5355\u53c2\u6570\u7248\u201d\u624d OK } }","title":"\u6848\u4f8b\uff1a\u7ed1\u5b9a\u6210\u5458\u51fd\u6570"},{"location":"lambda/#stdbind_front","text":"\u4e3a\u4e86\u89e3\u51b3 bind \u4e0d\u80fd\u6355\u83b7\u591a\u53c2\u6570\u91cd\u8f7d\u7684\u60c5\u51b5\uff0cC++17 \u5f15\u5165\u4e86 std::bind_front \u548c std::bind_back \uff0c\u4ed6\u4eec\u4e0d\u9700\u8981 placeholder\uff0c\u4f46\u53ea\u80fd\u7528\u4e8e\u8981\u7ed1\u5b9a\u7684\u53c2\u6570\u5728\u6700\u524d\u6216\u8005\u6700\u540e\u7684\u7279\u6b8a\u60c5\u51b5\u3002 \u5176\u4e2d std::bind_front \u5bf9\u4e8e\u6211\u4eec\u53ea\u9700\u8981\u628a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7ed1\u5b9a\u4e3a this \uff0c\u5176\u4ed6\u53c2\u6570\u5982\u6570\u8f6c\u53d1\u7684\u573a\u666f\uff0c\u7b80\u76f4\u662f\u96ea\u4e2d\u9001\u70ad\uff01 struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = std::bind_front(&Class::world, this); memfn(1, 2); memfn(3.14); // OK\uff01 } } auto memfn = std::bind_front(&Class::world, this); // C++17 \u7684 bind \u5b5d\u5b50\u8865\u6551\u63aa\u65bd auto memfn = BIND(world, this); // \u5c0f\u5f6d\u8001\u5e08\u7684 BIND \u5b8f\uff0cC++14 \u8d77\u53ef\u7528 \u4f60\u66f4\u559c\u6b22\u54ea\u4e00\u79cd\u5462\uff1f","title":"\u4f7f\u7528 std::bind_front \u4ee3\u66ff"},{"location":"lambda/#lambda_2","text":"\u800c C++14 \u8d77 lambda \u652f\u6301\u4e86\u53d8\u957f\u53c2\u6570\uff0c\u5c31\u4e0d\u7528\u8fd9\u4e48\u6b7b\u677f\uff1a struct Class { void world(int x, int y) { printf(\"world(%d, %d)\\n\"); } void world(double x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto ...args) { // \u8ba9 lambda \u63a5\u53d7\u4efb\u610f\u53c2\u6570 world(args...); // \u62f7\u8d1d\u8f6c\u53d1\u6240\u6709\u53c2\u6570\u7ed9 world }; memfn(1, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } } \u66f4\u597d\u7684\u662f\u914d\u5408 forward \u5b9e\u73b0\u53c2\u6570\u7684\u5b8c\u7f8e\u8f6c\u53d1\uff1a struct Class { void world(int &x, int &&y) { printf(\"world(%d, %d)\\n\"); ++x; } void world(double const &x) { printf(\"world(%d)\\n\"); } void hello() { auto memfn = [this] (auto &&...args) { // \u8ba9 lambda \u63a5\u53d7\u4e07\u80fd\u5f15\u7528\u505a\u53c2\u6570 world(std::forward(args)...); // \u901a\u8fc7 FWD \u5b8c\u7f8e\u8f6c\u53d1\u7ed9 world\uff0c\u907f\u514d\u5f15\u7528\u9000\u5316 }; int x = 1; memfn(x, 2); // \u53cc\u53c2\u6570\uff1aOK memfn(3.14); // \u5355\u53c2\u6570\uff1aOK } }","title":"\u4f7f\u7528 lambda \u4ee3\u66ff"},{"location":"lambda/#bind_3","text":"TODO\uff1a std::less \u548c std::bind","title":"bind \u4e0e\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u914d\u5408"},{"location":"lambda/#c","text":"","title":"\u51fd\u6570\u6307\u9488\u662f C \u8bed\u8a00\u964b\u4e60\uff0c\u6539\u6389"},{"location":"lambda/#lambda_3","text":"","title":"lambda \u8fdb\u9636\u6848\u4f8b"},{"location":"lambda/#lambda_4","text":"","title":"lambda \u5b9e\u73b0\u9012\u5f52"},{"location":"lambda/#lambda_5","text":"","title":"lambda \u907f\u514d\u5168\u5c40\u91cd\u8f7d\u51fd\u6570\u6355\u83b7\u4e3a\u53d8\u91cf\u65f6\u607c\u4eba\u7684\u9519\u8bef"},{"location":"lambda/#lambda-if-constexpr","text":"","title":"lambda \u914d\u5408 if-constexpr \u5b9e\u73b0\u7f16\u8bd1\u671f\u4e09\u76ee\u8fd0\u7b97\u7b26"},{"location":"lambda/#c23-stdmove_only_function-stdfunction","text":"\u901a\u8fc7\u6309\u503c\u79fb\u52a8\u6355\u83b7 [p = std::move(p)] \uff0clambda \u53ef\u4ee5\u6301\u6709\u4e00\u4e2a unique_ptr \u4f5c\u4e3a\u6355\u83b7\u53d8\u91cf\u3002 \u4f46\u662f\uff0c\u6211\u4eec\u4f1a\u53d1\u73b0\uff0c\u8fd9\u6837\u521b\u5efa\u51fa\u6765\u7684 lambda\uff0c\u5b58\u5165 std::function \u65f6\u4f1a\u62a5\u9519\uff1a TODO: \u4ee3\u7801","title":"\u63a8\u8350\u7528 C++23 \u7684 std::move_only_function \u53d6\u4ee3 std::function"},{"location":"lambda/#lambda_6","text":"","title":"\u65e0\u72b6\u6001 lambda \u9690\u5f0f\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488"},{"location":"lambda/#stdvariant-stdvisit","text":"TODO: \u4ee3\u7801\u6848\u4f8b \u5728\u4e4b\u540e\u7684 std::variant \u4e13\u9898\u7ae0\u8282 \u4e2d\u4f1a\u8fdb\u4e00\u6b65\u4ecb\u7ecd\u3002","title":"\u4e0e std::variant \u548c std::visit \u914d\u5408\u5b9e\u73b0\u52a8\u6001\u591a\u6001"},{"location":"lambda/#shared_from_this-this","text":"","title":"\u914d\u5408 shared_from_this \u5b9e\u73b0\u5ef6\u957f this \u751f\u547d\u5468\u671f"},{"location":"lambda/#mutable-lambda","text":"","title":"mutable lambda \u5b9e\u73b0\u8ba1\u6570\u5668"},{"location":"lambda/#c20-lambda","text":"","title":"C++20 \u4e2d\u7684 lambda \u6269\u5c55\u7528\u6cd5"},{"location":"llvm_intro/","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM \u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM LLVM \u4ecb\u7ecd \u53c2\u8003\u8d44\u6599 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u4e00\u70b9\u5fe0\u544a LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 Linux/MacOS \u7528\u6237 Windows \u7528\u6237 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 \u5f00\u59cb\u6784\u5efa \u8fd0\u884c\u8bd5\u8bd5 \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u8bed\u6cd5\u6811\uff08AST\uff09 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 LLVM IR \u7684\u7279\u70b9 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u7c7b\u578b\u7cfb\u7edf \u57fa\u7840\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u6307\u9488\u7c7b\u578b \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM IR \u6848\u4f8b\u5206\u6790 target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f define \u5b9a\u4e49\u51fd\u6570 alloca \u6307\u4ee4 store \u6307\u4ee4 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 load \u6307\u4ee4 add \u6307\u4ee4 ret \u6307\u4ee4 \u4e3a\u51fd\u6570\u6307\u5b9a attributes Clang \u751f\u6210 IR \u6c47\u7f16 \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c \u4e4b\u95f4\u7684\u8f6c\u6362 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u8c03\u7528 LLVM pass \u4f18\u5316 \u6848\u4f8b \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417 LLVM \u4ecb\u7ecd LLVM \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\u57fa\u7840\u8bbe\u65bd\uff0c\u5b83\u4e0d\u662f\u4e00\u4e2a\u5355\u4e00\u7684\u7f16\u8bd1\u5668\uff0c\u800c\u662f\u4e00\u7cfb\u5217\u5de5\u5177\u548c\u5e93\u7684\u96c6\u5408\uff0c\u5176\u63d0\u4f9b\u4e30\u5bcc\u7684\u6570\u636e\u7ed3\u6784 (ADT) \u548c\u4e2d\u95f4\u8868\u793a\u5c42 (IR)\uff0c\u662f\u5b9e\u73b0\u7f16\u8bd1\u5668\u7684\u6700\u4f73\u6846\u67b6\u3002 LLVM \u662f\u7f16\u8bd1\u5668\u7684\u4e2d\u540e\u7aef\uff0c\u4e2d\u7aef\u8d1f\u8d23\u4f18\u5316\uff0c\u540e\u7aef\u8d1f\u8d23\u6700\u7ec8\u6c47\u7f16\u4ee3\u7801\u7684\u751f\u6210\uff0c\u4ed6\u5e76\u4e0d\u5728\u4e4e\u8c03\u7528\u4ed6\u7684\u4ec0\u4e48\u9ad8\u7ea7\u8bed\u8a00\uff0c\u53ea\u8d1f\u8d23\u628a\u62bd\u8c61\u7684\u4ee3\u6570\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\uff0c\u57fa\u672c\u5757\uff0c\u8f6c\u5316\u4e3a\u8ba1\u7b97\u673a\u786c\u4ef6\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u4e5f\u6709\u4e9b\u6c99\u96d5\u6559\u6750\u4f1a\u628a\u4e2d\u7aef\u548c\u540e\u7aef\u7edf\u79f0\u4e3a\u540e\u7aef\u2026\u2026 Clang \u53ea\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u524d\u7aef\uff0c\u5176\u8d1f\u8d23\u7f16\u8bd1 C/C++ \u8fd9\u7c7b\u8bed\u8a00\uff0c\u8fd8\u6709\u7528\u4e8e\u7f16\u8bd1 Fotran \u7684 Flang \u524d\u7aef\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u8bf8\u5982 Rust\u3001Swift\u3001Haskell \u4e4b\u7c7b\u7684\u8bed\u8a00\uff0c\u4e5f\u90fd\u5728\u4f7f\u7528 LLVM \u505a\u540e\u7aef\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6790\u6784\u51fd\u6570\u5728 } \u5904\u8c03\u7528\uff0c\u8fd9\u662f C++ \u7684\u8bed\u6cd5\u89c4\u5219\uff0c\u5728 Clang \u524d\u7aef\u4e2d\u5904\u7406\u3002\u5f53 Clang \u5b8c\u6210 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u8bed\u4e49\u89c4\u5219\u7684\u89e3\u6790\u540e\uff0c\u5c31\u4f1a\u521b\u5efa\u4e00\u79cd\u53eb\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff0cIntermediate Representation\uff09\u7684\u4e1c\u897f\uff0c\u585e\u7ed9 LLVM \u540e\u7aef\u3002\u5728 IR \u5c42\u9762\uff0c\u6790\u6784\u51fd\u6570\u548c\u666e\u901a C \u8bed\u8a00\u51fd\u6570\u5df2\u7ecf\u6ca1\u6709\u533a\u522b\uff0c\u90fd\u662f\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\u5728 Clang \u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u786e\u5b9a\uff08\u57fa\u4e8e C++ \u8bed\u6cd5\u89c4\u5219\u51b3\u5b9a\uff09\u3002LLVM \u5e76\u4e0d\u5173\u5fc3\u8fd9\u4e2a\u51fd\u6570\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f Rust \u51fd\u6570\uff0c\u4ed6\u53ea\u77e5\u9053\u8fd9\u662f\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u53ea\u9700\u8981\u8fd9\u4e2a\u4fe1\u606f\uff0c\u5c31\u53ef\u4ee5\u53bb\u505a\u4f18\u5316\u4e86\u3002 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u5982\u679c\u6ca1\u6709 IR \u4f1a\u600e\u6837\uff1f\u5047\u8bbe\u6709 M M \u79cd\u8bed\u8a00\uff0c N N \u79cd\u786c\u4ef6\uff0c\u5c31\u9700\u8981\u91cd\u590d\u5b9e\u73b0 M \\times N M \\times N \u4e2a\u7f16\u8bd1\u5668\uff01\u800c IR \u4f5c\u4e3a\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4ee4\u8bed\u8a00\u548c\u786c\u4ef6\u7684\u5177\u4f53\u7ec6\u8282\u89e3\u8026\u4e86\uff0c\u4ece\u800c\u53ea\u9700\u8981\u5199 M + N M + N \u4efd\u4ee3\u7801\u5c31\u53ef\u4ee5\uff1a\u8bed\u8a00\u7684\u5f00\u53d1\u8005\u53ea\u9700\u8981\u8003\u8651\u8bed\u6cd5\u5982\u4f55\u53d8\u6210\u6570\u5b66\u8fd0\u7b97\u548c\u63a7\u5236\u6d41\uff0c\u786c\u4ef6\u5382\u5546\u53ea\u9700\u8981\u8003\u8651\u5982\u4f55\u628a\u6570\u5b66\u548c\u8df3\u8f6c\u6307\u4ee4\u53d8\u6210\u81ea\u5df1\u7279\u5b9a\u7684\u673a\u5668\u7801\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u662f LLVM/Clang \u8fd8\u662f GCC \u5bb6\u65cf\uff0c\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u5185\u90e8\u90fd\u65e0\u4e00\u4f8b\u5916\u91c7\u7528\u4e86 IR \u505a\u4e2d\u95f4\u8868\u793a\u3002 \u6709\u4e86\u7edf\u4e00\u7684\u62bd\u8c61 IR \u4ee5\u540e\uff0c\u4e0d\u7ba1\u4f60\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f C \u8bed\u8a00\u666e\u901a\u51fd\u6570\uff0c\u8fdb\u4e86 IR \u4ee5\u540e\u90fd\u662f\u4e00\u6837\u7684\u51fd\u6570\u8c03\u7528\uff0c\u51cf\u8f7b\u4e86\u7f16\u8bd1\u5668\u4e2d\u540e\u7aef\u5f00\u53d1\u8005\u7684\u5fc3\u667a\u8d1f\u62c5\u3002\u8981\u5f00\u53d1\u4e00\u79cd\u65b0\u8bed\u8a00\uff0c\u53ea\u7ba1\u89e3\u6790\u5b8c\u8bed\u6cd5\u751f\u6210 IR \u8f93\u5165 LLVM\uff0c\u4ed6\u4f1a\u66ff\u4f60\u5305\u529e\u597d\u4f18\u5316\u548c\u6c47\u7f16\u7684\u4e8b\u3002 \u53c2\u8003\u8d44\u6599 LLVM \u5b98\u65b9\u4ed3\u5e93\uff1ahttps://github.com/llvm/llvm-project LLVM \u7528\u6237\u6587\u6863\uff1ahttps://llvm.org/docs/ LLVM \u6e90\u7801\u7ea7\u6587\u6863\uff1ahttps://llvm.org/doxygen/ LLVM IR \u5168\u6587\u6863\uff1ahttps://llvm.org/docs/LangRef.html \u300aLearn LLVM 17\u300b\uff1ahttps://github.com/xiaoweiChen/Learn-LLVM-17 \u300a\u5f00\u59cb\u5b66\u4e60 LLVM\u300b\uff1ahttps://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/ \u300aminiSysY \u7f16\u8bd1\u5b9e\u9a8c\u300b\uff1ahttps://buaa-se-compiling.github.io/miniSysY-tutorial/pre/llvm.html \u300aA Gentle Introduction to LLVM IR\u300b\uff1ahttps://mcyoung.xyz/2023/08/01/llvm-ir/ \u300aLLVM IR C++ API Tutorial\u300b\uff1ahttps://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/ \u4e0d\u5efa\u8bae\u6309\u987a\u5e8f\u5168\u90e8\u9010\u4e2a\u9605\u8bfb\u5b8c\uff0c\u8fd9\u4e48\u591a\u6587\u6863\u5c0f\u5f6d\u8001\u5e08\u90fd\u770b\u4e0d\u5b8c\u3002\u5efa\u8bae\u9047\u5230\u4e86\u4e0d\u719f\u6089\u7684\u6307\u4ee4\u65f6\uff0c\u518d\u53bb\u9488\u5bf9\u6027\u5730\u627e\u5230\u76f8\u5e94\u7ae0\u8282\uff0c\u5b66\u4e60\u3002 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM \u5982\u679c\u4f60\u5bf9 C++ \u8bed\u8a00\u7684\u5e95\u5c42\u5b9e\u73b0\u611f\u5174\u8da3\uff0c\u7f16\u8bd1\u5668\u662f\u7ed5\u4e0d\u8fc7\u7684\u4e00\u73af\u3002\u5fa1\u4e09\u5bb6\u4e2d\uff0cMSVC \u662f\u95ed\u6e90\u7684\u65e0\u6cd5\u5b66\u4e60\uff0cGCC \u4ee3\u7801\u9ad8\u5ea6\u8026\u5408\uff0c\u4e14\u5f88\u591a\u539f\u59cb\u7684 C \u8bed\u8a00\u201c\u53e4\u795e\u4f4e\u8bed\u201d\u6df7\u6742\u5176\u4e2d\uff0c\u53ef\u8bfb\u6027\u8f83\u5dee\u3002Clang \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 C++ \u7f16\u8bd1\u5668\u524d\u7aef\uff0c\u800c LLVM \u6b63\u662f\u4ed6\u7684\u540e\u7aef\uff0c\u9ad8\u5ea6\u6a21\u5757\u5316\u7684\u8bbe\u8ba1\uff0c\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5f88\u5bb9\u6613\u52a0\u5165\u81ea\u5df1\u7684\u65b0\u6a21\u5757\uff0c\u6700\u9002\u5408\u7f16\u8bd1\u5668\u65b0\u4eba\u4e0a\u624b\u5b66\u4e60\u3002\u9664\u53bb Clang \u8d1f\u8d23\u7684 C++ \u8bed\u6cd5\u89e3\u6790\u540e\uff0cLLVM \u540e\u7aef\u5360\u636e\u4e86\u534a\u58c1\u6c5f\u5c71\u3002\u4f60\u60f3\u4e0d\u60f3\u63a2\u7a76\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5229\u7528\u672a\u5b9a\u4e49\u884c\u4e3a\u4f18\u5316\u7684\uff1f\u60f3\u4e0d\u60f3\u77e5\u9053\u4e3a\u4ec0\u4e48\u6709\u65f6 C++ \u7f16\u8bd1\u5668\u51fa\u73b0\u5f02\u5e38\u7684\u884c\u4e3a\uff1f\u60f3\u4e0d\u60f3\u4e86\u89e3\u600e\u6837\u624d\u80fd\u5199\u51fa\u5bf9\u7f16\u8bd1\u5668\u53cb\u597d\u7684\u4ee3\u7801\uff0c\u65b9\u4fbf\u7f16\u8bd1\u5668\u81ea\u52a8\u5e2e\u4f60\u4f18\u5316\uff1f\u90a3\u5c31\u6765\u5b66\u4e60 LLVM \u5427\uff01 \u524d\u7aef\u548c\u540e\u7aef\u4f17\u591a\uff0c\u65e0\u8bba\u4f60\u662f\u6253\u7b97\u5f00\u53d1\u4e00\u79cd\u65b0\u578b\u8bed\u8a00\uff0c\u8fd8\u662f\u81ea\u7814\u4e00\u79cd\u65b0\u7684 CPU \u67b6\u6784\uff0c\u8003\u8651\u652f\u6301 LLVM \u4f5c\u4e3a\u4e2d\u7aef\u51e0\u4e4e\u662f\u4f60\u552f\u4e00\u7684\u9009\u62e9\u3002 \u5bf9\u4e8e CPU/GPU \u786c\u4ef6\u5382\u5546\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u524d\u7aef\uff0c\u652f\u6301 LLVM \u5c06\u4f7f\u4f60\u7684\u786c\u4ef6\u76f4\u63a5\u652f\u6301 C/C++/CUDA/OpenCL/SyCL/Objective-C/Fortran/Rust/Swift/Haskell \u7b49\u6240\u6709 LLVM \u6709\u524d\u7aef\u7684\u8bed\u8a00\u3002\u4f8b\u5982\u6709\u7684\u56fd\u4ea7\u663e\u5361\u57fa\u4e8e LLVM \u6dfb\u52a0\u4e86\u81ea\u5df1\u7684\u786c\u4ef6\u6307\u4ee4\u96c6\u4f5c\u4e3a\u540e\u7aef\uff0c\u7136\u540e\u518d\u5229\u7528 LLVM \u7684 CUDA \u524d\u7aef\uff0c\u5c31\u5b9e\u73b0\u4e86\u517c\u5bb9 CUDA\uff0cAMD \u5f97\u4ee5\u5b9e\u73b0 CUDA \u517c\u5bb9\u4e5f\u662f\u57fa\u4e8e\u6b64\u3002\u53cd\u4e4b\uff0c\u65b0\u8bed\u8a00\u4e5f\u53ef\u4ee5\u4f7f\u7528 LLVM \u7684 PTX \u540e\u7aef\u8f93\u51fa\uff0c\u4ece\u800c\u652f\u6301\u5728 NVIDIA \u663e\u5361\u4e0a\u6267\u884c\u3002 \u5bf9\u4e8e\u60f3\u53d1\u660e\u65b0\u8bed\u8a00\u6216\u4e3a\u73b0\u6709\u811a\u672c\u8bed\u8a00\u5b9e\u73b0 JIT \u52a0\u901f\u7684\u5f00\u53d1\u8005\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u540e\u7aef\uff0c\u65b0\u8bed\u8a00\u4f7f\u7528 LLVM \u5c31\u80fd\u76f4\u63a5\u652f\u6301 x86/ARM/MIPS/PPC/BPF/PTX/AMDGPU/SPIR-V \u7b49\u5404\u79cd\u67b6\u6784\u548c\u6307\u4ee4\u96c6\uff0c\u800c\u81ea\u5df1\u4e0d\u7528\u589e\u52a0\u4efb\u4f55\u5e95\u5c42\u7ec6\u8282\u8d1f\u62c5\u3002\u4f8b\u5982\u4e00\u4e9b Rust \u7528\u6237\u867d\u7136\u5ba3\u79f0\u53ef\u4ee5\u53d6\u4ee3 C++\uff0c\u4f46 Rust \u7f16\u8bd1\u5668\u6700\u7ec8\u4ecd\u662f\u8c03\u7528 LLVM \u5b9e\u73b0\u7f16\u8bd1\uff0c\u4ea7\u751f\u53ef\u4ee5\u6267\u884c\u7684\u4e8c\u8fdb\u5236\u7801\u3002\u81ea\u5df1\u4e00\u4e2a\u4e2a\u9002\u914d\u6240\u6709\u786c\u4ef6\u5e73\u53f0\u7684\u673a\u5668\u7801\u6210\u672c\u5b9e\u5728\u592a\u9ad8\u4e86\uff0c\u4e14\u4e0d\u8bba\u8fd8\u8981\u4e13\u95e8\u5f00\u53d1\u6240\u6709\u7684\u4f18\u5316 pass\uff0c\u800c LLVM \u4f5c\u4e3a\u4e1a\u754c\u652f\u6301\u6700\u5b8c\u5584\u7684\u73b0\u6210\u54c1\u5728\u5f88\u957f\u4e00\u6bb5\u65f6\u95f4\u5185\u90fd\u5f88\u96be\u4ee3\u66ff\u3002 \u4e2d\u7aef\u4f18\u5316\u548c\u5206\u6790\u80fd\u529b\u5f3a\u5927\uff0c\u65b0\u8bed\u8a00\u82e5\u57fa\u4e8e LLVM\uff0c\u4f18\u5316\u65b9\u9762\u7684\u5de5\u4f5c\u90fd\u6709\u73b0\u6210\u7684\u5b9e\u73b0\uff0c\u53ef\u4ee5\u5168\u90e8\u8ba9 LLVM \u4ee3\u52b3\uff0c\u81ea\u5df1\u53ea\u9700\u8981\u8d1f\u8d23\u89e3\u6790\u8bed\u6cd5\uff0c\u751f\u6210 LLVM IR \u5373\u53ef\uff0c\u5982\u4f55\u4f18\u5316\u540e\u751f\u6210\u4e8c\u8fdb\u5236\u7801\u6839\u672c\u65e0\u9700\u64cd\u5fc3\uff0cLLVM \u4f1a\u81ea\u52a8\u6839\u636e\u5f53\u524d\u7684\u76ee\u6807\u5e73\u53f0\u5224\u65ad\u3002 \u9ad8\u5ea6\u81ea\u5305\u542b\uff0c\u5b8c\u5168\u57fa\u4e8e CMake \u7684\u6a21\u5757\u5316\u6784\u5efa\uff0c\u5145\u6ee1\u73b0\u4ee3\u611f\u3002\u7528\u6237\u53ef\u81ea\u884c\u9009\u62e9\u8981\u6784\u5efa\u7684\u6a21\u5757\u3002\u4e14\u51e0\u4e4e\u5b8c\u5168\u65e0\u4f9d\u8d56\u5c31\u80fd\u6784\u5efa\uff0c\u6709 CMake \u6709\u7f16\u8bd1\u5668\u5c31\u884c\uff0c\u65e0\u9700\u5b89\u88c5\u7e41\u7410\u7684\u7b2c\u4e09\u65b9\u5e93\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u843d\u540e\u7684 Makefile + AutoConf \u6784\u5efa\u7cfb\u7edf\uff0c\u4e14\u7248\u672c\u8981\u6c42\u82db\u523b\u3002 LLVM \u91c7\u7528\u7684 MIT \u5f00\u6e90\u534f\u8bae\u5341\u5206\u5bbd\u677e\uff0c\u5bf9\u5546\u7528\u81ea\u7531\u5ea6\u8f83\u9ad8\u3002\u4e14\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5bb9\u6613\u81ea\u5df1\u63d2\u5165\u65b0\u529f\u80fd\uff0c\u53ef\u4fee\u6539\u540e\u4f9b\u81ea\u5df1\u4f7f\u7528\uff0c\u56e0\u6b64\u5e38\u7528\u4e8e\u95ed\u6e90\u9a71\u52a8\u4e2d\uff08\u4f8b\u5982 NVIDIA \u7684 OpenGL \u9a71\u52a8\u7b49\uff09\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u7684 GPL \u534f\u8bae\u5c31\u6bd4\u8f83\u4e25\u683c\uff0c\u4e0d\u5f97\u81ea\u5df1\u4fee\u6539\u540e\u95ed\u6e90\u53d1\u5e03\uff08\u5fc5\u987b\u8fde\u540c\u6e90\u4ee3\u7801\u4e00\u8d77\u53d1\u5e03\uff09\u3002 LLVM \u9644\u5e26\u4e86\u8bb8\u591a\u5b9e\u7528\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5e2e\u52a9\u6211\u4eec\u5206\u6790\u7f16\u8bd1\u5168\u8fc7\u7a0b\u7684\u4e2d\u95f4\u7ed3\u679c\uff0c\u7406\u89e3\u4f18\u5316\u662f\u5982\u4f55\u53d1\u751f\u7684\u3002\u4f8b\u5982 llvm-as\uff08LLVM IR \u8f6c\u4e3a\u538b\u7f29\u7684\u5b57\u8282\u7801\uff09\uff0cllvm-dis\uff08\u5b57\u8282\u7801\u8f6c\u4e3a IR\uff09\uff0copt\uff08\u53ef\u4ee5\u5bf9 IR \u8c03\u7528\u5355\u4e2a\u4f18\u5316 pass\uff09\uff0cllc\uff08\u5c06\u5b57\u8282\u7801\u8f6c\u6362\u4e3a\u76ee\u6807\u673a\u5668\u7684\u6c47\u7f16\u4ee3\u7801\uff09\uff0cllvm-link\uff08IR \u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u8f93\u5165\u591a\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u4ea7\u751f\u5355\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff09\uff0clld\uff08\u5bf9\u8c61\u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u7c7b\u4f3c\u4e8e GNU ld\uff09\uff0clli\uff08\u89e3\u91ca\u6267\u884c\u5b57\u8282\u7801\uff09\uff0cllvm-lit\uff08\u5355\u5143\u6d4b\u8bd5\u5de5\u5177\uff09\u3002 \u4e00\u4e9b\u82af\u7247\u76f8\u5173\u7684\u5927\u5382\u4e2d\uff0c\u7f16\u8bd1\u5668\u65b9\u9762\u7684\u5c97\u4f4d\u9700\u6c42\u91cf\u5f88\u5927\u3002\u800c\u5176\u4e2d\u4e3b\u8981\u7528\u7684\uff0c\u4f8b\u5982 NVIDIA \u7684\u7f16\u8bd1\u5668 nvcc\uff0c\u5176\u540e\u7aef\u5c31\u662f\u57fa\u4e8e LLVM \u9b54\u6539\u7684\uff0c\u56e0\u6b64\u5b66\u4e60 LLVM \u5f88\u6709\u5c31\u4e1a\u524d\u666f\u3002 \u4e3a\u4ec0\u4e48\u6709\u4e86 Clang \u8fd8\u8981 nvcc\uff1f\u867d\u7136 Clang \u4e5f\u80fd\u652f\u6301 CUDA\uff0c\u4f46 Clang \u53ea\u80fd\u628a CUDA \u7f16\u8bd1\u6210\u6240\u6709 NVIDIA \u663e\u5361\u90fd\u80fd\u901a\u7528\u7684 PTX\uff0c\u65e0\u6cd5\u751f\u6210\u4e13\u95e8\u5bf9\u4e0d\u540c\u663e\u5361\u578b\u53f7\u7279\u5316 SASS \u6c47\u7f16\uff08\u9700\u8981\u8c03\u7528 NVIDIA CUDA Toolkit \u63d0\u4f9b\u7684 ptxas \u624d\u80fd\u8f6c\u6362\uff09\u3002\u800c nvcc \u7684\u524d\u7aef\u9664\u4e86\u662f\u81ea\u5df1\u7684\uff0c\u540e\u7aef\u540c\u6837\u662f\u8c03\u7528 LLVM \u751f\u6210 PTX \u6c47\u7f16\uff0c\u53ea\u662f NVIDIA \u5bf9 LLVM \u505a\u4e86\u4e00\u4e9b\u95ed\u6e90\u7684\u9b54\u6539\uff08\u5176\u5b9e\u65e9\u671f nvcc \u7684\u540e\u7aef\u662f\u57fa\u4e8e NVIDIA \u81ea\u7814\u7684 NVVM \u540e\u7aef\uff0c\u4f46\u662f\u53d1\u73b0\u6548\u679c\u4e0d\u597d\uff0c\u6700\u8fd1\u6b63\u5728\u9010\u6b65\u5207\u6362\u5230 LLVM \u540e\u7aef\uff0c\u6bd5\u7adf\u662f\u8001\u724c\u9879\u76ee\uff09\u3002\u5982\u679c\u5bf9 C++ \u65b0\u7279\u6027\u6709\u8ffd\u6c42\uff0c\u53ef\u4ee5\u7528 Clang \u524d\u7aef + LLVM \u751f\u6210 PTX + ptxas \u6c47\u7f16\u7684\u7ec4\u5408\uff0c\u5b9e\u73b0\u81ea\u7531\u4e16\u754c\u7684 CUDA \u5de5\u4f5c\u6d41\uff08\u4e4b\u540e\u4ecb\u7ecd\uff09\u3002\u4f46\u662f\u56e0\u4e3a ptxas\uff0c\u4ee5\u53ca CUDA \u5176\u4ed6\u8fd0\u884c\u65f6\u5e93\u7684\u9700\u8981\uff0cClang CUDA \u4f9d\u7136\u9700\u8981\u5b89\u88c5 CUDA Toolkit \u624d\u80fd\u6b63\u5e38\u8fd0\u884c\uff0c\u4e14\u5bf9 CUDA \u7248\u672c\u8981\u6c42\u6bd4\u8f83\u4e25\u683c\uff0c\u53ef\u80fd\u9700\u8981\u8f83\u591a\u7684\u914d\u7f6e\u529f\u592b\u3002 Rust \u7f16\u8bd1\u5668\u6700\u8fd1\u4e5f\u6709\u63d0\u51fa\u4e86 gcc-rust\uff0c\u4f7f\u7528 GCC \u505a\u540e\u7aef\u4ee3\u66ff LLVM \u7684\u8ba1\u5212\u2026\u2026\u5c31\u4e0d\u80fd\u81ea\u7814\u4e00\u4e2a RRVM \u4e48\uff1f\u4e0d\u4ec5\u662f Rust \u7f16\u8bd1\u5668\uff0c\u4f60\u4f1a\u53d1\u73b0\u5f88\u591a Rust \u9879\u76ee\u6700\u7ec8\u6216\u591a\u6216\u5c11\u90fd\u5728\u4f9d\u8d56\u4e00\u4e9b C++ \u5e93\uff0c\u6bd4\u5982 RustDesk \u8fd9\u6b3e\u9ad8\u6027\u80fd\u7684\u8fdc\u7a0b\u63a7\u5236\u8f6f\u4ef6\uff0c\u4e0d\u77e5\u548b\u5730\u5c31\u975e\u8981\u4f9d\u8d56 libyuv \u548c libvpx\uff0c\u8fd8\u8981\u6c42\u7528\u6c99\u96d5\u7684 vcpkg \u5b89\u88c5\u2026\u2026\u662f\u81ea\u5df1\u5199\u4e0d\u6765\u8fd8\u662f\u61d2\u5f97\u5199\u4e86\uff1fRust \u4e0d\u662f\u9ad8\u6027\u80fd\u7684\u7cfb\u7edf\u7ea7\u8bed\u8a00\u4e48\uff1f\u5982\u679c Rust \u793e\u533a\u4e0d\u4f1a\u5199 YUV \u7f16\u7801\uff0c\u53ef\u4ee5\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\u5e2e\u5fd9\u7684\u3002\u603b\u4e4b\uff0c\u73b0\u5728\u641e\u5f97 Rust \u548c Python \u4e00\u6837\uff0c\u6210\u5305\u76ae\u8bed\u8a00\u4e86\u3002\u4eca\u540e\u5bf9 Rust \u7684\u5b66\u4e60\uff0c\u6050\u6015\u8fd8\u662f\u5c48\u670d\u4e8e\u5b9e\u7528\uff0c\u548c Python \u4e00\u6837\u5404\u79cd\u201cAPI bindings\u201d\u3002 LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f LLVM \u9879\u76ee\u4e0d\u4ec5\u5305\u542b\u4e86 LLVM \u672c\u4f53\uff0c\u8fd8\u6709\u4e00\u7cfb\u5217\u56f4\u7ed5 LLVM \u5f00\u53d1\u7684\u4e0a\u4e0b\u6e38\u5de5\u5177\u3002\u4f8b\u5982 Clang \u7f16\u8bd1\u5668\u5c31\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff0c\u4ed6\u662f\u4e00\u4e2a C/C++/CUDA/OpenCL/SyCL/Objective-C \u7b49 C \u7c7b\u8bed\u8a00\u7684\u524d\u7aef\uff0c\u53ea\u8d1f\u8d23\u5b8c\u6210\u8bed\u6cd5\u7684\u89e3\u6790\uff0c\u5b9e\u9645\u7f16\u8bd1\u548c\u4e8c\u8fdb\u5236\u751f\u6210\u4ea4\u7ed9 LLVM \u672c\u4f53\uff08\u4e2d\u540e\u7aef\uff09\u6765\u5904\u7406\u3002\u901a\u5e38\u8bf4\u7684 LLVM \u6307\u7684\u662f LLVM \u672c\u4f53\uff0c\u5176\u662f\u4e00\u4e2a\u901a\u7528\u7684\u7f16\u8bd1\u5668\u57fa\u5efa\uff0c\u4ec5\u5305\u542b\u4e2d\u7aef\uff08\u5404\u79cd\u4f18\u5316\uff09\u548c\u540e\u7aef\uff08\u751f\u6210 x86/ARM/MIPS \u7b49\u786c\u4ef6\u7684\u6307\u4ee4\u7801\uff09\u3002Clang \u89e3\u6790 .cpp \u6587\u4ef6\u540e\u4ea7\u751f IR\uff0c\u8c03\u7528 LLVM \u7f16\u8bd1\u751f\u6210\u7684 .o \u5bf9\u8c61\u6587\u4ef6\uff0c\u53c8\u4f1a\u88ab\u8f93\u5165\u5230\u540c\u5c5e LLVM \u9879\u76ee\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff1aLLD \u94fe\u63a5\u5668\u4e2d\uff0c\u94fe\u63a5\u5f97\u5230\u6700\u7ec8\u7684\u5355\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\uff08.exe\uff09\u6216\u52a8\u6001\u94fe\u63a5\u5e93\uff08.dll\uff09\uff0cLLD \u8fd8\u53ef\u4ee5\u5f00\u542f\u94fe\u63a5\u65f6\u4f18\u5316\uff0c\u8fd9\u53c8\u4f1a\u7528\u5230 BOLT \u8fd9\u4e2a\u94fe\u63a5\u65f6\u4f18\u5316\u5668\uff0c\u5bf9\u751f\u6210\u7684\u5355\u4e2a\u4e8c\u8fdb\u5236\u505a\u8fdb\u4e00\u6b65\u6c47\u7f16\u7ea7\u522b\u7684\u4f18\u5316\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8457\u540d\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\u4e4b\u4e00\uff0clibc++\uff0c\u4e5f\u662f LLVM \u9879\u76ee\u7684\u4e00\u90e8\u5206\uff0c\u76f8\u6bd4 GCC \u5bb6\u65cf\u7684 libstdc++ \u66f4\u7b80\u5355\uff0c\u66f4\u9002\u5408\u5b66\u4e60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5e76\u884c\u7684 STL \u5b9e\u73b0 pstl\uff0cOpenCL \u7f16\u8bd1\u5668 libclc \u7b49\u2026\u2026\u5e94\u6709\u5c3d\u6709\uff0c\u662f\u7f16\u8bd1\u5668\u5f00\u53d1\u8005\u7684\u5929\u5802\u3002 Clang \u7f16\u8bd1 C++ \u7a0b\u5e8f\u7684\u6574\u4e2a\u8fc7\u7a0b\uff1a Clang \u524d\u7aef\u89e3\u6790 C++ \u8bed\u6cd5 -> LLVM \u4e2d\u7aef\u4f18\u5316 -> LLVM \u540e\u7aef\u751f\u6210\u6307\u4ee4\u7801 -> LLD \u94fe\u63a5 -> BOLT \u94fe\u63a5\u540e\u4f18\u5316 \u800c GCC \u5c31\u6ca1\u6709\u8fd9\u4e48\u6a21\u5757\u5316\u4e86\uff0c\u867d\u7136 GCC \u5185\u90e8\u540c\u6837\u662f\u6709\u524d\u7aef\u548c\u4e2d\u7aef IR\uff0c\u4f46\u662f\u6574\u4e2a\u5c31\u662f\u7cca\u5728\u4e00\u4e2a GCC \u53ef\u6267\u884c\u6587\u4ef6\u91cc\uff0c\u96be\u4ee5\u91cd\u6784\uff0c\u79ef\u91cd\u96be\u53cd\uff0c\u4e5f\u96be\u4ee5\u8de8\u5e73\u53f0\uff08MinGW \u8fd8\u662f\u6c11\u95f4\u81ea\u5df1\u79fb\u690d\u8fc7\u53bb\u7684\uff0c\u5e76\u975e GCC \u5b98\u65b9\u9879\u76ee\uff09\u3002\u548c Clang \u80fd\u8f7b\u6613\u4f5c\u4e3a libclang \u548c libLLVM \u5e93\u53d1\u5e03\u76f8\u6bd4\uff0c\u9ad8\u4e0b\u7acb\u5224\u3002MSVC \u66f4\u662f\u4e0d\u5fc5\u591a\u8bf4\uff0c\u8fde\u6e90\u7801\u90fd\u4e0d\u5f00\u653e\uff0c\u8ba9\u4eba\u600e\u4e48\u5b66\u4e60\u548c\u9b54\u6539\u554a\uff1f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u8981\u5b66\u4e60 LLVM\uff0c\u80af\u5b9a\u4e0d\u80fd\u7eb8\u4e0a\u8c08\u5175\u3002LLVM \u662f\u5f00\u6e90\u8f6f\u4ef6\uff0c\u6700\u597d\u662f\u81ea\u5df1\u4e0b\u8f7d\u4e00\u4e2a LLVM \u5168\u5bb6\u6876\u6e90\u7801\uff0c\u7136\u540e\u81ea\u5df1\u4ece\u6e90\u7801\u6784\u5efa\u3002 \u6ce8\u610f\uff1a\u6211\u4eec\u6700\u597d\u662f\u4ece\u6e90\u7801\u6784\u5efa LLVM \u548c Clang\uff0c\u65b9\u4fbf\u6211\u4eec\u52a8\u624b\u4fee\u6539\u5176\u6e90\u7801\uff0c\u6dfb\u52a0\u6a21\u5757\uff0c\u67e5\u770b\u6548\u679c\u3002\u4e0b\u8f7d\u4e8c\u8fdb\u5236\u53d1\u5e03\u7248 LLVM \u6216 Clang \u7684\u8bdd\uff0c\u867d\u7136\u540c\u6837\u53ef\u4ee5\u4f7f\u7528\u6240\u6709\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5c31\u53ea\u80fd\u5bf9\u7740 IR \u4e00\u901a\u5206\u6790\u76f2\u731c\u4e86\u3002 \u6e90\u7801\u9762\u524d\uff0c\u4e86\u65e0\u79d8\u5bc6\u3002 \u867d\u7136 LLVM \u51e0\u4e4e\u662f\u65e0\u4f9d\u8d56\u7684\uff0c\u53ea\u9700\u8981 CMake \u548c\u7f16\u8bd1\u5668\u5c31\u80fd\u6784\u5efa\uff0c\u4f46\u4f9d\u7136\u63a8\u8350\u4f7f\u7528 Linux \u7cfb\u7edf\u8fdb\u884c\u5b9e\u9a8c\uff0c\u4ee5\u83b7\u5f97\u548c\u5c0f\u5f6d\u8001\u5e08\u540c\u6837\u7684\u5f00\u53d1\u4f53\u9a8c\u3002Windows \u7528\u6237\u5efa\u8bae\u4f7f\u7528 Visual Studio \u6216 CLion \u7b49\u5f3a\u5927 IDE \u5e2e\u52a9\u9605\u8bfb\u7406\u89e3\u6e90\u7801\uff1bLinux \u7528\u6237\u5efa\u8bae\u5b89\u88c5 \u5c0f\u5f6d\u8001\u5e08 vimrc \uff1b\u6216\u8005\u5982\u679c\u4f60\u662f\u8fdc\u7a0b Linux\uff0c\u53ef\u4ee5\u8bd5\u8bd5\u770b VSCode \u7684\u8fdc\u7a0b SSH \u8fde\u63a5\u63d2\u4ef6\uff1bCLion \u4f3c\u4e4e\u4e5f\u6709\u8fdc\u7a0b\u63d2\u4ef6\uff0c\u53ea\u4e0d\u8fc7\u9700\u8981\u5728\u8fdc\u7a0b\u5b89\u88c5\u597d\u5ba2\u6237\u7aef\u3002 \u5f3a\u5927\u7684 IDE \u548c\u7f16\u8f91\u5668\u5bf9\u5b66\u4e60\u4efb\u4f55\u5927\u578b\u9879\u76ee\u90fd\u662f\u5fc5\u4e0d\u53ef\u5c11\u7684\uff0c\u7279\u522b\u662f\u8df3\u8f6c\u5230\u5b9a\u4e49\uff0c\u4ee5\u53ca\u8fd4\u56de\u8fd9\u4e24\u4e2a\u64cd\u4f5c\uff0c\u662f\u4f7f\u7528\u9891\u7387\u6700\u9ad8\u7684\uff0c\u5728\u6e90\u7801\u4e4b\u95f4\u7684\u5feb\u901f\u8df3\u8f6c\u5c06\u5927\u5927\u6709\u52a9\u4e8e\u5feb\u901f\u7406\u89e3\u548c\u638c\u63e1\u4ee3\u7801\u7ed3\u6784\u3002 \u5982\u679c\u5b9e\u5728\u6ca1\u6709\u6761\u4ef6\u81ea\u5df1\u6784\u5efa LLVM \u6e90\u7801\uff0c\u6216\u8005 IDE \u6bd4\u8f83\u62c9\u80ef\uff1a\u53ef\u4ee5\u53bb LLVM \u7684\u5728\u7ebf\u6e90\u7801\u7ea7\u6587\u6863\uff08\u4f7f\u7528 Doxygen \u751f\u6210\uff09\u770b\u770b\u3002\u5176\u4e0d\u4ec5\u63d0\u4f9b\u4e86 LLVM \u4e2d\u6240\u6709\u7c7b\u548c\u51fd\u6570\u7684\u8be6\u5c3d\u6587\u6863\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u7528\u6cd5\u8bf4\u660e\u7b49\uff1b\u8fd8\u63d0\u4f9b\u4e86\u6bcf\u4e2a\u51fd\u6570\u7684\u6240\u5728\u6587\u4ef6\u548c\u884c\u53f7\u4fe1\u606f\uff0c\u70b9\u51fb\u7c7b\u578b\u6216\u51fd\u6570\u540d\u7684\u8d85\u94fe\u63a5\uff0c\u5c31\u53ef\u4ee5\u5728\u6e90\u7801\u548c\u6587\u6863\u4e4b\u95f4\u6765\u56de\u8df3\u8f6c\u3002\u8fd8\u80fd\u770b\u5230\u54ea\u91cc\u5f15\u7528\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u8fd8\u80fd\u663e\u793a\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb\u56fe\uff0c\u975e\u5e38\u9002\u5408\u4e0a\u73ed\u8def\u4e0a\u6ca1\u6cd5\u6253\u5f00\u7535\u8111\u65f6\u5077\u5b66 LLVM \u6e90\u7801\u7528\u3002\u4f8b\u5982\uff0c llvm::VectorType \u8fd9\u4e2a\u7c7b\u7684\u6587\u6863\uff1ahttps://llvm.org/doxygen/classllvm_1_1VectorType.html \u4e00\u70b9\u5fe0\u544a \u5bf9\u4e8e LLVM \u8fd9\u79cd\u5927\u578b\u9879\u76ee\uff0c\u7531\u4e8e\u4f60\u662f\u521d\u5b66\u8005\uff0c\u52a1\u5fc5\u505a\u5230\u201c\u4e0d\u6c42\u751a\u89e3\u201d\uff01 \u4f60\u5fc5\u7136\u4e00\u65f6\u534a\u4f1a\u4e0d\u80fd\u5b8c\u5168\u770b\u61c2\u6bcf\u4e2a\u7ec6\u8282\uff0c\u5343\u4e07\u4e0d\u8981\u6b7b\u6263\u7ec6\u8282\uff0c\u4e00\u4e2a\u7ec6\u8282\u4e0d\u7406\u89e3\u5c31\u786c\u77aa\u773c\u5e72\u770b\uff01 \u770b\u4e0d\u61c2\u7684\u5148\u8df3\u8fc7\u53bb\u5373\u53ef\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\u3002\u7535\u89c6\u8fde\u7eed\u5267\u8df3\u4e00\u4e24\u96c6\uff0c\u751a\u81f3\u4ece\u4e2d\u95f4\u5f00\u59cb\u770b\uff0c\u90fd\u80fd\u770b\u61c2\u5462\uff01\u6ca1\u6709\u90a3\u4e48\u4e25\u683c\u7684\u987a\u5e8f\u4f9d\u8d56\u3002 \u4ee5\u540e\u77e5\u8bc6\u50a8\u5907\u591f\u4e86\uff0c\u6216\u8005\u5de5\u4f5c\u4e2d\u9700\u8981\u7528\u5230\u4e86\uff0c\u518d\u56de\u8fc7\u5934\u6765\u67e5\u6f0f\u8865\u7f3a\u4e5f\u4e0d\u8fdf\u3002 \u6211\u6700\u6015\u67d0\u4e9b\u540c\u5b66\u76ef\u7740\u67d0\u4e2a\u6b21\u8981\u7684\u7ec6\u8282\u6b7b\u52b2\u60f3\uff0c\u60f3\u4e0d\u51fa\u5c31\u6b62\u6b65\u4e0d\u524d\u4e86\u3002\u6bd4\u5982\u4ed6\u9047\u5230\u4e00\u4e2a\u8001\u5916\u8bf4\uff1a My dick is bleeding, could you tell me where is the toilet? \u800c \u2018dick\u2019 \u662f\u8fd9\u4e2a\u540c\u5b66\u770b\u4e0d\u61c2\u7684\u201c\u751f\u8bcd\u201d\uff0c\u4ed6\u5c31\u6b7b\u6263\u8fd9\u4e2a\u5b57\u773c\uff0c\u8ba4\u4e3a\u770b\u4e0d\u61c2\u8fd9\u4e2a\u8bcd\uff0c\u540e\u9762\u7684\u5bf9\u8bdd\u4e5f\u4f1a\u770b\u4e0d\u61c2\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u9700\u8981\u628a\u8fd9\u4e2a\u770b\u4e0d\u61c2\u7684\u5730\u65b9\u8df3\u8fc7\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\uff0c\u5c31\u5f53\u4ed6\u662f\u4e00\u4e2a\u4e71\u7801\u585e\u5728\u90a3\u91cc\u5e72\u6270\u4f60\u9605\u8bfb\u7684\uff0c\u4f60\u53ea\u7ba1\u7ee7\u7eed\u770b\u4e0b\u53bb\uff1a My \ufffd\ufffd\ufffd is \ufffd\ufffd\ufffd\ufffd\ufffd, could you tell me where is the toilet? \u4e00\u6837\u80fd\u770b\u61c2\u8001\u5916\u60f3\u8981\u95ee\u7684\u662f\u5395\u6240\uff08toilet\uff09\uff0c\u6839\u672c\u4e0d\u9700\u8981\u77e5\u9053\u524d\u9762\u7684 \u2018dick\u2019 \u662f\u4ec0\u4e48\u610f\u601d\u3002 \u81f4\u6d82\u9ed1\u4e16\u754c\u7684\u4e66\u4fe1 LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 LLVM\uff08\u548c Clang\uff09\u7684\u6784\u5efa\u4f9d\u8d56\u9879\u51e0\u4e4e\u6ca1\u6709\uff0c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\uff0c\u975e\u5e38\u7684\u73b0\u4ee3\u3002 Linux/MacOS \u7528\u6237 \u9996\u5148\u5b89\u88c5 Git\u3001CMake\u3001Ninja\u3001GCC\uff08\u6216 Clang\uff09\u3002 \u5176\u4e2d Ninja \u53ef\u4ee5\u4e0d\u5b89\u88c5\uff0c\u53ea\u662f\u56e0\u4e3a Ninja \u6784\u5efa\u901f\u5ea6\u6bd4 Make \u5feb\uff0c\u7279\u522b\u662f\u5f53\u6587\u4ef6\u975e\u5e38\u591a\uff0c\u800c\u4f60\u6539\u52a8\u975e\u5e38\u5c11\u65f6\u3002\u800c\u4e14 Ninja \u9ed8\u8ba4\u5c31\u5f00\u542f\u591a\u6838\u5e76\u884c\u6784\u5efa\uff0c\u6240\u4ee5\u5927\u578b\u9879\u76ee\u901a\u5e38\u4f1a\u5c3d\u91cf\u7ed9 cmake \u6307\u5b9a\u4e00\u4e0b -G Ninja \u9009\u9879\uff0c\u8ba9\u5176\u4f7f\u7528\u66f4\u9ad8\u6548\u7684 Ninja \u540e\u7aef\u6784\u5efa\u3002 Arch Linux: sudo pacman -S git cmake ninja gcc Ubuntu: sudo apt-get install git cmake ninja-build g++ MacOS: brew install git cmake ninja gcc \u5f00\u59cb\u514b\u9686\u9879\u76ee\uff08\u9700\u8981\u65f6\u95f4\uff09\uff1a git clone https://github.com/llvm/llvm-project \u5982\u679c\u4f60\u7684 GitHub \u7f51\u901f\u8f83\u6162\uff0c\u53ef\u4ee5\u6539\u7528 Gitee \u56fd\u5185\u955c\u50cf\uff08\u53ea\u4e0d\u8fc7\u8fd9\u6837\u4f60\u5c31\u6ca1\u6cd5\u7ed9 LLVM \u5b98\u65b9\u6c34 PR \u4e86 \ud83e\udd23\uff09\uff1a git clone https://gitee.com/mirrors/LLVM Windows \u7528\u6237 \u5373\u4f7f\u662f LLVM \u8fd9\u6837\u6beb\u65e0\u4f9d\u8d56\u9879\u7684\u9879\u76ee\uff0c\u201c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\u201d\uff0c\u5728 Windows \u7528\u6237\u770b\u6765\u4f9d\u7136\u975e\u5e38\u79d1\u5e7b\u3002 \u597d\u5728\u5fae\u8f6f\u4e5f\u610f\u8bc6\u5230\u4e86\u81ea\u5df1\u7684\u6b8b\u5e9f\uff0c\u73b0\u5728 Virtual Studio 2022 \u5df2\u7ecf\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff08\u81ea\u5e26 Git\u3001CMake \u548c Ninja \u4e86\uff09\u3002 \u5982\u679c\u4f60\u662f\u7528 VS2022 \u81ea\u5e26\u7684 Git \u514b\u9686 llvm-project\uff0c\u8bb0\u5f97 cd \u5230 llvm \u6587\u4ef6\u5939\u91cc\u518d\u7528 cmake\uff0c\u7136\u800c\u8d35\u7269 IDE \u7684\u4e00\u4e2a cd \u90fd\u662f\u5982\u6b64\u7684\u56f0\u96be\u3002 \u6240\u4ee5\u8fd9\u8fb9\u5efa\u8bae\u4f60\u76f4\u63a5\u5148\u628a llvm-project \u4ed3\u5e93\u4f5c\u4e3a ZIP \u4e0b\u8f7d\u4e0b\u6765\uff0c\u7136\u540e\u6253\u5f00\u5176\u4e2d\u7684 llvm \u5b50\u6587\u4ef6\u5939\uff0c\u7136\u540e\u7528 VS2022 \u6253\u5f00\u5176\u4e2d\u7684 CMakeLists.txt\uff0c\u7136\u540e\u5f00\u59cb\u6784\u5efa\u3002 \u7136\u540e\uff0c\u8981\u5f00\u542f\u4e00\u4e2a CMake \u9009\u9879 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \uff0c\u624d\u80fd\u6784\u5efa Clang \u5b50\u9879\u76ee\uff08\u5426\u5219\u6784\u5efa\u7684\u662f\u8d64\u818a LLVM\uff0c\u6ca1\u6709\u4efb\u4f55\u524d\u7aef\uff0c\u8fd9\u6beb\u65e0\u610f\u4e49\uff09\u3002\u4ec5\u6b64\u662f\u6307\u5b9a\u8fd9\u4e00\u4e2a\u5c0f\u5c0f\u9009\u9879\u5bf9\u4e8e IDE \u53d7\u5bb3\u8005\u53c8\u662f\u4f55\u7b49\u7684\u56f0\u96be\u2026\u2026\u4ed6\u4eec\u9700\u8981\u5728 VS2022 \u4e2d\u6253\u5f00 CMakeSettings.json\uff0c\u4fee\u6539 x64-Debug \u7684\u914d\u7f6e\uff0c\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\uff0c\u503c\u4e3a \u201cclang;clang-tools-extra\u201d\u2026\u2026\u5982\u679c\u4ed6\u4eec\u8981\u6539\u6210 Release \u914d\u7f6e\uff0c\u53c8\u8981\u70b9\u51fb\u52a0\u53f7\u521b\u5efa x64-Release\uff08\u5343\u4e07\u522b\u70b9\u9519\u6210 x86-Release\uff01\uff09\uff0c\u7136\u540e\u518d\u6b21\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\u2026\u2026 \u56e0\u4e3a llvm-project \u662f\u8bb8\u591a\u9879\u76ee\u7684\u96c6\u5408\uff0c\u6839\u76ee\u5f55\u91cc\u5e76\u6ca1\u6709 CMakeLists.txt\uff0c\u800c VS2022 \u4f3c\u4e4e\u53ea\u80fd\u8bc6\u522b\u6839\u76ee\u5f55\u7684 CMakeLists.txt\u2026\u2026 \u6b63\u5e38\u7cfb\u7edf\u53ea\u9700\u8981\u7ed9\u4f60\u5199\u4e00\u4e32\u547d\u4ee4\uff0c\u4f60\u53ea\u7ba1\u590d\u5236\u7c98\u8d34\u5230 Shell \u91cc\u4e00\u6267\u884c\u5c31\u641e\u5b9a\u4e86\u3002\u8111\u762b\u7cfb\u7edf\u9700\u8981\u5927\u91cf\u65e0\u8c13\u7684\u6587\u5b57\u63cf\u8ff0\u548c\u622a\u56fe\u7bad\u5934\u6307\u793a\u534a\u5929\uff0c\u8fd8\u7ecf\u5e38\u6709\u4eba\u770b\u4e0d\u61c2\uff0c\u8981\u53cd\u590d\u5f3a\u8c03\uff0c\u753b\u7bad\u5934\uff0c\u52a0\u7c97\u5b57\u4f53\uff0c\u624d\u80fd\u64cd\u63a7\u4ed6\u7684\u9f20\u6807\u70b9\u51fb\u5230\u6b63\u786e\u6309\u94ae\u4e0a\u3002\u6211\u4e5f\u60f3\u628a\u9f20\u6807\u5b8f\u5f55\u4e0b\u6765\uff0c\u53ef\u662f\u4e0d\u540c\u7535\u8111\u5206\u8fa8\u7387\u4e0d\u540c\uff0c\u7a97\u53e3\u4f4d\u7f6e\u53c8\u5f88\u968f\u673a\uff0c\u7535\u8111\u54cd\u5e94\u901f\u5ea6\u53c8\u968f\u673a\uff0c\u6709\u65f6\u5019 C \u76d8\uff0c\u6709\u65f6\u5019\u53c8 D \u76d8\uff0c\u6839\u672c\u4e0d\u7ed9\u4e00\u4e2a\u7edf\u4e00\u7684\u64cd\u4f5c\u65b9\u5f0f,\u7edf\u4e00\u7684\u547d\u4ee4\u884c\u5c31\u6ca1\u6709\u8fd9\u79cd\u70e6\u607c\u3002\u6240\u4ee5\uff0c\u80fd\u5378\u8f7d\u7684\u5378\u8f7d\uff0c\u80fd\u53cc\u7cfb\u7edf\u7684\u53cc\u7cfb\u7edf\uff0c\u80fd WSL \u4e5f\u603b\u6bd4\u8171\u9798\u7c89\u788e\u5668\uff08\u9f20\u6807\uff09\u597d\uff0c\u81f3\u5c11\u80fd\u4e00\u952e\u7c98\u8d34\u5c0f\u5f6d\u8001\u5e08\u540c\u6b3e\u64cd\u4f5c\u3002 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 $ cd llvm-project $ ls bolt CONTRIBUTING.md LICENSE.TXT pstl build cross-project-tests lld pyproject.toml build.sh flang lldb README.md clang libc llvm runtimes clang-tools-extra libclc llvm-libgcc SECURITY.md cmake libcxx mlir third-party CODE_OF_CONDUCT.md libcxxabi openmp utils compiler-rt libunwind polly \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u7684\u5b50\u9879\u76ee\uff0c\u5176\u4e2d\u6211\u4eec\u4e3b\u8981\u5b66\u4e60\u7684\u5c31\u662f\u8fd9\u91cc\u9762\u7684 llvm \u6587\u4ef6\u5939\uff0c\u4ed6\u662f LLVM \u7684\u672c\u4f53\u3002\u5176\u4e2d\u4e0d\u4ec5\u5305\u542b LLVM \u5e93\uff0c\u4e5f\u5305\u542b\u4e00\u4e9b\u5904\u7406 LLVM IR \u548c\u5b57\u8282\u7801\u7684\u5b9e\u7528\u5de5\u5177\uff08\u4f8b\u5982 llvm-as\uff09\u3002 \u5176\u6b21\u5c31\u662f clang \u6587\u4ef6\u5939\uff0c\u8fd9\u4e2a\u5b50\u9879\u76ee\u5c31\u662f\u5927\u540d\u9f0e\u9f0e\u7684 Clang \u7f16\u8bd1\u5668\uff0c\u4ed6\u4e5f\u662f\u57fa\u4e8e LLVM \u672c\u4f53\u5b9e\u73b0\u7684\uff0c\u672c\u8eab\u53ea\u662f\u4e2a\u524d\u7aef\uff0c\u5e76\u4e0d\u505a\u4f18\u5316\u548c\u540e\u7aef\u6c47\u7f16\u751f\u6210\u3002 clang-tools-extra \u8fd9\u4e2a\u5b50\u9879\u76ee\u662f clangd\u3001clang-tidy\u3001clang-format \u7b49 C/C++ \u4ee3\u7801\u8d28\u91cf\u5de5\u5177\uff0c\u53ef\u4ee5\u9009\u62e9\u4e0d\u6784\u5efa\u3002 libc \u662f Clang \u5b98\u914d\u7684 C \u6807\u51c6\u5e93\uff0c\u800c libcxx \u662f Clang \u5b98\u914d\u7684 C++ \u6807\u51c6\u5e93\uff0c\u60f3\u5b66\u6807\u51c6\u5e93\u6e90\u7801\u7684\u540c\u5b66\u53ef\u4ee5\u770b\u770b\u3002 flang \u662f LLVM \u7684 Fortran \u524d\u7aef\uff0c\u7f16\u7a0b\u754c\u7684\u6d3b\u5316\u77f3\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 lldb \u662f LLVM \u5b98\u65b9\u7684\u8c03\u8bd5\u5668\uff0c\u5bf9\u6807 GCC \u7684 gdb \u8c03\u8bd5\u5668\uff0cVSCode \u4e2d\u7684\u8c03\u8bd5\u9ed8\u8ba4\u5c31\u662f\u57fa\u4e8e lldb \u7684\u3002 lld \u662f LLVM \u5b98\u65b9\u7684\u4e8c\u8fdb\u5236\u94fe\u63a5\u5668\uff0c\u5bf9\u6807 GCC \u7684 ld \u548c ld.gold\uff1b\u800c bolt \u662f\u94fe\u63a5\u540e\u4f18\u5316\u5668\uff0c\u7528\u7684\u4e0d\u591a\u3002 compiler-rt \u662f\u8bf8\u5982 AddressSantizer\uff08\u5185\u5b58\u6ea2\u51fa\u68c0\u6d4b\u5de5\u5177\uff09\u3001MSAN\uff08\u5185\u5b58\u6cc4\u6f0f\u68c0\u6d4b\uff09\u3001TSAN\uff08\u7ebf\u7a0b\u5b89\u5168\u68c0\u6d4b\uff09\u3001UBSAN\uff08\u672a\u5b9a\u4e49\u884c\u4e3a\u68c0\u6d4b\uff09\u7b49\u5de5\u5177\u7684\u5b9e\u73b0\u3002 mlir \u662f LLVM \u5bf9 MLIR \u7684\u7f16\u8bd1\u5668\u5b9e\u73b0\uff08\u4e00\u79cd\u4e3a\u673a\u5668\u5b66\u4e60\u5b9a\u5236\uff0c\u5141\u8bb8\u7528\u6237\u81ea\u5b9a\u4e49\u65b0\u7684 IR \u8282\u70b9\uff0c\u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\u7b49\u9ad8\u9636\u64cd\u4f5c\uff0c\u65b9\u4fbf\u7279\u5b9a\u786c\u4ef6\u8bc6\u522b\u5230\u5e76\u4f18\u5316\u6210\u81ea\u7814\u786c\u4ef6\u4e13\u95e8\u7684\u77e9\u9635\u4e58\u6cd5\u6307\u4ee4\uff0c\u6700\u8fd1\u4f3c\u4e4e\u5728 AI \u5b5d\u5b50\u4e2d\u5f88\u6d41\u884c\uff09\u3002 libclc \u662f LLVM \u5bf9 OpenCL \u7684\u5b9e\u73b0\uff08OpenCL \u8bed\u8a00\u89c4\u8303\u7684\u7f16\u8bd1\u5668\uff09\uff0cOpenCL \u662f\u5b64\u513f\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 openmp \u662f LLVM \u5bf9 OpenMP \u7684\u5b9e\u73b0\uff08\u4e00\u79cd\u7528\u4e8e\u50bb\u74dc\u5f0f CPU \u5355\u673a\u5e76\u884c\u7684\u6846\u67b6\uff0c\u7528\u6cd5\u5f62\u5982 #pragma omp parallel for \uff09\u3002 pstl \u662f LLVM \u5bf9 C++17 Parallel STL \u7684\u5b9e\u73b0\uff08\u540c\u6837\u662f\u5355\u673a CPU \u5e76\u884c\uff0c\u4f18\u52bf\u5728\u4e8e\u5229\u7528\u4e86 C++ \u8bed\u6cd5\u7cd6\uff0c\u4e5f\u6bd4\u8f83\u5b64\u513f\uff0c\u7528\u7684\u4e0d\u591a\uff09\u3002 cmake \u6587\u4ef6\u5939\u5e76\u4e0d\u662f\u5b50\u9879\u76ee\uff0c\u800c\u662f\u88c5\u7740\u548c LLVM \u76f8\u5173\u7684\u4e00\u4e9b CMake \u811a\u672c\u6587\u4ef6\u3002 build \u6587\u4ef6\u5939\u662f\u4f7f\u7528\u8fc7 CMake \u540e\u4f1a\u624d\u751f\u6210\u7684\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u662f cmake -B build \u547d\u4ee4\u751f\u6210\u7684\u3002\u5176\u4e2d\u5b58\u50a8\u7740\u6784\u5efa\u9879\u76ee\u8fc7\u7a0b\u4e2d\u4ea7\u751f\u7684\u4e34\u65f6\u5bf9\u8c61\u6587\u4ef6\u548c\u6700\u7ec8\u7684\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u6240\u6709\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u653e\u5728 build/bin \u5b50\u6587\u4ef6\u5939\u4e2d\uff0c\u4f8b\u5982 build/bin/llvm-as\u3002\u5982\u679c CMake \u51fa\u73b0\u4e0d\u542c\u4f7f\u5524\u7684\u95ee\u9898\uff0c\u53ef\u4ee5\u5220\u9664 build \u6587\u4ef6\u5939\u8bd5\u8bd5\uff0c\u8fd9\u4f1a\u8feb\u4f7f CMake \u91cd\u65b0\u751f\u6210\uff08\u5efa\u8bae\u6bcf\u6b21\u4fee\u6539\u8fc7 CMake \u9009\u9879\u540e\u90fd\u5220 build\uff09\u3002 \u5f00\u59cb\u6784\u5efa cd llvm-project bash build.sh build.sh \u811a\u672c\u7684\u5185\u5bb9\u7b49\u4ef7\u4e8e\uff1a cmake -Sllvm -Bbuild -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" -GNinja ninja -Cbuild \u4f60\u5728\u547d\u4ee4\u884c\u624b\u52a8\u8f93\u5165\u8fd9\u4e24\u6761\u547d\u4ee4\u4e5f\u662f\u7b49\u4ef7\u7684\uff0c build.sh \u53ea\u662f\u4e3a\u4e86\u65b9\u4fbf\u3002 \u6b64\u5904 -S llvm \u9009\u9879\u8868\u793a\u6307\u5b9a\u6e90\u7801\u8def\u5f84\u4e3a\u6839\u76ee\u5f55\u4e0b\u7684 llvm \u5b50\u9879\u76ee\u6587\u4ef6\u5939\uff0c\u548c cd llvm && cmake -B build \u7b49\u4ef7\uff0c\u4f46\u662f\u4e0d\u7528\u5207\u6362\u76ee\u5f55\u3002 -G Ninja \u8868\u793a\u4f7f\u7528 Ninja \u540e\u7aef\uff0c\u5982\u679c\u4f60\u6ca1\u6709 Ninja\uff0c\u53ef\u4ee5\u53bb\u6389\u8be5\u9009\u9879\uff0cCMake \u5c06\u4f1a\u91c7\u7528\u9ed8\u8ba4\u7684 Makefile \u540e\u7aef\uff08\u66f4\u6162\uff09\u3002 \u5982\u679c\u4f60\u662f Wendous \u53d7\u5bb3\u8005\uff0c\u8bf7\u81ea\u884c\u7528\u9f20\u6807\u70b9\u51fb\u5e8f\u5217\u5728 VS2022 \u4e2d\u6a21\u62df\u4ee5\u4e0a\u4ee3\u7801\u4e4b\u540c\u7b49\u6548\u679c\uff0c\u795d\u60a8\u8171\u9798\u6109\u5feb\uff01 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \u8868\u793a\u542f\u7528 clang \u548c clang-tools-extra \u4e24\u4e2a\u5b50\u9879\u76ee\u3002 \u8fd9\u662f\u56e0\u4e3a\u901a\u5e38\u7528\u7684\u524d\u7aef\u90fd\u662f C++\uff0c\u6240\u4ee5 LLVM \u5b98\u65b9\u5728 build.sh \u91cc\u5c31\u8fd9\u4e48\u5199\u4e86\u3002 \u5982\u679c\u4f60\u53e3\u5473\u6bd4\u8f83\u91cd\uff0c\u60f3\u7814\u7a76 Fortran \u524d\u7aef\uff0c\u4e5f\u53ef\u4ee5\u5b9a\u4e49\u8be5 CMake \u53d8\u91cf\u4e3a -DLLVM_ENABLE_PROJECTS=\"flang\" \u3002 build.sh \u540e\uff0c\u9700\u8981\u82b1\u8d39\u5927\u7ea6 10 \u5206\u949f\u65f6\u95f4\uff08\u53d6\u51b3\u4e8e\u4f60\u7684\u7535\u8111\u914d\u7f6e\uff09\uff0c\u8fd9\u6bb5\u65f6\u95f4\u4f60\u53ef\u4ee5\u5148\u770b\u4e0b\u9762\u7684\u57fa\u672c\u6982\u5ff5\u901f\u89c8\u3002\u7b49\u98ce\u6247\u505c\u4e86\u4ee5\u540e\uff0cLLVM \u548c Clang \u5c31\u6784\u5efa\u597d\u4e86\u3002 \u8fd0\u884c\u8bd5\u8bd5 ls build/bin \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u53ea\u662f\u8ba9\u4f60\u83b7\u5f97\u4e00\u4e2a\u5168\u5c40\u89c2\u5ff5\uff08overview\uff09\uff0c\u4e0d\u7528\u6df1\u7a76\u7ec6\u8282\uff0c\u4e4b\u540e\u4f1a\u518d\u8be6\u7ec6\u5c55\u5f00\u4ecb\u7ecd\u7684\u3002 \u5b66\u8fc7 C \u8bed\u8a00\u7684\u540c\u5b66\u90fd\u77e5\u9053\uff0c\u4e00\u4e2a C/C++ \u6e90\u7801\u6587\u4ef6\u5230\u8ba1\u7b97\u673a\u5b9e\u9645\u53ef\u6267\u884c\u7684 EXE \u6587\u4ef6\u4e4b\u95f4\uff0c\u4e3b\u8981\u6709\u4e24\u6b65\u64cd\u4f5c\uff1a\u7f16\u8bd1\uff08compile\uff09\u548c\u94fe\u63a5\uff08link\uff09\u3002 \u4e4b\u6240\u4ee5\u628a\u7f16\u8bd1\u548c\u94fe\u63a5\u5206\u5f00\uff0c\u662f\u56e0\u4e3a\u4e00\u4e2a\u9879\u76ee\u5e38\u5e38\u7531\u8bb8\u591a\u6e90\u7801\u6587\u4ef6\u7ec4\u6210\uff0c\u800c\u4e0d\u53ea\u662f\u5355\u4e2a\u6587\u4ef6\u3002\u7f16\u8bd1\u5668\u628a C++ \u6e90\u7801\u7f16\u8bd1\u6210\u4e2d\u95f4\u5bf9\u8c61\u6587\u4ef6\uff08.o \u6216 .obj \u683c\u5f0f\uff09\uff0c\u5982\u679c\u6709\u5f88\u591a .cpp \u6587\u4ef6\uff0c\u5c31\u4f1a\u5f97\u5230\u5f88\u591a .o \u6587\u4ef6\uff0c\u7136\u540e\u7531\u94fe\u63a5\u5668\u8d1f\u8d23\u7edf\u4e00\u94fe\u63a5\u6240\u6709 .o \u6587\u4ef6\uff0c\u5c31\u5f97\u5230\u4e86\u6700\u7ec8\u7684 .exe \u6216 .dll \u76ee\u6807\u6587\u4ef6\u3002 \u5206\u79bb\u591a .cpp \u6587\u4ef6\u7684\u597d\u5904\u662f\uff0c\u7f16\u8bd1\u901f\u5ea6\u66f4\u5feb\uff0c\u53ef\u4ee5\u5e76\u884c\u7f16\u8bd1\u3002\u800c\u4e14\u4fee\u6539\u4e86\u5176\u4e2d\u4e00\u4e2a .cpp \u6587\u4ef6\uff0c\u53ea\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u90a3\u4e2a .cpp \u5bf9\u5e94\u7684 .o \u6587\u4ef6\uff0c\u7136\u540e\u91cd\u65b0\u94fe\u63a5\u6700\u7ec8\u7684 .exe \u5373\u53ef\uff0c\u65e0\u9700\u518d\u91cd\u590d\u7f16\u8bd1\u5176\u4ed6 .cpp \u6587\u4ef6\u7684 .o \u6587\u4ef6\u4e86\u3002\u81ea\u52a8\u68c0\u6d4b\u54ea\u4e9b .cpp \u6587\u4ef6\u66f4\u65b0\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u7f16\u8bd1 .o \u6587\u4ef6\uff0c\u662f Makefile \u548c Ninja \u4e4b\u7c7b\u6784\u5efa\u7cfb\u7edf\u7684\u804c\u8d23\u3002 \u6211\u4eec\u73b0\u5728\u8981\u6765\u5b66\u4e60\u7684\u5c31\u662f\u5176\u4e2d\u7684\u7f16\u8bd1\u9636\u6bb5\uff0c\u8fd9\u4e5f\u662f\u5927\u90e8\u5206\u4eba\u60f3\u5173\u6ce8\u7684\u91cd\u70b9\u3002 \u5728\u8fd9\u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\uff0c\u53d1\u751f\u4e86\u5f88\u591a\u6709\u8da3\u7684\u4e8b\uff0c\u4f46\u5374\u88ab\u4f20\u7edf\u6559\u6750\u7684 C++ \u201c\u4e24\u6bb5\u5f0f\u201d\u7f16\u8bd1\u6a21\u578b\uff08\u7f16\u8bd1 -> \u94fe\u63a5\uff09\u4e00\u7b14\u5e26\u8fc7\u4e86\u3002 \u5c31\u62ff\u8fd9\u91cc\u9762\u7684\u201c\u7f16\u8bd1\u201d\u9636\u6bb5\u5c55\u5f00\u8bb2\u8bb2\uff0c\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5c06 .cpp \u6587\u4ef6\u8f6c\u6362\u4e3a\u5145\u65a5\u7740\u673a\u5668\u6307\u4ee4\u7801 .o \u6587\u4ef6\u7684\uff1f .o \u6587\u4ef6\u91cc\u51e0\u4e4e\u5168\u662f\u5b8c\u6210\u7684\u673a\u5668\u6307\u4ee4\u7801\uff0c\u9664\u4e86\u90e8\u5206 call \u5230\u5916\u90e8\u51fd\u6570\u7684\u4e00\u90e8\u5206\u6307\u4ee4\uff0c\u4f1a\u7559\u767d\u3002\u8fd9\u90e8\u5206\u7559\u767d\u4f1a\u7b49\u5230\u94fe\u63a5\u9636\u6bb5\u65f6\uff0c\u7531\u94fe\u63a5\u5668\u5728\u5176\u4ed6 .o \u6587\u4ef6\u4e2d\u627e\u5230\u76f8\u540c\u7684\u7b26\u53f7\u65f6\u66ff\u6362\u4e0a\u6b63\u786e\u7684\u5730\u5740\u548c\u504f\u79fb\u91cf\uff0c\u5f97\u5230\u5b8c\u6574\u7684\u53ef\u6267\u884c .exe \u6587\u4ef6\u3002 \u8fc7\u53bb\uff0c\u6211\u4eec\u628a\u7f16\u8bd1\u5668\u770b\u4f5c\u9ed1\u7bb1\uff0c\u8fdb\u53bb\u6e90\u7801\uff0c\u51fa\u6765\u673a\u5668\u7801\uff0c\u4e2d\u95f4\u6709\u54ea\u4e9b\u8fc7\u7a0b\uff1f\u53ea\u80fd\u8ba4\u4e3a\u662f\u9b54\u6cd5\u3002 \u73b0\u5728\uff0c\u6709\u4e86 LLVM \u548c Clang \u6e90\u7801\u5728\u624b\uff0c\u7ec8\u4e8e\u53ef\u4ee5\u4e00\u63a2\u7a76\u7adf\u4e86\u3002 \u5b9e\u9645\u4e0a\uff0c\u201c\u7f16\u8bd1\u201d\u8fd9\u4e00\u8fc7\u7a0b\uff0c\u8fd8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u62c6\u5206\u6210\u4e09\u4e2a\u9636\u6bb5\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u7f16\u8bd1\u5668\uff08Compiler\uff09\u7684\u5de5\u4f5c\u6d41\u7a0b\u53ef\u4ee5\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\uff1a \u524d\u7aef\uff08Front-end\uff09\uff1a\u8d1f\u8d23\u63a5\u6536\u6e90\u4ee3\u7801\uff0c\u89e3\u6790\u51fa\u62bd\u8c61\u8bed\u6cd5\u6811\uff08AST\uff09\uff0c\u5e76\u8fdb\u884c\u8bed\u6cd5\u548c\u8bed\u4e49\u5206\u6790\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\u3002 \u4e2d\u7aef\uff08Middle-end\uff09\uff1a\u8d1f\u8d23\u4f18\u5316\u4e2d\u95f4\u8868\u793a\u7801\u3002 \u540e\u7aef\uff08Back-end\uff09\uff1a\u8d1f\u8d23\u5c06\u4f18\u5316\u5b8c\u6bd5\u7684\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u4e2d\u540e\u7aef\u548c\u4e92\u8054\u7f51\u5f00\u53d1\u8005\u6240\u8bf4\u7684\u524d\u540e\u7aef\u65e0\u5173\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u662f\u524d\u7aef\u9ad8\u624b\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u96c7\u4f63\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u8ba8\u538c JS\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u4f60\u4e0d\u662f\u524d\u7aef\u9ad8\u624b\u5417\uff1f\u5c0f\u5f6d\u8001\u5e08\uff1a\u7f16\u8bd1\u5668\u524d\u7aef\u3002 \u5982\u679c\u4f60\u60f3\u8981\u7814\u7a76 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u6bd4\u5982\u505a\u4e2a C++ \u8bed\u6cd5\u9ad8\u4eae\u63d2\u4ef6\uff0c\u90a3\u5c31\u9700\u8981\u770b\u524d\u7aef\u3002libclang \u548c clangd \u53ef\u4ee5\u5e2e\u52a9\u4f60\u89e3\u6790 C++ \u7e41\u7410\u7684\u8bed\u6cd5\uff0c\u5e76\u4ee5 AST \u6811\u7684\u7ed3\u6784\u63d0\u4f9b\u7ed9\u4f60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u5982\u679c\u4f60\u8981\u8bbe\u8ba1\u4e00\u95e8\u65b0\u8bed\u8a00\uff0c\u751a\u81f3\u662f OpenGL \u9a71\u52a8\uff08\u5176\u9700\u8981\u5b9e\u73b0 GLSL \u7f16\u8bd1\u5668\uff09\uff0c\u5b9e\u9645\u4e0a\u4e5f\u5c31\u662f\u4e3a LLVM \u6dfb\u52a0\u4e00\u4e2a\u524d\u7aef\u3002 \u5982\u679c\u4f60\u5bf9\u5185\u5b58\u6a21\u578b\uff0c\u6027\u80fd\u4f18\u5316\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u7814\u7a76\u4e2d\u7aef\u3002\u8fd9\u662f\u76ee\u524d\u5b66\u672f\u7814\u7a76\u6bd4\u8f83\u6d3b\u8dc3\u7684\u9886\u57df\uff0c\u7279\u522b\u662f\u591a\u9762\u4f53\u4f18\u5316\u65b9\u5411\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6c34\u4e24\u5f20 paper \u6216 PR\u3002\u8fd9\u90e8\u5206\u90fd\u662f\u57fa\u4e8e LLVM IR \u64cd\u4f5c\u7684\uff0c\u6709\u7279\u522b\u591a\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u3002 \u5982\u679c\u4f60\u5bf9\u6c47\u7f16\u8bed\u8a00\uff0c\u673a\u5668\u6307\u4ee4\uff0c\u786c\u4ef6\u67b6\u6784\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u770b\u540e\u7aef\u3002\u8fd9\u91cc\u9762\u6709\u628a\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u771f\u6b63\u53ef\u6267\u884c\u7684\u6c47\u7f16\u6307\u4ee4\u7684\u5b8c\u6574\u8fc7\u7a0b\uff0c\u81ea\u7814\u82af\u7247\u7684\u5927\u5382\u901a\u5e38\u60f3\u8981\u4e3a LLVM \u6dfb\u52a0\u540e\u7aef\u3002 \u6ce8\u610f\u94fe\u63a5\u9636\u6bb5\uff08Link\uff09\u5c5e\u4e8e\u94fe\u63a5\u5668\u7684\u804c\u8d23\uff0c\u4e0d\u5c5e\u4e8e\u72ed\u4e49\u4e0a\u7684\u7f16\u8bd1\u5668\uff1b\u524d\u4e2d\u540e\u7aef\u53ea\u662f\u5bf9\u7f16\u8bd1\uff08Compile\uff09\u8fd9\u4e00\u9636\u6bb5\u7684\u8fdb\u4e00\u6b65\u62c6\u5206\u3002 \u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u8d70\u8fdb LLVM \u8fd9\u5ea7\u5f00\u6e90\u5de5\u5382\uff0c\u4e00\u6b65\u6b65\u89c2\u5bdf\u4e00\u6bb5 C++ \u4ee3\u7801\u88ab\u7f16\u8bd1\u6210\u6c47\u7f16\u7684\u5168\u8fc7\u7a0b\u3002 \u8bed\u6cd5\u6811\uff08AST\uff09 \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u8d1f\u8d23\u89e3\u6790 C++ \u8fd9\u7c7b\u9ad8\u7ea7\u8bed\u8a00\u7684\u6e90\u4ee3\u7801\uff0c\u751f\u6210\u62bd\u8c61\u8bed\u6cd5\u6811\uff08Abstract Syntax Tree\uff0cAST\uff09\u3002AST \u662f\u6e90\u4ee3\u7801\u7684\u4e00\u79cd\u62bd\u8c61\u8868\u793a\uff0c\u5176\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u6e90\u4ee3\u7801\u4e2d\u7684\u4e00\u4e2a\u8bed\u6cd5\u7ed3\u6784\uff0c\u4f8b\u5982 if\u3001while\u3001for\u3001\u51fd\u6570\u8c03\u7528\u3001\u8fd0\u7b97\u7b26\u3001\u53d8\u91cf\u58f0\u660e\u7b49\u3002\u6bcf\u4e2a AST \u8282\u70b9\u90fd\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982\u7c7b\u578b\u3001\u4f5c\u7528\u57df\u3001\u4fee\u9970\u7b26\u7b49\u3002 \u4e0d\u540c\u7c7b\u578b\u7684 AST \u8282\u70b9\u6709\u4e0d\u540c\u7684\u7c7b\u578b\u540d\uff0c\u4f8b\u5982 IntegerLiterial \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6574\u6570\u7c7b\u578b\u7684\u5e38\u91cf\uff0c\u800c BinaryOperator \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u4e8c\u5143\u8fd0\u7b97\u7b26\uff08\u53ef\u80fd\u662f\u52a0\u51cf\u4e58\u9664\u7b49\u4e8c\u5143\u8fd0\u7b97\uff09\u3002 AST \u8282\u70b9\u53ef\u4ee5\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u8282\u70b9\uff0c\u8bb8\u591a\u8282\u70b9\u5c31\u6784\u6210\u4e86\u4e00\u9897\u8bed\u6cd5\u6811\u3002\u6bcf\u4e2a .cpp \u6587\u4ef6\u90fd\u53ef\u4ee5\u89e3\u6790\u5f97\u5230\u4e00\u9897\u8bed\u6cd5\u6811\uff0c\u5728 C++ \u7684\u8bed\u6cd5\u4e2d\uff0c\u6bcf\u9897\u6811\u7684\u6839\u90e8\u603b\u662f\u4e00\u4e2a TranslationUnitDecl \u7c7b\u578b\u7684\u8282\u70b9\u3002\u8fd9\u662f\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\uff0c\u5176\u4e2d\u5305\u542b\u4e86\u4efb\u610f\u591a\u7684\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u7b49\uff0c\u4f5c\u4e3a TU \u7684\u5b50\u8282\u70b9\u5b58\u5728\u5176\u4e2d\u3002 \u5bf9\u6811\u505a\u4e86\u4e00\u4e9b\u8bed\u6cd5\u8bed\u4e49\u4e0a\u7684\u6b63\u786e\u6027\u68c0\u6d4b\u540e\uff0c\u5c31\u4f1a\u904d\u5386\u8fd9\u9897\u6811\uff0c\u4e3a\u6bcf\u4e2a\u8282\u70b9\u9010\u4e00\u751f\u6210\u5bf9\u5e94\u7684 LLVM IR\uff0c\u8f93\u5165\u5230\u4e2d\u540e\u7aef\u4f18\u5316\u5e76\u751f\u6210\u771f\u6b63\u7684\u6c47\u7f16\u3002 // Clang \u6e90\u7801\u4e2d\u7684 AST \u8282\u70b9\u7c7b\u578b\u5927\u81f4\u957f\u8fd9\u6837\uff08\u5df2\u7b80\u5316\uff09 struct ASTNode { std::string type; std::vector children; }; \u8fd9\u90e8\u5206\u7684\u5b9e\u73b0\u5728 clang \u5b50\u9879\u76ee\u4e2d\u3002 clang \u89e3\u6790\u6e90\u7801\u751f\u6210\u8bed\u6cd5\u6811\u7684\u6848\u4f8b\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u8fd0\u884c\u547d\u4ee4\uff1a clang -fsyntax-only -Xclang -ast-dump test.cpp -fsyntax-only \u610f\u5473\u7740\u53ea\u89e3\u6790\u8bed\u6cd5\uff0c\u4e0d\u8fdb\u884c\u7f16\u8bd1\u548c\u94fe\u63a5\uff08\u4e0d\u4f1a\u751f\u6210 a.out\uff09\uff1b -Xclang \u662f\u6307\u5411 Clang \u6838\u5fc3\u4f20\u9012\u4e00\u4e2a\u9009\u9879\uff0c\u4e5f\u5c31\u662f\u540e\u9762\u7d27\u6328\u7740\u7684 -ast-dump \uff1b -ast-dump \u662f Clang \u6838\u5fc3\u7684\u9009\u9879\uff0c\u8868\u793a\u8981\u6c42\u6253\u5370\u51fa\u8bed\u6cd5\u6811\u3002 \u8f93\u51fa\uff1a \u5df2\u7701\u7565 \u5934\u6587\u4ef6\u90e8\u5206\u7684\u5b50\u8282\u70b9\uff0c\u4ec5\u5c55\u793a\u4e86 main \u7684\u90e8\u5206\uff0c\u5426\u5219\u5c31\u592a\u957f\u4e86\u3002 \u6700\u6839\u90e8\u7684 TranslationUnitDecl \u8282\u70b9\uff0c\u662f\u6574\u4e2a\u5f53\u524d\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\u3002 \u6240\u6709\u7684 C++ \u6e90\u7801\u89e3\u6790\u540e\u5f97\u5230\u7684\uff0c\u603b\u662f\u4ee5 TranslationUnitDecl \u4e3a\u6839\u8282\u70b9\u7684\u4e00\u9897\u8bed\u6cd5\u6811\u3002 \u7ffb\u8bd1\u5355\u5143 \u6307\u7684\u5c31\u662f\u5355\u4e2a .cpp \u6587\u4ef6\uff0c\u53ca\u5176\u5bfc\u5165\u7684\u6240\u6709 .h \u5934\u6587\u4ef6\u62fc\u63a5\u5f62\u6210\u7684\u6574\u6bb5 C++ \u6e90\u7801\uff0c\u662f C++ \u7f16\u8bd1\u7684\u6700\u5c0f\u5355\u5143\u3002\u4e0d\u540c\u7ffb\u8bd1\u5355\u5143\u7f16\u8bd1\u6210\u5404\u81ea\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u540e\uff0c\u4e4b\u95f4\u518d\u901a\u8fc7\u201c\u94fe\u63a5\u5668\u201d\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e00\u4e2a\u6700\u7ec8\u7684\u76ee\u6807\u6587\u4ef6\uff08.exe \u6216 .dll\uff09\u3002 \u7ffb\u8bd1\u5355\u5143\u4e2d\u5305\u542b\u4e86\u6240\u6709\u5f53\u524d .cpp \u53ca\u5176\u5bfc\u5165\u7684\u5934\u6587\u4ef6\u4e2d\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\u8282\u70b9\u6709\u7740\u8bb8\u591a\u5b50\u8282\u70b9\uff0c\u4e00\u5927\u5806\u90fd\u662f \u5934\u6587\u4ef6\u4e2d\u5bfc\u5165\u8fdb\u6765\u7684\u51fd\u6570\u58f0\u660e\u548c\u7c7b\u578b\u5b9a\u4e49\u3002 \u4e3a\u4e86\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u6211\u7279\u610f\u4ece\u622a\u56fe\u4e2d\u6263\u6389\u4e86\u6240\u6709\u6765\u81ea \u7684\u8282\u70b9\uff0c\u5e76\u4e0d\u662f\u8bf4\u7ffb\u8bd1\u5355\u5143\u4e0d\u5305\u62ec\u5934\u6587\u4ef6\u54e6\uff01 \u6211\u4eec\u6700\u5173\u5fc3\u7684\u662f\u5176\u4e2d\u4e00\u4e2a\u5b50\u8282\u70b9\uff1a\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u8282\u70b9\uff0c\u7c7b\u578b\u4e3a FunctionDecl\u3002 \u6b64\u5904 FunctionDecl \u5c31\u8868\u660e\uff0c\u8be5\u8282\u70b9\u662f\u4e00\u4e2a\u51fd\u6570\uff08Function\uff09\u7684\u58f0\u660e\uff08Decleration\uff09\u3002\u6ce8\u610f\u5230\u540e\u9762\u8ddf\u7740\u8bb8\u591a\u548c\u8be5\u51fd\u6570\u5b9a\u4e49\u6709\u5173\u7684\u5173\u952e\u4fe1\u606f\uff0c\u8ba9\u6211\u4eec\u9010\u4e00\u5206\u6790\uff1a \u8fd9\u91cc\u7684\u5341\u516d\u8fdb\u5236\u6570 0x567bdbf246d8 \u662f AST \u8282\u70b9\u5728\u7f16\u8bd1\u5668\u5185\u5b58\u4e2d\u7684\u5730\u5740\uff0c\u6bcf\u6b21\u90fd\u4e0d\u4e00\u6837\uff0c\u65e0\u610f\u4e49\u3002 \u540e\u9762\u7684\u5c16\u62ec\u53f7 \u91cc\u8fd8\u597d\u5fc3\u63d0\u9192\u4e86\u51fd\u6570\u5b9a\u4e49\u7684\u4f4d\u7f6e\u3002 \u6700\u540e\u662f\u51fd\u6570\u540d main \u548c\u51fd\u6570\u7c7b\u578b int () \uff0c\u8bf4\u660e\u8fd9\u662f\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u3002 \u6709\u8da3\u7684\u662f\uff0c\u8be5\u8282\u70b9\u7684\u7c7b\u578b\u662f FunctionDecl\uff0c\u7ffb\u8bd1\u6210\u4e2d\u6587\u5c31\u662f\u51fd\u6570\u58f0\u660e\u3002\u4f46\u662f\u6211\u4eec\u5199\u7684\u660e\u660e\u662f\u4e00\u4e2a\u51fd\u6570\u7684 \u5b9a\u4e49 \u554a\uff01\u4e3a\u4ec0\u4e48\u88ab Clang AST \u5f53\u4f5c\u4e86 \u58f0\u660e \u5462\uff1f\u539f\u6765\uff0cC++ \u5b98\u65b9\u7684\u8bdd\u8bed\u4e2d\uff0c\u5b9a\u4e49\u4e5f\u662f\u58f0\u660e\uff01\u4f46\u58f0\u660e\u4e0d\u90fd\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u8fd9\u91cc\u7684 FunctionDecl \u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u901a\u7528\u7684\u8282\u70b9\uff0c\u65e2\u53ef\u4ee5\u662f\u58f0\u660e\uff08\u540e\u9762\u76f4\u63a5\u63a5 ; \u7684\uff09\uff0c\u4e5f\u53ef\u4ee5\u662f\u5b9a\u4e49\uff08\u540e\u9762\u63a5\u7740 {} \u7684\uff09\uff0c\u8981\u6839\u636e\u662f\u5426\u6709\u5b50\u8282\u70b9\uff08\u82b1\u62ec\u53f7\u8bed\u53e5\u5757\uff09\u6765\u5224\u65ad\u3002 \u603b\u4e4b\uff0c\u5b9a\u4e49\u548c\u58f0\u660e\u662f\u5b50\u96c6\u5173\u7cfb\u3002\u5f53\u6211\u4eec\u8981\u5f3a\u8c03\u4e00\u4e2a\u58f0\u660e\u53ea\u662f\u58f0\u660e\uff0c\u6ca1\u6709\u5b9a\u4e49\u65f6\uff0c\u4f1a\u7528 \u975e\u5b9a\u4e49\u58f0\u660e \u8fd9\u6837\u4e25\u8c28\u7684\u5f8b\u5e08\u8bf4\u6cd5\u3002\u4f46\u65e5\u5e38\u63d0\u95ee\u65f6\u4f60\u8bf4\u201c\u58f0\u660e\u201d\u6211\u4e5f\u660e\u767d\uff0c\u4f60\u6307\u7684\u5e94\u8be5\u662f\u975e\u5b9a\u4e49\u58f0\u660e\u3002\u66f4\u591a\u76f8\u5173\u6982\u5ff5\u8bf7\u770b \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49 \u7ae0\u8282\u548c \u767d\u5f8b\u5e08\u7684\u9510\u8bc4 \uff0c\u7528\u6587\u6c0f\u56fe\u6765\u753b\u5c31\u662f\uff1a \u51fd\u6570\u5b9a\u4e49\u8282\u70b9\u53c8\u5177\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f CompoundStmt\u3002\u8fd9\u4e2a\u5b9e\u9645\u4e0a\u5c31\u662f\u6211\u4eec\u6240\u8bf4\u7684\u82b1\u62ec\u53f7\u8bed\u53e5\u5757 {} \u4e86\u3002\u4ed6\u672c\u8eab\u4e5f\u662f\u4e00\u6761\u8bed\u53e5\uff0c\u4f46\u91cc\u9762\u7531\u5f88\u591a\u6761\u5b50\u8bed\u53e5\u7ec4\u6210\u3002\u89c4\u5b9a\u51fd\u6570\u58f0\u660e FunctionDecl \u5982\u679c\u662f\u5b9a\u4e49\uff0c\u5219\u5176\u552f\u4e00\u5b50\u8282\u70b9\u5fc5\u987b\u662f\u8bed\u53e5\u5757\u7c7b\u578b CompoundStmt\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u719f\u6089\u7684\u51fd\u6570\u58f0\u660e\u540e\u7d27\u63a5\u7740\u82b1\u62ec\u53f7\uff0c\u5c31\u80fd\u5b9a\u4e49\u51fd\u6570\u3002\u5982\u679c\u662f\u975e\u5b9a\u4e49\u58f0\u660e\uff08\u4ec5\u58f0\u660e\uff0c\u4e0d\u5b9a\u4e49\uff09\u90a3\u5c31\u6ca1\u6709\u8fd9\u4e2a\u5b50\u8282\u70b9\u3002 \u63a5\u4e0b\u6765\u53ef\u4ee5\u770b\u5230 CompountStmt \u5185\u90e8\uff0c\u53c8\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1aCallExpr \u548c ReturnStmt\uff0c\u5206\u522b\u662f\u6211\u4eec\u5bf9 printf \u51fd\u6570\u7684\u8c03\u7528\uff0c\u548c return 0 \u8fd9\u4e24\u6761\u5b50\u8bed\u53e5\u3002 ReturnStmt \u5f88\u597d\u7406\u89e3\uff0c\u4ed6\u53ea\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f IntegerLiterial\uff0c\u8868\u793a\u4e00\u4e2a\u6574\u5f62\u5e38\u6570\uff0c\u6574\u6570\u7684\u7c7b\u578b\u662f int\uff0c\u503c\u662f 0\u3002\u8fd9\u79cd\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\u7684 ReturnStmt \u8282\u70b9\uff0c\u5c31\u8868\u793a\u4e00\u4e2a\u6709\u8fd4\u56de\u503c\u7684 return \u8bed\u53e5\uff0c\u6574\u4f53\u6765\u770b\u4e5f\u5c31\u662f\u6211\u4eec\u4ee3\u7801\u91cc\u5199\u7684 return 0 \u3002 \u4e3e\u4e00\u53cd\u4e09\uff0c\u53ef\u4ee5\u60f3\u8c61\uff1a\u5982\u679c\u4ee3\u7801\u91cc\u5199\u7684\u662f return x + 1 \uff0c\u90a3\u4e48 ReturnStmt \u7684\u5b50\u8282\u70b9\u5c31\u4f1a\u53d8\u6210\u8fd0\u7b97\u7b26\u4e3a + \u7684 BinaryOperator\u3002\u5176\u53c8\u5177\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1a\u5de6\u4fa7\u662f DeclRefExpr \u8282\u70b9\uff0c\u6807\u8bc6\u7b26\u4e3a x \uff1b\u53f3\u4fa7\u662f IntegerLiterial \u8282\u70b9\uff0c\u503c\u4e3a 1\u3002 \u7136\u540e\u6211\u4eec\u6765\u770b printf \u51fd\u6570\u8c03\u7528\u8fd9\u6761\u8bed\u53e5\uff1a \u53ef\u4ee5\u770b\u5230\u662f\u4e00\u4e2a CallExpr\uff0c\u8868\u793a\u8fd9\u662f\u51fd\u6570\u8c03\u7528\uff0c\u800c\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\u9700\u8981\u77e5\u9053\u4e24\u4e2a\u4fe1\u606f\uff1a \u8c03\u7528\u54ea\u4e2a\u51fd\u6570\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f printf \u51fd\u6570\u3002 \u4f20\u9012\u7ed9\u51fd\u6570\u7684\u5b9e\u53c2\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f \"Hello, world!\" \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u3002 \u8fd9\u5c31\u5206\u522b\u7528\u4e24\u4e2a\u5b50\u8282\u70b9\u8868\u793a\u4e86\u3002 \u6ce8\u610f\u5230\u8fd9\u91cc printf \u53d1\u751f\u4e86\u4e00\u4e2a\u9690\u5f0f\u8f6c\u6362 ImplicitCastExpr \u540e\u624d\u4f5c\u4e3a CallExpr \u7684\u7b2c\u4e00\u4e2a\u5b50\u8282\u70b9\uff08\u56de\u7b54\u4e86\u8c03\u7528\u54ea\u4e2a\u51fd\u6570\u7684\u95ee\u9898\uff09\uff0c\u5e76\u4e14\u540e\u9762\u6ce8\u91ca\u4e86\u8bf4 FunctionToPointerDecay \u3002\u4e5f\u5c31\u662f\u8bf4\uff0c printf \u8fd9\u4e2a\u6807\u8bc6\u7b26\uff08DeclRefExpr\uff09\u672c\u6765\u662f\u4e00\u4e2a\u5bf9\u51fd\u6570\u6807\u8bc6\u7b26\u7684\u5f15\u7528\uff0c\u8fd8\u6ca1\u6709\u53d8\u6210\u51fd\u6570\u6307\u9488\uff0c\u8fd9\u65f6\u5019\u8fd8\u6ca1\u6709\u5b8c\u6210\u51fd\u6570\u7684\u91cd\u8f7d\u51b3\u8bae\u3002\u662f\u7b49\u5230\u51fd\u6570\u88ab () \u8c03\u7528\u65f6\uff0c\u624d\u4f1a\u89e6\u53d1\u91cd\u8f7d\u51b3\u8bae\uff0c\u800c\u5b9e\u73b0\u533a\u5206\u91cd\u8f7d\u7684\u65b9\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\u5f15\u7528\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u6210\u51fd\u6570\u6307\u9488\u7684\u8fc7\u7a0b\u6240\u89e6\u53d1\u7684\uff0c\u4e5f\u5c31\u662f\u8fd9\u91cc\u7684 ImplicitCastExpr \u9690\u5f0f\u8f6c\u6362\u8282\u70b9\u4e86\u3002\u8fd9\u79cd\u81ea\u52a8\u53d1\u751f\u7684\u9690\u5f0f\u8f6c\u6362\u88ab\u79f0\u4e3a\u201c\u9000\u5316\u201d\uff08decay\uff09\u3002\u6240\u4ee5\uff0c\u51fd\u6570\u5f15\u7528\u65e0\u6cd5\u76f4\u63a5\u8c03\u7528\uff0cClang \u91cc\u4e00\u76f4\u90fd\u662f\u9700\u8981\u9000\u5316\u6210\u6307\u9488\u624d\u8c03\u7528\u7684\u3002 \u7136\u540e\uff0c\u8fd9\u91cc\u7684\u51fd\u6570\u53c2\u6570\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6309\u7406\u8bf4\u4e00\u4e2a StringLiterial \u8282\u70b9\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u6709\u4e2a ImplicitCastExpr\uff1f\u8fd9\u91cc\u6709\u4e2a\u5e38\u89c1\u8bef\u533a\u9700\u8981\u7ea0\u6b63\uff1a\u5f88\u591a\u540c\u5b66\u5e38\u5e38\u60f3\u5f53\u7136\u4ee5\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char * \u3002\u5b9e\u9645\u4e0a\uff0c\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char [] \uff0c\u662f\u4e00\u4e2a\u6570\u7ec4\u7c7b\u578b\uff01\u6570\u7ec4\u4e0d\u662f\u6307\u9488\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u5b8c\u5168\u4e0d\u540c\u7684\u7c7b\u578b\u3002\u4e4b\u6240\u4ee5\u4f60\u4f1a\u6709\u6570\u7ec4\u662f\u6307\u9488\u7684\u9519\u89c9\uff0c\u662f\u56e0\u4e3a\u6570\u7ec4\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a\u5143\u7d20\u7c7b\u578b\u7684\u6307\u9488\u3002\u800c\u8fd9\u662f\u201c\u9000\u5316\u201d\u89c4\u5219\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u51fd\u6570\u53c2\u6570\u3001auto \u63a8\u5bfc\u7684\u65f6\u5019\u662f\u81ea\u52a8\u53d1\u751f\u7684\uff08\u6b63\u5982\u4e0a\u9762\u8bf4\u7684\u51fd\u6570\u5f15\u7528\u4f1a\u5728\u8c03\u7528\u65f6\u81ea\u52a8\u201c\u9000\u5316\u201d\u6210\u51fd\u6570\u6307\u9488\u4e00\u6837\uff09\u3002 \u6570\u7ec4\u80fd\u81ea\u52a8\u9000\u5316\u6210\u6307\u9488\uff0c\u4e0d\u4ee3\u8868\u6570\u7ec4\u5c31\u662f\u6307\u9488\u3002\u4f8b\u5982 int \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a double\uff0c\u96be\u9053\u5c31\u53ef\u4ee5\u8bf4\u201cint \u5c31\u662f double\u201d\u5417\uff1f\u540c\u6837\u5730\uff0c\u4e0d\u80fd\u8bf4\u201c\u6570\u7ec4\u5c31\u662f\u6307\u9488\u201d\u3002\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\uff0c\u4ece\u6765\u90fd\u662f const char [N] \uff0c\u5176\u4e2d N \u662f\u5b57\u7b26\u4e32\u4e2d\u5b57\u7b26\u7684\u4e2a\u6570\uff08\u5305\u62ec\u672b\u5c3e\u81ea\u52a8\u52a0\u4e0a\u7684 '\\0' \u7ed3\u675f\u7b26\uff09\u3002\u53ea\u4e0d\u8fc7\u662f\u5728\u4f20\u5165\u51fd\u6570\u53c2\u6570\uff08\u6b64\u5904\u662f printf \u51fd\u6570\u7684\u5b57\u7b26\u4e32\u53c2\u6570\uff09\u65f6\uff0c\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u4e3a const char * \u4e86\u800c\u5df2\u3002\u6b63\u5982\u8fd9\u4e2a ImplicitCastExpr \u540e\u9762\u5c16\u62ec\u53f7\u7684\u63d0\u793a\u4e2d\u6240\u8bf4\uff0cArrayToPointerDecay\uff0c\u662f\u6570\u7ec4\u7c7b\u578b\u5230\u6307\u9488\u7c7b\u578b\u7684\u81ea\u52a8\u9000\u5316\uff0c\u4ece const char [14] \u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u5230\u4e86 const char * \u3002 #include int main() { printf(\"Hello, world!\"); // \u7b49\u4ef7\u4e8e static_cast(printf) ( static_cast(\"Hello, world!\") ); return 0; } \u603b\u4e4b\uff0c\u901a\u8fc7\u89c2\u5bdf Clang AST \u6811\uff0c\u53ef\u4ee5\u83b7\u5f97\u5f88\u591a\u9690\u85cf\u7684\u4fe1\u606f\uff0c\u7279\u522b\u662f C++ \u7684\u5404\u79cd\u9690\u85cf\u8bed\u6cd5\u89c4\u5219\uff0c\u53ef\u4ee5\u5e2e\u4f60\u89e3\u6784\u8bed\u6cd5\u7cd6\u3002 Clang \u89e3\u6790\u51fa AST \u6811\u540e\uff0c\u4f1a\u518d\u6b21\u904d\u5386\u8be5\u6811\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\uff0c\u8f93\u5165 LLVM \u540e\u7aef\u7f16\u8bd1\uff0c\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff08 -S \uff09\u6216\u4e8c\u8fdb\u5236\u6307\u4ee4\u7801\uff08 -c \uff09\u3002 \u5982\u679c\u6307\u5b9a\u4e86 -emit-llvm \u9009\u9879\uff0c\u5219\u4e0d\u4f1a\u8f93\u5165 LLVM \u540e\u7aef\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6307\u4ee4\u7801\uff0c\u800c\u662f\u76f4\u63a5\u628a\u4ea7\u751f\u7684 IR \u4ee5 IR \u6c47\u7f16\uff08 -S -emit-llvm \uff09\u6216 IR \u5b57\u8282\u7801\uff08 -c -emit-llvm \uff09\u7684\u683c\u5f0f\u5bfc\u51fa\uff0c\u65b9\u4fbf\u6211\u4eec\u5206\u6790\u548c\u67e5\u770b\u3002 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 \u4e2d\u95f4\u8868\u793a\u7801\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u673a\u5668\u6307\u4ee4\uff0c\u5b83\u4e0d\u9488\u5bf9\u5177\u4f53\u7684\u786c\u4ef6\uff0c\u800c\u662f\u4e00\u79cd\u901a\u7528\u7684\u6307\u4ee4\u96c6\u3002\u5b83\u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u8fbe\uff0c\u53ef\u4ee5\u88ab\u8fdb\u4e00\u6b65\u7f16\u8bd1\u4e3a\u76ee\u6807\u4ee3\u7801\u3002 LLVM IR\uff08Intermediate Representation\uff09\u662f\u4e00\u79cd\u4e2d\u95f4\u8bed\u8a00\u8868\u793a\uff0c\u4f5c\u4e3a\u7f16\u8bd1\u5668\u524d\u7aef\u548c\u540e\u7aef\u7684\u5206\u6c34\u5cad\u3002LLVM \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u2014\u2014Clang \u8d1f\u8d23\u4ea7\u751f IR\uff0c\u800c\u5176 LLVM \u540e\u7aef\u8d1f\u8d23\u6d88\u8d39 IR\u3002 C++ \u6e90\u7801 -> IR -> \u76ee\u6807\u5e73\u53f0\u6c47\u7f16 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 IR \u5e76\u4e0d\u662f LLVM \u7684\u4e13\u5229\uff0c\u6240\u6709\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u90fd\u4f7f\u7528 IR\uff0c\u5305\u62ec GCC \u548c MSVC\u3002\u4e5f\u6709\u5f88\u591a\u72ec\u7acb\u4e8e\u7f16\u8bd1\u5668\u7684\u8de8\u5e73\u53f0 IR \u89c4\u8303\uff0c\u4f8b\u5982 SPIR-V\u3001MLIR\u3001MIR\uff0cLLVM IR \u53ea\u662f\u4f17\u591a IR \u4e2d\u7684\u4e00\u79cd\uff0c\u4e13\u7528\u4e8e LLVM \u7f16\u8bd1\u5668\u5168\u5bb6\u6876\u3002\u7531\u4e8e\u672c\u8bfe\u7a0b\u662f LLVM \u8bfe\u7a0b\uff0c\u4ee5\u540e\u63d0\u5230 IR\uff0c\u8bfb\u8005\u5e94\u9ed8\u8ba4\u6307\u7684\u662f LLVM IR\u3002 LLVM IR \u6709\u591a\u79cd\u8868\u73b0\u5f62\u5f0f\uff1a \u5185\u5b58\u4e2d\u7684 IR \u8282\u70b9\u5bf9\u8c61\uff0c\u4f4d\u4e8e clang \u548c libLLVM.so \u8fdb\u7a0b\u7684\u5185\u5b58\u4e2d\uff0c\u90fd\u662f\u4e00\u4e2a\u4e2a C++ \u7c7b\uff0c\u901a\u8fc7\u6307\u9488\u4e92\u76f8\u8fde\u63a5\u3002LLVM \u4f5c\u4e3a\u4e00\u4e2a C++ \u7a0b\u5e8f\uff0c\u5904\u7406 IR \u65f6\u90fd\u662f\u8981\u8bfb\u5230\u5185\u5b58\u4e2d\u5904\u7406\u7684\u3002\u4f46\u7531\u4e8e\u5185\u5b58\u4e2d\u7684 IR \u5bf9\u8c61\u5b58\u5728\u865a\u8868\u6307\u9488\u4ee5\u53ca\u590d\u6742\u7684\u6811\u72b6\u6570\u636e\u7ed3\u6784\uff0c\u65e0\u6cd5\u76f4\u63a5\u5b58\u5165\u78c1\u76d8\uff0c\u4e5f\u65e0\u6cd5\u4f9b\u4eba\u7c7b\u9605\u8bfb\uff0c\u9700\u8981\u5e8f\u5217\u5316\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u683c\u5f0f\u540e\u5b58\u50a8\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u6c47\u7f16\uff08Assembly\uff09\uff0c\u4ee5\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c\u5f62\u5f0f\uff08\u7eaf ASCII \u5b57\u7b26\uff09\u5b58\u50a8\u5728\u78c1\u76d8\u4e2d\uff0c\u65b9\u4fbf\u4eba\u7c7b\u89c2\u5bdf\u3001\u4fee\u6539\u548c\u8c03\u8bd5\u3002\u6211\u4eec\u540e\u9762\u7684\u8bfe\u7a0b\uff0c\u4e5f\u4f1a\u7ecf\u5e38\u89c2\u5bdf\u4e2d\u95f4\u4ea7\u7269\u7684 IR \u6c47\u7f16\uff0c\u5206\u6790 LLVM \u7684\u884c\u4e3a\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u5b58\u50a8\u7684 IR\uff0c\u672c\u8d28\u4e0a\u548c IR \u6c47\u7f16\u76f8\u540c\uff0c\u53ea\u662f\u4ee5\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u5b57\u8282\u5b58\u50a8\u3002\u7f3a\u70b9\u662f\u4eba\u7c7b\u770b\u4e0d\u61c2\uff0c\u4f18\u70b9\u662f\u8282\u7ea6\u78c1\u76d8\u7a7a\u95f4\uff0c\u65b9\u4fbf\u7a0b\u5e8f\u5feb\u901f\u89e3\u6790\u3002 \u5f53\u9700\u8981\u957f\u671f\u50a8\u5b58 IR \u7684\u4e2d\u95f4\u7ed3\u679c\u65f6\u4f1a\u7528\u5230 IR \u5b57\u8282\u7801\uff0c\u5f53\u9700\u8981\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\u4e2d\u95f4\u7ed3\u679c\u65f6\u5c31\u9700\u8981 IR \u6c47\u7f16\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 \u6ce8\u610f IR \u6c47\u7f16\u5e76\u4e0d\u662f\u771f\u6b63\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u8bed\u8a00\uff08Assembly\uff09\uff0c\u4ed6\u53ea\u662f\u4e00\u79cd\u4e2d\u95f4\u4ea7\u7269\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16\uff0c\u6b63\u5982 IR \u5b57\u8282\u7801\u4e0d\u662f x86 \u7684\u673a\u5668\u7801\u4e00\u6837\u3002IR \u7684\u4e1c\u897f\u90fd\u662f LLVM \u5f00\u53d1\u8005\u81ea\u62df\u7684\u4e00\u5957\u683c\u5f0f\uff0c\u548c\u786c\u4ef6\u65e0\u5173\uff0c\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u65e0\u5173\u3002\u4e0d\u8bba\u76ee\u6807\u5e73\u53f0\u662f\u4ec0\u4e48\uff0c\u6765\u81ea\u4ec0\u4e48\u6e90\u7801\u8bed\u8a00\uff0cLLVM IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u683c\u5f0f\u90fd\u662f\u4e00\u6837\u7684\u3002 \u4f46\u4e0d\u540c\u5e73\u53f0\u7684 IR \u4f1a\u9644\u52a0\u4e0d\u540c\u7684 intrinsics \u6307\u4ee4\uff0c\u9664\u6b64\u4e4b\u5916\u7684\u90e8\u5206\u90fd\u662f\u5171\u901a\u7684\u3002\u7531\u4e8e\u5f88\u591a\u7a0b\u5e8f\u4f1a\u5229\u7528\u76ee\u6807\u786c\u4ef6\u505a\u5224\u65ad\uff08\u4f8b\u5982 #ifdef __x86_64__ \uff09\uff0c\u751f\u6210\u4e0d\u540c\u7684 intrinsics\uff0c\u56e0\u6b64 IR \u5e76\u4e0d\u662f\u5b8c\u5168\u8de8\u5e73\u53f0\u7684\u3002 IR \u7684\u76ee\u7684\u662f\u628a\u5927\u90e8\u5206\u901a\u7528\u7684\u8ba1\u7b97\uff0c\u4f8b\u5982\u52a0\u51cf\u4e58\u9664\u3001\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u7edf\u4e00\u6210\u76f8\u540c\u7684 IR \u6c47\u7f16\u3002\u800c\u4e0d\u662f x86 \u6c47\u7f16\u91cc\u53eb call \uff0cARM \u6c47\u7f16\u91cc\u53eb bl \u7684\u4e11\u6001\uff0c\u8fd9\u5c31\u591f\u4e86\u3002\u5bf9\u4e8e\u5229\u7528\u786c\u4ef6\u7279\u6709\u7684\u6307\u4ee4\uff08\u4f8b\u5982 SSE\u3001NEON \u6307\u4ee4\u96c6\uff09\u6765\u4f18\u5316\uff0c\u4ee5\u53ca\u5185\u8054\u6c47\u7f16\uff08 asm \u5173\u952e\u5b57\uff09\u7b49\uff0cLLVM IR \u4e5f\u662f\u652f\u6301\u7684\u3002 \u901a\u7528\u7684\u90a3\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201ccommon IR\u201d\uff0c\u4f8b\u5982 Function\u3001Instruction \u7b49\u3002\u8fd9\u90e8\u5206\u662f\u8de8\u5e73\u53f0\u7684\uff0c\u7edf\u4e00\u4e86\u5206\u5d29\u79bb\u6790\u7684\u5404\u5927\u786c\u4ef6\u6c47\u7f16\uff0c\u4fbf\u4e8e\u7edf\u4e00\u7f16\u5199\u4f18\u5316\u5f15\u64ce\u3002 \u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201cspecific IR\u201d\uff0c\u4f8b\u5982 MachineFunction\u3001MachineInstr \u7b49\u3002\u8fd9\u90e8\u5206\u57fa\u672c\u662f\u7528\u4e8e\u6a21\u4eff\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff0c\u5c31\u662f\u8fd9\u90e8\u5206\u7684\u5b58\u5728\u5bfc\u81f4\u4e86 LLVM IR \u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 \u5728\u8fdb\u5165\u540e\u7aef\u7684\u201c\u6307\u4ee4\u9009\u62e9\u201d\u9636\u6bb5\u540e\uff0cIR \u8282\u70b9\u4e2d\u901a\u7528\u7684\u90a3\u90e8\u5206\u8282\u70b9\uff0c\u4f1a\u9010\u6b65\u88ab\u66ff\u6362\u4e3a\u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u76f8\u5e94 MachineInstr \u8282\u70b9\uff0c\u5728\u201c\u6307\u4ee4\u9009\u62e9\u201d\u540e\u7684\u9636\u6bb5\u770b\u6765\uff0c\u5c31\u597d\u50cf\u524d\u9762\u8f93\u51fa\u4e86\u4e00\u5927\u5806\u5185\u8054\u6c47\u7f16\u4e00\u6837\uff0c\u6700\u7ec8\uff0c\u9010\u6e10\u53d8\u6210\u4e86\u5b8c\u5168\u7684\u76ee\u6807\u5e73\u53f0\u6c47\u7f16\uff0c\u6700\u7ec8\u8f93\u51fa\u3002 LLVM IR \u7684\u7279\u70b9 IR \u548c\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u76f8\u6bd4\uff0c\u4e0d\u4ec5\u4ec5\u662f\u7edf\u4e00\uff0c\u597d\u5904\u6709\u5f88\u591a\u3002 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u6bcf\u4e2a C++ \u6587\u4ef6\u7f16\u8bd1\u5f97\u5230\u7684 IR \u6c47\u7f16\u5747\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u5b9a\u4e49\uff08\u548c\u5c11\u91cf\u7279\u6b8a\u6307\u4ee4\uff0c\u6bd4\u5982 target triple \uff09\u7ec4\u6210\uff0c\u6240\u6709\u7684 IR \u6307\u4ee4\u90fd\u5305\u5728\u51fd\u6570\u4e2d\u3002 \u51fd\u6570\u662f LLVM \u4f18\u5316\u7684\u57fa\u672c\u5355\u4f4d\uff0c\u7edd\u5927\u591a\u6570 LLVM pass\uff0c\u90fd\u662f\u4ee5\u5355\u4e2a\u51fd\u6570\u4e3a\u5355\u4f4d\u6765\u4f18\u5316\u7684\u3002\u53ea\u6709\u5185\u8054\u4f18\u5316\u548c IPO \u4f18\u5316\uff0c\u53ef\u4ee5\u5b9e\u73b0\u8de8\u51fd\u6570\u7684\u4f18\u5316\u3002 \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u5185\u8054\u4f18\u5316\u4e0d\u4ec5\u4ec5\u662f\u201c\u51fd\u6570\u539f\u5c01\u4e0d\u52a8\u63d2\u5165\u8c03\u7528\u4f4d\u7f6e\u201d\u3002\u628a\u51fd\u6570\u63d2\u5165\u8c03\u7528\u8005\u4f53\u5185\u540e\uff0c\u4e24\u4e2a\u51fd\u6570\u878d\u5408\u4e3a\u4e00\u4e2a\u51fd\u6570\u4e86\uff0c\u4f7f\u4f18\u5316\u5668\u7684\u201c\u89c6\u91ce\u201d\u66f4\u5927\uff08\u56e0\u4e3a\u5927\u90e8\u5206\u4f18\u5316\u4e0d\u80fd\u8de8\u8d8a\u51fd\u6570\u8fb9\u754c\uff09\uff01\u4ece\u800c\u5e2e\u52a9\u4e86\u5176\u4ed6\u4ee5\u51fd\u6570\u4e3a\u8fb9\u754c\u7684\u4f18\u5316 pass \u80fd\u591f\u66f4\u597d\u7684\u4f18\u5316\u3002\u4f8b\u5982\u5728 main \u4e2d\u4ee5\u8fed\u4ee3\u5668\u904d\u5386\u4e00\u4e2a\u5bb9\u5668\uff1a\u672c\u6765 main \u51fd\u6570\u662f\u8c03\u7528\u8fed\u4ee3\u5668\u7684 operator++ \uff0c\u800c operator++ \u4e0d\u5185\u8054\u6389\u7684\u8bdd\uff0c main \u7684\u4f18\u5316\u5668\u6c38\u8fdc\u65e0\u6cd5\u610f\u8bc6\u5230 operator++ \u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u6307\u9488\u7684\u52a0\u6cd5\uff0c\u53ea\u80fd\u8001\u8001\u5b9e\u5b9e\u5206\u914d alloca \u7136\u540e\u83b7\u53d6\u51fa this \u6307\u9488\u4f20\u5165 operator++ \u51fd\u6570\u3002\u800c\u5185\u8054\u4ee5\u540e\uff0c operator++ \u7684\u5185\u5bb9\u66b4\u9732\u5728\u4f18\u5316 pass \u773c\u524d\uff0c\u4ed6\u5c31\u77e5\u9053\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u4f18\u5316\u6210\u4e00\u4e2a\u9759\u6001\u5bc4\u5b58\u5668\u4e86\uff0c\u6839\u672c\u4e0d\u7528\u4e3a\u5176\u5206\u914d\u5185\u5b58\uff01\u6700\u7ec8\u4ea7\u751f\u7684\u6c47\u7f16\u4e00\u4e0b\u5b50\u4ece\u5fc5\u987b\u5206\u914d\u5728\u6808\u5185\u5b58\u4e0a\uff0c\u5230\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u6307\u9488\u653e\u5728\u5bc4\u5b58\u5668\u91cc\u4e86\u3002\u800c IPO (Inter-procedure Optimization) \u5219\u662f\u6839\u636e\u51fd\u6570\u53c2\u6570\u4e3a\u5e38\u6570\u7684\u60c5\u51b5\u505a\u5206\u53d1\uff0c\u5206\u53d1\u540e\u53ef\u4ee5\u9488\u5bf9\u4e0d\u540c\u5e38\u6570\u53c2\u6570\u7684\u7ed3\u679c\u505a\u7279\u5b9a\u4f18\u5316\uff0c\u4f46\u4e0d\u5408\u5e76\u51fd\u6570\uff0c\u65e0\u6cd5\u8d4b\u80fd\u5176\u4ed6\u4f18\u5316 pass\uff0c\u6548\u679c\u770b\u8d77\u6765\u5c31\u6ca1\u6709\u5185\u8054\u5f3a\u4e86\u3002\u4f46\u662f\u8981\u6ce8\u610f\u5f88\u591a\u4f18\u5316 pass \u7684\u5f00\u9500\u662f\u548c\u51fd\u6570\u7684\u5927\u5c0f\uff08IR \u6307\u4ee4\u6570\u91cf\uff09\u6210\u6b63\u6bd4\u7684\uff0c\u6240\u4ee5\u5185\u8054\u592a\u591a\u5c42\u5bfc\u81f4\u4e00\u4e2a\u51fd\u6570\u5f88\u5927\u7684\u8bdd\uff0c\u7f16\u8bd1\u4f1a\u53d8\u5f97\u6bd4\u8f83\u6162\u3002 \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u5bc4\u5b58\u5668\u65e0\u9650\u91cf\u4f9b\u5e94\uff01\u4e00\u4e2a\u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u5b9a\u4e49\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668\uff0c\u65e0\u9700\u8003\u8651\u786c\u4ef6\u5177\u4f53\u63d0\u4f9b\u4e86\u591a\u5c11\u4e2a\u5bc4\u5b58\u5668\u3002\u56e0\u4e3a\u548c\u786c\u4ef6\u5bc4\u5b58\u5668\u8131\u94a9\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u79f0\u4e4b\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u53ea\u5728 LLVM \u4e2d\u7aef\u91cc\u51fa\u73b0\uff0c\u4e3a\u4e86\u4fbf\u4e8e\u4f18\u5316\u548c\u5904\u7406\u91c7\u53d6\u7684\u7b80\u5316\u7b56\u7565\u3002 \u865a\u62df\u5bc4\u5b58\u5668\u7edf\u4e00\u4ee5 %0 %1 %2 \u547d\u540d\u3002\u5982\u679c\u6253\u7b97\u624b\u5199 IR\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5b9a\u4e49\u540d\u5b57\u5982 %x %i \uff0c\u4e0d\u8fc7 Clang \u81ea\u52a8\u751f\u6210\u7684 IR \u4e2d\u5bc4\u5b58\u5668\u90fd\u662f\u4ece 0 \u5f00\u59cb\uff0c\u81ea\u52a8\u9012\u589e\u7684\u547d\u540d\u3002 \u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u4f1a\u628a\u8fd9\u4e9b\u5bc4\u5b58\u5668\u6620\u5c04\u5230\u76f8\u5e94\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u4e0d\u7528\u62c5\u5fc3\uff01\u5982\u679c\u540e\u7aef\u53d1\u73b0 IR \u4e2d\u7684\u5bc4\u5b58\u5668\u7528\u91cf\u8d85\u51fa\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u5bc4\u5b58\u5668\u6570\u91cf\u4e0a\u9650\uff0c\u90a3\u4e48\u4f1a\u9009\u62e9\u4e00\u90e8\u5206\u201c\u6253\u7ffb\u201d\uff08spill\uff09\u5230\u5185\u5b58\u4e2d\u53bb\u3002 \u800c\u4e14\u5982\u679c\u53d1\u73b0\u5bc4\u5b58\u5668\u53ef\u4ee5\u590d\u7528\uff0c\u4e5f\u4f1a\u590d\u7528\u4e4b\u524d\u5df2\u7ecf\u6ca1\u7528\u5230\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982\u4ee5\u4e0b IR \u4e2d\uff0c\u770b\u4f3c\u7528\u5230\u4e86\u4e94\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u5b9e\u9645\u53ea\u9700\u8981\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u53ef\u4ee5\u4e86\uff0c\u56e0\u4e3a %1 \u5728\u88ab %2 \u7684 add \u6307\u4ee4\u7528\u5b8c\u4ee5\u540e\uff0c\u5c31\u6ca1\u4eba\u518d\u4f7f\u7528\u4e86\u3002\u8fd9\u65f6\u5c31\u7a7a\u51fa\u4e86\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u8d44\u6e90\uff0c\u540e\u6765\u65b0\u7684\u5bc4\u5b58\u5668\u53ef\u4ee5\u4ece\u8fd9\u91cc\u9876\u66ff\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, 1 \u5728 LLVM \u4e2d\uff0c\u662f\u5229\u7528\u7ebf\u6027\u626b\u63cf\u6cd5\uff08\u7535\u68af\u7b97\u6cd5\uff09\u6765\u786e\u5b9a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff08\u4ece\u7b2c\u4e00\u6b21\u521b\u5efa\uff0c\u5230\u6700\u540e\u4e00\u6b21\u4f7f\u7528\u4e4b\u95f4\u7684\u65f6\u95f4\u6bb5\uff09\uff0c\u5bf9\u4e8e\u751f\u547d\u5468\u671f\u6709\u91cd\u53e0\u7684\u591a\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u624d\u9700\u8981\u4e3a\u4ed6\u4eec\u5206\u914d\u72ec\u7acb\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\uff0c\u5982\u679c\u751f\u547d\u5468\u671f\u6ca1\u6709\u4ea4\u96c6\uff0c\u90a3\u4e48\u53ef\u4ee5\u8ba9\u65b0\u6765\u7684\u865a\u62df\u5bc4\u5b58\u5668\u590d\u7528\u8001\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u53ea\u9700\u8981\u7528\u5230\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u591f\u4e86\uff1a eax = 0 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 \u800c\u5982\u679c %1 \u5bc4\u5b58\u5668\u540e\u9762\u8fd8\u6709\u4f7f\u7528\uff0c\u90a3\u5c31\u4e0d\u80fd\u628a %1 \u6240\u5728\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u590d\u7528\u4e86\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, %1 ; \u6b64\u5904\u7684\u201c\u4f7f\u7528\u201d\u5ef6\u957f\u4e86 %1 \u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff01 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u81f3\u591a\u9700\u8981\u5206\u914d\u4e24\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u8d44\u6e90\uff1a eax = 0 ecx = add eax, 1 ecx = add ecx, 1 ecx = add ecx, 1 ecx = add ecx, 1 eax = add eax, ecx \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u865a\u62df\u5bc4\u5b58\u5668\u90fd\u662f\u53ea\u8bfb\u7684\uff01\u4e00\u6b21\u6027\u8d4b\u503c\u5b8c\u6bd5\u540e\uff0c\u5c31\u4e0d\u5141\u8bb8\u518d\u6b21\u4fee\u6539\uff0c\u6240\u6709\u7684\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u80fd\u5728\u5b9a\u4e49\u7684\u5730\u65b9\u8d4b\u503c\u3002 \u5982\u679c\u9700\u8981\u80fd\u4fee\u6539\u7684\u53d8\u91cf\uff0c\u9700\u8981\u7528 IR \u4e2d\u7684 alloca \u6307\u4ee4\u5728\u51fd\u6570\u6808\u4e0a\u5206\u914d\uff08\u9759\u6001\u5927\u5c0f\u7684\uff09\u7a7a\u95f4\uff0c\u5176\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\u3002 \u5728 Clang \u4e2d\uff0c\u4f1a\u5148\u628a\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u90fd\u5b9a\u4e49\u4e3a alloca \u7684\uff0c\u5f53\u521d\u59cb\u5316\u53d8\u91cf\u65f6\uff0c\u7528 IR \u4e2d\u7684\u5185\u5b58\u5199\u6307\u4ee4 store \u5199\u5165\u521d\u59cb\u503c\u3002 \u7136\u540e\uff0c\u5728\u5f00\u542f\u4e86\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0cLLVM \u4e2d\u7aef\u4e00\u4e2a\u53eb\u505a mem2reg \u7684\u4f18\u5316 pass\uff0c\u4f1a\u68c0\u6d4b\u5230\u6240\u6709\u53ea\u6709\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u5e38\u91cf\u53d8\u91cf\u7684 alloca\uff0c\u5e76\u5c1d\u8bd5\u628a\u4ed6\u4eec\u4f18\u5316\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\u3002 \u5bf9\u4e8e\u5b58\u5728 if \u6761\u4ef6\u8d4b\u503c\uff0c\u4ee5\u53ca for \u5faa\u73af\u7684\uff0c\u5219\u4f1a\u5229\u7528 Phi \u8282\u70b9\uff0c\u4f9d\u7136\u53ef\u4ee5\u4f18\u5316\u79f0\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002\uff08\u540e\u9762\u7684\u7ae0\u8282\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd Phi \u7684\u77e5\u8bc6\uff09 \u5982\u679c\u5b9e\u5728\u907f\u514d\u4e0d\u4e86 alloca\uff08\u6bd4\u5982\u5bf9\u53d8\u91cf\u7528\u5230\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26\uff0c\u800c\u865a\u62df\u5bc4\u5b58\u5668\u6ca1\u6709\u5185\u5b58\u5730\u5740\uff09\uff0c\u90a3\u5c31\u4f1a\u653e\u5f03\u4f18\u5316\u8fd9\u4e2a\u53d8\u91cf\uff0c\u4f9d\u7136\u4fdd\u6301 alloca + store \u7684\u72b6\u6001\u3002 \u6700\u7ec8\uff0c\u6240\u6709\u80fd\u4f18\u5316\u6210\u7684\uff0c\u90fd\u53d8\u6210\u65e0\u9650\u4f9b\u5e94\u4e14\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u4e86\u3002 \u8fd9\u79cd\u5bc4\u5b58\u5668\u53ea\u8bfb\u7684 IR\uff0c\u88ab\u79f0\u4e3a SSA IR\uff08Static Single Assignment IR\uff09\uff0c\u4e2d\u6587\u5c31\u662f\u662f\u201c\u9759\u6001\u5355\u8d4b\u503c IR\u201d\u3002 \u9759\u6001\uff1a\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u548c\u5e8f\u53f7\u662f\u786e\u5b9a\u7684\uff0c\u5728\u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u56fa\u5b9a\u3002 \u5355\u8d4b\u503c\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u53ea\u80fd\u8d4b\u503c\u4e00\u6b21\uff0c\u4e4b\u540e\u4e0d\u5f97\u4fee\u6539\u3002 SSA IR \u7684\u597d\u5904\u662f\u65b9\u4fbf\u4f18\u5316\uff0c\u4f8b\u5982\uff1a x = 1; x = 2; y = x; return y; \u5f88\u660e\u663e\uff0c\u6211\u4eec\u53ef\u4ee5\u628a x = 1 \u8fd9\u4e00\u884c\u4f18\u5316\u6389\uff0c\u56e0\u4e3a\u540e\u9762\u7684 x = 2 \u5df2\u7ecf\u628a\u4ed6\u8986\u76d6\u4e86\u3002\u4f46\u662f\u5982\u4f55\u786e\u5b9a\u8fd9\u4e00\u70b9\uff1f\u5f88\u56f0\u96be\u3002 \u800c\u5982\u679c\u5148\u901a\u8fc7 mem2reg \u8f6c\u6210 SSA IR \u7684\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u8fd9\u65f6\u4ed6\u4f1a\u6ce8\u610f\u5230 x = 1 \u548c x = 2 \u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u8d4b\u503c\uff0c\u751f\u547d\u5468\u671f\u4e92\u4e0d\u91cd\u53e0\uff0c\u53ef\u4ee5\u62c6\u6210\u4e24\u4e2a\u5e38\u91cf\uff0c\u5b89\u5168\u653e\u8fdb\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002 x1 = 1; // \u68c0\u6d4b\u5230\u201c\u4e0d\u53ef\u8fbe\u201d\u7684\u5bc4\u5b58\u5668 x2 = 2; y = x2; return y; \u7136\u540e\uff0c\u7531\u4e8e x1 \u6839\u672c\u6ca1\u6709\u4f7f\u7528\u8fc7\uff0c\u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u5f88\u5bb9\u6613\u5c31\u628a x1 \u8fd9\u4e2a\u672a\u4f7f\u7528\u7684\u53d8\u91cf\u5254\u9664\u6389\u3002\u5373\u4f7f\u4e0d\u662f\u540e\u7aef\uff0c\u4e2d\u7aef\u7684\u4e00\u4e9b\u5176\u4ed6\u4f18\u5316 pass \u4e5f\u5f88\u5bb9\u6613\u6e05\u9664\u8fd9\u4e9b\u672a\u4f7f\u7528\u7684\u5e38\u91cf\u5bc4\u5b58\u5668\u3002 \u603b\u4e4b\uff0c\u901a\u8fc7 SSA \u89c4\u5219\uff0c\u628a\u201c\u5bc4\u5b58\u5668\u88ab\u8986\u76d6\u201d\u8fd9\u4e2a\u6bd4\u8f83\u96be\u68c0\u6d4b\u7684\u6761\u4ef6\uff0c\u53d8\u6210\u4e86\u201c\u5bc4\u5b58\u5668\u53ea\u5b9a\u4e49\uff0c\u6ca1\u4eba\u4f7f\u7528\u201d\u8fd9\u4e2a\u5f88\u5bb9\u6613\u68c0\u6d4b\u7684\u4e8b\u5b9e\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u7531\u4e8e LLVM \u7684\u7814\u7a76\u4e3b\u8981\u96c6\u4e2d\u5728\u4e2d\u7aef\uff0c\u5728\u4e2d\u7aef\u7684\u8bed\u5883\u4e0b\u63d0\u5230\u7684\u5bc4\u5b58\u5668\uff0c\u5982\u975e\u7279\u522b\u8bf4\u660e\uff0c\u8bfb\u8005\u5e94\u5f53\u9ed8\u8ba4\u6307\u7684\u5c31\u662f LLVM \u865a\u62df\u5bc4\u5b58\u5668\uff0c\u800c\u4e0d\u662f\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u6700\u540e\uff0c\u5728\u201c\u5206\u914d\u5bc4\u5b58\u5668\u201d\u9636\u6bb5\uff0c\u628a\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u5bb9\u7eb3\u4e0d\u4e0b\u6216\u65e0\u6cd5\u53d8\u6210\u5355\u6b21\u9759\u6001\u8d4b\u503c\u7684\u90e8\u5206\u53d8\u91cf\uff0c\u518d\u9009\u62e9\u6027\u5730\u201c\u6253\u7ffb\u201d\u5230\u5185\u5b58\u4e2d\u53bb\u3002\u8fd9\u6837\u4e00\u6765\u4e00\u56de\uff0c\u5728\u4e2d\u7aef\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u540e\u7aef\u53c8\u4e00\u6837\u80fd\u6b63\u5e38\u751f\u6210\u6c47\u7f16\uff0c\u5bf9\u4e8e\u5bc4\u5b58\u5668\u7528\u91cf\u8f83\u5c11\u7684\u51fd\u6570\u5219\u5b8c\u5168\u907f\u514d\u4e86\u5185\u5b58\u8bfb\u5199\u3002\u4e3a\u4e86\u4fdd\u8bc1\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf\u90fd\u5b58\u5230\u5bc4\u5b58\u5668\u4e2d\uff0c\u4f60\u53ef\u4ee5\u81ea\u5df1\u6570\u4e00\u4e0b\uff0c\u6240\u6709\u53d8\u91cf\u751f\u547d\u5468\u671f\u91cd\u53e0\u7684\u6700\u591a\u7684\u6570\u91cf\u662f\u591a\u5c11\uff0c\u662f\u5426\u8d85\u8fc7\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u4e0a\u9650\uff1a\u5bf9 x86 \u6765\u8bf4\uff0c\u5c31\u662f\u9664 rsp \u548c rbp \u5916\u6240\u6709\u7684\u901a\u7528\u5bc4\u5b58\u5668\uff08\u6574\u6570\u53d8\u91cf\uff09\u548c\u6240\u6709 xmm \u7cfb\u5217\u5bc4\u5b58\u5668\uff08\u6d6e\u70b9\u53d8\u91cf\uff09\uff1b\u5982\u679c\u8be5\u51fd\u6570\u4e2d\u8fd8\u8c03\u7528\u4e86\u5176\u4ed6\u51fd\u6570\uff0c\u90a3\u4e48\u5c31\u53ea\u6709\u975e\u6613\u5931\u5bc4\u5b58\u5668\u53ef\u7528\u3002 \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u6211\u4eec\u719f\u6089\u7684 x86 \u6c47\u7f16\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u7531\u5176\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\uff08\u4f8b\u5982 add \uff09\u90fd\u662f\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668 + \u6e90\u5bc4\u5b58\u5668\u7684\u7279\u70b9\u5f97\u540d\u3002 add eax, ecx \u6548\u679c\uff1a eax = eax + ecx \u7c7b\u4f3c\u4e8e C \u8bed\u8a00\u4e2d\u7684 += \u8fd0\u7b97\u7b26\uff0c\u4fee\u6539\u662f\u5c31\u5730\u751f\u6548\u5728\u5176\u4e2d\u4e00\u4e2a\u5bc4\u5b58\u5668\u4e0a\u7684\uff0c\u5176\u4e2d\u5de6\u4fa7\u7684\u5bc4\u5b58\u5668\u65e2\u662f\u6e90\u5bc4\u5b58\u5668\u53c8\u662f\u76ee\u7684\u5bc4\u5b58\u5668\u3002 \u4f18\u70b9\uff1a\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u5c31\u5730\u5199\u5165\u53ef\u4ee5\u8282\u7701\u6307\u4ee4\u7801\u7684\u5927\u5c0f\uff0c\u8282\u7701\u7a7a\u95f4\uff0c\u7b26\u5408 x86 \u7684 CISC \u8bbe\u8ba1\u601d\u8def\u3002 \u7f3a\u70b9\uff1a\u5982\u679c\u9700\u8981\u628a\u7ed3\u679c\u5b58\u5728\u53e6\u4e00\u4e2a\u5bc4\u5b58\u5668\u91cc\uff0c\u5c31\u9700\u8981\u5148 mov \u6307\u4ee4\u62f7\u8d1d\u4e00\u4efd\uff0c\u4e14\u5b58\u5728\u526f\u4f5c\u7528\u4e0d\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u800c LLVM \u7684 IR \u662f\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u3002\u4f8b\u5982\uff1a %3 = add %1, %2 \u6548\u679c\uff1a %3 = %1 + %2 \u8fd9\u91cc\uff0c %3 \u662f\u76ee\u6807\u5bc4\u5b58\u5668\uff0c %1 \u548c %2 \u662f\u6e90\u5bc4\u5b58\u5668\uff0c add \u662f\u64cd\u4f5c\u6307\u4ee4\u3002 \u548c\u4e24\u64cd\u4f5c\u6570\u6307\u4ee4\u76f8\u6bd4\uff0c\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u7684\u597d\u5904\u662f\uff1a \u6e90\u5bc4\u5b58\u5668\u53ea\u8bfb\uff0c\u4e0d\u4f1a\u6539\u53d8\uff1a\u5982\u9700\u8ba1\u7b97\u4e00\u52a0\u4e00\u51cf\uff0c\u65e0\u9700\u9884\u5148\u62f7\u8d1d\u4e00\u4efd\u65e7\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u76f4\u63a5 %3 = add %1, %2 \u548c %4 = sub %1, %2 \u5373\u53ef\u3002 \u76ee\u7684\u5bc4\u5b58\u5668\u53ea\u5199\uff0c\u6ee1\u8db3\u4e86\u9759\u6001\u5355\u8d4b\u503c IR\uff08SSA IR\uff09\u7684\u8981\u6c42\uff0c\u4e0d\u9700\u8981\u8003\u8651\u526f\u4f5c\u7528\uff0c\u4f18\u5316\u8d77\u6765\u66f4\u65b9\u4fbf\uff0c\u662f\u4e2d\u95f4 IR \u7684\u7406\u60f3\u8bbe\u8ba1\u3002 \u6240\u6709\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u4e4b\u95f4\u987a\u5e8f\u65e0\u5173\uff0c\u53ef\u4ee5\u4efb\u610f\u8c03\u6362\u987a\u5e8f\uff0c\u53ef\u4ee5\u8f7b\u677e\u901a\u8fc7 DFS \u9012\u5f52\u627e\u51fa\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668\u6240\u6709\u76f4\u63a5\u548c\u95f4\u63a5\u4f9d\u8d56\u7684\u5bc4\u5b58\u5668\uff0c\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u7f3a\u70b9\uff1a\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u4f46\u662f LLVM IR \u662f\u53ea\u5728\u7f16\u8bd1\u671f\u5b58\u5728\u7684\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u5e76\u4e0d\u8fdb\u5165\u6700\u7ec8\u4e8c\u8fdb\u5236\u4ea7\u7269\uff0c\u6700\u7ec8\u7f16\u8bd1\u6210 x86 \u6c47\u7f16\u540e\u4f9d\u7136\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u6240\u4ee5\u8fd9\u4e2a\u7f3a\u70b9\u5e76\u4e0d\u5f71\u54cd\u3002 \u7c7b\u578b\u7cfb\u7edf LLVM IR \u4e2d\uff0c\u6240\u6709\u7684\u5bc4\u5b58\u5668\u5e76\u4e0d\u662f\u539f\u59cb\u7684\u4e8c\u8fdb\u5236\u5185\u5b58\uff0c\u800c\u662f\u6709\u7c7b\u578b\u7684\u3002 \u6709\u4eba\u4f1a\u8bf4\uff0c\u5df2\u7ecf\u8fdb\u5165 IR \u4e86\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u5fc5\u8981\uff1f\u628a\u6240\u6709\u7c7b\u578b\u90fd\u5f53\u6210\u4e8c\u8fdb\u5236\u5185\u5b58\u4e0d\u884c\u5417\uff1f \u5728 IR \u5c42\u9762\u533a\u5206\u7c7b\u578b\u7684\u597d\u5904\uff1a \u53ef\u4ee5\u660e\u786e\u5404\u79cd\u6570\u5b66\u8fd0\u7b97\u64cd\u4f5c\u6570\u7684\u7c7b\u578b\uff08\u4f8b\u5982\u6d6e\u70b9\u6570 f32 \u6216\u6574\u6570 i32 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bc4\u5b58\u5668\u7684\u5927\u5c0f\uff08\u4f8b\u5982 32 \u4f4d\u6574\u6570 i32 \u548c 8 \u4f4d\u6574\u6570 i8 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bf9\u9f50\u5ea6\u3002 \u53ef\u4ee5\u533a\u5206\u51fa\u6307\u9488\u548c\u666e\u901a\u7c7b\u578b\u4e24\u79cd\u4e0d\u540c\u7684\u7528\u9014\uff0c\u9632\u6b62\u6df7\u6dc6\uff08\u4f8b\u5982\u6574\u6570\u7c7b\u578b i32 \u548c\u4ed6\u7684\u6307\u9488 i32* \uff09\u3002 \u5f3a\u7c7b\u578b\u7684 IR \u53ef\u4ee5\u5927\u5927\u5e2e\u52a9\u4f18\u5316 pass \u7406\u89e3\u7a0b\u5e8f\u3002 \u7c7b\u578b\u4e3a\u4ec0\u4e48\u5e2e\u52a9\u4f18\u5316\uff1f\u4f8b\u5982\uff0c\u77e5\u9053\u7c7b\u578b\u4fe1\u606f\u540e\uff0c\u53ef\u4ee5\u914d\u5408 C++ \u7684 strict-aliasing \u89c4\u5219\u6392\u9664\u4e00\u90e8\u5206\u53ef\u80fd\u7684\u6307\u9488\u522b\u540d\uff0c\u79f0\u4e3a\u201c\u57fa\u4e8e\u7c7b\u578b\u7684\u522b\u540d\u5206\u6790\u201d\uff08TBAA, type-based-aliasing-analysis\uff09\u3002 \u522b\u540d\u6307\u7684\u662f\u4e24\u4e2a\u6307\u9488\u6709\u76f8\u4e92\u201c\u7a7f\u63d2\u201d\u7684\u90e8\u5206\uff0c\u6307\u9488\u5b58\u5728\u522b\u540d\u4f1a\u5bfc\u81f4 SIMD \u77e2\u91cf\u4f18\u5316\u5931\u8d25\u3002\u800c C++ \u7684 strict-aliasing \u53ef\u4ee5\u4fdd\u8bc1\u4e0d\u76f8\u5e72\u7c7b\u578b\u7684\u4e24\u4e2a\u6307\u9488\u4e4b\u95f4\u4e0d\u4f1a\u6709\u201c\u7a7f\u63d2\u201d\uff0c\u4ece\u800c\u5e2e\u52a9\u77e2\u91cf\u4f18\u5316\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u4ece int * \u5f3a\u8f6c\u4e3a float * \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u4e3a strict-aliasing \u8981\u6c42\u4e0d\u540c\u7c7b\u578b\u7684\u6307\u9488\u6ca1\u6709\u91cd\u53e0\u90e8\u5206\uff08\u6307\u5411\u76f8\u540c\u7684\u5730\u5740\uff09\uff0c\u5982\u679c\u4f60\u540c\u65f6\u7528\u4e86\u6307\u5411\u540c\u4e00\u4e2a\u5730\u5740\u7684 int * \u548c float * \uff0c\u90a3\u4e48\u5982\u679c LLVM \u5047\u5b9a\u4e86\u4ed6\u4eec\u4e0d\u80fd\u6307\u5411\u540c\u5730\u5740\u6765\u4f18\u5316\uff0c\u5c31\u4f1a\u5bfc\u81f4\u8fd0\u884c\u7ed3\u679c\u51fa\u9519\u3002\u4e0d\u8fc7 int * \u8f6c\u4e3a char * \u3001 unsigned char * \u5374\u662f\u5141\u8bb8\u7684\uff0c\u8fd9\u662f\u56e0\u4e3a\u7ecf\u5e38\u51fa\u73b0\u7528 char \u6765\u505a\u7f13\u51b2\u533a\uff0c\u7136\u540e\u89e3\u6790\u51fa\u7ed3\u6784\u4f53\u7684\u573a\u666f\uff0cC++ \u6807\u51c6\u4e3a\u8fd9\u79cd\u5e38\u7528\u60c5\u51b5\u5f00\u4e86\u540e\u95e8\u3002\u6240\u4ee5\u5982\u679c\u4f60\u9700\u8981\u5728 int \u548c float \u4e4b\u95f4\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 memcpy \u6765\u62f7\u8d1d\uff08 memcpy \u5185\u90e8\u88ab LLVM \u8ba4\u4e3a\u662f\u6309 unsigned char * \u8bbf\u95ee\u7684\uff09\uff0c\u4e0d\u8981\u5f3a\u8f6c\u6307\u9488\u8bbf\u95ee\u3002\u8be6\u89c1\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u3002 \u57fa\u7840\u7c7b\u578b LLVM IR \u4e2d\u7684\u57fa\u7840\u7c7b\u578b\u6709\uff1a LLVM \u7c7b\u578b C \u8bed\u8a00\u7c7b\u578b \u89e3\u91ca i1 bool 1 \u4f4d\u6574\u6570/\u5e03\u5c14\u7c7b\u578b i8 char 8 \u4f4d\u6574\u6570\u7c7b\u578b i16 short 16 \u4f4d\u6574\u6570\u7c7b\u578b i32 int 32 \u4f4d\u6574\u6570\u7c7b\u578b i64 long long 64 \u4f4d\u6574\u6570\u7c7b\u578b f16 _Float16 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b bf16 _BFloat16 \u7a84\u5e95 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b f32 float 32 \u4f4d\u6d6e\u70b9\u7c7b\u578b f64 double 64 \u4f4d\u6d6e\u70b9\u7c7b\u578b f80 long double 80 \u4f4d\u6d6e\u70b9\u7c7b\u578b f128 _Float128 128 \u4f4d\u6d6e\u70b9\u7c7b\u578b void void \u7a7a\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u5176\u4e2d i1 \u662f\u5e03\u5c14\u7c7b\u578b\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 bool \uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u6bd2\u503c\uff09\u3002 \u6307\u9488\u7c7b\u578b \u6240\u6709\u7c7b\u578b\u90fd\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u76f8\u5e94\u7684\u6307\u9488\u7c7b\u578b\uff0c\u7528\u4e00\u4e2a * \u505a\u540e\u7f00\u6765\u8868\u793a\u3002 \u4f8b\u5982\u4e00\u4e2a\u6307\u5411 i8 \u7684\u6307\u9488\uff0c\u7c7b\u578b\u5c31\u662f i8* \uff0c\u5bf9\u5e94 C \u8bed\u8a00\u4e2d\u7684 char * \u7c7b\u578b\u3002 \u6ce8\u610f LLVM IR \u4e2d\u4e0d\u533a\u5206\u7c7b\u578b\u7684 const \u4e0e\u5426\uff0c const \u53ea\u5728 C++ \u8bed\u6cd5\u5c42\u9762\u5b58\u5728\uff0c\u4f8b\u5982 const char * \u548c char * \u5728 LLVM IR \u4e2d\u5bf9\u5e94\u7684\u90fd\u662f i8* \u3002 \u53ef\u4ee5\u7528\u591a\u4e2a * \u540e\u7f00\u8868\u793a\u591a\u91cd\u6307\u9488\uff0c\u4f8b\u5982 char ** \u7c7b\u578b\u5728 LLVM IR \u4e2d\u5c31\u662f i8** \u3002 \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u6ce8\u610f\u5230\uff0cLLVM \u4e2d\u4f3c\u4e4e\u53ea\u6709 i32 \u800c\u6ca1\u6709 u32 \uff1f\u8fd9\u662f\u56e0\u4e3a LLVM IR \u7684\u7c7b\u578b\u7cfb\u7edf\u5e76\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\u3002 int \u548c unsigned int \u90fd\u7edf\u4e00\u7528 i32 \u8868\u793a\uff1b char \u548c unsigned char \u7edf\u4e00\u7528 i8 \u8868\u793a\u3002 \u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\uff1a LLVM IR \u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u4e0d\u5e94\u8be5\u5305\u542b\u592a\u591a\u8bed\u8a00\u7279\u6027\uff0c\u4fdd\u6301\u7b80\u5355\u3002 \u5927\u591a\u6570\u65f6\u5019\uff0c\u6211\u4eec\u5e76\u4e0d\u5173\u5fc3\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\uff0c\u53ea\u5173\u5fc3\u52a0\u51cf\u6cd5\u540e\u662f\u5426\u6ea2\u51fa\u3002 \u50cf\u52a0\u6cd5\uff08 add \uff09\u548c\u51cf\u6cd5\uff08 sub \uff09\u8fd9\u6837\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u7531\u4e8e\u8865\u7801\u7684\u5de7\u5999\u8bbe\u8ba1\uff0c\u65e0\u8bba\u64cd\u4f5c\u6570\u662f\u5426\u6709\u7b26\u53f7\uff0c\u5176\u7ed3\u679c\u5728\u4e8c\u8fdb\u5236\u4e0a\u90fd\u662f\u4e00\u6837\u7684\u3002 \u50cf\u6309\u4f4d\u6216\uff08 or \uff09\u548c\u6309\u4f4d\u4e0e\uff08 and \uff09\u8fd9\u6837\u7684\u903b\u8f91\u8fd0\u7b97\uff0c\u4e5f\u4e0d\u6d89\u53ca\u7b26\u53f7\u4f4d\uff0c\u90fd\u662f\u5f53\u6210\u666e\u901a\u7684\u4e8c\u8fdb\u5236\u4f4d\u6765\u8fd0\u7b97\uff0c\u7ed3\u679c\u4e5f\u6ca1\u6709\u533a\u522b\u3002 \u4fdd\u6301\u7b80\u5355\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\uff0c\u4f8b\u5982\uff0c\u4e0d\u7528\u8003\u8651 int \u7c7b\u578b\u548c unsigned int \u7c7b\u578b\u4e4b\u95f4\u7684\u6765\u56de\u8f6c\u6362\u3002 \u56e0\u6b64 i32 \u548c u32 \u7684 add \u548c sub \u6307\u4ee4\u53ef\u4ee5\u7edf\u4e00\u5f53\u4f5c i32 \u6765\u52a0\u51cf\u3002 \u800c\u5bf9\u4e8e\u4e58\u6cd5\u548c\u9664\u6cd5\u8fd9\u4e9b\u6709\u7b26\u53f7\u548c\u65e0\u7b26\u53f7\u7ed3\u679c\u4f1a\u4e0d\u540c\u7684\u6570\u5b66\u8fd0\u7b97\uff0cLLVM \u5c06\u4ed6\u4eec\u5206\u79bb\u6210\u4e24\u7ec4 IR \u6307\u4ee4\uff1a\u9488\u5bf9\u6709\u7b26\u53f7\u6570\u7684 smul \u548c sdiv \uff0c\u4ee5\u53ca\u9488\u5bf9\u65e0\u7b26\u53f7\u7684 umul \u548c udiv \u3002 \u6240\u4ee5\uff0cLLVM \u53ea\u662f\u9488\u5bf9\u4e58\u9664\u8fd9\u79cd\u6709\u65e0\u7b26\u53f7\u7ed3\u679c\u4e0d\u540c\u7684\u8fd0\u7b97\uff0c\u533a\u5206\u6210\u4e86\u4e24\u5957\u4e0d\u540c\u7684\u6307\u4ee4\uff1a\u7528 s \u548c u \u524d\u7f00\u533a\u5206\uff0c\u5176\u4f59\u50cf\u52a0\u51cf\u6cd5\u8fd9\u4e9b\u6307\u4ee4\u90fd\u662f\u5171\u7528\u7684\u3002 \u9700\u8981\u533a\u5206\u6709\u65e0\u7b26\u53f7\u7684\u6574\u6570\u8fd0\u7b97\u6307\u4ee4\uff1a\u4e58\u6cd5\u3001\u9664\u6cd5\u3001\u53d6\u6a21\u8fd0\u7b97\u3001\u6309\u4f4d\u53f3\u79fb\u3001\u6bd4\u8f83\u5927\u5c0f\u5173\u7cfb\u3002 \u4e0d\u9700\u8981\u533a\u5206\u7684\uff1a\u52a0\u6cd5\u3001\u51cf\u6cd5\u3001\u6309\u4f4d\u6216\u3001\u6309\u4f4d\u4e0e\u3001\u6309\u4f4d\u5f02\u6216\u3001\u6309\u4f4d\u5de6\u79fb\u3001\u6309\u4f4d\u53d6\u53cd\u3001\u6bd4\u8f83\u662f\u5426\u76f8\u7b49\u3002 \u4ece\u6307\u4ee4\u5c42\u9762\u4e0a\u533a\u5206\u6709\u65e0\u7b26\u53f7\u6570\uff0c\u800c\u7c7b\u578b\u5c42\u9762\u4e0a\u76f8\u540c\u3002\u8ba9\u662f\u5426\u6709\u7b26\u53f7\u53d8\u6210\u4e86\u6307\u4ee4\u7684\u7279\u6027\u800c\u4e0d\u662f\u7c7b\u578b\u7684\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u4e0d\u4ec5 LLVM IR \u4e2d\u5982\u6b64\uff0c\u5728 x86 \u6307\u4ee4\u96c6\u4e2d\u4e5f\u662f\u8fd9\u6837\u8bbe\u8ba1\u7684\u3002 \u81ea\u6b64\uff0c\u6709\u65e0\u7b26\u53f7\u7684\u4fe1\u606f\u53ea\u5728 Clang \u524d\u7aef\u4e2d\u51fa\u73b0\uff0c\u7531 Clang \u6839\u636e\u53d8\u91cf\u7c7b\u578b\u4fe1\u606f\uff0c\u9009\u62e9\u751f\u6210 smul \u6216 umul \u7b49 IR \u6307\u4ee4\uff0c\u7c7b\u578b\u90fd\u662f\u7edf\u4e00\u7684 i32 \u3002 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u8fd9\u91cc\u6211\u4eec\u6709\u5fc5\u8981\u660e\u786e\u4e00\u4e0b\u201c\u5b9a\u4e49(define)\u201d\u548c\u201c\u4f7f\u7528(use)\u201d\u3002\u8fd9\u662f\u4e24\u4e2a\u7f16\u8bd1\u5668\u9886\u57df\u7684\u672f\u8bed\uff0c\u7528\u4e8e\u63cf\u8ff0 SSA IR \u7684\u5bc4\u5b58\u5668\u53ca\u5176\u7528\u51b5\u3002 \u5b9a\u4e49\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u88ab\u8d4b\u503c\u7684\u5730\u65b9\uff0c\u5c31\u662f\u4ed6\u7684\u5b9a\u4e49\u3002 %1 = 1 ; %1 \u7684\u5b9a\u4e49 %2 = 2 ; %2 \u7684\u5b9a\u4e49 %3 = add %1, %2 ; %3 \u7684\u5b9a\u4e49 \u56e0\u4e3a LLVM IR \u662f SSA \u7684\uff0c\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c\u53ea\u80fd\u5728\u521d\u59cb\u5316\u65f6\u88ab\u8d4b\u503c\u4e00\u6b21\u3002\u6240\u4ee5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u662f\u552f\u4e00\u7684\uff0c\u4e5f\u5c31\u662f\u521d\u59cb\u5316\u7684\u90a3\u4e00\u6b21\u8d4b\u503c\u7684\u5730\u65b9\u3002 \u8868\u793a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e2d\uff0c\u5176\u521d\u59cb\u5316\uff0c\u7528\u5230\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\u505a\u53c2\u6570\u3002\u8fd9\u4e9b\u88ab\u5f15\u7528\u4e86\u7684\u201c\u53c2\u6570\u5bc4\u5b58\u5668\u201d\uff0c\u5c31\u662f\u4ed6\u7684\u201c\u4f7f\u7528\u201d\u3002 %1 = 1 %2 = 2 %3 = add %1, %2 ; %3 \u4f7f\u7528\u4e86 %1 \u548c %2 \u521d\u59cb\u5316\u4e3a\u5e38\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 %1 = 233 ; %1 \u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u4eba\uff01 \u5728 LLVM \u4e2d\u7ef4\u62a4\u6709\u201c\u5b9a\u4e49-\u4f7f\u7528(def-use)\u201d\u548c\u201c\u4f7f\u7528-\u5b9a\u4e49(use-def)\u201d\u7684\u53cc\u5411\u6620\u5c04\u5173\u7cfb\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\uff0c\u627e\u5230\u4ed6\u88ab\u54ea\u4e9b\u5bc4\u5b58\u5668\u201c\u4f7f\u7528\u201d\u4e86\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u4f7f\u7528\u201d\uff0c\u627e\u5230\u4ed6\u662f\u5728\u54ea\u91cc\u88ab\u201c\u5b9a\u4e49\u201d\u7684\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u548c\u201c\u4f7f\u7528\u5b9a\u4e49\u201d\u662f\u4e24\u4e2a\u4e92\u9006\u7684\u6620\u5c04\u3002\u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c\u4ed6\u4eec\u90fd\u4e0d\u662f\u4e00\u4e00\u6620\u5c04\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u53ef\u4ee5\u88ab\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u91cd\u590d\u4f7f\u7528\uff0c\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e5f\u53ef\u80fd\u4f7f\u7528\u5230\u4e86\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u6620\u5c04 \u7531\u4e8e\u6307\u4ee4\u5728\u4ed6\u7684\u6e90\u64cd\u4f5c\u6570\u4e2d\u6307\u5b9a\u4e86\u64cd\u4f5c\u6570\u6765\u81ea\u54ea\u4e2a\u5bc4\u5b58\u5668\uff0c\u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\u662f IR \u5929\u751f\u81ea\u5e26\u7684\uff0c\u76f4\u63a5\u901a\u8fc7 IR \u8282\u70b9\u7684 op \u6210\u5458\u51fd\u6570\uff0c\u5c31\u80fd\u67e5\u5230\u4ed6\u4f7f\u7528\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\uff08\u6216\u5e38\u6570\uff09\u3002 llvm::Instruction *pi = ...; for (llvm::Use &U: pi->operands()) { llvm::Value *v = U.get(); // v \u4f7f\u7528\u4e86 pi } \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04 \u800c\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff0c\u5c31\u9700\u8981\u6211\u4eec\u81ea\u5df1\u6784\u5efa\u4e86\u3002 \u5e78\u8fd0\u7684\u662f\uff0cLLVM \u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u4fbf\u7684\u5206\u6790\u5de5\u5177\uff0c\u6765\u81ea\u52a8\u6784\u5efa\u8fd9\u4e2a\u5173\u7cfb\uff1a def-use pass\u3002 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM \u4e2d\u7684 pass\uff0c\u662f\u6307\u4e00\u7ec4\u5bf9 IR \u8fdb\u884c\u64cd\u4f5c\u7684\u51fd\u6570\u3002pass \u5206\u4e3a\u5206\u6790\u7c7b pass \u548c\u4f18\u5316\u7c7b pass\u3002 \u5206\u6790\u7c7b pass \u53ea\u662f\u5e2e\u52a9\u6211\u4eec\u89c2\u5bdf IR\uff0c\u83b7\u5f97\u67d0\u4e9b\u6982\u62ec\u4fe1\u606f\uff0c\u5e76\u4e0d\u4fee\u6539 IR\u3002\u73b0\u5728\u6211\u4eec\u8981\u7528\u7684 def-use pass \u5c31\u5c5e\u4e8e\u5206\u6790\u7c7b pass\uff0c\u4ed6\u901a\u8fc7\u4e00\u6b21\u904d\u5386\u627e\u5230\u6240\u6709\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\u5173\u7cfb\u3002\u53ea\u8981 IR \u4e0d\u4fee\u6539\uff0c\u5c31\u53ef\u4ee5\u7f13\u5b58\u4e4b\u524d\u7684\u7ed3\u679c\uff0c\u4f9b\u540e\u6765\u8005\u91cd\u590d\u4f7f\u7528\u3002 \u4f18\u5316\u7c7b pass \u53ef\u4ee5\u4fee\u6539 IR \u7684\u8282\u70b9\uff0c\u4fee\u6539 IR \u539f\u6709\u7684\u7ed3\u6784\uff0c\u4f8b\u5982\u4e4b\u524d\u63d0\u5230\u7684 mem2reg pass \u5c31\u5c5e\u4e8e\u6b64\u7c7b\uff0c\u4ed6\u4f1a\u628a\u6240\u6709\u80fd\u4f18\u5316\u7684 alloca + store \u4fee\u6539\u6210\u9759\u6001\u5355\u8d4b\u503c\u7684\u5bc4\u5b58\u5668\u3002\u7531\u4e8e\u4f1a\u4fee\u6539 IR\uff0c\u53ef\u80fd\u5bfc\u81f4\u67d0\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u5931\u6548\uff0c\u4e0b\u6b21\u518d\u7528\u5230\u65f6\u9700\u8981\u91cd\u8dd1\u3002 \u533a\u522b\uff1a \u5206\u6790\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u5206\u6790\u7ed3\u679c\u7c7b\u578b\u3002\u4f8b\u5982\u5bf9\u4e8e def-use pass\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a Analysis \u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u4e2d\u7ef4\u62a4\u4e86\u4e00\u4e2a \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d \u7684\u53cc\u5411\u6620\u5c04\uff0c\u6211\u4eec def-use pass \u5206\u6790\u5f97\u5230\u7ed3\u679c\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u6620\u5c04\u6765\u67e5\u8be2\u3002 \u4f18\u5316\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u4e5f\u662f\u4e00\u6bb5 IR\uff0c\u88ab\u6539\u53d8\u540e\u7684 IR\u3002LLVM \u5b9e\u73b0\u4f18\u5316\uff0c\u5c31\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u4f18\u5316 pass \u7684\u7ec4\u5408\u5b8c\u6210\u7684\u3002\u6709\u65f6\uff0c\u4f18\u5316 pass \u4f1a\u9700\u8981\u4e00\u4e9b\u5206\u6790\u7684\u7ed3\u679c\uff0c\u624d\u80fd\u8fdb\u884c\uff0c\u56e0\u6b64\u4f18\u5316 pass \u6709\u65f6\u4f1a\u8bf7\u6c42\u4e00\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\uff0cLLVM \u4f1a\u68c0\u67e5\u8fd9\u4e2a\u5206\u6790\u4e4b\u524d\u6709\u6ca1\u6709\u8fdb\u884c\u8fc7\uff0c\u5982\u679c\u6709\uff0c\u5c31\u4f1a\u590d\u7528\u4e0a\u6b21\u5206\u6790\u7684\u7ed3\u679c\uff0c\u4e0d\u4f1a\u91cd\u65b0\u5206\u6790\u6d6a\u8d39\u65f6\u95f4\u3002\u4f18\u5316 pass \u5728\u4fee\u6539\u4e86 IR \u540e\uff0c\u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6807\u5fd7\u4f4d\uff0c\u8868\u793a IR \u4fee\u6539\u540e\uff0c\u54ea\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u5931\u6548\u3002\u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u5c31\u8fd4\u56de all \u5427\uff1a\u672c\u4f18\u5316 pass \u4fee\u6539\u8fc7 IR \u540e\u6240\u6709\u4e4b\u524d\u5206\u6790 pass \u7f13\u5b58\u7684\u7ed3\u679c\u90fd\u4f1a\u5931\u6548\u3002 \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\u662f\u5426\u53ef\u4ee5\u88ab\u4f18\u5316\u6389\uff1f\u68c0\u6d4b\u4ed6\u6709\u6ca1\u6709\u88ab\u522b\u4eba\u201c\u4f7f\u7528\u201d\uff1a\u4e5f\u5c31\u662f\u67e5\u8be2\u4ed6\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\uff0c\u5982\u679c\u53d1\u73b0\u201c\u4f7f\u7528\u8005\u5217\u8868\u201d\u4e3a\u7a7a\uff0c\u5c31\u8bf4\u660e\u8be5\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\u6ca1\u4eba\u4f7f\u7528\uff0c\u53ef\u4ee5\u4f18\u5316\u6389\u3002 LLVM IR \u6848\u4f8b\u5206\u6790 \u4ee5\u4e0b\u662f\u4e00\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u53ca\u5176\u6240\u5bf9\u5e94\u7684 LLVM IR \u6c47\u7f16\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u770b\u8d77\u6765\u597d\u590d\u6742\uff01\u8ba9\u6211\u4eec\u4e00\u884c\u4e00\u884c\u6765\u89e3\u8bfb\uff1a ; ModuleID = 'a.cpp' \u8fd9\u79cd\u4ee5\u5206\u53f7\u5f00\u5934\u7684\uff0c\u5c31\u662f IR \u6c47\u7f16\u8bed\u6cd5\u4e2d\u7684\u6ce8\u91ca\uff0c\u5206\u53f7\u540e\u9762\u7684\u4e1c\u897f\u4f1a\u88ab\u65e0\u89c6\uff0c\u4e0d\u5f71\u54cd\u5b9e\u9645\u7ed3\u679c\u3002\u5c31\u548c C \u8bed\u8a00\u7684 // \u4e00\u6837\uff0c\u5c5e\u4e8e\u884c\u6ce8\u91ca\u3002 Clang \u751f\u6210\u7684 IR \u6c47\u7f16\u6709\u65f6\u5e26\u6709\u6ce8\u91ca\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u7ed9\u4eba\u770b\u7684\uff0c\u5e76\u4e0d\u5f71\u54cd\u540e\u7aef\u7684\u89e3\u6790\u3002\u8fd9\u91cc\u7684\u6ce8\u91ca\u5f88\u660e\u663e\u662f\u5728\u63d0\u793a\uff0c\u8be5\u6c47\u7f16\u662f\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u7684\uff1f\u662f\u4e00\u4e2a\u53eb a.cpp \u7684\u6587\u4ef6\uff0c\u4f46\u4ed6\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u529b\uff0c\u53ea\u662f\u7ed9\u8bfb\u6c47\u7f16\u7684\u4f60\u6211\u770b\u3002 source_filename = \"a.cpp\" target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f \u8fd9\u624d\u662f\u771f\u6b63\u5bf9 LLVM \u4e2d\u7aef\u6709\u6548\u529b\u7684\u4e1c\u897f\uff0c\u4ed6\u8d4b\u503c\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u63d0\u793a\u8be5 IR \u6c47\u7f16\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u3002\u8fd9\u4e2a source_filename \u5c5e\u6027\uff0c\u662f\u7531 Clang \u5728\u751f\u6210 IR \u6c47\u7f16\u65f6\uff0c\u4e3b\u52a8\u52a0\u4e0a\u544a\u77e5 LLVM \u540e\u7aef\u7684\u3002\u4e5f\u662f\u4e3a\u4e86\u65b9\u4fbf\u8c03\u8bd5\uff0c\u4f8b\u5982\u5f53 LLVM \u4e2d\u7aef\u4e2d\u89e6\u53d1\u4e86\u62a5\u9519\uff0c\u4ed6\u53ef\u4ee5\u4ee5\u8fd9\u4e2a\u6587\u4ef6\u540d\u6765\u63d0\u793a\u7528\u6237\u3002 target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" \u8fd9\u91cc\u6307\u5b9a\u7684\u662f\u5173\u4e8e\u201c\u76ee\u6807\u5e73\u53f0\u201d\u7684\u4e00\u4e9b\u4fe1\u606f\uff0c\u5206\u4e3a\u4e24\u4e2a\u90e8\u5206\u3002 \u76ee\u6807\u5e73\u53f0\u6307\u7684\u662f\u5f53\u524d\u6e90\u7801\u8981\u7f16\u8bd1\u5230\u4ec0\u4e48\u786c\u4ef6\u4e0a\u6267\u884c\uff0c\u6bd4\u5982\u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u76ee\u6807\u5e73\u53f0\u5c31\u662f x86\u3002 \u5176\u4e2d target triple \u662f\u6307\u5b9a\u7684\u76ee\u6807\u5e73\u53f0\u7684\u540d\u5b57\uff0c\u8fd9\u91cc\u6211\u4eec\u662f x86_64-pc-linux-gnu \uff0c\u8868\u793a 64 \u4f4d x86 \u67b6\u6784\uff0c\u684c\u9762\u7aef\uff0cLinux \u7cfb\u7edf\uff0cGNU \u7f16\u8bd1\u5668\u63a5\u53e3\u3002\u4e0d\u540c\u7684 target triple \u4f1a\u5f71\u54cd\u6700\u7ec8\u751f\u6210\u7684\u6c47\u7f16\u4e2d\u51fd\u6570\u8c03\u7528\u7ea6\u5b9a\u3001C++ \u51fd\u6570\u540d\u91cd\u7ec4\u7b49\u7ec6\u8282\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a triple \u5c31\u662f\u6211\u4eec\u5e38\u8bf4\u7684 ABI\uff08\u4e8c\u8fdb\u5236\u5e94\u7528\u7a0b\u5e8f\u63a5\u53e3\uff09\u3002 \u4f8b\u5982\uff0c\u5728 Windows \u4e0a\u4f7f\u7528 clang \uff0c\u53ef\u80fd\u5f97\u5230 target triple \u662f x86_64-pc-windows-msvc \uff08\u5982\u679c\u4f60\u662f MSVC \u7f16\u8bd1\u5668\uff09\u6216\u8005 x86_64-pc-windows-gnu \uff08\u5982\u679c\u4f60\u662f MinGW \u7f16\u8bd1\u5668\uff09\uff0c\u4ea7\u751f\u7684 C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u4f1a\u6709\u4e0d\u540c\u3002\u5728 MacOS \u4e0a\u8fd8\u4f1a\u5f97\u5230 x86_64-apple-darwin \u6216 aarch64-apple-darmin \u3002 \u4e0d\u540c\u7684\u64cd\u4f5c\u7cfb\u7edf\u548c\u786c\u4ef6\uff0c\u90fd\u4f1a\u6709\u4e0d\u540c\u7684 ABI\uff0c\u4f8b\u5982 Linux \u5728 x86_64 \u4e0a\u7684 ABI \u89c4\u5b9a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7531 rdi \u4f20\u5165\uff0c\u800c Windows \u5219\u662f rcx \u3002\u8fd9\u4e9b\u7ec6\u8282\u90fd\u662f\u7531 target triple \u786e\u5b9a\u7684\u3002 target datalayout \u5219\u662f\u6307\u5b9a\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u7c7b\u578b\u5927\u5c0f\u548c\u5e03\u5c40\u7b49\u4fe1\u606f\uff0c\u4f8b\u5982\u6307\u9488\u5927\u5c0f\u3001\u5bf9\u9f50\u65b9\u5f0f\u7b49\u3002\u4f8b\u5982\u5728 x86_64-pc-linux-gnu \u8fd9\u4e2a ABI \u4e0a\uff0c long \u662f 64 \u4f4d\u3002\u800c\u5728 x86_64-pc-windows-msvc \u4e0a\uff0c long \u662f 32 \u4f4d\u3002\u8fd9\u4e9b\u4fe1\u606f\u4f1a\u5f71\u54cd\u540e\u7aef\u4ea7\u751f\u6c47\u7f16\u7684\u5185\u5b58\u5e03\u5c40\uff0c\u56e0\u6b64\uff0cIR \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 target datalayout \u662f\u4e00\u4e2a\u5f88\u957f\u7684\u5b57\u7b26\u4e32\uff0c\u91cc\u9762\u6709\u591a\u4e2a\u7531 - \u5206\u9694\u7684\u5b57\u6bb5\u3002\u6bcf\u4e2a\u5b57\u6bb5\u53ef\u4ee5\u5206\u522b\u7528\u6765\u63cf\u8ff0\u6307\u9488\u3001\u6574\u578b\u3001\u6d6e\u70b9\u578b\u3001\u77e2\u91cf\u3001\u6570\u7ec4\u3001\u7ed3\u6784\u4f53\u3001\u8054\u5408\u4f53\u7b49\u7684\u5927\u5c0f\u548c\u5185\u5b58\u5e03\u5c40\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 \uff0c\u6211\u4eec\u9996\u5148\u6309 - \u62c6\u5206\uff0c\u5f97\u5230\u6bcf\u4e00\u4e2a\u5b50\u5b57\u6bb5\u3002 e // \u8868\u793a\u76ee\u6807\u5e73\u53f0\u7684\u5b57\u8282\u5e8f\uff0ce=\u5c0f\u7aef\uff0cE=\u5927\u7aef m:e // \u8868\u793a C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u91c7\u7528\u4f55\u79cd\u673a\u5236\uff0ce=ELF\u98ce\u683c\uff0cw=Windows\u98ce\u683c\u2026\u2026\u7b49 p270:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p271:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p272:64:64 // \u6307\u9488\u5927\u5c0f 64 \u4f4d\uff0c\u5bf9\u9f50\u5230 64 \u4f4d i64:64 // __int64 \u91c7\u7528 64 \u4f4d\u6765\u5b58\u50a8 i128:128 // __int128 \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 f80:128 // long double \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 n8:16:32:64 // \u6307\u5b9a\u54ea\u4e9b\u662f\u76ee\u6807 CPU \u539f\u751f\u7684\u7c7b\u578b\u5927\u5c0f\uff0c\u5bf9\u4e8e 64 \u4f4d x86 \u6765\u8bf4\uff0c\u5206\u522b\u6709 8 \u4f4d\u300116 \u4f4d\u300132 \u4f4d\u300164 \u4f4d\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u90fd\u5199\u4e0a S128 // \u6808\u6307\u9488\uff08rsp\uff09\u5bf9\u9f50\u5230 128 \u4f4d\uff0816 \u5b57\u8282\uff09\uff0c\u8fd9\u662f 64 \u4f4d x86 ABI \u6240\u8981\u6c42\u7684 target datalayout \u7684\u8be6\u7ec6\u8bed\u6cd5\uff0c\u53ef\u4ee5\u53c2\u8003 LLVM \u5b98\u65b9\u6587\u6863 \u3002 270\u3001271\u3001272 \u662f\u4e09\u4e2a\u679a\u4e3e\u503c\uff0c\u5206\u522b\u8868\u793a PTR32_SPTR \u3001 PTR32_UPTR \u548c PTR64 \uff0c\u8868\u793a\u4e0d\u540c\u7684\u6307\u9488\u7c7b\u578b\u3002\u524d\u4e24\u4e2a\u662f\u56e0\u4e3a x86_64 \u67b6\u6784\u4f9d\u7136\u652f\u6301\u4ee5 32 \u4f4d\u5bc4\u5b58\u5668\u505a\u5730\u5740\u8bbf\u95ee\u5185\u5b58\uff08\u975e\u5e38\u611a\u8822\u7684\u8bbe\u5b9a\uff0c\u8bf7\u5ffd\u89c6\uff09\uff0c\u540e\u9762\u7684 PTR64 \u624d\u662f\u6211\u4eec\u6b63\u5e38\u4f7f\u7528\u7684 64 \u4f4d\u6307\u9488\u3002\u679a\u4e3e\u7684\u5b9a\u4e49\u8bf7\u770b llvm/lib/Target/X86/X86.h \u3002 define \u5b9a\u4e49\u51fd\u6570 \u7ee7\u7eed\u770b\u4e0b\u53bb: ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { ... } \u9996\u5148\uff0c\u4ee5\u5206\u53f7\u5f00\u5934\u7684 ; Function Attrs: ... \u662f\u6ce8\u91ca\uff0c\u53ef\u4ee5\u5ffd\u7565\u3002 \u6ce8\u91ca\u91cc\u9762\u7684 mustprogress noinline ... \u7b49\uff0c\u8868\u793a\u7684\u662f\u4e0b\u9762\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u5c5e\u6027\u201d\u3002\u4f46\u662f\u6ce8\u91ca\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u679c\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u4f5c\u7528\uff0c\u771f\u6b63\u8bbe\u7f6e\u4e86\u5c5e\u6027\u7684\u662f\u66f4\u4e0b\u9762\u7684 attributes #0 \u6307\u4ee4\uff0cClang \u751f\u6210\u4e00\u4e2a\u6ce8\u91ca\u53ea\u662f\u8ba9\u4f60\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u4e0d\u7528\u8dd1\u5230\u4e0b\u9762\u624d\u80fd\u770b\u5230\u5c5e\u6027\u3002 \u90a3\u4e48\uff0c\u53ea\u5269\u4e0b\u51fd\u6570\u7684\u5b9a\u4e49\u4e86\uff1a define dso_local noundef i32 @main() #0 { ... } define \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u51fd\u6570\u7684\u5b9a\u4e49\u3002 dso_local \u662f\u51fd\u6570 main \u7684\u4fee\u9970\u7b26\uff0c\u542b\u4e49\u76f8\u5f53\u4e8e extern \u8868\u793a\u8be5\u53d8\u91cf\u4e3a\u5bfc\u51fa\u7b26\u53f7\uff0c\u4e14\u8981\u6c42\u7b26\u5408 ODR \u89c4\u5219\u3002\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u610f\u5473\u7740\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u8bbe\u6807\u8bb0\u8be5\u51fd\u6570\u6216\u53d8\u91cf\u88ab\u89e3\u6790\u4e3a\u540c\u4e00\u94fe\u63a5\u5355\u5143\u5185\u7684\u7b26\u53f7\uff0cdso\u4ee3\u8868\u52a8\u6001\u5171\u4eab\u5bf9\u8c61\uff08dynamic shared object\uff09\uff0c\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 noundef \u662f\u8fd4\u56de\u7c7b\u578b i32 \u7684\u4fee\u9970\u7b26\uff0c\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u4f1a\u8fd4\u56de\u4e00\u4e2a\u672a\u5b9a\u4e49\u7684\u503c\uff0c\u6ce8\u610f noundef \u4fee\u9970\u7684\u662f\u53f3\u8fb9\u7684\u8fd4\u56de\u7c7b\u578b i32 \u800c\u4e0d\u662f\u51fd\u6570\u672c\u8eab\u3002\u8fd9\u4e2a\u5c5e\u6027\u53ef\u4ee5\u7528\u4e8e\u5e2e\u52a9\u7f16\u8bd1\u5668\u6392\u9664\u4e00\u4e9b\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e5f\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 i32 \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 int \u3002 @main \u662f\u51fd\u6570\u540d\u5b57\uff0c\u5176\u4e2d @ \u662f\u6240\u6709\u51fd\u6570\u540d\u7684\u56fa\u6709\u524d\u7f00\uff0c\u540e\u9762\u7684 main \u5c31\u662f\u6211\u4eec\u5f53\u524d\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u51fd\u6570\u540d\u5b57\u540e\u9762\u7d27\u63a5\u7740\u7684 () \u8868\u793a\u53c2\u6570\u5217\u8868\uff0c\u6b64\u5904\u6211\u4eec\u7684 main \u51fd\u6570\u521a\u597d\u6ca1\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u6240\u4ee5\u662f\u4e00\u4e2a\u7a7a\u7684\u62ec\u53f7\uff08\u7a0d\u540e\u6211\u4eec\u4f1a\u770b\u4e00\u4e2a\u6709\u53c2\u6570\u7684\u6848\u4f8b\uff09\u3002 #0 \u8868\u793a\u8be5\u51fd\u6570\u7684\u7f16\u53f7\uff0c\u5c31\u548c\u5bc4\u5b58\u5668\u7f16\u53f7\u4e00\u6837\uff0c\u6240\u6709\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u4ece 0 \u5f00\u59cb\u7684\u7f16\u53f7\u3002 {} \u4e2d\u7684\u5185\u5bb9\uff0c\u5c31\u662f\u51fd\u6570\u5757\u5185\u90e8\u7684 IR \u4e86\uff0c\u8fd9\u4e9b\u662f main \u51fd\u6570\u7684\u51fd\u6570\u4f53\uff0c\u6bcf\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u5c31\u4f1a\u6267\u884c\u5176\u4e2d\u7684\u6240\u6709 IR \u8282\u70b9\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7684\u5b9a\u4e49\u4e5f\u662f\u4e00\u4e2a IR \u8282\u70b9\uff0c\u540c\u6837\u6709\u4ece 0 \u5f00\u59cb\u9012\u589e\u7684\u201c\u5bc4\u5b58\u5668\u7f16\u53f7\u201d\uff0c\u4f46\u4ed6\u5e76\u4e0d\u662f\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7528 #n \u8868\u793a\uff0c\u800c\u5bc4\u5b58\u5668\u7528 %n \u8868\u793a\u3002 define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } \u8ba9\u6211\u4eec\u4e00\u6761\u4e00\u6761\u89e3\u6790\u51fd\u6570\u4f53\u5185\u7684\u8fd9\u4e9b IR \u8282\u70b9\u5427\uff01 alloca \u6307\u4ee4 %1 = alloca i32, align 4 %1 \u8868\u793a\u4e86\u5bc4\u5b58\u5668\u7684\u540d\u5b57\uff0c = \u53f3\u8fb9\u5c31\u662f\u8be5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u3002\u8fd9\u91cc\u8981\u4ecb\u7ecd LLVM IR \u7684\u4e00\u4e2a\u91cd\u8981\u89c4\u5219\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff01\u5bc4\u5b58\u5668\u4e00\u65e6\u5b9a\u4e49\uff08\u8d4b\u503c\uff09\u8fc7\u4e00\u6b21\u540e\u5c31\u4e0d\u80fd\u518d\u4fee\u6539\uff0c\u9664\u975e\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u5bc4\u5b58\u5668\u3002\u4e3a\u4e86\u4ea7\u751f\u53ef\u4ee5\u52a8\u6001\u4fee\u6539\u7684\u53d8\u91cf\uff0cClang \u5fc5\u987b\u4f7f\u7528 alloca \u6307\u4ee4\u5206\u914d\u4e00\u5757\u201c\u6808\u5185\u5b58\u201d\uff0c\u6808\u5185\u5b58\u603b\u662f\u53ef\u8bfb\u5199\u7684\u3002 alloca \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6808\u5185\u5b58\u5206\u914d\u6307\u4ee4\uff0c\u4ed6\u4f1a\u5728\u5f53\u524d\u51fd\u6570 main \u7684\u6808\u4e0a\u5206\u914d\u4e00\u4e2a\u7c7b\u578b\u4e3a i32 \u7684\u5185\u5b58\u7a7a\u95f4\u3002 i32 \u6307\u5b9a\u4e86\u6808\u5185\u5b58\u8981\u5206\u914d\u7684\u7c7b\u578b\u662f \u201c32 \u4f4d\u6574\u6570\u201d\u3002\u6ce8\u610f LLVM IR \u662f\u4e00\u4e2a\u6709\u7c7b\u578b\u7684 IR\uff0c\u6b64\u5904\u6211\u4eec\u9700\u8981\u6307\u5b9a\u53d8\u91cf\u7684\u5b9e\u9645\u7c7b\u578b i32 \u800c\u4e0d\u662f\u6307\u5b9a\u4e00\u4e2a 4 \u8868\u793a\u5927\u5c0f\u3002 align 4 \u8868\u793a\u8fd4\u56de\u5730\u5740\u6240\u8981\u6c42\u7684\u5bf9\u9f50\u5ea6\uff0c\u6839\u636e C \u8bed\u8a00\u89c4\u5219\u8981\u6c42\uff0c int \u7c7b\u578b\u5fc5\u987b\u5bf9\u9f50\u5230 4 \u5b57\u8282\uff0c\u56e0\u6b64\u6307\u5b9a align 4 \u3002\u5176\u4ed6\u8bed\u8a00\u82e5\u6ca1\u6709\u6b64\u89c4\u5b9a\uff0c\u4e5f\u53ef\u4ee5\u751f\u6210 align 1 \u5728 IR \u4e2d\u3002 alloca \u4f1a\u201c\u8fd4\u56de\u201d\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u521d\u59cb\u5316 %1 \u3002\u7c7b\u578b\u662f i32* \uff08\u8fd9\u91cc\u7684 * \u548c C \u8bed\u8a00\u7684\u6307\u9488\u4e00\u6837\uff0c\u8868\u793a\u524d\u9762\u7c7b\u578b\u7684\u6307\u9488\u7c7b\u578b\uff09\uff0c\u8be5\u6307\u9488\u6307\u5411\u6808\u4e0a\u5206\u914d\u597d\u7684 i32 \u53d8\u91cf\u3002 %1 \u5bc4\u5b58\u5668\u5c31\u8fd9\u6837\u88ab\u5b9a\u4e49\u4e3a\u5b9e\u9645\u53d8\u91cf\u7684\u5730\u5740\u503c\u3002 \u8fd9\u6761 IR \u6307\u4ee4\u6267\u884c\u5b8c\u6bd5\u540e\uff0c %1 \u5bc4\u5b58\u5668\u91cc\u7684\u503c\uff0c\u5c31\u662f\u6307\u5411\u7684\u6307\u9488\u3002\u7531\u4e8e\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c %1 \u8fd9\u4e2a\u6307\u9488\u672c\u8eab\u5728\u51fd\u6570\u9000\u51fa\u524d\uff0c\u5c06\u6c38\u8fdc\u4e0d\u53d8\u3002\u4f46\u662f\u6307\u9488\u4e0d\u80fd\u53d8\uff0c\u6307\u9488\u6307\u5411\u7684\u503c\u53ef\u4ee5\u53d8\uff0c\u6240\u4ee5\u4e4b\u540e\u53ea\u9700\u8981\u4ee5\u6307\u9488\u5f62\u5f0f\u8bfb\u5199\u5176\u6307\u5411\u7684\u5730\u5740\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u53ef\u53d8\u7684\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u53d7\u5236\u4e8e\u5bc4\u5b58\u5668\u4e0d\u53ef\u53d8\u3002 \u5728 LLVM IR \u5c42\u9762\uff0c\u4e0d\u5b58\u5728\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \u3002\u6216\u8005\u8bf4\uff0c\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u4fdd\u5b58\u7684\u672c\u6765\u5c31\u662f\u4ed6\u4eec\u7684\u5730\u5740\uff08\u901a\u8fc7 alloca \u8fd4\u56de\u7684\uff09\u3002\u6b63\u5e38\u8d4b\u503c\u548c\u8bfb\u53d6\u53d8\u91cf\u7684\u64cd\u4f5c\u90fd\u662f\u901a\u8fc7 store \u548c load \u95f4\u63a5\u901a\u8fc7\u53d8\u91cf\u7684\u6307\u9488\u6765\u4fee\u6539\u53d8\u91cf\u7684\uff0c\u5bc4\u5b58\u5668\u672c\u8eab\u4e0d\u53ef\u53d8\u3002\u5982\u679c\u4f7f\u7528\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u5c31\u662f\u539f\u5c01\u4e0d\u52a8\u628a\u5bc4\u5b58\u5668\u7684\u6307\u9488\u503c\u8d4b\u7ed9\u4f60\u800c\u5df2\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u7684\u7c7b\u578b\u672c\u8eab\u5c31\u662f\u6307\u9488\uff08\u6bd4\u5982 char * \uff09\uff0c\u90a3\u4e48\u901a\u8fc7 alloca i8* \u5b9a\u4e49\u7684\u5bc4\u5b58\u5668\u7684\u7c7b\u578b\u5c31\u4f1a\u662f\u4e00\u4e2a\u4e8c\u7ea7\u6307\u9488\uff08 i8** \uff09\u3002 C++ \u5f15\u7528\u5728 LLVM IR \u5c42\u9762\u540c\u6837\u4e5f\u4f1a\u53d8\u6210\u6307\u9488\u7c7b\u578b\u7684\u53d8\u91cf\u3002\u6ce8\u610f\uff0c\u6211\u53ea\u662f\u8bf4 C++ \u5f15\u7528\u548c\u6307\u9488\u4f1a\u5728 LLVM \u4e2d\u4f1a\u540c\u6837\u53d8\u6210\u6307\u9488\u7c7b\u578b\uff0c\u5e76\u4e0d\u662f\u8bf4\u5728 Clang \u524d\u7aef\u91cc\u5f15\u7528\u548c\u6307\u9488\u6ca1\u533a\u522b\u3002 \u6240\u4ee5\uff0c\u8fd9\u91cc\u7684 %1 \u548c %2 \u5176\u5b9e\u662f\u5bf9\u5e94\u6e90\u7801\u4e2d\u7684 a \u548c b \u53d8\u91cf\uff08\u7684\u6307\u9488\uff09\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e int * %1 = alloca(4) \u3002 store \u6307\u4ee4 \u7ee7\u7eed\u63a5\u7740\u770b\uff1a store i32 1, ptr %1, align 4 \u8fd9\u662f\u4e00\u6761 store \u6307\u4ee4\u3002 \u6307\u4ee4\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570 i32 1 \u8868\u793a\u8981\u5b58\u5165\u7684\u503c\uff0c\u8fd9\u91cc\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u5e38\u6570 1 \u3002LLVM IR \u4e2d\u6307\u4ee4\u6240\u6709\u7684\u53c2\u6570\u90fd\u9700\u8981\u5728\u524d\u9762\u6307\u5b9a\u7c7b\u578b\u540d\uff0c\u6211\u4eec\u8981\u5199\u5165\u7684 a \u53d8\u91cf\u662f int \u4e5f\u5c31\u662f i32 \u7c7b\u578b\uff0c\u6240\u4ee5\u7528 i32 \u4fee\u9970\u8981\u5199\u5165\u7684\u503c 1 \u3002 \u7b2c\u4e8c\u4e2a\u53c2\u6570 ptr %1 \u8868\u793a\u8981\u5199\u5165\u5230\u7684\u5730\u5740\uff0c\u5fc5\u987b\u662f\u6307\u9488\u7c7b\u578b\u3002\u8fd9\u91cc\u7684 ptr \u662f i32* \u7684\u7b80\u5199\uff0c\u7b49\u4ef7\u4e8e i32* %1 \u3002\u7531\u4e8e\u521a\u624d %1 \u5b9a\u4e49\u4e3a alloca \uff0c\u4e5f\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\u4e86\u4e00\u4e2a\u53d8\u91cf\uff08C++ \u6e90\u7801\u4e2d\u7684 a \uff09\u3002 %1 \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u5176\u503c\u662f a \u7684\u5730\u5740\u3002\u6240\u4ee5\u6b64\u5904 store \u7684\u6548\u679c\u662f\u5f80\u53d8\u91cf a \u4e2d\u5199\u5165\u4e86\u4e00\u4e2a\u5e38\u6570 1 \u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 alloca \u548c\u7d27\u63a5\u7740\u7684 store \u8fd9\u4e24\u6761\u6307\u4ee4\uff0c\u8fde\u8d77\u6765\uff0c\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\uff08 alloca \uff09\u4e86\u4e00\u4e2a\u53d8\u91cf a \u4e4b\u540e\uff0c\u5411\u5176\u4e2d\u8d4b\u4e86\u4e00\u4e2a\u521d\u59cb\u503c 0 \u3002 \u6ce8\u610f\u5230\uff0c store \u5e76\u6ca1\u6709\u7528\u4e8e\u5b9a\u4e49\u4e00\u4e2a\u5bc4\u5b58\u5668\uff08\u4f8b\u5982 %1 = store ... \uff09\u3002 store \u6307\u4ee4\u6ca1\u6709\u201c\u8fd4\u56de\u503c\u201d\uff0c\u56e0\u6b64\u4ed6\u4e0d\u4f1a\u5b9a\u4e49\u4efb\u4f55\u5bc4\u5b58\u5668\uff1b store \u672c\u8eab\u662f\u56e0\u4e3a\u5176\u5199\u5165\u4ea7\u751f\u7684\u526f\u4f5c\u7528\u800c\u5b58\u5728\uff0c\u4e0d\u9700\u8981\u6709\u4eba\u201c\u4f7f\u7528\u201d\u4ed6\u7684\u503c\u3002 \u56e0\u4e3a\u6709\u526f\u4f5c\u7528\uff0c store \u5c31\u4e0d\u80fd\u7b80\u5355\u5730\u88ab def-use \u5206\u6790 pass \u4f18\u5316\u6389\u4e86\uff0c\u6240\u4ee5\u9700\u8981\u5148\u8fc7\u4e00\u4e2a mem2reg pass \u628a\u80fd\u8f6c\u5316\u6389\u7684 store \u5c3d\u53ef\u80fd\u8f6c\u6210\u5bb9\u6613\u4f18\u5316\u7684\u5bc4\u5b58\u5668\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b store i32 1, ptr %1, align 4 ; a = 1 store i32 2, ptr %2, align 4 ; a = 2 \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e *%1 = 1 \u3002 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 \u5982\u679c\u4f60\u53ea\u662f alloca \uff0c\u800c\u6ca1\u6709\u5f80\u91cc\u9762 store \u8d4b\u503c\u8fc7\u7684\u8bdd\uff0c\u90a3\u4e48\u8be5\u6808\u53d8\u91cf\u7684\u503c\u662f\u201c\u672a\u5b9a\u4e49\u503c\u201d\uff0c\u5728 C++ \u6807\u51c6\u4e2d\uff0c\u8bbf\u95ee\uff08 load \uff09\u4e00\u4e2a\u201c\u672a\u5b9a\u4e49\u503c\u201d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4f8b\u5982\uff1a int a; return a; // \u9519\u8bef\uff1aa \u672a\u521d\u59cb\u5316\uff0c\u91cc\u9762\u7684\u503c\u662f\u672a\u5b9a\u4e49\u503c\uff01 \u8bfb\u53d6\u6ca1\u6709\u521d\u59cb\u5316\u8fc7\u7684\u6808\u53d8\u91cf\uff0c\u5728 x86 \u548c ARM \u7b49\u5177\u4f53\u67b6\u6784\u4e2d\uff0c\u4f60\u53ef\u80fd\u4f1a\u8bfb\u5230\u5185\u5b58\u4e2d\u7684\u968f\u673a\u53d8\u91cf\u3002 \u5728 LLVM \u4e2d\uff0c\u8fd9\u7c7b\u5904\u4e8e\u672a\u521d\u59cb\u5316\u72b6\u6001\u7684\u503c\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u540d\u5b57\uff0c\u53eb\u201c\u6bd2\u503c\u201d\uff08poison value\uff09\u3002 \u6bd2\u503c\u4e0d\u662f C++ \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f\u786c\u4ef6\u67b6\u6784\u7684\u4e00\u90e8\u5206\uff0c\u800c\u662f LLVM \u4e2d\u7aef\u4eba\u4e3a\u5b9a\u4e49\u7684\uff08\u56e0\u4e3a\u5f88\u591a\u7cfb\u7edf\u7ea7\u8bed\u8a00\u90fd\u6709\u652f\u6301\u672a\u521d\u59cb\u5316\u7684\u5185\u5b58\uff0c\u77e5\u9053\u54ea\u4e9b\u503c\u662f\u4e0d\u53ef\u80fd\u7684\u6709\u52a9\u4e8e LLVM \u4f18\u5316\uff09\u3002 \u201c\u6bd2\u503c\u201d\u5e76\u4e0d\u662f\u968f\u673a\u503c\uff0c\u4ed6\u662f i32 \u8868\u793a\u7a7a\u95f4\u4e4b\u5916\u7684\u4e00\u4e2a\u7279\u6b8a\u503c\uff0c\u4e0d\u662f\u88ab 0 \u5230 4294967295 \u8303\u56f4\u5185\u7684\u4efb\u4f55\u6574\u6570\uff0c\u800c\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u7528\u4e8e\u6807\u8bc6\u201c\u672a\u5b9a\u4e49\u884c\u4e3a\u201d\u7684\u4e00\u4e2a LLVM \u4e2d\u624d\u6709\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u610f\u601d\u662f\u201c\u8fd9\u4e2a\u503c\u73b0\u5728\u4e0d\u80fd\u4f7f\u7528\u201d\u3002\u53ea\u4e0d\u8fc7\u5728\u8f6c\u6362\u4e3a\u5177\u4f53\u67b6\u6784\u7684\u6c47\u7f16\u4ee3\u7801\u540e\u5f80\u5f80\u4f1a\u53d8\u6210\u201c\u968f\u673a\u503c\u201d\u8fd9\u4e00\u5177\u4f53\u5b9e\u73b0\uff0c\u4f9d\u8d56\u8fd9\u4e00\u70b9\u7684\u540e\u679c\u662f\u672a\u5b9a\u4e49\u7684\u3002\uff08\u4f8b\u5982\u4f60\u4e0d\u80fd\u7528\u4e00\u4e2a\u201c\u672a\u521d\u59cb\u5316\u53d8\u91cf\u201d\u751f\u6210\u968f\u673a\u6570\uff0c\u5728\u9ad8\u4f18\u5316\u4e0b\u53ef\u80fd\u4ea7\u751f\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u800c\u4e14\u4e5f\u5e76\u4e0d\u4e00\u5b9a\u591f\u968f\u673a\uff09 \u6bd2\u503c\u7684\u7279\u70b9\uff1a alloca \u540e\u6ca1\u6709 store \u8fc7\u7684\u6808\u53d8\u91cf\u521d\u59cb\u5c31\u662f\u4e3a\u6bd2\u503c\u3002\u5982\u679c\u5c1d\u8bd5\u76f4\u63a5 load \u8fd9\u4e2a\u5730\u5740\uff0c\u90a3\u4e48 load \u8fd4\u56de\u7684\u5bc4\u5b58\u5668\u5c31\u548c\u521d\u59cb\u5316\u4e3a\u201c\u6bd2\u503c\u201d\u3002 \u6bd2\u503c\u4f1a\u611f\u67d3\u6240\u6709\u201c\u4f7f\u7528\u201d\u4e86\u4ed6\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982 %1 \u662f\u6bd2\u503c\uff0c\u90a3\u4e48 %2 = add %1, 1 \u4e5f\u662f\u6bd2\u503c\uff0c\u56e0\u4e3a %2 \u201c\u4f7f\u7528\u201d\u4e86\u7684 %1 \u662f\u6bd2\u503c\u3002 \u6807\u8bb0\u4e3a noundef \u7c7b\u578b\u7684\u53d8\u91cf\uff08\u4f8b\u5982 noundef i32 \uff09\uff0c\u5fc5\u987b\u4e0d\u80fd\u662f\u6bd2\u503c\uff0c\u5426\u5219\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u8fd4\u56de\u7c7b\u578b\u6807\u8bb0\u4e3a noundef \uff08\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5e94\u8fd4\u56de\u6bd2\u503c\uff09\u7684\u51fd\u6570\u8fd4\u56de\u4e86\u6bd2\u503c\uff0c\u90a3\u4e48\u5c31\u89e6\u53d1\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 load \u6307\u4ee4 %3 = load i32, ptr %1, align 4 ; \u52a0\u8f7d a %4 = load i32, ptr %2, align 4 ; \u52a0\u8f7d b load \u6307\u4ee4\u4ece\u5185\u5b58\u7684\u6307\u5b9a\u5730\u5740\u5904\u52a0\u8f7d\u4e00\u4e2a\u6307\u5b9a\u7c7b\u578b\u7684\u6570\u636e\uff0c\u8bfb\u53d6\u5230\u5bc4\u5b58\u5668\u4e2d\u3002 \u5206\u522b\u662f\u5bf9\u5e94\u52a0\u8f7d a \u548c b \u8fd9\u4e24\u4e2a\u53d8\u91cf\uff0c\u6765\u770b\u52a0\u8f7d a \u7684\u8fd9\u6761\u6307\u4ee4\uff1a %3 = load i32, ptr %1, align 4 i32 \u8868\u793a\u52a0\u8f7d\u4e00\u4e2a 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u8fd9\u4f1a\u628a = \u524d\u9762\u7684\u5bc4\u5b58\u5668 %3 \u5b9a\u4e49\u4e3a i32 \u7c7b\u578b\u7684\u3002 ptr %1 \u8868\u793a\u8981\u52a0\u8f7d\u7684\u5185\u5b58\u5730\u5740\uff0c\u6b64\u5904\u5730\u5740\u901a\u8fc7 %1 \u5bc4\u5b58\u5668\u6307\u5b9a\uff0c\u800c %1 \u88ab\u5b9a\u4e49\u4e3a alloca i32 \uff0c\u4e5f\u5c31\u662f\u4e00\u4e2a\u6808\u53d8\u91cf\u7684\u6307\u9488\uff0c\u6240\u4ee5\u6b64\u5904 load i32, ptr %1 \u5c31\u662f\u5728\u52a0\u8f7d\u8fd9\u4e2a\u6808\u53d8\u91cf\u7684\u503c\u3002 \u6ce8\u610f\u8fd9\u91cc\u7684\u53c2\u6570\u6307\u9488 %1 \u5fc5\u987b\u662f\u4e0e\u8981\u52a0\u8f7d\u7c7b\u578b i32 \u5bf9\u5e94\u7684\u6307\u9488\u7c7b\u578b i32* \uff0c\u800c alloca i32 \u8fd4\u56de\u7684\u6070\u597d\u662f i32* \u7c7b\u578b\u7684\u6307\u9488\uff0c\u7b26\u5408\u8981\u6c42\u3002 \u6b64\u5904 ptr %1 \u5b9e\u9645\u4e0a\u662f i32* %1 \u7684\u7b80\u5199\uff0c ptr \u662f\u4e00\u4e2a\u8bed\u6cd5\u7cd6\uff0c\u56e0\u4e3a\u524d\u9762 load i32 \u5df2\u7ecf\u6307\u5b9a\u4e86\u8981\u52a0\u8f7d\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u5177\u4f53\u7684\u6307\u9488\u7c7b\u578b i32* \u53ef\u4ee5\u7701\u7565\uff0c\u7528 ptr \u4ee3\u66ff\u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 \u7531\u4e8e\u4e4b\u524d\u5df2\u7ecf\u5f80 ptr %1 \u6307\u5411\u7684\u5730\u65b9\uff08\u5c40\u90e8\u53d8\u91cf a \uff09\u91cc store \u8fc7\u6574\u6570\u503c 1 \u4e86\uff0c\u6240\u4ee5\u8fd9\u91cc load \u51fa\u6765\u4e5f\u4f1a\u662f 1 \u3002 \u8fd9\u6837\u91cd\u590d\u7684 store \u548c load \u4f1a\u88ab\u540e\u7eed\u7684 LLVM \u4f18\u5316\u6389\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u7684 clang \u6ca1\u6709\u5f00\u542f\u4f18\u5316\uff08\u9ed8\u8ba4 -O0 \uff09\uff0c\u6240\u4ee5\u4f9d\u7136\u4fdd\u6301\u539f\u59cb\u7684 store \u548c load \u91cd\u590d\u52b3\u52a8\uff0c\u5fe0\u5b9e\u590d\u523b\u539f\u672c\u7684 C++ \u4ee3\u7801\u8bed\u4e49\u3002 \u56e0\u4e3a\u5f88\u591a\u8c61\u7259\u5854\u7262\u6e7f\u8981\u4e48\u201c\u547d\u4ee4\u884c\u8c03\u7528\u7f16\u8bd1\u201d\uff0c\u8981\u4e48 IDE \u662f\u9ed8\u8ba4\u7684\u201cDebug\u201d\u6a21\u5f0f\uff0c\u5b83\u4eec\u4e0d\u77e5\u9053\u53ef\u4ee5\u901a\u8fc7 -O \u9009\u9879\u5f00\u542f\u4f18\u5316\uff0c\u751a\u81f3\u6709\u4eba\u8ba4\u4e3a\u201c\u4f18\u5316\u201d\u662f\u4e0d\u6807\u51c6\u7684\uff0c\u8ba4\u4e3a\u4e0d\u5f00\u4f18\u5316\u7684 C++ \u624d\u80fd\u6d4b\u5f97\u771f\u5b9e\u6027\u80fd\u3002\u800c\u5b83\u4eec\u5bf9\u7f16\u8bd1\u5668\u7684\u7406\u89e3\u53c8\u662f\u7c97\u7cd9\u7684\u201c\u6ca1\u6709 AST\uff0c\u6ca1\u6709 IR\uff0c\u524d\u7aef\u89e3\u6790\u7684\u8fc7\u7a0b\u4e2d\u76f4\u63a5\u751f\u6210\u6c47\u7f16\u4ee3\u7801\u201d\uff0c\u6240\u4ee5\u624d\u4f1a\u628a C++ \u51fd\u6570\u5c40\u90e8\u53d8\u91cf\u548c\u4e00\u4e9b CPU \u540e\u7aef\u5177\u4f53\u5b9e\u73b0\u4e2d\u7684\u201c\u6808\u201d\u6df7\u4e3a\u4e00\u8c08\u3002\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u4f53\u5185\u5b9a\u4e49\u7684\u5c40\u90e8\u53d8\u91cf\uff08\u5f8b\u5e08\u7684\u8bf4\u6cd5\u662f\u201c\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u53d8\u91cf\u201d\uff0c\u5f97\u540d\u4e8e\u51fd\u6570\u4f5c\u7528\u57df\u9000\u51fa\u65f6\u4f1a\u81ea\u52a8\u6790\u6784\u548c\u91ca\u653e\u5185\u5b58\uff09\uff0c\u90fd\u53ef\u4ee5\u88ab\u4f18\u5316\u5230\u5bc4\u5b58\u5668\u4e2d\u3002\u8fd8\u6709\u4e00\u4e9b GPU \u76ee\u6807\u67b6\u6784\uff0c\u4f8b\u5982\u5728 CUDA \u4e2d\uff0c\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u6781\u591a\uff0c\u5c40\u90e8\u53d8\u91cf\u51e0\u4e4e\u603b\u662f\u53ef\u4ee5\u653e\u5230\u5728\u5bc4\u5b58\u5668\u4e0a\uff0c\u751a\u81f3\u5c40\u90e8\u6570\u7ec4\u53d8\u91cf\uff08\u5982\u679c\u4e0b\u6807\u8bbf\u95ee\u90fd\u662f\u5e38\u6570\uff09\u4e5f\u53ef\u4ee5\u653e\u5230\u5bc4\u5b58\u5668\u4e0a\u3002\u8981\u662f\u4e0d\u5f00\u5bc4\u5b58\u5668\u4f18\u5316\u5c31\u5168\u90e8\u8981\u6253\u7ffb\u5230\u5168\u5c40\u5185\u5b58\u4e86\uff0c\u4f1a\u53d8\u5f97\u548c\u5168\u5c40\u5185\u5b58\u4e00\u6837\u6162\uff01\u6240\u4ee5 nvcc \u54ea\u6015\u4e0d\u5f00 -O \u7684\u60c5\u51b5\u4e0b\u4e5f\u4f1a\u5c1d\u8bd5\u628a\u5c40\u90e8\u53d8\u91cf\u4f18\u5316\u5230\u786c\u4ef6\u5bc4\u5b58\u5668\u91cc\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %3 = *%1 \u3002 add \u6307\u4ee4 %5 = add nsw i32 %3, %4 LLVM \u4e2d\u6709\u52a0\u51cf\u4e58\u9664\u7684\u6307\u4ee4\uff0c\u5176\u4e2d add \u5c31\u662f\u5176\u4e2d\u8d1f\u8d23\u6574\u6570\u52a0\u6cd5\u8fd0\u7b97\u7684\u6307\u4ee4\uff0c\u4ed6\u63a5\u53d7\u4e24\u4e2a\u64cd\u4f5c\u6570\u505a\u53c2\u6570\u3002 add \u8868\u793a\u8fd9\u662f\u4e00\u6761\u52a0\u6cd5\u8fd0\u7b97\u6307\u4ee4\u3002 nsw \u662f\u4e00\u4e2a\u4fee\u9970\u7b26\uff0c\u53ef\u4ee5\u5148\u5ffd\u7565\u4e0d\u7ba1\u3002 i32 \u8868\u793a\u52a0\u6cd5\u64cd\u4f5c\u7684\u7c7b\u578b\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5728\u8fdb\u884c\u52a0\u6cd5\u524d\uff0c\u5fc5\u987b\u5148\u628a\u4e24\u8fb9\u7684\u6574\u6570\u7c7b\u578b\u8f6c\u6362\u5230\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u65e0\u6cd5\u76f8\u52a0\u3002 %3, %4 \u8868\u793a\u4e86\u52a0\u6cd5\u7684\u4e24\u4e2a\u64cd\u4f5c\u6570\uff0c\u8fd9\u4e24\u4e2a\u6570\u4f1a\u88ab\u52a0\u8d77\u6765\uff0c\u7ed3\u679c\u5b58\u5230 %5 \u5bc4\u5b58\u5668\u4e2d\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %5 = %3 + %4 \u3002 \u5728 Clang \u524d\u7aef\u4e2d\uff0c\u5982\u679c\u53d1\u73b0\u4e24\u8fb9\u7684\u7c7b\u578b\u5927\u5c0f\u4e0d\u540c\uff1a\u4f1a\u5148\u7528 sext \uff08\u6709\u7b26\u53f7\u6269\u5c55\uff09\u6216 zext \uff08\u65e0\u7b26\u53f7\u6269\u5c55\uff09\u6307\u4ee4\uff0c\u628a\u8f83\u5c0f\u90a3\u8fb9\u7684\u7c7b\u578b\uff0c\u8f6c\u6362\u5230\u4e24\u8005\u4e4b\u95f4\u6700\u5927\u7684\u90a3\u4e2a\u7c7b\u578b\u3002\u7136\u540e\u518d\u505a\u52a0\u6cd5\u3002\u5bf9\u4e8e\u6d6e\u70b9\u6570\u548c\u6574\u6570\u76f8\u52a0\u7684\u60c5\u51b5\uff0c\u5219\u662f\u5148\u628a\u6574\u6570\u8f6c\u6362\u4e3a\u6d6e\u70b9\u6570\u540e\u518d\u8c03\u7528\u6d6e\u70b9\u6570\u52a0\u6cd5 fadd \u3002\u603b\u4e4b\uff0cLLVM IR \u91cc\u6240\u6709\u7684\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\u90fd\u53d1\u751f\u5728\u76f8\u540c\u7c7b\u578b\u4e4b\u95f4\u3002 \u5bf9\u4e8e\u597d\u5947\u5b9d\u5b9d\uff1a nsw \u8868\u793a no signed wrap\uff0c\u610f\u601d\u662f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u8fd9\u4e2a\u662f\u6709\u7b26\u53f7\u52a0\u6cd5\uff0c\u5e76\u4e14\u4fdd\u8bc1\u4e0d\u4f1a\u6ea2\u51fa\u3002\u4e3a\u4ec0\u4e48\u4e0d\u4f1a\u6ea2\u51fa\uff1f\u56e0\u4e3a C++ \u6807\u51c6\u89c4\u5b9a\u201c\u6709\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u52a0\u6cd5\u5982\u679c\u53d1\u751f\u6ea2\u51fa\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u56de\u73af\uff08wrap\uff09\u201d\uff0c\u6240\u4ee5 Clang \u628a\u8fd9\u4e2a\u4fe1\u606f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u7528\u6237\u8fd9\u4e2a\u52a0\u6cd5\u5982\u679c\u6ea2\u51fa\u4e86\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cLLVM \u53ef\u4ee5\u5229\u7528\u8fd9\u4e00\u70b9\u6765\u4f18\u5316\uff01\u6362\u53e5\u8bdd\u8bf4\uff1a nsw \u8868\u793a\u5de6\u53f3\u4e24\u4e2a i32 \u4f5c\u4e3a\u6709\u7b26\u53f7\u6570\u76f8\u52a0\u5982\u679c\u6ea2\u51fa\u4f1a\u8fd4\u56de\u201c\u6bd2\u503c\u201d\u3002\u4f46\u662f C++ \u6807\u51c6\u53c8\u89c4\u5b9a\u65e0\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u6ea2\u51fa\u662f\u5fc5\u5b9a\u56de\u73af\uff0c\u4e0d\u4f1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6240\u4ee5\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b\u628a int \u66ff\u6362\u4e3a unsigned int \uff0c\u4f60\u4f1a\u53d1\u73b0 nsw \u6ca1\u4e86\uff0c\u56e0\u4e3a Clang \u77e5\u9053 C++ \u6807\u51c6\u5141\u8bb8 unsigned int \u52a0\u6cd5\u51fa\u73b0\u56de\u73af\u3002\u53e6\u5916\uff0c\u5982\u679c\u4f7f\u7528 Rust \u7684 i32 \u52a0\u6cd5\uff0c\u4e5f\u4f1a\u6ca1\u6709 nsw \uff0c\u56e0\u4e3a Rust \u6807\u51c6\u89c4\u5b9a\u6574\u6570\u65e0\u8bba\u6709\u6ca1\u6709\u7b26\u53f7\uff0c\u5176\u52a0\u6cd5\u6ea2\u51fa\u603b\u662f\u56de\u73af\uff0c\u4e0d\u4f1a\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u90a3\u4e48 LLVM \u540e\u7aef\u6536\u5230 Rust \u7f16\u8bd1\u5668\u4ea7\u751f\u7684 IR \u540e\uff0c\u5c31\u4e0d\u4f1a\u5047\u5b9a\u52a0\u6cd5\u4e0d\u4f1a\u6ea2\u51fa\u6765\u4f18\u5316\u4e86\u3002 \u8fd9\u6761\u6307\u4ee4\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 a + b \u8868\u8fbe\u5f0f\uff0c\u7528\u4e8e\u8ba1\u7b97\u4e24\u4e2a\u53d8\u91cf\u7684\u548c\uff0c\u8ba1\u7b97\u7ed3\u679c\u5b58\u5165 %5 \u5bc4\u5b58\u5668\u3002 ret \u6307\u4ee4 ret i32 %5 ret \u8868\u793a\u51fd\u6570\u8fd4\u56de\u3002\u901a\u5e38\u51fa\u73b0\u5728\u51fd\u6570\u7684\u672b\u5c3e\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return \u8bed\u53e5\u3002 \u5982\u679c\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \uff0c\u5219\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u8fd4\u56de\u503c\uff08\u4ee5\u5e38\u6570\u6216\u5bc4\u5b58\u5668\u7684\u5f62\u5f0f\uff09\u3002\u4f8b\u5982\u8fd9\u91cc\u6307\u5b9a\u7684 ret i32 %5 \u5c31\u8868\u793a\u51fd\u6570\u4f1a\u8fd4\u56de\u5bc4\u5b58\u5668 %5 \u7684\u503c\u3002 \u800c %5 \u5c31\u662f\u521a\u624d\u6211\u4eec add \u6307\u4ee4\u7684\u8fd0\u7b97\u7ed3\u679c\uff0c\u6240\u4ee5 ret \u548c add \u8fd9\u4e24\u6761\u6307\u4ee4\u5c31\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return a + b \u3002 \u548c store \u4e00\u6837\uff0c ret \u4e5f\u662f\u4e00\u6761\u65e0\u5bc4\u5b58\u5668\u5b9a\u4e49\u7684\u6307\u4ee4\u3002 \u901a\u5e38\u6765\u8bf4\u4f1a\u662f ret i32 0 \uff0c\u8868\u793a return 0 \u3002 \u4e3a\u51fd\u6570\u6307\u5b9a attributes \u6ce8\u610f\u5230\u51fd\u6570\u5b9a\u4e49\u540e\u9762\u6709 attributes \u6307\u4ee4\uff1a define dso_local noundef i32 @main() #0 { ... } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } \u4f5c\u7528\u662f\u4e3a\u51fd\u6570\u8d4b\u4e88\u5c5e\u6027\u503c\uff0c\u5c5e\u6027\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\u540e\u8d4b\u4e88\u7684\uff0c\u7528 #0 \u6765\u5f15\u7528\u4e4b\u524d\u5b9a\u4e49\u7684\u51fd\u6570 main \u3002 \u683c\u5f0f\u4e3a attributes #\u51fd\u6570\u7f16\u53f7 = { \u5c5e\u6027\u5217\u8868... } \u5c5e\u6027\u5217\u8868\u53ef\u4ee5\u662f noinline \u8fd9\u6837\u7684\u5355\u6761\u5c5e\u6027\uff0c\u4e5f\u53ef\u4ee5\u662f\u5e26\u503c\u53c2\u6570\u7684\uff0c\u4f8b\u5982 \"target-cpu\"=\"x86-64\" \u3002 \u73b0\u5728\u6765\u89e3\u91ca\u5176\u4e2d\u91cd\u8981\u7684\u5c5e\u6027\uff1a mustprogress \u8868\u793a\u5fc5\u5b9a\u524d\u8fdb\u5047\u8bbe\uff0c\u8fd9\u662f C++ \u672a\u5b9a\u4e49\u884c\u4e3a\u89c4\u5b9a\u4e2d\u7684\u4e00\u6761\uff0c\u8981\u6c42\u7a0b\u5e8f\u4e00\u76f4\u5904\u4e8e\u201c\u8fdb\u5c55\u201d\u3002\u610f\u601d\u662f\u4e0d\u5f97\u51fa\u73b0\u65e0\u526f\u4f5c\u7528\u7684\u6b7b\u5faa\u73af\uff0c\u5426\u5219\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982 while (true) {} \u662f\u4e0d\u5141\u8bb8\u7684\uff1b\u4f46\u662f while (true) { volatile int i = 0; } \u5c31\u53ef\u4ee5\uff0c\u56e0\u4e3a volatile \u53d8\u91cf\u7684\u521d\u59cb\u5316\u88ab\u89c6\u4e3a\u526f\u4f5c\u7528\uff1b while (true) { cin >> i; } \u4e5f\u53ef\u4ee5\uff0c\u56e0\u4e3a cin \u5c5e\u4e8e IO \u64cd\u4f5c\uff0c\u662f\u6709\u5bf9\u5916\u754c\u73af\u5883\u9020\u6210\u526f\u4f5c\u7528\u7684\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 clang++ \u5f00\u7740\u4f18\u5316\u7f16\u8bd1 while (1); \u65f6\u4f1a\u4ea7\u751f\u53cd\u5e38\u7684\u6c47\u7f16\u7ed3\u679c\uff0c\u800c clang \u4e0d\u4f1a\u3002\u56e0\u4e3a\u53ea\u6709 C++ \u6807\u51c6\u8981\u6c42\u4e86\u201c\u5fc5\u5b9a\u524d\u8fdb\u201d\uff0c\u800c C \u6807\u51c6\u6ca1\u6709\u3002 C++ \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u524d\u8fdb\uff0c\u4f60\u4eec\u53ea\u80fd\u524d\u8fdb\uff0c\u4e0d\u62e9\u624b\u6bb5\u7684\u524d\u8fdb\uff08\u5b5d\u55b7\uff09 noinline \u6307\u5b9a\u4e86\u8be5\u51fd\u6570\u4e0d\u5f97\u88ab\u5185\u8054\u4f18\u5316\uff0c\u56e0\u4e3a\u6211\u4eec\u662f main \u51fd\u6570\uff0c\u662f\u6ce8\u5b9a\u4e0d\u80fd\u88ab\u5185\u8054\u7684\uff0c\u6240\u4ee5 Clang \u81ea\u52a8\u52a0\u4e0a\u4e86\u8fd9\u6761\u5c5e\u6027\u3002 optnone \u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5141\u8bb8\u4f18\u5316\u3002\u4e0d\u5f00\u542f\u4f18\u5316\uff08 -O0 \uff09\u65f6\uff0cClang \u4f1a\u81ea\u52a8\u4e3a\u6240\u6709\u51fd\u6570\u52a0\u4e0a optnone \u5c5e\u6027\u3002 LLVM \u4e2d\u7aef\u4e00\u65e6\u770b\u5230\u5e26\u6709 optnone \u5c5e\u6027\u7684\u51fd\u6570\uff0c\u4f1a\u8df3\u8fc7\u7edd\u5927\u90e8\u5206\u4f18\u5316 pass\u3002\u53ea\u4fdd\u7559\u6781\u5c11\u4e00\u90e8\u5206\u5fc5\u8981\u7684\u8f6c\u6362 pass\uff0c\u4f8b\u5982\u201c\u6307\u4ee4\u9009\u62e9\u201d\u548c\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u5c31\u4e0d\u4f1a\u88ab optnone \u5c4f\u853d\u3002\u6240\u4ee5\uff0cLLVM \u4e2d\u7aef\u4e2d\u4e00\u4e2a pass \u662f\u4f18\u5316\u6027\u8d28\u7684\u8fd8\u662f\u8f6c\u6362\u6027\u8d28\u7684\uff0c\u5c31\u53ef\u4ee5\u4ece\u4ed6\u662f\u5426\u4f1a\u88ab optnone \u5c4f\u853d\u770b\u51fa\u3002 \u53ea\u6709\u5168\u5c40\u5f00\u542f\u4e86 -O \u9009\u9879\u540e\uff0c\u6216\u662f\u4e3a\u5f53\u524d\u51fd\u6570\u6307\u5b9a\u4e86 __attribute__((optimize(\"-O\"))) \u8fd9\u4e00\u7279\u6b8a\u6269\u5c55\u8bed\u6cd5\u540e\uff0cClang \u624d\u4f1a\u53bb\u9664\u51fd\u6570\u7684 optnone \u5c5e\u6027\uff0c\u8ba9 LLVM \u4e2d\u7aef\u7684\u4f18\u5316 pass \u5f97\u4ee5\u5bf9\u8be5\u51fd\u6570\u751f\u6548\u3002 Clang \u751f\u6210 IR \u6c47\u7f16 \u6211\u4eec\u7f16\u5199\u4e00\u6bb5\u7b80\u5355\u7684 C++ \u201c\u4f60\u597d\uff0c\u4e16\u754c\u201d\u4ee3\u7801\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u6307\u5b9a -S -emit-llvm \u9009\u9879\uff0c\u5c31\u53ef\u4ee5\u8ba9 clang \u751f\u6210 IR \u6c47\u7f16\u4f9b\u4f60\u67e5\u770b\u4e86\uff08 -o \u53ef\u4ee5\u6307\u5b9a\u8f93\u51fa\u5230\u7684\u6587\u4ef6\u8def\u5f84\uff09\u3002 clang -S -emit-llvm a.cpp -o a.ll \u4ee5\u4e0b\u662f Clang \u89e3\u6790\u5f97\u5230\u7684 IR\uff08\u6c47\u7f16\u5f62\u5f0f\u6253\u5370\uff09\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 ; Function Attrs: mustprogress noinline norecurse optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } declare i32 @printf(ptr noundef, ...) #1 attributes #0 = { mustprogress noinline norecurse optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } attributes #1 = { \"frame-pointer\"=\"all\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u8fd8\u662f\u7167\u4f8b\u4ecb\u7ecd\u4e00\u4e0b\u65b0\u51fa\u73b0\u7684\u6307\u4ee4\uff1a \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u8fd9\u91cc\u7684 @.str \u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u3002 @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 \u6ce8\u610f\u5230\u4e86\u5417\uff1f\u5168\u5c40\u51fd\u6570\u548c\u53d8\u91cf\u90fd\u662f @ \u5f00\u5934\u7684\uff0c\u5c40\u90e8\u5bc4\u5b58\u5668\u90fd\u662f % \u5f00\u5934\u7684\uff0c\u51fd\u6570\u7f16\u53f7\u90fd\u662f # \u5f00\u5934\u7684\uff0c\u7f16\u8bd1\u671f\u4fe1\u606f\u90fd\u662f ! \u5f00\u5934\u7684\u3002 \u800c . \u5f00\u5934\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u533f\u540d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u4e0d\u5bf9\u5916\u53ef\u89c1\uff0c\u4f8b\u5982 @.str \u5e76\u4e0d\u4ee3\u8868\u771f\u7684\u6709\u4e00\u4e2a const char str[14] \uff0c\u53ea\u662f\u4e3a\u4e86\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u4e34\u65f6\u751f\u6210\u7684\u4e00\u4e2a\u533f\u540d\u5168\u5c40\u53d8\u91cf\u800c\u5df2\u3002 @.str \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u540d\u5b57\uff0c\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u5168\u5c40\u7684\u5b9a\u4e49\u90fd\u662f\u4ee5 @ \u5f00\u5934\u3002 private \u8868\u793a\u5bf9\u5916\u4e0d\u53ef\u89c1\uff0c\u662f\u4e00\u4e2a\u79c1\u6709\u53d8\u91cf\u3002 unnamed_addr \u8868\u793a\u8be5\u53d8\u91cf\u6ca1\u6709\u540d\u5b57\uff0c\u662f\u533f\u540d\u7684\u3002 constant \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u4e0d\u53ef\u4ee5\u88ab\u4fee\u6539\u3002 [14 x i8] \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u7c7b\u578b\uff0c [14 x i8] \u7684\u610f\u601d\u662f\u4e00\u4e2a\u957f\u5ea6\u4e3a 14 \u7684 i8 \u6570\u7ec4\uff0c\u7531 14 \u4e2a i8 \u7c7b\u578b\u7ec4\u6210\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 \u6570\u7ec4\u7c7b\u578b char [14] \u3002 c\"Hello, world!\\00\" \u8868\u793a\u8be5\u6570\u7ec4\u7684\u521d\u59cb\u5316\u503c\uff0c\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u3002 align 1 \u8868\u793a\u8be5\u5168\u5c40\u53d8\u91cf\u7684\u9996\u5730\u5740\u5bf9\u9f50\u5230 1 \u5b57\u8282\uff0c\u56e0\u4e3a\u8fd9\u662f\u4e00\u4e2a char \u6570\u7ec4\uff0c char \u53ea\u8981\u6c42\u5bf9\u9f50\u5230 1 \u5b57\u8282\u5373\u53ef\u3002 \u548c\u4e0d\u53c2\u4e0e\u7b26\u53f7\u94fe\u63a5\u7684\u5c40\u90e8\u5bc4\u5b58\u5668 % \u4e0d\u540c\uff0c\u5168\u5c40\u53d8\u91cf @ \u540e\u9762\u7684\u540d\u5b57\u5c31\u662f\u4ed6\u4eec\u5728\u94fe\u63a5\u65f6\u5bfc\u51fa\u7b26\u53f7\u7684\u540d\u5b57\u3002\u6240\u4ee5\u5168\u5c40\u53d8\u91cf\u5fc5\u987b\u662f\u6709\u540d\u5b57\u7684\uff0c\u4e0d\u80fd\u7528\u6570\u5b57\u5e8f\u53f7\u8868\u793a\u3002 \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u5982\u679c\u6211\u5b9a\u4e49\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf int i \u4f1a\u4ea7\u751f\u600e\u6837\u7684 IR\uff1f int i = 42; @i = dso_local global i32 42, align 4 align 4 \u662f\u56e0\u4e3a i \u662f int \u6216\u8005\u8bf4 i32 \u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309 C++ \u6807\u51c6\u8981\u6c42\u9700\u8981\u5bf9\u9f50\u5230 4 \u5b57\u8282\u3002 \u8fd9\u91cc global \u548c\u4e4b\u524d\u5e38\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 constant \u4e0d\u540c\uff0c\u8868\u793a\u662f\u53ef\u8bfb\u5199\u7684\u5168\u5c40\u53d8\u91cf\u3002 \u8fd9\u91cc\u7684 dso_local \u4fee\u9970\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u8868\u793a i \u4e3a\u5168\u5c40\u5bfc\u51fa\u7b26\u53f7\uff08ODR external linkage\uff09\u3002 C++ \u4ee3\u7801 LLVM IR \u4e2d\u7684\u4fee\u9970 C++ \u5f8b\u5e08\u672f\u8bed static int i @i = internal internal linkage inline int i @i = linkonce_odr dso_local non-ODR external linkage int i @i = dso_local ODR external linkage int i \uff08\u51fd\u6570\u5c40\u90e8\uff09 %1 %2 %3 \u2026 no linkage\uff0c\u4e0d\u9700\u8981\u77e5\u9053\u540d\u5b57 \u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\u3002 \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 \u6ce8\u610f\uff0c\u5168\u5c40\u53d8\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 @i \u662f\u4e00\u4e2a\u5730\u5740\uff01\u5c31\u548c alloca \u5b9a\u4e49\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u662f\u6307\u5411\u6808\u4e0a\u5185\u5b58\u7684\u5730\u5740\u4e00\u6837\u3002 \u5982\u679c\u9700\u8981\u52a0\u8f7d\u5176\u4e2d\u7684\u503c\uff0c\u8fd8\u9700\u8981\u7528 load \u547d\u4ee4\u8bfb\u53d6\u5230\u51fd\u6570\u7684\u5c40\u90e8\u5bc4\u5b58\u5668\u4e2d\uff0c\u624d\u80fd\u5c06\u5176\u4e2d\u7684\u503c\u7528\u4e8e\u8fd4\u56de\u3002 static int i = 42; int main() { return i; // \u4f1a\u4ea7\u751f load @i \u6307\u4ee4 } @i = dso_local global i32 42, align 4 ; @i \u662f i32* \u7c7b\u578b define dso_local noundef i32 @main() #0 { %1 = load i32, ptr @i, align 4 ; load \u8bfb\u53d6\u8be5\u6307\u9488\u624d\u80fd\u8bfb\u5230 i \u53d8\u91cf\u7684\u503c ret i32 %1 ; %1 \u4e2d\u662f i \u53d8\u91cf\u7684\u503c } \u5982\u679c\u76f4\u63a5 ret i32 @i \u7684\u8bdd\uff0c\u5c31\u53d8\u6210 return &i \u7684\u6548\u679c\u4e86\u3002 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } TODO \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 Clang \u7f16\u8bd1\u65f6\u662f\u4ec0\u4e48\u5e73\u53f0\u5c31\u662f\u4ec0\u4e48\u5e73\u53f0\u4e86\uff0c\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7684 IR \u4f1a\u6709\u4e9b\u5fae\u7684\u4e0d\u4e00\u6837\uff08\u7531\u4e8e\u4e00\u4e9b\u8f6f\u4ef6\u9700\u8981\u5229\u7528\u786c\u4ef6 intrinsics\uff09\u3002\u4e00\u4efd IR \u4ece\u751f\u6210\u5f00\u59cb\uff0c\u5c31\u6ce8\u5b9a\u6c38\u8fdc\u53ea\u80fd\u53d8\u6210\u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u3002 \u8fd9\u662f\u56e0\u4e3a\u867d\u7136 IR \u662f\u901a\u7528\u7684\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4f46\u7c7b\u578b\u5927\u5c0f\uff0c\u77e2\u91cf\u5bbd\u5ea6\u7b49\u4fe1\u606f\u548c\u786c\u4ef6\u9ad8\u5ea6\u7ed1\u5b9a\u3002 \u800c\u4e14\u6709\u65f6\u7528\u6237\u9700\u8981\u6839\u636e #ifdef __x86_64__ \u5224\u65ad\uff0c\u9488\u5bf9\u4e0d\u540c\u7684\u786c\u4ef6\uff0c\u4f7f\u7528\u4e0d\u540c\u7684 intrinsics\u3002 \u8fd9\u5bfc\u81f4\u5373\u4f7f\u662f\u540c\u4e00\u4efd .cpp \u6587\u4ef6\uff0c\u9488\u5bf9\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7f16\u8bd1\u7684\u4ea7\u751f\u7684 IR\uff0c\u4e5f\u5fc5\u7136\u662f\u4e0d\u540c\u7684\u3002 \u66f4\u4f55\u51b5 Windows \u548c Linux \u73af\u5883\u7684\u6807\u51c6\u5e93\u4e5f\u4e0d\u4e00\u6837\uff0c\u53ef\u80fd Windows \u7248\u7684\u7ffb\u8bd1\u5355\u5143\u5728\u4f1a\u6709\u4e00\u4e9b Windows \u7279\u6709\u51fd\u6570\u7684\u58f0\u660e\uff0c\u800c Linux \u4e0a\u7f16\u8bd1\u51fa\u6765\u5c31\u6ca1\u6709\u3002 \u603b\u4e4b\uff0c\u56e0\u4e3a\u8fd9\u6837\u90a3\u6837\u7684\u539f\u56e0\uff0cLLVM IR \u5e76\u4e0d\u652f\u6301\u8de8\u5e73\u53f0\u5171\u7528\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a Clang \u7f16\u8bd1\u51fa\u6765\u7684 IR \u6ce8\u5b9a\u662f\u4e0d\u540c\u7684\u3002 \u4e5f\u6709\u4e00\u4e9b\u652f\u6301\u8de8\u5e73\u53f0\u7684 IR\uff0c\u6bd4\u5982 SPIR-V \u548c MLIR\uff0c\u9002\u7528\u4e8e\u6e38\u620f\u5ba2\u6237\u7aef\u90e8\u7f72\u7684\u573a\u666f\u3002\u4f46\u663e\u7136 LLVM \u4f5c\u4e3a\u8ffd\u6c42\u6781\u81f4\u4f18\u5316\u7684\u88f8\u786c\u4ef6\u7f16\u8bd1\u5668\uff0c\u5176 LLVM IR \u5982\u679c\u8981\u6c42\u8de8\u5e73\u53f0\u4f1a\u5f88\u4e0d\u5229\u4e8e Clang \u524d\u7aef\u652f\u6301\u786c\u4ef6 intrinsics\uff0c\u4e5f\u4e0d\u5229\u4e8e LLVM \u4e2d\u7aef\u9488\u5bf9\u76ee\u6807\u786c\u4ef6\u7279\u6027\u505a\u4f18\u5316\uff0c\u4e5f\u4f1a\u65e0\u6cd5\u652f\u6301\u5185\u8054\u6c47\u7f16\uff0c\u6240\u4ee5\u5c31\u653e\u5f03\u4e86\u3002\u6240\u4ee5\u73b0\u5b9e\u4e2d\uff0c\u4eba\u4eec\u4f1a\u5148\u628a Vulkan \u7740\u8272\u5668\u7f16\u8bd1\u6210\u8de8\u5e73\u53f0\u7684 SPIR-V \u4e8c\u8fdb\u5236\u53d1\u5e03\uff0c\u7b49\u90e8\u7f72\u5230\u6e38\u620f\u73a9\u5bb6\u7535\u8111\u4e0a\u540e\uff0c\u7136\u540e\u518d\u8f93\u5165\u663e\u5361\u9a71\u52a8\u4e2d\u7684 LLVM \u5f97\u5230 LLVM IR \u540e\u4f18\u5316\uff0c\u7f16\u8bd1\u751f\u6210\u6700\u9002\u5408\u5f53\u524d\u73a9\u5bb6\u663e\u5361\u4f53\u8d28\u7684 GPU \u6c47\u7f16\u3002 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 \u4e0a\u9762\u4ecb\u7ecd\u7684 LLVM IR \u6c47\u7f16\uff0c\u662f\u4ee5\u6587\u672c\u5f62\u5f0f\u5b58\u50a8\u548c\u5904\u7406\uff0c\u867d\u7136\u65b9\u4fbf\u4e86\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\uff0c\u4f46\u5bf9\u7a0b\u5e8f\u800c\u8a00\u6548\u7387\u4e0d\u9ad8\u3002 \u56e0\u6b64 LLVM \u53c8\u53d1\u660e\u4e86\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u6765\u5b58\u50a8 IR\uff0c\u4e5f\u5c31\u662f\u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u53ef\u7b80\u5199\u4e3a BC\u3002 \u4ed6\u4eec\u662f \u5b8c\u5168\u7b49\u4ef7\u7684 \uff0c\u90fd\u662f IR \u7684\u4e24\u79cd\u8868\u73b0\u65b9\u5f0f\uff1a\u4e00\u4e2a\u662f\u6587\u672c\u683c\u5f0f\uff08\u9002\u5408\u4eba\u7c7b\u9605\u8bfb\uff09\uff0c\u4e00\u4e2a\u662f\u4e8c\u8fdb\u5236\u683c\u5f0f\uff08\u9002\u5408\u7a0b\u5e8f\u9605\u8bfb\uff09\u3002 IR \u5b57\u8282\u7801\u4e2d\u7684\u6bcf\u4e2a\uff08\u6216\u591a\u4e2a\uff09\u5b57\u8282\u90fd\u53ef\u4ee5\u548c IR \u6c47\u7f16\u4e2d\u7684\u4e00\u884c IR \u6307\u4ee4\u4e00\u4e00\u5bf9\u5e94\u3002 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c IR \u6c47\u7f16\uff1a .ll IR \u5b57\u8282\u7801: .bc \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c Clang \u751f\u6210 IR \u6c47\u7f16\uff1a\u4f7f\u7528 -S -emit-llvm \u9009\u9879\u3002 clang -S -emit-llvm a.cpp -o a.ll Clang \u751f\u6210 IR \u5b57\u8282\u7801\uff1a\u4f7f\u7528 -c -emit-llvm \u9009\u9879\u3002 clang -c -emit-llvm a.cpp -o a.bc \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c IR \u6c47\u7f16: \u6587\u672c\u683c\u5f0f\uff08a.ll\uff09 ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 1, ptr %2, align 4 %3 = load i32, ptr %2, align 4 %4 = add nsw i32 %3, 1 ret i32 %4 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 17.0.6\"} IR \u5b57\u8282\u7801: \u4e8c\u8fdb\u5236\u683c\u5f0f\uff08a.bc\uff09 00000000 42 43 c0 de 35 14 00 00 05 00 00 00 62 0c 30 24 |BC..5.......b.0$| 00000010 4a 59 be 66 bd fb b4 af 0b 51 80 4c 01 00 00 00 |JY.f.....Q.L....| 00000020 21 0c 00 00 e1 01 00 00 0b 02 21 00 02 00 00 00 |!.........!.....| 00000030 16 00 00 00 07 81 23 91 41 c8 04 49 06 10 32 39 |......#.A..I..29| 00000040 92 01 84 0c 25 05 08 19 1e 04 8b 62 80 0c 45 02 |....%......b..E.| ... \u4ee5\u4e0a\u4e3a\u4f7f\u7528 hexdump \u5de5\u5177\u67e5\u770b\u7684\u5341\u516d\u8fdb\u5236\u5b57\u8282\u53ef\u89c6\u5316\u7ed3\u679c\u3002 .bc \u7684\u5b9e\u9645\u5185\u5bb9\u5b8c\u5168\u662f\u4e8c\u8fdb\u5236\uff0c\u76f4\u63a5 cat \u5230\u7ec8\u7aef\u4f1a\u4e71\u7801\u3002 \u4e4b\u95f4\u7684\u8f6c\u6362 IR \u6c47\u7f16\u5230 IR \u5b57\u8282\u7801\uff1a llvm-as \uff0c\u628a\u6587\u672c IR \u7f16\u8bd1\u6210\u7d27\u51d1\u538b\u7f29\u7684\u5b57\u8282\u7801\u3002 llvm-as test.ll -o test.bc IR \u5b57\u8282\u7801\u5230 IR \u6c47\u7f16\uff1a llvm-dis \uff0c\u628a\u5b57\u8282\u7801\u91cd\u65b0\u8f6c\u56de\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c IR\u3002 llvm-dis test.bc -o test.ll \u518d\u6b21\u63d0\u9192\uff1a\u8fd9\u4e9b\u662f LLVM \u5185\u90e8\u7684 IR \u7684\u4e24\u79cd\u5f62\u5f0f\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u6c47\u7f16\u548c\u673a\u5668\u7801\u3002 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb IR \u5b57\u8282\u7801\u548c IR \u6c47\u7f16\u7684\u5173\u7cfb\uff0c\u6b63\u5982 x86 \u6c47\u7f16\u548c x86 \u673a\u5668\u7801\u7684\u5173\u7cfb\uff0c\u4e4b\u95f4\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb\u3002 IR \u5b57\u8282\u7801\u662f\u4e8c\u8fdb\u5236\u7684\uff0c\u5bf9\u8ba1\u7b97\u673a\u53cb\u597d\uff1b\u800c IR \u6c47\u7f16\u662f\u4eba\u7c7b\u53ef\u8bfb\u7684 ASCII \u5b57\u7b26\uff0c\u65b9\u4fbf\u4eba\u7c7b\u9605\u8bfb\u548c\u8c03\u8bd5\uff0c\u4ed6\u4eec\u672c\u8d28\u4e0a\u90fd\u662f IR\u3002 \u6c47\u7f16\u662f\u7ed9\u4eba\u770b\u7684\u6587\u672c\u6587\u4ef6\uff0c\u673a\u5668\u7801\u662f\u7ed9 CPU \u770b\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\uff1b\u540c\u6837\u5730\uff0cIR \u6c47\u7f16\u662f IR \u7684\u6587\u672c\u683c\u5f0f\uff0c\u662f\u6253\u5370\u7ed9\u4eba\u770b\u7684\uff1b\u800c IR \u5b57\u8282\u7801\u662f\u7ed9 LLVM \u7f16\u8bd1\u5668\u770b\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f IR\uff0c\u89e3\u6790\u8d77\u6765\u66f4\u5feb\uff0c\u4e5f\u8282\u7ea6\u5185\u5b58\u3002 \u4e0d\u8fc7\uff0c\u8981\u6ce8\u610f\u5b57\u8282\u7801\u548c\u673a\u5668\u7801\u4e0d\u540c\uff0c\u4ed6\u4f9d\u7136\u5c5e\u4e8e\u4e2d\u95f4\u8868\u793a\uff08\u53ea\u4e0d\u8fc7\u662f\u538b\u7f29\u5f97\u4eba\u7c7b\u770b\u4e0d\u61c2\u7684\u9ad8\u6548\u4e8c\u8fdb\u5236\u7248 IR\uff09\uff0c\u5e76\u4e0d\u80fd\u76f4\u63a5\u5728\u8ba1\u7b97\u673a\u4e2d\u6267\u884c\uff0cLLVM \u5b57\u8282\u7801\u53ea\u80fd\u5728 lli \u865a\u62df\u673a\u4e2d\u89e3\u91ca\u6267\u884c\uff0c\u6216\u8005\u901a\u8fc7 llc \u7f16\u8bd1\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u540e\u5728\u76ee\u6807\u5e73\u53f0\u88f8\u673a\u6267\u884c\u3002 \u4f46\u548c Java \u7684\u5b57\u8282\u7801\u53c8\u4e0d\u4e00\u6837\uff0cLLVM \u7684\u5b57\u8282\u7801\u672c\u6765\u5c31\u662f\u4e8c\u8fdb\u5236\u7684 IR\u3002\u800c IR \u5e76\u4e0d\u8de8\u5e73\u53f0\uff0c\u6240\u4ee5\u5b57\u8282\u7801\u4e5f\u4e0d\u8de8\u5e73\u53f0\u3002LLVM \u56e2\u961f\u63d0\u4f9b lli \u5de5\u5177\u4e3b\u8981\u662f\u4e3a\u4e86\u65b9\u4fbf\u4e34\u65f6\u6d4b\u8bd5 IR\uff0c\u7528\u4e8e\u751f\u4ea7\u73af\u5883\u7684\u80af\u5b9a\u8fd8\u662f llc \u7f16\u8bd1\u597d\u4ea7\u751f\u771f\u6b63\u7684\u9ad8\u6548\u673a\u5668\u7801\u3002 \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5f97\u5230\u7684 .bc \u5b57\u8282\u7801\u6587\u4ef6\u4e5f\u88ab\u79f0\u4e3a\u4e00\u4e2a\u6a21\u5757\uff08Module\uff09\uff0c\u6a21\u5757\u7531\u4e00\u7cfb\u5217 IR \u9636\u6bb5\u7684\u7ec4\u6210\uff1b\u6b63\u5982\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7531\u5927\u91cf\u6c47\u7f16\u6307\u4ee4\u7ec4\u6210\u4e00\u6837\u3002 \u8fd9\u91cc\u8bf4\u7684 LLVM \u6a21\u5757\u548c C++20 \u7684 Modules \u7279\u6027\u5173\u7cfb\u4e0d\u5927\uff0c\u6a21\u5757\u662f LLVM \u5f88\u65e9\u5c31\u6709\u7684\u6982\u5ff5\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u4e00\u4e2a .cpp \u6587\u4ef6\u7f16\u8bd1\u53ef\u4ee5\u4ea7\u751f IR \u6c47\u7f16\uff08.ll\uff09\uff0cIR \u6c47\u7f16\u53ef\u4ee5\u901a\u8fc7 llvm-as \u7f16\u8bd1\u5f97\u5230\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09\u3002\u56e0\u6b64\u53ef\u4ee5\u7c97\u7565\u7684\u8ba4\u4e3a\uff0c \u4e00\u4e2a\u6e90\u6587\u4ef6\uff08.cpp\uff09\u7f16\u8bd1\u540e\u5c31\u662f\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09 \u3002 \u800c LLVM \u6a21\u5757\uff08.bc\uff09\u53ef\u4ee5\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210\u901a\u7528\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\uff0c\u4ece\u800c\u5c31\u662f\u6211\u4eec\u770b\u5230\u7684\uff1a\u4e00\u4e2a .cpp \u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a .o \u6587\u4ef6\u4e86\u3002 \u6a21\u5757\u4e2d\u5305\u542b\u4e86\u4e4b\u524d\u4ecb\u7ecd\u7684 IR \u6c47\u7f16\u4e2d\u6240\u6709\u7684\u4fe1\u606f\uff0c\u4f8b\u5982\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u5e03\u5c40\u4fe1\u606f\uff0c\u5168\u5c40\u53d8\u91cf\uff0c\u7c7b\u578b\u58f0\u660e\uff0c\u51fd\u6570\u5b9a\u4e49\u548c\u58f0\u660e\u7b49\u3002 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b \u5b57\u8282\u7801\uff08.bc\uff09\u662f LLVM \u5185\u90e8\u7684\u6587\u4ef6\u683c\u5f0f\uff0c\u4e0d\u901a\u7528\u3002\u4f46\u7531\u4e8e\u5176\u76f4\u63a5\u5b58\u50a8 IR\uff0c\u65b9\u4fbf LLVM \u5904\u7406\u548c\u4f18\u5316\uff0c\u4e14\u53ef\u4ee5\u5f88\u5bb9\u6613\u901a\u8fc7 llvm-dis \u53cd\u6c47\u7f16\u6210\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\u6765\u67e5\u770b\uff08.ll\uff09\u3002\u901a\u5e38\u7528\u4e8e\u8c03\u8bd5 LLVM\uff0c\u4ee5\u53ca\u76ee\u6807\u5e73\u53f0\u4e0d\u662f CPU \u7684\u60c5\u51b5\uff08\u4f8b\u5982 CUDA PTX\uff09\u3002 \u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u662f\u7c7b Unix \u5e73\u53f0\u901a\u7528\u7684 ELF \u683c\u5f0f\uff08\u5728 Windows \u5e73\u53f0\u5219\u662f .obj \u6587\u4ef6\uff0cCOFF \u683c\u5f0f\uff09\uff0c\u5176\u4ed6\u652f\u6301 ELF \u7684\u7f16\u8bd1\u5668\u548c\u94fe\u63a5\u5668\u4e5f\u53ef\u4ee5\u4f7f\u7528\u3002\u4f8b\u5982 GCC \u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e5f\u53ef\u4ee5\u540c LLVM \u7f16\u8bd1\u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e00\u8d77\u94fe\u63a5\uff0c\u800c\u5982\u679c\u662f .bc \u683c\u5f0f GCC \u5c31\u8ba4\u4e0d\u51fa\u6765\u3002\u7f3a\u70b9\u662f\u4e00\u65e6\u7f16\u8bd1\u6210 .o \u6587\u4ef6\uff0c\u5c31\u65e0\u6cd5\u518d\u53cd\u63a8\u51fa IR \u4e86\uff0c\u53ea\u80fd\u901a\u8fc7 objdump \u53cd\u6c47\u7f16\u5f97\u5230\u6c47\u7f16\u4ee3\u7801\uff0c\u5c31\u4e0d\u65b9\u4fbf LLVM \u518d\u5904\u7406\u548c\u4f18\u5316\u4e86\u3002 LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u603b\u4e4b\u5728 LLVM / Clang \u5de5\u4f5c\u6d41\u4e2d\uff0c\u53ef\u4ee5\u7c97\u7565\u8ba4\u4e3a\uff0c\u4e00\u4e2a .cpp \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u4e5f\u6709\u4e00\u4e9b\u65f6\u5019\uff0c\u6211\u4eec\u7f16\u8bd1\u6a21\u5757\u7684\u76ee\u6807\u5e76\u4e0d\u662f CPU\uff0c\u4f8b\u5982 Taichi \u9879\u76ee\u4e2d\uff0c\u5c31\u662f\u901a\u8fc7 LLVM \u91cd\u65b0\u7f16\u8bd1 Python \u5b57\u8282\u7801\uff0c\u751f\u6210 .bc \u6a21\u5757\uff0c\u7136\u540e\u7f16\u8bd1\u4ea7\u751f PTX \u6c47\u7f16\uff0c\u8f6c\u5316\u4e3a CUBIN \u4e8c\u8fdb\u5236\u540e\uff0c\u63d0\u4ea4\u5230 CUDA \u9a71\u52a8\u4e2d\u6267\u884c\uff08\u5b9e\u9645\u4e0a\u6b64\u5904\u8fd8\u4f1a\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210 SASS \u6c47\u7f16\uff09\u3002 \u5728 LLVM / Clang CUDA \u5de5\u4f5c\u6d41\u4e2d\uff0c\u4e00\u4e2a .cu \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u5c0f\u5f6d\u8001\u5e08\u7ed8\u5236\u4e00\u526f\u4e16\u754c\u540d\u753b\u300aIntel \u8d4b\u80fd AI \u7f16\u8bd1\u5668\u300b\uff0c\u540c\u5b66\u95ee\uff0c\u6211\u53ea\u770b\u5230\u6309\u6469\u5e97\u548c\u6deb\u5a01\u5927\uff0c\u6a31\u7279\u5c14\u5728\u54ea\u5462\uff1f\u7b54\uff1a\u6a31\u7279\u5c14\u5728\u8d4b\u80fd\u3002 \u8fd9\u91cc\u7684 cubin \u5176\u5b9e\u5c31\u662f\u5e38\u542c\u5230\u7684 fatbin\uff0c\u4e8c\u8fdb\u5236\u7248\u7684 PTX \u6c47\u7f16\uff0cNVCC \u7684\u6d41\u7a0b\u4e5f\u548c\u8fd9\u4e2a\u5dee\u4e0d\u591a\u3002 \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\uff08.bc\uff09\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u94fe\u63a5\uff0c\u5f62\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6a21\u5757\uff0c\u5176\u4e2d\u5305\u542b\u6240\u6709\u5b50\u6a21\u5757\u7684\u5185\u5bb9\u3002 llvm-link test1.bc test2.bc -o test.bc \u901a\u8fc7\u94fe\u63a5\uff0c\u53ef\u4ee5\u628a\u591a\u4e2a\u6a21\u5757\u7684 IR \u5408\u5e76\u5230\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u65b9\u4fbf\u540e\u7eed\u4f18\u5316\u548c\u7f16\u8bd1\u3002 \u6ce8\u610f\uff01\u8fd9\u91cc\u7684 IR \u94fe\u63a5\uff08llvm-link\uff09\u53ea\u662f LLVM \u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\u7684\u4e00\u4e2a\u5c0f\u8fc7\u7a0b\uff0c\u548c\u6c47\u7f16\u9636\u6bb5\u540e\u751f\u6210\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7684\u771f\u6b63\u94fe\u63a5\uff08lld\uff09\u4e0d\u540c\u3002\u8fd9\u91cc\u53ea\u662f\u628a\u591a\u4e2a LLM \u6a21\u5757\u5408\u5e76\u6210\u4e00\u4e2a\u6a21\u5757\u800c\u5df2\uff0c\u6700\u540e\u8fd9\u4e2a\u603b\u6a21\u5757\u7f16\u8bd1\u4f9d\u7136\u662f\u5f97\u5230\u5355\u4e2a .o \u6587\u4ef6\uff0c\u8fd8\u662f\u8981\u7ecf\u8fc7\u771f\u6b63\u7684\u94fe\u63a5\u5668\uff08lld\uff09\uff0c\u4e0e\u5176\u4ed6 .o \u6587\u4ef6\u94fe\u63a5\u624d\u80fd\u5f62\u6210\u6700\u7ec8\u53ef\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 \u628a C++ \u6587\u4ef6\u7f16\u8bd1\u751f\u6210\u7684\u5b57\u8282\u7801\u6a21\u5757\u94fe\u63a5\u8d77\u6765\uff0c\u5c31\u50cf\u5f88\u591a\u4e2a C++ \u6587\u4ef6\u7a81\u7136\u56fd\u5b9d\u7279\u5de5\u5408\u4f53\u4e00\u6837\u3002 \u8c03\u7528 LLVM pass \u4f18\u5316 LLVM \u63d0\u4f9b\u4e86 opt \u8fd9\u4e2a\u65b9\u4fbf\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u53ef\u4ee5\u8c03\u7528 LLVM \u4e2d\u6307\u5b9a\u540d\u79f0\u7684\u4f18\u5316\u7c7b pass\uff0c\u7528\u6765\u4f18\u5316\u4f20\u5165\u7684 IR \u6587\u4ef6\uff08\u53ef\u4ee5\u662f IR \u6c47\u7f16\u6216 IR \u5b57\u8282\u7801\uff09\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8f93\u51fa\u7684\u662f\u4e8c\u8fdb\u5236\u7684 IR \u5b57\u8282\u7801\uff0c\u5982\u9700\u8f93\u51fa\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\uff0c\u53ef\u4ee5\u6307\u5b9a -S \u9009\u9879\uff08\u5c31\u548c\u521a\u624d\u6211\u4eec\u4f7f\u7528 clang -S \u8ba9 -emit-llvm \u751f\u6210 IR \u6c47\u7f16\u800c\u4e0d\u662f IR \u5b57\u8282\u7801\u4e00\u6837\uff09\u3002 # \u8f93\u5165 a.ll\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.ll\uff08IR \u6c47\u7f16\uff09 opt -S -p mem2reg a.ll -o a-opt.ll cat a-opt.ll # \u8f93\u5165 a.bc\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.bc\uff08IR \u5b57\u8282\u7801\uff09 opt -p mem2reg a.bc -o a-opt.bc llvm-dis a-opt.bc -o a-opt.ll # \u5982\u679c\u8f93\u51fa\u5b57\u8282\u7801\u683c\u5f0f\uff0c\u8fd8\u9700\u8981 llvm-dis \u624d\u80fd\u8ba9\u4eba\u7c7b\u770b\u61c2 \u6848\u4f8b \u8fd8\u662f\u8fd9\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u4f7f\u7528 clang \u7f16\u8bd1\uff0c\u751f\u6210 IR \u6c47\u7f16\uff1a clang -S -emit-llvm a.cpp -o a.ll \u5f97\u5230 a.ll\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 0, ptr %2, align 4 store i32 1, ptr %3, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %4, 1 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u73b0\u5728\uff0c\u6211\u4eec\u7528 opt \u5de5\u5177\u5bf9\u5176\u8fdb\u884c\u4f18\u5316\uff1a TODO \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM"},{"location":"llvm_intro/#llvm","text":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM LLVM \u4ecb\u7ecd \u53c2\u8003\u8d44\u6599 \u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f \u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907 \u4e00\u70b9\u5fe0\u544a LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa \u73af\u5883\u51c6\u5907 Linux/MacOS \u7528\u6237 Windows \u7528\u6237 \u9879\u76ee\u76ee\u5f55\u7ed3\u6784 \u5f00\u59cb\u6784\u5efa \u8fd0\u884c\u8bd5\u8bd5 \u57fa\u672c\u6982\u5ff5\u901f\u89c8 \u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef \u8bed\u6cd5\u6811\uff08AST\uff09 \u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16 LLVM IR \u7684\u7279\u70b9 \u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d \u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668 \u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb \u4e09\u64cd\u4f5c\u6570\u6307\u4ee4 \u7c7b\u578b\u7cfb\u7edf \u57fa\u7840\u7c7b\u578b \u5e03\u5c14\u7c7b\u578b \u6307\u9488\u7c7b\u578b \u7ed3\u6784\u4f53\u7c7b\u578b \u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7 \u5b9a\u4e49\u4e0e\u4f7f\u7528 \u4f18\u5316\u4e0e\u5206\u6790 pass LLVM IR \u6848\u4f8b\u5206\u6790 target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f define \u5b9a\u4e49\u51fd\u6570 alloca \u6307\u4ee4 store \u6307\u4ee4 \u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09 load \u6307\u4ee4 add \u6307\u4ee4 ret \u6307\u4ee4 \u4e3a\u51fd\u6570\u6307\u5b9a attributes Clang \u751f\u6210 IR \u6c47\u7f16 \u5b9a\u4e49\u5168\u5c40\u53d8\u91cf \u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage \u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740 call \u8c03\u7528\u5176\u4ed6\u51fd\u6570 \u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0 IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801 IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904 \u540e\u7f00\u540d\u4e0d\u540c \u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c \u5185\u5bb9\u683c\u5f0f\u4e0d\u540c \u4e4b\u95f4\u7684\u8f6c\u6362 \u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb \u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757 \u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe \u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5 \u8c03\u7528 LLVM pass \u4f18\u5316 \u6848\u4f8b \u57fa\u672c\u5757\u4e0e\u5206\u652f \u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09 \u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801 \u6784\u5efa\u597d\u4e86\u5417","title":"\u5c0f\u5f6d\u8001\u5e08\u5e26\u4f60\u5b66 LLVM"},{"location":"llvm_intro/#llvm_1","text":"LLVM \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\u57fa\u7840\u8bbe\u65bd\uff0c\u5b83\u4e0d\u662f\u4e00\u4e2a\u5355\u4e00\u7684\u7f16\u8bd1\u5668\uff0c\u800c\u662f\u4e00\u7cfb\u5217\u5de5\u5177\u548c\u5e93\u7684\u96c6\u5408\uff0c\u5176\u63d0\u4f9b\u4e30\u5bcc\u7684\u6570\u636e\u7ed3\u6784 (ADT) \u548c\u4e2d\u95f4\u8868\u793a\u5c42 (IR)\uff0c\u662f\u5b9e\u73b0\u7f16\u8bd1\u5668\u7684\u6700\u4f73\u6846\u67b6\u3002 LLVM \u662f\u7f16\u8bd1\u5668\u7684\u4e2d\u540e\u7aef\uff0c\u4e2d\u7aef\u8d1f\u8d23\u4f18\u5316\uff0c\u540e\u7aef\u8d1f\u8d23\u6700\u7ec8\u6c47\u7f16\u4ee3\u7801\u7684\u751f\u6210\uff0c\u4ed6\u5e76\u4e0d\u5728\u4e4e\u8c03\u7528\u4ed6\u7684\u4ec0\u4e48\u9ad8\u7ea7\u8bed\u8a00\uff0c\u53ea\u8d1f\u8d23\u628a\u62bd\u8c61\u7684\u4ee3\u6570\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\uff0c\u57fa\u672c\u5757\uff0c\u8f6c\u5316\u4e3a\u8ba1\u7b97\u673a\u786c\u4ef6\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u4e5f\u6709\u4e9b\u6c99\u96d5\u6559\u6750\u4f1a\u628a\u4e2d\u7aef\u548c\u540e\u7aef\u7edf\u79f0\u4e3a\u540e\u7aef\u2026\u2026 Clang \u53ea\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u524d\u7aef\uff0c\u5176\u8d1f\u8d23\u7f16\u8bd1 C/C++ \u8fd9\u7c7b\u8bed\u8a00\uff0c\u8fd8\u6709\u7528\u4e8e\u7f16\u8bd1 Fotran \u7684 Flang \u524d\u7aef\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u8bf8\u5982 Rust\u3001Swift\u3001Haskell \u4e4b\u7c7b\u7684\u8bed\u8a00\uff0c\u4e5f\u90fd\u5728\u4f7f\u7528 LLVM \u505a\u540e\u7aef\u3002 \u4e3e\u4e2a\u4f8b\u5b50\uff0c\u6790\u6784\u51fd\u6570\u5728 } \u5904\u8c03\u7528\uff0c\u8fd9\u662f C++ \u7684\u8bed\u6cd5\u89c4\u5219\uff0c\u5728 Clang \u524d\u7aef\u4e2d\u5904\u7406\u3002\u5f53 Clang \u5b8c\u6210 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u8bed\u4e49\u89c4\u5219\u7684\u89e3\u6790\u540e\uff0c\u5c31\u4f1a\u521b\u5efa\u4e00\u79cd\u53eb\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff0cIntermediate Representation\uff09\u7684\u4e1c\u897f\uff0c\u585e\u7ed9 LLVM \u540e\u7aef\u3002\u5728 IR \u5c42\u9762\uff0c\u6790\u6784\u51fd\u6570\u548c\u666e\u901a C \u8bed\u8a00\u51fd\u6570\u5df2\u7ecf\u6ca1\u6709\u533a\u522b\uff0c\u90fd\u662f\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u6790\u6784\u51fd\u6570\u8c03\u7528\u7684\u65f6\u673a\u5728 Clang \u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u786e\u5b9a\uff08\u57fa\u4e8e C++ \u8bed\u6cd5\u89c4\u5219\u51b3\u5b9a\uff09\u3002LLVM \u5e76\u4e0d\u5173\u5fc3\u8fd9\u4e2a\u51fd\u6570\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f Rust \u51fd\u6570\uff0c\u4ed6\u53ea\u77e5\u9053\u8fd9\u662f\u4e2a\u51fd\u6570\u8c03\u7528\uff0c\u53ea\u9700\u8981\u8fd9\u4e2a\u4fe1\u606f\uff0c\u5c31\u53ef\u4ee5\u53bb\u505a\u4f18\u5316\u4e86\u3002 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u5982\u679c\u6ca1\u6709 IR \u4f1a\u600e\u6837\uff1f\u5047\u8bbe\u6709 M M \u79cd\u8bed\u8a00\uff0c N N \u79cd\u786c\u4ef6\uff0c\u5c31\u9700\u8981\u91cd\u590d\u5b9e\u73b0 M \\times N M \\times N \u4e2a\u7f16\u8bd1\u5668\uff01\u800c IR \u4f5c\u4e3a\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4ee4\u8bed\u8a00\u548c\u786c\u4ef6\u7684\u5177\u4f53\u7ec6\u8282\u89e3\u8026\u4e86\uff0c\u4ece\u800c\u53ea\u9700\u8981\u5199 M + N M + N \u4efd\u4ee3\u7801\u5c31\u53ef\u4ee5\uff1a\u8bed\u8a00\u7684\u5f00\u53d1\u8005\u53ea\u9700\u8981\u8003\u8651\u8bed\u6cd5\u5982\u4f55\u53d8\u6210\u6570\u5b66\u8fd0\u7b97\u548c\u63a7\u5236\u6d41\uff0c\u786c\u4ef6\u5382\u5546\u53ea\u9700\u8981\u8003\u8651\u5982\u4f55\u628a\u6570\u5b66\u548c\u8df3\u8f6c\u6307\u4ee4\u53d8\u6210\u81ea\u5df1\u7279\u5b9a\u7684\u673a\u5668\u7801\u3002\u56e0\u6b64\uff0c\u4e0d\u8bba\u662f LLVM/Clang \u8fd8\u662f GCC \u5bb6\u65cf\uff0c\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u5185\u90e8\u90fd\u65e0\u4e00\u4f8b\u5916\u91c7\u7528\u4e86 IR \u505a\u4e2d\u95f4\u8868\u793a\u3002 \u6709\u4e86\u7edf\u4e00\u7684\u62bd\u8c61 IR \u4ee5\u540e\uff0c\u4e0d\u7ba1\u4f60\u662f C++ \u6790\u6784\u51fd\u6570\u8fd8\u662f C \u8bed\u8a00\u666e\u901a\u51fd\u6570\uff0c\u8fdb\u4e86 IR \u4ee5\u540e\u90fd\u662f\u4e00\u6837\u7684\u51fd\u6570\u8c03\u7528\uff0c\u51cf\u8f7b\u4e86\u7f16\u8bd1\u5668\u4e2d\u540e\u7aef\u5f00\u53d1\u8005\u7684\u5fc3\u667a\u8d1f\u62c5\u3002\u8981\u5f00\u53d1\u4e00\u79cd\u65b0\u8bed\u8a00\uff0c\u53ea\u7ba1\u89e3\u6790\u5b8c\u8bed\u6cd5\u751f\u6210 IR \u8f93\u5165 LLVM\uff0c\u4ed6\u4f1a\u66ff\u4f60\u5305\u529e\u597d\u4f18\u5316\u548c\u6c47\u7f16\u7684\u4e8b\u3002","title":"LLVM \u4ecb\u7ecd"},{"location":"llvm_intro/#_1","text":"LLVM \u5b98\u65b9\u4ed3\u5e93\uff1ahttps://github.com/llvm/llvm-project LLVM \u7528\u6237\u6587\u6863\uff1ahttps://llvm.org/docs/ LLVM \u6e90\u7801\u7ea7\u6587\u6863\uff1ahttps://llvm.org/doxygen/ LLVM IR \u5168\u6587\u6863\uff1ahttps://llvm.org/docs/LangRef.html \u300aLearn LLVM 17\u300b\uff1ahttps://github.com/xiaoweiChen/Learn-LLVM-17 \u300a\u5f00\u59cb\u5b66\u4e60 LLVM\u300b\uff1ahttps://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/ \u300aminiSysY \u7f16\u8bd1\u5b9e\u9a8c\u300b\uff1ahttps://buaa-se-compiling.github.io/miniSysY-tutorial/pre/llvm.html \u300aA Gentle Introduction to LLVM IR\u300b\uff1ahttps://mcyoung.xyz/2023/08/01/llvm-ir/ \u300aLLVM IR C++ API Tutorial\u300b\uff1ahttps://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/ \u4e0d\u5efa\u8bae\u6309\u987a\u5e8f\u5168\u90e8\u9010\u4e2a\u9605\u8bfb\u5b8c\uff0c\u8fd9\u4e48\u591a\u6587\u6863\u5c0f\u5f6d\u8001\u5e08\u90fd\u770b\u4e0d\u5b8c\u3002\u5efa\u8bae\u9047\u5230\u4e86\u4e0d\u719f\u6089\u7684\u6307\u4ee4\u65f6\uff0c\u518d\u53bb\u9488\u5bf9\u6027\u5730\u627e\u5230\u76f8\u5e94\u7ae0\u8282\uff0c\u5b66\u4e60\u3002","title":"\u53c2\u8003\u8d44\u6599"},{"location":"llvm_intro/#llvm_2","text":"\u5982\u679c\u4f60\u5bf9 C++ \u8bed\u8a00\u7684\u5e95\u5c42\u5b9e\u73b0\u611f\u5174\u8da3\uff0c\u7f16\u8bd1\u5668\u662f\u7ed5\u4e0d\u8fc7\u7684\u4e00\u73af\u3002\u5fa1\u4e09\u5bb6\u4e2d\uff0cMSVC \u662f\u95ed\u6e90\u7684\u65e0\u6cd5\u5b66\u4e60\uff0cGCC \u4ee3\u7801\u9ad8\u5ea6\u8026\u5408\uff0c\u4e14\u5f88\u591a\u539f\u59cb\u7684 C \u8bed\u8a00\u201c\u53e4\u795e\u4f4e\u8bed\u201d\u6df7\u6742\u5176\u4e2d\uff0c\u53ef\u8bfb\u6027\u8f83\u5dee\u3002Clang \u662f\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 C++ \u7f16\u8bd1\u5668\u524d\u7aef\uff0c\u800c LLVM \u6b63\u662f\u4ed6\u7684\u540e\u7aef\uff0c\u9ad8\u5ea6\u6a21\u5757\u5316\u7684\u8bbe\u8ba1\uff0c\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5f88\u5bb9\u6613\u52a0\u5165\u81ea\u5df1\u7684\u65b0\u6a21\u5757\uff0c\u6700\u9002\u5408\u7f16\u8bd1\u5668\u65b0\u4eba\u4e0a\u624b\u5b66\u4e60\u3002\u9664\u53bb Clang \u8d1f\u8d23\u7684 C++ \u8bed\u6cd5\u89e3\u6790\u540e\uff0cLLVM \u540e\u7aef\u5360\u636e\u4e86\u534a\u58c1\u6c5f\u5c71\u3002\u4f60\u60f3\u4e0d\u60f3\u63a2\u7a76\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5229\u7528\u672a\u5b9a\u4e49\u884c\u4e3a\u4f18\u5316\u7684\uff1f\u60f3\u4e0d\u60f3\u77e5\u9053\u4e3a\u4ec0\u4e48\u6709\u65f6 C++ \u7f16\u8bd1\u5668\u51fa\u73b0\u5f02\u5e38\u7684\u884c\u4e3a\uff1f\u60f3\u4e0d\u60f3\u4e86\u89e3\u600e\u6837\u624d\u80fd\u5199\u51fa\u5bf9\u7f16\u8bd1\u5668\u53cb\u597d\u7684\u4ee3\u7801\uff0c\u65b9\u4fbf\u7f16\u8bd1\u5668\u81ea\u52a8\u5e2e\u4f60\u4f18\u5316\uff1f\u90a3\u5c31\u6765\u5b66\u4e60 LLVM \u5427\uff01 \u524d\u7aef\u548c\u540e\u7aef\u4f17\u591a\uff0c\u65e0\u8bba\u4f60\u662f\u6253\u7b97\u5f00\u53d1\u4e00\u79cd\u65b0\u578b\u8bed\u8a00\uff0c\u8fd8\u662f\u81ea\u7814\u4e00\u79cd\u65b0\u7684 CPU \u67b6\u6784\uff0c\u8003\u8651\u652f\u6301 LLVM \u4f5c\u4e3a\u4e2d\u7aef\u51e0\u4e4e\u662f\u4f60\u552f\u4e00\u7684\u9009\u62e9\u3002 \u5bf9\u4e8e CPU/GPU \u786c\u4ef6\u5382\u5546\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u524d\u7aef\uff0c\u652f\u6301 LLVM \u5c06\u4f7f\u4f60\u7684\u786c\u4ef6\u76f4\u63a5\u652f\u6301 C/C++/CUDA/OpenCL/SyCL/Objective-C/Fortran/Rust/Swift/Haskell \u7b49\u6240\u6709 LLVM \u6709\u524d\u7aef\u7684\u8bed\u8a00\u3002\u4f8b\u5982\u6709\u7684\u56fd\u4ea7\u663e\u5361\u57fa\u4e8e LLVM \u6dfb\u52a0\u4e86\u81ea\u5df1\u7684\u786c\u4ef6\u6307\u4ee4\u96c6\u4f5c\u4e3a\u540e\u7aef\uff0c\u7136\u540e\u518d\u5229\u7528 LLVM \u7684 CUDA \u524d\u7aef\uff0c\u5c31\u5b9e\u73b0\u4e86\u517c\u5bb9 CUDA\uff0cAMD \u5f97\u4ee5\u5b9e\u73b0 CUDA \u517c\u5bb9\u4e5f\u662f\u57fa\u4e8e\u6b64\u3002\u53cd\u4e4b\uff0c\u65b0\u8bed\u8a00\u4e5f\u53ef\u4ee5\u4f7f\u7528 LLVM \u7684 PTX \u540e\u7aef\u8f93\u51fa\uff0c\u4ece\u800c\u652f\u6301\u5728 NVIDIA \u663e\u5361\u4e0a\u6267\u884c\u3002 \u5bf9\u4e8e\u60f3\u53d1\u660e\u65b0\u8bed\u8a00\u6216\u4e3a\u73b0\u6709\u811a\u672c\u8bed\u8a00\u5b9e\u73b0 JIT \u52a0\u901f\u7684\u5f00\u53d1\u8005\u800c\u8a00\uff1a\u7531\u4e8e\u4e30\u5bcc\u7684\u540e\u7aef\uff0c\u65b0\u8bed\u8a00\u4f7f\u7528 LLVM \u5c31\u80fd\u76f4\u63a5\u652f\u6301 x86/ARM/MIPS/PPC/BPF/PTX/AMDGPU/SPIR-V \u7b49\u5404\u79cd\u67b6\u6784\u548c\u6307\u4ee4\u96c6\uff0c\u800c\u81ea\u5df1\u4e0d\u7528\u589e\u52a0\u4efb\u4f55\u5e95\u5c42\u7ec6\u8282\u8d1f\u62c5\u3002\u4f8b\u5982\u4e00\u4e9b Rust \u7528\u6237\u867d\u7136\u5ba3\u79f0\u53ef\u4ee5\u53d6\u4ee3 C++\uff0c\u4f46 Rust \u7f16\u8bd1\u5668\u6700\u7ec8\u4ecd\u662f\u8c03\u7528 LLVM \u5b9e\u73b0\u7f16\u8bd1\uff0c\u4ea7\u751f\u53ef\u4ee5\u6267\u884c\u7684\u4e8c\u8fdb\u5236\u7801\u3002\u81ea\u5df1\u4e00\u4e2a\u4e2a\u9002\u914d\u6240\u6709\u786c\u4ef6\u5e73\u53f0\u7684\u673a\u5668\u7801\u6210\u672c\u5b9e\u5728\u592a\u9ad8\u4e86\uff0c\u4e14\u4e0d\u8bba\u8fd8\u8981\u4e13\u95e8\u5f00\u53d1\u6240\u6709\u7684\u4f18\u5316 pass\uff0c\u800c LLVM \u4f5c\u4e3a\u4e1a\u754c\u652f\u6301\u6700\u5b8c\u5584\u7684\u73b0\u6210\u54c1\u5728\u5f88\u957f\u4e00\u6bb5\u65f6\u95f4\u5185\u90fd\u5f88\u96be\u4ee3\u66ff\u3002 \u4e2d\u7aef\u4f18\u5316\u548c\u5206\u6790\u80fd\u529b\u5f3a\u5927\uff0c\u65b0\u8bed\u8a00\u82e5\u57fa\u4e8e LLVM\uff0c\u4f18\u5316\u65b9\u9762\u7684\u5de5\u4f5c\u90fd\u6709\u73b0\u6210\u7684\u5b9e\u73b0\uff0c\u53ef\u4ee5\u5168\u90e8\u8ba9 LLVM \u4ee3\u52b3\uff0c\u81ea\u5df1\u53ea\u9700\u8981\u8d1f\u8d23\u89e3\u6790\u8bed\u6cd5\uff0c\u751f\u6210 LLVM IR \u5373\u53ef\uff0c\u5982\u4f55\u4f18\u5316\u540e\u751f\u6210\u4e8c\u8fdb\u5236\u7801\u6839\u672c\u65e0\u9700\u64cd\u5fc3\uff0cLLVM \u4f1a\u81ea\u52a8\u6839\u636e\u5f53\u524d\u7684\u76ee\u6807\u5e73\u53f0\u5224\u65ad\u3002 \u9ad8\u5ea6\u81ea\u5305\u542b\uff0c\u5b8c\u5168\u57fa\u4e8e CMake \u7684\u6a21\u5757\u5316\u6784\u5efa\uff0c\u5145\u6ee1\u73b0\u4ee3\u611f\u3002\u7528\u6237\u53ef\u81ea\u884c\u9009\u62e9\u8981\u6784\u5efa\u7684\u6a21\u5757\u3002\u4e14\u51e0\u4e4e\u5b8c\u5168\u65e0\u4f9d\u8d56\u5c31\u80fd\u6784\u5efa\uff0c\u6709 CMake \u6709\u7f16\u8bd1\u5668\u5c31\u884c\uff0c\u65e0\u9700\u5b89\u88c5\u7e41\u7410\u7684\u7b2c\u4e09\u65b9\u5e93\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u843d\u540e\u7684 Makefile + AutoConf \u6784\u5efa\u7cfb\u7edf\uff0c\u4e14\u7248\u672c\u8981\u6c42\u82db\u523b\u3002 LLVM \u91c7\u7528\u7684 MIT \u5f00\u6e90\u534f\u8bae\u5341\u5206\u5bbd\u677e\uff0c\u5bf9\u5546\u7528\u81ea\u7531\u5ea6\u8f83\u9ad8\u3002\u4e14\u4ee3\u7801\u8d28\u91cf\u4f18\u79c0\uff0c\u5bb9\u6613\u81ea\u5df1\u63d2\u5165\u65b0\u529f\u80fd\uff0c\u53ef\u4fee\u6539\u540e\u4f9b\u81ea\u5df1\u4f7f\u7528\uff0c\u56e0\u6b64\u5e38\u7528\u4e8e\u95ed\u6e90\u9a71\u52a8\u4e2d\uff08\u4f8b\u5982 NVIDIA \u7684 OpenGL \u9a71\u52a8\u7b49\uff09\u3002\u76f8\u6bd4\u4e4b\u4e0b GCC \u91c7\u7528\u7684 GPL \u534f\u8bae\u5c31\u6bd4\u8f83\u4e25\u683c\uff0c\u4e0d\u5f97\u81ea\u5df1\u4fee\u6539\u540e\u95ed\u6e90\u53d1\u5e03\uff08\u5fc5\u987b\u8fde\u540c\u6e90\u4ee3\u7801\u4e00\u8d77\u53d1\u5e03\uff09\u3002 LLVM \u9644\u5e26\u4e86\u8bb8\u591a\u5b9e\u7528\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5e2e\u52a9\u6211\u4eec\u5206\u6790\u7f16\u8bd1\u5168\u8fc7\u7a0b\u7684\u4e2d\u95f4\u7ed3\u679c\uff0c\u7406\u89e3\u4f18\u5316\u662f\u5982\u4f55\u53d1\u751f\u7684\u3002\u4f8b\u5982 llvm-as\uff08LLVM IR \u8f6c\u4e3a\u538b\u7f29\u7684\u5b57\u8282\u7801\uff09\uff0cllvm-dis\uff08\u5b57\u8282\u7801\u8f6c\u4e3a IR\uff09\uff0copt\uff08\u53ef\u4ee5\u5bf9 IR \u8c03\u7528\u5355\u4e2a\u4f18\u5316 pass\uff09\uff0cllc\uff08\u5c06\u5b57\u8282\u7801\u8f6c\u6362\u4e3a\u76ee\u6807\u673a\u5668\u7684\u6c47\u7f16\u4ee3\u7801\uff09\uff0cllvm-link\uff08IR \u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u8f93\u5165\u591a\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff0c\u4ea7\u751f\u5355\u4e2a\u5b57\u8282\u7801\u6587\u4ef6\uff09\uff0clld\uff08\u5bf9\u8c61\u7ea7\u522b\u7684\u94fe\u63a5\uff0c\u7c7b\u4f3c\u4e8e GNU ld\uff09\uff0clli\uff08\u89e3\u91ca\u6267\u884c\u5b57\u8282\u7801\uff09\uff0cllvm-lit\uff08\u5355\u5143\u6d4b\u8bd5\u5de5\u5177\uff09\u3002 \u4e00\u4e9b\u82af\u7247\u76f8\u5173\u7684\u5927\u5382\u4e2d\uff0c\u7f16\u8bd1\u5668\u65b9\u9762\u7684\u5c97\u4f4d\u9700\u6c42\u91cf\u5f88\u5927\u3002\u800c\u5176\u4e2d\u4e3b\u8981\u7528\u7684\uff0c\u4f8b\u5982 NVIDIA \u7684\u7f16\u8bd1\u5668 nvcc\uff0c\u5176\u540e\u7aef\u5c31\u662f\u57fa\u4e8e LLVM \u9b54\u6539\u7684\uff0c\u56e0\u6b64\u5b66\u4e60 LLVM \u5f88\u6709\u5c31\u4e1a\u524d\u666f\u3002 \u4e3a\u4ec0\u4e48\u6709\u4e86 Clang \u8fd8\u8981 nvcc\uff1f\u867d\u7136 Clang \u4e5f\u80fd\u652f\u6301 CUDA\uff0c\u4f46 Clang \u53ea\u80fd\u628a CUDA \u7f16\u8bd1\u6210\u6240\u6709 NVIDIA \u663e\u5361\u90fd\u80fd\u901a\u7528\u7684 PTX\uff0c\u65e0\u6cd5\u751f\u6210\u4e13\u95e8\u5bf9\u4e0d\u540c\u663e\u5361\u578b\u53f7\u7279\u5316 SASS \u6c47\u7f16\uff08\u9700\u8981\u8c03\u7528 NVIDIA CUDA Toolkit \u63d0\u4f9b\u7684 ptxas \u624d\u80fd\u8f6c\u6362\uff09\u3002\u800c nvcc \u7684\u524d\u7aef\u9664\u4e86\u662f\u81ea\u5df1\u7684\uff0c\u540e\u7aef\u540c\u6837\u662f\u8c03\u7528 LLVM \u751f\u6210 PTX \u6c47\u7f16\uff0c\u53ea\u662f NVIDIA \u5bf9 LLVM \u505a\u4e86\u4e00\u4e9b\u95ed\u6e90\u7684\u9b54\u6539\uff08\u5176\u5b9e\u65e9\u671f nvcc \u7684\u540e\u7aef\u662f\u57fa\u4e8e NVIDIA \u81ea\u7814\u7684 NVVM \u540e\u7aef\uff0c\u4f46\u662f\u53d1\u73b0\u6548\u679c\u4e0d\u597d\uff0c\u6700\u8fd1\u6b63\u5728\u9010\u6b65\u5207\u6362\u5230 LLVM \u540e\u7aef\uff0c\u6bd5\u7adf\u662f\u8001\u724c\u9879\u76ee\uff09\u3002\u5982\u679c\u5bf9 C++ \u65b0\u7279\u6027\u6709\u8ffd\u6c42\uff0c\u53ef\u4ee5\u7528 Clang \u524d\u7aef + LLVM \u751f\u6210 PTX + ptxas \u6c47\u7f16\u7684\u7ec4\u5408\uff0c\u5b9e\u73b0\u81ea\u7531\u4e16\u754c\u7684 CUDA \u5de5\u4f5c\u6d41\uff08\u4e4b\u540e\u4ecb\u7ecd\uff09\u3002\u4f46\u662f\u56e0\u4e3a ptxas\uff0c\u4ee5\u53ca CUDA \u5176\u4ed6\u8fd0\u884c\u65f6\u5e93\u7684\u9700\u8981\uff0cClang CUDA \u4f9d\u7136\u9700\u8981\u5b89\u88c5 CUDA Toolkit \u624d\u80fd\u6b63\u5e38\u8fd0\u884c\uff0c\u4e14\u5bf9 CUDA \u7248\u672c\u8981\u6c42\u6bd4\u8f83\u4e25\u683c\uff0c\u53ef\u80fd\u9700\u8981\u8f83\u591a\u7684\u914d\u7f6e\u529f\u592b\u3002 Rust \u7f16\u8bd1\u5668\u6700\u8fd1\u4e5f\u6709\u63d0\u51fa\u4e86 gcc-rust\uff0c\u4f7f\u7528 GCC \u505a\u540e\u7aef\u4ee3\u66ff LLVM \u7684\u8ba1\u5212\u2026\u2026\u5c31\u4e0d\u80fd\u81ea\u7814\u4e00\u4e2a RRVM \u4e48\uff1f\u4e0d\u4ec5\u662f Rust \u7f16\u8bd1\u5668\uff0c\u4f60\u4f1a\u53d1\u73b0\u5f88\u591a Rust \u9879\u76ee\u6700\u7ec8\u6216\u591a\u6216\u5c11\u90fd\u5728\u4f9d\u8d56\u4e00\u4e9b C++ \u5e93\uff0c\u6bd4\u5982 RustDesk \u8fd9\u6b3e\u9ad8\u6027\u80fd\u7684\u8fdc\u7a0b\u63a7\u5236\u8f6f\u4ef6\uff0c\u4e0d\u77e5\u548b\u5730\u5c31\u975e\u8981\u4f9d\u8d56 libyuv \u548c libvpx\uff0c\u8fd8\u8981\u6c42\u7528\u6c99\u96d5\u7684 vcpkg \u5b89\u88c5\u2026\u2026\u662f\u81ea\u5df1\u5199\u4e0d\u6765\u8fd8\u662f\u61d2\u5f97\u5199\u4e86\uff1fRust \u4e0d\u662f\u9ad8\u6027\u80fd\u7684\u7cfb\u7edf\u7ea7\u8bed\u8a00\u4e48\uff1f\u5982\u679c Rust \u793e\u533a\u4e0d\u4f1a\u5199 YUV \u7f16\u7801\uff0c\u53ef\u4ee5\u96c7\u4f63\u5c0f\u5f6d\u8001\u5e08\u5e2e\u5fd9\u7684\u3002\u603b\u4e4b\uff0c\u73b0\u5728\u641e\u5f97 Rust \u548c Python \u4e00\u6837\uff0c\u6210\u5305\u76ae\u8bed\u8a00\u4e86\u3002\u4eca\u540e\u5bf9 Rust \u7684\u5b66\u4e60\uff0c\u6050\u6015\u8fd8\u662f\u5c48\u670d\u4e8e\u5b9e\u7528\uff0c\u548c Python \u4e00\u6837\u5404\u79cd\u201cAPI bindings\u201d\u3002","title":"\u4e3a\u4ec0\u4e48\u9009\u62e9 LLVM"},{"location":"llvm_intro/#llvm_3","text":"LLVM \u9879\u76ee\u4e0d\u4ec5\u5305\u542b\u4e86 LLVM \u672c\u4f53\uff0c\u8fd8\u6709\u4e00\u7cfb\u5217\u56f4\u7ed5 LLVM \u5f00\u53d1\u7684\u4e0a\u4e0b\u6e38\u5de5\u5177\u3002\u4f8b\u5982 Clang \u7f16\u8bd1\u5668\u5c31\u662f LLVM \u9879\u76ee\u4e2d\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff0c\u4ed6\u662f\u4e00\u4e2a C/C++/CUDA/OpenCL/SyCL/Objective-C \u7b49 C \u7c7b\u8bed\u8a00\u7684\u524d\u7aef\uff0c\u53ea\u8d1f\u8d23\u5b8c\u6210\u8bed\u6cd5\u7684\u89e3\u6790\uff0c\u5b9e\u9645\u7f16\u8bd1\u548c\u4e8c\u8fdb\u5236\u751f\u6210\u4ea4\u7ed9 LLVM \u672c\u4f53\uff08\u4e2d\u540e\u7aef\uff09\u6765\u5904\u7406\u3002\u901a\u5e38\u8bf4\u7684 LLVM \u6307\u7684\u662f LLVM \u672c\u4f53\uff0c\u5176\u662f\u4e00\u4e2a\u901a\u7528\u7684\u7f16\u8bd1\u5668\u57fa\u5efa\uff0c\u4ec5\u5305\u542b\u4e2d\u7aef\uff08\u5404\u79cd\u4f18\u5316\uff09\u548c\u540e\u7aef\uff08\u751f\u6210 x86/ARM/MIPS \u7b49\u786c\u4ef6\u7684\u6307\u4ee4\u7801\uff09\u3002Clang \u89e3\u6790 .cpp \u6587\u4ef6\u540e\u4ea7\u751f IR\uff0c\u8c03\u7528 LLVM \u7f16\u8bd1\u751f\u6210\u7684 .o \u5bf9\u8c61\u6587\u4ef6\uff0c\u53c8\u4f1a\u88ab\u8f93\u5165\u5230\u540c\u5c5e LLVM \u9879\u76ee\u7684\u4e00\u4e2a\u5b50\u9879\u76ee\uff1aLLD \u94fe\u63a5\u5668\u4e2d\uff0c\u94fe\u63a5\u5f97\u5230\u6700\u7ec8\u7684\u5355\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\uff08.exe\uff09\u6216\u52a8\u6001\u94fe\u63a5\u5e93\uff08.dll\uff09\uff0cLLD \u8fd8\u53ef\u4ee5\u5f00\u542f\u94fe\u63a5\u65f6\u4f18\u5316\uff0c\u8fd9\u53c8\u4f1a\u7528\u5230 BOLT \u8fd9\u4e2a\u94fe\u63a5\u65f6\u4f18\u5316\u5668\uff0c\u5bf9\u751f\u6210\u7684\u5355\u4e2a\u4e8c\u8fdb\u5236\u505a\u8fdb\u4e00\u6b65\u6c47\u7f16\u7ea7\u522b\u7684\u4f18\u5316\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8457\u540d\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\u4e4b\u4e00\uff0clibc++\uff0c\u4e5f\u662f LLVM \u9879\u76ee\u7684\u4e00\u90e8\u5206\uff0c\u76f8\u6bd4 GCC \u5bb6\u65cf\u7684 libstdc++ \u66f4\u7b80\u5355\uff0c\u66f4\u9002\u5408\u5b66\u4e60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5e76\u884c\u7684 STL \u5b9e\u73b0 pstl\uff0cOpenCL \u7f16\u8bd1\u5668 libclc \u7b49\u2026\u2026\u5e94\u6709\u5c3d\u6709\uff0c\u662f\u7f16\u8bd1\u5668\u5f00\u53d1\u8005\u7684\u5929\u5802\u3002 Clang \u7f16\u8bd1 C++ \u7a0b\u5e8f\u7684\u6574\u4e2a\u8fc7\u7a0b\uff1a Clang \u524d\u7aef\u89e3\u6790 C++ \u8bed\u6cd5 -> LLVM \u4e2d\u7aef\u4f18\u5316 -> LLVM \u540e\u7aef\u751f\u6210\u6307\u4ee4\u7801 -> LLD \u94fe\u63a5 -> BOLT \u94fe\u63a5\u540e\u4f18\u5316 \u800c GCC \u5c31\u6ca1\u6709\u8fd9\u4e48\u6a21\u5757\u5316\u4e86\uff0c\u867d\u7136 GCC \u5185\u90e8\u540c\u6837\u662f\u6709\u524d\u7aef\u548c\u4e2d\u7aef IR\uff0c\u4f46\u662f\u6574\u4e2a\u5c31\u662f\u7cca\u5728\u4e00\u4e2a GCC \u53ef\u6267\u884c\u6587\u4ef6\u91cc\uff0c\u96be\u4ee5\u91cd\u6784\uff0c\u79ef\u91cd\u96be\u53cd\uff0c\u4e5f\u96be\u4ee5\u8de8\u5e73\u53f0\uff08MinGW \u8fd8\u662f\u6c11\u95f4\u81ea\u5df1\u79fb\u690d\u8fc7\u53bb\u7684\uff0c\u5e76\u975e GCC \u5b98\u65b9\u9879\u76ee\uff09\u3002\u548c Clang \u80fd\u8f7b\u6613\u4f5c\u4e3a libclang \u548c libLLVM \u5e93\u53d1\u5e03\u76f8\u6bd4\uff0c\u9ad8\u4e0b\u7acb\u5224\u3002MSVC \u66f4\u662f\u4e0d\u5fc5\u591a\u8bf4\uff0c\u8fde\u6e90\u7801\u90fd\u4e0d\u5f00\u653e\uff0c\u8ba9\u4eba\u600e\u4e48\u5b66\u4e60\u548c\u9b54\u6539\u554a\uff1f","title":"LLVM \u4e0a\u4e0b\u6e38\u5168\u5bb6\u6876\u7684\u5b8f\u4f1f\u56fe\u666f"},{"location":"llvm_intro/#llvm_4","text":"\u8981\u5b66\u4e60 LLVM\uff0c\u80af\u5b9a\u4e0d\u80fd\u7eb8\u4e0a\u8c08\u5175\u3002LLVM \u662f\u5f00\u6e90\u8f6f\u4ef6\uff0c\u6700\u597d\u662f\u81ea\u5df1\u4e0b\u8f7d\u4e00\u4e2a LLVM \u5168\u5bb6\u6876\u6e90\u7801\uff0c\u7136\u540e\u81ea\u5df1\u4ece\u6e90\u7801\u6784\u5efa\u3002 \u6ce8\u610f\uff1a\u6211\u4eec\u6700\u597d\u662f\u4ece\u6e90\u7801\u6784\u5efa LLVM \u548c Clang\uff0c\u65b9\u4fbf\u6211\u4eec\u52a8\u624b\u4fee\u6539\u5176\u6e90\u7801\uff0c\u6dfb\u52a0\u6a21\u5757\uff0c\u67e5\u770b\u6548\u679c\u3002\u4e0b\u8f7d\u4e8c\u8fdb\u5236\u53d1\u5e03\u7248 LLVM \u6216 Clang \u7684\u8bdd\uff0c\u867d\u7136\u540c\u6837\u53ef\u4ee5\u4f7f\u7528\u6240\u6709\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u5c31\u53ea\u80fd\u5bf9\u7740 IR \u4e00\u901a\u5206\u6790\u76f2\u731c\u4e86\u3002 \u6e90\u7801\u9762\u524d\uff0c\u4e86\u65e0\u79d8\u5bc6\u3002 \u867d\u7136 LLVM \u51e0\u4e4e\u662f\u65e0\u4f9d\u8d56\u7684\uff0c\u53ea\u9700\u8981 CMake \u548c\u7f16\u8bd1\u5668\u5c31\u80fd\u6784\u5efa\uff0c\u4f46\u4f9d\u7136\u63a8\u8350\u4f7f\u7528 Linux \u7cfb\u7edf\u8fdb\u884c\u5b9e\u9a8c\uff0c\u4ee5\u83b7\u5f97\u548c\u5c0f\u5f6d\u8001\u5e08\u540c\u6837\u7684\u5f00\u53d1\u4f53\u9a8c\u3002Windows \u7528\u6237\u5efa\u8bae\u4f7f\u7528 Visual Studio \u6216 CLion \u7b49\u5f3a\u5927 IDE \u5e2e\u52a9\u9605\u8bfb\u7406\u89e3\u6e90\u7801\uff1bLinux \u7528\u6237\u5efa\u8bae\u5b89\u88c5 \u5c0f\u5f6d\u8001\u5e08 vimrc \uff1b\u6216\u8005\u5982\u679c\u4f60\u662f\u8fdc\u7a0b Linux\uff0c\u53ef\u4ee5\u8bd5\u8bd5\u770b VSCode \u7684\u8fdc\u7a0b SSH \u8fde\u63a5\u63d2\u4ef6\uff1bCLion \u4f3c\u4e4e\u4e5f\u6709\u8fdc\u7a0b\u63d2\u4ef6\uff0c\u53ea\u4e0d\u8fc7\u9700\u8981\u5728\u8fdc\u7a0b\u5b89\u88c5\u597d\u5ba2\u6237\u7aef\u3002 \u5f3a\u5927\u7684 IDE \u548c\u7f16\u8f91\u5668\u5bf9\u5b66\u4e60\u4efb\u4f55\u5927\u578b\u9879\u76ee\u90fd\u662f\u5fc5\u4e0d\u53ef\u5c11\u7684\uff0c\u7279\u522b\u662f\u8df3\u8f6c\u5230\u5b9a\u4e49\uff0c\u4ee5\u53ca\u8fd4\u56de\u8fd9\u4e24\u4e2a\u64cd\u4f5c\uff0c\u662f\u4f7f\u7528\u9891\u7387\u6700\u9ad8\u7684\uff0c\u5728\u6e90\u7801\u4e4b\u95f4\u7684\u5feb\u901f\u8df3\u8f6c\u5c06\u5927\u5927\u6709\u52a9\u4e8e\u5feb\u901f\u7406\u89e3\u548c\u638c\u63e1\u4ee3\u7801\u7ed3\u6784\u3002 \u5982\u679c\u5b9e\u5728\u6ca1\u6709\u6761\u4ef6\u81ea\u5df1\u6784\u5efa LLVM \u6e90\u7801\uff0c\u6216\u8005 IDE \u6bd4\u8f83\u62c9\u80ef\uff1a\u53ef\u4ee5\u53bb LLVM \u7684\u5728\u7ebf\u6e90\u7801\u7ea7\u6587\u6863\uff08\u4f7f\u7528 Doxygen \u751f\u6210\uff09\u770b\u770b\u3002\u5176\u4e0d\u4ec5\u63d0\u4f9b\u4e86 LLVM \u4e2d\u6240\u6709\u7c7b\u548c\u51fd\u6570\u7684\u8be6\u5c3d\u6587\u6863\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u7528\u6cd5\u8bf4\u660e\u7b49\uff1b\u8fd8\u63d0\u4f9b\u4e86\u6bcf\u4e2a\u51fd\u6570\u7684\u6240\u5728\u6587\u4ef6\u548c\u884c\u53f7\u4fe1\u606f\uff0c\u70b9\u51fb\u7c7b\u578b\u6216\u51fd\u6570\u540d\u7684\u8d85\u94fe\u63a5\uff0c\u5c31\u53ef\u4ee5\u5728\u6e90\u7801\u548c\u6587\u6863\u4e4b\u95f4\u6765\u56de\u8df3\u8f6c\u3002\u8fd8\u80fd\u770b\u5230\u54ea\u91cc\u5f15\u7528\u4e86\u8fd9\u4e2a\u51fd\u6570\uff0c\u8fd8\u80fd\u663e\u793a\u7c7b\u7684\u7ee7\u627f\u5173\u7cfb\u56fe\uff0c\u975e\u5e38\u9002\u5408\u4e0a\u73ed\u8def\u4e0a\u6ca1\u6cd5\u6253\u5f00\u7535\u8111\u65f6\u5077\u5b66 LLVM \u6e90\u7801\u7528\u3002\u4f8b\u5982\uff0c llvm::VectorType \u8fd9\u4e2a\u7c7b\u7684\u6587\u6863\uff1ahttps://llvm.org/doxygen/classllvm_1_1VectorType.html","title":"\u5b66\u4e60 LLVM \u524d\u7684\u51c6\u5907"},{"location":"llvm_intro/#_2","text":"\u5bf9\u4e8e LLVM \u8fd9\u79cd\u5927\u578b\u9879\u76ee\uff0c\u7531\u4e8e\u4f60\u662f\u521d\u5b66\u8005\uff0c\u52a1\u5fc5\u505a\u5230\u201c\u4e0d\u6c42\u751a\u89e3\u201d\uff01 \u4f60\u5fc5\u7136\u4e00\u65f6\u534a\u4f1a\u4e0d\u80fd\u5b8c\u5168\u770b\u61c2\u6bcf\u4e2a\u7ec6\u8282\uff0c\u5343\u4e07\u4e0d\u8981\u6b7b\u6263\u7ec6\u8282\uff0c\u4e00\u4e2a\u7ec6\u8282\u4e0d\u7406\u89e3\u5c31\u786c\u77aa\u773c\u5e72\u770b\uff01 \u770b\u4e0d\u61c2\u7684\u5148\u8df3\u8fc7\u53bb\u5373\u53ef\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\u3002\u7535\u89c6\u8fde\u7eed\u5267\u8df3\u4e00\u4e24\u96c6\uff0c\u751a\u81f3\u4ece\u4e2d\u95f4\u5f00\u59cb\u770b\uff0c\u90fd\u80fd\u770b\u61c2\u5462\uff01\u6ca1\u6709\u90a3\u4e48\u4e25\u683c\u7684\u987a\u5e8f\u4f9d\u8d56\u3002 \u4ee5\u540e\u77e5\u8bc6\u50a8\u5907\u591f\u4e86\uff0c\u6216\u8005\u5de5\u4f5c\u4e2d\u9700\u8981\u7528\u5230\u4e86\uff0c\u518d\u56de\u8fc7\u5934\u6765\u67e5\u6f0f\u8865\u7f3a\u4e5f\u4e0d\u8fdf\u3002 \u6211\u6700\u6015\u67d0\u4e9b\u540c\u5b66\u76ef\u7740\u67d0\u4e2a\u6b21\u8981\u7684\u7ec6\u8282\u6b7b\u52b2\u60f3\uff0c\u60f3\u4e0d\u51fa\u5c31\u6b62\u6b65\u4e0d\u524d\u4e86\u3002\u6bd4\u5982\u4ed6\u9047\u5230\u4e00\u4e2a\u8001\u5916\u8bf4\uff1a My dick is bleeding, could you tell me where is the toilet? \u800c \u2018dick\u2019 \u662f\u8fd9\u4e2a\u540c\u5b66\u770b\u4e0d\u61c2\u7684\u201c\u751f\u8bcd\u201d\uff0c\u4ed6\u5c31\u6b7b\u6263\u8fd9\u4e2a\u5b57\u773c\uff0c\u8ba4\u4e3a\u770b\u4e0d\u61c2\u8fd9\u4e2a\u8bcd\uff0c\u540e\u9762\u7684\u5bf9\u8bdd\u4e5f\u4f1a\u770b\u4e0d\u61c2\u3002 \u5b9e\u9645\u4e0a\uff0c\u53ea\u9700\u8981\u628a\u8fd9\u4e2a\u770b\u4e0d\u61c2\u7684\u5730\u65b9\u8df3\u8fc7\uff0c\u5f53\u4ed6\u4e0d\u5b58\u5728\uff0c\u5c31\u5f53\u4ed6\u662f\u4e00\u4e2a\u4e71\u7801\u585e\u5728\u90a3\u91cc\u5e72\u6270\u4f60\u9605\u8bfb\u7684\uff0c\u4f60\u53ea\u7ba1\u7ee7\u7eed\u770b\u4e0b\u53bb\uff1a My \ufffd\ufffd\ufffd is \ufffd\ufffd\ufffd\ufffd\ufffd, could you tell me where is the toilet? \u4e00\u6837\u80fd\u770b\u61c2\u8001\u5916\u60f3\u8981\u95ee\u7684\u662f\u5395\u6240\uff08toilet\uff09\uff0c\u6839\u672c\u4e0d\u9700\u8981\u77e5\u9053\u524d\u9762\u7684 \u2018dick\u2019 \u662f\u4ec0\u4e48\u610f\u601d\u3002 \u81f4\u6d82\u9ed1\u4e16\u754c\u7684\u4e66\u4fe1","title":"\u4e00\u70b9\u5fe0\u544a"},{"location":"llvm_intro/#llvm_5","text":"","title":"LLVM \u5f00\u53d1\u73af\u5883\u642d\u5efa"},{"location":"llvm_intro/#_3","text":"LLVM\uff08\u548c Clang\uff09\u7684\u6784\u5efa\u4f9d\u8d56\u9879\u51e0\u4e4e\u6ca1\u6709\uff0c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\uff0c\u975e\u5e38\u7684\u73b0\u4ee3\u3002","title":"\u73af\u5883\u51c6\u5907"},{"location":"llvm_intro/#linuxmacos","text":"\u9996\u5148\u5b89\u88c5 Git\u3001CMake\u3001Ninja\u3001GCC\uff08\u6216 Clang\uff09\u3002 \u5176\u4e2d Ninja \u53ef\u4ee5\u4e0d\u5b89\u88c5\uff0c\u53ea\u662f\u56e0\u4e3a Ninja \u6784\u5efa\u901f\u5ea6\u6bd4 Make \u5feb\uff0c\u7279\u522b\u662f\u5f53\u6587\u4ef6\u975e\u5e38\u591a\uff0c\u800c\u4f60\u6539\u52a8\u975e\u5e38\u5c11\u65f6\u3002\u800c\u4e14 Ninja \u9ed8\u8ba4\u5c31\u5f00\u542f\u591a\u6838\u5e76\u884c\u6784\u5efa\uff0c\u6240\u4ee5\u5927\u578b\u9879\u76ee\u901a\u5e38\u4f1a\u5c3d\u91cf\u7ed9 cmake \u6307\u5b9a\u4e00\u4e0b -G Ninja \u9009\u9879\uff0c\u8ba9\u5176\u4f7f\u7528\u66f4\u9ad8\u6548\u7684 Ninja \u540e\u7aef\u6784\u5efa\u3002 Arch Linux: sudo pacman -S git cmake ninja gcc Ubuntu: sudo apt-get install git cmake ninja-build g++ MacOS: brew install git cmake ninja gcc \u5f00\u59cb\u514b\u9686\u9879\u76ee\uff08\u9700\u8981\u65f6\u95f4\uff09\uff1a git clone https://github.com/llvm/llvm-project \u5982\u679c\u4f60\u7684 GitHub \u7f51\u901f\u8f83\u6162\uff0c\u53ef\u4ee5\u6539\u7528 Gitee \u56fd\u5185\u955c\u50cf\uff08\u53ea\u4e0d\u8fc7\u8fd9\u6837\u4f60\u5c31\u6ca1\u6cd5\u7ed9 LLVM \u5b98\u65b9\u6c34 PR \u4e86 \ud83e\udd23\uff09\uff1a git clone https://gitee.com/mirrors/LLVM","title":"Linux/MacOS \u7528\u6237"},{"location":"llvm_intro/#windows","text":"\u5373\u4f7f\u662f LLVM \u8fd9\u6837\u6beb\u65e0\u4f9d\u8d56\u9879\u7684\u9879\u76ee\uff0c\u201c\u53ea\u9700\u8981\u5b89\u88c5\u4e86\u7f16\u8bd1\u5668\u548c CMake \u5c31\u884c\u201d\uff0c\u5728 Windows \u7528\u6237\u770b\u6765\u4f9d\u7136\u975e\u5e38\u79d1\u5e7b\u3002 \u597d\u5728\u5fae\u8f6f\u4e5f\u610f\u8bc6\u5230\u4e86\u81ea\u5df1\u7684\u6b8b\u5e9f\uff0c\u73b0\u5728 Virtual Studio 2022 \u5df2\u7ecf\u66ff\u4f60\u5305\u529e\u597d\u4e86\uff08\u81ea\u5e26 Git\u3001CMake \u548c Ninja \u4e86\uff09\u3002 \u5982\u679c\u4f60\u662f\u7528 VS2022 \u81ea\u5e26\u7684 Git \u514b\u9686 llvm-project\uff0c\u8bb0\u5f97 cd \u5230 llvm \u6587\u4ef6\u5939\u91cc\u518d\u7528 cmake\uff0c\u7136\u800c\u8d35\u7269 IDE \u7684\u4e00\u4e2a cd \u90fd\u662f\u5982\u6b64\u7684\u56f0\u96be\u3002 \u6240\u4ee5\u8fd9\u8fb9\u5efa\u8bae\u4f60\u76f4\u63a5\u5148\u628a llvm-project \u4ed3\u5e93\u4f5c\u4e3a ZIP \u4e0b\u8f7d\u4e0b\u6765\uff0c\u7136\u540e\u6253\u5f00\u5176\u4e2d\u7684 llvm \u5b50\u6587\u4ef6\u5939\uff0c\u7136\u540e\u7528 VS2022 \u6253\u5f00\u5176\u4e2d\u7684 CMakeLists.txt\uff0c\u7136\u540e\u5f00\u59cb\u6784\u5efa\u3002 \u7136\u540e\uff0c\u8981\u5f00\u542f\u4e00\u4e2a CMake \u9009\u9879 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \uff0c\u624d\u80fd\u6784\u5efa Clang \u5b50\u9879\u76ee\uff08\u5426\u5219\u6784\u5efa\u7684\u662f\u8d64\u818a LLVM\uff0c\u6ca1\u6709\u4efb\u4f55\u524d\u7aef\uff0c\u8fd9\u6beb\u65e0\u610f\u4e49\uff09\u3002\u4ec5\u6b64\u662f\u6307\u5b9a\u8fd9\u4e00\u4e2a\u5c0f\u5c0f\u9009\u9879\u5bf9\u4e8e IDE \u53d7\u5bb3\u8005\u53c8\u662f\u4f55\u7b49\u7684\u56f0\u96be\u2026\u2026\u4ed6\u4eec\u9700\u8981\u5728 VS2022 \u4e2d\u6253\u5f00 CMakeSettings.json\uff0c\u4fee\u6539 x64-Debug \u7684\u914d\u7f6e\uff0c\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\uff0c\u503c\u4e3a \u201cclang;clang-tools-extra\u201d\u2026\u2026\u5982\u679c\u4ed6\u4eec\u8981\u6539\u6210 Release \u914d\u7f6e\uff0c\u53c8\u8981\u70b9\u51fb\u52a0\u53f7\u521b\u5efa x64-Release\uff08\u5343\u4e07\u522b\u70b9\u9519\u6210 x86-Release\uff01\uff09\uff0c\u7136\u540e\u518d\u6b21\u70b9\u51fb\u6dfb\u52a0\u4e00\u4e2a\u53d8\u91cf LLVM_ENABLE_PROJECTS\u2026\u2026 \u56e0\u4e3a llvm-project \u662f\u8bb8\u591a\u9879\u76ee\u7684\u96c6\u5408\uff0c\u6839\u76ee\u5f55\u91cc\u5e76\u6ca1\u6709 CMakeLists.txt\uff0c\u800c VS2022 \u4f3c\u4e4e\u53ea\u80fd\u8bc6\u522b\u6839\u76ee\u5f55\u7684 CMakeLists.txt\u2026\u2026 \u6b63\u5e38\u7cfb\u7edf\u53ea\u9700\u8981\u7ed9\u4f60\u5199\u4e00\u4e32\u547d\u4ee4\uff0c\u4f60\u53ea\u7ba1\u590d\u5236\u7c98\u8d34\u5230 Shell \u91cc\u4e00\u6267\u884c\u5c31\u641e\u5b9a\u4e86\u3002\u8111\u762b\u7cfb\u7edf\u9700\u8981\u5927\u91cf\u65e0\u8c13\u7684\u6587\u5b57\u63cf\u8ff0\u548c\u622a\u56fe\u7bad\u5934\u6307\u793a\u534a\u5929\uff0c\u8fd8\u7ecf\u5e38\u6709\u4eba\u770b\u4e0d\u61c2\uff0c\u8981\u53cd\u590d\u5f3a\u8c03\uff0c\u753b\u7bad\u5934\uff0c\u52a0\u7c97\u5b57\u4f53\uff0c\u624d\u80fd\u64cd\u63a7\u4ed6\u7684\u9f20\u6807\u70b9\u51fb\u5230\u6b63\u786e\u6309\u94ae\u4e0a\u3002\u6211\u4e5f\u60f3\u628a\u9f20\u6807\u5b8f\u5f55\u4e0b\u6765\uff0c\u53ef\u662f\u4e0d\u540c\u7535\u8111\u5206\u8fa8\u7387\u4e0d\u540c\uff0c\u7a97\u53e3\u4f4d\u7f6e\u53c8\u5f88\u968f\u673a\uff0c\u7535\u8111\u54cd\u5e94\u901f\u5ea6\u53c8\u968f\u673a\uff0c\u6709\u65f6\u5019 C \u76d8\uff0c\u6709\u65f6\u5019\u53c8 D \u76d8\uff0c\u6839\u672c\u4e0d\u7ed9\u4e00\u4e2a\u7edf\u4e00\u7684\u64cd\u4f5c\u65b9\u5f0f,\u7edf\u4e00\u7684\u547d\u4ee4\u884c\u5c31\u6ca1\u6709\u8fd9\u79cd\u70e6\u607c\u3002\u6240\u4ee5\uff0c\u80fd\u5378\u8f7d\u7684\u5378\u8f7d\uff0c\u80fd\u53cc\u7cfb\u7edf\u7684\u53cc\u7cfb\u7edf\uff0c\u80fd WSL \u4e5f\u603b\u6bd4\u8171\u9798\u7c89\u788e\u5668\uff08\u9f20\u6807\uff09\u597d\uff0c\u81f3\u5c11\u80fd\u4e00\u952e\u7c98\u8d34\u5c0f\u5f6d\u8001\u5e08\u540c\u6b3e\u64cd\u4f5c\u3002","title":"Windows \u7528\u6237"},{"location":"llvm_intro/#_4","text":"$ cd llvm-project $ ls bolt CONTRIBUTING.md LICENSE.TXT pstl build cross-project-tests lld pyproject.toml build.sh flang lldb README.md clang libc llvm runtimes clang-tools-extra libclc llvm-libgcc SECURITY.md cmake libcxx mlir third-party CODE_OF_CONDUCT.md libcxxabi openmp utils compiler-rt libunwind polly \u6ce8\u610f\u5230\u8fd9\u91cc\u9762\u6709\u5f88\u591a\u7684\u5b50\u9879\u76ee\uff0c\u5176\u4e2d\u6211\u4eec\u4e3b\u8981\u5b66\u4e60\u7684\u5c31\u662f\u8fd9\u91cc\u9762\u7684 llvm \u6587\u4ef6\u5939\uff0c\u4ed6\u662f LLVM \u7684\u672c\u4f53\u3002\u5176\u4e2d\u4e0d\u4ec5\u5305\u542b LLVM \u5e93\uff0c\u4e5f\u5305\u542b\u4e00\u4e9b\u5904\u7406 LLVM IR \u548c\u5b57\u8282\u7801\u7684\u5b9e\u7528\u5de5\u5177\uff08\u4f8b\u5982 llvm-as\uff09\u3002 \u5176\u6b21\u5c31\u662f clang \u6587\u4ef6\u5939\uff0c\u8fd9\u4e2a\u5b50\u9879\u76ee\u5c31\u662f\u5927\u540d\u9f0e\u9f0e\u7684 Clang \u7f16\u8bd1\u5668\uff0c\u4ed6\u4e5f\u662f\u57fa\u4e8e LLVM \u672c\u4f53\u5b9e\u73b0\u7684\uff0c\u672c\u8eab\u53ea\u662f\u4e2a\u524d\u7aef\uff0c\u5e76\u4e0d\u505a\u4f18\u5316\u548c\u540e\u7aef\u6c47\u7f16\u751f\u6210\u3002 clang-tools-extra \u8fd9\u4e2a\u5b50\u9879\u76ee\u662f clangd\u3001clang-tidy\u3001clang-format \u7b49 C/C++ \u4ee3\u7801\u8d28\u91cf\u5de5\u5177\uff0c\u53ef\u4ee5\u9009\u62e9\u4e0d\u6784\u5efa\u3002 libc \u662f Clang \u5b98\u914d\u7684 C \u6807\u51c6\u5e93\uff0c\u800c libcxx \u662f Clang \u5b98\u914d\u7684 C++ \u6807\u51c6\u5e93\uff0c\u60f3\u5b66\u6807\u51c6\u5e93\u6e90\u7801\u7684\u540c\u5b66\u53ef\u4ee5\u770b\u770b\u3002 flang \u662f LLVM \u7684 Fortran \u524d\u7aef\uff0c\u7f16\u7a0b\u754c\u7684\u6d3b\u5316\u77f3\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 lldb \u662f LLVM \u5b98\u65b9\u7684\u8c03\u8bd5\u5668\uff0c\u5bf9\u6807 GCC \u7684 gdb \u8c03\u8bd5\u5668\uff0cVSCode \u4e2d\u7684\u8c03\u8bd5\u9ed8\u8ba4\u5c31\u662f\u57fa\u4e8e lldb \u7684\u3002 lld \u662f LLVM \u5b98\u65b9\u7684\u4e8c\u8fdb\u5236\u94fe\u63a5\u5668\uff0c\u5bf9\u6807 GCC \u7684 ld \u548c ld.gold\uff1b\u800c bolt \u662f\u94fe\u63a5\u540e\u4f18\u5316\u5668\uff0c\u7528\u7684\u4e0d\u591a\u3002 compiler-rt \u662f\u8bf8\u5982 AddressSantizer\uff08\u5185\u5b58\u6ea2\u51fa\u68c0\u6d4b\u5de5\u5177\uff09\u3001MSAN\uff08\u5185\u5b58\u6cc4\u6f0f\u68c0\u6d4b\uff09\u3001TSAN\uff08\u7ebf\u7a0b\u5b89\u5168\u68c0\u6d4b\uff09\u3001UBSAN\uff08\u672a\u5b9a\u4e49\u884c\u4e3a\u68c0\u6d4b\uff09\u7b49\u5de5\u5177\u7684\u5b9e\u73b0\u3002 mlir \u662f LLVM \u5bf9 MLIR \u7684\u7f16\u8bd1\u5668\u5b9e\u73b0\uff08\u4e00\u79cd\u4e3a\u673a\u5668\u5b66\u4e60\u5b9a\u5236\uff0c\u5141\u8bb8\u7528\u6237\u81ea\u5b9a\u4e49\u65b0\u7684 IR \u8282\u70b9\uff0c\u4f8b\u5982\u77e9\u9635\u4e58\u6cd5\u7b49\u9ad8\u9636\u64cd\u4f5c\uff0c\u65b9\u4fbf\u7279\u5b9a\u786c\u4ef6\u8bc6\u522b\u5230\u5e76\u4f18\u5316\u6210\u81ea\u7814\u786c\u4ef6\u4e13\u95e8\u7684\u77e9\u9635\u4e58\u6cd5\u6307\u4ee4\uff0c\u6700\u8fd1\u4f3c\u4e4e\u5728 AI \u5b5d\u5b50\u4e2d\u5f88\u6d41\u884c\uff09\u3002 libclc \u662f LLVM \u5bf9 OpenCL \u7684\u5b9e\u73b0\uff08OpenCL \u8bed\u8a00\u89c4\u8303\u7684\u7f16\u8bd1\u5668\uff09\uff0cOpenCL \u662f\u5b64\u513f\uff0c\u6ca1\u4ec0\u4e48\u597d\u8bf4\u7684\u3002 openmp \u662f LLVM \u5bf9 OpenMP \u7684\u5b9e\u73b0\uff08\u4e00\u79cd\u7528\u4e8e\u50bb\u74dc\u5f0f CPU \u5355\u673a\u5e76\u884c\u7684\u6846\u67b6\uff0c\u7528\u6cd5\u5f62\u5982 #pragma omp parallel for \uff09\u3002 pstl \u662f LLVM \u5bf9 C++17 Parallel STL \u7684\u5b9e\u73b0\uff08\u540c\u6837\u662f\u5355\u673a CPU \u5e76\u884c\uff0c\u4f18\u52bf\u5728\u4e8e\u5229\u7528\u4e86 C++ \u8bed\u6cd5\u7cd6\uff0c\u4e5f\u6bd4\u8f83\u5b64\u513f\uff0c\u7528\u7684\u4e0d\u591a\uff09\u3002 cmake \u6587\u4ef6\u5939\u5e76\u4e0d\u662f\u5b50\u9879\u76ee\uff0c\u800c\u662f\u88c5\u7740\u548c LLVM \u76f8\u5173\u7684\u4e00\u4e9b CMake \u811a\u672c\u6587\u4ef6\u3002 build \u6587\u4ef6\u5939\u662f\u4f7f\u7528\u8fc7 CMake \u540e\u4f1a\u624d\u751f\u6210\u7684\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u662f cmake -B build \u547d\u4ee4\u751f\u6210\u7684\u3002\u5176\u4e2d\u5b58\u50a8\u7740\u6784\u5efa\u9879\u76ee\u8fc7\u7a0b\u4e2d\u4ea7\u751f\u7684\u4e34\u65f6\u5bf9\u8c61\u6587\u4ef6\u548c\u6700\u7ec8\u7684\u4e8c\u8fdb\u5236\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u6240\u6709\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u653e\u5728 build/bin \u5b50\u6587\u4ef6\u5939\u4e2d\uff0c\u4f8b\u5982 build/bin/llvm-as\u3002\u5982\u679c CMake \u51fa\u73b0\u4e0d\u542c\u4f7f\u5524\u7684\u95ee\u9898\uff0c\u53ef\u4ee5\u5220\u9664 build \u6587\u4ef6\u5939\u8bd5\u8bd5\uff0c\u8fd9\u4f1a\u8feb\u4f7f CMake \u91cd\u65b0\u751f\u6210\uff08\u5efa\u8bae\u6bcf\u6b21\u4fee\u6539\u8fc7 CMake \u9009\u9879\u540e\u90fd\u5220 build\uff09\u3002","title":"\u9879\u76ee\u76ee\u5f55\u7ed3\u6784"},{"location":"llvm_intro/#_5","text":"cd llvm-project bash build.sh build.sh \u811a\u672c\u7684\u5185\u5bb9\u7b49\u4ef7\u4e8e\uff1a cmake -Sllvm -Bbuild -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" -GNinja ninja -Cbuild \u4f60\u5728\u547d\u4ee4\u884c\u624b\u52a8\u8f93\u5165\u8fd9\u4e24\u6761\u547d\u4ee4\u4e5f\u662f\u7b49\u4ef7\u7684\uff0c build.sh \u53ea\u662f\u4e3a\u4e86\u65b9\u4fbf\u3002 \u6b64\u5904 -S llvm \u9009\u9879\u8868\u793a\u6307\u5b9a\u6e90\u7801\u8def\u5f84\u4e3a\u6839\u76ee\u5f55\u4e0b\u7684 llvm \u5b50\u9879\u76ee\u6587\u4ef6\u5939\uff0c\u548c cd llvm && cmake -B build \u7b49\u4ef7\uff0c\u4f46\u662f\u4e0d\u7528\u5207\u6362\u76ee\u5f55\u3002 -G Ninja \u8868\u793a\u4f7f\u7528 Ninja \u540e\u7aef\uff0c\u5982\u679c\u4f60\u6ca1\u6709 Ninja\uff0c\u53ef\u4ee5\u53bb\u6389\u8be5\u9009\u9879\uff0cCMake \u5c06\u4f1a\u91c7\u7528\u9ed8\u8ba4\u7684 Makefile \u540e\u7aef\uff08\u66f4\u6162\uff09\u3002 \u5982\u679c\u4f60\u662f Wendous \u53d7\u5bb3\u8005\uff0c\u8bf7\u81ea\u884c\u7528\u9f20\u6807\u70b9\u51fb\u5e8f\u5217\u5728 VS2022 \u4e2d\u6a21\u62df\u4ee5\u4e0a\u4ee3\u7801\u4e4b\u540c\u7b49\u6548\u679c\uff0c\u795d\u60a8\u8171\u9798\u6109\u5feb\uff01 -DLLVM_ENABLE_PROJECTS=\"clang;clang-tools-extra\" \u8868\u793a\u542f\u7528 clang \u548c clang-tools-extra \u4e24\u4e2a\u5b50\u9879\u76ee\u3002 \u8fd9\u662f\u56e0\u4e3a\u901a\u5e38\u7528\u7684\u524d\u7aef\u90fd\u662f C++\uff0c\u6240\u4ee5 LLVM \u5b98\u65b9\u5728 build.sh \u91cc\u5c31\u8fd9\u4e48\u5199\u4e86\u3002 \u5982\u679c\u4f60\u53e3\u5473\u6bd4\u8f83\u91cd\uff0c\u60f3\u7814\u7a76 Fortran \u524d\u7aef\uff0c\u4e5f\u53ef\u4ee5\u5b9a\u4e49\u8be5 CMake \u53d8\u91cf\u4e3a -DLLVM_ENABLE_PROJECTS=\"flang\" \u3002 build.sh \u540e\uff0c\u9700\u8981\u82b1\u8d39\u5927\u7ea6 10 \u5206\u949f\u65f6\u95f4\uff08\u53d6\u51b3\u4e8e\u4f60\u7684\u7535\u8111\u914d\u7f6e\uff09\uff0c\u8fd9\u6bb5\u65f6\u95f4\u4f60\u53ef\u4ee5\u5148\u770b\u4e0b\u9762\u7684\u57fa\u672c\u6982\u5ff5\u901f\u89c8\u3002\u7b49\u98ce\u6247\u505c\u4e86\u4ee5\u540e\uff0cLLVM \u548c Clang \u5c31\u6784\u5efa\u597d\u4e86\u3002","title":"\u5f00\u59cb\u6784\u5efa"},{"location":"llvm_intro/#_6","text":"ls build/bin","title":"\u8fd0\u884c\u8bd5\u8bd5"},{"location":"llvm_intro/#_7","text":"\u53ea\u662f\u8ba9\u4f60\u83b7\u5f97\u4e00\u4e2a\u5168\u5c40\u89c2\u5ff5\uff08overview\uff09\uff0c\u4e0d\u7528\u6df1\u7a76\u7ec6\u8282\uff0c\u4e4b\u540e\u4f1a\u518d\u8be6\u7ec6\u5c55\u5f00\u4ecb\u7ecd\u7684\u3002 \u5b66\u8fc7 C \u8bed\u8a00\u7684\u540c\u5b66\u90fd\u77e5\u9053\uff0c\u4e00\u4e2a C/C++ \u6e90\u7801\u6587\u4ef6\u5230\u8ba1\u7b97\u673a\u5b9e\u9645\u53ef\u6267\u884c\u7684 EXE \u6587\u4ef6\u4e4b\u95f4\uff0c\u4e3b\u8981\u6709\u4e24\u6b65\u64cd\u4f5c\uff1a\u7f16\u8bd1\uff08compile\uff09\u548c\u94fe\u63a5\uff08link\uff09\u3002 \u4e4b\u6240\u4ee5\u628a\u7f16\u8bd1\u548c\u94fe\u63a5\u5206\u5f00\uff0c\u662f\u56e0\u4e3a\u4e00\u4e2a\u9879\u76ee\u5e38\u5e38\u7531\u8bb8\u591a\u6e90\u7801\u6587\u4ef6\u7ec4\u6210\uff0c\u800c\u4e0d\u53ea\u662f\u5355\u4e2a\u6587\u4ef6\u3002\u7f16\u8bd1\u5668\u628a C++ \u6e90\u7801\u7f16\u8bd1\u6210\u4e2d\u95f4\u5bf9\u8c61\u6587\u4ef6\uff08.o \u6216 .obj \u683c\u5f0f\uff09\uff0c\u5982\u679c\u6709\u5f88\u591a .cpp \u6587\u4ef6\uff0c\u5c31\u4f1a\u5f97\u5230\u5f88\u591a .o \u6587\u4ef6\uff0c\u7136\u540e\u7531\u94fe\u63a5\u5668\u8d1f\u8d23\u7edf\u4e00\u94fe\u63a5\u6240\u6709 .o \u6587\u4ef6\uff0c\u5c31\u5f97\u5230\u4e86\u6700\u7ec8\u7684 .exe \u6216 .dll \u76ee\u6807\u6587\u4ef6\u3002 \u5206\u79bb\u591a .cpp \u6587\u4ef6\u7684\u597d\u5904\u662f\uff0c\u7f16\u8bd1\u901f\u5ea6\u66f4\u5feb\uff0c\u53ef\u4ee5\u5e76\u884c\u7f16\u8bd1\u3002\u800c\u4e14\u4fee\u6539\u4e86\u5176\u4e2d\u4e00\u4e2a .cpp \u6587\u4ef6\uff0c\u53ea\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u90a3\u4e2a .cpp \u5bf9\u5e94\u7684 .o \u6587\u4ef6\uff0c\u7136\u540e\u91cd\u65b0\u94fe\u63a5\u6700\u7ec8\u7684 .exe \u5373\u53ef\uff0c\u65e0\u9700\u518d\u91cd\u590d\u7f16\u8bd1\u5176\u4ed6 .cpp \u6587\u4ef6\u7684 .o \u6587\u4ef6\u4e86\u3002\u81ea\u52a8\u68c0\u6d4b\u54ea\u4e9b .cpp \u6587\u4ef6\u66f4\u65b0\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u7f16\u8bd1 .o \u6587\u4ef6\uff0c\u662f Makefile \u548c Ninja \u4e4b\u7c7b\u6784\u5efa\u7cfb\u7edf\u7684\u804c\u8d23\u3002 \u6211\u4eec\u73b0\u5728\u8981\u6765\u5b66\u4e60\u7684\u5c31\u662f\u5176\u4e2d\u7684\u7f16\u8bd1\u9636\u6bb5\uff0c\u8fd9\u4e5f\u662f\u5927\u90e8\u5206\u4eba\u60f3\u5173\u6ce8\u7684\u91cd\u70b9\u3002 \u5728\u8fd9\u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\uff0c\u53d1\u751f\u4e86\u5f88\u591a\u6709\u8da3\u7684\u4e8b\uff0c\u4f46\u5374\u88ab\u4f20\u7edf\u6559\u6750\u7684 C++ \u201c\u4e24\u6bb5\u5f0f\u201d\u7f16\u8bd1\u6a21\u578b\uff08\u7f16\u8bd1 -> \u94fe\u63a5\uff09\u4e00\u7b14\u5e26\u8fc7\u4e86\u3002 \u5c31\u62ff\u8fd9\u91cc\u9762\u7684\u201c\u7f16\u8bd1\u201d\u9636\u6bb5\u5c55\u5f00\u8bb2\u8bb2\uff0c\u7f16\u8bd1\u5668\u662f\u5982\u4f55\u5c06 .cpp \u6587\u4ef6\u8f6c\u6362\u4e3a\u5145\u65a5\u7740\u673a\u5668\u6307\u4ee4\u7801 .o \u6587\u4ef6\u7684\uff1f .o \u6587\u4ef6\u91cc\u51e0\u4e4e\u5168\u662f\u5b8c\u6210\u7684\u673a\u5668\u6307\u4ee4\u7801\uff0c\u9664\u4e86\u90e8\u5206 call \u5230\u5916\u90e8\u51fd\u6570\u7684\u4e00\u90e8\u5206\u6307\u4ee4\uff0c\u4f1a\u7559\u767d\u3002\u8fd9\u90e8\u5206\u7559\u767d\u4f1a\u7b49\u5230\u94fe\u63a5\u9636\u6bb5\u65f6\uff0c\u7531\u94fe\u63a5\u5668\u5728\u5176\u4ed6 .o \u6587\u4ef6\u4e2d\u627e\u5230\u76f8\u540c\u7684\u7b26\u53f7\u65f6\u66ff\u6362\u4e0a\u6b63\u786e\u7684\u5730\u5740\u548c\u504f\u79fb\u91cf\uff0c\u5f97\u5230\u5b8c\u6574\u7684\u53ef\u6267\u884c .exe \u6587\u4ef6\u3002 \u8fc7\u53bb\uff0c\u6211\u4eec\u628a\u7f16\u8bd1\u5668\u770b\u4f5c\u9ed1\u7bb1\uff0c\u8fdb\u53bb\u6e90\u7801\uff0c\u51fa\u6765\u673a\u5668\u7801\uff0c\u4e2d\u95f4\u6709\u54ea\u4e9b\u8fc7\u7a0b\uff1f\u53ea\u80fd\u8ba4\u4e3a\u662f\u9b54\u6cd5\u3002 \u73b0\u5728\uff0c\u6709\u4e86 LLVM \u548c Clang \u6e90\u7801\u5728\u624b\uff0c\u7ec8\u4e8e\u53ef\u4ee5\u4e00\u63a2\u7a76\u7adf\u4e86\u3002 \u5b9e\u9645\u4e0a\uff0c\u201c\u7f16\u8bd1\u201d\u8fd9\u4e00\u8fc7\u7a0b\uff0c\u8fd8\u53ef\u4ee5\u8fdb\u4e00\u6b65\u62c6\u5206\u6210\u4e09\u4e2a\u9636\u6bb5\u3002","title":"\u57fa\u672c\u6982\u5ff5\u901f\u89c8"},{"location":"llvm_intro/#_8","text":"\u7f16\u8bd1\u5668\uff08Compiler\uff09\u7684\u5de5\u4f5c\u6d41\u7a0b\u53ef\u4ee5\u5206\u4e3a\u4e09\u4e2a\u9636\u6bb5\uff1a \u524d\u7aef\uff08Front-end\uff09\uff1a\u8d1f\u8d23\u63a5\u6536\u6e90\u4ee3\u7801\uff0c\u89e3\u6790\u51fa\u62bd\u8c61\u8bed\u6cd5\u6811\uff08AST\uff09\uff0c\u5e76\u8fdb\u884c\u8bed\u6cd5\u548c\u8bed\u4e49\u5206\u6790\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\u3002 \u4e2d\u7aef\uff08Middle-end\uff09\uff1a\u8d1f\u8d23\u4f18\u5316\u4e2d\u95f4\u8868\u793a\u7801\u3002 \u540e\u7aef\uff08Back-end\uff09\uff1a\u8d1f\u8d23\u5c06\u4f18\u5316\u5b8c\u6bd5\u7684\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u7684\u524d\u4e2d\u540e\u7aef\u548c\u4e92\u8054\u7f51\u5f00\u53d1\u8005\u6240\u8bf4\u7684\u524d\u540e\u7aef\u65e0\u5173\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u662f\u524d\u7aef\u9ad8\u624b\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u96c7\u4f63\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\uff1a\u6211\u8ba8\u538c JS\uff01\u4e92\u8054\u7f51\u5927\u5382\uff1a\u4f60\u4e0d\u662f\u524d\u7aef\u9ad8\u624b\u5417\uff1f\u5c0f\u5f6d\u8001\u5e08\uff1a\u7f16\u8bd1\u5668\u524d\u7aef\u3002 \u5982\u679c\u4f60\u60f3\u8981\u7814\u7a76 C++ \u8bed\u6cd5\u89c4\u5219\uff0c\u6bd4\u5982\u505a\u4e2a C++ \u8bed\u6cd5\u9ad8\u4eae\u63d2\u4ef6\uff0c\u90a3\u5c31\u9700\u8981\u770b\u524d\u7aef\u3002libclang \u548c clangd \u53ef\u4ee5\u5e2e\u52a9\u4f60\u89e3\u6790 C++ \u7e41\u7410\u7684\u8bed\u6cd5\uff0c\u5e76\u4ee5 AST \u6811\u7684\u7ed3\u6784\u63d0\u4f9b\u7ed9\u4f60\u3002\u4e0d\u4ec5\u5982\u6b64\uff0c\u5982\u679c\u4f60\u8981\u8bbe\u8ba1\u4e00\u95e8\u65b0\u8bed\u8a00\uff0c\u751a\u81f3\u662f OpenGL \u9a71\u52a8\uff08\u5176\u9700\u8981\u5b9e\u73b0 GLSL \u7f16\u8bd1\u5668\uff09\uff0c\u5b9e\u9645\u4e0a\u4e5f\u5c31\u662f\u4e3a LLVM \u6dfb\u52a0\u4e00\u4e2a\u524d\u7aef\u3002 \u5982\u679c\u4f60\u5bf9\u5185\u5b58\u6a21\u578b\uff0c\u6027\u80fd\u4f18\u5316\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u7814\u7a76\u4e2d\u7aef\u3002\u8fd9\u662f\u76ee\u524d\u5b66\u672f\u7814\u7a76\u6bd4\u8f83\u6d3b\u8dc3\u7684\u9886\u57df\uff0c\u7279\u522b\u662f\u591a\u9762\u4f53\u4f18\u5316\u65b9\u5411\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u6c34\u4e24\u5f20 paper \u6216 PR\u3002\u8fd9\u90e8\u5206\u90fd\u662f\u57fa\u4e8e LLVM IR \u64cd\u4f5c\u7684\uff0c\u6709\u7279\u522b\u591a\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\u3002 \u5982\u679c\u4f60\u5bf9\u6c47\u7f16\u8bed\u8a00\uff0c\u673a\u5668\u6307\u4ee4\uff0c\u786c\u4ef6\u67b6\u6784\u611f\u5174\u8da3\uff0c\u90a3\u5c31\u53bb\u770b\u540e\u7aef\u3002\u8fd9\u91cc\u9762\u6709\u628a\u4e2d\u95f4\u8868\u793a\u7801\u7ffb\u8bd1\u6210\u771f\u6b63\u53ef\u6267\u884c\u7684\u6c47\u7f16\u6307\u4ee4\u7684\u5b8c\u6574\u8fc7\u7a0b\uff0c\u81ea\u7814\u82af\u7247\u7684\u5927\u5382\u901a\u5e38\u60f3\u8981\u4e3a LLVM \u6dfb\u52a0\u540e\u7aef\u3002 \u6ce8\u610f\u94fe\u63a5\u9636\u6bb5\uff08Link\uff09\u5c5e\u4e8e\u94fe\u63a5\u5668\u7684\u804c\u8d23\uff0c\u4e0d\u5c5e\u4e8e\u72ed\u4e49\u4e0a\u7684\u7f16\u8bd1\u5668\uff1b\u524d\u4e2d\u540e\u7aef\u53ea\u662f\u5bf9\u7f16\u8bd1\uff08Compile\uff09\u8fd9\u4e00\u9636\u6bb5\u7684\u8fdb\u4e00\u6b65\u62c6\u5206\u3002 \u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u8d70\u8fdb LLVM \u8fd9\u5ea7\u5f00\u6e90\u5de5\u5382\uff0c\u4e00\u6b65\u6b65\u89c2\u5bdf\u4e00\u6bb5 C++ \u4ee3\u7801\u88ab\u7f16\u8bd1\u6210\u6c47\u7f16\u7684\u5168\u8fc7\u7a0b\u3002","title":"\u7f16\u8bd1\u5668\u7684\u524d\u3001\u4e2d\u3001\u540e\u7aef"},{"location":"llvm_intro/#ast","text":"\u7f16\u8bd1\u5668\u7684\u524d\u7aef\u8d1f\u8d23\u89e3\u6790 C++ \u8fd9\u7c7b\u9ad8\u7ea7\u8bed\u8a00\u7684\u6e90\u4ee3\u7801\uff0c\u751f\u6210\u62bd\u8c61\u8bed\u6cd5\u6811\uff08Abstract Syntax Tree\uff0cAST\uff09\u3002AST \u662f\u6e90\u4ee3\u7801\u7684\u4e00\u79cd\u62bd\u8c61\u8868\u793a\uff0c\u5176\u4e2d\u6bcf\u4e2a\u8282\u70b9\u4ee3\u8868\u6e90\u4ee3\u7801\u4e2d\u7684\u4e00\u4e2a\u8bed\u6cd5\u7ed3\u6784\uff0c\u4f8b\u5982 if\u3001while\u3001for\u3001\u51fd\u6570\u8c03\u7528\u3001\u8fd0\u7b97\u7b26\u3001\u53d8\u91cf\u58f0\u660e\u7b49\u3002\u6bcf\u4e2a AST \u8282\u70b9\u90fd\u6709\u81ea\u5df1\u7684\u5c5e\u6027\uff0c\u4f8b\u5982\u7c7b\u578b\u3001\u4f5c\u7528\u57df\u3001\u4fee\u9970\u7b26\u7b49\u3002 \u4e0d\u540c\u7c7b\u578b\u7684 AST \u8282\u70b9\u6709\u4e0d\u540c\u7684\u7c7b\u578b\u540d\uff0c\u4f8b\u5982 IntegerLiterial \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6574\u6570\u7c7b\u578b\u7684\u5e38\u91cf\uff0c\u800c BinaryOperator \u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u4e8c\u5143\u8fd0\u7b97\u7b26\uff08\u53ef\u80fd\u662f\u52a0\u51cf\u4e58\u9664\u7b49\u4e8c\u5143\u8fd0\u7b97\uff09\u3002 AST \u8282\u70b9\u53ef\u4ee5\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5b50\u8282\u70b9\uff0c\u8bb8\u591a\u8282\u70b9\u5c31\u6784\u6210\u4e86\u4e00\u9897\u8bed\u6cd5\u6811\u3002\u6bcf\u4e2a .cpp \u6587\u4ef6\u90fd\u53ef\u4ee5\u89e3\u6790\u5f97\u5230\u4e00\u9897\u8bed\u6cd5\u6811\uff0c\u5728 C++ \u7684\u8bed\u6cd5\u4e2d\uff0c\u6bcf\u9897\u6811\u7684\u6839\u90e8\u603b\u662f\u4e00\u4e2a TranslationUnitDecl \u7c7b\u578b\u7684\u8282\u70b9\u3002\u8fd9\u662f\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\uff0c\u5176\u4e2d\u5305\u542b\u4e86\u4efb\u610f\u591a\u7684\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u7b49\uff0c\u4f5c\u4e3a TU \u7684\u5b50\u8282\u70b9\u5b58\u5728\u5176\u4e2d\u3002 \u5bf9\u6811\u505a\u4e86\u4e00\u4e9b\u8bed\u6cd5\u8bed\u4e49\u4e0a\u7684\u6b63\u786e\u6027\u68c0\u6d4b\u540e\uff0c\u5c31\u4f1a\u904d\u5386\u8fd9\u9897\u6811\uff0c\u4e3a\u6bcf\u4e2a\u8282\u70b9\u9010\u4e00\u751f\u6210\u5bf9\u5e94\u7684 LLVM IR\uff0c\u8f93\u5165\u5230\u4e2d\u540e\u7aef\u4f18\u5316\u5e76\u751f\u6210\u771f\u6b63\u7684\u6c47\u7f16\u3002 // Clang \u6e90\u7801\u4e2d\u7684 AST \u8282\u70b9\u7c7b\u578b\u5927\u81f4\u957f\u8fd9\u6837\uff08\u5df2\u7b80\u5316\uff09 struct ASTNode { std::string type; std::vector children; }; \u8fd9\u90e8\u5206\u7684\u5b9e\u73b0\u5728 clang \u5b50\u9879\u76ee\u4e2d\u3002 clang \u89e3\u6790\u6e90\u7801\u751f\u6210\u8bed\u6cd5\u6811\u7684\u6848\u4f8b\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u8fd0\u884c\u547d\u4ee4\uff1a clang -fsyntax-only -Xclang -ast-dump test.cpp -fsyntax-only \u610f\u5473\u7740\u53ea\u89e3\u6790\u8bed\u6cd5\uff0c\u4e0d\u8fdb\u884c\u7f16\u8bd1\u548c\u94fe\u63a5\uff08\u4e0d\u4f1a\u751f\u6210 a.out\uff09\uff1b -Xclang \u662f\u6307\u5411 Clang \u6838\u5fc3\u4f20\u9012\u4e00\u4e2a\u9009\u9879\uff0c\u4e5f\u5c31\u662f\u540e\u9762\u7d27\u6328\u7740\u7684 -ast-dump \uff1b -ast-dump \u662f Clang \u6838\u5fc3\u7684\u9009\u9879\uff0c\u8868\u793a\u8981\u6c42\u6253\u5370\u51fa\u8bed\u6cd5\u6811\u3002 \u8f93\u51fa\uff1a \u5df2\u7701\u7565 \u5934\u6587\u4ef6\u90e8\u5206\u7684\u5b50\u8282\u70b9\uff0c\u4ec5\u5c55\u793a\u4e86 main \u7684\u90e8\u5206\uff0c\u5426\u5219\u5c31\u592a\u957f\u4e86\u3002 \u6700\u6839\u90e8\u7684 TranslationUnitDecl \u8282\u70b9\uff0c\u662f\u6574\u4e2a\u5f53\u524d\u7ffb\u8bd1\u5355\u5143\uff08TU\uff09\u7684\u58f0\u660e\u3002 \u6240\u6709\u7684 C++ \u6e90\u7801\u89e3\u6790\u540e\u5f97\u5230\u7684\uff0c\u603b\u662f\u4ee5 TranslationUnitDecl \u4e3a\u6839\u8282\u70b9\u7684\u4e00\u9897\u8bed\u6cd5\u6811\u3002 \u7ffb\u8bd1\u5355\u5143 \u6307\u7684\u5c31\u662f\u5355\u4e2a .cpp \u6587\u4ef6\uff0c\u53ca\u5176\u5bfc\u5165\u7684\u6240\u6709 .h \u5934\u6587\u4ef6\u62fc\u63a5\u5f62\u6210\u7684\u6574\u6bb5 C++ \u6e90\u7801\uff0c\u662f C++ \u7f16\u8bd1\u7684\u6700\u5c0f\u5355\u5143\u3002\u4e0d\u540c\u7ffb\u8bd1\u5355\u5143\u7f16\u8bd1\u6210\u5404\u81ea\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u540e\uff0c\u4e4b\u95f4\u518d\u901a\u8fc7\u201c\u94fe\u63a5\u5668\u201d\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e00\u4e2a\u6700\u7ec8\u7684\u76ee\u6807\u6587\u4ef6\uff08.exe \u6216 .dll\uff09\u3002 \u7ffb\u8bd1\u5355\u5143\u4e2d\u5305\u542b\u4e86\u6240\u6709\u5f53\u524d .cpp \u53ca\u5176\u5bfc\u5165\u7684\u5934\u6587\u4ef6\u4e2d\u53d8\u91cf\u3001\u51fd\u6570\u3001\u7c7b\u578b\u7684\u58f0\u660e\u548c\u5b9a\u4e49\u3002 \u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\u8282\u70b9\u6709\u7740\u8bb8\u591a\u5b50\u8282\u70b9\uff0c\u4e00\u5927\u5806\u90fd\u662f \u5934\u6587\u4ef6\u4e2d\u5bfc\u5165\u8fdb\u6765\u7684\u51fd\u6570\u58f0\u660e\u548c\u7c7b\u578b\u5b9a\u4e49\u3002 \u4e3a\u4e86\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u6211\u7279\u610f\u4ece\u622a\u56fe\u4e2d\u6263\u6389\u4e86\u6240\u6709\u6765\u81ea \u7684\u8282\u70b9\uff0c\u5e76\u4e0d\u662f\u8bf4\u7ffb\u8bd1\u5355\u5143\u4e0d\u5305\u62ec\u5934\u6587\u4ef6\u54e6\uff01 \u6211\u4eec\u6700\u5173\u5fc3\u7684\u662f\u5176\u4e2d\u4e00\u4e2a\u5b50\u8282\u70b9\uff1a\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u8282\u70b9\uff0c\u7c7b\u578b\u4e3a FunctionDecl\u3002 \u6b64\u5904 FunctionDecl \u5c31\u8868\u660e\uff0c\u8be5\u8282\u70b9\u662f\u4e00\u4e2a\u51fd\u6570\uff08Function\uff09\u7684\u58f0\u660e\uff08Decleration\uff09\u3002\u6ce8\u610f\u5230\u540e\u9762\u8ddf\u7740\u8bb8\u591a\u548c\u8be5\u51fd\u6570\u5b9a\u4e49\u6709\u5173\u7684\u5173\u952e\u4fe1\u606f\uff0c\u8ba9\u6211\u4eec\u9010\u4e00\u5206\u6790\uff1a \u8fd9\u91cc\u7684\u5341\u516d\u8fdb\u5236\u6570 0x567bdbf246d8 \u662f AST \u8282\u70b9\u5728\u7f16\u8bd1\u5668\u5185\u5b58\u4e2d\u7684\u5730\u5740\uff0c\u6bcf\u6b21\u90fd\u4e0d\u4e00\u6837\uff0c\u65e0\u610f\u4e49\u3002 \u540e\u9762\u7684\u5c16\u62ec\u53f7 \u91cc\u8fd8\u597d\u5fc3\u63d0\u9192\u4e86\u51fd\u6570\u5b9a\u4e49\u7684\u4f4d\u7f6e\u3002 \u6700\u540e\u662f\u51fd\u6570\u540d main \u548c\u51fd\u6570\u7c7b\u578b int () \uff0c\u8bf4\u660e\u8fd9\u662f\u4e3b\u51fd\u6570\u7684\u51fd\u6570\u58f0\u660e\u3002 \u6709\u8da3\u7684\u662f\uff0c\u8be5\u8282\u70b9\u7684\u7c7b\u578b\u662f FunctionDecl\uff0c\u7ffb\u8bd1\u6210\u4e2d\u6587\u5c31\u662f\u51fd\u6570\u58f0\u660e\u3002\u4f46\u662f\u6211\u4eec\u5199\u7684\u660e\u660e\u662f\u4e00\u4e2a\u51fd\u6570\u7684 \u5b9a\u4e49 \u554a\uff01\u4e3a\u4ec0\u4e48\u88ab Clang AST \u5f53\u4f5c\u4e86 \u58f0\u660e \u5462\uff1f\u539f\u6765\uff0cC++ \u5b98\u65b9\u7684\u8bdd\u8bed\u4e2d\uff0c\u5b9a\u4e49\u4e5f\u662f\u58f0\u660e\uff01\u4f46\u58f0\u660e\u4e0d\u90fd\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u8fd9\u91cc\u7684 FunctionDecl \u5b9e\u9645\u4e0a\u662f\u4e00\u4e2a\u901a\u7528\u7684\u8282\u70b9\uff0c\u65e2\u53ef\u4ee5\u662f\u58f0\u660e\uff08\u540e\u9762\u76f4\u63a5\u63a5 ; \u7684\uff09\uff0c\u4e5f\u53ef\u4ee5\u662f\u5b9a\u4e49\uff08\u540e\u9762\u63a5\u7740 {} \u7684\uff09\uff0c\u8981\u6839\u636e\u662f\u5426\u6709\u5b50\u8282\u70b9\uff08\u82b1\u62ec\u53f7\u8bed\u53e5\u5757\uff09\u6765\u5224\u65ad\u3002 \u603b\u4e4b\uff0c\u5b9a\u4e49\u548c\u58f0\u660e\u662f\u5b50\u96c6\u5173\u7cfb\u3002\u5f53\u6211\u4eec\u8981\u5f3a\u8c03\u4e00\u4e2a\u58f0\u660e\u53ea\u662f\u58f0\u660e\uff0c\u6ca1\u6709\u5b9a\u4e49\u65f6\uff0c\u4f1a\u7528 \u975e\u5b9a\u4e49\u58f0\u660e \u8fd9\u6837\u4e25\u8c28\u7684\u5f8b\u5e08\u8bf4\u6cd5\u3002\u4f46\u65e5\u5e38\u63d0\u95ee\u65f6\u4f60\u8bf4\u201c\u58f0\u660e\u201d\u6211\u4e5f\u660e\u767d\uff0c\u4f60\u6307\u7684\u5e94\u8be5\u662f\u975e\u5b9a\u4e49\u58f0\u660e\u3002\u66f4\u591a\u76f8\u5173\u6982\u5ff5\u8bf7\u770b \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49 \u7ae0\u8282\u548c \u767d\u5f8b\u5e08\u7684\u9510\u8bc4 \uff0c\u7528\u6587\u6c0f\u56fe\u6765\u753b\u5c31\u662f\uff1a \u51fd\u6570\u5b9a\u4e49\u8282\u70b9\u53c8\u5177\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f CompoundStmt\u3002\u8fd9\u4e2a\u5b9e\u9645\u4e0a\u5c31\u662f\u6211\u4eec\u6240\u8bf4\u7684\u82b1\u62ec\u53f7\u8bed\u53e5\u5757 {} \u4e86\u3002\u4ed6\u672c\u8eab\u4e5f\u662f\u4e00\u6761\u8bed\u53e5\uff0c\u4f46\u91cc\u9762\u7531\u5f88\u591a\u6761\u5b50\u8bed\u53e5\u7ec4\u6210\u3002\u89c4\u5b9a\u51fd\u6570\u58f0\u660e FunctionDecl \u5982\u679c\u662f\u5b9a\u4e49\uff0c\u5219\u5176\u552f\u4e00\u5b50\u8282\u70b9\u5fc5\u987b\u662f\u8bed\u53e5\u5757\u7c7b\u578b CompoundStmt\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u719f\u6089\u7684\u51fd\u6570\u58f0\u660e\u540e\u7d27\u63a5\u7740\u82b1\u62ec\u53f7\uff0c\u5c31\u80fd\u5b9a\u4e49\u51fd\u6570\u3002\u5982\u679c\u662f\u975e\u5b9a\u4e49\u58f0\u660e\uff08\u4ec5\u58f0\u660e\uff0c\u4e0d\u5b9a\u4e49\uff09\u90a3\u5c31\u6ca1\u6709\u8fd9\u4e2a\u5b50\u8282\u70b9\u3002 \u63a5\u4e0b\u6765\u53ef\u4ee5\u770b\u5230 CompountStmt \u5185\u90e8\uff0c\u53c8\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1aCallExpr \u548c ReturnStmt\uff0c\u5206\u522b\u662f\u6211\u4eec\u5bf9 printf \u51fd\u6570\u7684\u8c03\u7528\uff0c\u548c return 0 \u8fd9\u4e24\u6761\u5b50\u8bed\u53e5\u3002 ReturnStmt \u5f88\u597d\u7406\u89e3\uff0c\u4ed6\u53ea\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\uff0c\u7c7b\u578b\u662f IntegerLiterial\uff0c\u8868\u793a\u4e00\u4e2a\u6574\u5f62\u5e38\u6570\uff0c\u6574\u6570\u7684\u7c7b\u578b\u662f int\uff0c\u503c\u662f 0\u3002\u8fd9\u79cd\u6709\u4e00\u4e2a\u5b50\u8282\u70b9\u7684 ReturnStmt \u8282\u70b9\uff0c\u5c31\u8868\u793a\u4e00\u4e2a\u6709\u8fd4\u56de\u503c\u7684 return \u8bed\u53e5\uff0c\u6574\u4f53\u6765\u770b\u4e5f\u5c31\u662f\u6211\u4eec\u4ee3\u7801\u91cc\u5199\u7684 return 0 \u3002 \u4e3e\u4e00\u53cd\u4e09\uff0c\u53ef\u4ee5\u60f3\u8c61\uff1a\u5982\u679c\u4ee3\u7801\u91cc\u5199\u7684\u662f return x + 1 \uff0c\u90a3\u4e48 ReturnStmt \u7684\u5b50\u8282\u70b9\u5c31\u4f1a\u53d8\u6210\u8fd0\u7b97\u7b26\u4e3a + \u7684 BinaryOperator\u3002\u5176\u53c8\u5177\u6709\u4e24\u4e2a\u5b50\u8282\u70b9\uff1a\u5de6\u4fa7\u662f DeclRefExpr \u8282\u70b9\uff0c\u6807\u8bc6\u7b26\u4e3a x \uff1b\u53f3\u4fa7\u662f IntegerLiterial \u8282\u70b9\uff0c\u503c\u4e3a 1\u3002 \u7136\u540e\u6211\u4eec\u6765\u770b printf \u51fd\u6570\u8c03\u7528\u8fd9\u6761\u8bed\u53e5\uff1a \u53ef\u4ee5\u770b\u5230\u662f\u4e00\u4e2a CallExpr\uff0c\u8868\u793a\u8fd9\u662f\u51fd\u6570\u8c03\u7528\uff0c\u800c\u4e00\u4e2a\u51fd\u6570\u8c03\u7528\u9700\u8981\u77e5\u9053\u4e24\u4e2a\u4fe1\u606f\uff1a \u8c03\u7528\u54ea\u4e2a\u51fd\u6570\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f printf \u51fd\u6570\u3002 \u4f20\u9012\u7ed9\u51fd\u6570\u7684\u5b9e\u53c2\uff1f\u5728\u6211\u4eec\u7684\u4f8b\u5b50\u91cc\uff0c\u662f \"Hello, world!\" \u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u3002 \u8fd9\u5c31\u5206\u522b\u7528\u4e24\u4e2a\u5b50\u8282\u70b9\u8868\u793a\u4e86\u3002 \u6ce8\u610f\u5230\u8fd9\u91cc printf \u53d1\u751f\u4e86\u4e00\u4e2a\u9690\u5f0f\u8f6c\u6362 ImplicitCastExpr \u540e\u624d\u4f5c\u4e3a CallExpr \u7684\u7b2c\u4e00\u4e2a\u5b50\u8282\u70b9\uff08\u56de\u7b54\u4e86\u8c03\u7528\u54ea\u4e2a\u51fd\u6570\u7684\u95ee\u9898\uff09\uff0c\u5e76\u4e14\u540e\u9762\u6ce8\u91ca\u4e86\u8bf4 FunctionToPointerDecay \u3002\u4e5f\u5c31\u662f\u8bf4\uff0c printf \u8fd9\u4e2a\u6807\u8bc6\u7b26\uff08DeclRefExpr\uff09\u672c\u6765\u662f\u4e00\u4e2a\u5bf9\u51fd\u6570\u6807\u8bc6\u7b26\u7684\u5f15\u7528\uff0c\u8fd8\u6ca1\u6709\u53d8\u6210\u51fd\u6570\u6307\u9488\uff0c\u8fd9\u65f6\u5019\u8fd8\u6ca1\u6709\u5b8c\u6210\u51fd\u6570\u7684\u91cd\u8f7d\u51b3\u8bae\u3002\u662f\u7b49\u5230\u51fd\u6570\u88ab () \u8c03\u7528\u65f6\uff0c\u624d\u4f1a\u89e6\u53d1\u91cd\u8f7d\u51b3\u8bae\uff0c\u800c\u5b9e\u73b0\u533a\u5206\u91cd\u8f7d\u7684\u65b9\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u51fd\u6570\u5f15\u7528\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u6210\u51fd\u6570\u6307\u9488\u7684\u8fc7\u7a0b\u6240\u89e6\u53d1\u7684\uff0c\u4e5f\u5c31\u662f\u8fd9\u91cc\u7684 ImplicitCastExpr \u9690\u5f0f\u8f6c\u6362\u8282\u70b9\u4e86\u3002\u8fd9\u79cd\u81ea\u52a8\u53d1\u751f\u7684\u9690\u5f0f\u8f6c\u6362\u88ab\u79f0\u4e3a\u201c\u9000\u5316\u201d\uff08decay\uff09\u3002\u6240\u4ee5\uff0c\u51fd\u6570\u5f15\u7528\u65e0\u6cd5\u76f4\u63a5\u8c03\u7528\uff0cClang \u91cc\u4e00\u76f4\u90fd\u662f\u9700\u8981\u9000\u5316\u6210\u6307\u9488\u624d\u8c03\u7528\u7684\u3002 \u7136\u540e\uff0c\u8fd9\u91cc\u7684\u51fd\u6570\u53c2\u6570\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6309\u7406\u8bf4\u4e00\u4e2a StringLiterial \u8282\u70b9\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u6709\u4e2a ImplicitCastExpr\uff1f\u8fd9\u91cc\u6709\u4e2a\u5e38\u89c1\u8bef\u533a\u9700\u8981\u7ea0\u6b63\uff1a\u5f88\u591a\u540c\u5b66\u5e38\u5e38\u60f3\u5f53\u7136\u4ee5\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char * \u3002\u5b9e\u9645\u4e0a\uff0c\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\u662f const char [] \uff0c\u662f\u4e00\u4e2a\u6570\u7ec4\u7c7b\u578b\uff01\u6570\u7ec4\u4e0d\u662f\u6307\u9488\uff0c\u4ed6\u4eec\u662f\u4e24\u4e2a\u5b8c\u5168\u4e0d\u540c\u7684\u7c7b\u578b\u3002\u4e4b\u6240\u4ee5\u4f60\u4f1a\u6709\u6570\u7ec4\u662f\u6307\u9488\u7684\u9519\u89c9\uff0c\u662f\u56e0\u4e3a\u6570\u7ec4\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a\u5143\u7d20\u7c7b\u578b\u7684\u6307\u9488\u3002\u800c\u8fd9\u662f\u201c\u9000\u5316\u201d\u89c4\u5219\u4e4b\u4e00\uff0c\u8fd9\u4e2a\u8fc7\u7a0b\u5728\u51fd\u6570\u53c2\u6570\u3001auto \u63a8\u5bfc\u7684\u65f6\u5019\u662f\u81ea\u52a8\u53d1\u751f\u7684\uff08\u6b63\u5982\u4e0a\u9762\u8bf4\u7684\u51fd\u6570\u5f15\u7528\u4f1a\u5728\u8c03\u7528\u65f6\u81ea\u52a8\u201c\u9000\u5316\u201d\u6210\u51fd\u6570\u6307\u9488\u4e00\u6837\uff09\u3002 \u6570\u7ec4\u80fd\u81ea\u52a8\u9000\u5316\u6210\u6307\u9488\uff0c\u4e0d\u4ee3\u8868\u6570\u7ec4\u5c31\u662f\u6307\u9488\u3002\u4f8b\u5982 int \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a double\uff0c\u96be\u9053\u5c31\u53ef\u4ee5\u8bf4\u201cint \u5c31\u662f double\u201d\u5417\uff1f\u540c\u6837\u5730\uff0c\u4e0d\u80fd\u8bf4\u201c\u6570\u7ec4\u5c31\u662f\u6307\u9488\u201d\u3002\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7c7b\u578b\uff0c\u4ece\u6765\u90fd\u662f const char [N] \uff0c\u5176\u4e2d N \u662f\u5b57\u7b26\u4e32\u4e2d\u5b57\u7b26\u7684\u4e2a\u6570\uff08\u5305\u62ec\u672b\u5c3e\u81ea\u52a8\u52a0\u4e0a\u7684 '\\0' \u7ed3\u675f\u7b26\uff09\u3002\u53ea\u4e0d\u8fc7\u662f\u5728\u4f20\u5165\u51fd\u6570\u53c2\u6570\uff08\u6b64\u5904\u662f printf \u51fd\u6570\u7684\u5b57\u7b26\u4e32\u53c2\u6570\uff09\u65f6\uff0c\u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u4e3a const char * \u4e86\u800c\u5df2\u3002\u6b63\u5982\u8fd9\u4e2a ImplicitCastExpr \u540e\u9762\u5c16\u62ec\u53f7\u7684\u63d0\u793a\u4e2d\u6240\u8bf4\uff0cArrayToPointerDecay\uff0c\u662f\u6570\u7ec4\u7c7b\u578b\u5230\u6307\u9488\u7c7b\u578b\u7684\u81ea\u52a8\u9000\u5316\uff0c\u4ece const char [14] \u81ea\u52a8\u9690\u5f0f\u8f6c\u6362\u5230\u4e86 const char * \u3002 #include int main() { printf(\"Hello, world!\"); // \u7b49\u4ef7\u4e8e static_cast(printf) ( static_cast(\"Hello, world!\") ); return 0; } \u603b\u4e4b\uff0c\u901a\u8fc7\u89c2\u5bdf Clang AST \u6811\uff0c\u53ef\u4ee5\u83b7\u5f97\u5f88\u591a\u9690\u85cf\u7684\u4fe1\u606f\uff0c\u7279\u522b\u662f C++ \u7684\u5404\u79cd\u9690\u85cf\u8bed\u6cd5\u89c4\u5219\uff0c\u53ef\u4ee5\u5e2e\u4f60\u89e3\u6784\u8bed\u6cd5\u7cd6\u3002 Clang \u89e3\u6790\u51fa AST \u6811\u540e\uff0c\u4f1a\u518d\u6b21\u904d\u5386\u8be5\u6811\uff0c\u751f\u6210\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09\uff0c\u8f93\u5165 LLVM \u540e\u7aef\u7f16\u8bd1\uff0c\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff08 -S \uff09\u6216\u4e8c\u8fdb\u5236\u6307\u4ee4\u7801\uff08 -c \uff09\u3002 \u5982\u679c\u6307\u5b9a\u4e86 -emit-llvm \u9009\u9879\uff0c\u5219\u4e0d\u4f1a\u8f93\u5165 LLVM \u540e\u7aef\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u6307\u4ee4\u7801\uff0c\u800c\u662f\u76f4\u63a5\u628a\u4ea7\u751f\u7684 IR \u4ee5 IR \u6c47\u7f16\uff08 -S -emit-llvm \uff09\u6216 IR \u5b57\u8282\u7801\uff08 -c -emit-llvm \uff09\u7684\u683c\u5f0f\u5bfc\u51fa\uff0c\u65b9\u4fbf\u6211\u4eec\u5206\u6790\u548c\u67e5\u770b\u3002","title":"\u8bed\u6cd5\u6811\uff08AST\uff09"},{"location":"llvm_intro/#ir","text":"\u4e2d\u95f4\u8868\u793a\u7801\u662f\u4e00\u79cd\u62bd\u8c61\u7684\u673a\u5668\u6307\u4ee4\uff0c\u5b83\u4e0d\u9488\u5bf9\u5177\u4f53\u7684\u786c\u4ef6\uff0c\u800c\u662f\u4e00\u79cd\u901a\u7528\u7684\u6307\u4ee4\u96c6\u3002\u5b83\u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u8fbe\uff0c\u53ef\u4ee5\u88ab\u8fdb\u4e00\u6b65\u7f16\u8bd1\u4e3a\u76ee\u6807\u4ee3\u7801\u3002 LLVM IR\uff08Intermediate Representation\uff09\u662f\u4e00\u79cd\u4e2d\u95f4\u8bed\u8a00\u8868\u793a\uff0c\u4f5c\u4e3a\u7f16\u8bd1\u5668\u524d\u7aef\u548c\u540e\u7aef\u7684\u5206\u6c34\u5cad\u3002LLVM \u7f16\u8bd1\u5668\u7684\u524d\u7aef\u2014\u2014Clang \u8d1f\u8d23\u4ea7\u751f IR\uff0c\u800c\u5176 LLVM \u540e\u7aef\u8d1f\u8d23\u6d88\u8d39 IR\u3002 C++ \u6e90\u7801 -> IR -> \u76ee\u6807\u5e73\u53f0\u6c47\u7f16 IR \u4ecb\u4e8e\u9ad8\u7ea7\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u4e4b\u95f4\uff0c\u53d1\u660e IR \u662f\u4e3a\u4e86\u7edf\u4e00\u6765\u81ea\u4e0d\u540c\u6e90\u7801\u8bed\u8a00\uff0c\u53bb\u5f80\u4e0d\u540c\u76ee\u6807\u786c\u4ef6\u7684\u4e00\u5c42\u62bd\u8c61\u5c42\u3002\u4e00\u662f\u4fbf\u4e8e\u524d\u7aef\u7684\u7edf\u4e00\u5b9e\u73b0\uff0cClang \u8fd9\u6837\u7684\u524d\u7aef\u53ea\u9700\u8981\u751f\u6210\u62bd\u8c61\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u63a7\u5236\u6d41\u8fd9\u4e9b IR \u9884\u5148\u5b9a\u4e49\u597d\u7684\u6307\u4ee4\u5c31\u53ef\u4ee5\u4e86\uff0c\u4e0d\u7528\u53bb\u4e13\u95e8\u4e3a\u6bcf\u4e2a\u786c\u4ef6\u8bbe\u8ba1\u4e00\u5957\u751f\u6210\u6c47\u7f16\u7684\u5f15\u64ce\uff1b\u4e8c\u662f LLVM IR \u91c7\u7528\u4e86\u5bf9\u4f18\u5316\u66f4\u53cb\u597d\u7684 SSA \u683c\u5f0f\uff08\u7a0d\u540e\u4ecb\u7ecd\uff09\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684\u5bc4\u5b58\u5668\u683c\u5f0f\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u7b49\u9001\u5230\u540e\u7aef\u7684\u672b\u5c3e\u65f6\u624d\u4f1a\u5f00\u59cb\u5c06 IR \u7ffb\u8bd1\u4e3a\u6c47\u7f16\u4ee3\u7801\uff0c\u6700\u7ec8\u53d8\u6210\u53ef\u6267\u884c\u7684\u673a\u5668\u7801\u3002 IR \u5e76\u4e0d\u662f LLVM \u7684\u4e13\u5229\uff0c\u6240\u6709\u8de8\u5e73\u53f0\u7f16\u8bd1\u5668\u90fd\u4f7f\u7528 IR\uff0c\u5305\u62ec GCC \u548c MSVC\u3002\u4e5f\u6709\u5f88\u591a\u72ec\u7acb\u4e8e\u7f16\u8bd1\u5668\u7684\u8de8\u5e73\u53f0 IR \u89c4\u8303\uff0c\u4f8b\u5982 SPIR-V\u3001MLIR\u3001MIR\uff0cLLVM IR \u53ea\u662f\u4f17\u591a IR \u4e2d\u7684\u4e00\u79cd\uff0c\u4e13\u7528\u4e8e LLVM \u7f16\u8bd1\u5668\u5168\u5bb6\u6876\u3002\u7531\u4e8e\u672c\u8bfe\u7a0b\u662f LLVM \u8bfe\u7a0b\uff0c\u4ee5\u540e\u63d0\u5230 IR\uff0c\u8bfb\u8005\u5e94\u9ed8\u8ba4\u6307\u7684\u662f LLVM IR\u3002 LLVM IR \u6709\u591a\u79cd\u8868\u73b0\u5f62\u5f0f\uff1a \u5185\u5b58\u4e2d\u7684 IR \u8282\u70b9\u5bf9\u8c61\uff0c\u4f4d\u4e8e clang \u548c libLLVM.so \u8fdb\u7a0b\u7684\u5185\u5b58\u4e2d\uff0c\u90fd\u662f\u4e00\u4e2a\u4e2a C++ \u7c7b\uff0c\u901a\u8fc7\u6307\u9488\u4e92\u76f8\u8fde\u63a5\u3002LLVM \u4f5c\u4e3a\u4e00\u4e2a C++ \u7a0b\u5e8f\uff0c\u5904\u7406 IR \u65f6\u90fd\u662f\u8981\u8bfb\u5230\u5185\u5b58\u4e2d\u5904\u7406\u7684\u3002\u4f46\u7531\u4e8e\u5185\u5b58\u4e2d\u7684 IR \u5bf9\u8c61\u5b58\u5728\u865a\u8868\u6307\u9488\u4ee5\u53ca\u590d\u6742\u7684\u6811\u72b6\u6570\u636e\u7ed3\u6784\uff0c\u65e0\u6cd5\u76f4\u63a5\u5b58\u5165\u78c1\u76d8\uff0c\u4e5f\u65e0\u6cd5\u4f9b\u4eba\u7c7b\u9605\u8bfb\uff0c\u9700\u8981\u5e8f\u5217\u5316\u4e3a\u4ee5\u4e0b\u4e24\u79cd\u683c\u5f0f\u540e\u5b58\u50a8\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u6c47\u7f16\uff08Assembly\uff09\uff0c\u4ee5\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c\u5f62\u5f0f\uff08\u7eaf ASCII \u5b57\u7b26\uff09\u5b58\u50a8\u5728\u78c1\u76d8\u4e2d\uff0c\u65b9\u4fbf\u4eba\u7c7b\u89c2\u5bdf\u3001\u4fee\u6539\u548c\u8c03\u8bd5\u3002\u6211\u4eec\u540e\u9762\u7684\u8bfe\u7a0b\uff0c\u4e5f\u4f1a\u7ecf\u5e38\u89c2\u5bdf\u4e2d\u95f4\u4ea7\u7269\u7684 IR \u6c47\u7f16\uff0c\u5206\u6790 LLVM \u7684\u884c\u4e3a\u3002 \u78c1\u76d8\u4e2d\u7684 IR \u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u4ee5\u4e8c\u8fdb\u5236\u683c\u5f0f\u5b58\u50a8\u7684 IR\uff0c\u672c\u8d28\u4e0a\u548c IR \u6c47\u7f16\u76f8\u540c\uff0c\u53ea\u662f\u4ee5\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u5b57\u8282\u5b58\u50a8\u3002\u7f3a\u70b9\u662f\u4eba\u7c7b\u770b\u4e0d\u61c2\uff0c\u4f18\u70b9\u662f\u8282\u7ea6\u78c1\u76d8\u7a7a\u95f4\uff0c\u65b9\u4fbf\u7a0b\u5e8f\u5feb\u901f\u89e3\u6790\u3002 \u5f53\u9700\u8981\u957f\u671f\u50a8\u5b58 IR \u7684\u4e2d\u95f4\u7ed3\u679c\u65f6\u4f1a\u7528\u5230 IR \u5b57\u8282\u7801\uff0c\u5f53\u9700\u8981\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\u4e2d\u95f4\u7ed3\u679c\u65f6\u5c31\u9700\u8981 IR \u6c47\u7f16\u3002","title":"\u4e2d\u95f4\u8868\u793a\u7801\uff08IR\uff09"},{"location":"llvm_intro/#ir-x86","text":"\u6ce8\u610f IR \u6c47\u7f16\u5e76\u4e0d\u662f\u771f\u6b63\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u8bed\u8a00\uff08Assembly\uff09\uff0c\u4ed6\u53ea\u662f\u4e00\u79cd\u4e2d\u95f4\u4ea7\u7269\u3002 IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16\uff0c\u6b63\u5982 IR \u5b57\u8282\u7801\u4e0d\u662f x86 \u7684\u673a\u5668\u7801\u4e00\u6837\u3002IR \u7684\u4e1c\u897f\u90fd\u662f LLVM \u5f00\u53d1\u8005\u81ea\u62df\u7684\u4e00\u5957\u683c\u5f0f\uff0c\u548c\u786c\u4ef6\u65e0\u5173\uff0c\u548c\u64cd\u4f5c\u7cfb\u7edf\u4e5f\u65e0\u5173\u3002\u4e0d\u8bba\u76ee\u6807\u5e73\u53f0\u662f\u4ec0\u4e48\uff0c\u6765\u81ea\u4ec0\u4e48\u6e90\u7801\u8bed\u8a00\uff0cLLVM IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u683c\u5f0f\u90fd\u662f\u4e00\u6837\u7684\u3002 \u4f46\u4e0d\u540c\u5e73\u53f0\u7684 IR \u4f1a\u9644\u52a0\u4e0d\u540c\u7684 intrinsics \u6307\u4ee4\uff0c\u9664\u6b64\u4e4b\u5916\u7684\u90e8\u5206\u90fd\u662f\u5171\u901a\u7684\u3002\u7531\u4e8e\u5f88\u591a\u7a0b\u5e8f\u4f1a\u5229\u7528\u76ee\u6807\u786c\u4ef6\u505a\u5224\u65ad\uff08\u4f8b\u5982 #ifdef __x86_64__ \uff09\uff0c\u751f\u6210\u4e0d\u540c\u7684 intrinsics\uff0c\u56e0\u6b64 IR \u5e76\u4e0d\u662f\u5b8c\u5168\u8de8\u5e73\u53f0\u7684\u3002 IR \u7684\u76ee\u7684\u662f\u628a\u5927\u90e8\u5206\u901a\u7528\u7684\u8ba1\u7b97\uff0c\u4f8b\u5982\u52a0\u51cf\u4e58\u9664\u3001\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u7edf\u4e00\u6210\u76f8\u540c\u7684 IR \u6c47\u7f16\u3002\u800c\u4e0d\u662f x86 \u6c47\u7f16\u91cc\u53eb call \uff0cARM \u6c47\u7f16\u91cc\u53eb bl \u7684\u4e11\u6001\uff0c\u8fd9\u5c31\u591f\u4e86\u3002\u5bf9\u4e8e\u5229\u7528\u786c\u4ef6\u7279\u6709\u7684\u6307\u4ee4\uff08\u4f8b\u5982 SSE\u3001NEON \u6307\u4ee4\u96c6\uff09\u6765\u4f18\u5316\uff0c\u4ee5\u53ca\u5185\u8054\u6c47\u7f16\uff08 asm \u5173\u952e\u5b57\uff09\u7b49\uff0cLLVM IR \u4e5f\u662f\u652f\u6301\u7684\u3002 \u901a\u7528\u7684\u90a3\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201ccommon IR\u201d\uff0c\u4f8b\u5982 Function\u3001Instruction \u7b49\u3002\u8fd9\u90e8\u5206\u662f\u8de8\u5e73\u53f0\u7684\uff0c\u7edf\u4e00\u4e86\u5206\u5d29\u79bb\u6790\u7684\u5404\u5927\u786c\u4ef6\u6c47\u7f16\uff0c\u4fbf\u4e8e\u7edf\u4e00\u7f16\u5199\u4f18\u5316\u5f15\u64ce\u3002 \u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u90e8\u5206 IR \u8282\u70b9\uff0c\u88ab\u79f0\u4e3a\u201cspecific IR\u201d\uff0c\u4f8b\u5982 MachineFunction\u3001MachineInstr \u7b49\u3002\u8fd9\u90e8\u5206\u57fa\u672c\u662f\u7528\u4e8e\u6a21\u4eff\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\uff0c\u5c31\u662f\u8fd9\u90e8\u5206\u7684\u5b58\u5728\u5bfc\u81f4\u4e86 LLVM IR \u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 \u5728\u8fdb\u5165\u540e\u7aef\u7684\u201c\u6307\u4ee4\u9009\u62e9\u201d\u9636\u6bb5\u540e\uff0cIR \u8282\u70b9\u4e2d\u901a\u7528\u7684\u90a3\u90e8\u5206\u8282\u70b9\uff0c\u4f1a\u9010\u6b65\u88ab\u66ff\u6362\u4e3a\u548c\u786c\u4ef6\u7ed1\u5b9a\u7684\u76f8\u5e94 MachineInstr \u8282\u70b9\uff0c\u5728\u201c\u6307\u4ee4\u9009\u62e9\u201d\u540e\u7684\u9636\u6bb5\u770b\u6765\uff0c\u5c31\u597d\u50cf\u524d\u9762\u8f93\u51fa\u4e86\u4e00\u5927\u5806\u5185\u8054\u6c47\u7f16\u4e00\u6837\uff0c\u6700\u7ec8\uff0c\u9010\u6e10\u53d8\u6210\u4e86\u5b8c\u5168\u7684\u76ee\u6807\u5e73\u53f0\u6c47\u7f16\uff0c\u6700\u7ec8\u8f93\u51fa\u3002","title":"IR \u6c47\u7f16\u4e0d\u662f x86 \u6c47\u7f16"},{"location":"llvm_intro/#llvm-ir","text":"IR \u548c\u76ee\u6807\u5e73\u53f0\u7684\u6c47\u7f16\u76f8\u6bd4\uff0c\u4e0d\u4ec5\u4ec5\u662f\u7edf\u4e00\uff0c\u597d\u5904\u6709\u5f88\u591a\u3002","title":"LLVM IR \u7684\u7279\u70b9"},{"location":"llvm_intro/#_9","text":"\u6bcf\u4e2a C++ \u6587\u4ef6\u7f16\u8bd1\u5f97\u5230\u7684 IR \u6c47\u7f16\u5747\u7531\u4e00\u7cfb\u5217\u51fd\u6570\u5b9a\u4e49\uff08\u548c\u5c11\u91cf\u7279\u6b8a\u6307\u4ee4\uff0c\u6bd4\u5982 target triple \uff09\u7ec4\u6210\uff0c\u6240\u6709\u7684 IR \u6307\u4ee4\u90fd\u5305\u5728\u51fd\u6570\u4e2d\u3002 \u51fd\u6570\u662f LLVM \u4f18\u5316\u7684\u57fa\u672c\u5355\u4f4d\uff0c\u7edd\u5927\u591a\u6570 LLVM pass\uff0c\u90fd\u662f\u4ee5\u5355\u4e2a\u51fd\u6570\u4e3a\u5355\u4f4d\u6765\u4f18\u5316\u7684\u3002\u53ea\u6709\u5185\u8054\u4f18\u5316\u548c IPO \u4f18\u5316\uff0c\u53ef\u4ee5\u5b9e\u73b0\u8de8\u51fd\u6570\u7684\u4f18\u5316\u3002 \u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u5185\u8054\u4f18\u5316\u4e0d\u4ec5\u4ec5\u662f\u201c\u51fd\u6570\u539f\u5c01\u4e0d\u52a8\u63d2\u5165\u8c03\u7528\u4f4d\u7f6e\u201d\u3002\u628a\u51fd\u6570\u63d2\u5165\u8c03\u7528\u8005\u4f53\u5185\u540e\uff0c\u4e24\u4e2a\u51fd\u6570\u878d\u5408\u4e3a\u4e00\u4e2a\u51fd\u6570\u4e86\uff0c\u4f7f\u4f18\u5316\u5668\u7684\u201c\u89c6\u91ce\u201d\u66f4\u5927\uff08\u56e0\u4e3a\u5927\u90e8\u5206\u4f18\u5316\u4e0d\u80fd\u8de8\u8d8a\u51fd\u6570\u8fb9\u754c\uff09\uff01\u4ece\u800c\u5e2e\u52a9\u4e86\u5176\u4ed6\u4ee5\u51fd\u6570\u4e3a\u8fb9\u754c\u7684\u4f18\u5316 pass \u80fd\u591f\u66f4\u597d\u7684\u4f18\u5316\u3002\u4f8b\u5982\u5728 main \u4e2d\u4ee5\u8fed\u4ee3\u5668\u904d\u5386\u4e00\u4e2a\u5bb9\u5668\uff1a\u672c\u6765 main \u51fd\u6570\u662f\u8c03\u7528\u8fed\u4ee3\u5668\u7684 operator++ \uff0c\u800c operator++ \u4e0d\u5185\u8054\u6389\u7684\u8bdd\uff0c main \u7684\u4f18\u5316\u5668\u6c38\u8fdc\u65e0\u6cd5\u610f\u8bc6\u5230 operator++ \u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u6307\u9488\u7684\u52a0\u6cd5\uff0c\u53ea\u80fd\u8001\u8001\u5b9e\u5b9e\u5206\u914d alloca \u7136\u540e\u83b7\u53d6\u51fa this \u6307\u9488\u4f20\u5165 operator++ \u51fd\u6570\u3002\u800c\u5185\u8054\u4ee5\u540e\uff0c operator++ \u7684\u5185\u5bb9\u66b4\u9732\u5728\u4f18\u5316 pass \u773c\u524d\uff0c\u4ed6\u5c31\u77e5\u9053\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u4f18\u5316\u6210\u4e00\u4e2a\u9759\u6001\u5bc4\u5b58\u5668\u4e86\uff0c\u6839\u672c\u4e0d\u7528\u4e3a\u5176\u5206\u914d\u5185\u5b58\uff01\u6700\u7ec8\u4ea7\u751f\u7684\u6c47\u7f16\u4e00\u4e0b\u5b50\u4ece\u5fc5\u987b\u5206\u914d\u5728\u6808\u5185\u5b58\u4e0a\uff0c\u5230\u53ef\u4ee5\u628a\u8fed\u4ee3\u5668\u6307\u9488\u653e\u5728\u5bc4\u5b58\u5668\u91cc\u4e86\u3002\u800c IPO (Inter-procedure Optimization) \u5219\u662f\u6839\u636e\u51fd\u6570\u53c2\u6570\u4e3a\u5e38\u6570\u7684\u60c5\u51b5\u505a\u5206\u53d1\uff0c\u5206\u53d1\u540e\u53ef\u4ee5\u9488\u5bf9\u4e0d\u540c\u5e38\u6570\u53c2\u6570\u7684\u7ed3\u679c\u505a\u7279\u5b9a\u4f18\u5316\uff0c\u4f46\u4e0d\u5408\u5e76\u51fd\u6570\uff0c\u65e0\u6cd5\u8d4b\u80fd\u5176\u4ed6\u4f18\u5316 pass\uff0c\u6548\u679c\u770b\u8d77\u6765\u5c31\u6ca1\u6709\u5185\u8054\u5f3a\u4e86\u3002\u4f46\u662f\u8981\u6ce8\u610f\u5f88\u591a\u4f18\u5316 pass \u7684\u5f00\u9500\u662f\u548c\u51fd\u6570\u7684\u5927\u5c0f\uff08IR \u6307\u4ee4\u6570\u91cf\uff09\u6210\u6b63\u6bd4\u7684\uff0c\u6240\u4ee5\u5185\u8054\u592a\u591a\u5c42\u5bfc\u81f4\u4e00\u4e2a\u51fd\u6570\u5f88\u5927\u7684\u8bdd\uff0c\u7f16\u8bd1\u4f1a\u53d8\u5f97\u6bd4\u8f83\u6162\u3002","title":"\u4ee5\u51fd\u6570\u4e3a\u5355\u4f4d"},{"location":"llvm_intro/#_10","text":"\u5bc4\u5b58\u5668\u65e0\u9650\u91cf\u4f9b\u5e94\uff01\u4e00\u4e2a\u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u5b9a\u4e49\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668\uff0c\u65e0\u9700\u8003\u8651\u786c\u4ef6\u5177\u4f53\u63d0\u4f9b\u4e86\u591a\u5c11\u4e2a\u5bc4\u5b58\u5668\u3002\u56e0\u4e3a\u548c\u786c\u4ef6\u5bc4\u5b58\u5668\u8131\u94a9\uff0c\u6240\u4ee5\u6211\u4eec\u53ef\u4ee5\u79f0\u4e4b\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u53ea\u5728 LLVM \u4e2d\u7aef\u91cc\u51fa\u73b0\uff0c\u4e3a\u4e86\u4fbf\u4e8e\u4f18\u5316\u548c\u5904\u7406\u91c7\u53d6\u7684\u7b80\u5316\u7b56\u7565\u3002 \u865a\u62df\u5bc4\u5b58\u5668\u7edf\u4e00\u4ee5 %0 %1 %2 \u547d\u540d\u3002\u5982\u679c\u6253\u7b97\u624b\u5199 IR\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5b9a\u4e49\u540d\u5b57\u5982 %x %i \uff0c\u4e0d\u8fc7 Clang \u81ea\u52a8\u751f\u6210\u7684 IR \u4e2d\u5bc4\u5b58\u5668\u90fd\u662f\u4ece 0 \u5f00\u59cb\uff0c\u81ea\u52a8\u9012\u589e\u7684\u547d\u540d\u3002 \u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u4f1a\u628a\u8fd9\u4e9b\u5bc4\u5b58\u5668\u6620\u5c04\u5230\u76f8\u5e94\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u4e0d\u7528\u62c5\u5fc3\uff01\u5982\u679c\u540e\u7aef\u53d1\u73b0 IR \u4e2d\u7684\u5bc4\u5b58\u5668\u7528\u91cf\u8d85\u51fa\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u5bc4\u5b58\u5668\u6570\u91cf\u4e0a\u9650\uff0c\u90a3\u4e48\u4f1a\u9009\u62e9\u4e00\u90e8\u5206\u201c\u6253\u7ffb\u201d\uff08spill\uff09\u5230\u5185\u5b58\u4e2d\u53bb\u3002 \u800c\u4e14\u5982\u679c\u53d1\u73b0\u5bc4\u5b58\u5668\u53ef\u4ee5\u590d\u7528\uff0c\u4e5f\u4f1a\u590d\u7528\u4e4b\u524d\u5df2\u7ecf\u6ca1\u7528\u5230\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982\u4ee5\u4e0b IR \u4e2d\uff0c\u770b\u4f3c\u7528\u5230\u4e86\u4e94\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u5b9e\u9645\u53ea\u9700\u8981\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u53ef\u4ee5\u4e86\uff0c\u56e0\u4e3a %1 \u5728\u88ab %2 \u7684 add \u6307\u4ee4\u7528\u5b8c\u4ee5\u540e\uff0c\u5c31\u6ca1\u4eba\u518d\u4f7f\u7528\u4e86\u3002\u8fd9\u65f6\u5c31\u7a7a\u51fa\u4e86\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u8d44\u6e90\uff0c\u540e\u6765\u65b0\u7684\u5bc4\u5b58\u5668\u53ef\u4ee5\u4ece\u8fd9\u91cc\u9876\u66ff\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, 1 \u5728 LLVM \u4e2d\uff0c\u662f\u5229\u7528\u7ebf\u6027\u626b\u63cf\u6cd5\uff08\u7535\u68af\u7b97\u6cd5\uff09\u6765\u786e\u5b9a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff08\u4ece\u7b2c\u4e00\u6b21\u521b\u5efa\uff0c\u5230\u6700\u540e\u4e00\u6b21\u4f7f\u7528\u4e4b\u95f4\u7684\u65f6\u95f4\u6bb5\uff09\uff0c\u5bf9\u4e8e\u751f\u547d\u5468\u671f\u6709\u91cd\u53e0\u7684\u591a\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u624d\u9700\u8981\u4e3a\u4ed6\u4eec\u5206\u914d\u72ec\u7acb\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\uff0c\u5982\u679c\u751f\u547d\u5468\u671f\u6ca1\u6709\u4ea4\u96c6\uff0c\u90a3\u4e48\u53ef\u4ee5\u8ba9\u65b0\u6765\u7684\u865a\u62df\u5bc4\u5b58\u5668\u590d\u7528\u8001\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u53ea\u9700\u8981\u7528\u5230\u4e00\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u5c31\u591f\u4e86\uff1a eax = 0 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 eax = add eax, 1 \u800c\u5982\u679c %1 \u5bc4\u5b58\u5668\u540e\u9762\u8fd8\u6709\u4f7f\u7528\uff0c\u90a3\u5c31\u4e0d\u80fd\u628a %1 \u6240\u5728\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u590d\u7528\u4e86\u3002 %1 = 0 %2 = add %1, 1 %3 = add %2, 1 %4 = add %3, 1 %5 = add %4, %1 ; \u6b64\u5904\u7684\u201c\u4f7f\u7528\u201d\u5ef6\u957f\u4e86 %1 \u5bc4\u5b58\u5668\u7684\u751f\u547d\u5468\u671f\uff01 \u7ebf\u6027\u626b\u63cf\u540e\uff0c\u53d1\u73b0\u81f3\u591a\u9700\u8981\u5206\u914d\u4e24\u4e2a\u786c\u4ef6\u5bc4\u5b58\u5668\u8d44\u6e90\uff1a eax = 0 ecx = add eax, 1 ecx = add ecx, 1 ecx = add ecx, 1 ecx = add ecx, 1 eax = add eax, ecx","title":"\u4efb\u610f\u591a\u4e2a\u5bc4\u5b58\u5668"},{"location":"llvm_intro/#_11","text":"\u865a\u62df\u5bc4\u5b58\u5668\u90fd\u662f\u53ea\u8bfb\u7684\uff01\u4e00\u6b21\u6027\u8d4b\u503c\u5b8c\u6bd5\u540e\uff0c\u5c31\u4e0d\u5141\u8bb8\u518d\u6b21\u4fee\u6539\uff0c\u6240\u6709\u7684\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u80fd\u5728\u5b9a\u4e49\u7684\u5730\u65b9\u8d4b\u503c\u3002 \u5982\u679c\u9700\u8981\u80fd\u4fee\u6539\u7684\u53d8\u91cf\uff0c\u9700\u8981\u7528 IR \u4e2d\u7684 alloca \u6307\u4ee4\u5728\u51fd\u6570\u6808\u4e0a\u5206\u914d\uff08\u9759\u6001\u5927\u5c0f\u7684\uff09\u7a7a\u95f4\uff0c\u5176\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\u3002 \u5728 Clang \u4e2d\uff0c\u4f1a\u5148\u628a\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u90fd\u5b9a\u4e49\u4e3a alloca \u7684\uff0c\u5f53\u521d\u59cb\u5316\u53d8\u91cf\u65f6\uff0c\u7528 IR \u4e2d\u7684\u5185\u5b58\u5199\u6307\u4ee4 store \u5199\u5165\u521d\u59cb\u503c\u3002 \u7136\u540e\uff0c\u5728\u5f00\u542f\u4e86\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0cLLVM \u4e2d\u7aef\u4e00\u4e2a\u53eb\u505a mem2reg \u7684\u4f18\u5316 pass\uff0c\u4f1a\u68c0\u6d4b\u5230\u6240\u6709\u53ea\u6709\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u5e38\u91cf\u53d8\u91cf\u7684 alloca\uff0c\u5e76\u5c1d\u8bd5\u628a\u4ed6\u4eec\u4f18\u5316\u4e3a\u865a\u62df\u5bc4\u5b58\u5668\u3002 \u5bf9\u4e8e\u5b58\u5728 if \u6761\u4ef6\u8d4b\u503c\uff0c\u4ee5\u53ca for \u5faa\u73af\u7684\uff0c\u5219\u4f1a\u5229\u7528 Phi \u8282\u70b9\uff0c\u4f9d\u7136\u53ef\u4ee5\u4f18\u5316\u79f0\u4e00\u6b21\u6027\u8d4b\u503c\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002\uff08\u540e\u9762\u7684\u7ae0\u8282\u4e2d\u4f1a\u4e13\u95e8\u4ecb\u7ecd Phi \u7684\u77e5\u8bc6\uff09 \u5982\u679c\u5b9e\u5728\u907f\u514d\u4e0d\u4e86 alloca\uff08\u6bd4\u5982\u5bf9\u53d8\u91cf\u7528\u5230\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26\uff0c\u800c\u865a\u62df\u5bc4\u5b58\u5668\u6ca1\u6709\u5185\u5b58\u5730\u5740\uff09\uff0c\u90a3\u5c31\u4f1a\u653e\u5f03\u4f18\u5316\u8fd9\u4e2a\u53d8\u91cf\uff0c\u4f9d\u7136\u4fdd\u6301 alloca + store \u7684\u72b6\u6001\u3002 \u6700\u7ec8\uff0c\u6240\u6709\u80fd\u4f18\u5316\u6210\u7684\uff0c\u90fd\u53d8\u6210\u65e0\u9650\u4f9b\u5e94\u4e14\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u4e86\u3002 \u8fd9\u79cd\u5bc4\u5b58\u5668\u53ea\u8bfb\u7684 IR\uff0c\u88ab\u79f0\u4e3a SSA IR\uff08Static Single Assignment IR\uff09\uff0c\u4e2d\u6587\u5c31\u662f\u662f\u201c\u9759\u6001\u5355\u8d4b\u503c IR\u201d\u3002 \u9759\u6001\uff1a\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u548c\u5e8f\u53f7\u662f\u786e\u5b9a\u7684\uff0c\u5728\u751f\u6210 IR \u7684\u65f6\u5019\u5c31\u5df2\u7ecf\u56fa\u5b9a\u3002 \u5355\u8d4b\u503c\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u53ea\u80fd\u8d4b\u503c\u4e00\u6b21\uff0c\u4e4b\u540e\u4e0d\u5f97\u4fee\u6539\u3002 SSA IR \u7684\u597d\u5904\u662f\u65b9\u4fbf\u4f18\u5316\uff0c\u4f8b\u5982\uff1a x = 1; x = 2; y = x; return y; \u5f88\u660e\u663e\uff0c\u6211\u4eec\u53ef\u4ee5\u628a x = 1 \u8fd9\u4e00\u884c\u4f18\u5316\u6389\uff0c\u56e0\u4e3a\u540e\u9762\u7684 x = 2 \u5df2\u7ecf\u628a\u4ed6\u8986\u76d6\u4e86\u3002\u4f46\u662f\u5982\u4f55\u786e\u5b9a\u8fd9\u4e00\u70b9\uff1f\u5f88\u56f0\u96be\u3002 \u800c\u5982\u679c\u5148\u901a\u8fc7 mem2reg \u8f6c\u6210 SSA IR \u7684\u865a\u62df\u5bc4\u5b58\u5668\uff0c\u8fd9\u65f6\u4ed6\u4f1a\u6ce8\u610f\u5230 x = 1 \u548c x = 2 \u662f\u4e24\u4e2a\u72ec\u7acb\u7684\u8d4b\u503c\uff0c\u751f\u547d\u5468\u671f\u4e92\u4e0d\u91cd\u53e0\uff0c\u53ef\u4ee5\u62c6\u6210\u4e24\u4e2a\u5e38\u91cf\uff0c\u5b89\u5168\u653e\u8fdb\u53ea\u8bfb\u7684\u865a\u62df\u5bc4\u5b58\u5668\u3002 x1 = 1; // \u68c0\u6d4b\u5230\u201c\u4e0d\u53ef\u8fbe\u201d\u7684\u5bc4\u5b58\u5668 x2 = 2; y = x2; return y; \u7136\u540e\uff0c\u7531\u4e8e x1 \u6839\u672c\u6ca1\u6709\u4f7f\u7528\u8fc7\uff0c\u5728\u540e\u7aef\u7684\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u9636\u6bb5\uff0c\u5f88\u5bb9\u6613\u5c31\u628a x1 \u8fd9\u4e2a\u672a\u4f7f\u7528\u7684\u53d8\u91cf\u5254\u9664\u6389\u3002\u5373\u4f7f\u4e0d\u662f\u540e\u7aef\uff0c\u4e2d\u7aef\u7684\u4e00\u4e9b\u5176\u4ed6\u4f18\u5316 pass \u4e5f\u5f88\u5bb9\u6613\u6e05\u9664\u8fd9\u4e9b\u672a\u4f7f\u7528\u7684\u5e38\u91cf\u5bc4\u5b58\u5668\u3002 \u603b\u4e4b\uff0c\u901a\u8fc7 SSA \u89c4\u5219\uff0c\u628a\u201c\u5bc4\u5b58\u5668\u88ab\u8986\u76d6\u201d\u8fd9\u4e2a\u6bd4\u8f83\u96be\u68c0\u6d4b\u7684\u6761\u4ef6\uff0c\u53d8\u6210\u4e86\u201c\u5bc4\u5b58\u5668\u53ea\u5b9a\u4e49\uff0c\u6ca1\u4eba\u4f7f\u7528\u201d\u8fd9\u4e2a\u5f88\u5bb9\u6613\u68c0\u6d4b\u7684\u4e8b\u5b9e\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u7531\u4e8e LLVM \u7684\u7814\u7a76\u4e3b\u8981\u96c6\u4e2d\u5728\u4e2d\u7aef\uff0c\u5728\u4e2d\u7aef\u7684\u8bed\u5883\u4e0b\u63d0\u5230\u7684\u5bc4\u5b58\u5668\uff0c\u5982\u975e\u7279\u522b\u8bf4\u660e\uff0c\u8bfb\u8005\u5e94\u5f53\u9ed8\u8ba4\u6307\u7684\u5c31\u662f LLVM \u865a\u62df\u5bc4\u5b58\u5668\uff0c\u800c\u4e0d\u662f\u786c\u4ef6\u5bc4\u5b58\u5668\u3002 \u6700\u540e\uff0c\u5728\u201c\u5206\u914d\u5bc4\u5b58\u5668\u201d\u9636\u6bb5\uff0c\u628a\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u5bb9\u7eb3\u4e0d\u4e0b\u6216\u65e0\u6cd5\u53d8\u6210\u5355\u6b21\u9759\u6001\u8d4b\u503c\u7684\u90e8\u5206\u53d8\u91cf\uff0c\u518d\u9009\u62e9\u6027\u5730\u201c\u6253\u7ffb\u201d\u5230\u5185\u5b58\u4e2d\u53bb\u3002\u8fd9\u6837\u4e00\u6765\u4e00\u56de\uff0c\u5728\u4e2d\u7aef\u65b9\u4fbf\u4e86\u4f18\u5316\uff0c\u540e\u7aef\u53c8\u4e00\u6837\u80fd\u6b63\u5e38\u751f\u6210\u6c47\u7f16\uff0c\u5bf9\u4e8e\u5bc4\u5b58\u5668\u7528\u91cf\u8f83\u5c11\u7684\u51fd\u6570\u5219\u5b8c\u5168\u907f\u514d\u4e86\u5185\u5b58\u8bfb\u5199\u3002\u4e3a\u4e86\u4fdd\u8bc1\u6240\u6709\u7528\u5230\u7684\u53d8\u91cf\u90fd\u5b58\u5230\u5bc4\u5b58\u5668\u4e2d\uff0c\u4f60\u53ef\u4ee5\u81ea\u5df1\u6570\u4e00\u4e0b\uff0c\u6240\u6709\u53d8\u91cf\u751f\u547d\u5468\u671f\u91cd\u53e0\u7684\u6700\u591a\u7684\u6570\u91cf\u662f\u591a\u5c11\uff0c\u662f\u5426\u8d85\u8fc7\u7684\u786c\u4ef6\u5bc4\u5b58\u5668\u7684\u6570\u91cf\u4e0a\u9650\uff1a\u5bf9 x86 \u6765\u8bf4\uff0c\u5c31\u662f\u9664 rsp \u548c rbp \u5916\u6240\u6709\u7684\u901a\u7528\u5bc4\u5b58\u5668\uff08\u6574\u6570\u53d8\u91cf\uff09\u548c\u6240\u6709 xmm \u7cfb\u5217\u5bc4\u5b58\u5668\uff08\u6d6e\u70b9\u53d8\u91cf\uff09\uff1b\u5982\u679c\u8be5\u51fd\u6570\u4e2d\u8fd8\u8c03\u7528\u4e86\u5176\u4ed6\u51fd\u6570\uff0c\u90a3\u4e48\u5c31\u53ea\u6709\u975e\u6613\u5931\u5bc4\u5b58\u5668\u53ef\u7528\u3002","title":"\u865a\u62df\u5bc4\u5b58\u5668\u53ea\u8bfb"},{"location":"llvm_intro/#_12","text":"\u6211\u4eec\u719f\u6089\u7684 x86 \u6c47\u7f16\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u7531\u5176\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\uff08\u4f8b\u5982 add \uff09\u90fd\u662f\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668 + \u6e90\u5bc4\u5b58\u5668\u7684\u7279\u70b9\u5f97\u540d\u3002 add eax, ecx \u6548\u679c\uff1a eax = eax + ecx \u7c7b\u4f3c\u4e8e C \u8bed\u8a00\u4e2d\u7684 += \u8fd0\u7b97\u7b26\uff0c\u4fee\u6539\u662f\u5c31\u5730\u751f\u6548\u5728\u5176\u4e2d\u4e00\u4e2a\u5bc4\u5b58\u5668\u4e0a\u7684\uff0c\u5176\u4e2d\u5de6\u4fa7\u7684\u5bc4\u5b58\u5668\u65e2\u662f\u6e90\u5bc4\u5b58\u5668\u53c8\u662f\u76ee\u7684\u5bc4\u5b58\u5668\u3002 \u4f18\u70b9\uff1a\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u5c31\u5730\u5199\u5165\u53ef\u4ee5\u8282\u7701\u6307\u4ee4\u7801\u7684\u5927\u5c0f\uff0c\u8282\u7701\u7a7a\u95f4\uff0c\u7b26\u5408 x86 \u7684 CISC \u8bbe\u8ba1\u601d\u8def\u3002 \u7f3a\u70b9\uff1a\u5982\u679c\u9700\u8981\u628a\u7ed3\u679c\u5b58\u5728\u53e6\u4e00\u4e2a\u5bc4\u5b58\u5668\u91cc\uff0c\u5c31\u9700\u8981\u5148 mov \u6307\u4ee4\u62f7\u8d1d\u4e00\u4efd\uff0c\u4e14\u5b58\u5728\u526f\u4f5c\u7528\u4e0d\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u800c LLVM \u7684 IR \u662f\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u3002\u4f8b\u5982\uff1a %3 = add %1, %2 \u6548\u679c\uff1a %3 = %1 + %2 \u8fd9\u91cc\uff0c %3 \u662f\u76ee\u6807\u5bc4\u5b58\u5668\uff0c %1 \u548c %2 \u662f\u6e90\u5bc4\u5b58\u5668\uff0c add \u662f\u64cd\u4f5c\u6307\u4ee4\u3002 \u548c\u4e24\u64cd\u4f5c\u6570\u6307\u4ee4\u76f8\u6bd4\uff0c\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u7684\u597d\u5904\u662f\uff1a \u6e90\u5bc4\u5b58\u5668\u53ea\u8bfb\uff0c\u4e0d\u4f1a\u6539\u53d8\uff1a\u5982\u9700\u8ba1\u7b97\u4e00\u52a0\u4e00\u51cf\uff0c\u65e0\u9700\u9884\u5148\u62f7\u8d1d\u4e00\u4efd\u65e7\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u76f4\u63a5 %3 = add %1, %2 \u548c %4 = sub %1, %2 \u5373\u53ef\u3002 \u76ee\u7684\u5bc4\u5b58\u5668\u53ea\u5199\uff0c\u6ee1\u8db3\u4e86\u9759\u6001\u5355\u8d4b\u503c IR\uff08SSA IR\uff09\u7684\u8981\u6c42\uff0c\u4e0d\u9700\u8981\u8003\u8651\u526f\u4f5c\u7528\uff0c\u4f18\u5316\u8d77\u6765\u66f4\u65b9\u4fbf\uff0c\u662f\u4e2d\u95f4 IR \u7684\u7406\u60f3\u8bbe\u8ba1\u3002 \u6240\u6709\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4\u4e4b\u95f4\u987a\u5e8f\u65e0\u5173\uff0c\u53ef\u4ee5\u4efb\u610f\u8c03\u6362\u987a\u5e8f\uff0c\u53ef\u4ee5\u8f7b\u677e\u901a\u8fc7 DFS \u9012\u5f52\u627e\u51fa\u4e00\u4e2a\u76ee\u7684\u5bc4\u5b58\u5668\u6240\u6709\u76f4\u63a5\u548c\u95f4\u63a5\u4f9d\u8d56\u7684\u5bc4\u5b58\u5668\uff0c\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\u3002 \u7f3a\u70b9\uff1a\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u4f46\u662f LLVM IR \u662f\u53ea\u5728\u7f16\u8bd1\u671f\u5b58\u5728\u7684\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u5e76\u4e0d\u8fdb\u5165\u6700\u7ec8\u4e8c\u8fdb\u5236\u4ea7\u7269\uff0c\u6700\u7ec8\u7f16\u8bd1\u6210 x86 \u6c47\u7f16\u540e\u4f9d\u7136\u662f\u4e8c\u64cd\u4f5c\u6570\u6307\u4ee4\uff0c\u6240\u4ee5\u8fd9\u4e2a\u7f3a\u70b9\u5e76\u4e0d\u5f71\u54cd\u3002","title":"\u4e09\u64cd\u4f5c\u6570\u6307\u4ee4"},{"location":"llvm_intro/#_13","text":"LLVM IR \u4e2d\uff0c\u6240\u6709\u7684\u5bc4\u5b58\u5668\u5e76\u4e0d\u662f\u539f\u59cb\u7684\u4e8c\u8fdb\u5236\u5185\u5b58\uff0c\u800c\u662f\u6709\u7c7b\u578b\u7684\u3002 \u6709\u4eba\u4f1a\u8bf4\uff0c\u5df2\u7ecf\u8fdb\u5165 IR \u4e86\uff0c\u662f\u4e0d\u662f\u6ca1\u6709\u5fc5\u8981\uff1f\u628a\u6240\u6709\u7c7b\u578b\u90fd\u5f53\u6210\u4e8c\u8fdb\u5236\u5185\u5b58\u4e0d\u884c\u5417\uff1f \u5728 IR \u5c42\u9762\u533a\u5206\u7c7b\u578b\u7684\u597d\u5904\uff1a \u53ef\u4ee5\u660e\u786e\u5404\u79cd\u6570\u5b66\u8fd0\u7b97\u64cd\u4f5c\u6570\u7684\u7c7b\u578b\uff08\u4f8b\u5982\u6d6e\u70b9\u6570 f32 \u6216\u6574\u6570 i32 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bc4\u5b58\u5668\u7684\u5927\u5c0f\uff08\u4f8b\u5982 32 \u4f4d\u6574\u6570 i32 \u548c 8 \u4f4d\u6574\u6570 i8 \uff09\u3002 \u53ef\u4ee5\u660e\u786e\u5bf9\u9f50\u5ea6\u3002 \u53ef\u4ee5\u533a\u5206\u51fa\u6307\u9488\u548c\u666e\u901a\u7c7b\u578b\u4e24\u79cd\u4e0d\u540c\u7684\u7528\u9014\uff0c\u9632\u6b62\u6df7\u6dc6\uff08\u4f8b\u5982\u6574\u6570\u7c7b\u578b i32 \u548c\u4ed6\u7684\u6307\u9488 i32* \uff09\u3002 \u5f3a\u7c7b\u578b\u7684 IR \u53ef\u4ee5\u5927\u5927\u5e2e\u52a9\u4f18\u5316 pass \u7406\u89e3\u7a0b\u5e8f\u3002 \u7c7b\u578b\u4e3a\u4ec0\u4e48\u5e2e\u52a9\u4f18\u5316\uff1f\u4f8b\u5982\uff0c\u77e5\u9053\u7c7b\u578b\u4fe1\u606f\u540e\uff0c\u53ef\u4ee5\u914d\u5408 C++ \u7684 strict-aliasing \u89c4\u5219\u6392\u9664\u4e00\u90e8\u5206\u53ef\u80fd\u7684\u6307\u9488\u522b\u540d\uff0c\u79f0\u4e3a\u201c\u57fa\u4e8e\u7c7b\u578b\u7684\u522b\u540d\u5206\u6790\u201d\uff08TBAA, type-based-aliasing-analysis\uff09\u3002 \u522b\u540d\u6307\u7684\u662f\u4e24\u4e2a\u6307\u9488\u6709\u76f8\u4e92\u201c\u7a7f\u63d2\u201d\u7684\u90e8\u5206\uff0c\u6307\u9488\u5b58\u5728\u522b\u540d\u4f1a\u5bfc\u81f4 SIMD \u77e2\u91cf\u4f18\u5316\u5931\u8d25\u3002\u800c C++ \u7684 strict-aliasing \u53ef\u4ee5\u4fdd\u8bc1\u4e0d\u76f8\u5e72\u7c7b\u578b\u7684\u4e24\u4e2a\u6307\u9488\u4e4b\u95f4\u4e0d\u4f1a\u6709\u201c\u7a7f\u63d2\u201d\uff0c\u4ece\u800c\u5e2e\u52a9\u77e2\u91cf\u4f18\u5316\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u4ece int * \u5f3a\u8f6c\u4e3a float * \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u4e3a strict-aliasing \u8981\u6c42\u4e0d\u540c\u7c7b\u578b\u7684\u6307\u9488\u6ca1\u6709\u91cd\u53e0\u90e8\u5206\uff08\u6307\u5411\u76f8\u540c\u7684\u5730\u5740\uff09\uff0c\u5982\u679c\u4f60\u540c\u65f6\u7528\u4e86\u6307\u5411\u540c\u4e00\u4e2a\u5730\u5740\u7684 int * \u548c float * \uff0c\u90a3\u4e48\u5982\u679c LLVM \u5047\u5b9a\u4e86\u4ed6\u4eec\u4e0d\u80fd\u6307\u5411\u540c\u5730\u5740\u6765\u4f18\u5316\uff0c\u5c31\u4f1a\u5bfc\u81f4\u8fd0\u884c\u7ed3\u679c\u51fa\u9519\u3002\u4e0d\u8fc7 int * \u8f6c\u4e3a char * \u3001 unsigned char * \u5374\u662f\u5141\u8bb8\u7684\uff0c\u8fd9\u662f\u56e0\u4e3a\u7ecf\u5e38\u51fa\u73b0\u7528 char \u6765\u505a\u7f13\u51b2\u533a\uff0c\u7136\u540e\u89e3\u6790\u51fa\u7ed3\u6784\u4f53\u7684\u573a\u666f\uff0cC++ \u6807\u51c6\u4e3a\u8fd9\u79cd\u5e38\u7528\u60c5\u51b5\u5f00\u4e86\u540e\u95e8\u3002\u6240\u4ee5\u5982\u679c\u4f60\u9700\u8981\u5728 int \u548c float \u4e4b\u95f4\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 memcpy \u6765\u62f7\u8d1d\uff08 memcpy \u5185\u90e8\u88ab LLVM \u8ba4\u4e3a\u662f\u6309 unsigned char * \u8bbf\u95ee\u7684\uff09\uff0c\u4e0d\u8981\u5f3a\u8f6c\u6307\u9488\u8bbf\u95ee\u3002\u8be6\u89c1\u6211\u4eec\u7684 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u3002","title":"\u7c7b\u578b\u7cfb\u7edf"},{"location":"llvm_intro/#_14","text":"LLVM IR \u4e2d\u7684\u57fa\u7840\u7c7b\u578b\u6709\uff1a LLVM \u7c7b\u578b C \u8bed\u8a00\u7c7b\u578b \u89e3\u91ca i1 bool 1 \u4f4d\u6574\u6570/\u5e03\u5c14\u7c7b\u578b i8 char 8 \u4f4d\u6574\u6570\u7c7b\u578b i16 short 16 \u4f4d\u6574\u6570\u7c7b\u578b i32 int 32 \u4f4d\u6574\u6570\u7c7b\u578b i64 long long 64 \u4f4d\u6574\u6570\u7c7b\u578b f16 _Float16 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b bf16 _BFloat16 \u7a84\u5e95 16 \u4f4d\u6d6e\u70b9\u7c7b\u578b f32 float 32 \u4f4d\u6d6e\u70b9\u7c7b\u578b f64 double 64 \u4f4d\u6d6e\u70b9\u7c7b\u578b f80 long double 80 \u4f4d\u6d6e\u70b9\u7c7b\u578b f128 _Float128 128 \u4f4d\u6d6e\u70b9\u7c7b\u578b void void \u7a7a\u7c7b\u578b","title":"\u57fa\u7840\u7c7b\u578b"},{"location":"llvm_intro/#_15","text":"\u5176\u4e2d i1 \u662f\u5e03\u5c14\u7c7b\u578b\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 bool \uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u6bd2\u503c\uff09\u3002","title":"\u5e03\u5c14\u7c7b\u578b"},{"location":"llvm_intro/#_16","text":"\u6240\u6709\u7c7b\u578b\u90fd\u53ef\u4ee5\u4ea7\u751f\u4e00\u4e2a\u76f8\u5e94\u7684\u6307\u9488\u7c7b\u578b\uff0c\u7528\u4e00\u4e2a * \u505a\u540e\u7f00\u6765\u8868\u793a\u3002 \u4f8b\u5982\u4e00\u4e2a\u6307\u5411 i8 \u7684\u6307\u9488\uff0c\u7c7b\u578b\u5c31\u662f i8* \uff0c\u5bf9\u5e94 C \u8bed\u8a00\u4e2d\u7684 char * \u7c7b\u578b\u3002 \u6ce8\u610f LLVM IR \u4e2d\u4e0d\u533a\u5206\u7c7b\u578b\u7684 const \u4e0e\u5426\uff0c const \u53ea\u5728 C++ \u8bed\u6cd5\u5c42\u9762\u5b58\u5728\uff0c\u4f8b\u5982 const char * \u548c char * \u5728 LLVM IR \u4e2d\u5bf9\u5e94\u7684\u90fd\u662f i8* \u3002 \u53ef\u4ee5\u7528\u591a\u4e2a * \u540e\u7f00\u8868\u793a\u591a\u91cd\u6307\u9488\uff0c\u4f8b\u5982 char ** \u7c7b\u578b\u5728 LLVM IR \u4e2d\u5c31\u662f i8** \u3002","title":"\u6307\u9488\u7c7b\u578b"},{"location":"llvm_intro/#_17","text":"","title":"\u7ed3\u6784\u4f53\u7c7b\u578b"},{"location":"llvm_intro/#_18","text":"\u6ce8\u610f\u5230\uff0cLLVM \u4e2d\u4f3c\u4e4e\u53ea\u6709 i32 \u800c\u6ca1\u6709 u32 \uff1f\u8fd9\u662f\u56e0\u4e3a LLVM IR \u7684\u7c7b\u578b\u7cfb\u7edf\u5e76\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\u3002 int \u548c unsigned int \u90fd\u7edf\u4e00\u7528 i32 \u8868\u793a\uff1b char \u548c unsigned char \u7edf\u4e00\u7528 i8 \u8868\u793a\u3002 \u4e3a\u4ec0\u4e48\uff1f\u56e0\u4e3a\uff1a LLVM IR \u662f\u4e00\u79cd\u4e2d\u95f4\u8868\u793a\u7801\uff0c\u4e0d\u5e94\u8be5\u5305\u542b\u592a\u591a\u8bed\u8a00\u7279\u6027\uff0c\u4fdd\u6301\u7b80\u5355\u3002 \u5927\u591a\u6570\u65f6\u5019\uff0c\u6211\u4eec\u5e76\u4e0d\u5173\u5fc3\u6574\u6570\u7c7b\u578b\u662f\u5426\u6709\u7b26\u53f7\uff0c\u53ea\u5173\u5fc3\u52a0\u51cf\u6cd5\u540e\u662f\u5426\u6ea2\u51fa\u3002 \u50cf\u52a0\u6cd5\uff08 add \uff09\u548c\u51cf\u6cd5\uff08 sub \uff09\u8fd9\u6837\u7684\u6570\u5b66\u8fd0\u7b97\uff0c\u7531\u4e8e\u8865\u7801\u7684\u5de7\u5999\u8bbe\u8ba1\uff0c\u65e0\u8bba\u64cd\u4f5c\u6570\u662f\u5426\u6709\u7b26\u53f7\uff0c\u5176\u7ed3\u679c\u5728\u4e8c\u8fdb\u5236\u4e0a\u90fd\u662f\u4e00\u6837\u7684\u3002 \u50cf\u6309\u4f4d\u6216\uff08 or \uff09\u548c\u6309\u4f4d\u4e0e\uff08 and \uff09\u8fd9\u6837\u7684\u903b\u8f91\u8fd0\u7b97\uff0c\u4e5f\u4e0d\u6d89\u53ca\u7b26\u53f7\u4f4d\uff0c\u90fd\u662f\u5f53\u6210\u666e\u901a\u7684\u4e8c\u8fdb\u5236\u4f4d\u6765\u8fd0\u7b97\uff0c\u7ed3\u679c\u4e5f\u6ca1\u6709\u533a\u522b\u3002 \u4fdd\u6301\u7b80\u5355\u6709\u5229\u4e8e\u4f18\u5316\u548c\u5206\u6790\uff0c\u4f8b\u5982\uff0c\u4e0d\u7528\u8003\u8651 int \u7c7b\u578b\u548c unsigned int \u7c7b\u578b\u4e4b\u95f4\u7684\u6765\u56de\u8f6c\u6362\u3002 \u56e0\u6b64 i32 \u548c u32 \u7684 add \u548c sub \u6307\u4ee4\u53ef\u4ee5\u7edf\u4e00\u5f53\u4f5c i32 \u6765\u52a0\u51cf\u3002 \u800c\u5bf9\u4e8e\u4e58\u6cd5\u548c\u9664\u6cd5\u8fd9\u4e9b\u6709\u7b26\u53f7\u548c\u65e0\u7b26\u53f7\u7ed3\u679c\u4f1a\u4e0d\u540c\u7684\u6570\u5b66\u8fd0\u7b97\uff0cLLVM \u5c06\u4ed6\u4eec\u5206\u79bb\u6210\u4e24\u7ec4 IR \u6307\u4ee4\uff1a\u9488\u5bf9\u6709\u7b26\u53f7\u6570\u7684 smul \u548c sdiv \uff0c\u4ee5\u53ca\u9488\u5bf9\u65e0\u7b26\u53f7\u7684 umul \u548c udiv \u3002 \u6240\u4ee5\uff0cLLVM \u53ea\u662f\u9488\u5bf9\u4e58\u9664\u8fd9\u79cd\u6709\u65e0\u7b26\u53f7\u7ed3\u679c\u4e0d\u540c\u7684\u8fd0\u7b97\uff0c\u533a\u5206\u6210\u4e86\u4e24\u5957\u4e0d\u540c\u7684\u6307\u4ee4\uff1a\u7528 s \u548c u \u524d\u7f00\u533a\u5206\uff0c\u5176\u4f59\u50cf\u52a0\u51cf\u6cd5\u8fd9\u4e9b\u6307\u4ee4\u90fd\u662f\u5171\u7528\u7684\u3002 \u9700\u8981\u533a\u5206\u6709\u65e0\u7b26\u53f7\u7684\u6574\u6570\u8fd0\u7b97\u6307\u4ee4\uff1a\u4e58\u6cd5\u3001\u9664\u6cd5\u3001\u53d6\u6a21\u8fd0\u7b97\u3001\u6309\u4f4d\u53f3\u79fb\u3001\u6bd4\u8f83\u5927\u5c0f\u5173\u7cfb\u3002 \u4e0d\u9700\u8981\u533a\u5206\u7684\uff1a\u52a0\u6cd5\u3001\u51cf\u6cd5\u3001\u6309\u4f4d\u6216\u3001\u6309\u4f4d\u4e0e\u3001\u6309\u4f4d\u5f02\u6216\u3001\u6309\u4f4d\u5de6\u79fb\u3001\u6309\u4f4d\u53d6\u53cd\u3001\u6bd4\u8f83\u662f\u5426\u76f8\u7b49\u3002 \u4ece\u6307\u4ee4\u5c42\u9762\u4e0a\u533a\u5206\u6709\u65e0\u7b26\u53f7\u6570\uff0c\u800c\u7c7b\u578b\u5c42\u9762\u4e0a\u76f8\u540c\u3002\u8ba9\u662f\u5426\u6709\u7b26\u53f7\u53d8\u6210\u4e86\u6307\u4ee4\u7684\u7279\u6027\u800c\u4e0d\u662f\u7c7b\u578b\u7684\uff0c\u5927\u5927\u65b9\u4fbf\u4e86\u4f18\u5316\u3002 \u4e0d\u4ec5 LLVM IR \u4e2d\u5982\u6b64\uff0c\u5728 x86 \u6307\u4ee4\u96c6\u4e2d\u4e5f\u662f\u8fd9\u6837\u8bbe\u8ba1\u7684\u3002 \u81ea\u6b64\uff0c\u6709\u65e0\u7b26\u53f7\u7684\u4fe1\u606f\u53ea\u5728 Clang \u524d\u7aef\u4e2d\u51fa\u73b0\uff0c\u7531 Clang \u6839\u636e\u53d8\u91cf\u7c7b\u578b\u4fe1\u606f\uff0c\u9009\u62e9\u751f\u6210 smul \u6216 umul \u7b49 IR \u6307\u4ee4\uff0c\u7c7b\u578b\u90fd\u662f\u7edf\u4e00\u7684 i32 \u3002","title":"\u4e0d\u533a\u5206\u6574\u6570\u7c7b\u578b\u6709\u65e0\u7b26\u53f7"},{"location":"llvm_intro/#_19","text":"\u8fd9\u91cc\u6211\u4eec\u6709\u5fc5\u8981\u660e\u786e\u4e00\u4e0b\u201c\u5b9a\u4e49(define)\u201d\u548c\u201c\u4f7f\u7528(use)\u201d\u3002\u8fd9\u662f\u4e24\u4e2a\u7f16\u8bd1\u5668\u9886\u57df\u7684\u672f\u8bed\uff0c\u7528\u4e8e\u63cf\u8ff0 SSA IR \u7684\u5bc4\u5b58\u5668\u53ca\u5176\u7528\u51b5\u3002 \u5b9a\u4e49\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u88ab\u8d4b\u503c\u7684\u5730\u65b9\uff0c\u5c31\u662f\u4ed6\u7684\u5b9a\u4e49\u3002 %1 = 1 ; %1 \u7684\u5b9a\u4e49 %2 = 2 ; %2 \u7684\u5b9a\u4e49 %3 = add %1, %2 ; %3 \u7684\u5b9a\u4e49 \u56e0\u4e3a LLVM IR \u662f SSA \u7684\uff0c\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c\u53ea\u80fd\u5728\u521d\u59cb\u5316\u65f6\u88ab\u8d4b\u503c\u4e00\u6b21\u3002\u6240\u4ee5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u662f\u552f\u4e00\u7684\uff0c\u4e5f\u5c31\u662f\u521d\u59cb\u5316\u7684\u90a3\u4e00\u6b21\u8d4b\u503c\u7684\u5730\u65b9\u3002 \u8868\u793a\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e2d\uff0c\u5176\u521d\u59cb\u5316\uff0c\u7528\u5230\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\u505a\u53c2\u6570\u3002\u8fd9\u4e9b\u88ab\u5f15\u7528\u4e86\u7684\u201c\u53c2\u6570\u5bc4\u5b58\u5668\u201d\uff0c\u5c31\u662f\u4ed6\u7684\u201c\u4f7f\u7528\u201d\u3002 %1 = 1 %2 = 2 %3 = add %1, %2 ; %3 \u4f7f\u7528\u4e86 %1 \u548c %2 \u521d\u59cb\u5316\u4e3a\u5e38\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 %1 = 233 ; %1 \u6ca1\u6709\u4f7f\u7528\u4efb\u4f55\u4eba\uff01 \u5728 LLVM \u4e2d\u7ef4\u62a4\u6709\u201c\u5b9a\u4e49-\u4f7f\u7528(def-use)\u201d\u548c\u201c\u4f7f\u7528-\u5b9a\u4e49(use-def)\u201d\u7684\u53cc\u5411\u6620\u5c04\u5173\u7cfb\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\uff0c\u627e\u5230\u4ed6\u88ab\u54ea\u4e9b\u5bc4\u5b58\u5668\u201c\u4f7f\u7528\u201d\u4e86\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\uff1a\u901a\u8fc7\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u201c\u4f7f\u7528\u201d\uff0c\u627e\u5230\u4ed6\u662f\u5728\u54ea\u91cc\u88ab\u201c\u5b9a\u4e49\u201d\u7684\u3002 \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u548c\u201c\u4f7f\u7528\u5b9a\u4e49\u201d\u662f\u4e24\u4e2a\u4e92\u9006\u7684\u6620\u5c04\u3002\u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c\u4ed6\u4eec\u90fd\u4e0d\u662f\u4e00\u4e00\u6620\u5c04\uff1a\u4e00\u4e2a\u5bc4\u5b58\u5668\u53ef\u4ee5\u88ab\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u91cd\u590d\u4f7f\u7528\uff0c\u4e00\u4e2a\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u4e5f\u53ef\u80fd\u4f7f\u7528\u5230\u4e86\u591a\u4e2a\u5176\u4ed6\u5bc4\u5b58\u5668\u3002 \u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u6620\u5c04 \u7531\u4e8e\u6307\u4ee4\u5728\u4ed6\u7684\u6e90\u64cd\u4f5c\u6570\u4e2d\u6307\u5b9a\u4e86\u64cd\u4f5c\u6570\u6765\u81ea\u54ea\u4e2a\u5bc4\u5b58\u5668\uff0c\u201c\u4f7f\u7528-\u5b9a\u4e49\u201d\u5173\u7cfb\u662f IR \u5929\u751f\u81ea\u5e26\u7684\uff0c\u76f4\u63a5\u901a\u8fc7 IR \u8282\u70b9\u7684 op \u6210\u5458\u51fd\u6570\uff0c\u5c31\u80fd\u67e5\u5230\u4ed6\u4f7f\u7528\u4e86\u54ea\u4e9b\u5176\u4ed6\u5bc4\u5b58\u5668\uff08\u6216\u5e38\u6570\uff09\u3002 llvm::Instruction *pi = ...; for (llvm::Use &U: pi->operands()) { llvm::Value *v = U.get(); // v \u4f7f\u7528\u4e86 pi } \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04 \u800c\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u5173\u7cfb\uff0c\u5c31\u9700\u8981\u6211\u4eec\u81ea\u5df1\u6784\u5efa\u4e86\u3002 \u5e78\u8fd0\u7684\u662f\uff0cLLVM \u7ed9\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u4fbf\u7684\u5206\u6790\u5de5\u5177\uff0c\u6765\u81ea\u52a8\u6784\u5efa\u8fd9\u4e2a\u5173\u7cfb\uff1a def-use pass\u3002","title":"\u5b9a\u4e49\u4e0e\u4f7f\u7528"},{"location":"llvm_intro/#pass","text":"LLVM \u4e2d\u7684 pass\uff0c\u662f\u6307\u4e00\u7ec4\u5bf9 IR \u8fdb\u884c\u64cd\u4f5c\u7684\u51fd\u6570\u3002pass \u5206\u4e3a\u5206\u6790\u7c7b pass \u548c\u4f18\u5316\u7c7b pass\u3002 \u5206\u6790\u7c7b pass \u53ea\u662f\u5e2e\u52a9\u6211\u4eec\u89c2\u5bdf IR\uff0c\u83b7\u5f97\u67d0\u4e9b\u6982\u62ec\u4fe1\u606f\uff0c\u5e76\u4e0d\u4fee\u6539 IR\u3002\u73b0\u5728\u6211\u4eec\u8981\u7528\u7684 def-use pass \u5c31\u5c5e\u4e8e\u5206\u6790\u7c7b pass\uff0c\u4ed6\u901a\u8fc7\u4e00\u6b21\u904d\u5386\u627e\u5230\u6240\u6709\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\u5173\u7cfb\u3002\u53ea\u8981 IR \u4e0d\u4fee\u6539\uff0c\u5c31\u53ef\u4ee5\u7f13\u5b58\u4e4b\u524d\u7684\u7ed3\u679c\uff0c\u4f9b\u540e\u6765\u8005\u91cd\u590d\u4f7f\u7528\u3002 \u4f18\u5316\u7c7b pass \u53ef\u4ee5\u4fee\u6539 IR \u7684\u8282\u70b9\uff0c\u4fee\u6539 IR \u539f\u6709\u7684\u7ed3\u6784\uff0c\u4f8b\u5982\u4e4b\u524d\u63d0\u5230\u7684 mem2reg pass \u5c31\u5c5e\u4e8e\u6b64\u7c7b\uff0c\u4ed6\u4f1a\u628a\u6240\u6709\u80fd\u4f18\u5316\u7684 alloca + store \u4fee\u6539\u6210\u9759\u6001\u5355\u8d4b\u503c\u7684\u5bc4\u5b58\u5668\u3002\u7531\u4e8e\u4f1a\u4fee\u6539 IR\uff0c\u53ef\u80fd\u5bfc\u81f4\u67d0\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u5931\u6548\uff0c\u4e0b\u6b21\u518d\u7528\u5230\u65f6\u9700\u8981\u91cd\u8dd1\u3002 \u533a\u522b\uff1a \u5206\u6790\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u5206\u6790\u7ed3\u679c\u7c7b\u578b\u3002\u4f8b\u5982\u5bf9\u4e8e def-use pass\uff0c\u8f93\u51fa\u662f\u4e00\u4e2a Analysis \u7c7b\u578b\u7684\u5bf9\u8c61\uff0c\u8fd9\u4e2a\u5bf9\u8c61\u4e2d\u7ef4\u62a4\u4e86\u4e00\u4e2a \u201c\u5b9a\u4e49-\u4f7f\u7528\u201d \u7684\u53cc\u5411\u6620\u5c04\uff0c\u6211\u4eec def-use pass \u5206\u6790\u5f97\u5230\u7ed3\u679c\u540e\u5c31\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u6620\u5c04\u6765\u67e5\u8be2\u3002 \u4f18\u5316\u7c7b pass \u7684\u8f93\u5165\u662f\u4e00\u6bb5 IR\uff0c\u8f93\u51fa\u4e5f\u662f\u4e00\u6bb5 IR\uff0c\u88ab\u6539\u53d8\u540e\u7684 IR\u3002LLVM \u5b9e\u73b0\u4f18\u5316\uff0c\u5c31\u662f\u901a\u8fc7\u4e00\u7cfb\u5217\u4f18\u5316 pass \u7684\u7ec4\u5408\u5b8c\u6210\u7684\u3002\u6709\u65f6\uff0c\u4f18\u5316 pass \u4f1a\u9700\u8981\u4e00\u4e9b\u5206\u6790\u7684\u7ed3\u679c\uff0c\u624d\u80fd\u8fdb\u884c\uff0c\u56e0\u6b64\u4f18\u5316 pass \u6709\u65f6\u4f1a\u8bf7\u6c42\u4e00\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\uff0cLLVM \u4f1a\u68c0\u67e5\u8fd9\u4e2a\u5206\u6790\u4e4b\u524d\u6709\u6ca1\u6709\u8fdb\u884c\u8fc7\uff0c\u5982\u679c\u6709\uff0c\u5c31\u4f1a\u590d\u7528\u4e0a\u6b21\u5206\u6790\u7684\u7ed3\u679c\uff0c\u4e0d\u4f1a\u91cd\u65b0\u5206\u6790\u6d6a\u8d39\u65f6\u95f4\u3002\u4f18\u5316 pass \u5728\u4fee\u6539\u4e86 IR \u540e\uff0c\u9700\u8981\u8fd4\u56de\u4e00\u4e2a\u6807\u5fd7\u4f4d\uff0c\u8868\u793a IR \u4fee\u6539\u540e\uff0c\u54ea\u4e9b\u5206\u6790 pass \u7684\u7ed3\u679c\u53ef\u80fd\u4f1a\u5931\u6548\u3002\u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u5c31\u8fd4\u56de all \u5427\uff1a\u672c\u4f18\u5316 pass \u4fee\u6539\u8fc7 IR \u540e\u6240\u6709\u4e4b\u524d\u5206\u6790 pass \u7f13\u5b58\u7684\u7ed3\u679c\u90fd\u4f1a\u5931\u6548\u3002 \u5982\u4f55\u5224\u65ad\u4e00\u4e2a\u865a\u62df\u5bc4\u5b58\u5668\u662f\u5426\u53ef\u4ee5\u88ab\u4f18\u5316\u6389\uff1f\u68c0\u6d4b\u4ed6\u6709\u6ca1\u6709\u88ab\u522b\u4eba\u201c\u4f7f\u7528\u201d\uff1a\u4e5f\u5c31\u662f\u67e5\u8be2\u4ed6\u7684\u201c\u5b9a\u4e49-\u4f7f\u7528\u201d\u6620\u5c04\uff0c\u5982\u679c\u53d1\u73b0\u201c\u4f7f\u7528\u8005\u5217\u8868\u201d\u4e3a\u7a7a\uff0c\u5c31\u8bf4\u660e\u8be5\u5bc4\u5b58\u5668\u7684\u201c\u5b9a\u4e49\u201d\u6ca1\u4eba\u4f7f\u7528\uff0c\u53ef\u4ee5\u4f18\u5316\u6389\u3002","title":"\u4f18\u5316\u4e0e\u5206\u6790 pass"},{"location":"llvm_intro/#llvm-ir_1","text":"\u4ee5\u4e0b\u662f\u4e00\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u53ca\u5176\u6240\u5bf9\u5e94\u7684 LLVM IR \u6c47\u7f16\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u770b\u8d77\u6765\u597d\u590d\u6742\uff01\u8ba9\u6211\u4eec\u4e00\u884c\u4e00\u884c\u6765\u89e3\u8bfb\uff1a ; ModuleID = 'a.cpp' \u8fd9\u79cd\u4ee5\u5206\u53f7\u5f00\u5934\u7684\uff0c\u5c31\u662f IR \u6c47\u7f16\u8bed\u6cd5\u4e2d\u7684\u6ce8\u91ca\uff0c\u5206\u53f7\u540e\u9762\u7684\u4e1c\u897f\u4f1a\u88ab\u65e0\u89c6\uff0c\u4e0d\u5f71\u54cd\u5b9e\u9645\u7ed3\u679c\u3002\u5c31\u548c C \u8bed\u8a00\u7684 // \u4e00\u6837\uff0c\u5c5e\u4e8e\u884c\u6ce8\u91ca\u3002 Clang \u751f\u6210\u7684 IR \u6c47\u7f16\u6709\u65f6\u5e26\u6709\u6ce8\u91ca\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u7ed9\u4eba\u770b\u7684\uff0c\u5e76\u4e0d\u5f71\u54cd\u540e\u7aef\u7684\u89e3\u6790\u3002\u8fd9\u91cc\u7684\u6ce8\u91ca\u5f88\u660e\u663e\u662f\u5728\u63d0\u793a\uff0c\u8be5\u6c47\u7f16\u662f\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u7684\uff1f\u662f\u4e00\u4e2a\u53eb a.cpp \u7684\u6587\u4ef6\uff0c\u4f46\u4ed6\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u529b\uff0c\u53ea\u662f\u7ed9\u8bfb\u6c47\u7f16\u7684\u4f60\u6211\u770b\u3002 source_filename = \"a.cpp\"","title":"LLVM IR \u6848\u4f8b\u5206\u6790"},{"location":"llvm_intro/#target","text":"\u8fd9\u624d\u662f\u771f\u6b63\u5bf9 LLVM \u4e2d\u7aef\u6709\u6548\u529b\u7684\u4e1c\u897f\uff0c\u4ed6\u8d4b\u503c\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u63d0\u793a\u8be5 IR \u6c47\u7f16\u7531\u54ea\u4e2a\u6e90\u7801\u6587\u4ef6\u4ea7\u751f\u3002\u8fd9\u4e2a source_filename \u5c5e\u6027\uff0c\u662f\u7531 Clang \u5728\u751f\u6210 IR \u6c47\u7f16\u65f6\uff0c\u4e3b\u52a8\u52a0\u4e0a\u544a\u77e5 LLVM \u540e\u7aef\u7684\u3002\u4e5f\u662f\u4e3a\u4e86\u65b9\u4fbf\u8c03\u8bd5\uff0c\u4f8b\u5982\u5f53 LLVM \u4e2d\u7aef\u4e2d\u89e6\u53d1\u4e86\u62a5\u9519\uff0c\u4ed6\u53ef\u4ee5\u4ee5\u8fd9\u4e2a\u6587\u4ef6\u540d\u6765\u63d0\u793a\u7528\u6237\u3002 target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" \u8fd9\u91cc\u6307\u5b9a\u7684\u662f\u5173\u4e8e\u201c\u76ee\u6807\u5e73\u53f0\u201d\u7684\u4e00\u4e9b\u4fe1\u606f\uff0c\u5206\u4e3a\u4e24\u4e2a\u90e8\u5206\u3002 \u76ee\u6807\u5e73\u53f0\u6307\u7684\u662f\u5f53\u524d\u6e90\u7801\u8981\u7f16\u8bd1\u5230\u4ec0\u4e48\u786c\u4ef6\u4e0a\u6267\u884c\uff0c\u6bd4\u5982\u5728\u6211\u4eec\u7684\u6848\u4f8b\u4e2d\uff0c\u76ee\u6807\u5e73\u53f0\u5c31\u662f x86\u3002 \u5176\u4e2d target triple \u662f\u6307\u5b9a\u7684\u76ee\u6807\u5e73\u53f0\u7684\u540d\u5b57\uff0c\u8fd9\u91cc\u6211\u4eec\u662f x86_64-pc-linux-gnu \uff0c\u8868\u793a 64 \u4f4d x86 \u67b6\u6784\uff0c\u684c\u9762\u7aef\uff0cLinux \u7cfb\u7edf\uff0cGNU \u7f16\u8bd1\u5668\u63a5\u53e3\u3002\u4e0d\u540c\u7684 target triple \u4f1a\u5f71\u54cd\u6700\u7ec8\u751f\u6210\u7684\u6c47\u7f16\u4e2d\u51fd\u6570\u8c03\u7528\u7ea6\u5b9a\u3001C++ \u51fd\u6570\u540d\u91cd\u7ec4\u7b49\u7ec6\u8282\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u8fd9\u4e2a triple \u5c31\u662f\u6211\u4eec\u5e38\u8bf4\u7684 ABI\uff08\u4e8c\u8fdb\u5236\u5e94\u7528\u7a0b\u5e8f\u63a5\u53e3\uff09\u3002 \u4f8b\u5982\uff0c\u5728 Windows \u4e0a\u4f7f\u7528 clang \uff0c\u53ef\u80fd\u5f97\u5230 target triple \u662f x86_64-pc-windows-msvc \uff08\u5982\u679c\u4f60\u662f MSVC \u7f16\u8bd1\u5668\uff09\u6216\u8005 x86_64-pc-windows-gnu \uff08\u5982\u679c\u4f60\u662f MinGW \u7f16\u8bd1\u5668\uff09\uff0c\u4ea7\u751f\u7684 C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u4f1a\u6709\u4e0d\u540c\u3002\u5728 MacOS \u4e0a\u8fd8\u4f1a\u5f97\u5230 x86_64-apple-darwin \u6216 aarch64-apple-darmin \u3002 \u4e0d\u540c\u7684\u64cd\u4f5c\u7cfb\u7edf\u548c\u786c\u4ef6\uff0c\u90fd\u4f1a\u6709\u4e0d\u540c\u7684 ABI\uff0c\u4f8b\u5982 Linux \u5728 x86_64 \u4e0a\u7684 ABI \u89c4\u5b9a\u7b2c\u4e00\u4e2a\u53c2\u6570\u7531 rdi \u4f20\u5165\uff0c\u800c Windows \u5219\u662f rcx \u3002\u8fd9\u4e9b\u7ec6\u8282\u90fd\u662f\u7531 target triple \u786e\u5b9a\u7684\u3002 target datalayout \u5219\u662f\u6307\u5b9a\u4e86\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u7c7b\u578b\u5927\u5c0f\u548c\u5e03\u5c40\u7b49\u4fe1\u606f\uff0c\u4f8b\u5982\u6307\u9488\u5927\u5c0f\u3001\u5bf9\u9f50\u65b9\u5f0f\u7b49\u3002\u4f8b\u5982\u5728 x86_64-pc-linux-gnu \u8fd9\u4e2a ABI \u4e0a\uff0c long \u662f 64 \u4f4d\u3002\u800c\u5728 x86_64-pc-windows-msvc \u4e0a\uff0c long \u662f 32 \u4f4d\u3002\u8fd9\u4e9b\u4fe1\u606f\u4f1a\u5f71\u54cd\u540e\u7aef\u4ea7\u751f\u6c47\u7f16\u7684\u5185\u5b58\u5e03\u5c40\uff0c\u56e0\u6b64\uff0cIR \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 target datalayout \u662f\u4e00\u4e2a\u5f88\u957f\u7684\u5b57\u7b26\u4e32\uff0c\u91cc\u9762\u6709\u591a\u4e2a\u7531 - \u5206\u9694\u7684\u5b57\u6bb5\u3002\u6bcf\u4e2a\u5b57\u6bb5\u53ef\u4ee5\u5206\u522b\u7528\u6765\u63cf\u8ff0\u6307\u9488\u3001\u6574\u578b\u3001\u6d6e\u70b9\u578b\u3001\u77e2\u91cf\u3001\u6570\u7ec4\u3001\u7ed3\u6784\u4f53\u3001\u8054\u5408\u4f53\u7b49\u7684\u5927\u5c0f\u548c\u5185\u5b58\u5e03\u5c40\u3002 \u4f8b\u5982\u4e0a\u9762\u7684 e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128 \uff0c\u6211\u4eec\u9996\u5148\u6309 - \u62c6\u5206\uff0c\u5f97\u5230\u6bcf\u4e00\u4e2a\u5b50\u5b57\u6bb5\u3002 e // \u8868\u793a\u76ee\u6807\u5e73\u53f0\u7684\u5b57\u8282\u5e8f\uff0ce=\u5c0f\u7aef\uff0cE=\u5927\u7aef m:e // \u8868\u793a C++ \u51fd\u6570\u540d\u79f0\u91cd\u7ec4\u91c7\u7528\u4f55\u79cd\u673a\u5236\uff0ce=ELF\u98ce\u683c\uff0cw=Windows\u98ce\u683c\u2026\u2026\u7b49 p270:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p271:32:32 // \u5783\u573e\u4fe1\u606f\uff0c\u65e0\u89c6 p272:64:64 // \u6307\u9488\u5927\u5c0f 64 \u4f4d\uff0c\u5bf9\u9f50\u5230 64 \u4f4d i64:64 // __int64 \u91c7\u7528 64 \u4f4d\u6765\u5b58\u50a8 i128:128 // __int128 \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 f80:128 // long double \u91c7\u7528 128 \u4f4d\u6765\u5b58\u50a8 n8:16:32:64 // \u6307\u5b9a\u54ea\u4e9b\u662f\u76ee\u6807 CPU \u539f\u751f\u7684\u7c7b\u578b\u5927\u5c0f\uff0c\u5bf9\u4e8e 64 \u4f4d x86 \u6765\u8bf4\uff0c\u5206\u522b\u6709 8 \u4f4d\u300116 \u4f4d\u300132 \u4f4d\u300164 \u4f4d\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u90fd\u5199\u4e0a S128 // \u6808\u6307\u9488\uff08rsp\uff09\u5bf9\u9f50\u5230 128 \u4f4d\uff0816 \u5b57\u8282\uff09\uff0c\u8fd9\u662f 64 \u4f4d x86 ABI \u6240\u8981\u6c42\u7684 target datalayout \u7684\u8be6\u7ec6\u8bed\u6cd5\uff0c\u53ef\u4ee5\u53c2\u8003 LLVM \u5b98\u65b9\u6587\u6863 \u3002 270\u3001271\u3001272 \u662f\u4e09\u4e2a\u679a\u4e3e\u503c\uff0c\u5206\u522b\u8868\u793a PTR32_SPTR \u3001 PTR32_UPTR \u548c PTR64 \uff0c\u8868\u793a\u4e0d\u540c\u7684\u6307\u9488\u7c7b\u578b\u3002\u524d\u4e24\u4e2a\u662f\u56e0\u4e3a x86_64 \u67b6\u6784\u4f9d\u7136\u652f\u6301\u4ee5 32 \u4f4d\u5bc4\u5b58\u5668\u505a\u5730\u5740\u8bbf\u95ee\u5185\u5b58\uff08\u975e\u5e38\u611a\u8822\u7684\u8bbe\u5b9a\uff0c\u8bf7\u5ffd\u89c6\uff09\uff0c\u540e\u9762\u7684 PTR64 \u624d\u662f\u6211\u4eec\u6b63\u5e38\u4f7f\u7528\u7684 64 \u4f4d\u6307\u9488\u3002\u679a\u4e3e\u7684\u5b9a\u4e49\u8bf7\u770b llvm/lib/Target/X86/X86.h \u3002","title":"target \u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u4fe1\u606f"},{"location":"llvm_intro/#define","text":"\u7ee7\u7eed\u770b\u4e0b\u53bb: ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { ... } \u9996\u5148\uff0c\u4ee5\u5206\u53f7\u5f00\u5934\u7684 ; Function Attrs: ... \u662f\u6ce8\u91ca\uff0c\u53ef\u4ee5\u5ffd\u7565\u3002 \u6ce8\u91ca\u91cc\u9762\u7684 mustprogress noinline ... \u7b49\uff0c\u8868\u793a\u7684\u662f\u4e0b\u9762\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u5c5e\u6027\u201d\u3002\u4f46\u662f\u6ce8\u91ca\u5e76\u6ca1\u6709\u5b9e\u9645\u6548\u679c\uff0c\u4ec5\u4ec5\u662f\u63d0\u793a\u4f5c\u7528\uff0c\u771f\u6b63\u8bbe\u7f6e\u4e86\u5c5e\u6027\u7684\u662f\u66f4\u4e0b\u9762\u7684 attributes #0 \u6307\u4ee4\uff0cClang \u751f\u6210\u4e00\u4e2a\u6ce8\u91ca\u53ea\u662f\u8ba9\u4f60\u770b\u8d77\u6765\u65b9\u4fbf\uff0c\u4e0d\u7528\u8dd1\u5230\u4e0b\u9762\u624d\u80fd\u770b\u5230\u5c5e\u6027\u3002 \u90a3\u4e48\uff0c\u53ea\u5269\u4e0b\u51fd\u6570\u7684\u5b9a\u4e49\u4e86\uff1a define dso_local noundef i32 @main() #0 { ... } define \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u51fd\u6570\u7684\u5b9a\u4e49\u3002 dso_local \u662f\u51fd\u6570 main \u7684\u4fee\u9970\u7b26\uff0c\u542b\u4e49\u76f8\u5f53\u4e8e extern \u8868\u793a\u8be5\u53d8\u91cf\u4e3a\u5bfc\u51fa\u7b26\u53f7\uff0c\u4e14\u8981\u6c42\u7b26\u5408 ODR \u89c4\u5219\u3002\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u610f\u5473\u7740\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u8bbe\u6807\u8bb0\u8be5\u51fd\u6570\u6216\u53d8\u91cf\u88ab\u89e3\u6790\u4e3a\u540c\u4e00\u94fe\u63a5\u5355\u5143\u5185\u7684\u7b26\u53f7\uff0cdso\u4ee3\u8868\u52a8\u6001\u5171\u4eab\u5bf9\u8c61\uff08dynamic shared object\uff09\uff0c\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 noundef \u662f\u8fd4\u56de\u7c7b\u578b i32 \u7684\u4fee\u9970\u7b26\uff0c\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u4f1a\u8fd4\u56de\u4e00\u4e2a\u672a\u5b9a\u4e49\u7684\u503c\uff0c\u6ce8\u610f noundef \u4fee\u9970\u7684\u662f\u53f3\u8fb9\u7684\u8fd4\u56de\u7c7b\u578b i32 \u800c\u4e0d\u662f\u51fd\u6570\u672c\u8eab\u3002\u8fd9\u4e2a\u5c5e\u6027\u53ef\u4ee5\u7528\u4e8e\u5e2e\u52a9\u7f16\u8bd1\u5668\u6392\u9664\u4e00\u4e9b\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e5f\u53ef\u4ee5\u5148\u65e0\u89c6\u3002 i32 \u8868\u793a\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\uff0c\u4e5f\u5c31\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 int \u3002 @main \u662f\u51fd\u6570\u540d\u5b57\uff0c\u5176\u4e2d @ \u662f\u6240\u6709\u51fd\u6570\u540d\u7684\u56fa\u6709\u524d\u7f00\uff0c\u540e\u9762\u7684 main \u5c31\u662f\u6211\u4eec\u5f53\u524d\u5b9a\u4e49\u7684\u51fd\u6570\u540d\u79f0\u3002 \u51fd\u6570\u540d\u5b57\u540e\u9762\u7d27\u63a5\u7740\u7684 () \u8868\u793a\u53c2\u6570\u5217\u8868\uff0c\u6b64\u5904\u6211\u4eec\u7684 main \u51fd\u6570\u521a\u597d\u6ca1\u6709\u4efb\u4f55\u53c2\u6570\uff0c\u6240\u4ee5\u662f\u4e00\u4e2a\u7a7a\u7684\u62ec\u53f7\uff08\u7a0d\u540e\u6211\u4eec\u4f1a\u770b\u4e00\u4e2a\u6709\u53c2\u6570\u7684\u6848\u4f8b\uff09\u3002 #0 \u8868\u793a\u8be5\u51fd\u6570\u7684\u7f16\u53f7\uff0c\u5c31\u548c\u5bc4\u5b58\u5668\u7f16\u53f7\u4e00\u6837\uff0c\u6240\u6709\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u4ece 0 \u5f00\u59cb\u7684\u7f16\u53f7\u3002 {} \u4e2d\u7684\u5185\u5bb9\uff0c\u5c31\u662f\u51fd\u6570\u5757\u5185\u90e8\u7684 IR \u4e86\uff0c\u8fd9\u4e9b\u662f main \u51fd\u6570\u7684\u51fd\u6570\u4f53\uff0c\u6bcf\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u5c31\u4f1a\u6267\u884c\u5176\u4e2d\u7684\u6240\u6709 IR \u8282\u70b9\u3002 \u603b\u4e4b\uff0c\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7684\u5b9a\u4e49\u4e5f\u662f\u4e00\u4e2a IR \u8282\u70b9\uff0c\u540c\u6837\u6709\u4ece 0 \u5f00\u59cb\u9012\u589e\u7684\u201c\u5bc4\u5b58\u5668\u7f16\u53f7\u201d\uff0c\u4f46\u4ed6\u5e76\u4e0d\u662f\u5bc4\u5b58\u5668\uff0c\u6240\u4ee5\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u7528 #n \u8868\u793a\uff0c\u800c\u5bc4\u5b58\u5668\u7528 %n \u8868\u793a\u3002 define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 1, ptr %1, align 4 store i32 2, ptr %2, align 4 %3 = load i32, ptr %1, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %3, %4 ret i32 %5 } \u8ba9\u6211\u4eec\u4e00\u6761\u4e00\u6761\u89e3\u6790\u51fd\u6570\u4f53\u5185\u7684\u8fd9\u4e9b IR \u8282\u70b9\u5427\uff01","title":"define \u5b9a\u4e49\u51fd\u6570"},{"location":"llvm_intro/#alloca","text":"%1 = alloca i32, align 4 %1 \u8868\u793a\u4e86\u5bc4\u5b58\u5668\u7684\u540d\u5b57\uff0c = \u53f3\u8fb9\u5c31\u662f\u8be5\u5bc4\u5b58\u5668\u7684\u5b9a\u4e49\u3002\u8fd9\u91cc\u8981\u4ecb\u7ecd LLVM IR \u7684\u4e00\u4e2a\u91cd\u8981\u89c4\u5219\uff1a\u6240\u6709\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff01\u5bc4\u5b58\u5668\u4e00\u65e6\u5b9a\u4e49\uff08\u8d4b\u503c\uff09\u8fc7\u4e00\u6b21\u540e\u5c31\u4e0d\u80fd\u518d\u4fee\u6539\uff0c\u9664\u975e\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u5bc4\u5b58\u5668\u3002\u4e3a\u4e86\u4ea7\u751f\u53ef\u4ee5\u52a8\u6001\u4fee\u6539\u7684\u53d8\u91cf\uff0cClang \u5fc5\u987b\u4f7f\u7528 alloca \u6307\u4ee4\u5206\u914d\u4e00\u5757\u201c\u6808\u5185\u5b58\u201d\uff0c\u6808\u5185\u5b58\u603b\u662f\u53ef\u8bfb\u5199\u7684\u3002 alloca \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u6808\u5185\u5b58\u5206\u914d\u6307\u4ee4\uff0c\u4ed6\u4f1a\u5728\u5f53\u524d\u51fd\u6570 main \u7684\u6808\u4e0a\u5206\u914d\u4e00\u4e2a\u7c7b\u578b\u4e3a i32 \u7684\u5185\u5b58\u7a7a\u95f4\u3002 i32 \u6307\u5b9a\u4e86\u6808\u5185\u5b58\u8981\u5206\u914d\u7684\u7c7b\u578b\u662f \u201c32 \u4f4d\u6574\u6570\u201d\u3002\u6ce8\u610f LLVM IR \u662f\u4e00\u4e2a\u6709\u7c7b\u578b\u7684 IR\uff0c\u6b64\u5904\u6211\u4eec\u9700\u8981\u6307\u5b9a\u53d8\u91cf\u7684\u5b9e\u9645\u7c7b\u578b i32 \u800c\u4e0d\u662f\u6307\u5b9a\u4e00\u4e2a 4 \u8868\u793a\u5927\u5c0f\u3002 align 4 \u8868\u793a\u8fd4\u56de\u5730\u5740\u6240\u8981\u6c42\u7684\u5bf9\u9f50\u5ea6\uff0c\u6839\u636e C \u8bed\u8a00\u89c4\u5219\u8981\u6c42\uff0c int \u7c7b\u578b\u5fc5\u987b\u5bf9\u9f50\u5230 4 \u5b57\u8282\uff0c\u56e0\u6b64\u6307\u5b9a align 4 \u3002\u5176\u4ed6\u8bed\u8a00\u82e5\u6ca1\u6709\u6b64\u89c4\u5b9a\uff0c\u4e5f\u53ef\u4ee5\u751f\u6210 align 1 \u5728 IR \u4e2d\u3002 alloca \u4f1a\u201c\u8fd4\u56de\u201d\u4e00\u4e2a\u6307\u9488\uff0c\u7528\u4e8e\u521d\u59cb\u5316 %1 \u3002\u7c7b\u578b\u662f i32* \uff08\u8fd9\u91cc\u7684 * \u548c C \u8bed\u8a00\u7684\u6307\u9488\u4e00\u6837\uff0c\u8868\u793a\u524d\u9762\u7c7b\u578b\u7684\u6307\u9488\u7c7b\u578b\uff09\uff0c\u8be5\u6307\u9488\u6307\u5411\u6808\u4e0a\u5206\u914d\u597d\u7684 i32 \u53d8\u91cf\u3002 %1 \u5bc4\u5b58\u5668\u5c31\u8fd9\u6837\u88ab\u5b9a\u4e49\u4e3a\u5b9e\u9645\u53d8\u91cf\u7684\u5730\u5740\u503c\u3002 \u8fd9\u6761 IR \u6307\u4ee4\u6267\u884c\u5b8c\u6bd5\u540e\uff0c %1 \u5bc4\u5b58\u5668\u91cc\u7684\u503c\uff0c\u5c31\u662f\u6307\u5411\u7684\u6307\u9488\u3002\u7531\u4e8e\u5bc4\u5b58\u5668\u90fd\u662f\u5e38\u91cf\uff0c %1 \u8fd9\u4e2a\u6307\u9488\u672c\u8eab\u5728\u51fd\u6570\u9000\u51fa\u524d\uff0c\u5c06\u6c38\u8fdc\u4e0d\u53d8\u3002\u4f46\u662f\u6307\u9488\u4e0d\u80fd\u53d8\uff0c\u6307\u9488\u6307\u5411\u7684\u503c\u53ef\u4ee5\u53d8\uff0c\u6240\u4ee5\u4e4b\u540e\u53ea\u9700\u8981\u4ee5\u6307\u9488\u5f62\u5f0f\u8bfb\u5199\u5176\u6307\u5411\u7684\u5730\u5740\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0\u53ef\u53d8\u7684\u53d8\u91cf\uff0c\u800c\u4e0d\u7528\u53d7\u5236\u4e8e\u5bc4\u5b58\u5668\u4e0d\u53ef\u53d8\u3002 \u5728 LLVM IR \u5c42\u9762\uff0c\u4e0d\u5b58\u5728\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \u3002\u6216\u8005\u8bf4\uff0c\u6240\u6709\u5c40\u90e8\u53d8\u91cf\u4fdd\u5b58\u7684\u672c\u6765\u5c31\u662f\u4ed6\u4eec\u7684\u5730\u5740\uff08\u901a\u8fc7 alloca \u8fd4\u56de\u7684\uff09\u3002\u6b63\u5e38\u8d4b\u503c\u548c\u8bfb\u53d6\u53d8\u91cf\u7684\u64cd\u4f5c\u90fd\u662f\u901a\u8fc7 store \u548c load \u95f4\u63a5\u901a\u8fc7\u53d8\u91cf\u7684\u6307\u9488\u6765\u4fee\u6539\u53d8\u91cf\u7684\uff0c\u5bc4\u5b58\u5668\u672c\u8eab\u4e0d\u53ef\u53d8\u3002\u5982\u679c\u4f7f\u7528\u4e86\u53d6\u5730\u5740\u8fd0\u7b97\u7b26 & \uff0c\u90a3\u4e48\u5b9e\u9645\u4e0a\u5c31\u662f\u539f\u5c01\u4e0d\u52a8\u628a\u5bc4\u5b58\u5668\u7684\u6307\u9488\u503c\u8d4b\u7ed9\u4f60\u800c\u5df2\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u5c40\u90e8\u53d8\u91cf\u7684\u7c7b\u578b\u672c\u8eab\u5c31\u662f\u6307\u9488\uff08\u6bd4\u5982 char * \uff09\uff0c\u90a3\u4e48\u901a\u8fc7 alloca i8* \u5b9a\u4e49\u7684\u5bc4\u5b58\u5668\u7684\u7c7b\u578b\u5c31\u4f1a\u662f\u4e00\u4e2a\u4e8c\u7ea7\u6307\u9488\uff08 i8** \uff09\u3002 C++ \u5f15\u7528\u5728 LLVM IR \u5c42\u9762\u540c\u6837\u4e5f\u4f1a\u53d8\u6210\u6307\u9488\u7c7b\u578b\u7684\u53d8\u91cf\u3002\u6ce8\u610f\uff0c\u6211\u53ea\u662f\u8bf4 C++ \u5f15\u7528\u548c\u6307\u9488\u4f1a\u5728 LLVM \u4e2d\u4f1a\u540c\u6837\u53d8\u6210\u6307\u9488\u7c7b\u578b\uff0c\u5e76\u4e0d\u662f\u8bf4\u5728 Clang \u524d\u7aef\u91cc\u5f15\u7528\u548c\u6307\u9488\u6ca1\u533a\u522b\u3002 \u6240\u4ee5\uff0c\u8fd9\u91cc\u7684 %1 \u548c %2 \u5176\u5b9e\u662f\u5bf9\u5e94\u6e90\u7801\u4e2d\u7684 a \u548c b \u53d8\u91cf\uff08\u7684\u6307\u9488\uff09\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e int * %1 = alloca(4) \u3002","title":"alloca \u6307\u4ee4"},{"location":"llvm_intro/#store","text":"\u7ee7\u7eed\u63a5\u7740\u770b\uff1a store i32 1, ptr %1, align 4 \u8fd9\u662f\u4e00\u6761 store \u6307\u4ee4\u3002 \u6307\u4ee4\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570 i32 1 \u8868\u793a\u8981\u5b58\u5165\u7684\u503c\uff0c\u8fd9\u91cc\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u5e38\u6570 1 \u3002LLVM IR \u4e2d\u6307\u4ee4\u6240\u6709\u7684\u53c2\u6570\u90fd\u9700\u8981\u5728\u524d\u9762\u6307\u5b9a\u7c7b\u578b\u540d\uff0c\u6211\u4eec\u8981\u5199\u5165\u7684 a \u53d8\u91cf\u662f int \u4e5f\u5c31\u662f i32 \u7c7b\u578b\uff0c\u6240\u4ee5\u7528 i32 \u4fee\u9970\u8981\u5199\u5165\u7684\u503c 1 \u3002 \u7b2c\u4e8c\u4e2a\u53c2\u6570 ptr %1 \u8868\u793a\u8981\u5199\u5165\u5230\u7684\u5730\u5740\uff0c\u5fc5\u987b\u662f\u6307\u9488\u7c7b\u578b\u3002\u8fd9\u91cc\u7684 ptr \u662f i32* \u7684\u7b80\u5199\uff0c\u7b49\u4ef7\u4e8e i32* %1 \u3002\u7531\u4e8e\u521a\u624d %1 \u5b9a\u4e49\u4e3a alloca \uff0c\u4e5f\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\u4e86\u4e00\u4e2a\u53d8\u91cf\uff08C++ \u6e90\u7801\u4e2d\u7684 a \uff09\u3002 %1 \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u5176\u503c\u662f a \u7684\u5730\u5740\u3002\u6240\u4ee5\u6b64\u5904 store \u7684\u6548\u679c\u662f\u5f80\u53d8\u91cf a \u4e2d\u5199\u5165\u4e86\u4e00\u4e2a\u5e38\u6570 1 \u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 alloca \u548c\u7d27\u63a5\u7740\u7684 store \u8fd9\u4e24\u6761\u6307\u4ee4\uff0c\u8fde\u8d77\u6765\uff0c\u5c31\u662f\u5728\u6808\u4e0a\u5206\u914d\uff08 alloca \uff09\u4e86\u4e00\u4e2a\u53d8\u91cf a \u4e4b\u540e\uff0c\u5411\u5176\u4e2d\u8d4b\u4e86\u4e00\u4e2a\u521d\u59cb\u503c 0 \u3002 \u6ce8\u610f\u5230\uff0c store \u5e76\u6ca1\u6709\u7528\u4e8e\u5b9a\u4e49\u4e00\u4e2a\u5bc4\u5b58\u5668\uff08\u4f8b\u5982 %1 = store ... \uff09\u3002 store \u6307\u4ee4\u6ca1\u6709\u201c\u8fd4\u56de\u503c\u201d\uff0c\u56e0\u6b64\u4ed6\u4e0d\u4f1a\u5b9a\u4e49\u4efb\u4f55\u5bc4\u5b58\u5668\uff1b store \u672c\u8eab\u662f\u56e0\u4e3a\u5176\u5199\u5165\u4ea7\u751f\u7684\u526f\u4f5c\u7528\u800c\u5b58\u5728\uff0c\u4e0d\u9700\u8981\u6709\u4eba\u201c\u4f7f\u7528\u201d\u4ed6\u7684\u503c\u3002 \u56e0\u4e3a\u6709\u526f\u4f5c\u7528\uff0c store \u5c31\u4e0d\u80fd\u7b80\u5355\u5730\u88ab def-use \u5206\u6790 pass \u4f18\u5316\u6389\u4e86\uff0c\u6240\u4ee5\u9700\u8981\u5148\u8fc7\u4e00\u4e2a mem2reg pass \u628a\u80fd\u8f6c\u5316\u6389\u7684 store \u5c3d\u53ef\u80fd\u8f6c\u6210\u5bb9\u6613\u4f18\u5316\u7684\u5bc4\u5b58\u5668\u3002 %1 = alloca i32, align 4 ; int a %2 = alloca i32, align 4 ; int b store i32 1, ptr %1, align 4 ; a = 1 store i32 2, ptr %2, align 4 ; a = 2 \u603b\u4e4b\uff0c\u8fd9\u7b49\u4ef7\u4e8e *%1 = 1 \u3002","title":"store \u6307\u4ee4"},{"location":"llvm_intro/#_20","text":"\u5982\u679c\u4f60\u53ea\u662f alloca \uff0c\u800c\u6ca1\u6709\u5f80\u91cc\u9762 store \u8d4b\u503c\u8fc7\u7684\u8bdd\uff0c\u90a3\u4e48\u8be5\u6808\u53d8\u91cf\u7684\u503c\u662f\u201c\u672a\u5b9a\u4e49\u503c\u201d\uff0c\u5728 C++ \u6807\u51c6\u4e2d\uff0c\u8bbf\u95ee\uff08 load \uff09\u4e00\u4e2a\u201c\u672a\u5b9a\u4e49\u503c\u201d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4f8b\u5982\uff1a int a; return a; // \u9519\u8bef\uff1aa \u672a\u521d\u59cb\u5316\uff0c\u91cc\u9762\u7684\u503c\u662f\u672a\u5b9a\u4e49\u503c\uff01 \u8bfb\u53d6\u6ca1\u6709\u521d\u59cb\u5316\u8fc7\u7684\u6808\u53d8\u91cf\uff0c\u5728 x86 \u548c ARM \u7b49\u5177\u4f53\u67b6\u6784\u4e2d\uff0c\u4f60\u53ef\u80fd\u4f1a\u8bfb\u5230\u5185\u5b58\u4e2d\u7684\u968f\u673a\u53d8\u91cf\u3002 \u5728 LLVM \u4e2d\uff0c\u8fd9\u7c7b\u5904\u4e8e\u672a\u521d\u59cb\u5316\u72b6\u6001\u7684\u503c\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u540d\u5b57\uff0c\u53eb\u201c\u6bd2\u503c\u201d\uff08poison value\uff09\u3002 \u6bd2\u503c\u4e0d\u662f C++ \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f\u786c\u4ef6\u67b6\u6784\u7684\u4e00\u90e8\u5206\uff0c\u800c\u662f LLVM \u4e2d\u7aef\u4eba\u4e3a\u5b9a\u4e49\u7684\uff08\u56e0\u4e3a\u5f88\u591a\u7cfb\u7edf\u7ea7\u8bed\u8a00\u90fd\u6709\u652f\u6301\u672a\u521d\u59cb\u5316\u7684\u5185\u5b58\uff0c\u77e5\u9053\u54ea\u4e9b\u503c\u662f\u4e0d\u53ef\u80fd\u7684\u6709\u52a9\u4e8e LLVM \u4f18\u5316\uff09\u3002 \u201c\u6bd2\u503c\u201d\u5e76\u4e0d\u662f\u968f\u673a\u503c\uff0c\u4ed6\u662f i32 \u8868\u793a\u7a7a\u95f4\u4e4b\u5916\u7684\u4e00\u4e2a\u7279\u6b8a\u503c\uff0c\u4e0d\u662f\u88ab 0 \u5230 4294967295 \u8303\u56f4\u5185\u7684\u4efb\u4f55\u6574\u6570\uff0c\u800c\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u7528\u4e8e\u6807\u8bc6\u201c\u672a\u5b9a\u4e49\u884c\u4e3a\u201d\u7684\u4e00\u4e2a LLVM \u4e2d\u624d\u6709\u7684\u62bd\u8c61\u6982\u5ff5\uff0c\u610f\u601d\u662f\u201c\u8fd9\u4e2a\u503c\u73b0\u5728\u4e0d\u80fd\u4f7f\u7528\u201d\u3002\u53ea\u4e0d\u8fc7\u5728\u8f6c\u6362\u4e3a\u5177\u4f53\u67b6\u6784\u7684\u6c47\u7f16\u4ee3\u7801\u540e\u5f80\u5f80\u4f1a\u53d8\u6210\u201c\u968f\u673a\u503c\u201d\u8fd9\u4e00\u5177\u4f53\u5b9e\u73b0\uff0c\u4f9d\u8d56\u8fd9\u4e00\u70b9\u7684\u540e\u679c\u662f\u672a\u5b9a\u4e49\u7684\u3002\uff08\u4f8b\u5982\u4f60\u4e0d\u80fd\u7528\u4e00\u4e2a\u201c\u672a\u521d\u59cb\u5316\u53d8\u91cf\u201d\u751f\u6210\u968f\u673a\u6570\uff0c\u5728\u9ad8\u4f18\u5316\u4e0b\u53ef\u80fd\u4ea7\u751f\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u800c\u4e14\u4e5f\u5e76\u4e0d\u4e00\u5b9a\u591f\u968f\u673a\uff09 \u6bd2\u503c\u7684\u7279\u70b9\uff1a alloca \u540e\u6ca1\u6709 store \u8fc7\u7684\u6808\u53d8\u91cf\u521d\u59cb\u5c31\u662f\u4e3a\u6bd2\u503c\u3002\u5982\u679c\u5c1d\u8bd5\u76f4\u63a5 load \u8fd9\u4e2a\u5730\u5740\uff0c\u90a3\u4e48 load \u8fd4\u56de\u7684\u5bc4\u5b58\u5668\u5c31\u548c\u521d\u59cb\u5316\u4e3a\u201c\u6bd2\u503c\u201d\u3002 \u6bd2\u503c\u4f1a\u611f\u67d3\u6240\u6709\u201c\u4f7f\u7528\u201d\u4e86\u4ed6\u7684\u5bc4\u5b58\u5668\u3002\u4f8b\u5982 %1 \u662f\u6bd2\u503c\uff0c\u90a3\u4e48 %2 = add %1, 1 \u4e5f\u662f\u6bd2\u503c\uff0c\u56e0\u4e3a %2 \u201c\u4f7f\u7528\u201d\u4e86\u7684 %1 \u662f\u6bd2\u503c\u3002 \u6807\u8bb0\u4e3a noundef \u7c7b\u578b\u7684\u53d8\u91cf\uff08\u4f8b\u5982 noundef i32 \uff09\uff0c\u5fc5\u987b\u4e0d\u80fd\u662f\u6bd2\u503c\uff0c\u5426\u5219\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982\uff0c\u4e00\u4e2a\u8fd4\u56de\u7c7b\u578b\u6807\u8bb0\u4e3a noundef \uff08\u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5e94\u8fd4\u56de\u6bd2\u503c\uff09\u7684\u51fd\u6570\u8fd4\u56de\u4e86\u6bd2\u503c\uff0c\u90a3\u4e48\u5c31\u89e6\u53d1\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\u3002","title":"\u5c0f\u77e5\u8bc6\uff1a\u672a\u5b9a\u4e49\u503c\uff08\u6bd2\u503c\uff09"},{"location":"llvm_intro/#load","text":"%3 = load i32, ptr %1, align 4 ; \u52a0\u8f7d a %4 = load i32, ptr %2, align 4 ; \u52a0\u8f7d b load \u6307\u4ee4\u4ece\u5185\u5b58\u7684\u6307\u5b9a\u5730\u5740\u5904\u52a0\u8f7d\u4e00\u4e2a\u6307\u5b9a\u7c7b\u578b\u7684\u6570\u636e\uff0c\u8bfb\u53d6\u5230\u5bc4\u5b58\u5668\u4e2d\u3002 \u5206\u522b\u662f\u5bf9\u5e94\u52a0\u8f7d a \u548c b \u8fd9\u4e24\u4e2a\u53d8\u91cf\uff0c\u6765\u770b\u52a0\u8f7d a \u7684\u8fd9\u6761\u6307\u4ee4\uff1a %3 = load i32, ptr %1, align 4 i32 \u8868\u793a\u52a0\u8f7d\u4e00\u4e2a 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u8fd9\u4f1a\u628a = \u524d\u9762\u7684\u5bc4\u5b58\u5668 %3 \u5b9a\u4e49\u4e3a i32 \u7c7b\u578b\u7684\u3002 ptr %1 \u8868\u793a\u8981\u52a0\u8f7d\u7684\u5185\u5b58\u5730\u5740\uff0c\u6b64\u5904\u5730\u5740\u901a\u8fc7 %1 \u5bc4\u5b58\u5668\u6307\u5b9a\uff0c\u800c %1 \u88ab\u5b9a\u4e49\u4e3a alloca i32 \uff0c\u4e5f\u5c31\u662f\u4e00\u4e2a\u6808\u53d8\u91cf\u7684\u6307\u9488\uff0c\u6240\u4ee5\u6b64\u5904 load i32, ptr %1 \u5c31\u662f\u5728\u52a0\u8f7d\u8fd9\u4e2a\u6808\u53d8\u91cf\u7684\u503c\u3002 \u6ce8\u610f\u8fd9\u91cc\u7684\u53c2\u6570\u6307\u9488 %1 \u5fc5\u987b\u662f\u4e0e\u8981\u52a0\u8f7d\u7c7b\u578b i32 \u5bf9\u5e94\u7684\u6307\u9488\u7c7b\u578b i32* \uff0c\u800c alloca i32 \u8fd4\u56de\u7684\u6070\u597d\u662f i32* \u7c7b\u578b\u7684\u6307\u9488\uff0c\u7b26\u5408\u8981\u6c42\u3002 \u6b64\u5904 ptr %1 \u5b9e\u9645\u4e0a\u662f i32* %1 \u7684\u7b80\u5199\uff0c ptr \u662f\u4e00\u4e2a\u8bed\u6cd5\u7cd6\uff0c\u56e0\u4e3a\u524d\u9762 load i32 \u5df2\u7ecf\u6307\u5b9a\u4e86\u8981\u52a0\u8f7d\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u5177\u4f53\u7684\u6307\u9488\u7c7b\u578b i32* \u53ef\u4ee5\u7701\u7565\uff0c\u7528 ptr \u4ee3\u66ff\u3002 \u7b2c\u4e09\u4e2a\u53c2\u6570 align 4 \u544a\u8bc9\u7f16\u8bd1\u5668\u53ef\u4ee5\u5047\u5b9a ptr %1 \u662f\u5bf9\u9f50\u5230 4 \u5b57\u8282\u7684\uff0c\u63d0\u4f9b\u8be5\u4fe1\u606f\u6709\u52a9\u4e8e\u4e4b\u540e\u77e2\u91cf\u5316 pass \u7684\u4f18\u5316\u3002 \u7531\u4e8e\u4e4b\u524d\u5df2\u7ecf\u5f80 ptr %1 \u6307\u5411\u7684\u5730\u65b9\uff08\u5c40\u90e8\u53d8\u91cf a \uff09\u91cc store \u8fc7\u6574\u6570\u503c 1 \u4e86\uff0c\u6240\u4ee5\u8fd9\u91cc load \u51fa\u6765\u4e5f\u4f1a\u662f 1 \u3002 \u8fd9\u6837\u91cd\u590d\u7684 store \u548c load \u4f1a\u88ab\u540e\u7eed\u7684 LLVM \u4f18\u5316\u6389\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u7684 clang \u6ca1\u6709\u5f00\u542f\u4f18\u5316\uff08\u9ed8\u8ba4 -O0 \uff09\uff0c\u6240\u4ee5\u4f9d\u7136\u4fdd\u6301\u539f\u59cb\u7684 store \u548c load \u91cd\u590d\u52b3\u52a8\uff0c\u5fe0\u5b9e\u590d\u523b\u539f\u672c\u7684 C++ \u4ee3\u7801\u8bed\u4e49\u3002 \u56e0\u4e3a\u5f88\u591a\u8c61\u7259\u5854\u7262\u6e7f\u8981\u4e48\u201c\u547d\u4ee4\u884c\u8c03\u7528\u7f16\u8bd1\u201d\uff0c\u8981\u4e48 IDE \u662f\u9ed8\u8ba4\u7684\u201cDebug\u201d\u6a21\u5f0f\uff0c\u5b83\u4eec\u4e0d\u77e5\u9053\u53ef\u4ee5\u901a\u8fc7 -O \u9009\u9879\u5f00\u542f\u4f18\u5316\uff0c\u751a\u81f3\u6709\u4eba\u8ba4\u4e3a\u201c\u4f18\u5316\u201d\u662f\u4e0d\u6807\u51c6\u7684\uff0c\u8ba4\u4e3a\u4e0d\u5f00\u4f18\u5316\u7684 C++ \u624d\u80fd\u6d4b\u5f97\u771f\u5b9e\u6027\u80fd\u3002\u800c\u5b83\u4eec\u5bf9\u7f16\u8bd1\u5668\u7684\u7406\u89e3\u53c8\u662f\u7c97\u7cd9\u7684\u201c\u6ca1\u6709 AST\uff0c\u6ca1\u6709 IR\uff0c\u524d\u7aef\u89e3\u6790\u7684\u8fc7\u7a0b\u4e2d\u76f4\u63a5\u751f\u6210\u6c47\u7f16\u4ee3\u7801\u201d\uff0c\u6240\u4ee5\u624d\u4f1a\u628a C++ \u51fd\u6570\u5c40\u90e8\u53d8\u91cf\u548c\u4e00\u4e9b CPU \u540e\u7aef\u5177\u4f53\u5b9e\u73b0\u4e2d\u7684\u201c\u6808\u201d\u6df7\u4e3a\u4e00\u8c08\u3002\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u51fd\u6570\u4f53\u5185\u5b9a\u4e49\u7684\u5c40\u90e8\u53d8\u91cf\uff08\u5f8b\u5e08\u7684\u8bf4\u6cd5\u662f\u201c\u81ea\u52a8\u5b58\u50a8\u5468\u671f\u53d8\u91cf\u201d\uff0c\u5f97\u540d\u4e8e\u51fd\u6570\u4f5c\u7528\u57df\u9000\u51fa\u65f6\u4f1a\u81ea\u52a8\u6790\u6784\u548c\u91ca\u653e\u5185\u5b58\uff09\uff0c\u90fd\u53ef\u4ee5\u88ab\u4f18\u5316\u5230\u5bc4\u5b58\u5668\u4e2d\u3002\u8fd8\u6709\u4e00\u4e9b GPU \u76ee\u6807\u67b6\u6784\uff0c\u4f8b\u5982\u5728 CUDA \u4e2d\uff0c\u786c\u4ef6\u5bc4\u5b58\u5668\u6570\u91cf\u6781\u591a\uff0c\u5c40\u90e8\u53d8\u91cf\u51e0\u4e4e\u603b\u662f\u53ef\u4ee5\u653e\u5230\u5728\u5bc4\u5b58\u5668\u4e0a\uff0c\u751a\u81f3\u5c40\u90e8\u6570\u7ec4\u53d8\u91cf\uff08\u5982\u679c\u4e0b\u6807\u8bbf\u95ee\u90fd\u662f\u5e38\u6570\uff09\u4e5f\u53ef\u4ee5\u653e\u5230\u5bc4\u5b58\u5668\u4e0a\u3002\u8981\u662f\u4e0d\u5f00\u5bc4\u5b58\u5668\u4f18\u5316\u5c31\u5168\u90e8\u8981\u6253\u7ffb\u5230\u5168\u5c40\u5185\u5b58\u4e86\uff0c\u4f1a\u53d8\u5f97\u548c\u5168\u5c40\u5185\u5b58\u4e00\u6837\u6162\uff01\u6240\u4ee5 nvcc \u54ea\u6015\u4e0d\u5f00 -O \u7684\u60c5\u51b5\u4e0b\u4e5f\u4f1a\u5c1d\u8bd5\u628a\u5c40\u90e8\u53d8\u91cf\u4f18\u5316\u5230\u786c\u4ef6\u5bc4\u5b58\u5668\u91cc\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %3 = *%1 \u3002","title":"load \u6307\u4ee4"},{"location":"llvm_intro/#add","text":"%5 = add nsw i32 %3, %4 LLVM \u4e2d\u6709\u52a0\u51cf\u4e58\u9664\u7684\u6307\u4ee4\uff0c\u5176\u4e2d add \u5c31\u662f\u5176\u4e2d\u8d1f\u8d23\u6574\u6570\u52a0\u6cd5\u8fd0\u7b97\u7684\u6307\u4ee4\uff0c\u4ed6\u63a5\u53d7\u4e24\u4e2a\u64cd\u4f5c\u6570\u505a\u53c2\u6570\u3002 add \u8868\u793a\u8fd9\u662f\u4e00\u6761\u52a0\u6cd5\u8fd0\u7b97\u6307\u4ee4\u3002 nsw \u662f\u4e00\u4e2a\u4fee\u9970\u7b26\uff0c\u53ef\u4ee5\u5148\u5ffd\u7565\u4e0d\u7ba1\u3002 i32 \u8868\u793a\u52a0\u6cd5\u64cd\u4f5c\u7684\u7c7b\u578b\u662f 32 \u4f4d\u6574\u6570\u7c7b\u578b\uff0c\u5728\u8fdb\u884c\u52a0\u6cd5\u524d\uff0c\u5fc5\u987b\u5148\u628a\u4e24\u8fb9\u7684\u6574\u6570\u7c7b\u578b\u8f6c\u6362\u5230\u76f8\u540c\u7684\u7c7b\u578b\uff0c\u5426\u5219\u65e0\u6cd5\u76f8\u52a0\u3002 %3, %4 \u8868\u793a\u4e86\u52a0\u6cd5\u7684\u4e24\u4e2a\u64cd\u4f5c\u6570\uff0c\u8fd9\u4e24\u4e2a\u6570\u4f1a\u88ab\u52a0\u8d77\u6765\uff0c\u7ed3\u679c\u5b58\u5230 %5 \u5bc4\u5b58\u5668\u4e2d\u3002 \u603b\u4e4b\uff0c\u7b49\u4ef7\u4e8e %5 = %3 + %4 \u3002 \u5728 Clang \u524d\u7aef\u4e2d\uff0c\u5982\u679c\u53d1\u73b0\u4e24\u8fb9\u7684\u7c7b\u578b\u5927\u5c0f\u4e0d\u540c\uff1a\u4f1a\u5148\u7528 sext \uff08\u6709\u7b26\u53f7\u6269\u5c55\uff09\u6216 zext \uff08\u65e0\u7b26\u53f7\u6269\u5c55\uff09\u6307\u4ee4\uff0c\u628a\u8f83\u5c0f\u90a3\u8fb9\u7684\u7c7b\u578b\uff0c\u8f6c\u6362\u5230\u4e24\u8005\u4e4b\u95f4\u6700\u5927\u7684\u90a3\u4e2a\u7c7b\u578b\u3002\u7136\u540e\u518d\u505a\u52a0\u6cd5\u3002\u5bf9\u4e8e\u6d6e\u70b9\u6570\u548c\u6574\u6570\u76f8\u52a0\u7684\u60c5\u51b5\uff0c\u5219\u662f\u5148\u628a\u6574\u6570\u8f6c\u6362\u4e3a\u6d6e\u70b9\u6570\u540e\u518d\u8c03\u7528\u6d6e\u70b9\u6570\u52a0\u6cd5 fadd \u3002\u603b\u4e4b\uff0cLLVM IR \u91cc\u6240\u6709\u7684\u6570\u5b66\u8fd0\u7b97\u6307\u4ee4\u90fd\u53d1\u751f\u5728\u76f8\u540c\u7c7b\u578b\u4e4b\u95f4\u3002 \u5bf9\u4e8e\u597d\u5947\u5b9d\u5b9d\uff1a nsw \u8868\u793a no signed wrap\uff0c\u610f\u601d\u662f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u8fd9\u4e2a\u662f\u6709\u7b26\u53f7\u52a0\u6cd5\uff0c\u5e76\u4e14\u4fdd\u8bc1\u4e0d\u4f1a\u6ea2\u51fa\u3002\u4e3a\u4ec0\u4e48\u4e0d\u4f1a\u6ea2\u51fa\uff1f\u56e0\u4e3a C++ \u6807\u51c6\u89c4\u5b9a\u201c\u6709\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u52a0\u6cd5\u5982\u679c\u53d1\u751f\u6ea2\u51fa\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u56de\u73af\uff08wrap\uff09\u201d\uff0c\u6240\u4ee5 Clang \u628a\u8fd9\u4e2a\u4fe1\u606f\u544a\u8bc9 LLVM \u540e\u7aef\uff0c\u7528\u6237\u8fd9\u4e2a\u52a0\u6cd5\u5982\u679c\u6ea2\u51fa\u4e86\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cLLVM \u53ef\u4ee5\u5229\u7528\u8fd9\u4e00\u70b9\u6765\u4f18\u5316\uff01\u6362\u53e5\u8bdd\u8bf4\uff1a nsw \u8868\u793a\u5de6\u53f3\u4e24\u4e2a i32 \u4f5c\u4e3a\u6709\u7b26\u53f7\u6570\u76f8\u52a0\u5982\u679c\u6ea2\u51fa\u4f1a\u8fd4\u56de\u201c\u6bd2\u503c\u201d\u3002\u4f46\u662f C++ \u6807\u51c6\u53c8\u89c4\u5b9a\u65e0\u7b26\u53f7\u6574\u6570\u7c7b\u578b\u6ea2\u51fa\u662f\u5fc5\u5b9a\u56de\u73af\uff0c\u4e0d\u4f1a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6240\u4ee5\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u770b\u628a int \u66ff\u6362\u4e3a unsigned int \uff0c\u4f60\u4f1a\u53d1\u73b0 nsw \u6ca1\u4e86\uff0c\u56e0\u4e3a Clang \u77e5\u9053 C++ \u6807\u51c6\u5141\u8bb8 unsigned int \u52a0\u6cd5\u51fa\u73b0\u56de\u73af\u3002\u53e6\u5916\uff0c\u5982\u679c\u4f7f\u7528 Rust \u7684 i32 \u52a0\u6cd5\uff0c\u4e5f\u4f1a\u6ca1\u6709 nsw \uff0c\u56e0\u4e3a Rust \u6807\u51c6\u89c4\u5b9a\u6574\u6570\u65e0\u8bba\u6709\u6ca1\u6709\u7b26\u53f7\uff0c\u5176\u52a0\u6cd5\u6ea2\u51fa\u603b\u662f\u56de\u73af\uff0c\u4e0d\u4f1a\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u90a3\u4e48 LLVM \u540e\u7aef\u6536\u5230 Rust \u7f16\u8bd1\u5668\u4ea7\u751f\u7684 IR \u540e\uff0c\u5c31\u4e0d\u4f1a\u5047\u5b9a\u52a0\u6cd5\u4e0d\u4f1a\u6ea2\u51fa\u6765\u4f18\u5316\u4e86\u3002 \u8fd9\u6761\u6307\u4ee4\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 a + b \u8868\u8fbe\u5f0f\uff0c\u7528\u4e8e\u8ba1\u7b97\u4e24\u4e2a\u53d8\u91cf\u7684\u548c\uff0c\u8ba1\u7b97\u7ed3\u679c\u5b58\u5165 %5 \u5bc4\u5b58\u5668\u3002","title":"add \u6307\u4ee4"},{"location":"llvm_intro/#ret","text":"ret i32 %5 ret \u8868\u793a\u51fd\u6570\u8fd4\u56de\u3002\u901a\u5e38\u51fa\u73b0\u5728\u51fd\u6570\u7684\u672b\u5c3e\uff0c\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return \u8bed\u53e5\u3002 \u5982\u679c\u51fd\u6570\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \uff0c\u5219\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u8fd4\u56de\u503c\uff08\u4ee5\u5e38\u6570\u6216\u5bc4\u5b58\u5668\u7684\u5f62\u5f0f\uff09\u3002\u4f8b\u5982\u8fd9\u91cc\u6307\u5b9a\u7684 ret i32 %5 \u5c31\u8868\u793a\u51fd\u6570\u4f1a\u8fd4\u56de\u5bc4\u5b58\u5668 %5 \u7684\u503c\u3002 \u800c %5 \u5c31\u662f\u521a\u624d\u6211\u4eec add \u6307\u4ee4\u7684\u8fd0\u7b97\u7ed3\u679c\uff0c\u6240\u4ee5 ret \u548c add \u8fd9\u4e24\u6761\u6307\u4ee4\u5c31\u5bf9\u5e94\u4e8e C++ \u4e2d\u7684 return a + b \u3002 \u548c store \u4e00\u6837\uff0c ret \u4e5f\u662f\u4e00\u6761\u65e0\u5bc4\u5b58\u5668\u5b9a\u4e49\u7684\u6307\u4ee4\u3002 \u901a\u5e38\u6765\u8bf4\u4f1a\u662f ret i32 0 \uff0c\u8868\u793a return 0 \u3002","title":"ret \u6307\u4ee4"},{"location":"llvm_intro/#attributes","text":"\u6ce8\u610f\u5230\u51fd\u6570\u5b9a\u4e49\u540e\u9762\u6709 attributes \u6307\u4ee4\uff1a define dso_local noundef i32 @main() #0 { ... } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } \u4f5c\u7528\u662f\u4e3a\u51fd\u6570\u8d4b\u4e88\u5c5e\u6027\u503c\uff0c\u5c5e\u6027\u90fd\u662f\u51fd\u6570\u5b9a\u4e49\u540e\u8d4b\u4e88\u7684\uff0c\u7528 #0 \u6765\u5f15\u7528\u4e4b\u524d\u5b9a\u4e49\u7684\u51fd\u6570 main \u3002 \u683c\u5f0f\u4e3a attributes #\u51fd\u6570\u7f16\u53f7 = { \u5c5e\u6027\u5217\u8868... } \u5c5e\u6027\u5217\u8868\u53ef\u4ee5\u662f noinline \u8fd9\u6837\u7684\u5355\u6761\u5c5e\u6027\uff0c\u4e5f\u53ef\u4ee5\u662f\u5e26\u503c\u53c2\u6570\u7684\uff0c\u4f8b\u5982 \"target-cpu\"=\"x86-64\" \u3002 \u73b0\u5728\u6765\u89e3\u91ca\u5176\u4e2d\u91cd\u8981\u7684\u5c5e\u6027\uff1a mustprogress \u8868\u793a\u5fc5\u5b9a\u524d\u8fdb\u5047\u8bbe\uff0c\u8fd9\u662f C++ \u672a\u5b9a\u4e49\u884c\u4e3a\u89c4\u5b9a\u4e2d\u7684\u4e00\u6761\uff0c\u8981\u6c42\u7a0b\u5e8f\u4e00\u76f4\u5904\u4e8e\u201c\u8fdb\u5c55\u201d\u3002\u610f\u601d\u662f\u4e0d\u5f97\u51fa\u73b0\u65e0\u526f\u4f5c\u7528\u7684\u6b7b\u5faa\u73af\uff0c\u5426\u5219\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4f8b\u5982 while (true) {} \u662f\u4e0d\u5141\u8bb8\u7684\uff1b\u4f46\u662f while (true) { volatile int i = 0; } \u5c31\u53ef\u4ee5\uff0c\u56e0\u4e3a volatile \u53d8\u91cf\u7684\u521d\u59cb\u5316\u88ab\u89c6\u4e3a\u526f\u4f5c\u7528\uff1b while (true) { cin >> i; } \u4e5f\u53ef\u4ee5\uff0c\u56e0\u4e3a cin \u5c5e\u4e8e IO \u64cd\u4f5c\uff0c\u662f\u6709\u5bf9\u5916\u754c\u73af\u5883\u9020\u6210\u526f\u4f5c\u7528\u7684\u3002\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48 clang++ \u5f00\u7740\u4f18\u5316\u7f16\u8bd1 while (1); \u65f6\u4f1a\u4ea7\u751f\u53cd\u5e38\u7684\u6c47\u7f16\u7ed3\u679c\uff0c\u800c clang \u4e0d\u4f1a\u3002\u56e0\u4e3a\u53ea\u6709 C++ \u6807\u51c6\u8981\u6c42\u4e86\u201c\u5fc5\u5b9a\u524d\u8fdb\u201d\uff0c\u800c C \u6807\u51c6\u6ca1\u6709\u3002 C++ \u6807\u51c6\u59d4\u5458\u4f1a\uff1a\u524d\u8fdb\uff0c\u4f60\u4eec\u53ea\u80fd\u524d\u8fdb\uff0c\u4e0d\u62e9\u624b\u6bb5\u7684\u524d\u8fdb\uff08\u5b5d\u55b7\uff09 noinline \u6307\u5b9a\u4e86\u8be5\u51fd\u6570\u4e0d\u5f97\u88ab\u5185\u8054\u4f18\u5316\uff0c\u56e0\u4e3a\u6211\u4eec\u662f main \u51fd\u6570\uff0c\u662f\u6ce8\u5b9a\u4e0d\u80fd\u88ab\u5185\u8054\u7684\uff0c\u6240\u4ee5 Clang \u81ea\u52a8\u52a0\u4e0a\u4e86\u8fd9\u6761\u5c5e\u6027\u3002 optnone \u8868\u793a\u8be5\u51fd\u6570\u4e0d\u5141\u8bb8\u4f18\u5316\u3002\u4e0d\u5f00\u542f\u4f18\u5316\uff08 -O0 \uff09\u65f6\uff0cClang \u4f1a\u81ea\u52a8\u4e3a\u6240\u6709\u51fd\u6570\u52a0\u4e0a optnone \u5c5e\u6027\u3002 LLVM \u4e2d\u7aef\u4e00\u65e6\u770b\u5230\u5e26\u6709 optnone \u5c5e\u6027\u7684\u51fd\u6570\uff0c\u4f1a\u8df3\u8fc7\u7edd\u5927\u90e8\u5206\u4f18\u5316 pass\u3002\u53ea\u4fdd\u7559\u6781\u5c11\u4e00\u90e8\u5206\u5fc5\u8981\u7684\u8f6c\u6362 pass\uff0c\u4f8b\u5982\u201c\u6307\u4ee4\u9009\u62e9\u201d\u548c\u201c\u5bc4\u5b58\u5668\u5206\u914d\u201d\u5c31\u4e0d\u4f1a\u88ab optnone \u5c4f\u853d\u3002\u6240\u4ee5\uff0cLLVM \u4e2d\u7aef\u4e2d\u4e00\u4e2a pass \u662f\u4f18\u5316\u6027\u8d28\u7684\u8fd8\u662f\u8f6c\u6362\u6027\u8d28\u7684\uff0c\u5c31\u53ef\u4ee5\u4ece\u4ed6\u662f\u5426\u4f1a\u88ab optnone \u5c4f\u853d\u770b\u51fa\u3002 \u53ea\u6709\u5168\u5c40\u5f00\u542f\u4e86 -O \u9009\u9879\u540e\uff0c\u6216\u662f\u4e3a\u5f53\u524d\u51fd\u6570\u6307\u5b9a\u4e86 __attribute__((optimize(\"-O\"))) \u8fd9\u4e00\u7279\u6b8a\u6269\u5c55\u8bed\u6cd5\u540e\uff0cClang \u624d\u4f1a\u53bb\u9664\u51fd\u6570\u7684 optnone \u5c5e\u6027\uff0c\u8ba9 LLVM \u4e2d\u7aef\u7684\u4f18\u5316 pass \u5f97\u4ee5\u5bf9\u8be5\u51fd\u6570\u751f\u6548\u3002","title":"\u4e3a\u51fd\u6570\u6307\u5b9a attributes"},{"location":"llvm_intro/#clang-ir","text":"\u6211\u4eec\u7f16\u5199\u4e00\u6bb5\u7b80\u5355\u7684 C++ \u201c\u4f60\u597d\uff0c\u4e16\u754c\u201d\u4ee3\u7801\uff1a #include int main() { printf(\"Hello, world!\"); return 0; } \u6307\u5b9a -S -emit-llvm \u9009\u9879\uff0c\u5c31\u53ef\u4ee5\u8ba9 clang \u751f\u6210 IR \u6c47\u7f16\u4f9b\u4f60\u67e5\u770b\u4e86\uff08 -o \u53ef\u4ee5\u6307\u5b9a\u8f93\u51fa\u5230\u7684\u6587\u4ef6\u8def\u5f84\uff09\u3002 clang -S -emit-llvm a.cpp -o a.ll \u4ee5\u4e0b\u662f Clang \u89e3\u6790\u5f97\u5230\u7684 IR\uff08\u6c47\u7f16\u5f62\u5f0f\u6253\u5370\uff09\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 ; Function Attrs: mustprogress noinline norecurse optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } declare i32 @printf(ptr noundef, ...) #1 attributes #0 = { mustprogress noinline norecurse optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } attributes #1 = { \"frame-pointer\"=\"all\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u8fd8\u662f\u7167\u4f8b\u4ecb\u7ecd\u4e00\u4e0b\u65b0\u51fa\u73b0\u7684\u6307\u4ee4\uff1a","title":"Clang \u751f\u6210 IR \u6c47\u7f16"},{"location":"llvm_intro/#_21","text":"\u8fd9\u91cc\u7684 @.str \u662f\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u3002 @.str = private unnamed_addr constant [14 x i8] c\"Hello, world!\\00\", align 1 \u6ce8\u610f\u5230\u4e86\u5417\uff1f\u5168\u5c40\u51fd\u6570\u548c\u53d8\u91cf\u90fd\u662f @ \u5f00\u5934\u7684\uff0c\u5c40\u90e8\u5bc4\u5b58\u5668\u90fd\u662f % \u5f00\u5934\u7684\uff0c\u51fd\u6570\u7f16\u53f7\u90fd\u662f # \u5f00\u5934\u7684\uff0c\u7f16\u8bd1\u671f\u4fe1\u606f\u90fd\u662f ! \u5f00\u5934\u7684\u3002 \u800c . \u5f00\u5934\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u5c31\u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u533f\u540d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u4e0d\u5bf9\u5916\u53ef\u89c1\uff0c\u4f8b\u5982 @.str \u5e76\u4e0d\u4ee3\u8868\u771f\u7684\u6709\u4e00\u4e2a const char str[14] \uff0c\u53ea\u662f\u4e3a\u4e86\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u4e34\u65f6\u751f\u6210\u7684\u4e00\u4e2a\u533f\u540d\u5168\u5c40\u53d8\u91cf\u800c\u5df2\u3002 @.str \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u540d\u5b57\uff0c\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u5168\u5c40\u7684\u5b9a\u4e49\u90fd\u662f\u4ee5 @ \u5f00\u5934\u3002 private \u8868\u793a\u5bf9\u5916\u4e0d\u53ef\u89c1\uff0c\u662f\u4e00\u4e2a\u79c1\u6709\u53d8\u91cf\u3002 unnamed_addr \u8868\u793a\u8be5\u53d8\u91cf\u6ca1\u6709\u540d\u5b57\uff0c\u662f\u533f\u540d\u7684\u3002 constant \u8868\u793a\u8fd9\u662f\u4e00\u4e2a\u5e38\u91cf\uff0c\u4e0d\u53ef\u4ee5\u88ab\u4fee\u6539\u3002 [14 x i8] \u8868\u793a\u5168\u5c40\u53d8\u91cf\u7684\u7c7b\u578b\uff0c [14 x i8] \u7684\u610f\u601d\u662f\u4e00\u4e2a\u957f\u5ea6\u4e3a 14 \u7684 i8 \u6570\u7ec4\uff0c\u7531 14 \u4e2a i8 \u7c7b\u578b\u7ec4\u6210\uff0c\u76f8\u5f53\u4e8e C \u8bed\u8a00\u7684 \u6570\u7ec4\u7c7b\u578b char [14] \u3002 c\"Hello, world!\\00\" \u8868\u793a\u8be5\u6570\u7ec4\u7684\u521d\u59cb\u5316\u503c\uff0c\u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u3002 align 1 \u8868\u793a\u8be5\u5168\u5c40\u53d8\u91cf\u7684\u9996\u5730\u5740\u5bf9\u9f50\u5230 1 \u5b57\u8282\uff0c\u56e0\u4e3a\u8fd9\u662f\u4e00\u4e2a char \u6570\u7ec4\uff0c char \u53ea\u8981\u6c42\u5bf9\u9f50\u5230 1 \u5b57\u8282\u5373\u53ef\u3002 \u548c\u4e0d\u53c2\u4e0e\u7b26\u53f7\u94fe\u63a5\u7684\u5c40\u90e8\u5bc4\u5b58\u5668 % \u4e0d\u540c\uff0c\u5168\u5c40\u53d8\u91cf @ \u540e\u9762\u7684\u540d\u5b57\u5c31\u662f\u4ed6\u4eec\u5728\u94fe\u63a5\u65f6\u5bfc\u51fa\u7b26\u53f7\u7684\u540d\u5b57\u3002\u6240\u4ee5\u5168\u5c40\u53d8\u91cf\u5fc5\u987b\u662f\u6709\u540d\u5b57\u7684\uff0c\u4e0d\u80fd\u7528\u6570\u5b57\u5e8f\u53f7\u8868\u793a\u3002","title":"\u5b9a\u4e49\u5168\u5c40\u53d8\u91cf"},{"location":"llvm_intro/#linkage","text":"\u5982\u679c\u6211\u5b9a\u4e49\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf int i \u4f1a\u4ea7\u751f\u600e\u6837\u7684 IR\uff1f int i = 42; @i = dso_local global i32 42, align 4 align 4 \u662f\u56e0\u4e3a i \u662f int \u6216\u8005\u8bf4 i32 \u7c7b\u578b\u7684\u53d8\u91cf\uff0c\u6309 C++ \u6807\u51c6\u8981\u6c42\u9700\u8981\u5bf9\u9f50\u5230 4 \u5b57\u8282\u3002 \u8fd9\u91cc global \u548c\u4e4b\u524d\u5e38\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 constant \u4e0d\u540c\uff0c\u8868\u793a\u662f\u53ef\u8bfb\u5199\u7684\u5168\u5c40\u53d8\u91cf\u3002 \u8fd9\u91cc\u7684 dso_local \u4fee\u9970\u548c\u5168\u5c40\u51fd\u6570\u4e00\u6837\uff0c\u8868\u793a i \u4e3a\u5168\u5c40\u5bfc\u51fa\u7b26\u53f7\uff08ODR external linkage\uff09\u3002 C++ \u4ee3\u7801 LLVM IR \u4e2d\u7684\u4fee\u9970 C++ \u5f8b\u5e08\u672f\u8bed static int i @i = internal internal linkage inline int i @i = linkonce_odr dso_local non-ODR external linkage int i @i = dso_local ODR external linkage int i \uff08\u51fd\u6570\u5c40\u90e8\uff09 %1 %2 %3 \u2026 no linkage\uff0c\u4e0d\u9700\u8981\u77e5\u9053\u540d\u5b57 \u767d\u5f8b\u5e08\u6700\u6ee1\u610f\u7684\u4e00\u96c6\u3002","title":"\u77e5\u8bc6\u70b9\uff1a\u4e09\u5927 linkage"},{"location":"llvm_intro/#_22","text":"\u6ce8\u610f\uff0c\u5168\u5c40\u53d8\u91cf\u5b9a\u4e49\u5f97\u5230\u7684 @i \u662f\u4e00\u4e2a\u5730\u5740\uff01\u5c31\u548c alloca \u5b9a\u4e49\u7684 %1 \u5bc4\u5b58\u5668\uff0c\u662f\u6307\u5411\u6808\u4e0a\u5185\u5b58\u7684\u5730\u5740\u4e00\u6837\u3002 \u5982\u679c\u9700\u8981\u52a0\u8f7d\u5176\u4e2d\u7684\u503c\uff0c\u8fd8\u9700\u8981\u7528 load \u547d\u4ee4\u8bfb\u53d6\u5230\u51fd\u6570\u7684\u5c40\u90e8\u5bc4\u5b58\u5668\u4e2d\uff0c\u624d\u80fd\u5c06\u5176\u4e2d\u7684\u503c\u7528\u4e8e\u8fd4\u56de\u3002 static int i = 42; int main() { return i; // \u4f1a\u4ea7\u751f load @i \u6307\u4ee4 } @i = dso_local global i32 42, align 4 ; @i \u662f i32* \u7c7b\u578b define dso_local noundef i32 @main() #0 { %1 = load i32, ptr @i, align 4 ; load \u8bfb\u53d6\u8be5\u6307\u9488\u624d\u80fd\u8bfb\u5230 i \u53d8\u91cf\u7684\u503c ret i32 %1 ; %1 \u4e2d\u662f i \u53d8\u91cf\u7684\u503c } \u5982\u679c\u76f4\u63a5 ret i32 @i \u7684\u8bdd\uff0c\u5c31\u53d8\u6210 return &i \u7684\u6548\u679c\u4e86\u3002","title":"\u6ce8\u610f\uff0c\u5b9a\u4e49\u5f97\u5230\u7684\u662f\u5730\u5740"},{"location":"llvm_intro/#call","text":"define dso_local noundef i32 @main() #0 { %1 = call i32 (ptr, ...) @printf(ptr noundef @.str) ret i32 0 } TODO","title":"call \u8c03\u7528\u5176\u4ed6\u51fd\u6570"},{"location":"llvm_intro/#llvm-ir_2","text":"Clang \u7f16\u8bd1\u65f6\u662f\u4ec0\u4e48\u5e73\u53f0\u5c31\u662f\u4ec0\u4e48\u5e73\u53f0\u4e86\uff0c\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7684 IR \u4f1a\u6709\u4e9b\u5fae\u7684\u4e0d\u4e00\u6837\uff08\u7531\u4e8e\u4e00\u4e9b\u8f6f\u4ef6\u9700\u8981\u5229\u7528\u786c\u4ef6 intrinsics\uff09\u3002\u4e00\u4efd IR \u4ece\u751f\u6210\u5f00\u59cb\uff0c\u5c31\u6ce8\u5b9a\u6c38\u8fdc\u53ea\u80fd\u53d8\u6210\u6307\u5b9a\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u3002 \u8fd9\u662f\u56e0\u4e3a\u867d\u7136 IR \u662f\u901a\u7528\u7684\u4e2d\u95f4\u8868\u793a\u5c42\uff0c\u4f46\u7c7b\u578b\u5927\u5c0f\uff0c\u77e2\u91cf\u5bbd\u5ea6\u7b49\u4fe1\u606f\u548c\u786c\u4ef6\u9ad8\u5ea6\u7ed1\u5b9a\u3002 \u800c\u4e14\u6709\u65f6\u7528\u6237\u9700\u8981\u6839\u636e #ifdef __x86_64__ \u5224\u65ad\uff0c\u9488\u5bf9\u4e0d\u540c\u7684\u786c\u4ef6\uff0c\u4f7f\u7528\u4e0d\u540c\u7684 intrinsics\u3002 \u8fd9\u5bfc\u81f4\u5373\u4f7f\u662f\u540c\u4e00\u4efd .cpp \u6587\u4ef6\uff0c\u9488\u5bf9\u4e0d\u540c\u76ee\u6807\u5e73\u53f0\u7f16\u8bd1\u7684\u4ea7\u751f\u7684 IR\uff0c\u4e5f\u5fc5\u7136\u662f\u4e0d\u540c\u7684\u3002 \u66f4\u4f55\u51b5 Windows \u548c Linux \u73af\u5883\u7684\u6807\u51c6\u5e93\u4e5f\u4e0d\u4e00\u6837\uff0c\u53ef\u80fd Windows \u7248\u7684\u7ffb\u8bd1\u5355\u5143\u5728\u4f1a\u6709\u4e00\u4e9b Windows \u7279\u6709\u51fd\u6570\u7684\u58f0\u660e\uff0c\u800c Linux \u4e0a\u7f16\u8bd1\u51fa\u6765\u5c31\u6ca1\u6709\u3002 \u603b\u4e4b\uff0c\u56e0\u4e3a\u8fd9\u6837\u90a3\u6837\u7684\u539f\u56e0\uff0cLLVM IR \u5e76\u4e0d\u652f\u6301\u8de8\u5e73\u53f0\u5171\u7528\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a Clang \u7f16\u8bd1\u51fa\u6765\u7684 IR \u6ce8\u5b9a\u662f\u4e0d\u540c\u7684\u3002 \u4e5f\u6709\u4e00\u4e9b\u652f\u6301\u8de8\u5e73\u53f0\u7684 IR\uff0c\u6bd4\u5982 SPIR-V \u548c MLIR\uff0c\u9002\u7528\u4e8e\u6e38\u620f\u5ba2\u6237\u7aef\u90e8\u7f72\u7684\u573a\u666f\u3002\u4f46\u663e\u7136 LLVM \u4f5c\u4e3a\u8ffd\u6c42\u6781\u81f4\u4f18\u5316\u7684\u88f8\u786c\u4ef6\u7f16\u8bd1\u5668\uff0c\u5176 LLVM IR \u5982\u679c\u8981\u6c42\u8de8\u5e73\u53f0\u4f1a\u5f88\u4e0d\u5229\u4e8e Clang \u524d\u7aef\u652f\u6301\u786c\u4ef6 intrinsics\uff0c\u4e5f\u4e0d\u5229\u4e8e LLVM \u4e2d\u7aef\u9488\u5bf9\u76ee\u6807\u786c\u4ef6\u7279\u6027\u505a\u4f18\u5316\uff0c\u4e5f\u4f1a\u65e0\u6cd5\u652f\u6301\u5185\u8054\u6c47\u7f16\uff0c\u6240\u4ee5\u5c31\u653e\u5f03\u4e86\u3002\u6240\u4ee5\u73b0\u5b9e\u4e2d\uff0c\u4eba\u4eec\u4f1a\u5148\u628a Vulkan \u7740\u8272\u5668\u7f16\u8bd1\u6210\u8de8\u5e73\u53f0\u7684 SPIR-V \u4e8c\u8fdb\u5236\u53d1\u5e03\uff0c\u7b49\u90e8\u7f72\u5230\u6e38\u620f\u73a9\u5bb6\u7535\u8111\u4e0a\u540e\uff0c\u7136\u540e\u518d\u8f93\u5165\u663e\u5361\u9a71\u52a8\u4e2d\u7684 LLVM \u5f97\u5230 LLVM IR \u540e\u4f18\u5316\uff0c\u7f16\u8bd1\u751f\u6210\u6700\u9002\u5408\u5f53\u524d\u73a9\u5bb6\u663e\u5361\u4f53\u8d28\u7684 GPU \u6c47\u7f16\u3002","title":"\u8f76\u4e8b\uff1aLLVM IR \u4e0d\u8de8\u5e73\u53f0"},{"location":"llvm_intro/#ir_1","text":"\u4e0a\u9762\u4ecb\u7ecd\u7684 LLVM IR \u6c47\u7f16\uff0c\u662f\u4ee5\u6587\u672c\u5f62\u5f0f\u5b58\u50a8\u548c\u5904\u7406\uff0c\u867d\u7136\u65b9\u4fbf\u4e86\u4eba\u7c7b\u89c2\u5bdf\u5206\u6790\uff0c\u4f46\u5bf9\u7a0b\u5e8f\u800c\u8a00\u6548\u7387\u4e0d\u9ad8\u3002 \u56e0\u6b64 LLVM \u53c8\u53d1\u660e\u4e86\u4e00\u79cd\u66f4\u9ad8\u6548\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\u6765\u5b58\u50a8 IR\uff0c\u4e5f\u5c31\u662f\u5b57\u8282\u7801\uff08Bitcode\uff09\uff0c\u53ef\u7b80\u5199\u4e3a BC\u3002 \u4ed6\u4eec\u662f \u5b8c\u5168\u7b49\u4ef7\u7684 \uff0c\u90fd\u662f IR \u7684\u4e24\u79cd\u8868\u73b0\u65b9\u5f0f\uff1a\u4e00\u4e2a\u662f\u6587\u672c\u683c\u5f0f\uff08\u9002\u5408\u4eba\u7c7b\u9605\u8bfb\uff09\uff0c\u4e00\u4e2a\u662f\u4e8c\u8fdb\u5236\u683c\u5f0f\uff08\u9002\u5408\u7a0b\u5e8f\u9605\u8bfb\uff09\u3002 IR \u5b57\u8282\u7801\u4e2d\u7684\u6bcf\u4e2a\uff08\u6216\u591a\u4e2a\uff09\u5b57\u8282\u90fd\u53ef\u4ee5\u548c IR \u6c47\u7f16\u4e2d\u7684\u4e00\u884c IR \u6307\u4ee4\u4e00\u4e00\u5bf9\u5e94\u3002","title":"IR \u7684\u4e8c\u8fdb\u5236\u538b\u7f29\u7248\uff1a\u5b57\u8282\u7801"},{"location":"llvm_intro/#ir-ir","text":"","title":"IR \u6c47\u7f16\u548c IR \u5b57\u8282\u7801\u7684\u4e0d\u540c\u4e4b\u5904"},{"location":"llvm_intro/#_23","text":"IR \u6c47\u7f16\uff1a .ll IR \u5b57\u8282\u7801: .bc","title":"\u540e\u7f00\u540d\u4e0d\u540c"},{"location":"llvm_intro/#_24","text":"Clang \u751f\u6210 IR \u6c47\u7f16\uff1a\u4f7f\u7528 -S -emit-llvm \u9009\u9879\u3002 clang -S -emit-llvm a.cpp -o a.ll Clang \u751f\u6210 IR \u5b57\u8282\u7801\uff1a\u4f7f\u7528 -c -emit-llvm \u9009\u9879\u3002 clang -c -emit-llvm a.cpp -o a.bc","title":"\u751f\u6210\u7528\u7684\u547d\u4ee4\u4e0d\u540c"},{"location":"llvm_intro/#_25","text":"IR \u6c47\u7f16: \u6587\u672c\u683c\u5f0f\uff08a.ll\uff09 ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 1, ptr %2, align 4 %3 = load i32, ptr %2, align 4 %4 = add nsw i32 %3, 1 ret i32 %4 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 17.0.6\"} IR \u5b57\u8282\u7801: \u4e8c\u8fdb\u5236\u683c\u5f0f\uff08a.bc\uff09 00000000 42 43 c0 de 35 14 00 00 05 00 00 00 62 0c 30 24 |BC..5.......b.0$| 00000010 4a 59 be 66 bd fb b4 af 0b 51 80 4c 01 00 00 00 |JY.f.....Q.L....| 00000020 21 0c 00 00 e1 01 00 00 0b 02 21 00 02 00 00 00 |!.........!.....| 00000030 16 00 00 00 07 81 23 91 41 c8 04 49 06 10 32 39 |......#.A..I..29| 00000040 92 01 84 0c 25 05 08 19 1e 04 8b 62 80 0c 45 02 |....%......b..E.| ... \u4ee5\u4e0a\u4e3a\u4f7f\u7528 hexdump \u5de5\u5177\u67e5\u770b\u7684\u5341\u516d\u8fdb\u5236\u5b57\u8282\u53ef\u89c6\u5316\u7ed3\u679c\u3002 .bc \u7684\u5b9e\u9645\u5185\u5bb9\u5b8c\u5168\u662f\u4e8c\u8fdb\u5236\uff0c\u76f4\u63a5 cat \u5230\u7ec8\u7aef\u4f1a\u4e71\u7801\u3002","title":"\u5185\u5bb9\u683c\u5f0f\u4e0d\u540c"},{"location":"llvm_intro/#_26","text":"IR \u6c47\u7f16\u5230 IR \u5b57\u8282\u7801\uff1a llvm-as \uff0c\u628a\u6587\u672c IR \u7f16\u8bd1\u6210\u7d27\u51d1\u538b\u7f29\u7684\u5b57\u8282\u7801\u3002 llvm-as test.ll -o test.bc IR \u5b57\u8282\u7801\u5230 IR \u6c47\u7f16\uff1a llvm-dis \uff0c\u628a\u5b57\u8282\u7801\u91cd\u65b0\u8f6c\u56de\u4eba\u7c7b\u53ef\u8bfb\u7684\u6587\u672c IR\u3002 llvm-dis test.bc -o test.ll \u518d\u6b21\u63d0\u9192\uff1a\u8fd9\u4e9b\u662f LLVM \u5185\u90e8\u7684 IR \u7684\u4e24\u79cd\u5f62\u5f0f\uff0c\u5e76\u4e0d\u662f\u771f\u6b63\u7684\u6c47\u7f16\u548c\u673a\u5668\u7801\u3002","title":"\u4e4b\u95f4\u7684\u8f6c\u6362"},{"location":"llvm_intro/#_27","text":"IR \u5b57\u8282\u7801\u548c IR \u6c47\u7f16\u7684\u5173\u7cfb\uff0c\u6b63\u5982 x86 \u6c47\u7f16\u548c x86 \u673a\u5668\u7801\u7684\u5173\u7cfb\uff0c\u4e4b\u95f4\u662f\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb\u3002 IR \u5b57\u8282\u7801\u662f\u4e8c\u8fdb\u5236\u7684\uff0c\u5bf9\u8ba1\u7b97\u673a\u53cb\u597d\uff1b\u800c IR \u6c47\u7f16\u662f\u4eba\u7c7b\u53ef\u8bfb\u7684 ASCII \u5b57\u7b26\uff0c\u65b9\u4fbf\u4eba\u7c7b\u9605\u8bfb\u548c\u8c03\u8bd5\uff0c\u4ed6\u4eec\u672c\u8d28\u4e0a\u90fd\u662f IR\u3002 \u6c47\u7f16\u662f\u7ed9\u4eba\u770b\u7684\u6587\u672c\u6587\u4ef6\uff0c\u673a\u5668\u7801\u662f\u7ed9 CPU \u770b\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\uff1b\u540c\u6837\u5730\uff0cIR \u6c47\u7f16\u662f IR \u7684\u6587\u672c\u683c\u5f0f\uff0c\u662f\u6253\u5370\u7ed9\u4eba\u770b\u7684\uff1b\u800c IR \u5b57\u8282\u7801\u662f\u7ed9 LLVM \u7f16\u8bd1\u5668\u770b\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f IR\uff0c\u89e3\u6790\u8d77\u6765\u66f4\u5feb\uff0c\u4e5f\u8282\u7ea6\u5185\u5b58\u3002 \u4e0d\u8fc7\uff0c\u8981\u6ce8\u610f\u5b57\u8282\u7801\u548c\u673a\u5668\u7801\u4e0d\u540c\uff0c\u4ed6\u4f9d\u7136\u5c5e\u4e8e\u4e2d\u95f4\u8868\u793a\uff08\u53ea\u4e0d\u8fc7\u662f\u538b\u7f29\u5f97\u4eba\u7c7b\u770b\u4e0d\u61c2\u7684\u9ad8\u6548\u4e8c\u8fdb\u5236\u7248 IR\uff09\uff0c\u5e76\u4e0d\u80fd\u76f4\u63a5\u5728\u8ba1\u7b97\u673a\u4e2d\u6267\u884c\uff0cLLVM \u5b57\u8282\u7801\u53ea\u80fd\u5728 lli \u865a\u62df\u673a\u4e2d\u89e3\u91ca\u6267\u884c\uff0c\u6216\u8005\u901a\u8fc7 llc \u7f16\u8bd1\u4ea7\u751f\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u540e\u5728\u76ee\u6807\u5e73\u53f0\u88f8\u673a\u6267\u884c\u3002 \u4f46\u548c Java \u7684\u5b57\u8282\u7801\u53c8\u4e0d\u4e00\u6837\uff0cLLVM \u7684\u5b57\u8282\u7801\u672c\u6765\u5c31\u662f\u4e8c\u8fdb\u5236\u7684 IR\u3002\u800c IR \u5e76\u4e0d\u8de8\u5e73\u53f0\uff0c\u6240\u4ee5\u5b57\u8282\u7801\u4e5f\u4e0d\u8de8\u5e73\u53f0\u3002LLVM \u56e2\u961f\u63d0\u4f9b lli \u5de5\u5177\u4e3b\u8981\u662f\u4e3a\u4e86\u65b9\u4fbf\u4e34\u65f6\u6d4b\u8bd5 IR\uff0c\u7528\u4e8e\u751f\u4ea7\u73af\u5883\u7684\u80af\u5b9a\u8fd8\u662f llc \u7f16\u8bd1\u597d\u4ea7\u751f\u771f\u6b63\u7684\u9ad8\u6548\u673a\u5668\u7801\u3002","title":"\u4e00\u4e00\u5bf9\u5e94\u7684\u7ffb\u8bd1\u5173\u7cfb"},{"location":"llvm_intro/#_28","text":"\u5f97\u5230\u7684 .bc \u5b57\u8282\u7801\u6587\u4ef6\u4e5f\u88ab\u79f0\u4e3a\u4e00\u4e2a\u6a21\u5757\uff08Module\uff09\uff0c\u6a21\u5757\u7531\u4e00\u7cfb\u5217 IR \u9636\u6bb5\u7684\u7ec4\u6210\uff1b\u6b63\u5982\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7531\u5927\u91cf\u6c47\u7f16\u6307\u4ee4\u7ec4\u6210\u4e00\u6837\u3002 \u8fd9\u91cc\u8bf4\u7684 LLVM \u6a21\u5757\u548c C++20 \u7684 Modules \u7279\u6027\u5173\u7cfb\u4e0d\u5927\uff0c\u6a21\u5757\u662f LLVM \u5f88\u65e9\u5c31\u6709\u7684\u6982\u5ff5\uff0c\u649e\u540d\u4e86\u800c\u5df2\u3002 \u4e00\u4e2a .cpp \u6587\u4ef6\u7f16\u8bd1\u53ef\u4ee5\u4ea7\u751f IR \u6c47\u7f16\uff08.ll\uff09\uff0cIR \u6c47\u7f16\u53ef\u4ee5\u901a\u8fc7 llvm-as \u7f16\u8bd1\u5f97\u5230\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09\u3002\u56e0\u6b64\u53ef\u4ee5\u7c97\u7565\u7684\u8ba4\u4e3a\uff0c \u4e00\u4e2a\u6e90\u6587\u4ef6\uff08.cpp\uff09\u7f16\u8bd1\u540e\u5c31\u662f\u4e00\u4e2a\u6a21\u5757\uff08.bc\uff09 \u3002 \u800c LLVM \u6a21\u5757\uff08.bc\uff09\u53ef\u4ee5\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210\u901a\u7528\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\uff0c\u4ece\u800c\u5c31\u662f\u6211\u4eec\u770b\u5230\u7684\uff1a\u4e00\u4e2a .cpp \u6587\u4ef6\u5bf9\u5e94\u4e00\u4e2a .o \u6587\u4ef6\u4e86\u3002 \u6a21\u5757\u4e2d\u5305\u542b\u4e86\u4e4b\u524d\u4ecb\u7ecd\u7684 IR \u6c47\u7f16\u4e2d\u6240\u6709\u7684\u4fe1\u606f\uff0c\u4f8b\u5982\u76ee\u6807\u5e73\u53f0\u7684\u6570\u636e\u5e03\u5c40\u4fe1\u606f\uff0c\u5168\u5c40\u53d8\u91cf\uff0c\u7c7b\u578b\u58f0\u660e\uff0c\u51fd\u6570\u5b9a\u4e49\u548c\u58f0\u660e\u7b49\u3002","title":"\u5b57\u8282\u7801\u6587\u4ef6\u5c31\u662f\u6a21\u5757"},{"location":"llvm_intro/#_29","text":"\u5b57\u8282\u7801\uff08.bc\uff09\u662f LLVM \u5185\u90e8\u7684\u6587\u4ef6\u683c\u5f0f\uff0c\u4e0d\u901a\u7528\u3002\u4f46\u7531\u4e8e\u5176\u76f4\u63a5\u5b58\u50a8 IR\uff0c\u65b9\u4fbf LLVM \u5904\u7406\u548c\u4f18\u5316\uff0c\u4e14\u53ef\u4ee5\u5f88\u5bb9\u6613\u901a\u8fc7 llvm-dis \u53cd\u6c47\u7f16\u6210\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\u6765\u67e5\u770b\uff08.ll\uff09\u3002\u901a\u5e38\u7528\u4e8e\u8c03\u8bd5 LLVM\uff0c\u4ee5\u53ca\u76ee\u6807\u5e73\u53f0\u4e0d\u662f CPU \u7684\u60c5\u51b5\uff08\u4f8b\u5982 CUDA PTX\uff09\u3002 \u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u662f\u7c7b Unix \u5e73\u53f0\u901a\u7528\u7684 ELF \u683c\u5f0f\uff08\u5728 Windows \u5e73\u53f0\u5219\u662f .obj \u6587\u4ef6\uff0cCOFF \u683c\u5f0f\uff09\uff0c\u5176\u4ed6\u652f\u6301 ELF \u7684\u7f16\u8bd1\u5668\u548c\u94fe\u63a5\u5668\u4e5f\u53ef\u4ee5\u4f7f\u7528\u3002\u4f8b\u5982 GCC \u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e5f\u53ef\u4ee5\u540c LLVM \u7f16\u8bd1\u4ea7\u751f\u7684 .o \u6587\u4ef6\u4e00\u8d77\u94fe\u63a5\uff0c\u800c\u5982\u679c\u662f .bc \u683c\u5f0f GCC \u5c31\u8ba4\u4e0d\u51fa\u6765\u3002\u7f3a\u70b9\u662f\u4e00\u65e6\u7f16\u8bd1\u6210 .o \u6587\u4ef6\uff0c\u5c31\u65e0\u6cd5\u518d\u53cd\u63a8\u51fa IR \u4e86\uff0c\u53ea\u80fd\u901a\u8fc7 objdump \u53cd\u6c47\u7f16\u5f97\u5230\u6c47\u7f16\u4ee3\u7801\uff0c\u5c31\u4e0d\u65b9\u4fbf LLVM \u518d\u5904\u7406\u548c\u4f18\u5316\u4e86\u3002","title":"\u5b57\u8282\u7801\u6a21\u5757\u548c\u5bf9\u8c61\u6587\u4ef6\u7684\u533a\u522b"},{"location":"llvm_intro/#llvm_6","text":"\u603b\u4e4b\u5728 LLVM / Clang \u5de5\u4f5c\u6d41\u4e2d\uff0c\u53ef\u4ee5\u7c97\u7565\u8ba4\u4e3a\uff0c\u4e00\u4e2a .cpp \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u4e5f\u6709\u4e00\u4e9b\u65f6\u5019\uff0c\u6211\u4eec\u7f16\u8bd1\u6a21\u5757\u7684\u76ee\u6807\u5e76\u4e0d\u662f CPU\uff0c\u4f8b\u5982 Taichi \u9879\u76ee\u4e2d\uff0c\u5c31\u662f\u901a\u8fc7 LLVM \u91cd\u65b0\u7f16\u8bd1 Python \u5b57\u8282\u7801\uff0c\u751f\u6210 .bc \u6a21\u5757\uff0c\u7136\u540e\u7f16\u8bd1\u4ea7\u751f PTX \u6c47\u7f16\uff0c\u8f6c\u5316\u4e3a CUBIN \u4e8c\u8fdb\u5236\u540e\uff0c\u63d0\u4ea4\u5230 CUDA \u9a71\u52a8\u4e2d\u6267\u884c\uff08\u5b9e\u9645\u4e0a\u6b64\u5904\u8fd8\u4f1a\u8fdb\u4e00\u6b65\u7f16\u8bd1\u6210 SASS \u6c47\u7f16\uff09\u3002 \u5728 LLVM / Clang CUDA \u5de5\u4f5c\u6d41\u4e2d\uff0c\u4e00\u4e2a .cu \u6e90\u7801\u6587\u4ef6\u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u662f\uff1a \u5c0f\u5f6d\u8001\u5e08\u7ed8\u5236\u4e00\u526f\u4e16\u754c\u540d\u753b\u300aIntel \u8d4b\u80fd AI \u7f16\u8bd1\u5668\u300b\uff0c\u540c\u5b66\u95ee\uff0c\u6211\u53ea\u770b\u5230\u6309\u6469\u5e97\u548c\u6deb\u5a01\u5927\uff0c\u6a31\u7279\u5c14\u5728\u54ea\u5462\uff1f\u7b54\uff1a\u6a31\u7279\u5c14\u5728\u8d4b\u80fd\u3002 \u8fd9\u91cc\u7684 cubin \u5176\u5b9e\u5c31\u662f\u5e38\u542c\u5230\u7684 fatbin\uff0c\u4e8c\u8fdb\u5236\u7248\u7684 PTX \u6c47\u7f16\uff0cNVCC \u7684\u6d41\u7a0b\u4e5f\u548c\u8fd9\u4e2a\u5dee\u4e0d\u591a\u3002","title":"LLVM \u7f16\u8bd1\u7684\u5168\u8fc7\u7a0b\u56fe"},{"location":"llvm_intro/#_30","text":"\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\uff08.bc\uff09\u4e4b\u95f4\u53ef\u4ee5\u4e92\u76f8\u94fe\u63a5\uff0c\u5f62\u6210\u4e00\u4e2a\u66f4\u5927\u7684\u6a21\u5757\uff0c\u5176\u4e2d\u5305\u542b\u6240\u6709\u5b50\u6a21\u5757\u7684\u5185\u5bb9\u3002 llvm-link test1.bc test2.bc -o test.bc \u901a\u8fc7\u94fe\u63a5\uff0c\u53ef\u4ee5\u628a\u591a\u4e2a\u6a21\u5757\u7684 IR \u5408\u5e76\u5230\u4e00\u4e2a\u6a21\u5757\u4e2d\uff0c\u65b9\u4fbf\u540e\u7eed\u4f18\u5316\u548c\u7f16\u8bd1\u3002 \u6ce8\u610f\uff01\u8fd9\u91cc\u7684 IR \u94fe\u63a5\uff08llvm-link\uff09\u53ea\u662f LLVM \u7f16\u8bd1\u9636\u6bb5\u5185\u90e8\u7684\u4e00\u4e2a\u5c0f\u8fc7\u7a0b\uff0c\u548c\u6c47\u7f16\u9636\u6bb5\u540e\u751f\u6210\u7684\u5bf9\u8c61\u6587\u4ef6\uff08.o\uff09\u7684\u771f\u6b63\u94fe\u63a5\uff08lld\uff09\u4e0d\u540c\u3002\u8fd9\u91cc\u53ea\u662f\u628a\u591a\u4e2a LLM \u6a21\u5757\u5408\u5e76\u6210\u4e00\u4e2a\u6a21\u5757\u800c\u5df2\uff0c\u6700\u540e\u8fd9\u4e2a\u603b\u6a21\u5757\u7f16\u8bd1\u4f9d\u7136\u662f\u5f97\u5230\u5355\u4e2a .o \u6587\u4ef6\uff0c\u8fd8\u662f\u8981\u7ecf\u8fc7\u771f\u6b63\u7684\u94fe\u63a5\u5668\uff08lld\uff09\uff0c\u4e0e\u5176\u4ed6 .o \u6587\u4ef6\u94fe\u63a5\u624d\u80fd\u5f62\u6210\u6700\u7ec8\u53ef\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 \u628a C++ \u6587\u4ef6\u7f16\u8bd1\u751f\u6210\u7684\u5b57\u8282\u7801\u6a21\u5757\u94fe\u63a5\u8d77\u6765\uff0c\u5c31\u50cf\u5f88\u591a\u4e2a C++ \u6587\u4ef6\u7a81\u7136\u56fd\u5b9d\u7279\u5de5\u5408\u4f53\u4e00\u6837\u3002","title":"\u8f76\u4e8b\uff1a\u591a\u4e2a\u5b57\u8282\u7801\u6a21\u5757\u53ef\u4ee5\u94fe\u63a5"},{"location":"llvm_intro/#llvm-pass","text":"LLVM \u63d0\u4f9b\u4e86 opt \u8fd9\u4e2a\u65b9\u4fbf\u7684\u547d\u4ee4\u884c\u5de5\u5177\uff0c\u53ef\u4ee5\u8c03\u7528 LLVM \u4e2d\u6307\u5b9a\u540d\u79f0\u7684\u4f18\u5316\u7c7b pass\uff0c\u7528\u6765\u4f18\u5316\u4f20\u5165\u7684 IR \u6587\u4ef6\uff08\u53ef\u4ee5\u662f IR \u6c47\u7f16\u6216 IR \u5b57\u8282\u7801\uff09\u3002 \u9ed8\u8ba4\u60c5\u51b5\u4e0b\u8f93\u51fa\u7684\u662f\u4e8c\u8fdb\u5236\u7684 IR \u5b57\u8282\u7801\uff0c\u5982\u9700\u8f93\u51fa\u4eba\u7c7b\u53ef\u8bfb\u7684 IR \u6c47\u7f16\uff0c\u53ef\u4ee5\u6307\u5b9a -S \u9009\u9879\uff08\u5c31\u548c\u521a\u624d\u6211\u4eec\u4f7f\u7528 clang -S \u8ba9 -emit-llvm \u751f\u6210 IR \u6c47\u7f16\u800c\u4e0d\u662f IR \u5b57\u8282\u7801\u4e00\u6837\uff09\u3002 # \u8f93\u5165 a.ll\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.ll\uff08IR \u6c47\u7f16\uff09 opt -S -p mem2reg a.ll -o a-opt.ll cat a-opt.ll # \u8f93\u5165 a.bc\uff0c\u4f7f\u7528 mem2reg \u8fd9\u4e2a\u4f18\u5316 pass \u540e\uff0c\u7ed3\u679c\u8f93\u51fa\u5230 a-opt.bc\uff08IR \u5b57\u8282\u7801\uff09 opt -p mem2reg a.bc -o a-opt.bc llvm-dis a-opt.bc -o a-opt.ll # \u5982\u679c\u8f93\u51fa\u5b57\u8282\u7801\u683c\u5f0f\uff0c\u8fd8\u9700\u8981 llvm-dis \u624d\u80fd\u8ba9\u4eba\u7c7b\u770b\u61c2","title":"\u8c03\u7528 LLVM pass \u4f18\u5316"},{"location":"llvm_intro/#_31","text":"\u8fd8\u662f\u8fd9\u6bb5 C++ \u4ee3\u7801\uff1a int main() { int a = 0; int b = 1; return a + 1; } \u4f7f\u7528 clang \u7f16\u8bd1\uff0c\u751f\u6210 IR \u6c47\u7f16\uff1a clang -S -emit-llvm a.cpp -o a.ll \u5f97\u5230 a.ll\uff1a ; ModuleID = 'a.cpp' source_filename = \"a.cpp\" target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\" target triple = \"x86_64-pc-linux-gnu\" ; Function Attrs: mustprogress noinline norecurse nounwind optnone sspstrong uwtable define dso_local noundef i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, ptr %1, align 4 store i32 0, ptr %2, align 4 store i32 1, ptr %3, align 4 %4 = load i32, ptr %2, align 4 %5 = add nsw i32 %4, 1 ret i32 %5 } attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwtable \"frame-pointer\"=\"all\" \"min-legal-vector-width\"=\"0\" \"no-trapping-math\"=\"true\" \"stack-protector-buffer-size\"=\"8\" \"target-cpu\"=\"x86-64\" \"target-features\"=\"+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87\" \"tune-cpu\"=\"generic\" } !llvm.module.flags = !{!0, !1, !2, !3, !4} !llvm.ident = !{!5} !0 = !{i32 1, !\"wchar_size\", i32 4} !1 = !{i32 8, !\"PIC Level\", i32 2} !2 = !{i32 7, !\"PIE Level\", i32 2} !3 = !{i32 7, !\"uwtable\", i32 2} !4 = !{i32 7, !\"frame-pointer\", i32 2} !5 = !{!\"clang version 18.1.8\"} \u73b0\u5728\uff0c\u6211\u4eec\u7528 opt \u5de5\u5177\u5bf9\u5176\u8fdb\u884c\u4f18\u5316\uff1a TODO","title":"\u6848\u4f8b"},{"location":"llvm_intro/#_32","text":"","title":"\u57fa\u672c\u5757\u4e0e\u5206\u652f"},{"location":"llvm_intro/#asm","text":"","title":"\u6c47\u7f16\u8bed\u8a00\uff08ASM\uff09"},{"location":"llvm_intro/#_33","text":"","title":"\u6c47\u7f16\u8bed\u8a00\u7684\u7ec8\u5c40\uff1a\u673a\u5668\u7801"},{"location":"llvm_intro/#_34","text":"","title":"\u6784\u5efa\u597d\u4e86\u5417"},{"location":"no_more_new/","text":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb \u4f7f\u7528 new \u548c delete \u662f\u4e00\u79cd\u8fc7\u65f6\u7684\u5185\u5b58\u7ba1\u7406\u65b9\u5f0f\uff0c\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u60ac\u7a7a\u6307\u9488\uff0c\u5e94\u5f53\u6c38\u4e0d\u4f7f\u7528\u3002 \u4f18\u79c0\u7684\u73b0\u4ee3 C++ \u9879\u76ee\uff0c\u90fd\u4f7f\u7528 \u667a\u80fd\u6307\u9488 \u548c \u5bb9\u5668 \u7ba1\u7406\u5185\u5b58\uff0c\u4ece\u6765\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efa\u539f\u59cb\u6307\u9488\u3002 \u4e0b\u5217\u4e09\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 new \u548c delete\uff1a \u4f60\u5728\u5c01\u88c5\u4e00\u4e2a\u975e\u5e38\u5e95\u5c42\u7684\u5185\u5b58\u5206\u914d\u5668\u5e93\u3002 \u4f60\u662f C++98 \u7528\u6237\uff0c\u4e14\u4f60\u7684\u8001\u677f\u4e0d\u5141\u8bb8\u4f7f\u7528 boost\uff08\u5176\u63d0\u4f9b\u4e86\u667a\u80fd\u6307\u9488\uff09\u3002 \u4f60\u60f3\u8981\u521b\u9020\u4e00\u4e9b\u5185\u5b58\u6cc4\u6f0f\u6765\u60e9\u7f5a\u62d6\u6b20\u5de5\u8d44\u7684\u8111\u677f\u3002 \u540c\u7406\uff0cmalloc \u548c free \u4e5f\u662f\u4e0d\u5141\u8bb8\u7684\u3002 \u4e0d\u4ec5 new \u4e0d\u5e94\u8be5\u51fa\u73b0\uff0c\u539f\u59cb\u6307\u9488\u4e5f\u5e94\u8be5\u5c11\u51fa\u73b0\uff0c\u800c\u662f\u66f4\u5b89\u5168\uff0c\u7528\u6cd5\u66f4\u5355\u4e00\u7684 \u5f15\u7528 \u6216 span \u4ee3\u66ff\u3002 \u7528\u6cd5\u66f4\u5355\u4e00\u4e3a\u4ec0\u4e48\u662f\u597d\u4e8b\uff1f\u8bf7\u770b \u5f3a\u7c7b\u578b API \u8bbe\u8ba1\u4e13\u9898\u7ae0 \u3002 \u6848\u4f8b 1 \u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; } \u8d34\u58eb 1.1 \u6211\u4e00\u822c\u4f1a\u7528\u66f4\u76f4\u89c2\u7684 auto \u5199\u6cd5\uff0c\u8fd9\u6837\u66f4\u80fd\u660e\u786e\u8fd9\u662f\u5728\u521b\u5efa\u4e00\u4e2a vector \u5bf9\u8c61\uff0c\u7136\u540e\u4fdd\u5b58\u5230 mem \u8fd9\u4e2a\u53d8\u91cf\u540d\u4e2d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size()); \u8fd9\u88ab\u79f0\u4e3a auto-idiom\uff1a\u59cb\u7ec8\u4f7f\u7528 auto \u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6c38\u8fdc\u522b\u4f7f\u7528\u53ef\u80fd\u5f15\u53d1\u6b67\u4e49\u7684\u7c7b\u578b\u524d\u7f6e\u3002 \u8d34\u58eb 1.2 \u6709\u7684\u540c\u5b66\u4f1a\u60f3\u5f53\u7136\u5730\u63d0\u51fa\uff0c\u7528\u667a\u80fd\u6307\u9488\u4ee3\u66ff new\u3002 auto mem = make_shared(1024); read(1, mem.get(), 1024); \u53ef new \u7684\u66ff\u4ee3\u54c1\u4ece\u6765\u4e0d\u53ea\u6709\u667a\u80fd\u6307\u9488\u4e00\u4e2a\uff0c\u4e5f\u53ef\u4ee5\u662f vector \u5bb9\u5668\uff01 \u667a\u80fd\u6307\u9488\u53ea\u4f1a\u7528\u4e8e \u5355\u4e2a\u5bf9\u8c61 \uff01 \u52a8\u6001\u957f\u5ea6\u7684\u6570\u7ec4 \uff0c\u6b63\u5e38\u4eba\u90fd\u662f\u7528 vector \u7ba1\u7406\u7684\u3002 \u5f88\u591a\u52a3\u8d28\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u6750\u201d \u90fd\u5ffd\u7565\u4e86\u8fd9\u4e00\u70b9\uff0c\u603b\u662f\u523b\u610f\u5938\u5927\u4e86\u667a\u80fd\u6307\u9488\u7684\u8986\u76d6\u8303\u56f4\uff0c\u4e3a\u4e86\u65b0\u800c\u65b0\uff0c\u800c\u5bf9\u5b9e\u9645\u4e0a\u66f4\u9002\u5408\u7ba1\u7406 \u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4 \u7684 vector \u53ea\u5b57\u4e0d\u63d0\u3002 vector \u7ba1\u7406\u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4\u7684\u4f18\u52bf\uff1a \u4f60\u53ef\u4ee5\u968f\u65f6\u968f\u5730 resize \u548c push_back\uff0c\u52a0\u5165\u65b0\u5143\u7d20\uff0c\u800c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\u8981\u91cd\u65b0\u8c03\u6574\u5927\u5c0f\u5c31\u6bd4\u8f83\u56f0\u96be\u3002 vector \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6df1\u62f7\u8d1d\uff0c\u7b26\u5408 C++ \u5bb9\u5668\u7684\u4e00\u822c\u7ea6\u5b9a\u3002\u800c unique_ptr \u5b8c\u5168\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u6df1\u62f7\u8d1d\u9700\u8981\u989d\u5916\u7684\u4ee3\u7801\uff0cshared_ptr \u5219\u662f\u6d45\u62f7\u8d1d\uff0c\u6709\u65f6\u4f1a\u5bfc\u81f4\u6570\u636e\u8986\u76d6\u3002 \u5176\u5b9e shared_ptr \u4e5f\u4e0d\u662f\u4e0d\u53ef\u4ee5\u7528\uff0c\u7136\u800c\uff0c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\uff0c\u5e76\u4e0d\u80fd\u65b9\u4fbf\u5730\u901a\u8fc7 .size() \u83b7\u53d6\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5fc5\u987b\u7528\u53e6\u4e00\u4e2a\u53d8\u91cf\u5355\u72ec\u5b58\u50a8\u8fd9\u4e2a\u957f\u5ea6\u3002\u8fd9\u5c31\u8fdd\u80cc\u4e86\u5c01\u88c5\u539f\u5219\uff0c\u90a3\u4f1a\u4f7f\u4f60\u7684\u4ee3\u7801\u53d8\u5f97\u4e0d\u53ef\u7ef4\u62a4\u3002 \u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u53ef\u7ef4\u62a4\u6027\u603b\u662f\u6bd4\u6027\u80fd\u91cd\u8981\u7684\uff0c\u4f60\u53ea\u9700\u8981\u6bd4\u8f83 \u4f60\u91cd\u6784\u4ee3\u7801\u82b1\u7684\u65f6\u95f4 \u548c \u8ba1\u7b97\u673a\u8fd0\u884c\u8fd9\u6bb5\u4ee3\u7801\u6240\u9700\u65f6\u95f4 \u5c31\u660e\u767d\u503c\u4e0d\u503c\u4e86\u3002 \u8d34\u58eb 1.3 \u5982\u679c\u662f\u5176\u4ed6\u7c7b\u578b\uff0c\u53ef\u80fd\u9700\u8981\u4e58\u4ee5 sizeof(\u5143\u7d20\u7c7b\u578b) \uff0c\u53d6\u51b3\u4e8e\u90a3\u4e2a C \u51fd\u6570\u8981\u6c42\u7684\u662f\u201c\u5b57\u8282\u6570\u201d\u8fd8\u662f\u201c\u5143\u7d20\u6570\u201d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size() * sizeof(mem[0])); auto max = find_max(mem.data(), mem.size()); \u8d34\u58eb 1.4 \u5bf9\u4e8e\u4f60\u81ea\u5df1\u7684 C++ \u51fd\u6570\uff0c\u5c31\u6ca1\u5fc5\u8981\u518d\u63d0\u4f9b TODO: span, gsl::span, boost::span \u6848\u4f8b 2 \u540c\u5b66\uff1a\u6211\u9700\u8981\u5728\u201c\u5806\u201d\u4e0a\u5206\u914d\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u4ed6\u6301\u4e45\u5b58\u5728\u3002\u4f60\u4e0d\u8ba9\u6211\u7528 new\uff0c\u6211\u53ea\u80fd\u5728\u201c\u6808\u201d\u4e0a\u521b\u5efa\u4e34\u65f6\u5bf9\u8c61\u4e86\uff0c\u5982\u679c\u8981\u8fd4\u56de\u6216\u5b58\u8d77\u6765\u7684\u8bdd\u6839\u672c\u7528\u4e0d\u4e86\u554a\u3002 Foo *hello() { Foo *foo = new Foo(); return foo; } \u5c0f\u5f6d\u8001\u5e08\uff1a\u4f60\u53ef\u4ee5\u4f7f\u7528\u667a\u80fd\u6307\u9488\uff0c\u6700\u9002\u5408\u65b0\u4eba\u4e0a\u624b\u7684\u667a\u80fd\u6307\u9488\u662f shared_ptr\u3002 \u5f53\u6ca1\u6709\u4efb\u4f55\u51fd\u6570\u6216\u5bf9\u8c61\u6301\u6709\u8be5 shared_ptr \u6307\u5411\u7684\u5bf9\u8c61\u65f6\uff0c\u4e5f\u5c31\u662f\u5f53\u8c03\u7528\u8005\u5b58\u50a8 hello() \u8fd4\u56de\u503c\u7684\u51fd\u6570\u4f53\u9000\u51fa\u65f6\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u88ab\u81ea\u52a8\u91ca\u653e\u3002 shared_ptr hello() { shared_ptr foo = make_shared(); return foo; } \u603b\u4e4b\uff0c\u8fd9\u6837\u66ff\u6362\u4f60\u7684\u4ee3\u7801\uff1a T * \u6362\u6210 shared_ptr new T(...) \u6362\u6210 make_shared(...) \u4f60\u7684\u4ee3\u7801\u5c31\u57fa\u672c\u4e0a\u5b89\u5168\u4e86\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8 delete \u4e86\u3002 \u6709\u4e2a\u7528\u4e86 shared_ptr \u8fd8\u4f1a\u5185\u5b58\u6cc4\u6f0f\u7684\u8fb9\u7f18\u60c5\u51b5\uff1a\u5faa\u73af\u5f15\u7528\uff0c\u901a\u5e38\u662f\u5b9e\u73b0\u53cc\u5411\u94fe\u8868\u65f6\uff0cweak_ptr \u53ef\u4ee5\u89e3\u51b3\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 \u8d34\u58eb 2.1 unique_ptr \u548c shared_ptr \u6709\u4ec0\u4e48\u533a\u522b\uff1f\u521d\u5b66\u8005\u5e94\u8be5\u5148\u5b66\u54ea\u4e2a\uff1f unique_ptr \u662f\u72ec\u5360\u6240\u6709\u6743\uff0c\u4ed6\u7684\u9650\u5236\u66f4\u591a\uff0c\u6bd4\u5982\uff1a \u4e0d\u5141\u8bb8\u62f7\u8d1d\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u3002 \u4e0d\u5141\u8bb8\u8d4b\u503c\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u8d4b\u503c\u3002 \u7528 unique_ptr \u4e3b\u8981\u662f\u51fa\u4e8e\u6027\u80fd\u4f18\u52bf\u3002 \u7136\u800c\u6027\u80fd\u603b\u662f\u4e0d\u5982\u5b89\u5168\u91cd\u8981\u7684\uff0c\u4f60\u662f\u60f3\u8981 \u4e00\u4e2a\u9020\u5728\u706b\u661f\u7684\u8c6a\u534e\u5bab\u6bbf\uff0c\u8fd8\u662f\u4e00\u4e2a\u5730\u7403\u7684\u5b89\u5168\u8001\u5bb6\uff1f \u6240\u4ee5\uff0c\u5efa\u8bae\u4f60\u5148\u5168\u90e8\u66ff\u6362\u6210\u6cdb\u7528\u6027\u5f3a\u3001\u6613\u7528\u7684 shared_ptr\u3002\u7b49\u786e\u5b9e\u51fa\u73b0\u6027\u80fd\u74f6\u9888\u65f6\uff0c\u518d\u5bf9\u74f6\u9888\u90e8\u5206\u5355\u72ec\u8c03\u8bd5\u4f18\u5316\u4e5f\u4e0d\u8fdf\u3002 \u5148\u628a\u8001\u5bb6\u9020\u597d\u4e86\uff0c\u7136\u540e\u518d\u60f3\u529e\u6cd5\u79fb\u6c11\u706b\u661f\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002 \u8d34\u58eb 2.2 \u6709\u4e9b\u8001\u5f0f\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u7a0b\u201d \u4e2d\uff0c\u4f1a\u770b\u5230\u8fd9\u6837 new \u4e0e\u667a\u80fd\u6307\u9488\u5e76\u7528\u7684\u5199\u6cd5\uff1a shared_ptr foo(new Foo()); \u4ece C++14 \u5f00\u59cb\uff0c\u8fd9\u5df2\u7ecf\u662f \u8fc7\u65f6\u7684 \uff01\u5177\u6709\u5b89\u5168\u9690\u60a3\uff08\u5982\u679c\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u51fa\u5f02\u5e38\uff09\uff0c\u4e14\u5199\u8d77\u6765\u4e5f\u4e0d\u591f\u76f4\u89c2\u3002 \u73b0\u5728\u4eba\u4eec\u4e00\u822c\u90fd\u4f1a\u7528 make_shared \u51fd\u6570\uff0c\u5176\u5185\u90e8\u5c01\u88c5\u4e0d\u4ec5\u4fdd\u8bc1\u4e86\u5f02\u5e38\u5b89\u5168\uff0c\u800c\u4e14\u4f1a\u4f7f shared_ptr \u7684\u63a7\u5236\u5757\u4e0e Foo \u5bf9\u8c61\u524d\u540e\u7d27\u6328\u7740\uff0c\u53ea\u9700\u4e00\u6b21\u5185\u5b58\u5206\u914d\uff0c\u4e0d\u4ec5\u66f4\u76f4\u89c2\uff0c\u8fd8\u63d0\u5347\u4e86\u6027\u80fd\u3002 auto foo = make_shared(); \u6709\u8da3\u7684\u662f\uff0cmake_shared \u5728 C++11 \u5c31\u5f15\u5165\u4e86\uff0cmake_unique \u5374\u76f4\u5230 C++14 \u624d\u5f15\u5165\u3002 \u4ece C++14 \u5f00\u59cb\uff0c\u5185\u5b58\u5b89\u5168\u7684\u73b0\u4ee3 C++ \u7a0b\u5e8f\u4e2d\u5c31\u4e0d\u4f1a\u51fa\u73b0\u4efb\u4f55\u663e\u5f0f\u7684 new \u4e86\uff0c\u54ea\u6015\u662f\u5305\u5728 shared_ptr \u6216 unique_ptr \u5185\u7684\u4e5f\u4e0d\u884c\u3002\uff08\u9664\u4e86\u6700\u4e0a\u9762\u8bf4\u7684 3 \u79cd\u7279\u6b8a\u60c5\u51b5\uff09 \u8d34\u58eb 2.3 \u5982\u679c\u4f60\u9700\u8981\u8c03\u7528\u7684 C \u8bed\u8a00\u63a5\u53e3\u8fd8\u9700\u8981\u539f\u59cb\u6307\u9488\u7684\u8bdd\uff0c\u7528 .get() \u53ef\u4ee5\u4ece\u667a\u80fd\u6307\u9488\u4e2d\u83b7\u53d6\u539f\u59cb\u6307\u9488\u3002\u5efa\u8bae\u53ea\u5728\u548c C \u8bed\u8a00\u6253\u4ea4\u9053\u65f6 .get() \uff0c\u5176\u4f59\u65f6\u95f4\u4e00\u5f8b shared_ptr \u4fdd\u8bc1\u5b89\u5168\u3002 extern \"C\" void some_c_function(Foo *foo); auto foo = make_shared(); some_c_function(foo.get()); RAII \u6bd4\u8d77\u624b\u52a8 delete \u7684\u4f18\u52bf \u5728\u65e5\u5e38\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u5e38\u5e38\u4f1a\u4f7f\u7528\u201c\u5982\u679c\u9519\u8bef\u4e86\u5c31\u63d0\u524d\u8fd4\u56de\u201d\u7684\u5199\u6cd5\u3002\u8fd9\u88ab\u79f0\u4e3a \u63d0\u524d\u8fd4\u56de (early-return) \uff0c\u4e00\u79cd\u4f18\u8d28\u7684\u4ee3\u7801\u5199\u6cd5\uff0c\u6bd4\u5f04\u4e2a\u5f88\u5927\u7684 else \u5206\u652f\u8981\u53ef\u7ef4\u62a4\u5f97\u591a\u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u7136\u800c\u8fd9\u6709\u65f6\u6211\u4eec\u4f1a\u5fd8\u8bb0\u5728\u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d delete \u4e4b\u524d\u5206\u914d\u8fc7\u7684\u6240\u6709\u6307\u5411\u52a8\u6001\u5185\u5b58\u7684\u6307\u9488\u3002 int func() { Foo *foo = new Foo(); ... if (\u51fa\u9519) { // \u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d\u5fd8\u8bb0 delete foo\uff01 return -1; } ... delete foo; return 0; } \u8fc7\u53bb\uff0c\u4eba\u4eec\u4f7f\u7528 goto \u5927\u6cd5\u62d9\u52a3\u5730\u5728\u63d0\u524d\u8fd4\u56de\u65f6 delete \u52a8\u6001\u5185\u5b58\uff1a int main() { Foo *foo1, *foo2; int ret = 0; foo1 = new Foo(); ... if (\u51fa\u9519) { ret = -1; goto out_foo1; } ... Foo *foo2 = new Foo(); ... if (\u51fa\u9519) { ret = -2; goto out_foo2; } ... out_foo2: delete foo2; out_foo1: delete foo1; return ret; } \u8fd9\u5bf9\u4e8e\u201c\u5199\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5176\u5b9e\u8fd8\u4e0d\u7b97\u4ec0\u4e48\uff0c\u65e0\u975e\u5c31\u662f\u6ce8\u610f\u5339\u914d\uff0c\u53cd\u6b63\u90fd\u662f\u4e00\u6b21\u6027\u5199\u5b8c\u5c31\u5f97\u4e86\u3002 \u771f\u6b63\u906d\u7f6a\u7684\u662f\u201c\u6539\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5982\u679c\u4ed6\u8981\u5220\u6389foo1\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u5728\u4e24\u4e2a\u5730\u65b9\u6765\u56de\u8df3\u8f6c\uff0c\u5982\u679cfoo1\u53d8\u6210 new[] \u4e86\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u8df3\u5230\u4e0b\u9762\u628a delete foo1 \u4e5f\u6539\u6210 delete[] foo1 \u3002\u5982\u679cfoo1\u8981\u6539\u540d\uff0c\u90a3\u4e48\u8fd8\u9700\u8981\u8df3\u5230\u4e0b\u9762 out_foo1: \u6807\u7b7e\u4e5f\u6539\u4e86\u3002\u5982\u679c\u8981\u65b0\u589e\u4e00\u4e2afoo3\u6307\u9488\uff0c\u90a3\u8fd8\u9700\u8981\u8df3\u5230\u4e0a\u9762\u52a0\u4e2a Foo *foo3; \uff0c\u4e0b\u9762\u52a0\u4e2a\u6807\u7b7e\u548c delete\u3002 BUG\u6f2b\u6f2b\u5176\u4fee\u8fdc\u516e\uff0c\u543e\u5c06\u4e0a\u4e0b\u800c\u6c42\u7d22\u3002 \u4f60\u662f\u5426\u9047\u5230\u8fc7\u5199\u7a0b\u5e8f\u68ad\u54c8\uff0c\u4e8b\u540e\u201c\u4e0a\u4e0b\u6c42\u7d22\u201d\u7684\u60c5\u51b5\uff1f\u540c\u4e00\u4e2a\u53d8\u91cf foo \u7684\u751f\u547d\u5468\u671f\u88ab\u6781\u9650\u6495\u626f\uff0c\u5206\u5c45\u4e24\u5730\uff0c\u6781\u5927\u7684\u59a8\u788d\u4e86\u6211\u4eec\u6539\u7a0b\u5e8f\u7684\u6548\u7387\u3002 \u800c\u7edf\u8ba1\u8868\u660e\uff0c\u7a0b\u5e8f\u545810%\u7684\u65f6\u95f4\u7528\u4e8e\u5199\u4ee3\u7801\uff0c90%\u7684\u65f6\u95f4\u82b1\u5728\u6539\u4ee3\u7801\u4e0a\u3002\u8282\u7ea6\u6539\u4ee3\u7801\u7684\u65f6\u95f4\uff0c\u5c31\u662f\u8282\u7ea6\u7a0b\u5e8f\u545890%\u7684\u751f\u547d\u3002\u6539\u4ee3\u7801\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u53ef\u4ee5\u7701\u53bb\u8f6f\u4ef6\u4e2d90%\u7684BUG\u3002 \u6240\u4ee5\uff0c\u9664\u975e\u4f60\u662f\u4e00\u6b21\u6027\u4ea4\u5dee\u9879\u76ee\u4e0d\u6253\u7b97\u66f4\u65b0\u4e86\uff0c\u6216\u8005\u786e\u8ba4\u4e86\u6539\u4ee3\u7801\u7684\u4eba\u4e0d\u4f1a\u662f\u4f60\uff0c\u5426\u5219\u5fc5\u7136\u8981\u7528\u5305\u62ec\u667a\u80fd\u6307\u9488\u3001\u8bbe\u8ba1\u6a21\u5f0f\u5728\u5185\u7684\u5404\u79cd\u624b\u6bb5\u7aed\u529b\u907f\u514d\u4ee3\u7801\u5206\u6563\u5316\u3002 \u5728\u4e00\u4e2a\u5e9e\u5927\u7684\u4ee3\u7801\u7cfb\u7edf\u4e2d\u770b\u5230\u539f\u59cb\u6307\u9488\u662f\u6700\u5934\u75bc\u7684\uff1a Student *getstu(const char *name); \u6ca1\u6709\u4efb\u4f55\u4fe1\u606f\u544a\u8bc9\u6211\uff1a \u8fd9\u4e2a\u6307\u9488\u6307\u5411\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5982\u4f55\uff1f \u8981\u6211\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u5417\uff1f \u5982\u4f55\u91ca\u653e\uff0c delete \u3001 delete[] \u3001 free \u3001\u8fd8\u662f fclose \uff1f \u53ef\u4ee5\u662f\u7a7a\u6307\u9488\u5417\uff1f \u6570\u7ec4\u8fd8\u662f\u5355\u4e2a\u5bf9\u8c61\uff1f \u5982\u679c\u662f\u6570\u7ec4\uff0c\u90a3\u4e48\u957f\u5ea6\u591a\u5c11\uff1f\u662fC\u98ce\u683c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u5417\uff1f \u662f\u5426\u79fb\u4ea4\u6240\u6709\u6743\uff1f \u5171\u4eab\u6216\u72ec\u5360\uff1f \u8be5\u8d44\u6e90\u53ef\u4ee5\u62f7\u8d1d\u5417\uff1f \u5982\u679c\u53ef\u4ee5\uff0c\u5982\u4f55\u62f7\u8d1d\uff1f \u800c\u4f60\u53ea\u80fd\u901a\u8fc7\u67e5\u9605\u6587\u6863\uff0c\u624d\u80fd\u786e\u8ba4\u8fd9\u4e9b\u4fe1\u606f\uff0c\u62d6\u6162\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u800c\u4f7f\u7528 RAII \u5bb9\u5668\uff08\u4e0d\u4ec5\u662f\u53ea\u80fd\u6307\u9488\uff09\u4f5c\u4e3a\u7c7b\u578b\uff0c\u5c31\u80fd\u8ba9\u4eba\u4e00\u773c\u5c31\u770b\u51fa\u4ee5\u4e0a10\u4e2a\u4fe1\u606f\u3002 gsl::not_null> getstu1(std::string_view name); Student &getstu2(std::string_view name); \u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u4e00\u770b\u5c31\u660e\u767d\uff0cgetstu1\u4f1a\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\uff1bgetstu2\u4e0d\u8f6c\u79fb\u6240\u6709\u6743\uff0c\u4ec5\u4ec5\u53ea\u662f\u63d0\u4f9b\u7ed9\u8c03\u7528\u8005\u8bbf\u95ee\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u3002 \u4f20\u7edf\u6307\u9488\u56e0\u4e3a\u8bed\u4e49\u4e0d\u660e\u786e\uff0c\u529f\u80fd\u591a\u6837\u5316\uff0c\u6709\u7528\u9519\u7684\u53ef\u80fd\uff0c\u4f8b\u5982\u7528\u6237\u53ef\u80fd\u5077\u61d2\u4e0d\u770b\u6587\u6863\uff0c\u5c31\u64c5\u81ea\u778e\u5199\uff1a char name; Student *stu = getstu(&name); if (stu == NULL) exit(1); free(stu); \u5b9e\u9645\u4e0a getstu \u7684\u53c2\u6570 name \u9700\u8981\u662f\u4e00\u4e2a C \u98ce\u683c 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u7528\u6237\u5374\u4e0d\u5c0f\u5fc3\u5f53\u4f5c\u5355\u4e2a char \u7684\u6307\u9488\u5199\u4e86\uff0c\u7f16\u8bd1\u5668\u6ca1\u6709\u62a5\u9519\u3002 \u800c stu \u5b9e\u9645\u4e0a\u662f getstu \u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u4e34\u65f6\u5f15\u7528\uff0c\u5e76\u4e0d\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u800c\u7528\u6237\u5374\u60f3\u5f53\u7136\u7684\u91ca\u653e\u4e86\u3002 \u5e76\u4e14\u5b9e\u9645\u4e0a getstu \u4ece\u4e0d\u8fd4\u56de\u7a7a\u6307\u9488\uff0c\u7528\u6237\u6839\u672c\u4e0d\u7528\u63d0\u5fc3\u540a\u80c6\u5730\u68c0\u67e5\u3002 \u4e00\u4e2a\u4f18\u8d28\u7684\u51fd\u6570\u63a5\u53e3\uff0c\u5c31\u4e0d\u5e94\u8be5\u7ed9\u7528\u6237\u8fd9\u79cd\u72af\u9519\u7684\u673a\u4f1a\u3002 \u6211\u77e5\u9053\uff0c\u4f60\u4f1a\u8bf4\uff0c std::string \u4e0d\u4e5f\u80fd\u4ece &name \u6784\u9020\uff0c\u653e\u4efb\u7f16\u8bd1\u901a\u8fc7\uff0c\u4e0d\u4e5f\u4f1a\u72af\u9519\u5417\uff1f \u662f\u8fd9\u6837\u7684\uff0c\u4f60\u751a\u81f3\u53ef\u4ee5\u4ece 0 \u6784\u9020 std::string \uff0c\u7f16\u8bd1\u4e00\u6837\u901a\u8fc7\uff0c\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u5d29\u6e83\uff1a std::string s = 0; // 0 \u88ab\u5f53\u4f5c NULL\uff0c\u4ece\u800c\u8c03\u7528\u6784\u9020\u51fd\u6570 std::string(const char *) \u6807\u51c6\u5e93\u91cc\u4e0d\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u6a21\u5f0f\u7684\u591a\u4e86\u53bb\u4e86\uff0c\u6807\u51c6\u5e93\u7684\u5783\u573e\u662f\u5386\u53f2\u9057\u7559\u95ee\u9898\uff0c\u4e0d\u662f\u5c0f\u5f6d\u8001\u5e08\u7684\u95ee\u9898\u3002 \u800c\u667a\u80fd\u6307\u9488\uff0c\u4e0d\u8bba\u662f\u63d0\u524d\u8fd4\u56de\u8fd8\u662f\u6700\u7ec8\u7684\u8fd4\u56de\uff0c\u53ea\u8981\u662f\u51fd\u6570\u7ed3\u675f\u4e86\uff0c\u90fd\u80fd\u81ea\u52a8\u91ca\u653e\u3002\u667a\u80fd\u6307\u9488\u4f7f\u5f97\u7a0b\u5e8f\u5458\u5199\u51fa\u201c\u63d0\u524d\u8fd4\u56de\u5f0f\u201d\u6beb\u65e0\u7cbe\u795e\u538b\u529b\uff0c\u518d\u4e5f\u4e0d\u7528\u60e6\u8bb0\u7740\u54ea\u4e9b\u9700\u8981\u91ca\u653e\u3002 int func() { shared_ptr foo = make_shared(); ... if (\u51fa\u9519) { return -1; } ... return 0; } shared_ptr \u5c0f\u8bfe\u5802 \u81ea\u52a8\u91ca\u653e void func() { shared_ptr fooPtr = make_shared(); ... } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 fooPtr \u662f\u552f\u4e00\u4e5f\u662f\u6700\u540e\u4e00\u4e2a\u6301\u6709 foo \u5bf9\u8c61\u7684\u667a\u80fd\u6307\u9488\u3002 \u6240\u4ee5\u79bb\u5f00 func \u4f5c\u7528\u57df\u65f6\uff0c\u5176\u6307\u5411\u7684 foo \u5bf9\u8c61\u5c31\u4f1a\u9500\u6bc1\u3002 \u4fdd\u5b58\u7eed\u547d shared_ptr globalPtr; void func() { shared_ptr fooPtr = make_shared(); ... globalPtr = fooPtr; } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 \u4f46\u662f globalPtr \u662f\u5168\u5c40\u53d8\u91cf\uff0c\u76f4\u5230\u7a0b\u5e8f\u9000\u51fa\u624d\u4f1a\u9500\u6bc1\u3002 \u76f8\u5f53\u4e8e\u5e2e\u539f fooPtr \u6307\u5411\u7684\u5bf9\u8c61\u5e2e\u7eed\u547d\u4e86\uff01 \u63d0\u524d\u91ca\u653e void other() { globalPtr = nullptr; // \u76f8\u5f53\u4e8e\u4f20\u7edf\u6307\u9488\u7684 delete } \u4f46\u662f\u5982\u679c\u73b0\u5728\u53c8\u4e00\u4e2a\u51fd\u6570\u7ed9 globalPtr \u5199\u5165\u7a7a\u6307\u9488\u3002 \u8fd9\u65f6\u4e4b\u524d\u5bf9\u539f\u5bf9\u8c61\u7684\u5f15\u7528\u5c31\u6ca1\u6709\u4e86\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u4e00\u4e2a\u7a7a\u6307\u9488\u53ef\u4ee5\u4f7f\u5176\u6307\u5411\u7684\u5bf9\u8c61\u91ca\u653e\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u7a7a\u6307\u9488\u7684\u6548\u679c\u548c delete \u5f88\u50cf\uff0c\u533a\u522b\u5728\u4e8e\uff1a \u5982\u679c\u4f60\u5fd8\u4e86 delete \u5c31\u5b8c\u4e86\uff01 \u4f60\u5c31\u7b97\u4e0d\u5199\u5165\u7a7a\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u4e5f\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u5199\u5165\u7a7a\u6307\u9488\u53ea\u662f\u628a\u6b7b\u671f\u63d0\u524d\u4e86\u4e00\u70b9\u800c\u5df2\u2026\u2026 shared_ptr p = make_shared(); p = nullptr; // 1 p.reset(); // 2 } // 3 P.S. \u540c\u7406\uff0cvector \u4e5f\u53ef\u4ee5\u901a\u8fc7 v = {} \u6216 v.clear() \u6765\u63d0\u524d\u91ca\u653e\u5185\u5b58\u3002 \u603b\u7ed3 \u5f53\u4f60\u9700\u8981\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4\uff1avector \u5f53\u4f60\u9700\u8981\u521b\u5efa\u5355\u4e2a\u5bf9\u8c61\uff1ashared_ptr \u5f53\u4f60\u60f3\u63d0\u524d delete\uff1a\u5199\u5165\u7a7a\u6307\u9488 \u7ebf\u7a0b\u5b89\u5168\uff1f \u4f3c\u4e4e\u5f88\u591a\u4e09\u811a\u732b\u6559\u6750\u90fd\u5728\u6a21\u68f1\u4e24\u53ef\u5730\u8fa9\u8bba\u4e00\u4e2a\u95ee\u9898\uff1ashared_ptr \u5230\u5e95\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff1f \u4e0d\u8bba\u4ec0\u4e48\u7c7b\u578b\uff0c\u90fd\u8981\u770b\u4f60\u7684\u7528\u51b5\uff0c\u624d\u80fd\u77e5\u9053\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\uff0c\u8fd9\u91cc\u5206\u4e3a\u4e09\u79cd\u60c5\u51b5\u8ba8\u8bba\uff1a \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u540c\u4e00\u4e2a\u5730\u65b9\u62f7\u8d1d shared_ptr \u51fa\u6765\u662f\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b\u53ea\u8bfb\u6c38\u8fdc\u5b89\u5168\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1 = a; } void t1() { shared_ptr b2 = a; } \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u5f80\u540c\u4e00\u4e2a\u5730\u65b9\u5199\u5165 shared_ptr \u662f\u4e0d\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b 1 \u5199 n \u8bfb\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1; a = b1; } void t1() { shared_ptr b2; a = b2; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f atomic> \u3002 shared_ptr \u5e76\u4e0d\u4fdd\u62a4\u5176\u6307\u5411 T \u7c7b\u578b\u7684\u7ebf\u7a0b\u5b89\u5168\uff08\u4f60\u81ea\u5df1 T \u5b9e\u73b0\u7684\u5c31\u4e0d\u5b89\u5168\u602a\u6211\u6307\u9488???\uff09\uff1a shared_ptr a; void t1() { a->b1 = 0; } void t1() { a->b1 = 1; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f\u7ed9\u4f60\u7684 T \u7c7b\u578b\u91cc\u9762\u52a0\u4e2a mutex \u4fdd\u62a4\u597d\u81ea\u5df1\uff0c\u800c\u4e0d\u662f\u6765\u602a\u6211\u6307\u9488\u3002 \u76f4\u63a5\u7684\u7b54\u6848\uff1a\u4ed6\u4eec\u8bf4\u7684\u662f\uff0cshared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u8fd9\u4e0d\u662f\u5e9f\u8bdd\u5417\uff1f\u6211\u53ea\u662f\u62f7\u8d1d\u53e6\u4e00\u4e2a shared_ptr\uff0c\u5bf9\u90a3\u4e2a shared_ptr \u53c8\u4e0d\u8fdb\u884c\u66f4\u6539\uff0c\u5f53\u7136\u4e0d\u4f1a\u53d1\u751f\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u6211\u81ea\u5df1\u6790\u6784\u5173\u4f60\u5176\u4ed6 shared_ptr \u4ec0\u4e48\u4e8b\uff0c\u5f53\u7136\u5c31\u6ca1\u6709\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u8fd9\u662f\u975e\u5e38\u76f4\u89c2\u7684\uff0c\u548c\u666e\u901a\u6307\u9488\u7684\u7ebf\u7a0b\u5b89\u5168\u6ca1\u6709\u4efb\u4f55\u4e0d\u540c\u3002 \u4e4b\u6240\u4ee5\u8fd9\u4e9b\u72d7\u5e01\u6559\u6750\u4f1a\u8fa9\u8bba\uff0c\u662f\u56e0\u4e3a\u4ed6\u4eec\u8001\u7231\u591a\u7ba1\u95f2\u4e8b\uff0c\u4ed6\u4eec\u4e86\u89e3\u5230 shared_ptr \u7684\u5e95\u5c42\u7ec6\u8282\u4e2d\u6709\u4e2a\u63a7\u5236\u5757\u7684\u5b58\u5728\uff0c\u800c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u9700\u8981\u4fee\u6539\u63a7\u5236\u5757\u7684\u8ba1\u6570\u503c\uff0c\u6240\u4ee5\u5b9e\u9645\u6807\u51c6\u5e93\u7684\u5b9e\u73b0\u4e2d\uff0c\u4f1a\u628a\u8fd9\u4e2a\u8ba1\u6570\u5668\u8bbe\u4e3a\u539f\u5b50\u7684\uff0c\u6700\u7ec8\u7ed3\u679c\u662f\u4f7f\u5f97 shared_ptr \u5728\u591a\u7ebf\u7a0b\u4e2d\u548c\u666e\u901a\u6307\u9488\u4e00\u6837\u5b89\u5168\u3002\u8fd9\u662f\u6807\u51c6\u5e93\u5e95\u5c42\u5b9e\u73b0\u7ec6\u8282\uff0c\u6211\u4eec\u4f5c\u4e3a\u9ad8\u5c42\u7528\u6237\u5e76\u4e0d\u9700\u8981\u8003\u8651\u4ed6\u5e95\u5c42\u5982\u4f55\u5b9e\u73b0\uff0c\u6211\u4eec\u53ea\u9700\u8981\u8bb0\u4f4f\u539f\u59cb\u6307\u9488\u600e\u6837\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0cshared_ptr \u5c31\u600e\u6837\u7ebf\u7a0b\u5b89\u5168\u3002 \u4f60\u4f1a\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5199\u5165\u540c\u4e00\u4e2a\u539f\u59cb\u6307\u9488\u5417\uff1f\u540c\u6837\u5730\uff0c\u5982\u679c\u4f60\u539f\u59cb\u6307\u9488\u4e0d\u4f1a\u72af\u9519\uff0cshared_ptr \u4e3a\u4ec0\u4e48\u4f1a\u72af\u9519\uff1f \u4f60\u53ef\u4ee5\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u540c\u4e00\u4e2a\u5168\u5c40\u7684\u539f\u59cb\u6307\u9488\u53d8\u91cf\uff0c\u540c\u6837\u5730\uff0cshared_ptr \u4e5f\u53ef\u4ee5\uff0c\u6709\u4efb\u4f55\u533a\u522b\u5417\uff1f \u53cd\u6b63\uff0cshared_ptr \u5185\u90e8\u4e13\u95e8\u4e3a\u7ebf\u7a0b\u5b89\u5168\u505a\u8fc7\u8bbe\u8ba1\uff0c\u4f60\u4e0d\u7528\u53bb\u64cd\u5fc3\u3002 placement new placement new \u548c placement delete \u4e5f\u53ef\u4ee5\u7528 std::construct_at \u548c std::destroy_at \u4ee3\u66ff\uff1a #include struct Foo { explicit Foo(int age) { ... } Foo(Foo &&) = delete; ~Foo() { ... } }; void func() { alignas(Foo) unsigned char buffer[sizeof(Foo)]; Foo *foo = std::construct_at(reinterpret_cast(buffer), 42, \"hello\"); // \u7b49\u4ef7\u4e8e new (buffer) Foo(42); ... std::destroy_at(foo); // \u7b49\u4ef7\u4e8e foo->~Foo(); } \u5728 \u5185\u5b58\u6a21\u578b\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb"},{"location":"no_more_new/#c-new","text":"\u4f7f\u7528 new \u548c delete \u662f\u4e00\u79cd\u8fc7\u65f6\u7684\u5185\u5b58\u7ba1\u7406\u65b9\u5f0f\uff0c\u5bb9\u6613\u5bfc\u81f4\u5185\u5b58\u6cc4\u6f0f\u548c\u60ac\u7a7a\u6307\u9488\uff0c\u5e94\u5f53\u6c38\u4e0d\u4f7f\u7528\u3002 \u4f18\u79c0\u7684\u73b0\u4ee3 C++ \u9879\u76ee\uff0c\u90fd\u4f7f\u7528 \u667a\u80fd\u6307\u9488 \u548c \u5bb9\u5668 \u7ba1\u7406\u5185\u5b58\uff0c\u4ece\u6765\u4e0d\u9700\u8981\u76f4\u63a5\u521b\u5efa\u539f\u59cb\u6307\u9488\u3002 \u4e0b\u5217\u4e09\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528 new \u548c delete\uff1a \u4f60\u5728\u5c01\u88c5\u4e00\u4e2a\u975e\u5e38\u5e95\u5c42\u7684\u5185\u5b58\u5206\u914d\u5668\u5e93\u3002 \u4f60\u662f C++98 \u7528\u6237\uff0c\u4e14\u4f60\u7684\u8001\u677f\u4e0d\u5141\u8bb8\u4f7f\u7528 boost\uff08\u5176\u63d0\u4f9b\u4e86\u667a\u80fd\u6307\u9488\uff09\u3002 \u4f60\u60f3\u8981\u521b\u9020\u4e00\u4e9b\u5185\u5b58\u6cc4\u6f0f\u6765\u60e9\u7f5a\u62d6\u6b20\u5de5\u8d44\u7684\u8111\u677f\u3002 \u540c\u7406\uff0cmalloc \u548c free \u4e5f\u662f\u4e0d\u5141\u8bb8\u7684\u3002 \u4e0d\u4ec5 new \u4e0d\u5e94\u8be5\u51fa\u73b0\uff0c\u539f\u59cb\u6307\u9488\u4e5f\u5e94\u8be5\u5c11\u51fa\u73b0\uff0c\u800c\u662f\u66f4\u5b89\u5168\uff0c\u7528\u6cd5\u66f4\u5355\u4e00\u7684 \u5f15\u7528 \u6216 span \u4ee3\u66ff\u3002 \u7528\u6cd5\u66f4\u5355\u4e00\u4e3a\u4ec0\u4e48\u662f\u597d\u4e8b\uff1f\u8bf7\u770b \u5f3a\u7c7b\u578b API \u8bbe\u8ba1\u4e13\u9898\u7ae0 \u3002","title":"\u73b0\u4ee3 C++ \u4ece\u62d2\u7edd new \u5f00\u59cb"},{"location":"no_more_new/#1","text":"\u540c\u5b66\uff1a\u6211\u60f3\u8981 \u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4 \uff0c\u4f60\u4e0d\u8ba9\u6211 new\uff0c\u6211\u8fd8\u80fd\u600e\u4e48\u529e\u5462\uff1f char *mem = new char[1024]; // \u540c\u5b66\u60f3\u8981 1024 \u5b57\u8282\u7684\u7f13\u51b2\u533a read(1, mem, 1024); // \u7528\u4e8e\u4f9b C \u8bed\u8a00\u7684\u8bfb\u6587\u4ef6\u51fd\u6570\u4f7f\u7528 delete[] mem; // \u9700\u8981\u624b\u52a8 delete \u53ef\u4ee5\u770b\u5230\uff0c\u4ed6\u6240\u8c13\u7684\u201c\u5185\u5b58\u7a7a\u95f4\u201d\u5b9e\u9645\u4e0a\u5c31\u662f\u4e00\u4e2a\u201cchar \u6570\u7ec4\u201d\u3002 \u5c0f\u5f6d\u8001\u5e08\uff1a\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0cvector \u5c31\u53ef\u4ee5\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 vector mem(1024); read(1, mem.data(), mem.size()); vector \u4e00\u6837\u7b26\u5408 RAII \u601d\u60f3\uff0c\u6784\u9020\u65f6\u81ea\u52a8\u7533\u8bf7\u5185\u5b58\uff0c\u79bb\u5f00\u4f5c\u7528\u57df\u65f6\u81ea\u52a8\u91ca\u653e\u3002 \u53ea\u9700\u5728\u8c03\u7528 C \u8bed\u8a00\u63a5\u53e3\u65f6\uff0c\u53d6\u51fa\u539f\u59cb\u6307\u9488\uff1a \u7528 data() \u5373\u53ef\u83b7\u53d6\u51fa\u9996\u4e2a char \u5143\u7d20\u7684\u6307\u9488\uff0c\u7528\u4e8e\u4f20\u9012\u7ed9 C \u8bed\u8a00\u51fd\u6570\u4f7f\u7528\u3002 \u7528 size() \u53d6\u51fa\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5373\u662f\u5185\u5b58\u7a7a\u95f4\u7684\u5b57\u8282\u6570\uff0c\u56e0\u4e3a\u6211\u4eec\u7684\u5143\u7d20\u7c7b\u578b\u662f char\uff0cchar \u521a\u597d\u5c31\u662f 1 \u5b57\u8282\u7684\uff0csize() \u521a\u597d\u5c31\u662f\u5b57\u8282\u7684\u6570\u91cf\u3002 \u6b64\u5904 read \u51fd\u6570\u8bfb\u5b8c\u540e\uff0c\u6570\u636e\u5c31\u76f4\u63a5\u8fdb\u5165\u4e86 vector \u4e2d\uff0c\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48 new\u3002 \u66f4\u73b0\u4ee3\u7684 C++ \u601d\u60f3\u5bb6\u8fd8\u4f1a\u7528 vector \uff0c\u660e\u786e\u533a\u5206\u8fd9\u662f\u201c\u5b57\u8282\u201d\u4e0d\u662f\u201c\u5b57\u7b26\u201d\u3002\u5982\u679c\u4f60\u8bfb\u51fa\u6765\u7684\u76ee\u7684\u662f\u5f53\u4f5c\u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528 std::string \u3002 \u6ce8\u610f\uff1a\u4e00\u4e9b\u611a\u8822\u7684\u6559\u6750\u4e2d\uff0c\u7528 shared_ptr \u548c unique_ptr \u6765\u7ba1\u7406\u6570\u7ec4\uff0c\u8fd9\u662f\u9519\u8bef\u7684\u3002 shared_ptr \u548c unique_ptr \u667a\u80fd\u6307\u9488\u4e3b\u8981\u662f\u7528\u4e8e\u7ba1\u7406\u201c\u5355\u4e2a\u5bf9\u8c61\u201d\u7684\uff0c\u4e0d\u662f\u7ba1\u7406\u201c\u6570\u7ec4\u201d\u7684\u3002 vector \u4e00\u76f4\u90fd\u662f\u6570\u7ec4\u7684\u7ba1\u7406\u65b9\u5f0f\uff0c\u4e14\u4ece C++98 \u5c31\u6709\u3002\u4e0d\u8981\u770b\u5230 \u201cnew \u7684\u66ff\u4ee3\u54c1\u201d \u53ea\u60f3\u5230\u667a\u80fd\u6307\u9488\u554a\uff01\u201cnew [] \u7684\u66ff\u4ee3\u54c1\u201d \u662f vector \u554a\uff01 \u6b64\u5904\u653e\u51fa\u4e00\u4e2a\u5229\u7528 std::wstring \u5206\u914d wchar_t * \u5185\u5b58\u7684\u6848\u4f8b\uff1a std::wstring utf8_to_wstring(std::string const &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), nullptr, 0); // \u5148\u786e\u5b9a\u957f\u5ea6 std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.data(), s.size(), ws.data(), ws.size()); // \u518d\u8bfb\u51fa\u6570\u636e return ws; }","title":"\u6848\u4f8b 1"},{"location":"no_more_new/#11","text":"\u6211\u4e00\u822c\u4f1a\u7528\u66f4\u76f4\u89c2\u7684 auto \u5199\u6cd5\uff0c\u8fd9\u6837\u66f4\u80fd\u660e\u786e\u8fd9\u662f\u5728\u521b\u5efa\u4e00\u4e2a vector \u5bf9\u8c61\uff0c\u7136\u540e\u4fdd\u5b58\u5230 mem \u8fd9\u4e2a\u53d8\u91cf\u540d\u4e2d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size()); \u8fd9\u88ab\u79f0\u4e3a auto-idiom\uff1a\u59cb\u7ec8\u4f7f\u7528 auto \u521d\u59cb\u5316\u53d8\u91cf\uff0c\u6c38\u8fdc\u522b\u4f7f\u7528\u53ef\u80fd\u5f15\u53d1\u6b67\u4e49\u7684\u7c7b\u578b\u524d\u7f6e\u3002","title":"\u8d34\u58eb 1.1"},{"location":"no_more_new/#12","text":"\u6709\u7684\u540c\u5b66\u4f1a\u60f3\u5f53\u7136\u5730\u63d0\u51fa\uff0c\u7528\u667a\u80fd\u6307\u9488\u4ee3\u66ff new\u3002 auto mem = make_shared(1024); read(1, mem.get(), 1024); \u53ef new \u7684\u66ff\u4ee3\u54c1\u4ece\u6765\u4e0d\u53ea\u6709\u667a\u80fd\u6307\u9488\u4e00\u4e2a\uff0c\u4e5f\u53ef\u4ee5\u662f vector \u5bb9\u5668\uff01 \u667a\u80fd\u6307\u9488\u53ea\u4f1a\u7528\u4e8e \u5355\u4e2a\u5bf9\u8c61 \uff01 \u52a8\u6001\u957f\u5ea6\u7684\u6570\u7ec4 \uff0c\u6b63\u5e38\u4eba\u90fd\u662f\u7528 vector \u7ba1\u7406\u7684\u3002 \u5f88\u591a\u52a3\u8d28\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u6750\u201d \u90fd\u5ffd\u7565\u4e86\u8fd9\u4e00\u70b9\uff0c\u603b\u662f\u523b\u610f\u5938\u5927\u4e86\u667a\u80fd\u6307\u9488\u7684\u8986\u76d6\u8303\u56f4\uff0c\u4e3a\u4e86\u65b0\u800c\u65b0\uff0c\u800c\u5bf9\u5b9e\u9645\u4e0a\u66f4\u9002\u5408\u7ba1\u7406 \u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4 \u7684 vector \u53ea\u5b57\u4e0d\u63d0\u3002 vector \u7ba1\u7406\u52a8\u6001\u957f\u5ea6\u5185\u5b58\u7a7a\u95f4\u7684\u4f18\u52bf\uff1a \u4f60\u53ef\u4ee5\u968f\u65f6\u968f\u5730 resize \u548c push_back\uff0c\u52a0\u5165\u65b0\u5143\u7d20\uff0c\u800c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\u8981\u91cd\u65b0\u8c03\u6574\u5927\u5c0f\u5c31\u6bd4\u8f83\u56f0\u96be\u3002 vector \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6df1\u62f7\u8d1d\uff0c\u7b26\u5408 C++ \u5bb9\u5668\u7684\u4e00\u822c\u7ea6\u5b9a\u3002\u800c unique_ptr \u5b8c\u5168\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u6df1\u62f7\u8d1d\u9700\u8981\u989d\u5916\u7684\u4ee3\u7801\uff0cshared_ptr \u5219\u662f\u6d45\u62f7\u8d1d\uff0c\u6709\u65f6\u4f1a\u5bfc\u81f4\u6570\u636e\u8986\u76d6\u3002 \u5176\u5b9e shared_ptr \u4e5f\u4e0d\u662f\u4e0d\u53ef\u4ee5\u7528\uff0c\u7136\u800c\uff0c\u667a\u80fd\u6307\u9488\u7ba1\u7406\u7684\u6570\u7ec4\uff0c\u5e76\u4e0d\u80fd\u65b9\u4fbf\u5730\u901a\u8fc7 .size() \u83b7\u53d6\u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5fc5\u987b\u7528\u53e6\u4e00\u4e2a\u53d8\u91cf\u5355\u72ec\u5b58\u50a8\u8fd9\u4e2a\u957f\u5ea6\u3002\u8fd9\u5c31\u8fdd\u80cc\u4e86\u5c01\u88c5\u539f\u5219\uff0c\u90a3\u4f1a\u4f7f\u4f60\u7684\u4ee3\u7801\u53d8\u5f97\u4e0d\u53ef\u7ef4\u62a4\u3002 \u7edd\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u53ef\u7ef4\u62a4\u6027\u603b\u662f\u6bd4\u6027\u80fd\u91cd\u8981\u7684\uff0c\u4f60\u53ea\u9700\u8981\u6bd4\u8f83 \u4f60\u91cd\u6784\u4ee3\u7801\u82b1\u7684\u65f6\u95f4 \u548c \u8ba1\u7b97\u673a\u8fd0\u884c\u8fd9\u6bb5\u4ee3\u7801\u6240\u9700\u65f6\u95f4 \u5c31\u660e\u767d\u503c\u4e0d\u503c\u4e86\u3002","title":"\u8d34\u58eb 1.2"},{"location":"no_more_new/#13","text":"\u5982\u679c\u662f\u5176\u4ed6\u7c7b\u578b\uff0c\u53ef\u80fd\u9700\u8981\u4e58\u4ee5 sizeof(\u5143\u7d20\u7c7b\u578b) \uff0c\u53d6\u51b3\u4e8e\u90a3\u4e2a C \u51fd\u6570\u8981\u6c42\u7684\u662f\u201c\u5b57\u8282\u6570\u201d\u8fd8\u662f\u201c\u5143\u7d20\u6570\u201d\u3002 auto mem = vector(1024); read(1, mem.data(), mem.size() * sizeof(mem[0])); auto max = find_max(mem.data(), mem.size());","title":"\u8d34\u58eb 1.3"},{"location":"no_more_new/#14","text":"\u5bf9\u4e8e\u4f60\u81ea\u5df1\u7684 C++ \u51fd\u6570\uff0c\u5c31\u6ca1\u5fc5\u8981\u518d\u63d0\u4f9b TODO: span, gsl::span, boost::span","title":"\u8d34\u58eb 1.4"},{"location":"no_more_new/#2","text":"\u540c\u5b66\uff1a\u6211\u9700\u8981\u5728\u201c\u5806\u201d\u4e0a\u5206\u914d\u4e00\u4e2a\u5bf9\u8c61\uff0c\u8ba9\u4ed6\u6301\u4e45\u5b58\u5728\u3002\u4f60\u4e0d\u8ba9\u6211\u7528 new\uff0c\u6211\u53ea\u80fd\u5728\u201c\u6808\u201d\u4e0a\u521b\u5efa\u4e34\u65f6\u5bf9\u8c61\u4e86\uff0c\u5982\u679c\u8981\u8fd4\u56de\u6216\u5b58\u8d77\u6765\u7684\u8bdd\u6839\u672c\u7528\u4e0d\u4e86\u554a\u3002 Foo *hello() { Foo *foo = new Foo(); return foo; } \u5c0f\u5f6d\u8001\u5e08\uff1a\u4f60\u53ef\u4ee5\u4f7f\u7528\u667a\u80fd\u6307\u9488\uff0c\u6700\u9002\u5408\u65b0\u4eba\u4e0a\u624b\u7684\u667a\u80fd\u6307\u9488\u662f shared_ptr\u3002 \u5f53\u6ca1\u6709\u4efb\u4f55\u51fd\u6570\u6216\u5bf9\u8c61\u6301\u6709\u8be5 shared_ptr \u6307\u5411\u7684\u5bf9\u8c61\u65f6\uff0c\u4e5f\u5c31\u662f\u5f53\u8c03\u7528\u8005\u5b58\u50a8 hello() \u8fd4\u56de\u503c\u7684\u51fd\u6570\u4f53\u9000\u51fa\u65f6\uff0c\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u88ab\u81ea\u52a8\u91ca\u653e\u3002 shared_ptr hello() { shared_ptr foo = make_shared(); return foo; } \u603b\u4e4b\uff0c\u8fd9\u6837\u66ff\u6362\u4f60\u7684\u4ee3\u7801\uff1a T * \u6362\u6210 shared_ptr new T(...) \u6362\u6210 make_shared(...) \u4f60\u7684\u4ee3\u7801\u5c31\u57fa\u672c\u4e0a\u5b89\u5168\u4e86\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8 delete \u4e86\u3002 \u6709\u4e2a\u7528\u4e86 shared_ptr \u8fd8\u4f1a\u5185\u5b58\u6cc4\u6f0f\u7684\u8fb9\u7f18\u60c5\u51b5\uff1a\u5faa\u73af\u5f15\u7528\uff0c\u901a\u5e38\u662f\u5b9e\u73b0\u53cc\u5411\u94fe\u8868\u65f6\uff0cweak_ptr \u53ef\u4ee5\u89e3\u51b3\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002","title":"\u6848\u4f8b 2"},{"location":"no_more_new/#21","text":"unique_ptr \u548c shared_ptr \u6709\u4ec0\u4e48\u533a\u522b\uff1f\u521d\u5b66\u8005\u5e94\u8be5\u5148\u5b66\u54ea\u4e2a\uff1f unique_ptr \u662f\u72ec\u5360\u6240\u6709\u6743\uff0c\u4ed6\u7684\u9650\u5236\u66f4\u591a\uff0c\u6bd4\u5982\uff1a \u4e0d\u5141\u8bb8\u62f7\u8d1d\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u3002 \u4e0d\u5141\u8bb8\u8d4b\u503c\uff0c\u53ea\u5141\u8bb8\u79fb\u52a8\u8d4b\u503c\u3002 \u7528 unique_ptr \u4e3b\u8981\u662f\u51fa\u4e8e\u6027\u80fd\u4f18\u52bf\u3002 \u7136\u800c\u6027\u80fd\u603b\u662f\u4e0d\u5982\u5b89\u5168\u91cd\u8981\u7684\uff0c\u4f60\u662f\u60f3\u8981 \u4e00\u4e2a\u9020\u5728\u706b\u661f\u7684\u8c6a\u534e\u5bab\u6bbf\uff0c\u8fd8\u662f\u4e00\u4e2a\u5730\u7403\u7684\u5b89\u5168\u8001\u5bb6\uff1f \u6240\u4ee5\uff0c\u5efa\u8bae\u4f60\u5148\u5168\u90e8\u66ff\u6362\u6210\u6cdb\u7528\u6027\u5f3a\u3001\u6613\u7528\u7684 shared_ptr\u3002\u7b49\u786e\u5b9e\u51fa\u73b0\u6027\u80fd\u74f6\u9888\u65f6\uff0c\u518d\u5bf9\u74f6\u9888\u90e8\u5206\u5355\u72ec\u8c03\u8bd5\u4f18\u5316\u4e5f\u4e0d\u8fdf\u3002 \u5148\u628a\u8001\u5bb6\u9020\u597d\u4e86\uff0c\u7136\u540e\u518d\u60f3\u529e\u6cd5\u79fb\u6c11\u706b\u661f\uff0c\u800c\u4e0d\u662f\u53cd\u8fc7\u6765\u3002","title":"\u8d34\u58eb 2.1"},{"location":"no_more_new/#22","text":"\u6709\u4e9b\u8001\u5f0f\u7684\u6240\u8c13 \u201c\u73b0\u4ee3 C++ \u6559\u7a0b\u201d \u4e2d\uff0c\u4f1a\u770b\u5230\u8fd9\u6837 new \u4e0e\u667a\u80fd\u6307\u9488\u5e76\u7528\u7684\u5199\u6cd5\uff1a shared_ptr foo(new Foo()); \u4ece C++14 \u5f00\u59cb\uff0c\u8fd9\u5df2\u7ecf\u662f \u8fc7\u65f6\u7684 \uff01\u5177\u6709\u5b89\u5168\u9690\u60a3\uff08\u5982\u679c\u6784\u9020\u51fd\u6570\u53ef\u80fd\u629b\u51fa\u5f02\u5e38\uff09\uff0c\u4e14\u5199\u8d77\u6765\u4e5f\u4e0d\u591f\u76f4\u89c2\u3002 \u73b0\u5728\u4eba\u4eec\u4e00\u822c\u90fd\u4f1a\u7528 make_shared \u51fd\u6570\uff0c\u5176\u5185\u90e8\u5c01\u88c5\u4e0d\u4ec5\u4fdd\u8bc1\u4e86\u5f02\u5e38\u5b89\u5168\uff0c\u800c\u4e14\u4f1a\u4f7f shared_ptr \u7684\u63a7\u5236\u5757\u4e0e Foo \u5bf9\u8c61\u524d\u540e\u7d27\u6328\u7740\uff0c\u53ea\u9700\u4e00\u6b21\u5185\u5b58\u5206\u914d\uff0c\u4e0d\u4ec5\u66f4\u76f4\u89c2\uff0c\u8fd8\u63d0\u5347\u4e86\u6027\u80fd\u3002 auto foo = make_shared(); \u6709\u8da3\u7684\u662f\uff0cmake_shared \u5728 C++11 \u5c31\u5f15\u5165\u4e86\uff0cmake_unique \u5374\u76f4\u5230 C++14 \u624d\u5f15\u5165\u3002 \u4ece C++14 \u5f00\u59cb\uff0c\u5185\u5b58\u5b89\u5168\u7684\u73b0\u4ee3 C++ \u7a0b\u5e8f\u4e2d\u5c31\u4e0d\u4f1a\u51fa\u73b0\u4efb\u4f55\u663e\u5f0f\u7684 new \u4e86\uff0c\u54ea\u6015\u662f\u5305\u5728 shared_ptr \u6216 unique_ptr \u5185\u7684\u4e5f\u4e0d\u884c\u3002\uff08\u9664\u4e86\u6700\u4e0a\u9762\u8bf4\u7684 3 \u79cd\u7279\u6b8a\u60c5\u51b5\uff09","title":"\u8d34\u58eb 2.2"},{"location":"no_more_new/#23","text":"\u5982\u679c\u4f60\u9700\u8981\u8c03\u7528\u7684 C \u8bed\u8a00\u63a5\u53e3\u8fd8\u9700\u8981\u539f\u59cb\u6307\u9488\u7684\u8bdd\uff0c\u7528 .get() \u53ef\u4ee5\u4ece\u667a\u80fd\u6307\u9488\u4e2d\u83b7\u53d6\u539f\u59cb\u6307\u9488\u3002\u5efa\u8bae\u53ea\u5728\u548c C \u8bed\u8a00\u6253\u4ea4\u9053\u65f6 .get() \uff0c\u5176\u4f59\u65f6\u95f4\u4e00\u5f8b shared_ptr \u4fdd\u8bc1\u5b89\u5168\u3002 extern \"C\" void some_c_function(Foo *foo); auto foo = make_shared(); some_c_function(foo.get());","title":"\u8d34\u58eb 2.3"},{"location":"no_more_new/#raii-delete","text":"\u5728\u65e5\u5e38\u4ee3\u7801\u4e2d\uff0c\u6211\u4eec\u5e38\u5e38\u4f1a\u4f7f\u7528\u201c\u5982\u679c\u9519\u8bef\u4e86\u5c31\u63d0\u524d\u8fd4\u56de\u201d\u7684\u5199\u6cd5\u3002\u8fd9\u88ab\u79f0\u4e3a \u63d0\u524d\u8fd4\u56de (early-return) \uff0c\u4e00\u79cd\u4f18\u8d28\u7684\u4ee3\u7801\u5199\u6cd5\uff0c\u6bd4\u5f04\u4e2a\u5f88\u5927\u7684 else \u5206\u652f\u8981\u53ef\u7ef4\u62a4\u5f97\u591a\u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u7136\u800c\u8fd9\u6709\u65f6\u6211\u4eec\u4f1a\u5fd8\u8bb0\u5728\u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d delete \u4e4b\u524d\u5206\u914d\u8fc7\u7684\u6240\u6709\u6307\u5411\u52a8\u6001\u5185\u5b58\u7684\u6307\u9488\u3002 int func() { Foo *foo = new Foo(); ... if (\u51fa\u9519) { // \u63d0\u524d\u8fd4\u56de\u7684\u5206\u652f\u4e2d\u5fd8\u8bb0 delete foo\uff01 return -1; } ... delete foo; return 0; } \u8fc7\u53bb\uff0c\u4eba\u4eec\u4f7f\u7528 goto \u5927\u6cd5\u62d9\u52a3\u5730\u5728\u63d0\u524d\u8fd4\u56de\u65f6 delete \u52a8\u6001\u5185\u5b58\uff1a int main() { Foo *foo1, *foo2; int ret = 0; foo1 = new Foo(); ... if (\u51fa\u9519) { ret = -1; goto out_foo1; } ... Foo *foo2 = new Foo(); ... if (\u51fa\u9519) { ret = -2; goto out_foo2; } ... out_foo2: delete foo2; out_foo1: delete foo1; return ret; } \u8fd9\u5bf9\u4e8e\u201c\u5199\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5176\u5b9e\u8fd8\u4e0d\u7b97\u4ec0\u4e48\uff0c\u65e0\u975e\u5c31\u662f\u6ce8\u610f\u5339\u914d\uff0c\u53cd\u6b63\u90fd\u662f\u4e00\u6b21\u6027\u5199\u5b8c\u5c31\u5f97\u4e86\u3002 \u771f\u6b63\u906d\u7f6a\u7684\u662f\u201c\u6539\u201d\u7a0b\u5e8f\u7684\u4eba\uff0c\u5982\u679c\u4ed6\u8981\u5220\u6389foo1\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u5728\u4e24\u4e2a\u5730\u65b9\u6765\u56de\u8df3\u8f6c\uff0c\u5982\u679cfoo1\u53d8\u6210 new[] \u4e86\uff0c\u90a3\u4e48\u4ed6\u9700\u8981\u8df3\u5230\u4e0b\u9762\u628a delete foo1 \u4e5f\u6539\u6210 delete[] foo1 \u3002\u5982\u679cfoo1\u8981\u6539\u540d\uff0c\u90a3\u4e48\u8fd8\u9700\u8981\u8df3\u5230\u4e0b\u9762 out_foo1: \u6807\u7b7e\u4e5f\u6539\u4e86\u3002\u5982\u679c\u8981\u65b0\u589e\u4e00\u4e2afoo3\u6307\u9488\uff0c\u90a3\u8fd8\u9700\u8981\u8df3\u5230\u4e0a\u9762\u52a0\u4e2a Foo *foo3; \uff0c\u4e0b\u9762\u52a0\u4e2a\u6807\u7b7e\u548c delete\u3002 BUG\u6f2b\u6f2b\u5176\u4fee\u8fdc\u516e\uff0c\u543e\u5c06\u4e0a\u4e0b\u800c\u6c42\u7d22\u3002 \u4f60\u662f\u5426\u9047\u5230\u8fc7\u5199\u7a0b\u5e8f\u68ad\u54c8\uff0c\u4e8b\u540e\u201c\u4e0a\u4e0b\u6c42\u7d22\u201d\u7684\u60c5\u51b5\uff1f\u540c\u4e00\u4e2a\u53d8\u91cf foo \u7684\u751f\u547d\u5468\u671f\u88ab\u6781\u9650\u6495\u626f\uff0c\u5206\u5c45\u4e24\u5730\uff0c\u6781\u5927\u7684\u59a8\u788d\u4e86\u6211\u4eec\u6539\u7a0b\u5e8f\u7684\u6548\u7387\u3002 \u800c\u7edf\u8ba1\u8868\u660e\uff0c\u7a0b\u5e8f\u545810%\u7684\u65f6\u95f4\u7528\u4e8e\u5199\u4ee3\u7801\uff0c90%\u7684\u65f6\u95f4\u82b1\u5728\u6539\u4ee3\u7801\u4e0a\u3002\u8282\u7ea6\u6539\u4ee3\u7801\u7684\u65f6\u95f4\uff0c\u5c31\u662f\u8282\u7ea6\u7a0b\u5e8f\u545890%\u7684\u751f\u547d\u3002\u6539\u4ee3\u7801\u4e0d\u5bb9\u6613\u51fa\u9519\uff0c\u53ef\u4ee5\u7701\u53bb\u8f6f\u4ef6\u4e2d90%\u7684BUG\u3002 \u6240\u4ee5\uff0c\u9664\u975e\u4f60\u662f\u4e00\u6b21\u6027\u4ea4\u5dee\u9879\u76ee\u4e0d\u6253\u7b97\u66f4\u65b0\u4e86\uff0c\u6216\u8005\u786e\u8ba4\u4e86\u6539\u4ee3\u7801\u7684\u4eba\u4e0d\u4f1a\u662f\u4f60\uff0c\u5426\u5219\u5fc5\u7136\u8981\u7528\u5305\u62ec\u667a\u80fd\u6307\u9488\u3001\u8bbe\u8ba1\u6a21\u5f0f\u5728\u5185\u7684\u5404\u79cd\u624b\u6bb5\u7aed\u529b\u907f\u514d\u4ee3\u7801\u5206\u6563\u5316\u3002 \u5728\u4e00\u4e2a\u5e9e\u5927\u7684\u4ee3\u7801\u7cfb\u7edf\u4e2d\u770b\u5230\u539f\u59cb\u6307\u9488\u662f\u6700\u5934\u75bc\u7684\uff1a Student *getstu(const char *name); \u6ca1\u6709\u4efb\u4f55\u4fe1\u606f\u544a\u8bc9\u6211\uff1a \u8fd9\u4e2a\u6307\u9488\u6307\u5411\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5982\u4f55\uff1f \u8981\u6211\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u5417\uff1f \u5982\u4f55\u91ca\u653e\uff0c delete \u3001 delete[] \u3001 free \u3001\u8fd8\u662f fclose \uff1f \u53ef\u4ee5\u662f\u7a7a\u6307\u9488\u5417\uff1f \u6570\u7ec4\u8fd8\u662f\u5355\u4e2a\u5bf9\u8c61\uff1f \u5982\u679c\u662f\u6570\u7ec4\uff0c\u90a3\u4e48\u957f\u5ea6\u591a\u5c11\uff1f\u662fC\u98ce\u683c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u5417\uff1f \u662f\u5426\u79fb\u4ea4\u6240\u6709\u6743\uff1f \u5171\u4eab\u6216\u72ec\u5360\uff1f \u8be5\u8d44\u6e90\u53ef\u4ee5\u62f7\u8d1d\u5417\uff1f \u5982\u679c\u53ef\u4ee5\uff0c\u5982\u4f55\u62f7\u8d1d\uff1f \u800c\u4f60\u53ea\u80fd\u901a\u8fc7\u67e5\u9605\u6587\u6863\uff0c\u624d\u80fd\u786e\u8ba4\u8fd9\u4e9b\u4fe1\u606f\uff0c\u62d6\u6162\u4e86\u5f00\u53d1\u6548\u7387\u3002 \u800c\u4f7f\u7528 RAII \u5bb9\u5668\uff08\u4e0d\u4ec5\u662f\u53ea\u80fd\u6307\u9488\uff09\u4f5c\u4e3a\u7c7b\u578b\uff0c\u5c31\u80fd\u8ba9\u4eba\u4e00\u773c\u5c31\u770b\u51fa\u4ee5\u4e0a10\u4e2a\u4fe1\u606f\u3002 gsl::not_null> getstu1(std::string_view name); Student &getstu2(std::string_view name); \u4ee5\u4e0a\u4ee3\u7801\u4e2d\uff0c\u4e00\u770b\u5c31\u660e\u767d\uff0cgetstu1\u4f1a\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\uff1bgetstu2\u4e0d\u8f6c\u79fb\u6240\u6709\u6743\uff0c\u4ec5\u4ec5\u53ea\u662f\u63d0\u4f9b\u7ed9\u8c03\u7528\u8005\u8bbf\u95ee\uff0c\u4e14\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u3002 \u4f20\u7edf\u6307\u9488\u56e0\u4e3a\u8bed\u4e49\u4e0d\u660e\u786e\uff0c\u529f\u80fd\u591a\u6837\u5316\uff0c\u6709\u7528\u9519\u7684\u53ef\u80fd\uff0c\u4f8b\u5982\u7528\u6237\u53ef\u80fd\u5077\u61d2\u4e0d\u770b\u6587\u6863\uff0c\u5c31\u64c5\u81ea\u778e\u5199\uff1a char name; Student *stu = getstu(&name); if (stu == NULL) exit(1); free(stu); \u5b9e\u9645\u4e0a getstu \u7684\u53c2\u6570 name \u9700\u8981\u662f\u4e00\u4e2a C \u98ce\u683c 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u7528\u6237\u5374\u4e0d\u5c0f\u5fc3\u5f53\u4f5c\u5355\u4e2a char \u7684\u6307\u9488\u5199\u4e86\uff0c\u7f16\u8bd1\u5668\u6ca1\u6709\u62a5\u9519\u3002 \u800c stu \u5b9e\u9645\u4e0a\u662f getstu \u8fd4\u56de\u7ed9\u8c03\u7528\u8005\u7684\u4e34\u65f6\u5f15\u7528\uff0c\u5e76\u4e0d\u79fb\u4ea4\u6240\u6709\u6743\uff0c\u800c\u7528\u6237\u5374\u60f3\u5f53\u7136\u7684\u91ca\u653e\u4e86\u3002 \u5e76\u4e14\u5b9e\u9645\u4e0a getstu \u4ece\u4e0d\u8fd4\u56de\u7a7a\u6307\u9488\uff0c\u7528\u6237\u6839\u672c\u4e0d\u7528\u63d0\u5fc3\u540a\u80c6\u5730\u68c0\u67e5\u3002 \u4e00\u4e2a\u4f18\u8d28\u7684\u51fd\u6570\u63a5\u53e3\uff0c\u5c31\u4e0d\u5e94\u8be5\u7ed9\u7528\u6237\u8fd9\u79cd\u72af\u9519\u7684\u673a\u4f1a\u3002 \u6211\u77e5\u9053\uff0c\u4f60\u4f1a\u8bf4\uff0c std::string \u4e0d\u4e5f\u80fd\u4ece &name \u6784\u9020\uff0c\u653e\u4efb\u7f16\u8bd1\u901a\u8fc7\uff0c\u4e0d\u4e5f\u4f1a\u72af\u9519\u5417\uff1f \u662f\u8fd9\u6837\u7684\uff0c\u4f60\u751a\u81f3\u53ef\u4ee5\u4ece 0 \u6784\u9020 std::string \uff0c\u7f16\u8bd1\u4e00\u6837\u901a\u8fc7\uff0c\u7a0b\u5e8f\u4f1a\u76f4\u63a5\u5d29\u6e83\uff1a std::string s = 0; // 0 \u88ab\u5f53\u4f5c NULL\uff0c\u4ece\u800c\u8c03\u7528\u6784\u9020\u51fd\u6570 std::string(const char *) \u6807\u51c6\u5e93\u91cc\u4e0d\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u8bbe\u8ba1\u6a21\u5f0f\u7684\u591a\u4e86\u53bb\u4e86\uff0c\u6807\u51c6\u5e93\u7684\u5783\u573e\u662f\u5386\u53f2\u9057\u7559\u95ee\u9898\uff0c\u4e0d\u662f\u5c0f\u5f6d\u8001\u5e08\u7684\u95ee\u9898\u3002 \u800c\u667a\u80fd\u6307\u9488\uff0c\u4e0d\u8bba\u662f\u63d0\u524d\u8fd4\u56de\u8fd8\u662f\u6700\u7ec8\u7684\u8fd4\u56de\uff0c\u53ea\u8981\u662f\u51fd\u6570\u7ed3\u675f\u4e86\uff0c\u90fd\u80fd\u81ea\u52a8\u91ca\u653e\u3002\u667a\u80fd\u6307\u9488\u4f7f\u5f97\u7a0b\u5e8f\u5458\u5199\u51fa\u201c\u63d0\u524d\u8fd4\u56de\u5f0f\u201d\u6beb\u65e0\u7cbe\u795e\u538b\u529b\uff0c\u518d\u4e5f\u4e0d\u7528\u60e6\u8bb0\u7740\u54ea\u4e9b\u9700\u8981\u91ca\u653e\u3002 int func() { shared_ptr foo = make_shared(); ... if (\u51fa\u9519) { return -1; } ... return 0; }","title":"RAII \u6bd4\u8d77\u624b\u52a8 delete \u7684\u4f18\u52bf"},{"location":"no_more_new/#shared_ptr","text":"","title":"shared_ptr \u5c0f\u8bfe\u5802"},{"location":"no_more_new/#_1","text":"void func() { shared_ptr fooPtr = make_shared(); ... } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 fooPtr \u662f\u552f\u4e00\u4e5f\u662f\u6700\u540e\u4e00\u4e2a\u6301\u6709 foo \u5bf9\u8c61\u7684\u667a\u80fd\u6307\u9488\u3002 \u6240\u4ee5\u79bb\u5f00 func \u4f5c\u7528\u57df\u65f6\uff0c\u5176\u6307\u5411\u7684 foo \u5bf9\u8c61\u5c31\u4f1a\u9500\u6bc1\u3002","title":"\u81ea\u52a8\u91ca\u653e"},{"location":"no_more_new/#_2","text":"shared_ptr globalPtr; void func() { shared_ptr fooPtr = make_shared(); ... globalPtr = fooPtr; } \u79bb\u5f00 func \u4f5c\u7528\u57df\uff0cfooPtr \u5c31\u9500\u6bc1\u4e86\u3002 \u4f46\u662f globalPtr \u662f\u5168\u5c40\u53d8\u91cf\uff0c\u76f4\u5230\u7a0b\u5e8f\u9000\u51fa\u624d\u4f1a\u9500\u6bc1\u3002 \u76f8\u5f53\u4e8e\u5e2e\u539f fooPtr \u6307\u5411\u7684\u5bf9\u8c61\u5e2e\u7eed\u547d\u4e86\uff01","title":"\u4fdd\u5b58\u7eed\u547d"},{"location":"no_more_new/#_3","text":"void other() { globalPtr = nullptr; // \u76f8\u5f53\u4e8e\u4f20\u7edf\u6307\u9488\u7684 delete } \u4f46\u662f\u5982\u679c\u73b0\u5728\u53c8\u4e00\u4e2a\u51fd\u6570\u7ed9 globalPtr \u5199\u5165\u7a7a\u6307\u9488\u3002 \u8fd9\u65f6\u4e4b\u524d\u5bf9\u539f\u5bf9\u8c61\u7684\u5f15\u7528\u5c31\u6ca1\u6709\u4e86\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u4e00\u4e2a\u7a7a\u6307\u9488\u53ef\u4ee5\u4f7f\u5176\u6307\u5411\u7684\u5bf9\u8c61\u91ca\u653e\u3002 \u5bf9\u667a\u80fd\u6307\u9488\u5199\u5165\u7a7a\u6307\u9488\u7684\u6548\u679c\u548c delete \u5f88\u50cf\uff0c\u533a\u522b\u5728\u4e8e\uff1a \u5982\u679c\u4f60\u5fd8\u4e86 delete \u5c31\u5b8c\u4e86\uff01 \u4f60\u5c31\u7b97\u4e0d\u5199\u5165\u7a7a\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u4e5f\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u5199\u5165\u7a7a\u6307\u9488\u53ea\u662f\u628a\u6b7b\u671f\u63d0\u524d\u4e86\u4e00\u70b9\u800c\u5df2\u2026\u2026 shared_ptr p = make_shared(); p = nullptr; // 1 p.reset(); // 2 } // 3 P.S. \u540c\u7406\uff0cvector \u4e5f\u53ef\u4ee5\u901a\u8fc7 v = {} \u6216 v.clear() \u6765\u63d0\u524d\u91ca\u653e\u5185\u5b58\u3002","title":"\u63d0\u524d\u91ca\u653e"},{"location":"no_more_new/#_4","text":"\u5f53\u4f60\u9700\u8981\u5206\u914d\u4e00\u6bb5\u5185\u5b58\u7a7a\u95f4\uff1avector \u5f53\u4f60\u9700\u8981\u521b\u5efa\u5355\u4e2a\u5bf9\u8c61\uff1ashared_ptr \u5f53\u4f60\u60f3\u63d0\u524d delete\uff1a\u5199\u5165\u7a7a\u6307\u9488","title":"\u603b\u7ed3"},{"location":"no_more_new/#_5","text":"\u4f3c\u4e4e\u5f88\u591a\u4e09\u811a\u732b\u6559\u6750\u90fd\u5728\u6a21\u68f1\u4e24\u53ef\u5730\u8fa9\u8bba\u4e00\u4e2a\u95ee\u9898\uff1ashared_ptr \u5230\u5e95\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff1f \u4e0d\u8bba\u4ec0\u4e48\u7c7b\u578b\uff0c\u90fd\u8981\u770b\u4f60\u7684\u7528\u51b5\uff0c\u624d\u80fd\u77e5\u9053\u662f\u4e0d\u662f\u7ebf\u7a0b\u5b89\u5168\uff0c\u8fd9\u91cc\u5206\u4e3a\u4e09\u79cd\u60c5\u51b5\u8ba8\u8bba\uff1a \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u540c\u4e00\u4e2a\u5730\u65b9\u62f7\u8d1d shared_ptr \u51fa\u6765\u662f\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b\u53ea\u8bfb\u6c38\u8fdc\u5b89\u5168\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1 = a; } void t1() { shared_ptr b2 = a; } \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u4ece\u5f80\u540c\u4e00\u4e2a\u5730\u65b9\u5199\u5165 shared_ptr \u662f\u4e0d\u5b89\u5168\u7684\uff08\u591a\u7ebf\u7a0b 1 \u5199 n \u8bfb\u5b9a\u5f8b\uff09\uff1a shared_ptr a; void t1() { shared_ptr b1; a = b1; } void t1() { shared_ptr b2; a = b2; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f atomic> \u3002 shared_ptr \u5e76\u4e0d\u4fdd\u62a4\u5176\u6307\u5411 T \u7c7b\u578b\u7684\u7ebf\u7a0b\u5b89\u5168\uff08\u4f60\u81ea\u5df1 T \u5b9e\u73b0\u7684\u5c31\u4e0d\u5b89\u5168\u602a\u6211\u6307\u9488???\uff09\uff1a shared_ptr a; void t1() { a->b1 = 0; } void t1() { a->b1 = 1; } \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u5e94\u8be5\u8003\u8651\u7684\u662f\u7ed9\u4f60\u7684 T \u7c7b\u578b\u91cc\u9762\u52a0\u4e2a mutex \u4fdd\u62a4\u597d\u81ea\u5df1\uff0c\u800c\u4e0d\u662f\u6765\u602a\u6211\u6307\u9488\u3002 \u76f4\u63a5\u7684\u7b54\u6848\uff1a\u4ed6\u4eec\u8bf4\u7684\u662f\uff0cshared_ptr \u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u8fd9\u4e0d\u662f\u5e9f\u8bdd\u5417\uff1f\u6211\u53ea\u662f\u62f7\u8d1d\u53e6\u4e00\u4e2a shared_ptr\uff0c\u5bf9\u90a3\u4e2a shared_ptr \u53c8\u4e0d\u8fdb\u884c\u66f4\u6539\uff0c\u5f53\u7136\u4e0d\u4f1a\u53d1\u751f\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u6211\u81ea\u5df1\u6790\u6784\u5173\u4f60\u5176\u4ed6 shared_ptr \u4ec0\u4e48\u4e8b\uff0c\u5f53\u7136\u5c31\u6ca1\u6709\u7ebf\u7a0b\u51b2\u7a81\u54af\u3002\u8fd9\u662f\u975e\u5e38\u76f4\u89c2\u7684\uff0c\u548c\u666e\u901a\u6307\u9488\u7684\u7ebf\u7a0b\u5b89\u5168\u6ca1\u6709\u4efb\u4f55\u4e0d\u540c\u3002 \u4e4b\u6240\u4ee5\u8fd9\u4e9b\u72d7\u5e01\u6559\u6750\u4f1a\u8fa9\u8bba\uff0c\u662f\u56e0\u4e3a\u4ed6\u4eec\u8001\u7231\u591a\u7ba1\u95f2\u4e8b\uff0c\u4ed6\u4eec\u4e86\u89e3\u5230 shared_ptr \u7684\u5e95\u5c42\u7ec6\u8282\u4e2d\u6709\u4e2a\u63a7\u5236\u5757\u7684\u5b58\u5728\uff0c\u800c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u3001\u6790\u6784\u51fd\u6570\u9700\u8981\u4fee\u6539\u63a7\u5236\u5757\u7684\u8ba1\u6570\u503c\uff0c\u6240\u4ee5\u5b9e\u9645\u6807\u51c6\u5e93\u7684\u5b9e\u73b0\u4e2d\uff0c\u4f1a\u628a\u8fd9\u4e2a\u8ba1\u6570\u5668\u8bbe\u4e3a\u539f\u5b50\u7684\uff0c\u6700\u7ec8\u7ed3\u679c\u662f\u4f7f\u5f97 shared_ptr \u5728\u591a\u7ebf\u7a0b\u4e2d\u548c\u666e\u901a\u6307\u9488\u4e00\u6837\u5b89\u5168\u3002\u8fd9\u662f\u6807\u51c6\u5e93\u5e95\u5c42\u5b9e\u73b0\u7ec6\u8282\uff0c\u6211\u4eec\u4f5c\u4e3a\u9ad8\u5c42\u7528\u6237\u5e76\u4e0d\u9700\u8981\u8003\u8651\u4ed6\u5e95\u5c42\u5982\u4f55\u5b9e\u73b0\uff0c\u6211\u4eec\u53ea\u9700\u8981\u8bb0\u4f4f\u539f\u59cb\u6307\u9488\u600e\u6837\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0cshared_ptr \u5c31\u600e\u6837\u7ebf\u7a0b\u5b89\u5168\u3002 \u4f60\u4f1a\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5199\u5165\u540c\u4e00\u4e2a\u539f\u59cb\u6307\u9488\u5417\uff1f\u540c\u6837\u5730\uff0c\u5982\u679c\u4f60\u539f\u59cb\u6307\u9488\u4e0d\u4f1a\u72af\u9519\uff0cshared_ptr \u4e3a\u4ec0\u4e48\u4f1a\u72af\u9519\uff1f \u4f60\u53ef\u4ee5\u4e24\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bfb\u53d6\u540c\u4e00\u4e2a\u5168\u5c40\u7684\u539f\u59cb\u6307\u9488\u53d8\u91cf\uff0c\u540c\u6837\u5730\uff0cshared_ptr \u4e5f\u53ef\u4ee5\uff0c\u6709\u4efb\u4f55\u533a\u522b\u5417\uff1f \u53cd\u6b63\uff0cshared_ptr \u5185\u90e8\u4e13\u95e8\u4e3a\u7ebf\u7a0b\u5b89\u5168\u505a\u8fc7\u8bbe\u8ba1\uff0c\u4f60\u4e0d\u7528\u53bb\u64cd\u5fc3\u3002","title":"\u7ebf\u7a0b\u5b89\u5168\uff1f"},{"location":"no_more_new/#placement-new","text":"placement new \u548c placement delete \u4e5f\u53ef\u4ee5\u7528 std::construct_at \u548c std::destroy_at \u4ee3\u66ff\uff1a #include struct Foo { explicit Foo(int age) { ... } Foo(Foo &&) = delete; ~Foo() { ... } }; void func() { alignas(Foo) unsigned char buffer[sizeof(Foo)]; Foo *foo = std::construct_at(reinterpret_cast(buffer), 42, \"hello\"); // \u7b49\u4ef7\u4e8e new (buffer) Foo(42); ... std::destroy_at(foo); // \u7b49\u4ef7\u4e8e foo->~Foo(); } \u5728 \u5185\u5b58\u6a21\u578b\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"placement new"},{"location":"platform/","text":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 \u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC GCC Clang \u7f16\u8bd1\u5668\u9009\u9879 C++ \u6807\u51c6 \u4f18\u5316\u7b49\u7ea7 \u8c03\u8bd5\u4fe1\u606f \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f C++11 ABI \u95ee\u9898 TODO IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 TODO \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u662f\u5c06\u6e90\u4ee3\u7801 ( .cpp ) \u7f16\u8bd1\u6210\u53ef\u6267\u884c\u7a0b\u5e8f ( .exe ) \u7684\u5de5\u5177\u3002 C++ \u662f \u7f16\u8bd1\u578b\u8bed\u8a00 \uff0c\u6e90\u4ee3\u7801\u4e0d\u80fd\u76f4\u63a5\u6267\u884c\u54e6\uff01\u521a\u5f00\u59cb\u5b66\u7f16\u7a0b\u7684\u5c0f\u5f6d\u8001\u5e08\u66fe\u7ecf\u628a\u7f51\u4e0a\u7684 \u201cHello, World\u201d \u4ee3\u7801\u62f7\u8d1d\u5230 .c \u6e90\u7801\u6587\u4ef6\u4e2d\uff0c\u7136\u540e\u628a\u540e\u7f00\u540d\u6539\u6210 .exe \uff0c\u53d1\u73b0\u8fd9\u6837\u6839\u672c\u6267\u884c\u4e0d\u4e86\u2026\u2026\u540e\u6765\u624d\u77e5\u9053\u9700\u8981\u901a\u8fc7\u4e00\u79cd\u53eb\u505a \u7f16\u8bd1\u5668 \u7f16\u8bd1 .c \u6587\u4ef6\uff0c\u624d\u80fd\u5f97\u5230\u8ba1\u7b97\u673a\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 C++ \u6e90\u7801 .cpp \u662f\u5199\u7ed9\u4eba\u7c7b\u770b\u7684\uff01\u8ba1\u7b97\u673a\u5e76\u4e0d\u8ba4\u8bc6\uff0c\u8ba1\u7b97\u673a\u53ea\u8ba4\u8bc6\u4e8c\u8fdb\u5236\u7684\u673a\u5668\u7801\u3002\u8981\u628a C++ \u6e90\u7801\u8f6c\u6362\u4e3a\u8ba1\u7b97\u673a\u53ef\u4ee5\u6267\u884c\u7684\u673a\u5668\u7801\u3002 \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u6700\u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u6709\uff1aGCC\u3001Clang\u3001MSVC \u4fd7\u79f0\u201c\u5fa1\u4e09\u5bb6\u201d\u3002 \u8fd9\u4e9b\u7f16\u8bd1\u5668\u90fd\u652f\u6301\u4e86\u5927\u90e8\u5206 C++20 \u6807\u51c6\u548c\u5c0f\u90e8\u5206 C++23 \u6807\u51c6\uff0c\u800c C++17 \u6807\u51c6\u90fd\u662f\u5b8c\u5168\u652f\u6301\u7684\u3002 \u6709\u4eba\u8bf4\u8fc7\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f GCC\u3002\u201d GCC \u4e3b\u8981\u53ea\u5728 Linux \u548c MacOS \u7b49 Unix \u7c7b\u7cfb\u7edf\u53ef\u7528\uff0c\u4e0d\u652f\u6301 Windows \u7cfb\u7edf\u3002\u4f46\u662f GCC \u6709\u7740\u5927\u91cf\u597d\u7528\u7684\u6269\u5c55\u529f\u80fd\uff0c\u4f8b\u5982\u5927\u540d\u9f0e\u9f0e\u7684 pbds \uff08\u57fa\u4e8e\u7b56\u7565\u7684\u6570\u636e\u7ed3\u6784\uff09\uff0c\u8fd8\u6709\u5404\u79cd __attribute__ \uff0c\u5404\u79cd __builtin_ \u7cfb\u5217\u51fd\u6570\u3002\u4e0d\u8fc7\u968f\u7740\u65b0\u6807\u51c6\u7684\u51fa\u53f0\uff0c\u5f88\u591a\u539f\u672c\u5c5e\u4e8e GCC \u7684\u529f\u80fd\u90fd\u6210\u4e86\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f8b\u5982 __attribute__((warn_unused)) \u53d8\u6210\u4e86\u6807\u51c6\u7684 [[nodiscard]] \uff0c __builtin_clz \u53d8\u6210\u4e86\u6807\u51c6\u7684 std::countl_zero \uff0c __VA_OPT__ \u540d\u5b57\u90fd\u6ca1\u53d8\u5c31\u8fdb\u4e86 C++20 \u6807\u51c6\u3002 PBDS \u53c8\u79f0 \u201c\u5e73\u677f\u7535\u89c6\u201d \u4e5f\u6709 MinGW \u8fd9\u6837\u7684\u9b54\u6539\u7248 GCC \u7f16\u8bd1\u5668\uff0c\u628a GCC \u79fb\u690d\u5230\u4e86 Windows \u7cfb\u7edf\u4e0a\uff0c\u540c\u65f6\u4e5f\u80fd\u7528 GCC \u7684\u4e00\u4e9b\u7279\u6027\u3002\u4e0d\u8fc7 MinGW \u6700\u8fd1\u5df2\u7ecf\u505c\u6b62\u66f4\u65b0\uff0c\u6700\u65b0\u7684 GCC Windows \u79fb\u690d\u7248\u7531 MinGW-w64 \u7ee7\u7eed\u7ef4\u62a4\u3002 Clang \u662f\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\uff0c\u652f\u6301\u5927\u591a\u6570\u4e3b\u6d41\u5e73\u53f0\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u754c\u7684\u5fa1\u4e09\u5bb6\uff1aLinux\u3001MacOS\u3001Windows\u3002Clang \u652f\u6301\u4e86\u5f88\u5927\u4e00\u90e8\u5206 GCC \u7279\u6027\u548c\u90e8\u5206 MSVC \u7279\u6027\u3002\u5176\u6240\u5c5e\u7684 LLVM \u9879\u76ee\u66f4\u662f\u7f16\u8bd1\u5668\u9886\u57df\u7684\u4e2d\u6d41\u7825\u67f1\uff0c\u4e0d\u4ec5\u652f\u6301 C\u3001C++\u3001Objective-C\u3001Fortran \u7b49\uff0cRust \u548c Swift \u7b49\u8bed\u8a00\u4e5f\u662f\u57fa\u4e8e LLVM \u540e\u7aef\u7f16\u8bd1\u7684\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5f88\u591a\u663e\u5361\u5382\u5546\u7684 OpenGL \u9a71\u52a8\u4e5f\u662f\u57fa\u4e8e LLVM \u5b9e\u73b0\u7f16\u8bd1\u7684\u3002\u5e76\u4e14 Clang \u8eab\u517c\u6570\u804c\uff0c\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u8bd1\uff0c\u8fd8\u652f\u6301\u9759\u6001\u5206\u6790\u3002\u8bb8\u591a IDE \u5e38\u89c1\u7684\u8bed\u8a00\u670d\u52a1\u534f\u8bae (LSP) \u5c31\u662f\u57fa\u4e8e Clang \u7684\u670d\u52a1\u7248\u2014\u2014\u2014\u2014Clangd \u5b9e\u73b0\u7684 (\u4f8b\u5982\u4f60\u53ef\u4ee5\u6309 Ctrl \u70b9\u51fb\uff0c\u8df3\u8f6c\u5230\u51fd\u6570\u5b9a\u4e49\uff0c\u8fd9\u6837\u7684\u529f\u80fd\u5c31\u662f IDE \u901a\u8fc7\u8c03\u7528 Clangd \u7684 LSP \u63a5\u53e3\u5b9e\u73b0\uff09\u3002\u4e0d\u8fc7 Clang \u7684\u6027\u80fd\u4f18\u5316\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u867d\u7136\u6709\u52a9\u4e8e\u6027\u80fd\u63d0\u5347\uff0c\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u72af\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u53ef\u80fd\u4f18\u5316\u51fa\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u5982\u679c\u4f60\u8981\u5b9e\u9a8c\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u662f\u6700\u64c5\u957f\u590d\u73b0\u7684\u3002\u4e14 Clang \u5bf9\u4e00\u4e9b C++ \u65b0\u6807\u51c6\u7279\u6027\u652f\u6301\u76f8\u5bf9\u8f83\u6162\uff0c\u6ca1\u6709 GCC \u548c MSVC \u90a3\u4e48\u4e0a\u5fc3\u3002 \u4f8b\u5982 C++20 \u65e9\u5df2\u5141\u8bb8 lambda \u8868\u8fbe\u5f0f\u6355\u83b7 structural-binding \u53d8\u91cf\uff0c\u800c Clang \u81f3\u4eca\u8fd8\u6ca1\u6709\u652f\u6301\uff0c\u5c3d\u7ba1 Clang \u5df2\u7ecf\u652f\u6301\u4e86\u5f88\u591a\u5176\u4ed6 C++20 \u7279\u6027\u3002 Apple Clang \u662f\u82f9\u679c\u516c\u53f8\u81ea\u5df1\u9b54\u6539\u7684 Clang \u7248\u672c\uff0c\u53ea\u5728 MacOS \u7cfb\u7edf\u4e0a\u53ef\u7528\uff0c\u652f\u6301 Objective-C \u548c Swift \u8bed\u8a00\u3002\u4f46\u662f\u7248\u672c\u8f83\u5b98\u65b9 Clang \u843d\u540e\u4e00\u4e9b\uff0c\u5f88\u591a\u65b0\u7279\u6027\u90fd\u6ca1\u6709\u8ddf\u8fdb\uff0c\u57fa\u672c\u4e0a\u53ea\u6709\u4e13\u95e8\u4f3a\u5019\u82f9\u679c\u7684\u5f00\u53d1\u8005\u4f1a\u7528\u3002 GCC \u548c Clang \u4e5f\u652f\u6301 Objective-C\u3002 MSVC \u662f Windows \u9650\u5b9a\u7684\u7f16\u8bd1\u5668\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a MSVC \u7279\u6709\u7684\u6269\u5c55\u3002\u4e5f\u6709\u4eba\u5728 Clang \u4e0a\u9b54\u6539\u51fa\u4e86 MSVC \u517c\u5bb9\u6a21\u5f0f\uff0c\u517c\u987e Clang \u7279\u6027\u7684\u540c\u65f6\uff0c\u652f\u6301\u4e86 MSVC \u7684\u4e00\u4e9b\u7279\u6027\uff08\u4f8b\u5982 __declspec \uff09\uff0c\u53ef\u4ee5\u7f16\u8bd1\u7528\u4e86 MSVC \u7279\u6027\u7684\u4ee3\u7801\uff0c\u5373 clang-cl \uff0c\u5728\u6700\u65b0\u7684 VS2022 IDE \u4e2d\u4e5f\u96c6\u6210\u4e86 clang-cl \u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cMSVC \u7684\u4f18\u5316\u80fd\u529b\u662f\u6bd4\u8f83\u5dee\u7684\uff0c\u6bd4 GCC \u548c Clang \u90fd\u5dee\uff0c\u4f8b\u5982 MSVC \u51e0\u4e4e\u603b\u662f\u5047\u5b9a\u6240\u6709\u6307\u9488 aliasing\uff0c\u8fd9\u610f\u5473\u7740\u5f53\u9047\u5230\u5f88\u591a\u6307\u9488\u64cd\u4f5c\u7684\u5faa\u73af\u65f6\uff0c\u51e0\u4e4e\u6ca1\u6cd5\u505a\u5faa\u73af\u77e2\u91cf\u5316\u3002\u4f46\u662f\u4e5f\u4f7f\u5f97\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f Bug\uff0c\u53e6\u4e00\u65b9\u9762\uff0c\u8fd9\u4e5f\u5bfc\u81f4\u4e00\u4e9b\u53ea\u7528 MSVC \u7684\u4eba\u4e0d\u77e5\u9053\u67d0\u4e9b\u5199\u6cd5\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 Intel C++ compiler \u662f\u82f1\u7279\u5c14\u5f00\u53d1\u7684 C++ \u7f16\u8bd1\u5668\uff0c\u7531\u4e8e\u662f\u786c\u4ef6\u5382\u5546\u5f00\u53d1\u7684\uff0c\u7279\u522b\u64c5\u957f\u505a\u6027\u80fd\u4f18\u5316\u3002\u4f46\u7531\u4e8e\u66f4\u65b0\u8f83\u6162\uff0c\u57fa\u672c\u6ca1\u6709\u66f4\u4e0a\u65b0\u7279\u6027\uff0c\u4e5f\u6ca1\u4ec0\u4e48\u4eba\u5728\u7528\u4e86\u3002 \u6700\u8fd1\u4ed6\u4eec\u53c8\u51fa\u4e86\u4e2a Intel DPC++ compiler\uff0c\u652f\u6301\u6700\u65b0\u7684\u5e76\u884c\u7f16\u7a0b\u9886\u57df\u7279\u5b9a\u8bed\u8a00 SyCL\u3002 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC cl.exe main.cpp \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main.exe \u4e86\u3002 GCC g++ main.cpp -o main \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main \u4e86\u3002 Linux \u7cfb\u7edf\u7684\u53ef\u6267\u884c\u6587\u4ef6\u5e76\u6ca1\u6709\u540e\u7f00\u540d\uff0c\u6240\u4ee5\u6ca1\u6709 .exe \u540e\u7f00\u3002 Clang Windows \u4e0a\uff1a clang++.exe main.cpp -o main.exe Linux / MacOS \u4e0a\uff1a clang++ main.cpp -o main \u7f16\u8bd1\u5668\u9009\u9879 \u7f16\u8bd1\u5668\u9009\u9879\u662f\u7528\u6765\u63a7\u5236\u7f16\u8bd1\u5668\u7684\u884c\u4e3a\u7684\u3002\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u6709\u4e0d\u540c\u7684\u9009\u9879\uff0c\u8bed\u6cd5\u6709\u5fae\u5999\u7684\u4e0d\u540c\uff0c\u4f46\u5927\u81f4\u529f\u6548\u76f8\u540c\u3002 \u4f8b\u5982\u5f53\u6211\u4eec\u8bf4\u201c\u7f16\u8bd1\u8fd9\u4e2a\u6e90\u7801\u65f6\uff0c\u6211\u7528\u4e86 GCC \u7f16\u8bd1\u5668\uff0c -O3 \u548c -std=c++20 \u9009\u9879\u201d\uff0c\u8bf4\u7684\u5c31\u662f\u628a\u8fd9\u4e9b\u9009\u9879\u52a0\u5230\u4e86 g++ \u7684\u547d\u4ee4\u884c\u53c2\u6570\u4e2d\uff1a g++ -O3 -std=c++20 main.cpp -o main \u5176\u4e2d Clang \u548c GCC \u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\u5f88\u5927\u4ea4\u96c6\u3002\u800c MSVC \u57fa\u672c\u81ea\u6210\u4e00\u6d3e\u3002 Clang \u548c GCC \u7684\u9009\u9879\u90fd\u662f -xxx \u7684\u5f62\u5f0f\uff0cMSVC \u7684\u9009\u9879\u662f /xxx \u7684\u5f62\u5f0f\u3002 \u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\uff1a C++ \u6807\u51c6 \u6307\u5b9a\u8981\u9009\u7528\u7684 C++ \u6807\u51c6\u3002 Clang \u548c GCC\uff1a -std=c++98 \u3001 -std=c++03 \u3001 -std=c++11 \u3001 -std=c++14 \u3001 -std=c++17 \u3001 -std=c++20 \u3001 -std=c++23 MSVC\uff1a /std:c++98 \u3001 /std:c++11 \u3001 /std:c++14 \u3001 /std:c++17 \u3001 /std:c++20 \u3001 /std:c++latest \u4f8b\u5982\u8981\u7f16\u8bd1\u4e00\u4e2a C++20 \u6e90\u7801\u6587\u4ef6\uff0c\u5206\u522b\u7528 GCC\u3001Clang\u3001MSVC\uff1a GCC\uff08Linux\uff09\uff1a g++ -std=c++20 main.cpp -o main Clang\uff08Linux\uff09\uff1a clang++ -std=c++20 main.cpp -o main MSVC\uff08Windows\uff09\uff1a cl.exe /std:c++20 /c main.cpp \u4f18\u5316\u7b49\u7ea7 Clang \u548c GCC\uff1a -O0 \u3001 -O1 \u3001 -O2 \u3001 -O3 \u3001 -Ofast \u3001 -Os \u3001 -Oz \u3001 -Og -O0 \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u7f16\u8bd1\u901f\u5ea6\u6700\u5feb\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u5f00\u53d1\u4eba\u5458\u5185\u90e8\u8c03\u8bd5\u9636\u6bb5\u3002 -O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\uff08\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u7684\u4e0d\u53ef\u62b5\u8fbe\u4ee3\u7801\uff09\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u90e8\u5206\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\uff0c\u7f16\u8bd1\u901f\u5ea6\u8f83\u5feb\uff0c\u6267\u884c\u901f\u5ea6\u4e5f\u6bd4 -O0 \u5feb\u3002\u4f46\u662f\u4f1a\u4e22\u5931\u51fd\u6570\u7684\u884c\u53f7\u4fe1\u606f\uff0c\u5f71\u54cd\u8bf8\u5982 gdb \u7b49\u8c03\u8bd5\uff0c\u5982\u9700\u5feb\u901f\u8c03\u8bd5\u53ef\u4ee5\u7528 -Og \u9009\u9879\u3002 -O2 \uff1a\u6bd4 -O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\uff0c\u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002 -O3 \uff1a\u6bd4 -O2 \u66f4\u6fc0\u8fdb\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u590d\u6742\u7684\u5faa\u73af\u7528 SIMD \u77e2\u91cf\u6307\u4ee4\u4f18\u5316\u52a0\u901f\uff0c\u628a\u4e00\u4e9b\u590d\u6742\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u6027\u80fd\u63d0\u5347\u5f88\u5927\uff0c\u4f46\u662f\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b Bug\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u5219\u7edd\u4e0d\u4f1a\u6709\u95ee\u9898\uff0c\u5bf9\u81ea\u5df1\u7684\u4ee3\u7801\u8d28\u91cf\u6709\u81ea\u4fe1\u5c31\u53ef\u4ee5\u653e\u5fc3\u5f00\uff0c\u7f16\u8bd1\u901f\u5ea6\u4e5f\u4f1a\u5f88\u6162\uff0c\u4e00\u822c\u7528\u4e8e\u7a0b\u5e8f\u6700\u7ec8\u6210\u54c1\u53d1\u5e03\u9636\u6bb5\u3002 -Ofast \uff1a\u5728 -O3 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u5bf9\u6d6e\u70b9\u6570\u7684\u8fd0\u7b97\u8fdb\u884c\u66f4\u6df1\u5c42\u6b21\u7684\u4f18\u5316\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b\u6d6e\u70b9\u6570\u8ba1\u7b97\u7ed3\u679c\u4e0d\u51c6\u786e\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u4e0d\u6d89\u53ca\u5230 NaN \u548c Inf \u7684\u5904\u7406\uff0c\u90a3\u4e48 -Ofast \u4e0d\u4f1a\u6709\u592a\u5927\u7684\u95ee\u9898\uff0c\u4e00\u822c\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u9886\u57df\u7684\u7ec8\u6781\u6027\u80fd\u4f18\u5316\u3002 -Os \uff1a\u5728 -O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u6bd4 -O0 \u3001 -O1 \u3001 -O2 \u90fd\u8981\u5c0f\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Oz \uff1a\u5728 -Os \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u628a\u4ee3\u7801\u538b\u7f29\uff0c\u53ef\u80fd\u628a\u672c\u53ef\u4ee5\u4e00\u6761\u5927\u6307\u4ee4\u5b8c\u6210\u7684\u4efb\u52a1\u4e5f\u62c6\u6210\u591a\u6761\u5c0f\u6307\u4ee4\uff0c\u4e3a\u4e86\u7f29\u5c0f\u5c3a\u5bf8\u727a\u7272\u8fd0\u884c\u65f6\u6027\u80fd\uff0c\u5927\u5e45\u51cf\u5c11\u4e86\u51fd\u6570\u5185\u8054\u7684\u673a\u4f1a\uff0c\u6709\u65f6\u7528\u4e8e\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Og \uff1a\u5728 -O0 \u7684\u57fa\u7840\u4e0a\uff0c\u5c3d\u53ef\u80fd\u4fdd\u7559\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\uff0c\u4e0d\u505a\u7834\u574f\u51fd\u6570\u884c\u53f7\u7b49\u4fe1\u606f\u7684\u4f18\u5316\uff0c\u5efa\u8bae\u914d\u5408\u4ea7\u751f\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\u7684 -g \u9009\u9879\u4f7f\u7528\u3002\u4f46\u8fd8\u662f\u4f1a\u505a\u4e00\u4e9b\u7b80\u5355\u7684\u4f18\u5316\uff0c\u6bd4 -O0 \u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002\u4f46 -Og \u7684\u6240\u6709\u4f18\u5316\u90fd\u4e0d\u4f1a\u6d89\u53ca\u5230\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u6b64\u975e\u5e38\u9002\u5408\u8c03\u8bd5\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u4f46\u662f\u7531\u4e8e\u63d2\u5165\u4e86\u8c03\u8bd5\u4fe1\u606f\uff0c\u6700\u7ec8\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4f1a\u53d8\u5f97\u5f88\u5927\uff0c\u4e00\u822c\u5728\u5f00\u53d1\u4eba\u5458\u8c03\u8bd5\u65f6\u4f7f\u7528\u3002 MSVC\uff1a /Od \u3001 /O1 \u3001 /O2 \u3001 /Ox \u3001 /Ob1 \u3001 /Ob2 \u3001 /Os /Od \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u8c03\u8bd5\u9636\u6bb5\u3002 /O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\u3002 /O2 \uff1a\u6bd4 /O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u8fd8\u4f1a\u5c1d\u8bd5\u628a\u4e00\u4e9b\u5faa\u73af\u77e2\u91cf\u5316\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ox \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u4f18\u5316\uff0c\u4f46\u662f\u4e0d\u4f1a\u5bfc\u81f4\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ob1 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\u3002 /Ob2 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\uff0c\u4f46\u662f\u4f1a\u6269\u5927\u5185\u8054\u8303\u56f4\uff0c\u4e00\u822c\u6bd4 /Ob1 \u66f4\u5feb\uff0c\u4f46\u662f\u4e5f\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u3002 /Os \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 \u6ce8\u610f\uff1a\u51fd\u6570\u5185\u8054\u662f\u4e00\u79cd\u4f18\u5316\u7b56\u7565\uff0c\u548c inline \u5173\u952e\u5b57\u6beb\u65e0\u5173\u7cfb\uff0c\u8bf7\u770b\u7a0d\u540e\u63a8\u51fa\u7684\u7b26\u53f7\u94fe\u63a5\u4e13\u9898\u8bfe\u7a0b\u6216\u62a2\u5148\u770b \u5c0f\u5f6d\u8001\u5e08\u89c6\u9891 \u4e86\u89e3 inline \uff0c\u4ee5\u540e\u7684\u6027\u80fd\u4f18\u5316\u4e13\u9898\u8bfe\u7a0b\u4e5f\u4f1a\u4ecb\u7ecd\u51fd\u6570\u5185\u8054\u4f18\u5316\u7684\u6210\u529f\u6848\u4f8b\u3002 \u8c03\u8bd5\u4fe1\u606f Clang \u548c GCC\uff1a -g \u3001 -g0 \u3001 -g1 \u3001 -g2 \u3001 -g3 MSVC\uff1a /Z7 \u3001 /Zi \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f Clang \u548c GCC\uff1a -Dmacro=value MSVC\uff1a /Dmacro=value \u4f8b\u5982\uff1a \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 libstdc++ \u662f GCC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e GCC \u662f Linux \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libstdc++ \u4e5f\u662f Linux \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002\u4f60\u53ef\u4ee5\u5728\u8fd9\u91cc\u770b\u5230\u4ed6\u7684\u6e90\u7801\uff1ahttps://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3 libc++ \u662f Clang \u5b98\u65b9\u7f16\u5199\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e Clang \u662f MacOS \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libc++ \u4e5f\u662f MacOS \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002libc++ \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u65e9\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\u3002\u9879\u76ee\u7684\u5f00\u6e90\u5730\u5740\u662f\uff1ahttps://github.com/llvm/llvm-project/tree/main/libcxx MSVC STL \u662f MSVC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e MSVC \u662f Windows \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 MSVC STL \u4e5f\u662f Windows \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002MSVC STL \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u665a\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\uff0c\u4f46\u662f\u73b0\u5728\u4ed6\u5df2\u7ecf\u5b8c\u5168\u652f\u6301 C++20\uff0c\u5e76\u4e14\u4e5f\u5b8c\u5168\u5f00\u6e90\u4e86\uff1ahttps://github.com/microsoft/STL \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6807\u51c6\u5e93\u548c\u7f16\u8bd1\u5668\u5e76\u4e0d\u662f\u7ed1\u5b9a\u7684\uff0c\u4f8b\u5982 Clang \u53ef\u4ee5\u7528 libstdc++ \u6216 MSVC STL\uff0cGCC \u4e5f\u53ef\u4ee5\u88ab\u914d\u7f6e\u4f7f\u7528 libc++\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0cClang \u9ed8\u8ba4\u7528\u7684\u5c31\u662f libstdc++\u3002\u9700\u8981\u4e3a Clang \u6307\u5b9a -stdlib=libc++ \u9009\u9879\uff0c\u624d\u80fd\u4f7f\u7528\u3002 \u725b\u5934\u4eba\u7b11\u8bdd\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u6807\u51c6\u5e93\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f libstdc++\u3002\u56e0\u4e3a\u5373\u4f7f\u4ed6\u7684\u7f16\u8bd1\u5668\u662f Clang\uff0c\u4ed6\u7528\u7684\u5927\u6982\u7387\u4f9d\u7136\u662f libstdc++\u3002\u201d \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f TODO C++11 ABI \u95ee\u9898 \u5728\u4e00\u4e9b\u7279\u522b\u53e4\u8001\u7684\u53d1\u884c\u7248\u4e0a\uff08\u6bd4\u5982 Ubuntu 16.04\u3001CentOS\uff09\uff0c\u4ed6\u4eec\u7684\u6807\u51c6\u5e93\u4e0d\u652f\u6301 C++11\uff0c\u53ef\u4ee5\u5f00\u542f\u8fd9\u4e2a\u5b8f\uff1a #define _GLIBCXX_USE_CXX11_ABI 0 \u6216\u8005\u547d\u4ee4\u884c\u9009\u9879 -D_GLIBCXX_USE_CXX11_ABI=0 \u3002 \u4e3a\u4e86\u66f4\u597d\u7684\u5b66\u4e60\u73b0\u4ee3 C++\uff0c\u8fd8\u662f\u5efa\u8bae\u5b89\u88c5\u65b0\u7684\u53d1\u884c\u7248\u3002","title":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9"},{"location":"platform/#_1","text":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9 IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01 \u7f16\u8bd1\u5668\u662f\uff1f \u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6 \u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801 MSVC GCC Clang \u7f16\u8bd1\u5668\u9009\u9879 C++ \u6807\u51c6 \u4f18\u5316\u7b49\u7ea7 \u8c03\u8bd5\u4fe1\u606f \u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93 \u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84 \u5b9a\u4e49\u5b8f \u8b66\u544a\u5f00\u5173 \u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6 \u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f C++11 ABI \u95ee\u9898 TODO","title":"\u5f00\u53d1\u73af\u5883\u4e0e\u5e73\u53f0\u9009\u62e9"},{"location":"platform/#ide","text":"TODO","title":"IDE \u4e0d\u662f\u7f16\u8bd1\u5668\uff01"},{"location":"platform/#_2","text":"\u7f16\u8bd1\u5668\u662f\u5c06\u6e90\u4ee3\u7801 ( .cpp ) \u7f16\u8bd1\u6210\u53ef\u6267\u884c\u7a0b\u5e8f ( .exe ) \u7684\u5de5\u5177\u3002 C++ \u662f \u7f16\u8bd1\u578b\u8bed\u8a00 \uff0c\u6e90\u4ee3\u7801\u4e0d\u80fd\u76f4\u63a5\u6267\u884c\u54e6\uff01\u521a\u5f00\u59cb\u5b66\u7f16\u7a0b\u7684\u5c0f\u5f6d\u8001\u5e08\u66fe\u7ecf\u628a\u7f51\u4e0a\u7684 \u201cHello, World\u201d \u4ee3\u7801\u62f7\u8d1d\u5230 .c \u6e90\u7801\u6587\u4ef6\u4e2d\uff0c\u7136\u540e\u628a\u540e\u7f00\u540d\u6539\u6210 .exe \uff0c\u53d1\u73b0\u8fd9\u6837\u6839\u672c\u6267\u884c\u4e0d\u4e86\u2026\u2026\u540e\u6765\u624d\u77e5\u9053\u9700\u8981\u901a\u8fc7\u4e00\u79cd\u53eb\u505a \u7f16\u8bd1\u5668 \u7f16\u8bd1 .c \u6587\u4ef6\uff0c\u624d\u80fd\u5f97\u5230\u8ba1\u7b97\u673a\u53ef\u4ee5\u76f4\u63a5\u6267\u884c\u7684 .exe \u6587\u4ef6\u3002 C++ \u6e90\u7801 .cpp \u662f\u5199\u7ed9\u4eba\u7c7b\u770b\u7684\uff01\u8ba1\u7b97\u673a\u5e76\u4e0d\u8ba4\u8bc6\uff0c\u8ba1\u7b97\u673a\u53ea\u8ba4\u8bc6\u4e8c\u8fdb\u5236\u7684\u673a\u5668\u7801\u3002\u8981\u628a C++ \u6e90\u7801\u8f6c\u6362\u4e3a\u8ba1\u7b97\u673a\u53ef\u4ee5\u6267\u884c\u7684\u673a\u5668\u7801\u3002","title":"\u7f16\u8bd1\u5668\u662f\uff1f"},{"location":"platform/#_3","text":"\u6700\u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u6709\uff1aGCC\u3001Clang\u3001MSVC \u4fd7\u79f0\u201c\u5fa1\u4e09\u5bb6\u201d\u3002 \u8fd9\u4e9b\u7f16\u8bd1\u5668\u90fd\u652f\u6301\u4e86\u5927\u90e8\u5206 C++20 \u6807\u51c6\u548c\u5c0f\u90e8\u5206 C++23 \u6807\u51c6\uff0c\u800c C++17 \u6807\u51c6\u90fd\u662f\u5b8c\u5168\u652f\u6301\u7684\u3002 \u6709\u4eba\u8bf4\u8fc7\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f GCC\u3002\u201d GCC \u4e3b\u8981\u53ea\u5728 Linux \u548c MacOS \u7b49 Unix \u7c7b\u7cfb\u7edf\u53ef\u7528\uff0c\u4e0d\u652f\u6301 Windows \u7cfb\u7edf\u3002\u4f46\u662f GCC \u6709\u7740\u5927\u91cf\u597d\u7528\u7684\u6269\u5c55\u529f\u80fd\uff0c\u4f8b\u5982\u5927\u540d\u9f0e\u9f0e\u7684 pbds \uff08\u57fa\u4e8e\u7b56\u7565\u7684\u6570\u636e\u7ed3\u6784\uff09\uff0c\u8fd8\u6709\u5404\u79cd __attribute__ \uff0c\u5404\u79cd __builtin_ \u7cfb\u5217\u51fd\u6570\u3002\u4e0d\u8fc7\u968f\u7740\u65b0\u6807\u51c6\u7684\u51fa\u53f0\uff0c\u5f88\u591a\u539f\u672c\u5c5e\u4e8e GCC \u7684\u529f\u80fd\u90fd\u6210\u4e86\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f8b\u5982 __attribute__((warn_unused)) \u53d8\u6210\u4e86\u6807\u51c6\u7684 [[nodiscard]] \uff0c __builtin_clz \u53d8\u6210\u4e86\u6807\u51c6\u7684 std::countl_zero \uff0c __VA_OPT__ \u540d\u5b57\u90fd\u6ca1\u53d8\u5c31\u8fdb\u4e86 C++20 \u6807\u51c6\u3002 PBDS \u53c8\u79f0 \u201c\u5e73\u677f\u7535\u89c6\u201d \u4e5f\u6709 MinGW \u8fd9\u6837\u7684\u9b54\u6539\u7248 GCC \u7f16\u8bd1\u5668\uff0c\u628a GCC \u79fb\u690d\u5230\u4e86 Windows \u7cfb\u7edf\u4e0a\uff0c\u540c\u65f6\u4e5f\u80fd\u7528 GCC \u7684\u4e00\u4e9b\u7279\u6027\u3002\u4e0d\u8fc7 MinGW \u6700\u8fd1\u5df2\u7ecf\u505c\u6b62\u66f4\u65b0\uff0c\u6700\u65b0\u7684 GCC Windows \u79fb\u690d\u7248\u7531 MinGW-w64 \u7ee7\u7eed\u7ef4\u62a4\u3002 Clang \u662f\u8de8\u5e73\u53f0\u7684\u7f16\u8bd1\u5668\uff0c\u652f\u6301\u5927\u591a\u6570\u4e3b\u6d41\u5e73\u53f0\uff0c\u5305\u62ec\u64cd\u4f5c\u7cfb\u7edf\u754c\u7684\u5fa1\u4e09\u5bb6\uff1aLinux\u3001MacOS\u3001Windows\u3002Clang \u652f\u6301\u4e86\u5f88\u5927\u4e00\u90e8\u5206 GCC \u7279\u6027\u548c\u90e8\u5206 MSVC \u7279\u6027\u3002\u5176\u6240\u5c5e\u7684 LLVM \u9879\u76ee\u66f4\u662f\u7f16\u8bd1\u5668\u9886\u57df\u7684\u4e2d\u6d41\u7825\u67f1\uff0c\u4e0d\u4ec5\u652f\u6301 C\u3001C++\u3001Objective-C\u3001Fortran \u7b49\uff0cRust \u548c Swift \u7b49\u8bed\u8a00\u4e5f\u662f\u57fa\u4e8e LLVM \u540e\u7aef\u7f16\u8bd1\u7684\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709\u5f88\u591a\u663e\u5361\u5382\u5546\u7684 OpenGL \u9a71\u52a8\u4e5f\u662f\u57fa\u4e8e LLVM \u5b9e\u73b0\u7f16\u8bd1\u7684\u3002\u5e76\u4e14 Clang \u8eab\u517c\u6570\u804c\uff0c\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u8bd1\uff0c\u8fd8\u652f\u6301\u9759\u6001\u5206\u6790\u3002\u8bb8\u591a IDE \u5e38\u89c1\u7684\u8bed\u8a00\u670d\u52a1\u534f\u8bae (LSP) \u5c31\u662f\u57fa\u4e8e Clang \u7684\u670d\u52a1\u7248\u2014\u2014\u2014\u2014Clangd \u5b9e\u73b0\u7684 (\u4f8b\u5982\u4f60\u53ef\u4ee5\u6309 Ctrl \u70b9\u51fb\uff0c\u8df3\u8f6c\u5230\u51fd\u6570\u5b9a\u4e49\uff0c\u8fd9\u6837\u7684\u529f\u80fd\u5c31\u662f IDE \u901a\u8fc7\u8c03\u7528 Clangd \u7684 LSP \u63a5\u53e3\u5b9e\u73b0\uff09\u3002\u4e0d\u8fc7 Clang \u7684\u6027\u80fd\u4f18\u5316\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u867d\u7136\u6709\u52a9\u4e8e\u6027\u80fd\u63d0\u5347\uff0c\u5982\u679c\u4f60\u4e0d\u5c0f\u5fc3\u72af\u4e86\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u53ef\u80fd\u4f18\u5316\u51fa\u532a\u5937\u6240\u601d\u7684\u7ed3\u679c\uff0c\u5982\u679c\u4f60\u8981\u5b9e\u9a8c\u672a\u5b9a\u4e49\u884c\u4e3a\uff0cClang \u662f\u6700\u64c5\u957f\u590d\u73b0\u7684\u3002\u4e14 Clang \u5bf9\u4e00\u4e9b C++ \u65b0\u6807\u51c6\u7279\u6027\u652f\u6301\u76f8\u5bf9\u8f83\u6162\uff0c\u6ca1\u6709 GCC \u548c MSVC \u90a3\u4e48\u4e0a\u5fc3\u3002 \u4f8b\u5982 C++20 \u65e9\u5df2\u5141\u8bb8 lambda \u8868\u8fbe\u5f0f\u6355\u83b7 structural-binding \u53d8\u91cf\uff0c\u800c Clang \u81f3\u4eca\u8fd8\u6ca1\u6709\u652f\u6301\uff0c\u5c3d\u7ba1 Clang \u5df2\u7ecf\u652f\u6301\u4e86\u5f88\u591a\u5176\u4ed6 C++20 \u7279\u6027\u3002 Apple Clang \u662f\u82f9\u679c\u516c\u53f8\u81ea\u5df1\u9b54\u6539\u7684 Clang \u7248\u672c\uff0c\u53ea\u5728 MacOS \u7cfb\u7edf\u4e0a\u53ef\u7528\uff0c\u652f\u6301 Objective-C \u548c Swift \u8bed\u8a00\u3002\u4f46\u662f\u7248\u672c\u8f83\u5b98\u65b9 Clang \u843d\u540e\u4e00\u4e9b\uff0c\u5f88\u591a\u65b0\u7279\u6027\u90fd\u6ca1\u6709\u8ddf\u8fdb\uff0c\u57fa\u672c\u4e0a\u53ea\u6709\u4e13\u95e8\u4f3a\u5019\u82f9\u679c\u7684\u5f00\u53d1\u8005\u4f1a\u7528\u3002 GCC \u548c Clang \u4e5f\u652f\u6301 Objective-C\u3002 MSVC \u662f Windows \u9650\u5b9a\u7684\u7f16\u8bd1\u5668\uff0c\u63d0\u4f9b\u4e86\u5f88\u591a MSVC \u7279\u6709\u7684\u6269\u5c55\u3002\u4e5f\u6709\u4eba\u5728 Clang \u4e0a\u9b54\u6539\u51fa\u4e86 MSVC \u517c\u5bb9\u6a21\u5f0f\uff0c\u517c\u987e Clang \u7279\u6027\u7684\u540c\u65f6\uff0c\u652f\u6301\u4e86 MSVC \u7684\u4e00\u4e9b\u7279\u6027\uff08\u4f8b\u5982 __declspec \uff09\uff0c\u53ef\u4ee5\u7f16\u8bd1\u7528\u4e86 MSVC \u7279\u6027\u7684\u4ee3\u7801\uff0c\u5373 clang-cl \uff0c\u5728\u6700\u65b0\u7684 VS2022 IDE \u4e2d\u4e5f\u96c6\u6210\u4e86 clang-cl \u3002\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cMSVC \u7684\u4f18\u5316\u80fd\u529b\u662f\u6bd4\u8f83\u5dee\u7684\uff0c\u6bd4 GCC \u548c Clang \u90fd\u5dee\uff0c\u4f8b\u5982 MSVC \u51e0\u4e4e\u603b\u662f\u5047\u5b9a\u6240\u6709\u6307\u9488 aliasing\uff0c\u8fd9\u610f\u5473\u7740\u5f53\u9047\u5230\u5f88\u591a\u6307\u9488\u64cd\u4f5c\u7684\u5faa\u73af\u65f6\uff0c\u51e0\u4e4e\u6ca1\u6cd5\u505a\u5faa\u73af\u77e2\u91cf\u5316\u3002\u4f46\u662f\u4e5f\u4f7f\u5f97\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f Bug\uff0c\u53e6\u4e00\u65b9\u9762\uff0c\u8fd9\u4e5f\u5bfc\u81f4\u4e00\u4e9b\u53ea\u7528 MSVC \u7684\u4eba\u4e0d\u77e5\u9053\u67d0\u4e9b\u5199\u6cd5\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 Intel C++ compiler \u662f\u82f1\u7279\u5c14\u5f00\u53d1\u7684 C++ \u7f16\u8bd1\u5668\uff0c\u7531\u4e8e\u662f\u786c\u4ef6\u5382\u5546\u5f00\u53d1\u7684\uff0c\u7279\u522b\u64c5\u957f\u505a\u6027\u80fd\u4f18\u5316\u3002\u4f46\u7531\u4e8e\u66f4\u65b0\u8f83\u6162\uff0c\u57fa\u672c\u6ca1\u6709\u66f4\u4e0a\u65b0\u7279\u6027\uff0c\u4e5f\u6ca1\u4ec0\u4e48\u4eba\u5728\u7528\u4e86\u3002 \u6700\u8fd1\u4ed6\u4eec\u53c8\u51fa\u4e86\u4e2a Intel DPC++ compiler\uff0c\u652f\u6301\u6700\u65b0\u7684\u5e76\u884c\u7f16\u7a0b\u9886\u57df\u7279\u5b9a\u8bed\u8a00 SyCL\u3002","title":"\u7f16\u8bd1\u5668\u5fa1\u4e09\u5bb6"},{"location":"platform/#_4","text":"","title":"\u4f7f\u7528\u7f16\u8bd1\u5668\u7f16\u8bd1\u6e90\u7801"},{"location":"platform/#msvc","text":"cl.exe main.cpp \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main.exe \u4e86\u3002","title":"MSVC"},{"location":"platform/#gcc","text":"g++ main.cpp -o main \u8fd9\u6837\u5c31\u53ef\u4ee5\u5f97\u5230\u53ef\u6267\u884c\u6587\u4ef6 main \u4e86\u3002 Linux \u7cfb\u7edf\u7684\u53ef\u6267\u884c\u6587\u4ef6\u5e76\u6ca1\u6709\u540e\u7f00\u540d\uff0c\u6240\u4ee5\u6ca1\u6709 .exe \u540e\u7f00\u3002","title":"GCC"},{"location":"platform/#clang","text":"Windows \u4e0a\uff1a clang++.exe main.cpp -o main.exe Linux / MacOS \u4e0a\uff1a clang++ main.cpp -o main","title":"Clang"},{"location":"platform/#_5","text":"\u7f16\u8bd1\u5668\u9009\u9879\u662f\u7528\u6765\u63a7\u5236\u7f16\u8bd1\u5668\u7684\u884c\u4e3a\u7684\u3002\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u6709\u4e0d\u540c\u7684\u9009\u9879\uff0c\u8bed\u6cd5\u6709\u5fae\u5999\u7684\u4e0d\u540c\uff0c\u4f46\u5927\u81f4\u529f\u6548\u76f8\u540c\u3002 \u4f8b\u5982\u5f53\u6211\u4eec\u8bf4\u201c\u7f16\u8bd1\u8fd9\u4e2a\u6e90\u7801\u65f6\uff0c\u6211\u7528\u4e86 GCC \u7f16\u8bd1\u5668\uff0c -O3 \u548c -std=c++20 \u9009\u9879\u201d\uff0c\u8bf4\u7684\u5c31\u662f\u628a\u8fd9\u4e9b\u9009\u9879\u52a0\u5230\u4e86 g++ \u7684\u547d\u4ee4\u884c\u53c2\u6570\u4e2d\uff1a g++ -O3 -std=c++20 main.cpp -o main \u5176\u4e2d Clang \u548c GCC \u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\u5f88\u5927\u4ea4\u96c6\u3002\u800c MSVC \u57fa\u672c\u81ea\u6210\u4e00\u6d3e\u3002 Clang \u548c GCC \u7684\u9009\u9879\u90fd\u662f -xxx \u7684\u5f62\u5f0f\uff0cMSVC \u7684\u9009\u9879\u662f /xxx \u7684\u5f62\u5f0f\u3002 \u5e38\u89c1\u7684\u7f16\u8bd1\u5668\u9009\u9879\u6709\uff1a","title":"\u7f16\u8bd1\u5668\u9009\u9879"},{"location":"platform/#c","text":"\u6307\u5b9a\u8981\u9009\u7528\u7684 C++ \u6807\u51c6\u3002 Clang \u548c GCC\uff1a -std=c++98 \u3001 -std=c++03 \u3001 -std=c++11 \u3001 -std=c++14 \u3001 -std=c++17 \u3001 -std=c++20 \u3001 -std=c++23 MSVC\uff1a /std:c++98 \u3001 /std:c++11 \u3001 /std:c++14 \u3001 /std:c++17 \u3001 /std:c++20 \u3001 /std:c++latest \u4f8b\u5982\u8981\u7f16\u8bd1\u4e00\u4e2a C++20 \u6e90\u7801\u6587\u4ef6\uff0c\u5206\u522b\u7528 GCC\u3001Clang\u3001MSVC\uff1a GCC\uff08Linux\uff09\uff1a g++ -std=c++20 main.cpp -o main Clang\uff08Linux\uff09\uff1a clang++ -std=c++20 main.cpp -o main MSVC\uff08Windows\uff09\uff1a cl.exe /std:c++20 /c main.cpp","title":"C++ \u6807\u51c6"},{"location":"platform/#_6","text":"Clang \u548c GCC\uff1a -O0 \u3001 -O1 \u3001 -O2 \u3001 -O3 \u3001 -Ofast \u3001 -Os \u3001 -Oz \u3001 -Og -O0 \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u7f16\u8bd1\u901f\u5ea6\u6700\u5feb\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u5f00\u53d1\u4eba\u5458\u5185\u90e8\u8c03\u8bd5\u9636\u6bb5\u3002 -O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\uff08\u7f16\u8bd1\u5668\u68c0\u6d4b\u5230\u7684\u4e0d\u53ef\u62b5\u8fbe\u4ee3\u7801\uff09\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u90e8\u5206\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\uff0c\u7f16\u8bd1\u901f\u5ea6\u8f83\u5feb\uff0c\u6267\u884c\u901f\u5ea6\u4e5f\u6bd4 -O0 \u5feb\u3002\u4f46\u662f\u4f1a\u4e22\u5931\u51fd\u6570\u7684\u884c\u53f7\u4fe1\u606f\uff0c\u5f71\u54cd\u8bf8\u5982 gdb \u7b49\u8c03\u8bd5\uff0c\u5982\u9700\u5feb\u901f\u8c03\u8bd5\u53ef\u4ee5\u7528 -Og \u9009\u9879\u3002 -O2 \uff1a\u6bd4 -O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\uff0c\u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002 -O3 \uff1a\u6bd4 -O2 \u66f4\u6fc0\u8fdb\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u590d\u6742\u7684\u5faa\u73af\u7528 SIMD \u77e2\u91cf\u6307\u4ee4\u4f18\u5316\u52a0\u901f\uff0c\u628a\u4e00\u4e9b\u590d\u6742\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u6027\u80fd\u63d0\u5347\u5f88\u5927\uff0c\u4f46\u662f\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b Bug\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u5219\u7edd\u4e0d\u4f1a\u6709\u95ee\u9898\uff0c\u5bf9\u81ea\u5df1\u7684\u4ee3\u7801\u8d28\u91cf\u6709\u81ea\u4fe1\u5c31\u53ef\u4ee5\u653e\u5fc3\u5f00\uff0c\u7f16\u8bd1\u901f\u5ea6\u4e5f\u4f1a\u5f88\u6162\uff0c\u4e00\u822c\u7528\u4e8e\u7a0b\u5e8f\u6700\u7ec8\u6210\u54c1\u53d1\u5e03\u9636\u6bb5\u3002 -Ofast \uff1a\u5728 -O3 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u5bf9\u6d6e\u70b9\u6570\u7684\u8fd0\u7b97\u8fdb\u884c\u66f4\u6df1\u5c42\u6b21\u7684\u4f18\u5316\uff0c\u4f46\u662f\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4e00\u4e9b\u6d6e\u70b9\u6570\u8ba1\u7b97\u7ed3\u679c\u4e0d\u51c6\u786e\u3002\u5982\u679c\u4f60\u7684\u4ee3\u7801\u4e0d\u6d89\u53ca\u5230 NaN \u548c Inf \u7684\u5904\u7406\uff0c\u90a3\u4e48 -Ofast \u4e0d\u4f1a\u6709\u592a\u5927\u7684\u95ee\u9898\uff0c\u4e00\u822c\u7528\u4e8e\u79d1\u5b66\u8ba1\u7b97\u9886\u57df\u7684\u7ec8\u6781\u6027\u80fd\u4f18\u5316\u3002 -Os \uff1a\u5728 -O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u6bd4 -O0 \u3001 -O1 \u3001 -O2 \u90fd\u8981\u5c0f\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Oz \uff1a\u5728 -Os \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u628a\u4ee3\u7801\u538b\u7f29\uff0c\u53ef\u80fd\u628a\u672c\u53ef\u4ee5\u4e00\u6761\u5927\u6307\u4ee4\u5b8c\u6210\u7684\u4efb\u52a1\u4e5f\u62c6\u6210\u591a\u6761\u5c0f\u6307\u4ee4\uff0c\u4e3a\u4e86\u7f29\u5c0f\u5c3a\u5bf8\u727a\u7272\u8fd0\u884c\u65f6\u6027\u80fd\uff0c\u5927\u5e45\u51cf\u5c11\u4e86\u51fd\u6570\u5185\u8054\u7684\u673a\u4f1a\uff0c\u6709\u65f6\u7528\u4e8e\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 -Og \uff1a\u5728 -O0 \u7684\u57fa\u7840\u4e0a\uff0c\u5c3d\u53ef\u80fd\u4fdd\u7559\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\uff0c\u4e0d\u505a\u7834\u574f\u51fd\u6570\u884c\u53f7\u7b49\u4fe1\u606f\u7684\u4f18\u5316\uff0c\u5efa\u8bae\u914d\u5408\u4ea7\u751f\u66f4\u591a\u8c03\u8bd5\u4fe1\u606f\u7684 -g \u9009\u9879\u4f7f\u7528\u3002\u4f46\u8fd8\u662f\u4f1a\u505a\u4e00\u4e9b\u7b80\u5355\u7684\u4f18\u5316\uff0c\u6bd4 -O0 \u6267\u884c\u901f\u5ea6\u66f4\u5feb\u3002\u4f46 -Og \u7684\u6240\u6709\u4f18\u5316\u90fd\u4e0d\u4f1a\u6d89\u53ca\u5230\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u56e0\u6b64\u975e\u5e38\u9002\u5408\u8c03\u8bd5\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u4f46\u662f\u7531\u4e8e\u63d2\u5165\u4e86\u8c03\u8bd5\u4fe1\u606f\uff0c\u6700\u7ec8\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4f1a\u53d8\u5f97\u5f88\u5927\uff0c\u4e00\u822c\u5728\u5f00\u53d1\u4eba\u5458\u8c03\u8bd5\u65f6\u4f7f\u7528\u3002 MSVC\uff1a /Od \u3001 /O1 \u3001 /O2 \u3001 /Ox \u3001 /Ob1 \u3001 /Ob2 \u3001 /Os /Od \uff1a\u4e0d\u8fdb\u884c\u4efb\u4f55\u4f18\u5316\uff0c\u5fe0\u5b9e\u590d\u523b\u4f60\u5199\u7684\u4ee3\u7801\uff0c\u672a\u5b9a\u4e49\u884c\u4e3a\u4e0d\u5bb9\u6613\u4ea7\u751f\u8be1\u5f02\u7684\u7ed3\u679c\uff0c\u4e00\u822c\u7528\u4e8e\u8c03\u8bd5\u9636\u6bb5\u3002 /O1 \uff1a\u6700\u57fa\u672c\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6b7b\u4ee3\u7801\u5220\u9664\uff0c\u53bb\u6389\u6ca1\u6709\u7528\u7684\u53d8\u91cf\uff0c\u628a\u53d8\u91cf\u7528\u5bc4\u5b58\u5668\u4ee3\u66ff\u7b49\u3002 /O2 \uff1a\u6bd4 /O1 \u66f4\u5f3a\u7684\u4f18\u5316\uff0c\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\uff0c\u628a\u4e00\u4e9b\u51fd\u6570\u5185\u8054\uff0c\u51cf\u5c11\u51fd\u6570\u8c03\u7528\uff0c\u8fd8\u4f1a\u5c1d\u8bd5\u628a\u4e00\u4e9b\u5faa\u73af\u77e2\u91cf\u5316\uff0c\u628a\u4e00\u4e9b\u7b80\u5355\u7684\u6570\u7ec4\u64cd\u4f5c\u7528\u66f4\u5feb\u7684\u6307\u4ee4\u66ff\u4ee3\u7b49\u3002\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ox \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u8fdb\u4e00\u6b65\u4f18\u5316\uff0c\u4f46\u662f\u4e0d\u4f1a\u5bfc\u81f4\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4e00\u822c\u7528\u4e8e\u53d1\u5e03\u9636\u6bb5\u3002 /Ob1 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\u3002 /Ob2 \uff1a\u542f\u7528\u51fd\u6570\u5185\u8054\uff0c\u4f46\u662f\u4f1a\u6269\u5927\u5185\u8054\u8303\u56f4\uff0c\u4e00\u822c\u6bd4 /Ob1 \u66f4\u5feb\uff0c\u4f46\u662f\u4e5f\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u3002 /Os \uff1a\u5728 /O2 \u7684\u57fa\u7840\u4e0a\uff0c\u4e13\u95e8\u4f18\u5316\u4ee3\u7801\u5927\u5c0f\uff0c\u6027\u80fd\u88ab\u5f53\u4f5c\u6b21\u8981\u9700\u6c42\uff0c\u4f46\u662f\u4f1a\u7981\u6b62\u4f1a\u5bfc\u81f4\u53ef\u6267\u884c\u6587\u4ef6\u53d8\u5927\u7684\u4f18\u5316\u3002\u4f1a\u628a\u4e00\u4e9b\u5faa\u73af\u5c55\u5f00\u3001\u5185\u8054\u7b49\u4f18\u5316\u5173\u95ed\uff0c\u628a\u4e00\u4e9b\u4ee3\u7801\u7528\u66f4\u5c0f\u7684\u6307\u4ee4\u5b9e\u73b0\uff0c\u5c3d\u53ef\u80fd\u51cf\u5c0f\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5c3a\u5bf8\uff0c\u901a\u5e38\u7528\u4e8e\u9700\u8981\u8282\u7701\u5185\u5b58\u7684\u5d4c\u5165\u5f0f\u7cfb\u7edf\u5f00\u53d1\u3002 \u6ce8\u610f\uff1a\u51fd\u6570\u5185\u8054\u662f\u4e00\u79cd\u4f18\u5316\u7b56\u7565\uff0c\u548c inline \u5173\u952e\u5b57\u6beb\u65e0\u5173\u7cfb\uff0c\u8bf7\u770b\u7a0d\u540e\u63a8\u51fa\u7684\u7b26\u53f7\u94fe\u63a5\u4e13\u9898\u8bfe\u7a0b\u6216\u62a2\u5148\u770b \u5c0f\u5f6d\u8001\u5e08\u89c6\u9891 \u4e86\u89e3 inline \uff0c\u4ee5\u540e\u7684\u6027\u80fd\u4f18\u5316\u4e13\u9898\u8bfe\u7a0b\u4e5f\u4f1a\u4ecb\u7ecd\u51fd\u6570\u5185\u8054\u4f18\u5316\u7684\u6210\u529f\u6848\u4f8b\u3002","title":"\u4f18\u5316\u7b49\u7ea7"},{"location":"platform/#_7","text":"Clang \u548c GCC\uff1a -g \u3001 -g0 \u3001 -g1 \u3001 -g2 \u3001 -g3 MSVC\uff1a /Z7 \u3001 /Zi","title":"\u8c03\u8bd5\u4fe1\u606f"},{"location":"platform/#_8","text":"","title":"\u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84"},{"location":"platform/#_9","text":"","title":"\u6307\u5b9a\u8981\u94fe\u63a5\u7684\u5e93"},{"location":"platform/#_10","text":"","title":"\u5e93\u6587\u4ef6\u641c\u7d22\u8def\u5f84"},{"location":"platform/#_11","text":"Clang \u548c GCC\uff1a -Dmacro=value MSVC\uff1a /Dmacro=value \u4f8b\u5982\uff1a","title":"\u5b9a\u4e49\u5b8f"},{"location":"platform/#_12","text":"","title":"\u8b66\u544a\u5f00\u5173"},{"location":"platform/#_13","text":"libstdc++ \u662f GCC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e GCC \u662f Linux \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libstdc++ \u4e5f\u662f Linux \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002\u4f60\u53ef\u4ee5\u5728\u8fd9\u91cc\u770b\u5230\u4ed6\u7684\u6e90\u7801\uff1ahttps://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3 libc++ \u662f Clang \u5b98\u65b9\u7f16\u5199\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e Clang \u662f MacOS \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 libc++ \u4e5f\u662f MacOS \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002libc++ \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u65e9\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\u3002\u9879\u76ee\u7684\u5f00\u6e90\u5730\u5740\u662f\uff1ahttps://github.com/llvm/llvm-project/tree/main/libcxx MSVC STL \u662f MSVC \u5b98\u65b9\u7684 C++ \u6807\u51c6\u5e93\u5b9e\u73b0\uff0c\u7531\u4e8e MSVC \u662f Windows \u7cfb\u7edf\u7684\u4e3b\u6d41\u7f16\u8bd1\u5668\uff0c\u6240\u4ee5 MSVC STL \u4e5f\u662f Windows \u4e0a\u6700\u5e38\u7528\u7684\u6807\u51c6\u5e93\u3002MSVC STL \u4e5f\u662f C++ \u6807\u51c6\u5e93\u4e2d\u6700\u665a\u5b9e\u73b0 C++11 \u6807\u51c6\u7684\uff0c\u4f46\u662f\u73b0\u5728\u4ed6\u5df2\u7ecf\u5b8c\u5168\u652f\u6301 C++20\uff0c\u5e76\u4e14\u4e5f\u5b8c\u5168\u5f00\u6e90\u4e86\uff1ahttps://github.com/microsoft/STL \u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0c\u6807\u51c6\u5e93\u548c\u7f16\u8bd1\u5668\u5e76\u4e0d\u662f\u7ed1\u5b9a\u7684\uff0c\u4f8b\u5982 Clang \u53ef\u4ee5\u7528 libstdc++ \u6216 MSVC STL\uff0cGCC \u4e5f\u53ef\u4ee5\u88ab\u914d\u7f6e\u4f7f\u7528 libc++\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0cClang \u9ed8\u8ba4\u7528\u7684\u5c31\u662f libstdc++\u3002\u9700\u8981\u4e3a Clang \u6307\u5b9a -stdlib=libc++ \u9009\u9879\uff0c\u624d\u80fd\u4f7f\u7528\u3002 \u725b\u5934\u4eba\u7b11\u8bdd\uff1a\u201c\u5982\u679c\u4f60\u4e0d\u77e5\u9053\u4e00\u4e2a\u4eba\u662f\u7528\u7684\u4ec0\u4e48\u6807\u51c6\u5e93\uff0c\u90a3\u4e48\u4f60\u53ef\u4ee5\u731c\u4ed6\u7528\u7684\u662f libstdc++\u3002\u56e0\u4e3a\u5373\u4f7f\u4ed6\u7684\u7f16\u8bd1\u5668\u662f Clang\uff0c\u4ed6\u7528\u7684\u5927\u6982\u7387\u4f9d\u7136\u662f libstdc++\u3002\u201d","title":"\u6807\u51c6\u5e93\u5fa1\u4e09\u5bb6"},{"location":"platform/#_14","text":"TODO","title":"\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f"},{"location":"platform/#c11-abi","text":"\u5728\u4e00\u4e9b\u7279\u522b\u53e4\u8001\u7684\u53d1\u884c\u7248\u4e0a\uff08\u6bd4\u5982 Ubuntu 16.04\u3001CentOS\uff09\uff0c\u4ed6\u4eec\u7684\u6807\u51c6\u5e93\u4e0d\u652f\u6301 C++11\uff0c\u53ef\u4ee5\u5f00\u542f\u8fd9\u4e2a\u5b8f\uff1a #define _GLIBCXX_USE_CXX11_ABI 0 \u6216\u8005\u547d\u4ee4\u884c\u9009\u9879 -D_GLIBCXX_USE_CXX11_ABI=0 \u3002 \u4e3a\u4e86\u66f4\u597d\u7684\u5b66\u4e60\u73b0\u4ee3 C++\uff0c\u8fd8\u662f\u5efa\u8bae\u5b89\u88c5\u65b0\u7684\u53d1\u884c\u7248\u3002","title":"C++11 ABI \u95ee\u9898"},{"location":"recommend/","text":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee \u8d44\u6e90\u63a8\u8350 hackingcpp.com learncpp.com cppreference.com godbolt.org cppinsights.io quick-bench.com github.com stackoverflow.com effective c++ \u5c0f\u5f6d\u8001\u5e08 (\u53cc\u7b19\u5b50\u4f6f\u8c2c) \u767d\u5f8b\u5e08 (mq\u767dcpp) \u9879\u76ee\u63a8\u8350 \u96c6\u5927\u6210\u8005 boost qt llvm \u73b0\u4ee3 utfcpp fmt spdlog rapidjson nlohmann-json ranges-v3 matchit.cpp \u9ad8\u6027\u80fd tbb cub cutlass thrust highway numcpp amgcl eigen \u56fe\u5f62\u5b66 sfml libigl openvdb cgal \u5b9e\u7528\u6269\u5c55 tsl-robin-map absl backward-cpp iguana magic_enum \u53e4\u4ee3 opencv nothings/stb google/benchmark jsoncpp gtest catch3 tinyxml2 poco incbin \u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b parallel101/course parallel101/opengltutor parallel101/openglslides parallel101/cppguidebook parallel101/simdtutor \u5c0f\u5f6d\u8001\u5e08\u81ea\u7814 zenustech/zeno archibate/co_async parallel101/stl1weekend archibate/mallocvis archibate/reflect-hpp archibate/debug-hpp archibate/hermes archibate/genius.nvim LanbingIce/IsaacSocket-Utility archibate/qdanmu zenustech/zeno3-poc archibate/minilog archibate/threebody-example archibate/babyjson-demo taichi-dev/taichi_three taichi-dev/taichi_blend taichi-dev/taichi.js archibate/ptina zenustech/zenoblend archibate/NBodySolver archibate/vue-class-manage-system archibate/facereco archibate/jsp-chess archibate/pysobol archibate/newos archibate/poczfx archibate/logisim archibate/newton archibate/vimrc GCC \u5efa\u8bae\u5f00\u542f\u7684\u8b66\u544a\u9009\u9879 -Wall -Wextra -Weffc++ -Werror=uninitialized -Werror=return-type -Wconversion -Wsign-compare -Werror=unused-result -Werror=suggest-override -Wzero-as-null-pointer-constant -Wmissing-declarations -Wold-style-cast -Werror=vla -Wnon-virtual-dtor","title":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee"},{"location":"recommend/#_1","text":"","title":"\u53c2\u8003\u8d44\u6599\u4e0e\u9879\u76ee"},{"location":"recommend/#_2","text":"hackingcpp.com learncpp.com cppreference.com godbolt.org cppinsights.io quick-bench.com github.com stackoverflow.com effective c++ \u5c0f\u5f6d\u8001\u5e08 (\u53cc\u7b19\u5b50\u4f6f\u8c2c) \u767d\u5f8b\u5e08 (mq\u767dcpp)","title":"\u8d44\u6e90\u63a8\u8350"},{"location":"recommend/#_3","text":"","title":"\u9879\u76ee\u63a8\u8350"},{"location":"recommend/#_4","text":"boost qt llvm","title":"\u96c6\u5927\u6210\u8005"},{"location":"recommend/#_5","text":"utfcpp fmt spdlog rapidjson nlohmann-json ranges-v3 matchit.cpp","title":"\u73b0\u4ee3"},{"location":"recommend/#_6","text":"tbb cub cutlass thrust highway numcpp amgcl eigen","title":"\u9ad8\u6027\u80fd"},{"location":"recommend/#_7","text":"sfml libigl openvdb cgal","title":"\u56fe\u5f62\u5b66"},{"location":"recommend/#_8","text":"tsl-robin-map absl backward-cpp iguana magic_enum","title":"\u5b9e\u7528\u6269\u5c55"},{"location":"recommend/#_9","text":"opencv nothings/stb google/benchmark jsoncpp gtest catch3 tinyxml2 poco incbin","title":"\u53e4\u4ee3"},{"location":"recommend/#_10","text":"parallel101/course parallel101/opengltutor parallel101/openglslides parallel101/cppguidebook parallel101/simdtutor","title":"\u5c0f\u5f6d\u8001\u5e08\u8bfe\u7a0b"},{"location":"recommend/#_11","text":"zenustech/zeno archibate/co_async parallel101/stl1weekend archibate/mallocvis archibate/reflect-hpp archibate/debug-hpp archibate/hermes archibate/genius.nvim LanbingIce/IsaacSocket-Utility archibate/qdanmu zenustech/zeno3-poc archibate/minilog archibate/threebody-example archibate/babyjson-demo taichi-dev/taichi_three taichi-dev/taichi_blend taichi-dev/taichi.js archibate/ptina zenustech/zenoblend archibate/NBodySolver archibate/vue-class-manage-system archibate/facereco archibate/jsp-chess archibate/pysobol archibate/newos archibate/poczfx archibate/logisim archibate/newton archibate/vimrc","title":"\u5c0f\u5f6d\u8001\u5e08\u81ea\u7814"},{"location":"recommend/#gcc","text":"-Wall -Wextra -Weffc++ -Werror=uninitialized -Werror=return-type -Wconversion -Wsign-compare -Werror=unused-result -Werror=suggest-override -Wzero-as-null-pointer-constant -Wmissing-declarations -Wold-style-cast -Werror=vla -Wnon-virtual-dtor","title":"GCC \u5efa\u8bae\u5f00\u542f\u7684\u8b66\u544a\u9009\u9879"},{"location":"stl_map/","text":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u8ba9\u9ad8\u6027\u80fd\u6570\u636e\u7ed3\u6784\u60e0\u53ca\u6bcf\u4e00\u4eba STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \u8bfe\u7a0b\u4eae\u70b9 \u8bfe\u7a0b\u5927\u7eb2 \u5b9e\u9a8c\u73af\u5883 \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 map \u7684\u903b\u8f91\u7ed3\u6784 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 map \u7684\u7269\u7406\u7ed3\u6784 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u4e8c\u53c9\u6392\u5e8f\u6811 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u5e73\u8861\u6811 \u7ea2\u9ed1\u6811 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u603b\u7ed3 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type typename \u4fee\u9970 decltype \u5927\u6cd5\u597d \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f count \u548c contains \u6ca1\u533a\u522b end \u4e0d\u80fd\u89e3\u5f15\u7528 find \u7684\u597d\u5904 C++17 \u8bed\u6cd5\u7cd6 \u9898\u5916\u8bdd \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if insert_or_assign insert_or_assign \u7684\u4f18\u52bf \u6548\u7387\u95ee\u9898 [] insert_or_assign \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u6279\u91cf insert \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u5c31\u5730\u5199\u5165\uff01 \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 assign \u51fd\u6570 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u5206\u5974 emplace emplace_hint emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 try_emplace \u66f4\u597d try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u8c03\u7528\u5f00\u9500\u5206\u6790 try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace emplace \u5bb6\u65cf\u603b\u7ed3 map \u4e0e RAII \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u6539\u67e5 \u521d\u59cb\u5316 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract \u7528\u9014\u4e3e\u4f8b insert \u8282\u70b9\u7248 insert_return_type extract + insert \u8fd0\u7528\u6848\u4f8b extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 \u6279\u91cf insert vs merge merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 std::less \u7684\u4f5c\u7528 operator() \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u5efa\u8bae\u7528 function \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u795e\u5947\u7684 multimap \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 \u8bfe\u540e\u7ec3\u4e60 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u54c8\u5e0c\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d \u54c8\u5e0c\u51b2\u7a81 (hash-collision) unordered_map \u4e0e map \u7684\u5f02\u540c \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 hash \u548c equal_to \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 \u81ea\u52a8\u53d6\u6a21 hash \u662f\u4e2a trait \u7c7b \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 \u8d1f\u8f7d\u7387\uff08load_factor\uff09 rehash \u51fd\u6570 hash \u9700\u8981\u7279\u5316 \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 \u66f4\u597d\u7684 hash_combine \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 \u5e94\u7528 \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 \u672c\u671f\u5b5d\u70b9\u603b\u7ed3 \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \ud83d\ude00\ud83d\ude00\ud83d\ude00 \u9762\u5411\u5df2\u7ecf\u4e86\u89e3\u4e00\u5b9a C++ \u8bed\u6cd5\uff0c\u6b63\u5728\u5b66\u4e60\u6807\u51c6\u5e93\u7684\u7ae5\u978b\u3002 C++ \u6807\u51c6\u5e93\u53c8\u79f0 STL\uff0c\u5305\u542b\u4e86\u5927\u91cf\u7a0b\u5e8f\u5458\u5e38\u7528\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\uff0c\u662f Bjarne Stroustrup \u9001\u7ed9\u6240\u6709 C++ \u7a0b\u5e8f\u5458\u7684\u4e00\u628a\u745e\u58eb\u519b\u5200\uff0c\u7136\u800c\u53d1\u73b0\u5f88\u591a\u7ae5\u978b\u5e76\u6ca1\u6709\u5b8c\u5168\u7528\u597d\u4ed6\uff0c\u53cd\u800c\u8fd8\u88ab\u5176\u590d\u6742\u6027\u8bef\u4f24\u4e86\u3002 \u5982\u679c\u4f60\u4e5f\u5bf9\u6807\u51c6\u5e93\u4e00\u77e5\u534a\u89e3\uff0c\u9700\u8981\u7cfb\u7edf\u5b66\u4e60\u7684\u8bdd\uff0c\u90a3\u4e48\u672c\u8bfe\u7a0b\u9002\u5408\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\u5c06\u8fd0\u7528\u4ed6\u7279\u6709\u7684\u5e7d\u9ed8\u7b54\u8fa9\u6bd4\u55bb\uff0c\u5168\u9762\u4ecb\u7ecd\u5404 STL \u5bb9\u5668\u7684\u6240\u6709\u7528\u6cd5\u3002\u7ed3\u5408\u4e00\u7cfb\u5217\u5b9e\u6218\u6848\u4f8b\uff0c\u5256\u6790\u5e38\u89c1\u5751\u70b9\uff0c\u4f7f\u7528\u6280\u5de7\u7b49\u3002\u5bf9\u6bd4\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u4e0e\u53ef\u8bfb\u6027\uff0c\u8fd8\u4f1a\u4e0e Python \u8bed\u8a00\u76f8\u4e92\u7c7b\u6bd4\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u79d1\u666e\u7684\u90e8\u5206\u51b7\u77e5\u8bc6\u53ef\u4ee5\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u52a0\u5206\u9879\u3002 \u672c\u8bfe\u7a0b\u53d7\u5230\u7ae5\u978b\u4e00\u81f4\u597d\u8bc4 \u8bfe\u7a0b\u4eae\u70b9 \ud83d\udc4d\ud83d\udc4d\ud83d\udc4d \u672c\u7cfb\u5217\u8bfe\u7a0b\u4e0e\u300a\u4faf\u6770\u8001\u5e08 STL \u8bfe\u300b\u7684\u533a\u522b\uff1a \u4faf\u6770\u8001\u5e08\u4ef7\u503c 2650 \u5143\uff0c\u672c\u8bfe\u7a0b\u5f55\u64ad\u4e0a\u4f20 B \u7ad9\u514d\u8d39\u89c2\u770b\uff0c\u89c2\u4f17\u53ef\u4ee5\u81ea\u884c\u9009\u62e9\u662f\u5426\u4e00\u952e\u4e09\u8fde\u3002 \u8bfe\u4ef6\u548c\u6848\u4f8b\u6e90\u7801\u5f00\u6e90\uff0c\u4e0a\u4f20\u5728 GitHub\uff0c\u53ef\u4ee5\u81ea\u5df1\u4e0b\u8f7d\u6765\u505a\u4fee\u6539\uff0c\u7136\u540e\u81ea\u5df1\u52a8\u624b\u5b9e\u9a8c\uff0c\u52a0\u6df1\u7406\u89e3\u3002 \u4faf\u6770\u8001\u5e08\u6ce8\u91cd\u7406\u8bba\u548c\u5e95\u5c42\u5b9e\u73b0\u539f\u7406\uff0c\u800c\u672c\u8bfe\u7a0b\u6ce8\u91cd\u5e94\u7528\uff0c\u7ed3\u5408\u5b9e\u6218\u6848\u4f8b\uff0c\u7740\u91cd\u5c55\u5f00\u91cd\u96be\u70b9\uff0c\u5751\u70b9\u7b49\u3002 \u5f88\u591a\u5b66\u6821\u91cc\u6559\u7684\uff0c\u767e\u5ea6\u4e0a\u641c\u7684\uff0c\u5927\u591a\u662f\u8001\u7248\u672c C++\uff0c\u5df2\u7ecf\u8fc7\u65f6\uff0c\u800c\u672c\u8bfe\u7a0b\u57fa\u4e8e\u8f83\u65b0\u7684 C++17 \u548c C++20 \u6807\u51c6\u3002 \u6709\u65f6\u5b58\u5728\u90e8\u5206 C++ \u9ad8\u7ea7\u7528\u6cd5\u8fc7\u4e8e\u8270\u6df1\uff0c\u4e0d\u80fd\u9002\u5408\u6240\u6709\u540c\u5b66\uff0c\u672c\u8bfe\u7a0b\u91c7\u7528\u56e0\u6750\u65bd\u6559\u601d\u60f3\uff1a\u5bf9\u4e8e\u65b0\u624b\uff0c\u53ef\u4ee5\u8df3\u8fc7\u770b\u4e0d\u61c2\u7684\u90e8\u5206\uff0c\u770b\u6211\u63d0\u4f9b\u7684\u201c\u4fdd\u5e95\u7528\u6cd5\u201d\uff0c\u4e0d\u4fdd\u8bc1\u9ad8\u6027\u80fd\u548c\u201c\u4f18\u96c5\u201d\uff0c\u4f46\u81f3\u5c11\u80fd\u7528\uff1b\u5bf9\u5b66\u6709\u4f59\u529b\u7684\u7ae5\u978b\uff0c\u5219\u53ef\u4ee5\u640f\u4e00\u640f\u4e0a\u9650\uff0c\u628a\u9ad8\u7ea7\u7528\u6cd5\u4e5f\u770b\u61c2\uff0c\u63d0\u5347\u9762\u8bd5\u7ade\u4e89\u529b\u3002\u603b\u4e4b\u4e0d\u8bba\u4f60\u662f\u54ea\u4e2a\u9636\u6bb5\u7684\u5b66\u4e60\u8005\uff0c\u90fd\u80fd\u4ece\u6b64\u8bfe\u7a0b\u4e2d\u83b7\u76ca\u3002 \u8bfe\u7a0b\u5927\u7eb2 \u2728\u2728\u2728 \u4e4b\u524d\u51e0\u671f\u8bfe\u7a0b\u7684\u5f55\u64ad\u5df2\u7ecf\u4e0a\u4f20\u5230\u6bd4\u7ad9\u4e86 1 \u3002 vector \u5bb9\u5668\u521d\u4f53\u9a8c & \u8fed\u4ee3\u5668\u5165\u95e8 (BV1qF411T7sd) \u4f60\u6240\u4e0d\u77e5\u9053\u7684 set \u5bb9\u5668 & \u8fed\u4ee3\u5668\u5206\u7c7b (BV1m34y157wb) string\uff0cstring_view\uff0cconst char * \u7684\u7231\u6068\u7ea0\u845b (BV1ja411M7Di) \u4e07\u80fd\u7684 map \u5bb9\u5668\u5168\u5bb6\u6876\u53ca\u5176\u5999\u7528\u4e3e\u4f8b (\u672c\u671f) \u51fd\u5b50 functor \u4e0e lambda \u8868\u8fbe\u5f0f\u77e5\u591a\u5c11 \u901a\u8fc7\u5b9e\u6218\u6848\u4f8b\u6765\u5b66\u4e60 STL \u7b97\u6cd5\u5e93 C++ \u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6d41 & \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 traits \u6280\u672f\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u8fed\u4ee3\u5668\u4e0e\u7b97\u6cd5 allocator\uff0c\u5185\u5b58\u7ba1\u7406\u4e0e\u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u5f02\u5e38\u5904\u7406\u673a\u5236\u7684\u524d\u4e16\u4eca\u751f \u5b9e\u9a8c\u73af\u5883 \u2705\u2705\u2705 \u5c0f\u5f6d\u8001\u5e08\u4e2a\u4eba\u63a8\u8350\u5b9e\u9a8c\u73af\u5883\u5982\u4e0b\uff1a \u8981\u6c42 \u2764\u2764\u2764 \ud83d\udca3\ud83d\udca3\ud83d\udca3 \ud83d\udca9\ud83d\udca9\ud83d\udca9 \ud83d\udc80\ud83d\udc80\ud83d\udc80 \u64cd\u4f5c\u7cfb\u7edf Arch Linux Ubuntu 20.04 Wendous 10 Maike OS \u77e5\u8bc6\u50a8\u5907 \u4f1a\u4e00\u70b9 C++ \u5927\u5b66 C \u8bed\u8a00 Java \u9762\u5411\u5bf9\u8c61 \u7f16\u7a0b\u5c0f\u767d \u7f16\u8bd1\u5668 GCC 9 \u4ee5\u4e0a Clang 12 VS2019 Apple Clang \u6784\u5efa\u7cfb\u7edf CMake 3.18 \u4efb\u610f C++ IDE \u5355\u6587\u4ef6\u7f16\u8bd1\u8fd0\u884c \u547d\u4ee4\u884c\u624b\u52a8\u7f16\u8bd1 \u7f16\u8f91\u5668 Vim/NeoVim CLion VS Code notepad \u6e38\u620f\u96be\u5ea6\uff1a\u2764 = \u7b80\u5355\uff0c\ud83d\udca3 = \u666e\u901a\uff0c\ud83d\udca9 = \u56f0\u96be\uff0c\ud83d\udc80 = \u5730\u72f1\u526f\u672c \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \ud83e\udd70\ud83e\udd70\ud83e\udd70 \u672c\u671f\u5b9e\u9a8c\u6e90\u7801\u5747\u516c\u5e03\u5728\uff1ahttps://github.com/parallel101/course/tree/master/slides/stl_map/experiment/ \u4f8b\u5982\u672c\u671f\u7684\u8bfe\u4ef6\u4f4d\u4e8e course/stlseries/stl_map/slides.md \u3002 \u8bfe\u4ef6\u57fa\u4e8e Mkdocs \u5f00\u53d1\uff0cMarkdown \u683c\u5f0f\u4e66\u5199\uff0c\u5728\u6d4f\u89c8\u5668\u4e2d\u663e\u793a\uff0c\u5728\u672c\u5730\u8fd0\u884c\u8bfe\u4ef6\u9700\u8981 Mkdocs \u73af\u5883\uff1a \u8fd0\u884c\u547d\u4ee4 pip install -r requirements.txt \u5373\u53ef\u81ea\u52a8\u5b89\u88c5 Mkdocs \u7b49\u6240\u9700\u4f9d\u8d56 \u8fd0\u884c\u547d\u4ee4 mkdocs serve \u5373\u53ef\u8fd0\u884c Mkdocs \u670d\u52a1 \u6d4f\u89c8\u5668\u8bbf\u95ee http://127.0.0.1:8000 \u5373\u53ef\u770b\u5230\u8bfe\u4ef6 \u5982\u679c\u4e0d\u60f3\u81ea\u5df1\u914d\u7f6e Mkdocs \u4e5f\u53ef\u4ee5\u76f4\u63a5\u4ee5\u6587\u672c\u6587\u4ef6\u683c\u5f0f\u6253\u5f00 docs/stl_map.md \u6d4f\u89c8\u8bfe\u4ef6\u3002 Mkdocs \u670d\u52a1\u8fd0\u884c\u65f6\uff0c\u4f60\u5bf9 docs/stl_map.md \u7684\u6240\u6709\u4fee\u6539\u4f1a\u7acb\u523b\u5b9e\u65f6\u663e\u73b0\u5728\u6d4f\u89c8\u5668\u4e2d\u3002 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \ud83e\udd7a\ud83e\udd7a\ud83e\udd7a \u6848\u4f8b\u6e90\u7801\u548c\u6240\u9700\u5934\u6587\u4ef6\u4f4d\u4e8e\u8bfe\u4ef6\u540c\u76ee\u5f55\u7684 course/stlseries/stl_map/experiment/ \u6587\u4ef6\u5939\u4e0b\u3002 \u5176\u4e2d main.cpp \u4ec5\u5bfc\u5165\u8fd0\u884c\u6848\u4f8b\u6240\u9700\u7684\u5934\u6587\u4ef6\uff0c\u5177\u4f53\u5404\u4e2a\u6848\u4f8b\u4ee3\u7801\u5206\u5e03\u5728 slides.md \u91cc\u3002 \u5982\u9700\u6d4b\u8bd5\u8bfe\u4ef6\u4e2d\u7684\u5177\u4f53\u4ee3\u7801\uff0c\u53ef\u4ee5\u628a slides.md \u4e2d\u7684\u6848\u4f8b\u4ee3\u7801\u7c98\u8d34\u5230 main.cpp \u7684 main \u51fd\u6570\u4f53\u4e2d\u8fdb\u884c\u5b9e\u9a8c\u3002 \u6b64\u5916\u4e3a\u4e86\u65b9\u4fbf\uff0c\u8fd8\u6709\u4e00\u4e9b\u5f62\u5982 testxxx.cpp \u7684\u6587\u4ef6\u662f\u4e00\u4e9b\u5b8c\u6574\u7684\u6d4b\u8bd5\u6848\u4f8b\uff0c\u4e0d\u7528\u4ece slides.md \u4e2d\u62f7\u8d1d\uff0c\u53ef\u76f4\u63a5\u5355\u72ec\u8fd0\u884c\u3002 \u4e3a\u4e86\u65b9\u4fbf\u540c\u5b66\u4eec\u5b9e\u9a8c\uff0c\u6240\u9700\u5934\u6587\u4ef6\u90fd\u5728\u540c\u4e00\u4e2a\u76ee\u5f55\uff0c\u6ca1\u6709\u7b2c\u4e09\u65b9\u5e93\u4f9d\u8d56\u3002\u65e2\u53ef\u4ee5\u7528 CMake \u6784\u5efa\uff0c\u4e5f\u53ef\u4ee5\u7528\u4efb\u610f\u81ea\u5df1\u559c\u6b22\u7684 IDE \u6216\u7f16\u8f91\u5668 \u5355\u6587\u4ef6\u7f16\u8bd1 \u8fd0\u884c\uff0c\u65e0\u5f3a\u5236\u8981\u6c42\uff0c\u53ea\u9700\u7f16\u8bd1\u5668\u652f\u6301 C++17 \u5373\u53ef\u3002 \u5982\u679c\u4f60\u7528 Visual Studio \u81ea\u5df1\u7684 sln \u7cfb\u7edf\u6784\u5efa\u9879\u76ee\uff0c\u8bb0\u5f97\u5f00\u542f /std:c++17 \u9009\u9879\u3002\u5982\u679c\u4f60\u7528\u6700\u65b0\u7684 Visual Studio\uff08\u5df2\u7ecf\u652f\u6301 CMake\uff09\u5219\u76f4\u63a5\u9009\u62e9\u201c\u6253\u5f00\u6587\u4ef6\u5939\u201d\u6253\u5f00\u672c\u9879\u76ee\u7684 experiment \u76ee\u5f55\u5373\u53ef\u3002 \u5728\u5b9e\u9a8c\u6e90\u7801\u4ed3\u5e93\u4e2d\uff0c\u9644\u8d60\u4e86\u4e00\u4e9b\u5b9e\u7528\u5934\u6587\u4ef6\uff0c\u540c\u978b\u4eec\u53ef\u4ee5\u4e0b\u8f7d\u6765\u7814\u7a76\uff0c\u6216\u8005\u5728\u81ea\u5df1\u7684\u9879\u76ee\u91cc\u968f\u610f\u8fd0\u7528\u3002 \u6587\u4ef6\u540d \u529f\u80fd print.h \u5185\u542b print \u51fd\u6570\uff0c\u652f\u6301\u6253\u5370\u7edd\u5927\u591a\u6570 STL \u5bb9\u5668\uff0c\u65b9\u4fbf\u8c03\u8bd5 map_get.h \u5e26\u9ed8\u8ba4\u503c\u7684 map \u8868\u9879\u67e5\u8be2\uff0c\u7a0d\u540e\u8bfe\u7a0b\u4e2d\u4f1a\u4ecb\u7ecd\u5230 ScopeProfiler.h \u57fa\u4e8e RAII \u7684\u51fd\u6570\u8017\u65f6\u7edf\u8ba1\uff0c\u7528\u4e8e\u6d4b\u91cf\u6027\u80fd OrderedMap.h \u904d\u5386\u987a\u5e8f\u59cb\u7ec8\u4fdd\u6301\u548c\u63d2\u5165\u987a\u5e8f\u4e00\u81f4\u7684\u9b54\u6539\u7248 map cppdemangle.h \u83b7\u5f97\u7c7b\u578b\u7684\u540d\u5b57\uff0c\u4ee5\u6a21\u677f\u53c2\u6570\u4f20\u5165\uff0c\u8be6\u89c1\u8be5\u6587\u4ef6\u4e2d\u7684\u6ce8\u91ca hash.h \u6bd4 std::hash \u66f4\u901a\u7528\u7684 generic_hash \u5b9e\u73b0\uff0c\u652f\u6301\u4efb\u610f\u533a\u95f4\u548c\u5143\u7ec4 bits_stdc++.h \u4eff\u7167 bits/stdc++.h \u7684\u4e07\u80fd\u5934\u6587\u4ef6\u8de8\u5e73\u53f0\u7248\uff0c\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5e93 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e int const &i // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef const int& i // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef template // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef template // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef \u4ec5\u4e3a\u4e2a\u4eba\u4e66\u5199\u4e60\u60ef\u4e0d\u540c\uff0c\u5728 C++ \u7f16\u8bd1\u5668\u770b\u6765\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u6211\u559c\u6b22\u628a const \u540e\u7f6e\uff0c\u5176\u4e00\u662f\u56e0\u4e3a\u8fd9\u6709\u5229\u4e8e\u7406\u89e3 int const * \u548c int *const \u7684\u533a\u522b\uff0c\u5982\u679c\u5199\u6210 const int * \u5c31\u4f1a\u5f88\u56f0\u60d1 const \u7a76\u7adf\u662f\u4fee\u9970\u8c01\u7684\uff0c\u800c\u7528\u6211\u7684\u5199\u6cd5\u53ea\u9700\u8981\u7b80\u5355\u7406\u89e3\u4e3a \u201cconst \u53ea\u4fee\u9970\u4ed6\u524d\u9762\u7684\u201d\u3002\u5176\u4e8c\u6211\u7ecf\u5e38\u9700\u8981\u628a\u51fd\u6570\u53c2\u6570\u4e2d T t \u4fee\u6539\u6210 T const &t \u3002\u8fde\u5728\u4e00\u8d77\u52a0\u8d77\u6765\u6bd4\u8f83\u65b9\u4fbf\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6027\u63d2\u5165 const & \u5373\u53ef\uff0c\u4e0d\u7528\u524d\u540e\u4e24\u4e2a\u5730\u65b9\u5206\u522b\u52a0 const \u548c & \uff0c\u4f60\u89c9\u5f97\u5462\uff1f using namespace std; // \u4ec5\u4e3a\u6559\u5b66\u65b9\u4fbf\u76ee\u7684\uff0c\u4e0d\u5efa\u8bae\u5728\u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4f7f\u7528 \u26a0\ufe0f \u7531\u4e8e\u4f7f\u7528\u4e86 using namespace std \uff0c\u672c\u8bfe\u7a0b\u4ee3\u7801\u4e2d\u7684 std:: \u524d\u7f00\u5747\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a map> m; erase_if(m, pred); \u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4e0d\u5efa\u8bae using namespace std \uff0c\u8bf7\u663e\u5f0f\u5199\u51fa std:: \u524d\u7f00\uff1a std::map> m; std::erase_if(m, pred); \u6211\u4eec\u81ea\u5df1\u505a\u6d4b\u8bd5\u65f6\u7ecf\u5e38\u4f1a\u7528 \u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u3002 \u53ef\u60dc\u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u5728 VS \u4e2d\u4f3c\u4e4e\u4e0d\u5b58\u5728 1 \uff0c\u56e0\u6b64\u6211\u81ea\u5df1\u5199\u4e86\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 \"bits_stdc++.h\" \u653e\u5728\u6e90\u7801\u540c\u76ee\u5f55\uff1a #include \"bits_stdc++.h\" // \u81ea\u52a8\u5bfc\u5165\u6240\u6709\u6807\u51c6\u5e93\u7684\u5934\u6587\u4ef6 \u4e0d\u8fc7\u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u8fd8\u662f\u5efa\u8bae\u6839\u636e\u9700\u8981\u4e00\u4e2a\u4e2a\u5bfc\u5165\uff0c\u4e0d\u8981\u5077\u61d2\u7528\u8fd9\u4e2a\u4e0d\u6807\u51c6\u7684\u5934\u6587\u4ef6\uff1a #include // \u5bfc\u5165 std::map, std::multimap #include // \u5bfc\u5165 std::unordered_map, std::unordered_multimap #include // \u5bfc\u5165 std::string, std::wstring #include // \u5bfc\u5165 std::set_difference, std::set_union, std::set_intersection \u7b49\u4e00\u7cfb\u5217\u5168\u5c40\u51fd\u6570 // \u4e0b\u9762\u4ee3\u7801\u4e2d\u7528\u5230\u54ea\u4e9b\u5bb9\u5668\uff0c\u5c31\u5bfc\u5165\u54ea\u4e9b\u5934\u6587\u4ef6 \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6709\u4e00\u6b21\u4e00\u4e2a\u540c\u5b66\u53d1\u7ed9\u6211\u4e00\u4efd\u6e90\u7801\u6587\u4ef6 tetreader.py\uff0c\u5176\u529f\u80fd\u662f\u8bfb\u53d6\u4e00\u4e2a tet \u683c\u5f0f\u7684\u6587\u4ef6\uff08\u56db\u9762\u4f53\u7f51\u683c\u6a21\u578b\uff09\u3002 \u4ed6\u95ee\u6211\u4e3a\u4ec0\u4e48\u4ed6\u5199\u7684\u8fd9\u4e2a Python \u4ee3\u7801\u8fd9\u4e48\u6162\uff0c\u8bfb\u53d6\u4e00\u4e2a\u7a0d\u5fae\u5927\u4e00\u70b9\u7684\u6a21\u578b\u5c31\u9700\u8981\u597d\u51e0\u79d2\uff0c\u4ed6\u8bf4\u4e45\u4ef0\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u4f18\u5316\u7684\u5927\u540d\uff0c\u60f3\u8981\u6211\u5e2e\u4ed6\u4f18\u5316\u4e00\u4e0b\uff0c\u8fd8\u95ee\u662f\u4e0d\u662f\u5e94\u8be5\u7528 C++ \u5199\u4f1a\u6bd4\u8f83\u9ad8\u6548\u4e00\u70b9\uff1f \u6211\u5e76\u4e0d\u61c2\u5f97\u56db\u9762\u4f53\uff0c\u4f46\u6027\u80fd\u4f18\u5316\u7684\u601d\u8def\u662f\u901a\u7528\u7684\u3002\u6211\u6253\u5f00\u6587\u4ef6\u770b\u4e86\u4e00\u4e0b\uff0c\u6211\u53d1\u73b0\u4ed6\u8bfb\u53d6\u65f6\u9700\u8981\u67e5\u8be2\u4e00\u4e2a\u70b9\u5468\u56f4\u6240\u6709\u7684\u9762\uff0c\u4ed6\u662f\u8fd9\u6837\u67e5\u8be2\u7684\uff1a # \u4ee5\u4e0b\u4e3a\u4ed6\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = [] for ... in ...: face_lut.append(vert_id) # O(1) \u2705 for ... in ...: face_id = face_lut.index(vert_id) # O(N) \u26a0\ufe0f \u6211\u8bf4\u4f60\u8fd9\u4e2a face_lut \u662f\u4e2a\u666e\u901a\u6570\u7ec4\uff0c\u6570\u7ec4\u7684 index \u51fd\u6570\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u4f60\u4e0d\u77e5\u9053\u5417\uff1f\u4ed6\u76f8\u5f53\u4e8e\u66b4\u529b\u904d\u5386\u4e86\u6570\u7ec4\u627e\u5230\u4f60\u9700\u8981\u7684\u503c\uff0c\u4f60\u8fd9\u4e2a index \u7684\u8c03\u7528\u8fd8\u662f\u5728\u4e00\u4e2a\u5faa\u73af\u91cc\u7684\uff0c\u6240\u4ee5\u662f O(N^2) O(N^2) \u590d\u6742\u5ea6\uff01\u96be\u602a\u8fd9\u4e48\u6162\u4e86\u3002 \u540e\u6765\u6211\u7ed9\u4ed6\u6539\u4e86\u4e00\u4e0b\uff0c\u628a\u4ed6\u7684 face_lut \u6539\u6210\u5b57\u5178\uff0c\u7528\u5b57\u5178\u67e5\u627e\uff0c\u9ad8\u6548\u5f97\u591a\u4e86\uff1a # \u4ee5\u4e0b\u4e3a\u6211\u4f18\u5316\u540e\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = {} for ... in ...: face_lut[vert_id] = face_id # O(1)+ \u2705 for ... in ...: face_id = face_lut[vert_id] # O(1)+ \u2705 \u4e00\u6b21\u5b57\u5178\u7684\u67e5\u8be2\u53ea\u9700\u8981 O(1)+ O(1)+ \uff0c\u52a0\u4e0a\u4ed6\u5916\u9762\u7684\u5faa\u73af\u603b\u5171\u53ea\u6709 O(N) O(N) \uff0c\u53d8\u6210\u7ebf\u6027\u590d\u6742\u5ea6\u4e86\u3002\u4ed6\u4e00\u8bd5\uff0c\u679c\u7136\u51e0\u6beb\u79d2\u5c31\u52a0\u8f7d\u5b8c\u4e86\uff0c\u6211\u8bf4\u7528\u5b57\u5178\u52a0\u901f\u67e5\u627e\u8fd9\u4e0d\u662f\u5e38\u8bc6\u5417\uff1f\u8fd8\u6401\u7740 C++ \u5462\uff1f\u4f60\u5c31\u662f CUDA \u6765\u4e86\u4e5f\u538b\u4e0d\u4f4f\u590d\u6742\u5ea6\u7684\u7206\u8868\u5440\uff1f \u4ed6\u5f88\u9ad8\u5174\uff0c\u4e0d\u77e5\u9053\u600e\u4e48\u611f\u8c22\u6211\uff0c\u4e8e\u662f\u5c31\u628a\u6211\u63a8\u8350\u7ed9\u5f20\u5fc3\u6b23\u4e86\u3002 \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 \u4e0d\u8bba\u4ec0\u4e48\u8bed\u8a00\uff0c\u5bb9\u5668\uff08\u6216\u8005\u7528\u5b66\u6821\u91cc\u7684\u8bdd\u8bf4\uff1a\u6570\u636e\u7ed3\u6784\uff09\u7684\u6b63\u786e\u4f7f\u7528\uff0c\u80fd\u591f\u5728\u590d\u6742\u5ea6\u5c42\u9762\u4e0a\uff0c\u5927\u5e45\u63d0\u5347\u6027\u80fd\u3002 C++ \u4e2d\u4e5f\u662f\u5982\u6b64\uff0c\u6709\u6570\u7ec4\uff08vector\uff09\uff0c\u5b57\u5178\uff08map\uff09\uff0c\u8fd8\u6709\u4e0a\u4e00\u8bfe\u8bb2\u8fc7\u7684\u96c6\u5408\uff08set\uff09\u3002 \u4eca\u5929\u6211\u4eec\u8981\u4ecb\u7ecd\u7684\u5c31\u662f C++ \u7684\u5b57\u5178\u5bb9\u5668 map\uff0c\u4ee5\u53ca C++11 \u5f15\u5165\u7684\u53e6\u4e00\u4e2a\u5b57\u5178\u5bb9\u5668 unordered_map\uff0c\u4ed6\u4eec\u7684\u533a\u522b\u6211\u4eec\u6700\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u3002\u6211\u4eec\u5148\u5b66\u4e60\u8f83\u4e3a\u7b80\u5355\u7684 map\uff0c\u968f\u540e\u5b66\u4e60 unordered_map \u65f6\u4e5f\u53ef\u4ee5\u4e3e\u4e00\u53cd\u4e09\u3001\u878d\u4f1a\u8d2f\u901a\u3002 \u4ecb\u7ecd\u5b8c\u8fd9\u4e24\u4e2a\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u5b57\u5178\u5bb9\u5668\u540e\uff0c\u6211\u4eec\u8fd8\u5c06\u4ecb\u7ecd\u4e00\u4e9b\u5e38\u7528\u7684\u7b2c\u4e09\u65b9\u5e93\u5bb9\u5668\uff0c\u4f8b\u5982 absl::flat_hash_map\u3001tbb::concurrent_hash_map\u3001google::dense_hash_map\u3001robin_hood::unordered_map\u3001tsl::robin_pg_map \u7b49\uff0c\u9700\u8981\u6839\u636e\u5e94\u7528\u573a\u666f\u9009\u62e9\u9002\u5408\u7684\u5bb9\u5668\u3002 map/set \u5bb6\u65cf\u90fd\u662f\u9ad8\u6548\u67e5\u627e\u7684\u4e13\u5bb6\uff1a vector \u5bb9\u5668\u7528 std::find \u67e5\u627e\uff1a O(N) O(N) map \u6216 set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(\\log N) O(\\log N) unordered_map \u6216 unordered_set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(1)+ O(1)+ \u4e0d\u4ec5\u662f\u67e5\u627e\uff0cmap \u4eec\u8fd8\u652f\u6301\u9ad8\u6548\u7684\u589e\u5220\u6539\u67e5\u7b49\u64cd\u4f5c\u3002 map \u7684\u903b\u8f91\u7ed3\u6784 \u7279\u70b9\uff1a \u7531\u4e00\u7cfb\u5217 \u952e\u503c\u5bf9 \u7ec4\u6210 \u4e00\u4e2a\u952e\u53ea\u80fd\u5bf9\u5e94\u4e00\u4e2a\u503c \u952e\u4e0d\u5f97\u91cd\u590d\uff0c\u503c\u53ef\u4ee5\u91cd\u590d std::map, std::unordered_map, absl::flat_hash_map, tbb::concurrent_hash_map \u90fd\u6ee1\u8db3\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u4e00\u57fa\u672c\u903b\u8f91\u7ed3\u6784\uff0c\u53ea\u662f\u7269\u7406\u5b9e\u73b0\u4e0d\u540c\u3002 \u9762\u58c1\u8005\u7f57\u8f91\u76d1\u7763\u4f60\u7684\u5b66\u4e60\uff01 \u5728\u7f16\u7a0b\u4e2d\u6211\u4eec\u5e38\u5e38\u9700\u8981\u7528\u5230\u201c\u6620\u5c04\u201d\u7684\u5173\u7cfb\uff0c\u8fd9\u5c31\u975e\u5e38\u9700\u8981\u7528\u5230\u4ee5 map \u4e3a\u9996\u7684\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u7c7b\u5bb9\u5668\u4e86\u3002 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map map \u7684\u5177\u4f53\u5b9e\u73b0\u53ef\u4ee5\u662f\u7ea2\u9ed1\u6811\u3001AVL \u6811\u3001\u7ebf\u6027\u54c8\u5e0c\u8868\u3001\u94fe\u8868\u54c8\u5e0c\u8868\u3001\u8df3\u8868\u2026\u2026\u4e0d\u540c\u7684\u5b9e\u73b0\u5728\u4e0d\u540c\u64cd\u4f5c\u4e0a\u7684\u590d\u6742\u5ea6\u4e0d\u540c\uff0c\u5206\u522b\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u666f\u3002 \u7528\u6cd5\u4e0a\u51e0\u4e4e\u662f\u5dee\u4e0d\u591a\u7684\uff0c\u4ed6\u4eec\u90fd\u6709\u7740\u51e0\u4e4e\u76f8\u540c\u7684\u63a5\u53e3\uff08\u9664\u4e86\u90e8\u5206\u6269\u5c55\u529f\u80fd\uff09\u3002\u5f53\u4f60\u89c9\u5f97\u7ea2\u9ed1\u6811\u7684 std::map \u4e0d\u5408\u9002\u65f6\uff0c\u53ef\u4ee5\u8f7b\u677e\u628a\u5bf9\u8c61\u7c7b\u578b\u5c31\u5730\u66ff\u6362\u4e3a\u94fe\u8868\u54c8\u5e0c\u8868 std::unordered_map \u6216\u662f\u662f\u7ebf\u6027\u54c8\u5e0c\u8868 absl::flat_hash_map\uff0c\u800c\u4e0d\u7528\u5bf9\u5176\u4ed6\u4ee3\u7801\u6709\u4efb\u4f55\u66f4\u6539\u3002 \u8fd9\u5c31\u662f\u6240\u6709 map \u7c7b\u5bb9\u5668\u90fd\u6709\u7740\u76f8\u540c\u7684 \u903b\u8f91\u7ed3\u6784 \uff1a\u90fd\u662f\u4e00\u4e2a\u952e-\u503c\u6620\u5c04\uff0c\u4e0d\u540c\u7684\u53ea\u662f\u4ed6\u4eec\u7684 \u7269\u7406\u7ed3\u6784 \u800c\u5df2\u3002 \u6240\u6709\u7684 map \u5b9e\u73b0\uff0c\u90fd\u4f1a\u6a21\u4eff\u63d0\u4f9b\u548c std::map \u4e00\u6837\u7684 API\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u867d\u7136 std::map \u5b9e\u73b0\u7684\u5f88\u4f4e\u6548\uff0c\u6211\u4eec\u8fd8\u662f\u8981\u5b66\u4ed6\u7684\u539f\u56e0\u3002std::map \u672c\u8eab\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\uff0c\u4f46\u5374\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6240\u6709\u7b2c\u4e09\u65b9\u90fd\u4f1a\u9075\u5faa\u7684\u7edf\u4e00\u63a5\u53e3\u3002\u5b66\u4f1a\u4e86 std::map\uff0c\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93\u7684 map \u7c7b\u5bb9\u5668\u4f60\u90fd\u53ef\u4ee5\u8f7b\u6613\u4e3e\u4e00\u53cd\u4e09\u3002 \u4e0d\u4ec5\u662f\u5404\u79cd\u7b2c\u4e09\u65b9\u7684 map \u5e93\uff0c\u6bd4\u5982 rapidjson \u5e93\u4e2d\u7684 JSON \u5bf9\u8c61\uff0c\u4e5f\u63d0\u4f9b\u4e86\u7c7b\u4f3c std::map \u7684 find \u548c end \u8fed\u4ee3\u5668\u63a5\u53e3\uff1a MemberFind \u548c MemberEnd \uff0c\u6765\u67e5\u627e\u4e00\u4e2a\u5b57\u5178\u7684\u5b50\u952e\uff1b\u51e0\u4f55\u5904\u7406\u5e93 cgal \u4e2d\u7684\u201c\u9876\u70b9\u67e5\u627e\u201d\u529f\u80fd\u4e5f\u662f\u57fa\u4e8e\u7c7b\u4f3c\u7684\u8fed\u4ee3\u5668\u63a5\u53e3\u3002\u603b\u4e4b\uff0c\u5b66\u4f1a std::map \u5c06\u5927\u5927\u6709\u52a9\u4e8e\u4f60\u770b\u61c2\u8fd9\u7c7b\u4e1a\u754c\u516c\u8ba4\u7684\u63a5\u53e3\u89c4\u8303\u3002 \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 \u6807\u51c6\u5e93\u4e2d\uff0cmap 1 \u662f\u4e00\u4e2a \u6a21\u677f\u7c7b \uff0c\u4ed6\u7684\u952e\u7c7b\u578b\uff0c\u503c\u7c7b\u578b\uff0c\u53ef\u4ee5\u7531\u5c16\u62ec\u53f7\u5185\u7684\u53c2\u6570\u6307\u5b9a\uff0c\u4fbf\u4e8e\u9002\u5e94\u4e0d\u540c\u7684\u7528\u6237\u9700\u6c42\u3002 \u7531\u4e8e C++ \u6807\u51c6\u5e93\u7684\u5bb9\u5668\u5927\u591a\u90fd\u662f\u6a21\u677f\u7c7b\uff0c\u63d0\u4f9b\u7684\u7b97\u6cd5\u4e5f\u5927\u591a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u56e0\u6b64 C++ \u6807\u51c6\u5e93\u5e38\u88ab\u79f0\u4e3a\u6807\u51c6\u6a21\u677f\u5e93 (Standard-Template-Library, STL)\u3002 \u952e\u7c7b\u578b\u548c\u503c\u7c7b\u578b\u53ef\u4ee5\u662f\u4efb\u610f\u7c7b\u578b\uff0c\u5305\u62ec\u57fa\u672c\u7c7b\u578b\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u7c7b\uff0c\u5176\u4ed6 STL \u5bb9\u5668\u7b49\uff0c\u4f53\u73b0\u4e86\u5bb9\u5668\u7684\u6cdb\u7528\u6027\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\uff1a\u952e\u5fc5\u987b\u652f\u6301\u6bd4\u8f83\uff0c\u8fd9\u91cc map \u8981\u6c42\u7684\u662f\u5c0f\u4e8e\u8fd0\u7b97\u7b26 < \u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a string\uff0c\u503c\u7c7b\u578b\u4e3a int \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a int\uff0c\u503c\u7c7b\u578b\u4e3a Student \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map> \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a char\uff0c\u503c\u7c7b\u578b\u4e3a vector \u7684 map \u5bb9\u5668\u3002 \u540e\u9762\u4e3a\u4e86\u65b9\u4fbf\u7814\u7a76\uff0c\u4ee5 map \u5f62\u5f0f\u4e66\u5199\u5f97\u51fa\u7684\u7ed3\u8bba\uff0c\u5bf9\u4e8e\u4efb\u4f55\u5b9e\u9645\u952e\u548c\u503c\u7c7b\u578b\uff0c\u53ea\u9700\u4ee3\u5165 K \u548c V \u5373\u53ef\u3002 \u5df2\u77e5\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 K \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < \u3002 \u53ef\u5f97\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 string \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < 2 \u3002 \u5df2\u77e5\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e K \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 \u53ef\u5f97\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e int \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 map \u7684\u7269\u7406\u7ed3\u6784 map \u548c set \u4e00\u6837\uff0c\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u5b9e\u73b0 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u9ad8\u6548\u67e5\u627e\u3002 vector \u5c31\u662f\u56e0\u4e3a\u5143\u7d20\u6ca1\u6709\u56fa\u5b9a\u7684\u987a\u5e8f\uff0c\u6240\u4ee5\u624d\u9700\u8981\u66b4\u529b\u904d\u5386\u67e5\u627e\u3002 \u5728\u6301\u7eed\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u4e0b\uff0c\u59cb\u7ec8\u7ef4\u6301\u5143\u7d20\u7684\u6709\u5e8f\u6027\uff0c\u6b63\u662f map \u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\u7684\u5173\u952e\u6240\u5728\u3002 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u59cb\u7ec8\u4fdd\u5b58\u5143\u7d20\u6309\u952e\u6392\u5e8f\u7684\u597d\u5904\u662f\uff0c\u5982\u679c\u9700\u8981\u5bfb\u627e\u6307\u5b9a\u952e\u503c\u7684\u5143\u7d20\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u4e8c\u5206\u6cd5\uff1a \u4ece\u6839\u8282\u70b9\u5f00\u59cb\u67e5\u627e\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5c0f\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u5de6\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5927\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u53f3\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u7b49\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u8be5\u8282\u70b9\u5c31\u662f\u8981\u627e\u7684\u8282\u70b9\uff0c\u8fd4\u56de\u8be5\u8282\u70b9\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u662f\u6700\u540e\u4e00\u5c42\u53f6\u5b50\u8282\u70b9\uff0c\u4e5f\u6ca1\u627e\u5230\u76f8\u7b49\u7684\u952e\uff0c\u5219\u8bf4\u660e\u8be5\u952e\u4e0d\u5b58\u5728\u3002 \u628a\u5de6/\u53f3\u5b50\u8282\u70b9\u8bbe\u4e3a\u65b0\u7684\u5f53\u524d\u8282\u70b9\uff0c\u7136\u540e\u56de\u5230\u7b2c 2 \u6b65\uff0c\u91cd\u590d\u8fd9\u4e00\u67e5\u627e\u8fc7\u7a0b\u3002 \u4e8c\u53c9\u6392\u5e8f\u6811 \u7531\u4e8e map \u7684\u5b9e\u73b0\u57fa\u4e8e\u4e8c\u53c9\u6392\u5e8f\u6811\uff0cmap \u989d\u5916\u6709\u4e00\u4e2a\u7279\u70b9\uff1a \u6709\u5e8f \u3002 map (\u6216 set) \u4e2d\u7684\u952e K \u603b\u662f\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u65b9\u4fbf\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u627e\u5230\u5bf9\u5e94\u5143\u7d20\u3002 \u6bcf\u6b21\u63d2\u5165\u65b0\u7684\u952e\u65f6\uff0c\u4f1a\u627e\u5230\u9002\u5f53\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u4f7f\u5f97\u63d2\u5165\u540e\u7684 map \u4ecd\u7136\u6709\u5e8f\u3002 \u6ce8\uff1a\u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\u5b9e\u73b0\u7684 unordered_map (\u548c unordered_set)\uff0c\u5c31\u4e0d\u5177\u5907 \u6709\u5e8f \u8fd9\u4e00\u7279\u70b9\u3002 \u4e24\u8005\u7684\u533a\u522b\u5728\u4e8e\uff1amap \u5728 K \u4e4b\u5916\uff0c\u989d\u5916\u5916\u6302\u4e86\u4e00\u4e2a V \u7c7b\u578b\u3002 map \u4e2d\u7684 V \u7c7b\u578b\u4e0d\u53c2\u4e0e\u6392\u5e8f\uff0c\u53ea\u6309\u7167 K \u8fdb\u884c\u6392\u5e8f\u3002 \u8fd9\u6837\u5f53\u7528\u6237\u6839\u636e K \u627e\u5230\u7684\u662f K-V \u5bf9\uff0c\u7136\u540e\u53ef\u4ee5\u53d6\u51fa K \u5bf9\u5e94\u7684 V\u3002 \u8fd9\u5c31\u5b9e\u73b0\u4e86\u4ece K \u5230 V \u7684\u6620\u5c04\u3002 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u4e8c\u53c9\u6392\u5e8f\u6811\u53ea\u89e3\u51b3\u4e86\u67e5\u627e\u7684\u95ee\u9898\uff0c\u4f46\u662f\u4ed6\u5e76\u4e0d\u80fd\u4fdd\u8bc1\u7ecf\u5386\u4e00\u901a\u63d2\u5165\u540e\u7684\u6811\u4e0d\u4f1a\u201c\u9000\u5316\u201d\u3002 \u5982\u679c\u63d2\u5165\u7684\u65f6\u5019\u4e0d\u5c0f\u5fc3\uff0c\u53ef\u80fd\u4f1a\u8ba9\u6811\u7684\u5f62\u72b6\u53d8\u5f97\u975e\u5e38\u8be1\u5f02\uff01 \u4f8b\u5982\uff0c\u82e5\u63d2\u5165\u6570\u636e\u7684\u987a\u5e8f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u90a3\u5c31\u4f1a\u4e00\u76f4\u5728\u5f80\u53f3\u63d2\u5165\uff0c\u6e05\u4e00\u8272\u7684\u4e00\u8fb9\u5012\uff0c\u4ee5\u81f3\u4e8e\u51e0\u4e4e\u6210\u4e86\u4e00\u6839\u5f80\u53f3\u8dd1\u7684\u94fe\u8868\u3002 \u5982\u679c\u63d2\u5165\u987a\u5e8f\u662f\u4ece\u5927\u5230\u5c0f\uff0c\u5c31\u53d8\u6210\u4e00\u76f4\u5f80\u5de6\u8fb9\u5012\u3002\u5373\u4f7f\u63d2\u5165\u7684\u987a\u5e8f\u4e0d\u90a3\u4e48\u523b\u610f\uff0c\u4f9d\u7136\u53ef\u80fd\u4ea7\u751f\u975e\u5e38\u53d8\u6001\u7684\u5f62\u72b6\uff0c\u8fdd\u80cc\u4e86\u4e8c\u53c9\u6811\u7684\u521d\u8877\u3002 \u54e5\u4fe9\u751f\u5f02\u5f62\u5462\uff1f \u8fd9\u6837\u201c\u9000\u5316\u201d\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u867d\u7136\u80fd\u4fdd\u6301\u6709\u5e8f\uff0c\u4f46\u4e8c\u5206\u67e5\u627e\u65f6\u5c31\u8d77\u4e0d\u5230\u52a0\u901f\u4f5c\u7528\u4e86\u3002 \u5982\u679c\u8981\u627e\u4e00\u4e2a\u4e2d\u95f4\u7684\u5143\u7d20\uff0c\u51e0\u4e4e\u5c31\u548c\u94fe\u8868\u4e00\u6837\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u53f3\u679d\u5e72\u3002 \u4e3a\u4e86\u9650\u5236\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0d\u8981\u957f\u6210\u7578\u5f62\uff0c\u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u6307\u6807\uff1a\u201c\u6df1\u5ea6\u201d\uff0c\u8868\u793a\u4ece\u6839\u8282\u70b9\u5230\u6700\u5e95\u5c42\u53f6\u5b50\u8282\u70b9\u7684\u8ddd\u79bb\u3002 \u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u5c31\u9700\u8981\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u5c3d\u53ef\u80fd\u7684\u4f4e\u3002 \u56e0\u4e3a\u4e8c\u5206\u67e5\u627e\u7684\u6b21\u6570\u5c31\u53d6\u51b3\u4e8e\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u7684\u5e73\u5747\u6df1\u5ea6\uff0c\u8981\u5c3d\u53ef\u80fd\u51cf\u5c11\u5e73\u5747\u9700\u8981\u8bbf\u95ee\u7684\u6b21\u6570\uff0c\u5c31\u662f\u8981\u51cf\u5c11\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u3002 \u4e5f\u5c31\u662f\u8bf4\u8981\u8ba9\u5927\u5bb6\u90fd\u5c3d\u53ef\u80fd\u8d34\u8fd1\u6839\u90e8\uff0c\u4f46\u6211\u4eec\u4e0d\u53ef\u80fd\u8ba9\u6240\u6709\u53f6\u5b50\u90fd\u6700\u8d34\u8fd1\u6839\u90e8\u3002 \u4f8b\u5982\u53f3\u4fa7\u53ea\u6709\u4e00\u4e2a\u53f6\u5b50\u8282\u70b9\uff0c\u4ed6\u81ea\u5df1\u662f\u6df1\u5ea6\u6700\u4f4e\u4e86\uff0c\u4f46\u4ee3\u4ef7\u662f\u5de6\u8fb9\u5168\u90e8\u6324\u5728\u4e00\u6761\u94fe\u8868\u4e0a\u4e86\uff01\u8fd9\u4e0d\u516c\u5e73\u3002 \u5b83\u81ea\u5df1\u5012\u662f\u81ea\u7531\u4e86\uff0c\u4f46\u5b83\u5974\u5f79\u4e86\u6240\u6709\u7684\u4eba\u6c11 \u6240\u4ee5\u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u6211\u4eec\u771f\u6b63\u9700\u8981\u7684\u662f\u8ba9\u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u5c3d\u53ef\u80fd\u201c\u5e73\u7b49\u201d\uff01 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u4e3a\u4e86\u907f\u514d\u4e8c\u53c9\u6811\u957f\u6210\u7578\u5f62\uff0c\u9677\u5165\u4e00\u8fb9\u5012\u7684\u60c5\u51b5\u3002\u6211\u4eec\u9700\u8981\u5728\u6bcf\u6b21\u63d2\u5165\u540e\uff0c\u68c0\u67e5\u4e8c\u53c9\u6811\u662f\u5426\u6df1\u5ea6\u5dee\u8ddd\u8fc7\u5927\u3002 \u5982\u679c\u5dee\u7684\u592a\u591a\u4e86\uff0c\u5c31\u9700\u8981\u8fdb\u884c\u4e00\u7cfb\u5217\u77eb\u6b63\u64cd\u4f5c\uff0c\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\uff0c\u628a\u592a\u957f\u7684\u679d\u5e72\u780d\u65ad\uff0c\u63a5\u5728\u77ed\u7684\u5730\u65b9\uff0c\u5c3d\u53ef\u80fd\u4fdd\u6301\u6240\u6709\u53f6\u5b50\u8def\u5f84\u7684\u6df1\u5ea6\u5dee\u4e0d\u591a\uff0c\u8fd9\u4e2a\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u52a8\u4f5c\u5c31\u662f \u5e73\u8861\u64cd\u4f5c (balancing) \u3002 \u95ee\u9898\u662f\uff0c\u6700\u5927\u80fd\u5bb9\u5fcd\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u591a\u5927\u7684\u6df1\u5ea6\u5dee\u624d\u5f00\u59cb\u77eb\u6b63\uff1f\u9488\u5bf9\u8fd9\u4e2a\u95ee\u9898\uff0c\u4e8c\u53c9\u6392\u5e8f\u6811\u5206\u4e3a\u4e24\u6d3e\uff1a \u5e73\u8861\u6811 \u6700\u7406\u60f3\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u9897\u542b\u6709 N N \u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u81f3\u5c11\u9700\u8981\u6709 \\lceil \\log N \\rceil \\lceil \\log N \\rceil \u6df1\u5ea6\u3002 \u8fd9\u5c31\u662f\u5e73\u8861\u6811\uff08AVL\uff09\uff0c\u4ed6\u5f3a\u5236\u4fdd\u8bc1\u6574\u4e2a\u6811\u5904\u4e8e\u5b8c\u7f8e\u7684\u5e73\u8861\u72b6\u6001\uff0c\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u6df1\u5ea6\u5dee\u8ddd\u4e0d\u4f1a\u8d85\u8fc7 1\uff08\u5f53\u8282\u70b9\u6570\u91cf N N \u4e0d\u662f 2 \u7684\u6574\u6570\u500d\u65f6\uff0c\u8fd9\u662f\u4e0d\u5f97\u4e0d\u5b58\u5728\u7684 1 \u683c\u5dee\u8ddd\uff09\u3002 \u4f18\u70b9\uff1a\u59cb\u7ec8\u4fdd\u6301\u6700\u5b8c\u7f8e\u7684\u5e73\u8861\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u548c\u6700\u574f\u590d\u6742\u5ea6\u6700\u4f4e\u3002\u6240\u4ee5\u5e73\u8861\u6811\u7684\u67e5\u627e\u6027\u80fd\u662f\u6700\u597d\u7684\u3002 \u7f3a\u70b9\uff1a\u7136\u800c\u59cb\u7ec8\u4fdd\u6301\u5b8c\u7f8e\u7684\u5e73\u8861\u610f\u5473\u7740\uff0c\u51e0\u4e4e\u6bcf\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff08\u53ef\u80fd\u4f1a\u7a81\u7136\u4ea7\u751f\u6df1\u5ea6\u5dee\u8ddd\u8d85\u8fc7 1 \u7684\u60c5\u51b5\uff09\uff0c\u5c31\u7acb\u5373\u9700\u8981\u5e73\u8861\u4e00\u6b21\u3002\u5e73\u8861\u4e00\u6b21\u7684\u5f00\u9500\u662f\u6bd4\u8f83\u5927\u7684\uff0c\u6240\u4ee5\u5e73\u8861\u6811\u7684\u6027\u80fd\u662f\u63d2\u5165\u6027\u80fd\u662f\u6bd4\u8f83\u5dee\u7684\u3002 \u5e73\u8861\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u65b9\u5f0f\u662f\u201c\u65cb\u8f6c\u201d\uff0c\u4ed6\u80fd\u59cb\u7ec8\u4fdd\u6301\u6700\u4f4e\u7684\u6df1\u5ea6\u5dee\uff1a \u8fd9\u91cc\u7684\u7ec6\u8282\u6211\u4eec\u4e0d\u4f1a\u6df1\u7a76\uff0c\u90a3\u662f\u6570\u636e\u7ed3\u6784\u8bfe\u7684\u5185\u5bb9\uff0c\u5c4a\u65f6\u4f1a\u5e26\u5927\u5bb6\u624b\u6413\u5e73\u8861\u6811\u548c\u7ea2\u9ed1\u6811\uff0c\u672c\u671f\u53ea\u662f\u7a0d\u5fae\u4e86\u89e3 map \u5e38\u89c1\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5e2e\u52a9\u4f60\u7406\u89e3\u4e3a\u4ec0\u4e48 map \u662f\u6709\u5e8f\u5bb9\u5668\u3002 \u7ea2\u9ed1\u6811 \u800c\u7ea2\u9ed1\u6811\u8ba4\u4e3a\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u603b\u662f\u4fdd\u6301\u6df1\u5ea6\u5dee\u8ddd\u4e3a 1 \u90a3\u4e48\u5c0f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u5373\u53ef\u3002 \u4f8b\u5982\u6700\u6d45\u7684\u4e00\u4e2a\u53f6\u5b50\u662f 6 \u6df1\u5ea6\uff0c\u53e6\u4e00\u4e2a\u6700\u6df1\u7684\u53f6\u5b50\u53ef\u4ee5\u662f 12 \u6df1\u5ea6\u3002\u53ea\u6709\u5f53\u6700\u6df1\u7684\u53f6\u5b50\u8d85\u8fc7 12 \u6df1\u5ea6\u65f6\uff0c\u7ea2\u9ed1\u6811\u624d\u4f1a\u5f00\u59cb\u4e3b\u52a8\u5e72\u9884\u5e73\u8861\uff0c\u907f\u514d\u7ee7\u7eed\u7578\u5f62\u53d1\u5c55\u4e0b\u53bb\u3002 \u7f3a\u70b9\uff1a\u6811\u53ef\u80fd\u6709\u4e00\u5b9a\u7684\u4e00\u8fb9\u5012\u60c5\u51b5\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u7a0d\u5fae\u964d\u4f4e\uff0c\u6700\u574f\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u539f\u6765\u7684 2 \u500d\uff01 \u4f18\u70b9\uff1a\u56e0\u4e3a\u5bf9\u4e0d\u5e73\u8861\u73b0\u8c61\u66f4\u52a0\u5bbd\u677e\uff0c\u6b63\u5e38\u63d2\u5165\u65f6\u57fa\u672c\u4e0d\u9700\u8981\u5e73\u8861\uff0c\u53ea\u6709\u7279\u522b\u626d\u66f2\u4e86\u624d\u4f1a\u4e0b\u573a\u201c\u6551\u6025\u201d\u3002\u6240\u4ee5\u7ea2\u9ed1\u6811\u662f\u727a\u7272\u4e86\u4e00\u90e8\u5206\u67e5\u627e\u6027\u80fd\uff0c\u6362\u53d6\u4e86\u66f4\u597d\u7684\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7684\u7528\u51b5\u662f\u63d2\u5165\u6bd4\u8f83\u5c11\uff0c\u4f46\u662f\u67e5\u8be2\u975e\u5e38\u591a\uff0c\u90a3\u5c31\u9002\u5408\u7528\u5e73\u8861\u6811\u3002 \u7531\u4e8e\u6362\u6765\u7684\u8fd9\u90e8\u5206\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u5b9e\u9645\u4e0a\u6bd4\u635f\u5931\u7684\u67e5\u627e\u6027\u80fd\u591a\uff0c\u800c map \u5e38\u89c1\u7684\u7528\u51b5\u786e\u5b9e\u9700\u8981\u7ecf\u5e38\u589e\u5220\u6539\u67e5\uff0c\u6240\u4ee5\u73b0\u5728 C++ \u6807\u51c6\u5e93\u7684 map \u5e95\u5c42\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u5b9e\u73b0\u7684\u3002 \u5982\u679c\u4f60\u7684\u9700\u6c42\u662f\u5927\u91cf\u67e5\u627e\u7684\u8bdd\uff0c\u5b8c\u5168\u53ef\u4ee5\u8003\u8651\u7528\u67e5\u627e\u5e73\u5747\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u7684\u54c8\u5e0c\u8868 unordered_map\u3002 \u5982\u679c\u662f\u4e00\u6b21\u6027\u63d2\u5165\u5b8c\u6bd5\u540e\u4e0d\u4f1a\u518d\u4fee\u6539\uff0c\u8fd8\u53ef\u4ee5\u7528\u5b8c\u7f8e\u54c8\u5e0c\u8868\uff08frozen_map\uff09\uff0c\u4ed6\u4f1a\u4e3a\u4f60\u7684\u952e\u503c\u5e8f\u5217\u4e13\u95e8\u751f\u6210\u4e00\u4e2a\u4e13\u7528\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u4e14\u4fdd\u8bc1\u5b8c\u5168\u65e0\u51b2\u7a81\u3002\u4f8b\u5982\u4f60\u5728\u505a\u4e00\u79cd\u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u6709\u5f88\u591a\u201c\u5173\u952e\u5b57\u201d\uff0c\u6bd4\u5982\u201cif\u201d\u3001\u201cwhile\u201d\uff0c\u4f60\u9700\u8981\u8fd0\u884c\u65f6\u9891\u7e41\u7684\u67e5\u627e\u8fd9\u4e9b\u5173\u952e\u5b57\uff0c\u800c\u5173\u952e\u5b57\u6709\u54ea\u4e9b\u5728\u7f16\u8bd1\u671f\u662f\u56fa\u5b9a\u7684\uff0c\u90a3\u5c31\u5f88\u9002\u5408\u7528\u5b8c\u7f8e\u54c8\u5e0c\u3002 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u7ea2\u9ed1\u6811\u662f\u5982\u4f55\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u7684\u5462\uff1f \u4ed6\u8bbe\u5b9a\u4e86\u8fd9\u6837 5 \u6761\u89c4\u5219\uff1a \u8282\u70b9\u53ef\u4ee5\u662f\u7ea2\u8272\u6216\u9ed1\u8272\u7684\u3002 \u6839\u8282\u70b9\u603b\u662f\u9ed1\u8272\u7684\u3002 \u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u662f\u9ed1\u8272\uff08\u53f6\u5b50\u8282\u70b9\u5c31\u662f NULL\uff09\u3002 \u7ea2\u8272\u8282\u70b9\u7684\u4e24\u4e2a\u5b50\u8282\u70b9\u5fc5\u987b\u90fd\u662f\u9ed1\u8272\u7684\u3002 \u4ece\u4efb\u4e00\u8282\u70b9\u5230\u5176\u6240\u6709\u53f6\u5b50\u8282\u70b9\u7684\u8def\u5f84\u90fd\u5305\u542b\u76f8\u540c\u6570\u91cf\u7684\u9ed1\u8272\u8282\u70b9\u3002 \u4ec0\u4e48\u89c4\u5219\u7c7b\u602a\u8c08\u2026\u2026 \u770b\u8d77\u6765\u597d\u50cf\u5f88\u590d\u6742\uff0c\u4f46\u5b9e\u9645\u4e0a\u5927\u591a\u662f\u5e9f\u8bdd\uff0c\u6709\u7528\u7684\u53ea\u662f 4 \u548c 5 \u8fd9\u4e24\u6761\u3002 \u89c4\u5219 4 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4e0d\u5f97\u51fa\u73b0\u76f8\u90bb\u7684\u7ea2\u8272\u8282\u70b9\uff08\u76f8\u90bb\u6307\u4e24\u4e2a\u8282\u70b9\u662f\u7236\u5b50\u5173\u7cfb\uff09\u3002\u8fd9\u6761\u89c4\u5219\u8fd8\u6709\u4e00\u4e2a\u9690\u542b\u7684\u4fe1\u606f\uff1a\u9ed1\u8272\u8282\u70b9\u53ef\u4ee5\u76f8\u90bb\uff01 \u89c4\u5219 5 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6240\u6709\u5e95\u5c42\u53f6\u5b50\u7684\u8ddd\u79bb\uff08\u4ee5\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u8ba1\uff09\uff0c\u5fc5\u987b\u76f8\u7b49\u3002 \u56e0\u4e3a\u89c4\u5219 4 \u7684\u5b58\u5728\uff0c\u7ea2\u8272\u8282\u70b9\u4e0d\u53ef\u80fd\u76f8\u90bb\uff0c\u4e5f\u5c31\u662f\u8bf4\u6700\u6df1\u7684\u679d\u5e72\u53ea\u80fd\u662f\uff1a\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1\u3002 \u7ed3\u5408\u89c4\u5219 5 \u6765\u770b\uff0c\u4e5f\u5c31\u662f\u8bf4\u6bcf\u6761\u679d\u5e72\u4e0a\u7684\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u5fc5\u987b\u76f8\u540c\uff0c\u56e0\u4e3a\u6700\u6df1\u7684\u679d\u5e72\u662f 4 \u4e2a\u9ed1\u8282\u70b9\u4e86\uff0c\u6240\u4ee5\u6700\u6d45\u7684\u679d\u5e72\u81f3\u5c11\u4e5f\u5f97\u6709 4 \u4e2a\u8282\u70b9\u5168\u662f\u9ed1\u8272\u7684\uff1a\u9ed1-\u9ed1-\u9ed1-\u9ed1\u3002 \u53ef\u4ee5\u770b\u5230\uff0c\u89c4\u5219 4 \u548c\u89c4\u5219 5 \u8054\u5408\u8d77\u6765\u5b9e\u9645\u4e0a\u5c31\u4fdd\u8bc1\u4e86\uff1a\u6700\u6df1\u679d\u5e72\u7684\u6df1\u5ea6\u4e0d\u4f1a\u8d85\u8fc7\u6700\u6d45\u679d\u5e72\u7684 2 \u500d\u3002 \u5982\u679c\u8d85\u51fa\u4e86 2 \u500d\uff0c\u5c31\u4e0d\u5f97\u4e0d\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u89c4\u5219 4 \u6216 5\uff0c\u4ece\u800c\u89e6\u53d1\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u5e73\u8861\u64cd\u4f5c\uff0c\u4ece\u800c\u963b\u6b62\u4e86\u4e8c\u53c9\u6811\u8fc7\u4e8e\u7578\u5f62\u5316\u3002 \u7ea2\u9ed1\u6811\u5982\u4f55\u5b9e\u73b0\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u7ec6\u8282\u6211\u4eec\u5c31\u4e0d\u518d\u591a\u8c08\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u70b9\u5230\u4e3a\u6b62\uff0c\u63a5\u4e0b\u6765\u76f4\u63a5\u8fdb\u5165\u6b63\u9898\uff1a \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u521b\u5efa\u4e00\u4e2a map \u5bf9\u8c61\uff1a map config; \u4e00\u5f00\u59cb map \u521d\u59cb\u662f\u7a7a\u7684\uff0c\u5982\u4f55\u63d2\u5165\u4e00\u4e9b\u521d\u59cb\u6570\u636e\uff1f config[\"timeout\"] = 985; config[\"delay\"] = 211; \u6570\u636e\u63d2\u5165\u6210\u529f\u4e86\uff0c\u6839\u636e\u952e\u67e5\u8be2\u5bf9\u5e94\u7684\u503c\uff1f print(config[\"timeout\"]); print(config[\"delay\"]); \u67e5\u8be2\u65f6\u5efa\u8bae\u7528 .at(key) \u800c\u4e0d\u662f [key] \uff1a print(config.at(\"timeout\")); print(config.at(\"delay\")); \u8001\u751f\u5e38\u8c08\u7684\u95ee\u9898\uff1amap \u4e2d\u5b58 string \u8fd8\u662f const char *\uff1f map m; m[\"hello\"] = \"old\"; // \u5e38\u91cf\u533a\u7684 \"hello\" char key[] = \"hello\"; // key \u7684\u5730\u5740\u5728\u6808\u4e0a print(key == \"hello\"); // false m[key] = \"new\"; // \u6808\u4e0a\u53d8\u91cf\u7684 key = \"hello\" print(m); // \u4e24\u4e2a\u91cd\u590d\u7684\u952e \"hello\" false {hello: old, hello: new} \u5728 C++ \u4e2d\uff0c\u4efb\u4f55\u65f6\u5019\u90fd\u52a1\u5fc5\u7528 string\uff01\u522b\u7528 C \u8bed\u8a00\u8001\u6389\u7259\u7684 const char *\uff0c\u592a\u5371\u9669\u4e86\u3002 const char * \u5371\u9669\u7684\u539f\u56e0\uff1a const char * \u7684 == \u5224\u65ad\u7684\u662f\u6307\u9488\u7684\u76f8\u7b49\uff0c\u4e24\u4e2a const char * \u53ea\u8981\u5730\u5740\u4e0d\u540c\uff0c\u5373\u4f7f\u5b9e\u9645\u7684\u5b57\u7b26\u4e32\u76f8\u540c\uff0c\u4e5f\u4e0d\u4f1a\u88ab\u89c6\u4e3a\u540c\u4e00\u4e2a\u5143\u7d20\uff08\u5982\u4e0a\u4ee3\u7801\u6848\u4f8b\u6240\u793a\uff09\u3002\u5bfc\u81f4 map \u91cc\u4f1a\u51fa\u73b0\u91cd\u590d\u7684\u952e\uff0c\u4ee5\u53ca\u6309\u952e\u67e5\u627e\u53ef\u80fd\u627e\u4e0d\u5230\u7b49\u3002 \u4fdd\u5b58\u7684\u662f\u5f31\u5f15\u7528\uff0c\u5982\u679c\u4f60\u628a\u5c40\u90e8\u7684 char [] \u6216 string.c_str() \u8fd4\u56de\u7684 const char * \u5b58\u5165 map\uff0c\u7b49\u8fd9\u4e9b\u5c40\u90e8\u91ca\u653e\u4e86\uff0cmap \u4e2d\u7684 const char * \u5c31\u662f\u4e00\u4e2a\u7a7a\u60ac\u6307\u9488\u4e86\uff0c\u4f1a\u9020\u6210 segfault\u3002 \u8bf7\u7528\u5b89\u5168\u7684 string\uff1a map m; m[\"hello\"] = \"old\"; string key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // string \u7684 == \u8fd0\u7b97\u7b26\u662f\u7ecf\u8fc7\u91cd\u8f7d\u7684\uff0c\u6bd4\u8f83\u7684\u662f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u5185\u5bb9\u76f8\u7b49\uff0c\u800c\u4e0d\u662f\u5730\u5740\u76f8\u7b49 {\"hello\": \"new\"} true \u63cf\u8ff0 C++ Java Python \u5185\u5bb9\u76f8\u7b49 string(\"hello\") == string(\"hello\") \"hello\".equals(\"hello\") 'hello' == 'hello' \u5730\u5740\u76f8\u7b49 \"hello\" == \"hello\" \"hello\" == \"hello\" id('hello') == id('hello') \u5982\u679c\u4f60\u7cbe\u901a\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u80fd\u4fdd\u8bc1 key \u6307\u5411\u7684\u5b57\u7b26\u4e32\u6d3b\u7684\u6bd4 m \u4e45\uff0c\u60f3\u8981\u907f\u514d\u62f7\u8d1d\uff0c\u8282\u7701\u6027\u80fd\u3002 string \u7684\u5f31\u5f15\u7528\u7248\u672c\uff1astring_view\uff0c\u540c\u6837\u53ef\u4ee5\u7528\u5c01\u88c5\u4e86\u6b63\u786e\u7684 == \u8fd0\u7b97\u7b26\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\uff1a map m; m[\"hello\"] = \"old\"; string_view key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // \u6b64\u5904 m \u662f\u6808\u4e0a\u53d8\u91cf\uff0ckey \u662f\u5f31\u5f15\u7528\u6307\u5411\u5168\u5c40\u5e38\u91cf\u533a\uff08rodata\uff09\uff0ckey \u6bd4 m \u6d3b\u5f97\u4e45\uff0c\u6ca1\u6709\u7a7a\u60ac\u6307\u9488\u95ee\u9898 {\"hello\": \"new\"} true \u26a0\ufe0f string_view \u5c5e\u4e8e\u4e0d\u5efa\u8bae\u521d\u5b66\u8005\u4f7f\u7528\u7684\u4f18\u5316\u5c0f\u5bc4\u5de7\uff1a\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528\u3002 \u6ce8\uff1amap \u5b9e\u9645\u4e0a\u5b8c\u5168\u6ca1\u6709\u7528\u5230 ==\uff0c\u7528\u5230\u7684\u53ea\u6709 < \u8fd0\u7b97\u7b26\uff0c\u5f53\u9700\u8981\u5224\u5b9a a == b \u65f6\uff0c\u4ed6\u4f1a\u8f6c\u800c\u7528 !(a < b || b < a) \u6765\u5224\u5b9a\u3002 string_view \u4e5f\u5177\u6709\u6b63\u786e\u7684 hash \u7279\u5316\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528\u505a unordered_map \u7684\u952e\u7c7b\u578b\u3002string_view \u8bd5\u56fe\u548c string \u8868\u73b0\u5f97\u5b8c\u5168\u4e00\u6837\uff0c\u533a\u522b\u5728\u4e8e\u4ed6\u662f\u4e2a\u5f31\u5f15\u7528\uff0c\u4e0d\u6301\u6709\u5bf9\u8c61\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\u3002string_view \u5927\u5c0f\u53ea\u6709 16 \u4e2a\u5b57\u8282\uff0c\u5185\u90e8\u662f\u4e00\u4e2a const char * \u548c size_t\uff0c\u4f46\u5c01\u88c5\u4e86\u6b63\u786e\u7684 ==\uff0c<\uff0c> \u548c hash\u3002 C++11 \u65b0\u7279\u6027\u2014\u2014\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\uff0c\u5141\u8bb8\u521b\u5efa map \u65f6\u76f4\u63a5\u6307\u5b9a\u521d\u59cb\u6570\u636e\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211} }; \u901a\u5e38\u6211\u4eec\u4f1a\u6362\u884c\u5199\uff0c\u4e00\u884c\u4e00\u4e2a\u952e\u503c\u5bf9\uff0c\u770b\u8d77\u6765\u6761\u7406\u66f4\u6e05\u6670\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 \u603b\u7ed3\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5\uff1a map m = { {k1, v1}, {k2, v2}, ..., }; \u8ba9 map \u521d\u59cb\u5c31\u5177\u6709\u8fd9\u4e9b\u6570\u636e\u3002 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; \u7b49\u53f7\u53ef\u4ee5\u7701\u7565\uff08\u8fd9\u5176\u5b9e\u76f8\u5f53\u4e8e\u662f\u5728\u8c03\u7528 map \u7684\u6784\u9020\u51fd\u6570\uff09\uff1a map config{ {\"timeout\", 985}, {\"delay\", 211}, }; \u4e5f\u53ef\u4ee5\u5148\u6784\u9020\u518d\u8d4b\u503c\u7ed9 auto \u53d8\u91cf\uff1a auto config = map{ {\"timeout\", 985}, {\"delay\", 211}, }; \u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u5173\u4e8e\u6784\u9020\u51fd\u6570\u3001\u82b1\u62ec\u53f7\u5217\u8868\u7684\u5177\u4f53\u8bed\u6cd5\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u300b\u7cfb\u5217\u7b2c\u4e8c\u8bfe\uff1ahttps://www.bilibili.com/video/BV1LY411H7Gg\u3002\u5728 C++ \u5c0f\u5999\u62db \u4e00\u7ae0\u4e2d\u4e5f\u6709\u4ecb\u7ecd\u3002 \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u53ef\u4ee5\u7528\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\u5c31\u5730\u6784\u9020\u4e00\u4e2a map \u5bf9\u8c61\uff1a void myfunc(map config); // \u51fd\u6570\u58f0\u660e myfunc(map{ // \u76f4\u63a5\u521b\u5efa\u4e00\u4e2a map \u4f20\u5165 {\"timeout\", 985}, {\"delay\", 211}, }); \u7531\u4e8e myfunc \u51fd\u6570\u5177\u6709\u552f\u4e00\u786e\u5b9a\u7684\u91cd\u8f7d\uff0c\u8981\u6784\u9020\u7684\u53c2\u6570\u7c7b\u578b map \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a myfunc({ {\"timeout\", 985}, {\"delay\", 211}, }); \u51fd\u6570\u8fd9\u8fb9\uff0c\u901a\u5e38\u8fd8\u4f1a\u52a0\u4e0a const & \u4fee\u9970\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d\u3002 void myfunc(map const &config); \u4ece vector \u4e2d\u6279\u91cf\u5bfc\u5165\u952e\u503c\u5bf9\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs.begin(), kvs.end()); \u4e0e\u521a\u521a\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u7684\u5199\u6cd5\u7b49\u4ef7\uff0c\u53ea\u4e0d\u8fc7\u662f\u4ece\u73b0\u6709\u7684 vector \u4e2d\u5bfc\u5165\u3002\u540c\u6837\u7684\u5199\u6cd5\u4e5f\u9002\u7528\u4e8e\u4ece array \u5bfc\u5165\u3002 \u5982\u679c\u8bb0\u4e0d\u4f4f\u8fd9\u4e2a\u5199\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5df1\u624b\u5199 for \u5faa\u73af\u904d\u5386 vector \u9010\u4e2a\u9010\u4e2a\u63d2\u5165 map\uff0c\u6548\u679c\u662f\u4e00\u6837\u7684\u3002 \u51b7\u77e5\u8bc6\uff0c\u5982\u679c\u4e0d\u662f vector \u6216 array\uff0c\u800c\u662f\u60f3\u4ece\u4f20\u7edf\u7684 C \u8bed\u8a00\u6570\u7ec4\u4e2d\u5bfc\u5165\uff1a pair kvs[] = { // C \u8bed\u8a00\u539f\u59cb\u6570\u7ec4 {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs, kvs + 2); // C++98 map config(std::begin(kvs), std::end(kvs)); // C++17 \u5176\u4e2d std::begin \u548c std::end \u4e3a C++17 \u65b0\u589e\u51fd\u6570\uff0c\u4e13\u95e8\u7528\u4e8e\u7167\u987e\u6ca1\u6cd5\u6709\u6210\u5458\u51fd\u6570 .begin() \u7684 C \u8bed\u8a00\u6570\u7ec4\u3002\u7c7b\u4f3c\u7684\u5168\u5c40\u51fd\u6570\u8fd8\u6709 std::size \u548c std::data \u7b49\u2026\u2026\u4ed6\u4eec\u90fd\u662f\u65e2\u517c\u5bb9 STL \u5bb9\u5668\u4e5f\u517c\u5bb9 C \u6570\u7ec4\u7684\u3002 \u91cd\u70b9\u6765\u4e86\uff1a\u5982\u4f55\u6839\u636e\u952e\u67e5\u8be2\u76f8\u5e94\u7684\u503c\uff1f \u5f88\u591a\u540c\u5b66\u90fd\u77e5\u9053 map \u5177\u6709 [] \u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c[] \u91cc\u5199\u8981\u67e5\u8be2\u7684\u952e\u5c31\u53ef\u4ee5\u8fd4\u56de\u5bf9\u5e94\u503c\uff0c\u4e5f\u53ef\u4ee5\u7528 = \u5f80\u91cc\u9762\u8d4b\u503c\uff0c\u548c\u67d0\u4e9b\u811a\u672c\u8bed\u8a00\u4e00\u6837\u76f4\u89c2\u6613\u61c2\u3002 config[\"timeout\"] = 985; // \u628a config \u4e2d\u952e timeout \u5bf9\u5e94\u503c\u8bbe\u4e3a 985 auto val = config[\"timeout\"]; // \u8bfb\u53d6 config \u4e2d\u952e timeout \u5bf9\u5e94\u503c print(val); // 985 \u4f46\u5176\u5b9e\u7528 [] \u53bb \u8bfb\u53d6\u5143\u7d20 \u662f\u5f88\u4e0d\u5b89\u5168\u7684\uff0c\u4e0b\u9762\u6211\u4f1a\u505a\u5b9e\u9a8c\u6f14\u793a\u8fd9\u4e00\u70b9\u3002 \u6c89\u9ed8\u7684 []\uff0c\u65e0\u8a00\u7684\u5371\u9669\uff1a\u5f53\u952e\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8fd4\u56de 0 \u800c\u4e0d\u4f1a\u51fa\u9519\uff01 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // 985 print(config[\"tmeout\"]); // \u9ed8\u9ed8\u8fd4\u56de 0 985 0 \u5f53\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c[] \u4f1a\u9ed8\u9ed8\u521b\u5efa\u5e76\u8fd4\u56de 0\uff0c\u800c\u4e0d\u4f1a\u7206\u51fa\u4efb\u4f55\u9519\u8bef\u3002 \u8fd9\u975e\u5e38\u5371\u9669\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b80\u7b80\u5355\u5355\u7684\u62fc\u5199\u9519\u8bef\uff0c\u5c31\u4f1a\u5bfc\u81f4 map \u7684\u67e5\u8be2\u9ed8\u9ed8\u8fd4\u56de 0\uff0c\u4f60\u8fd8\u5728\u90a3\u91cc\u627e\u4e86\u534a\u5929\u6478\u4e0d\u7740\u5934\u8111\uff0c\u6839\u672c\u6ca1\u53d1\u73b0\u9519\u8bef\u539f\u6765\u5728 map \u8fd9\u91cc\u3002 \u7231\u54ed\u7231\u95f9\u7684 at()\uff0c\u53cd\u800c\u66f4\u8ba8\u4eba\u559c\u6b22 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 print(config.at(\"tmeout\")); // \u8be5\u952e\u4e0d\u5b58\u5728\uff01\u54cd\u4eae\u5730\u51fa\u9519 985 terminate called after throwing an instance of 'std::out_of_range' what(): map::at Aborted (core dumped) \u6709\u7ecf\u9a8c\u7684\u8001\u624b\u90fd\u660e\u767d\u4e00\u4e2a\u9053\u7406\uff1a \u53ca\u65f6\u5954\u6e83 \u6bd4 \u5bb9\u5fcd\u9519\u8bef \u66f4\u6709\u5229\u4e8e\u8c03\u8bd5\u3002\u5373 fail-early, fail-loudly 1 \u539f\u5219\u3002 \u4f8b\u5982 JS \u548c Lua \u7684 [] \u8bbf\u95ee\u8d8a\u754c\u4e0d\u62a5\u9519\u800c\u662f\u8fd4\u56de undefined / nil\uff0c\u5bfc\u81f4\u5b9e\u9645\u51fa\u9519\u7684\u4f4d\u7f6e\u5728\u597d\u51e0\u5341\u884c\u4e4b\u540e\uff0c\u65e0\u6cd5\u5b9a\u4f4d\u5230\u771f\u6b63\u51fa\u9519\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u540e\u6765\u53d1\u660e\u4e86\u9519\u8bef\u68c0\u67e5\u66f4\u4e25\u683c\u7684 TS\u3002 \u4f7f\u7528 at() \u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230\u9519\u8bef\uff0c\u662f\u597d\u4e8b\u3002 \u5728\u5b98\u65b9\u6587\u6863\u548c\u5404\u79cd\u6559\u5b66\u8bfe\u4ef6\u4e2d\uff0c\u90fd\u4f1a\u5c55\u793a\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u539f\u578b\u201d\u6765\u8bb2\u89e3\u3002 \u539f\u578b\u5c55\u73b0\u4e86\u4e00\u4e2a\u51fd\u6570\u7684\u540d\u79f0\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u8fd4\u56de\u7c7b\u578b\u7b49\u4fe1\u606f\uff0c\u638c\u63e1\u4e86\u51fd\u6570\u7684\u539f\u578b\u5c31\u7b49\u4e8e\u638c\u63e1\u4e86\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u3002 \u672c\u8bfe\u7a0b\u540e\u9762\u4e5f\u4f1a\u5927\u91cf\u4f7f\u7528\uff0c\u73b0\u5728\u6765\u6559\u4f60\u5982\u4f55\u770b\u61c2\u6210\u5458\u51fd\u6570\u7684\u539f\u578b\u3002 \u5047\u8bbe\u8981\u7814\u7a76\u7684\u7c7b\u578b\u4e3a map \uff0c\u5176\u4e2d K \u548c V \u662f\u6a21\u677f\u53c2\u6570\uff0c\u53ef\u4ee5\u66ff\u6362\u6210\u4f60\u5177\u4f53\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u5f53\u6211\u4f7f\u7528 map \u65f6\uff0c\u5c31\u628a\u4e0b\u9762\u6240\u6709\u7684 K \u66ff\u6362\u6210 string\uff0cV \u66ff\u6362\u6210 int\u3002 map \u7684 [] \u548c at \u5458\u51fd\u6570\uff0c\u539f\u578b\u5982\u4e0b\uff1a V &operator[](K const &k); V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u53ef\u89c1 operator[] \u53ea\u6709\u4e00\u4e2a\u7248\u672c\uff0cat \u5c45\u7136\u6709\u540d\u5b57\u76f8\u540c\u7684\u4e24\u4e2a\uff01\u8fd9\u6837\u4e0d\u4f1a\u53d1\u751f\u51b2\u7a81\u5417\uff1f \u8fd9\u662f\u5229\u7528\u4e86 C++ \u7684\u201c\u91cd\u8f7d\u201d\u529f\u80fd\uff0c\u91cd\u8f7d\u5c31\u662f\u540c\u4e00\u4e2a\u51fd\u6570\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u7248\u672c\uff0c\u5404\u4e2a\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u6253\u7535\u8bdd\u7ed9 110\uff0c\u5047\u5982\u8b66\u5bdf\u53d4\u53d4\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u62a5\u7684\u6848\u5b50\u662f\u7f51\u7edc\u8bc8\u9a97\uff0c\u90a3\u4e48\u4ed6\u4eec\u4f1a\u5e2e\u6211\u8f6c\u63a5\u5230\u7f51\u8b66\u90e8\u95e8\uff1b\u5047\u5982\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u662f\u88ab\u7ed1\u67b6\u4e86\uff0c\u90a3\u4e48\u4ed6\u4eec\u53ef\u80fd\u4f1a\u51fa\u52a8\u6b66\u8b66\u89e3\u6551\u5c0f\u5f6d\u8001\u5e08\u3002\u8fd9\u5c31\u662f 110 \u51fd\u6570\u7684\u4e24\u4e2a\u91cd\u8f7d\uff0c\u6839\u636e\u8c03\u7528\u8005\u4f20\u5165\u7684\u4fe1\u606f\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8f6c\u7ed9\u54ea\u4e00\u4e2a\u5b50\u90e8\u95e8\u3002 \u540c\u7406\uff0c\u7f16\u8bd1\u5668\u4e5f\u662f\u4f1a\u6839\u636e\u8c03\u7528\u65f6\u4f60\u4f20\u5165\u7684\u53c2\u6570\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8c03\u7528\u91cd\u8f7d\u7684\u54ea\u4e00\u4e2a\u5177\u4f53\u7248\u672c\u3002 C \u8bed\u8a00\u6ca1\u6709\u91cd\u8f7d\uff0c\u51fd\u6570\u540d\u5b57\u76f8\u540c\u5c31\u4f1a\u53d1\u751f\u51b2\u7a81\uff0c\u7f16\u8bd1\u5668\u4f1a\u5f53\u573a\u62a5\u9519\u3002 C++ \u652f\u6301\u91cd\u8f7d\uff0c\u53ea\u6709\u5f53\u51fd\u6570\u540d\u5b57\u76f8\u540c\uff0c\u53c2\u6570\u5217\u8868\u4e5f\u76f8\u540c\u65f6\uff0c\u624d\u4f1a\u53d1\u751f\u51b2\u7a81\u3002 \u8fd4\u56de\u503c\u7c7b\u578b\u4e0d\u5f71\u54cd\u91cd\u8f7d\uff0c\u91cd\u8f7d\u53ea\u770b\u53c2\u6570\u5217\u8868\u3002 \u83dc\u9e1f\u6559\u7a0b\u4e0a\u5bf9 C++ \u91cd\u8f7d\u7684\u89e3\u91ca 1 \uff1a C++ \u5141\u8bb8\u5728\u540c\u4e00\u4f5c\u7528\u57df\u4e2d\u7684\u67d0\u4e2a\u51fd\u6570\u548c\u8fd0\u7b97\u7b26\u6307\u5b9a\u591a\u4e2a\u5b9a\u4e49\uff0c\u5206\u522b\u79f0\u4e3a\u51fd\u6570\u91cd\u8f7d\u548c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u91cd\u8f7d\u58f0\u660e\u662f\u6307\u4e00\u4e2a\u4e0e\u4e4b\u524d\u5df2\u7ecf\u5728\u8be5\u4f5c\u7528\u57df\u5185\u58f0\u660e\u8fc7\u7684\u51fd\u6570\u6216\u65b9\u6cd5\u5177\u6709\u76f8\u540c\u540d\u79f0\u7684\u58f0\u660e\uff0c\u4f46\u662f\u5b83\u4eec\u7684\u53c2\u6570\u5217\u8868\u548c\u5b9a\u4e49\uff08\u5b9e\u73b0\uff09\u4e0d\u76f8\u540c\u3002 \u5f53\u60a8\u8c03\u7528\u4e00\u4e2a\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u65f6\uff0c\u7f16\u8bd1\u5668\u901a\u8fc7\u628a\u60a8\u6240\u4f7f\u7528\u7684\u53c2\u6570\u7c7b\u578b\u4e0e\u5b9a\u4e49\u4e2d\u7684\u53c2\u6570\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\uff0c\u51b3\u5b9a\u9009\u7528\u6700\u5408\u9002\u7684\u5b9a\u4e49\u3002\u9009\u62e9\u6700\u5408\u9002\u7684\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u7684\u8fc7\u7a0b\uff0c\u79f0\u4e3a\u91cd\u8f7d\u51b3\u7b56\u3002 \u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\uff0c\u53ef\u4ee5\u58f0\u660e\u51e0\u4e2a\u529f\u80fd\u7c7b\u4f3c\u7684\u540c\u540d\u51fd\u6570\uff0c\u4f46\u662f\u8fd9\u4e9b\u540c\u540d\u51fd\u6570\u7684\u5f62\u5f0f\u53c2\u6570\uff08\u6307\u53c2\u6570\u7684\u4e2a\u6570\u3001\u7c7b\u578b\u6216\u8005\u987a\u5e8f\uff09\u5fc5\u987b\u4e0d\u540c\u3002\u60a8\u4e0d\u80fd\u4ec5\u901a\u8fc7\u8fd4\u56de\u7c7b\u578b\u7684\u4e0d\u540c\u6765\u91cd\u8f7d\u51fd\u6570\u3002 V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u4f46\u662f\u4e0a\u9762\u8fd9\u4e24\u4e2a at \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u90fd\u662f K const & \uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u91cd\u8f7d\u5462\uff1f \u6ce8\u610f\u770b\u7b2c\u4e8c\u4e2a\u7248\u672c\u6700\u540e\u9762\u591a\u4e86\u4e00\u4e2a const \u5173\u952e\u5b57\uff0c\u8fd9\u79cd\u5199\u6cd5\u662f\u4ec0\u4e48\u610f\u601d\uff1f\u5c0f\u5f6d\u8001\u5e08\u5bf9\u5176\u8fdb\u884c\u795b\u9b45\u5316\uff1a V &at(map *this, K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(map const *this, K const &k); // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u539f\u6765\u52a0\u5728\u51fd\u6570\u62ec\u53f7\u540e\u9762\u7684 const\uff0c\u5b9e\u9645\u4e0a\u662f\u7528\u4e8e\u4fee\u9970 this \u6307\u9488\u7684\uff01 \u8be5\u5199\u6cd5\u4ec5\u4f9b\u793a\u610f\uff0c\u5e76\u4e0d\u662f\u771f\u7684\u53ef\u4ee5\u628a this \u5199\u6210\u53c2\u6570 \u6240\u4ee5\u4e24\u4e2a at \u7684\u53c2\u6570\u5217\u8868\u4e0d\u540c\uff0c\u4e0d\u540c\u5728\u4e8e\u4f20\u5165 this \u6307\u9488\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u53ef\u4ee5\u91cd\u8f7d\uff0c\u4e0d\u4f1a\u51b2\u7a81\u3002 \u5f53 map \u5bf9\u8c61\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map const * \uff0c\u6240\u4ee5\u53ea\u80fd\u8c03\u7528\u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at\u3002 \u5f53 map \u5bf9\u8c61\u4e0d\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map * \uff0c\u4e24\u4e2a\u91cd\u8f7d\u90fd\u53ef\u4ee5\u8c03\u7528\uff0c\u4f46\u7531\u4e8e\u7b2c\u4e00\u4e2a\u91cd\u8f7d\u66f4\u52a0\u7b26\u5408\uff0c\u6240\u4ee5\u4f1a\u8c03\u7528\u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at\u3002 \u6709\u8da3\u7684\u662f\uff0cC++23 \u652f\u6301\u4e86\u663e\u5f0f\u5bf9\u8c61\u5f62\u53c2\uff08deducing-this\uff09\uff0cthis \u4e5f\u80fd\u50cf\u666e\u901a\u53c2\u6570\u4e00\u6837\u5b9a\u4e49\u4e86\uff01\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u6210\uff1a class map { ... V &at(this map &self, K const &k) { // \u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u4f7f\u7528self\u4ee3\u66ff\u539f\u6765\u7684this\uff08this\u5c06\u4e0d\u518d\u53ef\u7528\uff09 ... } V const &at(this map const &self, K const &k) { ... } }; \u521a\u521a\u89e3\u91ca\u4e86\u51fd\u6570\u91cd\u8f7d\uff0c\u90a3\u4e48\u8fd0\u7b97\u7b26\u91cd\u8f7d\u5462\uff1f \u56e0\u4e3a\u539f\u672c C \u8bed\u8a00\u5c31\u6709 [] \u8fd0\u7b97\u7b26\uff0c\u4e0d\u8fc7\u90a3\u53ea\u9002\u7528\u4e8e\u539f\u59cb\u6307\u9488\u548c\u539f\u59cb\u6570\u7ec4\u3002\u800c C++ \u5141\u8bb8\u4e5f [] \u8fd0\u7b97\u7b26\u652f\u6301\u5176\u4ed6\u7528\u6237\u81ea\u5b9a\u4e49\u7c7b\u578b\uff08\u6bd4\u5982 std::map\uff09\uff0c\u548c C \u8bed\u8a00\u81ea\u5e26\u7684\u76f8\u6bd4\u5c31\u53ea\u6709\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\uff08\u4e00\u4e2a\u662f\u539f\u59cb\u6570\u7ec4\uff0c\u4e00\u4e2a\u662f std::map\uff09\uff0c\u6240\u4ee5\u548c\u51fd\u6570\u91cd\u8f7d\u5f88\u76f8\u4f3c\uff0c\u8fd9\u5c31\u662f\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 m[\"key\"]; \u4f1a\u88ab\u7f16\u8bd1\u5668\u201c\u7ffb\u8bd1\u201d\u6210\uff1a m.operator[](\"key\"); \u4ee5\u4e0a\u4ee3\u7801\u5e76\u975e\u4ec5\u4f9b\u793a\u610f\uff0c\u662f\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u8fd0\u884c\u7684\u3002 operator[] \u867d\u7136\u770b\u8d77\u6765\u5f88\u590d\u6742\u4e00\u4e2a\u5173\u952e\u5b57\u52a0\u7279\u6b8a\u7b26\u53f7\uff0c\u5176\u5b9e\u65e0\u975e\u5c31\u662f\u4e2a\u7279\u6b8a\u7684\u51fd\u6570\u540d\uff0c\u5b66\u8fc7 Python \u7684\u7ae5\u978b\u53ef\u4ee5\u628a\u4ed6\u60f3\u8c61\u6210 __getitem__ \u3002 V &operator[](K const &k); \u7ed3\u8bba\uff1a[] \u8fd0\u7b97\u7b26\u5b9e\u9645\u4e0a\u662f\u5728\u8c03\u7528 operator[] \u51fd\u6570\u3002 \u6240\u6709\u7684\u6240\u8c13\u201c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u51fd\u6570\u201d\u5b9e\u9645\u4e0a\u90fd\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6807\u8bc6\u7b26\uff0c\u4ee5 operator + \u8fd0\u7b97\u7b26\u7684\u5f62\u5f0f\uff0c\u4ed6\u4eec\u4e24\u4e2a\u7ec4\u6210\u4e00\u4e2a\u6574\u4f53\uff0c\u4f60\u8fd8\u53ef\u4ee5\u8bd5\u8bd5 string(\"hel\").operator+(\"lo\") \uff0c\u548c string(\"hel\") + \"lo\" \u662f\u7b49\u4ef7\u7684\u3002 \u56e0\u4e3a operator[] \u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u540e\u9762\u6ca1\u6709 const \u4fee\u9970\uff0c\u56e0\u6b64\u5f53 map \u4fee\u9970\u4e3a const \u65f6\u7f16\u8bd1\u4f1a\u4e0d\u901a\u8fc7 1 \uff1a const map config = { // \u6b64\u5904\u5982\u679c\u662f\u5e26 const & \u4fee\u9970\u7684\u51fd\u6570\u53c2\u6570\u4e5f\u662f\u540c\u7406 {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // \u7f16\u8bd1\u51fa\u9519 /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp: In function \u2018int main()\u2019: /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp:10:23: error: passing \u2018const std::map, int>\u2019 as \u2018this\u2019 argument discards qualifiers [-fpermissive] 10 | print(config[\"timeout\"]); \u7f16\u8bd1\u5668\u8bf4 discards qualifiers\uff0c\u610f\u601d\u662f map \u6709 const \u4fee\u9970\uff0c\u4f46\u662f operator[] \u6ca1\u6709\u3002 \u8fd9\u5b9e\u9645\u4e0a\u5c31\u662f\u5728\u8bf4\uff1a map const *this \u4e0d\u80fd\u8f6c\u6362\u6210 map *this \u3002 \u6709 const \u4fee\u9970\u7684 map \u4f5c\u4e3a this \u6307\u9488\u4f20\u5165\u6ca1 const \u4fee\u9970\u7684 operator[] \u51fd\u6570\uff0c\u662f\u51cf\u5c11\u4e86\u4fee\u9970\uff08discards qualifers\uff09\u3002 C++ \u89c4\u5b9a\u4f20\u53c2\u65f6\u53ea\u80fd\u589e\u52a0\u4fee\u9970\u4e0d\u80fd\u51cf\u5c11\u4fee\u9970\uff1a\u53ea\u80fd\u4ece map * \u8f6c\u6362\u5230 map const * \u800c\u4e0d\u80fd\u53cd\u4e4b\u3002 \u6240\u4ee5\u5bf9\u7740\u4e00\u4e2a const map \u8c03\u7528\u975e const \u7684\u6210\u5458\u51fd\u6570 operator[] \u5c31\u51fa\u9519\u4e86\uff0c\u76f8\u6bd4\u4e4b\u4e0b at() \u5c31\u53ef\u4ee5\u5728 const \u4fee\u9970\u4e0b\u7f16\u8bd1\u901a\u8fc7\u3002 \u4e3a\u4ec0\u4e48 operator[] \u662f\u975e const \u4fee\u9970\u7684\u5462\uff1f\u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u4e0d\u662f const\uff0c\u610f\u5473\u7740\u4ed6\u4f1a \u5c31\u5730\u4fee\u6539 this \u5bf9\u8c61 \u3002 \u5176\u5b9e\uff0coperator[] \u53d1\u73b0\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config); print(config[\"tmeout\"]); // \u6709\u526f\u4f5c\u7528\uff01 print(config); {\"delay\": 211, \"timeout\": 985} 0 {\"delay\": 211, \"timeout\": 985, \"tmeout\": 0} \u4f1a\u81ea\u52a8\u521b\u5efa\u90a3\u4e2a\u4e0d\u5b58\u5728\u7684\u952e\u503c\uff01 \u4f60\u4ee5\u4e3a\u4f60\u53ea\u662f\u89c2\u5bdf\u4e86\u4e00\u4e0b map \u91cc\u7684 \u201ctmeout\u201d \u5143\u7d20\uff0c\u5374\u610f\u5916\u6539\u53d8\u4e86 map \u7684\u5185\u5bb9\uff0c\u859b\u5b9a\u8c14\u76f4\u547c\u5185\u884c\u3002 \u4e3a\u4ec0\u4e48\u628a [] \u8bbe\u8ba1\u7684\u8fd9\u4e48\u5371\u9669\uff1f \u65e2\u7136\u5df2\u7ecf\u6709\u66f4\u5b89\u5168\u7684 .at()\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u8ba9 [] \u7ee7\u7eed\u5b58\u5728\u5462\uff1f map config = { {\"delay\", 211}, }; config.at(\"timeout\") = 985; // \u952e\u503c\u4e0d\u5b58\u5728\uff0c\u62a5\u9519\uff01 config[\"timeout\"] = 985; // \u6210\u529f\u521b\u5efa\u5e76\u5199\u5165 985 \u7531\u4e0a\u53ef\u89c1\uff0c\u5f53\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u672c\u4e0d\u5b58\u5728\u7684\u952e\u503c\u7684\u65f6\u5019\uff0c\u6070\u6070\u9700\u8981 [] \u7684\u201c\u81ea\u52a8\u521b\u5efa\u201d\u8fd9\u4e00\u7279\u6027\uff0c\u8fd9\u662f at() \u6240\u4e0d\u5177\u6709\u7684\u3002 \u603b\u7ed3\uff1a\u8bfb\u53d6\u65f6\u5e94\u8be5\u7528 at() \u66f4\u5b89\u5168\uff0c\u5199\u5165\u65f6\u624d\u9700\u8981\u7528\u5e26\u6709\u81ea\u52a8\u521b\u5efa\u529f\u80fd\u7684 []\u3002 \u8bb8\u591a\u7b2c\u4e09\u65b9\u5e93\uff0c\u4f8b\u5982 jsoncpp\uff0c\u4ed6\u4eec\u7684\u5b57\u5178\u7c7b\u578b\u4e5f\u4f7f\u7528\u7c7b\u4f3c\u7684\u63a5\u53e3\uff0cat() \u8d1f\u8d23\u8bfb\uff0c[] \u8d1f\u8d23\u5199\uff0c\u5206\u5de5\u660e\u786e\uff01 \u603b\u7ed3 \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 at() \u5199\u5165\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 [] auto val = m.at(\"key\"); m[\"key\"] = val; \u4e3a\u4ec0\u4e48\u5176\u4ed6\u8bed\u8a00\u6bd4\u5982 Python\uff0c\u53ea\u6709\u4e00\u4e2a [] \u5c31\u884c\u4e86\u5462\uff1f\u800c C++ \u9700\u8981\u4e24\u4e2a\uff1f \u56e0\u4e3a Python \u4f1a\u68c0\u6d4b [] \u4f4d\u4e8e\u7b49\u53f7\u5de6\u4fa7\u8fd8\u662f\u53f3\u4fa7\uff0c\u6839\u636e\u60c5\u51b5\u5206\u522b\u8c03\u7528 __getitem__ \u6216\u8005 __setitem__ \u3002 C++ \u7f16\u8bd1\u5668\u6ca1\u6709\u8fd9\u4e2a\u7279\u6b8a\u68c0\u6d4b\uff0c\u4e5f\u68c0\u6d4b\u4e0d\u4e86\uff0c\u56e0\u4e3a C++ \u7684 [] \u53ea\u662f\u8fd4\u56de\u4e86\u4e2a\u5f15\u7528\uff0c\u5e76\u4e0d\u77e5\u9053 [] \u51fd\u6570\u8fd4\u56de\u4ee5\u540e\uff0c\u4f60\u662f\u62ff\u8fd9\u4e2a\u5f15\u7528\u5199\u5165\u8fd8\u662f\u8bfb\u53d6\u3002\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\u4ed6\u9ed8\u8ba4\u4f60\u662f\u5199\u5165\uff0c\u6240\u4ee5\u5148\u5e2e\u4f60\u521b\u5efa\u4e86\u5143\u7d20\uff0c\u8fd4\u56de\u8fd9\u4e2a\u5143\u7d20\u7684\u5f15\u7528\uff0c\u8ba9\u4f60\u5199\u5165\u3002 \u800c Python \u7684\u5f15\u7528\u662f\u4e0d\u80fd\u7528 = \u8986\u76d6\u539f\u503c\u7684\uff0c\u90a3\u6837\u53ea\u4f1a\u8ba9\u53d8\u91cf\u6307\u5411\u65b0\u7684\u5f15\u7528\uff0c\u53ea\u80fd\u7528 .func() \u5f15\u7528\u6210\u5458\u51fd\u6570\u6216\u8005 += \u624d\u80fd\u5c31\u5730\u4fee\u6539\u539f\u53d8\u91cf\uff0c\u8fd9\u662f Python \u8fd9\u7c7b\u811a\u672c\u8bed\u8a00\u548c C++ \u6700\u672c\u8d28\u7684\u4e0d\u540c\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7528 C++ \u7684 map \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u9700\u8981\u663e\u5f0f\u5730\u7528 at() \u544a\u8bc9\u7f16\u8bd1\u5668\u6211\u662f\u6253\u7b97\u8bfb\u53d6\u3002 [] \u627e\u4e0d\u5230\u5c31\u8fd4\u56de\u4e2a\u201c\u9ed8\u8ba4\u503c\u201d\uff0c\u5176\u5b9e\u4e5f\u662f\u5f88\u591a\u8bed\u8a00\u7684\u4f20\u7edf\u5f02\u80fd\u4e86\uff0c\u53ea\u6709\u521a\u597d Python \u6bd4\u8f83\u5bf9\u521d\u5b66\u8005\u53cb\u597d\uff0c\u4f1a\u81ea\u52a8\u5224\u65ad\u4f60\u7684 [] \u662f\u8bfb\u53d6\u8fd8\u662f\u5199\u5165\uff0c\u5982\u679c\u662f\u8bfb\u53d6\uff0c\u5f53\u627e\u4e0d\u5230\u952e\u503c\u65f6\u80fd\u53cb\u5584\u7684\u7ed9\u4f60\u62a5\u9519\u3002 \u8bed\u8a00\u53ca\u5176\u5173\u8054\u5bb9\u5668\u540d C++ map Python dict Lua table JS HashMap Java HashMap \u627e\u4e0d\u5230\u952e\u65f6\u7684\u884c\u4e3a \u9ed8\u9ed8\u8fd4\u56de 0 \u62a5\u9519 KeyError \u9ed8\u9ed8\u8fd4\u56de nil \u9ed8\u9ed8\u8fd4\u56de undefined .get()\uff0c\u9ed8\u9ed8\u8fd4\u56de null \u5176\u4e2d C++ \u7684 [] \u6700\u4e3a\u6076\u52a3\uff0c\u56e0\u4e3a\u53e4\u4ee3 C++ \u4e2d\u5e76\u6ca1\u6709\u4e00\u4e2a null \u6216 nil \u4e4b\u7c7b\u7684\u989d\u5916\u7279\u6b8a\u5e38\u91cf\u3002 [] \u8fd4\u56de\u7684\u5fc5\u987b\u662f\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u7531\u4e8e [] \u4e0d\u80fd\u62a5\u9519\uff0c\u503c\u7684\u7c7b\u578b\u53c8\u5343\u53d8\u4e07\u5316\uff0c map \u7684 [] \u53ea\u80fd\u8fd4\u56de\u201cV \u7c7b\u578b\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u7684\u503c\u201d\uff1a\u5bf9\u4e8e int \u800c\u8a00\u662f 0\uff0c\u5bf9\u4e8e string \u800c\u8a00\u662f \u201c\u201d\uff08\u7a7a\u5b57\u7b26\u4e32\uff09\u3002 \u4e5f\u6b63\u56e0\u5982\u6b64\uff0c\u5982\u679c\u4e00\u4e2a map \u4e2d\u7684 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5c31\u65e0\u6cd5\u4f7f\u7528 [] \u4e86\u3002\u770b\u4f3c\u7f8e\u597d\u7684 [] \u53ea\u662f\u9a97\u9a97\u5c0f\u5f6d\u53cb\u7684\u9762\u5b50\u5de5\u7a0b\uff0c\u6a21\u68f1\u4e24\u53ef\uff0c\u5145\u6ee1\u5371\u9669\u3002\u9ad8\u624b\u90fd\u4f7f\u7528\u66f4\u4e13\u4e1a\u7684\u5199\u5165\u51fd\u6570\uff1ainsert \u6216 insert_or_assign \u4ee3\u66ff\u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\u4e0d\u9700\u8981\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u66f4\u9ad8\u6548\u4e00\u4e9b\uff0c\u7a0d\u540e\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u3002 at \u4e0e [] \u5b9e\u6218\u6f14\u7ec3 \u6211\u4eec\u73b0\u5728\u7684\u7532\u65b9\u662f\u4e00\u4e2a\u5b66\u6821\u7684\u5927\u8001\u677f\uff0c\u4ed6\u5e0c\u671b\u8ba9\u6211\u4eec\u7ba1\u7406\u5b66\u751f\u4fe1\u606f\uff0c\u56e0\u6b64\u9700\u8981\u5efa\u7acb\u4e00\u4e2a\u6620\u5c04\u8868\uff0c\u80fd\u591f\u5feb\u901f\u901a\u8fc7\u5b66\u751f\u540d\u5b57\u67e5\u8be2\u5230\u76f8\u5e94\u7684\u5b66\u751f\u4fe1\u606f\u3002\u601d\u6765\u60f3\u53bb C++ \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668\u6700\u5408\u9002\u3002\u51b3\u5b9a\u8bbe\u8ba1\u5982\u4e0b\uff1a \u952e\u4e3a\u5b66\u751f\u7684\u540d\u5b57\uff0cstring \u7c7b\u578b\u3002 \u503c\u4e3a\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7ed3\u6784\u4f53\uff0cStudent \u7c7b\u578b\uff0c\u91cc\u9762\u5b58\u653e\u5404\u79cd\u5b66\u751f\u4fe1\u606f\u3002 \u7136\u540e\u81ea\u5b9a\u4e49\u4e00\u4e0b Student \u7ed3\u6784\u4f53\uff0c\u73b0\u5728\u628a\u9664\u4e86\u540d\u5b57\u4ee5\u5916\u7684\u5b66\u751f\u4fe1\u606f\u90fd\u585e\u5230\u8fd9\u4e2a\u7ed3\u6784\u4f53\u91cc\u3002 \u521b\u5efa map \u5bf9\u8c61\uff0c\u53d8\u91cf\u540d\u4e3a stus \uff0c\u8fd9\u4e2a map \u5c31\u662f\u7532\u65b9\u8981\u6c42\u7684\u5b66\u751f\u8868\uff0c\u6210\u529f\u4ea4\u5dee\u3002 struct Student { int id; // \u5b66\u53f7 int age; // \u5e74\u9f84 string sex; // \u6027\u522b int money; // \u5b58\u6b3e set skills; // \u6280\u80fd }; map stus; \u73b0\u5728\u5c0f\u5f6d\u8001\u5e08\u548c\u4ed6\u7684\u7ae5\u978b\u4eec\u8981\u8fdb\u5165\u8fd9\u5bb6\u5b66\u6821\u4e86\uff0c\u8ba9\u6211\u4eec\u7528 [] \u5927\u6cd5\u63d2\u5165\u4ed6\u7684\u4e2a\u4eba\u4fe1\u606f\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = Student{20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = Student{20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = Student{20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = Student{20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u7531\u4e8e C++11 \u5141\u8bb8\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b\u4e0d\u5199\uff0c\u6240\u4ee5 Student \u53ef\u4ee5\u7701\u7565\uff0c\u7b80\u5199\u6210\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = {20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = {20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u53c8\u7531\u4e8e map \u652f\u6301\u5728\u521d\u59cb\u5316\u65f6\u5c31\u6307\u5b9a\u6240\u6709\u5143\u7d20\uff0c\u6211\u4eec\u76f4\u63a5\u5199\uff1a map stus = { {\"\u5f6d\u4e8e\u658c\", {20220301, 22, \"\u81ea\u5b9a\u4e49\", 1000, {\"C\", \"C++\"}}}, {\"\u76f8\u4f9d\", {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}}, {\"\u6a31\u82b1\u7c89\u871c\u7cd6\", {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}}, {\"Sputnik02\", {20220301, 19, \"\u7537\", 4000, {\"C++\"}}}, }; \u73b0\u5728\u7532\u65b9\u8981\u6c42\u6dfb\u52a0\u4e00\u4e2a\u201c\u57f9\u8bad\u201d\u51fd\u6570\uff0c\u7528\u4e8e\u4ed6\u4eec\u7684 C++ \u57f9\u8bad\u8bfe\u3002 \u57f9\u8bad\u51fd\u6570\u7684\u53c2\u6570\u4e3a\u5b57\u7b26\u4e32\uff0c\u8868\u793a\u8981\u6d88\u8d39\u5b66\u751f\u7684\u540d\u5b57\u3002\u5982\u679c\u8be5\u540d\u5b57\u5b66\u751f\u4e0d\u5b58\u5728\uff0c\u5219\u5e94\u8be5\u53ca\u65f6\u62a5\u9519\u3002 \u6bcf\u6b21\u57f9\u8bad\u9700\u8981\u6d88\u8d39 2650 \u5143\uff0c\u6d88\u8d39\u6210\u529f\u540e\uff0c\u5f80\u6280\u80fd skills \u96c6\u5408\u4e2d\u52a0\u5165 \u201cC++\u201d\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u8fd9\u662f\u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 stu.money -= 2650; stu.skills.insert(\"C++\"); } \u7136\u800c\uff0c\u8fd9\u6837\u5199\u662f\u4e0d\u5bf9\u7684\uff01 stus.at(stuName) \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528 Student & \u6307\u5411 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u4f46\u662f\u7b49\u53f7\u5de6\u4fa7\uff0c\u5374\u662f\u4e2a\u4e0d\u5e26\u4efb\u4f55\u4fee\u9970\u7684 auto \uff0c\u4ed6\u4f1a\u88ab\u63a8\u5bfc\u4e3a Student \u3002\u5982\u4f55\u4ece\u4e00\u4e2a\u5f15\u7528 Student & \u8f6c\u6362\u4e3a\u5177\u4f53\u7684 Student \uff1f\u627e\u4e0d\u5230 Student(Student &) \uff0c\u4f46\u662f\u627e\u5230\u4e86\u6700\u63a5\u8fd1\u7684 Student(Student const &) \u51fd\u6570\uff08\u8fd9\u662f\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff09\uff0c\u56e0\u6b64\u6211\u4eec\u62f7\u8d1d\u4e86\u4e00\u4efd map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\uff0c\u5230\u6808\u4e0a\u7684 stu \u53d8\u91cf\uff0c\u4e4b\u540e\u4e0d\u8bba\u5982\u4f55\u4fee\u6539\uff0c\u4fee\u6539\u7684\u90fd\u662f\u8fd9\u4e2a\u6808\u4e0a\u5bf9\u8c61\uff0c\u800c\u4e0d\u4f1a\u5bf9 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u4ea7\u751f\u4efb\u4f55\u5f71\u54cd\u3002 \u7ed3\u8bba\uff1a\u628a\u5f15\u7528\u4fdd\u5b58\u5230\u666e\u901a\u53d8\u91cf\u4e2d\uff0c\u5219\u5f15\u7528\u4f1a\u9000\u5316\uff0c\u9020\u6210\u6df1\u62f7\u8d1d\uff01\u4e0d\u4ec5\u5f71\u54cd\u6027\u80fd\uff0c\u8fd8\u5f71\u54cd\u529f\u80fd\uff01stu \u5df2\u7ecf\u662f\u4e00\u4e2a\u72ec\u7acb\u7684 Student \u5bf9\u8c61\uff0c\u5bf9 stu \u7684\u4fee\u6539\u5df2\u7ecf\u4e0d\u4f1a\u5f71\u54cd\u5230 stus.at(stuName) \u6307\u5411\u7684\u90a3\u4e2a Student \u5bf9\u8c61\u4e86\u3002 \u6b64\u65f6\u4f60\u5bf9\u8fd9\u4e2a\u666e\u901a\u53d8\u91cf\u7684\u6240\u6709\u4fee\u6539\uff0c\u90fd\u4e0d\u4f1a\u540c\u6b65\u5230 map \u4e2d\u7684\u90a3\u4e2a Student \u4e2d\u53bb\uff01 \u6211\u4eec\u73b0\u5728\u5bf9\u76f8\u4f9d\u7ae5\u978b\u8fdb\u884c C++ \u57f9\u8bad\uff1a PeiXunCpp(\"\u76f8\u4f9d\"); print(stus.at(\"\u76f8\u4f9d\")); \u7ed3\u679c\u53d1\u73b0\u4ed6\u7684\u5b58\u6b3e\u4e00\u5206\u6ca1\u5c11\uff0c\u4e5f\u6ca1\u5b66\u4f1a C++\uff1a {id: 20220302, age: 21, sex: \"\u7537\", money: 2000, skills: {\"C\", \"Java\"}} \u770b\u6765\u6211\u4eec\u7684\u4fee\u6539\u6ca1\u6709\u5728 map \u4e2d\u751f\u6548\uff1f\u539f\u6765\u662f\u56e0\u4e3a\u6211\u4eec\u5728 PeiXunCpp \u51fd\u6570\u91cc\uff1a auto stu = stus.at(stuName); // \u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 \u4e00\u4e0d\u5c0f\u5fc3\u5c31\u7528\u4e86\u201c\u514b\u9686\u4eba\u201d\u6280\u672f\uff01\u4ece\u5b66\u751f\u8868\u91cc\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\uff0c\u514b\u9686\u4e86\u4e00\u4efd\u653e\u5230\u6808\u4e0a\u7684\u201c\u76f8\u4f9d2\u53f7\u201d\uff01 \u7136\u540e\u6211\u4eec\u6263\u4e86\u8fd9\u4e2a\u4e34\u65f6\u514b\u9686\u4eba\u201c\u76f8\u4f9d2\u53f7\u201d\u7684\u94b1\uff0c\u5e76\u7ed9\u4ed6\u57f9\u8bad C++ \u6280\u672f\u3002 \u7136\u800c\u6211\u4eec\u57f9\u8bad\u7684\u662f\u6808\u4e0a\u7684\u4e34\u65f6\u53d8\u91cf\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u514b\u9686\u524d\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5e76\u6ca1\u6709\u53d7\u5230\u57f9\u8bad\uff0c\u4e5f\u6ca1\u6709\u6263\u94b1\u3002 \u7136\u540e\u5462\uff1f\u6b8b\u5fcd\u7684\u4e8b\u60c5\u53d1\u751f\u4e86\uff01\u5728\u5c0f\u5f6d\u8001\u5e08\u4e00\u901a\u64cd\u4f5c\u57f9\u8bad\u5b8c\u201c\u76f8\u4f9d2\u53f7\u201d\u540e\uff0c\u6211\u4eec\u628a\u4ed6\u9001\u4e0a\u65ad\u5934\u53f0\u2014\u2014\u6790\u6784\u4e86\uff01 \u800c\u8fd9\u4e00\u5207\u201c\u76f8\u4f9d1\u53f7\u201d\u5b8c\u5168\u4e0d\u77e5\u60c5\uff0c\u4ed6\u53ea\u77e5\u9053\u6709\u4eba\u558a\u4ed6\u505a\u514b\u9686\uff0c\u7136\u540e\u5c31\u56de\u5bb6\u73a9 Java \u53bb\u4e86\uff0c\u5e76\u6ca1\u6709\u57f9\u8bad C++ \u7684\u8bb0\u5fc6\u3002 \u8981\u9632\u6b62\u5f15\u7528\u9000\u5316\u6210\u666e\u901a\u53d8\u91cf\uff0c\u9700\u8981\u628a\u53d8\u91cf\u7c7b\u578b\u4e5f\u6539\u6210\u5f15\u7528\uff01\u8fd9\u79cd\u662f\u6d45\u62f7\u8d1d\uff0cstu \u548c stus.at(stuName) \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u4e2a Student \u5bf9\u8c61\u3002\u7528 auto \u6355\u83b7\u7684\u8bdd\uff0c\u6539\u6210 auto & \u5c31\u884c\u3002 void PeiXunCpp(string stuName) { auto &stu = stus.at(stuName); // \u5728\u6808\u4e0a\u521b\u5efa\u4e00\u4e2a\u6307\u5411\u539f Student \u5bf9\u8c61\u7684\u5f15\u7528 stu.money -= 2650; stu.skills.insert(\"C++\"); } {id: 20220302, age: 21, sex: \"\u7537\", money: -650, skills: {\"C\", \"C++\", \"Java\"}} \u7ec8\u4e8e\uff0c\u6b63\u7248\u201c\u76f8\u4f9d1\u53f7\u201d\u672c\u4f53\u978b\u5e9f\u4e86 C++\uff01 \u4e4b\u540e\u5982\u679c\u518d\u4ece\u201c\u76f8\u4f9d1\u53f7\u201d\u8eab\u4e0a\u514b\u9686\uff0c\u514b\u9686\u51fa\u6765\u7684\u201c\u76f8\u4f9dn\u53f7\u201d\u4e5f\u90fd\u4f1a\u5177\u6709\u57f9\u8bad\u8fc7 C++ \u7684\u8bb0\u5fc6\u4e86\u3002 \u5f15\u7528\u76f8\u5f53\u4e8e\u8eab\u4efd\u8bc1\uff0c\u6211\u4eec\u590d\u5370\u4e86\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\uff0c\u8eab\u4efd\u8bc1\u4e0d\u4ec5\u590d\u5370\u8d77\u6765\u6bd4\u514b\u9686\u4e00\u4e2a\u5927\u6d3b\u4eba\u5bb9\u6613\uff08\u62f7\u8d1d\u5f00\u9500\uff09\u4ece\u800c\u63d0\u5347\u6027\u80fd\uff0c\u800c\u4e14\u901a\u8fc7\u8eab\u4efd\u8bc1\u53ef\u4ee5\u627e\u5230\u672c\u4eba\uff0c\u5bf9\u8eab\u4efd\u8bc1\u7684\u4fee\u6539\u4f1a\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u6539\u4e3a\u5bf9\u672c\u4eba\u7684\u4fee\u6539\uff0c\u4f8b\u5982\u901a\u8fc7\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\u5728\u94f6\u884c\u5f00\u5361\u7b49\uff0c\u94f6\u884c\u8981\u7684\u662f\u8eab\u4efd\u8bc1\uff0c\u4e0d\u662f\u514b\u9686\u4eba\u54e6\u3002 \u5f15\u7528\u662f\u4e00\u4e2a\u70eb\u624b\u7684\u9999\u9999\u9762\u5305\uff0c\u666e\u901a\u53d8\u91cf\u5c31\u50cf\u4e00\u4e2a\u81ed\u81ed\u7684\u7b54\u8fa9\u9a6c\u6876\uff0c\u628a\u9762\u5305\u653e\u5230\u9a6c\u6876\uff08auto\uff09\u91cc\uff0c\u9762\u5305\u5c31\u81ed\u6389\uff0c\u8150\u70c2\u6389\uff0c\u4e0d\u80fd\u5403\u4e86\uff01\u8981\u8ba9\u9762\u5305\u8f6c\u79fb\u9635\u5730\u4e86\u4ee5\u540e\u4f9d\u7136\u597d\u5403\uff0c\u9700\u8981\u653e\u5230\u4fdd\u9c9c\u76d2\uff08auto &\uff09\u91cc\u3002 \u8fd9\u5c31\u662f C++ \u7684 decay\uff08\u4e2d\u6587\u521a\u597d\u662f\u201c\u9000\u5316\u201d\u3001\u201c\u53d8\u8d28\u201d\u7684\u610f\u601d\uff09\u89c4\u5219\u3002 \u4ee5\u4e0b\u90fd\u662f\u201c\u9999\u9999\u9762\u5305\u201d\uff0c\u653e\u8fdb\u9a6c\u6876\u91cc\u4f1a\u53d8\u8d28\uff1a T & \u4f1a\u53d8\u8d28\u6210 T \uff08\u5f15\u7528\u53d8\u8d28\u6210\u666e\u901a\u53d8\u91cf\uff09 T [] \u4f1a\u53d8\u8d28\u6210 T * \uff08\u6570\u7ec4\u53d8\u8d28\u6210\u9996\u5730\u5740\u6307\u9488\uff09 T () \u4f1a\u53d8\u8d28\u6210 T (*)() \uff08\u51fd\u6570\u53d8\u8d28\u6210\u51fd\u6570\u6307\u9488\uff09 \u5728\u51fd\u6570\u7684\u53c2\u6570\u4e2d\u3001\u51fd\u6570\u7684\u8fd4\u56de\u503c\u4e2d\u3001auto \u6355\u83b7\u7684\u53d8\u91cf\u4e2d\uff0c\u653e\u5165\u8fd9\u4e9b\u201c\u9999\u9999\u9762\u5305\u201d\u90fd\u4f1a\u53d1\u751f\u53d8\u8d28\uff01 \u5982\u4f55\u907f\u514d\u53d8\u8d28\uff1f\u90a3\u5c31\u4e0d\u8981\u7528\u9a6c\u6876\uff08\u666e\u901a\u53d8\u91cf\uff09\u88c5\u9762\u5305\u5457\uff01\u7528\u4fdd\u9c9c\u76d2\uff08\u5f15\u7528\u53d8\u91cf\uff09\u88c5\uff01 \u907f\u514d\u5f15\u7528 T &t \u53d8\u8d28\uff0c\u5c31\u5f97\u628a\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u6539\u6210\u5f15\u7528\uff0c\u6216\u8005\u7528 auto & \uff0c auto const & \u6355\u83b7\u624d\u884c\u3002 \u907f\u514d\u539f\u751f\u6570\u7ec4 T t[N] \u53d8\u8d28\uff0c\u4e5f\u53ef\u4ee5\u6539\u6210\u5f15\u7528 T (&t)[N] \uff0c\u4f46\u6bd4\u8f83\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u5c01\u88c5\u7684\u5b89\u5168\u9759\u6001\u6570\u7ec4 array \u6216 C++98 \u5c31\u6709\u7684\u5b89\u5168\u52a8\u6001\u6570\u7ec4 vector \u3002 \u907f\u514d\u51fd\u6570 T f() \u53d8\u8d28\uff0c\u53ef\u4ee5 T (&f)() \uff0c\u4f46\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u7684\u51fd\u6570\u5bf9\u8c61 function \u3002 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u9898\u5916\u8bdd\uff1a\u90aa\u6076\u7684\u9000\u5316\u89c4\u5219\u9020\u6210\u7a7a\u60ac\u6307\u9488\u7684\u6848\u4f8b typedef double arr_t[10]; auto func(arr_t val) { arr_t ret; memcpy(ret, val, sizeof(arr_t)); // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; // double [10] \u81ea\u52a8\u53d8\u8d28\u6210 double * } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); // \u6b64\u5904 auto \u4f1a\u88ab\u63a8\u5bfc\u4e3a double * print(std::span(ret, ret + 10)); return 0; } Segmentation fault (core dumped) \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6 ^{14}C ^{14}C \u8bed\u8a00\u201c\u8870\u53d8\u201d\u5bfc\u81f4\u7a0b\u5e8f Segmentation fault \u4e86\u3002 \u4fee\u590d\u65b9\u6cd5\uff1a\u522b\u518d\u7528 C \u8bed\u8a00\u7684\u715e\u7b14\u539f\u59cb\u4eba\u6570\u7ec4\u4e86\uff01\u7528 C++ \u5c01\u88c5\u597d\u7684 array\uff0c\u65e0\u9690\u60a3 typedef std::array arr_t; // \u5982\u9700\u52a8\u6001\u957f\u5ea6\uff0c\u6539\u7528 vector \u4ea6\u53ef auto func(arr_t val) { arr_t ret; ret = val; // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); print(ret); return 0; } {1, 2, 3, 4, 0, 0, 0, 0, 0, 0} \u5982\u679c\u4f60\u8fd8\u662f\u5b66\u4e0d\u4f1a\u600e\u4e48\u4fdd\u7559\u9999\u9999\u5f15\u7528\u7684\u8bdd\uff0c\u571f\u529e\u6cd5\uff1a\u4e5f\u53ef\u4ee5\u5728\u4fee\u6539\u540e\u518d\u6b21\u7528 [] \u5199\u56de\u5b66\u751f\u8868\u3002\u8fd9\u6837\u5b66\u751f\u8868\u91cc\u4e0d\u4f1a C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5c31\u4f1a\u88ab\u6211\u4eec\u6808\u4e0a\u57f9\u8bad\u8fc7 C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u8986\u76d6\uff0c\u73b0\u5728\u5b66\u751f\u8868\u91cc\u7684\u4e5f\u662f\u6709 C++ \u6280\u80fd\u7684\u201c\u76f8\u4f9d\u201d\u8fa3\uff01\u53ea\u4e0d\u8fc7\u9700\u8981\u7ffb\u6765\u8986\u53bb\u514b\u9686\u4e86\u597d\u51e0\u6b21\u6bd4\u8f83\u4f4e\u6548\u800c\u5df2\uff0c\u81f3\u5c11\u80fd\u7528\u4e86\uff0c\u5efa\u8bae\u53ea\u6709\u5b66\u4e0d\u61c2\u5f15\u7528\u7684\u7ae5\u978b\u518d\u7528\u8fd9\u79cd\u4fdd\u5e95\u5199\u6cd5\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u514b\u9686\u4e86\u4e00\u4efd\u201c\u76f8\u4f9d2\u53f7\u201d stu.money -= 2650; stu.skills.insert(\"C++\"); stus[stuName] = stu; // \u201c\u76f8\u4f9d2\u53f7\u201d\u593a\u820d\uff0c\u628a\u201c\u76f8\u4f9d1\u53f7\u201d\u7ed9\u8986\u76d6\u6389\u4e86 } \u72c2\u60f3\uff1a\u5982\u679c\u514b\u9686\u201c\u76f8\u4f9d1\u53f7\u201d\u540c\u5b66\uff0c\u5f97\u5230\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u7136\u540e\u628a\u539f\u6765\u7684\u6740\u2026\u2026\u554a\u4e0d\u5bf9\uff0c\u201c\u6790\u6784\u201d\u6389\uff0c\u7136\u540e\u5bf9\u5916\u8c0e\u79f0\u201c\u8fd9\u8fd8\u662f\u539f\u6765\u7684\u76f8\u4f9d1\u53f7\u5440\uff01\u201d\u4f1a\u4e0d\u4f1a\u88ab\u53d1\u73b0\u5462\uff1f \u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u4e0a\u9762\u4ee3\u7801\u7b2c 5 \u884c\u4e5f\u53ef\u4ee5\u6539\u7528 at\uff0c\u4e3a\u4ec0\u4e48\uff1f\u5c0f\u5f6d\u8001\u5e08\u4e0d\u662f\u8bf4 \u201cat \u7528\u4e8e\u8bfb\u53d6\uff0c[] \u7528\u4e8e\u5199\u5165\u201d \u5417\uff1f \u6211\u4eec\u7ae5\u978b\u8981\u5b66\u4f1a\u53d8\u901a\uff01\u5c0f\u5f6d\u8001\u5e08\u8b66\u544a\u8bf4 \u201c[] \u53ea\u80fd\u7528\u4e8e\u5199\u5165\u201d\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u5e73\u65f6\u7684\u5199\u5165\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u9700\u8981\u5199\u5165\u5230\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u6240\u4ee5 [] \u4f1a\u81ea\u52a8\u521b\u5efa\u5143\u7d20\u5c31\u5f88\u65b9\u4fbf\uff1b\u5982\u679c\u662f at() \u5c31\u4e0d\u7b26\u5408\u201c\u5199\u5165\u65f6\u81ea\u52a8\u521b\u5efa\u4e0d\u5b58\u5728\u7684\u952e\u201c\u3002\u4f46\u662f\u73b0\u5728\u7684\u60c5\u51b5\u662f\u6211\u4eec\u7b2c 2 \u884c\u5df2\u7ecf\u8bbf\u95ee\u8fc7 at(\"\u76f8\u4f9d\") \uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u786e\u8ba4 \"\u76f8\u4f9d\" \u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u56e0\u6b64\u6211\u5199\u5165\u7684\u4e00\u5b9a\u662f\u4e2a\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\uff0c\u8fd9\u65f6 [] \u548c at \u5df2\u7ecf\u6ca1\u533a\u522b\u4e86\uff0c\u6240\u4ee5\u7528 at \u7684\u975e const \u91cd\u8f7d\uff0c\u4e00\u6837\u53ef\u4ee5\u5199\u5165\u3002 \u6211\u4eec\u7ae5\u978b\u4e0d\u662f\u53bb\u6b7b\u8bb0\u786c\u80cc\u300a\u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55\u300b\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u540d\u8a00\u5f53\u505a\u201c\u4e24\u4e2a\u51e1\u662f\u201d\u5723\u7ecf\u3002\u8981\u7406\u89e3\u5c0f\u5f6d\u8001\u5e08\u4f1a\u8fd9\u4e48\u8bf4\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u624d\u80fd\u6839\u636e\u4e0d\u540c\u5b9e\u9645\u60c5\u51b5\uff0c\u5b9e\u4e8b\u6c42\u662f\u770b\u95ee\u9898\uff0c\u624d\u662f\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u552f\u7269\u7f16\u7a0b\u89c2\u7684\uff08\u5b5d\uff09 \u5982\u679c\u8981\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u5462\uff1f\u90a3\u5c31\u4ee5\u5b66\u53f7\u4e3a\u952e\uff0c\u7136\u540e\u628a\u5b66\u751f\u59d3\u540d\u653e\u5230 Student \u7ed3\u6784\u4f53\u4e2d\u3002 \u5982\u679c\u540c\u65f6\u6709\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u548c\u6839\u636e\u59d3\u540d\u67e5\u627e\u4e24\u79cd\u9700\u6c42\u5462\uff1f \u540c\u65f6\u9ad8\u6548\u5730\u6839\u636e\u591a\u4e2a\u952e\u8fdb\u884c\u67e5\u627e\uff0c\u751a\u81f3\u6307\u5b9a\u5404\u79cd\u6761\u4ef6\uff0c\u6bd4\u5982\u67e5\u8be2\u6240\u6709\u4f1a C++ \u7684\u5b66\u751f\u7b49\uff0c\u8fd9\u53ef\u4e0d\u662f map \u80fd\u641e\u5b9a\u7684\uff0c\u6216\u8005\u8bf4\u80fd\u641e\u5b9a\u4f46\u4e0d\u9ad8\u6548\uff08\u6700\u540e\u5f80\u5f80\u53ea\u80fd\u66b4\u529b\u904d\u5386\u67e5\u627e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u592a\u9ad8\uff09\u3002\u8fd9\u662f\u4e2a\u4e13\u95e8\u7684\u7814\u7a76\u9886\u57df\uff0c\u79f0\u4e3a\uff1a\u5173\u7cfb\u6570\u636e\u5e93\u3002 \u5173\u7cfb\u6570\u636e\u5e93\u7684\u5b9e\u73b0\u6709 MySQL\uff0cSQLite\uff0cMongoDB \u7b49\u3002C++ \u7b49\u7f16\u7a0b\u8bed\u8a00\u53ea\u9700\u8c03\u7528\u4ed6\u4eec\u63d0\u4f9b\u7684 API \u5373\u53ef\uff0c\u4e0d\u5fc5\u81ea\u5df1\u624b\u52a8\u5b9e\u73b0\u8fd9\u4e9b\u590d\u6742\u7684\u67e5\u627e\u548c\u63d2\u5165\u7b97\u6cd5\u3002 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u4e13\u4e1a\u7684\u201c\u5b66\u751f\u7ba1\u7406\u7cfb\u7edf\u201d\u90fd\u4f1a\u7528\u5173\u7cfb\u6570\u636e\u5e93\uff0c\u800c\u4e0d\u662f\u81ea\u5df1\u624b\u52a8\u7ef4\u62a4\u4e00\u4e2a map\u3002\u5173\u7cfb\u6570\u636e\u5e93\u5e95\u5c42\u7684\u6570\u636e\u7ed3\u6784\u66f4\u590d\u6742\uff0c\u4f46\u7ecf\u8fc7\u9ad8\u5ea6\u5c01\u88c5\uff0c\u6548\u7387\u66f4\u9ad8\uff0c\u63d0\u4f9b\u7684\u529f\u80fd\u4e5f\u66f4\u5168\u9762\uff0c\u7528\u8d77\u6765\u4e5f\u6bd4\u8f83\u65e0\u611f\u3002\u4f55\u51b5 map \u5b58\u5728\u5185\u5b58\u4e2d\uff0c\u7535\u8111\u4e00\u5173\u673a\uff0c\u5b66\u751f\u6570\u636e\u5c31\u6ca1\u4e86\uff01\u800c\u6570\u636e\u5e93\u53ef\u4ee5\u628a\u6570\u636e\u6301\u4e45\u5316\u5230\u78c1\u76d8\u4e2d\uff0c\u76f8\u5f53\u4e8e\u5728\u78c1\u76d8\u91cc\u6784\u5efa\u51fa\u4e86\u4e00\u9897\u67e5\u627e\u6811\uff0c\u5173\u673a\u540e\u6570\u636e\u4f9d\u7136\u4fdd\u6301\u3002 \u76f8\u4f9d\u540c\u5b66\u597d\u4e0d\u5bb9\u6613\u8003\u51fa\u6ee1\u5206\uff0c\u7ed3\u679c\u5c0f\u5f6d\u8001\u5e08\u4e00\u4e0d\u5c0f\u5fc3\u8e22\u4e86\u4e00\u811a\u7535\u8111\uff0c\u91cd\u542f\uff0c\u5168\u90e8\u5b66\u751f\u6863\u6848\u4e22\u5931\uff0c\u767d\u8003\uff01 \u67e5\u8be2 map \u4e2d\u5143\u7d20\u7684\u6570\u91cf size_t size() const noexcept; \u4f7f\u7528 m.size() \u83b7\u5f97\u7684 map \u5927\u5c0f\uff0c\u6216\u8005\u8bf4\u5176\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002 map m; print(m.size()); // 0 m[\"fuck\"] = 985; print(m.size()); // 1 m[\"dick\"] = 211; print(m.size()); // 2 \u5e94\u7528\u4e3e\u4f8b\uff1a\u7ed9\u6bcf\u4e2a\u952e\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u8ba1\u6570 map m; m[\"fuck\"] = m.size(); m[\"dick\"] = m.size(); \u9700\u8981 C++17 \u4ee5\u4e0a\u7684\u7248\u672c\uff0c\u624d\u80fd\u4fdd\u8bc1\u7b49\u53f7\u53f3\u8fb9\u7684 m.size() \u5148\u4e8e m[\"fuck\"] \u6c42\u503c\u3002C++14 \u4e2d\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u884c\u4e3a\u672a\u5b9a\u4e49\uff0c\u9700\u8981\u6539\u7528 m.insert({\"fuck\", m.size()}) \u7684\u5199\u6cd5\uff08\u51fd\u6570\u53c2\u6570\u603b\u662f\u4f18\u5148\u4e8e\u51fd\u6570\u6c42\u503c\uff0c\u8fd9\u4fdd\u8bc1 m.size() \u5148\u6c42\u503c\uff0c\u7136\u540e\u624d\u53d1\u751f\u5143\u7d20\u63d2\u5165\uff09\u3002 \u5224\u65ad\u4e00\u4e2a\u952e\u662f\u5426\u5b58\u5728\uff1acount \u51fd\u6570 size_t count(K const &k) const; count \u8fd4\u56de\u5bb9\u5668\u4e2d\u952e\u548c\u53c2\u6570 k \u76f8\u7b49\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 count \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u4e00\u4e2a\u952e\u5728 map \u4e2d\u662f\u5426\u5b58\u5728\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.count(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } if (msg.count(\"dick\")) { print(\"\u5b58\u5728dick\uff0c\u5176\u503c\u4e3a\", msg.at(\"suck\")); } else { print(\"\u627e\u4e0d\u5230dick\"); } {\"fuck\": \"rust\", \"hello\": \"world\"} \u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a \"rust\" \u627e\u4e0d\u5230dick C++20 \u4e2d\u5efa\u8bae\u6539\u7528\u8fd4\u56de\u7c7b\u578b\u4e3a bool \u7684 contains \u51fd\u6570\uff0c\u51fd\u6570\u540d\u548c\u7c7b\u578b\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u4f46\u5b9e\u9645\u6548\u679c\u548c count \u662f\u4e00\u6837\u7684\u3002 if (msg.contains(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 \u9664\u4e86\u5199\u5165\u5143\u7d20\u9700\u8981\u7528 [] \u4ee5\u5916\uff0c\u8fd8\u6709\u4e00\u4e9b\u6848\u4f8b\u4e2d\u5408\u7406\u8fd0\u7528 [] \u4f1a\u975e\u5e38\u7684\u65b9\u4fbf\u3002 [] \u7684\u6548\u679c\uff1a\u5f53\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u4e00\u4e2a\u5143\u7d20 1 \u3002 \u5bf9\u4e8e int, float \u7b49\u6570\u503c\u7c7b\u578b\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f 0\u3002 \u5bf9\u4e8e\u6307\u9488\uff08\u5305\u62ec\u667a\u80fd\u6307\u9488\uff09\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f nullptr\u3002 \u5bf9\u4e8e string \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 \u201c\u201d\u3002 \u5bf9\u4e8e vector \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u6570\u7ec4 {}\u3002 \u5bf9\u4e8e\u81ea\u5b9a\u4e49\u7c7b\u800c\u8a00\uff0c\u4f1a\u8c03\u7528\u4f60\u5199\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5219\u6bcf\u4e2a\u6210\u5458\u90fd\u53d6\u9ed8\u8ba4\u503c\u3002 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 vector input = {\"hello\", \"world\", \"hello\"}; map counter; for (auto const &key: input) { counter[key]++; } print(counter); {\"hello\": 2, \"world\": 1} \u5bf9\u6bd4 \u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa 0 \u5143\u7d20\u7684\u7279\u6027 map counter; for (auto const &key: input) { counter[key]++; } \u53e4\u677f\u7684\u5199\u6cd5 map counter; for (auto const &key: input) { if (!counter.count(key)) { counter[key] = 1; } else { counter[key] = counter.at(key) + 1; } } [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b vector input = {\"happy\", \"world\", \"hello\", \"weak\", \"strong\"}; map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); {'h': {\"happy\", \"hello\"}, 'w': {\"world\", \"weak\"}, 's': {\"strong\"}} \u5bf9\u6bd4 \u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa\u201d\u9ed8\u8ba4\u503c\u201d\u5143\u7d20\u7684\u7279\u6027 map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); \u53e4\u677f\u7684\u5199\u6cd5 map> categories; for (auto const &str: input) { char key = str[0]; if (!categories.count(key)) { categories[key] = {str}; } else { categories[key].push_back(str); } } [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf concurrent_map tls; parallel_for([] { Data &data = tls[std::this_thread::get_id()]; ...; }); \u4e0d\u8fc7 thread_local \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u53d6\u4ee3\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 \u53cd\u9762\u5178\u578b\uff1a\u67e5\u627e\u7279\u5b9a\u5143\u7d20\u5728 vector \u4e2d\u7684\u4f4d\u7f6e\uff08\u4e0b\u6807\uff09 size_t array_find(vector const &arr, string const &val) { for (size_t i = 0; i < arr.size(); i++) { if (arr[i] == val) return i; } return (size_t)-1; } vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; print(\"hello\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"fucker\")); // O(N) \u4f4e\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"nice\")); // O(N) \u4f4e\u6548 \u6bcf\u6b21\u8c03\u7528 array_find \uff0c\u90fd\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a0 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N^2) O(N^2) \u3002 \u6ce8\uff1a\u5047\u8bbe vector \u4e2d\u4e0d\u5b58\u5728\u91cd\u590d\u7684\u5143\u7d20 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 \u6b63\u786e\u505a\u6cd5\uff1a\u6784\u5efa vector \u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u4ee5\u540e\u67e5\u627e\u66f4\u9ad8\u6548 vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; map arrinv; for (size_t i = 0; i < arr.size(); i++) { // O(N) \u4e00\u6b21\u6027\u53d7\u82e6 arrinv[arr[i]] = i; } print(\"\u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a\", arrinv); print(\"fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"fucker\")); // O(log N) \u9ad8\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"nice\")); // O(log N) \u9ad8\u6548 \u53ea\u6709\u7b2c\u4e00\u6b21\u6784\u9020\u53cd\u5411\u67e5\u627e\u8868\u65f6\uff0c\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u4ee5\u540e\u6bcf\u6b21\u8c03\u7528 map.at \uff0c\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a{\"day\": 3, \"fucker\", 4, \"hello\": 0, \"nice\": 2, \"world\": 1} fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a4 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u8f76\u4e8b\uff1a\u5728\u6570\u636e\u5e93\u4e2d\uff0c\u8fd9\u79cd\u53cd\u5411\u67e5\u627e\u8868\u88ab\u79f0\u4e3a\u201c\u5012\u5e8f\u7d22\u5f15\u201d\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u5728\u4e0d\u77e5\u9053\u8fd9\u4e2a\u672f\u8bed\u7684\u60c5\u51b5\u4e0b\uff0c\u72ec\u7acb\u4ea7\u751f\u4e86\u53cd\u5411\u67e5\u627e\u8868\u7684\u601d\u60f3 for (size_t i = 0; i < arr.size(); i++) { arrinv[arr[i]] = i; } \u63d0\u524d\u6784\u9020\u597d\u67e5\u627e\u8868 O(N) O(N) \uff0c\u4ee5\u540e\u6bcf\u6b21\u67e5\u627e\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u5c31\u884c\u3002 \uff08\u6b63\u5411\u67e5\u627e\uff09\u5df2\u77e5\u4e0b\u6807 i\uff0c\u6c42\u5143\u7d20 v\uff1a v = arr[i] \uff08\u53cd\u5411\u67e5\u627e\uff09\u5df2\u77e5\u5143\u7d20 v\uff0c\u6c42\u4e0b\u6807 i\uff1a i = arrinv[v] \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N \\log N) O(N \\log N) \uff0c\u6bd4\u4f18\u5316\u524d\u9ad8\u6548\u3002 \u56e0\u6b64\u5f53\u9700\u8981\u591a\u6b21\u67e5\u627e\u4e14\u539f\u6570\u7ec4\u4fdd\u6301\u4e0d\u53d8\u65f6\uff0c\u5f3a\u70c8\u63a8\u8350\u7528\u8fd9\u79cd\u65b9\u6cd5\uff0c\u66f4\u9ad8\u6548\u3002 \u53ea\u6709\u5f53 vector \u66f4\u65b0\u65f6\uff0c\u624d\u9700\u8981\u91cd\u65b0\u6784\u5efa map\u3002\u5982\u679c vector \u7684\u5220\u9664\u91c7\u7528 back-swap-erase\uff08\u89c1 C++ \u5c0f\u5999\u62db \uff09\uff0c\u90a3\u4e48\u65e0\u9700\u5b8c\u5168\u91cd\u6784 map\uff0c\u53ea\u9700\u66f4\u65b0 swap \u7684\u4e24\u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u603b\u590d\u6742\u5ea6 O(\\log N) O(\\log N) \uff0c\u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a O(\\log N) O(\\log N) \u7684\u6709\u4e0b\u6807\u53c8\u80fd\u5feb\u901f\u67e5\u627e\u6570\u7ec4\uff0c\u517c\u5177 map \u548c vector \u7684\u4f18\u52bf\u3002\u5728\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8fdb\u9636\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u6b64\u7c7b\u590d\u5408\u6570\u636e\u7ed3\u6784\u3002 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map \u53ea\u80fd\u901a\u8fc7\u503c\u6620\u5c04\u5230\u952e\uff0c\u80fd\u4e0d\u80fd\u53cd\u8fc7\u6765\u901a\u8fc7\u952e\u67e5\u627e\u503c\uff1f \u6848\u4f8b\uff1a\u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map tab = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; map tabinv; for (auto const &[k, v]: tab) { tabinv[v] = k; } print(tabinv); \u6548\u679c\u5c31\u662f\uff0c\u952e\u53d8\u503c\uff0c\u503c\u53d8\u952e\uff0c\u53cd\u4e00\u53cd\uff0c\u4e24\u4e2a map \u4e92\u4e3a\u9006\u8fd0\u7b97\uff1a {\"rust\": \"fuck\", \"world\": \"hello\"} \u6ce8\u610f\uff1a\u8981\u6c42 tab \u4e2d\u4e0d\u80fd\u5b58\u5728\u91cd\u590d\u7684\u503c\uff0c\u952e\u548c\u503c\u5fc5\u987b\u662f\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\uff0c\u624d\u80fd\u7528\u8fd9\u79cd\u65b9\u5f0f\u6784\u5efa\u53cc\u5411\u67e5\u627e\u8868\u3002\u5426\u5219\u4e00\u4e2a\u503c\u53ef\u80fd\u5bf9\u5e94\u5230\u4e24\u4e2a\u952e\uff0c\u53cd\u5411\u8868\u5fc5\u987b\u662f map> \u4e86\u3002 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1a value_type STL \u5bb9\u5668\u7684\u5143\u7d20\u7c7b\u578b\u90fd\u53ef\u4ee5\u901a\u8fc7\u6210\u5458 value_type \u67e5\u8be2\uff0c\u5e38\u7528\u4e8e\u6cdb\u578b\u7f16\u7a0b\uff08\u53c8\u79f0\u5143\u7f16\u7a0b\uff09\u3002 set::value_type // int vector::value_type // int string::value_type // char \u6b64\u5916\u8fd8\u6709\u5f15\u7528\u7c7b\u578b reference \uff0c\u8fed\u4ee3\u5668\u7c7b\u578b iterator \uff0c\u5e38\u8fed\u4ee3\u5668\u7c7b\u578b const_iterator \u7b49\u3002 \u66fe\u7ecf\u5728 C++98 \u4e2d\u5f88\u5e38\u7528\uff0c\u4e0d\u8fc7\u81ea\u4ece C++11 \u6709\u4e86 auto \u548c decltype \u4ee5\u540e\uff0c\u5c31\u4e0d\u600e\u4e48\u7528\u4e86\uff0c\u53cd\u6b63\u80fd\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 C++23: std::vector arr; for (auto const &elem: arr) { std::println(\"{}\", elem); } C++17: std::vector arr; for (auto const &elem: arr) { std::cout << elem << '\\n'; } C++11: std::vector arr; for (auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } C++98: std::vector arr; for (std::vector::iterator it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } typename \u4fee\u9970 \u5f53\u5bb9\u5668\u6709\u81f3\u5c11\u4e00\u4e2a\u4e0d\u786e\u5b9a\u7684\u7c7b\u578b T \u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u65f6\uff0c\u5c31\u9700\u8981\u524d\u9762\u52a0\u4e0a typename \u4fee\u9970\u4e86\uff1a set::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 typename set::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename set>::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 K\u3001T \u662f\u4e0d\u5b9a\u7c7b\u578b map::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 \u5982\u679c\u4f60\u641e\u4e0d\u6e05\u695a\uff0c\u59cb\u7ec8\u52a0 typename \u5c31\u884c\u4e86\uff0c\u53cd\u6b63\u52a0\u591a\u80af\u5b9a\u4e0d\u4f1a\u6709\u9519\u3002\u4f60\u5c31\u8ba4\u4e3a\uff1a\u8fd9\u5c31\u662f\u4e00\u4e2a\u5e73\u65f6\u53ef\u4ee5\u7701\u7565\uff0c\u5076\u5c14\u4e0d\u80fd\u7701\u7565\u7684\u4e1c\u897f\u3002 typename set::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb typename set::value_type; // \u4e0d\u80fd\u7701\u7565 typename set>::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb \u542b\u6709 T \u7684\u7c7b\u578b\u8868\u8fbe\u5f0f\u79f0\u4e3a dependent-type\uff0c\u6839\u672c\u539f\u56e0\u662f\u56e0\u4e3a\u5728\u4e0d\u77e5\u9053\u5177\u4f53\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\u8fd8\u662f\u503c\u8868\u8fbe\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u7f16\u8bd1\u5668\u65e0\u6cd5\u533a\u5206\u6a21\u677f\u7684 < \u548c\u5c0f\u4e8e\u7b26\u53f7 < \uff0c\u4ee5\u53ca\u7c7b\u578b\u7684\u6307\u9488 * \u548c\u6570\u503c\u4e58\u6cd5 * \u3002\u9ed8\u8ba4\u4f1a\u8ba4\u4e3a\u662f\u5c0f\u4e8e\u7b26\u53f7\u548c\u6570\u503c\u4e58\u6cd5\uff0c\u52a0\u4e0a typename \u540e\u660e\u786e\u524d\u9762\u8fd9\u4e00\u4e32\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\uff0c\u624d\u77e5\u9053\u8fd9\u662f\u6a21\u677f\u7684 < \u548c\u6307\u9488\u7684 * \u3002 decltype \u5927\u6cd5\u597d \u4e5f\u6709\u66f4\u76f4\u89c2\u7684\u83b7\u53d6 STL \u5bb9\u5668\u5143\u7d20\u7c7b\u578b\u7684\u65b9\u6cd5\uff1a std::vector arr; using T = std::decay_t; // T = int decltype \u5fc5\u987b\u914d\u5408 std::decay_t \u624d\u80fd\u7528\uff01\u5426\u5219\u4f1a\u5f97\u5230\u5f15\u7528\u7c7b\u578b int & \uff0c\u540e\u7eed\u4f7f\u7528\u4e2d\u5c31\u5751\u5230\u4f60\uff01\uff08\u56e0\u4e3a arr \u7684 [] \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528\u7c7b\u578b\uff09 // \u9519\u8bef\u793a\u8303 using T = decltype(arr[0]); // T = int & T i = 0; // int &i = 0; \u540e\u7eed\u4f7f\u7528\u4e2d\u7f16\u8bd1\u51fa\u9519\uff01 \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 \u5728\u672c\u8bfe\u7a0b\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\u9644\u5e26\u7684 \u201ccppdemangle.h\u201d\uff0c\u53ef\u4ee5\u5b9e\u73b0\u6839\u636e\u6307\u5b9a\u7684\u7c7b\u578b\u67e5\u8be2\u7c7b\u578b\u540d\u79f0\u5e76\u6253\u5370\u51fa\u6765\u3002 \u8de8\u5e73\u53f0\uff0c\u9700\u8981 C++11\uff0c\u652f\u6301 MSVC\uff0cClang\uff0cGCC \u4e09\u5927\u7f16\u8bd1\u5668\uff0c\u4f8b\u5982\uff1a int i; print(cppdemangle()); print(cppdemangle()); print(cppdemangle()); \u5728\u6211\u7684 GCC 12.2.1 \u4e0a\u5f97\u5230\uff1a \"int &&\" \"std::__cxx11::basic_string, std::allocator >\" \"wchar_t\" map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f map \u5177\u6709\u4e09\u4e2a\u6210\u5458\u7c7b\u578b 1 \uff1a \u5143\u7d20\u7c7b\u578b\uff1a value_type \u952e\u7c7b\u578b\uff1a key_type \u503c\u7c7b\u578b\uff1a mapped_type \u540e\u9762\uff0c\u5c06\u4f1a\u4e00\u76f4\u4ee5\u201c\u5143\u7d20\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cvalue\u201d\uff0c\u201c\u952e\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201ckey\u201d\uff0c\u201c\u503c\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cmapped\u201d \u7528 cppdemangle \u505a\u5b9e\u9a8c\uff0c\u770b\u770b\u8fd9\u4e9b\u6210\u5458\u7c7b\u578b\u5177\u4f53\u662f\u4ec0\u4e48\u5427\uff1a map::value_type // pair map::key_type // int map::mapped_type // float \u7ed3\u8bba\uff1a map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u800c\u4e0d\u662f V \u3002 \u7591\u60d1\uff1a pair \u4e2d\uff0c\u4e3a\u4ec0\u4e48 K \u8981\u52a0 const\uff1f \u6211\u4eec\u5728 set \u8bfe\u4e2d\u8bf4\u8fc7\uff0cset \u5185\u90e8\u91c7\u7528\u7ea2\u9ed1\u6811\u6570\u636e\u7ed3\u6784\u4fdd\u6301\u6709\u5e8f\uff0c\u8fd9\u6837\u624d\u80fd\u5b9e\u73b0\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u9ad8\u6548\u67e5\u627e\u3002 \u952e\u503c\u6539\u53d8\u7684\u8bdd\u4f1a\u9700\u8981\u91cd\u65b0\u6392\u5e8f\uff0c\u5982\u679c\u53ea\u4fee\u6539\u952e\u503c\u800c\u4e0d\u91cd\u65b0\u6392\u5e8f\uff0c\u4f1a\u7834\u574f\u6709\u5e8f\u6027\uff0c\u5bfc\u81f4\u4e8c\u5206\u67e5\u627e\u7ed3\u679c\u9519\u8bef\uff01\u6240\u4ee5 set \u53ea\u63d0\u4f9b\u4e86\u4e0d\u53ef\u53d8\u8fed\u4ee3\u5668\uff08const_iterator\uff09\uff0c\u6ca1\u6709\u53ef\u53d8\u7684\u8fed\u4ee3\u5668\uff0c\u4e0d\u5141\u8bb8\u7528\u6237\u4fee\u6539\u4efb\u4f55\u5143\u7d20\u7684\u503c\u3002 map \u548c set \u4e00\u6837\u4e5f\u662f\u7ea2\u9ed1\u6811\uff0c\u4e0d\u540c\u5728\u4e8e\uff1amap \u53ea\u6709\u952e K \u7684\u90e8\u5206\u4f1a\u53c2\u4e0e\u6392\u5e8f\uff0cV \u662f\u4e2a\u65c1\u89c2\u8005\uff0c\u968f\u4fbf\u4fee\u6539\u4e5f\u6ca1\u5173\u7cfb\u3002 \u6240\u4ee5 map \u6709\u53ef\u53d8\u8fed\u4ee3\u5668\uff0c\u53ea\u662f\u5728\u5176\u503c\u7c7b\u578b value_type \u4e2d\u7ed9\u952e\u7684\u90e8\u5206\uff0cK\uff0c\u52a0\u4e0a\u4e86 const \u4fee\u9970\uff1a\u4e0d\u5141\u8bb8\u4fee\u6539 K\uff0c\u4f46\u53ef\u4ee5\u968f\u610f\u4fee\u6539 V\u3002 \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u4fee\u6539\u952e\u503c\uff0c\u90a3\u4e48\u8bf7\u5148\u53d6\u51fa\u65e7\u503c\uff0c\u628a\u8fd9\u4e2a\u952e\u5220\u4e86\uff0c\u7136\u540e\u518d\u4ee5\u540c\u6837\u7684\u503c\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u5230\u65b0\u7684\u952e\u3002\u76f8\u5f53\u4e8e\u91cd\u65b0\u6784\u5efa\u4e86\u4e00\u4e2a pair \u5bf9\u8c61\u3002 C++17 \u5f00\u59cb\u4e5f\u53ef\u4ee5\u7528\u66f4\u9ad8\u6548 node_handle \u7cfb\u5217 API\uff0c\u907f\u514d\u6570\u636e\u53d1\u751f\u79fb\u52a8\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; begin() \u548c end() \u8fed\u4ee3\u5668\u5206\u522b\u6307\u5411 map \u7684\u9996\u4e2a\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u540e\u4e00\u4f4d\u3002 \u5176\u4e2d end() \u8fed\u4ee3\u5668\u6307\u5411\u7684\u5730\u5740\u4e3a\u865a\u7a7a\u7d22\u654c\uff0c\u4e0d\u53ef\u89e3\u5f15\u7528\uff0c\u4ec5\u4ec5\u4f5c\u4e3a\u4e00\u4e2a\u201c\u6807\u5fd7\u201d\u5b58\u5728\uff08\u56de\u987e\u4e4b\u524d vector \u8bfe\uff09\u3002 \u8fed\u4ee3\u5668\u53ef\u4ee5\u901a\u8fc7 *it \u6216 it-> \u89e3\u5f15\u7528\uff0c\u83b7\u53d6\u5176\u6307\u5411\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u9996\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5c0f\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5927\u7684\u5143\u7d20\u3002 \u4f8b\u5982\u8981\u67e5\u8be2\u6210\u7ee9\u6700\u597d\u548c\u6700\u574f\u7684\u5b66\u751f\uff0c\u53ef\u4ee5\u628a\u6210\u7ee9\u5f53\u505a key\uff0c\u5b66\u751f\u540d\u505a value \u4f9d\u6b21\u63d2\u5165 map\uff0c\u4ed6\u4f1a\u5e2e\u6211\u4eec\u6392\u5e8f\uff1a map score = { {100, \"\u5f6d\u4e8e\u658c\"}, {80, \"\u6a31\u82b1\u7c89\u871c\u7cd6\"}, {0, \"\u76f8\u4f9d\"}, {60, \"Sputnik02\"}, }; string poorestStudent = score.begin()->second; // \u6210\u7ee9\u6700\u5dee\u5b66\u751f\u7684\u59d3\u540d string bestStudent = prev(score.end())->second; // \u6210\u7ee9\u6700\u597d\u5b66\u751f\u7684\u59d3\u540d print(\"\u6700\u4f4e\u5206:\", poorestStudent); print(\"\u6700\u9ad8\u5206:\", bestStudent); \u6700\u4f4e\u5206: \"\u76f8\u4f9d\" \u6700\u9ad8\u5206: \"\u5f6d\u4e8e\u658c\" \u6ce8\uff1a\u4ec5\u5f53\u786e\u4fdd score.size() != 0 \u65f6\u624d\u53ef\u4ee5\u89e3\u5f15\u7528\uff0c\u5426\u5219 begin() \u548c end() \u90fd\u662f\u865a\u7a7a\u8fed\u4ee3\u5668\uff0c\u8fd9\u65f6\u89e3\u5f15\u7528\u4f1a\u5954\u6e83\u3002 map \u7684\u904d\u5386\uff1a\u53e4\u4ee3 C++98 \u7684\u8fed\u4ee3\u5668\u5927\u6cd5 for (map::iterator it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8981\u7279\u522b\u6ce8\u610f\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u6307\u5411\u5143\u7d20\u7684\u6307\u9488\uff0c\u4e0d\u662f\u5143\u7d20\u672c\u8eab\uff01\u8981\u7528 -> \u800c\u4e0d\u662f . \u3002 \u8fd0\u7528 C++11 \u7684 auto \u7b80\u5199\u4e00\u4e0b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\uff08structured-binding\uff09\u8bed\u6cd5 1 \u76f4\u63a5\u62c6\u5f00 pair \u7c7b\u578b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; print(\"Key:\", k); print(\"Value:\", v); } map \u7684\u904d\u5386\uff1a\u73b0\u4ee3 C++17 \u57fa\u4e8e\u8303\u56f4\u7684\u5faa\u73af\uff08range-based loop\uff09 for (auto kv: m) { print(\"Key:\", kv.first); print(\"Value:\", kv.second); } \u540c\u65f6\u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\u8bed\u6cd5 1 \uff1a for (auto [k, v]: m) { print(\"Key:\", k); print(\"Value:\", v); } \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u53e4\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto it = m.begin(); it != m.end(); ++it) { it->second = it->second + 1; } print(m); {\"fuck\": 986, \"rust\": 212} \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u73b0\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto [k, v]: m) { v = v + 1; } print(m); {\"fuck\": 985, \"rust\": 211} \u6ca1\u6709\u6210\u529f\u4fee\u6539\uff01\u4e3a\u4ec0\u4e48\uff1f for (auto [k, v]: m) { v = v + 1; } Range-based loop \u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; v = v + 1; } Structured-binding \u4e5f\u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto tmp = *it; auto k = tmp.first; auto v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u6808\u4e0a\u53d8\u91cf\uff0c\u662f\u5bf9\u539f\u503c\u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u4e0d\u4ec5\u6d6a\u8d39\u6027\u80fd\uff0c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4e0d\u4f1a\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\uff01 for (auto &[k, v]: m) { // \u89e3\u51b3\u65b9\u6848\u662f\u5728\u8fd9\u91cc\u52a0\u4e00\u4e2a\u5c0f\u5c0f\u7684 &\uff0c\u8ba9 range-based loop \u6355\u83b7\u5f15\u7528\u800c\u4e0d\u662f\u62f7\u8d1d v = v + 1; } \u540c\u6837\u662f\u62c6\u9664 Range-based loop \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &[k, v] = *it; v = v + 1; } \u7ee7\u7eed\u62c6\u9664 Structured-binding \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &tmp = *it; auto &k = tmp.first; auto &v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u5f15\u7528\uff0c\u662f\u5bf9\u539f\u503c\u7684\u5f15\u7528\uff08\u7528 Rust \u7684\u8bdd\u8bf4\u53eb borrowed\uff09\u3002\u4e0d\u4ec5\u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\u8282\u7701\u4e86\u6027\u80fd\uff0c\u800c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4f1a\u5b9e\u65f6\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\u3002 \u603b\u7ed3\uff0c\u5f53\u9700\u8981\u5728\u904d\u5386\u7684\u540c\u65f6\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u8981\u7528 auto & \u6355\u83b7\u5f15\u7528\uff1a for (auto &[k, v]: m) { // \u6355\u83b7\u4e00\u4e2a\u5f15\u7528\uff0c\u5199\u5165\u8fd9\u4e2a\u5f15\u7528\u4f1a\u7acb\u5373\u4f5c\u7528\u5728\u539f\u503c\u4e0a v = v + 1; } \u5373\u4f7f\u4e0d\u9700\u8981\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u4e5f\u5efa\u8bae\u7528 auto const & \u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\uff1a for (auto const &[k, v]: m) { // \u6355\u83b7\u53ea\u8bfb\u7684 const \u5f15\u7528\uff0c\u5f15\u7528\u907f\u514d\u62f7\u8d1d\u5f00\u9500\uff0cconst \u907f\u514d\u4e0d\u5c0f\u5fc3\u624b\u6ed1\u5199\u5165 print(v); } \u6ce8\uff1a\u5373\u4f7f\u6355\u83b7\u4e3a auto & \uff0c\u7531\u4e8e map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5 K \u90e8\u5206\u8fd8\u662f\u4f1a\u6355\u83b7\u4e3a K const & \uff0c\u65e0\u6cd5\u5199\u5165\u3002 for (auto &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // OK } \u53ea\u662f\u5982\u679c\u6355\u83b7\u4e3a auto const & \u5c31\u4e24\u4e2a\u90fd\u4e0d\u5141\u8bb8\u5199\u5165\u4e86\u3002 for (auto const &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 } iterator find(K const &k); const_iterator find(K const &k) const; m.find(key) \u51fd\u6570\uff0c\u6839\u636e\u6307\u5b9a\u7684\u952e key \u67e5\u627e\u5143\u7d20 1 \u3002 \u6210\u529f\u627e\u5230\uff0c\u5219\u8fd4\u56de\u6307\u5411\u627e\u5230\u5143\u7d20\u7684\u8fed\u4ee3\u5668 \u627e\u4e0d\u5230\uff0c\u5219\u8fd4\u56de m.end() \u7531\u4e8e STL \u4f20\u7edf\u5f02\u80fd\u4e4b end() \u865a\u7a7a\u7d22\u654c\uff0c\u4ed6\u4e0d\u53ef\u80fd\u6307\u5411\u4efb\u4f55\u503c\uff0c\u6240\u4ee5\u7ecf\u5e38\u4f5c\u4e3a\u627e\u4e0d\u5230\u65f6\u5019\u7f3a\u7701\u7684\u8fd4\u56de\u503c\u3002 \u53ef\u4ee5\u7528 m.find(key) != m.end() \u5224\u65ad\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u5b58\u5728\uff0c\u7b49\u4ef7\u4e8e m.count(key) != 0 \u3002 \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684\u539f\u578b\u4f5c\u7528\u662f\uff1a\u5982\u679c map \u672c\u8eab\u6709 const \u4fee\u9970\uff0c\u5219\u8fd4\u56de\u7684\u4e5f\u662f const \u8fed\u4ee3\u5668\u3002 \u4e3a\u7684\u662f\u9632\u6b62\u4f60\u5728\u4e00\u4e2a const map \u91cc find \u4e86\u4ee5\u540e\u5229\u7528\u8fed\u4ee3\u5668\u53d8\u76f8\u4fee\u6539 map \u91cc\u7684\u503c\u3002 count \u548c contains \u6ca1\u533a\u522b \u5b9e\u9645\u4e0a count \u548c contains \u51fd\u6570\u5c31\u662f\u57fa\u4e8e find \u5b9e\u73b0\u7684\uff0c\u6027\u80fd\u6ca1\u6709\u533a\u522b\uff0cglibc \u6e90\u7801\uff1a #if __cplusplus > 201703L /** * @brief Finds whether an element with the given key exists. * @param __x Key of (key, value) pairs to be located. * @return True if there is an element with the specified key. */ bool contains(const key_type& __x) const { return _M_t.find(__x) != _M_t.end(); } template auto contains(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x), void(), true) { return _M_t._M_find_tr(__x) != _M_t.end(); } #endif /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. * * This function only makes sense for multimaps; for map the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } // \u4ee5\u4e0b\u4e09\u8005\u7b49\u4ef7 m.contains(key) m.count(key) m.find(key) != m.end() end \u4e0d\u80fd\u89e3\u5f15\u7528 \u68c0\u67e5\u8fc7\u4e0d\u662f m.end()\uff0c\u4ee5\u786e\u8ba4\u6210\u529f\u627e\u5230\u540e\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528\u83b7\u53d6\u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c\uff1a map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { auto kv = *it; // \u89e3\u5f15\u7528\u5f97\u5230 K-V \u5bf9 print(kv); // {\"fuck\", 985} print(kv.first); // \"fuck\" print(kv.second); // 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); } find \u7684\u597d\u5904 find \u7684\u9ad8\u6548\u5728\u4e8e\uff0c\u53ef\u4ee5\u628a\u4e24\u6b21\u67e5\u8be2\u5408\u5e76\u6210\u4e00\u6b21\u3002 \u4fdd\u5e95\u5199\u6cd5\uff1a\u5f00\u9500 2 \\log N 2 \\log N if (m.count(\"key\")) { // \u7b2c\u4e00\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(m.at(\"key\")); // \u7b2c\u4e8c\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } \u9ad8\u6548\u5199\u6cd5\uff1a\u5f00\u9500 \\log N \\log N auto it = m.find(\"key\"); // \u4e00\u6b21\u6027\u67e5\u8be2 if (it != m.end()) { // \u67e5\u8be2\u7684\u7ed3\u679c\uff0c\u65e2\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(it->second); // \u4e5f\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } C++17 \u8bed\u6cd5\u7cd6 C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u5982\u4f55\u7b80\u5316 find \u7684\u8fed\u4ee3\u5668\u5224\u65ad auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } auto it = m.find(\"key2\"); // \u7f16\u8bd1\u5668\u62a5\u9519\uff1a\u53d8\u91cf it \u91cd\u590d\u5b9a\u4e49\uff01 if (it != m.end()) { print(it->second); } \u867d\u7136\u5220\u53bb\u524d\u9762\u7684 auto \u53ef\u4ee5\u89e3\u51b3\u95ee\u9898\uff0c\u4f46\u662f\u5982\u679c\u8fd9\u91cc\u662f\u4e0d\u540c\u7c7b\u578b\u7684 map \u5c31\u5c2c\u4e86\uff0c\u5f97\u53e6\u5916\u60f3\u4e00\u4e2a\u53d8\u91cf\u540d\u3002 \u800c C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u6355\u83b7\u7684 it \u662f\u9650\u5236\u5728\u5f53\u524d if \u4f5c\u7528\u57df\u7684\uff0c\u4e0d\u4f1a\u8dd1\u51fa\u53bb\u548c\u522b\u4eba\u53d1\u751f\u51b2\u7a81\u3002 if (auto it = m.find(\"key1\"); it != m.end()) { print(it->second); } if (auto it = m.find(\"key2\"); it != m.end()) { // \u8fd9\u4e2a\u53d8\u91cf it \u662f\u5c40\u57df\u7684\uff0c\u4e0d\u4f1a\u548c\u4e0a\u4e00\u4e2a\u5c40\u57df\u7684 it \u4ea7\u751f\u540d\u5b57\u51b2\u7a81 print(it->second); } \u7b49\u4ef7\u4e8e\uff1a { auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } } \u9898\u5916\u8bdd \u6211\u7ed9 C++ \u6807\u51c6\u59d4\u5458\u4f1a\u63d0\u4e00\u4e2a\u5efa\u8bae\uff0c\u80fd\u4e0d\u80fd\u7ed9\u8fed\u4ee3\u5668\u52a0\u4e00\u4e2a operator bool \u4ee3\u66ff\u70e6\u4eba\u7684 != m.end() \uff1f struct iterator { _RbTreeNode *node; bool operator!=(iterator const &other) const noexcept { return node == other.node; } operator bool() const noexcept { return node; } }; \u90a3\u6837\u7684\u8bdd\u5c31\u53ef\u4ee5\u76f4\u63a5\uff1a if (auto it = m.find(\"key\")) { print(it->second); } \u56e0\u4e3a if-auto \u7701\u7565\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u65f6\uff0c\u9ed8\u8ba4\u5c31\u662f if (auto it = m.find(\"key\"); (bool)it) \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u6ce8\u610f *it \u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u7c7b\u578b\u7684\u952e\u503c\u5bf9\uff0c\u9700\u8981 (*it).second \u624d\u80fd\u83b7\u53d6\u5355\u72ec\u7684\u503c V\u3002 \u597d\u5728 C \u8bed\u8a00\u5c31\u6709 -> \u8fd0\u7b97\u7b26\u4f5c\u4e3a\u8bed\u6cd5\u7cd6\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 it->second \uff0c\u4e0e (*it).second \u7b49\u4ef7\u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { print(it->second); // \u8fed\u4ee3\u5668\u6709\u6548\uff0c\u53ef\u4ee5\u76f4\u63a5\u83b7\u5f97\u503c\u90e8\u5206 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); // \u8fd9\u4e2a\u5206\u652f\u91cc\u4e0d\u5f97\u7528 * \u548c -> \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528 it } \u5927\u591a\u6570\u60c5\u51b5\u4e0b\u6211\u4eec\u67e5\u8be2\u53ea\u9700\u8981\u83b7\u53d6\u503c V \u7684\u90e8\u5206\u5c31\u884c\u4e86\uff0c\u76f4\u63a5 it->second \u5c31\u53ef\u4ee5\u4e86\u2705 \u6ce8\u610f\uff1afind \u627e\u4e0d\u5230\u952e\u65f6\uff0c\u4f1a\u8fd4\u56de m.end() \uff0c\u8fd9\u662f\u4e2a\u65e0\u6548\u8fed\u4ee3\u5668\uff0c\u53ea\u4f5c\u4e3a\u6807\u8bc6\u7b26\u4f7f\u7528\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 find \u6709\u65f6\u4f1a\u8fd4\u56de -1\uff09\u3002 \u6ca1\u6709\u786e\u8ba4 it != m.end() \u524d\uff0c\u4e0d\u53ef\u4ee5\u8bbf\u95ee it->second \uff01\u90a3\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e00\u4e2a\u7a7a\u6307\u9488\uff0c\u4f1a\u9020\u6210 segfault\uff08\u66f4\u4e13\u4e1a\u4e00\u70b9\u8bf4\u662f UB\uff09\u3002 \u8bb0\u4f4f\uff0c\u4e00\u5b9a\u8981\u5728 it != m.end() \u7684\u5206\u652f\u91cc\u624d\u80fd\u8bbf\u95ee it->second \u54e6\uff01\u4f60\u5f97\u5148\u68c0\u67e5\u8fc7\u996d\u7897\u91cc\u6ca1\u6709\u8001\u9f20\ud83d\udca9\u4e4b\u540e\uff0c\u624d\u80fd\u5b89\u5fc3\u5403\u996d\uff01 \u5982\u679c\u4f60\u60f3\u8ba9\u8001\u5988\uff08\u6807\u51c6\u5e93\uff09\u81ea\u52a8\u5e2e\u4f60\u68c0\u67e5\u6709\u6ca1\u6709\u8001\u9f20\ud83d\udca9\uff0c\u90a3\u5c31\u7528\u4f1a\u81ea\u52a8\u62a5\u9519\u7684 at\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 index \u627e\u4e0d\u5230\u76f4\u63a5\u62a5\u9519\uff09\u3002 \u4e4b\u6240\u4ee5\u7528 find\uff0c\u662f\u56e0\u4e3a\u6709\u65f6\u996d\u7897\u91cc\u51fa\u8001\u9f20\ud83d\udca9\uff0c\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff01\u4f8b\u5982\u5f53\u6709\u8001\u9f20\ud83d\udca9\u65f6\u4f60\u53ef\u4ee5\u6539\u5403\u522b\u7684\u96f6\u98df\u3002\u800c at \u8fd9\u4e2a\u826f\u5fc3\u8001\u5988\u5462\uff1f\u4e00\u53d1\u73b0\u8001\u9f20\ud83d\udca9\u5c31\u62d6\u7740\u4f60\u53bb\u8b66\u5bdf\u5c40\u62a5\u6848\uff0c\u96f6\u98df\uff08\u9ed8\u8ba4\u503c\uff09\u4e5f\u4e0d\u8ba9\u4f60\u5403\u4e86\u3002\u4eca\u65e5\u884c\u7a0b\u5168\u90e8\u53d6\u6d88\uff0c\u7ef4\u6743\uff08\u5f02\u5e38\u5904\u7406\uff0c\u627e\u4e0a\u5c42 try-catch \u5757\uff09\u8bbe\u4e3a\u7b2c\u4e00\u8981\u52a1\u3002 iterator find(K const &k); const_iterator find(K const &k) const; \u5982\u679c map \u6ca1\u6709 const \u4fee\u9970\uff0c\u5219\u5176 find \u8fd4\u56de\u7684 it \u4e5f\u662f\u975e const \u8fed\u4ee3\u5668\u3002 const map cm; map::const_iterator cit = cm.find(\"key\"); print(cit->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 cit->second = 1; // \u7f16\u8bd1\u671f\u62a5\u9519: \u4e0d\u5141\u8bb8\u5199\u5165 const \u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c map m; map::iterator it = m.find(\"key\"); print(it->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 it->second = 1; // OK: \u53ef\u4ee5\u5199\u5165 it->second \u53ef\u4ee5\u5199\u5165\uff0cit \u662f\u8fed\u4ee3\u5668\uff0c\u8fed\u4ee3\u5668\u7c7b\u4f3c\u4e8e\u6307\u9488\uff0c\u5199\u5165\u8fed\u4ee3\u5668\u6307\u5411\u7684 second \u5c31\u53ef\u4ee5\u4fee\u6539 map \u91cc\u7684\u503c\u90e8\u5206\u3002 it->first \u662f\u952e\u90e8\u5206\uff0c\u7531\u4e8e map \u7684\u771f\u6b63\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5\u8fd9\u90e8\u5206\u65e0\u6cd5\u88ab\u4fee\u6539\u3002 \u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2 \u4f17\u6240\u5468\u77e5\uff0cPython \u4e2d\u7684 dict \u6709\u4e00\u4e2a m.get(key, defl) \u7684\u529f\u80fd\uff0c\u6548\u679c\u662f\u5f53 key \u4e0d\u5b58\u5728\u65f6\uff0c\u8fd4\u56de defl \u8fd9\u4e2a\u9ed8\u8ba4\u503c\u4ee3\u66ff m[key]\uff0c\u800c C++ \u7684 map \u5374\u6ca1\u6709\uff0c\u53ea\u80fd\u7528\u4e00\u5957\u7ec4\u5408\u62f3\u4ee3\u66ff\uff1a m.count(key) ? m.at(key) : defl \u4f46\u4e0a\u9762\u8fd9\u6837\u5199\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\uff0c\u76f8\u5f53\u4e8e\u67e5\u8be2\u4e86 map \u4e24\u904d\uff0cat \u91cc\u8fd8\u989d\u5916\u505a\u4e86\u4e00\u6b21\u591a\u4f59\u7684\u5f02\u5e38\u5224\u65ad\u3002 \u6b63\u5e38\u6765\u8bf4\u662f\u7528\u901a\u7528 find \u53bb\u627e\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7136\u540e\u5224\u65ad\u662f\u4e0d\u662f end() \u51b3\u5b9a\u8981\u4e0d\u8981\u91c7\u7528\u9ed8\u8ba4\u503c\u3002 auto it = m.find(key); return it != m.end() ? it->second : defl; \u996d\u7897\u91cc\u53d1\u73b0\u4e86\u8001\u9f20\ud83d\udca9\uff1f\u522b\u6025\u7740\u62a5\u8b66\uff0c\u8fd9\u4e5f\u5728\u6211\u7684\u9884\u6599\u4e4b\u4e2d\uff1a\u542f\u7528 B \u8ba1\u5212\uff0c\u6539\u5403 defl \u8fd9\u6b3e\u7f8e\u5473\u96f6\u98df\u5373\u53ef\uff01 \u5982\u679c\u662f\u826f\u5fc3\u8001\u5988 at\uff0c\u5c31\u76f4\u63a5\u542f\u7528 C \u8ba1\u5212\uff1a \u629b\u51fa\u5f02\u5e38\u7136\u540e\u5954\u6e83\u4e86\uff0c\u867d\u7136\u8fd9\u5f88\u65b9\u4fbf\u6211\u4eec\u7a0b\u5e8f\u5458\u8c03\u8bd5\u3002 \u7531\u4e8e\u81ea\u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2\u8fd9\u4e00\u529f\u80fd\u5b9e\u5728\u662f\u592a\u5e38\u7528\u4e86\uff0c\u4e3a\u4e86\u628a\u8fd9\u4e2a\u64cd\u4f5c\u6d53\u7f29\u5230\u4e00\u884c\uff0c\u6211\u5efa\u8bae\u540c\u5b66\u4eec\u5c01\u88c5\u6210\u51fd\u6570\u653e\u5230\u81ea\u5df1\u7684\u9879\u76ee\u516c\u5171\u5934\u6587\u4ef6\uff08\u4e00\u822c\u662f utils.h \u4e4b\u7c7b\u7684\u540d\u79f0\uff09\u91cc\u65b9\u4fbf\u4ee5\u540e\u4f7f\u7528\uff1a template typename M::mapped_type map_get ( M const &m , typename M::key_type const &key , typename M::mapped_type const &defl ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return defl; } } int val = map_get(config, \"timeout\", -1); // \u5982\u679c\u914d\u7f6e\u6587\u4ef6\u91cc\u4e0d\u6307\u5b9a\uff0c\u5219\u9ed8\u8ba4 timeout \u4e3a -1 \u8fd9\u6837\u8fd8\u4e0d\u591f\u4f18\u96c5\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u66f4\u4f18\u96c5\u5730\u8fd0\u7528 C++17 \u7684\u51fd\u6570\u5f0f\u5bb9\u5668 optional\uff1a template std::optional map_get ( M const &m , typename M::key_type const &key ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return std::nullopt; } } \u5f53\u627e\u4e0d\u5230\u65f6\u5c31\u8fd4\u56de nullopt\uff0c\u627e\u5230\u5c31\u8fd4\u56de\u542b\u6709\u503c\u7684 optional\u3002 \u672c\u6bb5\u4ee3\u7801\u5df2\u9644\u5728\u6848\u4f8b\u4ee3\u7801\u5e93\u7684 \u201cmap_get.h\u201d \u6587\u4ef6\u4e2d\uff0c\u7b49\u8bfe\u540e\u53ef\u4ee5\u53bb GitHub \u4e0b\u8f7d\uff0c\u8d76\u7d27\u7528\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u5427\uff01 \u8c03\u7528\u8005\u53ef\u4ee5\u81ea\u884c\u8fd0\u7528 optional \u7684 value_or \u51fd\u6570 1 \u6307\u5b9a\u627e\u4e0d\u5230\u65f6\u91c7\u7528\u7684\u9ed8\u8ba4\u503c\uff1a int val = map_get(config, \"timeout\").value_or(-1); \u5982\u679c\u8981\u5b9e\u73b0 at \u540c\u6837\u7684\u627e\u4e0d\u5230\u5c31\u81ea\u52a8\u62a5\u9519\u529f\u80fd\uff0c\u90a3\u5c31\u6539\u7528 value \u51fd\u6570\uff1a int val = map_get(config, \"timeout\").value(); optional \u5177\u6709 operator bool \u548c\u65e0\u5f02\u5e38\u7684 operator* \uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u914d\u5408 if-auto \u8bed\u6cd5\u7cd6\u4f7f\u7528\uff1a if (auto o_val = map_get(config, \"timeout\")) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u7b49\u4ef7\u4e8e\uff1a auto o_val = map_get(config, \"timeout\"); if (o_val) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u4ee5\u4e0a\u662f\u5178\u578b\u7684\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f (FP)\uff0cC++20 \u8fd8\u5f15\u5165\u4e86\u66f4\u591a\u8fd9\u6837\u7684\u73a9\u610f 2 \uff0c\u7b49\u6709\u7a7a\u4f1a\u4e13\u95e8\u5f00\u8282\u8bfe\u4e3a\u5927\u5bb6\u4e00\u4e00\u4ecb\u7ecd\u3002 auto even = [] (int i) { return 0 == i % 2; }; auto square = [] (int i) { return i * i; }; for (int i: std::views::iota(0, 6) | std::views::filter(even) | std::views::transform(square)) print(i); // 0 4 16 \u73b0\u5728\u5b66\u4e60\u5220\u9664\u5143\u7d20\u7528\u7684 erase \u51fd\u6570\uff0c\u5176\u539f\u578b\u5982\u4e0b 1 \uff1a size_t erase(K const &key); \u6307\u5b9a\u952e\u503c key\uff0cerase \u4f1a\u5220\u9664\u8fd9\u4e2a\u952e\u503c\u5bf9\u5e94\u7684\u5143\u7d20\u3002 \u8fd4\u56de\u4e00\u4e2a\u6574\u6570\uff0c\u8868\u793a\u5220\u9664\u4e86\u591a\u5c11\u4e2a\u5143\u7d20\uff08\u53ea\u80fd\u662f 0 \u6216 1\uff09\u3002 size_t erase(K const &key); erase \u8fd0\u7528\u4e3e\u4f8b\uff1a\u5220\u9664\u4e00\u4e2a\u5143\u7d20 map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); msg.erase(\"fuck\"); print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} {\"hello\": \"world\"} size_t erase(K const &key); erase \u7684\u8fd4\u56de\u503c\u548c count \u4e00\u6837\uff0c\u8fd4\u56de\u6210\u529f\u5220\u9664\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 erase \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u662f\u5426\u5220\u9664\u6210\u529f\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.erase(\"fuck\")) { print(\"\u5220\u9664fuck\u6210\u529f\"); } else { print(\"\u5220\u9664fuck\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } if (msg.erase(\"dick\")) { print(\"\u5220\u9664dick\u6210\u529f\"); } else { print(\"\u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} \u5220\u9664fuck\u6210\u529f \u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728 {\"hello\": \"world\"} size_t erase(K const &key); // \u6307\u5b9a\u952e\u7248 iterator erase(iterator it); // \u5df2\u77e5\u4f4d\u7f6e\u7248 \u533a\u522b\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u5b9e\u9645\u4e0a\u9700\u8981\u5148\u8c03\u7528 find(key) \u627e\u5230\u5143\u7d20\u4f4d\u7f6e\uff0c\u7136\u540e\u624d\u80fd\u5220\u9664\uff0c\u800c\u4e14\u8fd8\u6709\u627e\u4e0d\u5230\u7684\u53ef\u80fd\u6027\u3002 \u800c\u5df2\u77e5\u4f4d\u7f6e\u7684\u8bdd\uff08\u6bd4\u5982\u4f60\u5df2\u7ecf\u4e8b\u5148\u7528 find \u627e\u5230\u4e86\u5143\u7d20\u4f4d\u7f6e\uff09\uff0c\u53ef\u4ee5\u7528 erase(it) \u76f4\u63a5\u7528\u8fed\u4ee3\u5668\u4f5c\u4e3a\u53c2\u6570 \u590d\u6742\u5ea6\u4e0d\u540c\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(\\log N) O(\\log N) \u3002 \u5df2\u77e5\u4f4d\u7f6e\u7248 erase(it) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(1)+ O(1)+ \uff0c\u66f4\u9ad8\u6548\u3002 \u5176\u4e2d + + \u4ee3\u8868\u8fd9\u662f\u5e73\u644a\uff08Amortized\uff09\u4e0b\u6765\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8fd9\u662f\u56e0\u4e3a\u5373\u4f7f\u5df2\u77e5\u4f4d\u7f6e\uff0cerase \u6709\u53ef\u80fd\u6d89\u53ca\u6811\u7684\u66f4\u65b0\uff0c\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u4f46\u662f\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u9700\u8981\u7684\u66f4\u65b0\u5f88\u5c11\uff0c\u5e73\u5747\u4e0b\u6765\u662f O(1) O(1) \u7684\u3002 \u8fd9\u79cd\u60c5\u51b5\u5c31\u4f1a\u7528\u8bb0\u53f7 O(1)+ O(1)+ \u6765\u8868\u793a\u3002 erase(key) \u53ef\u80fd\u662f\u57fa\u4e8e erase(it) \u5b9e\u73b0\u7684\uff1a size_t erase(K const &key) { // \u5c0f\u5f6d\u8001\u5e08\u731c\u60f3\u6807\u51c6\u5e93\u5185\u90e8 auto it = this->find(key); // O(log N) if (it != this->end()) { this->erase(it); // O(1)+ return 1; // \u627e\u5230\u4e86\uff0c\u5220\u9664\u6210\u529f } else { return 0; // \u627e\u4e0d\u5230\uff0c\u6ca1\u6709\u5220\u9664 } } // \u5f00\u9500\u5927\u7684 find(key) \u4f1a\u8986\u76d6\u5c0f\u7684 erase(it)\uff0c\u6240\u4ee5 erase(key) \u7684\u603b\u590d\u6742\u5ea6\u4e3a O(log N) \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u8fd4\u56de\u7684\u662f\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u4f4d\u7f6e\u3002 \u7531\u4e8e map \u5185\u90e8\u4fdd\u6301\u952e\u4ece\u5c0f\u5230\u5927\u5347\u5e8f\u6392\u5217\uff0c\u6240\u8c13\u7684\u4e0b\u4e00\u4e2a\u5c31\u662f\u952e\u6bd4\u5f53\u524d\u952e\u5927\u4e00\u4e2a\u7684\u5143\u7d20\uff0c\u4f8b\u5982\uff1a {\"answer\": 42, \"hello\": 985, \"world\": 211} erase(find(\u201canswer\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201chello\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201chello\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201canswer\u201d\u3002 erase(find(\u201chello\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201cworld\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201cworld\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201chello\u201d\u3002 erase(find(\u201cworld\u201d)) \u4f1a\u8fd4\u56de end()\uff0c\u56e0\u4e3a \u201cworld\u201d \u5df2\u7ecf\u662f\u6700\u5927\u952e\uff0c\u6ca1\u6709\u4e0b\u4e00\u4e2a\u3002 \u6b64\u5916 erase(it) \u8fd8\u6709\u6027\u80fd\u4e0a\u7684\u4f18\u52bf\uff1a \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u7684\u590d\u6742\u5ea6\u662f O(1)+ O(1)+ \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u590d\u6742\u5ea6\u662f O(\\log N) O(\\log N) \u5f53\u5df2\u77e5\u6307\u5411\u8981\u5220\u9664\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u65f6\uff08\u4f8b\u5982\u5148\u901a\u8fc7 find \u627e\u5230\uff09\uff0c\u76f4\u63a5\u6307\u5b9a\u90a3\u4e2a\u8fed\u4ee3\u5668\u6bd4\u6307\u5b9a\u952e\u53c2\u6570\u66f4\u9ad8\u6548\u3002 \u5220\u9664\u6210\u7ee9\u6700\u5dee\u7684\u5b66\u751f\uff1a score.erase(score.begin()); \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 \u5e38\u89c1\u9700\u6c42\u573a\u666f\uff1a\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u9519\u8bef\u793a\u8303\uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto const &[k, v]: msg) { if (k.starts_with(\"fuck\")) { msg.erase(k); // \u904d\u5386\u8fc7\u7a0b\u4e2d\u5220\u9664\u5f53\u524d\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u6b63\u5728\u904d\u5386\u4e2d\u7684\u8fed\u4ee3\u5668\u5931\u6548\uff0c\u5954\u6e83 } } print(msg); Segmentation fault (core dumped) \u5f15\u51fa\u95ee\u9898\uff1a\u8fed\u4ee3\u5668\u5931\u6548 \u6bcf\u5f53\u5f80 map \u4e2d\u63d2\u5165\u65b0\u5143\u7d20\u65f6\uff0c\u539f\u5148\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u4e0d\u4f1a\u5931\u6548\u3002 \u5220\u9664 map \u4e2d\u7684\u5176\u4ed6\u5143\u7d20\u65f6\uff0c\u4e5f\u4e0d\u4f1a\u5931\u6548\u3002 \u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\uff0c\u624d\u4f1a\u5931\u6548 \u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); m[\"dick\"] = 211; print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"dick\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"fuck\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 map \u6bd4\u8d77 unordered_map \u6765\uff0c\u5df2\u7ecf\u662f\u975e\u5e38\u7a33\u5b9a\uff0c\u968f\u4fbf\u589e\u5220\u6539\u67e5\u90fd\u4e0d\u4f1a\u8fed\u4ee3\u5668\u5931\u6548\u3002 \u53ea\u6709\u4e00\u4e2a\u4f8b\u5916\uff1a\u5220\u9664\u7684\u5143\u7d20\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u3002 \u4f60\u62ff\u7740\u4e2a\u4f60\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u7ed3\u679c\u4f60\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\uff0c\u8fd8\u6478\u4e0d\u7740\u5934\u8111\u201c\u5947\u602a\uff0c\u660e\u660e\u5c31\u662f\u8fd9\u4e2a\u5730\u5740\u5440\u201d\uff0c\u8fd9\u65f6\u786e\u5b9e\u65e0\u8bba\u5982\u4f55\u90fd\u4e0d\u80fd\u907f\u514d\u5931\u6548\uff0c\u4e0d\u80fd\u602a map\u3002 \u800c\u521a\u521a\u7684\u6848\u4f8b\u4e2d\uff0c\u6211\u4eec\u5220\u9664\u7684\u6070\u597d\u5c31\u662f\u5f53\u524d\u6b63\u5728\u904d\u5386\u7684\u8fed\u4ee3\u5668\u6b63\u5728\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\uff08\u5373\u4f7f\u4f60\u7528\u4e86 range-based loop \u8bed\u6cd5\u7cd6\u4ed6\u80cc\u540e\u8fd8\u662f\u8fed\u4ee3\u5668\u904d\u5386\uff09\u3002 \u800c\u5f53\u4f60\u5bf9\u7740\u4e00\u4e2a\u5931\u6548\u7684\u8fed\u4ee3\u5668\u6267\u884c ++it \u65f6\uff0c\u5c31\u4ea7\u751f\u4e86 segfault \u9519\u8bef\u3002\u56e0\u4e3a\u7ea2\u9ed1\u6811\u7684\u8fed\u4ee3\u5668\u8981\u627e\u5230\u201c\u4e0b\u4e00\u4e2a\u201d\u8282\u70b9\uff0c\u9700\u8981\u8bbf\u95ee\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u4e2d\u5b58\u7684 next \u6307\u9488\uff0c\u800c\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u90fd\u5df2\u7ecf\u5220\u9664\u4e86\u5df2\u7ecf\u6790\u6784\u4e86\u5df2\u7ecf\u91ca\u653e\u5185\u5b58\u4e86\uff0c\u91cc\u9762\u5b58\u7684 next \u6307\u9488\u4e5f\u5df2\u7ecf\u91ca\u653e\uff0c\u88ab\u5176\u4ed6\u7cfb\u7edf\u6570\u636e\u8986\u76d6\uff0c\u8fd9\u65f6\u4f1a\u8bbf\u95ee\u5230\u9519\u8bef\u7684\u6307\u9488\u2014\u2014\u91ce\u6307\u9488\u3002 \u6240\u4ee5\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u5b8c\u6574\u7684\u5267\u60c5\u662f\uff1a \u4f60\u6709\u597d\u591a\u670b\u53cb\uff0c\u4eca\u5929\u4f60\u8981\u628a\u4ed6\u4eec\u5168\u70b8\u4e86\u3002 1\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 2\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77403\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 \u2026 \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it /* \u8fdb\u5165\u71c3\u70e7\u4e2d\u76841\u53f7\u670b\u53cb\u5bb6 */) { m.erase(it); // \u4e00\u53d1 RPG \u5bfc\u5f39\u70b8\u6bc11\u53f7\u670b\u53cb\u5bb6 } \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it) { m.erase(it); // it \u5df2\u7ecf\u5931\u6548\uff01 } \u6b63\u786e\u7684\u505a\u6cd5\u662f\uff0c\u5148\u8fdb\u51651\u53f7\u670b\u53cb\u5bb6\uff0c\u5b89\u5168\u53d6\u51fa\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761\u540e\uff0c\u518d\u6765\u4e00\u53d1 RPG \u628a1\u53f7\u670b\u53cb\u5bb6\u70b8\u6389\u3002\u8fd9\u6837\u624d\u80fd\u987a\u5229\u627e\u52302\u53f7\u670b\u53cb\u5bb6\uff0c\u4ee5\u6b64\u7c7b\u63a8\u7ee7\u7eed\u62c63\u53f7\u2026\u2026 for (auto it = m.begin(); it != m.end(); ) { auto next_it = it; // \u5148\u8fdb\u51651\u53f7\u670b\u53cb\u7684\u5bb6 ++next_it; // \u62ff\u51fa\u5199\u67092\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761 m.erase(it); // \u518d\u53d1\u5c04 RPG \u5bfc\u5f39 it = next_it; // \u524d\u5f802\u53f7\u670b\u53cb\u5bb6 } \u6ce8\u610f\u5230 erase \u4f1a\u8fd4\u56de\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\u8fd9\u4e2a RPG \u5bfc\u5f39\u975e\u5e38\u667a\u80fd\uff0c\u597d\u50cf\u4ed6\u5c31\u662f\u4e13\u4e3a\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u8bbe\u8ba1\u7684\u4e00\u6837\uff1a\u4ed6\u80fd\u5728\u70b8\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u524d\uff0c\u81ea\u52a8\u62ff\u5230\u5176\u4e2d\u7684\u5b57\u6761\uff0c\u5e76\u628a\u4ed6\u901a\u8fc7\u201c\u5f39\u5c04\u5ea7\u6905\u201d\u5f39\u51fa\u6765\u9001\u5230\u95e8\u5916\u7684\u4f60\u624b\u4e0a\uff0c\u628a\u7eb8\u6761\u5b89\u5168\u9001\u51fa\u6765\u540e\uff0c\u518d\u7206\u70b8\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u3002\u8fd9\u6837\u4f60\u5c31\u4e0d\u7528\u5192\u9669\u8fdb\u5165\u71c3\u70e7\u7684\u623f\u5c4b\u62ff\u5b57\u6761\uff08\u8fed\u4ee3\u5668\u5931\u6548\u5bfc\u81f4 segfault\uff09\uff0c\u4e5f\u4e0d\u7528\u5148\u52b3\u70e6\u60a8\u81ea\u5df1\u5148\u8fdb\u53bb\u4e00\u8d9f\u623f\u5c4b\u62ff\u5b57\u6761\u4e86\uff08\u4e0a\u4e00\u9875\u4e2d\u90a3\u6837\u63d0\u524d\u4fdd\u5b58 next_it\uff09\u3002 for (auto it = m.begin(); it != m.end(); ) { it = m.erase(it); // \u8fd9\u6b3e RPG \u5bfc\u5f39\u201c\u667a\u80fd\u5730\u201d\u5728\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u540c\u65f6\u628a\u5176\u4e2d\u7684\u5b57\u6761\u62ff\u51fa\u6765\u4e86!? } \u53ea\u662f\u6ce8\u610f\u8fd9\u91cc for \u5faa\u73af\u7684\u6b65\u8fdb\u6761\u4ef6 ++it \u8981\u5220\u6389\uff0c\u56e0\u4e3a\u667a\u80fd\u7684 RPG \u5bfc\u5f39 it = m.erase(it) \u5df2\u7ecf\u5e2e\u4f60\u6b65\u8fdb\u4e86\u3002 \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u6b63\u89e3 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto it = m.begin(); it != m.end(); ) { // \u6ca1\u6709 ++it auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u4e0d\u5954\u6e83 for (auto it = m.begin(); it != m.end(); ) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } \u5954\u6e83 for (auto it = m.begin(); it != m.end(); ++it) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { msg.erase(it); // \u6216\u8005 msg.erase(k); } } C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if \u6279\u91cf\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff08C++20 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; std::erase_if(msg, [&] (auto const &kv) { auto &[k, v] = kv; return k.starts_with(\"fuck\"); }); print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u5982\u679c\u4f60\u641e\u4e0d\u61c2\u8fed\u4ee3\u5668\u8fd9\u4e9b\uff0c\u8fd9\u91cc\u6211\u63d0\u4f9b\u4e00\u4e2a\u4fdd\u5e95\u5199\u6cd5\uff0c\u5148\u628a\u952e\u63d0\u524d\u4fdd\u5b58\u5230\u4e00\u4e2a vector \u4e2d\u53bb\uff1a map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; vector keys; // vector \u6216\u8005 set \u90fd\u53ef\u4ee5 for (auto const &[k, v]: msg) { // \u5148\u628a\u6240\u6709\u952e\u63d0\u524d\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc keys.push_back(k); } for (auto const &k: keys) { // \u904d\u5386\u521a\u624d\u4fdd\u5b58\u7684\u952e if (k.starts_with(\"fuck\")) { msg.erase(k); // \u952e\u503c\u5bf9\u5df2\u7ecf\u63d0\u524d\u6df1\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc\uff0c\u8fd9\u65f6\u5220\u9664 map \u91cc\u7684\u952e\u4e0d\u4f1a\u5954\u6e83 } } \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u795b\u9b45\u5927\u5e08\u3002 \u8fd8\u662f\u641e\u4e0d\u61c2\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u65b0\u5efa\u4e00\u4e2a map\uff0c\u6761\u4ef6\u53cd\u4e4b\uff0c\u628a\u4e0d\u9700\u8981\u5220\u9664\u7684\u5143\u7d20\u63d2\u5165\u65b0 map\uff0c\u8fc7\u6ee4\u51fa\u9700\u8981\u4fdd\u7559\u7684\u5143\u7d20\uff0c\u6700\u540e\u518d\u4e00\u6b21\u6027\u7528\u65b0 map \u8986\u76d6\u65e7 map\u3002 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; map newmsg; for (auto const &[k, v]: msg) { if (!k.starts_with(\"fuck\")) { // \u6ce8\u610f\u8fd9\u91cc\u6761\u4ef6\u53cd\u4e86\uff0c\u4e0d\u9700\u8981\u5220\u9664\u7684\u624d\u63d2\u5165 newmsg newmsg[k] = v; } } msg = std::move(newmsg); // \u8986\u76d6\u65e7\u7684 map\uff0c\u7528\u66f4\u9ad8\u6548\u7684\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff0cO(1) \u590d\u6742\u5ea6 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u4fdd\u5e95\u5927\u5e08\u3002 \u63a5\u4e0b\u6765\u5f00\u59cb\u5b66\u4e60\u5982\u4f55\u63d2\u5165\u5143\u7d20\uff0cmap \u7684\u6210\u5458 insert \u51fd\u6570\u539f\u578b\u5982\u4e0b 1 \uff1a pair insert(pair const &kv); pair insert(pair &&kv); \u4ed6\u7684\u53c2\u6570\u7c7b\u578b\u5c31\u662f\u521a\u521a\u4ecb\u7ecd\u7684 value_type \uff0c\u4e5f\u5c31\u662f pair \u3002 pair \u662f\u4e00\u4e2a STL \u4e2d\u5e38\u89c1\u7684\u6a21\u677f\u7c7b\u578b\uff0c pair \u6709\u4e24\u4e2a\u6210\u5458\u53d8\u91cf\uff1a first\uff1aK \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u952e second\uff1aV \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u503c \u6211\u79f0\u4e4b\u4e3a\u201d\u952e\u503c\u5bf9\u201d\u3002 \u8bd5\u7740\u7528 insert \u63d2\u5165\u952e\u503c\u5bf9\uff1a map m; pair p; p.first = \"fuck\"; // \u952e p.second = 985; // \u503c m.insert(p); // pair \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a insert \u53c2\u6570\u6240\u9700\u7684 pair print(m); \u7ed3\u679c\uff1a {\"fuck\": 985} \u7b80\u5316 insert \u76f4\u63a5\u4f7f\u7528 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u521d\u59cb\u5316 first \u548c second pair p(\"fuck\", 985); m.insert(p); \u4e0d\u7528\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0cpair \u8868\u8fbe\u5f0f\u76f4\u63a5\u4f5c\u4e3a insert \u51fd\u6570\u7684\u53c2\u6570 m.insert(pair(\"fuck\", 985)); \u53ef\u4ee5\u7528 std::make_pair \u8fd9\u4e2a\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u63a8\u5bfc\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u7701\u7565 m.insert(make_pair(\"fuck\", 985)); // \u867d\u7136\u4f1a\u63a8\u5bfc\u4e3a pair \u4f46\u8fd8\u662f\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a pair \u7531\u4e8e insert \u51fd\u6570\u539f\u578b\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528 C++11 \u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868 {\u2026}\uff0c\u65e0\u9700\u6307\u5b9a\u7c7b\u578b m.insert({\"fuck\", 985}); // \u2705 \u56e0\u6b64\uff0cinsert \u7684\u6700\u4f73\u7528\u6cd5\u662f\uff1a map m; m.insert({\"key\", \"val\"}); insert \u63d2\u5165\u548c [] \u5199\u5165\u7684\u5f02\u540c\uff1a \u540c\uff1a\u5f53\u952e K \u4e0d\u5b58\u5728\u65f6\uff0cinsert \u548c [] \u90fd\u4f1a\u521b\u5efa\u952e\u503c\u5bf9\u3002 \u5f02\uff1a\u5f53\u952e K \u5df2\u7ecf\u5b58\u5728\u65f6\uff0cinsert \u4e0d\u4f1a\u8986\u76d6\uff0c\u9ed8\u9ed8\u79bb\u5f00\uff1b\u800c [] \u4f1a\u8986\u76d6\u65e7\u7684\u503c\u3002 \u4f8b\u5b50\uff1a map m; m.insert({\"key\", \"old\"}); m.insert({\"key\", \"new\"}); // \u63d2\u5165\u5931\u8d25\uff0c\u9ed8\u9ed8\u653e\u5f03\u4e0d\u51fa\u9519 print(m); {\"key\": \"old\"} map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; // \u5df2\u7ecf\u5b58\u5728\uff1f\u6211\u8e0f\u9a6c\u5f3a\u884c\u8986\u76d6\uff01 print(m); {\"key\": \"new\"} insert \u7684\u8fd4\u56de\u503c\u662f pair \u7c7b\u578b\uff0c STL \u7684\u5c3f\u6027\uff1a\u5728\u9700\u8981\u4e00\u6b21\u6027\u8fd4\u56de\u4e24\u4e2a\u503c\u65f6\u559c\u6b22\u7528 pair \u3002 \u8fd9\u53c8\u662f\u4e00\u4e2a pair \u7c7b\u578b\uff0c\u5176\u5177\u6709\u4e24\u4e2a\u6210\u5458\uff1a first\uff1aiterator \u7c7b\u578b\uff0c\u662f\u4e2a\u8fed\u4ee3\u5668 second\uff1abool \u7c7b\u578b\uff0c\u8868\u793a\u63d2\u5165\u6210\u529f\u4e0e\u5426\uff0c\u5982\u679c\u53d1\u751f\u952e\u51b2\u7a81\u5219\u4e3a false \u5176\u4e2d first \u8fd9\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\uff1a \u5982\u679c\u63d2\u5165\u6210\u529f\uff08second \u4e3a true\uff09\uff0c\u6307\u5411\u521a\u521a\u6210\u529f\u63d2\u5165\u7684\u5143\u7d20\u4f4d\u7f6e \u5982\u679c\u63d2\u5165\u5931\u8d25\uff08second \u4e3a false\uff09\uff0c\u8bf4\u660e\u5df2\u7ecf\u6709\u76f8\u540c\u7684\u952e K \u5b58\u5728\uff0c\u53d1\u751f\u4e86\u952e\u51b2\u7a81\uff0c\u6307\u5411\u5df2\u7ecf\u5b58\u5728\u7684\u90a3\u4e2a\u5143\u7d20 \u5176\u5b9e insert \u8fd4\u56de\u7684 first \u8fed\u4ee3\u5668\u7b49\u4ef7\u4e8e\u63d2\u5165\u4ee5\u540e\u518d\u91cd\u65b0\u7528 find \u627e\u5230\u521a\u521a\u63d2\u5165\u7684\u90a3\u4e2a\u952e\uff0c\u53ea\u662f\u6548\u7387\u66f4\u9ad8\uff1a auto it = m.insert({k, v}).first; // \u9ad8\u6548\uff0c\u53ea\u9700\u904d\u5386\u4e00\u6b21 m.insert({k, v}); // \u63d2\u5165\u5b8c\u5c31\u5fd8\u4e8b\u4e86 auto it = m.find(k); // \u91cd\u65b0\u904d\u5386\u7b2c\u4e8c\u6b21\uff0c\u4f46\u7ed3\u679c\u4e00\u6837 \u53c2\u8003 C \u7f16\u7a0b\u7f51 1 \u5bf9 insert \u8fd4\u56de\u503c\u7684\u89e3\u91ca\uff1a \u5f53\u8be5\u65b9\u6cd5\u5c06\u65b0\u952e\u503c\u5bf9\u6210\u529f\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u65f6\uff0c\u8fd4\u56de\u7684\u8fed\u4ee3\u5668\u6307\u5411\u65b0\u6dfb\u52a0\u7684\u952e\u503c\u5bf9\uff1b \u53cd\u4e4b\uff0c\u5982\u679c\u6dfb\u52a0\u5931\u8d25\uff0c\u8be5\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\u5bb9\u5668\u4e2d\u548c\u8981\u6dfb\u52a0\u952e\u503c\u5bf9\u952e\u76f8\u540c\u7684\u90a3\u4e2a\u952e\u503c\u5bf9\u3002 \u53ef\u4ee5\u7528 insert \u8fd4\u56de\u7684 second \u5224\u65ad\u63d2\u5165\u591a\u6b21\u662f\u5426\u6210\u529f\uff1a map m; print(m.insert({\"key\", \"old\"}).second); // true print(m.insert({\"key\", \"new\"}).second); // false m.erase(\"key\"); // \u628a\u539f\u6765\u7684 {\"key\", \"old\"} \u5220\u4e86 print(m.insert({\"key\", \"new\"}).second); // true \u4e5f\u53ef\u4ee5\u7528 structured-binding \u8bed\u6cd5\u62c6\u89e3\u4ed6\u8fd4\u56de\u7684 pair \uff1a map counter; auto [it, success] = counter.insert(\"key\", 1); // \u76f4\u63a5\u7528 if (!success) { // \u5982\u679c\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4fee\u6539\u5176\u503c+1 it->second = it->second + 1; } else { // \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6253\u5370\u4ee5\u4e0b\u4fe1\u606f print(\"created a new entry!\"); } \u4ee5\u4e0a\u8fd9\u4e00\u957f\u4e32\u4ee3\u7801\u548c\u4e4b\u524d\u201c\u4f18\u96c5\u201d\u7684\u8ba1\u6570 [] \u7b49\u4ef7\uff1a counter[\"key\"]++; insert_or_assign \u5728 C++17 \u4e2d\uff0c[] \u5199\u5165\u6709\u4e86\u4e2a\u66f4\u9ad8\u6548\u7684\u66ff\u4ee3\u54c1 insert_or_assign 1 \uff1a pair insert_or_assign(K const &k, V v); pair insert_or_assign(K &&k, V v); \u6b63\u5982\u4ed6\u540d\u5b57\u7684\u542b\u4e49\uff0c\u201c\u63d2\u5165\u6216\u8005\u5199\u5165\u201d\uff1a \u5982\u679c K \u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff08\u63d2\u5165\uff09 \u5982\u679c K \u5df2\u7ecf\u5b58\u5728\u5219\u8986\u76d6\uff08\u5199\u5165\uff09 \u7528\u6cd5\u5982\u4e0b\uff1a m.insert_or_assign(\"key\", \"new\"); // \u4e0e insert \u4e0d\u540c\uff0c\u4ed6\u4e0d\u9700\u8981 {...}\uff0c\u4ed6\u7684\u53c2\u6570\u5c31\u662f\u4e24\u4e2a\u5355\u72ec\u7684 K \u548c V \u8fd4\u56de\u503c\u4f9d\u65e7\u662f pair \u3002\u7531\u4e8e\u8fd9\u51fd\u6570\u5728\u952e\u51b2\u7a81\u65f6\u4f1a\u8986\u76d6\uff0c\u6309\u7406\u8bf4\u662f\u5fc5\u5b9a\u6210\u529f\u4e86\uff0c\u56e0\u6b64\u8fd9\u4e2a bool \u7684\u542b\u4e49\u4ece\u201c\u662f\u5426\u63d2\u5165\u6210\u529f\u201d\u53d8\u4e3a\u201c\u662f\u5426\u521b\u5efa\u4e86\u5143\u7d20\u201d\uff0c\u5982\u679c\u662f\u521b\u5efa\u7684\u65b0\u5143\u7d20\u8fd4\u56detrue\uff0c\u5982\u679c\u8986\u76d6\u4e86\u65e7\u5143\u7d20\u8fd4\u56defalse\u3002 insert_or_assign \u7684\u4f18\u52bf \u770b\u6765 insert_or_assign \u548c [] \u7684\u6548\u679c\u5b8c\u5168\u76f8\u540c\uff01\u90fd\u662f\u5728\u952e\u503c\u51b2\u7a81\u65f6\u8986\u76d6\u65e7\u503c\u3002 \u65e2\u7136 [] \u5df2\u7ecf\u53ef\u4ee5\u505a\u5230\u540c\u6837\u7684\u6548\u679c\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u53d1\u660e\u4e2a insert_or_assign \u5462\uff1f insert_or_assign \u7684\u4f18\u70b9\u662f \u4e0d\u9700\u8981\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 \uff0c\u53ef\u4ee5\u63d0\u5347\u6027\u80fd\u3002 \u5176\u5e94\u7528\u573a\u666f\u6709\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff1a \u23f1 \u60a8\u7279\u522b\u5728\u4e4e\u6027\u80fd \u274c \u6709\u65f6 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u7528 [] \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \ud83e\udd75 \u5f3a\u8feb\u75c7\u53d1\u4f5c \u5426\u5219\u7528 [] \u5199\u5165\u4e5f\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u800c\u4e14 insert_or_assign \u80fd\u53d6\u4ee3 [] \u7684\u5c97\u4f4d\u4ec5\u9650\u4e8e\u7eaf\u5199\u5165\uff0c\u4e4b\u524d counter[key]++ \u8fd9\u79cd\u201c\u4f18\u96c5\u201d\u5199\u6cd5\u4f9d\u7136\u662f\u9700\u8981\u7528 [] \u7684\u3002 \u6548\u7387\u95ee\u9898 \u521b\u5efa\u65b0\u952e\u65f6\uff0cinsert_or_assign \u66f4\u9ad8\u6548\u3002 [] map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 V() \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) insert_or_assign map m; m.insert_or_assign(\"key\", \"old\"); m.insert_or_assign(\"key\", \"new\"); print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u6784\u9020\u51fd\u6570 V(V &&) \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 \u603b\u7ed3\uff0c\u5982\u679c\u4f60\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u5e76\u4e14\u662f C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 insert_or_assign \u8bfb\u53d6\u7528 at \u5982\u679c\u6ca1\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u6216\u8005\u4f60\u7684\u7f16\u8bd1\u5668\u4e0d\u652f\u6301 C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 [] \u8bfb\u53d6\u7528 at \u6700\u540e\uff0c\u5982\u679c\u4f60\u662f\u8fd8\u539f\u8bba\u8005\uff0c\u53ea\u9700\u8981 find \u548c insert \u51fd\u6570\u5c31\u662f\u5b8c\u5907\u7684\u4e86\uff0c\u522b\u7684\u51fd\u6570\u90fd\u4e0d\u7528\u53bb\u8bb0\u3002\u6240\u6709 at\u3001[]\u3001insert_or_assign \u4e4b\u7c7b\u7684\u64cd\u4f5c\u90fd\u53ef\u4ee5\u901a\u8fc7 find \u548c insert \u7684\u7ec4\u5408\u62f3\u5b9e\u73b0\uff0c\u4f8b\u5982\u521a\u521a\u6211\u4eec\u81ea\u5b9a\u4e49\u7684 map_get\u3002 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u56de\u987e\u4e4b\u524d\u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u5982\u679c\u6709\u91cd\u590d\uff0c\u5982\u4f55\u533a\u5206\u627e\u7b2c\u4e00\u4e2a\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\uff1f \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u6700\u540e\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert_or_assign(arr[i], i); // \u7b49\u4ef7\u4e8e arrinv[arr[i]] = i; } \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u7b2c\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert({arr[i], i}); } \u6279\u91cf insert \u521a\u521a\u4ecb\u7ecd\u7684\u90a3\u4e9b insert \u4e00\u6b21\u53ea\u80fd\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0cinsert \u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u7248\u672c\uff0c\u7528\u4e8e\u6279\u91cf\u63d2\u5165\u4e00\u7cfb\u5217\u5143\u7d20\u3002 template void insert(InputIt beg, InputIt end); \u53c2\u6570 1 \u662f\u4e24\u4e2a\u8fed\u4ee3\u5668 beg \u548c end\uff0c\u7ec4\u6210\u4e00\u4e2a\u533a\u95f4\uff0c\u4e4b\u95f4\u662f\u4f60\u8981\u63d2\u5165\u7684\u6570\u636e\u3002 \u8be5\u533a\u95f4\u53ef\u4ee5\u662f\u4efb\u4f55\u5176\u4ed6\u5bb9\u5668\u7684 begin() \u548c end() \u8fed\u4ee3\u5668\u2014\u2014\u90a3\u4f1a\u628a\u8be5\u5bb9\u5668\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u63d2\u5165\u5230\u672c map \u4e2d\u53bb\u3002 \u4f8b\u5982\uff0c\u628a vector \u4e2d\u7684\u952e\u503c\u5bf9\u6279\u91cf\u63d2\u5165 map\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); // {\"delay\": 211, \"timeout\": 985} \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6ce8\uff1a\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5982\u679c vector \u4e2d\u6709\u91cd\u590d\u7684\u952e\uff0c\u5219\u4f1a\u4ee5\u952e\u7b2c\u4e00\u6b21\u51fa\u73b0\u65f6\u7684\u503c\u4e3a\u51c6\uff0c\u4e4b\u540e\u91cd\u590d\u51fa\u73b0\u7684\u952e\u4f1a\u88ab\u5ffd\u89c6\u3002 vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); {\"delay\": 211, \"timeout\": 985} vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config = { {\"timeout\", 404}, }; config.insert(kvs.begin(), kvs.end()); print(config); vector> v; {\"delay\": 211, \"timeout\": 404} \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u6279\u91cf insert \u8fd0\u7528\u6848\u4f8b\uff1a\u4e24\u4e2a map \u5408\u5e76 \u8fd9\u4e2a\u6279\u91cf insert \u8f93\u5165\u7684\u8fed\u4ee3\u5668\u53ef\u4ee5\u662f\u4efb\u4f55\u5bb9\u5668\uff0c\u751a\u81f3\u53ef\u4ee5\u662f\u53e6\u4e00\u4e2a map \u5bb9\u5668\u3002 \u8fd0\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u4e24\u4e2a map \u7684\u5e76\u96c6\u64cd\u4f5c\u3002 map m1 = { // \u7b2c\u4e00\u4e2a map {\"answer\", 42}, {\"timeout\", 7}, }; map m2 = { // \u7b2c\u4e8c\u4e2a map {\"timeout\", 985}, {\"delay\", 211}, }; m1.insert(m2.begin(), m2.end()); // \u628a m2 \u7684\u5185\u5bb9\u4e0e m1 \u5408\u5e76\uff0c\u7ed3\u679c\u5199\u56de\u5230 m1 print(m1); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd8\u662f\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5f53\u9047\u5230\u91cd\u590d\u7684\u952e\u65f6\uff08\u4f8b\u5982\u4e0a\u9762\u7684 \u201ctimeout\u201d\uff09\uff0c\u4f1a\u4ee5 m1 \u4e2d\u7684\u503c\u4e3a\u51c6\u3002 \u5c31\u5730\u5199\u5165\uff01 \u4f7f\u7528 m1.insert(m2.begin(), m2.end()) \u540e\uff0c\u5408\u5e76\u7684\u7ed3\u679c\u4f1a\u5c31\u5730\u5199\u5165 m1\u3002 \u5982\u679c\u5e0c\u671b\u5408\u5e76\u7ed3\u679c\u653e\u5230\u4e00\u4e2a\u65b0\u7684 map \u5bb9\u5668\u4e2d\u800c\u4e0d\u662f\u5c31\u5730\u4fee\u6539 m1\uff0c\u8bf7\u5148\u81ea\u884c\u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d\uff1a const map m1 = { // \u7b2c\u4e00\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"answer\", 42}, {\"timeout\", 7}, }; const map m2 = { // \u7b2c\u4e8c\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"timeout\", 985}, {\"delay\", 211}, }; auto m12 = m1; // \u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d m12\uff0c\u907f\u514d insert \u5c31\u5730\u4fee\u6539 m1 m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 auto m12 = m1; m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m1 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u521a\u521a\u5199\u7684 m1 \u548c m2 \u5408\u5e76\uff0c\u9047\u5230\u91cd\u590d\u65f6\u4f1a\u4f18\u5148\u91c7\u53d6 m1 \u91cc\u7684\u503c\uff0c\u5982\u679c\u5e0c\u671b\u4f18\u5148\u91c7\u53d6 m2 \u7684\u5462\uff1f\u53cd\u4e00\u53cd\u5c31\u53ef\u4ee5\u4e86\uff1a auto m12 = m2; m12.insert(m1.begin(), m1.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m2 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 985} \u8981\u662f\u5b66\u4e0d\u4f1a\u6279\u91cf insert\uff0c\u90a3\u624b\u5199\u4e00\u4e2a for \u5faa\u73af\u904d\u5386 m2\uff0c\u7136\u540e m1.insert_or_assign(k2, v2) \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u603b\u4e4b\u8981\u61c2\u5f97\u53d8\u901a\uff0c\u52a8\u52a8\u8111\uff0c\u603b\u662f\u6709\u4fdd\u5e95\u5199\u6cd5\u7684\u3002 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 \u6709\u540c\u5b66\u5c31\u95ee\u4e86\uff0c\u8fd9\u4e2a insert \u5b9e\u73b0\u4e86 map \u7684\u5e76\u96c6\u64cd\u4f5c\uff0c\u90a3\u4ea4\u96c6\u64cd\u4f5c\u5462\uff1f\u8fd9\u5176\u5b9e\u662f set \u7684\u5e38\u89c4\u64cd\u4f5c\u800c\u4e0d\u662f map \u7684\uff1a set_intersection\uff08\u53d6\u96c6\u5408\u4ea4\u96c6\uff09 set_union\uff08\u53d6\u96c6\u5408\u5e76\u96c6\uff09 set_difference\uff08\u53d6\u96c6\u5408\u5dee\u96c6\uff09 set_symmetric_difference\uff08\u53d6\u96c6\u5408\u5bf9\u79f0\u5dee\u96c6\uff09 \u975e\u5e38\u62b1\u6b49\u5728\u4e4b\u524d\u7684 set \u8bfe\u4e2d\u5b8c\u5168\u6ca1\u6709\u63d0\u53ca\uff0c\u56e0\u4e3a\u6211\u8ba4\u4e3a\u90a3\u662f \u5934\u6587\u4ef6\u91cc\u7684\u4e1c\u897f\u3002 \u4e0d\u8fc7\u522b\u62c5\u5fc3\uff0c\u4e4b\u540e\u6211\u4eec\u4f1a\u4e13\u95e8\u6709\u4e00\u8282 algorithm \u8bfe\u8be6\u89e3 STL \u4e2d\u8fd9\u4e9b\u5168\u5c40\u51fd\u6570\u2014\u2014\u6211\u79f0\u4e4b\u4e3a\u7b97\u6cd5\u6a21\u677f\uff0c\u56e0\u4e3a\u4ed6\u63d0\u4f9b\u4e86\u5f88\u591a\u5e38\u7528\u7684\u7b97\u6cd5\uff0c\u5bf9\u5c0f\u5f6d\u8001\u5e08\u8fd9\u79cd\u7b97\u6cd5\u5f31\u9e21\u800c\u8a00\uff0c\u5b9e\u5728\u975e\u5e38\u597d\u7528\uff0c\u5988\u5988\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3\u6211\u7684 ACM \u5956\u676f\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u5236\u4f5c\u5b8c algorithm \u8bfe\u4e4b\u524d\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u81ea\u884c\u53c2\u8003 https://blog.csdn.net/u013095333/article/details/89322501 \u63d0\u524d\u8fdb\u884c\u5b66\u4e60\u8fd9\u56db\u4e2a\u51fd\u6570\u3002 std::set_union(A.begin(), A.end(), B.begin(), B.end(), std::inserter(C, C.begin())); // C = A U B \u6ce8\uff1aset_union \u4ec5\u4ec5\u8981\u6c42\u8f93\u5165\u7684\u4e24\u4e2a\u533a\u95f4\u6709\u5e8f\uff0c\u53ef\u4ee5\u662f set\uff0c\u4e5f\u53ef\u4ee5\u662f\u6392\u5e8f\u8fc7\u7684 vector\u3002\u800c\u4e14\u901a\u8fc7\u91cd\u8f7d\u8fd0\u7b97\u7b26\u6216\u8005\u6307\u5b9a compare \u51fd\u6570\uff0c\u540c\u6837\u53ef\u4ee5\u6a21\u62df map \u53ea\u5bf9 key \u90e8\u5206\u6392\u5e8f\u7684\u6548\u679c\u2014\u2014\u53c2\u8003 thrust::sort_by_key\uff0c\u4f46\u5f88\u53ef\u60dc STL \u6ca1\u6709\u8fd9\u51fd\u6570\uff0c\u9700\u8981\u81ea\u5b9a\u4e49 compare \u51fd\u6570\u6a21\u62df\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u662f\u5f88\u5bb9\u6613\u57fa\u4e8e map \u7684 contains\u3001erase\u3001insert \u7b49\u63a5\u53e3\u201c\u52a8\u52a8\u8111\u201d\u5199\u51fa\u4fdd\u5e95\u5199\u6cd5\uff1a map m12; for (const auto &[k, v] : m2) { if (m1.contains(k)) { // \u6b64\u5904\u4e3a count \u4e5f\u53ef\u4ee5 // \u4ea4\u96c6\u64cd\u4f5c\uff1a\u5982\u679c m1 \u548c m2 \u90fd\u6709\u8fd9\u4e2a\u952e\uff0c\u5219\u63d2\u5165\u4ed6\u4fe9\u7684\u4ea4\u96c6 m12 m12.insert({k, v}); } } insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 C++11 \u8fd8\u5f15\u5165\u4e86\u4e00\u4e2a\u4ee5\u521d\u59cb\u5316\u5217\u8868\uff08initializer_list\uff09\u4e3a\u53c2\u6570\u7684 insert \u7248\u672c\uff1a void insert(initializer_list> ilist); \u7528\u6cd5\u548c map \u7684\u6784\u9020\u51fd\u6570\u4e00\u6837\uff0c\u8fd8\u662f\u7528\u82b1\u62ec\u53f7\u5217\u8868\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m.insert({ // \u6279\u91cf\u518d\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, // \"timeout\" \u53d1\u751f\u952e\u51b2\u7a81\uff0c\u6839\u636e insert \u7684\u7279\u6027\uff0c\u4e0d\u4f1a\u8986\u76d6 {\"delay\", 211}, }); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd9\u91cc\u8fd8\u662f\u548c\u9010\u4e2a insert \u4e00\u6837\uff0c\u91cd\u590d\u7684\u952e \u201ctimeout\u201d \u6ca1\u6709\u88ab\u8986\u76d6\uff0c\u4f9d\u65e7\u4e86\u4fdd\u7559\u539f\u503c\u3002 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 m.insert({ {\"timeout\", 985}, {\"delay\", 211}, }); \u603b\u4e4b\u8fd9\u73a9\u610f\u548c\u5206\u522b\u8c03\u7528\u4e24\u6b21 insert \u7b49\u4ef7\uff1a m.insert({\"timeout\", 985}); m.insert({\"delay\", 211}); \u5982\u679c\u9700\u8981\u8986\u76d6\u539f\u503c\u7684\u6279\u91cf\u5199\u5165\uff0c\u8fd8\u662f\u5f97\u4e56\u4e56\u5199\u4e2a for \u5faa\u73af\u8c03\u7528 [] \u6216 insert_or_assign\u3002 \u95ee\uff1a\u65e2\u7136\u548c\u6279\u91cf\u63d2\u5165\u6ca1\u4ec0\u4e48\u533a\u522b\uff0c\u590d\u6742\u5ea6\u4e5f\u4e00\u6837\u662f O(\\log N) O(\\log N) \uff0c\u90a3\u6279\u91cf insert \u7a76\u7adf\u8fd8\u6709\u4ec0\u4e48\u5b58\u5728\u7684\u5fc5\u8981\u5462\uff1fmap \u53c8\u4e0d\u50cf vector \u4e00\u4e2a\u4e2a\u5206\u522b\u63d2\u5165\u4f1a\u53d8\u6210 O(N^2) O(N^2) \u590d\u6742\u5ea6\uff0c\u786e\u5b9e\u9700\u8981\u63d0\u4f9b\u4e2a\u6279\u91cf\u63d2\u5165\u7684\u65b9\u6cd5\u3002 \u7b54\uff1a \u662f\u4e3a\u4e86\u7edf\u4e00\uff0c\u65e2\u7136 vector \u90fd\u6709\u6279\u91cf insert\uff0c\u90a3 set \u548c map \u4e5f\u5f97\u6709\u624d\u7b26\u5408\u5b8c\u7f8e\u4e3b\u4e49\u7f8e\u5b66\uff0c\u800c\u4e14\u7528\u4ed6\u6765\u5408\u5e76\u4e24\u4e2a map \u4e5f\u5f88\u65b9\u4fbf\u3002 \u590d\u6742\u5ea6\u5e76\u4e0d\u4e00\u6837\uff0c\u5f53\u8f93\u5165\u5df2\u7ecf\u6709\u5e8f\u65f6\uff0c\u6279\u91cf insert \u4f1a\u6bd4\u9010\u4e2a insert \u66f4\u5feb\uff0c\u53ea\u9700 O(N) O(N) \u800c\u4e0d\u662f O(N \\log N) O(N \\log N) \uff1b\u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \uff0c\u7a0d\u540e\u4f1a\u8bb2\u539f\u7406\u3002 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 map &operator=(initializer_list> ilist); map \u4e5f\u652f\u6301\u8d4b\u503c\u51fd\u6570\uff0c\u4e0d\u4ec5\u6709 map \u81ea\u5df1\u7ed9\u81ea\u5df1\u8d4b\u503c\u7684\u79fb\u52a8\u8d4b\u503c\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff0c\u8fd8\u6709\u4ece\u5217\u8868\u521d\u59cb\u5316\u7684\u51fd\u6570\u3002 \u7528\u6cd5\u662f\u7b49\u53f7\u53f3\u8fb9\u4e00\u4e2a\u82b1\u62ec\u53f7\u5217\u8868\uff0c\u4f5c\u7528\u662f\u6e05\u7a7a\u539f\u6709\u5185\u5bb9\uff0c\u76f4\u63a5\u8bbe\u4e3a\u4e00\u4e2a\u5168\u65b0\u7684 map\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m = { // \u539f\u6709\u5185\u5bb9\u5168\u90e8\u6e05\u7a7a\uff01\u91cd\u65b0\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, {\"delay\", 211}, }; {\"delay\": 211, \"timeout\": 985} \u76f8\u5f53\u4e8e clear \u4e86\u518d\u91cd\u65b0 insert\uff0c\u539f\u6709\u7684 \u201canswer\u201d \u952e\u4e5f\u88ab\u5220\u6389\u4e86\u3002 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 \u8981\u6ce8\u610f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) \u548c\u6784\u9020\u51fd\u6570 map(initializer_list) \u662f\u4e0d\u540c\u7684\u3002 \u6784\u9020\u51fd\u6570\u662f\u521d\u59cb\u5316\u65f6\u8c03\u7528\u7684\uff08\u65e0\u8bba\u6709\u6ca1\u6709 = \u53f7\uff09\uff0c\u8d4b\u503c\u51fd\u6570\u662f\u540e\u671f\u91cd\u65b0\u8d4b\u503c\u65f6\u8c03\u7528\u7684\u3002 map m{ // \u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; map m = { // \u867d\u7136\u6709\u7b49\u53f7\uff0c\u4f46\u8fd9\u91cc\u662f\u521d\u59cb\u5316\u8bed\u5883\uff0c\u8c03\u7528\u7684\u4f9d\u7136\u662f\u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; m = { // m \u5df2\u7ecf\u521d\u59cb\u5316\u8fc7\uff0c\u8fd9\u91cc\u662f\u91cd\u65b0\u8d4b\u503c\uff0c\u624d\u662f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) {\"timeout\", 985}, {\"delay\", 211}, }; \u5982\u679c\u4e00\u4e2a\u7c7b\u8981\u652f\u6301\u521d\u59cb\u5316\uff0c\u53c8\u8981\u652f\u6301\u540e\u671f\u91cd\u65b0\u8d4b\u503c\uff0c\u90a3\u4e48\u6784\u9020\u51fd\u6570\u548c\u8d4b\u503c\u51fd\u6570\u90fd\u8981\u5b9e\u73b0\u3002 \u4f46\u4e5f\u53ef\u4ee5\u9009\u62e9\u53ea\u5b9a\u4e49 operator=(map &&) \u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u800c\u4e0d\u5b9a\u4e49 operator=(initializer_list) \u3002\u8fd9\u6837\u5f53\u8bd5\u56fe operator=(initializer_list) \u65f6\uff0c\u4f1a\u5339\u914d\u5230 map(initializer_list) \u8fd9\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\uff0c\u7136\u540e\u8c03\u7528\u5230 operator=(map &&) \u3002\u6807\u51c6\u5e93\u9009\u62e9\u5c06\u4e24\u4e2a\u90fd\u5b9a\u4e49\u53ef\u80fd\u662f\u5904\u4e8e\u907f\u514d\u4e00\u6b21 map \u79fb\u52a8\u7684\u6548\u7387\u8003\u91cf\u3002 assign \u51fd\u6570 map \u8fd8\u6709\u4e00\u4e2a assign \u51fd\u6570\uff0c\u4ed6\u548c operator= \u7b49\u4ef7\uff1a void assign(initializer_list> ilist); assign \u7684\u989d\u5916\u597d\u5904\u662f\u4ed6\u62e5\u6709\u4e24\u4e2a\u8fed\u4ee3\u5668\u53c2\u6570\u7ec4\u6210\u533a\u95f4\u7684\u7248\u672c\uff0c\u548c\u6279\u91cf insert \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7 assign \u4f1a\u6e05\u9664\u5df2\u6709\u7684\u5143\u7d20\u3002 template void assign(InputIt first, InputIt last); \u548c operator=(map(first, last)) \u7b49\u4ef7\u3002 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert iterator insert(const_iterator pos, pair const &kv); \u8fd9\u53c8\u662f insert \u51fd\u6570\u7684\u4e00\u4e2a\u91cd\u8f7d\u7248\uff0c\u589e\u52a0\u4e86 pos \u53c2\u6570\u63d0\u793a\u63d2\u5165\u4f4d\u7f6e\uff0c\u5b98\u65b9\u6587\u6863\u79f0 1 \uff1a Inserts value in the position as close as possible to the position just prior to pos. \u628a\u5143\u7d20\uff08\u952e\u503c\u5bf9\uff09\u63d2\u5165\u5230\u4f4d\u4e8e pos \u4e4b\u524d\uff0c\u53c8\u79bb pos \u5c3d\u53ef\u80fd\u8fd1\u7684\u5730\u65b9\u3002 \u7136\u800c map \u4f5c\u4e3a\u7ea2\u9ed1\u6811\u5e94\u8be5\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0c\u63d2\u5165\u4f4d\u7f6e\u53ef\u4ee5\u7531 K \u552f\u4e00\u786e\u5b9a\uff0c\u4e3a\u5565\u8fd8\u8981\u63d0\u793a\uff1f \u662f\u4e3a\u4e86\u5728\u5df2\u77e5\u8981\u63d2\u5165\u7684\u5927\u81f4\u4f4d\u7f6e\u65f6\uff0c\u80fd\u591f\u63d0\u5347\u6027\u80fd\u3002 \uff08\u5e26\u63d0\u793a\u7684 insert \u7248\u672c\uff09\u4e2d\u4f20\u5165\u7684\u8fed\u4ee3\u5668\uff0c\u4ec5\u662f\u7ed9 map \u5bb9\u5668\u63d0\u4f9b\u4e00\u4e2a\u5efa\u8bae\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u88ab\u5bb9\u5668\u91c7\u7eb3\u3002\u8be5\u8fed\u4ee3\u5668\u8868\u660e\u5c06\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\uff0c\u5e76\u4e0d\u662f\u6b64\u8fed\u4ee3\u5668\u8bf4\u4e86\u7b97\uff0c\u6700\u7ec8\u4ecd\u53d6\u51b3\u4e8e\u8be5\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c\u3002 2 \u4e5f\u5c31\u662f\u8bf4\u8fd9\u73a9\u610f\u8fd8\u4e0d\u4e00\u5b9a\u7ba1\u7528\uff0c\u53ea\u662f\u63d0\u793a\u6027\u8d28\u7684\uff08\u548c mmap \u51fd\u6570\u7684 start \u53c2\u6570\u5f88\u50cf\uff0c\u4f60\u53ef\u4ee5\u6307\u5b9a\uff0c\u4f46\u53ea\u662f\u4e2a\u63d0\u793a\uff0c\u6307\u5b9a\u4e86\u4e0d\u4e00\u5b9a\u6709\u4ec0\u4e48\u8f6f\u7528\uff0c\u5177\u4f53\u4ec0\u4e48\u5730\u5740\u8fd8\u662f\u64cd\u4f5c\u7cfb\u7edf\u8bf4\u4e86\u7b97\uff0c\u4ed6\u4ece\u8fd4\u56de\u503c\u91cc\u7ed9\u4f60\u7684\u5730\u5740\u624d\u662f\u6b63\u786e\u7b54\u6848\uff09\u3002\u4f8b\u5982\u5df2\u77e5\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u60f3\u8981\u63d2\u5165 \u201ckea\u201d\uff0c\u90a3\u4e48\u6307\u5b9a\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\u5c31\u4f1a\u8ba9 insert \u80fd\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230 \u201ckea\u201d \u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba iterator insert(const_iterator pos, pair const &kv); \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u7684\u51c6\u786e\u65f6\uff0cinsert \u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u4f4e\u81f3 O(1)+ O(1)+ \u3002 \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u4e0d\u51c6\u786e\u65f6\uff0c\u548c\u666e\u901a\u7684 insert \u4e00\u6837\uff0c\u8fd8\u662f O(\\log N) O(\\log N) \u3002 \u8fd4\u56de\u6307\u5411\u6210\u529f\u63d2\u5165\u5143\u7d20\u4f4d\u7f6e\u7684\u8fed\u4ee3\u5668\u3002 \u60f3\u60f3\u770b\uff0c\u8fd9\u4e09\u4e2a\u770b\u4f3c\u4e0d\u76f8\u5e72\u7684\u7279\u6027\uff0c\u80fd\u6709\u4ec0\u4e48\u7528\u5462\uff1f \u53ef\u4ee5\u8ba9\u5df2\u7ecf\u6709\u5e8f\u6570\u636e\u7684\u6279\u91cf\u63d2\u5165\u66f4\u9ad8\u6548\uff01 \u4f17\u6240\u5468\u77e5\uff0c\u666e\u901a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4e3a O(N \\log N) O(N \\log N) \u3002 vector> arr; map tab; for (auto const &[k, v]: arr) { tab.insert({k, v}); // O(log N) } // \u603b\u5171 O(N log N) \u5047\u5982\u8f93\u5165\u672c\u5c31\u6709\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(N) O(N) \u3002 \u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \u4e0d\u53d8\u3002 vector> arr; map tab; auto hint = tab.begin(); for (auto const &[k, v]: arr) { hint = tab.insert(hint, {k, v}); // \u5e73\u5747 O(1) } // \u603b\u5171 O(N) \u60f3\u4e00\u60f3\uff0c\u4e3a\u4ec0\u4e48\uff1f \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u4f60\u662f\u4e00\u540d\u5c0f\u5b66\u8001\u5e08\uff0c\u9a6c\u4e0a\u5c31\u8981\u51fa\u65e9\u64cd\u4e86\uff0c\u4e3a\u5e94\u4ed8\u9886\u5bfc\u9762\u5b50\uff0c\u4f60\u9700\u8981\u7ed9\u4f60\u7684\u5b66\u751f\u6392\u961f\uff0c\u6839\u636e\u4e2a\u5b50\u4ece\u77ee\u5230\u9ad8\u6392\u5217\u3002 \u4e0d\u8fc7\u8fd9\u6240\u5c0f\u5b66\u7684\u5b66\u751f\u90fd\u6bd4\u8f83\u61d2\u6563\uff0c\u6709\u7684\u6765\u5f97\u65e9\u6709\u7684\u6765\u5f97\u665a\uff0c\u800c\u4e14\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u4ed6\u4eec\u7684\u9ad8\u77ee\u65e0\u5173\u3002 \u4f60\u672c\u6765\u6253\u7b97\u7b49\u6240\u6709\u4eba\u5230\u9f50\u4e4b\u540e\u518d\u4e00\u6b21\u6027\u5b8c\u6210\u6392\u5e8f\uff08std::sort\uff09\u7684\uff0c\u4f46\u662f\u540c\u5b66\u6765\u7684\u65f6\u95f4\u5b9e\u5728\u662f\u592a\u5206\u6563\u4e86\uff1a\u660e\u660e 8 \u70b9\u5c31\u8981\u51fa\u65e9\u64cd\uff0c\u6700\u665a\u7684\u540c\u5b66\u5374 7 \u70b9 59 \u5206\u624d\u5230\u8fbe\u3002\u610f\u5473\u7740\u4f60\u9700\u8981\u4e00\u76f4\u5e72\u7b49\u7740\u8fd9\u4e2a\u61d2\u6563\u7684\u540c\u5b66\uff0c\u6700\u540e\u5728 1 \u5206\u949f\u65f6\u95f4\u5185\u4e34\u65f6\u62b1\u4f5b\u811a\uff0c\u5b8c\u6210\u5feb\u901f\u6392\u5e8f\u3002\u8fd9\u662f\u4e0d\u53ef\u80fd\u7684\uff0c\u53ea\u80fd\u5728\u540c\u5b66\u9646\u7eed\u62b5\u8fbe\u7684\u540c\u65f6\u8fdb\u884c\u6392\u5e8f\uff0c\u8fd9\u5c31\u662f\u5806\u6392\u5e8f\uff0c\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u6392\u5e8f\uff0c\u6bcf\u6b21\u63d2\u5165\u540e\u90fd\u4fdd\u8bc1\u6709\u5e8f\uff0c\u4e0e\u63d2\u5165\u6392\u5e8f\u4e0d\u540c\u4ed6\u4f7f\u7528\u5806\u5185\u5b58\u4e2d\u7684\u8282\u70b9\u800c\u4e0d\u662f\u6570\u7ec4\u907f\u514d\u6602\u8d35\u7684\u6570\u7ec4\u5e73\u79fb\u64cd\u4f5c\u3002 \u6bcf\u5f53\u6765\u4e00\u4e2a\u5b66\u751f\uff0c\u4f60\u5c31\u5f97\u628a\u4ed6\u63d2\u5165\u5230\u73b0\u6709\u7684\u4e00\u4e2a\u5df2\u7ecf\u6392\u597d\u7684\u961f\u4f0d\u4e2d\u53bb\u3002 \u5982\u4f55\u786e\u5b9a\u63d2\u5165\u7684\u4f4d\u7f6e\uff1f\u4e8c\u5206\u6cd5\u3002\u5148\u4ece\u73b0\u6709\u961f\u4f0d\u7684\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\uff0c\u6bd4\u8f83\u4e2d\u95f4\u8fd9\u4e2a\u5b66\u751f\u548c\u65b0\u6765\u7684\u5b66\u751f\u54ea\u4e2a\u9ad8\u54ea\u4e2a\u77ee\uff0c\u5982\u679c\u53d1\u73b0\u65b0\u6765\u7684\u5b66\u751f\u9ad8\uff0c\u5219\u7ee7\u7eed\u4ece\u961f\u5217\u7684 3/4 \u5904\u90a3\u4e2a\u540c\u5b66\u5f00\u59cb\u6bd4\u9ad8\u77ee\uff0c\u5982\u679c\u65b0\u6765\u7684\u5b66\u751f\u77ee\u5c31\u4ece\u961f\u5217\u7684 1/4 \u5904\u7ee7\u7eed\u6bd4\u8f83\u3002\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6700\u7ec8\u552f\u4e00\u786e\u5b9a\u65b0\u540c\u5b66\u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002\u56e0\u4e3a\u6bcf\u6b21\u786e\u5b9a\u7684\u8303\u56f4\u5c31\u5c0f\u4e00\u534a\uff0c\u6240\u4ee5\u6700\u591a\u53ea\u9700\u8981 \\log N \\log N \u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u6210\u529f\u63d2\u5165\uff0c\u5176\u4e2d N N \u662f\u5f53\u524d\u5df2\u6709\u5b66\u751f\u7684\u6570\u91cf\u3002 \u603b\u5171\u8981\u6765 N N \u540d\u5b66\u751f\uff0c\u5219\u4f60\u603b\u5171\u9700\u8981\u6bd4\u8f83 N \\log N N \\log N \u6b21\u3002\u80fd\u4e0d\u80fd\u4f18\u5316\uff1f\u8ba9\u6211\u4eec\u5c0f\u5f6d\u8001\u5e08\u7701\u529b\u70b9\uff1f \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u540e\u6765\u4f60\u53d1\u73b0\u4e00\u4e2a\u89c4\u5f8b\uff0c\u4f3c\u4e4e\u5b66\u751f\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u6709\u5173\uff1a\u77ee\u5c0f\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u65e9\uff0c\u9ad8\u5927\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u665a\u3002 \u77e5\u9053\u8fd9\u4e2a\u89c4\u5f8b\u540e\uff0c\u4f60\u6539\u53d8\u4f60\u7684\u7b56\u7565\uff1a\u4e8c\u5206\u6cd5\u65f6\uff0c\u4e0d\u662f\u5148\u4ece\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\u67e5\u627e\uff0c\u800c\u662f\u4ece\u6700\u672b\u5c3e\u5f00\u59cb\u67e5\u627e\u3002\u56e0\u4e3a\u77ee\u5c0f\u540c\u5b66\u4f1a\u65e9\u5230\uff0c\u5bfc\u81f4\u6bcf\u6b21\u65b0\u6765\u7684\u540c\u5b66\u5f80\u5f80\u603b\u662f\u961f\u5217\u4e2d\u6700\u9ad8\u7684\u90a3\u4e00\u4e2a\u3002\u6240\u4ee5\u53ef\u4ee5\u4ece\u961f\u4f0d\u7684\u672b\u5c3e\uff08\u6700\u9ad8\u7684\u5730\u65b9\uff09\u5f00\u59cb\u627e\uff0c\u4f8b\u5982\u6709 64 \u540d\u540c\u5b66\u5219\u4f18\u5148\u548c 65/64 \u5904\u6bd4\u8f83\uff0c\u627e\u4e0d\u5230\u518d\u5f80\u4e0a\u4e00\u7ea7\u548c 31/32 \u5904\u6bd4\u8f83\u3002 \u8fd9\u4e2a\u7b56\u7565\u4e5f\u6709\u7f3a\u70b9\uff1a\u5bf9\u4e8e\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u65e0\u5173\u3001\u751a\u81f3\u8d1f\u76f8\u5173\u7684\u60c5\u51b5\uff0c\u6bcf\u6b21\u63d2\u5165\u7684\u6d88\u8017\u5c31\u4f1a\u53d8\u6210 2 \\log N 2 \\log N \u4e86\u3002 \u6700\u7ec8\u6211\u4eec\u51b3\u5b9a\u91c7\u7528\u7684\u7b56\u7565\u662f\uff1a\u4e0d\u662f\u4ece\u4e2d\u95f4\uff0c\u4e5f\u4e0d\u662f\u4ece\u5f00\u5934\uff0c\u4e5f\u4e0d\u662f\u4ece\u672b\u5c3e\uff0c\u800c\u662f \u8bb0\u4f4f\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e \uff0c\u4e0b\u4e00\u6b21\u4ece\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e\u5f00\u59cb\u627e\u3002\u8fd9\u4e2a\u8bb0\u5fc6\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u5c31\u662f\u521a\u521a\u4ee3\u7801\u4e2d\u90a3\u4e2a\u4f4d\u7f6e\u63d0\u793a\u8fed\u4ee3\u5668 hint\u3002 \u8fd9\u6b63\u662f\u6211\u4eec\u4ee3\u7801\u7684\u5199\u6cd5\uff1a hint = tab.insert(hint, {k, v}); \u5b9e\u9645\u4e0a\uff0cinsert \u7684\u6279\u91cf\u63d2\u5165\u7248 insert(arr.begin(), arr.end()) \u5185\u90e8\u5c31\u4f1a\u4f7f\u7528\u8fd9\u79cd\u5e26\u63d0\u793a\u7684\u65b9\u5f0f\uff0c\u9010\u4e2a\u63d2\u5165\u3002 vector> arr; \u5206\u5974 emplace insert \u7684\u7a76\u6781\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace template pair emplace(Args &&...args); \u867d\u7136\u53d8\u957f\u53c2\u6570\u5217\u8868 Args &&...args \u770b\u8d77\u6765\u5f88\u9177\uff0c\u7136\u800c\u7531\u4e8e map \u7684\u7279\u6b8a\u6027\uff0c\u5176\u5143\u7d20\u7c7b\u578b\u662f pair \uff0c\u800c pair \u7684\u6784\u9020\u51fd\u6570\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\uff0c\u5bfc\u81f4\u5b9e\u9645\u4e0a\u8fd9\u4e2a\u770b\u4f3c\u70ab\u9177\u7684\u53d8\u957f\u53c2\u6570\u5217\u8868\u5f80\u5f80\u53ea\u80fd\u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\uff0c\u56e0\u6b64\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u5b9e\u9645\u4e0a\u53ea\u80fd\u662f\uff1a pair emplace(K k, V v); \u5199\u6cd5\uff1a m.emplace(key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert({key, val}); \u8fd4\u56de\u503c\u8fd8\u662f pair \uff0c\u5176\u610f\u4e49\u548c insert \u4e00\u6837\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002 emplace_hint insert \u7684\u5b87\u5b99\u65e0\u654c\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace_hint 1 template iterator emplace_hint(const_iterator pos, Args &&...args); \u5199\u6cd5\uff1a m.emplace_hint(pos, key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert(pos, {key, val}); \u4e4b\u6240\u4ee5\u8981\u5206\u4e24\u4e2a\u51fd\u6570\u540d emplace \u548c emplace_hint \u800c\u4e0d\u662f\u5229\u7528\u91cd\u8f7d\u533a\u5206\uff0c\u662f\u56e0\u4e3a\u76f4\u63a5\u4f20\u5165 pos \u4f1a\u88ab emplace \u5f53\u505a pair \u7684\u6784\u9020\u53c2\u6570\uff0c\u800c\u4e0d\u662f\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u3002 emplace \u5bf9\u5e94\u4e8e\u666e\u901a\u7684 insert(pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u5bf9\u5e94\u4e8e\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert(const_iterator, pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u548c\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u4e00\u6837\uff0c\u662f\u5355\u72ec\u4e00\u4e2a iterator\u3002 emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 template pair emplace(Args &&...args); emplace \u5bf9\u4e8e set\uff0c\u5143\u7d20\u7c7b\u578b\u662f\u6bd4\u8f83\u5927\u7684\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 set> \uff0c\u53ef\u80fd\u786e\u5b9e\u80fd\u8d77\u5230\u51cf\u5c11\u79fb\u52a8\u6784\u9020\u51fd\u6570\u5f00\u9500\u7684\u4f5c\u7528\u3002 \u4f46\u662f\u8fd9\u4e2a map \u4ed6\u7684\u5143\u7d20\u7c7b\u578b\u4e0d\u662f\u76f4\u63a5\u7684 V \u800c\u662f\u4e00\u4e2a pair\uff0c\u4ed6\u5206\u7684\u662f pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709\u7528\uff0cV \u90e8\u5206\u8fd8\u662f\u4f1a\u9020\u6210\u4e00\u6b21\u989d\u5916\u7684\u79fb\u52a8\u5f00\u9500\uff0c\u6240\u4ee5\u8fd9\u73a9\u610f\u9664\u4e86\u59a8\u788d\u7c7b\u578b\u5b89\u5168\u548c\u53ef\u8bfb\u6027\u4ee5\u5916\uff0c\u6ca1\u6709\u4efb\u4f55\u6536\u76ca\u3002 set \u53ef\u4ee5\u7528 emplace/emplace_hint\u3002 vector \u53ef\u4ee5\u7528 emplace_back\u3002 \u4e0d\u5efa\u8bae\u5728 map \u4e0a\u4f7f\u7528 emplace/emplace_hint\uff0c\u8bf7\u6539\u7528 try_emplace\u3002 try_emplace \u66f4\u597d emplace \u53ea\u652f\u6301 pair \u7684\u5c31\u5730\u6784\u9020\uff0c\u8fd9\u6709\u4ec0\u4e48\u7528\uff1f\u6211\u4eec\u8981\u7684\u662f pair \u4e2d\u503c\u7c7b\u578b\u7684\u5c31\u5730\u6784\u9020\uff01\u8fd9\u5c31\u662f try_emplace \u7684\u4f5c\u7528\u4e86\uff0c\u4ed6\u5bf9 key \u90e8\u5206\u4f9d\u7136\u662f\u4f20\u7edf\u7684\u79fb\u52a8\uff0c\u53ea\u5bf9 value \u90e8\u5206\u91c7\u7528\u5c31\u5730\u6784\u9020\u3002 \u8fd9\u662f\u89c2\u5bdf\u5230\u5927\u591a\u662f\u503c\u7c7b\u578b\u5f88\u5927\uff0c\u6025\u9700\u5c31\u5730\u6784\u9020\uff0c\u800c\u952e\u7c7b\u578b\u6ca1\u7528\u591a\u5c11\u5c31\u5730\u6784\u9020\u7684\u9700\u6c42\u3002\u4f8b\u5982 map> \u5982\u679c\u60f3\u4e0d\u7528 try_emplace\uff0c\u5b8c\u5168\u57fa\u4e8e emplace \u5b9e\u73b0\u9488\u5bf9\u503c value \u7684\u5c31\u5730\u6784\u9020\u9700\u8981\u7528\u5230 std::piecewise_construct \u548c std::forward_as_tuple\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 insert \u7684\u6258\u9a6c\u65af\u9ec4\u91d1\u5927\u56de\u65cb\u5206\u5974\u7248\uff1atry_emplace\uff08C++17 \u5f15\u5165\uff09 template pair try_emplace(K const &k, Args &&...args); \u5199\u6cd5\uff1a m.try_emplace(key, arg1, arg2, ...); \u4ed6\u7b49\u4ef7\u4e8e\uff1a m.insert({key, V(arg1, arg2, ...)}); \u540e\u9762\u7684\u53d8\u957f\u53c2\u6570\u4e5f\u53ef\u4ee5\u5b8c\u5168\u6ca1\u6709\uff1a m.try_emplace(key); \u4ed6\u7b49\u4ef7\u4e8e\u8c03\u7528 V \u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a m.insert({key, V()}); \u7531\u4e8e emplace \u5b9e\u5728\u662f\u61a8\u61a8\uff0c\u4ed6\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u7684\u662f pair\uff0c\u7136\u800c pair \u7684\u6784\u9020\u51fd\u6570\u6b63\u5e38\u4e0d\u5c31\u662f\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\u5417\uff0c\u53d8\u957f\u6ca1\u6709\u7528\u3002\u5b9e\u9645\u6709\u7528\u7684\u5f80\u5f80\u662f\u6211\u4eec\u5e0c\u671b\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u503c\u7c7b\u578b V\uff0c\u5bf9 K \u90e8\u5206\u5e76\u4e0d\u5173\u7cfb\u3002\u56e0\u6b64 C++17 \u5f15\u5165\u4e86 try_emplace\uff0c\u5176\u952e\u90e8\u5206\u4fdd\u6301 K const & \uff0c\u503c\u90e8\u5206\u91c7\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u3002 \u6211\u7684\u8bc4\u4ef7\u662f\uff1a\u8fd9\u4e2a\u6bd4 emplace \u5b9e\u7528\u591a\u4e86\uff0c\u5982\u679c\u8981\u4e0e vector \u7684 emplace_back \u5bf9\u6807\uff0c\u90a3\u4e48 map \u4e0e\u4e4b\u5bf9\u5e94\u7684\u4e00\u5b9a\u662f try_emplace\u3002\u540c\u5b66\u4eec\u5982\u679c\u8981\u5206\u5974\u7684\u8bdd\u8fd8\u662f\u5efa\u8bae\u7528 try_emplace\u3002 try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 insert \u7c7b\u51fd\u6570\u603b\u662f\u4e0d\u53ef\u907f\u514d\u7684\u9700\u8981\u79fb\u52a8\u6784\u9020\uff1a\u5148\u5728\u51fd\u6570\u4e2d\u6784\u9020\u51fa\u4e34\u65f6\u5bf9\u8c61\uff0c\u7136\u540e\u6784\u9020\u5230\u771f\u6b63\u7684 pair \u4e0a\u3002 \u800c try_emplace \u53ef\u4ee5\u5141\u8bb8\u4f60\u5c31\u5730\u6784\u9020\u503c\u5bf9\u8c61\uff0c\u907f\u514d\u79fb\u52a8\u9020\u6210\u5f00\u9500\u3002 try_emplace \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u952e\uff0c\u7b2c\u4e8c\u4e2a\u5f00\u59cb\u662f\u4f20\u7ed9\u6784\u9020\u51fd\u6570\u7684\u53c2\u6570\uff0c\u5982\u53ea\u6709\u7b2c\u4e00\u4e2a\u53c2\u6570\u5219\u662f\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570\u3002 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(int i) { printf(\"MyClass(int)\\n\"); } MyClass(const char *p, float x) { printf(\"MyClass(const char *, float)\\n\"); } }; map m; m.try_emplace(\"key\"); // MyClass() m.try_emplace(\"key\", 42); // MyClass(int) m.try_emplace(\"key\", \"hell\", 3.14f); // MyClass(const char *, float) // \u7b49\u4ef7\u4e8e\uff1a m.insert({\"key\", MyClass()}); // MyClass() m.insert({\"key\", MyClass(42)}); // MyClass(int) m.insert({\"key\", MyClass(\"hell\", 3.14f)}); // MyClass(const char *, float) \u5bf9\u4e8e\u79fb\u52a8\u5f00\u9500\u8f83\u5927\u7684\u7c7b\u578b\uff08\u4f8b\u5982 array \uff09\uff0ctry_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff1b\u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u503c\u7c7b\u578b\uff0c\u5c31\u5fc5\u987b\u4f7f\u7528 try_emplace \u4e86\u3002 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 // \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u6548\u679c\u7b49\u4ef7\uff0c\u53ea\u6709\u6027\u80fd\u4e0d\u540c m.try_emplace(key, arg1, arg2, ...); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 m.insert({key, V(arg1, arg2, ...)}); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 2\u6b21\u79fb\u52a8\u51fd\u6570 m.insert(make_pair(key, V(arg1, arg2, ...))); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 3\u6b21\u79fb\u52a8\u51fd\u6570 \u4f46\u662f\u7531\u4e8e try_emplace \u662f\u7528\u5706\u62ec\u53f7\u5e2e\u4f60\u8c03\u7528\u7684\u6784\u9020\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u3002 \u5bfc\u81f4\u4f60\u8981\u4e48\u65e0\u6cd5\u7701\u7565\u7c7b\u578b\uff0c\u8981\u4e48\u4f60\u5f97\u624b\u52a8\u5b9a\u4e49\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff1a struct Student { // \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u82b1\u62ec\u53f7\u8bed\u6cd5\u8fdb\u884c\u521d\u59cb\u5316 string sex; int age; }; map m; m.insert({\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}}); // OK: insert \u53c2\u6570\u7c7b\u578b\u5df2\u77e5\uff0cStudent \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff0c\u4f46\u662f\u4f1a\u9020\u6210 2 \u6b21\u79fb\u52a8 m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // ERROR: \u4e0d\u5b58\u5728\u6784\u9020\u51fd\u6570 Student(string, int)\uff1bC++20 \u5f00\u59cb\u5219 OK: C++20 \u8d77\u805a\u5408\u521d\u59cb\u5316\u540c\u65f6\u652f\u6301\u82b1\u62ec\u53f7\u548c\u5706\u62ec\u53f7 m.try_emplace(\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}); // ERROR: \u53c2\u6570\u7c7b\u578b\u662f\u6a21\u677f\u7c7b\u578b\uff0c\u672a\u77e5\uff0c\u65e0\u6cd5\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b m.try_emplace(\"\u5f6d\u4e8e\u658c\", Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: \u660e\u786e\u6307\u5b9a\u7c7b\u578b\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff1b\u4f46\u8fd9\u6837\u53c8\u4f1a\u9020\u6210 1 \u6b21\u79fb\u52a8\uff0c\u5931\u53bb\u4e86 try_emplace \u907f\u514d\u79fb\u52a8\u7684\u610f\u4e49 \u6b64\u5916\u8fd8\u8981\u6ce8\u610f\u4e0d\u8bba insert\u3001emplace\u3001emplace_hint\u3001try_emplace\uff0c\u90fd\u662f\u4e00\u4e2a\u5c3f\u6027\uff1a\u952e\u51b2\u7a81\u65f6\u4e0d\u4f1a\u8986\u76d6\u5df2\u6709\u5143\u7d20\u3002 \u5982\u679c\u9700\u8981\u8986\u76d6\u6027\u7684\u63d2\u5165\uff0c\u8fd8\u5f97\u4e56\u4e56\u7528 [] \u6216\u8005 insert_or_assign \u51fd\u6570\u3002 \u7531\u4e8e try_emplace \u91cc\u5199\u6b7b\u4e86\u5706\u62ec\u53f7\uff0c\u6211\u4eec\u53ea\u597d\u624b\u52a8\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\u624d\u80fd\u52b3\u9a7e try_emplace \u5c31\u5730\u6784\u9020\u3002 struct Student { string sex; int age; Student(string sex, int age) : sex(std::move(sex)) , age(age) {} // \u7531\u4e8e try_emplace \u4f1a\u5c31\u5730\u6784\u9020\u5bf9\u8c61\uff0c\u5176\u503c\u7c7b\u578b\u53ef\u4ee5\u6ca1\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u800c insert \u4f1a\u51fa\u9519 Student(Student &&) = delete; Student &operator=(Student &&) = delete; Student(Student const &) = delete; Student &operator=(Student const &) = delete; }; map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570 Student(string, int) \u5c31\u5730\u6784\u9020\u5bf9\u8c61 m.insert({\"\u5f6d\u4e8e\u658c\", Student(\"\u81ea\u5b9a\u4e49\", 22)}); // ERROR: insert \u9700\u8981\u79fb\u52a8 Student \u800c Student \u7684\u79fb\u52a8\u88ab delete \u4e86\uff01 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 \u65e0\u6784\u9020\u51fd\u6570\u65f6\uff0cC++11 \u652f\u6301\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff08\u5b98\u65b9\u540d: \u805a\u5408\u521d\u59cb\u5316 1 \uff09\uff0cC++20 \u5f00\u59cb\u805a\u5408\u521d\u59cb\u5316\u4e5f\u80fd\u7528\u5706\u62ec\u53f7\uff08\u6240\u4ee5 emplace / try_emplace \u8fd9\u7c7b\u51fd\u6570\u53d8\u5f97\u66f4\u597d\u7528\u4e86\uff09\uff1a struct Student { string sex; int age; }; auto s1 = Student{\"\u81ea\u5b9a\u4e49\", 22}; // C++11 \u8d77 OK: \u65e0\u6784\u9020\u51fd\u6570\u65f6\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5 auto s2 = Student(\"\u81ea\u5b9a\u4e49\", 22); // C++20 \u8d77 OK: \u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u751f\u6210\u5706\u62ec\u53f7\u6784\u9020\u51fd\u6570 Student(string, int) \u548c\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u65f6\u4e00\u6837\uff0c\u53ef\u4ee5\u7701\u7565\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u8fd9\u90e8\u5206\u53c2\u6570\u4f1a\u7528\u4ed6\u4eec\u7684\u9ed8\u8ba4\u503c\uff1a auto s1 = Student(\"\u81ea\u5b9a\u4e49\", 22); // OK: sex \u4e3a \"\u81ea\u5b9a\u4e49\"\uff0cage \u4e3a 22 auto s2 = Student(\"\u81ea\u5b9a\u4e49\"); // OK: \u7701\u7565 age \u81ea\u52a8\u4e3a 0 auto s3 = Student(); // OK: \u7701\u7565 sex \u81ea\u52a8\u4e3a \"\" \u4e0d\u8fc7\u4ed6\u548c\u82b1\u62ec\u53f7\u4e0d\u4e00\u6837\u7684\u662f\uff0c\u4f5c\u4e3a\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\u7684\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u7c7b\u578b\u540d\u4e0d\u80fd\u7701\u7565\u4e86\uff1a void func(Student const &stu); // \u5df2\u77e5\u51fd\u6570\u7b7e\u540d func(Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5 func({\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5\uff0c\u5df2\u77e5\u51fd\u6570\u5177\u6709\u552f\u4e00\u91cd\u8f7d\u7684\u60c5\u51b5\u4e0b\u7c7b\u540d\u53ef\u4ee5\u7701\u7565 func(Student(\"\u81ea\u5b9a\u4e49\", 22)); // OK: C++20 \u8bed\u6cd5 func((\"\u81ea\u5b9a\u4e49\", 22)); // ERROR: \u65e0\u6cd5\u4ece int \u8f6c\u6362\u4e3a Student C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u6240\u4ee5\u73b0\u5728 try_emplace \u4e5f\u53ef\u4ee5\u5c31\u5730\u6784\u9020\u65e0\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u4e86\uff1a map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 22} m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 0} m.try_emplace(\"\u5f6d\u4e8e\u658c\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\", 0} \u65b9\u4fbf\uff01 \u5173\u4e8e\u66f4\u591a C++20 \u7684\u805a\u5408\u521d\u59cb\u5316\u5c0f\u77e5\u8bc6\uff0c\u53ef\u4ee5\u770b\u8fd9\u671f CppCon \u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=flLNi0aejew \u4e3a\u65b9\u4fbf\u4f60\u5728\u6bd4\u7ad9\u641c\u7d22\u642c\u8fd0\uff0c\u4ed6\u7684\u6807\u9898\u662f\uff1aLightning Talk: Direct Aggregate Initialisation - Timur Doumler - CppCon 2021 \u8c03\u7528\u5f00\u9500\u5206\u6790 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(MyClass &&) noexcept { printf(\"MyClass(MyClass &&)\\n\"); } MyClass &operator=(MyClass &&) noexcept { printf(\"MyClass &operator=(MyClass &&)\\n\"); return *this; } }; map tab; printf(\"insert\u7684\u5f00\u9500:\\n\"); tab.insert({1, MyClass()}); printf(\"try_emplace\u7684\u5f00\u9500:\\n\"); tab.try_emplace(2); // try_emplace \u53ea\u6709\u4e00\u4e2a key \u53c2\u6570\u65f6\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570 MyClass() insert \u8c03\u7528\u4e86\u4e24\u6b21\u79fb\u52a8\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 insert \u628a\u53c2\u6570 pair \u79fb\u8fdb\u7ea2\u9ed1\u6811\u8282\u70b9\u91cc\u3002 \u800c try_emplace \u5185\u90e8\u4f7f\u7528\u4e86\u73b0\u4ee3 C++ \u7684\u5c31\u5730\u6784\u9020\uff08placement new\uff09\uff0c\u76f4\u63a5\u5728\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u5185\u5b58\u4e2d\u6784\u9020 MyClass\uff0c\u65e0\u9700\u53cd\u590d\u79fb\u52a8\uff0c\u5bf9\u4e8e\u5c3a\u5bf8\u8f83\u5927\u7684\u503c\u7c7b\u578b\u4f1a\u66f4\u9ad8\u6548\u3002 insert\u7684\u5f00\u9500: MyClass() MyClass(MyClass &&) MyClass(MyClass &&) try_emplace\u7684\u5f00\u9500: MyClass() try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u63d0\u5347\u4e86 1.42 \u500d\u6027\u80fd\uff0c\u4e0d\u80fd\u8bf4\u662f\u60ca\u5929\u5730\u6ce3\u9b3c\u795e\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u804a\u80dc\u4e8e\u65e0\u4e86\u3002\u8fd9\u91cc\u7684\u503c\u7c7b\u578b string \u53ea\u6709 32 \u5b57\u8282\u8fd8\u4e0d\u591f\u660e\u663e\uff0c\u53ef\u80fd\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\u4f1a\u6709\u660e\u663e\u7684\u4f18\u52bf\u3002\u8fd9\u79cd\u4f18\u5316\u7684\u7406\u8bba\u4e0a\u9650\u662f 3 \u500d\uff0c\u6700\u591a\u80fd\u4ece try_emplace \u83b7\u5f97 3 \u500d\u6027\u80fd\u63d0\u5347\u3002 template static void test_insert(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) 2\u6b21string(string &&) tab.insert({i, \"hello\"}); } } template static void test_try_emplace(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) tab.try_emplace(i, \"hello\"); } } int main() { for (int i = 0; i < 1000; i++) { map tab; test_insert(tab); doNotOptimize(tab); } for (int i = 0; i < 1000; i++) { map tab; test_try_emplace(tab); doNotOptimize(tab); } printScopeProfiler(); } avg | min | max | total | cnt | tag 39| 34| 218| 39927| 1000| test_insert 28| 27| 91| 28181| 1000| test_try_emplace \u5982\u679c\u6539\u6210\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\uff0c\u53ef\u4ee5\u63d0\u5347 2.3 \u500d\u3002 struct MyClass { int arr[4096]; }; avg | min | max | total | cnt | tag 1312| 1193| 18298| 1312871| 1000| test_insert 573| 537| 1064| 573965| 1000| test_try_emplace \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace insert \u7684\u70ab\u5f69\u4e2d\u4e8c\u6447\u6446\u6df7\u6c8c\u5927\u9b54\u738b\u5206\u5974\u7248\uff1a\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace template iterator try_emplace(const_iterator pos, K const &k, Args &&...args); \u5199\u6cd5\uff1a hint = m.try_emplace(hint, key, arg1, arg2, ...); \u7b49\u4ef7\u4e8e\uff1a hint = m.insert(hint, {key, V(arg1, arg2, ...)}); \u8fd9\u6b21\u4e0d\u9700\u8981\u518d\u5206\u4e00\u4e2a\u4ec0\u4e48 try_emplace_hint \u51fa\u6765\u4e86\uff0c\u662f\u56e0\u4e3a try_emplace \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f K \u7c7b\u578b\u800c\u4e0d\u662f\u6cdb\u578b\uff0c\u4e0d\u53ef\u80fd\u548c const_iterator \u7c7b\u578b\u6df7\u6dc6\uff0c\u56e0\u6b64 C++ \u59d4\u5458\u4f1a\u6700\u7ec8\u51b3\u5b9a\u76f4\u63a5\u5171\u7528\u540c\u4e00\u4e2a\u540d\u5b57\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u91cd\u8f7d\u4e86\u3002 emplace \u5bb6\u65cf\u603b\u7ed3 \u603b\u7ed3\uff0c\u5982\u4f55\u7528 emplace \u5bb6\u65cf\u4f18\u5316\uff1f\u5206\u76f4\u63a5\u63d2\u5165\u548c\u5e26\u63d0\u793a\u63d2\u5165\u4e24\u79cd\u7528\u6cd5\uff0c\u548c\u4f60\u662f\u5426\u9700\u8981\u9ad8\u6027\u80fd\u4e24\u79cd\u9700\u6c42\uff0c\u8fd9\u91cc\u6807\u4e86\u201c\u63a8\u8350\u201d\u7684\u662f\u5efa\u8bae\u91c7\u7528\u7684\uff1a // \u76f4\u63a5\u63d2\u5165\u7248 m.insert({\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 m.try_emplace(\"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 m.emplace(\"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 m.emplace(std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 // \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7248 hint = m.insert(hint, {\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 hint = m.try_emplace(hint, \"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 hint = m.emplace_hint(hint, \"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 hint = m.emplace_hint(hint, std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 map \u4e0e RAII \u68a6\u5e7b\u8054\u52a8\uff1amap \u5bb9\u5668\u4e0e RAII \u7684\u53cc\u5411\u5954\u8d74 \u5982\u679c map \u4e2d\u5143\u7d20\u7684\u503c\u7c7b\u578b\u662f RAII \u7c7b\u578b\uff0c\u5176\u6790\u6784\u51fd\u6570\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u8c03\u7528\u3002 map \u88ab\u79fb\u52a8\u65f6\uff0c\u4e0d\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u79fb\u52a8\u51fd\u6570\uff0c\u56e0\u4e3a map \u91cc\u53ea\u5b58\u7740\u6307\u5411\u7ea2\u9ed1\u6811\u6839\u8282\u70b9\u7684\u6307\u9488\uff0c\u53ea\u9700\u6307\u9488\u79fb\u52a8\u5373\u53ef\u3002 map \u88ab\u62f7\u8d1d\u65f6\uff0c\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u62f7\u8d1d\u51fd\u6570\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u5219 map \u7684\u62f7\u8d1d\u4e5f\u4f1a\u88ab\u7981\u7528\uff08delete\uff09\u6389\u3002 map \u88ab\u6790\u6784\u65f6\uff0c\u5176\u6240\u6709\u5143\u7d20\u90fd\u4f1a\u88ab\u6790\u6784\u3002 \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\\n\", i); } RAII &operator=(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\u8d4b\u503c\\n\", i); return *this; } ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; RAII &operator=(RAII &&) = delete; RAII(RAII const &) = delete; RAII &operator=(RAII const &) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u65b0\u624b\u5b9a\u4e49 RAII \u7c7b\u65f6\uff0c\u8bb0\u5f97\u628a\u79fb\u52a8\u548c\u62f7\u8d1d 4 \u4e2a\u51fd\u6570\u5168\u90e8\u5220\u9664\u3002\u6ca1\u9519\uff0c \u79fb\u52a8\u4e5f\u8981\u5220\u9664 \uff0c\u5f88\u591a\u65b0\u624b\u4f1a\u89c9\u5f97\u8d44\u6e90\u7c7b\u5e94\u8be5\u53ef\u4ee5\u79fb\u52a8\u7684\u5440\uff1f\u8981\u662f\u60f3\u4fdd\u7559\u79fb\u52a8\uff0c\u5c31\u5f97\u9884\u7559\u4e00\u4e2a i == 0 \u7684\u7a7a\u72b6\u6001\uff0c\u90a3\u79cd\u5904\u7406\u5f88\u590d\u6742\u7684\u3002\u603b\u4e4b\u4e00\u65e6\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5168\u90e8 4 \u4e2a\u51fd\u6570\u90fd\u5f97\u5220\u9664\uff0c\u9664\u975e\u4f60\u6709\u76f8\u5173\u7ecf\u9a8c\u3002\u53c2\u89c1 C++ \u751f\u547d\u5468\u671f\u4e0e\u6790\u6784\u51fd\u6570\u4e13\u9898 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u8fd9\u65f6\u5c31\u4f53\u73b0\u51fa try_emplace \u7684\u597d\u5904\u4e86\uff1a\u503c\u7c7b\u578b\u4e0d\u9700\u8981\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\u4e5f\u53ef\u4ee5\u63d2\u5165\u3002 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u5269\u4e0b 3 \u4e2a\uff0c\u8fd9\u662f\u56e0\u4e3a\u770b\u5230\u4f60\u7528\u4e86 && \u5c31\u77e5\u9053\u4f60\u662f\u61c2 C++11 \u7684\uff0c\u6240\u4ee5\u4e0d\u7528\u7167\u987e C++98 \u517c\u5bb9\u6027\u4fdd\u7559\u70e6\u4eba\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u5220\u4e86\uff0c\u8fd9\u662f\u4e2a\u6807\u51c6\uff0c\u6240\u6709 C++ \u7f16\u8bd1\u5668\u90fd\u662f\u8fd9\u6837\u7684\uff08\u8981\u6211\u8bf4\uff0c\u5efa\u8bae\u6539\u6210\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\u5c31\u81ea\u52a8\u5220\u5168 4 \u4e2a\u51fd\u6570\uff0c\u53ef\u60dc\u6807\u51c6\u59d4\u5458\u4f1a\u8981\u7167\u987e\u517c\u5bb9\u6027\u2026\uff09 \u4ee5\u540e RAII \u7c7b\u53ea\u9700\u8981\u4e00\u884c C(C &&) = delete \u5c31\u591f\u4e86\u3002 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u5982\u679c\u4f60\u60f3\u7528\u66f4\u53ef\u8bfb\u7684 insert\uff0cRAII \u8d44\u6e90\u7c7b\u53c8\u4e0d\u652f\u6301\u79fb\u52a8\uff0c\u53ef\u4ee5\u7528 unique_ptr \u5305\u88c5\u4e00\u4e0b\uff1a ```cpp int main() { { map> m; m.insert(\"\u8d44\u6e901\u53f7\", std::make_unique(1)); m.insert(\"\u8d44\u6e902\u53f7\", std::make_unique(2)); m.erase(\"\u8d44\u6e901\u53f7\"); m.insert(\"\u8d44\u6e903\u53f7\", std::make_unique(3)); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u5bf9\u4e8e\u5f88\u5927\u7684 V \u7c7b\u578b\uff0c\u4e5f\u53ef\u4ee5\u6539\u7528 map> \u907f\u514d\u53cd\u590d\u79fb\u52a8\u5143\u7d20\u672c\u4f53\u3002\uff08\u7528\u5728\u9700\u8981\u53cd\u590d\u6269\u5bb9\u7684 vector \u4e2d\u4e5f\u6709\u5947\u6548\uff09 \u56e0\u4e3a\u5305\u62ec map \u5728\u5185\u7684\u6240\u6709\u5bb9\u5668\u90fd\u5b8c\u7f8e\u652f\u6301 RAII \u7c7b\u578b\uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u7528\u667a\u80fd\u6307\u9488\u4f5c\u4e3a\u8fd9\u4e9b\u5bb9\u5668\u7684\u5143\u7d20\u3002 struct MyData { int value; // \u5047\u8bbe\u8fd9\u4e2a\u5f88\u5927 explicit MyData(int value_) : value(value_) {} }; map> m; m.insert({\"answer\", make_unique(42)}); // \u53ea\u6709 8 \u5b57\u8282\u7684 unique_ptr \u88ab\u79fb\u52a8 2 \u6b21 m.insert({\"fuck\", make_unique(985)}); print(m.at(\"answer\")->value); // 42 // \u2191\u7b49\u4ef7\u4e8e\uff1aprint((*m.at(\"answer\")).value); map> \u4e2d\uff0c\u667a\u80fd\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u91ca\u653e\u3002 map \u4e2d\uff0cC \u8bed\u8a00\u539f\u59cb\u6307\u9488\u4e0d\u5177\u5907 RAII \u529f\u80fd\uff0c\u9664\u975e\u8be5\u6307\u9488\u88ab\u5176\u4ed6\u667a\u80fd\u6307\u9488\u6253\u7406\u7740\uff0c\u6216\u8005\u7528\u6237\u5220\u9664\u5143\u7d20\u4e4b\u524d\u624b\u52a8 delete\uff0c\u5426\u5219\u5f53\u5143\u7d20\u5220\u9664\u65f6\u5185\u5b58\u4f1a\u6cc4\u9732\uff01 \u6211\u63a8\u8350\u5b8c\u5168\u91c7\u7528\u667a\u80fd\u6307\u9488\u6765\u81ea\u52a8\u7ba1\u7406\u5185\u5b58\uff0c\u667a\u80fd\u6307\u9488\u548c\u540c\u6837\u7b26\u5408 RAII \u601d\u60f3\u7684\u5404\u5927\u5bb9\u5668\u4e5f\u662f\u76f8\u6027\u5f88\u597d\u7684\u3002 \u5982\u679c\u9700\u8981\u6d45\u62f7\u8d1d\u7684\u8bdd\uff0c\u5219\u53ef\u4ee5\u6539\u7528 map> \uff0c\u5c0f\u5f6d\u8001\u5e08\u5728\u4ed6\u7684 Zeno \u9879\u76ee\u4e2d\u5c31\u662f\u8fd9\u6837\u7528\u7684\u3002 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.insert(make_pair(key, val)) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++98 \ud83d\udca9 m.insert({key, val}) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \u2764 m.emplace(key, val) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \ud83d\udca9 m.try_emplace(key, valargs...) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++17 \ud83d\udca3 m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 C++17 \u2764 m[key] = val \u63d2\u5165\u6216\u8986\u76d6 C++98 \ud83d\udca3 m.erase(key) \u5220\u9664\u6307\u5b9a\u5143\u7d20 C++98 \u2764 \u6539\u67e5 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.at(key) \u627e\u4e0d\u5230\u5219\u51fa\u9519\uff0c\u627e\u5230\u5219\u8fd4\u56de\u5f15\u7528 C++98 \u2764 m[key] \u627e\u4e0d\u5230\u5219\u81ea\u52a8\u521b\u5efa 0 \u503c\uff0c\u8fd4\u56de\u5f15\u7528 C++98 \ud83d\udca3 myutils::map_get(m, key, defl) \u627e\u4e0d\u5230\u5219\u8fd4\u56de\u9ed8\u8ba4\u503c C++98 \u2764 m.find(key) == m.end() \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \ud83d\udca3 m.count(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \u2764 m.contains(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++20 \ud83d\udca9 \u521d\u59cb\u5316 \u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 map m = {{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 auto m = map{{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \ud83d\udca9 func({{k1, v1}, {k2, v2}}) \u7ed9\u51fd\u6570\u53c2\u6570\u4f20\u5165\u4e00\u4e2a map C++11 \u2764 m = {{k1, v1}, {k2, v2}} \u91cd\u7f6e\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 m.clear() \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++98 \u2764 m = {} \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++11 \ud83d\udca3 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract C++17 \u65b0\u589e\u7684 extract \u51fd\u6570 1 \u53ef\u4ee5\u201c\u5265\u79bb\u201d\u51fa\u5355\u4e2a\u8282\u70b9\uff1a node_type extract(K const &key); node_type extract(const_iterator pos); auto node = m.extract(\"fuck\"); auto &k = node.key(); // \u952e\uff08\u5f15\u7528\uff09 auto &v = node.mapped(); // \u503c\uff08\u5f15\u7528\uff09 \u5176\u529f\u80fd\u4e0e erase \u7c7b\u4f3c\uff0c\u90fd\u4f1a\u5c06\u5143\u7d20\u4ece map \u4e2d\u5220\u9664\uff0c\u4f46 extract \u53ea\u662f\u628a\u8282\u70b9\u4ece map \u4e2d\u79fb\u8d70\uff0c\u5e76\u4e0d\u4f1a\u76f4\u63a5\u9500\u6bc1\u8282\u70b9\u3002 extract \u4f1a\u8fd4\u56de\u8fd9\u4e2a\u521a\u88ab\u201c\u5265\u79bb\u201d\u51fa\u6765\u8282\u70b9\u7684\u53e5\u67c4\uff0c\u7c7b\u578b\u4e3a node_type\uff0c\u8282\u70b9\u7684\u751f\u6740\u5927\u6743\u5c31\u8fd9\u6837\u8fd4\u56de\u7ed9\u4e86\u7528\u6237\u6765\u5904\u7f6e\u3002 node_type \u662f\u6307\u5411\u6e38\u79bb\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff0c\u79f0\u4e3a\u8282\u70b9\u53e5\u67c4 2 \u3002\u53ea\u53ef\u79fb\u52a8\u4e0d\u53ef\u62f7\u8d1d\uff0c\u7c7b\u4f3c\u4e00\u4e2a\u6307\u5411\u8282\u70b9\u7684 unique_ptr\u3002 \u5f53\u8c03\u7528 extract(key) \u65f6\u4f1a\u628a key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u7ea2\u9ed1\u6811\u8282\u70b9\u201c\u8131\u79bb\u201d\u51fa\u6765\u2014\u2014\u4e0d\u662f\u76f4\u63a5\u91ca\u653e\u8282\u70b9\u5185\u5b58\u5e76\u9500\u6bc1\u952e\u503c\u5bf9\u8c61\uff0c\u800c\u662f\u628a\u5220\u9664\u7684\u8282\u70b9\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u8c03\u7528\u8005\uff0c\u4ee5\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488 node_type \u7684\u5f62\u5f0f\u3002 \u8c03\u7528 extract \u540e\uff0c\u8282\u70b9\u53e5\u67c4\u6307\u5411\u7684\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u5df2\u7ecf\u4ece map \u4e2d\u79fb\u9664\uff08\u5176 left\u3001right\u3001parent \u7b49\u6307\u9488\u4e3a NULL\uff09\uff0c\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\u3002 \u8282\u70b9\u4e2d\u4e0d\u4ec5\u5b58\u50a8\u7740\u6211\u4eec\u611f\u5174\u8da3\u7684\u952e\u548c\u503c\uff0c\u8fd8\u6709 left\u3001right\u3001parent\u3001color \u7b49\u7528\u4e8e\u7ef4\u62a4\u6570\u636e\u7ed3\u6784\u7684\u6210\u5458\u53d8\u91cf\uff0c\u5bf9\u7528\u6237\u4e0d\u53ef\u89c1\u3002 \u53ea\u662f\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u7ef4\u6301\u7740\u8282\u70b9\u7684\u751f\u547d\u5468\u671f\uff0c\u4fdd\u62a4\u7740\u952e key() \u548c\u503c mapped() \u6ca1\u6709\u88ab\u9500\u6bc1\uff0c\u5185\u5b58\u6ca1\u6709\u88ab\u91ca\u653e\u3002 \u5982\u679c\u8c03\u7528\u8005\u63a5\u4e0b\u6765\u4e0d\u505a\u64cd\u4f5c\uff0c\u90a3\u4e48\u5f53\u79bb\u5f00\u8c03\u7528\u8005\u6240\u5728\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u8fd9\u4e2a\u7279\u6b8a\u7684 unique_ptr \u4f1a\u81ea\u52a8\u91ca\u653e\u5176\u6307\u5411\u8282\u70b9\u3002 \u5bf9\u4e8e\u7b2c\u4e00\u4e2a\u6309\u952e\u53d6\u51fa\u8282\u70b9\u53e5\u67c4\u7684 extract \u91cd\u8f7d\uff1a\u5982\u679c\u952e\u503c\u4e0d\u5b58\u5728\uff0c\u90a3\u4e48 extract \u4f1a\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u7684\u7a7a\u8282\u70b9\u53e5\u67c4\uff0c\u7c7b\u4f3c\u4e8e\u7a7a\u6307\u9488\u3002\u53ef\u4ee5\u901a\u8fc7 (bool)node \u6765\u5224\u65ad\u4e00\u4e2a\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u7a7a\u3002 \u5bf9\u4e8e\u7b2c\u4e8c\u4e2a\u6309\u8fed\u4ee3\u5668\u53d6\u51fa\u53e5\u67c4\u7684 extract\uff1a\u603b\u662f\u6210\u529f\uff0c\u56e0\u4e3a\u65e2\u7136\u4f60\u5df2\u7ecf\u83b7\u5f97\u4e86\u8fed\u4ee3\u5668\uff0c\u80af\u5b9a\u662f find \u83b7\u5f97\u7684\uff0c\u800c find \u627e\u4e0d\u5230\u8fd4\u56de\u7684 end \u4f20\u5165 extract \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u6b63\u5982 erase \u8fed\u4ee3\u5668\u7248\u91cd\u8f7d erase(it) \u603b\u662f\u6210\u529f\u4e00\u6837\u3002 \u7528\u9014\u4e3e\u4f8b \u8c03\u7528\u8005\u7a0d\u540e\u53ef\u4ee5\u76f4\u63a5\u9500\u6bc1\u8fd9\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff1a { auto node = m.extract(\"fuck\"); print(node.key(), node.mapped()); } // node \u5728\u6b64\u81ea\u52a8\u9500\u6bc1 \u4e5f\u53ef\u4ee5\u505a\u4e00\u4e9b\u4fee\u6539\u540e\uff08\u4f8b\u5982\u4fee\u6539\u952e\u503c\uff09\uff0c\u7a0d\u540e\u91cd\u65b0\u7528 insert(node) \u91cd\u65b0\u628a\u4ed6\u63d2\u5165\u56de\u53bb\uff1a auto node = m.extract(\"fuck\"); node.key() = \"love\"; m.insert(std::move(node)); \u8fc7\u53bb\uff0c\u901a\u8fc7\u8fed\u4ee3\u5668\u6765\u4fee\u6539\u952e\u503c\u662f\u4e0d\u5141\u8bb8\u7684\uff1a map m; auto it = m.find(\"fuck\"); assert(it != m.end()); // *it \u662f pair it->first = \"love\"; // \u9519\u8bef\uff01first \u662f const string \u7c7b\u578b m.insert(*it); \u56e0\u4e3a\u76f4\u63a5\u4fee\u6539\u5728 map \u91cc\u9762\u7684\u4e00\u4e2a\u8282\u70b9\u7684\u952e\uff0c\u4f1a\u5bfc\u81f4\u6392\u5e8f\u5931\u6548\uff0c\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u3002\u800c extract \u53d6\u51fa\u6765\u7684\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u53ef\u4ee5\u4fee\u6539 .key() \uff0c\u4e0d\u4f1a\u5f71\u54cd\u4efb\u4f55\u7ea2\u9ed1\u6811\u7684\u987a\u5e8f\uff0c\u4ed6\u5df2\u7ecf\u4e0d\u5728\u6811\u91cc\u9762\u4e86\u3002 \u6216\u8005\u63d2\u5165\u5230\u53e6\u4e00\u4e2a\u4e0d\u540c\u7684 map \u5bf9\u8c61\uff08\u4f46\u952e\u548c\u503c\u7c7b\u578b\u76f8\u540c\uff09\u91cc\uff1a // \u4ece m1 \u632a\u5230 m2 auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); \u4f18\u70b9\u5728\u4e8e\uff0cextract \u548c\u8282\u70b9\u7248 insert \u4e0d\u6d89\u53ca\u5185\u5b58\u7684\u91cd\u65b0\u5206\u914d\u4e0e\u91ca\u653e\uff0c\u4e0d\u6d89\u53ca\u5143\u7d20\u7c7b\u578b\u7684\u79fb\u52a8\uff08\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e\u667a\u80fd\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u7684\u79fb\u52a8\u5e76\u4e0d\u4f1a\u5bfc\u81f4\u5176\u6307\u5411\u5bf9\u8c61\u7684\u79fb\u52a8\uff09\uff0c\u6240\u4ee5\u4f1a\u6bd4\u4e0b\u9762\u8fd9\u79cd\u4f20\u7edf\u5199\u6cd5\u66f4\u9ad8\u6548\uff1a // \u4ece m1 \u632a\u5230 m2\uff1a\u4f20\u7edf\u5199\u6cd5 if (m1.count(\"fuck\")) { auto value = std::move(m1.at(\"fuck\")); m2[\"fuck\"] = std::move(value); m1.erase(it); } \u4e0d\u7528 auto \u5b8c\u6574\u5199\u51fa\u5168\u90e8\u7c7b\u578b\u7684\u5f62\u5f0f\uff08\u53e4\u4ee3 C++98 \u4f5c\u98ce\uff09\uff1a typename map::node_type node = m.extract(\"fuck\"); K &k = node.key(); V &v = node.mapped(); set \u4e5f\u6709 extract \u51fd\u6570\uff0c\u5176\u8282\u70b9\u53e5\u67c4\u6ca1\u6709 key() \u548c mapped() \u4e86\uff0c\u800c\u662f\u53ea\u6709\u4e00\u4e2a value()\uff0c\u83b7\u53d6\u5176\u4e2d\u7684\u503c set s = {\"fuck\", \"suck\", \"dick\"}; set::node_type node = s.extract(\"fuck\"); V &v = node.value(); insert \u8282\u70b9\u7248 insert \u51fd\u6570\uff1a\u63d2\u5165\u6e38\u79bb\u8282\u70b9\u7684\u7248\u672c insert_return_type insert(node_type &&node); iterator insert(const_iterator pos, node_type &&node); // \u5e26\u63d0\u793a\u7684\u7248\u672c \u53ef\u4ee5\u7528 insert(move(node)) \u76f4\u63a5\u63d2\u5165\u4e00\u4e2a\u8282\u70b9\u3002 map m1 = { {\"fuck\", 985}, {\"dick\", 211}, }; map m2; auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); // \u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u4e0d\u53ef\u62f7\u8d1d\uff0c\u9700\u8981\u7528\u79fb\u52a8\u8bed\u4e49\u8fdb\u884c\u63d2\u5165 \u8c03\u7528 insert(move(node)) \u540e\u7531\u4e8e\u6240\u6709\u6743\u88ab\u79fb\u8d70\uff0cnode \u5c06\u4f1a\u5904\u4e8e\u201c\u7a7a\u6307\u9488\u201d\u72b6\u6001\uff0c\u53ef\u4ee5\u7528 node.empty() \u67e5\u8be2\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u201c\u7a7a\u201d\u72b6\u6001\uff0c\u5373\u8282\u70b9\u6240\u6709\u6743\u662f\u5426\u5df2\u7ecf\u79fb\u8d70\u3002 insert_return_type \u8fd9\u4e2a\u7248\u672c\u7684 insert \u8fd4\u56de\u503c\u7c7b\u578b insert_return_type \u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff08\u6211\u7684\u5929\u4ed6\u4eec\u7ec8\u4e8e\u80af\u7528\u7ed3\u6784\u4f53\u800c\u4e0d\u662f pair \u4e86\uff09\uff1a struct insert_return_type { iterator position; bool inserted; node_type node; }; insert_return_type insert(node_type &&nh); \u5b98\u65b9\u8bf4\u6cd5\u662f 1 \uff1a If nh is empty, inserted is false, position is end(), and node is empty. Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty. If the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key(). extract + insert \u8fd0\u7528\u6848\u4f8b map hells = { {666, \"devil\"}, }; map schools = { {985, \"professor\"}, {211, \"doctor\"}, {996, \"fucker\"}, }; auto node = schools.extract(996); hells.insert(std::move(node)); print(schools); print(hells); {211: \"doctor\", 985: \"professor\"} {666: \"devil\", 996: \"fucker\"} extract + insert(move(node)) \u5bf9\u6bd4 find + insert({key, val})\uff0c\u53ef\u4ee5\u907f\u514d\u952e\u548c\u503c\u7c7b\u578b\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u5f00\u9500\uff0c\u81f3\u59cb\u81f3\u7ec8\u79fb\u52a8\u7684\u53ea\u662f\u4e00\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u6307\u9488\uff0c\u5143\u7d20\u6ca1\u6709\u88ab\u79fb\u52a8\uff0c\u4e5f\u6ca1\u6709\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u4e0d\u5fc5\u8981\u7684\u5206\u914d\u548c\u91ca\u653e\u3002 \u4f46\u662f insert(move(node)) \u4ec5\u9002\u7528\u4e8e\u4ece extract \u4e2d\u53d6\u51fa\u73b0\u6709\u8282\u70b9\u7684\u60c5\u51b5\uff0c\u5982\u679c\u8981\u65b0\u5efa\u8282\u70b9\u8fd8\u5f97\u9760 insert({key, val}) \u6216\u8005 try_emplace(key, val) \u7684\u3002 extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u5df2\u77e5\u4e24\u4e2a\u6620\u5c04\u8868 tab1 \u548c tab2\uff0c\u548c\u4e00\u4e2a\u63a5\u53d7 K \u7c7b\u578b\u505a\u53c2\u6570\u7684\u4eff\u51fd\u6570 cond\u3002 \u8981\u6c42\u628a tab1 \u4e2d\u952e\u7b26\u5408 cond \u6761\u4ef6\u7684\u5143\u7d20\u79fb\u52a8\u5230 tab2 \u4e2d\u53bb\uff0c\u5176\u4f59\u4fdd\u7559\u5728 tab1 \u4e2d\u3002 \u6211\u4eec\u7f16\u5199\u56db\u4efd\u540c\u6837\u529f\u80fd\u7684\u7a0b\u5e8f\uff0c\u5206\u522b\u91c7\u7528\uff1a extract + \u5e26\u63d0\u793a\u7684 insert erase + \u5e26\u63d0\u793a\u7684 insert extract + \u76f4\u63a5 insert erase + \u76f4\u63a5 insert template void filter_with_extract(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); tab2.insert(std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); tab2.insert(std::move(kv)); } else ++it; } } template void filter_with_extract_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); hint = tab2.insert(hint, std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); hint = tab2.insert(hint, std::move(kv)); } else ++it; } } extract vs erase \u6027\u80fd\u6d4b\u8bd5\u7ed3\u679c (testextractvserase.cpp)\uff1a avg | min | max | total | cnt | tag 889| 803| 2388| 889271| 1000| filter_with_erase 642| 595| 1238| 642542| 1000| filter_with_extract 525| 491| 1398| 525137| 1000| filter_with_erase_with_hint 305| 289| 842| 305472| 1000| filter_with_extract_with_hint extract + \u5e26\u63d0\u793a\u7684 insert \u83b7\u80dc\uff0c\u5373\u51fd\u6570 filter_with_extract_with_hint \u662f\u6027\u80fd\u6700\u597d\u7684\u90a3\u4e00\u4e2a\u3002 \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u7531\u4e8e\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\uff0c\u6e38\u79bb\u8282\u70b9\u4e0d\u5c5e\u4e8e\u4efb\u4f55 map \u4e2d\uff0c\u4e0d\u9700\u8981\u6ee1\u8db3\u6392\u5e8f\u6027\u8d28\uff0c\u56e0\u6b64 node.key() \u53ef\u4fee\u6539\u3002 \u5148\u7528 extract \u53d6\u51fa\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u4fee\u6539\u5b8c\u8282\u70b9\u7684\u952e\u540e\u518d\u91cd\u65b0\u63d2\u5165\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u505a\u5230\u4ee5\u524d\u505a\u4e0d\u5230\u7684\u4fee\u6539\u952e\u503c\u3002 map m = { {\"fuck\", 985}, }; auto node = m.extract(\"fuck\"); // \u79fb\u51fa \"fuck\" \u952e\u5bf9\u5e94\u7684\u8282\u70b9\uff0c\u6b64\u65f6 m \u4f1a\u53d8\u4e3a\u7a7a node.key() = \"fxxk\"; // \u4fee\u6539\u952e\uff08\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->first \u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u952e\u7684\uff0c\u56e0\u4e3a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u8282\u70b9\u4e0d\u662f\u6e38\u79bb\u72b6\u6001\uff0c\u4fee\u6539\u952e\u4f1a\u7834\u574f\u6392\u5e8f\uff09 node.mapped() = 211; // \u4fee\u6539\u503c\uff08\u8fd9\u4e2a\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->second \u4e5f\u53ef\u4ee5\u4fee\u6539\uff09 m.insert(move(node)); // \u628a\u4fee\u6539\u597d\u7684\u8282\u70b9\u63d2\u5165\u56de\u53bb print(m); // {{\"fxxk\": 211}} \u76f8\u5f53\u4e8e\u4f60\u7ed9\u5c0f\u5b66\u751f\u6392\u961f\u65f6\uff0c\u6709\u4e00\u4e2a\u5c0f\u5b66\u751f\u7a81\u7136\u77ac\u95f4\u4e0d\u77e5\u9053\u5403\u4e86\u4ec0\u4e48\u6fc0\u7d20\u957f\u9ad8\u4e86\uff0c\u4f60\u7684\u961f\u4f0d\u5c31\u4f1a\u4e71\u6389\u3002 \u6240\u4ee5\u9700\u8981\u8ba9\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5148\u51fa\u5217\uff0c\u8ba9\u4ed6\u5355\u72ec\u4e00\u4e2a\u4eba\u957f\u9ad8\uff0c\u7b49\u4ed6\u957f\u9ad8\u5b8c\u4e86\u518d\u63d2\u5165\u56de\u961f\u5217\u3002 \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert \u4f46\u662f\u5c0f\u5b66\u751f\u957f\u9ad8\u7684\u91cf\u53ef\u80fd\u662f\u6709\u9650\u7684\uff08\u65b0\u7684\u952e\u53ef\u80fd\u548c\u8001\u952e\u5f88\u63a5\u8fd1\uff09\u3002 \u8fd9\u65f6\u63d2\u5165\u53ef\u4ee5\u4f18\u5148\u4ece\u4ed6\u957f\u9ad8\u4e4b\u524d\u7684\u4f4d\u7f6e\u5f00\u59cb\u4e8c\u5206\u6cd5\uff0c\u4e5f\u5c31\u662f\u7528 extract \u4e4b\u524d\uff0c\u8fd9\u4e2a\u5c0f\u5b66\u751f\u540e\u4e00\u4f4d\u540c\u5b66\u7684\u4f4d\u7f6e\uff0c\u4f5c\u4e3a insert \u7684\u63d0\u793a\uff0c\u8ba9 insert \u66f4\u5feb\u5b9a\u4f4d\u5230\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5e94\u8be5\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 auto it = m.find(\"fuck\"); assert(it != m.end()); // \u5047\u5b9a \"fuck\" \u5fc5\u987b\u5b58\u5728\uff08\u5982\u679c\u4e0d\u5b58\u5728\u4f1a\u8fd4\u56de end\uff09 auto next_it = std::next(it); // \u4e0b\u4e00\u4f4d\u540c\u5b66\uff08\u53ef\u80fd\u4f1a\u5f97\u5230 end\uff0c\u4f46\u6ca1\u5173\u7cfb\uff0c\u56e0\u4e3a insert \u7684\u63d0\u793a\u4e5f\u5141\u8bb8\u4e3a end \u8fed\u4ee3\u5668\uff09 auto node = m.extract(it); node.key() = \"fxxk\"; // \u4fee\u6539\u952e\u503c\uff0c\u53d8\u5316\u4e0d\u5927 m.insert(next_it, move(node)); // \u5982\u679c\u952e\u503c\u53d8\u52a8\u4e0d\u5927\uff0c\u4f18\u5148\u5c1d\u8bd5\u5728\u8001\u4f4d\u7f6e\u63d2\u5165 \u8fd9\u91cc\u7684 std::next(it) \u5bf9\u4e8e\u7b49\u4ef7\u4e8e it + 1\u3002\u4f46\u662f map \u5c5e\u4e8e\u53cc\u5411\u8fed\u4ee3\u5668\uff08\u800c\u4e0d\u662f\u968f\u673a\u8fed\u4ee3\u5668\uff09\uff0c\u4e0d\u652f\u6301\u52a0\u6cd5\u64cd\u4f5c\uff0c\u53ea\u652f\u6301\u5c31\u5730 ++\u3002\u6240\u4ee5 std::next \u5185\u90e8\u7b49\u4ef7\u4e8e\uff1a auto next(auto it) { auto next_it = it; // \u5148\u62f7\u8d1d\u4e00\u4efd\uff0c\u9632\u6b62\u539f\u8fed\u4ee3\u5668\u88ab\u7834\u574f\uff08\u8fed\u4ee3\u5668\u90fd\u652f\u6301\u62f7\u8d1d\uff0c\u6027\u8d28\u4e0a\u662f\u6d45\u62f7\u8d1d\uff09 ++next_it; // \u518d\u8ba9 next_it \u5c31\u5730\u81ea\u589e\u5230\u4e0b\u4e00\u4f4d return next_it; // \u8fd4\u56de\u73b0\u5728\u5df2\u7ecf\u76f8\u5f53\u4e8e it + 1 \u7684 next_it } \u5982\u679c\u952e\u4e0d\u53d8\uff0c\u6216\u8005\u952e\u53d8\u4e86\u4ee5\u540e\uff0c\u63d2\u5165\u4f4d\u7f6e\u4e0d\u53d8\u7684\u8bdd\uff0c\u90a3\u4e48\u8fd9\u6b21 insert \u53ef\u4ee5\u4f4e\u81f3 O(1) O(1) \u590d\u6742\u5ea6\u3002 map m = { {\"dick\", 211}, {\"fuck\", 985}, // \"fuck\" -> \"fxxk\" \u540e\uff0c\u91cd\u65b0\u63d2\u5165\uff0c\u5176\u4f9d\u5b57\u5178\u5e8f\u7684\u201c\u5927\u5c0f\u201d\u4f9d\u7136\u662f\u4ecb\u4e8e \"dick\" \u548c \"suck\" {\"suck\", 996}, }; merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 C++17 \u65b0\u589e\u7684 merge \u51fd\u6570 1 template void merge(map &__source); \u6ce8\uff1aset \u4e5f\u6709 merge \u51fd\u6570 \u6ce8\u610f\u5230 merge \u7684\u53c2\u6570\u662f\u53e6\u4e00\u4e2a map\uff0c\u53ef\u53d8\u5f15\u7528\uff0c\u5fc5\u987b\u548c\u672c map \u540c\u7c7b\u578b\uff08\u8fd9\u662f\u4e3a\u4e86\u4fdd\u8bc1\u8282\u70b9\u53e5\u67c4\u7c7b\u578b\u76f8\u540c\uff09\uff0c\u4f46\u5141\u8bb8\u6709\u4e0d\u540c\u7684\u6bd4\u8f83\u51fd\u6570 merge(source) \u4f1a\u628a source \u4e2d\u7684\u6240\u6709\u8282\u70b9\u90fd \u79fb\u52a8 \u5e76\u5408\u5e76\u5230\u672c map\uff0c\u6ce8\u610f\u662f \u79fb\u52a8 \u800c\u4e0d\u662f\u62f7\u8d1d\uff0csource \u5c06\u4f1a\u88ab\u6e05\u7a7a\uff0c\u8fd9\u6837\u662f\u4e3a\u4e86\u66f4\u9ad8\u6548\u3002 insert(source.begin(), source.end()) \u5219\u662f\u628a source \u91cc\u7684\u5143\u7d20\u62f7\u8d1d\u540e\u63d2\u5165\u5230\u672c map\uff0c\u66f4\u4f4e\u6548\uff0c\u56e0\u4e3a\u9700\u8981\u62f7\u8d1d\uff0c\u8fd8\u5f97\u65b0\u5efa\u7ea2\u9ed1\u6811\u8282\u70b9\uff0c\u989d\u5916\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 \u5bf9\u4e8e\u952e\u5b58\u5728\u51b2\u7a81\u7684\u60c5\u51b5\uff1a merge: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u79fb\u52a8\uff0c\u4fdd\u7559\u5728 source \u91cc\u3002 insert: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u63d2\u5165\u672c map\u3002\u65e0\u8bba\u6709\u6ca1\u6709\u63d2\u5165\u672c map\uff0c\u539f source \u4e2d\u7684\u952e\u90fd\u4e0d\u4f1a\u88ab\u6e05\u9664\u3002 \u56e0\u6b64\uff0cmerge \u4e5f\u5e76\u4e0d\u603b\u662f\u5b8c\u5168\u6e05\u7a7a source\uff0c\u5f53 source \u548c\u672c map \u6709\u51b2\u7a81\u65f6\uff0c\u51b2\u7a81\u7684\u952e\u5c31\u4fdd\u7559\u5728 source \u91cc\u4e86\u3002 merge \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u624b\u52a8\u7528 extract \u548c insert \u6765\u79fb\u52a8\u8282\u70b9\u7684\u4ee3\u7801\uff1a // m1.merge(m2) \u7b49\u4ef7\u4e8e\uff1a auto hint = m1.begin(); for (auto it = m2.begin(); it != m2.end(); ++it) { if (!m1.contains(it->first)) { auto node = m2.extract(it); hint = m1.insert(hint, node); } } \u6279\u91cf insert vs merge \u540c\u6837\u505a\u5230\u4e24\u4e2a map \u5408\u5e76\uff0c m1.merge(m2) \u4e0e m1.insert(m2.begin(), m2.end()) \u6027\u80fd\u6bd4\u8f83\uff1a #include #include #include \"benchmark/benchmark.h\" using namespace std; static void BM_Insert(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.insert(m1.begin(), m1.end()); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Insert)->Arg(1000); static void BM_Merge(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.merge(m1); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Merge)->Arg(1000); merge \u51fd\u6570\u4e0d\u4f1a\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u5185\u5b58\u5206\u914d\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u6240\u4ee5\u66f4\u9ad8\u6548\u3002\u4f46\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u4ed6\u4f1a\u6e05\u7a7a m2\uff01 merge \u76f8\u5f53\u4e8e\u628a m2 \u7684\u5143\u7d20\u201c\u79fb\u52a8\u201d\u5230 m1 \u4e2d\u53bb\u4e86\u3002 insert \u5219\u662f\u628a m2 \u7684\u5143\u7d20\u201c\u62f7\u8d1d\u201d\u4e86\u4e00\u4efd\u63d2\u5165\u5230 m1 \u4e2d\u53bb\uff0c\u6548\u7387\u81ea\u7136\u4f4e\u4e0b\u3002 \u5982\u679c\u4e0d\u60f3\u7834\u574f\u6389 m2\uff0c\u6216\u8005\u4f60\u7528\u4e0d\u4e0a C++17\uff0c\u5219\u4ecd\u9700\u8981\u4f20\u7edf\u7684 insert\u3002 merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c merge(m2) \u548c insert(m2.begin(), m2.end()) \u4e00\u6837\u5c3f\u6027\uff1a\u5982\u679c m2 \u4e2d\u7684\u952e\u5728 m1 \u4e2d\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4e0d\u4f1a extract \u8be5 m2 \u4e2d\u7684\u8282\u70b9\uff0c\u4ecd\u7136\u7559\u5728 m2 \u4e2d\u3002 int main() { std::map ma {{1, \"apple\"}, {5, \"pear\"}, {10, \"banana\"}}; std::map mb {{2, \"zorro\"}, {4, \"batman\"}, {5, \"X\"}, {8, \"alpaca\"}}; std::map u; u.merge(ma); std::cout << \"ma.size(): \" << ma.size() << '\\n'; u.merge(mb); std::cout << \"mb.size(): \" << mb.size() << '\\n'; std::cout << \"mb.at(5): \" << mb.at(5) << '\\n'; for(auto const &kv: u) std::cout << kv.first << \", \" << kv.second << '\\n'; } map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 map \u5bb9\u5668\u7684\u5168\u90e8\u53c2\u6570\u4e3a\uff1a std::map \u5176\u4e2d\u7b2c 3\u30014 \u4e2a\u53c2\u6570 Cmp \u548c Alloc \u53ef\u4ee5\u7701\u7565\u3002 Cmp \u9ed8\u8ba4\u4e3a std::less Alloc \u9ed8\u8ba4\u4e3a std::allocator> \u56e0\u6b64 map \u7684\u5b8c\u6574\u6a21\u677f\u53c2\u6570\u662f\uff1a std::map, std::allocator>> \u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 map \u3002 \u5176\u4e2d allocator \u6211\u4eec\u4ee5\u540e\u4e13\u95e8\u5f00\u4e00\u8282\u8bfe\u8bb2\uff0c\u5176\u4ed6\u5f88\u591a\u5bb9\u5668\u90fd\u6709 allocator\u3002 \u4eca\u5929\u53ea\u7814\u7a76 Cmp \u8fd9\u4e2a\u53c2\u6570\uff0c\u4ed6\u51b3\u5b9a\u4e86 map \u5982\u4f55\u6392\u5e8f\uff0c\u5224\u65ad\u76f8\u7b49\u3002 std::map> \u8fd9\u4e2a std::less \u662f\u4e2a\u4ec0\u4e48\u5462\uff1f\u662f\u4e00\u4e2a\u4eff\u51fd\u6570(functor)\u3002 template struct less { constexpr bool operator()(T const &x, T const &y) const { return x < y; } }; \u5177\u6709\u6210\u5458\u51fd\u6570 operator() \u7684\u7c7b\u578b\uff0c\u90fd\u88ab\u79f0\u4e4b\u4e3a\u4eff\u51fd\u6570\u3002 std::less \u7684\u4f5c\u7528 \u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u5706\u62ec\u53f7\u5f53\u505a\u666e\u901a\u51fd\u6570\u8c03\u7528\uff0c\u8fd9\u5c31\u662f\u201c\u4eff\u51fd\u6570\u201d\u7684\u5f97\u540d\u539f\u56e0\uff0c\u4f8b\u5982\uff1a less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true operator() \u6ce8\u610f\u4eff\u51fd\u6570\u7684\u6210\u5458\u51fd\u6570 operator() \u662f\u4e24\u4e2a\u62ec\u53f7\uff1a operator()(...) \u7b2c\u4e00\u4e2a\u62ec\u53f7\u662f operator() \u7684\u4e00\u90e8\u5206\uff0c\u8868\u793a\u8fd9\u662f\u5bf9\u5706\u62ec\u53f7 () \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u7b2c\u4e8c\u4e2a\u62ec\u53f7\u662f\u51fd\u6570\u7684\u53c2\u6570\u5217\u8868\uff0c\u91cc\u9762\u662f operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u5f62\u53c2\u3002 operator() \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __call__ \u3002\u6b63\u5982 operator< \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __lt__ \u3002\u8fd9\u91cc operator \u548c () \u662f\u4e00\u4e2a\u6574\u4f53\uff0c\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e86\u4e00\u4e2a\u6807\u8bc6\u7b26\u3002 \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f std::map> \u6211\u4eec\u4e4b\u524d\u63d0\u5230 map \u5185\u90e8\u7684\u5143\u7d20\u59cb\u7ec8\u6309\u7167\u952e K \u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002 map \u51b3\u5b9a\u5927\u5c0f\u987a\u5e8f\u7684\uff0c\u5e76\u4e0d\u662f\u76f4\u63a5\u8c03\u7528 K \u7c7b\u578b\u7684\u6bd4\u8f83\u8fd0\u7b97\u7b26 operator< \u3002 \u800c\u662f\u8c03\u7528\u4ed6\u7684\u6a21\u677f\u53c2\u6570 Cmp \u7c7b\u578b\u7684 operator() \u3002 \u8fd9\u662f\u4e3a\u4e86\u5141\u8bb8\u7528\u6237\u901a\u8fc7\u4fee\u6539\u8fd9\u4e2a\u53c2\u6570\uff0c\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\uff0c\u9632\u6b62 map \u6570\u636e\u7ed3\u6784\u4e0e\u5177\u4f53\u7684\u6bd4\u8f83\u65b9\u6cd5\u8026\u5408\u3002 \u7531\u4e8e\u9ed8\u8ba4\u7684 Cmp \u662f less \uff0c\u8c03\u7528 Cmp()(x, y) \u5c31\u76f8\u5f53\u4e8e x < y \uff0c\u7531\u6b64\u5b9e\u73b0\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002 \u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u4fee\u6539\u8fd9\u4e00\u9ed8\u8ba4\u884c\u4e3a\u3002 \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u4e00\u4e2a\u7c7b\u578b\u8981\u60f3\u4f5c\u4e3a map \u7684\u952e\uff0c\u53ea\u9700\u8981\u4ed6\u652f\u6301 < \u8fd0\u7b97\u7b26\u5373\u53ef\uff0c\u4e0d\u5fc5\u5b9a\u4e49\u5176\u4ed6 > \u3001 == \u8fd0\u7b97\u7b26\u3002 \u5f53 map \u9700\u8981\u5224\u65ad\u4e24\u4e2a\u952e\u662f\u5426\u76f8\u7b49\u65f6 x == y \uff0c\u4f1a\u7528 !(x < y) && !(y < x) \u6765\u7b49\u4ef7\u5730\u8ba1\u7b97\u3002 string, string_view, int, float, void *, shared_ptr, pair, tuple, array\u2026 \u8fd9\u4e9b\u7c7b\u578b\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u90fd\u53ef\u4ee5\u4f5c\u4e3a map \u7684\u952e\u3002 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u5982\u679c\u4f60\u5199\u4e86\u4e2a\u81ea\u5b9a\u4e49\u7c7b Student\uff0c\u8981\u8ba9\u4ed6\u4f5c\u4e3a map \u7684\u952e\u7c7b\u578b\uff0c\u6709\u4e09\u79cd\u65b9\u6cd5\uff1a \u4e00\u3001\u5728 Student \u7c7b\u4e2d\u6dfb\u52a0 operator< struct Student { string name; int id; string sex; bool operator<(Student const &that) const { return x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))); // \u7b49\u4ef7\u4e8e\uff1a return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); // tuple \u5b9e\u73b0\u4e86\u6b63\u786e\u7684 operator< \u8fd0\u7b97\u7b26 } }; map stutab; \u4e8c\u3001\u7279\u5316 less \uff0c\u6dfb\u52a0 operator() struct Student { string name; int id; string sex; }; template <> struct std::less { // \u7528\u6237\u53ef\u4ee5\u7279\u5316\u6807\u51c6\u5e93\u4e2d\u7684 trait bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u5982\u679c map \u5916\u9762\u8981\u7528\u7528\u5230\u8fd9\u4e2a\u7c7b\u7684\u5927\u5c0f\u6bd4\u8f83\uff0c\u4e5f\u53ea\u80fd\u7528 less()(stu1, stu2) \u4ee3\u66ff stu1 < stu2 \u3002 \u4e09\u3001\u91cd\u65b0\u81ea\u5b9a\u4e49\u4e00\u4e2a\u4eff\u51fd\u6570\u7c7b LessStudent \uff0c\u6dfb\u52a0 operator() \uff0c\u7136\u540e\u628a\u8fd9\u4e2a LessStudent \u4f5c\u4e3a map \u7684\u6bd4\u8f83\u5668\u4f20\u5165\u6a21\u677f struct Student { string name; int id; string sex; }; struct LessStudent { bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u6bcf\u6b21\u521b\u5efa\u65b0\u7684 map \u65f6\uff0c\u90fd\u9700\u8981\u52a0\u4e00\u4e2a LessStudent \u53c2\u6570\u3002 \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 \u5982\u679c\u5e0c\u671b map \u5728\u67e5\u627e\u65f6\u53ea\u6839\u636e\u5b66\u751f\u59d3\u540d\u7d22\u5f15\uff0c\u5219\u53ea\u9700\u8981\u6539\u4e00\u4e0b\u6bd4\u8f83\u5668\u7684\u5b9e\u73b0\uff0c\u8ba9\u4ed6\u53ea\u6bd4\u8f83\u59d3\u540d\u5b57\u6bb5\u5373\u53ef\u3002 struct LessStudent { bool operator()(Student const &x, Student const &y) const { return x.name < y.name; } }; \u4e0a\u9762\u8fd9\u6837\u7684\u6bd4\u8f83\u5668\uff0cmap \u4f1a\u8ba4\u4e3a\u59d3\u540d name \u76f8\u540c\u7684 Student \u5c31\u662f\u76f8\u7b49\u7684\uff0c\u5e76\u53bb\u91cd\u3002\u5373\u4f7f id \u548c sex \u4e0d\u540c\uff0c\u53ea\u8981\u540d\u5b57\u76f8\u7b49\u5c31\u4f1a\u89c6\u4e3a\u91cd\u590d\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u9488\u5bf9\u7279\u5b9a\u5b57\u6bb5\u7684\u53bb\u91cd\u3002 \u7ed3\u8bba\uff1amap \u7684\u6392\u5e8f\u548c\u53bb\u91cd\uff0c\u90fd\u53d6\u51b3\u4e8e\u4e8e\u4f60\u7684\u6bd4\u8f83\u5668\u5982\u4f55\u5b9e\u73b0\uff01\u6bd4\u8f83\u5668\u91cc\u6ca1\u6bd4\u8f83\u7684\u5b57\u6bb5\uff0c\u5c31\u4f1a\u88ab\u5ffd\u7565\u800c\u4e0d\u53c2\u4e0e\u6392\u5e8f\u3001\u7d22\u5f15\u3001\u548c\u53bb\u91cd\u3002 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u56db\uff08\u540c\u4e00\uff09\u3001\u5229\u7528 C++20 \u65b0\u7279\u6027\uff0c\u4e09\u8def\u6bd4\u8f83\u8fd0\u7b97\u7b26 <=> \uff1a\u5982\u679c\u81ea\u5b9a\u4e49\u7c7b\u7684\u6bcf\u4e2a\u6210\u5458\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u53ef\u4ee5\u628a operator<=> \u51fd\u6570\u58f0\u660e\u4e3a default \uff0c\u7136\u540e\u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u6dfb\u52a0\u81ea\u5b9a\u4e49\u7c7b\u7684\u6240\u6709\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 struct Student { string name; int id; string sex; auto operator<=>(Student const &) const = default; }; \u6b64\u65f6\u9ed8\u8ba4\u7684 operator< \u5b9e\u73b0\u7b49\u4ef7\u4e8e x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))) \u3002 <=> \u7684\u8fd4\u56de\u7c7b\u578b\u662f std::strong_ordering \uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u4e09\u79cd\u53d6\u503c\u7684\u5f3a\u679a\u4e3e\u7c7b\u578b <=> \u5bf9\u5e94\u7684\u4eff\u51fd\u6570\u4e3a std::compare_three_way \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 libstdc++ \u5934\u6587\u4ef6\u4e2d\u7684 less \u548c greater \u5b9e\u73b0\u53c2\u8003\uff1a template struct less : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template struct greater : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; \u7c7b\u4f3c\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u8fd8\u6709\uff1a \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b x == y std::equal_to x != y std::not_equal_to x < y std::less x > y std::greater x <= y std::less_equal x >= y std::greater_equal x + y std::plus x - y std::minus x * y std::multiplies x / y std::divides x % y std::modulus -x std::negate \u4ed6\u4eec\u90fd\u5728 #include \u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u3002 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u6848\u4f8b\uff1a\u4f7f\u7528 greater \u4eff\u51fd\u6570\uff0c\u8ba9 map \u53cd\u8fc7\u6765\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\uff1a auto ilist = { {985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}, }; map m1 = ilist; // \u4ece\u5c0f\u5230\u5927\u6392\u5e8f map> m2 = ilist; // \u4ece\u5927\u5230\u5c0f\u6392\u5e8f print(m1); // {{211, \"\u811a\u8e22\"}, {985, \"\u62f3\u6253\"}} print(m2); // {{985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}} \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u81ea\u5b9a\u4e49\u6bd4\u8f83\u4eff\u51fd\u6570\uff0c\u5b9e\u73b0\u65e0\u89c6\u952e\u5927\u5c0f\u5199\u7684 map \u5bb9\u5668\uff1a struct LessIgnoreCase { bool operator()(std::string const &lhs, std::string const &rhs) const { return std::lexicographical_compare // \u4f4d\u4e8e \u5934\u6587\u4ef6\uff0c\u548c std::string \u540c\u6b3e\u7684\u5b57\u5178\u5e8f\u6bd4\u8f83 ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); } }; int main() { map m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"STUdy\"}, \"cpp\"}, {{\"stUDy\"}, \"js\"}, }; print(m); print(\"fuck\u5bf9\u5e94\u7684\u503c\u4e3a:\", m.at(\"fuck\")); return 0; } {\"Fuck\": \"rust\", \"STUdy\": \"cpp\"} fuck\u5bf9\u5e94\u7684\u503c\u4e3a: \"rust\" \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 C++11 \u7684 lambda \u8868\u8fbe\u5f0f\u4e5f\u662f\u4eff\u51fd\u6570\uff0c\u914d\u5408 decltype \u540e\u5c31\u53ef\u4ee5\u4f20\u5165 map \u4f5c\u4e3a\u6bd4\u8f83\u5668\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m({ {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }, cmp); print(m); auto val = m.at({\"fuck\"}); print(val); \u5199\u7684\u66f4\u6e05\u6670\u4e00\u70b9\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m(cmp); m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }; print(m); auto val = m.at({\"fuck\"}); print(val); map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u521a\u521a\u7528\u5230\u7684\u4e24\u4e2a map \u6784\u9020\u51fd\u6570\uff1a template > class map { explicit map(Cmp cmp); map(initializer_list> ilist, Cmp cmp); }; \u57fa\u672c\u6bcf\u4e2a map \u7684\u6784\u9020\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u63d0\u4f9b\u989d\u5916 cmp \u53c2\u6570\u7684\u7248\u672c\uff0c\u7edf\u4e00\u90fd\u662f\u5728\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u540e\u9762\u8ffd\u52a0\u3002 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u4f20\u5165\u7684\u4eff\u51fd\u6570 cmp \u751a\u81f3\u53ef\u4ee5\u6355\u83b7\u5176\u4ed6\u53d8\u91cf\uff0c\u8fd9\u79cd\u6355\u83b7\u4e86\u53d8\u91cf\u7684\u4eff\u51fd\u6570\u79f0\u4e4b\u4e3a\u6709\u72b6\u6001\u4eff\u51fd\u6570 - stateful functor\uff0c\u548c\u65e0\u72b6\u6001\u4eff\u51fd\u6570 - stateless functor \u76f8\u5bf9\uff1a vector arr = {1, 4, 2, 8, 5, 7}; auto cmp = [&] (int i, int j) { return arr[i] < arr[j]; }; map m(cmp); \u5229\u7528\u6709\u72b6\u6001\u4eff\u51fd\u6570\u53ef\u4ee5\u5b9e\u73b0 argsort \u7b49\u64cd\u4f5c\uff0c\u4f8b\u5982\u4e0a\u9762\u4ee3\u7801\u5c31\u662f\u6839\u636e\u5728 arr \u91cc\u5bf9\u5e94\u7d22\u5f15\u7684\u503c\u6765\u6392\u5e8f\u3002 \u7531\u4e8e map \u9700\u8981\u6bd4\u8f83\u4eff\u51fd\u6570\u4e3a\u7eaf\u51fd\u6570(pure function)\uff0c\u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c\u8bf7\u4fdd\u8bc1 map \u5b58\u5728\u671f\u95f4 arr \u7684\u5185\u5bb9\u4e0d\u53d1\u751f\u53d8\u5316\uff0c\u5426\u5219 map \u57fa\u4e8e\u6392\u5e8f\u7684\u4e8c\u5206\u67e5\u627e\u529f\u80fd\u4f1a\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u4f20\u5165\u6bd4\u8f83\u5668\u4eff\u51fd\u6570\u662f\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u5178\u578b\u7684\u7b56\u7565\u6a21\u5f0f\uff0c\u901a\u8fc7\u4f9d\u8d56\u6ce8\u5165\uff0c\u5141\u8bb8\u6211\u4eec\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\u3002 \u5efa\u8bae\u7528 function \u5982\u679c\u5acc decltype \u9ebb\u70e6\uff08\u96be\u4ee5\u5728\u5168\u5c40\u6216\u7c7b\u5185\u90e8\u7528\uff09\uff0cfunction \u5bb9\u5668\u4f5c\u4e3a\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u7edf\u4e00\u4e86\uff1a auto cmp = [] (int i, int j) { return i < j; }; map> m; \u7a0d\u540e\u8fd8\u53ef\u4ee5\u901a\u8fc7 key_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u952e\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff0c\u8fd9\u4e2a\u5c31\u662f\u4f60\u521a\u521a\u4f20\u5165\u7684 cmp \u53c2\u6570\uff1a m.key_comp()(1, 2); // \u7b49\u4ef7\u4e8e cmp(1, 2) value_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u5143\u7d20\uff08\u952e-\u503c\u5bf9\uff09\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff08\u4ed6\u5e2e\u4f60\u9002\u914d\u53c2\u6570\u7c7b\u578b\u4e86\uff09\uff1a m.value_comp()({1, 0}, {2, 0}); // \u7b49\u4ef7\u4e8e cmp(1, 2) \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 C++14 \u65b0\u589e\u4e86\u201c\u900f\u660e(transparent)\u201d\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u3002 \u5bf9\u4e8e less\u3001greater \u8fd9\u7c7b\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u4eff\u51fd\u6570\uff0c\u6307\u5b9a\u6a21\u677f\u53c2\u6570\u4e3a void \u5373\u53ef\u8ba9\u4e00\u4e2a\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u53d8\u6210\u201c\u900f\u660e\u201d\u7684\u3002\u4f8b\u5982\u5bf9 less \u800c\u8a00\uff0c\u4ed6\u7684\u900f\u660e\u7248\u5c31\u662f less \u3002 C++14 \u4e4b\u524d\u7528\u7684\u90fd\u662f\u201c\u4e0d\u900f\u660e\u201d\u7248\u7684\u4eff\u51fd\u6570\uff0c\u5fc5\u987b\u6307\u5b9a\u4e00\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u4f8b\u5982 less \u5c31\u53ea\u80fd\u7528\u4e8e int \u7c7b\u578b\u7684\u6bd4\u8f83\uff0c less \u5c31\u53ea\u80fd\u7528\u4e8e string \u7c7b\u578b\u7684\u6bd4\u8f83\u3002 \u65e0\u6cd5\u7528 less \u4eff\u51fd\u6570\u6bd4\u8f83 string \u7c7b\u578b\u3002 \u800c less \u662f\u901a\u7528\u7684\uff0c\u4ed6\u7684 operator() \u51fd\u6570\u662f\u6cdb\u578b\u7684\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u3002 template <> struct less { // \u9488\u5bf9 void \u7684\u7279\u5316 // \u6807\u51c6\u59d4\u5458\u4f1a\u60f3\uff1a\u7531\u4e8e void \u7c7b\u578b\u4e0d\u53ef\u80fd\u6709 < \u8fd0\u7b97\u7b26\u7684\u9700\u6c42\uff0c\u6240\u4ee5\u4ed6\u4eec\u5e72\u8106\u62ff void \u4f5c\u4e3a\u900f\u660e\u7248\u7684\u6a21\u677f\u53c2\u6570\u201c\u5360\u4f4d\u7b26\u201d\u4e86 template constexpr decltype(auto) operator()(Tx &&x, Ty &&y) const { return forward(x) < forward(y); } struct is_transparent; // \u7a7a\u7c7b\uff0c\u4ec5\u4f9b SFINAE \u5143\u7f16\u7a0b\u65f6\u68c0\u6d4b\u4e00\u4e2a\u4eff\u51fd\u6570\u662f\u5426\u900f\u660e\u65f6\u4f7f\u7528 }; \u6211\u7684\u601d\u8003\uff1a\u4e0d\u900f\u660e\u7248\u7684 less \u6cdb\u578b\u4f53\u73b0\u5728\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u4e0a\uff0c\u800c\u900f\u660e\u7248\u7684\u4f53\u73b0\u5728\u4e86\u6210\u5458\u51fd\u6570 operator() \u7684\u6a21\u677f\u53c2\u6570\u4e0a\u3002 \u8fd9\u91cc\u7528 void \u7279\u5316\u53ea\u662f\u4e00\u4e2a\u5077\u61d2\uff0c void \u5e76\u6ca1\u6709\u4ec0\u4e48\u7279\u6b8a\u7684\uff0c\u5b9e\u9645\u4e0a\u5e94\u8be5\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u6ca1\u6709\u6a21\u677f\u7684 transparent_less \u7c7b\uff0c\u4f46\u4ed6\u4eec\u5c31\u662f\u61d2\u5f97\u5f15\u5165\u65b0\u6807\u8bc6\u7b26\u3002 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u201c\u900f\u660e\u201d\u7248\u7684\u597d\u5904\u662f\u53ef\u4ee5\u540c\u4e00\u4e2a\u517c\u5bb9\u4efb\u610f\u7c7b\u578b\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a cmp \u5bf9\u8c61\u3002\u800c\u4e0d\u900f\u660e\u7248\u7684\u597d\u5904\u662f\u65b9\u4fbf\u7279\u5316 traits\uff0c\u4f46\u6bd5\u7adf < \u8fd0\u7b97\u7b26\u662f\u53ef\u4ee5\u7528\u6237\u81ea\u5b9a\u4e49(\u8fd0\u7b97\u7b26\u91cd\u8f7d)\u7684\uff0c\u6ca1\u5fc5\u8981\u7528 traits \u7279\u5316\uff0c\u6240\u4ee5\u4ed6\u4eec\u9010\u6b65\u53d1\u73b0\u900f\u660e\u7248\u9999\u4e86\uff0c\u8fd8\u80fd\u652f\u6301\u5de6\u53f3\u53c2\u6570\u4e3a\u4e0d\u540c\u7c7b\u578b\u3002 less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u4f46\u4e5f\u8981\u7279\u522b\u6ce8\u610f\u4e0d\u80fd\u518d\u4f9d\u8d56\u53c2\u6570\u7c7b\u578b\u81ea\u52a8\u7684\u9690\u5f0f\u8f6c\u6362\u4e86\uff0c\u5fc5\u987b\u81f3\u5c11\u5199\u5b8c\u6574\u5176\u4e2d\u4e00\u4e2a string(\"hello\") \u624d\u80fd\u89e6\u53d1 string \u7684 operator< \u800c\u4e0d\u662f const char * \u7684\u6307\u9488\u6bd4\u5927\u5c0f\u3002\u5982\u679c\u53ea\u5199 cmp(\"cmake\", \"cppcon\") \u5219\u662f\u5728\u6bd4\u8f83\u6307\u9488\u7684\u5730\u5740\u5927\u5c0f\uff0c\u7ed3\u679c\u662f\u4e0d\u4e00\u5b9a\u7684\u3002 \u7531\u4e8e C++14 \u7684 less \u6a21\u677f\u53c2\u6570 T \u9ed8\u8ba4\u4e3a void\uff0c\u6240\u4ee5 less \u8fd8\u53ef\u4ee5\u7b80\u5199\u6210 less<> \u3002 less<> cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u666e\u901a find \u51fd\u6570\uff1a\u952e\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570 iterator find(K const &k); const_iterator find(K const &k) const; C++14 \u65b0\u589e\u6cdb\u578b\u7248\u7684 find \u51fd\u6570 1 \uff1a\u4efb\u610f\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570\uff0c\u53ea\u8981\u8be5\u7c7b\u578b\u652f\u6301\u4e0e\u548c\u952e\u6bd4\u5927\u5c0f\u3002 template iterator find(Kt &&k); template const_iterator find(Kt &&k) const; \u8fd9\u91cc\u7684 Kt \u662f\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\uff0c\u6b64\u5904 && \u662f\u4e07\u80fd\u5f15\u7528\u4e0d\u662f\u53f3\u503c\u5f15\u7528\u3002 \u76f8\u540c\u70b9\uff1a\u627e\u5230\u4e86\u5c31\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u4e0e\u8be5\u53c2\u6570\u76f8\u7b49\u7684\u5143\u7d20\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8fd8\u662f\u8fd4\u56de end()\u3002 \u4e0d\u540c\u70b9\uff1a\u6cdb\u578b\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b Kt \u4e0d\u5fc5\u548c\u952e\u7c7b\u578b K \u4e00\u81f4\uff0c\u53ea\u8981 Kt \u548c K \u53ef\u4ee5\u6bd4\u8f83\u5927\u5c0f\uff08< \u8fd0\u7b97\u7b26\uff09\u5373\u53ef\u3002 \u4e0d\u4ec5 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u8981\u60f3\u7528\u6cdb\u578b\u7248\u7684 find \u51fd\u6570\u6709\u4e00\u4e2a\u6761\u4ef6\uff1a map \u7684\u6bd4\u8f83\u5668\u5fc5\u987b\u662f\u201c\u900f\u660e(transparent)\u201d\u7684\uff0c\u4e5f\u5c31\u662f less \u8fd9\u79cd\u3002\u5426\u5219\u6cdb\u578b\u7248\u7684 find(Kt &&) \u4e0d\u4f1a\u53c2\u4e0e\u91cd\u8f7d\uff0c\u4e5f\u5c31\u662f\u53ea\u80fd\u8c03\u7528\u4f20\u7edf\u7684 find(K const &) \u3002 \u4f46\u662f map \u9ed8\u8ba4\u7684\u6bd4\u8f83\u5668\u662f less \uff0c\u4ed6\u662f\u4e0d\u900f\u660e\u7684\uff0c\u6bd4\u8f83\u7684\u4e24\u8fb9\u5fc5\u987b\u90fd\u662f K \u7c7b\u578b\u3002\u5982\u679c\u5176\u4e2d\u4e00\u8fb9\u4e0d\u662f\u7684\u8bdd\uff0c\u5c31\u5f97\u5148\u9690\u5f0f\u8f6c\u6362\u4e3a K \u624d\u80fd\u7528\u3002 \u8fd9\u662f\u65e9\u671f C++98 \u8bbe\u8ba1\u7684\u5931\u8d25\uff0c\u5f53\u65f6\u4ed6\u4eec\u6ca1\u60f3\u5230 find \u8fd8\u53ef\u4ee5\u63a5\u53d7 string_view \u548c const char * \u8fd9\u7c7b\u53ef\u4ee5\u548c string \u6bd4\u8f83\uff0c\u4f46\u6784\u9020\u4f1a\u5ec9\u4ef7\u5f97\u591a\u7684\u5f31\u5f15\u7528\u7c7b\u578b\u3002 \u53ea\u597d\u540e\u6765\u5f15\u5165\u4e86\u900f\u660e\u6bd4\u8f83\u5668\u4f01\u56fe\u529b\u633d\u72c2\u6f9c\uff0c\u7136\u800c\u4e3a\u4e86\u5386\u53f2\u517c\u5bb9\uff0c map \u9ed8\u8ba4\u4ecd\u7136\u662f map> \u3002 \u5982\u679c\u6211\u4eec\u540c\u5b66\u7684\u7f16\u8bd1\u5668\u652f\u6301 C++14\uff0c\u5efa\u8bae\u5168\u90e8\u6539\u7528\u8fd9\u79cd\u5199\u6cd5 map> \uff0c\u4ece\u800c\u7528\u4e0a\u66f4\u9ad8\u6548\u7684 find\u3001at\u3001erase\u3001count\u3001contains \u7b49\u9700\u8981\u6309\u952e\u67e5\u627e\u5143\u7d20\u7684\u51fd\u6570\u3002 \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u9664\u975e\u4f20\u5165\u7684\u521a\u597d\u5c31\u662f\u4e00\u4e2a string \u7684 const \u5f15\u7528\uff0c\u5426\u5219\u5c31\u4f1a\u53d1\u751f\u9690\u5f0f\u6784\u9020 string \u7684\u64cd\u4f5c\u3002 \u5982\u679c\u4f20\u5165\u7684\u662f\u4e00\u4e2a string_view \u6216 const char * \uff0c\u90a3\u4e48\u9700\u8981\u4ece\u4ed6\u4eec\u6784\u9020\u51fa\u4e00\u4e2a string \uff0c\u7136\u540e\u624d\u80fd\u4f20\u5165\u4f20\u7edf\u7684 find(string const &) \u51fd\u6570\u3002\u800c string \u7684\u6784\u9020\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e14\u53ef\u80fd\u4ea7\u751f\u5185\u5b58\u5206\u914d\u3002 \u5bf9\u4e8e\u6bd4\u8f83\u5927\u7684\u5b57\u7b26\u4e32\u505a\u952e\u503c\uff0c\u6bcf\u6b21\u67e5\u627e\u90fd\u9700\u8981\u91cd\u65b0\u6784\u9020\u4e00\u4e2a string \u5bf9\u8c61\uff0c\u5f00\u9500\u4f1a\u6bd4\u8f83\u5927\u3002 map lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(string(\"a-very-very-very-very-long-key\")); // \u9690\u5f0f\u6784\u9020\u4e86\u4e00\u4e2a string\uff0c\u5bfc\u81f4\u6df1\u62f7\u8d1d\u4e86\u6574\u4e2a\u5b57\u7b26\u4e32\uff01 \u800c\u542f\u7528\u4e86\u900f\u660e\u6bd4\u8f83\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u6bcf\u6b21\u90fd\u62f7\u8d1d\u6574\u4e2a\u5b57\u7b26\u4e32\u6765\u6784\u9020 string \u4e86\u3002\u56e0\u4e3a find\u3001at \u8fd9\u7c7b\u51fd\u6570\u4f1a\u542f\u7528\u4e00\u4e2a\u6cdb\u578b\u7684\u7248\u672c at(Kt &&) \uff0cKt \u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\uff0c\u53ea\u8981\u4ed6\u652f\u6301\u4e0e string \u6bd4\u8f83\u3002\u53ef\u4ee5\u662f const char * \uff0c string_view \u6216\u53e6\u4e00\u4e2a string \u3002 map> lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(\"a-very-very-very-very-long-key\"); \u56e0\u4e3a\u4e0d\u7528\u62f7\u8d1d\u4e86\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5bf9\u4e8e\u952e\u5b57\u7b26\u4e32\u975e\u5e38\u957f\u7684\u60c5\u51b5\u3002 at \u5185\u90e8\u4e5f\u4e0d\u4f1a\u6784\u9020\u4efb\u4f55\u65b0\u7684 string \uff0c\u4ed6\u4f1a\u62ff\u7740 const char * \u548c\u7ea2\u9ed1\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u8c03\u7528 == \u6bd4\u8f83\u3002 string == const char * \u662f\u5b89\u5168\u7684\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\u3002 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u67d0\u6709\u67d0\u4e9b\u7279\u6b8a\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u628a\u6307\u9488\uff0c\u751a\u81f3\u667a\u80fd\u6307\u9488\uff01\u653e\u8fdb map \u6216 set \u7684\u952e\u4e2d\uff0c\u7528\u4e8e\u5feb\u901f\u6309\u6307\u9488\u7684\u503c\u67e5\u627e\u5230\u5143\u7d20\u3002\uff08\u662f\u7684\u4f60\u6ca1\u542c\u9519\uff0c\u662f\u653e\u5728 \u952e\u7c7b\u578b \u91cc\uff01\uff09 \u8f76\u4e8b\uff1a\u628a\u6307\u9488\u653e\u5728\u952e\u91cc\u5e76\u4e0d\u7f55\u89c1\uff0c\u5e38\u89c1\u7684\u4e00\u4e2a\u7528\u6cd5\u662f set \u3002\u597d\u5904\u662f\u5f53 Node \u6790\u6784\u65f6\uff0c\u4ed6\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528 set.erase(this) \u628a\u81ea\u5df1\u5254\u9664\u6389\u3002\u800c\u666e\u901a\u7684 set \u5c31\u5f88\u96be\u505a\u5230\u8fd9\u4e00\u70b9\u4e86\uff0c\u4f60\u65e0\u6cd5\u901a\u8fc7 Node \u7684 this \u6307\u9488\u83b7\u5f97\u4ed6\u5728 set \u4e2d\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u65e0\u6cd5\u77e5\u9053\u81ea\u5df1\u4f4d\u4e8e\u54ea\u4e2a set \u4e2d\u3002\u4fb5\u5165\u5f0f\u7ea2\u9ed1\u6811\u5b8c\u7f8e\u89e3\u51b3\u4e86\u8fd9\u4e00\u75db\u70b9\uff0cLLVM \u548c Linux \u5185\u6838\u4e2d\u90fd\u5927\u91cf\u8fd0\u7528\u4e86\u4fb5\u5165\u5f0f\u94fe\u8868/LRU/\u7ea2\u9ed1\u6811\uff0c\u4ee5\u540e\u7684\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4e2d\u4f1a\u4e3a\u4f60\u8bb2\u89e3\u3002 map lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); \u5982\u679c\u662f\u667a\u80fd\u6307\u9488\uff0c\u5c31\u6bd4\u8f83\u56f0\u96be\u4e86\uff0c\u7279\u522b\u662f unique_ptr \u3002\u5982\u679c\u4f60\u5df2\u77e5\u4e00\u4e2a\u539f\u59cb\u6307\u9488\uff0c\u60f3\u8981\u5728 map \u4e2d\u67e5\u627e\u6307\u5411\u540c\u6837\u7684\u667a\u80fd\u6307\u9488\u952e\u3002 map, int> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece Node * \u9690\u5f0f\u6784\u9020 unique_ptr \u8fc7\u53bb\uff0c\u4eba\u4eec\u4e0d\u5f97\u4e0d\u7528\u4e00\u79cd\u79f0\u4e3a stale-ptr\uff08\u53d8\u8d28\u6307\u9488\uff09\u7684\u9ed1\u79d1\u6280\uff0c\u6765\u6784\u9020\u4e00\u4e2a\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u4f2a unique_ptr \u51fa\u6765\uff1a map, int> lut; Node *raw_ptr = get_some_ptr(); unique_ptr stale_ptr(raw_ptr); // \u4e00\u4e2a\u5e76\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u201c\u53d8\u8d28\u667a\u80fd\u6307\u9488\u201d lut.find(stale_ptr); // OK: \u5339\u914d\u5230 find(unique_ptr const &) \u91cd\u8f7d stale_ptr.release(); // \u5fc5\u987b\uff01\u5426\u5219\u4f1a\u51fa\u73b0\u53cc\u91cd\u91ca\u653e (double-free) \u9519\u8bef \u800c C++14 \u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u5b9a\u4e49\u4e00\u4e2a\u900f\u660e\u7684\u6bd4\u8f83\u51fd\u6570\uff0c\u652f\u6301 Node * \u4e0e unique_ptr \u4e92\u76f8\u6bd4\u8f83\u5373\u53ef\uff1a struct transparent_ptr_less { template bool operator()(T *const &p1, T const &p2) const { return p1 < p2; } template bool operator()(T *const &p1, unique_ptr const &p2) const { return p1 < p2.get(); } template bool operator()(unique_ptr const &p1, T *const &p2) const { return p1.get() < p2; } template bool operator()(unique_ptr const &p1, unique_ptr const &p2) const { return p1.get() < p2.get(); } using is_transparent = std::true_type; }; map, int, transparent_ptr_less> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // OK: \u5339\u914d\u5230\u6cdb\u578b\u7684 find(Kt &&) \u91cd\u8f7d\uff0c\u5176\u4e2d Kt \u63a8\u5bfc\u4e3a Node *const & \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u4ee5\u4e0b\u6458\u81ea cppreference \u4e0a\u6cdb\u578b find \u7684\u5b98\u65b9\u6848\u4f8b\uff1a struct FatKey { int x; int data[1000]; }; struct LightKey { int x; }; // Note: as detailed above, the container must use std::less<> (or other // transparent Comparator) to access these overloads. // This includes standard overloads, such as between std::string and std::string_view. bool operator<(const FatKey& fk, const LightKey& lk) { return fk.x < lk.x; } bool operator<(const LightKey& lk, const FatKey& fk) { return lk.x < fk.x; } bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.x < fk2.x; } int main() { // transparent comparison demo std::map> example = {{{1, {}}, 'a'}, {{2, {}}, 'b'}}; LightKey lk = {2}; if (auto search = example.find(lk); search != example.end()) std::cout << \"Found \" << search->first.x << \" \" << search->second << '\\n'; else std::cout << \"Not found\\n\"; } Found 2 b \u795e\u5947\u7684 multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\u7684 multimap map \u4e2d\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e00\u4e2a\u503c\uff0c\u800c multimap \u4e00\u4e2a\u952e\u53ef\u4ee5\u5bf9\u5e94\u591a\u4e2a\u503c\u3002 map\uff1a\u6392\u5e8f + \u53bb\u91cd\uff1b multimap\uff1a\u53ea\u6392\u5e8f\uff0c\u4e0d\u53bb\u91cd\u3002 // map \u7684\u63d2\u5165\u51fd\u6570\uff1a pair insert(pair const &kv); pair insert(pair &&kv); // multimap \u7684\u63d2\u5165\u51fd\u6570\uff1a iterator insert(pair const &kv); iterator insert(pair &&kv); \u56e0\u4e3a multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\uff0c\u6240\u4ee5\u63d2\u5165\u603b\u662f\u6210\u529f\uff0c\u4e0e\u666e\u901a map \u76f8\u6bd4\u4e0d\u7528\u8fd4\u56de bool \u8868\u793a\u662f\u5426\u6210\u529f\u4e86\u3002 \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); print(tab); {\"cpp\": \"smart\", \"cpp\": \"fast\", \"java\": \"pig\", \"rust\": \"silly\", \"rust\": \"trash\", \"rust\": \"trash\", \"rust\": \"lazy\"} \u63d2\u5165\u8fdb multimap \u7684\u91cd\u590d\u952e\u4f1a\u7d27\u6328\u7740\uff0c\u4ed6\u4eec\u4e4b\u95f4\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u63d2\u5165\u7684\u987a\u5e8f\u3002\u4f8b\u5982\u4e0a\u9762\u952e\u540c\u6837\u662f \u201ccpp\u201d \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u201dsmart\u201d \u5148\u4e8e \u201cfast\u201d \u63d2\u5165\uff0c\u6240\u4ee5 \u201csmart\u201d \u9760\u524d\u4e86\u3002 \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 multimap / multiset \u7684\u4f5c\u7528\u901a\u5e38\u5c31\u4e0d\u662f\u952e\u503c\u6620\u5c04\u4e86\uff0c\u800c\u662f\u5229\u7528\u7ea2\u9ed1\u6811\u4f1a\u4fdd\u6301\u5143\u7d20\u6709\u5e8f\u7684\u7279\u6027\uff08\u4efb\u4f55\u4e8c\u53c9\u641c\u7d22\u6811\u90fd\u8fd9\u6837\uff09\u5b9e\u73b0\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u52a8\u6001\u6392\u5e8f\u3002 \u4f20\u7edf\u6392\u5e8f\u65b9\u5f0f\uff1a std::vector arr; int i; while (cin >> i) { arr.push_back(i); } std::sort(arr.begin(), arr.end(), std::less()); multiset \u6392\u5e8f\u65b9\u5f0f\uff1a std::multiset tab; int i; while (cin >> i) { tab.insert(i); } // \u65e0\u9700\u518d\u6392\u5e8f\uff0ctab \u4e2d\u7684\u952e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\u4e86\uff01 // \u5982\u9700\u53d6\u51fa\u5230 vector: std::vector arr(tab.begin(), tab.end()); \u5229\u7528 multimap \u952e-\u503c\u5bf9\u7684\u7279\u70b9\uff0c\u8fd8\u80fd\u8f7b\u6613\u5b9e\u73b0\u53ea\u5bf9\u952e\u6392\u5e8f\uff0c\u503c\u7684\u90e8\u5206\u4e0d\u53c2\u4e0e\u6392\u5e8f\u7684\u6548\u679c\u3002 multimap \u6392\u5e8f\u7684\u597d\u5904\u662f\uff1a \u52a8\u6001\u6392\u5e8f\uff0c\u5728\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\u5c31\u4fdd\u6301\u6574\u4e2a\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6027\uff0c\u6700\u540e\u4efb\u4f55\u65e0\u9700\u989d\u5916\u64cd\u4f5c\u3002 \u5728\u4e00\u6b21\u6b21\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u65f6\u6bcf\u523b\u90fd\u662f\u6709\u5e8f\u7684\uff0c\u800c\u4e0d\u5fc5\u7b49\u5230\u6700\u540e\u624d\u53d8\u5f97\u6709\u5e8f\u3002 \u53ef\u4ee5\u968f\u65f6\u52a8\u6001\u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff0c\u540c\u6837\u4e0d\u4f1a\u7834\u574f\u6709\u5e8f\u6027\u3002 \u8fd8\u5f88\u65b9\u4fbf\u968f\u65f6\u6309\u952e\u503c\u67e5\u627e\u5230\u548c\u6211\u76f8\u7b49\u7684\u5143\u7d20\u3002 \u5982\u679c\u8fd8\u989d\u5916\u9700\u8981\u53bb\u91cd\uff0c\u5219\u53ea\u9700\u6539\u7528\u666e\u901a map \u666e\u901a map \u8f7b\u677e\u5b9e\u73b0\u53bb\u91cd + \u52a8\u6001\u6392\u5e8f\uff0c\u5982\u4f55\u5904\u7f6e\u91cd\u590d\u7684\u952e\u968f\u4f60\u51b3\u5b9a\uff1a \u666e\u901a map \u7684 insert \u53ea\u63a5\u53d7\u7b2c\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u666e\u901a map \u7684 insert_or_assign \u53ea\u4fdd\u7559\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c \u56e0\u4e3a multimap \u4e2d\uff0c\u4e00\u4e2a\u952e\u4e0d\u518d\u5bf9\u4e8e\u5355\u4e2a\u503c\u4e86\uff1b\u6240\u4ee5 multimap \u6ca1\u6709 [] \u548c at \u4e86\uff0c\u4e5f\u6ca1\u6709 insert_or_assign \uff08\u53cd\u6b63 insert \u6c38\u8fdc\u4e0d\u4f1a\u53d1\u751f\u952e\u51b2\u7a81\uff01\uff09 pair equal_range(K const &k); template pair equal_range(Kt &&k); \u8981\u67e5\u8be2 multimap \u4e2d\u7684\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e86\u54ea\u4e9b\u503c\uff0c\u53ef\u4ee5\u7528 equal_range \u83b7\u53d6\u4e00\u524d\u4e00\u540e\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4ed6\u4eec\u5f62\u6210\u4e00\u4e2a\u533a\u95f4\u3002\u8fd9\u4e2a\u533a\u95f4\u5185\u6240\u6709\u7684\u5143\u7d20\u90fd\u662f\u540c\u6837\u7684\u952e\u3002 multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); auto range = tab.equal_range(\"cpp\"); for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } cpp smart cpp fast equal_range \u8fd4\u56de\u4e24\u4e2a\u8fed\u4ee3\u5668\u76f8\u7b49\u65f6\uff08\u5373\u533a\u95f4\u5927\u5c0f\u4e3a 0\uff09\uff0c\u5c31\u4ee3\u8868\u627e\u4e0d\u5230\u8be5\u952e\u503c\u3002 auto range = tab.equal_range(\"html\"); if (range.first == range.second) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } } equal_range \u8fd4\u56de\u7684\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4e5f\u53ef\u4ee5\u7528 lower_bound \u548c upper_bound \u5206\u522b\u83b7\u5f97\uff1a auto begin_it = tab.lower_bound(\"html\"); auto end_it = tab.upper_bound(\"html\"); if (begin_it == end_it) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = begin_it; it != end_it; ++it) { print(it->first, it->second); } } lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 lower_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\u7b49\u4e8e\uff08>=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 upper_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\uff08>\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 lower_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\uff08<\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 upper_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\u7b49\u4e8e\uff08<=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 \u4f8b\u5982\u6211\u8981\u5bf9\u4e00\u7cfb\u5217\u5c0f\u5f6d\u53cb\u7684\u6210\u7ee9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u8981\u6c42\u67e5\u51fa\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u6240\u6709\u540c\u5b66\uff0c\u53d1\u653e\u201c\u5c0f\u7ea2\u82b1\u201d\uff1a struct Student { string name; int score; }; vector students; \u5c31\u53ef\u4ee5\u628a\u6210\u7ee9 int \u4f5c\u4e3a\u952e\uff0c\u5b66\u751f\u540d\u5b57\u4f5c\u4e3a\u503c\uff0c\u63d2\u5165 multimap\u3002 \u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d multimap \u5c31\u81ea\u52a8\u4e3a\u4f60\u52a8\u6001\u6392\u5e8f\u4e86\u3002 multimap sorted; for (auto const &stu: students) { sorted.insert({stu.score, stu.name}); } \u7136\u540e\uff0c\u8981\u627e\u51fa\u6240\u6709\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u540c\u5b66\uff0c\u4e5f\u5c31\u662f lower_bound(60) \u5230 end() \u8fd9\u4e2a\u533a\u95f4\uff1a // where score >= 60 for (auto it = sorted.lower_bound(60); it != sorted.end(); ++it) { print(\"\u606d\u559c {} \u540c\u5b66\uff0c\u8003\u51fa\u4e86 {} \u5206\uff0c\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u7ea2\u82b1\", it->second, it->first); } \u627e\u51fa 30\uff08\u542b\uff09\u5230 60\uff08\u4e0d\u542b\uff09\u5206\u7684\u540c\u5b66\u4e5f\u5f88\u5bb9\u6613\uff1a // where 30 <= score and score < 60 for (auto it = sorted.upper_bound(30); it != sorted.lower_bound(60); ++it) { print(\"{} \u540c\u5b66\u8003\u51fa\u4e86 {} \u5206\uff0c\u4e0d\u8981\u7070\u5fc3\uff01\u5c0f\u5f6d\u8001\u5e08\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u9ec4\u82b1\uff0c\u8868\u793a\u9ec4\u724c\u8b66\u544a\", it->second, it->first); } \u8bfe\u540e\u7ec3\u4e60 \u5c1d\u8bd5\u7528 multimap \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5b66\u751f\u6210\u7ee9\u7ba1\u7406\u7cfb\u7edf\uff0c\u8981\u6c42\u5982\u4e0b\uff1a \u5b66\u751f\u4fe1\u606f\u5305\u62ec\u59d3\u540d\u548c\u6210\u7ee9\u3002 \u80fd\u591f\u52a8\u6001\u63d2\u5165\u548c\u5220\u9664\u5b66\u751f\u4fe1\u606f\uff0c\u59cb\u7ec8\u4fdd\u6301\u6309\u6210\u7ee9\u6392\u5e8f\u3002 \u80fd\u591f\u67e5\u8be2\u7ed9\u5b9a\u6210\u7ee9\u8303\u56f4\u5185\u7684\u6240\u6709\u5b66\u751f\u3002 \u5b9e\u9645\u4e0a\uff0c\u6570\u636e\u5e93\u5c31\u662f\u8fd9\u6837\u5b9e\u73b0\u7684\uff0c\u6211\u4eec\u7684 multimap \u53ea\u662f\u7b80\u5355\u5730\u5bf9\u6210\u7ee9\u8fd9\u4e00\u4e2a\u5b57\u6bb5\u6392\u5e8f\uff0c\u800c\u4e13\u4e1a\u7684\u5173\u7cfb\u6570\u636e\u5e93\u4f1a\u4e3a\u6bcf\u4e2a\u5b57\u6bb5\u90fd\u5efa\u7acb\u7d22\u5f15\uff0c\u5206\u522b\u6392\u5e8f\u540e\u5b58\u50a8\uff0c\u4ee5\u52a0\u901f\u67e5\u627e\u3002\u5b66\u6709\u4f59\u529b\u7684\u540c\u5b66\u53ef\u4ee5\u5c1d\u8bd5\u8ba9\u5b66\u751f\u4fe1\u606f\u5305\u542b\u59d3\u540d\u3001\u6210\u7ee9\u3001\u5e74\u9f84\u3001\u5b66\u53f7\uff0c\u7136\u540e\u5206\u522b\u6784\u5efa\u8fd9\u56db\u4e2a\u5b57\u6bb5\u7684\u7d22\u5f15\uff0c\u652f\u6301\u6307\u5b9a\u503c\u67e5\u627e\u548c\u8303\u56f4\u67e5\u627e\uff0c\u5176\u4e2d\u59d3\u540d\u548c\u5b66\u53f7\u8981\u6c42\u552f\u4e00\u6027\u3002\u63d0\u793a\uff1a\u7528\u4e4b\u524d\u63d0\u5230\u7684 vector + map \u7684\u65b9\u6cd5\u3002\u505a\u51fa\u6765\u4ee5\u540e\uff0c\u9762\u8bd5\u6570\u636e\u5e93\u65f6\u4f60\u5c31\u53ef\u4ee5\u79c0\u7406\u89e3\u4e86\u3002 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m1 = move(m2) \u79fb\u52a8 O(1) O(1) m1 = m2 \u62f7\u8d1d O(N) O(N) swap(m1, m2) \u4ea4\u6362 O(1) O(1) m.clear() \u6e05\u7a7a O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert({key, val}) \u63d2\u5165\u952e\u503c\u5bf9 O(\\log N) O(\\log N) m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u51c6\u786e O(1) O(1) + m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u4e0d\u51c6\u786e O(\\log N) O(\\log N) m[key] = val \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert({vals\u2026}) \u8bbe M \u4e3a\u5f85\u63d2\u5165\u5143\u7d20\uff08vals\uff09\u7684\u6570\u91cf O(M \\log N) O(M \\log N) map m = \u5982\u679c vals \u65e0\u5e8f O(N \\log N) O(N \\log N) map m = \u5982\u679c vals \u5df2\u4e8b\u5148\u4ece\u5c0f\u5230\u5927\u6392\u5217 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.at(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u503c\u7684\u5f15\u7528 O(\\log N) O(\\log N) m.find(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u8fed\u4ee3\u5668 O(\\log N) O(\\log N) m.count(key) \u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u952e\u5143\u7d20\uff0c\u8fd4\u56de\u76f8\u540c\u952e\u7684\u5143\u7d20\u6570\u91cf\uff08\u53ea\u80fd\u4e3a 0 \u6216 1\uff09 O(\\log N) O(\\log N) m.equal_range(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u786e\u5b9a\u4e0a\u4e0b\u754c\uff0c\u8fd4\u56de\u533a\u95f4 O(\\log N) O(\\log N) m.size() map \u4e2d\u6240\u6709\u5143\u7d20\u7684\u6570\u91cf O(1) O(1) m.erase(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u5220\u9664\u5143\u7d20 O(\\log N) O(\\log N) m.erase(it) \u6839\u636e\u627e\u5230\u7684\u8fed\u4ee3\u5668\uff0c\u5220\u9664\u5143\u7d20 O(1)+ O(1)+ m.erase(beg, end) \u6279\u91cf\u5220\u9664\u533a\u95f4\u5185\u7684\u5143\u7d20\uff0c\u8bbe\u8be5\u533a\u95f4\uff08beg \u548c end \u4e4b\u95f4\uff09\u6709 M \u4e2a\u5143\u7d20 O(M + \\log N) O(M + \\log N) erase_if(m, cond) \u6279\u91cf\u5220\u9664\u6240\u6709\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert(node) O(\\log N) O(\\log N) node = m.extract(it) O(1)+ O(1)+ node = m.extract(key) O(\\log N) O(\\log N) m1.merge(m2) \u5408\u5e76\u4e24\u4e2a map\uff0c\u6e05\u7a7a m2\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) m1.insert(m2.begin(), m2.end()) \u5408\u5e76\u4e24\u4e2a map\uff0cm2 \u4fdd\u6301\u4e0d\u53d8\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) \u54c8\u5e0c\u8868 unordered_map C++11 \u65b0\u589e\uff1a\u57fa\u4e8e\u54c8\u5e0c (hash) \u7684\u6620\u5c04\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u4e4b\u524d\u63d0\u5230\uff0cmap \u5e95\u5c42\u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5927\u591a\u6570\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(\\log N) O(\\log N) \u7ea7\u522b\u7684\uff0c\u5176\u4e2d\u90e8\u5206\u6309\u8fed\u4ee3\u5668\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(1) O(1) \u3002 \u800c unordered_map \u5219\u662f\u57fa\u4e8e\u54c8\u5e0c\u8868\u7684\u66f4\u9ad8\u6548\u67e5\u627e\uff0c\u53ea\u9700 O(1) O(1) \u590d\u6742\u5ea6\uff01\u4ed6\u80fd\u5b9e\u73b0\u5982\u6b64\u9ad8\u6548\u67e5\u627e\u5f97\u76ca\u4e8e\u54c8\u5e0c\u51fd\u6570\u53ef\u4ee5\u628a\u6563\u5217\u552f\u4e00\u5b9a\u4f4d\u5230\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0b\u6807\u4e2d\u53bb\uff0c\u800c\u6570\u7ec4\u7684\u7d22\u5f15\u662f O(1) O(1) \u7684\u3002\u7f3a\u70b9\u662f\u54c8\u5e0c\u503c\u53ef\u80fd\u4ea7\u751f\u51b2\u7a81\uff0c\u800c\u4e14\u54c8\u5e0c\u6570\u7ec4\u53ef\u80fd\u6709\u7a7a\u4f4d\u6ca1\u6709\u586b\u6ee1\uff0c\u6d6a\u8d39\u4e00\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u3002\u603b\u7684\u6765\u8bf4\u54c8\u5e0c\u8868\u5728\u5e73\u5747\u590d\u6742\u5ea6\u4e0a\uff08 O(1) O(1) \uff09\u6bd4\u7ea2\u9ed1\u6811\u8fd9\u7c7b\u57fa\u4e8e\u6811\u7684\u590d\u6742\u5ea6\uff08 O(\\log N) O(\\log N) \uff09\u66f4\u4f4e\uff0c\u867d\u7136\u56fa\u6709\u5ef6\u8fdf\u9ad8\uff0c\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u8fd8\u5bb9\u6613\u88ab\u54c8\u5e0c\u51b2\u7a81\u653b\u51fb\u3002 \u54c8\u5e0c\u8868\u7ed3\u6784\u7b80\u5355\u65e0\u8111\uff0c\u5728\u5de8\u91cf\u7684\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u65f6\u4f1a\u53d1\u6325\u51fa\u660e\u663e\u7684\u6027\u80fd\u4f18\u52bf\uff0c\u5e38\u7528\u4e8e\u9700\u8981\u9ad8\u541e\u5410\u91cf\u4f46\u4e0d\u592a\u5728\u4e4e\u5ef6\u8fdf\u7684\u56fe\u5f62\u5b66\u5e94\u7528\u3002 \u800c\u5404\u79cd\u57fa\u4e8e\u6811\u7684\u6570\u636e\u7ed3\u6784\uff0c\u590d\u6742\u5ea6\u66f4\u52a0\u7a33\u5b9a\uff0c\u770b\u4f3c\u9002\u5408\u5c0f\u89c4\u6a21\u6570\u636e\uff0c\u4f46\u662f\u56e0\u4e3a\u4fdd\u6301\u6709\u5e8f\u7684\u7279\u6027\uff0c\u975e\u5e38\u9002\u5408\u6570\u636e\u5e93\u8fd9\u79cd\u9700\u8981\u8303\u56f4\u67e5\u8be2\u7684\u60c5\u51b5\uff0c\u4e14\u6709\u5e8f\u6027\u53cd\u800c\u6709\u5229\u4e8e\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u65e0\u5e8f\u7684\u54c8\u5e0c\u8868\u96be\u4ee5\u80dc\u4efb\u3002 \u6700\u8fd1\u65b0\u63d0\u51fa\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u8df3\u8868\uff0c\u4e5f\u662f\u6709\u5e8f\u7684\uff0c\u4f46\u57fa\u4e8e\u94fe\u8868\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u5728 Redis \u7b49\u8f6f\u4ef6\u4e2d\u90fd\u6709\u5e94\u7528\u3002\u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u5e76\u5e26\u4f60\u624b\u6413\u6240\u6709\u8fd9\u4e9b\uff01 \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d unordered_map \u5982\u4f55\u5feb\u901f\u68c0\u7d22\u6570\u636e\uff1f\u9ad8\u6548\u7684\u79d8\u8bc0\u5728\u4e8e unordered_map \u5185\u90e8\u662f\u4e00\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u7531\u8bb8\u591a\u201c\u6876\u201d\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u63d2\u5165\u65f6\u628a\u952e\u503c\u5bf9\u5b58\u5230\u952e\u7684 hash \u5bf9\u5e94\u7f16\u53f7\u7684\u6876\u53bb\uff0c\u67e5\u8be2\u65f6\u5c31\u6839\u636e hash \u53bb\u7ebf\u6027\u5730\u67e5\u627e\u6876\uff08\u8fd9\u4e00\u64cd\u4f5c\u662f O(1) O(1) \u7684\uff09\u3002 \u4f8b\u5982\u952e\u4e3a \u201chello\u201d\uff0c\u5047\u8bbe\u7b97\u51fa\u4ed6\u7684 hash \u4e3a 42\u3002\u800c\u5f53\u524d\u6876\u7684\u6570\u91cf\u662f 32 \u4e2a\uff0c\u5219\u4f1a\u628a \u201chello\u201d \u5b58\u5230 42 % 32 = 10 \u53f7\u6876\u53bb\u3002\u67e5\u8be2\u65f6\uff0c\u540c\u6837\u8ba1\u7b97\u51fa hash(\u201chello\u201d) % 32 = 10 \u53f7\u6876\uff0c\u7136\u540e\u5c31\u53ef\u4ee5\u4ece 10 \u53f7\u6876\u53d6\u51fa \u201chello\u201d \u5bf9\u5e94\u7684\u6570\u636e\u4e86\u3002 template class unordered_map { array, 32> buckets; void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97\u51fa\u6765\u7684 hash \u53ef\u80fd\u5f88\u5927\uff0c\u53d6\u6a21\u53ef\u4ee5\u9632\u6b62 h >= buckets.size() buckets[h] = kv; } V &at(K k) { size_t h = hash(k) % buckets.size(); auto &kv = buckets[h]; if (k != kv.first) throw out_of_range{}; return kv.second; } }; \u54c8\u5e0c\u51b2\u7a81 (hash-collision) \u4f46\u662f\u8fd9\u91cc\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u4e24\u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u521a\u597d hash \u4ee5\u540e\u7684\u6a21\u76f8\u540c\u600e\u4e48\u529e\uff1f\u8fd9\u79cd\u73b0\u8c61\u79f0\u4e3a hash \u51b2\u7a81\u3002 C++ \u6807\u51c6\u5e93\u7684\u89e3\u51b3\u65b9\u6848\u662f\u91c7\u7528\u94fe\u8868\u6cd5\uff1a\u4e00\u4e2a\u6876\u4e0d\u662f\u5355\u72ec\u7684\u4e00\u4e2a K-V \u5bf9\uff0c\u800c\u662f\u6570\u4e2a K-V \u5bf9\u7ec4\u6210\u7684\u5355\u94fe\u8868\uff08forward_list\uff09\u3002\u4e00\u4e2a\u6876\u4e0d\u662f\u53ea\u5b58\u50a8\u4e00\u4e2a\u6570\u636e\uff0c\u800c\u662f\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u591a\u4e2a\u6570\u636e\uff080\u5230\u221e\u4e2a\uff09\u3002 \u63d2\u5165\u65f6\uff0c\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5f80\u94fe\u8868\u7684\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684 K-V \u5bf9\u3002\u67e5\u627e\u65f6\uff0c\u5148\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5728\u8fd9\u4e2a\u6876\u91cc\u7684\u94fe\u8868\u91cc\u987a\u5e8f\u904d\u5386\u67e5\u627e\uff0c\u7531\u4e8e\u7b2c\u4e00\u6b65\u7684\u6876\u67e5\u627e\u662f O(1) O(1) \u7684\uff0c\u867d\u7136\u6700\u540e\u8fd8\u662f\u94fe\u8868\u66b4\u529b\u67e5\u627e\uff0c\u4f46\u662f\u5df2\u7ecf\u88ab\u6876\u5206\u644a\u4e86\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u56e0\u6b64\u67e5\u627e\u7684\u5e73\u5747\u590d\u6742\u5ea6\u8fd8\u662f O(1)+ O(1)+ \u7684\u3002 void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 buckets[h].push_front(kv); // \u5355\u94fe\u8868\u7684\u5934\u63d2\uff0c\u662f\u6700\u9ad8\u6548\u7684 } V &at(K k) { size_t h = hash(k) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 for (auto &kv: buckets[h]) { if (k == kv.first) // \u53ef\u80fd\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u952e\u521a\u597d\u6709\u76f8\u540c\u7684 hash \u6a21\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5224\u65ad\u952e\u786e\u5b9e\u76f8\u7b49\u624d\u80fd\u8fd4\u56de return kv.second; } throw out_of_range{}; } \u8fd9\u91cc\u8fd8\u662f\u6709\u4e00\u4e2a\u95ee\u9898\uff0chash \u51b2\u7a81\u65f6\uff0c\u5bf9\u94fe\u8868\u7684\u66b4\u529b\u904d\u5386\u67e5\u627e\u590d\u6742\u5ea6\u662f O(N) O(N) \u7684\uff0c\u968f\u7740\u8d8a\u6765\u8d8a\u591a\u7684\u5143\u7d20\u88ab\u63d2\u5165\u8fdb\u6765\uff0c32 \u4e2a\u6876\u5c06\u4f1a\u62e5\u6324\u4e0d\u582a\u3002\u5047\u8bbe\u6709 n \u4e2a\u5143\u7d20\uff0c\u5219\u5e73\u5747\u6bcf\u4e2a\u6876\u90fd\u4f1a\u6709 n / 32 \u4e2a\u5143\u7d20\uff0c\u9700\u8981 n / 32 \u6b21\u904d\u5386\u3002\u6240\u4ee5\u5143\u7d20\u6570\u91cf\u5145\u5206\u5927\u65f6 unordered_map \u53c8\u4f1a\u9000\u5316\u6210\u66b4\u529b\u904d\u5386\u7684 O(N) O(N) \u590d\u6742\u5ea6\uff0c\u6ee1\u8db3\u4e0d\u4e86\u6211\u4eec\u7528\u4ed6\u52a0\u901f\u67e5\u627e\u7684\u76ee\u7684\u3002 \u6876\u7684\u6570\u91cf\u76f8\u6bd4\u5143\u7d20\u7684\u6570\u91cf\u8d8a\u662f\u4e0d\u8db3\uff0c\u8d8a\u662f\u62e5\u6324\uff0c\u8d8a\u662f\u5bb9\u6613\u9000\u5316\u6210\u94fe\u8868\u3002 \u56e0\u6b64 C++ \u6807\u51c6\u5e93\u89c4\u5b9a\uff0c\u63d2\u5165\u65f6\uff0c\u5f53\u68c0\u6d4b\u5230\u5e73\u5747\u6bcf\u4e2a\u6876\u91cc\u90fd\u6709 1 \u4e2a\u5143\u7d20\u65f6\uff0c\u4e5f\u5c31\u662f\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u6570\u91cf\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\uff0c\u4e00\u6b21\u6027\u8ba9\u6876\u7684\u6570\u91cf\u6269\u5145 2 \u500d\uff0c\u5e76\u91cd\u65b0\u8ba1\u7b97\u6bcf\u4e2a\u5143\u7d20\u7684 hash \u6a21\uff08\u6876\u7f16\u53f7\uff09\u5168\u90e8\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u3002 \u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u7684\u6570\u91cf\u88ab\u79f0\u4e3a\u201c\u8d1f\u8f7d\u7387\uff08load factor\uff09\uff0c\u5bf9\u4e8e\u94fe\u8868\u6cd5\u7684\u54c8\u5e0c\u8868 unordered_map \u6765\u8bf4\uff0c\u8d1f\u8f7d\u7387\u53ef\u4ee5\u9ad8\u4e8e 1\uff1b\u5bf9\u4e8e\u7ebf\u6027\u5730\u5740\u6cd5\u7684 flat_hash_map \u5219\u6700\u9ad8\u4e3a 1\u3002C++ \u6807\u51c6\u5e93\u901a\u5e38\u7684 unordered_map \u5b9e\u73b0\u4e2d\uff0c\u8d1f\u8f7d\u7387\u9ad8\u4e8e 1 \u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\u3002\u53ef\u4ee5\u901a\u8fc7 .load_factor() \u51fd\u6570\u67e5\u8be2\u4e00\u4e2a unordered_map \u7684\u8d1f\u8f7d\u7387\u3002 template class unordered_map { vector>> buckets; // \u56e0\u4e3a\u9700\u8981\u52a8\u6001\u6269\u5bb9\uff0c\u6876\u6570\u7ec4\u53d8\u6210\u4e86\u52a8\u6001\u6570\u7ec4 vector size_t size = 0; // \u8bb0\u5f55\u5f53\u524d\u5bb9\u5668\u5171\u6709\u591a\u5c11\u4e2a\u5143\u7d20 void insert(pair kv) { if (size + 1 > buckets.size()) reserve(n); // \u5982\u679c\u63d2\u5165\u540e\u7684\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u5bb9\u91cf\uff0c\u5219\u6269\u5bb9 size_t h = hash(kv.first) % buckets.size(); buckets[h].push_front(kv); size++; // insert \u65f6 size \u81ea\u52a8\u52a0 1\uff0cerase \u65f6\u4e5f\u8981\u8bb0\u5f97\u51cf 1 } void reserve(size_t n) { if (n <= buckets.size()) return; // \u5982\u679c\u8981\u6c42\u7684\u5927\u5c0f\u5df2\u7ecf\u6ee1\u8db3\uff0c\u4e0d\u9700\u8981\u6269\u5bb9 buckets.resize(max(n, buckets.size() * 2)); // \u628a\u6876\u6570\u7ec4\u81f3\u5c11\u6269\u5927 2 \u500d\uff08\u907f\u514d\u91cd\u590d\u6269\u5bb9\uff09\uff0c\u81f3\u591a\u6269\u5230 n \u6b64\u5904\u7701\u7565 rehash \u7684\u5177\u4f53\u5b9e\u73b0 // \u6876\u7684\u6570\u91cf\u53d1\u751f\u53d8\u5316\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u8ba1\u7b97\u4e00\u904d\u6240\u6709\u5143\u7d20 hash \u7684\u6a21\uff0c\u5e76\u91cd\u65b0\u63d2\u5165 } }; \u6bcf\u4e2a key \u6240\u5728\u7684\u6876\u7f16\u53f7\u8ba1\u7b97\u516c\u5f0f\uff1abucket_index(key) = hash(key) % bucket_count() \u8fd8\u662f\u5b58\u5728\u95ee\u9898\uff0c\u521a\u521a\u7684 insert \u6839\u672c\u6ca1\u6709\u68c0\u6d4b\u8981\u63d2\u5165\u7684\u952e\u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e86\u3002\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u8fd8\u63d2\u5165\uff0c\u90a3\u5c31\u53d8\u6210 unordered_multimap \u4e86\uff01\u6211\u4eec\u662f\u666e\u901a\u7684\u9700\u8981\u53bb\u91cd\u7684 unordered_map\uff0c\u6240\u4ee5\u63d2\u5165\u65f6\u5148\u9700\u8981\u904d\u5386\u4e0b\u94fe\u8868\u68c0\u6d4b\u4e00\u4e0b\u3002 template class unordered_map { vector>> buckets; size_t size = 0; struct iterator { explicit iterator(pair &kv) { /* ... */ } // ... }; pair insert(pair kv) { if (size + 1 > buckets.size()) reserve(size + 1); size_t h = hash(kv.first) % buckets.size(); for (auto &kv2: buckets[h]) { if (kv.first == kv2.first) // \u68c0\u6d4b\u662f\u5426\u53d1\u751f\u4e86\u51b2\u7a81 return {iterator(kv2), false}; // \u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6307\u5411\u5df2\u5b58\u5728\u7684\u952e\u7684\u8fed\u4ee3\u5668 } buckets[h].push_front(kv); size++; return {iterator(buckets.front()), true}; // \u6ca1\u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6210\u529f\u63d2\u5165\u5143\u7d20\u7684\u8fed\u4ee3\u5668 } }; unordered_map \u4e0e map \u7684\u5f02\u540c \u7528\u6cd5\u4e0a\uff0cunordered_map \u57fa\u672c\u4e0e map \u76f8\u540c\uff0c\u4ee5\u4e0b\u7740\u91cd\u4ecb\u7ecd\u4ed6\u4eec\u7684\u4e0d\u540c\u70b9\u3002 \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 map \u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u987a\u5e8f\u6392\u5217\uff0c\u904d\u5386\u65f6\u4e5f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u6bd4\u5927\u5c0f\uff08std::less \u6216 <\uff09\u3002 unordered_map \u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\uff0c\u91cc\u9762\u5143\u7d20\u987a\u5e8f\u968f\u673a\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u54c8\u5e0c\u503c\u8ba1\u7b97\uff08std::hash\uff09\u548c\u5224\u65ad\u76f8\u7b49\uff08std::equal_to \u6216 ==\uff09\u3002 map \u4e2d\u7684\u5143\u7d20\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0cunordered_map \u91cc\u9762\u7684\u5143\u7d20\u662f\u968f\u673a\u7684\u3002 \u8fd9\u4e5f\u610f\u5473\u7740 std::set_union \u8fd9\u7c7b\u8981\u6c42\u8f93\u5165\u533a\u95f4\u6709\u5e8f\u7684 algorithm \u51fd\u6570\u65e0\u6cd5\u9002\u7528\u4e8e unordered_map/set\u3002 hash \u548c equal_to map \u53ea\u9700\u8981 K \u7c7b\u578b\u652f\u6301\u4e00\u4e2a less \u5c31\u80fd\u5de5\u4f5c\u3002 \u800c unordered_map \u9700\u8981 K \u652f\u6301\u7684 trait \u6709\u4e24\u4e2a\uff1ahash \u548c equal_to\u3002 unordered_map \u7684\u5b8c\u6574\u5f62\u6001\u662f\uff1a unordered_map, equal_to, allocator>> \u5176\u4e2d allocator \u6211\u4eec\u7167\u4f8b\u5148\u8df3\u8fc7\u4e0d\u8bb2\uff0c\u4e4b\u540e\u5206\u914d\u5668\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4ecb\u7ecd\u3002 hash \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u6c42\u952e\u7684\u54c8\u5e0c\u503c\uff1fhash \u4eff\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a K \u7c7b\u578b\u7684\u952e\uff0c\u8fd4\u56de\u4e00\u4e2a size_t\uff08\u5728 64 \u4f4d\u7cfb\u7edf\u4e0a\u662f\u4e2a\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff0c\u8868\u793a\u54c8\u5e0c\u503c\uff09\u3002 equal_to \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u5224\u65ad\u4e24\u4e2a\u952e\u76f8\u7b49\uff1f\u5982\u679c\u4e24\u4e2a\u952e\u5b8c\u5168\u76f8\u7b49\uff0c\u4ed6\u4f1a\u8fd4\u56de true\u3002 \u8fd9\u91cc\u5bf9 hash \u7684\u5b9e\u73b0\u53ea\u6709\u4e00\u4e2a\u8981\u6c42\uff0c \u5982\u679c\u4e24\u4e2a\u952e\u76f8\u7b49\uff0c\u5219\u4ed6\u4eec\u7684\u54c8\u5e0c\u5fc5\u5b9a\u4e5f\u76f8\u7b49\uff0c\u53cd\u4e4b\u5219\u4e0d\u4e00\u5b9a \u3002 \u8fd9\u4e2a\u5047\u8bbe\u6784\u6210\u4e86 unordered_map \u5f97\u4ee5\u9ad8\u6548\u7684\u57fa\u77f3\uff0c\u4ed6\u4f7f\u5f97 unordered_map \u53ef\u4ee5\u66f4\u5feb\u6392\u9664\u4e0d\u53ef\u80fd\u7684\u7b54\u6848\uff0c\u800c\u4e0d\u5fc5\u50cf vector \u7684\u67e5\u627e\u90a3\u6837\u9700\u8981\u53bb\u66b4\u529b\u904d\u5386\u5168\u90e8\u5143\u7d20\uff0c\u53ea\u9700\u8981\u904d\u5386\u54c8\u5e0c\u76f8\u7b49\u7684\u90a3\u4e00\u90e8\u5206\u5143\u7d20\u5c31\u591f\u4e86\u3002 template, // \u9ed8\u8ba4\u7684\u54c8\u5e0c\u51fd\u6570\u5b9e\u73b0\uff0c\u652f\u6301\u4e86 int, void *, string \u7b49\u7c7b\u578b typename _Pred = equal_to<_Key>, // \u9ed8\u8ba4\u7684 == \u8fd0\u7b97\u7b26 typename _Alloc = allocator>> class unordered_map \u6362\u8a00\u4e4b\uff0c\u53ea\u8981 unordered_map \u53d1\u73b0\u4e24\u4e2a\u952e\u4e0d\u76f8\u7b49\uff0c\u5c31\u4e0d\u7528\u518d\u505a\u5177\u4f53\u503c\u7684\u6bd4\u8f83\u4e86\uff0c\u4ed6\u4eec\u4e0d\u53ef\u80fd\u76f8\u7b49\u4e86\uff01 \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 hash \u8fd4\u56de\u7684 size_t \u8fd9\u4e2a\u6574\u6570\u53ef\u4ee5\u7406\u89e3\u4e3a\u4e00\u4e2a\u5bf9\u4efb\u610f\u7c7b\u578b\u7684\u201c\u6458\u8981\u201d\u3002 \u628a\u4e00\u4e2a\u5f88\u590d\u6742\u7684\u7c7b\u578b\uff08\u4f8b\u5982 string\uff09\u538b\u7f29\u6210\u4e00\u4e2a unordered_map \u5f88\u8f7b\u6613\u5c31\u80fd\u6bd4\u8f83\u7684 size_t \u6574\u6570\uff0c\u6574\u6570\u6bd4\u8f83\u8d77\u6765\u5c31\u5f88\u5bb9\u6613\uff0c\u800c\u4e14\u8fd8\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff08string \u4e0d\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff09\u3002 \u8fd9\u79cd\u6458\u8981\u7684\u5173\u952e\u5728\u4e8e\u5982\u4f55\u628a\u4e00\u4e2a\u6781\u4e3a\u590d\u6742\u7684\u7c7b\u578b\u201c\u6620\u5c04\u201d\u5230\u5c0f\u5c0f\u7684 size_t \u4e0a\u53bb\uff0c\u5e76\u4e14\u5206\u5e03\u5f97\u5c3d\u53ef\u80fd\u5747\u5300\uff0c\u4e0d\u8981\u51b2\u7a81\u3002 \u8fd9\u5c31\u9700\u8981\u6211\u4eec\u628a\u8fd9\u4e2a\u6781\u4e3a\u590d\u6742\u7c7b\u578b\u7684\u6bcf\u4e2a\u6210\u5458\uff08\u5bf9 string \u800c\u8a00\u5c31\u662f\u6bcf\u4e2a\u5b57\u7b26\uff09\u90fd\u52a0\u5230\u6700\u7ec8\u7ed3\u679c\u7684\u8868\u8fbe\u5f0f\u4e2d\u3002 \u4ee5\u5b57\u7b26\u4e32\u7c7b\u578b string \u4e3a\u4f8b\uff0c\u5e38\u89c1\u7684\u4e00\u79cd\u751f\u6210\u201c\u6458\u8981\u201d\u7684\u65b9\u6cd5\u662f\uff0c\u7528\u4e00\u4e2a\u4efb\u610f\u7d20\u6570\u7684\u4e58\u65b9\u5e8f\u5217\u548c\u5404\u5b57\u7b26\u7684 ASCII \u7801\u505a\u70b9\u79ef\uff1a size_t hash_string(string const &s) { size_t h = 0; for (char c: s) { h = h * 37 + c; } return h; } \u4f8b\u5982\u5bf9\u4e8e\u5b57\u7b26\u4e32 \u201chello\u201d\uff0c\u5219 hash \u53ef\u4ee5\u751f\u6210\u8fd9\u6837\u4e00\u4e2a\u6458\u8981\uff1a size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u76f8\u5f53\u4e8e h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o \u4e5f\u6709\u5176\u4ed6\u66f4\u9ad8\u6548\u7684\u751f\u6210\u6458\u8981\u7684\u65b9\u6cd5\uff0c\u4f8b\u5982\u501f\u52a9\u4f4d\u8fd0\u7b97\u3002 \u751a\u81f3\u8fd8\u6709\u5077\u61d2\u76f4\u63a5\u62ff strlen \u5f53\u54c8\u5e0c\u51fd\u6570\u7684\u201c\u4e16\u754c\u4e0a\u6700\u597d\u7684\u54c8\u5e0c\u8868\u201d\uff0c\u6211\u4e0d\u8bf4\u662f\u8c01\u3002\uff08\u5176\u5b9e\u662f\u65e9\u671f PHP \u5566\uff09 \u81ea\u52a8\u53d6\u6a21 size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u968f\u7740\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u589e\u52a0\uff0c\u8fd9\u4e2a h \u80af\u5b9a\u4f1a\u8d85\u8fc7 size_t \u7684\u8868\u793a\u8303\u56f4\uff0c\u4f46\u662f\u6ca1\u5173\u7cfb\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u7684\u4e58\u6cd5\u3001\u52a0\u6cd5\u6ea2\u51fa\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ed6\u4f1a\u81ea\u52a8 wrapping\uff08\u53d6\u5173\u4e8e 2^{64} 2^{64} \u7684\u6a21\uff09\uff0c\u4e5f\u5c31\u662f\u53ea\u4fdd\u7559\u4e58\u6cd5\u7ed3\u679c\u548c 2^64 \u53d6\u6a21\u7684\u90e8\u5206\u3002 \u53d6\u6a21\u4e5f\u662f\u5bf9\u54c8\u5e0c\u503c\u5e38\u89c1\u7684\u4e00\u4e2a\u64cd\u4f5c\uff0c\u53cd\u6b63\u54c8\u5e0c\u503c\u662f\u968f\u673a\u7684\uff0c\u53d6\u6a21\u4ee5\u540e\u4e5f\u662f\u968f\u673a\u7684\uff0c\u4f46\u662f\u7f29\u5c0f\u4e86\u8303\u56f4\u3002 \u57fa\u672c\u5047\u8bbe\uff1am \u8db3\u591f\u5c0f\u65f6\uff0c\u4e00\u4e2a\u5747\u5300\u7684\u5206\u5e03\u53d6\u4ee5 m \u7684\u6a21\u4ee5\u540e\u4ecd\u7136\u5e94\u8be5\u662f\u5747\u5300\u7684 unordered_map \u4e2d\u6876\u7684\u6570\u91cf\u662f\u6709\u9650\u7684\uff0c\u4e3a\u4e86\u628a\u8303\u56f4\u4ece 0 0 \u5230 2^{64} - 1 2^{64} - 1 \u7684\u54c8\u5e0c\u503c\u6620\u5c04\u4e3a 0 \u5230 bucket_count - 1 \u7684\u6876\u5e8f\u53f7\uff0c\u4ed6\u5185\u90e8\u4f1a\u628a\u952e\u7684\u54c8\u5e0c\u503c\u53d6\u4ee5\u6876\u6570\u91cf\u7684\u6a21\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u952e\u8981\u5b58\u50a8\u5230\u7684\u6876\u7684\u5e8f\u53f7\uff1a bucket_index = hash(key) % bucket_count hash \u662f\u4e2a trait \u7c7b std::hash \u5c31\u662f\u6807\u51c6\u5e93\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u7684\u4eff\u51fd\u6570\u7c7b\u4e86\uff0c\u4ed6\u548c std::less \u4e00\u6837\uff0c\u662f\u4e00\u4e2a trait \u7c7b\u3002 \u4e00\u4e9b\u5e38\u89c1\u7684\u7c7b\u578b\u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u9488\u5bf9\u81ea\u5b9a\u4e49\u7c7b\u578b\u6dfb\u52a0\u7279\u5316\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316 } }; template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u5bf9 T * \u7684\u504f\u7279\u5316 } }; std::hash \u9488\u5bf9\u6bcf\u4e2a\u4e0d\u540c\u7684\u7c7b\u578b\u505a\u4e86\u7279\u5316\uff0c\u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u8ba1\u7b97 string \u7c7b\u578b\u7684 hash \u65f6\uff1a string str = \"Hello, world\"; size_t h = hash()(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); \u6ce8\u610f\uff1a\u8fd9\u91cc\u6709\u4e24\u4e2a\u62ec\u53f7\uff0c\u7b2c\u4e00\u4e2a\u662f\u7a7a\u7684\u3002\u7b2c\u4e00\u4e2a\u62ec\u53f7\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u4e2a\u7528str\u4f5c\u4e3a\u5b9e\u53c2\u8c03\u7528\u4eff\u51fd\u6570\u7684 operator() \u3002\u5f53\u7136\u8fd8\u522b\u5fd8\u4e86\u7b2c\u4e00\u4e2a\u5c16\u62ec\u53f7\uff0c\u8fd9\u4e2a\u5c16\u62ec\u53f7\u91cc\u7684 string \u8868\u793a\u7684\u662f hash \u4eff\u51fd\u6570\u63a5\u4e0b\u6765\u8981\u63a5\u53d7\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u4e4b\u6240\u4ee5\u4f5c\u4e3a\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u800c\u4e0d\u662f\u6a21\u677f\u51fd\u6570\uff0c\u662f\u4e3a\u4e86\u65b9\u4fbf\u7279\u5316\u548c\u504f\u7279\u5316\u3002\u540c\u5b66\u4eec\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5199\u4e00\u4e2a\u8fd9\u6837\u7684\u51fd\u6570\uff0c\u7528\u8d77\u6765\u5c31\u4e0d\u7528\u6307\u5b9a\u7c7b\u578b\uff08\u5982\u8fd9\u91cc\u7684 string\uff09\u4e86\uff0c\u8ba9\u6a21\u677f\u51fd\u6570\u81ea\u52a8\u63a8\u5bfc\u53c2\u6570\u7c7b\u578b\uff08\u7c7b\u4f3c\u4e8e make_pair\uff09\uff1a template size_t do_hash(T const &t) { return hash()(t); } int main() { string str = \"Hello, world\"; size_t h = do_hash(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); } \"Hello, world\" \u7684\u54c8\u5e0c\u662f 14701251851404232991 \u5bf9\u4efb\u610f\u7c7b\u578b\u54c8\u5e0c\u7684\u7ed3\u679c\u90fd\u662f\u4e00\u4e2a size_t\uff0c\u5176\u5728 32 \u4f4d\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint32_t\uff0c\u5728\u6211\u4eec 64 \u4e3a\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint64_t\u3002\u9009\u62e9 size_t \u662f\u4e3a\u4e86\u80fd\u54c8\u5e0c\u4e86\u4ee5\u540e\u76f4\u63a5\u7528\u4e8e unordered_map \u4e2d\u6876\u7684\u7d22\u5f15\u3002 \u7531\u4e8e hash \u662f\u7528\u4f5c\u54c8\u5e0c\u8868\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7528\u4e8e\u52a0\u5bc6\u9886\u57df\uff08\u8bf7\u4f60\u79fb\u6b65 md5\uff09\uff0c\u6216\u662f\u7528\u4e8e\u968f\u673a\u6570\u751f\u6210\uff08\u8bf7\u79fb\u6b65 mt19937\uff09\uff0c\u56e0\u6b64\u5bf9\u4e8e\u4efb\u610f\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u6839\u636e\u4ed6\u751f\u6210\u4e00\u4e2a size_t \u7684\u54c8\u5e0c\u503c\u5373\u53ef\uff0c\u53ea\u8981\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5206\u5e03\u5747\u5300\u5373\u53ef\uff0c\u4e0d\u4e00\u5b9a\u8981\u6709\u968f\u673a\u6027\u3002\u4f8b\u5982\u6807\u51c6\u5e93\u5bf9 int \u7684 hash \u5b9e\u73b0\u5c31\u662f\u4e2a\u6052\u7b49\u51fd\u6570\u2014\u2014\u76f4\u63a5\u8fd4\u56de\u5176\u6574\u6570\u503c\uff0c\u4e0d\u7528\u505a\u4efb\u4f55\u8ba1\u7b97\uff1a template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316\u771f\u662f\u4ec0\u4e48\u4e5f\u4e0d\u505a\u5462\uff1f } }; \u800c\u5bf9\u4e8e\u4efb\u610f\u6307\u9488\u7684\u5b9e\u73b0\u5219\u662f\u76f4\u63a5\u628a\u6307\u9488 bit-cast \u6210 size_t\uff1a template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u6307\u9488\u5f3a\u5236\u8f6c\u6362\u4e3a\u6574\u6570 } }; int i = 42; int j = hash()(i); // \u6ca1\u60f3\u5230\u7f62\uff01\u6211\u7cfb\u6052\u7b49\u51fd\u6570\u54d2 print(i, j); 42 42 \u8bb0\u4f4f\uff0cstd::hash \u4e0d\u662f\u4e3a\u4e86\u52a0\u5bc6\u6216\u968f\u673a\u800c\u751f\u7684\uff0c\u4ed6\u7684\u529f\u80fd\u4ec5\u4ec5\u662f\u5c3d\u53ef\u80fd\u5feb\u901f\u5730\u628a\u4efb\u610f\u7c7b\u578b T \u6620\u5c04\u5230 size_t \u800c\u5df2\u3002 \u81f3\u4e8e\u8fd9\u5bf9 unordered_map \u7684\u6027\u80fd\u6709\u4f55\u5f71\u54cd\uff1f\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5f71\u54cd\uff0c\u9664\u975e\u8f93\u5165\u952e\u6545\u610f\u8bbe\u4e3a\u548c bucket_count \u540c\u6a21\uff0c\u6bd5\u7adf\u53cd\u6b63\u4f60\u4e5f\u65e0\u6cd5\u65ad\u5b9a\u8f93\u5165\u952e\u7684\u6392\u5e03\u6a21\u5f0f\uff0c\u4e0d\u8bba\u9009\u4ec0\u4e48\u54c8\u5e0c\u51fd\u6570\u53ea\u8981\u4fdd\u8bc1\u5747\u5300\u90fd\u662f\u53ef\u4ee5\u7684\u3002\u800c\u6052\u7b49\u51fd\u6570\u521a\u597d\u662f\u5747\u5300\u7684\uff0c\u53c8\u4e0d\u7528\u989d\u5916\u7684\u82b1\u91cc\u80e1\u54e8\u4f4d\u8fd0\u7b97\u6d6a\u8d39\u65f6\u95f4\uff0c\u53cd\u800c\u53ef\u80fd\u56e0\u4e3a\u952e\u6709\u5e8f\u800c\u63d0\u5347\u4e86\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u63d0\u5347\u4e86\u6027\u80fd\uff0c\u6240\u4ee5\u5404\u5927\u5382\u5546\u7684\u6807\u51c6\u5e93\u90fd\u662f\u8fd9\u4e48\u505a\u7684\u3002 \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(1)+ O(1)+ \u590d\u6742\u5ea6\u7684\u3002 \u770b\u8d77\u6765 unordered_map \u66f4\u9ad8\u6548\uff1f\u90a3\u8fd8\u8981 map \u5e72\u4ec0\u4e48\uff1f\u5b8c\u5168\u4e0a\u4f4d\u66ff\u4ee3\u554a\uff1f \u4f46\u662f\u6211\u4eec\u8981\u6ce8\u610f\uff0c\u4e0a\u9762\u6240\u8bf4\u7684\u590d\u6742\u5ea6 O(1) O(1) \u53ea\u662f\u5e73\u5747\u4e0b\u6765\u7684\uff0c\u5e76\u4e0d\u4ee3\u8868\u6bcf\u4e00\u6b21 unordered_map \u63d2\u5165\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(1) O(1) \uff01\u6240\u4ee5\uff0c\u590d\u6742\u5ea6\u8868\u793a\u6cd5\u91cc\u7684\u8fd9\u4e2a + \u53f7\u5c31\u662f\u8fd9\u4e2a\u610f\u601d\uff0c\u4ee3\u8868\u6211\u8fd9\u4e2a\u590d\u6742\u5ea6\u53ea\u662f\u591a\u6b21\u8fd0\u884c\u53d6\u5e73\u5747\uff0c\u5982\u679c\u53ea\u8003\u8651\u5355\u6b21\u6700\u574f\u7684\u60c5\u51b5\uff0c\u53ef\u80fd\u66f4\u9ad8\u3002 map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u4e5f\u53ea\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u53ef\u4ee5\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u3002 \u5904\u7406\u5f88\u9ad8\u7684\u6570\u636e\u91cf\u65f6\uff0c\u8fd9\u4e00\u70b9\u6700\u574f\u7684\u60c5\u51b5\u4f1a\u88ab\u5e73\u644a\u6389\uff0cunordered_map \u66f4\u9ad8\u6548\u3002 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u6240\u4ee5 unordered_map \u4e0d\u7a33\u5b9a\uff0c\u867d\u7136\u5e73\u5747\u662f O(1) O(1) \u590d\u6742\u5ea6\uff0c\u4f46\u6700\u574f\u53ef\u8fbe\u5230 O(N) O(N) \u590d\u6742\u5ea6\u3002\u80cc\u540e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\u5462\uff1f \u539f\u6765 unordered_map \u548c vector \u4e00\u6837\uff0c\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u52a8\u6001\u6269\u5bb9\u7684\u5bb9\u5668\u3002 \u5982\u679c\u4e0d\u6269\u5bb9\uff0c\u90a3\u4e48\u5f53\u5f88\u591a\u5143\u7d20\u6324\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u94fe\u8868\u7684\u538b\u529b\u5c31\u4f1a\u53d8\u5927\uff0c\u4f1a\u5f88\u4f4e\u6548\uff0c\u56e0\u6b64 unordered_map \u5fc5\u987b\u6269\u5bb9\u3002\u4f46\u662f\u5728\u6269\u5bb9\u7684\u65f6\u5019\u662f\u9700\u8981\u8fdb\u884c rehash \u64cd\u4f5c\u7684\u3002\u4e00\u6b21\u6269\u5bb9\uff0c\u5c31\u9700\u8981\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e00\u904d\u3002 \u7ed3\u679c\u5c31\u662f unordered_map \u7684\u63d2\u5165\u5982\u679c\u6ca1\u89e6\u53d1 rehash\uff0c\u90a3\u5c31\u662f O(1) O(1) \u7684\u3002\u89e6\u53d1\u4e86\uff0c\u90a3\u5c31\u662f\u6700\u574f\u7684\u60c5\u51b5\uff0c O(N) O(N) \u7684\u3002\u4f46\u662f\u4e0d\u89e6\u53d1\u7684\u60c5\u51b5\u8fdc\u591a\u4e8e\u89e6\u53d1\u4e86\u7684\uff0c\u6240\u4ee5\u5e73\u5747\u4e0b\u6765\u8fd8\u662f O(1) O(1) \uff0c\u4e3a\u4e86\u63d0\u9192\u4eba\u4eec\u4ed6\u6700\u574f\u7684\u60c5\u51b5\uff0c\u6240\u4ee5\u5199\u4f5c O(1)+ O(1)+ \uff0c\u8bfb\u4f5c\u201c\u5e73\u644a O1\u201d\uff08Amortized Constant\uff09\u3002 \u6b64\u5916\uff0c\u4e0d\u4ec5 unordered_map \u7684\u63d2\u5165\u51fd\u6570\u662f O(1)+ O(1)+ \uff0c\u4ed6\u7684\u67e5\u8be2\u51fd\u6570\u4e5f\u662f O(1)+ O(1)+ \u3002\u4e3a\u4ec0\u4e48\u5462\uff1f\u8bbe\u60f3\u4f60\u5728\u7f16\u5199\u4e00\u4e2a\u5bcc\u8fde\u7f51\u670d\u52a1\u5668\uff0c\u5982\u679c\u9ed1\u5ba2\u5df2\u77e5\u4f60\u7684 hash \u51fd\u6570\uff0c\u90a3\u4ed6\u5c31\u53ef\u4ee5\u901a\u8fc7\u6784\u9020\u4e00\u7cfb\u5217\u7279\u6b8a\u8bbe\u8ba1\u597d\u7684 key\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u521a\u597d\u76f8\u7b49\uff08\u6216\u540c\u6a21\uff09\uff0c\u8fd9\u6837\u5c31\u4f7f\u5f97\u6240\u6709 key \u521a\u597d\u5168\u90e8\u843d\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u5bfc\u81f4 unordered_map \u9000\u5316\u6210\u7ebf\u6027\u7684\u94fe\u8868\uff0c\u6240\u6709\u7684\u67e5\u8be2\u548c\u63d2\u5165\u90fd\u53d8\u6210\u4e86\u8fd9\u4e00\u4e2a\u6876\u4e0a\u7684\u94fe\u8868\u904d\u5386\u64cd\u4f5c\uff0c\u590d\u6742\u5ea6\u8fbe\u5230\u6700\u574f\u7684 O(N) O(N) \uff0c\u8fd9\u4e00\u73b0\u8c61\u53eb\u505a hash \u9000\u5316\u3002 \u56e0\u6b64 hash \u51fd\u6570\u7684\u597d\u574f\u51b3\u5b9a\u7740 unordered_map \u6027\u80fd\uff0c\u5bf9\u4e8e\u5b89\u5168\u9886\u57df\u6765\u8bf4\uff0c\u8fd8\u8981\u4fdd\u8bc1 hash \u51fd\u6570\u65e0\u6cd5\u88ab\u9ed1\u5ba2\u7834\u89e3\u3002\u53ea\u8981 hash \u51fd\u6570\u8db3\u591f\u968f\u673a\uff0c\u5c31\u80fd\u4fdd\u8bc1\u952e\u4e0d\u51b2\u7a81\uff0c\u5c31\u5f88\u5feb\uff0c\u4e00\u65e6\u51fa\u73b0\u952e\u51b2\u7a81\u5c31\u4f1a\u53d8\u6162\u3002\u4f46\u9700\u8981\u9891\u7e41\u4f7f\u7528\u7684 hash \u51fd\u6570\u8ba1\u7b97\u96be\u5ea6\u53c8\u4e0d\u80fd\u592a\u5927\uff0c\u90a3\u53c8\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u56e0\u6b64 hash \u4e5f\u4e0d\u80fd\u592a\u8fc7\u590d\u6742\u3002 \u6807\u51c6\u5e93\u91cc\u5b58\u5728\u8fd9\u79cd\u201c\u5e73\u644a\u590d\u6742\u5ea6\u201d\u7684\u4f8b\u5b50\u8fd8\u6709\u5f88\u591a\uff0c\u4f8b\u5982 vector \u7684 push_back \u4e0d reserve \u7684\u8bdd\uff0c\u5c31\u662f O(1)+ O(1)+ \u7684\uff0c\u56e0\u4e3a\u4ed6\u9700\u8981\u52a8\u6001\u6269\u5bb9\u3002 \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u4e00\u4e9b\u5b9e\u65f6\u6027\u8981\u6c42\u5f88\u9ad8\u7684\u9886\u57df\u5c31\u4e0d\u80fd\u7528 unordered_map\u3002\u4f8b\u5982\u4f60\u9020\u4e86\u4e2a\u706b\u7bad\uff0c\u89c4\u5b9a\uff1a\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u9700\u8981\u5728 1000 \u03bcs \u5185\u5bf9\u5916\u754c\u53d8\u5316\u505a\u51fa\u5b9e\u65f6\u53cd\u5e94\uff0c\u5982\u679c\u4e0d\u80fd\u53ca\u65f6\u505a\u51fa\u53cd\u5e94\uff0c\u706b\u7bad\u5c31\u4f1a\u505a\u6258\u9a6c\u65af\u56de\u65cb\u7ed9\u4f60\u770b\u3002 \u4f60\u5728\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u4e2d\u7528\u4e86 unordered_map\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u4e0d\u65ad\u8fd0\u884c\uff0c\u4ee5\u4fbf\u63a7\u5236\u706b\u7bad\u505a\u51fa\u6b63\u786e\u7684\u673a\u52a8\uff0c\u5bf9\u6297\u4fa7\u5411\u98ce\u5e72\u6270\u3002\u7b2c\u4e00\u6b21\u8fd0\u884c\u4ed6\u5728 180 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 250 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 245 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u9ad8\u6548\u3002 \u4f46\u662f\u7a81\u7136\u6709\u4e00\u6b21\uff0cunordered_map \u89c9\u5f97\u4ed6\u5185\u90e8\u201c\u6876\u592a\u4e71\u201d\u4e86\uff0c\u6025\u9700\u91cd\u65b0\u6269\u5bb9\u5e76 rehash \u4e00\u4e0b\u201c\u5fe7\u5316\u6027\u80fd\u201d\u3002\u7136\u540e\uff0c\u4ed6\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e86\u4e00\u904d\uff0c\u79fb\u52a8\u5b8c\u4e86\uff0c\u628a\u5904\u7406\u5b8c\u7684\u6570\u636e\u8fd4\u56de\u7ed9\u706b\u7bad\u59ff\u6001\u8c03\u63a7\u7cfb\u7edf\uff0c\u8ba4\u4e3a\u5927\u529f\u544a\u6210\u3002\u4f46\u5f53\u4ed6\u7741\u5f00\u773c\u775b\u4e00\u770b\uff0c\u521a\u60f3\u8981\u63a7\u5236\u4e00\u4e0b\u59ff\u6001\u5462\uff1f\u5374\u53d1\u73b0\u81ea\u5df1\u5df2\u7ecf\u5728\u505a\u6258\u9a6c\u65af\u56de\u65cb\u4e86\uff01\u539f\u6765\u6211\u8fd9\u4e00\u201c\u5fe7\u5316\u201d\u5c31\u5fe7\u4e86 4000 \u03bcs\uff0c\u8d85\u51fa\u4e86\u706b\u7bad\u5b9e\u65f6\u54cd\u5e94\u7684\u786c\u6027\u6307\u6807\uff0c\u5bfc\u81f4\u897f\u88c5\u9ab0\u5b50\u4eba\u5377\u6b3e\u8dd1\u8def\uff0c\u5c0f\u5f6d\u8001\u5e08\u7834\u4ea7\u3002 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u521b\u4e1a\uff0c\u8fd9\u6b21\u4ed6\u9009\u7528\u4e86\u7a33\u5b9a\u7684 map\uff0c\u7b2c\u4e00\u6b21\u4ed6\u5728 810 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 680 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 730 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u4f4e\u6548\u3002\u4f46\u662f\u4ed6\u6bcf\u4e00\u6b21\u90fd\u80fd\u6210\u529f\u5361\u70b9\u7ed9\u4f60\u5b8c\u6210\u4efb\u52a1\uff0c\u4ece\u6765\u4e0d\u4f1a\u7a81\u7136\u8d85\u8fc7 O(\\log N) O(\\log N) \uff0c\u4ed6\u7684\u6700\u574f\u60c5\u51b5\u662f\u53ef\u63a7\u7684\uff0c\u4ece\u800c\u907f\u514d\u4e86\u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb\u3002\u5c0f\u5f6d\u8001\u5e08\u6700\u7ec8\u521b\u4e1a\u6210\u529f\uff0c1000 \u5e74\u540e\uff0c\u6211\u53f8\u6210\u529f\u5efa\u9020\u5b8c\u6210 Type-II \u6587\u660e\u6240\u6025\u9700\u7684\u6234\u68ee\u7403\uff0c\u5411\u661f\u8fb0\u5927\u6d77\u8fdb\u519b\u3002 \u5bf9\u5b9e\u65f6\u6027\u8981\u6c42\u9ad8\u7684\u8fd9\u7c7b\u9886\u57df\u5305\u62ec\uff0c\u97f3\u89c6\u9891\uff0c\u9020\u706b\u7bad\uff0c\u91cf\u5316\u4ea4\u6613\u7b49\u3002\u8fd9\u7c7b\u4f4e\u5ef6\u8fdf\u4f4e\u541e\u5410\u91cf\u7684\u9886\u57df\u5bf9\u5e73\u644a\u590d\u6742\u5ea6\u5f88\u53cd\u611f\uff0c\u4ed6\u4eec\u53ea\u770b\u91cd\u6700\u574f\u7684\u590d\u6742\u5ea6\uff0c\u800c\u4e0d\u662f\u5e73\u5747\u7684\u3002 \u4f46\u5bf9\u4e8e\u4e3b\u6253\u4e00\u4e2a\u9ad8\u541e\u5410\u91cf\u65e0\u6240\u8c13\u5ef6\u8fdf\u7684\u79bb\u7ebf\u56fe\u5f62\u5b66\uff0c\u79bb\u7ebf\u79d1\u5b66\u8ba1\u7b97\uff0c\u5b9e\u65f6\u6027\u4e0d\u91cd\u8981\u7684\u751f\u6001\u5316\u53cd\u573a\u666f\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba4\u4e3a unordered_map \u7684\u5e73\u644a O(1)+ O(1)+ \u5c31\u662f\u6bd4 map \u9ad8\u6548\u7684\u3002 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 map \u548c unordered_map \u90fd\u662f\u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\u624d\u4f1a\u5931\u6548\uff0c\u8fd9\u70b9\u76f8\u540c\u3002 \u4f46 unordered_map \u6269\u5bb9\u65f6\u5019\u7684 rehash \u64cd\u4f5c\u4f1a\u9020\u6210\u6240\u6709\u8fed\u4ee3\u5668\u5931\u6548\u3002 insert \u53ef\u80fd\u5bfc\u81f4 unordered_map \u6269\u5bb9\uff0c\u5176\u4ed6\u53ea\u8bfb\u64cd\u4f5c\u4e0d\u4f1a\u3002 \u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u88ab\u5220\u9664\u65f6\uff0c\u4e0d\u8bba map \u548c unordered_map \u90fd\u4f1a\u5931\u6548\u3002 unordered_map \u5728 insert \u65f6\u5982\u679c\u53d1\u751f\u6269\u5bb9\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u5931\u6548\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528 reserve \u907f\u514d insert \u65f6\u6269\u5bb9\u3002 \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 clear swap opeartor= rehash vector \u662f \u5426 \u662f - map \u662f \u5426 \u662f - unordered_map \u662f \u5426 \u662f - \u5bb9\u5668 find count at [] vector \u5426 \u5426 \u5426 \u5426 map \u5426 \u5426 \u5426 \u5426 unordered_map \u5426 \u5426 \u5426 \u662f\uff0c\u5982\u679c\u521b\u5efa\u4e86\u65b0\u5143\u7d20\u4e14 size / bucket_count > max_load_factor \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 push_back insert erase reserve vector \u662f\uff0c\u5982\u679c size > capacity \u662f\uff0c\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216 size > capacity \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u5143\u7d20\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684 \u662f map - \u5426 \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 - unordered_map - \u662f\uff0c\u5982\u679c size / bucket_count > max_load_factor \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 \u662f \u4e5f\u53ef\u4ee5\u67e5\u770b\u5b98\u65b9\u7248\u300a\u8fed\u4ee3\u5668\u5931\u6548\u8868\u300b\uff1ahttps://en.cppreference.com/w/cpp/container#Iterator_invalidation \u8d1f\u8f7d\u7387\uff08load_factor\uff09 \u8ba1\u7b97\u516c\u5f0f\uff1a\u8d1f\u8f7d\u56e0\u5b50(load_factor) = \u5f53\u524d\u5143\u7d20\u6570\u91cf(size) \u00f7 \u5f53\u524d\u6876\u7684\u6570\u91cf(bucket_count) \u63d2\u5165\u65b0\u5143\u7d20\u540e\uff0c\u5f53\u68c0\u6d4b\u5230\u8d1f\u8f7d\u56e0\u5b50\u5927\u4e8e\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4 1.0\uff09\u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fdb\u884c rehash \u64cd\u4f5c\u3002 \u4e3a\u4e86\u907f\u514d\u91cd\u590d\u5c0f\u89c4\u6a21\u6269\u5bb9\u6d6a\u8d39\u65f6\u95f4\uff0c\u8fd9\u6b21 rehash \u4f1a\u4e00\u6b21\u6027\u6269\u5bb9\u4e24\u500d\uff08\u8ddf vector \u7684 push_back \u6269\u5bb9\u7c7b\u4f3c\uff09\u3002 \u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 max_load_factor \u51fd\u6570\u8c03\u6574\u3002\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 load_factor \u51fd\u6570\u67e5\u8be2\u3002 \u76f4\u89c2\u7406\u89e3\uff1a\u5f53\u6bcf\u4e2a\u6876\u5e73\u5747\u90fd\u6709\u4e00\u4e2a\u5143\u7d20\u65f6\uff0cunordered_map \u5c31\u4f1a\u8ba4\u4e3a\u5df2\u7ecf\u5f88\u6ee1\u4e86\uff0c\u5c31\u4f1a\u6269\u5bb9\u5e76\u91cd\u65b0\u5206\u914d\u4f4d\u7f6e\u3002 \u7531\u4e8e\u9ed8\u8ba4\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u662f 1.0\uff0c\u6240\u4ee5\u6269\u5bb9\u6761\u4ef6\u7b49\u4ef7\u4e8e size > bucket_count rehash \u51fd\u6570 \u5728\u64cd\u4f5c unordered_map \u5bb9\u5668\u8fc7\u7a0b\uff08\u5c24\u5176\u662f\u5411\u5bb9\u5668\u4e2d\u6dfb\u52a0\u65b0\u952e\u503c\u5bf9\uff09\u4e2d\uff0c\u4e00\u65e6\u5f53\u524d\u5bb9\u5668\u7684\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4\u503c\u4e3a 1.0\uff09\uff0c\u8be5\u5bb9\u5668\u5c31\u4f1a\u9002\u5f53\u589e\u52a0\u6876\u7684\u6570\u91cf\uff08\u901a\u5e38\u662f\u7ffb\u4e00\u500d\uff09\uff0c\u5e76\u81ea\u52a8\u6267\u884c rehash() \u6210\u5458\u65b9\u6cd5\uff0c\u91cd\u65b0\u8c03\u6574\u5404\u4e2a\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff08\u6b64\u8fc7\u7a0b\u53c8\u79f0\u201c\u91cd\u54c8\u5e0c\u201d\uff09\uff0c\u6b64\u8fc7\u7a0b\u5f88\u53ef\u80fd\u5bfc\u81f4\u4e4b\u524d\u521b\u5efa\u7684\u8fed\u4ee3\u5668\u5931\u6548\u3002 1 \u9664\u4e86\u6269\u5bb9\u65f6\u81ea\u52a8\u7684 rehash\uff0c\u786e\u8ba4\u6570\u636e\u63d2\u5165\u5b8c\u6bd5\u4e0d\u4f1a\u518d\u6539\u52a8\u65f6\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u6765\u4f18\u5316\u5bb9\u5668\u4e2d\u5143\u7d20\u7684\u6392\u5e03\uff0c\u63d0\u5347\u6027\u80fd\u3002 unordered_map umap; for (int i = 1; i <= 50; i++) { umap.emplace(i, i); } auto pair = umap.equal_range(49); //\u83b7\u53d6\u952e\u4e3a 49 \u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u533a\u95f4\uff0c\u7531\u4e8e\u4e0d\u662f multimap\uff0c\u533a\u95f4\u5927\u5c0f\u53ea\u80fd\u4e3a 0 \u6216 1 for (auto iter = pair.first; iter != pair.second; ++iter) { //\u8f93\u51fa pair \u8303\u56f4\u5185\u7684\u6bcf\u4e2a\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c cout << iter->first << '\\n'; } umap.rehash(10); //\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u91cd\u54c8\u5e0c\u4e3a 10 \u4e2a\u6876 for (auto iter = pair.first; iter != pair.second; ++iter) { // \u91cd\u54c8\u5e0c\u4e4b\u540e\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u4f1a\u53d1\u751f\u53d8\u5316 cout << iter->first << '\\n'; } 49 Segmentation fault (core dumped) hash \u9700\u8981\u7279\u5316 \u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6620\u5c04\u8868 map \u53ea\u9700\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7684 less \u5373\u53ef\uff0c\u800c unordered_map \u9700\u8981\u54c8\u5e0c\u548c\u76f8\u7b49\u4e24\u4e2a trait\uff0c\u4ed6\u4eec\u5206\u522b\u540d\u53eb std::hash \u548c std::equal_to\u3002 \u867d\u7136\u4e24\u8005\u90fd\u662f\u4eff\u51fd\u6570\uff0c\u4f46\u4e5f\u6709\u5f88\u591a\u533a\u522b\uff1a hash \u53ea\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u800c equal_to \u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\u3002 hash \u8fd4\u56de size_t\uff0c\u800c equal_to \u8fd4\u56de bool \u7c7b\u578b\u3002 equal_to \u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u8c03\u7528\u8fd0\u7b97\u7b26 ==\u3002\u800c hash \u6ca1\u6709\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u4e5f\u6ca1\u76f8\u5e94\u7684\u8fd0\u7b97\u7b26\uff0c\u53ea\u80fd\u624b\u52a8\u7279\u5316\u3002 \u6b63\u56e0\u4e3a\u5982\u6b64\uff0c\u901a\u5e38\u6211\u4eec\u9700\u8981\u8ba9\u4e00\u4e2a\u7c7b\uff08\u4f8b\u5982 Student\uff09\u652f\u6301 equal_to \u6216 less \u8fd9\u4e9b\u6709\u76f8\u5e94\u8fd0\u7b97\u7b26\u7684\u4eff\u51fd\u6570\u65f6\uff0c\u76f4\u63a5\u5728\u7c7b\u578b\u5185\u90e8\u5b9a\u4e49 operator== \u6216 operator< \u5373\u53ef\uff0c\u800c hash \u5219\u662f\u53ea\u80fd\u7528\u7279\u5316\u7684\u65b9\u6cd5\u624d\u80fd\u652f\u6301\u4e0a\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template struct equal_to { bool operator()(T const &x, T const &y) const noexcept { return x == y; } }; \u6709\u4e9b\u7c7b\u578b\u80fd\u7528\u4f5c map \u7684\u952e\uff0c\u4f46\u4e0d\u80fd\u7528\u4f5c unordered_map \u7684\u952e\u3002\u8fd9\u662f\u56e0\u4e3a\u5077\u61d2\u7684\u6807\u51c6\u5e93\u6ca1\u5bf9\u4ed6\u4eec\u7684 hash \u7279\u5316\uff01 \u4f8b\u5982 tuple \u652f\u6301 < \u8fd0\u7b97\u7b26\uff0c\u652f\u6301 less\u3002 \u4f46\u662f tuple \u6ca1\u6709 hash \u7684\u7279\u5316\uff0c\u4e0d\u652f\u6301 hash\u3002 tuple tup; size_t h = hash>()(tup); // \u7f16\u8bd1\u671f\u62a5\u9519\uff1a\u67e5\u65e0\u6b64\u51fd\u6570\uff01 unordered_map> \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u548c less \u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u662f\u6709\u4e09\u79cd\u89e3\u51b3\u65b9\u6848\uff1a \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u7279\u5316\uff0cequal_to \u7684\u7279\u5316 template <> struct std::hash { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; template <> struct std::equal_to { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u4e00\u4e2a equal_to \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u7136\u540e\u4f20\u5165 unordered_map \u505a\u6a21\u677f\u53c2\u6570 template <> struct HashStudent { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; struct EqualStudent { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u6ce8\uff1a\u5982\u679c Student \u5df2\u7ecf\u5b9a\u4e49\u4e86 operator== \uff0c\u5219\u8fd9\u91cc\u4e0d\u7528 EqualStudent\uff0c\u9ed8\u8ba4\u7684 equal_to \u4f1a\u81ea\u52a8\u8c03\u7528 == \u8fd0\u7b97\u7b26\u7684\u3002 \u5bf9\u4e8e tuple \u800c\u8a00\uff0ctuple \u5df2\u7ecf\u6709\u4e86 == \u8fd0\u7b97\u7b26\uff0c\u4e0d\u7528\u7279\u5316 equal_to \u4e86\uff0c\u53ea\u9700\u8981\u7279\u5316\u6216\u6307\u5b9a hash \u5373\u53ef template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; unordered_map, int> stutab; \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); // \u628a\u4efb\u610f\u591a\u4e2a\u5143\u7d20\u54c8\u5e0c\u901a\u8fc7\u201c\u4f4d\u5f02\u6216(^)\u201d\u62fc\u51d1\u6210\u4e00\u4e2a\u5355\u72ec\u7684\u54c8\u5e0c } template struct std::hash> { size_t operator()(std::tuple const &x) const { // std::apply \u4f1a\u628a tuple \u91cc\u7684\u5143\u7d20\u5168\u90e8\u5c55\u5f00\u6765\u8c03\u7528 hash_combine\uff0c\u76f8\u5f53\u4e8e Python \u91cc\u7684 *args return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 106 \u8fd9\u91cc\u7684\u8ba1\u7b97\u662f\uff1a42 ^ 64 = 106\uff0c\u4f4d\u5f02\u6216\u7684\u77e5\u8bc6\u53ef\u4ee5\u53bb Bing \u641c\u7d22\u4e00\u4e0b\uff0c\u6216\u8005\u95ee\u4e00\u4e0b GPT\uff0cCS \u5b66\u751f\u5e94\u8be5\u90fd\u77e5\u9053\u7684\u3002 \u66f4\u597d\u7684 hash_combine \u4f46\u662f\u7b80\u7b80\u5355\u5355\u7528\u4e00\u4e2a\u4f4d\u5f02\u6216 ^ \u6765\u628a\u4e24\u4e2a\u6210\u5458\u7684\u54c8\u5e0c\u7ec4\u5408\u8d77\u6765\uff0c\u6709\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u5982\u679c tuple \u91cc\u7684\u4e24\u4e2a\u6210\u5458\u503c\u521a\u597d\u4e00\u6837\uff0c\u5219\u5176\u4e24\u4e2a\u54c8\u5e0c\u503c\u4e5f\u4f1a\u4e00\u6837\uff0c\u90a3\u4e48\u4ed6\u4eec\u901a\u8fc7\u4f4d\u5f02\u6216 ^ \u5408\u5e76\u7684\u7ed3\u679c\u5c31\u4f1a\u59cb\u7ec8\u4e3a 0\u3002 \u4f8b\u5982\u4e0d\u8bba (42, 42) \u8fd8\u662f (64, 64) \u8fd9\u4e24\u4e2a tuple\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u503c\u90fd\u4f1a\u4e3a 0\u3002\u660e\u660e\u5177\u4f53\u503c\u4e0d\u540c\u54c8\u5e0c\u503c\u5374\u76f8\u540c\uff0c\u8fd9\u5c31\u662f\u53d1\u751f\u4e86\u54c8\u5e0c\u51b2\u7a81\uff0c\u8fd9\u4f1a\u4e25\u91cd\u5f71\u54cd unordered_map \u7684\u6027\u80fd\uff0c\u662f\u5fc5\u987b\u907f\u514d\u7684\u3002 \u7528 + \u6765\u7ec4\u5408\u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u7b2c\u4e00\u4e2a\u6210\u5458\u521a\u597d\u662f\u53e6\u4e00\u4e2a\u7684\u76f8\u53cd\u6570\uff0c\u6216\u53ea\u8981\u662f\u4e24\u4e2a\u6570\u52a0\u8d77\u6765\u548c\u76f8\u7b49\uff0c\u5c31\u4f1a\u51b2\u7a81\u3002 \u4f8b\u5982\u5982\u679c\u6211\u4eec\u7528 unordered_map \u6784\u5efa\u4e00\u5f20\u5730\u56fe\u7684\u8bdd\uff0c\u5c31\u53d1\u73b0\u5f53\u73a9\u5bb6\u5728\u5f80\u659c\u4e0a\u65b9\u79fb\u52a8\u65f6\u5c31\u4f1a\u53d8\u5f97\u7279\u522b\u5361\u987f\uff0c\u539f\u6765\u662f\u56e0\u4e3a\u73a9\u5bb6\u7684\u5386\u53f2\u8f68\u8ff9\u521a\u597d\u662f\u4e00\u6761 y = x \u7684\u66f2\u7ebf\uff0c\u659c\u7387\u4e3a 1\uff0c\u7531\u4e8e\u6211\u4eec\u91c7\u7528 ^ \u6765\u7ec4\u5408\u54c8\u5e0c\uff0c\u5c31\u5bfc\u81f4\u521a\u597d\u8fd9\u6761\u7ebf\u4e0a\u6240\u6709\u7684\u70b9\u90fd\u4f1a\u584c\u7f29\u5230 0 \u53f7\u6876\u53bb\uff0c\u8ba9 unordered_map \u9000\u5316\u6210\u4e86 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 template inline size_t hash_combine(Ts const &...ts) { size_t h = 0; ((h ^= std::hash()(ts) + 0x9e3779b9 + (h << 6) + (h >> 2)), ...); return h; } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 175247763666 \u53ef\u4ee5\u770b\u5230\u968f\u673a\u6027\u5927\u5927\u63d0\u5347\u4e86\u3002 \u5e94\u7528 \u7528 hash_combine \u6539\u8fdb\u521a\u521a Student \u7684\u54c8\u5e0c\u51fd\u6570\u3002 template <> struct std::hash { bool operator()(Student const &x) const { return hash_combine(hash()(x.name), hash(x.id), hash(x.sex)); } }; \u540c\u7406\u53ef\u5f97 array \u7684\u7279\u5316 template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u7d20\u6570\u4e58\u65b9\u6cd5\u6765\u63d0\u5347\u54c8\u5e0c\u51fd\u6570\u7684\u5747\u5300\u6027\u548c\u968f\u673a\u6027\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h = h * 18412483 + hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u6700\u9ad8\u7ea7\u7684\uff0c\u57fa\u4e8e\u4f4d\u8fd0\u7b97\u7684\uff0c\u6700\u9ad8\u6548\u7684\uff0cboost::hash_combine \u7684\u5b9e\u73b0\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t) + 0x9e3779b9 + (h << 6) + (h >> 2); } return h; } }; unordered_map, int> stutab; \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 TODO map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API Student(Student &&) = delete; // \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u4e0b\u9762\u51e0\u4e2a\uff0c\u4e0d\u7528\u5199\u5168\uff1a // Student &operator=(Student &&) = delete; // Student(Student const &) = delete; // Student &operator=(Student const &) = delete; TODO \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 TODO \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 TODO \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 TODO \u672c\u671f\u5b5d\u70b9\u603b\u7ed3 \u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528 \u9a6c\u6876\u88c5\u9762\u5305 \u201c\u6790\u6784\u201d\u76f8\u4f9d1\u53f7 \u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55 \u770b\u5230\u8001\u9f20\ud83d\udca9\u8fc7\u6fc0\u53cd\u5e94 \u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b \u5c0f\u5b66\u751f\u65e9\u64cd\u6392\u961f \u5c0f\u9ec4\u82b1\u8868\u793a\u9ec4\u724c\u8b66\u544a \u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb http://c.biancheng.net/view/7236.html \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 https://en.cppreference.com/w/cpp/container/node_handle \u21a9 \u21a9 \u21a9 \u21a9","title":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec"},{"location":"stl_map/#stl-stdmap","text":"\u8ba9\u9ad8\u6027\u80fd\u6570\u636e\u7ed3\u6784\u60e0\u53ca\u6bcf\u4e00\u4eba STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec \u524d\u8a00 \u8bfe\u7a0b\u7b80\u4ecb \u8bfe\u7a0b\u4eae\u70b9 \u8bfe\u7a0b\u5927\u7eb2 \u5b9e\u9a8c\u73af\u5883 \u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6 \u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801 \u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e \u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6 \u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b \u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6 map \u7684\u903b\u8f91\u7ed3\u6784 \u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668 map \u7684\u7269\u7406\u7ed3\u6784 \u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5 \u4e8c\u53c9\u6392\u5e8f\u6811 \u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898 \u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811 \u5e73\u8861\u6811 \u7ea2\u9ed1\u6811 \u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6 \u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668 \u603b\u7ed3 C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45 \u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1 \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b \u5bf9\u6bd4 [] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf \u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868 map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868 map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 \u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type typename \u4fee\u9970 decltype \u5927\u6cd5\u597d \u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177 map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f count \u548c contains \u6ca1\u533a\u522b end \u4e0d\u80fd\u89e3\u5f15\u7528 find \u7684\u597d\u5904 C++17 \u8bed\u6cd5\u7cd6 \u9898\u5916\u8bdd \u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20 C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if insert_or_assign insert_or_assign \u7684\u4f18\u52bf \u6548\u7387\u95ee\u9898 [] insert_or_assign \u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48 insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898 \u6279\u91cf insert \u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219 \u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76 \u5c31\u5730\u5199\u5165\uff01 \u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684 \u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49 insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868 \u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528 operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868 \u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790 assign \u51fd\u6570 \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba \u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd \u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5 \u5206\u5974 emplace emplace_hint emplace \u7684\u539f\u7406\u548c\u4f18\u70b9 try_emplace \u66f4\u597d try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01 \u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9 \u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316 C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9 \u8c03\u7528\u5f00\u9500\u5206\u6790 try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace emplace \u5bb6\u65cf\u603b\u7ed3 map \u4e0e RAII \u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8 \u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8 \u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570 \u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406 \u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8 \u589e\u5220\u6539\u67e5\u603b\u7ed3 \u589e\u5220 \u6539\u67e5 \u521d\u59cb\u5316 \u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3 extract \u7528\u9014\u4e3e\u4f8b insert \u8282\u70b9\u7248 insert_return_type extract + insert \u8fd0\u7528\u6848\u4f8b extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b \u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c \u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09 \u6279\u91cf insert vs merge merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668 std::less \u7684\u4f5c\u7528 operator() \u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f \u53ea\u9700\u8981\u5c0f\u4e8e\u53f7 \u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f \u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15 C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=> \u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876 greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f \u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668 \u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668 map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684 \u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668 \u5efa\u8bae\u7528 function \u900f\u660e map \u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570 \u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570 \u6cdb\u578b\u7248\u7684 find \u51fd\u6570 \u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e \u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178 \u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178 \u795e\u5947\u7684 multimap \u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f \u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01 \u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2 \u8bfe\u540e\u7ec3\u4e60 \u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e \u54c8\u5e0c\u8868 unordered_map unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c \u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d \u54c8\u5e0c\u51b2\u7a81 (hash-collision) unordered_map \u4e0e map \u7684\u5f02\u540c \u533a\u522b 1\uff1a\u6709\u5e8f\u6027 hash \u548c equal_to \u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3 \u81ea\u52a8\u53d6\u6a21 hash \u662f\u4e2a trait \u7c7b \u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6 \u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a \u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236 \u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6 \u8d1f\u8f7d\u7387\uff08load_factor\uff09 rehash \u51fd\u6570 hash \u9700\u8981\u7279\u5316 \u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570 \u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01 \u66f4\u597d\u7684 hash_combine \u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5 \u5e94\u7528 \u7ecf\u5178\u6848\u4f8b map \u548c function \u7ed3\u5408\u4f7f\u7528 map \u548c variant \u7ed3\u5408\u4f7f\u7528 map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b \u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API \u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04 \u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570 \u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168 \u672c\u671f\u5b5d\u70b9\u603b\u7ed3","title":"STL \u7cbe\u8bb2\uff1astd::map \u548c\u4ed6\u7684\u670b\u53cb\u4eec"},{"location":"stl_map/#_1","text":"","title":"\u524d\u8a00"},{"location":"stl_map/#_2","text":"\ud83d\ude00\ud83d\ude00\ud83d\ude00 \u9762\u5411\u5df2\u7ecf\u4e86\u89e3\u4e00\u5b9a C++ \u8bed\u6cd5\uff0c\u6b63\u5728\u5b66\u4e60\u6807\u51c6\u5e93\u7684\u7ae5\u978b\u3002 C++ \u6807\u51c6\u5e93\u53c8\u79f0 STL\uff0c\u5305\u542b\u4e86\u5927\u91cf\u7a0b\u5e8f\u5458\u5e38\u7528\u7684\u7b97\u6cd5\u548c\u6570\u636e\u7ed3\u6784\uff0c\u662f Bjarne Stroustrup \u9001\u7ed9\u6240\u6709 C++ \u7a0b\u5e8f\u5458\u7684\u4e00\u628a\u745e\u58eb\u519b\u5200\uff0c\u7136\u800c\u53d1\u73b0\u5f88\u591a\u7ae5\u978b\u5e76\u6ca1\u6709\u5b8c\u5168\u7528\u597d\u4ed6\uff0c\u53cd\u800c\u8fd8\u88ab\u5176\u590d\u6742\u6027\u8bef\u4f24\u4e86\u3002 \u5982\u679c\u4f60\u4e5f\u5bf9\u6807\u51c6\u5e93\u4e00\u77e5\u534a\u89e3\uff0c\u9700\u8981\u7cfb\u7edf\u5b66\u4e60\u7684\u8bdd\uff0c\u90a3\u4e48\u672c\u8bfe\u7a0b\u9002\u5408\u4f60\u3002\u5c0f\u5f6d\u8001\u5e08\u5c06\u8fd0\u7528\u4ed6\u7279\u6709\u7684\u5e7d\u9ed8\u7b54\u8fa9\u6bd4\u55bb\uff0c\u5168\u9762\u4ecb\u7ecd\u5404 STL \u5bb9\u5668\u7684\u6240\u6709\u7528\u6cd5\u3002\u7ed3\u5408\u4e00\u7cfb\u5217\u5b9e\u6218\u6848\u4f8b\uff0c\u5256\u6790\u5e38\u89c1\u5751\u70b9\uff0c\u4f7f\u7528\u6280\u5de7\u7b49\u3002\u5bf9\u6bd4\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u4e0e\u53ef\u8bfb\u6027\uff0c\u8fd8\u4f1a\u4e0e Python \u8bed\u8a00\u76f8\u4e92\u7c7b\u6bd4\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u79d1\u666e\u7684\u90e8\u5206\u51b7\u77e5\u8bc6\u53ef\u4ee5\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u52a0\u5206\u9879\u3002 \u672c\u8bfe\u7a0b\u53d7\u5230\u7ae5\u978b\u4e00\u81f4\u597d\u8bc4","title":"\u8bfe\u7a0b\u7b80\u4ecb"},{"location":"stl_map/#_3","text":"\ud83d\udc4d\ud83d\udc4d\ud83d\udc4d \u672c\u7cfb\u5217\u8bfe\u7a0b\u4e0e\u300a\u4faf\u6770\u8001\u5e08 STL \u8bfe\u300b\u7684\u533a\u522b\uff1a \u4faf\u6770\u8001\u5e08\u4ef7\u503c 2650 \u5143\uff0c\u672c\u8bfe\u7a0b\u5f55\u64ad\u4e0a\u4f20 B \u7ad9\u514d\u8d39\u89c2\u770b\uff0c\u89c2\u4f17\u53ef\u4ee5\u81ea\u884c\u9009\u62e9\u662f\u5426\u4e00\u952e\u4e09\u8fde\u3002 \u8bfe\u4ef6\u548c\u6848\u4f8b\u6e90\u7801\u5f00\u6e90\uff0c\u4e0a\u4f20\u5728 GitHub\uff0c\u53ef\u4ee5\u81ea\u5df1\u4e0b\u8f7d\u6765\u505a\u4fee\u6539\uff0c\u7136\u540e\u81ea\u5df1\u52a8\u624b\u5b9e\u9a8c\uff0c\u52a0\u6df1\u7406\u89e3\u3002 \u4faf\u6770\u8001\u5e08\u6ce8\u91cd\u7406\u8bba\u548c\u5e95\u5c42\u5b9e\u73b0\u539f\u7406\uff0c\u800c\u672c\u8bfe\u7a0b\u6ce8\u91cd\u5e94\u7528\uff0c\u7ed3\u5408\u5b9e\u6218\u6848\u4f8b\uff0c\u7740\u91cd\u5c55\u5f00\u91cd\u96be\u70b9\uff0c\u5751\u70b9\u7b49\u3002 \u5f88\u591a\u5b66\u6821\u91cc\u6559\u7684\uff0c\u767e\u5ea6\u4e0a\u641c\u7684\uff0c\u5927\u591a\u662f\u8001\u7248\u672c C++\uff0c\u5df2\u7ecf\u8fc7\u65f6\uff0c\u800c\u672c\u8bfe\u7a0b\u57fa\u4e8e\u8f83\u65b0\u7684 C++17 \u548c C++20 \u6807\u51c6\u3002 \u6709\u65f6\u5b58\u5728\u90e8\u5206 C++ \u9ad8\u7ea7\u7528\u6cd5\u8fc7\u4e8e\u8270\u6df1\uff0c\u4e0d\u80fd\u9002\u5408\u6240\u6709\u540c\u5b66\uff0c\u672c\u8bfe\u7a0b\u91c7\u7528\u56e0\u6750\u65bd\u6559\u601d\u60f3\uff1a\u5bf9\u4e8e\u65b0\u624b\uff0c\u53ef\u4ee5\u8df3\u8fc7\u770b\u4e0d\u61c2\u7684\u90e8\u5206\uff0c\u770b\u6211\u63d0\u4f9b\u7684\u201c\u4fdd\u5e95\u7528\u6cd5\u201d\uff0c\u4e0d\u4fdd\u8bc1\u9ad8\u6027\u80fd\u548c\u201c\u4f18\u96c5\u201d\uff0c\u4f46\u81f3\u5c11\u80fd\u7528\uff1b\u5bf9\u5b66\u6709\u4f59\u529b\u7684\u7ae5\u978b\uff0c\u5219\u53ef\u4ee5\u640f\u4e00\u640f\u4e0a\u9650\uff0c\u628a\u9ad8\u7ea7\u7528\u6cd5\u4e5f\u770b\u61c2\uff0c\u63d0\u5347\u9762\u8bd5\u7ade\u4e89\u529b\u3002\u603b\u4e4b\u4e0d\u8bba\u4f60\u662f\u54ea\u4e2a\u9636\u6bb5\u7684\u5b66\u4e60\u8005\uff0c\u90fd\u80fd\u4ece\u6b64\u8bfe\u7a0b\u4e2d\u83b7\u76ca\u3002","title":"\u8bfe\u7a0b\u4eae\u70b9"},{"location":"stl_map/#_4","text":"\u2728\u2728\u2728 \u4e4b\u524d\u51e0\u671f\u8bfe\u7a0b\u7684\u5f55\u64ad\u5df2\u7ecf\u4e0a\u4f20\u5230\u6bd4\u7ad9\u4e86 1 \u3002 vector \u5bb9\u5668\u521d\u4f53\u9a8c & \u8fed\u4ee3\u5668\u5165\u95e8 (BV1qF411T7sd) \u4f60\u6240\u4e0d\u77e5\u9053\u7684 set \u5bb9\u5668 & \u8fed\u4ee3\u5668\u5206\u7c7b (BV1m34y157wb) string\uff0cstring_view\uff0cconst char * \u7684\u7231\u6068\u7ea0\u845b (BV1ja411M7Di) \u4e07\u80fd\u7684 map \u5bb9\u5668\u5168\u5bb6\u6876\u53ca\u5176\u5999\u7528\u4e3e\u4f8b (\u672c\u671f) \u51fd\u5b50 functor \u4e0e lambda \u8868\u8fbe\u5f0f\u77e5\u591a\u5c11 \u901a\u8fc7\u5b9e\u6218\u6848\u4f8b\u6765\u5b66\u4e60 STL \u7b97\u6cd5\u5e93 C++ \u6807\u51c6\u8f93\u5165\u8f93\u51fa\u6d41 & \u5b57\u7b26\u4e32\u683c\u5f0f\u5316 traits \u6280\u672f\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u8fed\u4ee3\u5668\u4e0e\u7b97\u6cd5 allocator\uff0c\u5185\u5b58\u7ba1\u7406\u4e0e\u5bf9\u8c61\u751f\u547d\u5468\u671f C++ \u5f02\u5e38\u5904\u7406\u673a\u5236\u7684\u524d\u4e16\u4eca\u751f","title":"\u8bfe\u7a0b\u5927\u7eb2"},{"location":"stl_map/#_5","text":"\u2705\u2705\u2705 \u5c0f\u5f6d\u8001\u5e08\u4e2a\u4eba\u63a8\u8350\u5b9e\u9a8c\u73af\u5883\u5982\u4e0b\uff1a \u8981\u6c42 \u2764\u2764\u2764 \ud83d\udca3\ud83d\udca3\ud83d\udca3 \ud83d\udca9\ud83d\udca9\ud83d\udca9 \ud83d\udc80\ud83d\udc80\ud83d\udc80 \u64cd\u4f5c\u7cfb\u7edf Arch Linux Ubuntu 20.04 Wendous 10 Maike OS \u77e5\u8bc6\u50a8\u5907 \u4f1a\u4e00\u70b9 C++ \u5927\u5b66 C \u8bed\u8a00 Java \u9762\u5411\u5bf9\u8c61 \u7f16\u7a0b\u5c0f\u767d \u7f16\u8bd1\u5668 GCC 9 \u4ee5\u4e0a Clang 12 VS2019 Apple Clang \u6784\u5efa\u7cfb\u7edf CMake 3.18 \u4efb\u610f C++ IDE \u5355\u6587\u4ef6\u7f16\u8bd1\u8fd0\u884c \u547d\u4ee4\u884c\u624b\u52a8\u7f16\u8bd1 \u7f16\u8f91\u5668 Vim/NeoVim CLion VS Code notepad \u6e38\u620f\u96be\u5ea6\uff1a\u2764 = \u7b80\u5355\uff0c\ud83d\udca3 = \u666e\u901a\uff0c\ud83d\udca9 = \u56f0\u96be\uff0c\ud83d\udc80 = \u5730\u72f1\u526f\u672c","title":"\u5b9e\u9a8c\u73af\u5883"},{"location":"stl_map/#_6","text":"\ud83e\udd70\ud83e\udd70\ud83e\udd70 \u672c\u671f\u5b9e\u9a8c\u6e90\u7801\u5747\u516c\u5e03\u5728\uff1ahttps://github.com/parallel101/course/tree/master/slides/stl_map/experiment/ \u4f8b\u5982\u672c\u671f\u7684\u8bfe\u4ef6\u4f4d\u4e8e course/stlseries/stl_map/slides.md \u3002 \u8bfe\u4ef6\u57fa\u4e8e Mkdocs \u5f00\u53d1\uff0cMarkdown \u683c\u5f0f\u4e66\u5199\uff0c\u5728\u6d4f\u89c8\u5668\u4e2d\u663e\u793a\uff0c\u5728\u672c\u5730\u8fd0\u884c\u8bfe\u4ef6\u9700\u8981 Mkdocs \u73af\u5883\uff1a \u8fd0\u884c\u547d\u4ee4 pip install -r requirements.txt \u5373\u53ef\u81ea\u52a8\u5b89\u88c5 Mkdocs \u7b49\u6240\u9700\u4f9d\u8d56 \u8fd0\u884c\u547d\u4ee4 mkdocs serve \u5373\u53ef\u8fd0\u884c Mkdocs \u670d\u52a1 \u6d4f\u89c8\u5668\u8bbf\u95ee http://127.0.0.1:8000 \u5373\u53ef\u770b\u5230\u8bfe\u4ef6 \u5982\u679c\u4e0d\u60f3\u81ea\u5df1\u914d\u7f6e Mkdocs \u4e5f\u53ef\u4ee5\u76f4\u63a5\u4ee5\u6587\u672c\u6587\u4ef6\u683c\u5f0f\u6253\u5f00 docs/stl_map.md \u6d4f\u89c8\u8bfe\u4ef6\u3002 Mkdocs \u670d\u52a1\u8fd0\u884c\u65f6\uff0c\u4f60\u5bf9 docs/stl_map.md \u7684\u6240\u6709\u4fee\u6539\u4f1a\u7acb\u523b\u5b9e\u65f6\u663e\u73b0\u5728\u6d4f\u89c8\u5668\u4e2d\u3002","title":"\u5982\u4f55\u4f7f\u7528\u8bfe\u4ef6"},{"location":"stl_map/#_7","text":"\ud83e\udd7a\ud83e\udd7a\ud83e\udd7a \u6848\u4f8b\u6e90\u7801\u548c\u6240\u9700\u5934\u6587\u4ef6\u4f4d\u4e8e\u8bfe\u4ef6\u540c\u76ee\u5f55\u7684 course/stlseries/stl_map/experiment/ \u6587\u4ef6\u5939\u4e0b\u3002 \u5176\u4e2d main.cpp \u4ec5\u5bfc\u5165\u8fd0\u884c\u6848\u4f8b\u6240\u9700\u7684\u5934\u6587\u4ef6\uff0c\u5177\u4f53\u5404\u4e2a\u6848\u4f8b\u4ee3\u7801\u5206\u5e03\u5728 slides.md \u91cc\u3002 \u5982\u9700\u6d4b\u8bd5\u8bfe\u4ef6\u4e2d\u7684\u5177\u4f53\u4ee3\u7801\uff0c\u53ef\u4ee5\u628a slides.md \u4e2d\u7684\u6848\u4f8b\u4ee3\u7801\u7c98\u8d34\u5230 main.cpp \u7684 main \u51fd\u6570\u4f53\u4e2d\u8fdb\u884c\u5b9e\u9a8c\u3002 \u6b64\u5916\u4e3a\u4e86\u65b9\u4fbf\uff0c\u8fd8\u6709\u4e00\u4e9b\u5f62\u5982 testxxx.cpp \u7684\u6587\u4ef6\u662f\u4e00\u4e9b\u5b8c\u6574\u7684\u6d4b\u8bd5\u6848\u4f8b\uff0c\u4e0d\u7528\u4ece slides.md \u4e2d\u62f7\u8d1d\uff0c\u53ef\u76f4\u63a5\u5355\u72ec\u8fd0\u884c\u3002 \u4e3a\u4e86\u65b9\u4fbf\u540c\u5b66\u4eec\u5b9e\u9a8c\uff0c\u6240\u9700\u5934\u6587\u4ef6\u90fd\u5728\u540c\u4e00\u4e2a\u76ee\u5f55\uff0c\u6ca1\u6709\u7b2c\u4e09\u65b9\u5e93\u4f9d\u8d56\u3002\u65e2\u53ef\u4ee5\u7528 CMake \u6784\u5efa\uff0c\u4e5f\u53ef\u4ee5\u7528\u4efb\u610f\u81ea\u5df1\u559c\u6b22\u7684 IDE \u6216\u7f16\u8f91\u5668 \u5355\u6587\u4ef6\u7f16\u8bd1 \u8fd0\u884c\uff0c\u65e0\u5f3a\u5236\u8981\u6c42\uff0c\u53ea\u9700\u7f16\u8bd1\u5668\u652f\u6301 C++17 \u5373\u53ef\u3002 \u5982\u679c\u4f60\u7528 Visual Studio \u81ea\u5df1\u7684 sln \u7cfb\u7edf\u6784\u5efa\u9879\u76ee\uff0c\u8bb0\u5f97\u5f00\u542f /std:c++17 \u9009\u9879\u3002\u5982\u679c\u4f60\u7528\u6700\u65b0\u7684 Visual Studio\uff08\u5df2\u7ecf\u652f\u6301 CMake\uff09\u5219\u76f4\u63a5\u9009\u62e9\u201c\u6253\u5f00\u6587\u4ef6\u5939\u201d\u6253\u5f00\u672c\u9879\u76ee\u7684 experiment \u76ee\u5f55\u5373\u53ef\u3002 \u5728\u5b9e\u9a8c\u6e90\u7801\u4ed3\u5e93\u4e2d\uff0c\u9644\u8d60\u4e86\u4e00\u4e9b\u5b9e\u7528\u5934\u6587\u4ef6\uff0c\u540c\u978b\u4eec\u53ef\u4ee5\u4e0b\u8f7d\u6765\u7814\u7a76\uff0c\u6216\u8005\u5728\u81ea\u5df1\u7684\u9879\u76ee\u91cc\u968f\u610f\u8fd0\u7528\u3002 \u6587\u4ef6\u540d \u529f\u80fd print.h \u5185\u542b print \u51fd\u6570\uff0c\u652f\u6301\u6253\u5370\u7edd\u5927\u591a\u6570 STL \u5bb9\u5668\uff0c\u65b9\u4fbf\u8c03\u8bd5 map_get.h \u5e26\u9ed8\u8ba4\u503c\u7684 map \u8868\u9879\u67e5\u8be2\uff0c\u7a0d\u540e\u8bfe\u7a0b\u4e2d\u4f1a\u4ecb\u7ecd\u5230 ScopeProfiler.h \u57fa\u4e8e RAII \u7684\u51fd\u6570\u8017\u65f6\u7edf\u8ba1\uff0c\u7528\u4e8e\u6d4b\u91cf\u6027\u80fd OrderedMap.h \u904d\u5386\u987a\u5e8f\u59cb\u7ec8\u4fdd\u6301\u548c\u63d2\u5165\u987a\u5e8f\u4e00\u81f4\u7684\u9b54\u6539\u7248 map cppdemangle.h \u83b7\u5f97\u7c7b\u578b\u7684\u540d\u5b57\uff0c\u4ee5\u6a21\u677f\u53c2\u6570\u4f20\u5165\uff0c\u8be6\u89c1\u8be5\u6587\u4ef6\u4e2d\u7684\u6ce8\u91ca hash.h \u6bd4 std::hash \u66f4\u901a\u7528\u7684 generic_hash \u5b9e\u73b0\uff0c\u652f\u6301\u4efb\u610f\u533a\u95f4\u548c\u5143\u7ec4 bits_stdc++.h \u4eff\u7167 bits/stdc++.h \u7684\u4e07\u80fd\u5934\u6587\u4ef6\u8de8\u5e73\u53f0\u7248\uff0c\u4e00\u6b21\u6027\u5bfc\u5165\u6240\u6709\u5e93","title":"\u5982\u4f55\u8fd0\u884c\u6848\u4f8b\u4ee3\u7801"},{"location":"stl_map/#_8","text":"int const &i // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef const int& i // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef template // \u672c\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef template // \u5b98\u65b9\u6587\u6863\u4e66\u5199\u4e60\u60ef \u4ec5\u4e3a\u4e2a\u4eba\u4e66\u5199\u4e60\u60ef\u4e0d\u540c\uff0c\u5728 C++ \u7f16\u8bd1\u5668\u770b\u6765\u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u6211\u559c\u6b22\u628a const \u540e\u7f6e\uff0c\u5176\u4e00\u662f\u56e0\u4e3a\u8fd9\u6709\u5229\u4e8e\u7406\u89e3 int const * \u548c int *const \u7684\u533a\u522b\uff0c\u5982\u679c\u5199\u6210 const int * \u5c31\u4f1a\u5f88\u56f0\u60d1 const \u7a76\u7adf\u662f\u4fee\u9970\u8c01\u7684\uff0c\u800c\u7528\u6211\u7684\u5199\u6cd5\u53ea\u9700\u8981\u7b80\u5355\u7406\u89e3\u4e3a \u201cconst \u53ea\u4fee\u9970\u4ed6\u524d\u9762\u7684\u201d\u3002\u5176\u4e8c\u6211\u7ecf\u5e38\u9700\u8981\u628a\u51fd\u6570\u53c2\u6570\u4e2d T t \u4fee\u6539\u6210 T const &t \u3002\u8fde\u5728\u4e00\u8d77\u52a0\u8d77\u6765\u6bd4\u8f83\u65b9\u4fbf\uff0c\u53ea\u9700\u8981\u4e00\u6b21\u6027\u63d2\u5165 const & \u5373\u53ef\uff0c\u4e0d\u7528\u524d\u540e\u4e24\u4e2a\u5730\u65b9\u5206\u522b\u52a0 const \u548c & \uff0c\u4f60\u89c9\u5f97\u5462\uff1f using namespace std; // \u4ec5\u4e3a\u6559\u5b66\u65b9\u4fbf\u76ee\u7684\uff0c\u4e0d\u5efa\u8bae\u5728\u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4f7f\u7528 \u26a0\ufe0f \u7531\u4e8e\u4f7f\u7528\u4e86 using namespace std \uff0c\u672c\u8bfe\u7a0b\u4ee3\u7801\u4e2d\u7684 std:: \u524d\u7f00\u5747\u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a map> m; erase_if(m, pred); \u73b0\u5b9e\u5de5\u7a0b\u4e2d\u4e0d\u5efa\u8bae using namespace std \uff0c\u8bf7\u663e\u5f0f\u5199\u51fa std:: \u524d\u7f00\uff1a std::map> m; std::erase_if(m, pred); \u6211\u4eec\u81ea\u5df1\u505a\u6d4b\u8bd5\u65f6\u7ecf\u5e38\u4f1a\u7528 \u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u3002 \u53ef\u60dc\u8fd9\u4e2a\u4e07\u80fd\u5934\u6587\u4ef6\u5728 VS \u4e2d\u4f3c\u4e4e\u4e0d\u5b58\u5728 1 \uff0c\u56e0\u6b64\u6211\u81ea\u5df1\u5199\u4e86\u4e00\u4e2a\u8de8\u5e73\u53f0\u7684 \"bits_stdc++.h\" \u653e\u5728\u6e90\u7801\u540c\u76ee\u5f55\uff1a #include \"bits_stdc++.h\" // \u81ea\u52a8\u5bfc\u5165\u6240\u6709\u6807\u51c6\u5e93\u7684\u5934\u6587\u4ef6 \u4e0d\u8fc7\u73b0\u5b9e\u5de5\u7a0b\u4e2d\uff0c\u8fd8\u662f\u5efa\u8bae\u6839\u636e\u9700\u8981\u4e00\u4e2a\u4e2a\u5bfc\u5165\uff0c\u4e0d\u8981\u5077\u61d2\u7528\u8fd9\u4e2a\u4e0d\u6807\u51c6\u7684\u5934\u6587\u4ef6\uff1a #include // \u5bfc\u5165 std::map, std::multimap #include // \u5bfc\u5165 std::unordered_map, std::unordered_multimap #include // \u5bfc\u5165 std::string, std::wstring #include // \u5bfc\u5165 std::set_difference, std::set_union, std::set_intersection \u7b49\u4e00\u7cfb\u5217\u5168\u5c40\u51fd\u6570 // \u4e0b\u9762\u4ee3\u7801\u4e2d\u7528\u5230\u54ea\u4e9b\u5bb9\u5668\uff0c\u5c31\u5bfc\u5165\u54ea\u4e9b\u5934\u6587\u4ef6","title":"\u8bfe\u7a0b\u4e66\u5199\u4e60\u60ef\u8bf4\u660e"},{"location":"stl_map/#_9","text":"","title":"\u4ec0\u4e48\u662f\u7b97\u6cd5\u590d\u6742\u5ea6"},{"location":"stl_map/#_10","text":"\u6709\u4e00\u6b21\u4e00\u4e2a\u540c\u5b66\u53d1\u7ed9\u6211\u4e00\u4efd\u6e90\u7801\u6587\u4ef6 tetreader.py\uff0c\u5176\u529f\u80fd\u662f\u8bfb\u53d6\u4e00\u4e2a tet \u683c\u5f0f\u7684\u6587\u4ef6\uff08\u56db\u9762\u4f53\u7f51\u683c\u6a21\u578b\uff09\u3002 \u4ed6\u95ee\u6211\u4e3a\u4ec0\u4e48\u4ed6\u5199\u7684\u8fd9\u4e2a Python \u4ee3\u7801\u8fd9\u4e48\u6162\uff0c\u8bfb\u53d6\u4e00\u4e2a\u7a0d\u5fae\u5927\u4e00\u70b9\u7684\u6a21\u578b\u5c31\u9700\u8981\u597d\u51e0\u79d2\uff0c\u4ed6\u8bf4\u4e45\u4ef0\u5c0f\u5f6d\u8001\u5e08\u6027\u80fd\u4f18\u5316\u7684\u5927\u540d\uff0c\u60f3\u8981\u6211\u5e2e\u4ed6\u4f18\u5316\u4e00\u4e0b\uff0c\u8fd8\u95ee\u662f\u4e0d\u662f\u5e94\u8be5\u7528 C++ \u5199\u4f1a\u6bd4\u8f83\u9ad8\u6548\u4e00\u70b9\uff1f \u6211\u5e76\u4e0d\u61c2\u5f97\u56db\u9762\u4f53\uff0c\u4f46\u6027\u80fd\u4f18\u5316\u7684\u601d\u8def\u662f\u901a\u7528\u7684\u3002\u6211\u6253\u5f00\u6587\u4ef6\u770b\u4e86\u4e00\u4e0b\uff0c\u6211\u53d1\u73b0\u4ed6\u8bfb\u53d6\u65f6\u9700\u8981\u67e5\u8be2\u4e00\u4e2a\u70b9\u5468\u56f4\u6240\u6709\u7684\u9762\uff0c\u4ed6\u662f\u8fd9\u6837\u67e5\u8be2\u7684\uff1a # \u4ee5\u4e0b\u4e3a\u4ed6\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = [] for ... in ...: face_lut.append(vert_id) # O(1) \u2705 for ... in ...: face_id = face_lut.index(vert_id) # O(N) \u26a0\ufe0f \u6211\u8bf4\u4f60\u8fd9\u4e2a face_lut \u662f\u4e2a\u666e\u901a\u6570\u7ec4\uff0c\u6570\u7ec4\u7684 index \u51fd\u6570\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u4f60\u4e0d\u77e5\u9053\u5417\uff1f\u4ed6\u76f8\u5f53\u4e8e\u66b4\u529b\u904d\u5386\u4e86\u6570\u7ec4\u627e\u5230\u4f60\u9700\u8981\u7684\u503c\uff0c\u4f60\u8fd9\u4e2a index \u7684\u8c03\u7528\u8fd8\u662f\u5728\u4e00\u4e2a\u5faa\u73af\u91cc\u7684\uff0c\u6240\u4ee5\u662f O(N^2) O(N^2) \u590d\u6742\u5ea6\uff01\u96be\u602a\u8fd9\u4e48\u6162\u4e86\u3002 \u540e\u6765\u6211\u7ed9\u4ed6\u6539\u4e86\u4e00\u4e0b\uff0c\u628a\u4ed6\u7684 face_lut \u6539\u6210\u5b57\u5178\uff0c\u7528\u5b57\u5178\u67e5\u627e\uff0c\u9ad8\u6548\u5f97\u591a\u4e86\uff1a # \u4ee5\u4e0b\u4e3a\u6211\u4f18\u5316\u540e\u7684\u5927\u81f4\u4f2a\u4ee3\u7801 face_lut = {} for ... in ...: face_lut[vert_id] = face_id # O(1)+ \u2705 for ... in ...: face_id = face_lut[vert_id] # O(1)+ \u2705 \u4e00\u6b21\u5b57\u5178\u7684\u67e5\u8be2\u53ea\u9700\u8981 O(1)+ O(1)+ \uff0c\u52a0\u4e0a\u4ed6\u5916\u9762\u7684\u5faa\u73af\u603b\u5171\u53ea\u6709 O(N) O(N) \uff0c\u53d8\u6210\u7ebf\u6027\u590d\u6742\u5ea6\u4e86\u3002\u4ed6\u4e00\u8bd5\uff0c\u679c\u7136\u51e0\u6beb\u79d2\u5c31\u52a0\u8f7d\u5b8c\u4e86\uff0c\u6211\u8bf4\u7528\u5b57\u5178\u52a0\u901f\u67e5\u627e\u8fd9\u4e0d\u662f\u5e38\u8bc6\u5417\uff1f\u8fd8\u6401\u7740 C++ \u5462\uff1f\u4f60\u5c31\u662f CUDA \u6765\u4e86\u4e5f\u538b\u4e0d\u4f4f\u590d\u6742\u5ea6\u7684\u7206\u8868\u5440\uff1f \u4ed6\u5f88\u9ad8\u5174\uff0c\u4e0d\u77e5\u9053\u600e\u4e48\u611f\u8c22\u6211\uff0c\u4e8e\u662f\u5c31\u628a\u6211\u63a8\u8350\u7ed9\u5f20\u5fc3\u6b23\u4e86\u3002","title":"\u5173\u4e8e\u7b97\u6cd5\u590d\u6742\u5ea6\uff0c\u4e00\u4e2a\u771f\u5b9e\u7684\u5c0f\u6545\u4e8b"},{"location":"stl_map/#_11","text":"\u4e0d\u8bba\u4ec0\u4e48\u8bed\u8a00\uff0c\u5bb9\u5668\uff08\u6216\u8005\u7528\u5b66\u6821\u91cc\u7684\u8bdd\u8bf4\uff1a\u6570\u636e\u7ed3\u6784\uff09\u7684\u6b63\u786e\u4f7f\u7528\uff0c\u80fd\u591f\u5728\u590d\u6742\u5ea6\u5c42\u9762\u4e0a\uff0c\u5927\u5e45\u63d0\u5347\u6027\u80fd\u3002 C++ \u4e2d\u4e5f\u662f\u5982\u6b64\uff0c\u6709\u6570\u7ec4\uff08vector\uff09\uff0c\u5b57\u5178\uff08map\uff09\uff0c\u8fd8\u6709\u4e0a\u4e00\u8bfe\u8bb2\u8fc7\u7684\u96c6\u5408\uff08set\uff09\u3002 \u4eca\u5929\u6211\u4eec\u8981\u4ecb\u7ecd\u7684\u5c31\u662f C++ \u7684\u5b57\u5178\u5bb9\u5668 map\uff0c\u4ee5\u53ca C++11 \u5f15\u5165\u7684\u53e6\u4e00\u4e2a\u5b57\u5178\u5bb9\u5668 unordered_map\uff0c\u4ed6\u4eec\u7684\u533a\u522b\u6211\u4eec\u6700\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u3002\u6211\u4eec\u5148\u5b66\u4e60\u8f83\u4e3a\u7b80\u5355\u7684 map\uff0c\u968f\u540e\u5b66\u4e60 unordered_map \u65f6\u4e5f\u53ef\u4ee5\u4e3e\u4e00\u53cd\u4e09\u3001\u878d\u4f1a\u8d2f\u901a\u3002 \u4ecb\u7ecd\u5b8c\u8fd9\u4e24\u4e2a\u6807\u51c6\u5e93\u81ea\u5e26\u7684\u5b57\u5178\u5bb9\u5668\u540e\uff0c\u6211\u4eec\u8fd8\u5c06\u4ecb\u7ecd\u4e00\u4e9b\u5e38\u7528\u7684\u7b2c\u4e09\u65b9\u5e93\u5bb9\u5668\uff0c\u4f8b\u5982 absl::flat_hash_map\u3001tbb::concurrent_hash_map\u3001google::dense_hash_map\u3001robin_hood::unordered_map\u3001tsl::robin_pg_map \u7b49\uff0c\u9700\u8981\u6839\u636e\u5e94\u7528\u573a\u666f\u9009\u62e9\u9002\u5408\u7684\u5bb9\u5668\u3002 map/set \u5bb6\u65cf\u90fd\u662f\u9ad8\u6548\u67e5\u627e\u7684\u4e13\u5bb6\uff1a vector \u5bb9\u5668\u7528 std::find \u67e5\u627e\uff1a O(N) O(N) map \u6216 set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(\\log N) O(\\log N) unordered_map \u6216 unordered_set \u5bb9\u5668\u7528 .find \u67e5\u627e\uff1a O(1)+ O(1)+ \u4e0d\u4ec5\u662f\u67e5\u627e\uff0cmap \u4eec\u8fd8\u652f\u6301\u9ad8\u6548\u7684\u589e\u5220\u6539\u67e5\u7b49\u64cd\u4f5c\u3002","title":"\u6570\u636e\u7ed3\u6784\u4e0e\u590d\u6742\u5ea6"},{"location":"stl_map/#map","text":"\u7279\u70b9\uff1a \u7531\u4e00\u7cfb\u5217 \u952e\u503c\u5bf9 \u7ec4\u6210 \u4e00\u4e2a\u952e\u53ea\u80fd\u5bf9\u5e94\u4e00\u4e2a\u503c \u952e\u4e0d\u5f97\u91cd\u590d\uff0c\u503c\u53ef\u4ee5\u91cd\u590d std::map, std::unordered_map, absl::flat_hash_map, tbb::concurrent_hash_map \u90fd\u6ee1\u8db3\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u4e00\u57fa\u672c\u903b\u8f91\u7ed3\u6784\uff0c\u53ea\u662f\u7269\u7406\u5b9e\u73b0\u4e0d\u540c\u3002 \u9762\u58c1\u8005\u7f57\u8f91\u76d1\u7763\u4f60\u7684\u5b66\u4e60\uff01 \u5728\u7f16\u7a0b\u4e2d\u6211\u4eec\u5e38\u5e38\u9700\u8981\u7528\u5230\u201c\u6620\u5c04\u201d\u7684\u5173\u7cfb\uff0c\u8fd9\u5c31\u975e\u5e38\u9700\u8981\u7528\u5230\u4ee5 map \u4e3a\u9996\u7684\u201c\u952e\u503c\u5bf9\u201d\u8fd9\u7c7b\u5bb9\u5668\u4e86\u3002","title":"map \u7684\u903b\u8f91\u7ed3\u6784"},{"location":"stl_map/#stdmap","text":"map \u7684\u5177\u4f53\u5b9e\u73b0\u53ef\u4ee5\u662f\u7ea2\u9ed1\u6811\u3001AVL \u6811\u3001\u7ebf\u6027\u54c8\u5e0c\u8868\u3001\u94fe\u8868\u54c8\u5e0c\u8868\u3001\u8df3\u8868\u2026\u2026\u4e0d\u540c\u7684\u5b9e\u73b0\u5728\u4e0d\u540c\u64cd\u4f5c\u4e0a\u7684\u590d\u6742\u5ea6\u4e0d\u540c\uff0c\u5206\u522b\u9002\u7528\u4e8e\u4e0d\u540c\u7684\u573a\u666f\u3002 \u7528\u6cd5\u4e0a\u51e0\u4e4e\u662f\u5dee\u4e0d\u591a\u7684\uff0c\u4ed6\u4eec\u90fd\u6709\u7740\u51e0\u4e4e\u76f8\u540c\u7684\u63a5\u53e3\uff08\u9664\u4e86\u90e8\u5206\u6269\u5c55\u529f\u80fd\uff09\u3002\u5f53\u4f60\u89c9\u5f97\u7ea2\u9ed1\u6811\u7684 std::map \u4e0d\u5408\u9002\u65f6\uff0c\u53ef\u4ee5\u8f7b\u677e\u628a\u5bf9\u8c61\u7c7b\u578b\u5c31\u5730\u66ff\u6362\u4e3a\u94fe\u8868\u54c8\u5e0c\u8868 std::unordered_map \u6216\u662f\u662f\u7ebf\u6027\u54c8\u5e0c\u8868 absl::flat_hash_map\uff0c\u800c\u4e0d\u7528\u5bf9\u5176\u4ed6\u4ee3\u7801\u6709\u4efb\u4f55\u66f4\u6539\u3002 \u8fd9\u5c31\u662f\u6240\u6709 map \u7c7b\u5bb9\u5668\u90fd\u6709\u7740\u76f8\u540c\u7684 \u903b\u8f91\u7ed3\u6784 \uff1a\u90fd\u662f\u4e00\u4e2a\u952e-\u503c\u6620\u5c04\uff0c\u4e0d\u540c\u7684\u53ea\u662f\u4ed6\u4eec\u7684 \u7269\u7406\u7ed3\u6784 \u800c\u5df2\u3002 \u6240\u6709\u7684 map \u5b9e\u73b0\uff0c\u90fd\u4f1a\u6a21\u4eff\u63d0\u4f9b\u548c std::map \u4e00\u6837\u7684 API\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u867d\u7136 std::map \u5b9e\u73b0\u7684\u5f88\u4f4e\u6548\uff0c\u6211\u4eec\u8fd8\u662f\u8981\u5b66\u4ed6\u7684\u539f\u56e0\u3002std::map \u672c\u8eab\u5e76\u4e0d\u662f\u5b8c\u7f8e\u7684\uff0c\u4f46\u5374\u63d0\u4f9b\u4e86\u4e00\u4e2a\u6240\u6709\u7b2c\u4e09\u65b9\u90fd\u4f1a\u9075\u5faa\u7684\u7edf\u4e00\u63a5\u53e3\u3002\u5b66\u4f1a\u4e86 std::map\uff0c\u4efb\u4f55\u7b2c\u4e09\u65b9\u5e93\u7684 map \u7c7b\u5bb9\u5668\u4f60\u90fd\u53ef\u4ee5\u8f7b\u6613\u4e3e\u4e00\u53cd\u4e09\u3002 \u4e0d\u4ec5\u662f\u5404\u79cd\u7b2c\u4e09\u65b9\u7684 map \u5e93\uff0c\u6bd4\u5982 rapidjson \u5e93\u4e2d\u7684 JSON \u5bf9\u8c61\uff0c\u4e5f\u63d0\u4f9b\u4e86\u7c7b\u4f3c std::map \u7684 find \u548c end \u8fed\u4ee3\u5668\u63a5\u53e3\uff1a MemberFind \u548c MemberEnd \uff0c\u6765\u67e5\u627e\u4e00\u4e2a\u5b57\u5178\u7684\u5b50\u952e\uff1b\u51e0\u4f55\u5904\u7406\u5e93 cgal \u4e2d\u7684\u201c\u9876\u70b9\u67e5\u627e\u201d\u529f\u80fd\u4e5f\u662f\u57fa\u4e8e\u7c7b\u4f3c\u7684\u8fed\u4ee3\u5668\u63a5\u53e3\u3002\u603b\u4e4b\uff0c\u5b66\u4f1a std::map \u5c06\u5927\u5927\u6709\u52a9\u4e8e\u4f60\u770b\u61c2\u8fd9\u7c7b\u4e1a\u754c\u516c\u8ba4\u7684\u63a5\u53e3\u89c4\u8303\u3002","title":"\u4e3a\u4ec0\u4e48\u8981\u5b66\u4e60 std::map"},{"location":"stl_map/#map_1","text":"\u6807\u51c6\u5e93\u4e2d\uff0cmap 1 \u662f\u4e00\u4e2a \u6a21\u677f\u7c7b \uff0c\u4ed6\u7684\u952e\u7c7b\u578b\uff0c\u503c\u7c7b\u578b\uff0c\u53ef\u4ee5\u7531\u5c16\u62ec\u53f7\u5185\u7684\u53c2\u6570\u6307\u5b9a\uff0c\u4fbf\u4e8e\u9002\u5e94\u4e0d\u540c\u7684\u7528\u6237\u9700\u6c42\u3002 \u7531\u4e8e C++ \u6807\u51c6\u5e93\u7684\u5bb9\u5668\u5927\u591a\u90fd\u662f\u6a21\u677f\u7c7b\uff0c\u63d0\u4f9b\u7684\u7b97\u6cd5\u4e5f\u5927\u591a\u662f\u6a21\u677f\u51fd\u6570\uff0c\u56e0\u6b64 C++ \u6807\u51c6\u5e93\u5e38\u88ab\u79f0\u4e3a\u6807\u51c6\u6a21\u677f\u5e93 (Standard-Template-Library, STL)\u3002 \u952e\u7c7b\u578b\u548c\u503c\u7c7b\u578b\u53ef\u4ee5\u662f\u4efb\u610f\u7c7b\u578b\uff0c\u5305\u62ec\u57fa\u672c\u7c7b\u578b\uff0c\u7528\u6237\u81ea\u5b9a\u4e49\u7684\u7c7b\uff0c\u5176\u4ed6 STL \u5bb9\u5668\u7b49\uff0c\u4f53\u73b0\u4e86\u5bb9\u5668\u7684\u6cdb\u7528\u6027\u3002 \u552f\u4e00\u7684\u8981\u6c42\u662f\uff1a\u952e\u5fc5\u987b\u652f\u6301\u6bd4\u8f83\uff0c\u8fd9\u91cc map \u8981\u6c42\u7684\u662f\u5c0f\u4e8e\u8fd0\u7b97\u7b26 < \u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a string\uff0c\u503c\u7c7b\u578b\u4e3a int \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a int\uff0c\u503c\u7c7b\u578b\u4e3a Student \u7684 map \u5bb9\u5668\u3002 \u4f8b\u5982 map> \u662f\u4e00\u4e2a\u952e\u7c7b\u578b\u4e3a char\uff0c\u503c\u7c7b\u578b\u4e3a vector \u7684 map \u5bb9\u5668\u3002 \u540e\u9762\u4e3a\u4e86\u65b9\u4fbf\u7814\u7a76\uff0c\u4ee5 map \u5f62\u5f0f\u4e66\u5199\u5f97\u51fa\u7684\u7ed3\u8bba\uff0c\u5bf9\u4e8e\u4efb\u4f55\u5b9e\u9645\u952e\u548c\u503c\u7c7b\u578b\uff0c\u53ea\u9700\u4ee3\u5165 K \u548c V \u5373\u53ef\u3002 \u5df2\u77e5\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 K \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < \u3002 \u53ef\u5f97\uff1a\u8981\u60f3\u4f7f\u7528 map \uff0c\u5c31\u5f97\u6ee1\u8db3 string \u5fc5\u987b\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26 < 2 \u3002 \u5df2\u77e5\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e K \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002 \u53ef\u5f97\uff1a\u904d\u5386 map \u65f6\uff0c\u662f\u4ee5\u952e int \u90e8\u5206\u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u904d\u5386\u7684\u3002","title":"\u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668"},{"location":"stl_map/#map_2","text":"map \u548c set \u4e00\u6837\uff0c\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u5b9e\u73b0 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u9ad8\u6548\u67e5\u627e\u3002 vector \u5c31\u662f\u56e0\u4e3a\u5143\u7d20\u6ca1\u6709\u56fa\u5b9a\u7684\u987a\u5e8f\uff0c\u6240\u4ee5\u624d\u9700\u8981\u66b4\u529b\u904d\u5386\u67e5\u627e\u3002 \u5728\u6301\u7eed\u7684\u63d2\u5165\u548c\u5220\u9664\u64cd\u4f5c\u4e0b\uff0c\u59cb\u7ec8\u7ef4\u6301\u5143\u7d20\u7684\u6709\u5e8f\u6027\uff0c\u6b63\u662f map \u5b9e\u73b0\u9ad8\u6548\u67e5\u627e\u7684\u5173\u952e\u6240\u5728\u3002","title":"map \u7684\u7269\u7406\u7ed3\u6784"},{"location":"stl_map/#_12","text":"\u59cb\u7ec8\u4fdd\u5b58\u5143\u7d20\u6309\u952e\u6392\u5e8f\u7684\u597d\u5904\u662f\uff0c\u5982\u679c\u9700\u8981\u5bfb\u627e\u6307\u5b9a\u952e\u503c\u7684\u5143\u7d20\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u4e8c\u5206\u6cd5\uff1a \u4ece\u6839\u8282\u70b9\u5f00\u59cb\u67e5\u627e\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5c0f\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u5de6\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u5927\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u5f80\u53f3\u5b50\u8282\u70b9\u79fb\u52a8\uff1b \u5982\u679c\u5f53\u524d\u8282\u70b9\u7684\u952e\u7b49\u4e8e\u8981\u627e\u7684\u952e\uff0c\u5219\u8be5\u8282\u70b9\u5c31\u662f\u8981\u627e\u7684\u8282\u70b9\uff0c\u8fd4\u56de\u8be5\u8282\u70b9\u3002 \u5982\u679c\u5f53\u524d\u8282\u70b9\u5df2\u7ecf\u662f\u6700\u540e\u4e00\u5c42\u53f6\u5b50\u8282\u70b9\uff0c\u4e5f\u6ca1\u627e\u5230\u76f8\u7b49\u7684\u952e\uff0c\u5219\u8bf4\u660e\u8be5\u952e\u4e0d\u5b58\u5728\u3002 \u628a\u5de6/\u53f3\u5b50\u8282\u70b9\u8bbe\u4e3a\u65b0\u7684\u5f53\u524d\u8282\u70b9\uff0c\u7136\u540e\u56de\u5230\u7b2c 2 \u6b65\uff0c\u91cd\u590d\u8fd9\u4e00\u67e5\u627e\u8fc7\u7a0b\u3002","title":"\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0e\u4e8c\u5206\u6cd5"},{"location":"stl_map/#_13","text":"\u7531\u4e8e map \u7684\u5b9e\u73b0\u57fa\u4e8e\u4e8c\u53c9\u6392\u5e8f\u6811\uff0cmap \u989d\u5916\u6709\u4e00\u4e2a\u7279\u70b9\uff1a \u6709\u5e8f \u3002 map (\u6216 set) \u4e2d\u7684\u952e K \u603b\u662f\u4ece\u5c0f\u5230\u5927\u6392\u5217\uff0c\u65b9\u4fbf\u8fdb\u884c\u4e8c\u5206\u67e5\u627e\uff0c\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u627e\u5230\u5bf9\u5e94\u5143\u7d20\u3002 \u6bcf\u6b21\u63d2\u5165\u65b0\u7684\u952e\u65f6\uff0c\u4f1a\u627e\u5230\u9002\u5f53\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u4f7f\u5f97\u63d2\u5165\u540e\u7684 map \u4ecd\u7136\u6709\u5e8f\u3002 \u6ce8\uff1a\u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\u5b9e\u73b0\u7684 unordered_map (\u548c unordered_set)\uff0c\u5c31\u4e0d\u5177\u5907 \u6709\u5e8f \u8fd9\u4e00\u7279\u70b9\u3002 \u4e24\u8005\u7684\u533a\u522b\u5728\u4e8e\uff1amap \u5728 K \u4e4b\u5916\uff0c\u989d\u5916\u5916\u6302\u4e86\u4e00\u4e2a V \u7c7b\u578b\u3002 map \u4e2d\u7684 V \u7c7b\u578b\u4e0d\u53c2\u4e0e\u6392\u5e8f\uff0c\u53ea\u6309\u7167 K \u8fdb\u884c\u6392\u5e8f\u3002 \u8fd9\u6837\u5f53\u7528\u6237\u6839\u636e K \u627e\u5230\u7684\u662f K-V \u5bf9\uff0c\u7136\u540e\u53ef\u4ee5\u53d6\u51fa K \u5bf9\u5e94\u7684 V\u3002 \u8fd9\u5c31\u5b9e\u73b0\u4e86\u4ece K \u5230 V \u7684\u6620\u5c04\u3002","title":"\u4e8c\u53c9\u6392\u5e8f\u6811"},{"location":"stl_map/#_14","text":"\u4e8c\u53c9\u6392\u5e8f\u6811\u53ea\u89e3\u51b3\u4e86\u67e5\u627e\u7684\u95ee\u9898\uff0c\u4f46\u662f\u4ed6\u5e76\u4e0d\u80fd\u4fdd\u8bc1\u7ecf\u5386\u4e00\u901a\u63d2\u5165\u540e\u7684\u6811\u4e0d\u4f1a\u201c\u9000\u5316\u201d\u3002 \u5982\u679c\u63d2\u5165\u7684\u65f6\u5019\u4e0d\u5c0f\u5fc3\uff0c\u53ef\u80fd\u4f1a\u8ba9\u6811\u7684\u5f62\u72b6\u53d8\u5f97\u975e\u5e38\u8be1\u5f02\uff01 \u4f8b\u5982\uff0c\u82e5\u63d2\u5165\u6570\u636e\u7684\u987a\u5e8f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u90a3\u5c31\u4f1a\u4e00\u76f4\u5728\u5f80\u53f3\u63d2\u5165\uff0c\u6e05\u4e00\u8272\u7684\u4e00\u8fb9\u5012\uff0c\u4ee5\u81f3\u4e8e\u51e0\u4e4e\u6210\u4e86\u4e00\u6839\u5f80\u53f3\u8dd1\u7684\u94fe\u8868\u3002 \u5982\u679c\u63d2\u5165\u987a\u5e8f\u662f\u4ece\u5927\u5230\u5c0f\uff0c\u5c31\u53d8\u6210\u4e00\u76f4\u5f80\u5de6\u8fb9\u5012\u3002\u5373\u4f7f\u63d2\u5165\u7684\u987a\u5e8f\u4e0d\u90a3\u4e48\u523b\u610f\uff0c\u4f9d\u7136\u53ef\u80fd\u4ea7\u751f\u975e\u5e38\u53d8\u6001\u7684\u5f62\u72b6\uff0c\u8fdd\u80cc\u4e86\u4e8c\u53c9\u6811\u7684\u521d\u8877\u3002 \u54e5\u4fe9\u751f\u5f02\u5f62\u5462\uff1f \u8fd9\u6837\u201c\u9000\u5316\u201d\u7684\u4e8c\u53c9\u6392\u5e8f\u6811\uff0c\u867d\u7136\u80fd\u4fdd\u6301\u6709\u5e8f\uff0c\u4f46\u4e8c\u5206\u67e5\u627e\u65f6\u5c31\u8d77\u4e0d\u5230\u52a0\u901f\u4f5c\u7528\u4e86\u3002 \u5982\u679c\u8981\u627e\u4e00\u4e2a\u4e2d\u95f4\u7684\u5143\u7d20\uff0c\u51e0\u4e4e\u5c31\u548c\u94fe\u8868\u4e00\u6837\uff0c\u9700\u8981\u904d\u5386\u6574\u4e2a\u53f3\u679d\u5e72\u3002 \u4e3a\u4e86\u9650\u5236\u4e8c\u53c9\u6392\u5e8f\u6811\u4e0d\u8981\u957f\u6210\u7578\u5f62\uff0c\u6211\u4eec\u5f15\u5165\u4e00\u4e2a\u6307\u6807\uff1a\u201c\u6df1\u5ea6\u201d\uff0c\u8868\u793a\u4ece\u6839\u8282\u70b9\u5230\u6700\u5e95\u5c42\u53f6\u5b50\u8282\u70b9\u7684\u8ddd\u79bb\u3002 \u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u5c31\u9700\u8981\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u5c3d\u53ef\u80fd\u7684\u4f4e\u3002 \u56e0\u4e3a\u4e8c\u5206\u67e5\u627e\u7684\u6b21\u6570\u5c31\u53d6\u51b3\u4e8e\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u7684\u5e73\u5747\u6df1\u5ea6\uff0c\u8981\u5c3d\u53ef\u80fd\u51cf\u5c11\u5e73\u5747\u9700\u8981\u8bbf\u95ee\u7684\u6b21\u6570\uff0c\u5c31\u662f\u8981\u51cf\u5c11\u4e8c\u53c9\u6811\u7684\u6df1\u5ea6\u3002 \u4e5f\u5c31\u662f\u8bf4\u8981\u8ba9\u5927\u5bb6\u90fd\u5c3d\u53ef\u80fd\u8d34\u8fd1\u6839\u90e8\uff0c\u4f46\u6211\u4eec\u4e0d\u53ef\u80fd\u8ba9\u6240\u6709\u53f6\u5b50\u90fd\u6700\u8d34\u8fd1\u6839\u90e8\u3002 \u4f8b\u5982\u53f3\u4fa7\u53ea\u6709\u4e00\u4e2a\u53f6\u5b50\u8282\u70b9\uff0c\u4ed6\u81ea\u5df1\u662f\u6df1\u5ea6\u6700\u4f4e\u4e86\uff0c\u4f46\u4ee3\u4ef7\u662f\u5de6\u8fb9\u5168\u90e8\u6324\u5728\u4e00\u6761\u94fe\u8868\u4e0a\u4e86\uff01\u8fd9\u4e0d\u516c\u5e73\u3002 \u5b83\u81ea\u5df1\u5012\u662f\u81ea\u7531\u4e86\uff0c\u4f46\u5b83\u5974\u5f79\u4e86\u6240\u6709\u7684\u4eba\u6c11 \u6240\u4ee5\u8981\u6700\u5927\u5316\u4e8c\u5206\u67e5\u627e\u7684\u6548\u7387\uff0c\u6211\u4eec\u771f\u6b63\u9700\u8981\u7684\u662f\u8ba9\u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u5c3d\u53ef\u80fd\u201c\u5e73\u7b49\u201d\uff01","title":"\u4e8c\u53c9\u6811\u9000\u5316\u95ee\u9898"},{"location":"stl_map/#vs","text":"\u4e3a\u4e86\u907f\u514d\u4e8c\u53c9\u6811\u957f\u6210\u7578\u5f62\uff0c\u9677\u5165\u4e00\u8fb9\u5012\u7684\u60c5\u51b5\u3002\u6211\u4eec\u9700\u8981\u5728\u6bcf\u6b21\u63d2\u5165\u540e\uff0c\u68c0\u67e5\u4e8c\u53c9\u6811\u662f\u5426\u6df1\u5ea6\u5dee\u8ddd\u8fc7\u5927\u3002 \u5982\u679c\u5dee\u7684\u592a\u591a\u4e86\uff0c\u5c31\u9700\u8981\u8fdb\u884c\u4e00\u7cfb\u5217\u77eb\u6b63\u64cd\u4f5c\uff0c\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\uff0c\u628a\u592a\u957f\u7684\u679d\u5e72\u780d\u65ad\uff0c\u63a5\u5728\u77ed\u7684\u5730\u65b9\uff0c\u5c3d\u53ef\u80fd\u4fdd\u6301\u6240\u6709\u53f6\u5b50\u8def\u5f84\u7684\u6df1\u5ea6\u5dee\u4e0d\u591a\uff0c\u8fd9\u4e2a\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u52a8\u4f5c\u5c31\u662f \u5e73\u8861\u64cd\u4f5c (balancing) \u3002 \u95ee\u9898\u662f\uff0c\u6700\u5927\u80fd\u5bb9\u5fcd\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u591a\u5927\u7684\u6df1\u5ea6\u5dee\u624d\u5f00\u59cb\u77eb\u6b63\uff1f\u9488\u5bf9\u8fd9\u4e2a\u95ee\u9898\uff0c\u4e8c\u53c9\u6392\u5e8f\u6811\u5206\u4e3a\u4e24\u6d3e\uff1a","title":"\u7ea2\u9ed1\u6811 vs \u5e73\u8861\u6811"},{"location":"stl_map/#_15","text":"\u6700\u7406\u60f3\u7684\u60c5\u51b5\u4e0b\uff0c\u4e00\u9897\u542b\u6709 N N \u4e2a\u8282\u70b9\u7684\u4e8c\u53c9\u6811\uff0c\u81f3\u5c11\u9700\u8981\u6709 \\lceil \\log N \\rceil \\lceil \\log N \\rceil \u6df1\u5ea6\u3002 \u8fd9\u5c31\u662f\u5e73\u8861\u6811\uff08AVL\uff09\uff0c\u4ed6\u5f3a\u5236\u4fdd\u8bc1\u6574\u4e2a\u6811\u5904\u4e8e\u5b8c\u7f8e\u7684\u5e73\u8861\u72b6\u6001\uff0c\u6bcf\u4e2a\u53f6\u5b50\u8282\u70b9\u4e4b\u95f4\u7684\u6df1\u5ea6\u5dee\u8ddd\u4e0d\u4f1a\u8d85\u8fc7 1\uff08\u5f53\u8282\u70b9\u6570\u91cf N N \u4e0d\u662f 2 \u7684\u6574\u6570\u500d\u65f6\uff0c\u8fd9\u662f\u4e0d\u5f97\u4e0d\u5b58\u5728\u7684 1 \u683c\u5dee\u8ddd\uff09\u3002 \u4f18\u70b9\uff1a\u59cb\u7ec8\u4fdd\u6301\u6700\u5b8c\u7f8e\u7684\u5e73\u8861\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u548c\u6700\u574f\u590d\u6742\u5ea6\u6700\u4f4e\u3002\u6240\u4ee5\u5e73\u8861\u6811\u7684\u67e5\u627e\u6027\u80fd\u662f\u6700\u597d\u7684\u3002 \u7f3a\u70b9\uff1a\u7136\u800c\u59cb\u7ec8\u4fdd\u6301\u5b8c\u7f8e\u7684\u5e73\u8861\u610f\u5473\u7740\uff0c\u51e0\u4e4e\u6bcf\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff08\u53ef\u80fd\u4f1a\u7a81\u7136\u4ea7\u751f\u6df1\u5ea6\u5dee\u8ddd\u8d85\u8fc7 1 \u7684\u60c5\u51b5\uff09\uff0c\u5c31\u7acb\u5373\u9700\u8981\u5e73\u8861\u4e00\u6b21\u3002\u5e73\u8861\u4e00\u6b21\u7684\u5f00\u9500\u662f\u6bd4\u8f83\u5927\u7684\uff0c\u6240\u4ee5\u5e73\u8861\u6811\u7684\u6027\u80fd\u662f\u63d2\u5165\u6027\u80fd\u662f\u6bd4\u8f83\u5dee\u7684\u3002 \u5e73\u8861\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u65b9\u5f0f\u662f\u201c\u65cb\u8f6c\u201d\uff0c\u4ed6\u80fd\u59cb\u7ec8\u4fdd\u6301\u6700\u4f4e\u7684\u6df1\u5ea6\u5dee\uff1a \u8fd9\u91cc\u7684\u7ec6\u8282\u6211\u4eec\u4e0d\u4f1a\u6df1\u7a76\uff0c\u90a3\u662f\u6570\u636e\u7ed3\u6784\u8bfe\u7684\u5185\u5bb9\uff0c\u5c4a\u65f6\u4f1a\u5e26\u5927\u5bb6\u624b\u6413\u5e73\u8861\u6811\u548c\u7ea2\u9ed1\u6811\uff0c\u672c\u671f\u53ea\u662f\u7a0d\u5fae\u4e86\u89e3 map \u5e38\u89c1\u7684\u5e95\u5c42\u5b9e\u73b0\uff0c\u5e2e\u52a9\u4f60\u7406\u89e3\u4e3a\u4ec0\u4e48 map \u662f\u6709\u5e8f\u5bb9\u5668\u3002","title":"\u5e73\u8861\u6811"},{"location":"stl_map/#_16","text":"\u800c\u7ea2\u9ed1\u6811\u8ba4\u4e3a\uff0c\u6211\u4eec\u4e0d\u9700\u8981\u603b\u662f\u4fdd\u6301\u6df1\u5ea6\u5dee\u8ddd\u4e3a 1 \u90a3\u4e48\u5c0f\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u5373\u53ef\u3002 \u4f8b\u5982\u6700\u6d45\u7684\u4e00\u4e2a\u53f6\u5b50\u662f 6 \u6df1\u5ea6\uff0c\u53e6\u4e00\u4e2a\u6700\u6df1\u7684\u53f6\u5b50\u53ef\u4ee5\u662f 12 \u6df1\u5ea6\u3002\u53ea\u6709\u5f53\u6700\u6df1\u7684\u53f6\u5b50\u8d85\u8fc7 12 \u6df1\u5ea6\u65f6\uff0c\u7ea2\u9ed1\u6811\u624d\u4f1a\u5f00\u59cb\u4e3b\u52a8\u5e72\u9884\u5e73\u8861\uff0c\u907f\u514d\u7ee7\u7eed\u7578\u5f62\u53d1\u5c55\u4e0b\u53bb\u3002 \u7f3a\u70b9\uff1a\u6811\u53ef\u80fd\u6709\u4e00\u5b9a\u7684\u4e00\u8fb9\u5012\u60c5\u51b5\uff0c\u5e73\u5747\u590d\u6742\u5ea6\u7a0d\u5fae\u964d\u4f4e\uff0c\u6700\u574f\u590d\u6742\u5ea6\u53ef\u4ee5\u8fbe\u5230\u539f\u6765\u7684 2 \u500d\uff01 \u4f18\u70b9\uff1a\u56e0\u4e3a\u5bf9\u4e0d\u5e73\u8861\u73b0\u8c61\u66f4\u52a0\u5bbd\u677e\uff0c\u6b63\u5e38\u63d2\u5165\u65f6\u57fa\u672c\u4e0d\u9700\u8981\u5e73\u8861\uff0c\u53ea\u6709\u7279\u522b\u626d\u66f2\u4e86\u624d\u4f1a\u4e0b\u573a\u201c\u6551\u6025\u201d\u3002\u6240\u4ee5\u7ea2\u9ed1\u6811\u662f\u727a\u7272\u4e86\u4e00\u90e8\u5206\u67e5\u627e\u6027\u80fd\uff0c\u6362\u53d6\u4e86\u66f4\u597d\u7684\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u3002 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u7684\u7528\u51b5\u662f\u63d2\u5165\u6bd4\u8f83\u5c11\uff0c\u4f46\u662f\u67e5\u8be2\u975e\u5e38\u591a\uff0c\u90a3\u5c31\u9002\u5408\u7528\u5e73\u8861\u6811\u3002 \u7531\u4e8e\u6362\u6765\u7684\u8fd9\u90e8\u5206\u63d2\u5165\u548c\u5220\u9664\u6027\u80fd\u5b9e\u9645\u4e0a\u6bd4\u635f\u5931\u7684\u67e5\u627e\u6027\u80fd\u591a\uff0c\u800c map \u5e38\u89c1\u7684\u7528\u51b5\u786e\u5b9e\u9700\u8981\u7ecf\u5e38\u589e\u5220\u6539\u67e5\uff0c\u6240\u4ee5\u73b0\u5728 C++ \u6807\u51c6\u5e93\u7684 map \u5e95\u5c42\u90fd\u662f\u57fa\u4e8e\u7ea2\u9ed1\u6811\u5b9e\u73b0\u7684\u3002 \u5982\u679c\u4f60\u7684\u9700\u6c42\u662f\u5927\u91cf\u67e5\u627e\u7684\u8bdd\uff0c\u5b8c\u5168\u53ef\u4ee5\u8003\u8651\u7528\u67e5\u627e\u5e73\u5747\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u7684\u54c8\u5e0c\u8868 unordered_map\u3002 \u5982\u679c\u662f\u4e00\u6b21\u6027\u63d2\u5165\u5b8c\u6bd5\u540e\u4e0d\u4f1a\u518d\u4fee\u6539\uff0c\u8fd8\u53ef\u4ee5\u7528\u5b8c\u7f8e\u54c8\u5e0c\u8868\uff08frozen_map\uff09\uff0c\u4ed6\u4f1a\u4e3a\u4f60\u7684\u952e\u503c\u5e8f\u5217\u4e13\u95e8\u751f\u6210\u4e00\u4e2a\u4e13\u7528\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u7f16\u8bd1\u671f\u786e\u5b9a\uff0c\u4e14\u4fdd\u8bc1\u5b8c\u5168\u65e0\u51b2\u7a81\u3002\u4f8b\u5982\u4f60\u5728\u505a\u4e00\u79cd\u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u6709\u5f88\u591a\u201c\u5173\u952e\u5b57\u201d\uff0c\u6bd4\u5982\u201cif\u201d\u3001\u201cwhile\u201d\uff0c\u4f60\u9700\u8981\u8fd0\u884c\u65f6\u9891\u7e41\u7684\u67e5\u627e\u8fd9\u4e9b\u5173\u952e\u5b57\uff0c\u800c\u5173\u952e\u5b57\u6709\u54ea\u4e9b\u5728\u7f16\u8bd1\u671f\u662f\u56fa\u5b9a\u7684\uff0c\u90a3\u5c31\u5f88\u9002\u5408\u7528\u5b8c\u7f8e\u54c8\u5e0c\u3002","title":"\u7ea2\u9ed1\u6811"},{"location":"stl_map/#_17","text":"\u7ea2\u9ed1\u6811\u662f\u5982\u4f55\u4fdd\u8bc1\u6700\u6df1\u53f6\u5b50\u548c\u6700\u6d45\u53f6\u5b50\u7684\u6df1\u5ea6\u5dee\u4e0d\u8d85\u8fc7 2 \u500d\u7684\u5462\uff1f \u4ed6\u8bbe\u5b9a\u4e86\u8fd9\u6837 5 \u6761\u89c4\u5219\uff1a \u8282\u70b9\u53ef\u4ee5\u662f\u7ea2\u8272\u6216\u9ed1\u8272\u7684\u3002 \u6839\u8282\u70b9\u603b\u662f\u9ed1\u8272\u7684\u3002 \u6240\u6709\u53f6\u5b50\u8282\u70b9\u90fd\u662f\u9ed1\u8272\uff08\u53f6\u5b50\u8282\u70b9\u5c31\u662f NULL\uff09\u3002 \u7ea2\u8272\u8282\u70b9\u7684\u4e24\u4e2a\u5b50\u8282\u70b9\u5fc5\u987b\u90fd\u662f\u9ed1\u8272\u7684\u3002 \u4ece\u4efb\u4e00\u8282\u70b9\u5230\u5176\u6240\u6709\u53f6\u5b50\u8282\u70b9\u7684\u8def\u5f84\u90fd\u5305\u542b\u76f8\u540c\u6570\u91cf\u7684\u9ed1\u8272\u8282\u70b9\u3002 \u4ec0\u4e48\u89c4\u5219\u7c7b\u602a\u8c08\u2026\u2026 \u770b\u8d77\u6765\u597d\u50cf\u5f88\u590d\u6742\uff0c\u4f46\u5b9e\u9645\u4e0a\u5927\u591a\u662f\u5e9f\u8bdd\uff0c\u6709\u7528\u7684\u53ea\u662f 4 \u548c 5 \u8fd9\u4e24\u6761\u3002 \u89c4\u5219 4 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4e0d\u5f97\u51fa\u73b0\u76f8\u90bb\u7684\u7ea2\u8272\u8282\u70b9\uff08\u76f8\u90bb\u6307\u4e24\u4e2a\u8282\u70b9\u662f\u7236\u5b50\u5173\u7cfb\uff09\u3002\u8fd9\u6761\u89c4\u5219\u8fd8\u6709\u4e00\u4e2a\u9690\u542b\u7684\u4fe1\u606f\uff1a\u9ed1\u8272\u8282\u70b9\u53ef\u4ee5\u76f8\u90bb\uff01 \u89c4\u5219 5 \u7ffb\u8bd1\u4e00\u4e0b\u5c31\u662f\uff1a\u4ece\u6839\u8282\u70b9\u5230\u6240\u6709\u5e95\u5c42\u53f6\u5b50\u7684\u8ddd\u79bb\uff08\u4ee5\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u8ba1\uff09\uff0c\u5fc5\u987b\u76f8\u7b49\u3002 \u56e0\u4e3a\u89c4\u5219 4 \u7684\u5b58\u5728\uff0c\u7ea2\u8272\u8282\u70b9\u4e0d\u53ef\u80fd\u76f8\u90bb\uff0c\u4e5f\u5c31\u662f\u8bf4\u6700\u6df1\u7684\u679d\u5e72\u53ea\u80fd\u662f\uff1a\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1-\u7ea2-\u9ed1\u3002 \u7ed3\u5408\u89c4\u5219 5 \u6765\u770b\uff0c\u4e5f\u5c31\u662f\u8bf4\u6bcf\u6761\u679d\u5e72\u4e0a\u7684\u9ed1\u8272\u8282\u70b9\u6570\u91cf\u5fc5\u987b\u76f8\u540c\uff0c\u56e0\u4e3a\u6700\u6df1\u7684\u679d\u5e72\u662f 4 \u4e2a\u9ed1\u8282\u70b9\u4e86\uff0c\u6240\u4ee5\u6700\u6d45\u7684\u679d\u5e72\u81f3\u5c11\u4e5f\u5f97\u6709 4 \u4e2a\u8282\u70b9\u5168\u662f\u9ed1\u8272\u7684\uff1a\u9ed1-\u9ed1-\u9ed1-\u9ed1\u3002 \u53ef\u4ee5\u770b\u5230\uff0c\u89c4\u5219 4 \u548c\u89c4\u5219 5 \u8054\u5408\u8d77\u6765\u5b9e\u9645\u4e0a\u5c31\u4fdd\u8bc1\u4e86\uff1a\u6700\u6df1\u679d\u5e72\u7684\u6df1\u5ea6\u4e0d\u4f1a\u8d85\u8fc7\u6700\u6d45\u679d\u5e72\u7684 2 \u500d\u3002 \u5982\u679c\u8d85\u51fa\u4e86 2 \u500d\uff0c\u5c31\u4e0d\u5f97\u4e0d\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u89c4\u5219 4 \u6216 5\uff0c\u4ece\u800c\u89e6\u53d1\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u5e73\u8861\u64cd\u4f5c\uff0c\u4ece\u800c\u963b\u6b62\u4e86\u4e8c\u53c9\u6811\u8fc7\u4e8e\u7578\u5f62\u5316\u3002 \u7ea2\u9ed1\u6811\u5982\u4f55\u5b9e\u73b0\u201c\u52ab\u5bcc\u6d4e\u8d2b\u201d\u7684\u7ec6\u8282\u6211\u4eec\u5c31\u4e0d\u518d\u591a\u8c08\u4e86\uff0c\u5c0f\u5f6d\u8001\u5e08\u70b9\u5230\u4e3a\u6b62\uff0c\u63a5\u4e0b\u6765\u76f4\u63a5\u8fdb\u5165\u6b63\u9898\uff1a","title":"\u7ea2\u9ed1\u6811\u5b9e\u73b0\u5e73\u8861\u7684\u79d8\u5bc6"},{"location":"stl_map/#map_3","text":"\u521b\u5efa\u4e00\u4e2a map \u5bf9\u8c61\uff1a map config; \u4e00\u5f00\u59cb map \u521d\u59cb\u662f\u7a7a\u7684\uff0c\u5982\u4f55\u63d2\u5165\u4e00\u4e9b\u521d\u59cb\u6570\u636e\uff1f config[\"timeout\"] = 985; config[\"delay\"] = 211; \u6570\u636e\u63d2\u5165\u6210\u529f\u4e86\uff0c\u6839\u636e\u952e\u67e5\u8be2\u5bf9\u5e94\u7684\u503c\uff1f print(config[\"timeout\"]); print(config[\"delay\"]); \u67e5\u8be2\u65f6\u5efa\u8bae\u7528 .at(key) \u800c\u4e0d\u662f [key] \uff1a print(config.at(\"timeout\")); print(config.at(\"delay\")); \u8001\u751f\u5e38\u8c08\u7684\u95ee\u9898\uff1amap \u4e2d\u5b58 string \u8fd8\u662f const char *\uff1f map m; m[\"hello\"] = \"old\"; // \u5e38\u91cf\u533a\u7684 \"hello\" char key[] = \"hello\"; // key \u7684\u5730\u5740\u5728\u6808\u4e0a print(key == \"hello\"); // false m[key] = \"new\"; // \u6808\u4e0a\u53d8\u91cf\u7684 key = \"hello\" print(m); // \u4e24\u4e2a\u91cd\u590d\u7684\u952e \"hello\" false {hello: old, hello: new} \u5728 C++ \u4e2d\uff0c\u4efb\u4f55\u65f6\u5019\u90fd\u52a1\u5fc5\u7528 string\uff01\u522b\u7528 C \u8bed\u8a00\u8001\u6389\u7259\u7684 const char *\uff0c\u592a\u5371\u9669\u4e86\u3002 const char * \u5371\u9669\u7684\u539f\u56e0\uff1a const char * \u7684 == \u5224\u65ad\u7684\u662f\u6307\u9488\u7684\u76f8\u7b49\uff0c\u4e24\u4e2a const char * \u53ea\u8981\u5730\u5740\u4e0d\u540c\uff0c\u5373\u4f7f\u5b9e\u9645\u7684\u5b57\u7b26\u4e32\u76f8\u540c\uff0c\u4e5f\u4e0d\u4f1a\u88ab\u89c6\u4e3a\u540c\u4e00\u4e2a\u5143\u7d20\uff08\u5982\u4e0a\u4ee3\u7801\u6848\u4f8b\u6240\u793a\uff09\u3002\u5bfc\u81f4 map \u91cc\u4f1a\u51fa\u73b0\u91cd\u590d\u7684\u952e\uff0c\u4ee5\u53ca\u6309\u952e\u67e5\u627e\u53ef\u80fd\u627e\u4e0d\u5230\u7b49\u3002 \u4fdd\u5b58\u7684\u662f\u5f31\u5f15\u7528\uff0c\u5982\u679c\u4f60\u628a\u5c40\u90e8\u7684 char [] \u6216 string.c_str() \u8fd4\u56de\u7684 const char * \u5b58\u5165 map\uff0c\u7b49\u8fd9\u4e9b\u5c40\u90e8\u91ca\u653e\u4e86\uff0cmap \u4e2d\u7684 const char * \u5c31\u662f\u4e00\u4e2a\u7a7a\u60ac\u6307\u9488\u4e86\uff0c\u4f1a\u9020\u6210 segfault\u3002 \u8bf7\u7528\u5b89\u5168\u7684 string\uff1a map m; m[\"hello\"] = \"old\"; string key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // string \u7684 == \u8fd0\u7b97\u7b26\u662f\u7ecf\u8fc7\u91cd\u8f7d\u7684\uff0c\u6bd4\u8f83\u7684\u662f\u5b57\u7b26\u4e32\u91cc\u9762\u7684\u5185\u5bb9\u76f8\u7b49\uff0c\u800c\u4e0d\u662f\u5730\u5740\u76f8\u7b49 {\"hello\": \"new\"} true \u63cf\u8ff0 C++ Java Python \u5185\u5bb9\u76f8\u7b49 string(\"hello\") == string(\"hello\") \"hello\".equals(\"hello\") 'hello' == 'hello' \u5730\u5740\u76f8\u7b49 \"hello\" == \"hello\" \"hello\" == \"hello\" id('hello') == id('hello') \u5982\u679c\u4f60\u7cbe\u901a\u5bf9\u8c61\u751f\u547d\u5468\u671f\u5206\u6790\uff0c\u80fd\u4fdd\u8bc1 key \u6307\u5411\u7684\u5b57\u7b26\u4e32\u6d3b\u7684\u6bd4 m \u4e45\uff0c\u60f3\u8981\u907f\u514d\u62f7\u8d1d\uff0c\u8282\u7701\u6027\u80fd\u3002 string \u7684\u5f31\u5f15\u7528\u7248\u672c\uff1astring_view\uff0c\u540c\u6837\u53ef\u4ee5\u7528\u5c01\u88c5\u4e86\u6b63\u786e\u7684 == \u8fd0\u7b97\u7b26\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\uff1a map m; m[\"hello\"] = \"old\"; string_view key = \"hello\"; m[key] = \"new\"; print(m); print(key == \"hello\"); // \u6b64\u5904 m \u662f\u6808\u4e0a\u53d8\u91cf\uff0ckey \u662f\u5f31\u5f15\u7528\u6307\u5411\u5168\u5c40\u5e38\u91cf\u533a\uff08rodata\uff09\uff0ckey \u6bd4 m \u6d3b\u5f97\u4e45\uff0c\u6ca1\u6709\u7a7a\u60ac\u6307\u9488\u95ee\u9898 {\"hello\": \"new\"} true \u26a0\ufe0f string_view \u5c5e\u4e8e\u4e0d\u5efa\u8bae\u521d\u5b66\u8005\u4f7f\u7528\u7684\u4f18\u5316\u5c0f\u5bc4\u5de7\uff1a\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528\u3002 \u6ce8\uff1amap \u5b9e\u9645\u4e0a\u5b8c\u5168\u6ca1\u6709\u7528\u5230 ==\uff0c\u7528\u5230\u7684\u53ea\u6709 < \u8fd0\u7b97\u7b26\uff0c\u5f53\u9700\u8981\u5224\u5b9a a == b \u65f6\uff0c\u4ed6\u4f1a\u8f6c\u800c\u7528 !(a < b || b < a) \u6765\u5224\u5b9a\u3002 string_view \u4e5f\u5177\u6709\u6b63\u786e\u7684 hash \u7279\u5316\uff0c\u56e0\u6b64\u4e5f\u53ef\u4ee5\u7528\u505a unordered_map \u7684\u952e\u7c7b\u578b\u3002string_view \u8bd5\u56fe\u548c string \u8868\u73b0\u5f97\u5b8c\u5168\u4e00\u6837\uff0c\u533a\u522b\u5728\u4e8e\u4ed6\u662f\u4e2a\u5f31\u5f15\u7528\uff0c\u4e0d\u6301\u6709\u5bf9\u8c61\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u662f\u6d45\u62f7\u8d1d\u3002string_view \u5927\u5c0f\u53ea\u6709 16 \u4e2a\u5b57\u8282\uff0c\u5185\u90e8\u662f\u4e00\u4e2a const char * \u548c size_t\uff0c\u4f46\u5c01\u88c5\u4e86\u6b63\u786e\u7684 ==\uff0c<\uff0c> \u548c hash\u3002 C++11 \u65b0\u7279\u6027\u2014\u2014\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\uff0c\u5141\u8bb8\u521b\u5efa map \u65f6\u76f4\u63a5\u6307\u5b9a\u521d\u59cb\u6570\u636e\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211} }; \u901a\u5e38\u6211\u4eec\u4f1a\u6362\u884c\u5199\uff0c\u4e00\u884c\u4e00\u4e2a\u952e\u503c\u5bf9\uff0c\u770b\u8d77\u6765\u6761\u7406\u66f4\u6e05\u6670\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 \u603b\u7ed3\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5\uff1a map m = { {k1, v1}, {k2, v2}, ..., }; \u8ba9 map \u521d\u59cb\u5c31\u5177\u6709\u8fd9\u4e9b\u6570\u636e\u3002 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; \u7b49\u53f7\u53ef\u4ee5\u7701\u7565\uff08\u8fd9\u5176\u5b9e\u76f8\u5f53\u4e8e\u662f\u5728\u8c03\u7528 map \u7684\u6784\u9020\u51fd\u6570\uff09\uff1a map config{ {\"timeout\", 985}, {\"delay\", 211}, }; \u4e5f\u53ef\u4ee5\u5148\u6784\u9020\u518d\u8d4b\u503c\u7ed9 auto \u53d8\u91cf\uff1a auto config = map{ {\"timeout\", 985}, {\"delay\", 211}, }; \u90fd\u662f\u7b49\u4ef7\u7684\u3002 \u5173\u4e8e\u6784\u9020\u51fd\u6570\u3001\u82b1\u62ec\u53f7\u5217\u8868\u7684\u5177\u4f53\u8bed\u6cd5\u53ef\u4ee5\u53c2\u8003\u6211\u7684\u300a\u9ad8\u6027\u80fd\u5e76\u884c\u300b\u7cfb\u5217\u7b2c\u4e8c\u8bfe\uff1ahttps://www.bilibili.com/video/BV1LY411H7Gg\u3002\u5728 C++ \u5c0f\u5999\u62db \u4e00\u7ae0\u4e2d\u4e5f\u6709\u4ecb\u7ecd\u3002 \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u53ef\u4ee5\u7528\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868\u5c31\u5730\u6784\u9020\u4e00\u4e2a map \u5bf9\u8c61\uff1a void myfunc(map config); // \u51fd\u6570\u58f0\u660e myfunc(map{ // \u76f4\u63a5\u521b\u5efa\u4e00\u4e2a map \u4f20\u5165 {\"timeout\", 985}, {\"delay\", 211}, }); \u7531\u4e8e myfunc \u51fd\u6570\u5177\u6709\u552f\u4e00\u786e\u5b9a\u7684\u91cd\u8f7d\uff0c\u8981\u6784\u9020\u7684\u53c2\u6570\u7c7b\u578b map \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff1a myfunc({ {\"timeout\", 985}, {\"delay\", 211}, }); \u51fd\u6570\u8fd9\u8fb9\uff0c\u901a\u5e38\u8fd8\u4f1a\u52a0\u4e0a const & \u4fee\u9970\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u62f7\u8d1d\u3002 void myfunc(map const &config); \u4ece vector \u4e2d\u6279\u91cf\u5bfc\u5165\u952e\u503c\u5bf9\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs.begin(), kvs.end()); \u4e0e\u521a\u521a\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u7684\u5199\u6cd5\u7b49\u4ef7\uff0c\u53ea\u4e0d\u8fc7\u662f\u4ece\u73b0\u6709\u7684 vector \u4e2d\u5bfc\u5165\u3002\u540c\u6837\u7684\u5199\u6cd5\u4e5f\u9002\u7528\u4e8e\u4ece array \u5bfc\u5165\u3002 \u5982\u679c\u8bb0\u4e0d\u4f4f\u8fd9\u4e2a\u5199\u6cd5\uff0c\u4e5f\u53ef\u4ee5\u81ea\u5df1\u624b\u5199 for \u5faa\u73af\u904d\u5386 vector \u9010\u4e2a\u9010\u4e2a\u63d2\u5165 map\uff0c\u6548\u679c\u662f\u4e00\u6837\u7684\u3002 \u51b7\u77e5\u8bc6\uff0c\u5982\u679c\u4e0d\u662f vector \u6216 array\uff0c\u800c\u662f\u60f3\u4ece\u4f20\u7edf\u7684 C \u8bed\u8a00\u6570\u7ec4\u4e2d\u5bfc\u5165\uff1a pair kvs[] = { // C \u8bed\u8a00\u539f\u59cb\u6570\u7ec4 {\"timeout\", 985}, {\"delay\", 211}, }; map config(kvs, kvs + 2); // C++98 map config(std::begin(kvs), std::end(kvs)); // C++17 \u5176\u4e2d std::begin \u548c std::end \u4e3a C++17 \u65b0\u589e\u51fd\u6570\uff0c\u4e13\u95e8\u7528\u4e8e\u7167\u987e\u6ca1\u6cd5\u6709\u6210\u5458\u51fd\u6570 .begin() \u7684 C \u8bed\u8a00\u6570\u7ec4\u3002\u7c7b\u4f3c\u7684\u5168\u5c40\u51fd\u6570\u8fd8\u6709 std::size \u548c std::data \u7b49\u2026\u2026\u4ed6\u4eec\u90fd\u662f\u65e2\u517c\u5bb9 STL \u5bb9\u5668\u4e5f\u517c\u5bb9 C \u6570\u7ec4\u7684\u3002 \u91cd\u70b9\u6765\u4e86\uff1a\u5982\u4f55\u6839\u636e\u952e\u67e5\u8be2\u76f8\u5e94\u7684\u503c\uff1f \u5f88\u591a\u540c\u5b66\u90fd\u77e5\u9053 map \u5177\u6709 [] \u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c[] \u91cc\u5199\u8981\u67e5\u8be2\u7684\u952e\u5c31\u53ef\u4ee5\u8fd4\u56de\u5bf9\u5e94\u503c\uff0c\u4e5f\u53ef\u4ee5\u7528 = \u5f80\u91cc\u9762\u8d4b\u503c\uff0c\u548c\u67d0\u4e9b\u811a\u672c\u8bed\u8a00\u4e00\u6837\u76f4\u89c2\u6613\u61c2\u3002 config[\"timeout\"] = 985; // \u628a config \u4e2d\u952e timeout \u5bf9\u5e94\u503c\u8bbe\u4e3a 985 auto val = config[\"timeout\"]; // \u8bfb\u53d6 config \u4e2d\u952e timeout \u5bf9\u5e94\u503c print(val); // 985 \u4f46\u5176\u5b9e\u7528 [] \u53bb \u8bfb\u53d6\u5143\u7d20 \u662f\u5f88\u4e0d\u5b89\u5168\u7684\uff0c\u4e0b\u9762\u6211\u4f1a\u505a\u5b9e\u9a8c\u6f14\u793a\u8fd9\u4e00\u70b9\u3002 \u6c89\u9ed8\u7684 []\uff0c\u65e0\u8a00\u7684\u5371\u9669\uff1a\u5f53\u952e\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8fd4\u56de 0 \u800c\u4e0d\u4f1a\u51fa\u9519\uff01 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // 985 print(config[\"tmeout\"]); // \u9ed8\u9ed8\u8fd4\u56de 0 985 0 \u5f53\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c[] \u4f1a\u9ed8\u9ed8\u521b\u5efa\u5e76\u8fd4\u56de 0\uff0c\u800c\u4e0d\u4f1a\u7206\u51fa\u4efb\u4f55\u9519\u8bef\u3002 \u8fd9\u975e\u5e38\u5371\u9669\uff0c\u4f8b\u5982\u4e00\u4e2a\u7b80\u7b80\u5355\u5355\u7684\u62fc\u5199\u9519\u8bef\uff0c\u5c31\u4f1a\u5bfc\u81f4 map \u7684\u67e5\u8be2\u9ed8\u9ed8\u8fd4\u56de 0\uff0c\u4f60\u8fd8\u5728\u90a3\u91cc\u627e\u4e86\u534a\u5929\u6478\u4e0d\u7740\u5934\u8111\uff0c\u6839\u672c\u6ca1\u53d1\u73b0\u9519\u8bef\u539f\u6765\u5728 map \u8fd9\u91cc\u3002 \u7231\u54ed\u7231\u95f9\u7684 at()\uff0c\u53cd\u800c\u66f4\u8ba8\u4eba\u559c\u6b22 map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config.at(\"timeout\")); // 985 print(config.at(\"tmeout\")); // \u8be5\u952e\u4e0d\u5b58\u5728\uff01\u54cd\u4eae\u5730\u51fa\u9519 985 terminate called after throwing an instance of 'std::out_of_range' what(): map::at Aborted (core dumped) \u6709\u7ecf\u9a8c\u7684\u8001\u624b\u90fd\u660e\u767d\u4e00\u4e2a\u9053\u7406\uff1a \u53ca\u65f6\u5954\u6e83 \u6bd4 \u5bb9\u5fcd\u9519\u8bef \u66f4\u6709\u5229\u4e8e\u8c03\u8bd5\u3002\u5373 fail-early, fail-loudly 1 \u539f\u5219\u3002 \u4f8b\u5982 JS \u548c Lua \u7684 [] \u8bbf\u95ee\u8d8a\u754c\u4e0d\u62a5\u9519\u800c\u662f\u8fd4\u56de undefined / nil\uff0c\u5bfc\u81f4\u5b9e\u9645\u51fa\u9519\u7684\u4f4d\u7f6e\u5728\u597d\u51e0\u5341\u884c\u4e4b\u540e\uff0c\u65e0\u6cd5\u5b9a\u4f4d\u5230\u771f\u6b63\u51fa\u9519\u7684\u4f4d\u7f6e\uff0c\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u540e\u6765\u53d1\u660e\u4e86\u9519\u8bef\u68c0\u67e5\u66f4\u4e25\u683c\u7684 TS\u3002 \u4f7f\u7528 at() \u53ef\u4ee5\u5e2e\u52a9\u4f60\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230\u9519\u8bef\uff0c\u662f\u597d\u4e8b\u3002 \u5728\u5b98\u65b9\u6587\u6863\u548c\u5404\u79cd\u6559\u5b66\u8bfe\u4ef6\u4e2d\uff0c\u90fd\u4f1a\u5c55\u793a\u4e00\u4e2a\u51fd\u6570\u7684\u201c\u539f\u578b\u201d\u6765\u8bb2\u89e3\u3002 \u539f\u578b\u5c55\u73b0\u4e86\u4e00\u4e2a\u51fd\u6570\u7684\u540d\u79f0\uff0c\u53c2\u6570\u7c7b\u578b\uff0c\u8fd4\u56de\u7c7b\u578b\u7b49\u4fe1\u606f\uff0c\u638c\u63e1\u4e86\u51fd\u6570\u7684\u539f\u578b\u5c31\u7b49\u4e8e\u638c\u63e1\u4e86\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u3002 \u672c\u8bfe\u7a0b\u540e\u9762\u4e5f\u4f1a\u5927\u91cf\u4f7f\u7528\uff0c\u73b0\u5728\u6765\u6559\u4f60\u5982\u4f55\u770b\u61c2\u6210\u5458\u51fd\u6570\u7684\u539f\u578b\u3002 \u5047\u8bbe\u8981\u7814\u7a76\u7684\u7c7b\u578b\u4e3a map \uff0c\u5176\u4e2d K \u548c V \u662f\u6a21\u677f\u53c2\u6570\uff0c\u53ef\u4ee5\u66ff\u6362\u6210\u4f60\u5177\u4f53\u7684\u7c7b\u578b\u3002 \u4f8b\u5982\u5f53\u6211\u4f7f\u7528 map \u65f6\uff0c\u5c31\u628a\u4e0b\u9762\u6240\u6709\u7684 K \u66ff\u6362\u6210 string\uff0cV \u66ff\u6362\u6210 int\u3002 map \u7684 [] \u548c at \u5458\u51fd\u6570\uff0c\u539f\u578b\u5982\u4e0b\uff1a V &operator[](K const &k); V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u53ef\u89c1 operator[] \u53ea\u6709\u4e00\u4e2a\u7248\u672c\uff0cat \u5c45\u7136\u6709\u540d\u5b57\u76f8\u540c\u7684\u4e24\u4e2a\uff01\u8fd9\u6837\u4e0d\u4f1a\u53d1\u751f\u51b2\u7a81\u5417\uff1f \u8fd9\u662f\u5229\u7528\u4e86 C++ \u7684\u201c\u91cd\u8f7d\u201d\u529f\u80fd\uff0c\u91cd\u8f7d\u5c31\u662f\u540c\u4e00\u4e2a\u51fd\u6570\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u7248\u672c\uff0c\u5404\u4e2a\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u6253\u7535\u8bdd\u7ed9 110\uff0c\u5047\u5982\u8b66\u5bdf\u53d4\u53d4\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u62a5\u7684\u6848\u5b50\u662f\u7f51\u7edc\u8bc8\u9a97\uff0c\u90a3\u4e48\u4ed6\u4eec\u4f1a\u5e2e\u6211\u8f6c\u63a5\u5230\u7f51\u8b66\u90e8\u95e8\uff1b\u5047\u5982\u53d1\u73b0\u5c0f\u5f6d\u8001\u5e08\u662f\u88ab\u7ed1\u67b6\u4e86\uff0c\u90a3\u4e48\u4ed6\u4eec\u53ef\u80fd\u4f1a\u51fa\u52a8\u6b66\u8b66\u89e3\u6551\u5c0f\u5f6d\u8001\u5e08\u3002\u8fd9\u5c31\u662f 110 \u51fd\u6570\u7684\u4e24\u4e2a\u91cd\u8f7d\uff0c\u6839\u636e\u8c03\u7528\u8005\u4f20\u5165\u7684\u4fe1\u606f\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8f6c\u7ed9\u54ea\u4e00\u4e2a\u5b50\u90e8\u95e8\u3002 \u540c\u7406\uff0c\u7f16\u8bd1\u5668\u4e5f\u662f\u4f1a\u6839\u636e\u8c03\u7528\u65f6\u4f60\u4f20\u5165\u7684\u53c2\u6570\u7c7b\u578b\uff0c\u51b3\u5b9a\u8981\u8c03\u7528\u91cd\u8f7d\u7684\u54ea\u4e00\u4e2a\u5177\u4f53\u7248\u672c\u3002 C \u8bed\u8a00\u6ca1\u6709\u91cd\u8f7d\uff0c\u51fd\u6570\u540d\u5b57\u76f8\u540c\u5c31\u4f1a\u53d1\u751f\u51b2\u7a81\uff0c\u7f16\u8bd1\u5668\u4f1a\u5f53\u573a\u62a5\u9519\u3002 C++ \u652f\u6301\u91cd\u8f7d\uff0c\u53ea\u6709\u5f53\u51fd\u6570\u540d\u5b57\u76f8\u540c\uff0c\u53c2\u6570\u5217\u8868\u4e5f\u76f8\u540c\u65f6\uff0c\u624d\u4f1a\u53d1\u751f\u51b2\u7a81\u3002 \u8fd4\u56de\u503c\u7c7b\u578b\u4e0d\u5f71\u54cd\u91cd\u8f7d\uff0c\u91cd\u8f7d\u53ea\u770b\u53c2\u6570\u5217\u8868\u3002 \u83dc\u9e1f\u6559\u7a0b\u4e0a\u5bf9 C++ \u91cd\u8f7d\u7684\u89e3\u91ca 1 \uff1a C++ \u5141\u8bb8\u5728\u540c\u4e00\u4f5c\u7528\u57df\u4e2d\u7684\u67d0\u4e2a\u51fd\u6570\u548c\u8fd0\u7b97\u7b26\u6307\u5b9a\u591a\u4e2a\u5b9a\u4e49\uff0c\u5206\u522b\u79f0\u4e3a\u51fd\u6570\u91cd\u8f7d\u548c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u91cd\u8f7d\u58f0\u660e\u662f\u6307\u4e00\u4e2a\u4e0e\u4e4b\u524d\u5df2\u7ecf\u5728\u8be5\u4f5c\u7528\u57df\u5185\u58f0\u660e\u8fc7\u7684\u51fd\u6570\u6216\u65b9\u6cd5\u5177\u6709\u76f8\u540c\u540d\u79f0\u7684\u58f0\u660e\uff0c\u4f46\u662f\u5b83\u4eec\u7684\u53c2\u6570\u5217\u8868\u548c\u5b9a\u4e49\uff08\u5b9e\u73b0\uff09\u4e0d\u76f8\u540c\u3002 \u5f53\u60a8\u8c03\u7528\u4e00\u4e2a\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u65f6\uff0c\u7f16\u8bd1\u5668\u901a\u8fc7\u628a\u60a8\u6240\u4f7f\u7528\u7684\u53c2\u6570\u7c7b\u578b\u4e0e\u5b9a\u4e49\u4e2d\u7684\u53c2\u6570\u7c7b\u578b\u8fdb\u884c\u6bd4\u8f83\uff0c\u51b3\u5b9a\u9009\u7528\u6700\u5408\u9002\u7684\u5b9a\u4e49\u3002\u9009\u62e9\u6700\u5408\u9002\u7684\u91cd\u8f7d\u51fd\u6570\u6216\u91cd\u8f7d\u8fd0\u7b97\u7b26\u7684\u8fc7\u7a0b\uff0c\u79f0\u4e3a\u91cd\u8f7d\u51b3\u7b56\u3002 \u5728\u540c\u4e00\u4e2a\u4f5c\u7528\u57df\u5185\uff0c\u53ef\u4ee5\u58f0\u660e\u51e0\u4e2a\u529f\u80fd\u7c7b\u4f3c\u7684\u540c\u540d\u51fd\u6570\uff0c\u4f46\u662f\u8fd9\u4e9b\u540c\u540d\u51fd\u6570\u7684\u5f62\u5f0f\u53c2\u6570\uff08\u6307\u53c2\u6570\u7684\u4e2a\u6570\u3001\u7c7b\u578b\u6216\u8005\u987a\u5e8f\uff09\u5fc5\u987b\u4e0d\u540c\u3002\u60a8\u4e0d\u80fd\u4ec5\u901a\u8fc7\u8fd4\u56de\u7c7b\u578b\u7684\u4e0d\u540c\u6765\u91cd\u8f7d\u51fd\u6570\u3002 V &at(K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(K const &k) const; // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u4f46\u662f\u4e0a\u9762\u8fd9\u4e24\u4e2a at \u51fd\u6570\u7684\u53c2\u6570\u7c7b\u578b\u90fd\u662f K const & \uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u91cd\u8f7d\u5462\uff1f \u6ce8\u610f\u770b\u7b2c\u4e8c\u4e2a\u7248\u672c\u6700\u540e\u9762\u591a\u4e86\u4e00\u4e2a const \u5173\u952e\u5b57\uff0c\u8fd9\u79cd\u5199\u6cd5\u662f\u4ec0\u4e48\u610f\u601d\uff1f\u5c0f\u5f6d\u8001\u5e08\u5bf9\u5176\u8fdb\u884c\u795b\u9b45\u5316\uff1a V &at(map *this, K const &k); // \u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at V const &at(map const *this, K const &k); // \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at \u539f\u6765\u52a0\u5728\u51fd\u6570\u62ec\u53f7\u540e\u9762\u7684 const\uff0c\u5b9e\u9645\u4e0a\u662f\u7528\u4e8e\u4fee\u9970 this \u6307\u9488\u7684\uff01 \u8be5\u5199\u6cd5\u4ec5\u4f9b\u793a\u610f\uff0c\u5e76\u4e0d\u662f\u771f\u7684\u53ef\u4ee5\u628a this \u5199\u6210\u53c2\u6570 \u6240\u4ee5\u4e24\u4e2a at \u7684\u53c2\u6570\u5217\u8868\u4e0d\u540c\uff0c\u4e0d\u540c\u5728\u4e8e\u4f20\u5165 this \u6307\u9488\u7684\u7c7b\u578b\uff0c\u6240\u4ee5\u53ef\u4ee5\u91cd\u8f7d\uff0c\u4e0d\u4f1a\u51b2\u7a81\u3002 \u5f53 map \u5bf9\u8c61\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map const * \uff0c\u6240\u4ee5\u53ea\u80fd\u8c03\u7528\u7b2c\u4e8c\u4e2a\u7248\u672c\u7684 at\u3002 \u5f53 map \u5bf9\u8c61\u4e0d\u4e3a const \u65f6\uff0c\u4f20\u5165\u7684 this \u6307\u9488\u4e3a map * \uff0c\u4e24\u4e2a\u91cd\u8f7d\u90fd\u53ef\u4ee5\u8c03\u7528\uff0c\u4f46\u7531\u4e8e\u7b2c\u4e00\u4e2a\u91cd\u8f7d\u66f4\u52a0\u7b26\u5408\uff0c\u6240\u4ee5\u4f1a\u8c03\u7528\u7b2c\u4e00\u4e2a\u7248\u672c\u7684 at\u3002 \u6709\u8da3\u7684\u662f\uff0cC++23 \u652f\u6301\u4e86\u663e\u5f0f\u5bf9\u8c61\u5f62\u53c2\uff08deducing-this\uff09\uff0cthis \u4e5f\u80fd\u50cf\u666e\u901a\u53c2\u6570\u4e00\u6837\u5b9a\u4e49\u4e86\uff01\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u4ee5\u5199\u6210\uff1a class map { ... V &at(this map &self, K const &k) { // \u51fd\u6570\u4f53\u5185\u53ef\u4ee5\u4f7f\u7528self\u4ee3\u66ff\u539f\u6765\u7684this\uff08this\u5c06\u4e0d\u518d\u53ef\u7528\uff09 ... } V const &at(this map const &self, K const &k) { ... } }; \u521a\u521a\u89e3\u91ca\u4e86\u51fd\u6570\u91cd\u8f7d\uff0c\u90a3\u4e48\u8fd0\u7b97\u7b26\u91cd\u8f7d\u5462\uff1f \u56e0\u4e3a\u539f\u672c C \u8bed\u8a00\u5c31\u6709 [] \u8fd0\u7b97\u7b26\uff0c\u4e0d\u8fc7\u90a3\u53ea\u9002\u7528\u4e8e\u539f\u59cb\u6307\u9488\u548c\u539f\u59cb\u6570\u7ec4\u3002\u800c C++ \u5141\u8bb8\u4e5f [] \u8fd0\u7b97\u7b26\u652f\u6301\u5176\u4ed6\u7528\u6237\u81ea\u5b9a\u4e49\u7c7b\u578b\uff08\u6bd4\u5982 std::map\uff09\uff0c\u548c C \u8bed\u8a00\u81ea\u5e26\u7684\u76f8\u6bd4\u5c31\u53ea\u6709\u53c2\u6570\u7c7b\u578b\u4e0d\u540c\uff08\u4e00\u4e2a\u662f\u539f\u59cb\u6570\u7ec4\uff0c\u4e00\u4e2a\u662f std::map\uff09\uff0c\u6240\u4ee5\u548c\u51fd\u6570\u91cd\u8f7d\u5f88\u76f8\u4f3c\uff0c\u8fd9\u5c31\u662f\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 m[\"key\"]; \u4f1a\u88ab\u7f16\u8bd1\u5668\u201c\u7ffb\u8bd1\u201d\u6210\uff1a m.operator[](\"key\"); \u4ee5\u4e0a\u4ee3\u7801\u5e76\u975e\u4ec5\u4f9b\u793a\u610f\uff0c\u662f\u53ef\u4ee5\u901a\u8fc7\u7f16\u8bd1\u8fd0\u884c\u7684\u3002 operator[] \u867d\u7136\u770b\u8d77\u6765\u5f88\u590d\u6742\u4e00\u4e2a\u5173\u952e\u5b57\u52a0\u7279\u6b8a\u7b26\u53f7\uff0c\u5176\u5b9e\u65e0\u975e\u5c31\u662f\u4e2a\u7279\u6b8a\u7684\u51fd\u6570\u540d\uff0c\u5b66\u8fc7 Python \u7684\u7ae5\u978b\u53ef\u4ee5\u628a\u4ed6\u60f3\u8c61\u6210 __getitem__ \u3002 V &operator[](K const &k); \u7ed3\u8bba\uff1a[] \u8fd0\u7b97\u7b26\u5b9e\u9645\u4e0a\u662f\u5728\u8c03\u7528 operator[] \u51fd\u6570\u3002 \u6240\u6709\u7684\u6240\u8c13\u201c\u8fd0\u7b97\u7b26\u91cd\u8f7d\u51fd\u6570\u201d\u5b9e\u9645\u4e0a\u90fd\u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u6807\u8bc6\u7b26\uff0c\u4ee5 operator + \u8fd0\u7b97\u7b26\u7684\u5f62\u5f0f\uff0c\u4ed6\u4eec\u4e24\u4e2a\u7ec4\u6210\u4e00\u4e2a\u6574\u4f53\uff0c\u4f60\u8fd8\u53ef\u4ee5\u8bd5\u8bd5 string(\"hel\").operator+(\"lo\") \uff0c\u548c string(\"hel\") + \"lo\" \u662f\u7b49\u4ef7\u7684\u3002 \u56e0\u4e3a operator[] \u8fd9\u4e2a\u6210\u5458\u51fd\u6570\u540e\u9762\u6ca1\u6709 const \u4fee\u9970\uff0c\u56e0\u6b64\u5f53 map \u4fee\u9970\u4e3a const \u65f6\u7f16\u8bd1\u4f1a\u4e0d\u901a\u8fc7 1 \uff1a const map config = { // \u6b64\u5904\u5982\u679c\u662f\u5e26 const & \u4fee\u9970\u7684\u51fd\u6570\u53c2\u6570\u4e5f\u662f\u540c\u7406 {\"timeout\", 985}, {\"delay\", 211}, }; print(config[\"timeout\"]); // \u7f16\u8bd1\u51fa\u9519 /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp: In function \u2018int main()\u2019: /home/bate/Codes/course/stlseries/stl_map/experiment/main.cpp:10:23: error: passing \u2018const std::map, int>\u2019 as \u2018this\u2019 argument discards qualifiers [-fpermissive] 10 | print(config[\"timeout\"]); \u7f16\u8bd1\u5668\u8bf4 discards qualifiers\uff0c\u610f\u601d\u662f map \u6709 const \u4fee\u9970\uff0c\u4f46\u662f operator[] \u6ca1\u6709\u3002 \u8fd9\u5b9e\u9645\u4e0a\u5c31\u662f\u5728\u8bf4\uff1a map const *this \u4e0d\u80fd\u8f6c\u6362\u6210 map *this \u3002 \u6709 const \u4fee\u9970\u7684 map \u4f5c\u4e3a this \u6307\u9488\u4f20\u5165\u6ca1 const \u4fee\u9970\u7684 operator[] \u51fd\u6570\uff0c\u662f\u51cf\u5c11\u4e86\u4fee\u9970\uff08discards qualifers\uff09\u3002 C++ \u89c4\u5b9a\u4f20\u53c2\u65f6\u53ea\u80fd\u589e\u52a0\u4fee\u9970\u4e0d\u80fd\u51cf\u5c11\u4fee\u9970\uff1a\u53ea\u80fd\u4ece map * \u8f6c\u6362\u5230 map const * \u800c\u4e0d\u80fd\u53cd\u4e4b\u3002 \u6240\u4ee5\u5bf9\u7740\u4e00\u4e2a const map \u8c03\u7528\u975e const \u7684\u6210\u5458\u51fd\u6570 operator[] \u5c31\u51fa\u9519\u4e86\uff0c\u76f8\u6bd4\u4e4b\u4e0b at() \u5c31\u53ef\u4ee5\u5728 const \u4fee\u9970\u4e0b\u7f16\u8bd1\u901a\u8fc7\u3002 \u4e3a\u4ec0\u4e48 operator[] \u662f\u975e const \u4fee\u9970\u7684\u5462\uff1f\u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u6210\u5458\u51fd\u6570\u4e0d\u662f const\uff0c\u610f\u5473\u7740\u4ed6\u4f1a \u5c31\u5730\u4fee\u6539 this \u5bf9\u8c61 \u3002 \u5176\u5b9e\uff0coperator[] \u53d1\u73b0\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff1a map config = { {\"timeout\", 985}, {\"delay\", 211}, }; print(config); print(config[\"tmeout\"]); // \u6709\u526f\u4f5c\u7528\uff01 print(config); {\"delay\": 211, \"timeout\": 985} 0 {\"delay\": 211, \"timeout\": 985, \"tmeout\": 0} \u4f1a\u81ea\u52a8\u521b\u5efa\u90a3\u4e2a\u4e0d\u5b58\u5728\u7684\u952e\u503c\uff01 \u4f60\u4ee5\u4e3a\u4f60\u53ea\u662f\u89c2\u5bdf\u4e86\u4e00\u4e0b map \u91cc\u7684 \u201ctmeout\u201d \u5143\u7d20\uff0c\u5374\u610f\u5916\u6539\u53d8\u4e86 map \u7684\u5185\u5bb9\uff0c\u859b\u5b9a\u8c14\u76f4\u547c\u5185\u884c\u3002 \u4e3a\u4ec0\u4e48\u628a [] \u8bbe\u8ba1\u7684\u8fd9\u4e48\u5371\u9669\uff1f \u65e2\u7136\u5df2\u7ecf\u6709\u66f4\u5b89\u5168\u7684 .at()\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u8ba9 [] \u7ee7\u7eed\u5b58\u5728\u5462\uff1f map config = { {\"delay\", 211}, }; config.at(\"timeout\") = 985; // \u952e\u503c\u4e0d\u5b58\u5728\uff0c\u62a5\u9519\uff01 config[\"timeout\"] = 985; // \u6210\u529f\u521b\u5efa\u5e76\u5199\u5165 985 \u7531\u4e0a\u53ef\u89c1\uff0c\u5f53\u6211\u4eec\u5199\u5165\u4e00\u4e2a\u672c\u4e0d\u5b58\u5728\u7684\u952e\u503c\u7684\u65f6\u5019\uff0c\u6070\u6070\u9700\u8981 [] \u7684\u201c\u81ea\u52a8\u521b\u5efa\u201d\u8fd9\u4e00\u7279\u6027\uff0c\u8fd9\u662f at() \u6240\u4e0d\u5177\u6709\u7684\u3002 \u603b\u7ed3\uff1a\u8bfb\u53d6\u65f6\u5e94\u8be5\u7528 at() \u66f4\u5b89\u5168\uff0c\u5199\u5165\u65f6\u624d\u9700\u8981\u7528\u5e26\u6709\u81ea\u52a8\u521b\u5efa\u529f\u80fd\u7684 []\u3002 \u8bb8\u591a\u7b2c\u4e09\u65b9\u5e93\uff0c\u4f8b\u5982 jsoncpp\uff0c\u4ed6\u4eec\u7684\u5b57\u5178\u7c7b\u578b\u4e5f\u4f7f\u7528\u7c7b\u4f3c\u7684\u63a5\u53e3\uff0cat() \u8d1f\u8d23\u8bfb\uff0c[] \u8d1f\u8d23\u5199\uff0c\u5206\u5de5\u660e\u786e\uff01","title":"\u5f00\u59cb\u4f7f\u7528 map \u5bb9\u5668"},{"location":"stl_map/#_18","text":"\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 at() \u5199\u5165\u5143\u7d20\u65f6\uff0c\u7edf\u4e00\u7528 [] auto val = m.at(\"key\"); m[\"key\"] = val; \u4e3a\u4ec0\u4e48\u5176\u4ed6\u8bed\u8a00\u6bd4\u5982 Python\uff0c\u53ea\u6709\u4e00\u4e2a [] \u5c31\u884c\u4e86\u5462\uff1f\u800c C++ \u9700\u8981\u4e24\u4e2a\uff1f \u56e0\u4e3a Python \u4f1a\u68c0\u6d4b [] \u4f4d\u4e8e\u7b49\u53f7\u5de6\u4fa7\u8fd8\u662f\u53f3\u4fa7\uff0c\u6839\u636e\u60c5\u51b5\u5206\u522b\u8c03\u7528 __getitem__ \u6216\u8005 __setitem__ \u3002 C++ \u7f16\u8bd1\u5668\u6ca1\u6709\u8fd9\u4e2a\u7279\u6b8a\u68c0\u6d4b\uff0c\u4e5f\u68c0\u6d4b\u4e0d\u4e86\uff0c\u56e0\u4e3a C++ \u7684 [] \u53ea\u662f\u8fd4\u56de\u4e86\u4e2a\u5f15\u7528\uff0c\u5e76\u4e0d\u77e5\u9053 [] \u51fd\u6570\u8fd4\u56de\u4ee5\u540e\uff0c\u4f60\u662f\u62ff\u8fd9\u4e2a\u5f15\u7528\u5199\u5165\u8fd8\u662f\u8bfb\u53d6\u3002\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\u4ed6\u9ed8\u8ba4\u4f60\u662f\u5199\u5165\uff0c\u6240\u4ee5\u5148\u5e2e\u4f60\u521b\u5efa\u4e86\u5143\u7d20\uff0c\u8fd4\u56de\u8fd9\u4e2a\u5143\u7d20\u7684\u5f15\u7528\uff0c\u8ba9\u4f60\u5199\u5165\u3002 \u800c Python \u7684\u5f15\u7528\u662f\u4e0d\u80fd\u7528 = \u8986\u76d6\u539f\u503c\u7684\uff0c\u90a3\u6837\u53ea\u4f1a\u8ba9\u53d8\u91cf\u6307\u5411\u65b0\u7684\u5f15\u7528\uff0c\u53ea\u80fd\u7528 .func() \u5f15\u7528\u6210\u5458\u51fd\u6570\u6216\u8005 += \u624d\u80fd\u5c31\u5730\u4fee\u6539\u539f\u53d8\u91cf\uff0c\u8fd9\u662f Python \u8fd9\u7c7b\u811a\u672c\u8bed\u8a00\u548c C++ \u6700\u672c\u8d28\u7684\u4e0d\u540c\u3002 \u603b\u800c\u8a00\u4e4b\uff0c\u6211\u4eec\u7528 C++ \u7684 map \u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u9700\u8981\u663e\u5f0f\u5730\u7528 at() \u544a\u8bc9\u7f16\u8bd1\u5668\u6211\u662f\u6253\u7b97\u8bfb\u53d6\u3002 [] \u627e\u4e0d\u5230\u5c31\u8fd4\u56de\u4e2a\u201c\u9ed8\u8ba4\u503c\u201d\uff0c\u5176\u5b9e\u4e5f\u662f\u5f88\u591a\u8bed\u8a00\u7684\u4f20\u7edf\u5f02\u80fd\u4e86\uff0c\u53ea\u6709\u521a\u597d Python \u6bd4\u8f83\u5bf9\u521d\u5b66\u8005\u53cb\u597d\uff0c\u4f1a\u81ea\u52a8\u5224\u65ad\u4f60\u7684 [] \u662f\u8bfb\u53d6\u8fd8\u662f\u5199\u5165\uff0c\u5982\u679c\u662f\u8bfb\u53d6\uff0c\u5f53\u627e\u4e0d\u5230\u952e\u503c\u65f6\u80fd\u53cb\u5584\u7684\u7ed9\u4f60\u62a5\u9519\u3002 \u8bed\u8a00\u53ca\u5176\u5173\u8054\u5bb9\u5668\u540d C++ map Python dict Lua table JS HashMap Java HashMap \u627e\u4e0d\u5230\u952e\u65f6\u7684\u884c\u4e3a \u9ed8\u9ed8\u8fd4\u56de 0 \u62a5\u9519 KeyError \u9ed8\u9ed8\u8fd4\u56de nil \u9ed8\u9ed8\u8fd4\u56de undefined .get()\uff0c\u9ed8\u9ed8\u8fd4\u56de null \u5176\u4e2d C++ \u7684 [] \u6700\u4e3a\u6076\u52a3\uff0c\u56e0\u4e3a\u53e4\u4ee3 C++ \u4e2d\u5e76\u6ca1\u6709\u4e00\u4e2a null \u6216 nil \u4e4b\u7c7b\u7684\u989d\u5916\u7279\u6b8a\u5e38\u91cf\u3002 [] \u8fd4\u56de\u7684\u5fc5\u987b\u662f\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u7531\u4e8e [] \u4e0d\u80fd\u62a5\u9519\uff0c\u503c\u7684\u7c7b\u578b\u53c8\u5343\u53d8\u4e07\u5316\uff0c map \u7684 [] \u53ea\u80fd\u8fd4\u56de\u201cV \u7c7b\u578b\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u7684\u503c\u201d\uff1a\u5bf9\u4e8e int \u800c\u8a00\u662f 0\uff0c\u5bf9\u4e8e string \u800c\u8a00\u662f \u201c\u201d\uff08\u7a7a\u5b57\u7b26\u4e32\uff09\u3002 \u4e5f\u6b63\u56e0\u5982\u6b64\uff0c\u5982\u679c\u4e00\u4e2a map \u4e2d\u7684 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5c31\u65e0\u6cd5\u4f7f\u7528 [] \u4e86\u3002\u770b\u4f3c\u7f8e\u597d\u7684 [] \u53ea\u662f\u9a97\u9a97\u5c0f\u5f6d\u53cb\u7684\u9762\u5b50\u5de5\u7a0b\uff0c\u6a21\u68f1\u4e24\u53ef\uff0c\u5145\u6ee1\u5371\u9669\u3002\u9ad8\u624b\u90fd\u4f7f\u7528\u66f4\u4e13\u4e1a\u7684\u5199\u5165\u51fd\u6570\uff1ainsert \u6216 insert_or_assign \u4ee3\u66ff\u3002\u8fd9\u4e24\u4e2a\u51fd\u6570\u4e0d\u9700\u8981\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u66f4\u9ad8\u6548\u4e00\u4e9b\uff0c\u7a0d\u540e\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u3002 at \u4e0e [] \u5b9e\u6218\u6f14\u7ec3 \u6211\u4eec\u73b0\u5728\u7684\u7532\u65b9\u662f\u4e00\u4e2a\u5b66\u6821\u7684\u5927\u8001\u677f\uff0c\u4ed6\u5e0c\u671b\u8ba9\u6211\u4eec\u7ba1\u7406\u5b66\u751f\u4fe1\u606f\uff0c\u56e0\u6b64\u9700\u8981\u5efa\u7acb\u4e00\u4e2a\u6620\u5c04\u8868\uff0c\u80fd\u591f\u5feb\u901f\u901a\u8fc7\u5b66\u751f\u540d\u5b57\u67e5\u8be2\u5230\u76f8\u5e94\u7684\u5b66\u751f\u4fe1\u606f\u3002\u601d\u6765\u60f3\u53bb C++ \u6807\u51c6\u5e93\u4e2d\u7684 map \u5bb9\u5668\u6700\u5408\u9002\u3002\u51b3\u5b9a\u8bbe\u8ba1\u5982\u4e0b\uff1a \u952e\u4e3a\u5b66\u751f\u7684\u540d\u5b57\uff0cstring \u7c7b\u578b\u3002 \u503c\u4e3a\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7ed3\u6784\u4f53\uff0cStudent \u7c7b\u578b\uff0c\u91cc\u9762\u5b58\u653e\u5404\u79cd\u5b66\u751f\u4fe1\u606f\u3002 \u7136\u540e\u81ea\u5b9a\u4e49\u4e00\u4e0b Student \u7ed3\u6784\u4f53\uff0c\u73b0\u5728\u628a\u9664\u4e86\u540d\u5b57\u4ee5\u5916\u7684\u5b66\u751f\u4fe1\u606f\u90fd\u585e\u5230\u8fd9\u4e2a\u7ed3\u6784\u4f53\u91cc\u3002 \u521b\u5efa map \u5bf9\u8c61\uff0c\u53d8\u91cf\u540d\u4e3a stus \uff0c\u8fd9\u4e2a map \u5c31\u662f\u7532\u65b9\u8981\u6c42\u7684\u5b66\u751f\u8868\uff0c\u6210\u529f\u4ea4\u5dee\u3002 struct Student { int id; // \u5b66\u53f7 int age; // \u5e74\u9f84 string sex; // \u6027\u522b int money; // \u5b58\u6b3e set skills; // \u6280\u80fd }; map stus; \u73b0\u5728\u5c0f\u5f6d\u8001\u5e08\u548c\u4ed6\u7684\u7ae5\u978b\u4eec\u8981\u8fdb\u5165\u8fd9\u5bb6\u5b66\u6821\u4e86\uff0c\u8ba9\u6211\u4eec\u7528 [] \u5927\u6cd5\u63d2\u5165\u4ed6\u7684\u4e2a\u4eba\u4fe1\u606f\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = Student{20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = Student{20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = Student{20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = Student{20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u7531\u4e8e C++11 \u5141\u8bb8\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b\u4e0d\u5199\uff0c\u6240\u4ee5 Student \u53ef\u4ee5\u7701\u7565\uff0c\u7b80\u5199\u6210\uff1a stus[\"\u5f6d\u4e8e\u658c\"] = {20220301, 22, \"\u81ea\u5b9a\u4e49\", {\"C\", \"C++\"}}; stus[\"\u76f8\u4f9d\"] = {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}; stus[\"\u6a31\u82b1\u7c89\u871c\u7cd6\"] = {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}; stus[\"Sputnik02\"] = {20220301, 19, \"\u7537\", 4000, {\"C++\"}}; \u53c8\u7531\u4e8e map \u652f\u6301\u5728\u521d\u59cb\u5316\u65f6\u5c31\u6307\u5b9a\u6240\u6709\u5143\u7d20\uff0c\u6211\u4eec\u76f4\u63a5\u5199\uff1a map stus = { {\"\u5f6d\u4e8e\u658c\", {20220301, 22, \"\u81ea\u5b9a\u4e49\", 1000, {\"C\", \"C++\"}}}, {\"\u76f8\u4f9d\", {20220301, 21, \"\u7537\", 2000, {\"Java\", \"C\"}}}, {\"\u6a31\u82b1\u7c89\u871c\u7cd6\", {20220301, 20, \"\u5973\", 3000, {\"Python\", \"CUDA\"}}}, {\"Sputnik02\", {20220301, 19, \"\u7537\", 4000, {\"C++\"}}}, }; \u73b0\u5728\u7532\u65b9\u8981\u6c42\u6dfb\u52a0\u4e00\u4e2a\u201c\u57f9\u8bad\u201d\u51fd\u6570\uff0c\u7528\u4e8e\u4ed6\u4eec\u7684 C++ \u57f9\u8bad\u8bfe\u3002 \u57f9\u8bad\u51fd\u6570\u7684\u53c2\u6570\u4e3a\u5b57\u7b26\u4e32\uff0c\u8868\u793a\u8981\u6d88\u8d39\u5b66\u751f\u7684\u540d\u5b57\u3002\u5982\u679c\u8be5\u540d\u5b57\u5b66\u751f\u4e0d\u5b58\u5728\uff0c\u5219\u5e94\u8be5\u53ca\u65f6\u62a5\u9519\u3002 \u6bcf\u6b21\u57f9\u8bad\u9700\u8981\u6d88\u8d39 2650 \u5143\uff0c\u6d88\u8d39\u6210\u529f\u540e\uff0c\u5f80\u6280\u80fd skills \u96c6\u5408\u4e2d\u52a0\u5165 \u201cC++\u201d\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u8fd9\u662f\u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 stu.money -= 2650; stu.skills.insert(\"C++\"); } \u7136\u800c\uff0c\u8fd9\u6837\u5199\u662f\u4e0d\u5bf9\u7684\uff01 stus.at(stuName) \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528 Student & \u6307\u5411 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u3002\u4f46\u662f\u7b49\u53f7\u5de6\u4fa7\uff0c\u5374\u662f\u4e2a\u4e0d\u5e26\u4efb\u4f55\u4fee\u9970\u7684 auto \uff0c\u4ed6\u4f1a\u88ab\u63a8\u5bfc\u4e3a Student \u3002\u5982\u4f55\u4ece\u4e00\u4e2a\u5f15\u7528 Student & \u8f6c\u6362\u4e3a\u5177\u4f53\u7684 Student \uff1f\u627e\u4e0d\u5230 Student(Student &) \uff0c\u4f46\u662f\u627e\u5230\u4e86\u6700\u63a5\u8fd1\u7684 Student(Student const &) \u51fd\u6570\uff08\u8fd9\u662f\u7f16\u8bd1\u5668\u81ea\u52a8\u751f\u6210\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff09\uff0c\u56e0\u6b64\u6211\u4eec\u62f7\u8d1d\u4e86\u4e00\u4efd map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\uff0c\u5230\u6808\u4e0a\u7684 stu \u53d8\u91cf\uff0c\u4e4b\u540e\u4e0d\u8bba\u5982\u4f55\u4fee\u6539\uff0c\u4fee\u6539\u7684\u90fd\u662f\u8fd9\u4e2a\u6808\u4e0a\u5bf9\u8c61\uff0c\u800c\u4e0d\u4f1a\u5bf9 map \u4e2d\u7684\u5b66\u751f\u5bf9\u8c61\u4ea7\u751f\u4efb\u4f55\u5f71\u54cd\u3002 \u7ed3\u8bba\uff1a\u628a\u5f15\u7528\u4fdd\u5b58\u5230\u666e\u901a\u53d8\u91cf\u4e2d\uff0c\u5219\u5f15\u7528\u4f1a\u9000\u5316\uff0c\u9020\u6210\u6df1\u62f7\u8d1d\uff01\u4e0d\u4ec5\u5f71\u54cd\u6027\u80fd\uff0c\u8fd8\u5f71\u54cd\u529f\u80fd\uff01stu \u5df2\u7ecf\u662f\u4e00\u4e2a\u72ec\u7acb\u7684 Student \u5bf9\u8c61\uff0c\u5bf9 stu \u7684\u4fee\u6539\u5df2\u7ecf\u4e0d\u4f1a\u5f71\u54cd\u5230 stus.at(stuName) \u6307\u5411\u7684\u90a3\u4e2a Student \u5bf9\u8c61\u4e86\u3002 \u6b64\u65f6\u4f60\u5bf9\u8fd9\u4e2a\u666e\u901a\u53d8\u91cf\u7684\u6240\u6709\u4fee\u6539\uff0c\u90fd\u4e0d\u4f1a\u540c\u6b65\u5230 map \u4e2d\u7684\u90a3\u4e2a Student \u4e2d\u53bb\uff01 \u6211\u4eec\u73b0\u5728\u5bf9\u76f8\u4f9d\u7ae5\u978b\u8fdb\u884c C++ \u57f9\u8bad\uff1a PeiXunCpp(\"\u76f8\u4f9d\"); print(stus.at(\"\u76f8\u4f9d\")); \u7ed3\u679c\u53d1\u73b0\u4ed6\u7684\u5b58\u6b3e\u4e00\u5206\u6ca1\u5c11\uff0c\u4e5f\u6ca1\u5b66\u4f1a C++\uff1a {id: 20220302, age: 21, sex: \"\u7537\", money: 2000, skills: {\"C\", \"Java\"}} \u770b\u6765\u6211\u4eec\u7684\u4fee\u6539\u6ca1\u6709\u5728 map \u4e2d\u751f\u6548\uff1f\u539f\u6765\u662f\u56e0\u4e3a\u6211\u4eec\u5728 PeiXunCpp \u51fd\u6570\u91cc\uff1a auto stu = stus.at(stuName); // \u5728\u6808\u4e0a\u62f7\u8d1d\u4e86\u4e00\u4efd\u5b8c\u6574\u7684 Student \u5bf9\u8c61 \u4e00\u4e0d\u5c0f\u5fc3\u5c31\u7528\u4e86\u201c\u514b\u9686\u4eba\u201d\u6280\u672f\uff01\u4ece\u5b66\u751f\u8868\u91cc\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\uff0c\u514b\u9686\u4e86\u4e00\u4efd\u653e\u5230\u6808\u4e0a\u7684\u201c\u76f8\u4f9d2\u53f7\u201d\uff01 \u7136\u540e\u6211\u4eec\u6263\u4e86\u8fd9\u4e2a\u4e34\u65f6\u514b\u9686\u4eba\u201c\u76f8\u4f9d2\u53f7\u201d\u7684\u94b1\uff0c\u5e76\u7ed9\u4ed6\u57f9\u8bad C++ \u6280\u672f\u3002 \u7136\u800c\u6211\u4eec\u57f9\u8bad\u7684\u662f\u6808\u4e0a\u7684\u4e34\u65f6\u53d8\u91cf\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u514b\u9686\u524d\u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5e76\u6ca1\u6709\u53d7\u5230\u57f9\u8bad\uff0c\u4e5f\u6ca1\u6709\u6263\u94b1\u3002 \u7136\u540e\u5462\uff1f\u6b8b\u5fcd\u7684\u4e8b\u60c5\u53d1\u751f\u4e86\uff01\u5728\u5c0f\u5f6d\u8001\u5e08\u4e00\u901a\u64cd\u4f5c\u57f9\u8bad\u5b8c\u201c\u76f8\u4f9d2\u53f7\u201d\u540e\uff0c\u6211\u4eec\u628a\u4ed6\u9001\u4e0a\u65ad\u5934\u53f0\u2014\u2014\u6790\u6784\u4e86\uff01 \u800c\u8fd9\u4e00\u5207\u201c\u76f8\u4f9d1\u53f7\u201d\u5b8c\u5168\u4e0d\u77e5\u60c5\uff0c\u4ed6\u53ea\u77e5\u9053\u6709\u4eba\u558a\u4ed6\u505a\u514b\u9686\uff0c\u7136\u540e\u5c31\u56de\u5bb6\u73a9 Java \u53bb\u4e86\uff0c\u5e76\u6ca1\u6709\u57f9\u8bad C++ \u7684\u8bb0\u5fc6\u3002 \u8981\u9632\u6b62\u5f15\u7528\u9000\u5316\u6210\u666e\u901a\u53d8\u91cf\uff0c\u9700\u8981\u628a\u53d8\u91cf\u7c7b\u578b\u4e5f\u6539\u6210\u5f15\u7528\uff01\u8fd9\u79cd\u662f\u6d45\u62f7\u8d1d\uff0cstu \u548c stus.at(stuName) \u6307\u5411\u7684\u4ecd\u7136\u662f\u540c\u4e00\u4e2a Student \u5bf9\u8c61\u3002\u7528 auto \u6355\u83b7\u7684\u8bdd\uff0c\u6539\u6210 auto & \u5c31\u884c\u3002 void PeiXunCpp(string stuName) { auto &stu = stus.at(stuName); // \u5728\u6808\u4e0a\u521b\u5efa\u4e00\u4e2a\u6307\u5411\u539f Student \u5bf9\u8c61\u7684\u5f15\u7528 stu.money -= 2650; stu.skills.insert(\"C++\"); } {id: 20220302, age: 21, sex: \"\u7537\", money: -650, skills: {\"C\", \"C++\", \"Java\"}} \u7ec8\u4e8e\uff0c\u6b63\u7248\u201c\u76f8\u4f9d1\u53f7\u201d\u672c\u4f53\u978b\u5e9f\u4e86 C++\uff01 \u4e4b\u540e\u5982\u679c\u518d\u4ece\u201c\u76f8\u4f9d1\u53f7\u201d\u8eab\u4e0a\u514b\u9686\uff0c\u514b\u9686\u51fa\u6765\u7684\u201c\u76f8\u4f9dn\u53f7\u201d\u4e5f\u90fd\u4f1a\u5177\u6709\u57f9\u8bad\u8fc7 C++ \u7684\u8bb0\u5fc6\u4e86\u3002 \u5f15\u7528\u76f8\u5f53\u4e8e\u8eab\u4efd\u8bc1\uff0c\u6211\u4eec\u590d\u5370\u4e86\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\uff0c\u8eab\u4efd\u8bc1\u4e0d\u4ec5\u590d\u5370\u8d77\u6765\u6bd4\u514b\u9686\u4e00\u4e2a\u5927\u6d3b\u4eba\u5bb9\u6613\uff08\u62f7\u8d1d\u5f00\u9500\uff09\u4ece\u800c\u63d0\u5347\u6027\u80fd\uff0c\u800c\u4e14\u901a\u8fc7\u8eab\u4efd\u8bc1\u53ef\u4ee5\u627e\u5230\u672c\u4eba\uff0c\u5bf9\u8eab\u4efd\u8bc1\u7684\u4fee\u6539\u4f1a\u88ab\u7f16\u8bd1\u5668\u81ea\u52a8\u6539\u4e3a\u5bf9\u672c\u4eba\u7684\u4fee\u6539\uff0c\u4f8b\u5982\u901a\u8fc7\u201c\u76f8\u4f9d\u201d\u7684\u8eab\u4efd\u8bc1\u5728\u94f6\u884c\u5f00\u5361\u7b49\uff0c\u94f6\u884c\u8981\u7684\u662f\u8eab\u4efd\u8bc1\uff0c\u4e0d\u662f\u514b\u9686\u4eba\u54e6\u3002 \u5f15\u7528\u662f\u4e00\u4e2a\u70eb\u624b\u7684\u9999\u9999\u9762\u5305\uff0c\u666e\u901a\u53d8\u91cf\u5c31\u50cf\u4e00\u4e2a\u81ed\u81ed\u7684\u7b54\u8fa9\u9a6c\u6876\uff0c\u628a\u9762\u5305\u653e\u5230\u9a6c\u6876\uff08auto\uff09\u91cc\uff0c\u9762\u5305\u5c31\u81ed\u6389\uff0c\u8150\u70c2\u6389\uff0c\u4e0d\u80fd\u5403\u4e86\uff01\u8981\u8ba9\u9762\u5305\u8f6c\u79fb\u9635\u5730\u4e86\u4ee5\u540e\u4f9d\u7136\u597d\u5403\uff0c\u9700\u8981\u653e\u5230\u4fdd\u9c9c\u76d2\uff08auto &\uff09\u91cc\u3002 \u8fd9\u5c31\u662f C++ \u7684 decay\uff08\u4e2d\u6587\u521a\u597d\u662f\u201c\u9000\u5316\u201d\u3001\u201c\u53d8\u8d28\u201d\u7684\u610f\u601d\uff09\u89c4\u5219\u3002 \u4ee5\u4e0b\u90fd\u662f\u201c\u9999\u9999\u9762\u5305\u201d\uff0c\u653e\u8fdb\u9a6c\u6876\u91cc\u4f1a\u53d8\u8d28\uff1a T & \u4f1a\u53d8\u8d28\u6210 T \uff08\u5f15\u7528\u53d8\u8d28\u6210\u666e\u901a\u53d8\u91cf\uff09 T [] \u4f1a\u53d8\u8d28\u6210 T * \uff08\u6570\u7ec4\u53d8\u8d28\u6210\u9996\u5730\u5740\u6307\u9488\uff09 T () \u4f1a\u53d8\u8d28\u6210 T (*)() \uff08\u51fd\u6570\u53d8\u8d28\u6210\u51fd\u6570\u6307\u9488\uff09 \u5728\u51fd\u6570\u7684\u53c2\u6570\u4e2d\u3001\u51fd\u6570\u7684\u8fd4\u56de\u503c\u4e2d\u3001auto \u6355\u83b7\u7684\u53d8\u91cf\u4e2d\uff0c\u653e\u5165\u8fd9\u4e9b\u201c\u9999\u9999\u9762\u5305\u201d\u90fd\u4f1a\u53d1\u751f\u53d8\u8d28\uff01 \u5982\u4f55\u907f\u514d\u53d8\u8d28\uff1f\u90a3\u5c31\u4e0d\u8981\u7528\u9a6c\u6876\uff08\u666e\u901a\u53d8\u91cf\uff09\u88c5\u9762\u5305\u5457\uff01\u7528\u4fdd\u9c9c\u76d2\uff08\u5f15\u7528\u53d8\u91cf\uff09\u88c5\uff01 \u907f\u514d\u5f15\u7528 T &t \u53d8\u8d28\uff0c\u5c31\u5f97\u628a\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u6539\u6210\u5f15\u7528\uff0c\u6216\u8005\u7528 auto & \uff0c auto const & \u6355\u83b7\u624d\u884c\u3002 \u907f\u514d\u539f\u751f\u6570\u7ec4 T t[N] \u53d8\u8d28\uff0c\u4e5f\u53ef\u4ee5\u6539\u6210\u5f15\u7528 T (&t)[N] \uff0c\u4f46\u6bd4\u8f83\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u5c01\u88c5\u7684\u5b89\u5168\u9759\u6001\u6570\u7ec4 array \u6216 C++98 \u5c31\u6709\u7684\u5b89\u5168\u52a8\u6001\u6570\u7ec4 vector \u3002 \u907f\u514d\u51fd\u6570 T f() \u53d8\u8d28\uff0c\u53ef\u4ee5 T (&f)() \uff0c\u4f46\u7e41\u7410\uff0c\u4e0d\u5982\u76f4\u63a5\u6539\u7528 C++11 \u7684\u51fd\u6570\u5bf9\u8c61 function \u3002","title":"\u603b\u7ed3"},{"location":"stl_map/#c","text":"\u9898\u5916\u8bdd\uff1a\u90aa\u6076\u7684\u9000\u5316\u89c4\u5219\u9020\u6210\u7a7a\u60ac\u6307\u9488\u7684\u6848\u4f8b typedef double arr_t[10]; auto func(arr_t val) { arr_t ret; memcpy(ret, val, sizeof(arr_t)); // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; // double [10] \u81ea\u52a8\u53d8\u8d28\u6210 double * } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); // \u6b64\u5904 auto \u4f1a\u88ab\u63a8\u5bfc\u4e3a double * print(std::span(ret, ret + 10)); return 0; } Segmentation fault (core dumped) \u5c0f\u65f6\u5019\u770b\u8fd9\u96c6 ^{14}C ^{14}C \u8bed\u8a00\u201c\u8870\u53d8\u201d\u5bfc\u81f4\u7a0b\u5e8f Segmentation fault \u4e86\u3002 \u4fee\u590d\u65b9\u6cd5\uff1a\u522b\u518d\u7528 C \u8bed\u8a00\u7684\u715e\u7b14\u539f\u59cb\u4eba\u6570\u7ec4\u4e86\uff01\u7528 C++ \u5c01\u88c5\u597d\u7684 array\uff0c\u65e0\u9690\u60a3 typedef std::array arr_t; // \u5982\u9700\u52a8\u6001\u957f\u5ea6\uff0c\u6539\u7528 vector \u4ea6\u53ef auto func(arr_t val) { arr_t ret; ret = val; // \u5bf9 val \u505a\u4e00\u4e9b\u8fd0\u7b97, \u628a\u8ba1\u7b97\u7ed3\u679c\u4fdd\u5b58\u5230 ret return ret; } int main() { arr_t val = {1, 2, 3, 4}; auto ret = func(val); print(ret); return 0; } {1, 2, 3, 4, 0, 0, 0, 0, 0, 0} \u5982\u679c\u4f60\u8fd8\u662f\u5b66\u4e0d\u4f1a\u600e\u4e48\u4fdd\u7559\u9999\u9999\u5f15\u7528\u7684\u8bdd\uff0c\u571f\u529e\u6cd5\uff1a\u4e5f\u53ef\u4ee5\u5728\u4fee\u6539\u540e\u518d\u6b21\u7528 [] \u5199\u56de\u5b66\u751f\u8868\u3002\u8fd9\u6837\u5b66\u751f\u8868\u91cc\u4e0d\u4f1a C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u5c31\u4f1a\u88ab\u6211\u4eec\u6808\u4e0a\u57f9\u8bad\u8fc7 C++ \u7684\u201c\u76f8\u4f9d1\u53f7\u201d\u8986\u76d6\uff0c\u73b0\u5728\u5b66\u751f\u8868\u91cc\u7684\u4e5f\u662f\u6709 C++ \u6280\u80fd\u7684\u201c\u76f8\u4f9d\u201d\u8fa3\uff01\u53ea\u4e0d\u8fc7\u9700\u8981\u7ffb\u6765\u8986\u53bb\u514b\u9686\u4e86\u597d\u51e0\u6b21\u6bd4\u8f83\u4f4e\u6548\u800c\u5df2\uff0c\u81f3\u5c11\u80fd\u7528\u4e86\uff0c\u5efa\u8bae\u53ea\u6709\u5b66\u4e0d\u61c2\u5f15\u7528\u7684\u7ae5\u978b\u518d\u7528\u8fd9\u79cd\u4fdd\u5e95\u5199\u6cd5\u3002 void PeiXunCpp(string stuName) { auto stu = stus.at(stuName); // \u514b\u9686\u4e86\u4e00\u4efd\u201c\u76f8\u4f9d2\u53f7\u201d stu.money -= 2650; stu.skills.insert(\"C++\"); stus[stuName] = stu; // \u201c\u76f8\u4f9d2\u53f7\u201d\u593a\u820d\uff0c\u628a\u201c\u76f8\u4f9d1\u53f7\u201d\u7ed9\u8986\u76d6\u6389\u4e86 } \u72c2\u60f3\uff1a\u5982\u679c\u514b\u9686\u201c\u76f8\u4f9d1\u53f7\u201d\u540c\u5b66\uff0c\u5f97\u5230\u201c\u76f8\u4f9d2\u53f7\u201d\uff0c\u7136\u540e\u628a\u539f\u6765\u7684\u6740\u2026\u2026\u554a\u4e0d\u5bf9\uff0c\u201c\u6790\u6784\u201d\u6389\uff0c\u7136\u540e\u5bf9\u5916\u8c0e\u79f0\u201c\u8fd9\u8fd8\u662f\u539f\u6765\u7684\u76f8\u4f9d1\u53f7\u5440\uff01\u201d\u4f1a\u4e0d\u4f1a\u88ab\u53d1\u73b0\u5462\uff1f \u8111\u7b4b\u6025\u8f6c\u5f2f\uff1a\u4e0a\u9762\u4ee3\u7801\u7b2c 5 \u884c\u4e5f\u53ef\u4ee5\u6539\u7528 at\uff0c\u4e3a\u4ec0\u4e48\uff1f\u5c0f\u5f6d\u8001\u5e08\u4e0d\u662f\u8bf4 \u201cat \u7528\u4e8e\u8bfb\u53d6\uff0c[] \u7528\u4e8e\u5199\u5165\u201d \u5417\uff1f \u6211\u4eec\u7ae5\u978b\u8981\u5b66\u4f1a\u53d8\u901a\uff01\u5c0f\u5f6d\u8001\u5e08\u8b66\u544a\u8bf4 \u201c[] \u53ea\u80fd\u7528\u4e8e\u5199\u5165\u201d\uff0c\u662f\u56e0\u4e3a\u6211\u4eec\u5e73\u65f6\u7684\u5199\u5165\uff0c\u5b9e\u9645\u4e0a\u90fd\u662f\u9700\u8981\u5199\u5165\u5230\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u5143\u7d20\uff0c\u6240\u4ee5 [] \u4f1a\u81ea\u52a8\u521b\u5efa\u5143\u7d20\u5c31\u5f88\u65b9\u4fbf\uff1b\u5982\u679c\u662f at() \u5c31\u4e0d\u7b26\u5408\u201c\u5199\u5165\u65f6\u81ea\u52a8\u521b\u5efa\u4e0d\u5b58\u5728\u7684\u952e\u201c\u3002\u4f46\u662f\u73b0\u5728\u7684\u60c5\u51b5\u662f\u6211\u4eec\u7b2c 2 \u884c\u5df2\u7ecf\u8bbf\u95ee\u8fc7 at(\"\u76f8\u4f9d\") \uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u786e\u8ba4 \"\u76f8\u4f9d\" \u5df2\u7ecf\u5b58\u5728\u4e86\uff0c\u56e0\u6b64\u6211\u5199\u5165\u7684\u4e00\u5b9a\u662f\u4e2a\u5df2\u7ecf\u5b58\u5728\u7684\u5143\u7d20\uff0c\u8fd9\u65f6 [] \u548c at \u5df2\u7ecf\u6ca1\u533a\u522b\u4e86\uff0c\u6240\u4ee5\u7528 at \u7684\u975e const \u91cd\u8f7d\uff0c\u4e00\u6837\u53ef\u4ee5\u5199\u5165\u3002 \u6211\u4eec\u7ae5\u978b\u4e0d\u662f\u53bb\u6b7b\u8bb0\u786c\u80cc\u300a\u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55\u300b\uff0c\u628a\u5c0f\u5f6d\u8001\u5e08\u540d\u8a00\u5f53\u505a\u201c\u4e24\u4e2a\u51e1\u662f\u201d\u5723\u7ecf\u3002\u8981\u7406\u89e3\u5c0f\u5f6d\u8001\u5e08\u4f1a\u8fd9\u4e48\u8bf4\u7684\u539f\u56e0\u662f\u4ec0\u4e48\uff0c\u8fd9\u6837\u624d\u80fd\u6839\u636e\u4e0d\u540c\u5b9e\u9645\u60c5\u51b5\uff0c\u5b9e\u4e8b\u6c42\u662f\u770b\u95ee\u9898\uff0c\u624d\u662f\u7b26\u5408\u5c0f\u5f6d\u8001\u5e08\u552f\u7269\u7f16\u7a0b\u89c2\u7684\uff08\u5b5d\uff09 \u5982\u679c\u8981\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u5462\uff1f\u90a3\u5c31\u4ee5\u5b66\u53f7\u4e3a\u952e\uff0c\u7136\u540e\u628a\u5b66\u751f\u59d3\u540d\u653e\u5230 Student \u7ed3\u6784\u4f53\u4e2d\u3002 \u5982\u679c\u540c\u65f6\u6709\u6839\u636e\u5b66\u53f7\u8fdb\u884c\u67e5\u627e\u548c\u6839\u636e\u59d3\u540d\u67e5\u627e\u4e24\u79cd\u9700\u6c42\u5462\uff1f \u540c\u65f6\u9ad8\u6548\u5730\u6839\u636e\u591a\u4e2a\u952e\u8fdb\u884c\u67e5\u627e\uff0c\u751a\u81f3\u6307\u5b9a\u5404\u79cd\u6761\u4ef6\uff0c\u6bd4\u5982\u67e5\u8be2\u6240\u6709\u4f1a C++ \u7684\u5b66\u751f\u7b49\uff0c\u8fd9\u53ef\u4e0d\u662f map \u80fd\u641e\u5b9a\u7684\uff0c\u6216\u8005\u8bf4\u80fd\u641e\u5b9a\u4f46\u4e0d\u9ad8\u6548\uff08\u6700\u540e\u5f80\u5f80\u53ea\u80fd\u66b4\u529b\u904d\u5386\u67e5\u627e\uff0c\u65f6\u95f4\u590d\u6742\u5ea6\u592a\u9ad8\uff09\u3002\u8fd9\u662f\u4e2a\u4e13\u95e8\u7684\u7814\u7a76\u9886\u57df\uff0c\u79f0\u4e3a\uff1a\u5173\u7cfb\u6570\u636e\u5e93\u3002 \u5173\u7cfb\u6570\u636e\u5e93\u7684\u5b9e\u73b0\u6709 MySQL\uff0cSQLite\uff0cMongoDB \u7b49\u3002C++ \u7b49\u7f16\u7a0b\u8bed\u8a00\u53ea\u9700\u8c03\u7528\u4ed6\u4eec\u63d0\u4f9b\u7684 API \u5373\u53ef\uff0c\u4e0d\u5fc5\u81ea\u5df1\u624b\u52a8\u5b9e\u73b0\u8fd9\u4e9b\u590d\u6742\u7684\u67e5\u627e\u548c\u63d2\u5165\u7b97\u6cd5\u3002 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u4e13\u4e1a\u7684\u201c\u5b66\u751f\u7ba1\u7406\u7cfb\u7edf\u201d\u90fd\u4f1a\u7528\u5173\u7cfb\u6570\u636e\u5e93\uff0c\u800c\u4e0d\u662f\u81ea\u5df1\u624b\u52a8\u7ef4\u62a4\u4e00\u4e2a map\u3002\u5173\u7cfb\u6570\u636e\u5e93\u5e95\u5c42\u7684\u6570\u636e\u7ed3\u6784\u66f4\u590d\u6742\uff0c\u4f46\u7ecf\u8fc7\u9ad8\u5ea6\u5c01\u88c5\uff0c\u6548\u7387\u66f4\u9ad8\uff0c\u63d0\u4f9b\u7684\u529f\u80fd\u4e5f\u66f4\u5168\u9762\uff0c\u7528\u8d77\u6765\u4e5f\u6bd4\u8f83\u65e0\u611f\u3002\u4f55\u51b5 map \u5b58\u5728\u5185\u5b58\u4e2d\uff0c\u7535\u8111\u4e00\u5173\u673a\uff0c\u5b66\u751f\u6570\u636e\u5c31\u6ca1\u4e86\uff01\u800c\u6570\u636e\u5e93\u53ef\u4ee5\u628a\u6570\u636e\u6301\u4e45\u5316\u5230\u78c1\u76d8\u4e2d\uff0c\u76f8\u5f53\u4e8e\u5728\u78c1\u76d8\u91cc\u6784\u5efa\u51fa\u4e86\u4e00\u9897\u67e5\u627e\u6811\uff0c\u5173\u673a\u540e\u6570\u636e\u4f9d\u7136\u4fdd\u6301\u3002 \u76f8\u4f9d\u540c\u5b66\u597d\u4e0d\u5bb9\u6613\u8003\u51fa\u6ee1\u5206\uff0c\u7ed3\u679c\u5c0f\u5f6d\u8001\u5e08\u4e00\u4e0d\u5c0f\u5fc3\u8e22\u4e86\u4e00\u811a\u7535\u8111\uff0c\u91cd\u542f\uff0c\u5168\u90e8\u5b66\u751f\u6863\u6848\u4e22\u5931\uff0c\u767d\u8003\uff01 \u67e5\u8be2 map \u4e2d\u5143\u7d20\u7684\u6570\u91cf size_t size() const noexcept; \u4f7f\u7528 m.size() \u83b7\u5f97\u7684 map \u5927\u5c0f\uff0c\u6216\u8005\u8bf4\u5176\u4e2d\u5143\u7d20\u7684\u6570\u91cf\u3002 map m; print(m.size()); // 0 m[\"fuck\"] = 985; print(m.size()); // 1 m[\"dick\"] = 211; print(m.size()); // 2 \u5e94\u7528\u4e3e\u4f8b\uff1a\u7ed9\u6bcf\u4e2a\u952e\u4e00\u4e2a\u72ec\u4e00\u65e0\u4e8c\u7684\u8ba1\u6570 map m; m[\"fuck\"] = m.size(); m[\"dick\"] = m.size(); \u9700\u8981 C++17 \u4ee5\u4e0a\u7684\u7248\u672c\uff0c\u624d\u80fd\u4fdd\u8bc1\u7b49\u53f7\u53f3\u8fb9\u7684 m.size() \u5148\u4e8e m[\"fuck\"] \u6c42\u503c\u3002C++14 \u4e2d\u4e0a\u9762\u8fd9\u6bb5\u4ee3\u7801\u884c\u4e3a\u672a\u5b9a\u4e49\uff0c\u9700\u8981\u6539\u7528 m.insert({\"fuck\", m.size()}) \u7684\u5199\u6cd5\uff08\u51fd\u6570\u53c2\u6570\u603b\u662f\u4f18\u5148\u4e8e\u51fd\u6570\u6c42\u503c\uff0c\u8fd9\u4fdd\u8bc1 m.size() \u5148\u6c42\u503c\uff0c\u7136\u540e\u624d\u53d1\u751f\u5143\u7d20\u63d2\u5165\uff09\u3002 \u5224\u65ad\u4e00\u4e2a\u952e\u662f\u5426\u5b58\u5728\uff1acount \u51fd\u6570 size_t count(K const &k) const; count \u8fd4\u56de\u5bb9\u5668\u4e2d\u952e\u548c\u53c2\u6570 k \u76f8\u7b49\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 count \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u4e00\u4e2a\u952e\u5728 map \u4e2d\u662f\u5426\u5b58\u5728\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.count(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); } if (msg.count(\"dick\")) { print(\"\u5b58\u5728dick\uff0c\u5176\u503c\u4e3a\", msg.at(\"suck\")); } else { print(\"\u627e\u4e0d\u5230dick\"); } {\"fuck\": \"rust\", \"hello\": \"world\"} \u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a \"rust\" \u627e\u4e0d\u5230dick C++20 \u4e2d\u5efa\u8bae\u6539\u7528\u8fd4\u56de\u7c7b\u578b\u4e3a bool \u7684 contains \u51fd\u6570\uff0c\u51fd\u6570\u540d\u548c\u7c7b\u578b\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u4f46\u5b9e\u9645\u6548\u679c\u548c count \u662f\u4e00\u6837\u7684\u3002 if (msg.contains(\"fuck\")) { print(\"\u5b58\u5728fuck\uff0c\u5176\u503c\u4e3a\", msg.at(\"fuck\")); } else { print(\"\u627e\u4e0d\u5230fuck\"); }","title":"C \u8bed\u8a00\u7684\u9000\u5316\u89c4\u5219\u771f\u662f\u5bb3\u4eba\u4e0d\u6d45"},{"location":"stl_map/#_19","text":"\u9664\u4e86\u5199\u5165\u5143\u7d20\u9700\u8981\u7528 [] \u4ee5\u5916\uff0c\u8fd8\u6709\u4e00\u4e9b\u6848\u4f8b\u4e2d\u5408\u7406\u8fd0\u7528 [] \u4f1a\u975e\u5e38\u7684\u65b9\u4fbf\u3002 [] \u7684\u6548\u679c\uff1a\u5f53\u6240\u67e5\u8be2\u7684\u952e\u503c\u4e0d\u5b58\u5728\u65f6\uff0c\u4f1a\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\u521b\u5efa\u4e00\u4e2a\u5143\u7d20 1 \u3002 \u5bf9\u4e8e int, float \u7b49\u6570\u503c\u7c7b\u578b\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f 0\u3002 \u5bf9\u4e8e\u6307\u9488\uff08\u5305\u62ec\u667a\u80fd\u6307\u9488\uff09\u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f nullptr\u3002 \u5bf9\u4e8e string \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u5b57\u7b26\u4e32 \u201c\u201d\u3002 \u5bf9\u4e8e vector \u800c\u8a00\uff0c\u9ed8\u8ba4\u503c\u662f\u7a7a\u6570\u7ec4 {}\u3002 \u5bf9\u4e8e\u81ea\u5b9a\u4e49\u7c7b\u800c\u8a00\uff0c\u4f1a\u8c03\u7528\u4f60\u5199\u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u5982\u679c\u6ca1\u6709\uff0c\u5219\u6bcf\u4e2a\u6210\u5458\u90fd\u53d6\u9ed8\u8ba4\u503c\u3002","title":"\u4f60\u77e5\u9053\u5417\uff1f[] \u7684\u5999\u7528"},{"location":"stl_map/#_20","text":"vector input = {\"hello\", \"world\", \"hello\"}; map counter; for (auto const &key: input) { counter[key]++; } print(counter); {\"hello\": 2, \"world\": 1}","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u51fa\u73b0\u6b21\u6570\u7edf\u8ba1"},{"location":"stl_map/#_21","text":"\u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa 0 \u5143\u7d20\u7684\u7279\u6027 map counter; for (auto const &key: input) { counter[key]++; } \u53e4\u677f\u7684\u5199\u6cd5 map counter; for (auto const &key: input) { if (!counter.count(key)) { counter[key] = 1; } else { counter[key] = counter.at(key) + 1; } }","title":"\u5bf9\u6bd4"},{"location":"stl_map/#_22","text":"vector input = {\"happy\", \"world\", \"hello\", \"weak\", \"strong\"}; map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); {'h': {\"happy\", \"hello\"}, 'w': {\"world\", \"weak\"}, 's': {\"strong\"}}","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u5f52\u7c7b"},{"location":"stl_map/#_23","text":"\u6d3b\u7528 [] \u81ea\u52a8\u521b\u5efa\u201d\u9ed8\u8ba4\u503c\u201d\u5143\u7d20\u7684\u7279\u6027 map> categories; for (auto const &str: input) { char key = str[0]; categories[key].push_back(str); } print(categories); \u53e4\u677f\u7684\u5199\u6cd5 map> categories; for (auto const &str: input) { char key = str[0]; if (!categories.count(key)) { categories[key] = {str}; } else { categories[key].push_back(str); } }","title":"\u5bf9\u6bd4"},{"location":"stl_map/#_24","text":"concurrent_map tls; parallel_for([] { Data &data = tls[std::this_thread::get_id()]; ...; }); \u4e0d\u8fc7 thread_local \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u53d6\u4ee3\u3002","title":"[] \u5999\u7528\u4e3e\u4f8b\uff1a\u7ebf\u7a0b\u5c40\u90e8\u53d8\u91cf"},{"location":"stl_map/#_25","text":"\u53cd\u9762\u5178\u578b\uff1a\u67e5\u627e\u7279\u5b9a\u5143\u7d20\u5728 vector \u4e2d\u7684\u4f4d\u7f6e\uff08\u4e0b\u6807\uff09 size_t array_find(vector const &arr, string const &val) { for (size_t i = 0; i < arr.size(); i++) { if (arr[i] == val) return i; } return (size_t)-1; } vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; print(\"hello\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"fucker\")); // O(N) \u4f4e\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", array_find(arr, \"nice\")); // O(N) \u4f4e\u6548 \u6bcf\u6b21\u8c03\u7528 array_find \uff0c\u90fd\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a0 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N^2) O(N^2) \u3002 \u6ce8\uff1a\u5047\u8bbe vector \u4e2d\u4e0d\u5b58\u5728\u91cd\u590d\u7684\u5143\u7d20","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u53cd\u5411\u67e5\u627e\u8868"},{"location":"stl_map/#map_4","text":"\u6b63\u786e\u505a\u6cd5\uff1a\u6784\u5efa vector \u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u4ee5\u540e\u67e5\u627e\u66f4\u9ad8\u6548 vector arr = {\"hello\", \"world\", \"nice\", \"day\", \"fucker\"}; map arrinv; for (size_t i = 0; i < arr.size(); i++) { // O(N) \u4e00\u6b21\u6027\u53d7\u82e6 arrinv[arr[i]] = i; } print(\"\u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a\", arrinv); print(\"fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"fucker\")); // O(log N) \u9ad8\u6548 print(\"nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a\", arrinv.at(\"nice\")); // O(log N) \u9ad8\u6548 \u53ea\u6709\u7b2c\u4e00\u6b21\u6784\u9020\u53cd\u5411\u67e5\u627e\u8868\u65f6\uff0c\u9700\u8981 O(N) O(N) \u590d\u6742\u5ea6\u3002 \u4ee5\u540e\u6bcf\u6b21\u8c03\u7528 map.at \uff0c\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u53cd\u5411\u67e5\u627e\u8868\u6784\u5efa\u6210\u529f\uff1a{\"day\": 3, \"fucker\", 4, \"hello\": 0, \"nice\": 2, \"world\": 1} fucker\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a4 nice\u5728\u6570\u7ec4\u4e2d\u7684\u4e0b\u6807\u662f\uff1a2 \u8f76\u4e8b\uff1a\u5728\u6570\u636e\u5e93\u4e2d\uff0c\u8fd9\u79cd\u53cd\u5411\u67e5\u627e\u8868\u88ab\u79f0\u4e3a\u201c\u5012\u5e8f\u7d22\u5f15\u201d\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u524d\u5728\u4e0d\u77e5\u9053\u8fd9\u4e2a\u672f\u8bed\u7684\u60c5\u51b5\u4e0b\uff0c\u72ec\u7acb\u4ea7\u751f\u4e86\u53cd\u5411\u67e5\u627e\u8868\u7684\u601d\u60f3 for (size_t i = 0; i < arr.size(); i++) { arrinv[arr[i]] = i; } \u63d0\u524d\u6784\u9020\u597d\u67e5\u627e\u8868 O(N) O(N) \uff0c\u4ee5\u540e\u6bcf\u6b21\u67e5\u627e\u53ea\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u5c31\u884c\u3002 \uff08\u6b63\u5411\u67e5\u627e\uff09\u5df2\u77e5\u4e0b\u6807 i\uff0c\u6c42\u5143\u7d20 v\uff1a v = arr[i] \uff08\u53cd\u5411\u67e5\u627e\uff09\u5df2\u77e5\u5143\u7d20 v\uff0c\u6c42\u4e0b\u6807 i\uff1a i = arrinv[v] \u5982\u679c\u67e5\u8be2 N \u6b21\uff0c\u5219\u590d\u6742\u5ea6\u5c31\u662f O(N \\log N) O(N \\log N) \uff0c\u6bd4\u4f18\u5316\u524d\u9ad8\u6548\u3002 \u56e0\u6b64\u5f53\u9700\u8981\u591a\u6b21\u67e5\u627e\u4e14\u539f\u6570\u7ec4\u4fdd\u6301\u4e0d\u53d8\u65f6\uff0c\u5f3a\u70c8\u63a8\u8350\u7528\u8fd9\u79cd\u65b9\u6cd5\uff0c\u66f4\u9ad8\u6548\u3002 \u53ea\u6709\u5f53 vector \u66f4\u65b0\u65f6\uff0c\u624d\u9700\u8981\u91cd\u65b0\u6784\u5efa map\u3002\u5982\u679c vector \u7684\u5220\u9664\u91c7\u7528 back-swap-erase\uff08\u89c1 C++ \u5c0f\u5999\u62db \uff09\uff0c\u90a3\u4e48\u65e0\u9700\u5b8c\u5168\u91cd\u6784 map\uff0c\u53ea\u9700\u66f4\u65b0 swap \u7684\u4e24\u4e2a\u5143\u7d20\u5373\u53ef\uff0c\u603b\u590d\u6742\u5ea6 O(\\log N) O(\\log N) \uff0c\u8fd9\u6837\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a O(\\log N) O(\\log N) \u7684\u6709\u4e0b\u6807\u53c8\u80fd\u5feb\u901f\u67e5\u627e\u6570\u7ec4\uff0c\u517c\u5177 map \u548c vector \u7684\u4f18\u52bf\u3002\u5728\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8fdb\u9636\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u6b64\u7c7b\u590d\u5408\u6570\u636e\u7ed3\u6784\u3002","title":"map \u6784\u5efa\u4e0b\u6807\u67e5\u627e\u8868"},{"location":"stl_map/#map-map","text":"map \u53ea\u80fd\u901a\u8fc7\u503c\u6620\u5c04\u5230\u952e\uff0c\u80fd\u4e0d\u80fd\u53cd\u8fc7\u6765\u901a\u8fc7\u952e\u67e5\u627e\u503c\uff1f \u6848\u4f8b\uff1a\u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868 map tab = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; map tabinv; for (auto const &[k, v]: tab) { tabinv[v] = k; } print(tabinv); \u6548\u679c\u5c31\u662f\uff0c\u952e\u53d8\u503c\uff0c\u503c\u53d8\u952e\uff0c\u53cd\u4e00\u53cd\uff0c\u4e24\u4e2a map \u4e92\u4e3a\u9006\u8fd0\u7b97\uff1a {\"rust\": \"fuck\", \"world\": \"hello\"} \u6ce8\u610f\uff1a\u8981\u6c42 tab \u4e2d\u4e0d\u80fd\u5b58\u5728\u91cd\u590d\u7684\u503c\uff0c\u952e\u548c\u503c\u5fc5\u987b\u662f\u4e00\u4e00\u5bf9\u5e94\u5173\u7cfb\uff0c\u624d\u80fd\u7528\u8fd9\u79cd\u65b9\u5f0f\u6784\u5efa\u53cc\u5411\u67e5\u627e\u8868\u3002\u5426\u5219\u4e00\u4e2a\u503c\u53ef\u80fd\u5bf9\u5e94\u5230\u4e24\u4e2a\u952e\uff0c\u53cd\u5411\u8868\u5fc5\u987b\u662f map> \u4e86\u3002","title":"map \u6784\u5efa\u53e6\u4e00\u4e2a map \u7684\u53cd\u5411\u67e5\u627e\u8868"},{"location":"stl_map/#value_type","text":"STL \u5bb9\u5668\u7684\u5143\u7d20\u7c7b\u578b\u90fd\u53ef\u4ee5\u901a\u8fc7\u6210\u5458 value_type \u67e5\u8be2\uff0c\u5e38\u7528\u4e8e\u6cdb\u578b\u7f16\u7a0b\uff08\u53c8\u79f0\u5143\u7f16\u7a0b\uff09\u3002 set::value_type // int vector::value_type // int string::value_type // char \u6b64\u5916\u8fd8\u6709\u5f15\u7528\u7c7b\u578b reference \uff0c\u8fed\u4ee3\u5668\u7c7b\u578b iterator \uff0c\u5e38\u8fed\u4ee3\u5668\u7c7b\u578b const_iterator \u7b49\u3002 \u66fe\u7ecf\u5728 C++98 \u4e2d\u5f88\u5e38\u7528\uff0c\u4e0d\u8fc7\u81ea\u4ece C++11 \u6709\u4e86 auto \u548c decltype \u4ee5\u540e\uff0c\u5c31\u4e0d\u600e\u4e48\u7528\u4e86\uff0c\u53cd\u6b63\u80fd\u81ea\u52a8\u63a8\u5bfc\u8fd4\u56de\u7c7b\u578b\u3002 C++23: std::vector arr; for (auto const &elem: arr) { std::println(\"{}\", elem); } C++17: std::vector arr; for (auto const &elem: arr) { std::cout << elem << '\\n'; } C++11: std::vector arr; for (auto it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; } C++98: std::vector arr; for (std::vector::iterator it = arr.begin(); it != arr.end(); ++it) { std::cout << *it << '\\n'; }","title":"\u5143\u7f16\u7a0b\u67e5\u8be2\u6210\u5458\u7c7b\u578b\uff1avalue_type"},{"location":"stl_map/#typename","text":"\u5f53\u5bb9\u5668\u6709\u81f3\u5c11\u4e00\u4e2a\u4e0d\u786e\u5b9a\u7684\u7c7b\u578b T \u4f5c\u4e3a\u6a21\u677f\u53c2\u6570\u65f6\uff0c\u5c31\u9700\u8981\u524d\u9762\u52a0\u4e0a typename \u4fee\u9970\u4e86\uff1a set::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 typename set::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename set>::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 T \u662f\u4e0d\u5b9a\u7c7b\u578b typename map::value_type; // \u5305\u542b\u6709 K\u3001T \u662f\u4e0d\u5b9a\u7c7b\u578b map::value_type; // \u6ca1\u6709\u4e0d\u5b9a\u7c7b\u578b\uff0c\u4e0d\u9700\u8981 \u5982\u679c\u4f60\u641e\u4e0d\u6e05\u695a\uff0c\u59cb\u7ec8\u52a0 typename \u5c31\u884c\u4e86\uff0c\u53cd\u6b63\u52a0\u591a\u80af\u5b9a\u4e0d\u4f1a\u6709\u9519\u3002\u4f60\u5c31\u8ba4\u4e3a\uff1a\u8fd9\u5c31\u662f\u4e00\u4e2a\u5e73\u65f6\u53ef\u4ee5\u7701\u7565\uff0c\u5076\u5c14\u4e0d\u80fd\u7701\u7565\u7684\u4e1c\u897f\u3002 typename set::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb typename set::value_type; // \u4e0d\u80fd\u7701\u7565 typename set>::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u4e0d\u80fd\u7701\u7565 typename map::value_type; // \u53ef\u4ee5\u7701\u7565\uff0c\u4f46\u4f60\u52a0\u4e86\u4e5f\u6ca1\u5173\u7cfb \u542b\u6709 T \u7684\u7c7b\u578b\u8868\u8fbe\u5f0f\u79f0\u4e3a dependent-type\uff0c\u6839\u672c\u539f\u56e0\u662f\u56e0\u4e3a\u5728\u4e0d\u77e5\u9053\u5177\u4f53\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\u8fd8\u662f\u503c\u8868\u8fbe\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u7f16\u8bd1\u5668\u65e0\u6cd5\u533a\u5206\u6a21\u677f\u7684 < \u548c\u5c0f\u4e8e\u7b26\u53f7 < \uff0c\u4ee5\u53ca\u7c7b\u578b\u7684\u6307\u9488 * \u548c\u6570\u503c\u4e58\u6cd5 * \u3002\u9ed8\u8ba4\u4f1a\u8ba4\u4e3a\u662f\u5c0f\u4e8e\u7b26\u53f7\u548c\u6570\u503c\u4e58\u6cd5\uff0c\u52a0\u4e0a typename \u540e\u660e\u786e\u524d\u9762\u8fd9\u4e00\u4e32\u662f\u7c7b\u578b\u8868\u8fbe\u5f0f\uff0c\u624d\u77e5\u9053\u8fd9\u662f\u6a21\u677f\u7684 < \u548c\u6307\u9488\u7684 * \u3002","title":"typename \u4fee\u9970"},{"location":"stl_map/#decltype","text":"\u4e5f\u6709\u66f4\u76f4\u89c2\u7684\u83b7\u53d6 STL \u5bb9\u5668\u5143\u7d20\u7c7b\u578b\u7684\u65b9\u6cd5\uff1a std::vector arr; using T = std::decay_t; // T = int decltype \u5fc5\u987b\u914d\u5408 std::decay_t \u624d\u80fd\u7528\uff01\u5426\u5219\u4f1a\u5f97\u5230\u5f15\u7528\u7c7b\u578b int & \uff0c\u540e\u7eed\u4f7f\u7528\u4e2d\u5c31\u5751\u5230\u4f60\uff01\uff08\u56e0\u4e3a arr \u7684 [] \u8fd4\u56de\u7684\u662f\u4e00\u4e2a\u5f15\u7528\u7c7b\u578b\uff09 // \u9519\u8bef\u793a\u8303 using T = decltype(arr[0]); // T = int & T i = 0; // int &i = 0; \u540e\u7eed\u4f7f\u7528\u4e2d\u7f16\u8bd1\u51fa\u9519\uff01","title":"decltype \u5927\u6cd5\u597d"},{"location":"stl_map/#_26","text":"\u5728\u672c\u8bfe\u7a0b\u7684\u6848\u4f8b\u4ee3\u7801\u4e2d\u9644\u5e26\u7684 \u201ccppdemangle.h\u201d\uff0c\u53ef\u4ee5\u5b9e\u73b0\u6839\u636e\u6307\u5b9a\u7684\u7c7b\u578b\u67e5\u8be2\u7c7b\u578b\u540d\u79f0\u5e76\u6253\u5370\u51fa\u6765\u3002 \u8de8\u5e73\u53f0\uff0c\u9700\u8981 C++11\uff0c\u652f\u6301 MSVC\uff0cClang\uff0cGCC \u4e09\u5927\u7f16\u8bd1\u5668\uff0c\u4f8b\u5982\uff1a int i; print(cppdemangle()); print(cppdemangle()); print(cppdemangle()); \u5728\u6211\u7684 GCC 12.2.1 \u4e0a\u5f97\u5230\uff1a \"int &&\" \"std::__cxx11::basic_string, std::allocator >\" \"wchar_t\"","title":"\u67e5\u8be2\u7c7b\u540d\u5c0f\u5de5\u5177"},{"location":"stl_map/#map_5","text":"map \u5177\u6709\u4e09\u4e2a\u6210\u5458\u7c7b\u578b 1 \uff1a \u5143\u7d20\u7c7b\u578b\uff1a value_type \u952e\u7c7b\u578b\uff1a key_type \u503c\u7c7b\u578b\uff1a mapped_type \u540e\u9762\uff0c\u5c06\u4f1a\u4e00\u76f4\u4ee5\u201c\u5143\u7d20\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cvalue\u201d\uff0c\u201c\u952e\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201ckey\u201d\uff0c\u201c\u503c\u201d\u79f0\u547c\u5b98\u65b9\u7684\u201cmapped\u201d \u7528 cppdemangle \u505a\u5b9e\u9a8c\uff0c\u770b\u770b\u8fd9\u4e9b\u6210\u5458\u7c7b\u578b\u5177\u4f53\u662f\u4ec0\u4e48\u5427\uff1a map::value_type // pair map::key_type // int map::mapped_type // float \u7ed3\u8bba\uff1a map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u800c\u4e0d\u662f V \u3002 \u7591\u60d1\uff1a pair \u4e2d\uff0c\u4e3a\u4ec0\u4e48 K \u8981\u52a0 const\uff1f \u6211\u4eec\u5728 set \u8bfe\u4e2d\u8bf4\u8fc7\uff0cset \u5185\u90e8\u91c7\u7528\u7ea2\u9ed1\u6811\u6570\u636e\u7ed3\u6784\u4fdd\u6301\u6709\u5e8f\uff0c\u8fd9\u6837\u624d\u80fd\u5b9e\u73b0\u5728 O(\\log N) O(\\log N) \u65f6\u95f4\u5185\u9ad8\u6548\u67e5\u627e\u3002 \u952e\u503c\u6539\u53d8\u7684\u8bdd\u4f1a\u9700\u8981\u91cd\u65b0\u6392\u5e8f\uff0c\u5982\u679c\u53ea\u4fee\u6539\u952e\u503c\u800c\u4e0d\u91cd\u65b0\u6392\u5e8f\uff0c\u4f1a\u7834\u574f\u6709\u5e8f\u6027\uff0c\u5bfc\u81f4\u4e8c\u5206\u67e5\u627e\u7ed3\u679c\u9519\u8bef\uff01\u6240\u4ee5 set \u53ea\u63d0\u4f9b\u4e86\u4e0d\u53ef\u53d8\u8fed\u4ee3\u5668\uff08const_iterator\uff09\uff0c\u6ca1\u6709\u53ef\u53d8\u7684\u8fed\u4ee3\u5668\uff0c\u4e0d\u5141\u8bb8\u7528\u6237\u4fee\u6539\u4efb\u4f55\u5143\u7d20\u7684\u503c\u3002 map \u548c set \u4e00\u6837\u4e5f\u662f\u7ea2\u9ed1\u6811\uff0c\u4e0d\u540c\u5728\u4e8e\uff1amap \u53ea\u6709\u952e K \u7684\u90e8\u5206\u4f1a\u53c2\u4e0e\u6392\u5e8f\uff0cV \u662f\u4e2a\u65c1\u89c2\u8005\uff0c\u968f\u4fbf\u4fee\u6539\u4e5f\u6ca1\u5173\u7cfb\u3002 \u6240\u4ee5 map \u6709\u53ef\u53d8\u8fed\u4ee3\u5668\uff0c\u53ea\u662f\u5728\u5176\u503c\u7c7b\u578b value_type \u4e2d\u7ed9\u952e\u7684\u90e8\u5206\uff0cK\uff0c\u52a0\u4e0a\u4e86 const \u4fee\u9970\uff1a\u4e0d\u5141\u8bb8\u4fee\u6539 K\uff0c\u4f46\u53ef\u4ee5\u968f\u610f\u4fee\u6539 V\u3002 \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u4fee\u6539\u952e\u503c\uff0c\u90a3\u4e48\u8bf7\u5148\u53d6\u51fa\u65e7\u503c\uff0c\u628a\u8fd9\u4e2a\u952e\u5220\u4e86\uff0c\u7136\u540e\u518d\u4ee5\u540c\u6837\u7684\u503c\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u5230\u65b0\u7684\u952e\u3002\u76f8\u5f53\u4e8e\u91cd\u65b0\u6784\u5efa\u4e86\u4e00\u4e2a pair \u5bf9\u8c61\u3002 C++17 \u5f00\u59cb\u4e5f\u53ef\u4ee5\u7528\u66f4\u9ad8\u6548 node_handle \u7cfb\u5217 API\uff0c\u907f\u514d\u6570\u636e\u53d1\u751f\u79fb\u52a8\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; begin() \u548c end() \u8fed\u4ee3\u5668\u5206\u522b\u6307\u5411 map \u7684\u9996\u4e2a\u5143\u7d20\u548c\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u7684\u540e\u4e00\u4f4d\u3002 \u5176\u4e2d end() \u8fed\u4ee3\u5668\u6307\u5411\u7684\u5730\u5740\u4e3a\u865a\u7a7a\u7d22\u654c\uff0c\u4e0d\u53ef\u89e3\u5f15\u7528\uff0c\u4ec5\u4ec5\u4f5c\u4e3a\u4e00\u4e2a\u201c\u6807\u5fd7\u201d\u5b58\u5728\uff08\u56de\u987e\u4e4b\u524d vector \u8bfe\uff09\u3002 \u8fed\u4ee3\u5668\u53ef\u4ee5\u901a\u8fc7 *it \u6216 it-> \u89e3\u5f15\u7528\uff0c\u83b7\u53d6\u5176\u6307\u5411\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u9996\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5c0f\u7684\u5143\u7d20\u3002 \u7531\u4e8e map \u5185\u90e8\u603b\u662f\u4fdd\u6301\u6709\u5e8f\uff0cmap \u7684\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u4e00\u5b9a\u662f\u952e\u6700\u5927\u7684\u5143\u7d20\u3002 \u4f8b\u5982\u8981\u67e5\u8be2\u6210\u7ee9\u6700\u597d\u548c\u6700\u574f\u7684\u5b66\u751f\uff0c\u53ef\u4ee5\u628a\u6210\u7ee9\u5f53\u505a key\uff0c\u5b66\u751f\u540d\u505a value \u4f9d\u6b21\u63d2\u5165 map\uff0c\u4ed6\u4f1a\u5e2e\u6211\u4eec\u6392\u5e8f\uff1a map score = { {100, \"\u5f6d\u4e8e\u658c\"}, {80, \"\u6a31\u82b1\u7c89\u871c\u7cd6\"}, {0, \"\u76f8\u4f9d\"}, {60, \"Sputnik02\"}, }; string poorestStudent = score.begin()->second; // \u6210\u7ee9\u6700\u5dee\u5b66\u751f\u7684\u59d3\u540d string bestStudent = prev(score.end())->second; // \u6210\u7ee9\u6700\u597d\u5b66\u751f\u7684\u59d3\u540d print(\"\u6700\u4f4e\u5206:\", poorestStudent); print(\"\u6700\u9ad8\u5206:\", bestStudent); \u6700\u4f4e\u5206: \"\u76f8\u4f9d\" \u6700\u9ad8\u5206: \"\u5f6d\u4e8e\u658c\" \u6ce8\uff1a\u4ec5\u5f53\u786e\u4fdd score.size() != 0 \u65f6\u624d\u53ef\u4ee5\u89e3\u5f15\u7528\uff0c\u5426\u5219 begin() \u548c end() \u90fd\u662f\u865a\u7a7a\u8fed\u4ee3\u5668\uff0c\u8fd9\u65f6\u89e3\u5f15\u7528\u4f1a\u5954\u6e83\u3002 map \u7684\u904d\u5386\uff1a\u53e4\u4ee3 C++98 \u7684\u8fed\u4ee3\u5668\u5927\u6cd5 for (map::iterator it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8981\u7279\u522b\u6ce8\u610f\u8fed\u4ee3\u5668\u662f\u4e00\u4e2a\u6307\u5411\u5143\u7d20\u7684\u6307\u9488\uff0c\u4e0d\u662f\u5143\u7d20\u672c\u8eab\uff01\u8981\u7528 -> \u800c\u4e0d\u662f . \u3002 \u8fd0\u7528 C++11 \u7684 auto \u7b80\u5199\u4e00\u4e0b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { print(\"Key:\", it->first); print(\"Value:\", it->second); } \u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\uff08structured-binding\uff09\u8bed\u6cd5 1 \u76f4\u63a5\u62c6\u5f00 pair \u7c7b\u578b\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; print(\"Key:\", k); print(\"Value:\", v); } map \u7684\u904d\u5386\uff1a\u73b0\u4ee3 C++17 \u57fa\u4e8e\u8303\u56f4\u7684\u5faa\u73af\uff08range-based loop\uff09 for (auto kv: m) { print(\"Key:\", kv.first); print(\"Value:\", kv.second); } \u540c\u65f6\u8fd0\u7528 C++17 \u7ed3\u6784\u5316\u7ed1\u5b9a\u8bed\u6cd5 1 \uff1a for (auto [k, v]: m) { print(\"Key:\", k); print(\"Value:\", v); } \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u53e4\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto it = m.begin(); it != m.end(); ++it) { it->second = it->second + 1; } print(m); {\"fuck\": 986, \"rust\": 212} \u5982\u4f55\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\u4fee\u6539\u503c\uff1f \u73b0\u4ee3\uff1a map m = { {\"fuck\", 985}, {\"rust\", 211}, }; for (auto [k, v]: m) { v = v + 1; } print(m); {\"fuck\": 985, \"rust\": 211} \u6ca1\u6709\u6210\u529f\u4fee\u6539\uff01\u4e3a\u4ec0\u4e48\uff1f for (auto [k, v]: m) { v = v + 1; } Range-based loop \u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto [k, v] = *it; v = v + 1; } Structured-binding \u4e5f\u53ea\u662f\u4e2a\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u4ed6\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto tmp = *it; auto k = tmp.first; auto v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u6808\u4e0a\u53d8\u91cf\uff0c\u662f\u5bf9\u539f\u503c\u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u4e0d\u4ec5\u6d6a\u8d39\u6027\u80fd\uff0c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4e0d\u4f1a\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\uff01 for (auto &[k, v]: m) { // \u89e3\u51b3\u65b9\u6848\u662f\u5728\u8fd9\u91cc\u52a0\u4e00\u4e2a\u5c0f\u5c0f\u7684 &\uff0c\u8ba9 range-based loop \u6355\u83b7\u5f15\u7528\u800c\u4e0d\u662f\u62f7\u8d1d v = v + 1; } \u540c\u6837\u662f\u62c6\u9664 Range-based loop \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &[k, v] = *it; v = v + 1; } \u7ee7\u7eed\u62c6\u9664 Structured-binding \u7684\u82b1\u54e8\u8bed\u6cd5\u7cd6\uff0c\u76f8\u5f53\u4e8e\uff1a for (auto it = m.begin(); it != m.end(); ++it) { auto &tmp = *it; auto &k = tmp.first; auto &v = tmp.second; v = v + 1; } \u8fd9\u6837\u4fdd\u5b58\u4e0b\u6765\u7684 v \u662f\u4e2a\u5f15\u7528\uff0c\u662f\u5bf9\u539f\u503c\u7684\u5f15\u7528\uff08\u7528 Rust \u7684\u8bdd\u8bf4\u53eb borrowed\uff09\u3002\u4e0d\u4ec5\u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\u8282\u7701\u4e86\u6027\u80fd\uff0c\u800c\u4e14\u5bf9 v \u7684\u4fee\u6539\u4f1a\u5b9e\u65f6\u53cd\u6620\u5230\u539f map \u4e2d\u53bb\u3002 \u603b\u7ed3\uff0c\u5f53\u9700\u8981\u5728\u904d\u5386\u7684\u540c\u65f6\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u8981\u7528 auto & \u6355\u83b7\u5f15\u7528\uff1a for (auto &[k, v]: m) { // \u6355\u83b7\u4e00\u4e2a\u5f15\u7528\uff0c\u5199\u5165\u8fd9\u4e2a\u5f15\u7528\u4f1a\u7acb\u5373\u4f5c\u7528\u5728\u539f\u503c\u4e0a v = v + 1; } \u5373\u4f7f\u4e0d\u9700\u8981\u4fee\u6539 map \u4e2d\u7684\u503c\u65f6\uff0c\u4e5f\u5efa\u8bae\u7528 auto const & \u907f\u514d\u62f7\u8d1d\u7684\u5f00\u9500\uff1a for (auto const &[k, v]: m) { // \u6355\u83b7\u53ea\u8bfb\u7684 const \u5f15\u7528\uff0c\u5f15\u7528\u907f\u514d\u62f7\u8d1d\u5f00\u9500\uff0cconst \u907f\u514d\u4e0d\u5c0f\u5fc3\u624b\u6ed1\u5199\u5165 print(v); } \u6ce8\uff1a\u5373\u4f7f\u6355\u83b7\u4e3a auto & \uff0c\u7531\u4e8e map \u7684\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5 K \u90e8\u5206\u8fd8\u662f\u4f1a\u6355\u83b7\u4e3a K const & \uff0c\u65e0\u6cd5\u5199\u5165\u3002 for (auto &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // OK } \u53ea\u662f\u5982\u679c\u6355\u83b7\u4e3a auto const & \u5c31\u4e24\u4e2a\u90fd\u4e0d\u5141\u8bb8\u5199\u5165\u4e86\u3002 for (auto const &[k, v]: m) { k = \"key\"; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 v = 985211; // \u7f16\u8bd1\u671f\u62a5\u9519\uff1aconst \u5f15\u7528\u4e0d\u53ef\u5199\u5165\uff01 } iterator find(K const &k); const_iterator find(K const &k) const; m.find(key) \u51fd\u6570\uff0c\u6839\u636e\u6307\u5b9a\u7684\u952e key \u67e5\u627e\u5143\u7d20 1 \u3002 \u6210\u529f\u627e\u5230\uff0c\u5219\u8fd4\u56de\u6307\u5411\u627e\u5230\u5143\u7d20\u7684\u8fed\u4ee3\u5668 \u627e\u4e0d\u5230\uff0c\u5219\u8fd4\u56de m.end() \u7531\u4e8e STL \u4f20\u7edf\u5f02\u80fd\u4e4b end() \u865a\u7a7a\u7d22\u654c\uff0c\u4ed6\u4e0d\u53ef\u80fd\u6307\u5411\u4efb\u4f55\u503c\uff0c\u6240\u4ee5\u7ecf\u5e38\u4f5c\u4e3a\u627e\u4e0d\u5230\u65f6\u5019\u7f3a\u7701\u7684\u8fd4\u56de\u503c\u3002 \u53ef\u4ee5\u7528 m.find(key) != m.end() \u5224\u65ad\u4e00\u4e2a\u5143\u7d20\u662f\u5426\u5b58\u5728\uff0c\u7b49\u4ef7\u4e8e m.count(key) != 0 \u3002 \u7b2c\u4e8c\u4e2a\u7248\u672c\u7684\u539f\u578b\u4f5c\u7528\u662f\uff1a\u5982\u679c map \u672c\u8eab\u6709 const \u4fee\u9970\uff0c\u5219\u8fd4\u56de\u7684\u4e5f\u662f const \u8fed\u4ee3\u5668\u3002 \u4e3a\u7684\u662f\u9632\u6b62\u4f60\u5728\u4e00\u4e2a const map \u91cc find \u4e86\u4ee5\u540e\u5229\u7528\u8fed\u4ee3\u5668\u53d8\u76f8\u4fee\u6539 map \u91cc\u7684\u503c\u3002","title":"map \u771f\u6b63\u7684\u5143\u7d20\u7c7b\u578b\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f"},{"location":"stl_map/#count-contains","text":"\u5b9e\u9645\u4e0a count \u548c contains \u51fd\u6570\u5c31\u662f\u57fa\u4e8e find \u5b9e\u73b0\u7684\uff0c\u6027\u80fd\u6ca1\u6709\u533a\u522b\uff0cglibc \u6e90\u7801\uff1a #if __cplusplus > 201703L /** * @brief Finds whether an element with the given key exists. * @param __x Key of (key, value) pairs to be located. * @return True if there is an element with the specified key. */ bool contains(const key_type& __x) const { return _M_t.find(__x) != _M_t.end(); } template auto contains(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x), void(), true) { return _M_t._M_find_tr(__x) != _M_t.end(); } #endif /** * @brief Finds the number of elements with given key. * @param __x Key of (key, value) pairs to be located. * @return Number of elements with specified key. * * This function only makes sense for multimaps; for map the result will * either be 0 (not present) or 1 (present). */ size_type count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } // \u4ee5\u4e0b\u4e09\u8005\u7b49\u4ef7 m.contains(key) m.count(key) m.find(key) != m.end()","title":"count \u548c contains \u6ca1\u533a\u522b"},{"location":"stl_map/#end","text":"\u68c0\u67e5\u8fc7\u4e0d\u662f m.end()\uff0c\u4ee5\u786e\u8ba4\u6210\u529f\u627e\u5230\u540e\uff0c\u5c31\u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528\u83b7\u53d6\u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c\uff1a map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { auto kv = *it; // \u89e3\u5f15\u7528\u5f97\u5230 K-V \u5bf9 print(kv); // {\"fuck\", 985} print(kv.first); // \"fuck\" print(kv.second); // 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); }","title":"end \u4e0d\u80fd\u89e3\u5f15\u7528"},{"location":"stl_map/#find","text":"find \u7684\u9ad8\u6548\u5728\u4e8e\uff0c\u53ef\u4ee5\u628a\u4e24\u6b21\u67e5\u8be2\u5408\u5e76\u6210\u4e00\u6b21\u3002 \u4fdd\u5e95\u5199\u6cd5\uff1a\u5f00\u9500 2 \\log N 2 \\log N if (m.count(\"key\")) { // \u7b2c\u4e00\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(m.at(\"key\")); // \u7b2c\u4e8c\u6b21\u67e5\u8be2\uff0c\u53ea\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f } \u9ad8\u6548\u5199\u6cd5\uff1a\u5f00\u9500 \\log N \\log N auto it = m.find(\"key\"); // \u4e00\u6b21\u6027\u67e5\u8be2 if (it != m.end()) { // \u67e5\u8be2\u7684\u7ed3\u679c\uff0c\u65e2\u5305\u542b\"\u662f\u5426\u627e\u5230\"\u7684\u4fe1\u606f print(it->second); // \u4e5f\u5305\u542b\"\u627e\u5230\u4e86\u4ec0\u4e48\"\u7684\u4fe1\u606f }","title":"find \u7684\u597d\u5904"},{"location":"stl_map/#c17","text":"C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u5982\u4f55\u7b80\u5316 find \u7684\u8fed\u4ee3\u5668\u5224\u65ad auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } auto it = m.find(\"key2\"); // \u7f16\u8bd1\u5668\u62a5\u9519\uff1a\u53d8\u91cf it \u91cd\u590d\u5b9a\u4e49\uff01 if (it != m.end()) { print(it->second); } \u867d\u7136\u5220\u53bb\u524d\u9762\u7684 auto \u53ef\u4ee5\u89e3\u51b3\u95ee\u9898\uff0c\u4f46\u662f\u5982\u679c\u8fd9\u91cc\u662f\u4e0d\u540c\u7c7b\u578b\u7684 map \u5c31\u5c2c\u4e86\uff0c\u5f97\u53e6\u5916\u60f3\u4e00\u4e2a\u53d8\u91cf\u540d\u3002 \u800c C++17 \u7684 if-auto \u8bed\u6cd5\u7cd6\u6355\u83b7\u7684 it \u662f\u9650\u5236\u5728\u5f53\u524d if \u4f5c\u7528\u57df\u7684\uff0c\u4e0d\u4f1a\u8dd1\u51fa\u53bb\u548c\u522b\u4eba\u53d1\u751f\u51b2\u7a81\u3002 if (auto it = m.find(\"key1\"); it != m.end()) { print(it->second); } if (auto it = m.find(\"key2\"); it != m.end()) { // \u8fd9\u4e2a\u53d8\u91cf it \u662f\u5c40\u57df\u7684\uff0c\u4e0d\u4f1a\u548c\u4e0a\u4e00\u4e2a\u5c40\u57df\u7684 it \u4ea7\u751f\u540d\u5b57\u51b2\u7a81 print(it->second); } \u7b49\u4ef7\u4e8e\uff1a { auto it = m.find(\"key1\"); if (it != m.end()) { print(it->second); } }","title":"C++17 \u8bed\u6cd5\u7cd6"},{"location":"stl_map/#_27","text":"\u6211\u7ed9 C++ \u6807\u51c6\u59d4\u5458\u4f1a\u63d0\u4e00\u4e2a\u5efa\u8bae\uff0c\u80fd\u4e0d\u80fd\u7ed9\u8fed\u4ee3\u5668\u52a0\u4e00\u4e2a operator bool \u4ee3\u66ff\u70e6\u4eba\u7684 != m.end() \uff1f struct iterator { _RbTreeNode *node; bool operator!=(iterator const &other) const noexcept { return node == other.node; } operator bool() const noexcept { return node; } }; \u90a3\u6837\u7684\u8bdd\u5c31\u53ef\u4ee5\u76f4\u63a5\uff1a if (auto it = m.find(\"key\")) { print(it->second); } \u56e0\u4e3a if-auto \u7701\u7565\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u65f6\uff0c\u9ed8\u8ba4\u5c31\u662f if (auto it = m.find(\"key\"); (bool)it)","title":"\u9898\u5916\u8bdd"},{"location":"stl_map/#map-pair","text":"\u6ce8\u610f *it \u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair \u7c7b\u578b\u7684\u952e\u503c\u5bf9\uff0c\u9700\u8981 (*it).second \u624d\u80fd\u83b7\u53d6\u5355\u72ec\u7684\u503c V\u3002 \u597d\u5728 C \u8bed\u8a00\u5c31\u6709 -> \u8fd0\u7b97\u7b26\u4f5c\u4e3a\u8bed\u6cd5\u7cd6\uff0c\u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 it->second \uff0c\u4e0e (*it).second \u7b49\u4ef7\u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); // \u5bfb\u627e K \u4e3a \"fuck\" \u7684\u5143\u7d20 if (it != m.end()) { print(it->second); // \u8fed\u4ee3\u5668\u6709\u6548\uff0c\u53ef\u4ee5\u76f4\u63a5\u83b7\u5f97\u503c\u90e8\u5206 985 } else { print(\"\u627e\u4e0d\u5230 fuck\uff01\"); // \u8fd9\u4e2a\u5206\u652f\u91cc\u4e0d\u5f97\u7528 * \u548c -> \u8fd0\u7b97\u7b26\u89e3\u5f15\u7528 it } \u5927\u591a\u6570\u60c5\u51b5\u4e0b\u6211\u4eec\u67e5\u8be2\u53ea\u9700\u8981\u83b7\u53d6\u503c V \u7684\u90e8\u5206\u5c31\u884c\u4e86\uff0c\u76f4\u63a5 it->second \u5c31\u53ef\u4ee5\u4e86\u2705 \u6ce8\u610f\uff1afind \u627e\u4e0d\u5230\u952e\u65f6\uff0c\u4f1a\u8fd4\u56de m.end() \uff0c\u8fd9\u662f\u4e2a\u65e0\u6548\u8fed\u4ee3\u5668\uff0c\u53ea\u4f5c\u4e3a\u6807\u8bc6\u7b26\u4f7f\u7528\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 find \u6709\u65f6\u4f1a\u8fd4\u56de -1\uff09\u3002 \u6ca1\u6709\u786e\u8ba4 it != m.end() \u524d\uff0c\u4e0d\u53ef\u4ee5\u8bbf\u95ee it->second \uff01\u90a3\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e00\u4e2a\u7a7a\u6307\u9488\uff0c\u4f1a\u9020\u6210 segfault\uff08\u66f4\u4e13\u4e1a\u4e00\u70b9\u8bf4\u662f UB\uff09\u3002 \u8bb0\u4f4f\uff0c\u4e00\u5b9a\u8981\u5728 it != m.end() \u7684\u5206\u652f\u91cc\u624d\u80fd\u8bbf\u95ee it->second \u54e6\uff01\u4f60\u5f97\u5148\u68c0\u67e5\u8fc7\u996d\u7897\u91cc\u6ca1\u6709\u8001\u9f20\ud83d\udca9\u4e4b\u540e\uff0c\u624d\u80fd\u5b89\u5fc3\u5403\u996d\uff01 \u5982\u679c\u4f60\u60f3\u8ba9\u8001\u5988\uff08\u6807\u51c6\u5e93\uff09\u81ea\u52a8\u5e2e\u4f60\u68c0\u67e5\u6709\u6ca1\u6709\u8001\u9f20\ud83d\udca9\uff0c\u90a3\u5c31\u7528\u4f1a\u81ea\u52a8\u62a5\u9519\u7684 at\uff08\u7c7b\u6bd4 Python \u4e2d\u7684 index \u627e\u4e0d\u5230\u76f4\u63a5\u62a5\u9519\uff09\u3002 \u4e4b\u6240\u4ee5\u7528 find\uff0c\u662f\u56e0\u4e3a\u6709\u65f6\u996d\u7897\u91cc\u51fa\u8001\u9f20\ud83d\udca9\uff0c\u662f\u8ba1\u5212\u7684\u4e00\u90e8\u5206\uff01\u4f8b\u5982\u5f53\u6709\u8001\u9f20\ud83d\udca9\u65f6\u4f60\u53ef\u4ee5\u6539\u5403\u522b\u7684\u96f6\u98df\u3002\u800c at \u8fd9\u4e2a\u826f\u5fc3\u8001\u5988\u5462\uff1f\u4e00\u53d1\u73b0\u8001\u9f20\ud83d\udca9\u5c31\u62d6\u7740\u4f60\u53bb\u8b66\u5bdf\u5c40\u62a5\u6848\uff0c\u96f6\u98df\uff08\u9ed8\u8ba4\u503c\uff09\u4e5f\u4e0d\u8ba9\u4f60\u5403\u4e86\u3002\u4eca\u65e5\u884c\u7a0b\u5168\u90e8\u53d6\u6d88\uff0c\u7ef4\u6743\uff08\u5f02\u5e38\u5904\u7406\uff0c\u627e\u4e0a\u5c42 try-catch \u5757\uff09\u8bbe\u4e3a\u7b2c\u4e00\u8981\u52a1\u3002 iterator find(K const &k); const_iterator find(K const &k) const; \u5982\u679c map \u6ca1\u6709 const \u4fee\u9970\uff0c\u5219\u5176 find \u8fd4\u56de\u7684 it \u4e5f\u662f\u975e const \u8fed\u4ee3\u5668\u3002 const map cm; map::const_iterator cit = cm.find(\"key\"); print(cit->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 cit->second = 1; // \u7f16\u8bd1\u671f\u62a5\u9519: \u4e0d\u5141\u8bb8\u5199\u5165 const \u8fed\u4ee3\u5668\u6307\u5411\u7684\u503c map m; map::iterator it = m.find(\"key\"); print(it->second); // OK: \u53ef\u4ee5\u8bfb\u53d6 it->second = 1; // OK: \u53ef\u4ee5\u5199\u5165 it->second \u53ef\u4ee5\u5199\u5165\uff0cit \u662f\u8fed\u4ee3\u5668\uff0c\u8fed\u4ee3\u5668\u7c7b\u4f3c\u4e8e\u6307\u9488\uff0c\u5199\u5165\u8fed\u4ee3\u5668\u6307\u5411\u7684 second \u5c31\u53ef\u4ee5\u4fee\u6539 map \u91cc\u7684\u503c\u90e8\u5206\u3002 it->first \u662f\u952e\u90e8\u5206\uff0c\u7531\u4e8e map \u7684\u771f\u6b63\u5143\u7d20\u7c7b\u578b\u662f pair \u6240\u4ee5\u8fd9\u90e8\u5206\u65e0\u6cd5\u88ab\u4fee\u6539\u3002 \u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2 \u4f17\u6240\u5468\u77e5\uff0cPython \u4e2d\u7684 dict \u6709\u4e00\u4e2a m.get(key, defl) \u7684\u529f\u80fd\uff0c\u6548\u679c\u662f\u5f53 key \u4e0d\u5b58\u5728\u65f6\uff0c\u8fd4\u56de defl \u8fd9\u4e2a\u9ed8\u8ba4\u503c\u4ee3\u66ff m[key]\uff0c\u800c C++ \u7684 map \u5374\u6ca1\u6709\uff0c\u53ea\u80fd\u7528\u4e00\u5957\u7ec4\u5408\u62f3\u4ee3\u66ff\uff1a m.count(key) ? m.at(key) : defl \u4f46\u4e0a\u9762\u8fd9\u6837\u5199\u662f\u6bd4\u8f83\u4f4e\u6548\u7684\uff0c\u76f8\u5f53\u4e8e\u67e5\u8be2\u4e86 map \u4e24\u904d\uff0cat \u91cc\u8fd8\u989d\u5916\u505a\u4e86\u4e00\u6b21\u591a\u4f59\u7684\u5f02\u5e38\u5224\u65ad\u3002 \u6b63\u5e38\u6765\u8bf4\u662f\u7528\u901a\u7528 find \u53bb\u627e\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\uff0c\u7136\u540e\u5224\u65ad\u662f\u4e0d\u662f end() \u51b3\u5b9a\u8981\u4e0d\u8981\u91c7\u7528\u9ed8\u8ba4\u503c\u3002 auto it = m.find(key); return it != m.end() ? it->second : defl; \u996d\u7897\u91cc\u53d1\u73b0\u4e86\u8001\u9f20\ud83d\udca9\uff1f\u522b\u6025\u7740\u62a5\u8b66\uff0c\u8fd9\u4e5f\u5728\u6211\u7684\u9884\u6599\u4e4b\u4e2d\uff1a\u542f\u7528 B \u8ba1\u5212\uff0c\u6539\u5403 defl \u8fd9\u6b3e\u7f8e\u5473\u96f6\u98df\u5373\u53ef\uff01 \u5982\u679c\u662f\u826f\u5fc3\u8001\u5988 at\uff0c\u5c31\u76f4\u63a5\u542f\u7528 C \u8ba1\u5212\uff1a \u629b\u51fa\u5f02\u5e38\u7136\u540e\u5954\u6e83\u4e86\uff0c\u867d\u7136\u8fd9\u5f88\u65b9\u4fbf\u6211\u4eec\u7a0b\u5e8f\u5458\u8c03\u8bd5\u3002 \u7531\u4e8e\u81ea\u5e26\u9ed8\u8ba4\u503c\u7684\u67e5\u8be2\u8fd9\u4e00\u529f\u80fd\u5b9e\u5728\u662f\u592a\u5e38\u7528\u4e86\uff0c\u4e3a\u4e86\u628a\u8fd9\u4e2a\u64cd\u4f5c\u6d53\u7f29\u5230\u4e00\u884c\uff0c\u6211\u5efa\u8bae\u540c\u5b66\u4eec\u5c01\u88c5\u6210\u51fd\u6570\u653e\u5230\u81ea\u5df1\u7684\u9879\u76ee\u516c\u5171\u5934\u6587\u4ef6\uff08\u4e00\u822c\u662f utils.h \u4e4b\u7c7b\u7684\u540d\u79f0\uff09\u91cc\u65b9\u4fbf\u4ee5\u540e\u4f7f\u7528\uff1a template typename M::mapped_type map_get ( M const &m , typename M::key_type const &key , typename M::mapped_type const &defl ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return defl; } } int val = map_get(config, \"timeout\", -1); // \u5982\u679c\u914d\u7f6e\u6587\u4ef6\u91cc\u4e0d\u6307\u5b9a\uff0c\u5219\u9ed8\u8ba4 timeout \u4e3a -1 \u8fd9\u6837\u8fd8\u4e0d\u591f\u4f18\u96c5\uff0c\u6211\u4eec\u8fd8\u53ef\u4ee5\u66f4\u4f18\u96c5\u5730\u8fd0\u7528 C++17 \u7684\u51fd\u6570\u5f0f\u5bb9\u5668 optional\uff1a template std::optional map_get ( M const &m , typename M::key_type const &key ) { typename M::const_iterator it = m.find(key); if (it != m.end()) { return it->second; } else { return std::nullopt; } } \u5f53\u627e\u4e0d\u5230\u65f6\u5c31\u8fd4\u56de nullopt\uff0c\u627e\u5230\u5c31\u8fd4\u56de\u542b\u6709\u503c\u7684 optional\u3002 \u672c\u6bb5\u4ee3\u7801\u5df2\u9644\u5728\u6848\u4f8b\u4ee3\u7801\u5e93\u7684 \u201cmap_get.h\u201d \u6587\u4ef6\u4e2d\uff0c\u7b49\u8bfe\u540e\u53ef\u4ee5\u53bb GitHub \u4e0b\u8f7d\uff0c\u8d76\u7d27\u7528\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u5427\uff01 \u8c03\u7528\u8005\u53ef\u4ee5\u81ea\u884c\u8fd0\u7528 optional \u7684 value_or \u51fd\u6570 1 \u6307\u5b9a\u627e\u4e0d\u5230\u65f6\u91c7\u7528\u7684\u9ed8\u8ba4\u503c\uff1a int val = map_get(config, \"timeout\").value_or(-1); \u5982\u679c\u8981\u5b9e\u73b0 at \u540c\u6837\u7684\u627e\u4e0d\u5230\u5c31\u81ea\u52a8\u62a5\u9519\u529f\u80fd\uff0c\u90a3\u5c31\u6539\u7528 value \u51fd\u6570\uff1a int val = map_get(config, \"timeout\").value(); optional \u5177\u6709 operator bool \u548c\u65e0\u5f02\u5e38\u7684 operator* \uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u914d\u5408 if-auto \u8bed\u6cd5\u7cd6\u4f7f\u7528\uff1a if (auto o_val = map_get(config, \"timeout\")) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u7b49\u4ef7\u4e8e\uff1a auto o_val = map_get(config, \"timeout\"); if (o_val) { int val = *o_val; print(\"\u627e\u5230\u4e86\", val); } else { print(\"\u627e\u4e0d\u5230\u65f6\u7684\u5904\u7406\u65b9\u6848...\"); } \u4ee5\u4e0a\u662f\u5178\u578b\u7684\u51fd\u6570\u5f0f\u7f16\u7a0b\u8303\u5f0f (FP)\uff0cC++20 \u8fd8\u5f15\u5165\u4e86\u66f4\u591a\u8fd9\u6837\u7684\u73a9\u610f 2 \uff0c\u7b49\u6709\u7a7a\u4f1a\u4e13\u95e8\u5f00\u8282\u8bfe\u4e3a\u5927\u5bb6\u4e00\u4e00\u4ecb\u7ecd\u3002 auto even = [] (int i) { return 0 == i % 2; }; auto square = [] (int i) { return i * i; }; for (int i: std::views::iota(0, 6) | std::views::filter(even) | std::views::transform(square)) print(i); // 0 4 16 \u73b0\u5728\u5b66\u4e60\u5220\u9664\u5143\u7d20\u7528\u7684 erase \u51fd\u6570\uff0c\u5176\u539f\u578b\u5982\u4e0b 1 \uff1a size_t erase(K const &key); \u6307\u5b9a\u952e\u503c key\uff0cerase \u4f1a\u5220\u9664\u8fd9\u4e2a\u952e\u503c\u5bf9\u5e94\u7684\u5143\u7d20\u3002 \u8fd4\u56de\u4e00\u4e2a\u6574\u6570\uff0c\u8868\u793a\u5220\u9664\u4e86\u591a\u5c11\u4e2a\u5143\u7d20\uff08\u53ea\u80fd\u662f 0 \u6216 1\uff09\u3002 size_t erase(K const &key); erase \u8fd0\u7528\u4e3e\u4f8b\uff1a\u5220\u9664\u4e00\u4e2a\u5143\u7d20 map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); msg.erase(\"fuck\"); print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} {\"hello\": \"world\"} size_t erase(K const &key); erase \u7684\u8fd4\u56de\u503c\u548c count \u4e00\u6837\uff0c\u8fd4\u56de\u6210\u529f\u5220\u9664\u7684\u5143\u7d20\u4e2a\u6570\uff0c\u7c7b\u578b\u4e3a size_t\uff08\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff09\u3002 \u7531\u4e8e map \u4e2d\u540c\u4e00\u4e2a\u952e\u6700\u591a\u53ea\u53ef\u80fd\u6709\u4e00\u4e2a\u5143\u7d20\uff0c\u53d6\u503c\u53ea\u80fd\u4e3a 0 \u6216 1\u3002 \u5e76\u4e14 size_t \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a bool \u7c7b\u578b\uff0c0 \u5219 false\uff0c1 \u5219 true\u3002 \u56e0\u6b64\u53ef\u4ee5\u76f4\u63a5\u901a\u8fc7 erase \u7684\u8fd4\u56de\u503c\u662f\u5426\u4e3a 0 \u5224\u65ad\u662f\u5426\u5220\u9664\u6210\u529f\uff1a map msg = { {\"hello\", \"world\"}, {\"fuck\", \"rust\"}, }; print(msg); if (msg.erase(\"fuck\")) { print(\"\u5220\u9664fuck\u6210\u529f\"); } else { print(\"\u5220\u9664fuck\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } if (msg.erase(\"dick\")) { print(\"\u5220\u9664dick\u6210\u529f\"); } else { print(\"\u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728\"); } print(msg); {\"fuck\": \"rust\", \"hello\": \"world\"} \u5220\u9664fuck\u6210\u529f \u5220\u9664dick\u5931\u8d25\uff0c\u952e\u4e0d\u5b58\u5728 {\"hello\": \"world\"} size_t erase(K const &key); // \u6307\u5b9a\u952e\u7248 iterator erase(iterator it); // \u5df2\u77e5\u4f4d\u7f6e\u7248 \u533a\u522b\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u5b9e\u9645\u4e0a\u9700\u8981\u5148\u8c03\u7528 find(key) \u627e\u5230\u5143\u7d20\u4f4d\u7f6e\uff0c\u7136\u540e\u624d\u80fd\u5220\u9664\uff0c\u800c\u4e14\u8fd8\u6709\u627e\u4e0d\u5230\u7684\u53ef\u80fd\u6027\u3002 \u800c\u5df2\u77e5\u4f4d\u7f6e\u7684\u8bdd\uff08\u6bd4\u5982\u4f60\u5df2\u7ecf\u4e8b\u5148\u7528 find \u627e\u5230\u4e86\u5143\u7d20\u4f4d\u7f6e\uff09\uff0c\u53ef\u4ee5\u7528 erase(it) \u76f4\u63a5\u7528\u8fed\u4ee3\u5668\u4f5c\u4e3a\u53c2\u6570 \u590d\u6742\u5ea6\u4e0d\u540c\uff1a \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(\\log N) O(\\log N) \u3002 \u5df2\u77e5\u4f4d\u7f6e\u7248 erase(it) \u7684\u65f6\u95f4\u590d\u6742\u5ea6\uff1a O(1)+ O(1)+ \uff0c\u66f4\u9ad8\u6548\u3002 \u5176\u4e2d + + \u4ee3\u8868\u8fd9\u662f\u5e73\u644a\uff08Amortized\uff09\u4e0b\u6765\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u3002 \u8fd9\u662f\u56e0\u4e3a\u5373\u4f7f\u5df2\u77e5\u4f4d\u7f6e\uff0cerase \u6709\u53ef\u80fd\u6d89\u53ca\u6811\u7684\u66f4\u65b0\uff0c\u9700\u8981 O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u3002 \u4f46\u662f\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u9700\u8981\u7684\u66f4\u65b0\u5f88\u5c11\uff0c\u5e73\u5747\u4e0b\u6765\u662f O(1) O(1) \u7684\u3002 \u8fd9\u79cd\u60c5\u51b5\u5c31\u4f1a\u7528\u8bb0\u53f7 O(1)+ O(1)+ \u6765\u8868\u793a\u3002 erase(key) \u53ef\u80fd\u662f\u57fa\u4e8e erase(it) \u5b9e\u73b0\u7684\uff1a size_t erase(K const &key) { // \u5c0f\u5f6d\u8001\u5e08\u731c\u60f3\u6807\u51c6\u5e93\u5185\u90e8 auto it = this->find(key); // O(log N) if (it != this->end()) { this->erase(it); // O(1)+ return 1; // \u627e\u5230\u4e86\uff0c\u5220\u9664\u6210\u529f } else { return 0; // \u627e\u4e0d\u5230\uff0c\u6ca1\u6709\u5220\u9664 } } // \u5f00\u9500\u5927\u7684 find(key) \u4f1a\u8986\u76d6\u5c0f\u7684 erase(it)\uff0c\u6240\u4ee5 erase(key) \u7684\u603b\u590d\u6742\u5ea6\u4e3a O(log N) \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u8fd4\u56de\u7684\u662f\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u4f4d\u7f6e\u3002 \u7531\u4e8e map \u5185\u90e8\u4fdd\u6301\u952e\u4ece\u5c0f\u5230\u5927\u5347\u5e8f\u6392\u5217\uff0c\u6240\u8c13\u7684\u4e0b\u4e00\u4e2a\u5c31\u662f\u952e\u6bd4\u5f53\u524d\u952e\u5927\u4e00\u4e2a\u7684\u5143\u7d20\uff0c\u4f8b\u5982\uff1a {\"answer\": 42, \"hello\": 985, \"world\": 211} erase(find(\u201canswer\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201chello\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201chello\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201canswer\u201d\u3002 erase(find(\u201chello\u201d)) \u4f1a\u8fd4\u56de\u6307\u5411 \u201cworld\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u56e0\u4e3a \u201cworld\u201d \u6700\u63a5\u8fd1\u4e14\u5927\u4e8e \u201chello\u201d\u3002 erase(find(\u201cworld\u201d)) \u4f1a\u8fd4\u56de end()\uff0c\u56e0\u4e3a \u201cworld\u201d \u5df2\u7ecf\u662f\u6700\u5927\u952e\uff0c\u6ca1\u6709\u4e0b\u4e00\u4e2a\u3002 \u6b64\u5916 erase(it) \u8fd8\u6709\u6027\u80fd\u4e0a\u7684\u4f18\u52bf\uff1a \u6307\u5b9a\u4f4d\u7f6e\u7248 erase(it) \u7684\u590d\u6742\u5ea6\u662f O(1)+ O(1)+ \u6307\u5b9a\u952e\u7248 erase(key) \u7684\u590d\u6742\u5ea6\u662f O(\\log N) O(\\log N) \u5f53\u5df2\u77e5\u6307\u5411\u8981\u5220\u9664\u5143\u7d20\u7684\u8fed\u4ee3\u5668\u65f6\uff08\u4f8b\u5982\u5148\u901a\u8fc7 find \u627e\u5230\uff09\uff0c\u76f4\u63a5\u6307\u5b9a\u90a3\u4e2a\u8fed\u4ee3\u5668\u6bd4\u6307\u5b9a\u952e\u53c2\u6570\u66f4\u9ad8\u6548\u3002 \u5220\u9664\u6210\u7ee9\u6700\u5dee\u7684\u5b66\u751f\uff1a score.erase(score.begin());","title":"\u5bf9 map \u800c\u8a00\uff0c\u8fed\u4ee3\u5668\u89e3\u5f15\u7528\u5f97\u5230\u7684\u662f pair"},{"location":"stl_map/#_28","text":"\u5e38\u89c1\u9700\u6c42\u573a\u666f\uff1a\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u9519\u8bef\u793a\u8303\uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto const &[k, v]: msg) { if (k.starts_with(\"fuck\")) { msg.erase(k); // \u904d\u5386\u8fc7\u7a0b\u4e2d\u5220\u9664\u5f53\u524d\u5143\u7d20\uff0c\u4f1a\u5bfc\u81f4\u6b63\u5728\u904d\u5386\u4e2d\u7684\u8fed\u4ee3\u5668\u5931\u6548\uff0c\u5954\u6e83 } } print(msg); Segmentation fault (core dumped) \u5f15\u51fa\u95ee\u9898\uff1a\u8fed\u4ee3\u5668\u5931\u6548 \u6bcf\u5f53\u5f80 map \u4e2d\u63d2\u5165\u65b0\u5143\u7d20\u65f6\uff0c\u539f\u5148\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u4e0d\u4f1a\u5931\u6548\u3002 \u5220\u9664 map \u4e2d\u7684\u5176\u4ed6\u5143\u7d20\u65f6\uff0c\u4e5f\u4e0d\u4f1a\u5931\u6548\u3002 \u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\uff0c\u624d\u4f1a\u5931\u6548 \u3002 map m = { {\"fuck\", 985}, }; auto it = m.find(\"fuck\"); m[\"dick\"] = 211; print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"dick\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 m.erase(\"fuck\"); print(it->second); // \u6ca1\u6709\u5931\u6548\uff0c\u6253\u5370 985 map \u6bd4\u8d77 unordered_map \u6765\uff0c\u5df2\u7ecf\u662f\u975e\u5e38\u7a33\u5b9a\uff0c\u968f\u4fbf\u589e\u5220\u6539\u67e5\u90fd\u4e0d\u4f1a\u8fed\u4ee3\u5668\u5931\u6548\u3002 \u53ea\u6709\u4e00\u4e2a\u4f8b\u5916\uff1a\u5220\u9664\u7684\u5143\u7d20\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u3002 \u4f60\u62ff\u7740\u4e2a\u4f60\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u7ed3\u679c\u4f60\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\uff0c\u8fd8\u6478\u4e0d\u7740\u5934\u8111\u201c\u5947\u602a\uff0c\u660e\u660e\u5c31\u662f\u8fd9\u4e2a\u5730\u5740\u5440\u201d\uff0c\u8fd9\u65f6\u786e\u5b9e\u65e0\u8bba\u5982\u4f55\u90fd\u4e0d\u80fd\u907f\u514d\u5931\u6548\uff0c\u4e0d\u80fd\u602a map\u3002 \u800c\u521a\u521a\u7684\u6848\u4f8b\u4e2d\uff0c\u6211\u4eec\u5220\u9664\u7684\u6070\u597d\u5c31\u662f\u5f53\u524d\u6b63\u5728\u904d\u5386\u7684\u8fed\u4ee3\u5668\u6b63\u5728\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\uff08\u5373\u4f7f\u4f60\u7528\u4e86 range-based loop \u8bed\u6cd5\u7cd6\u4ed6\u80cc\u540e\u8fd8\u662f\u8fed\u4ee3\u5668\u904d\u5386\uff09\u3002 \u800c\u5f53\u4f60\u5bf9\u7740\u4e00\u4e2a\u5931\u6548\u7684\u8fed\u4ee3\u5668\u6267\u884c ++it \u65f6\uff0c\u5c31\u4ea7\u751f\u4e86 segfault \u9519\u8bef\u3002\u56e0\u4e3a\u7ea2\u9ed1\u6811\u7684\u8fed\u4ee3\u5668\u8981\u627e\u5230\u201c\u4e0b\u4e00\u4e2a\u201d\u8282\u70b9\uff0c\u9700\u8981\u8bbf\u95ee\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u4e2d\u5b58\u7684 next \u6307\u9488\uff0c\u800c\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u90fd\u5df2\u7ecf\u5220\u9664\u4e86\u5df2\u7ecf\u6790\u6784\u4e86\u5df2\u7ecf\u91ca\u653e\u5185\u5b58\u4e86\uff0c\u91cc\u9762\u5b58\u7684 next \u6307\u9488\u4e5f\u5df2\u7ecf\u91ca\u653e\uff0c\u88ab\u5176\u4ed6\u7cfb\u7edf\u6570\u636e\u8986\u76d6\uff0c\u8fd9\u65f6\u4f1a\u8bbf\u95ee\u5230\u9519\u8bef\u7684\u6307\u9488\u2014\u2014\u91ce\u6307\u9488\u3002 \u6240\u4ee5\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u5b8c\u6574\u7684\u5267\u60c5\u662f\uff1a \u4f60\u6709\u597d\u591a\u670b\u53cb\uff0c\u4eca\u5929\u4f60\u8981\u628a\u4ed6\u4eec\u5168\u70b8\u4e86\u3002 1\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 2\u53f7\u670b\u53cb\u5bb6\u91cc\u6709\u4e00\u4e2a\u5b57\u6761\uff0c\u5199\u77403\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\u3002 \u2026 \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it /* \u8fdb\u5165\u71c3\u70e7\u4e2d\u76841\u53f7\u670b\u53cb\u5bb6 */) { m.erase(it); // \u4e00\u53d1 RPG \u5bfc\u5f39\u70b8\u6bc11\u53f7\u670b\u53cb\u5bb6 } \u4f60\u62ff\u77401\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4e00\u53d1 RPG \u5bfc\u5f39\u628a\u4ed6\u5bb6\u70b8\u4e86\u3002\u7136\u540e\u4f60\u73b0\u5728\u7a81\u7136\u610f\u8bc6\u5230\u9700\u89812\u53f7\u670b\u53cb\u5bb6\u7684\u5730\u5740\uff0c\u4f46\u662f1\u53f7\u670b\u53cb\u5bb6\u5df2\u7ecf\u88ab\u4f60\u70b8\u4e86\uff0c\u4f60\u50bb\u4e4e\u4e4e\u8fdb\u5165\u71c3\u70e7\u76841\u53f7\u670b\u53cb\u5bb6\uff0c\u88ab\u706b\u70e7\u6b7b\u4e86\u3002 for (auto it = m.begin(); it != m.end(); ++it) { m.erase(it); // it \u5df2\u7ecf\u5931\u6548\uff01 } \u6b63\u786e\u7684\u505a\u6cd5\u662f\uff0c\u5148\u8fdb\u51651\u53f7\u670b\u53cb\u5bb6\uff0c\u5b89\u5168\u53d6\u51fa\u5199\u77402\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761\u540e\uff0c\u518d\u6765\u4e00\u53d1 RPG \u628a1\u53f7\u670b\u53cb\u5bb6\u70b8\u6389\u3002\u8fd9\u6837\u624d\u80fd\u987a\u5229\u627e\u52302\u53f7\u670b\u53cb\u5bb6\uff0c\u4ee5\u6b64\u7c7b\u63a8\u7ee7\u7eed\u62c63\u53f7\u2026\u2026 for (auto it = m.begin(); it != m.end(); ) { auto next_it = it; // \u5148\u8fdb\u51651\u53f7\u670b\u53cb\u7684\u5bb6 ++next_it; // \u62ff\u51fa\u5199\u67092\u53f7\u670b\u53cb\u5bb6\u5730\u5740\u7684\u5b57\u6761 m.erase(it); // \u518d\u53d1\u5c04 RPG \u5bfc\u5f39 it = next_it; // \u524d\u5f802\u53f7\u670b\u53cb\u5bb6 } \u6ce8\u610f\u5230 erase \u4f1a\u8fd4\u56de\u5220\u9664\u5143\u7d20\u7684\u4e0b\u4e00\u4e2a\u5143\u7d20\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u5c31\u662f\u8bf4\u8fd9\u4e2a RPG \u5bfc\u5f39\u975e\u5e38\u667a\u80fd\uff0c\u597d\u50cf\u4ed6\u5c31\u662f\u4e13\u4e3a\u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b\u8bbe\u8ba1\u7684\u4e00\u6837\uff1a\u4ed6\u80fd\u5728\u70b8\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u524d\uff0c\u81ea\u52a8\u62ff\u5230\u5176\u4e2d\u7684\u5b57\u6761\uff0c\u5e76\u628a\u4ed6\u901a\u8fc7\u201c\u5f39\u5c04\u5ea7\u6905\u201d\u5f39\u51fa\u6765\u9001\u5230\u95e8\u5916\u7684\u4f60\u624b\u4e0a\uff0c\u628a\u7eb8\u6761\u5b89\u5168\u9001\u51fa\u6765\u540e\uff0c\u518d\u7206\u70b8\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u3002\u8fd9\u6837\u4f60\u5c31\u4e0d\u7528\u5192\u9669\u8fdb\u5165\u71c3\u70e7\u7684\u623f\u5c4b\u62ff\u5b57\u6761\uff08\u8fed\u4ee3\u5668\u5931\u6548\u5bfc\u81f4 segfault\uff09\uff0c\u4e5f\u4e0d\u7528\u5148\u52b3\u70e6\u60a8\u81ea\u5df1\u5148\u8fdb\u53bb\u4e00\u8d9f\u623f\u5c4b\u62ff\u5b57\u6761\u4e86\uff08\u4e0a\u4e00\u9875\u4e2d\u90a3\u6837\u63d0\u524d\u4fdd\u5b58 next_it\uff09\u3002 for (auto it = m.begin(); it != m.end(); ) { it = m.erase(it); // \u8fd9\u6b3e RPG \u5bfc\u5f39\u201c\u667a\u80fd\u5730\u201d\u5728\u6467\u6bc1\u4f60\u670b\u53cb\u7684\u623f\u5c4b\u540c\u65f6\u628a\u5176\u4e2d\u7684\u5b57\u6761\u62ff\u51fa\u6765\u4e86!? } \u53ea\u662f\u6ce8\u610f\u8fd9\u91cc for \u5faa\u73af\u7684\u6b65\u8fdb\u6761\u4ef6 ++it \u8981\u5220\u6389\uff0c\u56e0\u4e3a\u667a\u80fd\u7684 RPG \u5bfc\u5f39 it = m.erase(it) \u5df2\u7ecf\u5e2e\u4f60\u6b65\u8fdb\u4e86\u3002 \u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20\uff08\u6b63\u89e3 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; for (auto it = m.begin(); it != m.end(); ) { // \u6ca1\u6709 ++it auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u4e0d\u5954\u6e83 for (auto it = m.begin(); it != m.end(); ) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { it = msg.erase(it); } else { ++it; } } \u5954\u6e83 for (auto it = m.begin(); it != m.end(); ++it) { auto const &[k, v] = *it; if (k.starts_with(\"fuck\")) { msg.erase(it); // \u6216\u8005 msg.erase(k); } }","title":"\u4e00\u8fb9\u904d\u5386\u4e00\u8fb9\u5220\u9664\u90e8\u5206\u5143\u7d20"},{"location":"stl_map/#c20-erase_if","text":"\u6279\u91cf\u5220\u9664\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20\uff08C++20 1 \uff09 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; std::erase_if(msg, [&] (auto const &kv) { auto &[k, v] = kv; return k.starts_with(\"fuck\"); }); print(msg); {\"good\": \"job\", \"hello\": \"world\"} \u5982\u679c\u4f60\u641e\u4e0d\u61c2\u8fed\u4ee3\u5668\u8fd9\u4e9b\uff0c\u8fd9\u91cc\u6211\u63d0\u4f9b\u4e00\u4e2a\u4fdd\u5e95\u5199\u6cd5\uff0c\u5148\u628a\u952e\u63d0\u524d\u4fdd\u5b58\u5230\u4e00\u4e2a vector \u4e2d\u53bb\uff1a map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; vector keys; // vector \u6216\u8005 set \u90fd\u53ef\u4ee5 for (auto const &[k, v]: msg) { // \u5148\u628a\u6240\u6709\u952e\u63d0\u524d\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc keys.push_back(k); } for (auto const &k: keys) { // \u904d\u5386\u521a\u624d\u4fdd\u5b58\u7684\u952e if (k.starts_with(\"fuck\")) { msg.erase(k); // \u952e\u503c\u5bf9\u5df2\u7ecf\u63d0\u524d\u6df1\u62f7\u8d1d\u5230\u4e34\u65f6 vector \u91cc\uff0c\u8fd9\u65f6\u5220\u9664 map \u91cc\u7684\u952e\u4e0d\u4f1a\u5954\u6e83 } } \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u795b\u9b45\u5927\u5e08\u3002 \u8fd8\u662f\u641e\u4e0d\u61c2\u7684\u8bdd\uff0c\u4e5f\u53ef\u4ee5\u65b0\u5efa\u4e00\u4e2a map\uff0c\u6761\u4ef6\u53cd\u4e4b\uff0c\u628a\u4e0d\u9700\u8981\u5220\u9664\u7684\u5143\u7d20\u63d2\u5165\u65b0 map\uff0c\u8fc7\u6ee4\u51fa\u9700\u8981\u4fdd\u7559\u7684\u5143\u7d20\uff0c\u6700\u540e\u518d\u4e00\u6b21\u6027\u7528\u65b0 map \u8986\u76d6\u65e7 map\u3002 map msg = { {\"hello\", \"world\"}, {\"fucker\", \"rust\"}, {\"fucking\", \"java\"}, {\"good\", \"job\"}, }; map newmsg; for (auto const &[k, v]: msg) { if (!k.starts_with(\"fuck\")) { // \u6ce8\u610f\u8fd9\u91cc\u6761\u4ef6\u53cd\u4e86\uff0c\u4e0d\u9700\u8981\u5220\u9664\u7684\u624d\u63d2\u5165 newmsg newmsg[k] = v; } } msg = std::move(newmsg); // \u8986\u76d6\u65e7\u7684 map\uff0c\u7528\u66f4\u9ad8\u6548\u7684\u79fb\u52a8\u8d4b\u503c\u51fd\u6570\uff0cO(1) \u590d\u6742\u5ea6 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6c38\u8fdc\u7684\u4fdd\u5e95\u5927\u5e08\u3002 \u63a5\u4e0b\u6765\u5f00\u59cb\u5b66\u4e60\u5982\u4f55\u63d2\u5165\u5143\u7d20\uff0cmap \u7684\u6210\u5458 insert \u51fd\u6570\u539f\u578b\u5982\u4e0b 1 \uff1a pair insert(pair const &kv); pair insert(pair &&kv); \u4ed6\u7684\u53c2\u6570\u7c7b\u578b\u5c31\u662f\u521a\u521a\u4ecb\u7ecd\u7684 value_type \uff0c\u4e5f\u5c31\u662f pair \u3002 pair \u662f\u4e00\u4e2a STL \u4e2d\u5e38\u89c1\u7684\u6a21\u677f\u7c7b\u578b\uff0c pair \u6709\u4e24\u4e2a\u6210\u5458\u53d8\u91cf\uff1a first\uff1aK \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u952e second\uff1aV \u7c7b\u578b\uff0c\u8868\u793a\u8981\u63d2\u5165\u5143\u7d20\u7684\u503c \u6211\u79f0\u4e4b\u4e3a\u201d\u952e\u503c\u5bf9\u201d\u3002 \u8bd5\u7740\u7528 insert \u63d2\u5165\u952e\u503c\u5bf9\uff1a map m; pair p; p.first = \"fuck\"; // \u952e p.second = 985; // \u503c m.insert(p); // pair \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a insert \u53c2\u6570\u6240\u9700\u7684 pair print(m); \u7ed3\u679c\uff1a {\"fuck\": 985} \u7b80\u5316 insert \u76f4\u63a5\u4f7f\u7528 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u521d\u59cb\u5316 first \u548c second pair p(\"fuck\", 985); m.insert(p); \u4e0d\u7528\u521b\u5efa\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cf\uff0cpair \u8868\u8fbe\u5f0f\u76f4\u63a5\u4f5c\u4e3a insert \u51fd\u6570\u7684\u53c2\u6570 m.insert(pair(\"fuck\", 985)); \u53ef\u4ee5\u7528 std::make_pair \u8fd9\u4e2a\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u63a8\u5bfc\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u7701\u7565 m.insert(make_pair(\"fuck\", 985)); // \u867d\u7136\u4f1a\u63a8\u5bfc\u4e3a pair \u4f46\u8fd8\u662f\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a pair \u7531\u4e8e insert \u51fd\u6570\u539f\u578b\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528 C++11 \u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u5217\u8868 {\u2026}\uff0c\u65e0\u9700\u6307\u5b9a\u7c7b\u578b m.insert({\"fuck\", 985}); // \u2705 \u56e0\u6b64\uff0cinsert \u7684\u6700\u4f73\u7528\u6cd5\u662f\uff1a map m; m.insert({\"key\", \"val\"}); insert \u63d2\u5165\u548c [] \u5199\u5165\u7684\u5f02\u540c\uff1a \u540c\uff1a\u5f53\u952e K \u4e0d\u5b58\u5728\u65f6\uff0cinsert \u548c [] \u90fd\u4f1a\u521b\u5efa\u952e\u503c\u5bf9\u3002 \u5f02\uff1a\u5f53\u952e K \u5df2\u7ecf\u5b58\u5728\u65f6\uff0cinsert \u4e0d\u4f1a\u8986\u76d6\uff0c\u9ed8\u9ed8\u79bb\u5f00\uff1b\u800c [] \u4f1a\u8986\u76d6\u65e7\u7684\u503c\u3002 \u4f8b\u5b50\uff1a map m; m.insert({\"key\", \"old\"}); m.insert({\"key\", \"new\"}); // \u63d2\u5165\u5931\u8d25\uff0c\u9ed8\u9ed8\u653e\u5f03\u4e0d\u51fa\u9519 print(m); {\"key\": \"old\"} map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; // \u5df2\u7ecf\u5b58\u5728\uff1f\u6211\u8e0f\u9a6c\u5f3a\u884c\u8986\u76d6\uff01 print(m); {\"key\": \"new\"} insert \u7684\u8fd4\u56de\u503c\u662f pair \u7c7b\u578b\uff0c STL \u7684\u5c3f\u6027\uff1a\u5728\u9700\u8981\u4e00\u6b21\u6027\u8fd4\u56de\u4e24\u4e2a\u503c\u65f6\u559c\u6b22\u7528 pair \u3002 \u8fd9\u53c8\u662f\u4e00\u4e2a pair \u7c7b\u578b\uff0c\u5176\u5177\u6709\u4e24\u4e2a\u6210\u5458\uff1a first\uff1aiterator \u7c7b\u578b\uff0c\u662f\u4e2a\u8fed\u4ee3\u5668 second\uff1abool \u7c7b\u578b\uff0c\u8868\u793a\u63d2\u5165\u6210\u529f\u4e0e\u5426\uff0c\u5982\u679c\u53d1\u751f\u952e\u51b2\u7a81\u5219\u4e3a false \u5176\u4e2d first \u8fd9\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\uff1a \u5982\u679c\u63d2\u5165\u6210\u529f\uff08second \u4e3a true\uff09\uff0c\u6307\u5411\u521a\u521a\u6210\u529f\u63d2\u5165\u7684\u5143\u7d20\u4f4d\u7f6e \u5982\u679c\u63d2\u5165\u5931\u8d25\uff08second \u4e3a false\uff09\uff0c\u8bf4\u660e\u5df2\u7ecf\u6709\u76f8\u540c\u7684\u952e K \u5b58\u5728\uff0c\u53d1\u751f\u4e86\u952e\u51b2\u7a81\uff0c\u6307\u5411\u5df2\u7ecf\u5b58\u5728\u7684\u90a3\u4e2a\u5143\u7d20 \u5176\u5b9e insert \u8fd4\u56de\u7684 first \u8fed\u4ee3\u5668\u7b49\u4ef7\u4e8e\u63d2\u5165\u4ee5\u540e\u518d\u91cd\u65b0\u7528 find \u627e\u5230\u521a\u521a\u63d2\u5165\u7684\u90a3\u4e2a\u952e\uff0c\u53ea\u662f\u6548\u7387\u66f4\u9ad8\uff1a auto it = m.insert({k, v}).first; // \u9ad8\u6548\uff0c\u53ea\u9700\u904d\u5386\u4e00\u6b21 m.insert({k, v}); // \u63d2\u5165\u5b8c\u5c31\u5fd8\u4e8b\u4e86 auto it = m.find(k); // \u91cd\u65b0\u904d\u5386\u7b2c\u4e8c\u6b21\uff0c\u4f46\u7ed3\u679c\u4e00\u6837 \u53c2\u8003 C \u7f16\u7a0b\u7f51 1 \u5bf9 insert \u8fd4\u56de\u503c\u7684\u89e3\u91ca\uff1a \u5f53\u8be5\u65b9\u6cd5\u5c06\u65b0\u952e\u503c\u5bf9\u6210\u529f\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u65f6\uff0c\u8fd4\u56de\u7684\u8fed\u4ee3\u5668\u6307\u5411\u65b0\u6dfb\u52a0\u7684\u952e\u503c\u5bf9\uff1b \u53cd\u4e4b\uff0c\u5982\u679c\u6dfb\u52a0\u5931\u8d25\uff0c\u8be5\u8fed\u4ee3\u5668\u6307\u5411\u7684\u662f\u5bb9\u5668\u4e2d\u548c\u8981\u6dfb\u52a0\u952e\u503c\u5bf9\u952e\u76f8\u540c\u7684\u90a3\u4e2a\u952e\u503c\u5bf9\u3002 \u53ef\u4ee5\u7528 insert \u8fd4\u56de\u7684 second \u5224\u65ad\u63d2\u5165\u591a\u6b21\u662f\u5426\u6210\u529f\uff1a map m; print(m.insert({\"key\", \"old\"}).second); // true print(m.insert({\"key\", \"new\"}).second); // false m.erase(\"key\"); // \u628a\u539f\u6765\u7684 {\"key\", \"old\"} \u5220\u4e86 print(m.insert({\"key\", \"new\"}).second); // true \u4e5f\u53ef\u4ee5\u7528 structured-binding \u8bed\u6cd5\u62c6\u89e3\u4ed6\u8fd4\u56de\u7684 pair \uff1a map counter; auto [it, success] = counter.insert(\"key\", 1); // \u76f4\u63a5\u7528 if (!success) { // \u5982\u679c\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4fee\u6539\u5176\u503c+1 it->second = it->second + 1; } else { // \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u5219\u6253\u5370\u4ee5\u4e0b\u4fe1\u606f print(\"created a new entry!\"); } \u4ee5\u4e0a\u8fd9\u4e00\u957f\u4e32\u4ee3\u7801\u548c\u4e4b\u524d\u201c\u4f18\u96c5\u201d\u7684\u8ba1\u6570 [] \u7b49\u4ef7\uff1a counter[\"key\"]++;","title":"C++20 \u66f4\u597d\u7684\u5199\u6cd5\uff1aerase_if"},{"location":"stl_map/#insert_or_assign","text":"\u5728 C++17 \u4e2d\uff0c[] \u5199\u5165\u6709\u4e86\u4e2a\u66f4\u9ad8\u6548\u7684\u66ff\u4ee3\u54c1 insert_or_assign 1 \uff1a pair insert_or_assign(K const &k, V v); pair insert_or_assign(K &&k, V v); \u6b63\u5982\u4ed6\u540d\u5b57\u7684\u542b\u4e49\uff0c\u201c\u63d2\u5165\u6216\u8005\u5199\u5165\u201d\uff1a \u5982\u679c K \u4e0d\u5b58\u5728\u5219\u521b\u5efa\uff08\u63d2\u5165\uff09 \u5982\u679c K \u5df2\u7ecf\u5b58\u5728\u5219\u8986\u76d6\uff08\u5199\u5165\uff09 \u7528\u6cd5\u5982\u4e0b\uff1a m.insert_or_assign(\"key\", \"new\"); // \u4e0e insert \u4e0d\u540c\uff0c\u4ed6\u4e0d\u9700\u8981 {...}\uff0c\u4ed6\u7684\u53c2\u6570\u5c31\u662f\u4e24\u4e2a\u5355\u72ec\u7684 K \u548c V \u8fd4\u56de\u503c\u4f9d\u65e7\u662f pair \u3002\u7531\u4e8e\u8fd9\u51fd\u6570\u5728\u952e\u51b2\u7a81\u65f6\u4f1a\u8986\u76d6\uff0c\u6309\u7406\u8bf4\u662f\u5fc5\u5b9a\u6210\u529f\u4e86\uff0c\u56e0\u6b64\u8fd9\u4e2a bool \u7684\u542b\u4e49\u4ece\u201c\u662f\u5426\u63d2\u5165\u6210\u529f\u201d\u53d8\u4e3a\u201c\u662f\u5426\u521b\u5efa\u4e86\u5143\u7d20\u201d\uff0c\u5982\u679c\u662f\u521b\u5efa\u7684\u65b0\u5143\u7d20\u8fd4\u56detrue\uff0c\u5982\u679c\u8986\u76d6\u4e86\u65e7\u5143\u7d20\u8fd4\u56defalse\u3002","title":"insert_or_assign"},{"location":"stl_map/#insert_or_assign_1","text":"\u770b\u6765 insert_or_assign \u548c [] \u7684\u6548\u679c\u5b8c\u5168\u76f8\u540c\uff01\u90fd\u662f\u5728\u952e\u503c\u51b2\u7a81\u65f6\u8986\u76d6\u65e7\u503c\u3002 \u65e2\u7136 [] \u5df2\u7ecf\u53ef\u4ee5\u505a\u5230\u540c\u6837\u7684\u6548\u679c\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u53d1\u660e\u4e2a insert_or_assign \u5462\uff1f insert_or_assign \u7684\u4f18\u70b9\u662f \u4e0d\u9700\u8981\u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 \uff0c\u53ef\u4ee5\u63d0\u5347\u6027\u80fd\u3002 \u5176\u5e94\u7528\u573a\u666f\u6709\u4ee5\u4e0b\u4e09\u79cd\u60c5\u51b5\uff1a \u23f1 \u60a8\u7279\u522b\u5728\u4e4e\u6027\u80fd \u274c \u6709\u65f6 V \u7c7b\u578b\u6ca1\u6709\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff0c\u7528 [] \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \ud83e\udd75 \u5f3a\u8feb\u75c7\u53d1\u4f5c \u5426\u5219\u7528 [] \u5199\u5165\u4e5f\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u800c\u4e14 insert_or_assign \u80fd\u53d6\u4ee3 [] \u7684\u5c97\u4f4d\u4ec5\u9650\u4e8e\u7eaf\u5199\u5165\uff0c\u4e4b\u524d counter[key]++ \u8fd9\u79cd\u201c\u4f18\u96c5\u201d\u5199\u6cd5\u4f9d\u7136\u662f\u9700\u8981\u7528 [] \u7684\u3002","title":"insert_or_assign \u7684\u4f18\u52bf"},{"location":"stl_map/#_29","text":"\u521b\u5efa\u65b0\u952e\u65f6\uff0cinsert_or_assign \u66f4\u9ad8\u6548\u3002","title":"\u6548\u7387\u95ee\u9898"},{"location":"stl_map/#_30","text":"map m; m[\"key\"] = \"old\"; m[\"key\"] = \"new\"; print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 [] \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u9ed8\u8ba4\u6784\u9020\u51fd\u6570 V() \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&)","title":"[]"},{"location":"stl_map/#insert_or_assign_2","text":"map m; m.insert_or_assign(\"key\", \"old\"); m.insert_or_assign(\"key\", \"new\"); print(m); {\"key\": \"new\"} \u8986\u76d6\u65e7\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u8d4b\u503c\u51fd\u6570 V &operator=(V &&) \u521b\u5efa\u65b0\u952e\u65f6\uff0c\u4f7f\u7528 insert_or_assign \u9020\u6210\u7684\u5f00\u9500\uff1a \u8c03\u7528\u79fb\u52a8\u6784\u9020\u51fd\u6570 V(V &&)","title":"insert_or_assign"},{"location":"stl_map/#_31","text":"\u603b\u7ed3\uff0c\u5982\u679c\u4f60\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u5e76\u4e14\u662f C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 insert_or_assign \u8bfb\u53d6\u7528 at \u5982\u679c\u6ca1\u6709\u6027\u80fd\u5f3a\u8feb\u75c7\uff0c\u6216\u8005\u4f60\u7684\u7f16\u8bd1\u5668\u4e0d\u652f\u6301 C++17 \u6807\u51c6\uff1a \u5199\u5165\u7528 [] \u8bfb\u53d6\u7528 at \u6700\u540e\uff0c\u5982\u679c\u4f60\u662f\u8fd8\u539f\u8bba\u8005\uff0c\u53ea\u9700\u8981 find \u548c insert \u51fd\u6570\u5c31\u662f\u5b8c\u5907\u7684\u4e86\uff0c\u522b\u7684\u51fd\u6570\u90fd\u4e0d\u7528\u53bb\u8bb0\u3002\u6240\u6709 at\u3001[]\u3001insert_or_assign \u4e4b\u7c7b\u7684\u64cd\u4f5c\u90fd\u53ef\u4ee5\u901a\u8fc7 find \u548c insert \u7684\u7ec4\u5408\u62f3\u5b9e\u73b0\uff0c\u4f8b\u5982\u521a\u521a\u6211\u4eec\u81ea\u5b9a\u4e49\u7684 map_get\u3002","title":"\u90a3\u6211\u5e94\u8be5\u7528\u4ec0\u4e48"},{"location":"stl_map/#insert_or_assign-vs-insert","text":"\u56de\u987e\u4e4b\u524d\u7684\u53cd\u5411\u67e5\u627e\u8868\uff0c\u5982\u679c\u6709\u91cd\u590d\uff0c\u5982\u4f55\u533a\u5206\u627e\u7b2c\u4e00\u4e2a\u8fd8\u662f\u6700\u540e\u4e00\u4e2a\uff1f \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u6700\u540e\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert_or_assign(arr[i], i); // \u7b49\u4ef7\u4e8e arrinv[arr[i]] = i; } \u6784\u5efa\u53cd\u5411\u67e5\u627e\u8868\uff0c\u627e\u5230\u7b2c\u4e00\u4e2a\u7684\u4e0b\u6807\uff1a for (size_t i = 0; i < arr.size(); i++) { arrinv.insert({arr[i], i}); }","title":"insert_or_assign vs insert\uff1a\u987a\u5e8f\u95ee\u9898"},{"location":"stl_map/#insert","text":"\u521a\u521a\u4ecb\u7ecd\u7684\u90a3\u4e9b insert \u4e00\u6b21\u53ea\u80fd\u63d2\u5165\u4e00\u4e2a\u5143\u7d20\uff0cinsert \u8fd8\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u7248\u672c\uff0c\u7528\u4e8e\u6279\u91cf\u63d2\u5165\u4e00\u7cfb\u5217\u5143\u7d20\u3002 template void insert(InputIt beg, InputIt end); \u53c2\u6570 1 \u662f\u4e24\u4e2a\u8fed\u4ee3\u5668 beg \u548c end\uff0c\u7ec4\u6210\u4e00\u4e2a\u533a\u95f4\uff0c\u4e4b\u95f4\u662f\u4f60\u8981\u63d2\u5165\u7684\u6570\u636e\u3002 \u8be5\u533a\u95f4\u53ef\u4ee5\u662f\u4efb\u4f55\u5176\u4ed6\u5bb9\u5668\u7684 begin() \u548c end() \u8fed\u4ee3\u5668\u2014\u2014\u90a3\u4f1a\u628a\u8be5\u5bb9\u5668\u4e2d\u6240\u6709\u7684\u5143\u7d20\u90fd\u63d2\u5165\u5230\u672c map \u4e2d\u53bb\u3002 \u4f8b\u5982\uff0c\u628a vector \u4e2d\u7684\u952e\u503c\u5bf9\u6279\u91cf\u63d2\u5165 map\uff1a vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); // {\"delay\": 211, \"timeout\": 985}","title":"\u6279\u91cf insert"},{"location":"stl_map/#insert_1","text":"\u6ce8\uff1a\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5982\u679c vector \u4e2d\u6709\u91cd\u590d\u7684\u952e\uff0c\u5219\u4f1a\u4ee5\u952e\u7b2c\u4e00\u6b21\u51fa\u73b0\u65f6\u7684\u503c\u4e3a\u51c6\uff0c\u4e4b\u540e\u91cd\u590d\u51fa\u73b0\u7684\u952e\u4f1a\u88ab\u5ffd\u89c6\u3002 vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config; config.insert(kvs.begin(), kvs.end()); print(config); {\"delay\": 211, \"timeout\": 985} vector> kvs = { {\"timeout\", 985}, {\"delay\", 211}, {\"delay\", 666}, {\"delay\", 233}, {\"timeout\", 996}, }; map config = { {\"timeout\", 404}, }; config.insert(kvs.begin(), kvs.end()); print(config); vector> v; {\"delay\": 211, \"timeout\": 404}","title":"\u6279\u91cf insert \u540c\u6837\u9075\u5faa\u4e0d\u8986\u76d6\u539f\u5219"},{"location":"stl_map/#insert-map","text":"\u6279\u91cf insert \u8fd0\u7528\u6848\u4f8b\uff1a\u4e24\u4e2a map \u5408\u5e76 \u8fd9\u4e2a\u6279\u91cf insert \u8f93\u5165\u7684\u8fed\u4ee3\u5668\u53ef\u4ee5\u662f\u4efb\u4f55\u5bb9\u5668\uff0c\u751a\u81f3\u53ef\u4ee5\u662f\u53e6\u4e00\u4e2a map \u5bb9\u5668\u3002 \u8fd0\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u4e24\u4e2a map \u7684\u5e76\u96c6\u64cd\u4f5c\u3002 map m1 = { // \u7b2c\u4e00\u4e2a map {\"answer\", 42}, {\"timeout\", 7}, }; map m2 = { // \u7b2c\u4e8c\u4e2a map {\"timeout\", 985}, {\"delay\", 211}, }; m1.insert(m2.begin(), m2.end()); // \u628a m2 \u7684\u5185\u5bb9\u4e0e m1 \u5408\u5e76\uff0c\u7ed3\u679c\u5199\u56de\u5230 m1 print(m1); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd8\u662f\u7531\u4e8e insert \u4e0d\u8986\u76d6\u7684\u7279\u6027\uff0c\u5f53\u9047\u5230\u91cd\u590d\u7684\u952e\u65f6\uff08\u4f8b\u5982\u4e0a\u9762\u7684 \u201ctimeout\u201d\uff09\uff0c\u4f1a\u4ee5 m1 \u4e2d\u7684\u503c\u4e3a\u51c6\u3002","title":"\u6279\u91cf insert \u5b9e\u73b0 map \u5408\u5e76"},{"location":"stl_map/#_32","text":"\u4f7f\u7528 m1.insert(m2.begin(), m2.end()) \u540e\uff0c\u5408\u5e76\u7684\u7ed3\u679c\u4f1a\u5c31\u5730\u5199\u5165 m1\u3002 \u5982\u679c\u5e0c\u671b\u5408\u5e76\u7ed3\u679c\u653e\u5230\u4e00\u4e2a\u65b0\u7684 map \u5bb9\u5668\u4e2d\u800c\u4e0d\u662f\u5c31\u5730\u4fee\u6539 m1\uff0c\u8bf7\u5148\u81ea\u884c\u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d\uff1a const map m1 = { // \u7b2c\u4e00\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"answer\", 42}, {\"timeout\", 7}, }; const map m2 = { // \u7b2c\u4e8c\u4e2a map\uff0c\u4fee\u9970\u6709 const \u7981\u6b62\u4fee\u6539 {\"timeout\", 985}, {\"delay\", 211}, }; auto m12 = m1; // \u751f\u6210\u4e00\u4efd m1 \u7684\u6df1\u62f7\u8d1d m12\uff0c\u907f\u514d insert \u5c31\u5730\u4fee\u6539 m1 m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c {\"answer\": 42, \"delay\": 211, \"timeout\": 7}","title":"\u5c31\u5730\u5199\u5165\uff01"},{"location":"stl_map/#insert_2","text":"auto m12 = m1; m12.insert(m2.begin(), m2.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m1 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u521a\u521a\u5199\u7684 m1 \u548c m2 \u5408\u5e76\uff0c\u9047\u5230\u91cd\u590d\u65f6\u4f1a\u4f18\u5148\u91c7\u53d6 m1 \u91cc\u7684\u503c\uff0c\u5982\u679c\u5e0c\u671b\u4f18\u5148\u91c7\u53d6 m2 \u7684\u5462\uff1f\u53cd\u4e00\u53cd\u5c31\u53ef\u4ee5\u4e86\uff1a auto m12 = m2; m12.insert(m1.begin(), m1.end()); print(m12); // m1 \u548c m2 \u7684\u5408\u5e76\u7ed3\u679c\uff0c\u952e\u51b2\u7a81\u65f6\u4f18\u5148\u53d6 m2 \u7684\u503c {\"answer\": 42, \"delay\": 211, \"timeout\": 985} \u8981\u662f\u5b66\u4e0d\u4f1a\u6279\u91cf insert\uff0c\u90a3\u624b\u5199\u4e00\u4e2a for \u5faa\u73af\u904d\u5386 m2\uff0c\u7136\u540e m1.insert_or_assign(k2, v2) \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u603b\u4e4b\u8981\u61c2\u5f97\u53d8\u901a\uff0c\u52a8\u52a8\u8111\uff0c\u603b\u662f\u6709\u4fdd\u5e95\u5199\u6cd5\u7684\u3002","title":"\u6279\u91cf insert \u4f18\u5148\u4fdd\u7559\u5df2\u7ecf\u6709\u7684"},{"location":"stl_map/#_33","text":"\u6709\u540c\u5b66\u5c31\u95ee\u4e86\uff0c\u8fd9\u4e2a insert \u5b9e\u73b0\u4e86 map \u7684\u5e76\u96c6\u64cd\u4f5c\uff0c\u90a3\u4ea4\u96c6\u64cd\u4f5c\u5462\uff1f\u8fd9\u5176\u5b9e\u662f set \u7684\u5e38\u89c4\u64cd\u4f5c\u800c\u4e0d\u662f map \u7684\uff1a set_intersection\uff08\u53d6\u96c6\u5408\u4ea4\u96c6\uff09 set_union\uff08\u53d6\u96c6\u5408\u5e76\u96c6\uff09 set_difference\uff08\u53d6\u96c6\u5408\u5dee\u96c6\uff09 set_symmetric_difference\uff08\u53d6\u96c6\u5408\u5bf9\u79f0\u5dee\u96c6\uff09 \u975e\u5e38\u62b1\u6b49\u5728\u4e4b\u524d\u7684 set \u8bfe\u4e2d\u5b8c\u5168\u6ca1\u6709\u63d0\u53ca\uff0c\u56e0\u4e3a\u6211\u8ba4\u4e3a\u90a3\u662f \u5934\u6587\u4ef6\u91cc\u7684\u4e1c\u897f\u3002 \u4e0d\u8fc7\u522b\u62c5\u5fc3\uff0c\u4e4b\u540e\u6211\u4eec\u4f1a\u4e13\u95e8\u6709\u4e00\u8282 algorithm \u8bfe\u8be6\u89e3 STL \u4e2d\u8fd9\u4e9b\u5168\u5c40\u51fd\u6570\u2014\u2014\u6211\u79f0\u4e4b\u4e3a\u7b97\u6cd5\u6a21\u677f\uff0c\u56e0\u4e3a\u4ed6\u63d0\u4f9b\u4e86\u5f88\u591a\u5e38\u7528\u7684\u7b97\u6cd5\uff0c\u5bf9\u5c0f\u5f6d\u8001\u5e08\u8fd9\u79cd\u7b97\u6cd5\u5f31\u9e21\u800c\u8a00\uff0c\u5b9e\u5728\u975e\u5e38\u597d\u7528\uff0c\u5988\u5988\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3\u6211\u7684 ACM \u5956\u676f\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u5236\u4f5c\u5b8c algorithm \u8bfe\u4e4b\u524d\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u81ea\u884c\u53c2\u8003 https://blog.csdn.net/u013095333/article/details/89322501 \u63d0\u524d\u8fdb\u884c\u5b66\u4e60\u8fd9\u56db\u4e2a\u51fd\u6570\u3002 std::set_union(A.begin(), A.end(), B.begin(), B.end(), std::inserter(C, C.begin())); // C = A U B \u6ce8\uff1aset_union \u4ec5\u4ec5\u8981\u6c42\u8f93\u5165\u7684\u4e24\u4e2a\u533a\u95f4\u6709\u5e8f\uff0c\u53ef\u4ee5\u662f set\uff0c\u4e5f\u53ef\u4ee5\u662f\u6392\u5e8f\u8fc7\u7684 vector\u3002\u800c\u4e14\u901a\u8fc7\u91cd\u8f7d\u8fd0\u7b97\u7b26\u6216\u8005\u6307\u5b9a compare \u51fd\u6570\uff0c\u540c\u6837\u53ef\u4ee5\u6a21\u62df map \u53ea\u5bf9 key \u90e8\u5206\u6392\u5e8f\u7684\u6548\u679c\u2014\u2014\u53c2\u8003 thrust::sort_by_key\uff0c\u4f46\u5f88\u53ef\u60dc STL \u6ca1\u6709\u8fd9\u51fd\u6570\uff0c\u9700\u8981\u81ea\u5b9a\u4e49 compare \u51fd\u6570\u6a21\u62df\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u4e9b\u64cd\u4f5c\u4e5f\u662f\u5f88\u5bb9\u6613\u57fa\u4e8e map \u7684 contains\u3001erase\u3001insert \u7b49\u63a5\u53e3\u201c\u52a8\u52a8\u8111\u201d\u5199\u51fa\u4fdd\u5e95\u5199\u6cd5\uff1a map m12; for (const auto &[k, v] : m2) { if (m1.contains(k)) { // \u6b64\u5904\u4e3a count \u4e5f\u53ef\u4ee5 // \u4ea4\u96c6\u64cd\u4f5c\uff1a\u5982\u679c m1 \u548c m2 \u90fd\u6709\u8fd9\u4e2a\u952e\uff0c\u5219\u63d2\u5165\u4ed6\u4fe9\u7684\u4ea4\u96c6 m12 m12.insert({k, v}); } }","title":"\u5176\u4ed6\u64cd\u4f5c\uff1a\u4ea4\u96c6\u3001\u5e76\u96c6\u3001\u5dee\u96c6\u7b49"},{"location":"stl_map/#insert_3","text":"C++11 \u8fd8\u5f15\u5165\u4e86\u4e00\u4e2a\u4ee5\u521d\u59cb\u5316\u5217\u8868\uff08initializer_list\uff09\u4e3a\u53c2\u6570\u7684 insert \u7248\u672c\uff1a void insert(initializer_list> ilist); \u7528\u6cd5\u548c map \u7684\u6784\u9020\u51fd\u6570\u4e00\u6837\uff0c\u8fd8\u662f\u7528\u82b1\u62ec\u53f7\u5217\u8868\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m.insert({ // \u6279\u91cf\u518d\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, // \"timeout\" \u53d1\u751f\u952e\u51b2\u7a81\uff0c\u6839\u636e insert \u7684\u7279\u6027\uff0c\u4e0d\u4f1a\u8986\u76d6 {\"delay\", 211}, }); {\"answer\": 42, \"delay\": 211, \"timeout\": 7} \u6ce8\uff1a\u8fd9\u91cc\u8fd8\u662f\u548c\u9010\u4e2a insert \u4e00\u6837\uff0c\u91cd\u590d\u7684\u952e \u201ctimeout\u201d \u6ca1\u6709\u88ab\u8986\u76d6\uff0c\u4f9d\u65e7\u4e86\u4fdd\u7559\u539f\u503c\u3002","title":"insert \u4e00\u4e2a\u521d\u59cb\u5316\u5217\u8868"},{"location":"stl_map/#insert_4","text":"m.insert({ {\"timeout\", 985}, {\"delay\", 211}, }); \u603b\u4e4b\u8fd9\u73a9\u610f\u548c\u5206\u522b\u8c03\u7528\u4e24\u6b21 insert \u7b49\u4ef7\uff1a m.insert({\"timeout\", 985}); m.insert({\"delay\", 211}); \u5982\u679c\u9700\u8981\u8986\u76d6\u539f\u503c\u7684\u6279\u91cf\u5199\u5165\uff0c\u8fd8\u662f\u5f97\u4e56\u4e56\u5199\u4e2a for \u5faa\u73af\u8c03\u7528 [] \u6216 insert_or_assign\u3002 \u95ee\uff1a\u65e2\u7136\u548c\u6279\u91cf\u63d2\u5165\u6ca1\u4ec0\u4e48\u533a\u522b\uff0c\u590d\u6742\u5ea6\u4e5f\u4e00\u6837\u662f O(\\log N) O(\\log N) \uff0c\u90a3\u6279\u91cf insert \u7a76\u7adf\u8fd8\u6709\u4ec0\u4e48\u5b58\u5728\u7684\u5fc5\u8981\u5462\uff1fmap \u53c8\u4e0d\u50cf vector \u4e00\u4e2a\u4e2a\u5206\u522b\u63d2\u5165\u4f1a\u53d8\u6210 O(N^2) O(N^2) \u590d\u6742\u5ea6\uff0c\u786e\u5b9e\u9700\u8981\u63d0\u4f9b\u4e2a\u6279\u91cf\u63d2\u5165\u7684\u65b9\u6cd5\u3002 \u7b54\uff1a \u662f\u4e3a\u4e86\u7edf\u4e00\uff0c\u65e2\u7136 vector \u90fd\u6709\u6279\u91cf insert\uff0c\u90a3 set \u548c map \u4e5f\u5f97\u6709\u624d\u7b26\u5408\u5b8c\u7f8e\u4e3b\u4e49\u7f8e\u5b66\uff0c\u800c\u4e14\u7528\u4ed6\u6765\u5408\u5e76\u4e24\u4e2a map \u4e5f\u5f88\u65b9\u4fbf\u3002 \u590d\u6742\u5ea6\u5e76\u4e0d\u4e00\u6837\uff0c\u5f53\u8f93\u5165\u5df2\u7ecf\u6709\u5e8f\u65f6\uff0c\u6279\u91cf insert \u4f1a\u6bd4\u9010\u4e2a insert \u66f4\u5feb\uff0c\u53ea\u9700 O(N) O(N) \u800c\u4e0d\u662f O(N \\log N) O(N \\log N) \uff1b\u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u90a3\u4e48\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \uff0c\u7a0d\u540e\u4f1a\u8bb2\u539f\u7406\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u9510\u8bc4\u6279\u91cf insert \u6709\u4ec0\u4e48\u7528"},{"location":"stl_map/#operator","text":"map &operator=(initializer_list> ilist); map \u4e5f\u652f\u6301\u8d4b\u503c\u51fd\u6570\uff0c\u4e0d\u4ec5\u6709 map \u81ea\u5df1\u7ed9\u81ea\u5df1\u8d4b\u503c\u7684\u79fb\u52a8\u8d4b\u503c\u548c\u62f7\u8d1d\u8d4b\u503c\u51fd\u6570\uff0c\u8fd8\u6709\u4ece\u5217\u8868\u521d\u59cb\u5316\u7684\u51fd\u6570\u3002 \u7528\u6cd5\u662f\u7b49\u53f7\u53f3\u8fb9\u4e00\u4e2a\u82b1\u62ec\u53f7\u5217\u8868\uff0c\u4f5c\u7528\u662f\u6e05\u7a7a\u539f\u6709\u5185\u5bb9\uff0c\u76f4\u63a5\u8bbe\u4e3a\u4e00\u4e2a\u5168\u65b0\u7684 map\uff1a map m = { // \u521d\u59cb\u5316\u65f6\u5c31\u63d2\u5165\u4e24\u4e2a\u5143\u7d20 {\"answer\", 42}, {\"timeout\", 7}, }; m = { // \u539f\u6709\u5185\u5bb9\u5168\u90e8\u6e05\u7a7a\uff01\u91cd\u65b0\u63d2\u5165\u4e24\u4e2a\u65b0\u5143\u7d20 {\"timeout\", 985}, {\"delay\", 211}, }; {\"delay\": 211, \"timeout\": 985} \u76f8\u5f53\u4e8e clear \u4e86\u518d\u91cd\u65b0 insert\uff0c\u539f\u6709\u7684 \u201canswer\u201d \u952e\u4e5f\u88ab\u5220\u6389\u4e86\u3002","title":"operator= \u4e5f\u652f\u6301\u521d\u59cb\u5316\u5217\u8868"},{"location":"stl_map/#_34","text":"\u8981\u6ce8\u610f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) \u548c\u6784\u9020\u51fd\u6570 map(initializer_list) \u662f\u4e0d\u540c\u7684\u3002 \u6784\u9020\u51fd\u6570\u662f\u521d\u59cb\u5316\u65f6\u8c03\u7528\u7684\uff08\u65e0\u8bba\u6709\u6ca1\u6709 = \u53f7\uff09\uff0c\u8d4b\u503c\u51fd\u6570\u662f\u540e\u671f\u91cd\u65b0\u8d4b\u503c\u65f6\u8c03\u7528\u7684\u3002 map m{ // \u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; map m = { // \u867d\u7136\u6709\u7b49\u53f7\uff0c\u4f46\u8fd9\u91cc\u662f\u521d\u59cb\u5316\u8bed\u5883\uff0c\u8c03\u7528\u7684\u4f9d\u7136\u662f\u6784\u9020\u51fd\u6570 map(initializer_list) {\"answer\", 42}, {\"timeout\", 7}, }; m = { // m \u5df2\u7ecf\u521d\u59cb\u5316\u8fc7\uff0c\u8fd9\u91cc\u662f\u91cd\u65b0\u8d4b\u503c\uff0c\u624d\u662f\u8d4b\u503c\u51fd\u6570 operator=(initializer_list) {\"timeout\", 985}, {\"delay\", 211}, }; \u5982\u679c\u4e00\u4e2a\u7c7b\u8981\u652f\u6301\u521d\u59cb\u5316\uff0c\u53c8\u8981\u652f\u6301\u540e\u671f\u91cd\u65b0\u8d4b\u503c\uff0c\u90a3\u4e48\u6784\u9020\u51fd\u6570\u548c\u8d4b\u503c\u51fd\u6570\u90fd\u8981\u5b9e\u73b0\u3002 \u4f46\u4e5f\u53ef\u4ee5\u9009\u62e9\u53ea\u5b9a\u4e49 operator=(map &&) \u79fb\u52a8\u8d4b\u503c\u51fd\u6570\u800c\u4e0d\u5b9a\u4e49 operator=(initializer_list) \u3002\u8fd9\u6837\u5f53\u8bd5\u56fe operator=(initializer_list) \u65f6\uff0c\u4f1a\u5339\u914d\u5230 map(initializer_list) \u8fd9\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\u6765\u8f6c\u6362\uff0c\u7136\u540e\u8c03\u7528\u5230 operator=(map &&) \u3002\u6807\u51c6\u5e93\u9009\u62e9\u5c06\u4e24\u4e2a\u90fd\u5b9a\u4e49\u53ef\u80fd\u662f\u5904\u4e8e\u907f\u514d\u4e00\u6b21 map \u79fb\u52a8\u7684\u6548\u7387\u8003\u91cf\u3002","title":"\u8d4b\u503c\u51fd\u6570\u548c\u6784\u9020\u51fd\u6570\u6982\u5ff5\u8fa8\u6790"},{"location":"stl_map/#assign","text":"map \u8fd8\u6709\u4e00\u4e2a assign \u51fd\u6570\uff0c\u4ed6\u548c operator= \u7b49\u4ef7\uff1a void assign(initializer_list> ilist); assign \u7684\u989d\u5916\u597d\u5904\u662f\u4ed6\u62e5\u6709\u4e24\u4e2a\u8fed\u4ee3\u5668\u53c2\u6570\u7ec4\u6210\u533a\u95f4\u7684\u7248\u672c\uff0c\u548c\u6279\u91cf insert \u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7 assign \u4f1a\u6e05\u9664\u5df2\u6709\u7684\u5143\u7d20\u3002 template void assign(InputIt first, InputIt last); \u548c operator=(map(first, last)) \u7b49\u4ef7\u3002","title":"assign \u51fd\u6570"},{"location":"stl_map/#insert_5","text":"iterator insert(const_iterator pos, pair const &kv); \u8fd9\u53c8\u662f insert \u51fd\u6570\u7684\u4e00\u4e2a\u91cd\u8f7d\u7248\uff0c\u589e\u52a0\u4e86 pos \u53c2\u6570\u63d0\u793a\u63d2\u5165\u4f4d\u7f6e\uff0c\u5b98\u65b9\u6587\u6863\u79f0 1 \uff1a Inserts value in the position as close as possible to the position just prior to pos. \u628a\u5143\u7d20\uff08\u952e\u503c\u5bf9\uff09\u63d2\u5165\u5230\u4f4d\u4e8e pos \u4e4b\u524d\uff0c\u53c8\u79bb pos \u5c3d\u53ef\u80fd\u8fd1\u7684\u5730\u65b9\u3002 \u7136\u800c map \u4f5c\u4e3a\u7ea2\u9ed1\u6811\u5e94\u8be5\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0c\u63d2\u5165\u4f4d\u7f6e\u53ef\u4ee5\u7531 K \u552f\u4e00\u786e\u5b9a\uff0c\u4e3a\u5565\u8fd8\u8981\u63d0\u793a\uff1f \u662f\u4e3a\u4e86\u5728\u5df2\u77e5\u8981\u63d2\u5165\u7684\u5927\u81f4\u4f4d\u7f6e\u65f6\uff0c\u80fd\u591f\u63d0\u5347\u6027\u80fd\u3002 \uff08\u5e26\u63d0\u793a\u7684 insert \u7248\u672c\uff09\u4e2d\u4f20\u5165\u7684\u8fed\u4ee3\u5668\uff0c\u4ec5\u662f\u7ed9 map \u5bb9\u5668\u63d0\u4f9b\u4e00\u4e2a\u5efa\u8bae\uff0c\u5e76\u4e0d\u4e00\u5b9a\u4f1a\u88ab\u5bb9\u5668\u91c7\u7eb3\u3002\u8be5\u8fed\u4ee3\u5668\u8868\u660e\u5c06\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u65b0\u952e\u503c\u5bf9\u6dfb\u52a0\u5230\u5bb9\u5668\u4e2d\u7684\u4f4d\u7f6e\uff0c\u5e76\u4e0d\u662f\u6b64\u8fed\u4ee3\u5668\u8bf4\u4e86\u7b97\uff0c\u6700\u7ec8\u4ecd\u53d6\u51b3\u4e8e\u8be5\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c\u3002 2 \u4e5f\u5c31\u662f\u8bf4\u8fd9\u73a9\u610f\u8fd8\u4e0d\u4e00\u5b9a\u7ba1\u7528\uff0c\u53ea\u662f\u63d0\u793a\u6027\u8d28\u7684\uff08\u548c mmap \u51fd\u6570\u7684 start \u53c2\u6570\u5f88\u50cf\uff0c\u4f60\u53ef\u4ee5\u6307\u5b9a\uff0c\u4f46\u53ea\u662f\u4e2a\u63d0\u793a\uff0c\u6307\u5b9a\u4e86\u4e0d\u4e00\u5b9a\u6709\u4ec0\u4e48\u8f6f\u7528\uff0c\u5177\u4f53\u4ec0\u4e48\u5730\u5740\u8fd8\u662f\u64cd\u4f5c\u7cfb\u7edf\u8bf4\u4e86\u7b97\uff0c\u4ed6\u4ece\u8fd4\u56de\u503c\u91cc\u7ed9\u4f60\u7684\u5730\u5740\u624d\u662f\u6b63\u786e\u7b54\u6848\uff09\u3002\u4f8b\u5982\u5df2\u77e5\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\uff0c\u60f3\u8981\u63d2\u5165 \u201ckea\u201d\uff0c\u90a3\u4e48\u6307\u5b9a\u6307\u5411 \u201ckey\u201d \u7684\u8fed\u4ee3\u5668\u5c31\u4f1a\u8ba9 insert \u80fd\u66f4\u5bb9\u6613\u5b9a\u4f4d\u5230 \u201ckea\u201d \u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002","title":"\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert"},{"location":"stl_map/#_35","text":"iterator insert(const_iterator pos, pair const &kv); \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u7684\u51c6\u786e\u65f6\uff0cinsert \u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u4f4e\u81f3 O(1)+ O(1)+ \u3002 \u5f53\u63d2\u5165\u4f4d\u7f6e pos \u63d0\u793a\u4e0d\u51c6\u786e\u65f6\uff0c\u548c\u666e\u901a\u7684 insert \u4e00\u6837\uff0c\u8fd8\u662f O(\\log N) O(\\log N) \u3002 \u8fd4\u56de\u6307\u5411\u6210\u529f\u63d2\u5165\u5143\u7d20\u4f4d\u7f6e\u7684\u8fed\u4ee3\u5668\u3002 \u60f3\u60f3\u770b\uff0c\u8fd9\u4e09\u4e2a\u770b\u4f3c\u4e0d\u76f8\u5e72\u7684\u7279\u6027\uff0c\u80fd\u6709\u4ec0\u4e48\u7528\u5462\uff1f \u53ef\u4ee5\u8ba9\u5df2\u7ecf\u6709\u5e8f\u6570\u636e\u7684\u6279\u91cf\u63d2\u5165\u66f4\u9ad8\u6548\uff01 \u4f17\u6240\u5468\u77e5\uff0c\u666e\u901a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4e3a O(N \\log N) O(N \\log N) \u3002 vector> arr; map tab; for (auto const &[k, v]: arr) { tab.insert({k, v}); // O(log N) } // \u603b\u5171 O(N log N) \u5047\u5982\u8f93\u5165\u672c\u5c31\u6709\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(N) O(N) \u3002 \u5982\u679c\u8f93\u5165\u65e0\u5e8f\uff0c\u5e26\u63d0\u793a\u7684\u6279\u91cf insert \u590d\u6742\u5ea6\u4f9d\u7136\u662f O(N \\log N) O(N \\log N) \u4e0d\u53d8\u3002 vector> arr; map tab; auto hint = tab.begin(); for (auto const &[k, v]: arr) { hint = tab.insert(hint, {k, v}); // \u5e73\u5747 O(1) } // \u603b\u5171 O(N) \u60f3\u4e00\u60f3\uff0c\u4e3a\u4ec0\u4e48\uff1f","title":"\u590d\u6742\u5ea6\u5206\u7c7b\u8ba8\u8bba"},{"location":"stl_map/#_36","text":"\u4f60\u662f\u4e00\u540d\u5c0f\u5b66\u8001\u5e08\uff0c\u9a6c\u4e0a\u5c31\u8981\u51fa\u65e9\u64cd\u4e86\uff0c\u4e3a\u5e94\u4ed8\u9886\u5bfc\u9762\u5b50\uff0c\u4f60\u9700\u8981\u7ed9\u4f60\u7684\u5b66\u751f\u6392\u961f\uff0c\u6839\u636e\u4e2a\u5b50\u4ece\u77ee\u5230\u9ad8\u6392\u5217\u3002 \u4e0d\u8fc7\u8fd9\u6240\u5c0f\u5b66\u7684\u5b66\u751f\u90fd\u6bd4\u8f83\u61d2\u6563\uff0c\u6709\u7684\u6765\u5f97\u65e9\u6709\u7684\u6765\u5f97\u665a\uff0c\u800c\u4e14\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u4ed6\u4eec\u7684\u9ad8\u77ee\u65e0\u5173\u3002 \u4f60\u672c\u6765\u6253\u7b97\u7b49\u6240\u6709\u4eba\u5230\u9f50\u4e4b\u540e\u518d\u4e00\u6b21\u6027\u5b8c\u6210\u6392\u5e8f\uff08std::sort\uff09\u7684\uff0c\u4f46\u662f\u540c\u5b66\u6765\u7684\u65f6\u95f4\u5b9e\u5728\u662f\u592a\u5206\u6563\u4e86\uff1a\u660e\u660e 8 \u70b9\u5c31\u8981\u51fa\u65e9\u64cd\uff0c\u6700\u665a\u7684\u540c\u5b66\u5374 7 \u70b9 59 \u5206\u624d\u5230\u8fbe\u3002\u610f\u5473\u7740\u4f60\u9700\u8981\u4e00\u76f4\u5e72\u7b49\u7740\u8fd9\u4e2a\u61d2\u6563\u7684\u540c\u5b66\uff0c\u6700\u540e\u5728 1 \u5206\u949f\u65f6\u95f4\u5185\u4e34\u65f6\u62b1\u4f5b\u811a\uff0c\u5b8c\u6210\u5feb\u901f\u6392\u5e8f\u3002\u8fd9\u662f\u4e0d\u53ef\u80fd\u7684\uff0c\u53ea\u80fd\u5728\u540c\u5b66\u9646\u7eed\u62b5\u8fbe\u7684\u540c\u65f6\u8fdb\u884c\u6392\u5e8f\uff0c\u8fd9\u5c31\u662f\u5806\u6392\u5e8f\uff0c\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u6392\u5e8f\uff0c\u6bcf\u6b21\u63d2\u5165\u540e\u90fd\u4fdd\u8bc1\u6709\u5e8f\uff0c\u4e0e\u63d2\u5165\u6392\u5e8f\u4e0d\u540c\u4ed6\u4f7f\u7528\u5806\u5185\u5b58\u4e2d\u7684\u8282\u70b9\u800c\u4e0d\u662f\u6570\u7ec4\u907f\u514d\u6602\u8d35\u7684\u6570\u7ec4\u5e73\u79fb\u64cd\u4f5c\u3002 \u6bcf\u5f53\u6765\u4e00\u4e2a\u5b66\u751f\uff0c\u4f60\u5c31\u5f97\u628a\u4ed6\u63d2\u5165\u5230\u73b0\u6709\u7684\u4e00\u4e2a\u5df2\u7ecf\u6392\u597d\u7684\u961f\u4f0d\u4e2d\u53bb\u3002 \u5982\u4f55\u786e\u5b9a\u63d2\u5165\u7684\u4f4d\u7f6e\uff1f\u4e8c\u5206\u6cd5\u3002\u5148\u4ece\u73b0\u6709\u961f\u4f0d\u7684\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\uff0c\u6bd4\u8f83\u4e2d\u95f4\u8fd9\u4e2a\u5b66\u751f\u548c\u65b0\u6765\u7684\u5b66\u751f\u54ea\u4e2a\u9ad8\u54ea\u4e2a\u77ee\uff0c\u5982\u679c\u53d1\u73b0\u65b0\u6765\u7684\u5b66\u751f\u9ad8\uff0c\u5219\u7ee7\u7eed\u4ece\u961f\u5217\u7684 3/4 \u5904\u90a3\u4e2a\u540c\u5b66\u5f00\u59cb\u6bd4\u9ad8\u77ee\uff0c\u5982\u679c\u65b0\u6765\u7684\u5b66\u751f\u77ee\u5c31\u4ece\u961f\u5217\u7684 1/4 \u5904\u7ee7\u7eed\u6bd4\u8f83\u3002\u4ee5\u6b64\u7c7b\u63a8\uff0c\u6700\u7ec8\u552f\u4e00\u786e\u5b9a\u65b0\u540c\u5b66\u8981\u63d2\u5165\u7684\u4f4d\u7f6e\u3002\u56e0\u4e3a\u6bcf\u6b21\u786e\u5b9a\u7684\u8303\u56f4\u5c31\u5c0f\u4e00\u534a\uff0c\u6240\u4ee5\u6700\u591a\u53ea\u9700\u8981 \\log N \\log N \u6b21\u6bd4\u8f83\u5c31\u53ef\u4ee5\u6210\u529f\u63d2\u5165\uff0c\u5176\u4e2d N N \u662f\u5f53\u524d\u5df2\u6709\u5b66\u751f\u7684\u6570\u91cf\u3002 \u603b\u5171\u8981\u6765 N N \u540d\u5b66\u751f\uff0c\u5219\u4f60\u603b\u5171\u9700\u8981\u6bd4\u8f83 N \\log N N \\log N \u6b21\u3002\u80fd\u4e0d\u80fd\u4f18\u5316\uff1f\u8ba9\u6211\u4eec\u5c0f\u5f6d\u8001\u5e08\u7701\u529b\u70b9\uff1f","title":"\u5c0f\u5b66\u751f\u7684\u8da3\u5473\u65e9\u64cd"},{"location":"stl_map/#_37","text":"\u540e\u6765\u4f60\u53d1\u73b0\u4e00\u4e2a\u89c4\u5f8b\uff0c\u4f3c\u4e4e\u5b66\u751f\u6765\u7684\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u6709\u5173\uff1a\u77ee\u5c0f\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u65e9\uff0c\u9ad8\u5927\u7684\u540c\u5b66\u559c\u6b22\u8d77\u7684\u665a\u3002 \u77e5\u9053\u8fd9\u4e2a\u89c4\u5f8b\u540e\uff0c\u4f60\u6539\u53d8\u4f60\u7684\u7b56\u7565\uff1a\u4e8c\u5206\u6cd5\u65f6\uff0c\u4e0d\u662f\u5148\u4ece\u6700\u4e2d\u95f4\uff081/2 \u5904\uff09\u5f00\u59cb\u67e5\u627e\uff0c\u800c\u662f\u4ece\u6700\u672b\u5c3e\u5f00\u59cb\u67e5\u627e\u3002\u56e0\u4e3a\u77ee\u5c0f\u540c\u5b66\u4f1a\u65e9\u5230\uff0c\u5bfc\u81f4\u6bcf\u6b21\u65b0\u6765\u7684\u540c\u5b66\u5f80\u5f80\u603b\u662f\u961f\u5217\u4e2d\u6700\u9ad8\u7684\u90a3\u4e00\u4e2a\u3002\u6240\u4ee5\u53ef\u4ee5\u4ece\u961f\u4f0d\u7684\u672b\u5c3e\uff08\u6700\u9ad8\u7684\u5730\u65b9\uff09\u5f00\u59cb\u627e\uff0c\u4f8b\u5982\u6709 64 \u540d\u540c\u5b66\u5219\u4f18\u5148\u548c 65/64 \u5904\u6bd4\u8f83\uff0c\u627e\u4e0d\u5230\u518d\u5f80\u4e0a\u4e00\u7ea7\u548c 31/32 \u5904\u6bd4\u8f83\u3002 \u8fd9\u4e2a\u7b56\u7565\u4e5f\u6709\u7f3a\u70b9\uff1a\u5bf9\u4e8e\u65e9\u665a\u987a\u5e8f\u548c\u9ad8\u77ee\u65e0\u5173\u3001\u751a\u81f3\u8d1f\u76f8\u5173\u7684\u60c5\u51b5\uff0c\u6bcf\u6b21\u63d2\u5165\u7684\u6d88\u8017\u5c31\u4f1a\u53d8\u6210 2 \\log N 2 \\log N \u4e86\u3002 \u6700\u7ec8\u6211\u4eec\u51b3\u5b9a\u91c7\u7528\u7684\u7b56\u7565\u662f\uff1a\u4e0d\u662f\u4ece\u4e2d\u95f4\uff0c\u4e5f\u4e0d\u662f\u4ece\u5f00\u5934\uff0c\u4e5f\u4e0d\u662f\u4ece\u672b\u5c3e\uff0c\u800c\u662f \u8bb0\u4f4f\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e \uff0c\u4e0b\u4e00\u6b21\u4ece\u4e0a\u4e00\u6b21\u6210\u529f\u63d2\u5165\u7684\u4f4d\u7f6e\u5f00\u59cb\u627e\u3002\u8fd9\u4e2a\u8bb0\u5fc6\u7684\u63d2\u5165\u4f4d\u7f6e\uff0c\u5c31\u662f\u521a\u521a\u4ee3\u7801\u4e2d\u90a3\u4e2a\u4f4d\u7f6e\u63d0\u793a\u8fed\u4ee3\u5668 hint\u3002 \u8fd9\u6b63\u662f\u6211\u4eec\u4ee3\u7801\u7684\u5199\u6cd5\uff1a hint = tab.insert(hint, {k, v}); \u5b9e\u9645\u4e0a\uff0cinsert \u7684\u6279\u91cf\u63d2\u5165\u7248 insert(arr.begin(), arr.end()) \u5185\u90e8\u5c31\u4f1a\u4f7f\u7528\u8fd9\u79cd\u5e26\u63d0\u793a\u7684\u65b9\u5f0f\uff0c\u9010\u4e2a\u63d2\u5165\u3002 vector> arr;","title":"\u5c0f\u5b66\u751f\u6765\u7684\u987a\u5e8f\u5df2\u7ecf\u6709\u5e8f\u7684\u60c5\u51b5"},{"location":"stl_map/#emplace","text":"insert \u7684\u7a76\u6781\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace template pair emplace(Args &&...args); \u867d\u7136\u53d8\u957f\u53c2\u6570\u5217\u8868 Args &&...args \u770b\u8d77\u6765\u5f88\u9177\uff0c\u7136\u800c\u7531\u4e8e map \u7684\u7279\u6b8a\u6027\uff0c\u5176\u5143\u7d20\u7c7b\u578b\u662f pair \uff0c\u800c pair \u7684\u6784\u9020\u51fd\u6570\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\uff0c\u5bfc\u81f4\u5b9e\u9645\u4e0a\u8fd9\u4e2a\u770b\u4f3c\u70ab\u9177\u7684\u53d8\u957f\u53c2\u6570\u5217\u8868\u5f80\u5f80\u53ea\u80fd\u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\uff0c\u56e0\u6b64\u8fd9\u4e2a\u51fd\u6570\u7684\u8c03\u7528\u65b9\u6cd5\u5b9e\u9645\u4e0a\u53ea\u80fd\u662f\uff1a pair emplace(K k, V v); \u5199\u6cd5\uff1a m.emplace(key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert({key, val}); \u8fd4\u56de\u503c\u8fd8\u662f pair \uff0c\u5176\u610f\u4e49\u548c insert \u4e00\u6837\uff0c\u4e0d\u518d\u8d58\u8ff0\u3002","title":"\u5206\u5974 emplace"},{"location":"stl_map/#emplace_hint","text":"insert \u7684\u5b87\u5b99\u65e0\u654c\u5206\u5974\u7248\uff08\u4e0d\u63a8\u8350\uff09\uff1aemplace_hint 1 template iterator emplace_hint(const_iterator pos, Args &&...args); \u5199\u6cd5\uff1a m.emplace_hint(pos, key, val); \u7b49\u4ef7\u4e8e\uff1a m.insert(pos, {key, val}); \u4e4b\u6240\u4ee5\u8981\u5206\u4e24\u4e2a\u51fd\u6570\u540d emplace \u548c emplace_hint \u800c\u4e0d\u662f\u5229\u7528\u91cd\u8f7d\u533a\u5206\uff0c\u662f\u56e0\u4e3a\u76f4\u63a5\u4f20\u5165 pos \u4f1a\u88ab emplace \u5f53\u505a pair \u7684\u6784\u9020\u53c2\u6570\uff0c\u800c\u4e0d\u662f\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u3002 emplace \u5bf9\u5e94\u4e8e\u666e\u901a\u7684 insert(pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u5bf9\u5e94\u4e8e\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert(const_iterator, pair) \u8fd9\u4e00\u91cd\u8f7d\u3002 emplace_hint \u7684\u8fd4\u56de\u7c7b\u578b\u4e5f\u548c\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 insert \u4e00\u6837\uff0c\u662f\u5355\u72ec\u4e00\u4e2a iterator\u3002","title":"emplace_hint"},{"location":"stl_map/#emplace_1","text":"template pair emplace(Args &&...args); emplace \u5bf9\u4e8e set\uff0c\u5143\u7d20\u7c7b\u578b\u662f\u6bd4\u8f83\u5927\u7684\u7c7b\u578b\u65f6\uff0c\u4f8b\u5982 set> \uff0c\u53ef\u80fd\u786e\u5b9e\u80fd\u8d77\u5230\u51cf\u5c11\u79fb\u52a8\u6784\u9020\u51fd\u6570\u5f00\u9500\u7684\u4f5c\u7528\u3002 \u4f46\u662f\u8fd9\u4e2a map \u4ed6\u7684\u5143\u7d20\u7c7b\u578b\u4e0d\u662f\u76f4\u63a5\u7684 V \u800c\u662f\u4e00\u4e2a pair\uff0c\u4ed6\u5206\u7684\u662f pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u6ca1\u6709\u7528\uff0cV \u90e8\u5206\u8fd8\u662f\u4f1a\u9020\u6210\u4e00\u6b21\u989d\u5916\u7684\u79fb\u52a8\u5f00\u9500\uff0c\u6240\u4ee5\u8fd9\u73a9\u610f\u9664\u4e86\u59a8\u788d\u7c7b\u578b\u5b89\u5168\u548c\u53ef\u8bfb\u6027\u4ee5\u5916\uff0c\u6ca1\u6709\u4efb\u4f55\u6536\u76ca\u3002 set \u53ef\u4ee5\u7528 emplace/emplace_hint\u3002 vector \u53ef\u4ee5\u7528 emplace_back\u3002 \u4e0d\u5efa\u8bae\u5728 map \u4e0a\u4f7f\u7528 emplace/emplace_hint\uff0c\u8bf7\u6539\u7528 try_emplace\u3002","title":"emplace \u7684\u539f\u7406\u548c\u4f18\u70b9"},{"location":"stl_map/#try_emplace","text":"emplace \u53ea\u652f\u6301 pair \u7684\u5c31\u5730\u6784\u9020\uff0c\u8fd9\u6709\u4ec0\u4e48\u7528\uff1f\u6211\u4eec\u8981\u7684\u662f pair \u4e2d\u503c\u7c7b\u578b\u7684\u5c31\u5730\u6784\u9020\uff01\u8fd9\u5c31\u662f try_emplace \u7684\u4f5c\u7528\u4e86\uff0c\u4ed6\u5bf9 key \u90e8\u5206\u4f9d\u7136\u662f\u4f20\u7edf\u7684\u79fb\u52a8\uff0c\u53ea\u5bf9 value \u90e8\u5206\u91c7\u7528\u5c31\u5730\u6784\u9020\u3002 \u8fd9\u662f\u89c2\u5bdf\u5230\u5927\u591a\u662f\u503c\u7c7b\u578b\u5f88\u5927\uff0c\u6025\u9700\u5c31\u5730\u6784\u9020\uff0c\u800c\u952e\u7c7b\u578b\u6ca1\u7528\u591a\u5c11\u5c31\u5730\u6784\u9020\u7684\u9700\u6c42\u3002\u4f8b\u5982 map> \u5982\u679c\u60f3\u4e0d\u7528 try_emplace\uff0c\u5b8c\u5168\u57fa\u4e8e emplace \u5b9e\u73b0\u9488\u5bf9\u503c value \u7684\u5c31\u5730\u6784\u9020\u9700\u8981\u7528\u5230 std::piecewise_construct \u548c std::forward_as_tuple\uff0c\u975e\u5e38\u9ebb\u70e6\u3002 insert \u7684\u6258\u9a6c\u65af\u9ec4\u91d1\u5927\u56de\u65cb\u5206\u5974\u7248\uff1atry_emplace\uff08C++17 \u5f15\u5165\uff09 template pair try_emplace(K const &k, Args &&...args); \u5199\u6cd5\uff1a m.try_emplace(key, arg1, arg2, ...); \u4ed6\u7b49\u4ef7\u4e8e\uff1a m.insert({key, V(arg1, arg2, ...)}); \u540e\u9762\u7684\u53d8\u957f\u53c2\u6570\u4e5f\u53ef\u4ee5\u5b8c\u5168\u6ca1\u6709\uff1a m.try_emplace(key); \u4ed6\u7b49\u4ef7\u4e8e\u8c03\u7528 V \u7684\u9ed8\u8ba4\u6784\u9020\u51fd\u6570\uff1a m.insert({key, V()}); \u7531\u4e8e emplace \u5b9e\u5728\u662f\u61a8\u61a8\uff0c\u4ed6\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u7684\u662f pair\uff0c\u7136\u800c pair \u7684\u6784\u9020\u51fd\u6570\u6b63\u5e38\u4e0d\u5c31\u662f\u53ea\u6709\u4e24\u4e2a\u53c2\u6570\u5417\uff0c\u53d8\u957f\u6ca1\u6709\u7528\u3002\u5b9e\u9645\u6709\u7528\u7684\u5f80\u5f80\u662f\u6211\u4eec\u5e0c\u671b\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u5c31\u5730\u6784\u9020\u503c\u7c7b\u578b V\uff0c\u5bf9 K \u90e8\u5206\u5e76\u4e0d\u5173\u7cfb\u3002\u56e0\u6b64 C++17 \u5f15\u5165\u4e86 try_emplace\uff0c\u5176\u952e\u90e8\u5206\u4fdd\u6301 K const & \uff0c\u503c\u90e8\u5206\u91c7\u7528\u53d8\u957f\u53c2\u6570\u5217\u8868\u3002 \u6211\u7684\u8bc4\u4ef7\u662f\uff1a\u8fd9\u4e2a\u6bd4 emplace \u5b9e\u7528\u591a\u4e86\uff0c\u5982\u679c\u8981\u4e0e vector \u7684 emplace_back \u5bf9\u6807\uff0c\u90a3\u4e48 map \u4e0e\u4e4b\u5bf9\u5e94\u7684\u4e00\u5b9a\u662f try_emplace\u3002\u540c\u5b66\u4eec\u5982\u679c\u8981\u5206\u5974\u7684\u8bdd\u8fd8\u662f\u5efa\u8bae\u7528 try_emplace\u3002","title":"try_emplace \u66f4\u597d"},{"location":"stl_map/#try_emplace_1","text":"insert \u7c7b\u51fd\u6570\u603b\u662f\u4e0d\u53ef\u907f\u514d\u7684\u9700\u8981\u79fb\u52a8\u6784\u9020\uff1a\u5148\u5728\u51fd\u6570\u4e2d\u6784\u9020\u51fa\u4e34\u65f6\u5bf9\u8c61\uff0c\u7136\u540e\u6784\u9020\u5230\u771f\u6b63\u7684 pair \u4e0a\u3002 \u800c try_emplace \u53ef\u4ee5\u5141\u8bb8\u4f60\u5c31\u5730\u6784\u9020\u503c\u5bf9\u8c61\uff0c\u907f\u514d\u79fb\u52a8\u9020\u6210\u5f00\u9500\u3002 try_emplace \u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u952e\uff0c\u7b2c\u4e8c\u4e2a\u5f00\u59cb\u662f\u4f20\u7ed9\u6784\u9020\u51fd\u6570\u7684\u53c2\u6570\uff0c\u5982\u53ea\u6709\u7b2c\u4e00\u4e2a\u53c2\u6570\u5219\u662f\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570\u3002 struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(int i) { printf(\"MyClass(int)\\n\"); } MyClass(const char *p, float x) { printf(\"MyClass(const char *, float)\\n\"); } }; map m; m.try_emplace(\"key\"); // MyClass() m.try_emplace(\"key\", 42); // MyClass(int) m.try_emplace(\"key\", \"hell\", 3.14f); // MyClass(const char *, float) // \u7b49\u4ef7\u4e8e\uff1a m.insert({\"key\", MyClass()}); // MyClass() m.insert({\"key\", MyClass(42)}); // MyClass(int) m.insert({\"key\", MyClass(\"hell\", 3.14f)}); // MyClass(const char *, float) \u5bf9\u4e8e\u79fb\u52a8\u5f00\u9500\u8f83\u5927\u7684\u7c7b\u578b\uff08\u4f8b\u5982 array \uff09\uff0ctry_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff1b\u5bf9\u4e8e\u4e0d\u652f\u6301\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u503c\u7c7b\u578b\uff0c\u5c31\u5fc5\u987b\u4f7f\u7528 try_emplace \u4e86\u3002","title":"try_emplace \u53ef\u4ee5\u907f\u514d\u79fb\u52a8\uff01"},{"location":"stl_map/#try_emplace_2","text":"// \u4ee5\u4e0b\u4e24\u79cd\u65b9\u5f0f\u6548\u679c\u7b49\u4ef7\uff0c\u53ea\u6709\u6027\u80fd\u4e0d\u540c m.try_emplace(key, arg1, arg2, ...); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 m.insert({key, V(arg1, arg2, ...)}); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 2\u6b21\u79fb\u52a8\u51fd\u6570 m.insert(make_pair(key, V(arg1, arg2, ...))); // \u5f00\u9500\uff1a1\u6b21\u6784\u9020\u51fd\u6570 + 3\u6b21\u79fb\u52a8\u51fd\u6570 \u4f46\u662f\u7531\u4e8e try_emplace \u662f\u7528\u5706\u62ec\u53f7\u5e2e\u4f60\u8c03\u7528\u7684\u6784\u9020\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u3002 \u5bfc\u81f4\u4f60\u8981\u4e48\u65e0\u6cd5\u7701\u7565\u7c7b\u578b\uff0c\u8981\u4e48\u4f60\u5f97\u624b\u52a8\u5b9a\u4e49\u7c7b\u7684\u6784\u9020\u51fd\u6570\uff1a struct Student { // \u6ca1\u6709\u6784\u9020\u51fd\u6570\uff0c\u53ea\u80fd\u7528\u82b1\u62ec\u53f7\u8bed\u6cd5\u8fdb\u884c\u521d\u59cb\u5316 string sex; int age; }; map m; m.insert({\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}}); // OK: insert \u53c2\u6570\u7c7b\u578b\u5df2\u77e5\uff0cStudent \u53ef\u4ee5\u7701\u7565\u4e0d\u5199\uff0c\u4f46\u662f\u4f1a\u9020\u6210 2 \u6b21\u79fb\u52a8 m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // ERROR: \u4e0d\u5b58\u5728\u6784\u9020\u51fd\u6570 Student(string, int)\uff1bC++20 \u5f00\u59cb\u5219 OK: C++20 \u8d77\u805a\u5408\u521d\u59cb\u5316\u540c\u65f6\u652f\u6301\u82b1\u62ec\u53f7\u548c\u5706\u62ec\u53f7 m.try_emplace(\"\u5f6d\u4e8e\u658c\", {\"\u81ea\u5b9a\u4e49\", 22}); // ERROR: \u53c2\u6570\u7c7b\u578b\u662f\u6a21\u677f\u7c7b\u578b\uff0c\u672a\u77e5\uff0c\u65e0\u6cd5\u7701\u7565\u82b1\u62ec\u53f7\u524d\u7684\u7c7b\u578b m.try_emplace(\"\u5f6d\u4e8e\u658c\", Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: \u660e\u786e\u6307\u5b9a\u7c7b\u578b\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff1b\u4f46\u8fd9\u6837\u53c8\u4f1a\u9020\u6210 1 \u6b21\u79fb\u52a8\uff0c\u5931\u53bb\u4e86 try_emplace \u907f\u514d\u79fb\u52a8\u7684\u610f\u4e49 \u6b64\u5916\u8fd8\u8981\u6ce8\u610f\u4e0d\u8bba insert\u3001emplace\u3001emplace_hint\u3001try_emplace\uff0c\u90fd\u662f\u4e00\u4e2a\u5c3f\u6027\uff1a\u952e\u51b2\u7a81\u65f6\u4e0d\u4f1a\u8986\u76d6\u5df2\u6709\u5143\u7d20\u3002 \u5982\u679c\u9700\u8981\u8986\u76d6\u6027\u7684\u63d2\u5165\uff0c\u8fd8\u5f97\u4e56\u4e56\u7528 [] \u6216\u8005 insert_or_assign \u51fd\u6570\u3002 \u7531\u4e8e try_emplace \u91cc\u5199\u6b7b\u4e86\u5706\u62ec\u53f7\uff0c\u6211\u4eec\u53ea\u597d\u624b\u52a8\u5b9a\u4e49\u7684\u6784\u9020\u51fd\u6570\u624d\u80fd\u52b3\u9a7e try_emplace \u5c31\u5730\u6784\u9020\u3002 struct Student { string sex; int age; Student(string sex, int age) : sex(std::move(sex)) , age(age) {} // \u7531\u4e8e try_emplace \u4f1a\u5c31\u5730\u6784\u9020\u5bf9\u8c61\uff0c\u5176\u503c\u7c7b\u578b\u53ef\u4ee5\u6ca1\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u800c insert \u4f1a\u51fa\u9519 Student(Student &&) = delete; Student &operator=(Student &&) = delete; Student(Student const &) = delete; Student &operator=(Student const &) = delete; }; map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u4f1a\u8c03\u7528\u6784\u9020\u51fd\u6570 Student(string, int) \u5c31\u5730\u6784\u9020\u5bf9\u8c61 m.insert({\"\u5f6d\u4e8e\u658c\", Student(\"\u81ea\u5b9a\u4e49\", 22)}); // ERROR: insert \u9700\u8981\u79fb\u52a8 Student \u800c Student \u7684\u79fb\u52a8\u88ab delete \u4e86\uff01","title":"\u8c08\u8c08 try_emplace \u7684\u4f18\u7f3a\u70b9"},{"location":"stl_map/#_38","text":"\u65e0\u6784\u9020\u51fd\u6570\u65f6\uff0cC++11 \u652f\u6301\u82b1\u62ec\u53f7\u521d\u59cb\u5316\uff08\u5b98\u65b9\u540d: \u805a\u5408\u521d\u59cb\u5316 1 \uff09\uff0cC++20 \u5f00\u59cb\u805a\u5408\u521d\u59cb\u5316\u4e5f\u80fd\u7528\u5706\u62ec\u53f7\uff08\u6240\u4ee5 emplace / try_emplace \u8fd9\u7c7b\u51fd\u6570\u53d8\u5f97\u66f4\u597d\u7528\u4e86\uff09\uff1a struct Student { string sex; int age; }; auto s1 = Student{\"\u81ea\u5b9a\u4e49\", 22}; // C++11 \u8d77 OK: \u65e0\u6784\u9020\u51fd\u6570\u65f6\u7684\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u8bed\u6cd5 auto s2 = Student(\"\u81ea\u5b9a\u4e49\", 22); // C++20 \u8d77 OK: \u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u751f\u6210\u5706\u62ec\u53f7\u6784\u9020\u51fd\u6570 Student(string, int) \u548c\u82b1\u62ec\u53f7\u521d\u59cb\u5316\u65f6\u4e00\u6837\uff0c\u53ef\u4ee5\u7701\u7565\u4e00\u90e8\u5206\u53c2\u6570\uff0c\u8fd9\u90e8\u5206\u53c2\u6570\u4f1a\u7528\u4ed6\u4eec\u7684\u9ed8\u8ba4\u503c\uff1a auto s1 = Student(\"\u81ea\u5b9a\u4e49\", 22); // OK: sex \u4e3a \"\u81ea\u5b9a\u4e49\"\uff0cage \u4e3a 22 auto s2 = Student(\"\u81ea\u5b9a\u4e49\"); // OK: \u7701\u7565 age \u81ea\u52a8\u4e3a 0 auto s3 = Student(); // OK: \u7701\u7565 sex \u81ea\u52a8\u4e3a \"\" \u4e0d\u8fc7\u4ed6\u548c\u82b1\u62ec\u53f7\u4e0d\u4e00\u6837\u7684\u662f\uff0c\u4f5c\u4e3a\u5df2\u77e5\u53c2\u6570\u7c7b\u578b\u7684\u51fd\u6570\u53c2\u6570\u65f6\uff0c\u7c7b\u578b\u540d\u4e0d\u80fd\u7701\u7565\u4e86\uff1a void func(Student const &stu); // \u5df2\u77e5\u51fd\u6570\u7b7e\u540d func(Student{\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5 func({\"\u81ea\u5b9a\u4e49\", 22}); // OK: C++11 \u8bed\u6cd5\uff0c\u5df2\u77e5\u51fd\u6570\u5177\u6709\u552f\u4e00\u91cd\u8f7d\u7684\u60c5\u51b5\u4e0b\u7c7b\u540d\u53ef\u4ee5\u7701\u7565 func(Student(\"\u81ea\u5b9a\u4e49\", 22)); // OK: C++20 \u8bed\u6cd5 func((\"\u81ea\u5b9a\u4e49\", 22)); // ERROR: \u65e0\u6cd5\u4ece int \u8f6c\u6362\u4e3a Student","title":"\u4ec0\u4e48\u662f\u805a\u5408\u521d\u59cb\u5316"},{"location":"stl_map/#c20","text":"\u6240\u4ee5\u73b0\u5728 try_emplace \u4e5f\u53ef\u4ee5\u5c31\u5730\u6784\u9020\u65e0\u6784\u9020\u51fd\u6570\u7684\u7c7b\u578b\u4e86\uff1a map m; m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\", 22); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 22} m.try_emplace(\"\u5f6d\u4e8e\u658c\", \"\u81ea\u5b9a\u4e49\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\u81ea\u5b9a\u4e49\", 0} m.try_emplace(\"\u5f6d\u4e8e\u658c\"); // OK: \u7b49\u4ef7\u4e8e m[\"\u5f6d\u4e8e\u658c\"] = Student{\"\", 0} \u65b9\u4fbf\uff01 \u5173\u4e8e\u66f4\u591a C++20 \u7684\u805a\u5408\u521d\u59cb\u5316\u5c0f\u77e5\u8bc6\uff0c\u53ef\u4ee5\u770b\u8fd9\u671f CppCon \u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=flLNi0aejew \u4e3a\u65b9\u4fbf\u4f60\u5728\u6bd4\u7ad9\u641c\u7d22\u642c\u8fd0\uff0c\u4ed6\u7684\u6807\u9898\u662f\uff1aLightning Talk: Direct Aggregate Initialisation - Timur Doumler - CppCon 2021","title":"C++20 \u4fee\u590d\u4e86\u805a\u5408\u521d\u59cb\u5316\u4e0d\u652f\u6301\u5706\u62ec\u53f7\u7684\u7f3a\u70b9"},{"location":"stl_map/#_39","text":"struct MyClass { MyClass() { printf(\"MyClass()\\n\"); } MyClass(MyClass &&) noexcept { printf(\"MyClass(MyClass &&)\\n\"); } MyClass &operator=(MyClass &&) noexcept { printf(\"MyClass &operator=(MyClass &&)\\n\"); return *this; } }; map tab; printf(\"insert\u7684\u5f00\u9500:\\n\"); tab.insert({1, MyClass()}); printf(\"try_emplace\u7684\u5f00\u9500:\\n\"); tab.try_emplace(2); // try_emplace \u53ea\u6709\u4e00\u4e2a key \u53c2\u6570\u65f6\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u65e0\u53c2\u6784\u9020\u51fd\u6570 MyClass() insert \u8c03\u7528\u4e86\u4e24\u6b21\u79fb\u52a8\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 pair \u7684\u6784\u9020\u51fd\u6570\uff0c\u4e00\u6b21\u53d1\u751f\u5728 insert \u628a\u53c2\u6570 pair \u79fb\u8fdb\u7ea2\u9ed1\u6811\u8282\u70b9\u91cc\u3002 \u800c try_emplace \u5185\u90e8\u4f7f\u7528\u4e86\u73b0\u4ee3 C++ \u7684\u5c31\u5730\u6784\u9020\uff08placement new\uff09\uff0c\u76f4\u63a5\u5728\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u5185\u5b58\u4e2d\u6784\u9020 MyClass\uff0c\u65e0\u9700\u53cd\u590d\u79fb\u52a8\uff0c\u5bf9\u4e8e\u5c3a\u5bf8\u8f83\u5927\u7684\u503c\u7c7b\u578b\u4f1a\u66f4\u9ad8\u6548\u3002 insert\u7684\u5f00\u9500: MyClass() MyClass(MyClass &&) MyClass(MyClass &&) try_emplace\u7684\u5f00\u9500: MyClass()","title":"\u8c03\u7528\u5f00\u9500\u5206\u6790"},{"location":"stl_map/#try_emplace_3","text":"\u63d0\u5347\u4e86 1.42 \u500d\u6027\u80fd\uff0c\u4e0d\u80fd\u8bf4\u662f\u60ca\u5929\u5730\u6ce3\u9b3c\u795e\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u804a\u80dc\u4e8e\u65e0\u4e86\u3002\u8fd9\u91cc\u7684\u503c\u7c7b\u578b string \u53ea\u6709 32 \u5b57\u8282\u8fd8\u4e0d\u591f\u660e\u663e\uff0c\u53ef\u80fd\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\u4f1a\u6709\u660e\u663e\u7684\u4f18\u52bf\u3002\u8fd9\u79cd\u4f18\u5316\u7684\u7406\u8bba\u4e0a\u9650\u662f 3 \u500d\uff0c\u6700\u591a\u80fd\u4ece try_emplace \u83b7\u5f97 3 \u500d\u6027\u80fd\u63d0\u5347\u3002 template static void test_insert(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) 2\u6b21string(string &&) tab.insert({i, \"hello\"}); } } template static void test_try_emplace(map &tab) { DefScopeProfiler; for (int i = 0; i < 1000; i++) { // 1\u6b21string(const char *) tab.try_emplace(i, \"hello\"); } } int main() { for (int i = 0; i < 1000; i++) { map tab; test_insert(tab); doNotOptimize(tab); } for (int i = 0; i < 1000; i++) { map tab; test_try_emplace(tab); doNotOptimize(tab); } printScopeProfiler(); } avg | min | max | total | cnt | tag 39| 34| 218| 39927| 1000| test_insert 28| 27| 91| 28181| 1000| test_try_emplace \u5982\u679c\u6539\u6210\u66f4\u5927\u7684\u81ea\u5b9a\u4e49\u7c7b\u578b\uff0c\u53ef\u4ee5\u63d0\u5347 2.3 \u500d\u3002 struct MyClass { int arr[4096]; }; avg | min | max | total | cnt | tag 1312| 1193| 18298| 1312871| 1000| test_insert 573| 537| 1064| 573965| 1000| test_try_emplace","title":"try_emplace \u6210\u529f\u63d0\u5347\u6027\u80fd\u7684\u6848\u4f8b"},{"location":"stl_map/#try_emplace_4","text":"insert \u7684\u70ab\u5f69\u4e2d\u4e8c\u6447\u6446\u6df7\u6c8c\u5927\u9b54\u738b\u5206\u5974\u7248\uff1a\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace template iterator try_emplace(const_iterator pos, K const &k, Args &&...args); \u5199\u6cd5\uff1a hint = m.try_emplace(hint, key, arg1, arg2, ...); \u7b49\u4ef7\u4e8e\uff1a hint = m.insert(hint, {key, V(arg1, arg2, ...)}); \u8fd9\u6b21\u4e0d\u9700\u8981\u518d\u5206\u4e00\u4e2a\u4ec0\u4e48 try_emplace_hint \u51fa\u6765\u4e86\uff0c\u662f\u56e0\u4e3a try_emplace \u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f K \u7c7b\u578b\u800c\u4e0d\u662f\u6cdb\u578b\uff0c\u4e0d\u53ef\u80fd\u548c const_iterator \u7c7b\u578b\u6df7\u6dc6\uff0c\u56e0\u6b64 C++ \u59d4\u5458\u4f1a\u6700\u7ec8\u51b3\u5b9a\u76f4\u63a5\u5171\u7528\u540c\u4e00\u4e2a\u540d\u5b57\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u91cd\u8f7d\u4e86\u3002","title":"\u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7684 try_emplace"},{"location":"stl_map/#emplace_2","text":"\u603b\u7ed3\uff0c\u5982\u4f55\u7528 emplace \u5bb6\u65cf\u4f18\u5316\uff1f\u5206\u76f4\u63a5\u63d2\u5165\u548c\u5e26\u63d0\u793a\u63d2\u5165\u4e24\u79cd\u7528\u6cd5\uff0c\u548c\u4f60\u662f\u5426\u9700\u8981\u9ad8\u6027\u80fd\u4e24\u79cd\u9700\u6c42\uff0c\u8fd9\u91cc\u6807\u4e86\u201c\u63a8\u8350\u201d\u7684\u662f\u5efa\u8bae\u91c7\u7528\u7684\uff1a // \u76f4\u63a5\u63d2\u5165\u7248 m.insert({\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 m.try_emplace(\"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 m.emplace(\"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 m.emplace(std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5 // \u5e26\u63d2\u5165\u4f4d\u7f6e\u63d0\u793a\u7248 hint = m.insert(hint, {\"key\", MyClass(1, 2, 3)}); // \u53ef\u8bfb\u6027\u63a8\u8350 hint = m.try_emplace(hint, \"key\", 1, 2, 3); // \u9ad8\u6027\u80fd\u63a8\u8350 hint = m.emplace_hint(hint, \"key\", MyClass(1, 2, 3)); // \u6ca1\u610f\u4e49 hint = m.emplace_hint(hint, std::piecewise_construct, std::forward_as_tuple(\"key\"), std::forward_as_tuple(1, 2, 3)); // C++17 \u4ee5\u524d\u7684\u9ad8\u6027\u80fd\u5199\u6cd5","title":"emplace \u5bb6\u65cf\u603b\u7ed3"},{"location":"stl_map/#map-raii","text":"\u68a6\u5e7b\u8054\u52a8\uff1amap \u5bb9\u5668\u4e0e RAII \u7684\u53cc\u5411\u5954\u8d74 \u5982\u679c map \u4e2d\u5143\u7d20\u7684\u503c\u7c7b\u578b\u662f RAII \u7c7b\u578b\uff0c\u5176\u6790\u6784\u51fd\u6570\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u8c03\u7528\u3002 map \u88ab\u79fb\u52a8\u65f6\uff0c\u4e0d\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u79fb\u52a8\u51fd\u6570\uff0c\u56e0\u4e3a map \u91cc\u53ea\u5b58\u7740\u6307\u5411\u7ea2\u9ed1\u6811\u6839\u8282\u70b9\u7684\u6307\u9488\uff0c\u53ea\u9700\u6307\u9488\u79fb\u52a8\u5373\u53ef\u3002 map \u88ab\u62f7\u8d1d\u65f6\uff0c\u4f1a\u8c03\u7528\u5143\u7d20\u7684\u62f7\u8d1d\u51fd\u6570\uff0c\u5982\u679c\u5143\u7d20\u4e0d\u652f\u6301\u62f7\u8d1d\uff0c\u5219 map \u7684\u62f7\u8d1d\u4e5f\u4f1a\u88ab\u7981\u7528\uff08delete\uff09\u6389\u3002 map \u88ab\u6790\u6784\u65f6\uff0c\u5176\u6240\u6709\u5143\u7d20\u90fd\u4f1a\u88ab\u6790\u6784\u3002","title":"map \u4e0e RAII"},{"location":"stl_map/#1","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\\n\", i); } RAII &operator=(RAII &&) noexcept { printf(\"%d\u53f7\u8d44\u6e90\u79fb\u52a8\u8d4b\u503c\\n\", i); return *this; } ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e","title":"\u6848\u4f8b 1\uff1a\u8d44\u6e90\u7c7b\u53ef\u4ee5\u79fb\u52a8"},{"location":"stl_map/#2","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; RAII &operator=(RAII &&) = delete; RAII(RAII const &) = delete; RAII &operator=(RAII const &) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u65b0\u624b\u5b9a\u4e49 RAII \u7c7b\u65f6\uff0c\u8bb0\u5f97\u628a\u79fb\u52a8\u548c\u62f7\u8d1d 4 \u4e2a\u51fd\u6570\u5168\u90e8\u5220\u9664\u3002\u6ca1\u9519\uff0c \u79fb\u52a8\u4e5f\u8981\u5220\u9664 \uff0c\u5f88\u591a\u65b0\u624b\u4f1a\u89c9\u5f97\u8d44\u6e90\u7c7b\u5e94\u8be5\u53ef\u4ee5\u79fb\u52a8\u7684\u5440\uff1f\u8981\u662f\u60f3\u4fdd\u7559\u79fb\u52a8\uff0c\u5c31\u5f97\u9884\u7559\u4e00\u4e2a i == 0 \u7684\u7a7a\u72b6\u6001\uff0c\u90a3\u79cd\u5904\u7406\u5f88\u590d\u6742\u7684\u3002\u603b\u4e4b\u4e00\u65e6\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\uff0c\u5168\u90e8 4 \u4e2a\u51fd\u6570\u90fd\u5f97\u5220\u9664\uff0c\u9664\u975e\u4f60\u6709\u76f8\u5173\u7ecf\u9a8c\u3002\u53c2\u89c1 C++ \u751f\u547d\u5468\u671f\u4e0e\u6790\u6784\u51fd\u6570\u4e13\u9898 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e \u8fd9\u65f6\u5c31\u4f53\u73b0\u51fa try_emplace \u7684\u597d\u5904\u4e86\uff1a\u503c\u7c7b\u578b\u4e0d\u9700\u8981\u6709\u79fb\u52a8\u6784\u9020\u51fd\u6570\u4e5f\u53ef\u4ee5\u63d2\u5165\u3002","title":"\u6848\u4f8b 2\uff1a\u8d44\u6e90\u7c7b\u7981\u6b62\u79fb\u52a8"},{"location":"stl_map/#_40","text":"struct RAII { int i; explicit RAII(int i_) : i(i_) { printf(\"%d\u53f7\u8d44\u6e90\u521d\u59cb\u5316\\n\", i); } RAII(RAII &&) = delete; ~RAII() { printf(\"%d\u53f7\u8d44\u6e90\u91ca\u653e\\n\", i); } }; \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u5269\u4e0b 3 \u4e2a\uff0c\u8fd9\u662f\u56e0\u4e3a\u770b\u5230\u4f60\u7528\u4e86 && \u5c31\u77e5\u9053\u4f60\u662f\u61c2 C++11 \u7684\uff0c\u6240\u4ee5\u4e0d\u7528\u7167\u987e C++98 \u517c\u5bb9\u6027\u4fdd\u7559\u70e6\u4eba\u7684\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u81ea\u52a8\u5e2e\u4f60\u5220\u4e86\uff0c\u8fd9\u662f\u4e2a\u6807\u51c6\uff0c\u6240\u6709 C++ \u7f16\u8bd1\u5668\u90fd\u662f\u8fd9\u6837\u7684\uff08\u8981\u6211\u8bf4\uff0c\u5efa\u8bae\u6539\u6210\u5b9a\u4e49\u4e86\u6790\u6784\u51fd\u6570\u5c31\u81ea\u52a8\u5220\u5168 4 \u4e2a\u51fd\u6570\uff0c\u53ef\u60dc\u6807\u51c6\u59d4\u5458\u4f1a\u8981\u7167\u987e\u517c\u5bb9\u6027\u2026\uff09 \u4ee5\u540e RAII \u7c7b\u53ea\u9700\u8981\u4e00\u884c C(C &&) = delete \u5c31\u591f\u4e86\u3002 int main() { { map m; m.try_emplace(\"\u8d44\u6e901\u53f7\", 1); m.try_emplace(\"\u8d44\u6e902\u53f7\", 2); m.erase(\"\u8d44\u6e901\u53f7\"); m.try_emplace(\"\u8d44\u6e903\u53f7\", 3); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; } 1\u53f7\u8d44\u6e90\u521d\u59cb\u5316 2\u53f7\u8d44\u6e90\u521d\u59cb\u5316 1\u53f7\u8d44\u6e90\u91ca\u653e 3\u53f7\u8d44\u6e90\u521d\u59cb\u5316 3\u53f7\u8d44\u6e90\u91ca\u653e 2\u53f7\u8d44\u6e90\u91ca\u653e \u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e","title":"\u8bb0\u5f97\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570"},{"location":"stl_map/#_41","text":"\u5982\u679c\u4f60\u60f3\u7528\u66f4\u53ef\u8bfb\u7684 insert\uff0cRAII \u8d44\u6e90\u7c7b\u53c8\u4e0d\u652f\u6301\u79fb\u52a8\uff0c\u53ef\u4ee5\u7528 unique_ptr \u5305\u88c5\u4e00\u4e0b\uff1a ```cpp int main() { { map> m; m.insert(\"\u8d44\u6e901\u53f7\", std::make_unique(1)); m.insert(\"\u8d44\u6e902\u53f7\", std::make_unique(2)); m.erase(\"\u8d44\u6e901\u53f7\"); m.insert(\"\u8d44\u6e903\u53f7\", std::make_unique(3)); } printf(\"\u6b64\u65f6\u6240\u6709\u8d44\u6e90\u90fd\u5e94\u8be5\u5df2\u7ecf\u91ca\u653e\\n\"); return 0; }","title":"\u7edf\u4e00\u4ea4\u7ed9\u667a\u80fd\u6307\u9488\u7ba1\u7406"},{"location":"stl_map/#_42","text":"\u5bf9\u4e8e\u5f88\u5927\u7684 V \u7c7b\u578b\uff0c\u4e5f\u53ef\u4ee5\u6539\u7528 map> \u907f\u514d\u53cd\u590d\u79fb\u52a8\u5143\u7d20\u672c\u4f53\u3002\uff08\u7528\u5728\u9700\u8981\u53cd\u590d\u6269\u5bb9\u7684 vector \u4e2d\u4e5f\u6709\u5947\u6548\uff09 \u56e0\u4e3a\u5305\u62ec map \u5728\u5185\u7684\u6240\u6709\u5bb9\u5668\u90fd\u5b8c\u7f8e\u652f\u6301 RAII \u7c7b\u578b\uff0c\u6240\u4ee5\u4e5f\u53ef\u4ee5\u7528\u667a\u80fd\u6307\u9488\u4f5c\u4e3a\u8fd9\u4e9b\u5bb9\u5668\u7684\u5143\u7d20\u3002 struct MyData { int value; // \u5047\u8bbe\u8fd9\u4e2a\u5f88\u5927 explicit MyData(int value_) : value(value_) {} }; map> m; m.insert({\"answer\", make_unique(42)}); // \u53ea\u6709 8 \u5b57\u8282\u7684 unique_ptr \u88ab\u79fb\u52a8 2 \u6b21 m.insert({\"fuck\", make_unique(985)}); print(m.at(\"answer\")->value); // 42 // \u2191\u7b49\u4ef7\u4e8e\uff1aprint((*m.at(\"answer\")).value); map> \u4e2d\uff0c\u667a\u80fd\u6307\u9488\u6307\u5411\u7684\u5bf9\u8c61\u4f1a\u5728\u5143\u7d20\u88ab\u5220\u9664\u65f6\u81ea\u52a8\u91ca\u653e\u3002 map \u4e2d\uff0cC \u8bed\u8a00\u539f\u59cb\u6307\u9488\u4e0d\u5177\u5907 RAII \u529f\u80fd\uff0c\u9664\u975e\u8be5\u6307\u9488\u88ab\u5176\u4ed6\u667a\u80fd\u6307\u9488\u6253\u7406\u7740\uff0c\u6216\u8005\u7528\u6237\u5220\u9664\u5143\u7d20\u4e4b\u524d\u624b\u52a8 delete\uff0c\u5426\u5219\u5f53\u5143\u7d20\u5220\u9664\u65f6\u5185\u5b58\u4f1a\u6cc4\u9732\uff01 \u6211\u63a8\u8350\u5b8c\u5168\u91c7\u7528\u667a\u80fd\u6307\u9488\u6765\u81ea\u52a8\u7ba1\u7406\u5185\u5b58\uff0c\u667a\u80fd\u6307\u9488\u548c\u540c\u6837\u7b26\u5408 RAII \u601d\u60f3\u7684\u5404\u5927\u5bb9\u5668\u4e5f\u662f\u76f8\u6027\u5f88\u597d\u7684\u3002 \u5982\u679c\u9700\u8981\u6d45\u62f7\u8d1d\u7684\u8bdd\uff0c\u5219\u53ef\u4ee5\u6539\u7528 map> \uff0c\u5c0f\u5f6d\u8001\u5e08\u5728\u4ed6\u7684 Zeno \u9879\u76ee\u4e2d\u5c31\u662f\u8fd9\u6837\u7528\u7684\u3002","title":"\u667a\u80fd\u6307\u9488\u5e2e\u4f60\u907f\u514d\u79fb\u52a8"},{"location":"stl_map/#_43","text":"","title":"\u589e\u5220\u6539\u67e5\u603b\u7ed3"},{"location":"stl_map/#_44","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.insert(make_pair(key, val)) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++98 \ud83d\udca9 m.insert({key, val}) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \u2764 m.emplace(key, val) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++11 \ud83d\udca9 m.try_emplace(key, valargs...) \u63d2\u5165\u4f46\u4e0d\u8986\u76d6 C++17 \ud83d\udca3 m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 C++17 \u2764 m[key] = val \u63d2\u5165\u6216\u8986\u76d6 C++98 \ud83d\udca3 m.erase(key) \u5220\u9664\u6307\u5b9a\u5143\u7d20 C++98 \u2764","title":"\u589e\u5220"},{"location":"stl_map/#_45","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 m.at(key) \u627e\u4e0d\u5230\u5219\u51fa\u9519\uff0c\u627e\u5230\u5219\u8fd4\u56de\u5f15\u7528 C++98 \u2764 m[key] \u627e\u4e0d\u5230\u5219\u81ea\u52a8\u521b\u5efa 0 \u503c\uff0c\u8fd4\u56de\u5f15\u7528 C++98 \ud83d\udca3 myutils::map_get(m, key, defl) \u627e\u4e0d\u5230\u5219\u8fd4\u56de\u9ed8\u8ba4\u503c C++98 \u2764 m.find(key) == m.end() \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \ud83d\udca3 m.count(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++98 \u2764 m.contains(key) \u68c0\u67e5\u952e key \u662f\u5426\u5b58\u5728 C++20 \ud83d\udca9","title":"\u6539\u67e5"},{"location":"stl_map/#_46","text":"\u5199\u6cd5 \u6548\u679c \u7248\u672c \u63a8\u8350 map m = {{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 auto m = map{{k1, v1}, {k2, v2}} \u521d\u59cb\u5316\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \ud83d\udca9 func({{k1, v1}, {k2, v2}}) \u7ed9\u51fd\u6570\u53c2\u6570\u4f20\u5165\u4e00\u4e2a map C++11 \u2764 m = {{k1, v1}, {k2, v2}} \u91cd\u7f6e\u4e3a\u4e00\u7cfb\u5217\u952e\u503c\u5bf9 C++11 \u2764 m.clear() \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++98 \u2764 m = {} \u6e05\u7a7a\u6240\u6709\u8868\u9879 C++11 \ud83d\udca3","title":"\u521d\u59cb\u5316"},{"location":"stl_map/#_47","text":"","title":"\u8282\u70b9\u53e5\u67c4\u7cfb\u5217\u63a5\u53e3"},{"location":"stl_map/#extract","text":"C++17 \u65b0\u589e\u7684 extract \u51fd\u6570 1 \u53ef\u4ee5\u201c\u5265\u79bb\u201d\u51fa\u5355\u4e2a\u8282\u70b9\uff1a node_type extract(K const &key); node_type extract(const_iterator pos); auto node = m.extract(\"fuck\"); auto &k = node.key(); // \u952e\uff08\u5f15\u7528\uff09 auto &v = node.mapped(); // \u503c\uff08\u5f15\u7528\uff09 \u5176\u529f\u80fd\u4e0e erase \u7c7b\u4f3c\uff0c\u90fd\u4f1a\u5c06\u5143\u7d20\u4ece map \u4e2d\u5220\u9664\uff0c\u4f46 extract \u53ea\u662f\u628a\u8282\u70b9\u4ece map \u4e2d\u79fb\u8d70\uff0c\u5e76\u4e0d\u4f1a\u76f4\u63a5\u9500\u6bc1\u8282\u70b9\u3002 extract \u4f1a\u8fd4\u56de\u8fd9\u4e2a\u521a\u88ab\u201c\u5265\u79bb\u201d\u51fa\u6765\u8282\u70b9\u7684\u53e5\u67c4\uff0c\u7c7b\u578b\u4e3a node_type\uff0c\u8282\u70b9\u7684\u751f\u6740\u5927\u6743\u5c31\u8fd9\u6837\u8fd4\u56de\u7ed9\u4e86\u7528\u6237\u6765\u5904\u7f6e\u3002 node_type \u662f\u6307\u5411\u6e38\u79bb\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff0c\u79f0\u4e3a\u8282\u70b9\u53e5\u67c4 2 \u3002\u53ea\u53ef\u79fb\u52a8\u4e0d\u53ef\u62f7\u8d1d\uff0c\u7c7b\u4f3c\u4e00\u4e2a\u6307\u5411\u8282\u70b9\u7684 unique_ptr\u3002 \u5f53\u8c03\u7528 extract(key) \u65f6\u4f1a\u628a key \u5bf9\u5e94\u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u7ea2\u9ed1\u6811\u8282\u70b9\u201c\u8131\u79bb\u201d\u51fa\u6765\u2014\u2014\u4e0d\u662f\u76f4\u63a5\u91ca\u653e\u8282\u70b9\u5185\u5b58\u5e76\u9500\u6bc1\u952e\u503c\u5bf9\u8c61\uff0c\u800c\u662f\u628a\u5220\u9664\u7684\u8282\u70b9\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u8c03\u7528\u8005\uff0c\u4ee5\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488 node_type \u7684\u5f62\u5f0f\u3002 \u8c03\u7528 extract \u540e\uff0c\u8282\u70b9\u53e5\u67c4\u6307\u5411\u7684\u8fd9\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u5df2\u7ecf\u4ece map \u4e2d\u79fb\u9664\uff08\u5176 left\u3001right\u3001parent \u7b49\u6307\u9488\u4e3a NULL\uff09\uff0c\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\u3002 \u8282\u70b9\u4e2d\u4e0d\u4ec5\u5b58\u50a8\u7740\u6211\u4eec\u611f\u5174\u8da3\u7684\u952e\u548c\u503c\uff0c\u8fd8\u6709 left\u3001right\u3001parent\u3001color \u7b49\u7528\u4e8e\u7ef4\u62a4\u6570\u636e\u7ed3\u6784\u7684\u6210\u5458\u53d8\u91cf\uff0c\u5bf9\u7528\u6237\u4e0d\u53ef\u89c1\u3002 \u53ea\u662f\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u7ef4\u6301\u7740\u8282\u70b9\u7684\u751f\u547d\u5468\u671f\uff0c\u4fdd\u62a4\u7740\u952e key() \u548c\u503c mapped() \u6ca1\u6709\u88ab\u9500\u6bc1\uff0c\u5185\u5b58\u6ca1\u6709\u88ab\u91ca\u653e\u3002 \u5982\u679c\u8c03\u7528\u8005\u63a5\u4e0b\u6765\u4e0d\u505a\u64cd\u4f5c\uff0c\u90a3\u4e48\u5f53\u79bb\u5f00\u8c03\u7528\u8005\u6240\u5728\u7684\u51fd\u6570\u4f53\u65f6\uff0c\u8fd9\u4e2a\u7279\u6b8a\u7684 unique_ptr \u4f1a\u81ea\u52a8\u91ca\u653e\u5176\u6307\u5411\u8282\u70b9\u3002 \u5bf9\u4e8e\u7b2c\u4e00\u4e2a\u6309\u952e\u53d6\u51fa\u8282\u70b9\u53e5\u67c4\u7684 extract \u91cd\u8f7d\uff1a\u5982\u679c\u952e\u503c\u4e0d\u5b58\u5728\uff0c\u90a3\u4e48 extract \u4f1a\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u7684\u7a7a\u8282\u70b9\u53e5\u67c4\uff0c\u7c7b\u4f3c\u4e8e\u7a7a\u6307\u9488\u3002\u53ef\u4ee5\u901a\u8fc7 (bool)node \u6765\u5224\u65ad\u4e00\u4e2a\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u7a7a\u3002 \u5bf9\u4e8e\u7b2c\u4e8c\u4e2a\u6309\u8fed\u4ee3\u5668\u53d6\u51fa\u53e5\u67c4\u7684 extract\uff1a\u603b\u662f\u6210\u529f\uff0c\u56e0\u4e3a\u65e2\u7136\u4f60\u5df2\u7ecf\u83b7\u5f97\u4e86\u8fed\u4ee3\u5668\uff0c\u80af\u5b9a\u662f find \u83b7\u5f97\u7684\uff0c\u800c find \u627e\u4e0d\u5230\u8fd4\u56de\u7684 end \u4f20\u5165 extract \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u6b63\u5982 erase \u8fed\u4ee3\u5668\u7248\u91cd\u8f7d erase(it) \u603b\u662f\u6210\u529f\u4e00\u6837\u3002","title":"extract"},{"location":"stl_map/#_48","text":"\u8c03\u7528\u8005\u7a0d\u540e\u53ef\u4ee5\u76f4\u63a5\u9500\u6bc1\u8fd9\u4e2a\u7279\u6b8a\u667a\u80fd\u6307\u9488\uff1a { auto node = m.extract(\"fuck\"); print(node.key(), node.mapped()); } // node \u5728\u6b64\u81ea\u52a8\u9500\u6bc1 \u4e5f\u53ef\u4ee5\u505a\u4e00\u4e9b\u4fee\u6539\u540e\uff08\u4f8b\u5982\u4fee\u6539\u952e\u503c\uff09\uff0c\u7a0d\u540e\u91cd\u65b0\u7528 insert(node) \u91cd\u65b0\u628a\u4ed6\u63d2\u5165\u56de\u53bb\uff1a auto node = m.extract(\"fuck\"); node.key() = \"love\"; m.insert(std::move(node)); \u8fc7\u53bb\uff0c\u901a\u8fc7\u8fed\u4ee3\u5668\u6765\u4fee\u6539\u952e\u503c\u662f\u4e0d\u5141\u8bb8\u7684\uff1a map m; auto it = m.find(\"fuck\"); assert(it != m.end()); // *it \u662f pair it->first = \"love\"; // \u9519\u8bef\uff01first \u662f const string \u7c7b\u578b m.insert(*it); \u56e0\u4e3a\u76f4\u63a5\u4fee\u6539\u5728 map \u91cc\u9762\u7684\u4e00\u4e2a\u8282\u70b9\u7684\u952e\uff0c\u4f1a\u5bfc\u81f4\u6392\u5e8f\u5931\u6548\uff0c\u7834\u574f\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u3002\u800c extract \u53d6\u51fa\u6765\u7684\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u53ef\u4ee5\u4fee\u6539 .key() \uff0c\u4e0d\u4f1a\u5f71\u54cd\u4efb\u4f55\u7ea2\u9ed1\u6811\u7684\u987a\u5e8f\uff0c\u4ed6\u5df2\u7ecf\u4e0d\u5728\u6811\u91cc\u9762\u4e86\u3002 \u6216\u8005\u63d2\u5165\u5230\u53e6\u4e00\u4e2a\u4e0d\u540c\u7684 map \u5bf9\u8c61\uff08\u4f46\u952e\u548c\u503c\u7c7b\u578b\u76f8\u540c\uff09\u91cc\uff1a // \u4ece m1 \u632a\u5230 m2 auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); \u4f18\u70b9\u5728\u4e8e\uff0cextract \u548c\u8282\u70b9\u7248 insert \u4e0d\u6d89\u53ca\u5185\u5b58\u7684\u91cd\u65b0\u5206\u914d\u4e0e\u91ca\u653e\uff0c\u4e0d\u6d89\u53ca\u5143\u7d20\u7c7b\u578b\u7684\u79fb\u52a8\uff08\u56e0\u4e3a\u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e\u667a\u80fd\u6307\u9488\uff0c\u667a\u80fd\u6307\u9488\u7684\u79fb\u52a8\u5e76\u4e0d\u4f1a\u5bfc\u81f4\u5176\u6307\u5411\u5bf9\u8c61\u7684\u79fb\u52a8\uff09\uff0c\u6240\u4ee5\u4f1a\u6bd4\u4e0b\u9762\u8fd9\u79cd\u4f20\u7edf\u5199\u6cd5\u66f4\u9ad8\u6548\uff1a // \u4ece m1 \u632a\u5230 m2\uff1a\u4f20\u7edf\u5199\u6cd5 if (m1.count(\"fuck\")) { auto value = std::move(m1.at(\"fuck\")); m2[\"fuck\"] = std::move(value); m1.erase(it); } \u4e0d\u7528 auto \u5b8c\u6574\u5199\u51fa\u5168\u90e8\u7c7b\u578b\u7684\u5f62\u5f0f\uff08\u53e4\u4ee3 C++98 \u4f5c\u98ce\uff09\uff1a typename map::node_type node = m.extract(\"fuck\"); K &k = node.key(); V &v = node.mapped(); set \u4e5f\u6709 extract \u51fd\u6570\uff0c\u5176\u8282\u70b9\u53e5\u67c4\u6ca1\u6709 key() \u548c mapped() \u4e86\uff0c\u800c\u662f\u53ea\u6709\u4e00\u4e2a value()\uff0c\u83b7\u53d6\u5176\u4e2d\u7684\u503c set s = {\"fuck\", \"suck\", \"dick\"}; set::node_type node = s.extract(\"fuck\"); V &v = node.value();","title":"\u7528\u9014\u4e3e\u4f8b"},{"location":"stl_map/#insert_6","text":"insert \u51fd\u6570\uff1a\u63d2\u5165\u6e38\u79bb\u8282\u70b9\u7684\u7248\u672c insert_return_type insert(node_type &&node); iterator insert(const_iterator pos, node_type &&node); // \u5e26\u63d0\u793a\u7684\u7248\u672c \u53ef\u4ee5\u7528 insert(move(node)) \u76f4\u63a5\u63d2\u5165\u4e00\u4e2a\u8282\u70b9\u3002 map m1 = { {\"fuck\", 985}, {\"dick\", 211}, }; map m2; auto node = m1.extract(\"fuck\"); m2.insert(std::move(node)); // \u8282\u70b9\u53e5\u67c4\u7c7b\u4f3c\u4e8e unique_ptr\uff0c\u4e0d\u53ef\u62f7\u8d1d\uff0c\u9700\u8981\u7528\u79fb\u52a8\u8bed\u4e49\u8fdb\u884c\u63d2\u5165 \u8c03\u7528 insert(move(node)) \u540e\u7531\u4e8e\u6240\u6709\u6743\u88ab\u79fb\u8d70\uff0cnode \u5c06\u4f1a\u5904\u4e8e\u201c\u7a7a\u6307\u9488\u201d\u72b6\u6001\uff0c\u53ef\u4ee5\u7528 node.empty() \u67e5\u8be2\u8282\u70b9\u53e5\u67c4\u662f\u5426\u4e3a\u201c\u7a7a\u201d\u72b6\u6001\uff0c\u5373\u8282\u70b9\u6240\u6709\u6743\u662f\u5426\u5df2\u7ecf\u79fb\u8d70\u3002","title":"insert \u8282\u70b9\u7248"},{"location":"stl_map/#insert_return_type","text":"\u8fd9\u4e2a\u7248\u672c\u7684 insert \u8fd4\u56de\u503c\u7c7b\u578b insert_return_type \u662f\u4e00\u4e2a\u7ed3\u6784\u4f53\uff08\u6211\u7684\u5929\u4ed6\u4eec\u7ec8\u4e8e\u80af\u7528\u7ed3\u6784\u4f53\u800c\u4e0d\u662f pair \u4e86\uff09\uff1a struct insert_return_type { iterator position; bool inserted; node_type node; }; insert_return_type insert(node_type &&nh); \u5b98\u65b9\u8bf4\u6cd5\u662f 1 \uff1a If nh is empty, inserted is false, position is end(), and node is empty. Otherwise if the insertion took place, inserted is true, position points to the inserted element, and node is empty. If the insertion failed, inserted is false, node has the previous value of nh, and position points to an element with a key equivalent to nh.key().","title":"insert_return_type"},{"location":"stl_map/#extract-insert","text":"map hells = { {666, \"devil\"}, }; map schools = { {985, \"professor\"}, {211, \"doctor\"}, {996, \"fucker\"}, }; auto node = schools.extract(996); hells.insert(std::move(node)); print(schools); print(hells); {211: \"doctor\", 985: \"professor\"} {666: \"devil\", 996: \"fucker\"} extract + insert(move(node)) \u5bf9\u6bd4 find + insert({key, val})\uff0c\u53ef\u4ee5\u907f\u514d\u952e\u548c\u503c\u7c7b\u578b\u79fb\u52a8\u6784\u9020\u51fd\u6570\u7684\u5f00\u9500\uff0c\u81f3\u59cb\u81f3\u7ec8\u79fb\u52a8\u7684\u53ea\u662f\u4e00\u4e2a\u7ea2\u9ed1\u6811\u8282\u70b9\u7684\u6307\u9488\uff0c\u5143\u7d20\u6ca1\u6709\u88ab\u79fb\u52a8\uff0c\u4e5f\u6ca1\u6709\u9020\u6210\u5185\u5b58\u7a7a\u95f4\u4e0d\u5fc5\u8981\u7684\u5206\u914d\u548c\u91ca\u653e\u3002 \u4f46\u662f insert(move(node)) \u4ec5\u9002\u7528\u4e8e\u4ece extract \u4e2d\u53d6\u51fa\u73b0\u6709\u8282\u70b9\u7684\u60c5\u51b5\uff0c\u5982\u679c\u8981\u65b0\u5efa\u8282\u70b9\u8fd8\u5f97\u9760 insert({key, val}) \u6216\u8005 try_emplace(key, val) \u7684\u3002","title":"extract + insert \u8fd0\u7528\u6848\u4f8b"},{"location":"stl_map/#extract_1","text":"\u5df2\u77e5\u4e24\u4e2a\u6620\u5c04\u8868 tab1 \u548c tab2\uff0c\u548c\u4e00\u4e2a\u63a5\u53d7 K \u7c7b\u578b\u505a\u53c2\u6570\u7684\u4eff\u51fd\u6570 cond\u3002 \u8981\u6c42\u628a tab1 \u4e2d\u952e\u7b26\u5408 cond \u6761\u4ef6\u7684\u5143\u7d20\u79fb\u52a8\u5230 tab2 \u4e2d\u53bb\uff0c\u5176\u4f59\u4fdd\u7559\u5728 tab1 \u4e2d\u3002 \u6211\u4eec\u7f16\u5199\u56db\u4efd\u540c\u6837\u529f\u80fd\u7684\u7a0b\u5e8f\uff0c\u5206\u522b\u91c7\u7528\uff1a extract + \u5e26\u63d0\u793a\u7684 insert erase + \u5e26\u63d0\u793a\u7684 insert extract + \u76f4\u63a5 insert erase + \u76f4\u63a5 insert template void filter_with_extract(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); tab2.insert(std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); tab2.insert(std::move(kv)); } else ++it; } } template void filter_with_extract_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { auto next_it = it; ++next_it; auto node = tab1.extract(it); hint = tab2.insert(hint, std::move(node)); it = next_it; } else ++it; } } template void filter_with_erase_with_hint(map &tab1, map &tab2, Cond &&cond) { DefScopeProfiler; auto hint = tab2.begin(); for (auto it = tab1.begin(); it != tab1.end(); ) { if (cond(it->first)) { it = tab1.erase(it); auto kv = std::move(*it); hint = tab2.insert(hint, std::move(kv)); } else ++it; } } extract vs erase \u6027\u80fd\u6d4b\u8bd5\u7ed3\u679c (testextractvserase.cpp)\uff1a avg | min | max | total | cnt | tag 889| 803| 2388| 889271| 1000| filter_with_erase 642| 595| 1238| 642542| 1000| filter_with_extract 525| 491| 1398| 525137| 1000| filter_with_erase_with_hint 305| 289| 842| 305472| 1000| filter_with_extract_with_hint extract + \u5e26\u63d0\u793a\u7684 insert \u83b7\u80dc\uff0c\u5373\u51fd\u6570 filter_with_extract_with_hint \u662f\u6027\u80fd\u6700\u597d\u7684\u90a3\u4e00\u4e2a\u3002","title":"extract \u6027\u80fd\u4f18\u5316\u6848\u4f8b"},{"location":"stl_map/#_49","text":"\u7531\u4e8e\u5904\u4e8e\u6e38\u79bb\u72b6\u6001\uff0c\u6e38\u79bb\u8282\u70b9\u4e0d\u5c5e\u4e8e\u4efb\u4f55 map \u4e2d\uff0c\u4e0d\u9700\u8981\u6ee1\u8db3\u6392\u5e8f\u6027\u8d28\uff0c\u56e0\u6b64 node.key() \u53ef\u4fee\u6539\u3002 \u5148\u7528 extract \u53d6\u51fa\u6e38\u79bb\u6001\u8282\u70b9\uff0c\u4fee\u6539\u5b8c\u8282\u70b9\u7684\u952e\u540e\u518d\u91cd\u65b0\u63d2\u5165\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u505a\u5230\u4ee5\u524d\u505a\u4e0d\u5230\u7684\u4fee\u6539\u952e\u503c\u3002 map m = { {\"fuck\", 985}, }; auto node = m.extract(\"fuck\"); // \u79fb\u51fa \"fuck\" \u952e\u5bf9\u5e94\u7684\u8282\u70b9\uff0c\u6b64\u65f6 m \u4f1a\u53d8\u4e3a\u7a7a node.key() = \"fxxk\"; // \u4fee\u6539\u952e\uff08\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->first \u662f\u4e0d\u5141\u8bb8\u4fee\u6539\u952e\u7684\uff0c\u56e0\u4e3a\u8fed\u4ee3\u5668\u6307\u5411\u7684\u8282\u70b9\u4e0d\u662f\u6e38\u79bb\u72b6\u6001\uff0c\u4fee\u6539\u952e\u4f1a\u7834\u574f\u6392\u5e8f\uff09 node.mapped() = 211; // \u4fee\u6539\u503c\uff08\u8fd9\u4e2a\u4ee5\u524d\u7528\u8fed\u4ee3\u5668\u65f6 it->second \u4e5f\u53ef\u4ee5\u4fee\u6539\uff09 m.insert(move(node)); // \u628a\u4fee\u6539\u597d\u7684\u8282\u70b9\u63d2\u5165\u56de\u53bb print(m); // {{\"fxxk\": 211}} \u76f8\u5f53\u4e8e\u4f60\u7ed9\u5c0f\u5b66\u751f\u6392\u961f\u65f6\uff0c\u6709\u4e00\u4e2a\u5c0f\u5b66\u751f\u7a81\u7136\u77ac\u95f4\u4e0d\u77e5\u9053\u5403\u4e86\u4ec0\u4e48\u6fc0\u7d20\u957f\u9ad8\u4e86\uff0c\u4f60\u7684\u961f\u4f0d\u5c31\u4f1a\u4e71\u6389\u3002 \u6240\u4ee5\u9700\u8981\u8ba9\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5148\u51fa\u5217\uff0c\u8ba9\u4ed6\u5355\u72ec\u4e00\u4e2a\u4eba\u957f\u9ad8\uff0c\u7b49\u4ed6\u957f\u9ad8\u5b8c\u4e86\u518d\u63d2\u5165\u56de\u961f\u5217\u3002","title":"\u6e38\u79bb\u8282\u70b9\u53ef\u4ee5\u4fee\u6539\u952e\u503c"},{"location":"stl_map/#insert_7","text":"\u4f46\u662f\u5c0f\u5b66\u751f\u957f\u9ad8\u7684\u91cf\u53ef\u80fd\u662f\u6709\u9650\u7684\uff08\u65b0\u7684\u952e\u53ef\u80fd\u548c\u8001\u952e\u5f88\u63a5\u8fd1\uff09\u3002 \u8fd9\u65f6\u63d2\u5165\u53ef\u4ee5\u4f18\u5148\u4ece\u4ed6\u957f\u9ad8\u4e4b\u524d\u7684\u4f4d\u7f6e\u5f00\u59cb\u4e8c\u5206\u6cd5\uff0c\u4e5f\u5c31\u662f\u7528 extract \u4e4b\u524d\uff0c\u8fd9\u4e2a\u5c0f\u5b66\u751f\u540e\u4e00\u4f4d\u540c\u5b66\u7684\u4f4d\u7f6e\uff0c\u4f5c\u4e3a insert \u7684\u63d0\u793a\uff0c\u8ba9 insert \u66f4\u5feb\u5b9a\u4f4d\u5230\u8fd9\u4e2a\u5c0f\u5b66\u751f\u5e94\u8be5\u63d2\u5165\u7684\u4f4d\u7f6e\u3002 auto it = m.find(\"fuck\"); assert(it != m.end()); // \u5047\u5b9a \"fuck\" \u5fc5\u987b\u5b58\u5728\uff08\u5982\u679c\u4e0d\u5b58\u5728\u4f1a\u8fd4\u56de end\uff09 auto next_it = std::next(it); // \u4e0b\u4e00\u4f4d\u540c\u5b66\uff08\u53ef\u80fd\u4f1a\u5f97\u5230 end\uff0c\u4f46\u6ca1\u5173\u7cfb\uff0c\u56e0\u4e3a insert \u7684\u63d0\u793a\u4e5f\u5141\u8bb8\u4e3a end \u8fed\u4ee3\u5668\uff09 auto node = m.extract(it); node.key() = \"fxxk\"; // \u4fee\u6539\u952e\u503c\uff0c\u53d8\u5316\u4e0d\u5927 m.insert(next_it, move(node)); // \u5982\u679c\u952e\u503c\u53d8\u52a8\u4e0d\u5927\uff0c\u4f18\u5148\u5c1d\u8bd5\u5728\u8001\u4f4d\u7f6e\u63d2\u5165 \u8fd9\u91cc\u7684 std::next(it) \u5bf9\u4e8e\u7b49\u4ef7\u4e8e it + 1\u3002\u4f46\u662f map \u5c5e\u4e8e\u53cc\u5411\u8fed\u4ee3\u5668\uff08\u800c\u4e0d\u662f\u968f\u673a\u8fed\u4ee3\u5668\uff09\uff0c\u4e0d\u652f\u6301\u52a0\u6cd5\u64cd\u4f5c\uff0c\u53ea\u652f\u6301\u5c31\u5730 ++\u3002\u6240\u4ee5 std::next \u5185\u90e8\u7b49\u4ef7\u4e8e\uff1a auto next(auto it) { auto next_it = it; // \u5148\u62f7\u8d1d\u4e00\u4efd\uff0c\u9632\u6b62\u539f\u8fed\u4ee3\u5668\u88ab\u7834\u574f\uff08\u8fed\u4ee3\u5668\u90fd\u652f\u6301\u62f7\u8d1d\uff0c\u6027\u8d28\u4e0a\u662f\u6d45\u62f7\u8d1d\uff09 ++next_it; // \u518d\u8ba9 next_it \u5c31\u5730\u81ea\u589e\u5230\u4e0b\u4e00\u4f4d return next_it; // \u8fd4\u56de\u73b0\u5728\u5df2\u7ecf\u76f8\u5f53\u4e8e it + 1 \u7684 next_it } \u5982\u679c\u952e\u4e0d\u53d8\uff0c\u6216\u8005\u952e\u53d8\u4e86\u4ee5\u540e\uff0c\u63d2\u5165\u4f4d\u7f6e\u4e0d\u53d8\u7684\u8bdd\uff0c\u90a3\u4e48\u8fd9\u6b21 insert \u53ef\u4ee5\u4f4e\u81f3 O(1) O(1) \u590d\u6742\u5ea6\u3002 map m = { {\"dick\", 211}, {\"fuck\", 985}, // \"fuck\" -> \"fxxk\" \u540e\uff0c\u91cd\u65b0\u63d2\u5165\uff0c\u5176\u4f9d\u5b57\u5178\u5e8f\u7684\u201c\u5927\u5c0f\u201d\u4f9d\u7136\u662f\u4ecb\u4e8e \"dick\" \u548c \"suck\" {\"suck\", 996}, };","title":"\u5e26\u63d0\u793a\u7684\u8282\u70b9\u7248 insert"},{"location":"stl_map/#mergemap","text":"C++17 \u65b0\u589e\u7684 merge \u51fd\u6570 1 template void merge(map &__source); \u6ce8\uff1aset \u4e5f\u6709 merge \u51fd\u6570 \u6ce8\u610f\u5230 merge \u7684\u53c2\u6570\u662f\u53e6\u4e00\u4e2a map\uff0c\u53ef\u53d8\u5f15\u7528\uff0c\u5fc5\u987b\u548c\u672c map \u540c\u7c7b\u578b\uff08\u8fd9\u662f\u4e3a\u4e86\u4fdd\u8bc1\u8282\u70b9\u53e5\u67c4\u7c7b\u578b\u76f8\u540c\uff09\uff0c\u4f46\u5141\u8bb8\u6709\u4e0d\u540c\u7684\u6bd4\u8f83\u51fd\u6570 merge(source) \u4f1a\u628a source \u4e2d\u7684\u6240\u6709\u8282\u70b9\u90fd \u79fb\u52a8 \u5e76\u5408\u5e76\u5230\u672c map\uff0c\u6ce8\u610f\u662f \u79fb\u52a8 \u800c\u4e0d\u662f\u62f7\u8d1d\uff0csource \u5c06\u4f1a\u88ab\u6e05\u7a7a\uff0c\u8fd9\u6837\u662f\u4e3a\u4e86\u66f4\u9ad8\u6548\u3002 insert(source.begin(), source.end()) \u5219\u662f\u628a source \u91cc\u7684\u5143\u7d20\u62f7\u8d1d\u540e\u63d2\u5165\u5230\u672c map\uff0c\u66f4\u4f4e\u6548\uff0c\u56e0\u4e3a\u9700\u8981\u62f7\u8d1d\uff0c\u8fd8\u5f97\u65b0\u5efa\u7ea2\u9ed1\u6811\u8282\u70b9\uff0c\u989d\u5916\u5206\u914d\u5185\u5b58\u7a7a\u95f4\u3002 \u5bf9\u4e8e\u952e\u5b58\u5728\u51b2\u7a81\u7684\u60c5\u51b5\uff1a merge: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u79fb\u52a8\uff0c\u4fdd\u7559\u5728 source \u91cc\u3002 insert: \u5982\u679c source \u4e2d\u6709\u4e0e\u672c map \u91cd\u590d\u7684\u952e\uff0c\u5219\u8be5\u5143\u7d20\u4e0d\u4f1a\u88ab\u63d2\u5165\u672c map\u3002\u65e0\u8bba\u6709\u6ca1\u6709\u63d2\u5165\u672c map\uff0c\u539f source \u4e2d\u7684\u952e\u90fd\u4e0d\u4f1a\u88ab\u6e05\u9664\u3002 \u56e0\u6b64\uff0cmerge \u4e5f\u5e76\u4e0d\u603b\u662f\u5b8c\u5168\u6e05\u7a7a source\uff0c\u5f53 source \u548c\u672c map \u6709\u51b2\u7a81\u65f6\uff0c\u51b2\u7a81\u7684\u952e\u5c31\u4fdd\u7559\u5728 source \u91cc\u4e86\u3002 merge \u7b49\u4ef7\u4e8e\u4ee5\u4e0b\u624b\u52a8\u7528 extract \u548c insert \u6765\u79fb\u52a8\u8282\u70b9\u7684\u4ee3\u7801\uff1a // m1.merge(m2) \u7b49\u4ef7\u4e8e\uff1a auto hint = m1.begin(); for (auto it = m2.begin(); it != m2.end(); ++it) { if (!m1.contains(it->first)) { auto node = m2.extract(it); hint = m1.insert(hint, node); } }","title":"merge\uff1amap \u7684\u5408\u5e76\u64cd\u4f5c\uff08\u5e76\u96c6\uff09"},{"location":"stl_map/#insert-vs-merge","text":"\u540c\u6837\u505a\u5230\u4e24\u4e2a map \u5408\u5e76\uff0c m1.merge(m2) \u4e0e m1.insert(m2.begin(), m2.end()) \u6027\u80fd\u6bd4\u8f83\uff1a #include #include #include \"benchmark/benchmark.h\" using namespace std; static void BM_Insert(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.insert(m1.begin(), m1.end()); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Insert)->Arg(1000); static void BM_Merge(benchmark::State &state) { map m1_init; map m2_init; for (int i = 0; i < state.range(0); i++) { m1_init[to_string(i)] = i; m2_init[to_string(i + state.range(0))] = i; } for (auto _ : state) { auto m1 = m1_init; auto m2 = m2_init; m2.merge(m1); benchmark::DoNotOptimize(m2); } } BENCHMARK(BM_Merge)->Arg(1000); merge \u51fd\u6570\u4e0d\u4f1a\u4ea7\u751f\u4e0d\u5fc5\u8981\u7684\u5185\u5b58\u5206\u914d\u5bfc\u81f4\u5185\u5b58\u788e\u7247\u5316\uff0c\u6240\u4ee5\u66f4\u9ad8\u6548\u3002\u4f46\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u4ed6\u4f1a\u6e05\u7a7a m2\uff01 merge \u76f8\u5f53\u4e8e\u628a m2 \u7684\u5143\u7d20\u201c\u79fb\u52a8\u201d\u5230 m1 \u4e2d\u53bb\u4e86\u3002 insert \u5219\u662f\u628a m2 \u7684\u5143\u7d20\u201c\u62f7\u8d1d\u201d\u4e86\u4e00\u4efd\u63d2\u5165\u5230 m1 \u4e2d\u53bb\uff0c\u6548\u7387\u81ea\u7136\u4f4e\u4e0b\u3002 \u5982\u679c\u4e0d\u60f3\u7834\u574f\u6389 m2\uff0c\u6216\u8005\u4f60\u7528\u4e0d\u4e0a C++17\uff0c\u5219\u4ecd\u9700\u8981\u4f20\u7edf\u7684 insert\u3002","title":"\u6279\u91cf insert vs merge"},{"location":"stl_map/#merge-insert","text":"merge(m2) \u548c insert(m2.begin(), m2.end()) \u4e00\u6837\u5c3f\u6027\uff1a\u5982\u679c m2 \u4e2d\u7684\u952e\u5728 m1 \u4e2d\u5df2\u7ecf\u5b58\u5728\uff0c\u5219\u4e0d\u4f1a extract \u8be5 m2 \u4e2d\u7684\u8282\u70b9\uff0c\u4ecd\u7136\u7559\u5728 m2 \u4e2d\u3002 int main() { std::map ma {{1, \"apple\"}, {5, \"pear\"}, {10, \"banana\"}}; std::map mb {{2, \"zorro\"}, {4, \"batman\"}, {5, \"X\"}, {8, \"alpaca\"}}; std::map u; u.merge(ma); std::cout << \"ma.size(): \" << ma.size() << '\\n'; u.merge(mb); std::cout << \"mb.size(): \" << mb.size() << '\\n'; std::cout << \"mb.at(5): \" << mb.at(5) << '\\n'; for(auto const &kv: u) std::cout << kv.first << \", \" << kv.second << '\\n'; }","title":"merge \u548c insert \u4e00\u6837\u4e0d\u8986\u76d6\u65e7\u503c"},{"location":"stl_map/#map_6","text":"map \u5bb9\u5668\u7684\u5168\u90e8\u53c2\u6570\u4e3a\uff1a std::map \u5176\u4e2d\u7b2c 3\u30014 \u4e2a\u53c2\u6570 Cmp \u548c Alloc \u53ef\u4ee5\u7701\u7565\u3002 Cmp \u9ed8\u8ba4\u4e3a std::less Alloc \u9ed8\u8ba4\u4e3a std::allocator> \u56e0\u6b64 map \u7684\u5b8c\u6574\u6a21\u677f\u53c2\u6570\u662f\uff1a std::map, std::allocator>> \u6211\u4eec\u53ef\u4ee5\u7b80\u5199\u6210 map \u3002 \u5176\u4e2d allocator \u6211\u4eec\u4ee5\u540e\u4e13\u95e8\u5f00\u4e00\u8282\u8bfe\u8bb2\uff0c\u5176\u4ed6\u5f88\u591a\u5bb9\u5668\u90fd\u6709 allocator\u3002 \u4eca\u5929\u53ea\u7814\u7a76 Cmp \u8fd9\u4e2a\u53c2\u6570\uff0c\u4ed6\u51b3\u5b9a\u4e86 map \u5982\u4f55\u6392\u5e8f\uff0c\u5224\u65ad\u76f8\u7b49\u3002 std::map> \u8fd9\u4e2a std::less \u662f\u4e2a\u4ec0\u4e48\u5462\uff1f\u662f\u4e00\u4e2a\u4eff\u51fd\u6570(functor)\u3002 template struct less { constexpr bool operator()(T const &x, T const &y) const { return x < y; } }; \u5177\u6709\u6210\u5458\u51fd\u6570 operator() \u7684\u7c7b\u578b\uff0c\u90fd\u88ab\u79f0\u4e4b\u4e3a\u4eff\u51fd\u6570\u3002","title":"map \u81ea\u5b9a\u4e49\u6bd4\u8f83\u5668"},{"location":"stl_map/#stdless","text":"\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u5706\u62ec\u53f7\u5f53\u505a\u666e\u901a\u51fd\u6570\u8c03\u7528\uff0c\u8fd9\u5c31\u662f\u201c\u4eff\u51fd\u6570\u201d\u7684\u5f97\u540d\u539f\u56e0\uff0c\u4f8b\u5982\uff1a less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true less cmp; print(cmp(\"hello\", \"world\")); // \"hello\" < \"world\": false print(cmp(\"cmake\", \"cppcon\")); // \"cmake\" < \"cppcon\": true","title":"std::less \u7684\u4f5c\u7528"},{"location":"stl_map/#operator_1","text":"\u6ce8\u610f\u4eff\u51fd\u6570\u7684\u6210\u5458\u51fd\u6570 operator() \u662f\u4e24\u4e2a\u62ec\u53f7\uff1a operator()(...) \u7b2c\u4e00\u4e2a\u62ec\u53f7\u662f operator() \u7684\u4e00\u90e8\u5206\uff0c\u8868\u793a\u8fd9\u662f\u5bf9\u5706\u62ec\u53f7 () \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u3002 \u7b2c\u4e8c\u4e2a\u62ec\u53f7\u662f\u51fd\u6570\u7684\u53c2\u6570\u5217\u8868\uff0c\u91cc\u9762\u662f operator() \u8fd9\u4e2a\u51fd\u6570\u7684\u5f62\u53c2\u3002 operator() \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __call__ \u3002\u6b63\u5982 operator< \u76f8\u5f53\u4e8e Python \u4e2d\u7684 __lt__ \u3002\u8fd9\u91cc operator \u548c () \u662f\u4e00\u4e2a\u6574\u4f53\uff0c\u8fde\u5728\u4e00\u8d77\uff0c\u5f62\u6210\u4e86\u4e00\u4e2a\u6807\u8bc6\u7b26\u3002","title":"operator()"},{"location":"stl_map/#_50","text":"std::map> \u6211\u4eec\u4e4b\u524d\u63d0\u5230 map \u5185\u90e8\u7684\u5143\u7d20\u59cb\u7ec8\u6309\u7167\u952e K \u4ece\u5c0f\u5230\u5927\u7684\u987a\u5e8f\u6392\u5217\u3002 map \u51b3\u5b9a\u5927\u5c0f\u987a\u5e8f\u7684\uff0c\u5e76\u4e0d\u662f\u76f4\u63a5\u8c03\u7528 K \u7c7b\u578b\u7684\u6bd4\u8f83\u8fd0\u7b97\u7b26 operator< \u3002 \u800c\u662f\u8c03\u7528\u4ed6\u7684\u6a21\u677f\u53c2\u6570 Cmp \u7c7b\u578b\u7684 operator() \u3002 \u8fd9\u662f\u4e3a\u4e86\u5141\u8bb8\u7528\u6237\u901a\u8fc7\u4fee\u6539\u8fd9\u4e2a\u53c2\u6570\uff0c\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\uff0c\u9632\u6b62 map \u6570\u636e\u7ed3\u6784\u4e0e\u5177\u4f53\u7684\u6bd4\u8f83\u65b9\u6cd5\u8026\u5408\u3002 \u7531\u4e8e\u9ed8\u8ba4\u7684 Cmp \u662f less \uff0c\u8c03\u7528 Cmp()(x, y) \u5c31\u76f8\u5f53\u4e8e x < y \uff0c\u7531\u6b64\u5b9e\u73b0\u4ece\u5c0f\u5230\u5927\u6392\u5e8f\u3002 \u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u4fee\u6539\u8fd9\u4e00\u9ed8\u8ba4\u884c\u4e3a\u3002","title":"\u81ea\u5b9a\u4e49\u6392\u5e8f\u65b9\u5f0f"},{"location":"stl_map/#_51","text":"\u4e00\u4e2a\u7c7b\u578b\u8981\u60f3\u4f5c\u4e3a map \u7684\u952e\uff0c\u53ea\u9700\u8981\u4ed6\u652f\u6301 < \u8fd0\u7b97\u7b26\u5373\u53ef\uff0c\u4e0d\u5fc5\u5b9a\u4e49\u5176\u4ed6 > \u3001 == \u8fd0\u7b97\u7b26\u3002 \u5f53 map \u9700\u8981\u5224\u65ad\u4e24\u4e2a\u952e\u662f\u5426\u76f8\u7b49\u65f6 x == y \uff0c\u4f1a\u7528 !(x < y) && !(y < x) \u6765\u7b49\u4ef7\u5730\u8ba1\u7b97\u3002 string, string_view, int, float, void *, shared_ptr, pair, tuple, array\u2026 \u8fd9\u4e9b\u7c7b\u578b\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u90fd\u53ef\u4ee5\u4f5c\u4e3a map \u7684\u952e\u3002","title":"\u53ea\u9700\u8981\u5c0f\u4e8e\u53f7"},{"location":"stl_map/#_52","text":"\u5982\u679c\u4f60\u5199\u4e86\u4e2a\u81ea\u5b9a\u4e49\u7c7b Student\uff0c\u8981\u8ba9\u4ed6\u4f5c\u4e3a map \u7684\u952e\u7c7b\u578b\uff0c\u6709\u4e09\u79cd\u65b9\u6cd5\uff1a \u4e00\u3001\u5728 Student \u7c7b\u4e2d\u6dfb\u52a0 operator< struct Student { string name; int id; string sex; bool operator<(Student const &that) const { return x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))); // \u7b49\u4ef7\u4e8e\uff1a return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); // tuple \u5b9e\u73b0\u4e86\u6b63\u786e\u7684 operator< \u8fd0\u7b97\u7b26 } }; map stutab; \u4e8c\u3001\u7279\u5316 less \uff0c\u6dfb\u52a0 operator() struct Student { string name; int id; string sex; }; template <> struct std::less { // \u7528\u6237\u53ef\u4ee5\u7279\u5316\u6807\u51c6\u5e93\u4e2d\u7684 trait bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u5982\u679c map \u5916\u9762\u8981\u7528\u7528\u5230\u8fd9\u4e2a\u7c7b\u7684\u5927\u5c0f\u6bd4\u8f83\uff0c\u4e5f\u53ea\u80fd\u7528 less()(stu1, stu2) \u4ee3\u66ff stu1 < stu2 \u3002 \u4e09\u3001\u91cd\u65b0\u81ea\u5b9a\u4e49\u4e00\u4e2a\u4eff\u51fd\u6570\u7c7b LessStudent \uff0c\u6dfb\u52a0 operator() \uff0c\u7136\u540e\u628a\u8fd9\u4e2a LessStudent \u4f5c\u4e3a map \u7684\u6bd4\u8f83\u5668\u4f20\u5165\u6a21\u677f struct Student { string name; int id; string sex; }; struct LessStudent { bool operator()(Student const &x, Student const &y) const { return std::tie(x.name, x.id, y.sex) < std::tie(x.name, x.id, y.sex); } }; map stutab; \u7f3a\u70b9\uff1a\u4ee5\u540e\u6bcf\u6b21\u521b\u5efa\u65b0\u7684 map \u65f6\uff0c\u90fd\u9700\u8981\u52a0\u4e00\u4e2a LessStudent \u53c2\u6570\u3002","title":"\u81ea\u5b9a\u4e49\u5c0f\u4e8e\u53f7\u7684\u4e09\u79cd\u65b9\u5f0f"},{"location":"stl_map/#_53","text":"\u5982\u679c\u5e0c\u671b map \u5728\u67e5\u627e\u65f6\u53ea\u6839\u636e\u5b66\u751f\u59d3\u540d\u7d22\u5f15\uff0c\u5219\u53ea\u9700\u8981\u6539\u4e00\u4e0b\u6bd4\u8f83\u5668\u7684\u5b9e\u73b0\uff0c\u8ba9\u4ed6\u53ea\u6bd4\u8f83\u59d3\u540d\u5b57\u6bb5\u5373\u53ef\u3002 struct LessStudent { bool operator()(Student const &x, Student const &y) const { return x.name < y.name; } }; \u4e0a\u9762\u8fd9\u6837\u7684\u6bd4\u8f83\u5668\uff0cmap \u4f1a\u8ba4\u4e3a\u59d3\u540d name \u76f8\u540c\u7684 Student \u5c31\u662f\u76f8\u7b49\u7684\uff0c\u5e76\u53bb\u91cd\u3002\u5373\u4f7f id \u548c sex \u4e0d\u540c\uff0c\u53ea\u8981\u540d\u5b57\u76f8\u7b49\u5c31\u4f1a\u89c6\u4e3a\u91cd\u590d\uff0c\u5229\u7528\u8fd9\u4e00\u70b9\u53ef\u4ee5\u5b9e\u73b0\u9488\u5bf9\u7279\u5b9a\u5b57\u6bb5\u7684\u53bb\u91cd\u3002 \u7ed3\u8bba\uff1amap \u7684\u6392\u5e8f\u548c\u53bb\u91cd\uff0c\u90fd\u53d6\u51b3\u4e8e\u4e8e\u4f60\u7684\u6bd4\u8f83\u5668\u5982\u4f55\u5b9e\u73b0\uff01\u6bd4\u8f83\u5668\u91cc\u6ca1\u6bd4\u8f83\u7684\u5b57\u6bb5\uff0c\u5c31\u4f1a\u88ab\u5ffd\u7565\u800c\u4e0d\u53c2\u4e0e\u6392\u5e8f\u3001\u7d22\u5f15\u3001\u548c\u53bb\u91cd\u3002","title":"\u81ea\u5b9a\u4e49\u6309\u54ea\u4e2a\u5b57\u6bb5\u6765\u7d22\u5f15"},{"location":"stl_map/#c20_1","text":"\u56db\uff08\u540c\u4e00\uff09\u3001\u5229\u7528 C++20 \u65b0\u7279\u6027\uff0c\u4e09\u8def\u6bd4\u8f83\u8fd0\u7b97\u7b26 <=> \uff1a\u5982\u679c\u81ea\u5b9a\u4e49\u7c7b\u7684\u6bcf\u4e2a\u6210\u5458\u90fd\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u53ef\u4ee5\u628a operator<=> \u51fd\u6570\u58f0\u660e\u4e3a default \uff0c\u7136\u540e\u7f16\u8bd1\u5668\u4f1a\u81ea\u52a8\u6dfb\u52a0\u81ea\u5b9a\u4e49\u7c7b\u7684\u6240\u6709\u6bd4\u8f83\u8fd0\u7b97\u7b26\u3002 struct Student { string name; int id; string sex; auto operator<=>(Student const &) const = default; }; \u6b64\u65f6\u9ed8\u8ba4\u7684 operator< \u5b9e\u73b0\u7b49\u4ef7\u4e8e x.name < y.name || (x.name == y.name && (x.id < y.id || (x.id == y.id && x.sex < y.sex))) \u3002 <=> \u7684\u8fd4\u56de\u7c7b\u578b\u662f std::strong_ordering \uff0c\u8fd9\u662f\u4e00\u79cd\u6709\u4e09\u79cd\u53d6\u503c\u7684\u5f3a\u679a\u4e3e\u7c7b\u578b <=> \u5bf9\u5e94\u7684\u4eff\u51fd\u6570\u4e3a std::compare_three_way","title":"C++20 \u4e09\u8def\u8fd0\u7b97\u7b26 <=>"},{"location":"stl_map/#_54","text":"libstdc++ \u5934\u6587\u4ef6\u4e2d\u7684 less \u548c greater \u5b9e\u73b0\u53c2\u8003\uff1a template struct less : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; template struct greater : public binary_function<_Tp, _Tp, bool> { _GLIBCXX14_CONSTEXPR bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; \u7c7b\u4f3c\u7684\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u8fd8\u6709\uff1a \u8fd0\u7b97\u7b26 \u4eff\u51fd\u6570\u7c7b x == y std::equal_to x != y std::not_equal_to x < y std::less x > y std::greater x <= y std::less_equal x >= y std::greater_equal x + y std::plus x - y std::minus x * y std::multiplies x / y std::divides x % y std::modulus -x std::negate \u4ed6\u4eec\u90fd\u5728 #include \u5934\u6587\u4ef6\u4e2d\u5b9a\u4e49\u3002","title":"\u4eff\u51fd\u6570\u8fd0\u7b97\u7b26\u5168\u5bb6\u6876"},{"location":"stl_map/#greater","text":"\u6848\u4f8b\uff1a\u4f7f\u7528 greater \u4eff\u51fd\u6570\uff0c\u8ba9 map \u53cd\u8fc7\u6765\u4ece\u5927\u5230\u5c0f\u6392\u5e8f\uff1a auto ilist = { {985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}, }; map m1 = ilist; // \u4ece\u5c0f\u5230\u5927\u6392\u5e8f map> m2 = ilist; // \u4ece\u5927\u5230\u5c0f\u6392\u5e8f print(m1); // {{211, \"\u811a\u8e22\"}, {985, \"\u62f3\u6253\"}} print(m2); // {{985, \"\u62f3\u6253\"}, {211, \"\u811a\u8e22\"}}","title":"greater \u5b9e\u73b0\u53cd\u5411\u6392\u5e8f"},{"location":"stl_map/#_55","text":"\u81ea\u5b9a\u4e49\u6bd4\u8f83\u4eff\u51fd\u6570\uff0c\u5b9e\u73b0\u65e0\u89c6\u952e\u5927\u5c0f\u5199\u7684 map \u5bb9\u5668\uff1a struct LessIgnoreCase { bool operator()(std::string const &lhs, std::string const &rhs) const { return std::lexicographical_compare // \u4f4d\u4e8e \u5934\u6587\u4ef6\uff0c\u548c std::string \u540c\u6b3e\u7684\u5b57\u5178\u5e8f\u6bd4\u8f83 ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); } }; int main() { map m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"STUdy\"}, \"cpp\"}, {{\"stUDy\"}, \"js\"}, }; print(m); print(\"fuck\u5bf9\u5e94\u7684\u503c\u4e3a:\", m.at(\"fuck\")); return 0; } {\"Fuck\": \"rust\", \"STUdy\": \"cpp\"} fuck\u5bf9\u5e94\u7684\u503c\u4e3a: \"rust\"","title":"\u5927\u5c0f\u5199\u4e0d\u654f\u611f\u7684\u5b57\u7b26\u4e32\u6bd4\u8f83\u5668"},{"location":"stl_map/#lambda","text":"C++11 \u7684 lambda \u8868\u8fbe\u5f0f\u4e5f\u662f\u4eff\u51fd\u6570\uff0c\u914d\u5408 decltype \u540e\u5c31\u53ef\u4ee5\u4f20\u5165 map \u4f5c\u4e3a\u6bd4\u8f83\u5668\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m({ {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }, cmp); print(m); auto val = m.at({\"fuck\"}); print(val); \u5199\u7684\u66f4\u6e05\u6670\u4e00\u70b9\uff1a auto cmp = [] (std::string const &lhs, std::string const &rhs) { return std::lexicographical_compare ( lhs.begin(), lhs.end() , rhs.begin(), rhs.end() , [] (char lhs, char rhs) { return std::toupper(lhs) < std::toupper(rhs); }); }; map m(cmp); m = { {{\"Fuck\"}, \"rust\"}, {{\"fUCK\"}, \"java\"}, {{\"Study\"}, \"cpp\"}, }; print(m); auto val = m.at({\"fuck\"}); print(val);","title":"\u4f20\u5165 lambda \u505a\u6bd4\u8f83\u5668"},{"location":"stl_map/#map_7","text":"\u521a\u521a\u7528\u5230\u7684\u4e24\u4e2a map \u6784\u9020\u51fd\u6570\uff1a template > class map { explicit map(Cmp cmp); map(initializer_list> ilist, Cmp cmp); }; \u57fa\u672c\u6bcf\u4e2a map \u7684\u6784\u9020\u51fd\u6570\u90fd\u6709\u4e00\u4e2a\u63d0\u4f9b\u989d\u5916 cmp \u53c2\u6570\u7684\u7248\u672c\uff0c\u7edf\u4e00\u90fd\u662f\u5728\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u540e\u9762\u8ffd\u52a0\u3002","title":"map \u6784\u9020\u51fd\u6570\u662f\u5982\u4f55\u4f20\u5165\u6bd4\u8f83\u5668\u7684"},{"location":"stl_map/#_56","text":"\u4f20\u5165\u7684\u4eff\u51fd\u6570 cmp \u751a\u81f3\u53ef\u4ee5\u6355\u83b7\u5176\u4ed6\u53d8\u91cf\uff0c\u8fd9\u79cd\u6355\u83b7\u4e86\u53d8\u91cf\u7684\u4eff\u51fd\u6570\u79f0\u4e4b\u4e3a\u6709\u72b6\u6001\u4eff\u51fd\u6570 - stateful functor\uff0c\u548c\u65e0\u72b6\u6001\u4eff\u51fd\u6570 - stateless functor \u76f8\u5bf9\uff1a vector arr = {1, 4, 2, 8, 5, 7}; auto cmp = [&] (int i, int j) { return arr[i] < arr[j]; }; map m(cmp); \u5229\u7528\u6709\u72b6\u6001\u4eff\u51fd\u6570\u53ef\u4ee5\u5b9e\u73b0 argsort \u7b49\u64cd\u4f5c\uff0c\u4f8b\u5982\u4e0a\u9762\u4ee3\u7801\u5c31\u662f\u6839\u636e\u5728 arr \u91cc\u5bf9\u5e94\u7d22\u5f15\u7684\u503c\u6765\u6392\u5e8f\u3002 \u7531\u4e8e map \u9700\u8981\u6bd4\u8f83\u4eff\u51fd\u6570\u4e3a\u7eaf\u51fd\u6570(pure function)\uff0c\u5728\u4e0a\u9762\u4f8b\u5b50\u4e2d\uff0c\u8bf7\u4fdd\u8bc1 map \u5b58\u5728\u671f\u95f4 arr \u7684\u5185\u5bb9\u4e0d\u53d1\u751f\u53d8\u5316\uff0c\u5426\u5219 map \u57fa\u4e8e\u6392\u5e8f\u7684\u4e8c\u5206\u67e5\u627e\u529f\u80fd\u4f1a\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\u3002 \u4f20\u5165\u6bd4\u8f83\u5668\u4eff\u51fd\u6570\u662f\u8bbe\u8ba1\u6a21\u5f0f\u4e2d\u5178\u578b\u7684\u7b56\u7565\u6a21\u5f0f\uff0c\u901a\u8fc7\u4f9d\u8d56\u6ce8\u5165\uff0c\u5141\u8bb8\u6211\u4eec\u63a7\u5236 map \u5185\u90e8\u7684\u884c\u4e3a\u3002","title":"\u6709\u72b6\u6001\uff08\u6355\u83b7\u53d8\u91cf\uff09\u7684\u6bd4\u8f83\u5668"},{"location":"stl_map/#function","text":"\u5982\u679c\u5acc decltype \u9ebb\u70e6\uff08\u96be\u4ee5\u5728\u5168\u5c40\u6216\u7c7b\u5185\u90e8\u7528\uff09\uff0cfunction \u5bb9\u5668\u4f5c\u4e3a\u6bd4\u8f83\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u7edf\u4e00\u4e86\uff1a auto cmp = [] (int i, int j) { return i < j; }; map> m; \u7a0d\u540e\u8fd8\u53ef\u4ee5\u901a\u8fc7 key_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u952e\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff0c\u8fd9\u4e2a\u5c31\u662f\u4f60\u521a\u521a\u4f20\u5165\u7684 cmp \u53c2\u6570\uff1a m.key_comp()(1, 2); // \u7b49\u4ef7\u4e8e cmp(1, 2) value_comp() \u83b7\u53d6\u5230\u7528\u4e8e\u5143\u7d20\uff08\u952e-\u503c\u5bf9\uff09\u6bd4\u8f83\u7684\u4eff\u51fd\u6570\uff08\u4ed6\u5e2e\u4f60\u9002\u914d\u53c2\u6570\u7c7b\u578b\u4e86\uff09\uff1a m.value_comp()({1, 0}, {2, 0}); // \u7b49\u4ef7\u4e8e cmp(1, 2)","title":"\u5efa\u8bae\u7528 function"},{"location":"stl_map/#map_8","text":"","title":"\u900f\u660e map"},{"location":"stl_map/#_57","text":"C++14 \u65b0\u589e\u4e86\u201c\u900f\u660e(transparent)\u201d\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u3002 \u5bf9\u4e8e less\u3001greater \u8fd9\u7c7b\u6807\u51c6\u5e93\u63d0\u4f9b\u7684\u4eff\u51fd\u6570\uff0c\u6307\u5b9a\u6a21\u677f\u53c2\u6570\u4e3a void \u5373\u53ef\u8ba9\u4e00\u4e2a\u8fd0\u7b97\u7b26\u4eff\u51fd\u6570\u53d8\u6210\u201c\u900f\u660e\u201d\u7684\u3002\u4f8b\u5982\u5bf9 less \u800c\u8a00\uff0c\u4ed6\u7684\u900f\u660e\u7248\u5c31\u662f less \u3002 C++14 \u4e4b\u524d\u7528\u7684\u90fd\u662f\u201c\u4e0d\u900f\u660e\u201d\u7248\u7684\u4eff\u51fd\u6570\uff0c\u5fc5\u987b\u6307\u5b9a\u4e00\u4e2a\u5177\u4f53\u7684\u7c7b\u578b\uff0c\u4f8b\u5982 less \u5c31\u53ea\u80fd\u7528\u4e8e int \u7c7b\u578b\u7684\u6bd4\u8f83\uff0c less \u5c31\u53ea\u80fd\u7528\u4e8e string \u7c7b\u578b\u7684\u6bd4\u8f83\u3002 \u65e0\u6cd5\u7528 less \u4eff\u51fd\u6570\u6bd4\u8f83 string \u7c7b\u578b\u3002 \u800c less \u662f\u901a\u7528\u7684\uff0c\u4ed6\u7684 operator() \u51fd\u6570\u662f\u6cdb\u578b\u7684\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\u3002 template <> struct less { // \u9488\u5bf9 void \u7684\u7279\u5316 // \u6807\u51c6\u59d4\u5458\u4f1a\u60f3\uff1a\u7531\u4e8e void \u7c7b\u578b\u4e0d\u53ef\u80fd\u6709 < \u8fd0\u7b97\u7b26\u7684\u9700\u6c42\uff0c\u6240\u4ee5\u4ed6\u4eec\u5e72\u8106\u62ff void \u4f5c\u4e3a\u900f\u660e\u7248\u7684\u6a21\u677f\u53c2\u6570\u201c\u5360\u4f4d\u7b26\u201d\u4e86 template constexpr decltype(auto) operator()(Tx &&x, Ty &&y) const { return forward(x) < forward(y); } struct is_transparent; // \u7a7a\u7c7b\uff0c\u4ec5\u4f9b SFINAE \u5143\u7f16\u7a0b\u65f6\u68c0\u6d4b\u4e00\u4e2a\u4eff\u51fd\u6570\u662f\u5426\u900f\u660e\u65f6\u4f7f\u7528 }; \u6211\u7684\u601d\u8003\uff1a\u4e0d\u900f\u660e\u7248\u7684 less \u6cdb\u578b\u4f53\u73b0\u5728\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u4e0a\uff0c\u800c\u900f\u660e\u7248\u7684\u4f53\u73b0\u5728\u4e86\u6210\u5458\u51fd\u6570 operator() \u7684\u6a21\u677f\u53c2\u6570\u4e0a\u3002 \u8fd9\u91cc\u7528 void \u7279\u5316\u53ea\u662f\u4e00\u4e2a\u5077\u61d2\uff0c void \u5e76\u6ca1\u6709\u4ec0\u4e48\u7279\u6b8a\u7684\uff0c\u5b9e\u9645\u4e0a\u5e94\u8be5\u5355\u72ec\u5b9a\u4e49\u4e00\u4e2a\u6ca1\u6709\u6a21\u677f\u7684 transparent_less \u7c7b\uff0c\u4f46\u4ed6\u4eec\u5c31\u662f\u61d2\u5f97\u5f15\u5165\u65b0\u6807\u8bc6\u7b26\u3002","title":"\u4ec0\u4e48\u662f\u900f\u660e\u4eff\u51fd\u6570"},{"location":"stl_map/#_58","text":"\u201c\u900f\u660e\u201d\u7248\u7684\u597d\u5904\u662f\u53ef\u4ee5\u540c\u4e00\u4e2a\u517c\u5bb9\u4efb\u610f\u7c7b\u578b\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a cmp \u5bf9\u8c61\u3002\u800c\u4e0d\u900f\u660e\u7248\u7684\u597d\u5904\u662f\u65b9\u4fbf\u7279\u5316 traits\uff0c\u4f46\u6bd5\u7adf < \u8fd0\u7b97\u7b26\u662f\u53ef\u4ee5\u7528\u6237\u81ea\u5b9a\u4e49(\u8fd0\u7b97\u7b26\u91cd\u8f7d)\u7684\uff0c\u6ca1\u5fc5\u8981\u7528 traits \u7279\u5316\uff0c\u6240\u4ee5\u4ed6\u4eec\u9010\u6b65\u53d1\u73b0\u900f\u660e\u7248\u9999\u4e86\uff0c\u8fd8\u80fd\u652f\u6301\u5de6\u53f3\u53c2\u6570\u4e3a\u4e0d\u540c\u7c7b\u578b\u3002 less cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true \u4f46\u4e5f\u8981\u7279\u522b\u6ce8\u610f\u4e0d\u80fd\u518d\u4f9d\u8d56\u53c2\u6570\u7c7b\u578b\u81ea\u52a8\u7684\u9690\u5f0f\u8f6c\u6362\u4e86\uff0c\u5fc5\u987b\u81f3\u5c11\u5199\u5b8c\u6574\u5176\u4e2d\u4e00\u4e2a string(\"hello\") \u624d\u80fd\u89e6\u53d1 string \u7684 operator< \u800c\u4e0d\u662f const char * \u7684\u6307\u9488\u6bd4\u5927\u5c0f\u3002\u5982\u679c\u53ea\u5199 cmp(\"cmake\", \"cppcon\") \u5219\u662f\u5728\u6bd4\u8f83\u6307\u9488\u7684\u5730\u5740\u5927\u5c0f\uff0c\u7ed3\u679c\u662f\u4e0d\u4e00\u5b9a\u7684\u3002 \u7531\u4e8e C++14 \u7684 less \u6a21\u677f\u53c2\u6570 T \u9ed8\u8ba4\u4e3a void\uff0c\u6240\u4ee5 less \u8fd8\u53ef\u4ee5\u7b80\u5199\u6210 less<> \u3002 less<> cmp; print(cmp(1, 2)); // 1 < 2: true print(cmp(5, 2)); // 5 < 2: false print(cmp(string(\"hello\"), \"world\")); // \"hello\" < \"world\": false print(cmp(string(\"cmake\"), \"cppcon\")); // \"cmake\" < \"cppcon\": true","title":"\u4e3a\u4ec0\u4e48\u9700\u8981\u900f\u660e\u4eff\u51fd\u6570"},{"location":"stl_map/#find_1","text":"\u666e\u901a find \u51fd\u6570\uff1a\u952e\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570 iterator find(K const &k); const_iterator find(K const &k) const; C++14 \u65b0\u589e\u6cdb\u578b\u7248\u7684 find \u51fd\u6570 1 \uff1a\u4efb\u610f\u7c7b\u578b\u4f5c\u4e3a\u53c2\u6570\uff0c\u53ea\u8981\u8be5\u7c7b\u578b\u652f\u6301\u4e0e\u548c\u952e\u6bd4\u5927\u5c0f\u3002 template iterator find(Kt &&k); template const_iterator find(Kt &&k) const; \u8fd9\u91cc\u7684 Kt \u662f\u6a21\u677f\u53c2\u6570\u7c7b\u578b\uff0c\u53ef\u4ee5\u63a5\u53d7\u4efb\u610f\u7c7b\u578b\uff0c\u6b64\u5904 && \u662f\u4e07\u80fd\u5f15\u7528\u4e0d\u662f\u53f3\u503c\u5f15\u7528\u3002 \u76f8\u540c\u70b9\uff1a\u627e\u5230\u4e86\u5c31\u8fd4\u56de\u4e00\u4e2a\u8fed\u4ee3\u5668\u6307\u5411\u4e0e\u8be5\u53c2\u6570\u76f8\u7b49\u7684\u5143\u7d20\uff0c\u5982\u679c\u627e\u4e0d\u5230\u8fd8\u662f\u8fd4\u56de end()\u3002 \u4e0d\u540c\u70b9\uff1a\u6cdb\u578b\u7248\u672c\u7684\u53c2\u6570\u7c7b\u578b Kt \u4e0d\u5fc5\u548c\u952e\u7c7b\u578b K \u4e00\u81f4\uff0c\u53ea\u8981 Kt \u548c K \u53ef\u4ee5\u6bd4\u8f83\u5927\u5c0f\uff08< \u8fd0\u7b97\u7b26\uff09\u5373\u53ef\u3002 \u4e0d\u4ec5","title":"\u6cdb\u578b\u7248\u7684 find \u51fd\u6570"},{"location":"stl_map/#find_2","text":"\u8981\u60f3\u7528\u6cdb\u578b\u7248\u7684 find \u51fd\u6570\u6709\u4e00\u4e2a\u6761\u4ef6\uff1a map \u7684\u6bd4\u8f83\u5668\u5fc5\u987b\u662f\u201c\u900f\u660e(transparent)\u201d\u7684\uff0c\u4e5f\u5c31\u662f less \u8fd9\u79cd\u3002\u5426\u5219\u6cdb\u578b\u7248\u7684 find(Kt &&) \u4e0d\u4f1a\u53c2\u4e0e\u91cd\u8f7d\uff0c\u4e5f\u5c31\u662f\u53ea\u80fd\u8c03\u7528\u4f20\u7edf\u7684 find(K const &) \u3002 \u4f46\u662f map \u9ed8\u8ba4\u7684\u6bd4\u8f83\u5668\u662f less \uff0c\u4ed6\u662f\u4e0d\u900f\u660e\u7684\uff0c\u6bd4\u8f83\u7684\u4e24\u8fb9\u5fc5\u987b\u90fd\u662f K \u7c7b\u578b\u3002\u5982\u679c\u5176\u4e2d\u4e00\u8fb9\u4e0d\u662f\u7684\u8bdd\uff0c\u5c31\u5f97\u5148\u9690\u5f0f\u8f6c\u6362\u4e3a K \u624d\u80fd\u7528\u3002 \u8fd9\u662f\u65e9\u671f C++98 \u8bbe\u8ba1\u7684\u5931\u8d25\uff0c\u5f53\u65f6\u4ed6\u4eec\u6ca1\u60f3\u5230 find \u8fd8\u53ef\u4ee5\u63a5\u53d7 string_view \u548c const char * \u8fd9\u7c7b\u53ef\u4ee5\u548c string \u6bd4\u8f83\uff0c\u4f46\u6784\u9020\u4f1a\u5ec9\u4ef7\u5f97\u591a\u7684\u5f31\u5f15\u7528\u7c7b\u578b\u3002 \u53ea\u597d\u540e\u6765\u5f15\u5165\u4e86\u900f\u660e\u6bd4\u8f83\u5668\u4f01\u56fe\u529b\u633d\u72c2\u6f9c\uff0c\u7136\u800c\u4e3a\u4e86\u5386\u53f2\u517c\u5bb9\uff0c map \u9ed8\u8ba4\u4ecd\u7136\u662f map> \u3002 \u5982\u679c\u6211\u4eec\u540c\u5b66\u7684\u7f16\u8bd1\u5668\u652f\u6301 C++14\uff0c\u5efa\u8bae\u5168\u90e8\u6539\u7528\u8fd9\u79cd\u5199\u6cd5 map> \uff0c\u4ece\u800c\u7528\u4e0a\u66f4\u9ad8\u6548\u7684 find\u3001at\u3001erase\u3001count\u3001contains \u7b49\u9700\u8981\u6309\u952e\u67e5\u627e\u5143\u7d20\u7684\u51fd\u6570\u3002","title":"\u6cdb\u578b find \u7684\u8981\u6c42\uff1a\u900f\u660e"},{"location":"stl_map/#_59","text":"\u9664\u975e\u4f20\u5165\u7684\u521a\u597d\u5c31\u662f\u4e00\u4e2a string \u7684 const \u5f15\u7528\uff0c\u5426\u5219\u5c31\u4f1a\u53d1\u751f\u9690\u5f0f\u6784\u9020 string \u7684\u64cd\u4f5c\u3002 \u5982\u679c\u4f20\u5165\u7684\u662f\u4e00\u4e2a string_view \u6216 const char * \uff0c\u90a3\u4e48\u9700\u8981\u4ece\u4ed6\u4eec\u6784\u9020\u51fa\u4e00\u4e2a string \uff0c\u7136\u540e\u624d\u80fd\u4f20\u5165\u4f20\u7edf\u7684 find(string const &) \u51fd\u6570\u3002\u800c string \u7684\u6784\u9020\u4f1a\u53d1\u751f\u62f7\u8d1d\uff0c\u4e14\u53ef\u80fd\u4ea7\u751f\u5185\u5b58\u5206\u914d\u3002 \u5bf9\u4e8e\u6bd4\u8f83\u5927\u7684\u5b57\u7b26\u4e32\u505a\u952e\u503c\uff0c\u6bcf\u6b21\u67e5\u627e\u90fd\u9700\u8981\u91cd\u65b0\u6784\u9020\u4e00\u4e2a string \u5bf9\u8c61\uff0c\u5f00\u9500\u4f1a\u6bd4\u8f83\u5927\u3002 map lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(string(\"a-very-very-very-very-long-key\")); // \u9690\u5f0f\u6784\u9020\u4e86\u4e00\u4e2a string\uff0c\u5bfc\u81f4\u6df1\u62f7\u8d1d\u4e86\u6574\u4e2a\u5b57\u7b26\u4e32\uff01 \u800c\u542f\u7528\u4e86\u900f\u660e\u6bd4\u8f83\u540e\uff0c\u5c31\u4e0d\u9700\u8981\u6bcf\u6b21\u90fd\u62f7\u8d1d\u6574\u4e2a\u5b57\u7b26\u4e32\u6765\u6784\u9020 string \u4e86\u3002\u56e0\u4e3a find\u3001at \u8fd9\u7c7b\u51fd\u6570\u4f1a\u542f\u7528\u4e00\u4e2a\u6cdb\u578b\u7684\u7248\u672c at(Kt &&) \uff0cKt \u53ef\u4ee5\u662f\u4efb\u4f55\u7c7b\u578b\uff0c\u53ea\u8981\u4ed6\u652f\u6301\u4e0e string \u6bd4\u8f83\u3002\u53ef\u4ee5\u662f const char * \uff0c string_view \u6216\u53e6\u4e00\u4e2a string \u3002 map> lut; lut.at(\"a-very-very-very-very-long-key\"); // \u7b49\u4ef7\u4e8e: lut.at(\"a-very-very-very-very-long-key\"); \u56e0\u4e3a\u4e0d\u7528\u62f7\u8d1d\u4e86\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u7279\u522b\u662f\u5bf9\u4e8e\u952e\u5b57\u7b26\u4e32\u975e\u5e38\u957f\u7684\u60c5\u51b5\u3002 at \u5185\u90e8\u4e5f\u4e0d\u4f1a\u6784\u9020\u4efb\u4f55\u65b0\u7684 string \uff0c\u4ed6\u4f1a\u62ff\u7740 const char * \u548c\u7ea2\u9ed1\u6811\u4e2d\u7684\u6bcf\u4e2a\u8282\u70b9\u8c03\u7528 == \u6bd4\u8f83\u3002 string == const char * \u662f\u5b89\u5168\u7684\uff0c\u4f1a\u6bd4\u8f83\u5b57\u7b26\u4e32\u7684\u5185\u5bb9\u800c\u4e0d\u662f\u5730\u5740\u3002","title":"\u5e94\u7528\uff1a\u5b57\u7b26\u4e32\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#_60","text":"\u67d0\u6709\u67d0\u4e9b\u7279\u6b8a\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u9700\u8981\u628a\u6307\u9488\uff0c\u751a\u81f3\u667a\u80fd\u6307\u9488\uff01\u653e\u8fdb map \u6216 set \u7684\u952e\u4e2d\uff0c\u7528\u4e8e\u5feb\u901f\u6309\u6307\u9488\u7684\u503c\u67e5\u627e\u5230\u5143\u7d20\u3002\uff08\u662f\u7684\u4f60\u6ca1\u542c\u9519\uff0c\u662f\u653e\u5728 \u952e\u7c7b\u578b \u91cc\uff01\uff09 \u8f76\u4e8b\uff1a\u628a\u6307\u9488\u653e\u5728\u952e\u91cc\u5e76\u4e0d\u7f55\u89c1\uff0c\u5e38\u89c1\u7684\u4e00\u4e2a\u7528\u6cd5\u662f set \u3002\u597d\u5904\u662f\u5f53 Node \u6790\u6784\u65f6\uff0c\u4ed6\u53ef\u4ee5\u76f4\u63a5\u8c03\u7528 set.erase(this) \u628a\u81ea\u5df1\u5254\u9664\u6389\u3002\u800c\u666e\u901a\u7684 set \u5c31\u5f88\u96be\u505a\u5230\u8fd9\u4e00\u70b9\u4e86\uff0c\u4f60\u65e0\u6cd5\u901a\u8fc7 Node \u7684 this \u6307\u9488\u83b7\u5f97\u4ed6\u5728 set \u4e2d\u7684\u8fed\u4ee3\u5668\uff0c\u4e5f\u65e0\u6cd5\u77e5\u9053\u81ea\u5df1\u4f4d\u4e8e\u54ea\u4e2a set \u4e2d\u3002\u4fb5\u5165\u5f0f\u7ea2\u9ed1\u6811\u5b8c\u7f8e\u89e3\u51b3\u4e86\u8fd9\u4e00\u75db\u70b9\uff0cLLVM \u548c Linux \u5185\u6838\u4e2d\u90fd\u5927\u91cf\u8fd0\u7528\u4e86\u4fb5\u5165\u5f0f\u94fe\u8868/LRU/\u7ea2\u9ed1\u6811\uff0c\u4ee5\u540e\u7684\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4e2d\u4f1a\u4e3a\u4f60\u8bb2\u89e3\u3002 map lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); \u5982\u679c\u662f\u667a\u80fd\u6307\u9488\uff0c\u5c31\u6bd4\u8f83\u56f0\u96be\u4e86\uff0c\u7279\u522b\u662f unique_ptr \u3002\u5982\u679c\u4f60\u5df2\u77e5\u4e00\u4e2a\u539f\u59cb\u6307\u9488\uff0c\u60f3\u8981\u5728 map \u4e2d\u67e5\u627e\u6307\u5411\u540c\u6837\u7684\u667a\u80fd\u6307\u9488\u952e\u3002 map, int> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // \u9519\u8bef\uff1a\u65e0\u6cd5\u4ece Node * \u9690\u5f0f\u6784\u9020 unique_ptr \u8fc7\u53bb\uff0c\u4eba\u4eec\u4e0d\u5f97\u4e0d\u7528\u4e00\u79cd\u79f0\u4e3a stale-ptr\uff08\u53d8\u8d28\u6307\u9488\uff09\u7684\u9ed1\u79d1\u6280\uff0c\u6765\u6784\u9020\u4e00\u4e2a\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u4f2a unique_ptr \u51fa\u6765\uff1a map, int> lut; Node *raw_ptr = get_some_ptr(); unique_ptr stale_ptr(raw_ptr); // \u4e00\u4e2a\u5e76\u4e0d\u638c\u63e1\u751f\u547d\u5468\u671f\u7684\u201c\u53d8\u8d28\u667a\u80fd\u6307\u9488\u201d lut.find(stale_ptr); // OK: \u5339\u914d\u5230 find(unique_ptr const &) \u91cd\u8f7d stale_ptr.release(); // \u5fc5\u987b\uff01\u5426\u5219\u4f1a\u51fa\u73b0\u53cc\u91cd\u91ca\u653e (double-free) \u9519\u8bef \u800c C++14 \u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u5b9a\u4e49\u4e00\u4e2a\u900f\u660e\u7684\u6bd4\u8f83\u51fd\u6570\uff0c\u652f\u6301 Node * \u4e0e unique_ptr \u4e92\u76f8\u6bd4\u8f83\u5373\u53ef\uff1a struct transparent_ptr_less { template bool operator()(T *const &p1, T const &p2) const { return p1 < p2; } template bool operator()(T *const &p1, unique_ptr const &p2) const { return p1 < p2.get(); } template bool operator()(unique_ptr const &p1, T *const &p2) const { return p1.get() < p2; } template bool operator()(unique_ptr const &p1, unique_ptr const &p2) const { return p1.get() < p2.get(); } using is_transparent = std::true_type; }; map, int, transparent_ptr_less> lut; Node *raw_ptr = get_some_ptr(); lut.find(raw_ptr); // OK: \u5339\u914d\u5230\u6cdb\u578b\u7684 find(Kt &&) \u91cd\u8f7d\uff0c\u5176\u4e2d Kt \u63a8\u5bfc\u4e3a Node *const &","title":"\u5e94\u7528\uff1a\u667a\u80fd\u6307\u9488\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#_61","text":"\u4ee5\u4e0b\u6458\u81ea cppreference \u4e0a\u6cdb\u578b find \u7684\u5b98\u65b9\u6848\u4f8b\uff1a struct FatKey { int x; int data[1000]; }; struct LightKey { int x; }; // Note: as detailed above, the container must use std::less<> (or other // transparent Comparator) to access these overloads. // This includes standard overloads, such as between std::string and std::string_view. bool operator<(const FatKey& fk, const LightKey& lk) { return fk.x < lk.x; } bool operator<(const LightKey& lk, const FatKey& fk) { return lk.x < fk.x; } bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.x < fk2.x; } int main() { // transparent comparison demo std::map> example = {{{1, {}}, 'a'}, {{2, {}}, 'b'}}; LightKey lk = {2}; if (auto search = example.find(lk); search != example.end()) std::cout << \"Found \" << search->first.x << \" \" << search->second << '\\n'; else std::cout << \"Not found\\n\"; } Found 2 b","title":"\u5e94\u7528\uff1a\u8d85\u5927\u5bf9\u8c61\u4e3a\u952e\u7684\u5b57\u5178"},{"location":"stl_map/#multimap","text":"\u5141\u8bb8\u91cd\u590d\u952e\u503c\u7684 multimap map \u4e2d\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e00\u4e2a\u503c\uff0c\u800c multimap \u4e00\u4e2a\u952e\u53ef\u4ee5\u5bf9\u5e94\u591a\u4e2a\u503c\u3002 map\uff1a\u6392\u5e8f + \u53bb\u91cd\uff1b multimap\uff1a\u53ea\u6392\u5e8f\uff0c\u4e0d\u53bb\u91cd\u3002 // map \u7684\u63d2\u5165\u51fd\u6570\uff1a pair insert(pair const &kv); pair insert(pair &&kv); // multimap \u7684\u63d2\u5165\u51fd\u6570\uff1a iterator insert(pair const &kv); iterator insert(pair &&kv); \u56e0\u4e3a multimap \u5141\u8bb8\u91cd\u590d\u952e\u503c\uff0c\u6240\u4ee5\u63d2\u5165\u603b\u662f\u6210\u529f\uff0c\u4e0e\u666e\u901a map \u76f8\u6bd4\u4e0d\u7528\u8fd4\u56de bool \u8868\u793a\u662f\u5426\u6210\u529f\u4e86\u3002","title":"\u795e\u5947\u7684 multimap"},{"location":"stl_map/#_62","text":"multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); print(tab); {\"cpp\": \"smart\", \"cpp\": \"fast\", \"java\": \"pig\", \"rust\": \"silly\", \"rust\": \"trash\", \"rust\": \"trash\", \"rust\": \"lazy\"} \u63d2\u5165\u8fdb multimap \u7684\u91cd\u590d\u952e\u4f1a\u7d27\u6328\u7740\uff0c\u4ed6\u4eec\u4e4b\u95f4\u7684\u987a\u5e8f\u53d6\u51b3\u4e8e\u63d2\u5165\u7684\u987a\u5e8f\u3002\u4f8b\u5982\u4e0a\u9762\u952e\u540c\u6837\u662f \u201ccpp\u201d \u7684\u4e24\u4e2a\u5143\u7d20\uff0c\u201dsmart\u201d \u5148\u4e8e \u201cfast\u201d \u63d2\u5165\uff0c\u6240\u4ee5 \u201csmart\u201d \u9760\u524d\u4e86\u3002","title":"\u5143\u7d20\u7684\u6392\u5217\u987a\u5e8f"},{"location":"stl_map/#_63","text":"multimap / multiset \u7684\u4f5c\u7528\u901a\u5e38\u5c31\u4e0d\u662f\u952e\u503c\u6620\u5c04\u4e86\uff0c\u800c\u662f\u5229\u7528\u7ea2\u9ed1\u6811\u4f1a\u4fdd\u6301\u5143\u7d20\u6709\u5e8f\u7684\u7279\u6027\uff08\u4efb\u4f55\u4e8c\u53c9\u641c\u7d22\u6811\u90fd\u8fd9\u6837\uff09\u5b9e\u73b0\u4e00\u8fb9\u63d2\u5165\u4e00\u8fb9\u52a8\u6001\u6392\u5e8f\u3002 \u4f20\u7edf\u6392\u5e8f\u65b9\u5f0f\uff1a std::vector arr; int i; while (cin >> i) { arr.push_back(i); } std::sort(arr.begin(), arr.end(), std::less()); multiset \u6392\u5e8f\u65b9\u5f0f\uff1a std::multiset tab; int i; while (cin >> i) { tab.insert(i); } // \u65e0\u9700\u518d\u6392\u5e8f\uff0ctab \u4e2d\u7684\u952e\u5df2\u7ecf\u662f\u6709\u5e8f\u7684\u4e86\uff01 // \u5982\u9700\u53d6\u51fa\u5230 vector: std::vector arr(tab.begin(), tab.end()); \u5229\u7528 multimap \u952e-\u503c\u5bf9\u7684\u7279\u70b9\uff0c\u8fd8\u80fd\u8f7b\u6613\u5b9e\u73b0\u53ea\u5bf9\u952e\u6392\u5e8f\uff0c\u503c\u7684\u90e8\u5206\u4e0d\u53c2\u4e0e\u6392\u5e8f\u7684\u6548\u679c\u3002 multimap \u6392\u5e8f\u7684\u597d\u5904\u662f\uff1a \u52a8\u6001\u6392\u5e8f\uff0c\u5728\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\u5c31\u4fdd\u6301\u6574\u4e2a\u7ea2\u9ed1\u6811\u7684\u6709\u5e8f\u6027\uff0c\u6700\u540e\u4efb\u4f55\u65e0\u9700\u989d\u5916\u64cd\u4f5c\u3002 \u5728\u4e00\u6b21\u6b21\u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6bcf\u65f6\u6bcf\u523b\u90fd\u662f\u6709\u5e8f\u7684\uff0c\u800c\u4e0d\u5fc5\u7b49\u5230\u6700\u540e\u624d\u53d8\u5f97\u6709\u5e8f\u3002 \u53ef\u4ee5\u968f\u65f6\u52a8\u6001\u5220\u9664\u4e00\u4e2a\u5143\u7d20\uff0c\u540c\u6837\u4e0d\u4f1a\u7834\u574f\u6709\u5e8f\u6027\u3002 \u8fd8\u5f88\u65b9\u4fbf\u968f\u65f6\u6309\u952e\u503c\u67e5\u627e\u5230\u548c\u6211\u76f8\u7b49\u7684\u5143\u7d20\u3002 \u5982\u679c\u8fd8\u989d\u5916\u9700\u8981\u53bb\u91cd\uff0c\u5219\u53ea\u9700\u6539\u7528\u666e\u901a map \u666e\u901a map \u8f7b\u677e\u5b9e\u73b0\u53bb\u91cd + \u52a8\u6001\u6392\u5e8f\uff0c\u5982\u4f55\u5904\u7f6e\u91cd\u590d\u7684\u952e\u968f\u4f60\u51b3\u5b9a\uff1a \u666e\u901a map \u7684 insert \u53ea\u63a5\u53d7\u7b2c\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002 \u666e\u901a map \u7684 insert_or_assign \u53ea\u4fdd\u7559\u6700\u540e\u4e00\u6b21\u51fa\u73b0\u7684\u952e-\u503c\u5bf9\u3002","title":"\u7528\u9014\uff1a\u52a8\u6001\u6392\u5e8f\uff01"},{"location":"stl_map/#_64","text":"\u56e0\u4e3a multimap \u4e2d\uff0c\u4e00\u4e2a\u952e\u4e0d\u518d\u5bf9\u4e8e\u5355\u4e2a\u503c\u4e86\uff1b\u6240\u4ee5 multimap \u6ca1\u6709 [] \u548c at \u4e86\uff0c\u4e5f\u6ca1\u6709 insert_or_assign \uff08\u53cd\u6b63 insert \u6c38\u8fdc\u4e0d\u4f1a\u53d1\u751f\u952e\u51b2\u7a81\uff01\uff09 pair equal_range(K const &k); template pair equal_range(Kt &&k); \u8981\u67e5\u8be2 multimap \u4e2d\u7684\u4e00\u4e2a\u952e\u5bf9\u5e94\u4e86\u54ea\u4e9b\u503c\uff0c\u53ef\u4ee5\u7528 equal_range \u83b7\u53d6\u4e00\u524d\u4e00\u540e\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4ed6\u4eec\u5f62\u6210\u4e00\u4e2a\u533a\u95f4\u3002\u8fd9\u4e2a\u533a\u95f4\u5185\u6240\u6709\u7684\u5143\u7d20\u90fd\u662f\u540c\u6837\u7684\u952e\u3002 multimap tab; tab.insert({\"rust\", \"silly\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"rust\", \"trash\"}); tab.insert({\"cpp\", \"smart\"}); tab.insert({\"rust\", \"lazy\"}); tab.insert({\"cpp\", \"fast\"}); tab.insert({\"java\", \"pig\"}); auto range = tab.equal_range(\"cpp\"); for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } cpp smart cpp fast equal_range \u8fd4\u56de\u4e24\u4e2a\u8fed\u4ee3\u5668\u76f8\u7b49\u65f6\uff08\u5373\u533a\u95f4\u5927\u5c0f\u4e3a 0\uff09\uff0c\u5c31\u4ee3\u8868\u627e\u4e0d\u5230\u8be5\u952e\u503c\u3002 auto range = tab.equal_range(\"html\"); if (range.first == range.second) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = range.first; it != range.second; ++it) { print(it->first, it->second); } } equal_range \u8fd4\u56de\u7684\u4e24\u4e2a\u8fed\u4ee3\u5668\uff0c\u4e5f\u53ef\u4ee5\u7528 lower_bound \u548c upper_bound \u5206\u522b\u83b7\u5f97\uff1a auto begin_it = tab.lower_bound(\"html\"); auto end_it = tab.upper_bound(\"html\"); if (begin_it == end_it) { print(\"\u627e\u4e0d\u5230\u8be5\u5143\u7d20\uff01\"); } else { for (auto it = begin_it; it != end_it; ++it) { print(it->first, it->second); } }","title":"\u67e5\u8be2\u67d0\u4e2a\u952e\u5bf9\u5e94\u7684\u591a\u4e2a\u503c"},{"location":"stl_map/#lowerupper_bound","text":"lower_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\u7b49\u4e8e\uff08>=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 upper_bound(key) \u5230 end() \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5927\u4e8e\uff08>\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 lower_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\uff08<\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 begin() \u5230 upper_bound(key) \u8fed\u4ee3\u5668\u4e4b\u95f4\u7684\u5143\u7d20\uff0c\u90fd\u662f\u5c0f\u4e8e\u7b49\u4e8e\uff08<=\uff09\u5f53\u524d key \u7684\u5143\u7d20\u3002 \u4f8b\u5982\u6211\u8981\u5bf9\u4e00\u7cfb\u5217\u5c0f\u5f6d\u53cb\u7684\u6210\u7ee9\u6570\u636e\u8fdb\u884c\u6392\u5e8f\uff0c\u8981\u6c42\u67e5\u51fa\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u6240\u6709\u540c\u5b66\uff0c\u53d1\u653e\u201c\u5c0f\u7ea2\u82b1\u201d\uff1a struct Student { string name; int score; }; vector students; \u5c31\u53ef\u4ee5\u628a\u6210\u7ee9 int \u4f5c\u4e3a\u952e\uff0c\u5b66\u751f\u540d\u5b57\u4f5c\u4e3a\u503c\uff0c\u63d2\u5165 multimap\u3002 \u63d2\u5165\u7684\u8fc7\u7a0b\u4e2d multimap \u5c31\u81ea\u52a8\u4e3a\u4f60\u52a8\u6001\u6392\u5e8f\u4e86\u3002 multimap sorted; for (auto const &stu: students) { sorted.insert({stu.score, stu.name}); } \u7136\u540e\uff0c\u8981\u627e\u51fa\u6240\u6709\u5927\u4e8e\u7b49\u4e8e 60 \u5206\u7684\u540c\u5b66\uff0c\u4e5f\u5c31\u662f lower_bound(60) \u5230 end() \u8fd9\u4e2a\u533a\u95f4\uff1a // where score >= 60 for (auto it = sorted.lower_bound(60); it != sorted.end(); ++it) { print(\"\u606d\u559c {} \u540c\u5b66\uff0c\u8003\u51fa\u4e86 {} \u5206\uff0c\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u7ea2\u82b1\", it->second, it->first); } \u627e\u51fa 30\uff08\u542b\uff09\u5230 60\uff08\u4e0d\u542b\uff09\u5206\u7684\u540c\u5b66\u4e5f\u5f88\u5bb9\u6613\uff1a // where 30 <= score and score < 60 for (auto it = sorted.upper_bound(30); it != sorted.lower_bound(60); ++it) { print(\"{} \u540c\u5b66\u8003\u51fa\u4e86 {} \u5206\uff0c\u4e0d\u8981\u7070\u5fc3\uff01\u5c0f\u5f6d\u8001\u5e08\u5956\u52b1\u4f60\u4e00\u6735\u5c0f\u9ec4\u82b1\uff0c\u8868\u793a\u9ec4\u724c\u8b66\u544a\", it->second, it->first); }","title":"lower/upper_bound \u5b9e\u73b0\u8303\u56f4\u67e5\u8be2"},{"location":"stl_map/#_65","text":"\u5c1d\u8bd5\u7528 multimap \u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5b66\u751f\u6210\u7ee9\u7ba1\u7406\u7cfb\u7edf\uff0c\u8981\u6c42\u5982\u4e0b\uff1a \u5b66\u751f\u4fe1\u606f\u5305\u62ec\u59d3\u540d\u548c\u6210\u7ee9\u3002 \u80fd\u591f\u52a8\u6001\u63d2\u5165\u548c\u5220\u9664\u5b66\u751f\u4fe1\u606f\uff0c\u59cb\u7ec8\u4fdd\u6301\u6309\u6210\u7ee9\u6392\u5e8f\u3002 \u80fd\u591f\u67e5\u8be2\u7ed9\u5b9a\u6210\u7ee9\u8303\u56f4\u5185\u7684\u6240\u6709\u5b66\u751f\u3002 \u5b9e\u9645\u4e0a\uff0c\u6570\u636e\u5e93\u5c31\u662f\u8fd9\u6837\u5b9e\u73b0\u7684\uff0c\u6211\u4eec\u7684 multimap \u53ea\u662f\u7b80\u5355\u5730\u5bf9\u6210\u7ee9\u8fd9\u4e00\u4e2a\u5b57\u6bb5\u6392\u5e8f\uff0c\u800c\u4e13\u4e1a\u7684\u5173\u7cfb\u6570\u636e\u5e93\u4f1a\u4e3a\u6bcf\u4e2a\u5b57\u6bb5\u90fd\u5efa\u7acb\u7d22\u5f15\uff0c\u5206\u522b\u6392\u5e8f\u540e\u5b58\u50a8\uff0c\u4ee5\u52a0\u901f\u67e5\u627e\u3002\u5b66\u6709\u4f59\u529b\u7684\u540c\u5b66\u53ef\u4ee5\u5c1d\u8bd5\u8ba9\u5b66\u751f\u4fe1\u606f\u5305\u542b\u59d3\u540d\u3001\u6210\u7ee9\u3001\u5e74\u9f84\u3001\u5b66\u53f7\uff0c\u7136\u540e\u5206\u522b\u6784\u5efa\u8fd9\u56db\u4e2a\u5b57\u6bb5\u7684\u7d22\u5f15\uff0c\u652f\u6301\u6307\u5b9a\u503c\u67e5\u627e\u548c\u8303\u56f4\u67e5\u627e\uff0c\u5176\u4e2d\u59d3\u540d\u548c\u5b66\u53f7\u8981\u6c42\u552f\u4e00\u6027\u3002\u63d0\u793a\uff1a\u7528\u4e4b\u524d\u63d0\u5230\u7684 vector + map \u7684\u65b9\u6cd5\u3002\u505a\u51fa\u6765\u4ee5\u540e\uff0c\u9762\u8bd5\u6570\u636e\u5e93\u65f6\u4f60\u5c31\u53ef\u4ee5\u79c0\u7406\u89e3\u4e86\u3002","title":"\u8bfe\u540e\u7ec3\u4e60"},{"location":"stl_map/#_66","text":"\u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m1 = move(m2) \u79fb\u52a8 O(1) O(1) m1 = m2 \u62f7\u8d1d O(N) O(N) swap(m1, m2) \u4ea4\u6362 O(1) O(1) m.clear() \u6e05\u7a7a O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert({key, val}) \u63d2\u5165\u952e\u503c\u5bf9 O(\\log N) O(\\log N) m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u51c6\u786e O(1) O(1) + m.insert(pos, {key, val}) \u5e26\u63d0\u793a\u7684\u63d2\u5165\uff0c\u5982\u679c\u4f4d\u7f6e\u63d0\u793a\u4e0d\u51c6\u786e O(\\log N) O(\\log N) m[key] = val \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert_or_assign(key, val) \u63d2\u5165\u6216\u8986\u76d6 O(\\log N) O(\\log N) m.insert({vals\u2026}) \u8bbe M \u4e3a\u5f85\u63d2\u5165\u5143\u7d20\uff08vals\uff09\u7684\u6570\u91cf O(M \\log N) O(M \\log N) map m = \u5982\u679c vals \u65e0\u5e8f O(N \\log N) O(N \\log N) map m = \u5982\u679c vals \u5df2\u4e8b\u5148\u4ece\u5c0f\u5230\u5927\u6392\u5217 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.at(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u503c\u7684\u5f15\u7528 O(\\log N) O(\\log N) m.find(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u67e5\u627e\u5143\u7d20\uff0c\u8fd4\u56de\u8fed\u4ee3\u5668 O(\\log N) O(\\log N) m.count(key) \u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u952e\u5143\u7d20\uff0c\u8fd4\u56de\u76f8\u540c\u952e\u7684\u5143\u7d20\u6570\u91cf\uff08\u53ea\u80fd\u4e3a 0 \u6216 1\uff09 O(\\log N) O(\\log N) m.equal_range(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u786e\u5b9a\u4e0a\u4e0b\u754c\uff0c\u8fd4\u56de\u533a\u95f4 O(\\log N) O(\\log N) m.size() map \u4e2d\u6240\u6709\u5143\u7d20\u7684\u6570\u91cf O(1) O(1) m.erase(key) \u6839\u636e\u6307\u5b9a\u7684\u952e\uff0c\u5220\u9664\u5143\u7d20 O(\\log N) O(\\log N) m.erase(it) \u6839\u636e\u627e\u5230\u7684\u8fed\u4ee3\u5668\uff0c\u5220\u9664\u5143\u7d20 O(1)+ O(1)+ m.erase(beg, end) \u6279\u91cf\u5220\u9664\u533a\u95f4\u5185\u7684\u5143\u7d20\uff0c\u8bbe\u8be5\u533a\u95f4\uff08beg \u548c end \u4e4b\u95f4\uff09\u6709 M \u4e2a\u5143\u7d20 O(M + \\log N) O(M + \\log N) erase_if(m, cond) \u6279\u91cf\u5220\u9664\u6240\u6709\u7b26\u5408\u6761\u4ef6\u7684\u5143\u7d20 O(N) O(N) \u51fd\u6570\u6216\u5199\u6cd5 \u89e3\u91ca\u8bf4\u660e \u65f6\u95f4\u590d\u6742\u5ea6 m.insert(node) O(\\log N) O(\\log N) node = m.extract(it) O(1)+ O(1)+ node = m.extract(key) O(\\log N) O(\\log N) m1.merge(m2) \u5408\u5e76\u4e24\u4e2a map\uff0c\u6e05\u7a7a m2\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N) m1.insert(m2.begin(), m2.end()) \u5408\u5e76\u4e24\u4e2a map\uff0cm2 \u4fdd\u6301\u4e0d\u53d8\uff0c\u7ed3\u679c\u5199\u5165 m1 O(N \\log N) O(N \\log N)","title":"\u65f6\u95f4\u590d\u6742\u5ea6\u603b\u7ed3\u8bf4\u660e"},{"location":"stl_map/#unordered_map","text":"C++11 \u65b0\u589e\uff1a\u57fa\u4e8e\u54c8\u5e0c (hash) \u7684\u6620\u5c04\u8868 unordered_map","title":"\u54c8\u5e0c\u8868 unordered_map"},{"location":"stl_map/#unordered_map-map","text":"\u4e4b\u524d\u63d0\u5230\uff0cmap \u5e95\u5c42\u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5927\u591a\u6570\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(\\log N) O(\\log N) \u7ea7\u522b\u7684\uff0c\u5176\u4e2d\u90e8\u5206\u6309\u8fed\u4ee3\u5668\u7684\u63d2\u5165\u548c\u5220\u9664\u7684\u590d\u6742\u5ea6\u53ef\u4ee5\u964d\u4f4e\u5230 O(1) O(1) \u3002 \u800c unordered_map \u5219\u662f\u57fa\u4e8e\u54c8\u5e0c\u8868\u7684\u66f4\u9ad8\u6548\u67e5\u627e\uff0c\u53ea\u9700 O(1) O(1) \u590d\u6742\u5ea6\uff01\u4ed6\u80fd\u5b9e\u73b0\u5982\u6b64\u9ad8\u6548\u67e5\u627e\u5f97\u76ca\u4e8e\u54c8\u5e0c\u51fd\u6570\u53ef\u4ee5\u628a\u6563\u5217\u552f\u4e00\u5b9a\u4f4d\u5230\u4e00\u4e2a\u6570\u7ec4\u7684\u4e0b\u6807\u4e2d\u53bb\uff0c\u800c\u6570\u7ec4\u7684\u7d22\u5f15\u662f O(1) O(1) \u7684\u3002\u7f3a\u70b9\u662f\u54c8\u5e0c\u503c\u53ef\u80fd\u4ea7\u751f\u51b2\u7a81\uff0c\u800c\u4e14\u54c8\u5e0c\u6570\u7ec4\u53ef\u80fd\u6709\u7a7a\u4f4d\u6ca1\u6709\u586b\u6ee1\uff0c\u6d6a\u8d39\u4e00\u90e8\u5206\u5185\u5b58\u7a7a\u95f4\u3002\u603b\u7684\u6765\u8bf4\u54c8\u5e0c\u8868\u5728\u5e73\u5747\u590d\u6742\u5ea6\u4e0a\uff08 O(1) O(1) \uff09\u6bd4\u7ea2\u9ed1\u6811\u8fd9\u7c7b\u57fa\u4e8e\u6811\u7684\u590d\u6742\u5ea6\uff08 O(\\log N) O(\\log N) \uff09\u66f4\u4f4e\uff0c\u867d\u7136\u56fa\u6709\u5ef6\u8fdf\u9ad8\uff0c\u5360\u7528\u7a7a\u95f4\u5927\uff0c\u8fd8\u5bb9\u6613\u88ab\u54c8\u5e0c\u51b2\u7a81\u653b\u51fb\u3002 \u54c8\u5e0c\u8868\u7ed3\u6784\u7b80\u5355\u65e0\u8111\uff0c\u5728\u5de8\u91cf\u7684\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u65f6\u4f1a\u53d1\u6325\u51fa\u660e\u663e\u7684\u6027\u80fd\u4f18\u52bf\uff0c\u5e38\u7528\u4e8e\u9700\u8981\u9ad8\u541e\u5410\u91cf\u4f46\u4e0d\u592a\u5728\u4e4e\u5ef6\u8fdf\u7684\u56fe\u5f62\u5b66\u5e94\u7528\u3002 \u800c\u5404\u79cd\u57fa\u4e8e\u6811\u7684\u6570\u636e\u7ed3\u6784\uff0c\u590d\u6742\u5ea6\u66f4\u52a0\u7a33\u5b9a\uff0c\u770b\u4f3c\u9002\u5408\u5c0f\u89c4\u6a21\u6570\u636e\uff0c\u4f46\u662f\u56e0\u4e3a\u4fdd\u6301\u6709\u5e8f\u7684\u7279\u6027\uff0c\u975e\u5e38\u9002\u5408\u6570\u636e\u5e93\u8fd9\u79cd\u9700\u8981\u8303\u56f4\u67e5\u8be2\u7684\u60c5\u51b5\uff0c\u4e14\u6709\u5e8f\u6027\u53cd\u800c\u6709\u5229\u4e8e\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u65e0\u5e8f\u7684\u54c8\u5e0c\u8868\u96be\u4ee5\u80dc\u4efb\u3002 \u6700\u8fd1\u65b0\u63d0\u51fa\u7684\u4e00\u79cd\u6570\u636e\u7ed3\u6784\u2014\u2014\u8df3\u8868\uff0c\u4e5f\u662f\u6709\u5e8f\u7684\uff0c\u4f46\u57fa\u4e8e\u94fe\u8868\uff0c\u66f4\u52a0\u9ad8\u6548\uff0c\u5728 Redis \u7b49\u8f6f\u4ef6\u4e2d\u90fd\u6709\u5e94\u7528\u3002\u522b\u62c5\u5fc3\uff0c\u5c0f\u5f6d\u8001\u5e08\u4e4b\u540e\u7684\u6570\u636e\u7ed3\u6784\u8bfe\u7a0b\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u5e76\u5e26\u4f60\u624b\u6413\u6240\u6709\u8fd9\u4e9b\uff01","title":"unordered_map \u4e0e map \u4e4b\u4e89\uff1a\u9002\u7528\u573a\u666f\u4e0d\u540c"},{"location":"stl_map/#unordered_map_1","text":"unordered_map \u5982\u4f55\u5feb\u901f\u68c0\u7d22\u6570\u636e\uff1f\u9ad8\u6548\u7684\u79d8\u8bc0\u5728\u4e8e unordered_map \u5185\u90e8\u662f\u4e00\u4e2a\u6570\u7ec4\uff0c\u4e00\u4e2a\u7531\u8bb8\u591a\u201c\u6876\u201d\u7ec4\u6210\u7684\u6570\u7ec4\u3002\u63d2\u5165\u65f6\u628a\u952e\u503c\u5bf9\u5b58\u5230\u952e\u7684 hash \u5bf9\u5e94\u7f16\u53f7\u7684\u6876\u53bb\uff0c\u67e5\u8be2\u65f6\u5c31\u6839\u636e hash \u53bb\u7ebf\u6027\u5730\u67e5\u627e\u6876\uff08\u8fd9\u4e00\u64cd\u4f5c\u662f O(1) O(1) \u7684\uff09\u3002 \u4f8b\u5982\u952e\u4e3a \u201chello\u201d\uff0c\u5047\u8bbe\u7b97\u51fa\u4ed6\u7684 hash \u4e3a 42\u3002\u800c\u5f53\u524d\u6876\u7684\u6570\u91cf\u662f 32 \u4e2a\uff0c\u5219\u4f1a\u628a \u201chello\u201d \u5b58\u5230 42 % 32 = 10 \u53f7\u6876\u53bb\u3002\u67e5\u8be2\u65f6\uff0c\u540c\u6837\u8ba1\u7b97\u51fa hash(\u201chello\u201d) % 32 = 10 \u53f7\u6876\uff0c\u7136\u540e\u5c31\u53ef\u4ee5\u4ece 10 \u53f7\u6876\u53d6\u51fa \u201chello\u201d \u5bf9\u5e94\u7684\u6570\u636e\u4e86\u3002 template class unordered_map { array, 32> buckets; void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97\u51fa\u6765\u7684 hash \u53ef\u80fd\u5f88\u5927\uff0c\u53d6\u6a21\u53ef\u4ee5\u9632\u6b62 h >= buckets.size() buckets[h] = kv; } V &at(K k) { size_t h = hash(k) % buckets.size(); auto &kv = buckets[h]; if (k != kv.first) throw out_of_range{}; return kv.second; } };","title":"\u539f\u7406\uff1aunordered_map \u4e2d\u7684\u201c\u6876\u201d"},{"location":"stl_map/#hash-collision","text":"\u4f46\u662f\u8fd9\u91cc\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u4e24\u4e2a\u4e0d\u540c\u7684\u5b57\u7b26\u4e32\uff0c\u521a\u597d hash \u4ee5\u540e\u7684\u6a21\u76f8\u540c\u600e\u4e48\u529e\uff1f\u8fd9\u79cd\u73b0\u8c61\u79f0\u4e3a hash \u51b2\u7a81\u3002 C++ \u6807\u51c6\u5e93\u7684\u89e3\u51b3\u65b9\u6848\u662f\u91c7\u7528\u94fe\u8868\u6cd5\uff1a\u4e00\u4e2a\u6876\u4e0d\u662f\u5355\u72ec\u7684\u4e00\u4e2a K-V \u5bf9\uff0c\u800c\u662f\u6570\u4e2a K-V \u5bf9\u7ec4\u6210\u7684\u5355\u94fe\u8868\uff08forward_list\uff09\u3002\u4e00\u4e2a\u6876\u4e0d\u662f\u53ea\u5b58\u50a8\u4e00\u4e2a\u6570\u636e\uff0c\u800c\u662f\u53ef\u4ee5\u5b58\u50a8\u4efb\u610f\u591a\u4e2a\u6570\u636e\uff080\u5230\u221e\u4e2a\uff09\u3002 \u63d2\u5165\u65f6\uff0c\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5e76\u5f80\u94fe\u8868\u7684\u5934\u90e8\u63d2\u5165\u4e00\u4e2a\u65b0\u7684 K-V \u5bf9\u3002\u67e5\u627e\u65f6\uff0c\u5148\u627e\u5230\u5bf9\u5e94\u7684\u6876\uff0c\u5728\u8fd9\u4e2a\u6876\u91cc\u7684\u94fe\u8868\u91cc\u987a\u5e8f\u904d\u5386\u67e5\u627e\uff0c\u7531\u4e8e\u7b2c\u4e00\u6b65\u7684\u6876\u67e5\u627e\u662f O(1) O(1) \u7684\uff0c\u867d\u7136\u6700\u540e\u8fd8\u662f\u94fe\u8868\u66b4\u529b\u67e5\u627e\uff0c\u4f46\u662f\u5df2\u7ecf\u88ab\u6876\u5206\u644a\u4e86\u4e00\u4e2a\u7ef4\u5ea6\uff0c\u56e0\u6b64\u67e5\u627e\u7684\u5e73\u5747\u590d\u6742\u5ea6\u8fd8\u662f O(1)+ O(1)+ \u7684\u3002 void insert(pair kv) { size_t h = hash(kv.first) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 buckets[h].push_front(kv); // \u5355\u94fe\u8868\u7684\u5934\u63d2\uff0c\u662f\u6700\u9ad8\u6548\u7684 } V &at(K k) { size_t h = hash(k) % buckets.size(); // \u8ba1\u7b97 hash \u7684\u6a21\uff08\u6240\u5728\u6876\u7684\u7f16\u53f7\uff09 for (auto &kv: buckets[h]) { if (k == kv.first) // \u53ef\u80fd\u6709\u591a\u4e2a\u4e0d\u540c\u7684\u952e\u521a\u597d\u6709\u76f8\u540c\u7684 hash \u6a21\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5224\u65ad\u952e\u786e\u5b9e\u76f8\u7b49\u624d\u80fd\u8fd4\u56de return kv.second; } throw out_of_range{}; } \u8fd9\u91cc\u8fd8\u662f\u6709\u4e00\u4e2a\u95ee\u9898\uff0chash \u51b2\u7a81\u65f6\uff0c\u5bf9\u94fe\u8868\u7684\u66b4\u529b\u904d\u5386\u67e5\u627e\u590d\u6742\u5ea6\u662f O(N) O(N) \u7684\uff0c\u968f\u7740\u8d8a\u6765\u8d8a\u591a\u7684\u5143\u7d20\u88ab\u63d2\u5165\u8fdb\u6765\uff0c32 \u4e2a\u6876\u5c06\u4f1a\u62e5\u6324\u4e0d\u582a\u3002\u5047\u8bbe\u6709 n \u4e2a\u5143\u7d20\uff0c\u5219\u5e73\u5747\u6bcf\u4e2a\u6876\u90fd\u4f1a\u6709 n / 32 \u4e2a\u5143\u7d20\uff0c\u9700\u8981 n / 32 \u6b21\u904d\u5386\u3002\u6240\u4ee5\u5143\u7d20\u6570\u91cf\u5145\u5206\u5927\u65f6 unordered_map \u53c8\u4f1a\u9000\u5316\u6210\u66b4\u529b\u904d\u5386\u7684 O(N) O(N) \u590d\u6742\u5ea6\uff0c\u6ee1\u8db3\u4e0d\u4e86\u6211\u4eec\u7528\u4ed6\u52a0\u901f\u67e5\u627e\u7684\u76ee\u7684\u3002 \u6876\u7684\u6570\u91cf\u76f8\u6bd4\u5143\u7d20\u7684\u6570\u91cf\u8d8a\u662f\u4e0d\u8db3\uff0c\u8d8a\u662f\u62e5\u6324\uff0c\u8d8a\u662f\u5bb9\u6613\u9000\u5316\u6210\u94fe\u8868\u3002 \u56e0\u6b64 C++ \u6807\u51c6\u5e93\u89c4\u5b9a\uff0c\u63d2\u5165\u65f6\uff0c\u5f53\u68c0\u6d4b\u5230\u5e73\u5747\u6bcf\u4e2a\u6876\u91cc\u90fd\u6709 1 \u4e2a\u5143\u7d20\u65f6\uff0c\u4e5f\u5c31\u662f\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u6570\u91cf\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\uff0c\u4e00\u6b21\u6027\u8ba9\u6876\u7684\u6570\u91cf\u6269\u5145 2 \u500d\uff0c\u5e76\u91cd\u65b0\u8ba1\u7b97\u6bcf\u4e2a\u5143\u7d20\u7684 hash \u6a21\uff08\u6876\u7f16\u53f7\uff09\u5168\u90e8\u91cd\u65b0\u63d2\u5165\u4e00\u904d\u3002 \u5143\u7d20\u6570\u91cf\u9664\u4ee5\u6876\u7684\u6570\u91cf\u88ab\u79f0\u4e3a\u201c\u8d1f\u8f7d\u7387\uff08load factor\uff09\uff0c\u5bf9\u4e8e\u94fe\u8868\u6cd5\u7684\u54c8\u5e0c\u8868 unordered_map \u6765\u8bf4\uff0c\u8d1f\u8f7d\u7387\u53ef\u4ee5\u9ad8\u4e8e 1\uff1b\u5bf9\u4e8e\u7ebf\u6027\u5730\u5740\u6cd5\u7684 flat_hash_map \u5219\u6700\u9ad8\u4e3a 1\u3002C++ \u6807\u51c6\u5e93\u901a\u5e38\u7684 unordered_map \u5b9e\u73b0\u4e2d\uff0c\u8d1f\u8f7d\u7387\u9ad8\u4e8e 1 \u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u81ea\u52a8\u6269\u5bb9\u3002\u53ef\u4ee5\u901a\u8fc7 .load_factor() \u51fd\u6570\u67e5\u8be2\u4e00\u4e2a unordered_map \u7684\u8d1f\u8f7d\u7387\u3002 template class unordered_map { vector>> buckets; // \u56e0\u4e3a\u9700\u8981\u52a8\u6001\u6269\u5bb9\uff0c\u6876\u6570\u7ec4\u53d8\u6210\u4e86\u52a8\u6001\u6570\u7ec4 vector size_t size = 0; // \u8bb0\u5f55\u5f53\u524d\u5bb9\u5668\u5171\u6709\u591a\u5c11\u4e2a\u5143\u7d20 void insert(pair kv) { if (size + 1 > buckets.size()) reserve(n); // \u5982\u679c\u63d2\u5165\u540e\u7684\u5143\u7d20\u6570\u91cf\u5927\u4e8e\u6876\u7684\u5bb9\u91cf\uff0c\u5219\u6269\u5bb9 size_t h = hash(kv.first) % buckets.size(); buckets[h].push_front(kv); size++; // insert \u65f6 size \u81ea\u52a8\u52a0 1\uff0cerase \u65f6\u4e5f\u8981\u8bb0\u5f97\u51cf 1 } void reserve(size_t n) { if (n <= buckets.size()) return; // \u5982\u679c\u8981\u6c42\u7684\u5927\u5c0f\u5df2\u7ecf\u6ee1\u8db3\uff0c\u4e0d\u9700\u8981\u6269\u5bb9 buckets.resize(max(n, buckets.size() * 2)); // \u628a\u6876\u6570\u7ec4\u81f3\u5c11\u6269\u5927 2 \u500d\uff08\u907f\u514d\u91cd\u590d\u6269\u5bb9\uff09\uff0c\u81f3\u591a\u6269\u5230 n \u6b64\u5904\u7701\u7565 rehash \u7684\u5177\u4f53\u5b9e\u73b0 // \u6876\u7684\u6570\u91cf\u53d1\u751f\u53d8\u5316\u4e86\uff0c\u9700\u8981\u91cd\u65b0\u8ba1\u7b97\u4e00\u904d\u6240\u6709\u5143\u7d20 hash \u7684\u6a21\uff0c\u5e76\u91cd\u65b0\u63d2\u5165 } }; \u6bcf\u4e2a key \u6240\u5728\u7684\u6876\u7f16\u53f7\u8ba1\u7b97\u516c\u5f0f\uff1abucket_index(key) = hash(key) % bucket_count() \u8fd8\u662f\u5b58\u5728\u95ee\u9898\uff0c\u521a\u521a\u7684 insert \u6839\u672c\u6ca1\u6709\u68c0\u6d4b\u8981\u63d2\u5165\u7684\u952e\u662f\u5426\u5df2\u7ecf\u5b58\u5728\u4e86\u3002\u5982\u679c\u5df2\u7ecf\u5b58\u5728\u8fd8\u63d2\u5165\uff0c\u90a3\u5c31\u53d8\u6210 unordered_multimap \u4e86\uff01\u6211\u4eec\u662f\u666e\u901a\u7684\u9700\u8981\u53bb\u91cd\u7684 unordered_map\uff0c\u6240\u4ee5\u63d2\u5165\u65f6\u5148\u9700\u8981\u904d\u5386\u4e0b\u94fe\u8868\u68c0\u6d4b\u4e00\u4e0b\u3002 template class unordered_map { vector>> buckets; size_t size = 0; struct iterator { explicit iterator(pair &kv) { /* ... */ } // ... }; pair insert(pair kv) { if (size + 1 > buckets.size()) reserve(size + 1); size_t h = hash(kv.first) % buckets.size(); for (auto &kv2: buckets[h]) { if (kv.first == kv2.first) // \u68c0\u6d4b\u662f\u5426\u53d1\u751f\u4e86\u51b2\u7a81 return {iterator(kv2), false}; // \u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6307\u5411\u5df2\u5b58\u5728\u7684\u952e\u7684\u8fed\u4ee3\u5668 } buckets[h].push_front(kv); size++; return {iterator(buckets.front()), true}; // \u6ca1\u53d1\u751f\u51b2\u7a81\u5219\u8fd4\u56de\u6210\u529f\u63d2\u5165\u5143\u7d20\u7684\u8fed\u4ee3\u5668 } };","title":"\u54c8\u5e0c\u51b2\u7a81 (hash-collision)"},{"location":"stl_map/#unordered_map-map_1","text":"\u7528\u6cd5\u4e0a\uff0cunordered_map \u57fa\u672c\u4e0e map \u76f8\u540c\uff0c\u4ee5\u4e0b\u7740\u91cd\u4ecb\u7ecd\u4ed6\u4eec\u7684\u4e0d\u540c\u70b9\u3002","title":"unordered_map \u4e0e map \u7684\u5f02\u540c"},{"location":"stl_map/#1_1","text":"map \u57fa\u4e8e\u7ea2\u9ed1\u6811\uff0c\u5143\u7d20\u4ece\u5c0f\u5230\u5927\u987a\u5e8f\u6392\u5217\uff0c\u904d\u5386\u65f6\u4e5f\u662f\u4ece\u5c0f\u5230\u5927\u7684\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u6bd4\u5927\u5c0f\uff08std::less \u6216 <\uff09\u3002 unordered_map \u57fa\u4e8e\u54c8\u5e0c\u6563\u5217\u8868\uff0c\u91cc\u9762\u5143\u7d20\u987a\u5e8f\u968f\u673a\uff0c\u952e\u7c7b\u578b\u9700\u8981\u652f\u6301\u54c8\u5e0c\u503c\u8ba1\u7b97\uff08std::hash\uff09\u548c\u5224\u65ad\u76f8\u7b49\uff08std::equal_to \u6216 ==\uff09\u3002 map \u4e2d\u7684\u5143\u7d20\u59cb\u7ec8\u4fdd\u6301\u6709\u5e8f\uff0cunordered_map \u91cc\u9762\u7684\u5143\u7d20\u662f\u968f\u673a\u7684\u3002 \u8fd9\u4e5f\u610f\u5473\u7740 std::set_union \u8fd9\u7c7b\u8981\u6c42\u8f93\u5165\u533a\u95f4\u6709\u5e8f\u7684 algorithm \u51fd\u6570\u65e0\u6cd5\u9002\u7528\u4e8e unordered_map/set\u3002","title":"\u533a\u522b 1\uff1a\u6709\u5e8f\u6027"},{"location":"stl_map/#hash-equal_to","text":"map \u53ea\u9700\u8981 K \u7c7b\u578b\u652f\u6301\u4e00\u4e2a less \u5c31\u80fd\u5de5\u4f5c\u3002 \u800c unordered_map \u9700\u8981 K \u652f\u6301\u7684 trait \u6709\u4e24\u4e2a\uff1ahash \u548c equal_to\u3002 unordered_map \u7684\u5b8c\u6574\u5f62\u6001\u662f\uff1a unordered_map, equal_to, allocator>> \u5176\u4e2d allocator \u6211\u4eec\u7167\u4f8b\u5148\u8df3\u8fc7\u4e0d\u8bb2\uff0c\u4e4b\u540e\u5206\u914d\u5668\u4e13\u9898\u8bfe\u4e2d\u4f1a\u4ecb\u7ecd\u3002 hash \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u6c42\u952e\u7684\u54c8\u5e0c\u503c\uff1fhash \u4eff\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a K \u7c7b\u578b\u7684\u952e\uff0c\u8fd4\u56de\u4e00\u4e2a size_t\uff08\u5728 64 \u4f4d\u7cfb\u7edf\u4e0a\u662f\u4e2a\u65e0\u7b26\u53f7 64 \u4f4d\u6574\u6570\uff0c\u8868\u793a\u54c8\u5e0c\u503c\uff09\u3002 equal_to \u8bf4\u7684\u662f\uff0c\u5982\u4f55\u5224\u65ad\u4e24\u4e2a\u952e\u76f8\u7b49\uff1f\u5982\u679c\u4e24\u4e2a\u952e\u5b8c\u5168\u76f8\u7b49\uff0c\u4ed6\u4f1a\u8fd4\u56de true\u3002 \u8fd9\u91cc\u5bf9 hash \u7684\u5b9e\u73b0\u53ea\u6709\u4e00\u4e2a\u8981\u6c42\uff0c \u5982\u679c\u4e24\u4e2a\u952e\u76f8\u7b49\uff0c\u5219\u4ed6\u4eec\u7684\u54c8\u5e0c\u5fc5\u5b9a\u4e5f\u76f8\u7b49\uff0c\u53cd\u4e4b\u5219\u4e0d\u4e00\u5b9a \u3002 \u8fd9\u4e2a\u5047\u8bbe\u6784\u6210\u4e86 unordered_map \u5f97\u4ee5\u9ad8\u6548\u7684\u57fa\u77f3\uff0c\u4ed6\u4f7f\u5f97 unordered_map \u53ef\u4ee5\u66f4\u5feb\u6392\u9664\u4e0d\u53ef\u80fd\u7684\u7b54\u6848\uff0c\u800c\u4e0d\u5fc5\u50cf vector \u7684\u67e5\u627e\u90a3\u6837\u9700\u8981\u53bb\u66b4\u529b\u904d\u5386\u5168\u90e8\u5143\u7d20\uff0c\u53ea\u9700\u8981\u904d\u5386\u54c8\u5e0c\u76f8\u7b49\u7684\u90a3\u4e00\u90e8\u5206\u5143\u7d20\u5c31\u591f\u4e86\u3002 template, // \u9ed8\u8ba4\u7684\u54c8\u5e0c\u51fd\u6570\u5b9e\u73b0\uff0c\u652f\u6301\u4e86 int, void *, string \u7b49\u7c7b\u578b typename _Pred = equal_to<_Key>, // \u9ed8\u8ba4\u7684 == \u8fd0\u7b97\u7b26 typename _Alloc = allocator>> class unordered_map \u6362\u8a00\u4e4b\uff0c\u53ea\u8981 unordered_map \u53d1\u73b0\u4e24\u4e2a\u952e\u4e0d\u76f8\u7b49\uff0c\u5c31\u4e0d\u7528\u518d\u505a\u5177\u4f53\u503c\u7684\u6bd4\u8f83\u4e86\uff0c\u4ed6\u4eec\u4e0d\u53ef\u80fd\u76f8\u7b49\u4e86\uff01","title":"hash \u548c equal_to"},{"location":"stl_map/#_67","text":"hash \u8fd4\u56de\u7684 size_t \u8fd9\u4e2a\u6574\u6570\u53ef\u4ee5\u7406\u89e3\u4e3a\u4e00\u4e2a\u5bf9\u4efb\u610f\u7c7b\u578b\u7684\u201c\u6458\u8981\u201d\u3002 \u628a\u4e00\u4e2a\u5f88\u590d\u6742\u7684\u7c7b\u578b\uff08\u4f8b\u5982 string\uff09\u538b\u7f29\u6210\u4e00\u4e2a unordered_map \u5f88\u8f7b\u6613\u5c31\u80fd\u6bd4\u8f83\u7684 size_t \u6574\u6570\uff0c\u6574\u6570\u6bd4\u8f83\u8d77\u6765\u5c31\u5f88\u5bb9\u6613\uff0c\u800c\u4e14\u8fd8\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff08string \u4e0d\u80fd\u76f4\u63a5\u4f5c\u4e3a\u6570\u7ec4\u7684\u4e0b\u6807\uff09\u3002 \u8fd9\u79cd\u6458\u8981\u7684\u5173\u952e\u5728\u4e8e\u5982\u4f55\u628a\u4e00\u4e2a\u6781\u4e3a\u590d\u6742\u7684\u7c7b\u578b\u201c\u6620\u5c04\u201d\u5230\u5c0f\u5c0f\u7684 size_t \u4e0a\u53bb\uff0c\u5e76\u4e14\u5206\u5e03\u5f97\u5c3d\u53ef\u80fd\u5747\u5300\uff0c\u4e0d\u8981\u51b2\u7a81\u3002 \u8fd9\u5c31\u9700\u8981\u6211\u4eec\u628a\u8fd9\u4e2a\u6781\u4e3a\u590d\u6742\u7c7b\u578b\u7684\u6bcf\u4e2a\u6210\u5458\uff08\u5bf9 string \u800c\u8a00\u5c31\u662f\u6bcf\u4e2a\u5b57\u7b26\uff09\u90fd\u52a0\u5230\u6700\u7ec8\u7ed3\u679c\u7684\u8868\u8fbe\u5f0f\u4e2d\u3002 \u4ee5\u5b57\u7b26\u4e32\u7c7b\u578b string \u4e3a\u4f8b\uff0c\u5e38\u89c1\u7684\u4e00\u79cd\u751f\u6210\u201c\u6458\u8981\u201d\u7684\u65b9\u6cd5\u662f\uff0c\u7528\u4e00\u4e2a\u4efb\u610f\u7d20\u6570\u7684\u4e58\u65b9\u5e8f\u5217\u548c\u5404\u5b57\u7b26\u7684 ASCII \u7801\u505a\u70b9\u79ef\uff1a size_t hash_string(string const &s) { size_t h = 0; for (char c: s) { h = h * 37 + c; } return h; } \u4f8b\u5982\u5bf9\u4e8e\u5b57\u7b26\u4e32 \u201chello\u201d\uff0c\u5219 hash \u53ef\u4ee5\u751f\u6210\u8fd9\u6837\u4e00\u4e2a\u6458\u8981\uff1a size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u76f8\u5f53\u4e8e h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o h \\cdot 37^4 + e \\cdot 37^3 + l \\cdot 37^2 + l \\cdot 37 + o \u4e5f\u6709\u5176\u4ed6\u66f4\u9ad8\u6548\u7684\u751f\u6210\u6458\u8981\u7684\u65b9\u6cd5\uff0c\u4f8b\u5982\u501f\u52a9\u4f4d\u8fd0\u7b97\u3002 \u751a\u81f3\u8fd8\u6709\u5077\u61d2\u76f4\u63a5\u62ff strlen \u5f53\u54c8\u5e0c\u51fd\u6570\u7684\u201c\u4e16\u754c\u4e0a\u6700\u597d\u7684\u54c8\u5e0c\u8868\u201d\uff0c\u6211\u4e0d\u8bf4\u662f\u8c01\u3002\uff08\u5176\u5b9e\u662f\u65e9\u671f PHP \u5566\uff09","title":"\u54c8\u5e0c\u51fd\u6570\u7684\u601d\u60f3"},{"location":"stl_map/#_68","text":"size_t h = ((('h' * 37 + 'e') * 37 + 'l') * 37 + 'l') * 37 + 'o'; \u968f\u7740\u5b57\u7b26\u4e32\u957f\u5ea6\u7684\u589e\u52a0\uff0c\u8fd9\u4e2a h \u80af\u5b9a\u4f1a\u8d85\u8fc7 size_t \u7684\u8868\u793a\u8303\u56f4\uff0c\u4f46\u662f\u6ca1\u5173\u7cfb\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u7684\u4e58\u6cd5\u3001\u52a0\u6cd5\u6ea2\u51fa\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ed6\u4f1a\u81ea\u52a8 wrapping\uff08\u53d6\u5173\u4e8e 2^{64} 2^{64} \u7684\u6a21\uff09\uff0c\u4e5f\u5c31\u662f\u53ea\u4fdd\u7559\u4e58\u6cd5\u7ed3\u679c\u548c 2^64 \u53d6\u6a21\u7684\u90e8\u5206\u3002 \u53d6\u6a21\u4e5f\u662f\u5bf9\u54c8\u5e0c\u503c\u5e38\u89c1\u7684\u4e00\u4e2a\u64cd\u4f5c\uff0c\u53cd\u6b63\u54c8\u5e0c\u503c\u662f\u968f\u673a\u7684\uff0c\u53d6\u6a21\u4ee5\u540e\u4e5f\u662f\u968f\u673a\u7684\uff0c\u4f46\u662f\u7f29\u5c0f\u4e86\u8303\u56f4\u3002 \u57fa\u672c\u5047\u8bbe\uff1am \u8db3\u591f\u5c0f\u65f6\uff0c\u4e00\u4e2a\u5747\u5300\u7684\u5206\u5e03\u53d6\u4ee5 m \u7684\u6a21\u4ee5\u540e\u4ecd\u7136\u5e94\u8be5\u662f\u5747\u5300\u7684 unordered_map \u4e2d\u6876\u7684\u6570\u91cf\u662f\u6709\u9650\u7684\uff0c\u4e3a\u4e86\u628a\u8303\u56f4\u4ece 0 0 \u5230 2^{64} - 1 2^{64} - 1 \u7684\u54c8\u5e0c\u503c\u6620\u5c04\u4e3a 0 \u5230 bucket_count - 1 \u7684\u6876\u5e8f\u53f7\uff0c\u4ed6\u5185\u90e8\u4f1a\u628a\u952e\u7684\u54c8\u5e0c\u503c\u53d6\u4ee5\u6876\u6570\u91cf\u7684\u6a21\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u952e\u8981\u5b58\u50a8\u5230\u7684\u6876\u7684\u5e8f\u53f7\uff1a bucket_index = hash(key) % bucket_count","title":"\u81ea\u52a8\u53d6\u6a21"},{"location":"stl_map/#hash-trait","text":"std::hash \u5c31\u662f\u6807\u51c6\u5e93\u7528\u4e8e\u8ba1\u7b97\u54c8\u5e0c\u7684\u4eff\u51fd\u6570\u7c7b\u4e86\uff0c\u4ed6\u548c std::less \u4e00\u6837\uff0c\u662f\u4e00\u4e2a trait \u7c7b\u3002 \u4e00\u4e9b\u5e38\u89c1\u7684\u7c7b\u578b\u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u4e5f\u53ef\u4ee5\u9488\u5bf9\u81ea\u5b9a\u4e49\u7c7b\u578b\u6dfb\u52a0\u7279\u5316\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316 } }; template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u5bf9 T * \u7684\u504f\u7279\u5316 } }; std::hash \u9488\u5bf9\u6bcf\u4e2a\u4e0d\u540c\u7684\u7c7b\u578b\u505a\u4e86\u7279\u5316\uff0c\u4f8b\u5982\u5f53\u6211\u4eec\u9700\u8981\u8ba1\u7b97 string \u7c7b\u578b\u7684 hash \u65f6\uff1a string str = \"Hello, world\"; size_t h = hash()(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); \u6ce8\u610f\uff1a\u8fd9\u91cc\u6709\u4e24\u4e2a\u62ec\u53f7\uff0c\u7b2c\u4e00\u4e2a\u662f\u7a7a\u7684\u3002\u7b2c\u4e00\u4e2a\u62ec\u53f7\u521b\u5efa\u4eff\u51fd\u6570\u5bf9\u8c61\uff0c\u7b2c\u4e8c\u4e2a\u7528str\u4f5c\u4e3a\u5b9e\u53c2\u8c03\u7528\u4eff\u51fd\u6570\u7684 operator() \u3002\u5f53\u7136\u8fd8\u522b\u5fd8\u4e86\u7b2c\u4e00\u4e2a\u5c16\u62ec\u53f7\uff0c\u8fd9\u4e2a\u5c16\u62ec\u53f7\u91cc\u7684 string \u8868\u793a\u7684\u662f hash \u4eff\u51fd\u6570\u63a5\u4e0b\u6765\u8981\u63a5\u53d7\u53c2\u6570\u7684\u7c7b\u578b\uff0c\u4e4b\u6240\u4ee5\u4f5c\u4e3a\u7c7b\u7684\u6a21\u677f\u53c2\u6570\u800c\u4e0d\u662f\u6a21\u677f\u51fd\u6570\uff0c\u662f\u4e3a\u4e86\u65b9\u4fbf\u7279\u5316\u548c\u504f\u7279\u5316\u3002\u540c\u5b66\u4eec\u4e5f\u53ef\u4ee5\u81ea\u5df1\u5199\u4e00\u4e2a\u8fd9\u6837\u7684\u51fd\u6570\uff0c\u7528\u8d77\u6765\u5c31\u4e0d\u7528\u6307\u5b9a\u7c7b\u578b\uff08\u5982\u8fd9\u91cc\u7684 string\uff09\u4e86\uff0c\u8ba9\u6a21\u677f\u51fd\u6570\u81ea\u52a8\u63a8\u5bfc\u53c2\u6570\u7c7b\u578b\uff08\u7c7b\u4f3c\u4e8e make_pair\uff09\uff1a template size_t do_hash(T const &t) { return hash()(t); } int main() { string str = \"Hello, world\"; size_t h = do_hash(str); print(str, \"\u7684\u54c8\u5e0c\u662f\", h); } \"Hello, world\" \u7684\u54c8\u5e0c\u662f 14701251851404232991 \u5bf9\u4efb\u610f\u7c7b\u578b\u54c8\u5e0c\u7684\u7ed3\u679c\u90fd\u662f\u4e00\u4e2a size_t\uff0c\u5176\u5728 32 \u4f4d\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint32_t\uff0c\u5728\u6211\u4eec 64 \u4e3a\u7cfb\u7edf\u4e0a\u7b49\u540c\u4e8e uint64_t\u3002\u9009\u62e9 size_t \u662f\u4e3a\u4e86\u80fd\u54c8\u5e0c\u4e86\u4ee5\u540e\u76f4\u63a5\u7528\u4e8e unordered_map \u4e2d\u6876\u7684\u7d22\u5f15\u3002 \u7531\u4e8e hash \u662f\u7528\u4f5c\u54c8\u5e0c\u8868\u7684\u54c8\u5e0c\u51fd\u6570\uff0c\u800c\u4e0d\u662f\u7528\u4e8e\u52a0\u5bc6\u9886\u57df\uff08\u8bf7\u4f60\u79fb\u6b65 md5\uff09\uff0c\u6216\u662f\u7528\u4e8e\u968f\u673a\u6570\u751f\u6210\uff08\u8bf7\u79fb\u6b65 mt19937\uff09\uff0c\u56e0\u6b64\u5bf9\u4e8e\u4efb\u610f\u7c7b\u578b\uff0c\u53ea\u9700\u8981\u6839\u636e\u4ed6\u751f\u6210\u4e00\u4e2a size_t \u7684\u54c8\u5e0c\u503c\u5373\u53ef\uff0c\u53ea\u8981\u4fdd\u8bc1\u54c8\u5e0c\u503c\u5206\u5e03\u5747\u5300\u5373\u53ef\uff0c\u4e0d\u4e00\u5b9a\u8981\u6709\u968f\u673a\u6027\u3002\u4f8b\u5982\u6807\u51c6\u5e93\u5bf9 int \u7684 hash \u5b9e\u73b0\u5c31\u662f\u4e2a\u6052\u7b49\u51fd\u6570\u2014\u2014\u76f4\u63a5\u8fd4\u56de\u5176\u6574\u6570\u503c\uff0c\u4e0d\u7528\u505a\u4efb\u4f55\u8ba1\u7b97\uff1a template <> struct hash { size_t operator()(int t) const noexcept { return t; // \u5bf9 int \u7684\u7279\u5316\u771f\u662f\u4ec0\u4e48\u4e5f\u4e0d\u505a\u5462\uff1f } }; \u800c\u5bf9\u4e8e\u4efb\u610f\u6307\u9488\u7684\u5b9e\u73b0\u5219\u662f\u76f4\u63a5\u628a\u6307\u9488 bit-cast \u6210 size_t\uff1a template struct hash { size_t operator()(T *t) const noexcept { return reinterpret_cast(t); // \u6307\u9488\u5f3a\u5236\u8f6c\u6362\u4e3a\u6574\u6570 } }; int i = 42; int j = hash()(i); // \u6ca1\u60f3\u5230\u7f62\uff01\u6211\u7cfb\u6052\u7b49\u51fd\u6570\u54d2 print(i, j); 42 42 \u8bb0\u4f4f\uff0cstd::hash \u4e0d\u662f\u4e3a\u4e86\u52a0\u5bc6\u6216\u968f\u673a\u800c\u751f\u7684\uff0c\u4ed6\u7684\u529f\u80fd\u4ec5\u4ec5\u662f\u5c3d\u53ef\u80fd\u5feb\u901f\u5730\u628a\u4efb\u610f\u7c7b\u578b T \u6620\u5c04\u5230 size_t \u800c\u5df2\u3002 \u81f3\u4e8e\u8fd9\u5bf9 unordered_map \u7684\u6027\u80fd\u6709\u4f55\u5f71\u54cd\uff1f\u901a\u5e38\u6ca1\u6709\u4ec0\u4e48\u5f71\u54cd\uff0c\u9664\u975e\u8f93\u5165\u952e\u6545\u610f\u8bbe\u4e3a\u548c bucket_count \u540c\u6a21\uff0c\u6bd5\u7adf\u53cd\u6b63\u4f60\u4e5f\u65e0\u6cd5\u65ad\u5b9a\u8f93\u5165\u952e\u7684\u6392\u5e03\u6a21\u5f0f\uff0c\u4e0d\u8bba\u9009\u4ec0\u4e48\u54c8\u5e0c\u51fd\u6570\u53ea\u8981\u4fdd\u8bc1\u5747\u5300\u90fd\u662f\u53ef\u4ee5\u7684\u3002\u800c\u6052\u7b49\u51fd\u6570\u521a\u597d\u662f\u5747\u5300\u7684\uff0c\u53c8\u4e0d\u7528\u989d\u5916\u7684\u82b1\u91cc\u80e1\u54e8\u4f4d\u8fd0\u7b97\u6d6a\u8d39\u65f6\u95f4\uff0c\u53cd\u800c\u53ef\u80fd\u56e0\u4e3a\u952e\u6709\u5e8f\u800c\u63d0\u5347\u4e86\u7f13\u5b58\u5c40\u57df\u6027\uff0c\u63d0\u5347\u4e86\u6027\u80fd\uff0c\u6240\u4ee5\u5404\u5927\u5382\u5546\u7684\u6807\u51c6\u5e93\u90fd\u662f\u8fd9\u4e48\u505a\u7684\u3002","title":"hash \u662f\u4e2a trait \u7c7b"},{"location":"stl_map/#2_1","text":"map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u67e5\u8be2\u548c\u63d2\u5165\u64cd\u4f5c\u662f O(1)+ O(1)+ \u590d\u6742\u5ea6\u7684\u3002 \u770b\u8d77\u6765 unordered_map \u66f4\u9ad8\u6548\uff1f\u90a3\u8fd8\u8981 map \u5e72\u4ec0\u4e48\uff1f\u5b8c\u5168\u4e0a\u4f4d\u66ff\u4ee3\u554a\uff1f \u4f46\u662f\u6211\u4eec\u8981\u6ce8\u610f\uff0c\u4e0a\u9762\u6240\u8bf4\u7684\u590d\u6742\u5ea6 O(1) O(1) \u53ea\u662f\u5e73\u5747\u4e0b\u6765\u7684\uff0c\u5e76\u4e0d\u4ee3\u8868\u6bcf\u4e00\u6b21 unordered_map \u63d2\u5165\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u90fd\u662f O(1) O(1) \uff01\u6240\u4ee5\uff0c\u590d\u6742\u5ea6\u8868\u793a\u6cd5\u91cc\u7684\u8fd9\u4e2a + \u53f7\u5c31\u662f\u8fd9\u4e2a\u610f\u601d\uff0c\u4ee3\u8868\u6211\u8fd9\u4e2a\u590d\u6742\u5ea6\u53ea\u662f\u591a\u6b21\u8fd0\u884c\u53d6\u5e73\u5747\uff0c\u5982\u679c\u53ea\u8003\u8651\u5355\u6b21\u6700\u574f\u7684\u60c5\u51b5\uff0c\u53ef\u80fd\u66f4\u9ad8\u3002 map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u4e5f\u53ea\u662f O(\\log N) O(\\log N) \u590d\u6742\u5ea6\u7684\u3002 unordered_map \u7684\u63d2\u5165\u64cd\u4f5c \u6700\u574f \u53ef\u4ee5\u662f O(N) O(N) \u590d\u6742\u5ea6\u7684\u3002 \u5904\u7406\u5f88\u9ad8\u7684\u6570\u636e\u91cf\u65f6\uff0c\u8fd9\u4e00\u70b9\u6700\u574f\u7684\u60c5\u51b5\u4f1a\u88ab\u5e73\u644a\u6389\uff0cunordered_map \u66f4\u9ad8\u6548\u3002","title":"\u533a\u522b 2\uff1a\u65f6\u95f4\u590d\u6742\u5ea6"},{"location":"stl_map/#_69","text":"\u6240\u4ee5 unordered_map \u4e0d\u7a33\u5b9a\uff0c\u867d\u7136\u5e73\u5747\u662f O(1) O(1) \u590d\u6742\u5ea6\uff0c\u4f46\u6700\u574f\u53ef\u8fbe\u5230 O(N) O(N) \u590d\u6742\u5ea6\u3002\u80cc\u540e\u7684\u539f\u56e0\u662f\u4ec0\u4e48\u5462\uff1f \u539f\u6765 unordered_map \u548c vector \u4e00\u6837\uff0c\u662f\u4e00\u4e2a\u9700\u8981\u4e0d\u65ad\u52a8\u6001\u6269\u5bb9\u7684\u5bb9\u5668\u3002 \u5982\u679c\u4e0d\u6269\u5bb9\uff0c\u90a3\u4e48\u5f53\u5f88\u591a\u5143\u7d20\u6324\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u94fe\u8868\u7684\u538b\u529b\u5c31\u4f1a\u53d8\u5927\uff0c\u4f1a\u5f88\u4f4e\u6548\uff0c\u56e0\u6b64 unordered_map \u5fc5\u987b\u6269\u5bb9\u3002\u4f46\u662f\u5728\u6269\u5bb9\u7684\u65f6\u5019\u662f\u9700\u8981\u8fdb\u884c rehash \u64cd\u4f5c\u7684\u3002\u4e00\u6b21\u6269\u5bb9\uff0c\u5c31\u9700\u8981\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e00\u904d\u3002 \u7ed3\u679c\u5c31\u662f unordered_map \u7684\u63d2\u5165\u5982\u679c\u6ca1\u89e6\u53d1 rehash\uff0c\u90a3\u5c31\u662f O(1) O(1) \u7684\u3002\u89e6\u53d1\u4e86\uff0c\u90a3\u5c31\u662f\u6700\u574f\u7684\u60c5\u51b5\uff0c O(N) O(N) \u7684\u3002\u4f46\u662f\u4e0d\u89e6\u53d1\u7684\u60c5\u51b5\u8fdc\u591a\u4e8e\u89e6\u53d1\u4e86\u7684\uff0c\u6240\u4ee5\u5e73\u5747\u4e0b\u6765\u8fd8\u662f O(1) O(1) \uff0c\u4e3a\u4e86\u63d0\u9192\u4eba\u4eec\u4ed6\u6700\u574f\u7684\u60c5\u51b5\uff0c\u6240\u4ee5\u5199\u4f5c O(1)+ O(1)+ \uff0c\u8bfb\u4f5c\u201c\u5e73\u644a O1\u201d\uff08Amortized Constant\uff09\u3002 \u6b64\u5916\uff0c\u4e0d\u4ec5 unordered_map \u7684\u63d2\u5165\u51fd\u6570\u662f O(1)+ O(1)+ \uff0c\u4ed6\u7684\u67e5\u8be2\u51fd\u6570\u4e5f\u662f O(1)+ O(1)+ \u3002\u4e3a\u4ec0\u4e48\u5462\uff1f\u8bbe\u60f3\u4f60\u5728\u7f16\u5199\u4e00\u4e2a\u5bcc\u8fde\u7f51\u670d\u52a1\u5668\uff0c\u5982\u679c\u9ed1\u5ba2\u5df2\u77e5\u4f60\u7684 hash \u51fd\u6570\uff0c\u90a3\u4ed6\u5c31\u53ef\u4ee5\u901a\u8fc7\u6784\u9020\u4e00\u7cfb\u5217\u7279\u6b8a\u8bbe\u8ba1\u597d\u7684 key\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u521a\u597d\u76f8\u7b49\uff08\u6216\u540c\u6a21\uff09\uff0c\u8fd9\u6837\u5c31\u4f7f\u5f97\u6240\u6709 key \u521a\u597d\u5168\u90e8\u843d\u5728\u4e00\u4e2a\u6876\u91cc\uff0c\u5bfc\u81f4 unordered_map \u9000\u5316\u6210\u7ebf\u6027\u7684\u94fe\u8868\uff0c\u6240\u6709\u7684\u67e5\u8be2\u548c\u63d2\u5165\u90fd\u53d8\u6210\u4e86\u8fd9\u4e00\u4e2a\u6876\u4e0a\u7684\u94fe\u8868\u904d\u5386\u64cd\u4f5c\uff0c\u590d\u6742\u5ea6\u8fbe\u5230\u6700\u574f\u7684 O(N) O(N) \uff0c\u8fd9\u4e00\u73b0\u8c61\u53eb\u505a hash \u9000\u5316\u3002 \u56e0\u6b64 hash \u51fd\u6570\u7684\u597d\u574f\u51b3\u5b9a\u7740 unordered_map \u6027\u80fd\uff0c\u5bf9\u4e8e\u5b89\u5168\u9886\u57df\u6765\u8bf4\uff0c\u8fd8\u8981\u4fdd\u8bc1 hash \u51fd\u6570\u65e0\u6cd5\u88ab\u9ed1\u5ba2\u7834\u89e3\u3002\u53ea\u8981 hash \u51fd\u6570\u8db3\u591f\u968f\u673a\uff0c\u5c31\u80fd\u4fdd\u8bc1\u952e\u4e0d\u51b2\u7a81\uff0c\u5c31\u5f88\u5feb\uff0c\u4e00\u65e6\u51fa\u73b0\u952e\u51b2\u7a81\u5c31\u4f1a\u53d8\u6162\u3002\u4f46\u9700\u8981\u9891\u7e41\u4f7f\u7528\u7684 hash \u51fd\u6570\u8ba1\u7b97\u96be\u5ea6\u53c8\u4e0d\u80fd\u592a\u5927\uff0c\u90a3\u53c8\u4f1a\u5f71\u54cd\u6027\u80fd\uff0c\u56e0\u6b64 hash \u4e5f\u4e0d\u80fd\u592a\u8fc7\u590d\u6742\u3002 \u6807\u51c6\u5e93\u91cc\u5b58\u5728\u8fd9\u79cd\u201c\u5e73\u644a\u590d\u6742\u5ea6\u201d\u7684\u4f8b\u5b50\u8fd8\u6709\u5f88\u591a\uff0c\u4f8b\u5982 vector \u7684 push_back \u4e0d reserve \u7684\u8bdd\uff0c\u5c31\u662f O(1)+ O(1)+ \u7684\uff0c\u56e0\u4e3a\u4ed6\u9700\u8981\u52a8\u6001\u6269\u5bb9\u3002","title":"\u54c8\u5e0c\u8868\u7684\u590d\u6742\u5ea6\u4e0d\u7a33\u5b9a"},{"location":"stl_map/#_70","text":"\u4e00\u4e9b\u5b9e\u65f6\u6027\u8981\u6c42\u5f88\u9ad8\u7684\u9886\u57df\u5c31\u4e0d\u80fd\u7528 unordered_map\u3002\u4f8b\u5982\u4f60\u9020\u4e86\u4e2a\u706b\u7bad\uff0c\u89c4\u5b9a\uff1a\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u9700\u8981\u5728 1000 \u03bcs \u5185\u5bf9\u5916\u754c\u53d8\u5316\u505a\u51fa\u5b9e\u65f6\u53cd\u5e94\uff0c\u5982\u679c\u4e0d\u80fd\u53ca\u65f6\u505a\u51fa\u53cd\u5e94\uff0c\u706b\u7bad\u5c31\u4f1a\u505a\u6258\u9a6c\u65af\u56de\u65cb\u7ed9\u4f60\u770b\u3002 \u4f60\u5728\u706b\u7bad\u63a7\u5236\u7a0b\u5e8f\u4e2d\u7528\u4e86 unordered_map\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u4e0d\u65ad\u8fd0\u884c\uff0c\u4ee5\u4fbf\u63a7\u5236\u706b\u7bad\u505a\u51fa\u6b63\u786e\u7684\u673a\u52a8\uff0c\u5bf9\u6297\u4fa7\u5411\u98ce\u5e72\u6270\u3002\u7b2c\u4e00\u6b21\u8fd0\u884c\u4ed6\u5728 180 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 250 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 245 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u9ad8\u6548\u3002 \u4f46\u662f\u7a81\u7136\u6709\u4e00\u6b21\uff0cunordered_map \u89c9\u5f97\u4ed6\u5185\u90e8\u201c\u6876\u592a\u4e71\u201d\u4e86\uff0c\u6025\u9700\u91cd\u65b0\u6269\u5bb9\u5e76 rehash \u4e00\u4e0b\u201c\u5fe7\u5316\u6027\u80fd\u201d\u3002\u7136\u540e\uff0c\u4ed6\u628a\u6240\u6709\u7684\u5143\u7d20\u90fd\u79fb\u52a8\u4e86\u4e00\u904d\uff0c\u79fb\u52a8\u5b8c\u4e86\uff0c\u628a\u5904\u7406\u5b8c\u7684\u6570\u636e\u8fd4\u56de\u7ed9\u706b\u7bad\u59ff\u6001\u8c03\u63a7\u7cfb\u7edf\uff0c\u8ba4\u4e3a\u5927\u529f\u544a\u6210\u3002\u4f46\u5f53\u4ed6\u7741\u5f00\u773c\u775b\u4e00\u770b\uff0c\u521a\u60f3\u8981\u63a7\u5236\u4e00\u4e0b\u59ff\u6001\u5462\uff1f\u5374\u53d1\u73b0\u81ea\u5df1\u5df2\u7ecf\u5728\u505a\u6258\u9a6c\u65af\u56de\u65cb\u4e86\uff01\u539f\u6765\u6211\u8fd9\u4e00\u201c\u5fe7\u5316\u201d\u5c31\u5fe7\u4e86 4000 \u03bcs\uff0c\u8d85\u51fa\u4e86\u706b\u7bad\u5b9e\u65f6\u54cd\u5e94\u7684\u786c\u6027\u6307\u6807\uff0c\u5bfc\u81f4\u897f\u88c5\u9ab0\u5b50\u4eba\u5377\u6b3e\u8dd1\u8def\uff0c\u5c0f\u5f6d\u8001\u5e08\u7834\u4ea7\u3002 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u521b\u4e1a\uff0c\u8fd9\u6b21\u4ed6\u9009\u7528\u4e86\u7a33\u5b9a\u7684 map\uff0c\u7b2c\u4e00\u6b21\u4ed6\u5728 810 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e8c\u6b21\u5728 680 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u7b2c\u4e09\u6b21 730 \u03bcs \u5185\u53cd\u5e94\u4e86\uff0c\u4f60\u89c9\u5f97\u4ed6\u5f88\u4f4e\u6548\u3002\u4f46\u662f\u4ed6\u6bcf\u4e00\u6b21\u90fd\u80fd\u6210\u529f\u5361\u70b9\u7ed9\u4f60\u5b8c\u6210\u4efb\u52a1\uff0c\u4ece\u6765\u4e0d\u4f1a\u7a81\u7136\u8d85\u8fc7 O(\\log N) O(\\log N) \uff0c\u4ed6\u7684\u6700\u574f\u60c5\u51b5\u662f\u53ef\u63a7\u7684\uff0c\u4ece\u800c\u907f\u514d\u4e86\u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb\u3002\u5c0f\u5f6d\u8001\u5e08\u6700\u7ec8\u521b\u4e1a\u6210\u529f\uff0c1000 \u5e74\u540e\uff0c\u6211\u53f8\u6210\u529f\u5efa\u9020\u5b8c\u6210 Type-II \u6587\u660e\u6240\u6025\u9700\u7684\u6234\u68ee\u7403\uff0c\u5411\u661f\u8fb0\u5927\u6d77\u8fdb\u519b\u3002 \u5bf9\u5b9e\u65f6\u6027\u8981\u6c42\u9ad8\u7684\u8fd9\u7c7b\u9886\u57df\u5305\u62ec\uff0c\u97f3\u89c6\u9891\uff0c\u9020\u706b\u7bad\uff0c\u91cf\u5316\u4ea4\u6613\u7b49\u3002\u8fd9\u7c7b\u4f4e\u5ef6\u8fdf\u4f4e\u541e\u5410\u91cf\u7684\u9886\u57df\u5bf9\u5e73\u644a\u590d\u6742\u5ea6\u5f88\u53cd\u611f\uff0c\u4ed6\u4eec\u53ea\u770b\u91cd\u6700\u574f\u7684\u590d\u6742\u5ea6\uff0c\u800c\u4e0d\u662f\u5e73\u5747\u7684\u3002 \u4f46\u5bf9\u4e8e\u4e3b\u6253\u4e00\u4e2a\u9ad8\u541e\u5410\u91cf\u65e0\u6240\u8c13\u5ef6\u8fdf\u7684\u79bb\u7ebf\u56fe\u5f62\u5b66\uff0c\u79bb\u7ebf\u79d1\u5b66\u8ba1\u7b97\uff0c\u5b9e\u65f6\u6027\u4e0d\u91cd\u8981\u7684\u751f\u6001\u5316\u53cd\u573a\u666f\uff0c\u6211\u4eec\u53ef\u4ee5\u8ba4\u4e3a unordered_map \u7684\u5e73\u644a O(1)+ O(1)+ \u5c31\u662f\u6bd4 map \u9ad8\u6548\u7684\u3002","title":"\u54c8\u5e0c\u8868\u7684\u5e94\u7528\u9650\u5236"},{"location":"stl_map/#3","text":"map \u548c unordered_map \u90fd\u662f\u53ea\u6709\u5f53\u5220\u9664\u7684\u521a\u597d\u662f\u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u65f6\u624d\u4f1a\u5931\u6548\uff0c\u8fd9\u70b9\u76f8\u540c\u3002 \u4f46 unordered_map \u6269\u5bb9\u65f6\u5019\u7684 rehash \u64cd\u4f5c\u4f1a\u9020\u6210\u6240\u6709\u8fed\u4ee3\u5668\u5931\u6548\u3002 insert \u53ef\u80fd\u5bfc\u81f4 unordered_map \u6269\u5bb9\uff0c\u5176\u4ed6\u53ea\u8bfb\u64cd\u4f5c\u4e0d\u4f1a\u3002 \u8fed\u4ee3\u5668\u6307\u5411\u7684\u90a3\u4e2a\u5143\u7d20\u88ab\u5220\u9664\u65f6\uff0c\u4e0d\u8bba map \u548c unordered_map \u90fd\u4f1a\u5931\u6548\u3002 unordered_map \u5728 insert \u65f6\u5982\u679c\u53d1\u751f\u6269\u5bb9\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u5931\u6548\uff0c\u53ef\u4ee5\u901a\u8fc7\u8c03\u7528 reserve \u907f\u514d insert \u65f6\u6269\u5bb9\u3002 \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 clear swap opeartor= rehash vector \u662f \u5426 \u662f - map \u662f \u5426 \u662f - unordered_map \u662f \u5426 \u662f - \u5bb9\u5668 find count at [] vector \u5426 \u5426 \u5426 \u5426 map \u5426 \u5426 \u5426 \u5426 unordered_map \u5426 \u5426 \u5426 \u662f\uff0c\u5982\u679c\u521b\u5efa\u4e86\u65b0\u5143\u7d20\u4e14 size / bucket_count > max_load_factor \u5c0f\u5f6d\u8001\u5e08\u7f16\u5199\u597d\u4e86\u8fed\u4ee3\u5668\u5931\u6548\u8868\uff0c\u65b9\u4fbf\u4f60\u8bb0\u5fc6: \u5bb9\u5668 push_back insert erase reserve vector \u662f\uff0c\u5982\u679c size > capacity \u662f\uff0c\u5982\u679c\u63d2\u5165\u4f4d\u7f6e\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216 size > capacity \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u5143\u7d20\u5728\u5f53\u524d\u8fed\u4ee3\u5668\u4e4b\u524d\uff0c\u6216\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684 \u662f map - \u5426 \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 - unordered_map - \u662f\uff0c\u5982\u679c size / bucket_count > max_load_factor \u662f\uff0c\u5982\u679c\u5220\u9664\u7684\u521a\u597d\u662f\u5f53\u524d\u8fed\u4ee3\u5668\u6307\u5411\u7684\u5143\u7d20 \u662f \u4e5f\u53ef\u4ee5\u67e5\u770b\u5b98\u65b9\u7248\u300a\u8fed\u4ee3\u5668\u5931\u6548\u8868\u300b\uff1ahttps://en.cppreference.com/w/cpp/container#Iterator_invalidation","title":"\u533a\u522b 3\uff1a\u8fed\u4ee3\u5668\u5931\u6548\u6761\u4ef6"},{"location":"stl_map/#load_factor","text":"\u8ba1\u7b97\u516c\u5f0f\uff1a\u8d1f\u8f7d\u56e0\u5b50(load_factor) = \u5f53\u524d\u5143\u7d20\u6570\u91cf(size) \u00f7 \u5f53\u524d\u6876\u7684\u6570\u91cf(bucket_count) \u63d2\u5165\u65b0\u5143\u7d20\u540e\uff0c\u5f53\u68c0\u6d4b\u5230\u8d1f\u8f7d\u56e0\u5b50\u5927\u4e8e\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4 1.0\uff09\u65f6\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fdb\u884c rehash \u64cd\u4f5c\u3002 \u4e3a\u4e86\u907f\u514d\u91cd\u590d\u5c0f\u89c4\u6a21\u6269\u5bb9\u6d6a\u8d39\u65f6\u95f4\uff0c\u8fd9\u6b21 rehash \u4f1a\u4e00\u6b21\u6027\u6269\u5bb9\u4e24\u500d\uff08\u8ddf vector \u7684 push_back \u6269\u5bb9\u7c7b\u4f3c\uff09\u3002 \u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 max_load_factor \u51fd\u6570\u8c03\u6574\u3002\u5f53\u524d\u8d1f\u8f7d\u56e0\u5b50\u53ef\u4ee5\u901a\u8fc7 load_factor \u51fd\u6570\u67e5\u8be2\u3002 \u76f4\u89c2\u7406\u89e3\uff1a\u5f53\u6bcf\u4e2a\u6876\u5e73\u5747\u90fd\u6709\u4e00\u4e2a\u5143\u7d20\u65f6\uff0cunordered_map \u5c31\u4f1a\u8ba4\u4e3a\u5df2\u7ecf\u5f88\u6ee1\u4e86\uff0c\u5c31\u4f1a\u6269\u5bb9\u5e76\u91cd\u65b0\u5206\u914d\u4f4d\u7f6e\u3002 \u7531\u4e8e\u9ed8\u8ba4\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\u662f 1.0\uff0c\u6240\u4ee5\u6269\u5bb9\u6761\u4ef6\u7b49\u4ef7\u4e8e size > bucket_count","title":"\u8d1f\u8f7d\u7387\uff08load_factor\uff09"},{"location":"stl_map/#rehash","text":"\u5728\u64cd\u4f5c unordered_map \u5bb9\u5668\u8fc7\u7a0b\uff08\u5c24\u5176\u662f\u5411\u5bb9\u5668\u4e2d\u6dfb\u52a0\u65b0\u952e\u503c\u5bf9\uff09\u4e2d\uff0c\u4e00\u65e6\u5f53\u524d\u5bb9\u5668\u7684\u8d1f\u8f7d\u56e0\u5b50\u8d85\u8fc7\u6700\u5927\u8d1f\u8f7d\u56e0\u5b50\uff08\u9ed8\u8ba4\u503c\u4e3a 1.0\uff09\uff0c\u8be5\u5bb9\u5668\u5c31\u4f1a\u9002\u5f53\u589e\u52a0\u6876\u7684\u6570\u91cf\uff08\u901a\u5e38\u662f\u7ffb\u4e00\u500d\uff09\uff0c\u5e76\u81ea\u52a8\u6267\u884c rehash() \u6210\u5458\u65b9\u6cd5\uff0c\u91cd\u65b0\u8c03\u6574\u5404\u4e2a\u952e\u503c\u5bf9\u7684\u5b58\u50a8\u4f4d\u7f6e\uff08\u6b64\u8fc7\u7a0b\u53c8\u79f0\u201c\u91cd\u54c8\u5e0c\u201d\uff09\uff0c\u6b64\u8fc7\u7a0b\u5f88\u53ef\u80fd\u5bfc\u81f4\u4e4b\u524d\u521b\u5efa\u7684\u8fed\u4ee3\u5668\u5931\u6548\u3002 1 \u9664\u4e86\u6269\u5bb9\u65f6\u81ea\u52a8\u7684 rehash\uff0c\u786e\u8ba4\u6570\u636e\u63d2\u5165\u5b8c\u6bd5\u4e0d\u4f1a\u518d\u6539\u52a8\u65f6\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u6765\u4f18\u5316\u5bb9\u5668\u4e2d\u5143\u7d20\u7684\u6392\u5e03\uff0c\u63d0\u5347\u6027\u80fd\u3002 unordered_map umap; for (int i = 1; i <= 50; i++) { umap.emplace(i, i); } auto pair = umap.equal_range(49); //\u83b7\u53d6\u952e\u4e3a 49 \u7684\u952e\u503c\u5bf9\u6240\u5728\u7684\u533a\u95f4\uff0c\u7531\u4e8e\u4e0d\u662f multimap\uff0c\u533a\u95f4\u5927\u5c0f\u53ea\u80fd\u4e3a 0 \u6216 1 for (auto iter = pair.first; iter != pair.second; ++iter) { //\u8f93\u51fa pair \u8303\u56f4\u5185\u7684\u6bcf\u4e2a\u952e\u503c\u5bf9\u7684\u952e\u7684\u503c cout << iter->first << '\\n'; } umap.rehash(10); //\u624b\u52a8\u8c03\u7528 rehash() \u51fd\u6570\u91cd\u54c8\u5e0c\u4e3a 10 \u4e2a\u6876 for (auto iter = pair.first; iter != pair.second; ++iter) { // \u91cd\u54c8\u5e0c\u4e4b\u540e\uff0c\u4e4b\u524d\u4fdd\u5b58\u7684\u8fed\u4ee3\u5668\u53ef\u80fd\u4f1a\u53d1\u751f\u53d8\u5316 cout << iter->first << '\\n'; } 49 Segmentation fault (core dumped)","title":"rehash \u51fd\u6570"},{"location":"stl_map/#hash","text":"\u57fa\u4e8e\u7ea2\u9ed1\u6811\u7684\u6620\u5c04\u8868 map \u53ea\u9700\u652f\u6301\u6bd4\u8f83\u8fd0\u7b97\u7684 less \u5373\u53ef\uff0c\u800c unordered_map \u9700\u8981\u54c8\u5e0c\u548c\u76f8\u7b49\u4e24\u4e2a trait\uff0c\u4ed6\u4eec\u5206\u522b\u540d\u53eb std::hash \u548c std::equal_to\u3002 \u867d\u7136\u4e24\u8005\u90fd\u662f\u4eff\u51fd\u6570\uff0c\u4f46\u4e5f\u6709\u5f88\u591a\u533a\u522b\uff1a hash \u53ea\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u800c equal_to \u63a5\u53d7\u4e24\u4e2a\u53c2\u6570\u3002 hash \u8fd4\u56de size_t\uff0c\u800c equal_to \u8fd4\u56de bool \u7c7b\u578b\u3002 equal_to \u6709\u9ed8\u8ba4\u7684\u5b9e\u73b0\uff0c\u90a3\u5c31\u662f\u8c03\u7528\u8fd0\u7b97\u7b26 ==\u3002\u800c hash \u6ca1\u6709\u9ed8\u8ba4\u5b9e\u73b0\uff0c\u4e5f\u6ca1\u76f8\u5e94\u7684\u8fd0\u7b97\u7b26\uff0c\u53ea\u80fd\u624b\u52a8\u7279\u5316\u3002 \u6b63\u56e0\u4e3a\u5982\u6b64\uff0c\u901a\u5e38\u6211\u4eec\u9700\u8981\u8ba9\u4e00\u4e2a\u7c7b\uff08\u4f8b\u5982 Student\uff09\u652f\u6301 equal_to \u6216 less \u8fd9\u4e9b\u6709\u76f8\u5e94\u8fd0\u7b97\u7b26\u7684\u4eff\u51fd\u6570\u65f6\uff0c\u76f4\u63a5\u5728\u7c7b\u578b\u5185\u90e8\u5b9a\u4e49 operator== \u6216 operator< \u5373\u53ef\uff0c\u800c hash \u5219\u662f\u53ea\u80fd\u7528\u7279\u5316\u7684\u65b9\u6cd5\u624d\u80fd\u652f\u6301\u4e0a\u3002 template struct hash { size_t operator()(T const &t) const noexcept; // \u6709\u5f85\u5b9e\u73b0 }; template struct equal_to { bool operator()(T const &x, T const &y) const noexcept { return x == y; } }; \u6709\u4e9b\u7c7b\u578b\u80fd\u7528\u4f5c map \u7684\u952e\uff0c\u4f46\u4e0d\u80fd\u7528\u4f5c unordered_map \u7684\u952e\u3002\u8fd9\u662f\u56e0\u4e3a\u5077\u61d2\u7684\u6807\u51c6\u5e93\u6ca1\u5bf9\u4ed6\u4eec\u7684 hash \u7279\u5316\uff01 \u4f8b\u5982 tuple \u652f\u6301 < \u8fd0\u7b97\u7b26\uff0c\u652f\u6301 less\u3002 \u4f46\u662f tuple \u6ca1\u6709 hash \u7684\u7279\u5316\uff0c\u4e0d\u652f\u6301 hash\u3002 tuple tup; size_t h = hash>()(tup); // \u7f16\u8bd1\u671f\u62a5\u9519\uff1a\u67e5\u65e0\u6b64\u51fd\u6570\uff01 unordered_map>","title":"hash \u9700\u8981\u7279\u5316"},{"location":"stl_map/#tuple","text":"\u548c less \u7684\u60c5\u5f62\u4e00\u6837\uff0c\u4e5f\u662f\u6709\u4e09\u79cd\u89e3\u51b3\u65b9\u6848\uff1a \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u7279\u5316\uff0cequal_to \u7684\u7279\u5316 template <> struct std::hash { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; template <> struct std::equal_to { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u81ea\u5b9a\u4e49\u4e00\u4e2a hash \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u4e00\u4e2a equal_to \u7684\u4eff\u51fd\u6570\u7c7b\uff0c\u7136\u540e\u4f20\u5165 unordered_map \u505a\u6a21\u677f\u53c2\u6570 template <> struct HashStudent { bool operator()(Student const &x) const { return hash()(x.name) ^ hash(x.id) ^ hash(x.sex); } }; struct EqualStudent { bool operator()(Student const &x, Student const &y) const { return x.name == y.name && x.id == y.id && x.sex == y.sex; } }; unordered_map stutab; \u6ce8\uff1a\u5982\u679c Student \u5df2\u7ecf\u5b9a\u4e49\u4e86 operator== \uff0c\u5219\u8fd9\u91cc\u4e0d\u7528 EqualStudent\uff0c\u9ed8\u8ba4\u7684 equal_to \u4f1a\u81ea\u52a8\u8c03\u7528 == \u8fd0\u7b97\u7b26\u7684\u3002 \u5bf9\u4e8e tuple \u800c\u8a00\uff0ctuple \u5df2\u7ecf\u6709\u4e86 == \u8fd0\u7b97\u7b26\uff0c\u4e0d\u7528\u7279\u5316 equal_to \u4e86\uff0c\u53ea\u9700\u8981\u7279\u5316\u6216\u6307\u5b9a hash \u5373\u53ef template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; unordered_map, int> stutab;","title":"\u7ed9 tuple \u7b49\u590d\u5408\u7c7b\u578b\u81ea\u5b9a\u4e49\u54c8\u5e0c\u51fd\u6570"},{"location":"stl_map/#_71","text":"template inline size_t hash_combine(Ts const &...ts) { return (std::hash()(ts) ^ ...); // \u628a\u4efb\u610f\u591a\u4e2a\u5143\u7d20\u54c8\u5e0c\u901a\u8fc7\u201c\u4f4d\u5f02\u6216(^)\u201d\u62fc\u51d1\u6210\u4e00\u4e2a\u5355\u72ec\u7684\u54c8\u5e0c } template struct std::hash> { size_t operator()(std::tuple const &x) const { // std::apply \u4f1a\u628a tuple \u91cc\u7684\u5143\u7d20\u5168\u90e8\u5c55\u5f00\u6765\u8c03\u7528 hash_combine\uff0c\u76f8\u5f53\u4e8e Python \u91cc\u7684 *args return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 106 \u8fd9\u91cc\u7684\u8ba1\u7b97\u662f\uff1a42 ^ 64 = 106\uff0c\u4f4d\u5f02\u6216\u7684\u77e5\u8bc6\u53ef\u4ee5\u53bb Bing \u641c\u7d22\u4e00\u4e0b\uff0c\u6216\u8005\u95ee\u4e00\u4e0b GPT\uff0cCS \u5b66\u751f\u5e94\u8be5\u90fd\u77e5\u9053\u7684\u3002","title":"\u8bd5\u8bd5\u770b\u6548\u679c\u5427\uff01"},{"location":"stl_map/#hash_combine","text":"\u4f46\u662f\u7b80\u7b80\u5355\u5355\u7528\u4e00\u4e2a\u4f4d\u5f02\u6216 ^ \u6765\u628a\u4e24\u4e2a\u6210\u5458\u7684\u54c8\u5e0c\u7ec4\u5408\u8d77\u6765\uff0c\u6709\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u5982\u679c tuple \u91cc\u7684\u4e24\u4e2a\u6210\u5458\u503c\u521a\u597d\u4e00\u6837\uff0c\u5219\u5176\u4e24\u4e2a\u54c8\u5e0c\u503c\u4e5f\u4f1a\u4e00\u6837\uff0c\u90a3\u4e48\u4ed6\u4eec\u901a\u8fc7\u4f4d\u5f02\u6216 ^ \u5408\u5e76\u7684\u7ed3\u679c\u5c31\u4f1a\u59cb\u7ec8\u4e3a 0\u3002 \u4f8b\u5982\u4e0d\u8bba (42, 42) \u8fd8\u662f (64, 64) \u8fd9\u4e24\u4e2a tuple\uff0c\u4ed6\u4eec\u7684\u54c8\u5e0c\u503c\u90fd\u4f1a\u4e3a 0\u3002\u660e\u660e\u5177\u4f53\u503c\u4e0d\u540c\u54c8\u5e0c\u503c\u5374\u76f8\u540c\uff0c\u8fd9\u5c31\u662f\u53d1\u751f\u4e86\u54c8\u5e0c\u51b2\u7a81\uff0c\u8fd9\u4f1a\u4e25\u91cd\u5f71\u54cd unordered_map \u7684\u6027\u80fd\uff0c\u662f\u5fc5\u987b\u907f\u514d\u7684\u3002 \u7528 + \u6765\u7ec4\u5408\u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5982\u679c\u7b2c\u4e00\u4e2a\u6210\u5458\u521a\u597d\u662f\u53e6\u4e00\u4e2a\u7684\u76f8\u53cd\u6570\uff0c\u6216\u53ea\u8981\u662f\u4e24\u4e2a\u6570\u52a0\u8d77\u6765\u548c\u76f8\u7b49\uff0c\u5c31\u4f1a\u51b2\u7a81\u3002 \u4f8b\u5982\u5982\u679c\u6211\u4eec\u7528 unordered_map \u6784\u5efa\u4e00\u5f20\u5730\u56fe\u7684\u8bdd\uff0c\u5c31\u53d1\u73b0\u5f53\u73a9\u5bb6\u5728\u5f80\u659c\u4e0a\u65b9\u79fb\u52a8\u65f6\u5c31\u4f1a\u53d8\u5f97\u7279\u522b\u5361\u987f\uff0c\u539f\u6765\u662f\u56e0\u4e3a\u73a9\u5bb6\u7684\u5386\u53f2\u8f68\u8ff9\u521a\u597d\u662f\u4e00\u6761 y = x \u7684\u66f2\u7ebf\uff0c\u659c\u7387\u4e3a 1\uff0c\u7531\u4e8e\u6211\u4eec\u91c7\u7528 ^ \u6765\u7ec4\u5408\u54c8\u5e0c\uff0c\u5c31\u5bfc\u81f4\u521a\u597d\u8fd9\u6761\u7ebf\u4e0a\u6240\u6709\u7684\u70b9\u90fd\u4f1a\u584c\u7f29\u5230 0 \u53f7\u6876\u53bb\uff0c\u8ba9 unordered_map \u9000\u5316\u6210\u4e86 O(N) O(N) \u590d\u6742\u5ea6\u3002","title":"\u66f4\u597d\u7684 hash_combine"},{"location":"stl_map/#boosthash_combine","text":"template inline size_t hash_combine(Ts const &...ts) { size_t h = 0; ((h ^= std::hash()(ts) + 0x9e3779b9 + (h << 6) + (h >> 2)), ...); return h; } template struct std::hash> { size_t operator()(std::tuple const &x) const { return std::apply(hash_combine, x); } }; int main() { tuple t(42, 64); size_t h = hash>()(t); print(t, \"\u7684\u54c8\u5e0c\u503c\u662f:\", h); return 0; } {42, 64} \u7684\u54c8\u5e0c\u503c\u662f: 175247763666 \u53ef\u4ee5\u770b\u5230\u968f\u673a\u6027\u5927\u5927\u63d0\u5347\u4e86\u3002","title":"\u6700\u5148\u8fdb\u7684\u662f boost::hash_combine \u7684\u65b9\u6cd5"},{"location":"stl_map/#_72","text":"\u7528 hash_combine \u6539\u8fdb\u521a\u521a Student \u7684\u54c8\u5e0c\u51fd\u6570\u3002 template <> struct std::hash { bool operator()(Student const &x) const { return hash_combine(hash()(x.name), hash(x.id), hash(x.sex)); } }; \u540c\u7406\u53ef\u5f97 array \u7684\u7279\u5316 template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u7d20\u6570\u4e58\u65b9\u6cd5\u6765\u63d0\u5347\u54c8\u5e0c\u51fd\u6570\u7684\u5747\u5300\u6027\u548c\u968f\u673a\u6027\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h = h * 18412483 + hasher(t); } return h; } }; unordered_map, int> stutab; \u91c7\u7528\u6700\u9ad8\u7ea7\u7684\uff0c\u57fa\u4e8e\u4f4d\u8fd0\u7b97\u7684\uff0c\u6700\u9ad8\u6548\u7684\uff0cboost::hash_combine \u7684\u5b9e\u73b0\uff1a template struct std::hash> { size_t operator()(std::array const &x) const { std::hash hasher; size_t h = 0; for (T const &t: x) { h ^= hasher(t) + 0x9e3779b9 + (h << 6) + (h >> 2); } return h; } }; unordered_map, int> stutab;","title":"\u5e94\u7528"},{"location":"stl_map/#_73","text":"","title":"\u7ecf\u5178\u6848\u4f8b"},{"location":"stl_map/#map-function","text":"TODO","title":"map \u548c function \u7ed3\u5408\u4f7f\u7528"},{"location":"stl_map/#map-variant","text":"","title":"map \u548c variant \u7ed3\u5408\u4f7f\u7528"},{"location":"stl_map/#map-string_view","text":"","title":"map \u548c string_view \u7ed3\u5408\u4f7f\u7528\u900f\u660e\u67e5\u627e\u6848\u4f8b"},{"location":"stl_map/#c-api","text":"Student(Student &&) = delete; // \u51b7\u77e5\u8bc6\uff1a\u53ea\u9700\u8981\u5220\u9664\u79fb\u52a8\u6784\u9020\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u81ea\u52a8\u5e2e\u4f60\u5220\u9664\u4e0b\u9762\u51e0\u4e2a\uff0c\u4e0d\u7528\u5199\u5168\uff1a // Student &operator=(Student &&) = delete; // Student(Student const &) = delete; // Student &operator=(Student const &) = delete; TODO","title":"\u5168\u5c40\u53e5\u67c4\u8868\u5b9e\u73b0\u4eff C \u8bed\u8a00 API"},{"location":"stl_map/#_74","text":"TODO","title":"\u5168\u5c40\u6ce8\u518c\u8868\u5b9e\u73b0\u52a8\u6001\u53cd\u5c04"},{"location":"stl_map/#_75","text":"TODO","title":"\u5e26\u7f13\u5b58\u7684\u7f16\u8bd1\u51fd\u6570"},{"location":"stl_map/#_76","text":"TODO","title":"\u95ee\u9898\uff1a\u591a\u7ebf\u7a0b\u5b89\u5168"},{"location":"stl_map/#_77","text":"\u6709\u624b\u4e4b\u524d\uff0c\u975e\u5e38\u597d\u7528 \u9a6c\u6876\u88c5\u9762\u5305 \u201c\u6790\u6784\u201d\u76f8\u4f9d1\u53f7 \u5c0f\u5f6d\u8001\u5e08\u8bed\u5f55 \u770b\u5230\u8001\u9f20\ud83d\udca9\u8fc7\u6fc0\u53cd\u5e94 \u300a\u597d\u53cb\u6e05\u9664\u8ba1\u5212\u300b \u5c0f\u5b66\u751f\u65e9\u64cd\u6392\u961f \u5c0f\u9ec4\u82b1\u8868\u793a\u9ec4\u724c\u8b66\u544a \u6258\u9a6c\u65af\u7834\u4ea7\u56de\u65cb http://c.biancheng.net/view/7236.html \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 \u21a9 https://en.cppreference.com/w/cpp/container/node_handle \u21a9 \u21a9 \u21a9 \u21a9","title":"\u672c\u671f\u5b5d\u70b9\u603b\u7ed3"},{"location":"symbols/","text":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage) \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 mq \u767d\u5728 \u5ddd\u4e0a \u66f0\uff1a \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u56e0\u4e3a Game \u5728\u6b64\u5904\u4e3a\u4e0d\u5b8c\u6574\u7c7b\u578b \u6211\u80fd\u660e\u767d\u5176\u610f\u601d\uff0c\u5b9a\u4e49\u4e00\u5b9a\u662f\u58f0\u660e\uff0c\u58f0\u660e\u5374\u4e0d\u4e00\u5b9a\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u7528\u4e86\uff1a\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u8bcd\u8bed\uff0c\u5f88\u4e13\u4e1a\u7684\u63aa\u8f9e\u3002 \u4e0d\u8fc7\u6211\u89c9\u5f97\u5927\u591a\u6570\u666e\u901a\u5f00\u53d1\u8005\u5e76\u4e0d\u591f\u6e05\u695a\u8fd9\u4e00\u70b9\uff0c\u770b\u5230\u8fd9\u6bb5\u6ce8\u91ca\u540c\u6837\u4f1a\u611f\u5230\u7591\u60d1\u3002 \u5728\u4ed6\u4eec\u773c\u91cc\u58f0\u660e\u548c\u5b9a\u4e49\u662f\u4e24\u79cd\u4e1c\u897f\uff0c\u6b64\u5904\u5982\u679c\u76f4\u63a5\u7528\u58f0\u660e\u5b83\u4eec\u53ef\u80fd\u5c31\u4e0d\u4f1a\u6709\u7406\u89e3\u95ee\u9898\u4e86\u3002\u4f8b\u5982\uff1a\u201c\u53ea\u662f\u58f0\u660e\uff0c\u4e0d\u662f\u5b9a\u4e49\u201d\u4e4b\u7c7b\u7684\u63aa\u8f9e\u3002 \u6216\u8bb8\u6211\u4eec\u5e94\u8be5\u8003\u8651\u5728\u4fdd\u8bc1\u4e13\u4e1a\u4ee5\u53ca\u4e25\u8c28\u7684\u60c5\u51b5\u4e0b\uff0c\u7a0d\u5fae\u8865\u5145\u89e3\u91ca\u4e00\u4e0b\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u7528\u8bcd\u3002 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage) \u51fd\u6570\u548c\u53d8\u91cf\uff0c\u5728\u5bf9\u5916\u7684\u53ef\u89c1\u6027\u8fd9\u65b9\u9762\uff0c\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u5916\u90e8\u94fe\u63a5 (ODR external linkage)\uff1a\u5bf9\u5176\u4ed6\u7ffb\u8bd1\u5355\u5143\u53ef\u89c1 \u5171\u4eab\u94fe\u63a5 (non-ODR external linkage) \u5185\u90e8\u94fe\u63a5 (internal linkage) \u65e0\u94fe\u63a5 (no linkage) \u51fd\u6570\u548c\u53d8\u91cf\u7684\u53ef\u89c1\u6027\u8fd9\u4e00\u5c5e\u6027\uff0c\u88ab C++ \u5b98\u65b9\u79f0\u4e3a\u94fe\u63a5\uff08linkage\uff09\uff0c\u662f\u56e0\u4e3a\u7b26\u53f7\u7684\u53ef\u89c1\u6027\u5904\u7406\u901a\u5e38\u662f\u94fe\u63a5\u5668\uff08ld\uff09\u8d1f\u8d23\u7684\uff0c\u4e0d\u540c\u7c7b\u578b\u94fe\u63a5\uff08linkage\uff09\u7684\u6548\u679c\uff0c\u5728\u94fe\u63a5\uff08link\uff09\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002 \u5b9a\u4e49\u5728\u5168\u5c40\uff08\u540d\u5b57\u7a7a\u95f4\uff09\u4e2d\u7684\u60c5\u51b5\uff1a int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int i; // \u53d8\u91cf\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d inline int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d \u5b9a\u4e49\u5728\u7c7b\uff08class\uff09\u4e2d\u7684\u60c5\u51b5\uff1a struct Class { int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u65e0\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d };","title":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"symbols/#_1","text":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09 \u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406 \u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027 \u7ffb\u8bd1\u5355\u5143 (TU) \u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage)","title":"\u91cd\u65b0\u8ba4\u8bc6\u58f0\u660e\u4e0e\u5b9a\u4e49\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"symbols/#_2","text":"mq \u767d\u5728 \u5ddd\u4e0a \u66f0\uff1a \u975e\u5b9a\u4e49\u58f0\u660e\uff0c\u56e0\u4e3a Game \u5728\u6b64\u5904\u4e3a\u4e0d\u5b8c\u6574\u7c7b\u578b \u6211\u80fd\u660e\u767d\u5176\u610f\u601d\uff0c\u5b9a\u4e49\u4e00\u5b9a\u662f\u58f0\u660e\uff0c\u58f0\u660e\u5374\u4e0d\u4e00\u5b9a\u662f\u5b9a\u4e49\u3002\u6240\u4ee5\u7528\u4e86\uff1a\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u8bcd\u8bed\uff0c\u5f88\u4e13\u4e1a\u7684\u63aa\u8f9e\u3002 \u4e0d\u8fc7\u6211\u89c9\u5f97\u5927\u591a\u6570\u666e\u901a\u5f00\u53d1\u8005\u5e76\u4e0d\u591f\u6e05\u695a\u8fd9\u4e00\u70b9\uff0c\u770b\u5230\u8fd9\u6bb5\u6ce8\u91ca\u540c\u6837\u4f1a\u611f\u5230\u7591\u60d1\u3002 \u5728\u4ed6\u4eec\u773c\u91cc\u58f0\u660e\u548c\u5b9a\u4e49\u662f\u4e24\u79cd\u4e1c\u897f\uff0c\u6b64\u5904\u5982\u679c\u76f4\u63a5\u7528\u58f0\u660e\u5b83\u4eec\u53ef\u80fd\u5c31\u4e0d\u4f1a\u6709\u7406\u89e3\u95ee\u9898\u4e86\u3002\u4f8b\u5982\uff1a\u201c\u53ea\u662f\u58f0\u660e\uff0c\u4e0d\u662f\u5b9a\u4e49\u201d\u4e4b\u7c7b\u7684\u63aa\u8f9e\u3002 \u6216\u8bb8\u6211\u4eec\u5e94\u8be5\u8003\u8651\u5728\u4fdd\u8bc1\u4e13\u4e1a\u4ee5\u53ca\u4e25\u8c28\u7684\u60c5\u51b5\u4e0b\uff0c\u7a0d\u5fae\u8865\u5145\u89e3\u91ca\u4e00\u4e0b\u201c\u975e\u5b9a\u4e49\u58f0\u660e\u201d\u8fd9\u4e2a\u7528\u8bcd\u3002","title":"\u6211\u4eec\u8981\u7262\u8bb0\u767d\u6307\u5bfc\u8bf4\u7684\u9053\u7406"},{"location":"symbols/#_3","text":"","title":"\u591a\u6587\u4ef6\u7f16\u8bd1\u7684\u5fc5\u8981\u6027"},{"location":"symbols/#tu","text":"","title":"\u7ffb\u8bd1\u5355\u5143 (TU)"},{"location":"symbols/#linkage","text":"\u51fd\u6570\u548c\u53d8\u91cf\uff0c\u5728\u5bf9\u5916\u7684\u53ef\u89c1\u6027\u8fd9\u65b9\u9762\uff0c\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a \u5916\u90e8\u94fe\u63a5 (ODR external linkage)\uff1a\u5bf9\u5176\u4ed6\u7ffb\u8bd1\u5355\u5143\u53ef\u89c1 \u5171\u4eab\u94fe\u63a5 (non-ODR external linkage) \u5185\u90e8\u94fe\u63a5 (internal linkage) \u65e0\u94fe\u63a5 (no linkage) \u51fd\u6570\u548c\u53d8\u91cf\u7684\u53ef\u89c1\u6027\u8fd9\u4e00\u5c5e\u6027\uff0c\u88ab C++ \u5b98\u65b9\u79f0\u4e3a\u94fe\u63a5\uff08linkage\uff09\uff0c\u662f\u56e0\u4e3a\u7b26\u53f7\u7684\u53ef\u89c1\u6027\u5904\u7406\u901a\u5e38\u662f\u94fe\u63a5\u5668\uff08ld\uff09\u8d1f\u8d23\u7684\uff0c\u4e0d\u540c\u7c7b\u578b\u94fe\u63a5\uff08linkage\uff09\u7684\u6548\u679c\uff0c\u5728\u94fe\u63a5\uff08link\uff09\u7684\u65f6\u5019\u624d\u4f1a\u751f\u6548\u3002 \u5b9a\u4e49\u5728\u5168\u5c40\uff08\u540d\u5b57\u7a7a\u95f4\uff09\u4e2d\u7684\u60c5\u51b5\uff1a int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int i; // \u53d8\u91cf\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d extern int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d inline int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5185\u90e8\u94fe\u63a5\u201d \u5b9a\u4e49\u5728\u7c7b\uff08class\uff09\u4e2d\u7684\u60c5\u51b5\uff1a struct Class { int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u65e0\u94fe\u63a5\u201d int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d inline static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5171\u4eab\u94fe\u63a5\u201d static int i; // \u53d8\u91cf\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x); // \u51fd\u6570\u58f0\u660e\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d static int f(int x) {} // \u51fd\u6570\u58f0\u660e\u5e76\u5b9a\u4e49\u4e3a\u201c\u5916\u90e8\u94fe\u63a5\u201d };","title":"\u7b26\u53f7\u7684\u94fe\u63a5\u7c7b\u578b (linkage)"},{"location":"test_and_safe/","text":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09","title":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"test_and_safe/#_1","text":"","title":"\u6d4b\u8bd5\u4e0e\u5b89\u5168\u8bdd\u9898\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/","text":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09 \u521b\u5efa\u7ebf\u7a0b TODO \u4e3a\u4ec0\u4e48\u6570\u636e\u7ade\u4e89 if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } auto it = table.find(\"\u5c0f\u5f6d\u8001\u5e08\"); if (it != table.end()) { return it->second; } else { return 0; } \u5c0f\u5f6d\u8001\u5e08\u5bf9\u8bdd\u4e00\u5219 \u5173\u4e8e SharedPtr \u7684\u539f\u5b50\u5b89\u5168\u5b9e\u73b0\u3002 \u5bf9\u8bdd\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/issues/4 \u4ee3\u7801\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/blob/main/SharedPtr.hpp sharedptr\u5f15\u7528\u8ba1\u6570\u51cf\u88ab\u5c01\u88c5\u6210\u5982\u4e0b\u7684\u51fd\u6570 void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u8be5if\u5757\u5148\u5224\u65ad\u539f\u59cb\u5f15\u7528\u8ba1\u6570\u662f\u5426\u7b49\u4e8e1\uff0c\u5982\u679c\u4e3a\u771f\u5219\u8fdb\u884cdelete\u3002\u7136\u800c\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u5e76\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002\u662f\u5426\u5b58\u5728\u8fd9\u6837\u4e00\u79cd\u60c5\u51b5\uff1a\u5224\u65ad\u6761\u4ef6\u6210\u7acb\uff0c\u4f46\u5728delete\u524d\u6709\u5176\u5b83\u7ebf\u7a0b\u7ed9\u5f15\u7528\u8ba1\u6570+1\uff1f\u6b64\u65f6\u8fdb\u884cdelete\u5c31\u51fa\u9519\u4e86\u5427 \u5c0f\u5f6d\u8001\u5e08 \u6ca1\u6709\u95ee\u9898\u7684\uff0c\u56e0\u4e3afetch_sub\u8fd4\u56de1\uff0c\u5b9e\u9645\u4e0a\u8bf4\u660e\u5f15\u7528\u8ba1\u6570\u5df2\u7ecf\u662f0\u4e86\uff0cfetch_sub\u8fd4\u56de\u7684\u662f\u201c\u65e7\u503c\u201d\uff0c\u76f8\u5f53\u4e8e\u540e\u7f6ei\u2013\uff0c\u77e5\u9053\u5427\u3002\u5982\u679c\u5df2\u7ecf\u4e3a0\uff0c\u90a3\u5c31\u6ca1\u6709\u4efb\u4f55\u5176\u4ed6\u4eba\u6301\u6709\u8be5\u6307\u9488\uff0c\u6211\u662f\u72ec\u5360\u7684\uff0c\u90a3\u968f\u4fbfdelete\u3002 \u8fd9\u6837\u5427\uff0c\u6211\u4e5f\u542c\u4e0d\u61c2\u4f60\u5728\u8bb2\u4ec0\u4e48\uff0c\u4f60\u6765\u5199\u4e00\u4efd\u4f60\u8ba4\u4e3a\u4f1a\u4ea7\u751f\u95ee\u9898\u7684\u4ee3\u7801\uff0c\u8ba9\u6211\u5206\u6790\u3002 \u540c\u5b66 \u6211\u8bbe\u60f3\u4e86\u5982\u4e0b\u7684\u4ee3\u7801\uff1a shared_ptr a = make_shared(); void fun1() { a = nullptr; // \u6790\u6784a } void func2() { auto b = a; // \u62f7\u8d1da\u5230b } int main(){ auto t1=std::thread(func1); auto t2=std::thread(func2); t1.join(); t2.join(); return 0; } \u5728\u8fd9\u6bb5\u4ee3\u7801\u4e2d\uff0c\u7ebf\u7a0b1\u6790\u6784a\uff0c\u800c\u7ebf\u7a0b2\u62f7\u8d1da\u5230b\u3002\u7531\u4e8e\u591a\u7ebf\u7a0b\u7684\u7f18\u6545\uff0c\u6211\u8ba4\u4e3a\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u7684\u60c5\u51b5\uff0c\u7ebf\u7a0b1\u6267\u884c\u5224\u65ad\u65f6 if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) \u7531\u4e8efunc2\u521a\u8fdb\u5165\u5c1a\u672a\u6267\u884c\u62f7\u8d1d\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u7b49\u4e8e1\u8fd8\u4e0d\u662f2\uff0c\u6240\u4ee5\u8be5\u5224\u65ad\u4e3atrue\u3002\u4e8e\u662f\uff0c\u7ebf\u7a0b1\u51c6\u5907\u6267\u884c delete this \u5c06_SpCounter\u91ca\u653e\uff0c\u5c31\u5728\u8fd9\u65f6\u7ebf\u7a0b2\u5c06func2\u5f7b\u5e95\u6267\u884c\u4e86\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u53c8\u4ece0\u53d8\u4e3a\u4e861\uff0c\u7136\u800c\u7ebf\u7a0b1\u5e76\u4e0d\u77e5\u9053\u8fd9\u4e2a\u53d8\u5316\uff0c\u5b83\u4ecd\u7136\u6309\u7167\u539f\u672c\u7684\u8f68\u8ff9\u53bb\u6267\u884cdelete this\u3002\u6240\u4ee5\u6211\u8ba4\u4e3a\u8fd9\u5c31\u51fa\u9519\u4e86\uff0c\u800c\u51fa\u9519\u7684\u539f\u56e0\u662f void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u6b64\u5904\u7684\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u800c\u975e\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002 \u5f88\u62b1\u6b49\u4e4b\u524d\u672a\u80fd\u53ca\u65f6\u56de\u590d \u5c0f\u5f6d\u8001\u5e08 \u662f\u7684\uff0c\u8fd9\u6bb5\u4ee3\u7801\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u7136\u800c C++ \u6807\u51c6\u53ea\u8981\u6c42\u4e86\uff1a - \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 - \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6211\u7684\u539f\u5b50\u53d8\u91cf\u5df2\u7ecf\u4fdd\u8bc1\u4e86 \u62f7\u8d1d+\u62f7\u8d1d \u7684\u5b89\u5168\uff0c\u7b26\u5408 C++ \u6807\u51c6\u7684\u8981\u6c42\u3002 \u6790\u6784+\u62f7\u8d1d \u7684\u60c5\u51b5\uff0cC++ \u6807\u51c6\u5c31\u5e76\u4e0d\u8981\u6c42\u5b89\u5168\uff0c\u6240\u4ee5\u6211\u7684 shared_ptr \u4e5f\u6ca1\u6709\u8d23\u4efb\u53bb\u4fdd\u8bc1\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u5b89\u5168\u3002 \u6bd4\u5982\u6807\u51c6\u4e0d\u8981\u6c42 vector \u7684 clear \u548c push_back \u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u90a3\u4e48\u6211\u5c31\u4e0d\u9700\u8981\u628a vector \u5b9e\u73b0\u4e3a\u5b89\u5168\u7684\u3002 \u5982\u679c\u6807\u51c6\u89c4\u5b9a\u4e86\u54ea\u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u6211\u518d\u53bb\u505a\u3002 \u6bd4\u5982\u6807\u51c6\u5c31\u89c4\u5b9a\u4e86 size \u548c data \u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u6211\u53ea\u9700\u8981\u7b26\u5408\u8fd9\u4e2a\u5c31\u53ef\u4ee5\u3002 \u6807\u51c6\u90fd\u6ca1\u6709\u89c4\u5b9a\u5fc5\u987b\u5b89\u5168\u7684\u60c5\u51b5\uff0c\u6211\u7684\u5bb9\u5668\u5982\u679c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6211\u4e0d\u8d1f\u8d23\u4efb\u3002 \u4f8b\u5982\uff0cC++ \u6807\u51c6\u5bf9 shared_ptr \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 C++ \u6807\u51c6\u5bf9 atomic> \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6240\u4ee5\uff0c\u53ea\u6709\u5f53\u6211\u662f\u5728\u5b9e\u73b0atomic_shared_ptr\u65f6\uff0c\u624d\u9700\u8981\u8003\u8651\u4f60\u8bf4\u7684\u8fd9\u79cd\u60c5\u51b5\uff0c\u800c\u6211\u73b0\u5728\u5b9e\u73b0\u7684\u662fshared_ptr\uff0c\u4e0d\u9700\u8981\u8003\u8651 \u6790\u6784+\u62f7\u8d1d \u7684\u5b89\u5168\u3002 \u4e3a\u4ec0\u4e48\u62f7\u8d1d+\u62f7\u8d1d\u662f\u5b89\u5168\u7684\uff1f\u6211\u600e\u4e48\u6ca1\u770b\u5230cppreference\u8bf4\uff1f\u8fd9\u5f88\u590d\u6742\uff0c\u662f\u53e6\u4e00\u53e5\u8bdd\u91cc\u900f\u9732\u7684\u901a\u7528\u89c4\u5219\uff0c\u9002\u7528\u4e8e\u6240\u6709\u5bb9\u5668\uff0c\u5305\u62ecshared_ptr\u3001unique_ptr\u3001vector\u7b49\u5168\u90e8\u7684\u5bb9\u5668\uff1a \u4e24\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4e00\u4e2a\u975econst\u6210\u5458\u51fd\u6570+\u4e00\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8fd9\u53e5\u8bdd\u81ea\u52a8\u9002\u7528\u4e8e\u6240\u6709\u7684\u5bb9\u5668\u4e86\uff0c\u6240\u4ee5\u4f60\u770b\u5230shared_ptr\u91cc\u6ca1\u6709\u8bf4\uff0c\u4f46\u662f\u6211\u77e5\u9053\u4ed6\u662f\u5728\u53e6\u4e00\u4e2a\u5173\u4e8e\u7ebf\u7a0b\u5b89\u5168\u7684\u9875\u9762\u4e0a\u3002 \u90a3\u4e48\u5f88\u660e\u663e\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570 shared_ptr(shared_ptr const &that) \u662fconst\u7684\uff08\u5bf9\u4e8e\u88ab\u62f7\u8d1d\u7684that\uff09\uff0c\u800c\u6790\u6784\u51fd\u6570\u90fd\u662f\u975econst\u7684\uff0c\u6240\u4ee5\u5982\u679c\u6ca1\u6709\u7279\u522b\u8bf4\u660e\uff0c\u4e00\u4e2a\u5bb9\u5668\u540c\u65f6\u8c03\u7528\u62f7\u8d1d+\u6790\u6784\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u800catomic_shared_ptr\u5c31\u5c5e\u4e8e\u7279\u522b\u8bf4\u660e\u4e86\uff0c\u6240\u4ee5\u4ed6\u7279\u522b\u5730\u540c\u65f6\u8bbf\u95eeconst\u548c\u975econst\u51fd\u6570\u662f\u5b89\u5168\u7684\u3002 \u5b8c\u6574\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u89c4\u5219\u8868\uff1a \u8bfb+\u8bfb=\u5b89\u5168 \u8bfb+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u5199+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u6240\u4ee5\u5b9e\u9645\u4e0asharedptr\u6240\u8c13\u7684\u201c\u7ebf\u7a0b\u5b89\u5168\u201d\uff0c\u53ea\u4e0d\u8fc7\u662f\u62f7\u8d1d+\u62f7\u8d1d\u8fd9\u4e00\u60c5\u51b5\u7684\u5b89\u5168\u548c\u62f7\u8d1d+\u6790\u6784\u4e0d\u540c shared_ptr \u5b9e\u4f8b\uff0c\u540c\u4e00\u4e2a shared_ptr \u7684\u5e76\u53d1\u975econst\u8bbf\u95ee\u662f\u6ca1\u4fdd\u8bc1\u7684\uff0c shared_ptr \u6307\u5411\u7684\u90a3\u4e2a T \u4e5f\u662f\u4e0d\u4fdd\u8bc1\u7684\uff08\u7531 T \u7684\u5b9e\u73b0\u8005\u201c\u4f60\u201d\u6765\u4fdd\u8bc1\uff09\u3002 shared_ptr \u4e0d\u662f\u6709\u4e09\u5c42\u5417\uff1f\u901a\u4fd7\u7684\u8bf4\u5c31\u662f\u4ed6\u53ea\u9700\u8981\u4fdd\u8bc1\u4e2d\u95f4\u8fd9\u5c42\u63a7\u5236\u5757\u7684\u7ebf\u7a0b\u5b89\u5168\u6027\uff0c\u4e0d\u4fdd\u8bc1 shared_ptr \u5bf9\u8c61\u548c T \u5bf9\u8c61\u7684\u5b89\u5168\u6027\u3002","title":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/#c","text":"","title":"C++ \u591a\u7ebf\u7a0b\u7f16\u7a0b\uff08\u672a\u5b8c\u5de5\uff09"},{"location":"threading/#_1","text":"TODO","title":"\u521b\u5efa\u7ebf\u7a0b"},{"location":"threading/#_2","text":"if (table.count(\"\u5c0f\u5f6d\u8001\u5e08\")) { return table.at(\"\u5c0f\u5f6d\u8001\u5e08\"); } else { return 0; } auto it = table.find(\"\u5c0f\u5f6d\u8001\u5e08\"); if (it != table.end()) { return it->second; } else { return 0; }","title":"\u4e3a\u4ec0\u4e48\u6570\u636e\u7ade\u4e89"},{"location":"threading/#_3","text":"\u5173\u4e8e SharedPtr \u7684\u539f\u5b50\u5b89\u5168\u5b9e\u73b0\u3002 \u5bf9\u8bdd\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/issues/4 \u4ee3\u7801\u5730\u5740\uff1ahttps://github.com/parallel101/stl1weekend/blob/main/SharedPtr.hpp sharedptr\u5f15\u7528\u8ba1\u6570\u51cf\u88ab\u5c01\u88c5\u6210\u5982\u4e0b\u7684\u51fd\u6570 void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u8be5if\u5757\u5148\u5224\u65ad\u539f\u59cb\u5f15\u7528\u8ba1\u6570\u662f\u5426\u7b49\u4e8e1\uff0c\u5982\u679c\u4e3a\u771f\u5219\u8fdb\u884cdelete\u3002\u7136\u800c\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u5e76\u4e0d\u662f\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002\u662f\u5426\u5b58\u5728\u8fd9\u6837\u4e00\u79cd\u60c5\u51b5\uff1a\u5224\u65ad\u6761\u4ef6\u6210\u7acb\uff0c\u4f46\u5728delete\u524d\u6709\u5176\u5b83\u7ebf\u7a0b\u7ed9\u5f15\u7528\u8ba1\u6570+1\uff1f\u6b64\u65f6\u8fdb\u884cdelete\u5c31\u51fa\u9519\u4e86\u5427 \u5c0f\u5f6d\u8001\u5e08 \u6ca1\u6709\u95ee\u9898\u7684\uff0c\u56e0\u4e3afetch_sub\u8fd4\u56de1\uff0c\u5b9e\u9645\u4e0a\u8bf4\u660e\u5f15\u7528\u8ba1\u6570\u5df2\u7ecf\u662f0\u4e86\uff0cfetch_sub\u8fd4\u56de\u7684\u662f\u201c\u65e7\u503c\u201d\uff0c\u76f8\u5f53\u4e8e\u540e\u7f6ei\u2013\uff0c\u77e5\u9053\u5427\u3002\u5982\u679c\u5df2\u7ecf\u4e3a0\uff0c\u90a3\u5c31\u6ca1\u6709\u4efb\u4f55\u5176\u4ed6\u4eba\u6301\u6709\u8be5\u6307\u9488\uff0c\u6211\u662f\u72ec\u5360\u7684\uff0c\u90a3\u968f\u4fbfdelete\u3002 \u8fd9\u6837\u5427\uff0c\u6211\u4e5f\u542c\u4e0d\u61c2\u4f60\u5728\u8bb2\u4ec0\u4e48\uff0c\u4f60\u6765\u5199\u4e00\u4efd\u4f60\u8ba4\u4e3a\u4f1a\u4ea7\u751f\u95ee\u9898\u7684\u4ee3\u7801\uff0c\u8ba9\u6211\u5206\u6790\u3002 \u540c\u5b66 \u6211\u8bbe\u60f3\u4e86\u5982\u4e0b\u7684\u4ee3\u7801\uff1a shared_ptr a = make_shared(); void fun1() { a = nullptr; // \u6790\u6784a } void func2() { auto b = a; // \u62f7\u8d1da\u5230b } int main(){ auto t1=std::thread(func1); auto t2=std::thread(func2); t1.join(); t2.join(); return 0; } \u5728\u8fd9\u6bb5\u4ee3\u7801\u4e2d\uff0c\u7ebf\u7a0b1\u6790\u6784a\uff0c\u800c\u7ebf\u7a0b2\u62f7\u8d1da\u5230b\u3002\u7531\u4e8e\u591a\u7ebf\u7a0b\u7684\u7f18\u6545\uff0c\u6211\u8ba4\u4e3a\u4f1a\u51fa\u73b0\u4ee5\u4e0b\u7684\u60c5\u51b5\uff0c\u7ebf\u7a0b1\u6267\u884c\u5224\u65ad\u65f6 if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) \u7531\u4e8efunc2\u521a\u8fdb\u5165\u5c1a\u672a\u6267\u884c\u62f7\u8d1d\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u7b49\u4e8e1\u8fd8\u4e0d\u662f2\uff0c\u6240\u4ee5\u8be5\u5224\u65ad\u4e3atrue\u3002\u4e8e\u662f\uff0c\u7ebf\u7a0b1\u51c6\u5907\u6267\u884c delete this \u5c06_SpCounter\u91ca\u653e\uff0c\u5c31\u5728\u8fd9\u65f6\u7ebf\u7a0b2\u5c06func2\u5f7b\u5e95\u6267\u884c\u4e86\uff0c\u6b64\u65f6\u5f15\u7528\u8ba1\u6570\u53c8\u4ece0\u53d8\u4e3a\u4e861\uff0c\u7136\u800c\u7ebf\u7a0b1\u5e76\u4e0d\u77e5\u9053\u8fd9\u4e2a\u53d8\u5316\uff0c\u5b83\u4ecd\u7136\u6309\u7167\u539f\u672c\u7684\u8f68\u8ff9\u53bb\u6267\u884cdelete this\u3002\u6240\u4ee5\u6211\u8ba4\u4e3a\u8fd9\u5c31\u51fa\u9519\u4e86\uff0c\u800c\u51fa\u9519\u7684\u539f\u56e0\u662f void _M_decref() noexcept { if (_M_refcnt.fetch_sub(1, std::memory_order_relaxed) == 1) { delete this; } } \u6b64\u5904\u7684\u5224\u65ad\u548cdelete\u662f\u4e24\u4e2a\u64cd\u4f5c\uff0c\u800c\u975e\u4e00\u4e2a\u539f\u5b50\u64cd\u4f5c\u3002 \u5f88\u62b1\u6b49\u4e4b\u524d\u672a\u80fd\u53ca\u65f6\u56de\u590d \u5c0f\u5f6d\u8001\u5e08 \u662f\u7684\uff0c\u8fd9\u6bb5\u4ee3\u7801\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u7136\u800c C++ \u6807\u51c6\u53ea\u8981\u6c42\u4e86\uff1a - \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 - \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6211\u7684\u539f\u5b50\u53d8\u91cf\u5df2\u7ecf\u4fdd\u8bc1\u4e86 \u62f7\u8d1d+\u62f7\u8d1d \u7684\u5b89\u5168\uff0c\u7b26\u5408 C++ \u6807\u51c6\u7684\u8981\u6c42\u3002 \u6790\u6784+\u62f7\u8d1d \u7684\u60c5\u51b5\uff0cC++ \u6807\u51c6\u5c31\u5e76\u4e0d\u8981\u6c42\u5b89\u5168\uff0c\u6240\u4ee5\u6211\u7684 shared_ptr \u4e5f\u6ca1\u6709\u8d23\u4efb\u53bb\u4fdd\u8bc1\u8fd9\u79cd\u60c5\u51b5\u4e0b\u7684\u5b89\u5168\u3002 \u6bd4\u5982\u6807\u51c6\u4e0d\u8981\u6c42 vector \u7684 clear \u548c push_back \u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u90a3\u4e48\u6211\u5c31\u4e0d\u9700\u8981\u628a vector \u5b9e\u73b0\u4e3a\u5b89\u5168\u7684\u3002 \u5982\u679c\u6807\u51c6\u89c4\u5b9a\u4e86\u54ea\u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u5b89\u5168\u7684\uff0c\u6211\u518d\u53bb\u505a\u3002 \u6bd4\u5982\u6807\u51c6\u5c31\u89c4\u5b9a\u4e86 size \u548c data \u4e24\u4e2a\u51fd\u6570\u540c\u65f6\u8c03\u7528\u662f\u7ebf\u7a0b\u5b89\u5168\u7684\uff0c\u6211\u53ea\u9700\u8981\u7b26\u5408\u8fd9\u4e2a\u5c31\u53ef\u4ee5\u3002 \u6807\u51c6\u90fd\u6ca1\u6709\u89c4\u5b9a\u5fc5\u987b\u5b89\u5168\u7684\u60c5\u51b5\uff0c\u6211\u7684\u5bb9\u5668\u5982\u679c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u6211\u4e0d\u8d1f\u8d23\u4efb\u3002 \u4f8b\u5982\uff0cC++ \u6807\u51c6\u5bf9 shared_ptr \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 C++ \u6807\u51c6\u5bf9 atomic> \u7684\u8981\u6c42\uff1a \u6790\u6784+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u62f7\u8d1d+\u62f7\u8d1d \u540c\u65f6\u53d1\u751f\uff0c\u662f\u5b89\u5168\u7684\u3002 \u6240\u4ee5\uff0c\u53ea\u6709\u5f53\u6211\u662f\u5728\u5b9e\u73b0atomic_shared_ptr\u65f6\uff0c\u624d\u9700\u8981\u8003\u8651\u4f60\u8bf4\u7684\u8fd9\u79cd\u60c5\u51b5\uff0c\u800c\u6211\u73b0\u5728\u5b9e\u73b0\u7684\u662fshared_ptr\uff0c\u4e0d\u9700\u8981\u8003\u8651 \u6790\u6784+\u62f7\u8d1d \u7684\u5b89\u5168\u3002 \u4e3a\u4ec0\u4e48\u62f7\u8d1d+\u62f7\u8d1d\u662f\u5b89\u5168\u7684\uff1f\u6211\u600e\u4e48\u6ca1\u770b\u5230cppreference\u8bf4\uff1f\u8fd9\u5f88\u590d\u6742\uff0c\u662f\u53e6\u4e00\u53e5\u8bdd\u91cc\u900f\u9732\u7684\u901a\u7528\u89c4\u5219\uff0c\u9002\u7528\u4e8e\u6240\u6709\u5bb9\u5668\uff0c\u5305\u62ecshared_ptr\u3001unique_ptr\u3001vector\u7b49\u5168\u90e8\u7684\u5bb9\u5668\uff1a \u4e24\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u6ca1\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u4e00\u4e2a\u975econst\u6210\u5458\u51fd\u6570+\u4e00\u4e2aconst\u6210\u5458\u51fd\u6570\uff0c\u540c\u65f6\u53d1\u751f\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8fd9\u53e5\u8bdd\u81ea\u52a8\u9002\u7528\u4e8e\u6240\u6709\u7684\u5bb9\u5668\u4e86\uff0c\u6240\u4ee5\u4f60\u770b\u5230shared_ptr\u91cc\u6ca1\u6709\u8bf4\uff0c\u4f46\u662f\u6211\u77e5\u9053\u4ed6\u662f\u5728\u53e6\u4e00\u4e2a\u5173\u4e8e\u7ebf\u7a0b\u5b89\u5168\u7684\u9875\u9762\u4e0a\u3002 \u90a3\u4e48\u5f88\u660e\u663e\uff0c\u62f7\u8d1d\u6784\u9020\u51fd\u6570 shared_ptr(shared_ptr const &that) \u662fconst\u7684\uff08\u5bf9\u4e8e\u88ab\u62f7\u8d1d\u7684that\uff09\uff0c\u800c\u6790\u6784\u51fd\u6570\u90fd\u662f\u975econst\u7684\uff0c\u6240\u4ee5\u5982\u679c\u6ca1\u6709\u7279\u522b\u8bf4\u660e\uff0c\u4e00\u4e2a\u5bb9\u5668\u540c\u65f6\u8c03\u7528\u62f7\u8d1d+\u6790\u6784\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002\u800catomic_shared_ptr\u5c31\u5c5e\u4e8e\u7279\u522b\u8bf4\u660e\u4e86\uff0c\u6240\u4ee5\u4ed6\u7279\u522b\u5730\u540c\u65f6\u8bbf\u95eeconst\u548c\u975econst\u51fd\u6570\u662f\u5b89\u5168\u7684\u3002 \u5b8c\u6574\u7684\u591a\u7ebf\u7a0b\u5b89\u5168\u89c4\u5219\u8868\uff1a \u8bfb+\u8bfb=\u5b89\u5168 \u8bfb+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u5199+\u5199=\u672a\u5b9a\u4e49\u884c\u4e3a \u6240\u4ee5\u5b9e\u9645\u4e0asharedptr\u6240\u8c13\u7684\u201c\u7ebf\u7a0b\u5b89\u5168\u201d\uff0c\u53ea\u4e0d\u8fc7\u662f\u62f7\u8d1d+\u62f7\u8d1d\u8fd9\u4e00\u60c5\u51b5\u7684\u5b89\u5168\u548c\u62f7\u8d1d+\u6790\u6784\u4e0d\u540c shared_ptr \u5b9e\u4f8b\uff0c\u540c\u4e00\u4e2a shared_ptr \u7684\u5e76\u53d1\u975econst\u8bbf\u95ee\u662f\u6ca1\u4fdd\u8bc1\u7684\uff0c shared_ptr \u6307\u5411\u7684\u90a3\u4e2a T \u4e5f\u662f\u4e0d\u4fdd\u8bc1\u7684\uff08\u7531 T \u7684\u5b9e\u73b0\u8005\u201c\u4f60\u201d\u6765\u4fdd\u8bc1\uff09\u3002 shared_ptr \u4e0d\u662f\u6709\u4e09\u5c42\u5417\uff1f\u901a\u4fd7\u7684\u8bf4\u5c31\u662f\u4ed6\u53ea\u9700\u8981\u4fdd\u8bc1\u4e2d\u95f4\u8fd9\u5c42\u63a7\u5236\u5757\u7684\u7ebf\u7a0b\u5b89\u5168\u6027\uff0c\u4e0d\u4fdd\u8bc1 shared_ptr \u5bf9\u8c61\u548c T \u5bf9\u8c61\u7684\u5b89\u5168\u6027\u3002","title":"\u5c0f\u5f6d\u8001\u5e08\u5bf9\u8bdd\u4e00\u5219"},{"location":"type_rich_api/","text":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u5982\u4f55\u5199\u51fa\u6613\u4e8e\u7ef4\u62a4\u7684\u4ee3\u7801\uff0c\u963b\u6b62\u72af\u9519\uff1f \u7c7b\u578b\u5c31\u662f\u6700\u597d\u7684\u6ce8\u91ca\uff01 Type is all you need \u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 \u2014 \u2014 \u2014 \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u2014 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u2014 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u2014 \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u2014 RAII \u5c01\u88c5 \u2014 \u2014 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 void foo(string name, int age, int phone, int address); foo(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 12345, 67890); \u75db\u70b9\uff1a\u53c2\u6570\u591a\uff0c\u7c7b\u578b\u76f8\u4f3c\uff0c\u5bb9\u6613\u987a\u5e8f\u5199\u9519\u800c\u81ea\u5df1\u4e0d\u5bdf\u89c9 \u5929\u4e66\uff1a\u9605\u8bfb\u4ee3\u7801\u65f6\u770b\u4e0d\u89c1\u53c2\u6570\u540d\uff0c\u4e0d\u6e05\u695a\u6bcf\u4e2a\u53c2\u6570\u5206\u522b\u4ee3\u8868\u4ec0\u4e48 \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void foo(FooOptions opts); foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .phone = 12345, .address = 67890}); \u2714\ufe0f \u4f18\u96c5\uff0c\u6bcf\u4e2a\u53c2\u6570\u8d1f\u8d23\u505a\u4ec0\u4e48\u4e00\u76ee\u4e86\u7136 \u2014 \u4e5f\u6709\u67d0\u4e9b\u5927\u5382\u63a8\u5d07\u6ce8\u91ca\u53c2\u6570\u540d\u6765\u589e\u5f3a\u53ef\u8bfb\u6027\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*age=*/24, /*phone=*/12345, /*address=*/67890); \u4f46\u6ce8\u91ca\u53ef\u4ee5\u9a97\u4eba\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*phone=*/12345, /*age=*/24, /*address=*/67890); \u8fd9\u91cc age \u548c phone \u53c2\u6570\u5199\u53cd\u4e86\uff01\u9605\u8bfb\u8005\u5982\u679c\u4e0d\u770b\u4e0b foo \u7684\u5b9a\u4e49\uff0c\u6839\u672c\u53d1\u73b0\u4e0d\u4e86 \u800c\u4ee3\u7801\u4e0d\u4f1a\uff1a // \u5373\u4f7f\u987a\u5e8f\u5199\u9519\uff0c\u53ea\u8981\u540d\u5b57\u5199\u5bf9\u4f9d\u7136\u53ef\u4ee5\u6b63\u5e38\u8fd0\u884c foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u603b\u4e4b\uff0c\u597d\u7684 API \u8bbe\u8ba1\u7edd\u4e0d\u4f1a\u7ed9\u4eba\u7559\u4e0b\u72af\u9519\u7684\u673a\u4f1a\uff01 \u2014 \u518d\u6765\u770b\u4e00\u4e2a\u573a\u666f\uff0c\u5047\u8bbefoo\u5185\u90e8\u9700\u8981\u628a\u6240\u6709\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570bar\uff1a void bar(int index, string name, int age, int phone, int address); void foo(string name, int age, int phone, int address) { bar(get_hash_index(name), name, age, phone, address); } \u75db\u70b9\uff1a\u4f60\u9700\u8981\u4e0d\u65ad\u5730\u590d\u5236\u7c98\u8d34\u6240\u6709\u8fd9\u4e9b\u53c2\u6570\uff0c\u975e\u5e38\u5bb9\u6613\u6284\u9519 \u75db\u70b9\uff1a\u4e00\u65e6\u53c2\u6570\u7c7b\u578b\u6709\u6240\u4fee\u6539\uff0c\u6216\u8005\u8981\u52a0\u65b0\u53c2\u6570\uff0c\u9700\u8981\u6bcf\u4e2a\u5730\u65b9\u90fd\u6539\u4e00\u4e0b \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void bar(int index, FooOptions opts); void foo(FooOptions opts) { // \u6240\u6709\u903b\u8f91\u4e0a\u76f8\u5173\u7684\u53c2\u6570\u5168\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u65b9\u4fbf\u4f7f\u7528\u66f4\u65b9\u4fbf\u9605\u8bfb bar(get_hash_index(opts.name), opts); } \u2714\ufe0f \u4f18\u96c5 \u2014 \u5f53\u8001\u677f\u8981\u6c42\u4f60\u589e\u52a0\u4e00\u4e2a\u53c2\u6570 sex\uff0c\u52a0\u5728 age \u540e\u9762\uff1a -void foo(string name, int age, int phone, int address); +void foo(string name, int age, int sex, int phone, int address); \u4f60\u624b\u5fd9\u811a\u4e71\u5730\u6253\u5f00\u6240\u6709\u8c03\u7528\u4e86 foo \u7684\u6587\u4ef6\uff0c\u53d1\u73b0\u6709\u5927\u91cf\u5730\u65b9\u9700\u8981\u4fee\u6539\u2026 \u800c\u4f18\u96c5\u7684 API \u603b\u8bbe\u8ba1\u5e08\u5c0f\u5f6d\u8001\u5e08\u53ea\u9700\u8f7b\u8f7b\u4fee\u6539\u4e00\u5904\uff1a struct FooOptions { string name; int age; int sex = 0; // \u4ee4 sex \u9ed8\u8ba4\u4e3a 0 int phone; int address; }; \u6240\u6709\u7684\u8001\u4ee3\u7801\u4f9d\u7136\u7167\u5e38\u8c03\u7528\u65b0\u7684 foo \u51fd\u6570\uff0c\u672a\u6307\u5b9a\u7684 sex \u4f1a\u5177\u6709\u7ed3\u6784\u4f53\u91cc\u5b9a\u4e49\u7684\u9ed8\u8ba4\u503c 0\uff1a foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u5f53\u4f60\u9700\u8981\u591a\u4e2a\u8fd4\u56de\u503c\u65f6\uff1a\u4e0d\u8981\u8fd4\u56de pair \u6216 tuple\uff01 \u4e00\u4e9b STL \u5bb9\u5668\u7684 API \u8bbe\u8ba1\u662f\u53cd\u9762\u5178\u578b\uff0c\u4f8b\u5982\uff1a std::pair insert(std::pair entry); \u7528\u7684\u65f6\u5019\u6bcf\u6b21\u90fd\u8981\u60f3\u4e00\u4e0b\uff0c\u5230\u5e95\u7b2c\u4e00\u4e2a\u662f bool \u8fd8\u662f\u7b2c\u4e8c\u4e2a\u662f bool \u6765\u7740\uff1f\u7136\u540e\u770b\u4e00\u773c IDE \u63d0\u793a\uff0c\u624d\u53cd\u5e94\u8fc7\u6765\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.first << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.second << '\\n'; first\uff1fsecond\uff1f\u8fd9\u7b97\u4ec0\u4e48\u9b3c\uff1f \u66f4\u597d\u7684\u505a\u6cd5\u662f\u8fd4\u56de\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; insert_result_t insert(std::pair entry); \u76f4\u63a5\u901a\u8fc7\u540d\u5b57\u8bbf\u95ee\u6210\u5458\uff0c\u8bed\u4e49\u6e05\u6670\u660e\u786e\uff0c\u6211\u7ba1\u4f60\u662f\u7b2c\u4e00\u4e2a\u7b2c\u4e8c\u4e2a\uff0c\u6211\u53ea\u60f3\u8981\u8868\u793a\u201c\u662f\u5426\u6210\u529f(success)\u201d\u7684\u90a3\u4e2a\u53d8\u91cf\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.success << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.position << '\\n'; \u6700\u597d\u5f53\u7136\u662f\u8fd4\u56de\u548c\u53c2\u6570\u7c7b\u578b\u90fd\u662f\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; struct map_entry_t { K key; V value; }; insert_result_t insert(map_entry_t entry); \u8fd9\u91cc\u8bf4\u7684\u90fd\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u4f60\u53ef\u80fd\u6682\u65f6\u4e0d\u4f1a\u8ba4\u540c\uff0c\u7b49\u4f60\u5927\u624b\u5927\u811a\u72af\u4e86\u51e0\u4e2a\u9519\u4ee5\u540e\uff0c\u4f60\u81ea\u7136\u4f1a\u5fc3\u670d\u53e3\u670d\u3002 \u5c0f\u5f6d\u8001\u5e08\u4ee5\u524d\u4e5f\u548c\u4f60\u4e00\u6837\u662f\u6307\u9488\u4ed9\u4eba\uff0c\u4e0d\u559c\u6b22\u5f3a\u7c7b\u578b\uff0c\u559c\u6b22 void * \u6ee1\u5929\u98de\uff0c\u7136\u540e\u968f\u4fbf\u6539\u4e24\u884c\u5c31\u8e66\u51fa\u4e2a Segmentation Fault\uff0c\u6307\u9488\u4e00\u65f6\u723d\uff0c\u8c03\u8bd5\u706b\u846c\u573a\uff0c\u7136\u540e\u624d\u5f00\u59cb\u53cd\u601d\u3002 STL \u4e2d\u4f9d\u7136\u5728\u5927\u91cf\u7528 pair \u662f\u56e0\u4e3a map \u5bb9\u5668\u51fa\u73b0\u7684\u5f88\u65e9\uff0c\u5386\u53f2\u539f\u56e0\u3002 \u6211\u4eec\u81ea\u5df1\u9879\u76ee\u7684 API \u5c31\u4e0d\u8981\u8bbe\u8ba1\u6210\u8fd9\u718a\u6837\u4e86\u3002 \u5f53\u7136\uff0c\u548c\u67d0\u4e9b\u4e8c\u7ea7\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u76f8\u6bd4 cudaError_t cudaMalloc(void **pret); \uff0c\u8fd4\u56de pair \u5df2\u7ecf\u7b97\u5148\u8fdb\u7684\u4e86 \u4f8b\u5982 C++17 \u4e2d\u7684 from_chars \u51fd\u6570\uff0c\u4ed6\u7684\u8fd4\u56de\u7c7b\u578b\u5c31\u662f\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct from_chars_result { const char *ptr; errc ec; }; from_chars_result from_chars(const char *first, const char *last, int &value); \u8fd9\u8bf4\u660e\u4ed6\u4eec\u4e5f\u5df2\u7ecf\u610f\u8bc6\u5230\u4e86\u4ee5\u524d\u52a8\u4e0d\u52a8\u8fd4\u56de pair \u7684\u8bbe\u8ba1\u662f\u6709\u95ee\u9898\u7684\uff0c\u5df2\u7ecf\u5728\u65b0\u6807\u51c6\u4e2d\u5f00\u59cb\u6539\u7528\u66f4\u597d\u7684\u8bbe\u8ba1\u3002 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u8fd9\u4e2a\u51fd\u6570\uff1a void foo(char *x); \u8fd9\u91cc\u7684 x \u6709\u53ef\u80fd\u662f\uff1a 0\u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u53ea\u8bfb\uff0c\u4f46\u662f\u4f5c\u8005\u5fd8\u4e86\u52a0 const \u6307\u5411\u5355\u4e2a\u5b57\u7b26\uff0c\u7528\u4e8e\u8fd4\u56de\u5355\u4e2a char\uff08\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\uff09 \u6307\u5411\u4e00\u4e2a\u5b57\u7b26\u6570\u7ec4\u7f13\u51b2\u533a\uff0c\u7528\u4e8e\u8fd4\u56de\u5b57\u7b26\u4e32\uff0c\u4f46\u7f13\u51b2\u533a\u5927\u5c0f\u7684\u786e\u5b9a\u65b9\u5f0f\u672a\u77e5 \u5982\u679c\u4f5c\u8005\u6ca1\u5199\u6587\u6863\uff0c\u53d8\u91cf\u540d\u53c8\u975e\u5e38\u542b\u7cca\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u8fd9\u4e2a x \u53c2\u6570\u8981\u600e\u4e48\u7528\u3002 \u7c7b\u578b\u5199\u7684\u597d\uff0c\u80fd\u8d77\u5230\u6ce8\u91ca\u7684\u4f5c\u7528\uff01 void foo(string x); \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\u4e86\uff0c\u5f88\u660e\u663e\uff0c\u662f\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u53c2\u6570\u3002 void foo(string &x); \u770b\u8d77\u6765\u662f\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u4f46\u662f\u901a\u8fc7\u5f15\u7528\u4f20\u53c2\u7684\u65b9\u5f0f\u6765\u8fd4\u56de\u7684 string foo(); \u901a\u8fc7\u5e38\u89c4\u65b9\u5f0f\u76f4\u63a5\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 void foo(vector x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7ec4\u6210\u7684\u6570\u7ec4\uff01 void foo(span x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\u5207\u7247\u3002 void foo(string_view x); \u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5207\u7247\uff0c\u53ef\u80fd\u662f\u4f5c\u8005\u60f3\u8981\u907f\u514d\u62f7\u8d1d\u5f00\u9500\u3002 \u2014 \u8fd8\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using ISBN = string; BookInfo foo(ISBN isbn); \u8fd9\u6837\u7528\u6237\u4e00\u770b\u5c31\u660e\u767d\uff0c\u8fd9\u4e2a\u51fd\u6570\u662f\u63a5\u6536\u4e00\u4e2a ISBN \u7f16\u53f7\uff08\u51fa\u7248\u520a\u7269\u90fd\u6709\u4e00\u4e2a\u8fd9\u79cd\u7f16\u53f7\uff09\uff0c\u8fd4\u56de\u5173\u4e8e\u8fd9\u672c\u4e66\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 \u5c3d\u7ba1\u51fd\u6570\u540d foo \u8ba9\u4eba\u6478\u4e0d\u7740\u5934\u8111\uff0c\u4f46\u4ec5\u51ed\u76f4\u89c2\u7684\u7c7b\u578b\u6807\u8bc6\uff0c\u6211\u4eec\u5c31\u80fd\u51fd\u6570\u529f\u80fd\u628a\u731c\u7684\u4e03\u4e03\u516b\u516b\u3002 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u6ce8\u610f\uff0c\u8fd9\u91cc foo \u8fd4\u56de\u4e86\u4e00\u4e2a\u6307\u9488\uff01 BookInfo * foo(ISBN isbn); \u4ed6\u4ee3\u8868\u4ec0\u4e48\u610f\u601d\u5462\uff1f \u6307\u5411\u4e00\u4e2a\u5185\u5b58\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u4e66\u76ee\u9879\uff0c\u7531 foo \u8d1f\u8d23\u7ba1\u7406\u8fd9\u7247\u5185\u5b58 \u8fd4\u56de\u4e00\u4e2a new \u51fa\u6765\u7684 BookInfo \u7ed3\u6784\u4f53\uff0c\u7531\u7528\u6237\u8d1f\u8d23 delete \u91ca\u653e\u5185\u5b58 \u662f\u5426\u8fd8\u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u627e\u4e0d\u5230\u7684\u60c5\u51b5\uff1f \u751a\u81f3\u6709\u53ef\u80fd\u8fd4\u56de\u7684\u662f\u4e00\u4e2a BookInfo \u6570\u7ec4\uff1f\u6307\u9488\u6307\u5411\u6570\u7ec4\u7684\u9996\u4e2a\u5143\u7d20\uff0c\u6570\u7ec4\u957f\u5ea6\u7684\u5224\u5b9a\u65b9\u5f0f\u672a\u77e5\u2026 \u592a\u591a\u6b67\u4e49\u4e86\uff01 BookInfo & foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u4f1a\u8d1f\u8d23\u7ba1\u7406 BookInfo \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f\uff0c\u7528\u6237\u83b7\u5f97\u7684\u53ea\u662f\u4e00\u4e2a\u4e34\u65f6\u7684\u5f15\u7528\uff0c\u5e76\u4e0d\u6301\u6709\u6240\u6709\u6743\u3002 \u5f15\u7528\u7684\u7279\u70b9\uff1a \u4e00\u5b9a\u4e0d\u4f1a\u662f NULL\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de NULL \u7684\u7591\u8651\uff09 \u65e0\u6cd5 delete \u4e00\u4e2a\u5f15\u7528\uff08\u6392\u9664\u53ef\u80fd\u9700\u8981\u7528\u6237\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u7684\u7591\u8651\uff09 \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de\u6570\u7ec4\u9996\u5143\u7d20\u6307\u9488\u7684\u7591\u8651\uff09 \u6539\u7528\u5f15\u7528\u8fd4\u56de\u503c\uff0c\u4e00\u4e0b\u5b50\u601d\u8def\u5c31\u6e05\u6670\u4e86\u5f88\u591a\u3002\u6ca1\u6709\u90a3\u4e48\u591a\u6000\u7591\u548c\u731c\u6d4b\u4e86\uff0c\u7528\u9014\u5355\u4e00\uff0c\u7528\u6cd5\u660e\u786e\uff0c\u5f15\u7528\u771f\u662f\u7edd\u7edd\u5b50\u3002 std::unique_ptr foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684 BookInfo\uff0c\u5e76\u628a\u751f\u547d\u5468\u671f\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u7528\u6237\u3002 unique_ptr \u7684\u7279\u70b9\uff1a \u72ec\u5360\u6240\u6709\u6743\uff0c\u4e0d\u4f1a\u4e0e\u5176\u4ed6\u7ebf\u7a0b\u5171\u4eab\uff08\u6392\u9664\u53ef\u80fd\u591a\u7ebf\u7a0b\u7ade\u4e89\u7684\u7591\u8651\uff09 \u751f\u547d\u5468\u671f\u5df2\u7ecf\u79fb\u4ea4\u7ed9\u7528\u6237\uff0cunique_ptr \u53d8\u91cf\u79bb\u5f00\u7528\u6237\u7684\u4f5c\u7528\u57df\u540e\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u65e0\u9700\u624b\u52a8 delete \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u5982\u679c\u8981\u8868\u793a\u6570\u7ec4\uff0c\u4f1a\u7528 unique_ptr \u6216\u8005 vector \uff09 \u4f46\u662f unique_ptr \u6709\u4e00\u4e2a\u81f4\u547d\u7684\u7126\u8651\u70b9\uff1a\u4ed6\u53ef\u4ee5\u4e3a NULL\uff01 \u6240\u4ee5\u5f53\u4f60\u770b\u5230\u4e00\u4e2a\u51fd\u6570\u8fd4\u56de unique_ptr \u6216 shared_ptr\uff0c\u5c3d\u7ba1\u51cf\u5c11\u4e86\u5f88\u591a\u7684\u7591\u8651\uff0c\u4f46\u201c\u53ef\u80fd\u4e3aNULL\u201d\u7684\u62c5\u5fe7\u4ecd\u7136\u5b58\u5728\uff01 \u8981\u4e48 foo \u7684\u4f5c\u8005\u5728\u6ce8\u91ca\u6216\u6587\u6863\u91cc\u5199\u660e\uff0c\u201cfoo \u4e0d\u4f1a\u8fd4\u56de NULL\u201d\u6216\u8005\u201cfoo \u627e\u4e0d\u5230\u65f6\u4f1a\u8fd4\u56de NULL\u201d\uff0c\u6253\u6d88\u4f60\u7684\u7591\u8651\u3002 \u4f46\u6211\u4eec\u7684\u8bc9\u6c42\u662f\u901a\u8fc7\u7c7b\u578b\uff0c\u4e00\u773c\u5c31\u80fd\u770b\u51fa\u51fd\u6570\u6240\u6709\u7684\u53ef\u80fd\u6027\uff0c\u800c\u4e0d\u8981\u53bb\u4f9d\u8d56\u53ef\u80fd\u9a97\u4eba\u7684\u6ce8\u91ca\u3002 \u4e3a\u6b64\u5fae\u8f6f\u5b9e\u73b0\u4e86 gsl \u5e93\uff0c\u901a\u8fc7\u7c7b\u578b\u4fee\u9970\u89e3\u51b3\u6307\u9488\u7c7b\u8bed\u4e49\u542b\u7cca\u4e0d\u6e05\u7684\u95ee\u9898\uff1a \u4ed6\u89c4\u5b9a\uff0c\u6240\u6709\u5957\u4e86\u4e00\u5c42 gsl::not_null \u7684\u539f\u59cb\u6307\u9488\u6216\u667a\u80fd\u6307\u9488\uff0c\u91cc\u9762\u90fd\u5fc5\u7136\u4e0d\u4f1a\u4e3a NULL\u3002 \u5728 not_null \u7c7b\u7684\u6784\u9020\u51fd\u6570\u4e2d\uff0c\u6709\u76f8\u5e94\u7684\u65ad\u8a00\u68c0\u67e5\u4f20\u5165\u7684\u6307\u9488\u662f\u5426\u4e3a\u7a7a\uff0c\u5982\u679c\u4e3a\u7a7a\u4f1a\u76f4\u63a5\u62a5\u9519\u9000\u51fa\u3002 gsl::not_null p = nullptr; // \u7f16\u8bd1\u671f\u62a5\u9519\uff0c\u56e0\u4e3a\u4ed6\u91cc\u9762\u5199\u7740 not_null(nullptr_t) = delete; gsl::not_null p = fopen(...); // \u5982\u679c fopen \u6253\u5f00\u5931\u8d25\uff0c\u4e14\u4e3a Debug \u6784\u5efa\uff0c\u8fd0\u884c\u65f6\u4f1a\u89e6\u53d1\u65ad\u8a00\u9519\u8bef \u4fee\u6539\u540e\u7684\u51fd\u6570\u63a5\u53e3\u5982\u4e0b\uff1a gsl::not_null> foo(ISBN isbn); \u56e0\u4e3a gsl::not_null \u7684\u6784\u9020\u51fd\u6570\u4e2d\u4f1a\u68c0\u6d4b\u7a7a\u6307\u9488\uff0c\u5c31\u5411\u7528\u6237\u4fdd\u8bc1\u4e86\u6211\u8fd4\u56de\u7684\u4e0d\u4f1a\u662f NULL\u3002 \u4f46\u662f\uff0c\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u4f60\u5982\u679c\u8981\u8f6c\u79fb\u6240\u6709\u6743\u7684\u8bdd\uff0c\u6211\u76f4\u63a5\u8fd4\u56de BookInfo \u672c\u8eab\u4e0d\u5c31\u884c\u4e86\uff1f \u9664\u975e BookInfo \u7279\u522b\u5927\uff0c\u5927\u5230\u79fb\u52a8\u8fd4\u56de\u7684\u5f00\u9500\u90fd\u4e0d\u5f97\u4e86\u3002 \u76f4\u63a5\u8fd4\u56de\u7c7b\u578b\u672c\u8eab\uff0c\u5c31\u662f\u4e00\u5b9a\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u7684\uff0c\u4e14\u4e5f\u80fd\u8bf4\u660e\u79fb\u4ea4\u4e86\u5bf9\u8c61\u6240\u6709\u6743\u7ed9\u7528\u6237\u3002 BookInfo foo(ISBN isbn); \u2014 \u5176\u5b9e GSL \u91cc\u5927\u91cf\u90fd\u662f\u8fd9\u79cd\u53ef\u6709\u53ef\u65e0\u7684\u73a9\u610f\uff0c\u6bd4\u5982 C++20 \u5df2\u7ecf\u6709\u4e86 std::span \u548c std::byte\uff0c\u4f46\u662f GSL \u8fd8\u7ed9\u4f60\u5f04\u4e86\u4e2a gsl::span \u548c gsl::byte\uff0c\u4e3b\u8981\u662f\u4e3a\u4e86\u517c\u5bb9\u4f4e\u7248\u672c\u7f16\u8bd1\u5668\uff0c\u5982\u679c\u4f60\u5728\u65b0\u9879\u76ee\u91cc\u80fd\u76f4\u63a5\u7528\u4e0a C++20 \u6807\u51c6\u7684\u8bdd\uff0c\u4e2a\u4eba\u4e0d\u662f\u5f88\u63a8\u8350\u518d\u53bb\u7528\u4e86\u3002 \u518d\u6bd4\u5982 gsl::czstring \u662f const char * \u7684\u7c7b\u578b\u522b\u540d\uff0c\u660e\u786e\u8868\u793a\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\uff0c\u4e3a\u7684\u662f\u548c\u201c\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u201d\u533a\u5206\u5f00\u6765\uff0c\u6709\u5fc5\u8981\u5417\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u6211\u4eec\u73b0\u5728 const char * \u57fa\u672c\u4e0a\u5c31\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\u4e00\u79cd\u7528\u6cd5\uff0c\u800c\u4e14\u6211\u4eec\u5927\u591a\u4e5f\u90fd\u662f\u7528 string \u5c31\u53ef\u4ee5\u4e86\uff0cconst char * \u53c8\u4e0d\u5b89\u5168\uff0c\u53c8\u8bed\u4e49\u6a21\u68f1\u4e24\u53ef\uff0c\u4f55\u5fc5\u518d\u53bb\u4e3a\u4e86\u7528\u5b83\u4e13\u95e8\u5f15\u5165\u4e2a\u5e93\uff0c\u6574\u4e2a\u7c7b\u578b\u522b\u540d\u5462\uff1f using czstring = const char *; void foo(czstring s) { // \u53d1\u660e GSL \u7684\u4eba\u771f\u662f\u4e2a\u5929\u624d\uff01 if (s == \"\u5c0f\u5f6d\u8001\u5e08\") // \u9519\u8bef\uff01 if (strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u9519\u8bef\uff01 if (!strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u7ec8\u4e8e\u6b63\u786e // \u7136\u800c\u6211\u5b8c\u5168\u53ef\u4ee5\u76f4\u63a5\u7528 string\uff0c== \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u80fd\u76f4\u63a5\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9 // \u8fd8\u80fd\u968f\u65f6\u968f\u5730 substr \u5207\u7247\uff0cfind \u67e5\u627e\uff0csize \u5e38\u6570\u590d\u6742\u5ea6\u67e5\u5927\u5c0f } \u4f7f\u7528\u5404\u5f0f\u5404\u6837\u529f\u80fd\u660e\u786e\u7684\u7c7b\u578b\u548c\u5bb9\u5668\uff0c\u6bd4\u5982 string\uff0cvector\uff0c\u6216\u5f15\u7528\u3002 \u800c\u4e0d\u662f\u529f\u80fd\u592a\u591a\u7684\u6307\u9488\uff0c\u8ba9\u7528\u6237\u5b66\u4e60\u4f60\u7684 API \u65f6\u4ea7\u751f\u8bef\u89e3\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u5982\u679c\u9700\u8981\u6307\u9488\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 const \u9650\u5b9a\uff0c\u6765\u544a\u8bc9\u7528\u6237\u8fd9\u4e2a\u6307\u9488\u662f\u53ea\u8bfb\u7684\u8fd8\u662f\u53ef\u5199\u7684\u3002 \u603b\u4e4b\uff0c\u4ee3\u7801\u4e0d\u4f1a\u6492\u8c0e\uff0c\u4ee3\u7801\u5c42\u9762\u80fd\u7981\u6b62\u7684\uff0c\u80fd\u5c3d\u91cf\u9650\u5236\u7528\u6cd5\u7684\uff0c\u5c31\u4e0d\u8981\u7528\u6ce8\u91ca\u548c\u6587\u6863\u53bb\u534f\u5546\u89e3\u51b3\u3002 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u5047\u8bbe\u4f60\u6b63\u5728\u5b66\u4e60\u8fd9\u4e2a Linux \u7cfb\u7edf API \u51fd\u6570\uff1a ssize_t read(int fd, char *buf, size_t len); // fd - \u6587\u4ef6\u53e5\u67c4\uff0cint \u7c7b\u578b \u4f46\u662f\u4f60\u6ca1\u6709\u770b\u4ed6\u7684\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u548c\u540d\u5b57\u3002\u4f60\u662f\u8fd9\u6837\u8c03\u7528\u7684\uff1a int fd = open(...); char buf[32]; read(32, buf, fd); char buf[32]; read(32, buf, fd); \u4f60\u8fd9\u91cc\u7684 32 \u672c\u610f\u662f\u7f13\u51b2\u533a\u7684\u5927\u5c0f\uff0c\u5374\u4e0d\u5e78\u5730\u548c fd \u53c2\u6570\u5199\u9519\u4e86\u4f4d\u7f6e\uff0c\u800c\u7f16\u8bd1\u5668\u6beb\u65e0\u62a5\u9519\uff0c\u4f60\u6d51\u7136\u4e0d\u77e5\u3002 \u2014 \u4ec5\u4ec5\u53ea\u662f\u88c5\u6a21\u4f5c\u6837\u7684\u7528 typedef \u5b9a\u4e49\u4e2a\u597d\u770b\u7684\u7c7b\u578b\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\uff01 \u4ed6\u8fde\u4f60\u7684\u53c2\u6570\u540d fd \u90fd\u80fd\u770b\u4e0d\u89c1\uff0c\u4f60\u89c9\u5f97\u4ed6\u4f1a\u770b\u5230\u4f60\u7684\u53c2\u6570\u7c7b\u578b\u662f\u4e2a\u522b\u540d\uff1f \u7528\u6237\u4e00\u6837\u53ef\u4ee5\u7528\u4e00\u4e2a\u6839\u672c\u4e0d\u662f\u6587\u4ef6\u53e5\u67c4\u7684\u81ed\u6574\u6570\u6765\u8c03\u7528\u4f60\uff0c\u800c\u5f97\u4e0d\u5230\u4efb\u4f55\u8b66\u544a\u6216\u62a5\u9519\uff1a typedef int FileHandle; ssize_t read(FileHandle fd, char *buf, size_t len); read(32, buf, fd); // \u7167\u6837\u7f16\u8bd1\u901a\u8fc7\uff01 \u5982\u679c\u6211\u4eec\u628a\u6587\u4ef6\u53e5\u67c4\u5b9a\u4e49\u4e3a\u4e00\u4e2a\u7ed3\u6784\u4f53\uff1a struct FileHandle { int handle; explicit FileHandle(int handle) : handle(handle) {} }; ssize_t read(FileHandle handle, char *buf, size_t len); \u5c31\u80fd\u5728\u7528\u6237\u72af\u9a6c\u864e\u7684\u65f6\u5019\uff0c\u7ed9\u4ed6\u5f39\u51fa\u4e00\u4e2a\u7f16\u8bd1\u9519\u8bef\uff1a read(32, buf, fd); // \u7f16\u8bd1\u62a5\u9519\uff1a\u65e0\u6cd5\u5c06 int \u7c7b\u578b\u7684 32 \u9690\u5f0f\u8f6c\u6362\u4e3a FileHandle\uff01 \u5bf9\u4e8e\u6574\u6570\u7c7b\u578b\uff0c\u4e5f\u6709\u7684\u4eba\u559c\u6b22\u7528 C++11 \u7684\u5f3a\u7c7b\u578b\u679a\u4e3e\uff1a enum class FileHandle : int {}; \u8fd9\u6837\u4e00\u6765\uff0c\u5982\u679c\u7528\u6237\u771f\u7684\u662f\u60f3\u8981\u8bfb\u53d6\u201c32\u53f7\u53e5\u67c4\u201d\u7684\u6587\u4ef6\uff0c\u4ed6\u5c31\u5fc5\u987b\u663e\u5f0f\u5730\u5199\u51fa\u5b8c\u6574\u7c7b\u578b\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff1a read(FileHandle(32), buf, fd); // \u7f16\u8bd1\u901a\u8fc7\u4e86 \u5f3a\u8feb\u4f60\u5199\u4e0a\u7c7b\u578b\u540d\uff0c\u5c31\u7ed9\u4e86\u4f60\u4e00\u6b21\u518d\u601d\u8003\u7684\u673a\u4f1a\uff0c\u8ba9\u4f60\u7a81\u7136\u60ca\u9192\uff1a \u54e6\u5929\u54ea\uff0c\u6211\u600e\u4e48\u628a\u7f13\u51b2\u533a\u5927\u5c0f\u5f53\u6210\u53e5\u67c4\u6765\u4f20\u9012\u4e86\uff01 \u4ece\u800c\u51cf\u5c11\u7741\u7740\u773c\u775b\u8fd8\u72af\u9519\u7684\u53ef\u80fd\u3002 \u7136\u540e\uff0c\u4f60\u7684 open \u51fd\u6570\u4e5f\u8fd4\u56de FileHandle\uff0c\u6574\u4e2a\u4ee3\u7801\u4e2d\u5c31\u4e0d\u7528\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u4e86\u3002 FileHandle fd = open(std::filesystem::path(\"\u8def\u5f84\"), OpenFlag::Read); char buf[32]; read(fd, buf, 32); \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u5047\u5982\u4f60\u624b\u4e00\u6ed1\uff0c\u6216\u8005\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u628a buf \u7f13\u51b2\u533a\u5c11\u7559\u4e86\u4e24\u4e2a\u5b57\u8282\uff1a char buf[30]; read(fd, buf, 32); \u4f46\u4f60 read \u7684\u53c2\u6570\u4f9d\u7136\u662f 32\uff0c\u5c31\u4ea7\u751f\u4e86\u6570\u7ec4\u8d8a\u754c\uff0c\u53c8\u672a\u5b9a\u4e49\u884c\u4e3a\u4e86\u3002 \u6211\u4eec\u91c7\u7528\u5c01\u88c5\u7cbe\u795e\uff0c\u628a\u76f8\u5173\u7684 buf \u548c size \u5c01\u88c5\u6210\u4e00\u4e2a\u53c2\u6570\uff1a struct Span { char *data; size_t size; }; ssize_t read(FileHandle fd, Span buf); read(fd, Span{buf, 32}); \u6ce8\u610f\uff1aSpan \u4e0d\u9700\u8981\u4ee5\u5f15\u7528\u5f62\u5f0f\u4f20\u5165\u51fd\u6570\uff01 void read(std::string &buf); // \u5982\u679c\u662f string \u7c7b\u578b\uff0c\u53c2\u6570\u9700\u8981\u4e3a\u5f15\u7528\uff0c\u624d\u80fd\u8ba9 read \u80fd\u591f\u4fee\u6539 buf \u5b57\u7b26\u4e32 void read(Span buf); // Span \u4e0d\u9700\u8981\uff0c\u56e0\u4e3a Span \u5e76\u4e0d\u662f\u72ec\u5360\u8d44\u6e90\u7684\u7c7b\uff0cSpan \u672c\u8eab\u5c31\u662f\u4e2a\u8f7b\u91cf\u7ea7\u7684\u5f15\u7528 vector \u548c string \u8fd9\u79cd\u5177\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\u7684 RAII \u5c01\u88c5\u7c7b\u624d\u9700\u8981\u4f20\u5165\u5f15\u7528 string &buf \uff0c\u5982\u679c\u76f4\u63a5\u4f20\u5165\u4f1a\u53d1\u751f\u6df1\u62f7\u8d1d\uff0c\u5bfc\u81f4 read \u5185\u90e8\u4fee\u6539\u7684\u662f string \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u65e0\u6cd5\u5f71\u54cd\u5230\u5916\u754c\u539f\u6765\u7684 string\u3002 \u5982\u679c\u662f Span \u53c2\u6570\u5c31\u4e0d\u9700\u8981 Span &buf \u5f15\u7528\u4e86\uff0cSpan \u5e76\u4e0d\u662f RAII \u5c01\u88c5\u7c7b\uff0c\u5e76\u4e0d\u6301\u6709\u751f\u547d\u5468\u671f\uff0c\u5e76\u6ca1\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\uff0c\u4ed6\u53ea\u662f\u4e2a\u5bf9\u5916\u90e8\u5df2\u6709 vector\u3001string\u3001\u6216 char[] \u7684\u5f15\u7528\u3002\u6216\u8005\u8bf4 Span \u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u5bf9\u539f\u7f13\u51b2\u533a\u7684\u5f15\u7528\uff0c\u76f4\u63a5\u4f20\u5165 read \u5185\u90e8\u4e00\u6837\u53ef\u4ee5\u4fee\u6539\u4f60\u7684\u7f13\u51b2\u533a\u3002 \u2014 \u7528 Span \u7ed3\u6784\u4f53\u867d\u7136\u770b\u8d77\u6765\u66f4\u660e\u786e\u4e86\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u89e3\u51b3\u7528\u6237\u53ef\u80fd\u624b\u6ed1\u5199\u9519\u7f13\u51b2\u533a\u957f\u5ea6\u7684\u95ee\u9898\uff1a char buf[30]; read(fd, Span{buf, 32}); \u4e3a\u6b64\uff0c\u6211\u4eec\u5728 Span \u91cc\u52a0\u5165\u4e00\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} }; \u8fd9\u5c06\u5141\u8bb8 char [N] \u9690\u5f0f\u8f6c\u6362\u4e3a Span\uff0c\u4e14\u957f\u5ea6\u81ea\u52a8\u5c31\u662f N \u7684\u503c\u3002 \u6b64\u5904\u5982\u679c\u5199 Span(char buf[N]) \uff0c\u4f1a\u88ab C \u8bed\u8a00\u7684\u67d0\u6761\u6c99\u96d5\u89c4\u5219\uff0c\u51fd\u6570\u7b7e\u540d\u4f1a\u7b49\u4ef7\u4e8e Span(char *buf) \uff0c\u4ece\u800c\u53ea\u80fd\u83b7\u53d6\u8d77\u59cb\u5730\u5740\uff0c\u800c\u63a8\u5bfc\u4e0d\u4e86\u957f\u5ea6\u3002\u4f7f\u7528\u6570\u7ec4\u5f15\u7528\u4f5c\u4e3a\u53c2\u6570 Span(char (&buf)[N]) \u5c31\u4e0d\u4f1a\u88ab C \u8bed\u8a00\u81ea\u52a8\u9000\u5316\u6210\u8d77\u59cb\u5730\u5740\u6307\u9488\u4e86\u3002 \u7528\u6237\u53ea\u9700\u8981\uff1a char buf[30]; read(fd, Span{buf}); \u7b49\u4ef7\u4e8e Span{buf, 30} \uff0c\u6570\u7ec4\u957f\u5ea6\u81ea\u52a8\u63a8\u5bfc\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u7701\u7565 Span \u4e0d\u5199\uff1a char buf[30]; read(fd, buf); // \u81ea\u52a8\u8f6c\u6362\u6210 Span{buf, 30} \u52a0\u5165\u66f4\u591a\u7c7b\u578b\u7684\u652f\u6301\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(std::array &arr) : data(arr.data()), size(N) {} Span(std::vector &vec) : data(vec.data()), size(vec.size()) {} // \u5982\u679c\u6709\u9700\u8981\uff0c\u4e5f\u53ef\u4ee5\u663e\u5f0f\u5199\u51fa Span(buf, 30) \u4ece\u9996\u5730\u5740\u548c\u957f\u5ea6\u6784\u9020\u51fa\u4e00\u4e2a Span \u6765 explicit Span(char *data, size_t size) : data(data), size(size) {} }; \u73b0\u5728 C \u6570\u7ec4\u3001array\u3001vector\u3001\u90fd\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a Span \u4e86\uff1a char buf1[30]; Span span1 = buf1; std::array buf2; Span span2 = buf2; std::vector buf(30); Span span3 = buf3; const char *str = \"hello\"; Span span4 = Span(str, strlen(str)); \u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u81ea\u52a8\u652f\u6301\u4efb\u4f55\u5177\u6709 data \u548c size \u6210\u5458\u7684\u5404\u79cd\u6807\u51c6\u5e93\u5bb9\u5668\uff0c\u5305\u62ec\u7b2c\u4e09\u65b9\u7684\uff0c\u53ea\u8981\u4ed6\u63d0\u4f9b data \u548c size \u51fd\u6570\u3002 template concept has_data_size = requires (Arr arr) { { arr.data() } -> std::convertible_to; { arr.size() } -> std::same_as; }; struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(Arr &&arr) : data(arr.data()), size(arr.size()) {} // \u6ee1\u8db3 has_data_size \u7684\u4efb\u4f55\u7c7b\u578b\u90fd\u53ef\u4ee5\u6784\u9020\u51fa Span // \u800c\u6807\u51c6\u5e93\u7684 vector\u3001string\u3001array \u5bb9\u5668\u90fd\u542b\u6709 .data() \u548c .size() \u6210\u5458\u51fd\u6570 }; \u2014 \u5982\u679c\u7528\u6237\u786e\u5b9e\u6709\u4fee\u6539\u957f\u5ea6\u7684\u9700\u8981\uff0c\u53ef\u4ee5\u901a\u8fc7 subspan \u6210\u5458\u51fd\u6570\u5b9e\u73b0\uff1a char buf[32]; read(fd, Span(buf).subspan(0, 10)); // \u53ea\u8bfb\u53d6\u524d 10 \u4e2a\u5b57\u8282\uff01 subspan \u5185\u90e8\u5b9e\u73b0\u539f\u7406\uff1a struct Span { char *data; size_t size; Span subspan(size_t start, size_t length = (size_t)-1) const { if (start > size) // \u5982\u679c\u8d77\u59cb\u4f4d\u7f6e\u8d85\u51fa\u8303\u56f4\uff0c\u5219\u629b\u51fa\u5f02\u5e38 throw std::out_of_range(\"subspan start out of range\"); auto restSize = size - start; if (length > restSize) // \u5982\u679c\u957f\u5ea6\u8d85\u8fc7\u4e0a\u9650\uff0c\u5219\u81ea\u52a8\u622a\u65ad length = restSize; return Span(data + start, length); } }; \u2014 \u53ef\u4ee5\u628a Span \u53d8\u6210\u6a21\u677f\u7c7b\uff0c\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u6570\u7ec4\uff0c\u6bd4\u5982 Span \u3002 template concept has_data_size = requires (Arr arr) { { std::data(arr) } -> std::convertible_to; { std::size(arr) } -> std::same_as; // \u4f7f\u7528 std::data \u800c\u4e0d\u662f .data() \u7684\u597d\u5904\uff1a // std::data \u5bf9\u4e8e char (&buf)[N] \u8fd9\u79cd\u6570\u7ec4\u7c7b\u578b\u4e5f\u6709\u91cd\u8f7d\uff01 // \u4f8b\u5982 std::size(buf) \u4f1a\u5f97\u5230 int buf[N] \u7684\u6b63\u786e\u957f\u5ea6 N // \u800c sizeof buf \u4f1a\u5f97\u5230 N * sizeof(int) // \u7c7b\u4f3c\u4e8e sizeof(buf) / sizeof(buf[0]) \u7684\u6548\u679c // \u4e0d\u8fc7\u5982\u679c buf \u662f\u666e\u901a int * \u6307\u9488\uff0c\u4f1a\u91cd\u8f7d\u5931\u8d25\uff0c\u76f4\u63a5\u62a5\u9519\uff0c\u6ca1\u6709\u5b89\u5168\u9690\u60a3 }; template struct Span { T *data; size_t size; template Arr> Span(Arr &&arr) : data(std::data(arr)), size(std::size(arr)) {} // \ud83d\udc46 \u540c\u65f6\u56ca\u62ec\u4e86 vector\u3001string\u3001array\u3001\u539f\u59cb\u6570\u7ec4 }; template Span(Arr &&t) -> Span()))>>; \u2014 Span \u8868\u793a\u53ef\u8bfb\u5199\u7684\u6570\u7ec4\u3002 \u5bf9\u4e8e\u53ea\u8bfb\u7684\u6570\u7ec4\uff0c\u7528 Span \u5c31\u53ef\u4ee5\u3002 ssize_t read(FileHandle fd, Span buf); // buf \u53ef\u8bfb\u5199\uff01 ssize_t write(FileHandle fd, Span buf); // buf \u53ea\u8bfb\uff01 \u2014 \u597d\u6d88\u606f\uff01\u8fd9\u4e1c\u897f\u5728 C++20 \u5df2\u7ecf\u5b9e\u88c5\uff0c\u90a3\u5c31\u662f std::span\u3002 \u6ca1\u6709 C++20 \u5f00\u53d1\u73af\u5883\u7684\u540c\u5b66\uff0c\u4e5f\u53ef\u4ee5\u7528 GSL \u5e93\u7684 gsl::span\uff0c\u6216\u8005 ABSL \u5e93\u7684 absl::Span \u6765\u4f53\u9a8c\u3002 C++17 \u8fd8\u6709\u4e13\u95e8\u9488\u5bf9\u5b57\u7b26\u4e32\u7684\u533a\u95f4\u7c7b std::string_view\uff0c\u53ef\u4ee5\u4ece std::string \u9690\u5f0f\u6784\u9020\uff0c\u7528\u6cd5\u7c7b\u4f3c\uff0c\u4e0d\u8fc7\u5207\u7247\u51fd\u6570\u662f substr\uff0c\u8fd8\u652f\u6301 find\u3001find_first_of \u7b49 std::string \u6709\u7684\u5b57\u7b26\u4e32\u4e13\u5c5e\u51fd\u6570\u3002 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ef\u8bfb\u53ef\u5199\u6570\u7ec4 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ea\u8bfb\u6570\u7ec4 std::string_view - \u4efb\u610f\u5b57\u7b26\u4e32 \u5728 read \u51fd\u6570\u5185\u90e8\uff0c\u53ef\u4ee5\u7528 .data() \u548c .size() \u91cd\u65b0\u53d6\u51fa\u72ec\u7acb\u7684\u9996\u5730\u5740\u6307\u9488\u548c\u7f13\u51b2\u533a\u957f\u5ea6\uff0c\u7528\u4e8e\u4f3a\u5019 C \u8bed\u8a00\u7684\u8001\u51fd\u6570\uff1a ssize_t read(FileHandle fd, std::span buf) { memset(buf.data(), 0, buf.size()); // \u8bfe\u540e\u4f5c\u4e1a\uff0c\u7528\u6240\u5b66\u77e5\u8bc6\uff0c\u4f18\u5316 C \u8bed\u8a00\u7684 memset \u51fd\u6570\u5427\uff01 ... } \u4e5f\u53ef\u4ee5\u7528 range-based for \u5faa\u73af\u6765\u904d\u5386\uff1a ssize_t read(FileHandle fd, std::span buf) { for (auto & c : buf) { // \u6ce8\u610f\u8fd9\u91cc\u4e00\u5b9a\u8981\u7528 auto & \u54e6\uff01\u5426\u5219\u65e0\u6cd5\u4fee\u6539 buf \u5185\u5bb9 c = 'c'; ... } } \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u6709\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u521a\u624d\u7684 foo\uff0c\u4f1a\u9700\u8981\u8868\u793a\u201c\u53ef\u80fd\u627e\u4e0d\u5230\u8be5\u4e66\u672c\u201d\u7684\u60c5\u51b5\u3002 \u7c97\u7cd9\u7684 API \u8bbe\u8ba1\u8005\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\uff0c\u7136\u540e\u5728\u6587\u6863\u91cc\u8bf4\u201c\u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u8fd4\u56de NULL\uff01\u201d BookInfo *foo(ISBN isbn); \u5982\u679c\u662f\u8fd9\u6837\u7684\u51fd\u6570\u7b7e\u540d\uff0c\u662f\u4e0d\u662f\u4f60\u5f88\u5bb9\u6613\u5fd8\u8bb0 foo \u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\uff1f \u6bd4\u5982 malloc \u51fd\u6570\u5728\u5206\u914d\u5931\u8d25\u65f6\uff0c\u5c31\u4f1a\u8fd4\u56de NULL \u5e76\u8bbe\u7f6e errno \u4e3a ENOMEM\u3002 \u5728 man malloc \u6587\u6863\u4e2d\u5199\u7684\u6e05\u6e05\u695a\u695a\uff0c\u4f46\u662f\u8c01\u4f1a\u8bb0\u5f97\u8fd9\u4e2a\u8bbe\u5b9a\uff1f malloc \u5b8c\u968f\u624b\u5c31\u76f4\u63a5\u8bbf\u95ee\u4e86\uff08\u7a7a\u6307\u9488\u89e3\u5f15\u7528\u5c5e\u672a\u5b9a\u4e49\u884c\u4e3a\uff09\u3002 \u5728\u73b0\u4ee3 C++17 \u4e2d\u5f15\u5165\u4e86 optional\uff0c\u4ed6\u662f\u4e2a\u6a21\u677f\u7c7b\u578b\u3002 \u5f62\u5982 optional \u7684\u7c7b\u578b\u6709\u4e24\u79cd\u53ef\u80fd\u7684\u72b6\u6001\uff1a \u4e3a\u7a7a\uff08nullopt\uff09 \u6709\u503c\uff08T\uff09 \u5982\u679c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u6210\u529f\u8fd4\u56de T\uff0c\u4e5f\u53ef\u80fd\u5931\u8d25\uff0c\u90a3\u5c31\u53ef\u4ee5\u8ba9\u4ed6\u8fd4\u56de optional \uff0c\u7528 nullopt \u6765\u8868\u793a\u5931\u8d25\u3002 std::optional foo(ISBN isbn) { if (\u627e\u5230\u4e86) { return BookInfo(...); } else { return std::nullopt; } } nullopt \u548c\u6307\u9488\u7684 nullptr \u7c7b\u4f3c\uff0c\u4f46 optional \u7684\u7528\u9014\u66f4\u52a0\u5355\u4e00\uff0c\u66f4\u5177\u8bf4\u660e\u6027\u3002 \u5982\u679c\u4f60\u8fd4\u56de\u4e2a\u6307\u9488\u4eba\u5bb6\u4e0d\u4e00\u5b9a\u77e5\u9053\u4f60\u7684\u610f\u601d\u662f\u53ef\u80fd\u8fd4\u56de nullptr\uff0c\u53ef\u80fd\u8fd8\u4ee5\u4e3a\u4f60\u662f\u4e3a\u4e86\u8fd4\u56de\u4e2a new \u51fa\u6765\u7684\u6570\u7ec4\uff0c\u8bed\u4e49\u4e0d\u660e\u786e\u3002 \u8c03\u7528\u7684\u5730\u65b9\u8fd9\u6837\u5199\uff1a auto book = foo(isbn); if (book.has_value()) { // book.has_vlaue() \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u7c7b\u578b\u53ef\u4ee5\u5728 if \u6761\u4ef6\u4e2d\u81ea\u52a8\u8f6c\u6362\u4e3a bool\uff0c\u5224\u65ad\u662f\u5426\u6709\u503c\uff0c\u7b49\u4ef7\u4e8e .has_value() \uff1a auto book = foo(isbn); if (book) { // (bool)book \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8bfb\u53d6\u5176\u4e2d\u7684\u503c\uff0c\u7b49\u4ef7\u4e8e .value() \uff09\uff1a auto book = foo(isbn); if (book) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u8fd0\u7528 C++17 \u7684\u5c31\u5730 if \u8bed\u6cd5\uff1a if (auto book = foo(isbn); book.has_value()) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u7531\u4e8e auto \u51fa\u6765\u7684 optional \u53d8\u91cf\u53ef\u4ee5\u8f6c\u6362\u4e3a bool\uff0c\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u53ef\u4ee5\u7701\u7565\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", *book); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u4e5f\u652f\u6301 -> \u8fd0\u7b97\u7b26\u8bbf\u95ee\u6210\u5458\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", book->name); book->readOnline(); } optional \u7684 .value() \uff0c\u5982\u679c\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa std::bad_optional_access \u5f02\u5e38\u3002 \u7528\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4fbf\u6377\u5730\u628a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u8f6c\u6362\u4e3a\u5f02\u5e38\u629b\u51fa\u7ed9\u4e0a\u6e38\u8c03\u7528\u8005\uff0c\u800c\u4e0d\u7528\u6210\u5806\u7684 if \u5224\u65ad\u548c\u8fd4\u56de\u3002 BookInfo book = foo(isbn).value(); \u4e5f\u53ef\u4ee5\u901a\u8fc7 .value_or(\u9ed8\u8ba4\u503c) \u6307\u5b9a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u65f6\u7684\u9ed8\u8ba4\u503c\uff1a BookInfo defaultBook; BookInfo book = foo(isbn).value_or(defaultBook); \u2014 \u4f60\u63a5\u624b\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\u8f6c\u6574\u6570\uff08\u53ef\u80fd\u8f6c\u6362\u5931\u8d25\uff09\u7684\u51fd\u6570 API\uff1a // \u6587\u6863\uff1a\u5982\u679c\u5b57\u7b26\u4e32\u89e3\u6790\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de -1 \u5e76\u8bbe\u7f6e errno \u4e3a EINVAL\uff01\u8bb0\u5f97\u68c0\u67e5\uff01\u82e5\u4f60\u5fd8\u8bb0\u68c0\u67e5\u540e\u679c\u81ea\u8d1f\uff01 // \u5f53\u6307\u5b9a n \u4e3a 0 \u65f6\uff0cstr \u4e3a C \u8bed\u8a00\u7ecf\u5178\u6b3e 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u3002 // \u5f53\u6307\u5b9a n \u4e0d\u4e3a 0 \u65f6\uff0cstr \u7684\u957f\u5ea6\u56fa\u5b9a\u4e3a n\uff0c\u7528\u4e8e\u7167\u987e\u53c2\u6570\u53ef\u80fd\u4e0d\u4e3a 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u7684\u60c5\u51b5\u3002 int parseInt(const char *str, size_t n); \u90a3\u4e48\u6211\u5982\u679c\u68c0\u6d4b\u5230 -1\uff0c\u9b3c\u77e5\u9053\u662f\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u5b57\u5c31\u662f -1\uff0c\u8fd8\u662f\u56e0\u4e3a\u51fa\u9519\u624d\u8fd4\u56de -1\uff1f\u8fd8\u8981\u6211\u53bb\u68c0\u67e5 errno\uff0c\u4e07\u4e00\u4e0a\u4e00\u4e2a\u51fd\u6570\u51fa\u9519\u7559\u4e0b\u7684 EINVAL \u5462\uff1f\u4e07\u4e00\u6211\u5fd8\u8bb0\u68c0\u67e5\u5462\uff1f \u8fd0\u7528\u672c\u671f\u8bfe\u7a0b\u6240\u5b66\u77e5\u8bc6\u4f18\u5316\uff1a std::optional parseInt(std::string_view str); \u662f\u4e0d\u662f\u529f\u80fd\uff0c\u8fd4\u56de\u503c\uff0c\u53ef\u80fd\u5b58\u5728\u7684\u9519\u8bef\u60c5\u51b5\uff0c\u4e00\u76ee\u4e86\u7136\u4e86\uff1f\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48\u96be\u61c2\u7684\u6ce8\u91ca\uff0c\u6587\u6863\u3002 \u5982\u679c\u8c03\u7528\u8005\u60f3\u5047\u5b9a\u5b57\u7b26\u4e32\u89e3\u6790\u4e0d\u4f1a\u51fa\u9519\uff1a parseInt(\"233\").value(); \u5982\u679c\u8c03\u7528\u8005\u60f3\u5f53\u51fa\u9519\u65f6\u9ed8\u8ba4\u8fd4\u56de 0\uff1a parseInt(\"233\").value_or(0); parseInt \u5185\u90e8\u5b9e\u73b0\u53ef\u80fd\u5982\u4e0b\uff1a std::optional parseInt(std::string_view str) { int value; auto result = std::from_chars(str.data(), str.data() + str.size(), std::ref(value)); if (result.ec == std::errc()) return value; else return std::nullopt; } \u2014 \u8c03\u7528\u8005\u7684\u53c2\u6570\u4e0d\u8bba\u662f string \u8fd8\u662f C \u8bed\u8a00\u98ce\u683c\u7684 const char *\uff0c\u90fd\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a\u901a\u7528\u7684 string_view\u3002 parseInt(\"-1\"); string s; cin >> s; parseInt(s); char perfGeek[2] = {'-', '1'}; parseInt(std::string_view{perfGeek, 2}); \u7b11\u70b9\u89e3\u6790\uff1a\u4e0a\u9762\u7684\u4ee3\u7801\u6709\u4e00\u5904\u9519\u8bef\uff0c\u4f60\u80fd\u53d1\u89c9\u5417\uff1f \u2014 cin >> s; cin >> \u53ef\u80fd\u4f1a\u5931\u8d25\uff01\u6ca1 \u60f3 \u5230 \u5427 \u8981\u662f int \u7b49 POD \u7c7b\u578b\uff0c\u5982\u679c\u4e0d\u68c0\u6d4b\uff0c\u4f1a\u51fa\u73b0\u672a\u521d\u59cb\u5316\u7684 int \u503c\uff0c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 int i; cin >> i; return i; // \u5982\u679c\u7528\u6237\u7684\u8f93\u5165\u503c\u4e0d\u662f\u5408\u6cd5\u7684\u6574\u6570\uff0c\u8fd9\u91cc\u4f1a\u4ea7\u751f\u5178\u4e2d\u5178\u4e4b\u5185\u5b58\u4e2d\u7684\u968f\u673a\u6570\u70eb\u70eb\u70eb\u70e4\u9984\u9968\uff01 \u5b98\u65b9\u63a8\u8350\u7684\u505a\u6cd5\u662f\u6bcf\u6b21\u90fd\u8981\u68c0\u6d4b\u662f\u5426\u5931\u8d25\uff01 int i; if (!(cin >> i)) { throw std::runtime_error(\"\u8bfb\u5165 int \u53d8\u91cf\u5931\u8d25\uff01\"); } return i; \u4f46\u662f\u8c01\u8bb0\u5f97\u4f4f\uff1f\u6240\u4ee5\u4ece\u4e00\u5f00\u59cb\u5c31\u4e0d\u8981\u8bbe\u8ba1\u8fd9\u79cd\u7cdf\u7cd5\u7684 API\u3002 \u7279\u522b\u662f cin >> \u8fd9\u79cd\u901a\u8fc7\u5f15\u7528\u8fd4\u56de i\uff0c\u5374\u8981\u4eba\u8bb0\u5f97\u5224\u65ad\u8fd4\u56de bool \u8868\u793a\u6210\u8d25\uff0c\u5fd8\u8bb0\u5224\u65ad\u8fd8\u4f1a\u7ed9\u4f60\u7559\u7740\u672a\u521d\u59cb\u5316\u7684\u715e\u7b14\u8bbe\u8ba1\u3002 \u5982\u679c\u8ba9\u6211\u6765\u8bbe\u8ba1 cin \u7684\u8bdd\uff1a std::optional readInt(); int i = cin.readInt().value(); \u8fd9\u6837\u5982\u679c\u7528\u6237\u8981\u8bfb\u53d6\u5230\u503c\u7684\u8bdd\uff0c\u5fc5\u7136\u8981 .value() \uff0c\u4ece\u800c\u5982\u679c readInt \u5931\u8d25\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5c31\u5fc5\u7136\u629b\u51fa\u5f02\u5e38\uff0c\u907f\u514d\u4e86\u7528\u6237\u5fd8\u8bb0\u5224\u65ad\u9519\u8bef\u7684\u53ef\u80fd\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684\u4e00\u6b3e co_async \u534f\u7a0b\u5e93\u4e2d\uff0c\u5c31\u91cd\u65b0\u8bbe\u8ba1\u4e86\u81ea\u5df1\u7684\u5f02\u6b65\u5b57\u7b26\u6d41\u7c7b\uff0c\u4f8b\u5982\u5176\u4e2d getline \u51fd\u6570\u4f1a\u8fd4\u56de std::expected \u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002 \u2014 BookInfo * foo(ISBN isbn); \u8fd9\u662f\u4e2a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u7684\u51fd\u6570\uff0c\u5355\u4ece\u51fd\u6570\u58f0\u660e\u6765\u770b\uff0c\u4f60\u80fd\u5426\u77e5\u9053\u4ed6\u6709\u6ca1\u6709\u53ef\u80fd\u8fd4\u56de\u7a7a\u6307\u9488\uff1f\u4e0d\u786e\u5b9a\u3002 std::optional foo(ISBN isbn); \u73b0\u5728\u662f\u4e0d\u662f\u5f88\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo *\uff0c\u5927\u6982\u662f\u4e0d\u4f1a\u4e3a NULL \u7684\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e0b\u66f4\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo * \u56e0\u4e3a\u5957\u4e86\u4e00\u5c42 gsl::not_null\uff0c\u5fc5\u5b9a\u4e0d\u80fd\u4e3a NULL\uff08\u5426\u5219\u4f1a\u88ab gsl::not_null \u7684\u65ad\u8a00\u68c0\u6d4b\u5230\uff09\uff0c\u51fd\u6570\u7684\u4f5c\u8005\u662f\u7edd\u5bf9\u4e0d\u4f1a\u6545\u610f\u8fd4\u56de\u4e2a NULL \u7684\u3002 \u5982\u679c\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de nullopt\uff0c\u800c\u4e0d\u662f\u610f\u4e49\u4e0d\u660e\u8fd8\u5bb9\u6613\u5fd8\u8bb0\u7684\u7a7a\u6307\u9488\u3002 \u2014 \u8fd8\u662f\u4e0d\u5efa\u8bae\u76f4\u63a5\u7528\u539f\u59cb\u6307\u9488\uff0c\u5efa\u8bae\u7528\u667a\u80fd\u6307\u9488\u6216\u5f15\u7528\u3002 std::optional>> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4eab\u6709\u6240\u6709\u6743\u7684\u72ec\u5360\u6307\u9488\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211 optional \u51fa\u9519\u4e86\u600e\u4e48\u529e\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4e0d\u4eab\u6709\u6240\u6709\u6743\u7684\u5f15\u7528\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 reference_wrapper \u662f\u5bf9\u5f15\u7528\u7684\u5305\u88c5\uff0c\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u5f15\u7528\uff1a int i; std::reference_wrapper ref = i; int &r = ref; // r \u6307\u5411 i \u4f7f\u5f15\u7528\u53ef\u4ee5\u5b58\u5230\u5404\u79cd\u5bb9\u5668\u91cc\uff1a \u4e14\u9047\u5230 auto \u4e0d\u4f1a\u81ea\u52a8\u9000\u5316\uff08decay\uff09\uff1a int i; std::reference_wrapper ref = i; auto ref2 = ref; // ref2 \u63a8\u5bfc\u4e3a std::reference_wrapper int &r = i; auto r2 = r; // r2 \u63a8\u5bfc\u4e3a int \u4e14\u6c38\u8fdc\u4e0d\u4f1a\u4e3a NULL\uff1a std::reference_wrapper ref; // \u7f16\u8bd1\u9519\u8bef\uff1a\u5f15\u7528\u5fc5\u987b\u521d\u59cb\u5316\uff0creference_wrapper \u5f53\u7136\u4e5f\u5fc5\u987b\u521d\u59cb\u5316 \u4e5f\u53ef\u4ee5\u901a\u8fc7 * \u6216 -> \u89e3\u5f15\u7528\uff1a BookInfo book; std::reference_wrapper refBook = book; refBook->readOnline(); BookInfo deepCopyBook = *refBook; \u2014 \u6ce8\u610f .value() \u548c * \u662f\u6709\u533a\u522b\u7684\uff0c * \u4e0d\u4f1a\u68c0\u6d4b\u662f\u5426\u4e3a\u7a7a\uff0c\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u4f46\u66f4\u9ad8\u6548\u3002 o.value(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38 *o; // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 o->readOnline(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u56e0\u6b64\u4e00\u822c\u4f1a\u5728\u5224\u65ad\u4e86 optional \u4e0d\u4e3a\u7a7a\u4ee5\u540e\u624d\u4f1a\u53bb\u8bbf\u95ee * \u548c -> \u3002\u800c .value() \u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u3002 print(foo().value()); // .value() \u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\uff0c\u4e0d\u7528\u5224\u65ad if (auto o = foo()) { // \u5224\u65ad\u8fc7\u786e\u8ba4\u4e0d\u4e3a\u7a7a\u4e86\uff0c\u624d\u80fd\u8bbf\u95ee *o // \u5728\u5df2\u7ecf\u5224\u65ad\u8fc7\u4e0d\u4e3a\u7a7a\u7684 if \u5206\u652f\u4e2d\uff0c\u7528 * \u6bd4 .value() \u66f4\u9ad8\u6548 print(*o); } \u5171\u4eab\u6240\u6709\u6743 * n - shared_ptr * 1 - shared_ptr \u72ec\u5360\u6240\u6709\u6743 * n - vector , unique_ptr * 1 - unique_ptr \u6ca1\u6240\u6709\u6743 * n - span * 1 - reference_wrapper , T & \u2014 \u63a5\u4e0b\u6765\u4ecb\u7ecd optional \u7684\u4e00\u4e9b\u8fdb\u9636\u7528\u6cd5\u3002 std::optional o = BookInfo(1, 2, 3); // \u521d\u59cb\u5316\u4e3a BookInfo \u503c std::optional o; // \u4e0d\u5199\u65f6\u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u7a7a\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt o.emplace(1, 2, 3); // \u5c31\u5730\u6784\u9020\uff0c\u7b49\u4ef7\u4e8e o = BookInfo(1, 2, 3); \u4f46\u4e0d\u9700\u8981\u79fb\u52a8 BookInfo \u4e86 o.reset(); // \u5c31\u5730\u9500\u6bc1\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt; \u2014 \u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 int \u503c\u52a0 1\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readInt(); if (o) { o = *o + 1; } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 transform\uff1a std::optional o = cin.readInt(); o = o.transform([] (int n) { return n + 1; }); \u2014 \u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 string \u503c\u89e3\u6790\u4e3a int\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\u3002\u4e14\u89e3\u6790\u51fd\u6570\u53ef\u80fd\u5931\u8d25\uff0c\u5931\u8d25\u5219\u4e5f\u8981\u5c06 optional \u7f6e\u4e3a\u7a7a\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readLine(); std::optional o2; if (o) { o2 = parseInt(*o); } std::optional parseInt(std::string_view sv) { ... } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 and_then\uff1a auto o = cin.readLine().and_then(parseInt); \u2014 \u5f53\u627e\u4e0d\u5230\u6307\u5b9a\u4e66\u7c4d\u65f6\uff0c\u8fd4\u56de\u4e00\u672c\u9ed8\u8ba4\u4e66\u7c4d\u4f5c\u4e3a\u66ff\u4ee3\uff1a auto o = findBook(isbn).value_or(getDefaultBook()); \u7f3a\u70b9\uff1a\u7531\u4e8e value_or \u7684\u53c2\u6570\u4f1a\u63d0\u524d\u88ab\u6c42\u503c\uff0c\u5373\u4f7f findBook \u6210\u529f\u627e\u5230\u4e86\u4e66\u7c4d\uff0c\u4e5f\u4f1a\u6267\u884c getDefaultBook \u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u4f5c\u4e3a\u6b7b\u4ea1\u53f3\u503c\u4e22\u5f03\u3002\u5982\u679c\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\u7684\u8fc7\u7a0b\u5f88\u6162\uff0c\u90a3\u4e48\u5c31\u975e\u5e38\u4f4e\u6548\u3002 \u4e3a\u6b64\uff0cC++23 \u5f15\u5165\u4e86 or_else \u51fd\u6570\u3002 \u53ea\u6709 findBook \u627e\u4e0d\u5230\u65f6\u624d\u4f1a\u6267\u884c lambda \u4e2d\u7684\u51fd\u6570\u4f53\uff1a auto o = findBook(isbn).or_else([] -> std::optional { cout << \"findBook \u51fa\u9519\u4e86\uff0c\u73b0\u5728\u5f00\u59cb\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\uff0c\u975e\u5e38\u6162\\n\"; return getDefaultBook(); }); \u2014 \u6b64\u7c7b\u51fd\u6570\u90fd\u53ef\u4ee5\u53cd\u590d\u5d4c\u5957\uff1a int i = cin.readLine() .or_else(getDefaultLine) .and_then(parseInt) .transform([] (auto i) { return i * 2; }) .value_or(0); \u52a0\u5165\u51fd\u6570\u5f0f\u795e\u6559\u5427\uff0c\u51fd\u95e8\uff01 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u4f8b\u5982 std::stack \u7684\u8bbe\u8ba1\u5c31\u975e\u5e38\u5931\u8d25\uff1a if (!stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u6211\u4eec\u5fc5\u987b\u5224\u65ad stack \u4e0d\u4e3a\u7a7a\uff0c\u624d\u80fd\u5f39\u51fa\u6808\u9876\u5143\u7d20\u3002\u5bf9\u7740\u4e00\u4e2a\u7a7a\u7684\u6808 pop \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u800c pop() \u53c8\u662f\u4e00\u4e2a\u8fd4\u56de void \u7684\u51fd\u6570\uff0c\u4ed6\u53ea\u662f\u5220\u9664\u6808\u9876\u5143\u7d20\uff0c\u5e76\u4e0d\u4f1a\u8fd4\u56de\u5143\u7d20\u3002 \u6211\u4eec\u5fc5\u987b\u5148\u8c03\u7528 top() \u628a\u6808\u9876\u53d6\u51fa\u6765\uff0c\u7136\u540e\u624d\u80fd pop\uff01 \u660e\u660e\u662f\u540c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5374\u8981\u62c6\u6210\u4e09\u4e2a\u51fd\u6570\u6765\u5b8c\u6210\uff0c\u5f88\u70c2\u3002\u5982\u679c\u4f60\u4e0d\u614e\u628a\u5224\u65ad\u6761\u4ef6\u5199\u53cd\uff1a if (stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u5c31\u4e00\u4e2a Segmentation Fault \u8e66\u4f60\u8138\u4e0a\uff0c\u4f60\u627e\u534a\u5929\u90fd\u627e\u4e0d\u5230\u81ea\u5df1\u54ea\u9519\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u8bbe\u8ba1\uff0c\u6574\u5408\u6210\u4e00\u4e2a\u51fd\u6570\uff1a std::optional pop(); \u8bed\u4e49\u660e\u786e\uff0c\u7528\u8d77\u6765\u4e5f\u65b9\u4fbf\uff0c\u7528\u6237\u4e0d\u5bb9\u6613\u72af\u9519\u3002 if (auto val = stack.pop()) { ... } \u628a\u591a\u4e2a\u672c\u5c31\u5c5e\u4e8e\u540c\u4e00\u4ef6\u4e8b\u7684\u51fd\u6570\uff0c\u6574\u5408\u6210\u4e00\u4e2a\uff0c\u907f\u514d\u7528\u6237\u4e2d\u95f4\u51fa\u7eb0\u6f0f\u3002 \u4ece\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u4e0a\uff0c\u9650\u5b9a\u81ea\u7531\u5ea6\uff0c\u51cf\u8f7b\u7528\u6237\u601d\u8003\u8d1f\u62c5\u3002 \u2014 \u4f17\u6240\u5468\u77e5\uff0cvector \u6709\u4e24\u4e2a\u51fd\u6570\u7528\u4e8e\u8bbf\u95ee\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 int &operator[](size_t index); int &at(size_t index); vec[3]; // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u53d1\u751f\u6570\u7ec4\u8d8a\u754c\uff01\u8fd9\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vec.at(3); // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u629b\u51fa out_of_range \u5f02\u5e38 \u7528\u6237\u901a\u5e38\u4f1a\u6839\u636e\u81ea\u5df1\u7684\u9700\u8981\uff0c\u5982\u679c\u4ed6\u4eec\u975e\u5e38\u81ea\u4fe1\u81ea\u5df1\u7684\u7d22\u5f15\u4e0d\u4f1a\u8d8a\u754c\uff0c\u53ef\u4ee5\u7528\u9ad8\u6548\u7684 []\uff0c\u4e0d\u505a\u68c0\u6d4b\u3002 \u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u53ef\u4ee5\u7528\u66f4\u5b89\u5168\u7684 at()\uff0c\u4e00\u65e6\u8d8a\u754c\u81ea\u52a8\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u8c03\u8bd5\u3002 \u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u8bbe\u8ba1\u4e00\u4e2a .get() \u51fd\u6570\uff1a std::optional get(size_t index); \u5f53\u68c0\u6d4b\u5230\u6570\u7ec4\u8d8a\u754c\u65f6\uff0c\u8fd4\u56de nullopt\u3002 *vec.get(3); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u6027\u80fd\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ece\u800c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u4f18\u5316\u6389\u8d8a\u754c\u7684\u8def\u5f84 vec.get(3).value(); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u5b89\u5168\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u4e00\u4e2a\u5f02\u5e38 vec.get(3).value_or(0); // \u5982\u679c\u7528\u6237\u60f3\u8981\u5728\u8d8a\u754c\u65f6\u83b7\u5f97\u9ed8\u8ba4\u503c 0 \u8fd9\u6837\u5c31\u53ea\u9700\u8981\u4e00\u4e2a\u51fd\u6570\uff0c\u4e0d\u8bba\u7528\u6237\u60f3\u8981\u7684\u662f\u4ec0\u4e48\uff0c\u90fd\u53ea\u9700\u8981\u8fd9\u4e00\u4e2a\u7edf\u4e00\u7684 get() \u51fd\u6570\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8fd9\u4e2a\u53ea\u80fd get\uff0c\u8981\u5982\u4f55 set \u5440\uff1f std::optional get(size_t index); bool set(size_t index, int value); // \u5982\u679c\u8d8a\u754c\uff0c\u8fd4\u56de false \u7f3a\u70b91\uff1a\u8fd4\u56de bool \u65e0\u6cd5\u8fd0\u7528 optional \u7684\u5c0f\u6280\u5de7\uff1a\u901a\u8fc7 value() \u8f6c\u5316\u4e3a\u5f02\u5e38\uff0c\u4e14\u7528\u6237\u5bb9\u6613\u5fd8\u8bb0\u68c0\u67e5\u8fd4\u56de\u503c\u3002 \u7f3a\u70b92\uff1a\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f size_t \u4e00\u4e2a\u662f int\uff0c\u8fd8\u662f\u5f88\u5bb9\u6613\u987a\u5e8f\u641e\u6df7\u3002 std::optional> get(size_t index); auto x = **vec.get(3); // \u6027\u80fd\u8bfb auto x = *vec.get(3).value(); // \u5b89\u5168\u8bfb *vec.get(3) = 42; // \u6027\u80fd\u5199 vec.get(3).value() = 42; // \u5b89\u5168\u5199 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 void Sleep(int delay); \u8c01\u77e5\u9053\u8fd9\u4e2a delay \u7684\u5355\u4f4d\u662f\u4ec0\u4e48\uff1f\u79d2\uff1f\u6beb\u79d2\uff1f void Sleep(int ms); \u597d\u5427\uff0c\u662f\u6beb\u79d2\u3002\u53ef\u662f\u9664\u975e\u770b\u4e00\u773c\u51fd\u6570\u5b9a\u4e49\u6216\u6587\u6863\uff0c\u8c01\u60f3\u5f97\u5230\u8fd9\u662f\u4e2a\u6beb\u79d2\uff1f \u4e00\u4e2a\u7528\u6237\u60f3\u8981\u7761 3 \u79d2\uff0c\u4ed6\u5199\u9053\uff1a Sleep(3); \u7f16\u8bd1\u5668\u6ca1\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u4e00\u8fd0\u884c\u53ea\u7761\u4e86 3 \u6beb\u79d2\u3002 \u7528\u6237\u5927\u53d1\u96f7\u9706\u4ee5\u4e3a\u4f60\u7684 Sleep \u51fd\u6570\u6709 BUG\uff0c\u6211\u8ba9\u4ed6\u7761 3 \u79d2\u600e\u4e48\u597d\u50cf\u6839\u672c\u6ca1\u7761\u554a\u3002 \u2014 void SleepMilliSeconds(int ms); \u6539\u4e2a\u51fd\u6570\u540d\u53ef\u4ee5\u89e3\u51b3\u4e00\u90e8\u5206\u95ee\u9898\uff0c\u5f53\u7528\u6237\u8c03\u7528\u65f6\uff0c\u4ed6\u9700\u8981\u624b\u52a8\u6253\u51fa MilliSeconds \uff0c\u4ece\u800c\u5f3a\u8feb\u4ed6\u6e05\u9192\u4e00\u4e0b\uff0c\u81ea\u5df1\u7ed9\u7684 3 \u5230\u5e95\u662f\u4e0d\u662f\u81ea\u5df1\u60f3\u8981\u7684\u3002 \u2014 struct MilliSeconds { int count; explicit MilliSeconds(int count) : count(count) {} }; void Sleep(MilliSeconds delay); \u73b0\u5728\uff0c\u5982\u679c\u7528\u6237\u5199\u51fa Sleep(3); \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\u3002 \u4ed6\u5fc5\u987b\u660e\u786e\u5199\u51fa Sleep(MilliSeconds(3)); \u624d\u80fd\u901a\u8fc7\u7f16\u8bd1\u3002 \u2014 \u6807\u51c6\u5e93\u7684 chrono \u6a21\u5757\u5c31\u5927\u91cf\u8fd0\u7528\u4e86\u8fd9\u79cd\u5f3a\u7c7b\u578b\u5c01\u88c5\uff1a this_thread::sleep_for(chrono::seconds(3)); \u5982\u679c\u4f60 using namespace std::literials; \u8fd8\u53ef\u4ee5\u8fd9\u6837\u5feb\u6377\u5730\u521b\u5efa\u5b57\u9762\u91cf\uff1a this_thread::sleep_for(3ms); // 3 \u6beb\u79d2 this_thread::sleep_for(3s); // 3 \u79d2 this_thread::sleep_for(3m); // 3 \u5206\u949f this_thread::sleep_for(3h); // 3 \u5c0f\u65f6 \u4e14\u652f\u6301\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c\u4e0d\u540c\u5355\u4f4d\u4e4b\u95f4\u8fd8\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\uff1a this_thread::sleep_for(1s + 200ms); chrono::minutes three_minutes = 180s; \u2014 chrono \u662f\u4e00\u4e2a\u4f18\u79c0\u7684\u7c7b\u578b\u5c01\u88c5\u6848\u4f8b\uff0c\u628a time_t \u7c7b\u578b\u5c01\u88c5\u6210\u4e86\u5f3a\u7c7b\u578b\u7684 duration \u548c time_point\u3002 \u65f6\u95f4\u70b9\uff08time_point\uff09\u8868\u793a\u67d0\u4e2a\u5177\u4f53\u7684\u65f6\u95f4\uff0c\u4f8b\u5982 2024 \u5e74 5 \u6708 16 \u65e5 18:06:28\u3002 \u65f6\u95f4\u6bb5\uff08duration\uff09\u8868\u793a\u4e00\u6bb5\u65f6\u95f4\u7684\u957f\u5ea6\uff0c\u4f8b\u5982 1 \u5929\uff0c2 \u5c0f\u65f6\uff0c3 \u5206\u949f\uff0c4 \u79d2\u3002 \u65f6\u95f4\u6bb5\u5f88\u5bb9\u6613\u8868\u793a\uff0c\u53ea\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u5355\u4f4d\uff0c\u6bd4\u5982\u79d2\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u6570\u5b57\u5c31\u53ef\u4ee5\u8868\u793a\u591a\u5c11\u79d2\u7684\u65f6\u95f4\u6bb5\u3002 \u4f46\u662f\u65f6\u95f4\u70b9\u5c31\u5f88\u96be\u8868\u793a\u4e86\uff0c\u4f8b\u5982\u4f60\u65e0\u6cd5 Unix \u65f6\u95f4\u6233\u7528\u4e00\u4e2a\u6570\u5b57\u6765\u8868\u793a\u65f6\u95f4\u70b9\uff0c\u6570\u5b57\u7684\u542b\u4e49\u662f\u4ece\u5f53\u524d\u65f6\u95f4\u5230 1970 \u5e74 1 \u6708 1 \u65e5 00:00:00 \u7684\u79d2\u6570\u3002 \u4f8b\u5982\u5199\u4f5c\u8fd9\u7bc7\u6587\u7ae0\u7684\u65f6\u95f4\u6233\u662f 1715853968 (2024/5/16 18:06)\u3002 C \u8bed\u8a00\u7528\u4e00\u4e2a time_t \uff0c\u5b9e\u9645\u4e0a\u662f long \u7684\u7c7b\u578b\u522b\u540d\u6765\u8868\u793a\u65f6\u95f4\u6233\uff0c\u4f46\u5b83\u6709\u4e00\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff1a \u5b83\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u70b9\uff0c\u4e5f\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u6bb5\uff0c\u8fd9\u5c31\u9020\u6210\u4e86\u5de8\u5927\u7684\u6df7\u4e71\u3002 time_t t0 = time(NULL); // \u65f6\u95f4\u70b9 ... time_t t1 = time(NULL); // \u65f6\u95f4\u70b9 time_t dt = t1 - t0; // \u65f6\u95f4\u6bb5 \u75db\u70b9\uff1a\u5982\u679c\u8fd9\u91cc\u7684\u8d1f\u53f7\u5199\u9519\uff0c\u5199\u6210 t1 + t0 \uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u62a5\u9519\uff0c\u4f60\u53ef\u80fd\u6839\u672c\u6ca1\u53d1\u73b0\uff0c\u6d6a\u8d39\u5927\u91cf\u65f6\u95f4\u8c03\u8bd5\u6700\u540e\u53ea\u53d1\u73b0\u4e00\u4e2a\u4f4e\u7ea7\u9519\u8bef\u3002 \u6a21\u7cca\uff1a\u65f6\u95f4\u70b9\uff08t0\u3001t1\uff09\u548c\u65f6\u95f4\u6bb5\uff08dt\uff09\u90fd\u662f time_t\uff0c\u521d\u6b21\u9605\u8bfb\u4ee3\u7801\u5f88\u5bb9\u6613\u5206\u4e0d\u6e05\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5\u3002 \u5982\u679c\u4e0d\u614e\u628a\u201c\u65f6\u95f4\u70b9\u201d\u7684 time_t \u4f20\u5165\u5230\u672c\u5e94\u53ea\u652f\u6301\u201c\u65f6\u95f4\u6bb5\u201d\u7684 sleep \u51fd\u6570\uff0c\u4f1a\u51fa\u73b0\u201c\u7761\u7f8e\u4eba\u201d\u7684\u5947\u89c2\uff1a time_t t = time(NULL); // \u8fd4\u56de 1715853968 \u8868\u793a\u5f53\u524d\u65f6\u95f4\u70b9 sleep(t); // \u4e0d\u5c0f\u5fc3\u628a\u65f6\u95f4\u70b9\u5f53\u6210\u65f6\u95f4\u6bb5\u6765\u7528\u4e86\uff01 \u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u7761 1715853968 \u79d2\u540e\u624d\u9192\uff0c\u5373 54 \u5e74\u540e\uff01 chrono::system_clock::time_point last = chrono::system_clock::now(); ... chrono::system_clock::time_point now = chrono::system_clock::now(); chrono::system_clock::duration dt = now - last; cout << \"\u7528\u4e86 \" << duration_cast(dt).count() << \" \u79d2\\n\"; \u4e00\u770b\u5c31\u77e5\u9053\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5 \u7528\u9519\u4e86\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \u5355\u4f4d\u8f6c\u6362\u4e0d\u4f1a\u6df7\u6dc6 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u70b9 = \u7f16\u8bd1\u51fa\u9519\uff01\u56e0\u4e3a\u65f6\u95f4\u70b9\u4e4b\u95f4\u4e0d\u5141\u8bb8\u76f8\u52a0\uff0c2024 + 2024\uff0c\u4f60\u662f\u60f3\u52a0\u5230 4048 \u5e74\u53bb\u5417\uff1f \u65f6\u95f4\u70b9 - \u65f6\u95f4\u70b9 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u70b9 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u6bb5 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 \u00d7 \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 / \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u8fd9\u5c31\u662f\u672c\u671f\u8bfe\u7a0b\u7684\u4e3b\u9898\uff0c\u901a\u8fc7\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u5bf9\u53ef\u80fd\u7684\u7528\u6cd5\u52a0\u4ee5\u4e25\u683c\u7684\u9650\u5236\uff0c\u6700\u5927\u9650\u5ea6\u963b\u6b62\u7528\u6237\u4e0d\u7ecf\u610f\u95f4\u5199\u51fa\u9519\u8bef\u7684\u4ee3\u7801\u3002 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u4f60\u7684\u8001\u677f\u8981\u6c42\u4e00\u4e2a\u8bbe\u5b9a\u5ba2\u6237\u6027\u522b\u7684\u51fd\u6570\uff1a void foo(int sex); \u8001\u677f\u53e3\u5934\u548c\u5458\u5de5\u7ea6\u5b9a\u8bf4\uff0c0\u8868\u793a\u5973\uff0c1\u8868\u793a\u7537\uff0c2\u8868\u793a\u81ea\u5b9a\u4e49\u3002 \u8fd9\u8c01\u8bb0\u5f97\u4f4f\uff1f\u8bbe\u60f3\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u7684\u4ee3\u7801\uff1a foo(1); \u4f60\u80fd\u731c\u5230\u8fd9\u4e2a 1 \u662f\u4ec0\u4e48\u610f\u601d\u5417\uff1f \u89e3\u51b3\u65b9\u6cd5\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff0c\u7ed9\u6bcf\u4e2a\u6570\u503c\u4e00\u4e2a\u552f\u4e00\u7684\u540d\u5b57\uff1a enum Sex { Female = 0, Male = 1, Custom = 2, }; void foo(Sex sex); \u518d\u5047\u8bbe\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\uff1a foo(Male); \u662f\u4e0d\u662f\u5c31\u4e00\u76ee\u4e86\u7136\u5566\uff1f \u2014 \u679a\u4e3e\u7684\u503c\u4e5f\u53ef\u4ee5\u4e0d\u7528\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u6309 0\u30011\u30012 \u7684\u987a\u5e8f\u5206\u914d\u503c\uff1a enum Sex { Female, // 0 Male, // 1 Custom, // 2 }; \u53ef\u4ee5\u6307\u5b9a\u4ece 1 \u5f00\u59cb\u8ba1\u6570\uff1a enum Sex { Female = 1, Male, // 2 Custom, // 3 }; \u2014 \u4f46\u679a\u4e3e\u7c7b\u578b\u8fd8\u662f\u53ef\u4ee5\u9a97\u4eba\uff0c\u518d\u5047\u8bbe\u4f60\u662f\u65b0\u6765\u7684\uff0c\u770b\u5230\uff1a foo(Male, 24); \u662f\u4e0d\u662f\u60f3\u5f53\u7136\u7684\u611f\u89c9\u8fd9\u4e2a\u4ee3\u7801\u6ca1\u95ee\u9898\uff1f \u4f46\u5f53\u4f60\u770b\u5230 foo \u51c6\u786e\u7684\u51fd\u6570\u5b9a\u4e49\u65f6\uff0c\u50bb\u773c\u4e86\uff1a void foo(int age, Sex sex); \u76f8\u5f53\u4e8e\u6ce8\u518c\u4e86\u4e00\u4e2a 1 \u5c81\uff0c\u6027\u522b\u662f 24 \u7684\u4f2a\u4eba\u3002\u4e14\u7a0b\u5e8f\u5458\u5f88\u5bb9\u6613\u770b\u4e0d\u51fa\u95ee\u9898\uff0c\u7f16\u8bd1\u5668\u4e5f\u4e0d\u62a5\u9519\u3002 \u4e3a\u6b64\uff0cC++11 \u5f15\u5165\u4e86 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff1a enum class Sex { Female = 0, Male = 1, Custom = 2, }; \u73b0\u5728\uff0c\u5982\u679c\u4f60\u518d\u4e0d\u5c0f\u5fc3\u628a sex \u4f20\u5165 age \u7684\u8bdd\uff0c\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\uff01\u56e0\u4e3a\u5f3a\u7c7b\u578b\u679a\u4e3e\u4e0d\u5141\u8bb8\u4e0e int \u9690\u5f0f\u8f6c\u6362\u3002 \u800c\u4e14\u5f3a\u7c7b\u578b\u679a\u4e3e\u4f1a\u9700\u8981\u663e\u5f0f\u5199\u51fa Sex:: \u7c7b\u578b\u524d\u7f00\uff0c\u5f53\u4f60\u6709\u5f88\u591a\u679a\u4e3e\u7c7b\u578b\u65f6\u4e0d\u5bb9\u6613\u6df7\u6dc6\uff1a foo(24, Sex::Male); \u5982\u679c\u4f60\u7684 Sex \u8303\u56f4\u5f88\u5c0f\uff0c\u53ea\u9700\u8981 uint8_t \u7684\u5185\u5b58\u5c31\u591f\uff0c\u53ef\u4ee5\u7528\u8fd9\u4e2a\u8bed\u6cd5\u6307\u5b9a\u679a\u4e3e\u7684\u201c\u540e\u53f0\u7c7b\u578b\u201d\uff1a enum class Sex : uint8_t { Female = 0, Male = 1, Custom = 2, }; static_assert(sizeof(Sex) == 1); \u2014 \u5047\u5982\u4f60\u7684\u6240\u6709 age \u90fd\u662f int \u7c7b\u578b\u7684\uff0c\u4f46\u662f\u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u5fc3\u8840\u6765\u6f6e\uff1a \u8bf4\u4e3a\u4e86\u201c\u4f18\u5316\u5b58\u50a8\u7a7a\u95f4\u201d\uff0c\u60f3\u8981\u628a\u6240\u6709 age \u6539\u6210 uint8_t \u7c7b\u578b\u7684\uff01 \u4e3a\u4e86\u9884\u9632\u672a\u6765\u53ef\u80fd\u9700\u8981\u6539\u53d8\u7c7b\u578b\u7684\u9700\u6c42\uff0c\u4e5f\u662f\u4e3a\u4e86\u53ef\u8bfb\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using Age = int; void foo(Age age, Sex sex); \u8fd9\u6837\u5f53\u8001\u677f\u9700\u8981\u6539\u53d8\u5e95\u5c42\u7c7b\u578b\u65f6\uff0c\u53ea\u9700\u8981\u6539\u52a8\u4e00\u884c\uff1a using Age = uint8_t; \u5c31\u80fd\u81ea\u52a8\u8ba9\u6240\u6709\u4ee3\u7801\u90fd\u4f7f\u7528 uint8_t \u4f5c\u4e3a age \u4e86\u3002 \u2014 \u4f46\u662f\u7c7b\u578b\u522b\u540d\u6bd5\u7adf\u53ea\u662f\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u4fdd\u969c\uff1a using Age = int; using Phone = int; foo(Age age, Phone phone); void bar() { Age age = 42; Phone phone = 12345; foo(phone, age); // \u4e0d\u5c0f\u5fc3\u5199\u53cd\u4e86\uff01\u800c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u63d0\u9192\u4f60\uff01 } \u56e0\u4e3a Age \u548c Phone \u53ea\u662f\u7c7b\u578b\u522b\u540d\uff0c\u5b9e\u9645\u4e0a\u8fd8\u662f\u540c\u6837\u7684 int \u7c7b\u578b\u2026\u6240\u4ee5\u7f16\u8bd1\u5668\u751a\u81f3\u4e0d\u4f1a\u6709\u4efb\u4f55\u8b66\u544a\u3002 \u6709\u4e00\u79cd\u5f88\u6781\u7aef\u7684\u505a\u6cd5\u662f\u628a Age \u548c Phone \u4e5f\u505a\u6210\u679a\u4e3e\uff0c\u4f46\u6ca1\u6709\u5b9a\u4e49\u4efb\u4f55\u503c\uff1a enum class Age : int {}; enum class Phone : int {}; \u8fd9\u6837\u7528\u5230\u7684\u65f6\u5019\u5c31\u53ea\u80fd\u901a\u8fc7\u5f3a\u5236\u8f6c\u6362\u7684\u8bed\u6cd5\uff1a foo(Age(42), Phone(12345)); \u5e76\u4e14\u5982\u679c\u5199\u9519\u987a\u5e8f\uff0c\u5c1d\u8bd5\u628a Phone \u4f20\u5165 Age \u7c7b\u578b\u7684\u53c2\u6570\uff0c\u7f16\u8bd1\u5668\u4f1a\u7acb\u5373\u62a5\u9519\uff0c\u963b\u6b62\u4f60\u57cb\u4e0b BUG \u9690\u60a3\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u7684\u65b9\u6cd5\u4ee5\u540e\uff0c\u4e0d\u80fd\u505a\u52a0\u6cd5\u4e86\u600e\u4e48\u529e\uff1f Age(42) + Age(1) // \u7f16\u8bd1\u5668\u9519\u8bef\uff01 \u8fd9\u662f\u56e0\u4e3a Age \u662f\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u4e0d\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a int \u540e\u505a\u52a0\u6cd5\u3002 \u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff1a enum class Age : int {}; inline Age operator+(Age a, Age b) { return Age((int)a + (int)b); } \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u76f4\u63a5\u8ba9\u52a0\u6cd5\u8fd0\u7b97\u7b26\u5bf9\u4e8e\u6240\u6709\u679a\u4e3e\u7c7b\u578b\u90fd\u9ed8\u8ba4\u751f\u6548\uff1a template requires std::is_enum_v T operator+(T a, T b) { using U = std::underlying_type_t; return T((U)a + (U)b); } \u6709\u65f6\u8fd9\u53cd\u800c\u662f\u4e2a\u4f18\u70b9\uff0c\u6bd4\u5982\u4f60\u53ef\u4ee5\u53ea\u5b9a\u4e49\u52a0\u6cd5\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u8ba9 Age \u4e0d\u652f\u6301\u4e58\u6cd5\uff0c\u9700\u8981\u624b\u52a8\u8f6c\u6362\u540e\u624d\u80fd\u4e58\uff0c\u907f\u514d\u65e0\u610f\u4e2d\u72af\u9519\u7684\u53ef\u80fd\u3002 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u63a8\u8350\u7684 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff0c\u4e0d\u652f\u6301\u6211\u6700\u7231\u7684\u6216\u8fd0\u7b97 | \u4e86\u600e\u4e48\u529e\uff1f enum class OpenFlag { Create = 1, Read = 2, Write = 4, Truncate = 8, Append = 16, Binary = 32, }; inline OpenFlag operator|(OpenFlag a, OpenFlag b) { return OpenFlag((int)a | (int)b); } inline OpenFlag operator&(OpenFlag a, OpenFlag b) { return OpenFlag((int)a & (int)b); } inline OpenFlag operator~(OpenFlag a) { return OpenFlag(~(int)a); } \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5f88\u559c\u6b22\u5f3a\u7c7b\u578b\u679a\u4e3e\u8fd9\u4e00\u5957\uff0c\u4f46\u6211\u7684\u53c2\u6570\u4e0d\u662f\u6574\u6570\u7c7b\u578b\uff0c\u800c\u662f double\u3001string \u7b49\u7c7b\u578b\uff0c\u600e\u4e48\u529e\uff1f struct Name { private: std::string value; public: explicit operator std::string() const { return value; } explicit Name(std::string value) : value(value) {} }; \u8fd9\u91cc\u6211\u4eec\u5199 explicit \u5c31\u53ef\u4ee5\u963b\u6b62\u9690\u5f0f\u7c7b\u578b\u8f6c\u6362\uff0c\u8d77\u5230\u4e0e\u5f3a\u7c7b\u578b\u679a\u4e3e\u7c7b\u4f3c\u7684\u4f5c\u7528\u3002 \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff1a // \u6b64\u5904\u4f7f\u7528 CRTP \u6a21\u5f0f\u662f\u4e3a\u4e86\u8ba9 Typed \u6bcf\u6b21\u90fd\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684\u57fa\u7c7b\uff0c\u963b\u6b62 object-slicing template struct Typed { protected: T value; public: explicit operator T() const { return value; } explicit Typed(T value) : value(value) {} }; struct Name : Typed {}; struct Meter : Typed { using Typed::Typed; }; struct Kilometer : Typed { using Typed::Typed; operator Meter() const { // \u5141\u8bb8\u9690\u5f0f\u8f6c\u6362\u4e3a\u7c73 return Meter(value * 1000); } }; Meter m = Kilometer(1); // m = Meter(1000); foo(m); \u2014 RAII \u5c01\u88c5 \u2014 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7684\u51fd\u6570\u5c31\u662f\u6d89\u53ca\u201c\u5f00\u59cb\u201d\u548c\u201c\u7ed3\u675f\u201d\u4e24\u4e2a\u64cd\u4f5c\uff0c\u7528\u6237\u7684\u64cd\u4f5c\u9700\u8981\u7a7f\u63d2\u5728\u5176\u4e2d\u95f4\uff0c\u600e\u4e48\u6574\u5408\u5462\uff1f mysql_connection *conn = mysql_connect(\"127.0.0.1\"); mysql_execute(conn, \"drop database paolu\"); mysql_close(conn); // \u7528\u6237\u53ef\u80fd\u5fd8\u8bb0\u5173\u95ed\u8fde\u63a5\uff01\u7834\u574f\u5e93\u8bbe\u8ba1\u8005\u60f3\u8981\u7684\u7528\u6cd5 \u8fd9\u79cd\u5927\u591a\u662f\u83b7\u53d6\u8d44\u6e90\uff0c\u548c\u91ca\u653e\u8d44\u6e90\u4e24\u4e2a\u64cd\u4f5c\u3002 \u56e0\u4e3a mysql \u662f\u4e2a C \u8bed\u8a00\u7684\u5e93\uff0c\u4ed6\u6ca1\u6709 RAII \u5c01\u88c5\uff0c\u8ba9\u4ed6\u624b\u52a8\u5c01\u88c5\u6709\u7684\u540c\u5b66\u53c8\u5acc\u5f03\u9ebb\u70e6\u3002 \u8fd9\u65f6\u6211\u4f1a\u544a\u8bc9\u4ed6\u4eec\u4e00\u4e2a shared_ptr \u5c0f\u5999\u62db\uff1a\u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u6307\u5b9a\u91ca\u653e\u51fd\u6570\uff0c\u4ee3\u66ff\u9ed8\u8ba4\u7684 delete auto conn = std::shared_ptr(mysql_connect(\"127.0.0.1\"), mysql_close); mysql_execute(conn.get(), \"drop database paolu\"); // conn \u79bb\u5f00\u4f5c\u7528\u57df\u65f6\uff0c\u4f1a\u81ea\u52a8\u8c03\u7528 mysql_close\uff0c\u675c\u7edd\u4e86\u4e00\u4e2a\u51fa\u9519\u7684\u53ef\u80fd \u2014 \u4ee5\u5c01\u88c5 C \u8bed\u8a00\u7684 FILE \u4e3a\u4f8b\u3002 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *file); \u8fd9\u4e2a size \u548c nmemb \u771f\u662f\u592a\u7cdf\u7cd5\u4e86\uff0c\u672c\u610f\u662f\u4e3a\u4e86\u652f\u6301\u4e0d\u540c\u5143\u7d20\u7c7b\u578b\u7684\u6570\u7ec4\u3002 size \u662f\u5143\u7d20\u672c\u8eab\u5927\u5c0f\uff0cnmemb \u662f\u5143\u7d20\u6570\u91cf\u3002\u5b9e\u9645\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u662f size * nmemb\u3002 \u6211\u5c31\u7ecf\u5e38\u628a ptr \u548c file \u987a\u5e8f\u5199\u53cd\uff0c\u8fd9\u4e2a\u83ab\u540d\u5176\u5999\u7684\u53c2\u6570\u987a\u5e8f\u592a\u53cd\u76f4\u89c9\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u8fd0\u7528\u73b0\u4ee3 C++ \u601d\u60f3\u5c01\u88c5\u4e4b\uff1a using FileHandle = std::shared_ptr; enum class OpenMode { Read, Write, Append, }; inline OpenMode operator|(OpenMode a, OpenMode b) { return OpenMode((int)a | (int)b); } auto modeLut = std::map{ {OpenMode::Read, \"r\"}, {OpenMode::Write, \"w\"}, {OpenMode::Append, \"a\"}, {OpenMode::Read | OpenMode::Write, \"w+\"}, {OpenMode::Read | OpenMode::Append, \"a+\"}, }; FileHandle file_open(std::filesystem::path path, OpenMode mode) { #ifdef _WIN32 return std::shared_ptr(_wfopen(path.wstring().c_str(), modeLut.at(mode).c_str()), fclose); #else return std::shared_ptr(fopen(path.string().c_str(), modeLut.at(mode).c_str()), fclose); #endif } struct [[nodiscard]] FileResult { std::optional numElements; std::errc errorCode; // std::errc \u662f\u4e2a\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u7528\u4e8e\u53d6\u4ee3 C \u8bed\u8a00 errno \u7684 int \u7c7b\u578b bool isEndOfFile; }; template FileResult file_read(FileHandle file, std::span elements) { auto n = fread(elements.data(), sizeof(T), elements.size(), file.get()); return { .numElements = n == 0 ? std::optional(n) : std::nullopt, .errorCode = std::errc(ferror(file.get())), .isEndOfFile = (bool)feof(file.get()), }; } \u662f\u4e0d\u662f\u63a5\u53e3\u66f4\u52a0\u7b80\u5355\u6613\u61c2\uff0c\u6ca1\u6709\u72af\u9519\u7684\u673a\u4f1a\u4e86\uff1f FileHandle file = file_open(\"hello.txt\", OpenMode::Read); int arr[32]; file_read(file, arr).numElements.value(); // \u5982\u679c\u6ca1\u6709\u8bfb\u5230\u4e1c\u897f\uff0c\u8fd9\u91cc\u4f1a\u629b\u51fa\u5f02\u5e38 // \u9000\u51fa\u4f5c\u7528\u57df\u65f6\uff0cshared_ptr \u4f1a\u81ea\u52a8\u4e3a\u4f60\u5173\u95ed\u6587\u4ef6\uff0c\u65e0\u9700\u518d\u63d0\u4f9b file_close \u51fd\u6570 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014 TODO","title":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357"},{"location":"type_rich_api/#api","text":"\u5982\u4f55\u5199\u51fa\u6613\u4e8e\u7ef4\u62a4\u7684\u4ee3\u7801\uff0c\u963b\u6b62\u72af\u9519\uff1f \u7c7b\u578b\u5c31\u662f\u6700\u597d\u7684\u6ce8\u91ca\uff01 Type is all you need \u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357 \u2014 \u7ed3\u6784\u4f53\u4f20\u53c2 \u2014 \u2014 \u2014 \u2014 \u2014 \u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53 \u2014 \u7c7b\u578b\u5373\u6ce8\u91ca \u2014 \u2014 \u62d2\u7edd\u6307\u9488\uff01 \u2014 \u2014 \u5f3a\u7c7b\u578b\u5c01\u88c5 \u2014 \u2014 span \u201c\u80d6\u6307\u9488\u201d \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u7a7a\u503c\u8bed\u4e49 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1 \u2014 \u2014 \u2014 \u2014 \u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u679a\u4e3e\u7c7b\u578b \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u2014 \u5176\u4ed6\u7c7b\u578b\u5957\u76ae \u2014 \u2014 RAII \u5c01\u88c5 \u2014 \u2014 \u2014 Mutex \u5c01\u88c5 \u2014 \u2014 \u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218 \u2014 \u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236 \u2014 \u2014 \u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f \u2014","title":"\u73b0\u4ee3\u5316\u7684 API \u8bbe\u8ba1\u6307\u5357"},{"location":"type_rich_api/#_1","text":"","title":"—"},{"location":"type_rich_api/#_2","text":"","title":"\u7ed3\u6784\u4f53\u4f20\u53c2"},{"location":"type_rich_api/#_3","text":"void foo(string name, int age, int phone, int address); foo(\"\u5c0f\u5f6d\u8001\u5e08\", 24, 12345, 67890); \u75db\u70b9\uff1a\u53c2\u6570\u591a\uff0c\u7c7b\u578b\u76f8\u4f3c\uff0c\u5bb9\u6613\u987a\u5e8f\u5199\u9519\u800c\u81ea\u5df1\u4e0d\u5bdf\u89c9 \u5929\u4e66\uff1a\u9605\u8bfb\u4ee3\u7801\u65f6\u770b\u4e0d\u89c1\u53c2\u6570\u540d\uff0c\u4e0d\u6e05\u695a\u6bcf\u4e2a\u53c2\u6570\u5206\u522b\u4ee3\u8868\u4ec0\u4e48 \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void foo(FooOptions opts); foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .age = 24, .phone = 12345, .address = 67890}); \u2714\ufe0f \u4f18\u96c5\uff0c\u6bcf\u4e2a\u53c2\u6570\u8d1f\u8d23\u505a\u4ec0\u4e48\u4e00\u76ee\u4e86\u7136","title":"—"},{"location":"type_rich_api/#_4","text":"\u4e5f\u6709\u67d0\u4e9b\u5927\u5382\u63a8\u5d07\u6ce8\u91ca\u53c2\u6570\u540d\u6765\u589e\u5f3a\u53ef\u8bfb\u6027\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*age=*/24, /*phone=*/12345, /*address=*/67890); \u4f46\u6ce8\u91ca\u53ef\u4ee5\u9a97\u4eba\uff1a foo(/*name=*/\"\u5c0f\u5f6d\u8001\u5e08\", /*phone=*/12345, /*age=*/24, /*address=*/67890); \u8fd9\u91cc age \u548c phone \u53c2\u6570\u5199\u53cd\u4e86\uff01\u9605\u8bfb\u8005\u5982\u679c\u4e0d\u770b\u4e0b foo \u7684\u5b9a\u4e49\uff0c\u6839\u672c\u53d1\u73b0\u4e0d\u4e86 \u800c\u4ee3\u7801\u4e0d\u4f1a\uff1a // \u5373\u4f7f\u987a\u5e8f\u5199\u9519\uff0c\u53ea\u8981\u540d\u5b57\u5199\u5bf9\u4f9d\u7136\u53ef\u4ee5\u6b63\u5e38\u8fd0\u884c foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890}); \u603b\u4e4b\uff0c\u597d\u7684 API \u8bbe\u8ba1\u7edd\u4e0d\u4f1a\u7ed9\u4eba\u7559\u4e0b\u72af\u9519\u7684\u673a\u4f1a\uff01","title":"—"},{"location":"type_rich_api/#_5","text":"\u518d\u6765\u770b\u4e00\u4e2a\u573a\u666f\uff0c\u5047\u8bbefoo\u5185\u90e8\u9700\u8981\u628a\u6240\u6709\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u51fd\u6570bar\uff1a void bar(int index, string name, int age, int phone, int address); void foo(string name, int age, int phone, int address) { bar(get_hash_index(name), name, age, phone, address); } \u75db\u70b9\uff1a\u4f60\u9700\u8981\u4e0d\u65ad\u5730\u590d\u5236\u7c98\u8d34\u6240\u6709\u8fd9\u4e9b\u53c2\u6570\uff0c\u975e\u5e38\u5bb9\u6613\u6284\u9519 \u75db\u70b9\uff1a\u4e00\u65e6\u53c2\u6570\u7c7b\u578b\u6709\u6240\u4fee\u6539\uff0c\u6216\u8005\u8981\u52a0\u65b0\u53c2\u6570\uff0c\u9700\u8981\u6bcf\u4e2a\u5730\u65b9\u90fd\u6539\u4e00\u4e0b \u600e\u4e48\u529e\uff1f struct FooOptions { string name; int age; int phone; int address; }; void bar(int index, FooOptions opts); void foo(FooOptions opts) { // \u6240\u6709\u903b\u8f91\u4e0a\u76f8\u5173\u7684\u53c2\u6570\u5168\u5408\u5e76\u6210\u4e00\u4e2a\u7ed3\u6784\u4f53\uff0c\u65b9\u4fbf\u4f7f\u7528\u66f4\u65b9\u4fbf\u9605\u8bfb bar(get_hash_index(opts.name), opts); } \u2714\ufe0f \u4f18\u96c5","title":"—"},{"location":"type_rich_api/#_6","text":"\u5f53\u8001\u677f\u8981\u6c42\u4f60\u589e\u52a0\u4e00\u4e2a\u53c2\u6570 sex\uff0c\u52a0\u5728 age \u540e\u9762\uff1a -void foo(string name, int age, int phone, int address); +void foo(string name, int age, int sex, int phone, int address); \u4f60\u624b\u5fd9\u811a\u4e71\u5730\u6253\u5f00\u6240\u6709\u8c03\u7528\u4e86 foo \u7684\u6587\u4ef6\uff0c\u53d1\u73b0\u6709\u5927\u91cf\u5730\u65b9\u9700\u8981\u4fee\u6539\u2026 \u800c\u4f18\u96c5\u7684 API \u603b\u8bbe\u8ba1\u5e08\u5c0f\u5f6d\u8001\u5e08\u53ea\u9700\u8f7b\u8f7b\u4fee\u6539\u4e00\u5904\uff1a struct FooOptions { string name; int age; int sex = 0; // \u4ee4 sex \u9ed8\u8ba4\u4e3a 0 int phone; int address; }; \u6240\u6709\u7684\u8001\u4ee3\u7801\u4f9d\u7136\u7167\u5e38\u8c03\u7528\u65b0\u7684 foo \u51fd\u6570\uff0c\u672a\u6307\u5b9a\u7684 sex \u4f1a\u5177\u6709\u7ed3\u6784\u4f53\u91cc\u5b9a\u4e49\u7684\u9ed8\u8ba4\u503c 0\uff1a foo({.name = \"\u5c0f\u5f6d\u8001\u5e08\", .phone = 12345, .age = 24, .address = 67890});","title":"—"},{"location":"type_rich_api/#_7","text":"","title":"—"},{"location":"type_rich_api/#_8","text":"\u5f53\u4f60\u9700\u8981\u591a\u4e2a\u8fd4\u56de\u503c\u65f6\uff1a\u4e0d\u8981\u8fd4\u56de pair \u6216 tuple\uff01 \u4e00\u4e9b STL \u5bb9\u5668\u7684 API \u8bbe\u8ba1\u662f\u53cd\u9762\u5178\u578b\uff0c\u4f8b\u5982\uff1a std::pair insert(std::pair entry); \u7528\u7684\u65f6\u5019\u6bcf\u6b21\u90fd\u8981\u60f3\u4e00\u4e0b\uff0c\u5230\u5e95\u7b2c\u4e00\u4e2a\u662f bool \u8fd8\u662f\u7b2c\u4e8c\u4e2a\u662f bool \u6765\u7740\uff1f\u7136\u540e\u770b\u4e00\u773c IDE \u63d0\u793a\uff0c\u624d\u53cd\u5e94\u8fc7\u6765\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.first << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.second << '\\n'; first\uff1fsecond\uff1f\u8fd9\u7b97\u4ec0\u4e48\u9b3c\uff1f \u66f4\u597d\u7684\u505a\u6cd5\u662f\u8fd4\u56de\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; insert_result_t insert(std::pair entry); \u76f4\u63a5\u901a\u8fc7\u540d\u5b57\u8bbf\u95ee\u6210\u5458\uff0c\u8bed\u4e49\u6e05\u6670\u660e\u786e\uff0c\u6211\u7ba1\u4f60\u662f\u7b2c\u4e00\u4e2a\u7b2c\u4e8c\u4e2a\uff0c\u6211\u53ea\u60f3\u8981\u8868\u793a\u201c\u662f\u5426\u6210\u529f(success)\u201d\u7684\u90a3\u4e2a\u53d8\u91cf\u3002 auto result = map.insert({\"hello\", \"world\"}); cout << \"\u662f\u5426\u6210\u529f: \" << result.success << '\\n'; cout << \"\u63d2\u5165\u5230\u4f4d\u7f6e: \" << result.position << '\\n'; \u6700\u597d\u5f53\u7136\u662f\u8fd4\u56de\u548c\u53c2\u6570\u7c7b\u578b\u90fd\u662f\u7ed3\u6784\u4f53\uff1a struct insert_result_t { bool success; iterator position; }; struct map_entry_t { K key; V value; }; insert_result_t insert(map_entry_t entry); \u8fd9\u91cc\u8bf4\u7684\u90fd\u6bd4\u8f83\u6fc0\u8fdb\uff0c\u4f60\u53ef\u80fd\u6682\u65f6\u4e0d\u4f1a\u8ba4\u540c\uff0c\u7b49\u4f60\u5927\u624b\u5927\u811a\u72af\u4e86\u51e0\u4e2a\u9519\u4ee5\u540e\uff0c\u4f60\u81ea\u7136\u4f1a\u5fc3\u670d\u53e3\u670d\u3002 \u5c0f\u5f6d\u8001\u5e08\u4ee5\u524d\u4e5f\u548c\u4f60\u4e00\u6837\u662f\u6307\u9488\u4ed9\u4eba\uff0c\u4e0d\u559c\u6b22\u5f3a\u7c7b\u578b\uff0c\u559c\u6b22 void * \u6ee1\u5929\u98de\uff0c\u7136\u540e\u968f\u4fbf\u6539\u4e24\u884c\u5c31\u8e66\u51fa\u4e2a Segmentation Fault\uff0c\u6307\u9488\u4e00\u65f6\u723d\uff0c\u8c03\u8bd5\u706b\u846c\u573a\uff0c\u7136\u540e\u624d\u5f00\u59cb\u53cd\u601d\u3002 STL \u4e2d\u4f9d\u7136\u5728\u5927\u91cf\u7528 pair \u662f\u56e0\u4e3a map \u5bb9\u5668\u51fa\u73b0\u7684\u5f88\u65e9\uff0c\u5386\u53f2\u539f\u56e0\u3002 \u6211\u4eec\u81ea\u5df1\u9879\u76ee\u7684 API \u5c31\u4e0d\u8981\u8bbe\u8ba1\u6210\u8fd9\u718a\u6837\u4e86\u3002 \u5f53\u7136\uff0c\u548c\u67d0\u4e9b\u4e8c\u7ea7\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u76f8\u6bd4 cudaError_t cudaMalloc(void **pret); \uff0c\u8fd4\u56de pair \u5df2\u7ecf\u7b97\u5148\u8fdb\u7684\u4e86 \u4f8b\u5982 C++17 \u4e2d\u7684 from_chars \u51fd\u6570\uff0c\u4ed6\u7684\u8fd4\u56de\u7c7b\u578b\u5c31\u662f\u4e00\u4e2a\u5b9a\u5236\u7684\u7ed3\u6784\u4f53\uff1a struct from_chars_result { const char *ptr; errc ec; }; from_chars_result from_chars(const char *first, const char *last, int &value); \u8fd9\u8bf4\u660e\u4ed6\u4eec\u4e5f\u5df2\u7ecf\u610f\u8bc6\u5230\u4e86\u4ee5\u524d\u52a8\u4e0d\u52a8\u8fd4\u56de pair \u7684\u8bbe\u8ba1\u662f\u6709\u95ee\u9898\u7684\uff0c\u5df2\u7ecf\u5728\u65b0\u6807\u51c6\u4e2d\u5f00\u59cb\u6539\u7528\u66f4\u597d\u7684\u8bbe\u8ba1\u3002","title":"\u8fd4\u56de\u4e00\u4e2a\u7ed3\u6784\u4f53"},{"location":"type_rich_api/#_9","text":"","title":"—"},{"location":"type_rich_api/#_10","text":"\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u8fd9\u4e2a\u51fd\u6570\uff1a void foo(char *x); \u8fd9\u91cc\u7684 x \u6709\u53ef\u80fd\u662f\uff1a 0\u7ed3\u5c3e\u5b57\u7b26\u4e32\uff0c\u53ea\u8bfb\uff0c\u4f46\u662f\u4f5c\u8005\u5fd8\u4e86\u52a0 const \u6307\u5411\u5355\u4e2a\u5b57\u7b26\uff0c\u7528\u4e8e\u8fd4\u56de\u5355\u4e2a char\uff08\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\uff09 \u6307\u5411\u4e00\u4e2a\u5b57\u7b26\u6570\u7ec4\u7f13\u51b2\u533a\uff0c\u7528\u4e8e\u8fd4\u56de\u5b57\u7b26\u4e32\uff0c\u4f46\u7f13\u51b2\u533a\u5927\u5c0f\u7684\u786e\u5b9a\u65b9\u5f0f\u672a\u77e5 \u5982\u679c\u4f5c\u8005\u6ca1\u5199\u6587\u6863\uff0c\u53d8\u91cf\u540d\u53c8\u975e\u5e38\u542b\u7cca\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u8fd9\u4e2a x \u53c2\u6570\u8981\u600e\u4e48\u7528\u3002 \u7c7b\u578b\u5199\u7684\u597d\uff0c\u80fd\u8d77\u5230\u6ce8\u91ca\u7684\u4f5c\u7528\uff01 void foo(string x); \u8fd9\u6837\u5c31\u4e00\u76ee\u4e86\u7136\u4e86\uff0c\u5f88\u660e\u663e\uff0c\u662f\u5b57\u7b26\u4e32\u7c7b\u578b\u7684\u53c2\u6570\u3002 void foo(string &x); \u770b\u8d77\u6765\u662f\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u4f46\u662f\u901a\u8fc7\u5f15\u7528\u4f20\u53c2\u7684\u65b9\u5f0f\u6765\u8fd4\u56de\u7684 string foo(); \u901a\u8fc7\u5e38\u89c4\u65b9\u5f0f\u76f4\u63a5\u8fd4\u56de\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002 void foo(vector x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7ec4\u6210\u7684\u6570\u7ec4\uff01 void foo(span x); \u662f\u4e00\u4e2a 8 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\u7684\u6570\u7ec4\u5207\u7247\u3002 void foo(string_view x); \u662f\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5207\u7247\uff0c\u53ef\u80fd\u662f\u4f5c\u8005\u60f3\u8981\u907f\u514d\u62f7\u8d1d\u5f00\u9500\u3002","title":"\u7c7b\u578b\u5373\u6ce8\u91ca"},{"location":"type_rich_api/#_11","text":"\u8fd8\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using ISBN = string; BookInfo foo(ISBN isbn); \u8fd9\u6837\u7528\u6237\u4e00\u770b\u5c31\u660e\u767d\uff0c\u8fd9\u4e2a\u51fd\u6570\u662f\u63a5\u6536\u4e00\u4e2a ISBN \u7f16\u53f7\uff08\u51fa\u7248\u520a\u7269\u90fd\u6709\u4e00\u4e2a\u8fd9\u79cd\u7f16\u53f7\uff09\uff0c\u8fd4\u56de\u5173\u4e8e\u8fd9\u672c\u4e66\u7684\u8be6\u7ec6\u4fe1\u606f\u3002 \u5c3d\u7ba1\u51fd\u6570\u540d foo \u8ba9\u4eba\u6478\u4e0d\u7740\u5934\u8111\uff0c\u4f46\u4ec5\u51ed\u76f4\u89c2\u7684\u7c7b\u578b\u6807\u8bc6\uff0c\u6211\u4eec\u5c31\u80fd\u51fd\u6570\u529f\u80fd\u628a\u731c\u7684\u4e03\u4e03\u516b\u516b\u3002","title":"—"},{"location":"type_rich_api/#_12","text":"","title":"—"},{"location":"type_rich_api/#_13","text":"\u6ce8\u610f\uff0c\u8fd9\u91cc foo \u8fd4\u56de\u4e86\u4e00\u4e2a\u6307\u9488\uff01 BookInfo * foo(ISBN isbn); \u4ed6\u4ee3\u8868\u4ec0\u4e48\u610f\u601d\u5462\uff1f \u6307\u5411\u4e00\u4e2a\u5185\u5b58\u4e2d\u5df2\u7ecf\u5b58\u5728\u7684\u4e66\u76ee\u9879\uff0c\u7531 foo \u8d1f\u8d23\u7ba1\u7406\u8fd9\u7247\u5185\u5b58 \u8fd4\u56de\u4e00\u4e2a new \u51fa\u6765\u7684 BookInfo \u7ed3\u6784\u4f53\uff0c\u7531\u7528\u6237\u8d1f\u8d23 delete \u91ca\u653e\u5185\u5b58 \u662f\u5426\u8fd8\u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u627e\u4e0d\u5230\u7684\u60c5\u51b5\uff1f \u751a\u81f3\u6709\u53ef\u80fd\u8fd4\u56de\u7684\u662f\u4e00\u4e2a BookInfo \u6570\u7ec4\uff1f\u6307\u9488\u6307\u5411\u6570\u7ec4\u7684\u9996\u4e2a\u5143\u7d20\uff0c\u6570\u7ec4\u957f\u5ea6\u7684\u5224\u5b9a\u65b9\u5f0f\u672a\u77e5\u2026 \u592a\u591a\u6b67\u4e49\u4e86\uff01 BookInfo & foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u4f1a\u8d1f\u8d23\u7ba1\u7406 BookInfo \u5bf9\u8c61\u7684\u751f\u547d\u5468\u671f\uff0c\u7528\u6237\u83b7\u5f97\u7684\u53ea\u662f\u4e00\u4e2a\u4e34\u65f6\u7684\u5f15\u7528\uff0c\u5e76\u4e0d\u6301\u6709\u6240\u6709\u6743\u3002 \u5f15\u7528\u7684\u7279\u70b9\uff1a \u4e00\u5b9a\u4e0d\u4f1a\u662f NULL\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de NULL \u7684\u7591\u8651\uff09 \u65e0\u6cd5 delete \u4e00\u4e2a\u5f15\u7528\uff08\u6392\u9664\u53ef\u80fd\u9700\u8981\u7528\u6237\u8d1f\u8d23\u91ca\u653e\u5185\u5b58\u7684\u7591\u8651\uff09 \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u6392\u9664\u53ef\u80fd\u8fd4\u56de\u6570\u7ec4\u9996\u5143\u7d20\u6307\u9488\u7684\u7591\u8651\uff09 \u6539\u7528\u5f15\u7528\u8fd4\u56de\u503c\uff0c\u4e00\u4e0b\u5b50\u601d\u8def\u5c31\u6e05\u6670\u4e86\u5f88\u591a\u3002\u6ca1\u6709\u90a3\u4e48\u591a\u6000\u7591\u548c\u731c\u6d4b\u4e86\uff0c\u7528\u9014\u5355\u4e00\uff0c\u7528\u6cd5\u660e\u786e\uff0c\u5f15\u7528\u771f\u662f\u7edd\u7edd\u5b50\u3002 std::unique_ptr foo(ISBN isbn); \u8fd9\u5c31\u5f88\u6e05\u695a\uff0cfoo \u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684 BookInfo\uff0c\u5e76\u628a\u751f\u547d\u5468\u671f\u7684\u6240\u6709\u6743\u79fb\u4ea4\u7ed9\u4e86\u7528\u6237\u3002 unique_ptr \u7684\u7279\u70b9\uff1a \u72ec\u5360\u6240\u6709\u6743\uff0c\u4e0d\u4f1a\u4e0e\u5176\u4ed6\u7ebf\u7a0b\u5171\u4eab\uff08\u6392\u9664\u53ef\u80fd\u591a\u7ebf\u7a0b\u7ade\u4e89\u7684\u7591\u8651\uff09 \u751f\u547d\u5468\u671f\u5df2\u7ecf\u79fb\u4ea4\u7ed9\u7528\u6237\uff0cunique_ptr \u53d8\u91cf\u79bb\u5f00\u7528\u6237\u7684\u4f5c\u7528\u57df\u540e\u4f1a\u81ea\u52a8\u91ca\u653e\uff0c\u65e0\u9700\u624b\u52a8 delete \u4e0d\u4f1a\u7528\u4e8e\u8868\u793a\u6570\u7ec4\uff08\u5982\u679c\u8981\u8868\u793a\u6570\u7ec4\uff0c\u4f1a\u7528 unique_ptr \u6216\u8005 vector \uff09 \u4f46\u662f unique_ptr \u6709\u4e00\u4e2a\u81f4\u547d\u7684\u7126\u8651\u70b9\uff1a\u4ed6\u53ef\u4ee5\u4e3a NULL\uff01 \u6240\u4ee5\u5f53\u4f60\u770b\u5230\u4e00\u4e2a\u51fd\u6570\u8fd4\u56de unique_ptr \u6216 shared_ptr\uff0c\u5c3d\u7ba1\u51cf\u5c11\u4e86\u5f88\u591a\u7684\u7591\u8651\uff0c\u4f46\u201c\u53ef\u80fd\u4e3aNULL\u201d\u7684\u62c5\u5fe7\u4ecd\u7136\u5b58\u5728\uff01 \u8981\u4e48 foo \u7684\u4f5c\u8005\u5728\u6ce8\u91ca\u6216\u6587\u6863\u91cc\u5199\u660e\uff0c\u201cfoo \u4e0d\u4f1a\u8fd4\u56de NULL\u201d\u6216\u8005\u201cfoo \u627e\u4e0d\u5230\u65f6\u4f1a\u8fd4\u56de NULL\u201d\uff0c\u6253\u6d88\u4f60\u7684\u7591\u8651\u3002 \u4f46\u6211\u4eec\u7684\u8bc9\u6c42\u662f\u901a\u8fc7\u7c7b\u578b\uff0c\u4e00\u773c\u5c31\u80fd\u770b\u51fa\u51fd\u6570\u6240\u6709\u7684\u53ef\u80fd\u6027\uff0c\u800c\u4e0d\u8981\u53bb\u4f9d\u8d56\u53ef\u80fd\u9a97\u4eba\u7684\u6ce8\u91ca\u3002 \u4e3a\u6b64\u5fae\u8f6f\u5b9e\u73b0\u4e86 gsl \u5e93\uff0c\u901a\u8fc7\u7c7b\u578b\u4fee\u9970\u89e3\u51b3\u6307\u9488\u7c7b\u8bed\u4e49\u542b\u7cca\u4e0d\u6e05\u7684\u95ee\u9898\uff1a \u4ed6\u89c4\u5b9a\uff0c\u6240\u6709\u5957\u4e86\u4e00\u5c42 gsl::not_null \u7684\u539f\u59cb\u6307\u9488\u6216\u667a\u80fd\u6307\u9488\uff0c\u91cc\u9762\u90fd\u5fc5\u7136\u4e0d\u4f1a\u4e3a NULL\u3002 \u5728 not_null \u7c7b\u7684\u6784\u9020\u51fd\u6570\u4e2d\uff0c\u6709\u76f8\u5e94\u7684\u65ad\u8a00\u68c0\u67e5\u4f20\u5165\u7684\u6307\u9488\u662f\u5426\u4e3a\u7a7a\uff0c\u5982\u679c\u4e3a\u7a7a\u4f1a\u76f4\u63a5\u62a5\u9519\u9000\u51fa\u3002 gsl::not_null p = nullptr; // \u7f16\u8bd1\u671f\u62a5\u9519\uff0c\u56e0\u4e3a\u4ed6\u91cc\u9762\u5199\u7740 not_null(nullptr_t) = delete; gsl::not_null p = fopen(...); // \u5982\u679c fopen \u6253\u5f00\u5931\u8d25\uff0c\u4e14\u4e3a Debug \u6784\u5efa\uff0c\u8fd0\u884c\u65f6\u4f1a\u89e6\u53d1\u65ad\u8a00\u9519\u8bef \u4fee\u6539\u540e\u7684\u51fd\u6570\u63a5\u53e3\u5982\u4e0b\uff1a gsl::not_null> foo(ISBN isbn); \u56e0\u4e3a gsl::not_null \u7684\u6784\u9020\u51fd\u6570\u4e2d\u4f1a\u68c0\u6d4b\u7a7a\u6307\u9488\uff0c\u5c31\u5411\u7528\u6237\u4fdd\u8bc1\u4e86\u6211\u8fd4\u56de\u7684\u4e0d\u4f1a\u662f NULL\u3002 \u4f46\u662f\uff0c\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u4f60\u5982\u679c\u8981\u8f6c\u79fb\u6240\u6709\u6743\u7684\u8bdd\uff0c\u6211\u76f4\u63a5\u8fd4\u56de BookInfo \u672c\u8eab\u4e0d\u5c31\u884c\u4e86\uff1f \u9664\u975e BookInfo \u7279\u522b\u5927\uff0c\u5927\u5230\u79fb\u52a8\u8fd4\u56de\u7684\u5f00\u9500\u90fd\u4e0d\u5f97\u4e86\u3002 \u76f4\u63a5\u8fd4\u56de\u7c7b\u578b\u672c\u8eab\uff0c\u5c31\u662f\u4e00\u5b9a\u4e0d\u53ef\u80fd\u4e3a\u7a7a\u7684\uff0c\u4e14\u4e5f\u80fd\u8bf4\u660e\u79fb\u4ea4\u4e86\u5bf9\u8c61\u6240\u6709\u6743\u7ed9\u7528\u6237\u3002 BookInfo foo(ISBN isbn);","title":"\u62d2\u7edd\u6307\u9488\uff01"},{"location":"type_rich_api/#_14","text":"\u5176\u5b9e GSL \u91cc\u5927\u91cf\u90fd\u662f\u8fd9\u79cd\u53ef\u6709\u53ef\u65e0\u7684\u73a9\u610f\uff0c\u6bd4\u5982 C++20 \u5df2\u7ecf\u6709\u4e86 std::span \u548c std::byte\uff0c\u4f46\u662f GSL \u8fd8\u7ed9\u4f60\u5f04\u4e86\u4e2a gsl::span \u548c gsl::byte\uff0c\u4e3b\u8981\u662f\u4e3a\u4e86\u517c\u5bb9\u4f4e\u7248\u672c\u7f16\u8bd1\u5668\uff0c\u5982\u679c\u4f60\u5728\u65b0\u9879\u76ee\u91cc\u80fd\u76f4\u63a5\u7528\u4e0a C++20 \u6807\u51c6\u7684\u8bdd\uff0c\u4e2a\u4eba\u4e0d\u662f\u5f88\u63a8\u8350\u518d\u53bb\u7528\u4e86\u3002 \u518d\u6bd4\u5982 gsl::czstring \u662f const char * \u7684\u7c7b\u578b\u522b\u540d\uff0c\u660e\u786e\u8868\u793a\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\uff0c\u4e3a\u7684\u662f\u548c\u201c\u6307\u9488\u8fd4\u56de\u4ed9\u4eba\u201d\u533a\u5206\u5f00\u6765\uff0c\u6709\u5fc5\u8981\u5417\uff1f\u6709\u6ca1\u6709\u4e00\u79cd\u53ef\u80fd\uff0c\u6211\u4eec\u73b0\u5728 const char * \u57fa\u672c\u4e0a\u5c31\u201c0\u7ed3\u5c3e\u5b57\u7b26\u4e32\u201d\u4e00\u79cd\u7528\u6cd5\uff0c\u800c\u4e14\u6211\u4eec\u5927\u591a\u4e5f\u90fd\u662f\u7528 string \u5c31\u53ef\u4ee5\u4e86\uff0cconst char * \u53c8\u4e0d\u5b89\u5168\uff0c\u53c8\u8bed\u4e49\u6a21\u68f1\u4e24\u53ef\uff0c\u4f55\u5fc5\u518d\u53bb\u4e3a\u4e86\u7528\u5b83\u4e13\u95e8\u5f15\u5165\u4e2a\u5e93\uff0c\u6574\u4e2a\u7c7b\u578b\u522b\u540d\u5462\uff1f using czstring = const char *; void foo(czstring s) { // \u53d1\u660e GSL \u7684\u4eba\u771f\u662f\u4e2a\u5929\u624d\uff01 if (s == \"\u5c0f\u5f6d\u8001\u5e08\") // \u9519\u8bef\uff01 if (strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u9519\u8bef\uff01 if (!strcmp(s, \"\u5c0f\u5f6d\u8001\u5e08\")) // \u7ec8\u4e8e\u6b63\u786e // \u7136\u800c\u6211\u5b8c\u5168\u53ef\u4ee5\u76f4\u63a5\u7528 string\uff0c== \u7684\u8fd0\u7b97\u7b26\u91cd\u8f7d\u80fd\u76f4\u63a5\u6bd4\u8f83\u5b57\u7b26\u4e32\u5185\u5bb9 // \u8fd8\u80fd\u968f\u65f6\u968f\u5730 substr \u5207\u7247\uff0cfind \u67e5\u627e\uff0csize \u5e38\u6570\u590d\u6742\u5ea6\u67e5\u5927\u5c0f } \u4f7f\u7528\u5404\u5f0f\u5404\u6837\u529f\u80fd\u660e\u786e\u7684\u7c7b\u578b\u548c\u5bb9\u5668\uff0c\u6bd4\u5982 string\uff0cvector\uff0c\u6216\u5f15\u7528\u3002 \u800c\u4e0d\u662f\u529f\u80fd\u592a\u591a\u7684\u6307\u9488\uff0c\u8ba9\u7528\u6237\u5b66\u4e60\u4f60\u7684 API \u65f6\u4ea7\u751f\u8bef\u89e3\uff0c\u7559\u4e0b BUG \u9690\u60a3\u3002 \u5982\u679c\u9700\u8981\u6307\u9488\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7 const \u9650\u5b9a\uff0c\u6765\u544a\u8bc9\u7528\u6237\u8fd9\u4e2a\u6307\u9488\u662f\u53ea\u8bfb\u7684\u8fd8\u662f\u53ef\u5199\u7684\u3002 \u603b\u4e4b\uff0c\u4ee3\u7801\u4e0d\u4f1a\u6492\u8c0e\uff0c\u4ee3\u7801\u5c42\u9762\u80fd\u7981\u6b62\u7684\uff0c\u80fd\u5c3d\u91cf\u9650\u5236\u7528\u6cd5\u7684\uff0c\u5c31\u4e0d\u8981\u7528\u6ce8\u91ca\u548c\u6587\u6863\u53bb\u534f\u5546\u89e3\u51b3\u3002","title":"—"},{"location":"type_rich_api/#_15","text":"","title":"—"},{"location":"type_rich_api/#_16","text":"\u5047\u8bbe\u4f60\u6b63\u5728\u5b66\u4e60\u8fd9\u4e2a Linux \u7cfb\u7edf API \u51fd\u6570\uff1a ssize_t read(int fd, char *buf, size_t len); // fd - \u6587\u4ef6\u53e5\u67c4\uff0cint \u7c7b\u578b \u4f46\u662f\u4f60\u6ca1\u6709\u770b\u4ed6\u7684\u51fd\u6570\u53c2\u6570\u7c7b\u578b\u548c\u540d\u5b57\u3002\u4f60\u662f\u8fd9\u6837\u8c03\u7528\u7684\uff1a int fd = open(...); char buf[32]; read(32, buf, fd); char buf[32]; read(32, buf, fd); \u4f60\u8fd9\u91cc\u7684 32 \u672c\u610f\u662f\u7f13\u51b2\u533a\u7684\u5927\u5c0f\uff0c\u5374\u4e0d\u5e78\u5730\u548c fd \u53c2\u6570\u5199\u9519\u4e86\u4f4d\u7f6e\uff0c\u800c\u7f16\u8bd1\u5668\u6beb\u65e0\u62a5\u9519\uff0c\u4f60\u6d51\u7136\u4e0d\u77e5\u3002","title":"\u5f3a\u7c7b\u578b\u5c01\u88c5"},{"location":"type_rich_api/#_17","text":"\u4ec5\u4ec5\u53ea\u662f\u88c5\u6a21\u4f5c\u6837\u7684\u7528 typedef \u5b9a\u4e49\u4e2a\u597d\u770b\u7684\u7c7b\u578b\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u4efb\u4f55\u610f\u4e49\uff01 \u4ed6\u8fde\u4f60\u7684\u53c2\u6570\u540d fd \u90fd\u80fd\u770b\u4e0d\u89c1\uff0c\u4f60\u89c9\u5f97\u4ed6\u4f1a\u770b\u5230\u4f60\u7684\u53c2\u6570\u7c7b\u578b\u662f\u4e2a\u522b\u540d\uff1f \u7528\u6237\u4e00\u6837\u53ef\u4ee5\u7528\u4e00\u4e2a\u6839\u672c\u4e0d\u662f\u6587\u4ef6\u53e5\u67c4\u7684\u81ed\u6574\u6570\u6765\u8c03\u7528\u4f60\uff0c\u800c\u5f97\u4e0d\u5230\u4efb\u4f55\u8b66\u544a\u6216\u62a5\u9519\uff1a typedef int FileHandle; ssize_t read(FileHandle fd, char *buf, size_t len); read(32, buf, fd); // \u7167\u6837\u7f16\u8bd1\u901a\u8fc7\uff01 \u5982\u679c\u6211\u4eec\u628a\u6587\u4ef6\u53e5\u67c4\u5b9a\u4e49\u4e3a\u4e00\u4e2a\u7ed3\u6784\u4f53\uff1a struct FileHandle { int handle; explicit FileHandle(int handle) : handle(handle) {} }; ssize_t read(FileHandle handle, char *buf, size_t len); \u5c31\u80fd\u5728\u7528\u6237\u72af\u9a6c\u864e\u7684\u65f6\u5019\uff0c\u7ed9\u4ed6\u5f39\u51fa\u4e00\u4e2a\u7f16\u8bd1\u9519\u8bef\uff1a read(32, buf, fd); // \u7f16\u8bd1\u62a5\u9519\uff1a\u65e0\u6cd5\u5c06 int \u7c7b\u578b\u7684 32 \u9690\u5f0f\u8f6c\u6362\u4e3a FileHandle\uff01 \u5bf9\u4e8e\u6574\u6570\u7c7b\u578b\uff0c\u4e5f\u6709\u7684\u4eba\u559c\u6b22\u7528 C++11 \u7684\u5f3a\u7c7b\u578b\u679a\u4e3e\uff1a enum class FileHandle : int {}; \u8fd9\u6837\u4e00\u6765\uff0c\u5982\u679c\u7528\u6237\u771f\u7684\u662f\u60f3\u8981\u8bfb\u53d6\u201c32\u53f7\u53e5\u67c4\u201d\u7684\u6587\u4ef6\uff0c\u4ed6\u5c31\u5fc5\u987b\u663e\u5f0f\u5730\u5199\u51fa\u5b8c\u6574\u7c7b\u578b\u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff1a read(FileHandle(32), buf, fd); // \u7f16\u8bd1\u901a\u8fc7\u4e86 \u5f3a\u8feb\u4f60\u5199\u4e0a\u7c7b\u578b\u540d\uff0c\u5c31\u7ed9\u4e86\u4f60\u4e00\u6b21\u518d\u601d\u8003\u7684\u673a\u4f1a\uff0c\u8ba9\u4f60\u7a81\u7136\u60ca\u9192\uff1a \u54e6\u5929\u54ea\uff0c\u6211\u600e\u4e48\u628a\u7f13\u51b2\u533a\u5927\u5c0f\u5f53\u6210\u53e5\u67c4\u6765\u4f20\u9012\u4e86\uff01 \u4ece\u800c\u51cf\u5c11\u7741\u7740\u773c\u775b\u8fd8\u72af\u9519\u7684\u53ef\u80fd\u3002 \u7136\u540e\uff0c\u4f60\u7684 open \u51fd\u6570\u4e5f\u8fd4\u56de FileHandle\uff0c\u6574\u4e2a\u4ee3\u7801\u4e2d\u5c31\u4e0d\u7528\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u4e86\u3002 FileHandle fd = open(std::filesystem::path(\"\u8def\u5f84\"), OpenFlag::Read); char buf[32]; read(fd, buf, 32);","title":"—"},{"location":"type_rich_api/#_18","text":"","title":"—"},{"location":"type_rich_api/#span","text":"","title":"span \u201c\u80d6\u6307\u9488\u201d"},{"location":"type_rich_api/#_19","text":"\u5047\u5982\u4f60\u624b\u4e00\u6ed1\uff0c\u6216\u8005\u8001\u677f\u9700\u6c42\u6539\u53d8\uff0c\u628a buf \u7f13\u51b2\u533a\u5c11\u7559\u4e86\u4e24\u4e2a\u5b57\u8282\uff1a char buf[30]; read(fd, buf, 32); \u4f46\u4f60 read \u7684\u53c2\u6570\u4f9d\u7136\u662f 32\uff0c\u5c31\u4ea7\u751f\u4e86\u6570\u7ec4\u8d8a\u754c\uff0c\u53c8\u672a\u5b9a\u4e49\u884c\u4e3a\u4e86\u3002 \u6211\u4eec\u91c7\u7528\u5c01\u88c5\u7cbe\u795e\uff0c\u628a\u76f8\u5173\u7684 buf \u548c size \u5c01\u88c5\u6210\u4e00\u4e2a\u53c2\u6570\uff1a struct Span { char *data; size_t size; }; ssize_t read(FileHandle fd, Span buf); read(fd, Span{buf, 32}); \u6ce8\u610f\uff1aSpan \u4e0d\u9700\u8981\u4ee5\u5f15\u7528\u5f62\u5f0f\u4f20\u5165\u51fd\u6570\uff01 void read(std::string &buf); // \u5982\u679c\u662f string \u7c7b\u578b\uff0c\u53c2\u6570\u9700\u8981\u4e3a\u5f15\u7528\uff0c\u624d\u80fd\u8ba9 read \u80fd\u591f\u4fee\u6539 buf \u5b57\u7b26\u4e32 void read(Span buf); // Span \u4e0d\u9700\u8981\uff0c\u56e0\u4e3a Span \u5e76\u4e0d\u662f\u72ec\u5360\u8d44\u6e90\u7684\u7c7b\uff0cSpan \u672c\u8eab\u5c31\u662f\u4e2a\u8f7b\u91cf\u7ea7\u7684\u5f15\u7528 vector \u548c string \u8fd9\u79cd\u5177\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\u7684 RAII \u5c01\u88c5\u7c7b\u624d\u9700\u8981\u4f20\u5165\u5f15\u7528 string &buf \uff0c\u5982\u679c\u76f4\u63a5\u4f20\u5165\u4f1a\u53d1\u751f\u6df1\u62f7\u8d1d\uff0c\u5bfc\u81f4 read \u5185\u90e8\u4fee\u6539\u7684\u662f string \u7684\u4e00\u4efd\u62f7\u8d1d\uff0c\u65e0\u6cd5\u5f71\u54cd\u5230\u5916\u754c\u539f\u6765\u7684 string\u3002 \u5982\u679c\u662f Span \u53c2\u6570\u5c31\u4e0d\u9700\u8981 Span &buf \u5f15\u7528\u4e86\uff0cSpan \u5e76\u4e0d\u662f RAII \u5c01\u88c5\u7c7b\uff0c\u5e76\u4e0d\u6301\u6709\u751f\u547d\u5468\u671f\uff0c\u5e76\u6ca1\u6709\u201c\u62f7\u8d1d\u6784\u9020\u51fd\u6570\u201d\uff0c\u4ed6\u53ea\u662f\u4e2a\u5bf9\u5916\u90e8\u5df2\u6709 vector\u3001string\u3001\u6216 char[] \u7684\u5f15\u7528\u3002\u6216\u8005\u8bf4 Span \u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u5bf9\u539f\u7f13\u51b2\u533a\u7684\u5f15\u7528\uff0c\u76f4\u63a5\u4f20\u5165 read \u5185\u90e8\u4e00\u6837\u53ef\u4ee5\u4fee\u6539\u4f60\u7684\u7f13\u51b2\u533a\u3002","title":"—"},{"location":"type_rich_api/#_20","text":"\u7528 Span \u7ed3\u6784\u4f53\u867d\u7136\u770b\u8d77\u6765\u66f4\u660e\u786e\u4e86\uff0c\u4f46\u662f\u4f9d\u7136\u4e0d\u89e3\u51b3\u7528\u6237\u53ef\u80fd\u624b\u6ed1\u5199\u9519\u7f13\u51b2\u533a\u957f\u5ea6\u7684\u95ee\u9898\uff1a char buf[30]; read(fd, Span{buf, 32}); \u4e3a\u6b64\uff0c\u6211\u4eec\u5728 Span \u91cc\u52a0\u5165\u4e00\u4e2a\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} }; \u8fd9\u5c06\u5141\u8bb8 char [N] \u9690\u5f0f\u8f6c\u6362\u4e3a Span\uff0c\u4e14\u957f\u5ea6\u81ea\u52a8\u5c31\u662f N \u7684\u503c\u3002 \u6b64\u5904\u5982\u679c\u5199 Span(char buf[N]) \uff0c\u4f1a\u88ab C \u8bed\u8a00\u7684\u67d0\u6761\u6c99\u96d5\u89c4\u5219\uff0c\u51fd\u6570\u7b7e\u540d\u4f1a\u7b49\u4ef7\u4e8e Span(char *buf) \uff0c\u4ece\u800c\u53ea\u80fd\u83b7\u53d6\u8d77\u59cb\u5730\u5740\uff0c\u800c\u63a8\u5bfc\u4e0d\u4e86\u957f\u5ea6\u3002\u4f7f\u7528\u6570\u7ec4\u5f15\u7528\u4f5c\u4e3a\u53c2\u6570 Span(char (&buf)[N]) \u5c31\u4e0d\u4f1a\u88ab C \u8bed\u8a00\u81ea\u52a8\u9000\u5316\u6210\u8d77\u59cb\u5730\u5740\u6307\u9488\u4e86\u3002 \u7528\u6237\u53ea\u9700\u8981\uff1a char buf[30]; read(fd, Span{buf}); \u7b49\u4ef7\u4e8e Span{buf, 30} \uff0c\u6570\u7ec4\u957f\u5ea6\u81ea\u52a8\u63a8\u5bfc\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7531\u4e8e\u6211\u4eec\u662f\u9690\u5f0f\u6784\u9020\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u7701\u7565 Span \u4e0d\u5199\uff1a char buf[30]; read(fd, buf); // \u81ea\u52a8\u8f6c\u6362\u6210 Span{buf, 30} \u52a0\u5165\u66f4\u591a\u7c7b\u578b\u7684\u652f\u6301\uff1a struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(std::array &arr) : data(arr.data()), size(N) {} Span(std::vector &vec) : data(vec.data()), size(vec.size()) {} // \u5982\u679c\u6709\u9700\u8981\uff0c\u4e5f\u53ef\u4ee5\u663e\u5f0f\u5199\u51fa Span(buf, 30) \u4ece\u9996\u5730\u5740\u548c\u957f\u5ea6\u6784\u9020\u51fa\u4e00\u4e2a Span \u6765 explicit Span(char *data, size_t size) : data(data), size(size) {} }; \u73b0\u5728 C \u6570\u7ec4\u3001array\u3001vector\u3001\u90fd\u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a Span \u4e86\uff1a char buf1[30]; Span span1 = buf1; std::array buf2; Span span2 = buf2; std::vector buf(30); Span span3 = buf3; const char *str = \"hello\"; Span span4 = Span(str, strlen(str)); \u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u81ea\u52a8\u652f\u6301\u4efb\u4f55\u5177\u6709 data \u548c size \u6210\u5458\u7684\u5404\u79cd\u6807\u51c6\u5e93\u5bb9\u5668\uff0c\u5305\u62ec\u7b2c\u4e09\u65b9\u7684\uff0c\u53ea\u8981\u4ed6\u63d0\u4f9b data \u548c size \u51fd\u6570\u3002 template concept has_data_size = requires (Arr arr) { { arr.data() } -> std::convertible_to; { arr.size() } -> std::same_as; }; struct Span { char *data; size_t size; template Span(char (&buf)[N]) : data(buf), size(N) {} template Span(Arr &&arr) : data(arr.data()), size(arr.size()) {} // \u6ee1\u8db3 has_data_size \u7684\u4efb\u4f55\u7c7b\u578b\u90fd\u53ef\u4ee5\u6784\u9020\u51fa Span // \u800c\u6807\u51c6\u5e93\u7684 vector\u3001string\u3001array \u5bb9\u5668\u90fd\u542b\u6709 .data() \u548c .size() \u6210\u5458\u51fd\u6570 };","title":"—"},{"location":"type_rich_api/#_21","text":"\u5982\u679c\u7528\u6237\u786e\u5b9e\u6709\u4fee\u6539\u957f\u5ea6\u7684\u9700\u8981\uff0c\u53ef\u4ee5\u901a\u8fc7 subspan \u6210\u5458\u51fd\u6570\u5b9e\u73b0\uff1a char buf[32]; read(fd, Span(buf).subspan(0, 10)); // \u53ea\u8bfb\u53d6\u524d 10 \u4e2a\u5b57\u8282\uff01 subspan \u5185\u90e8\u5b9e\u73b0\u539f\u7406\uff1a struct Span { char *data; size_t size; Span subspan(size_t start, size_t length = (size_t)-1) const { if (start > size) // \u5982\u679c\u8d77\u59cb\u4f4d\u7f6e\u8d85\u51fa\u8303\u56f4\uff0c\u5219\u629b\u51fa\u5f02\u5e38 throw std::out_of_range(\"subspan start out of range\"); auto restSize = size - start; if (length > restSize) // \u5982\u679c\u957f\u5ea6\u8d85\u8fc7\u4e0a\u9650\uff0c\u5219\u81ea\u52a8\u622a\u65ad length = restSize; return Span(data + start, length); } };","title":"—"},{"location":"type_rich_api/#_22","text":"\u53ef\u4ee5\u628a Span \u53d8\u6210\u6a21\u677f\u7c7b\uff0c\u652f\u6301\u4efb\u610f\u7c7b\u578b\u7684\u6570\u7ec4\uff0c\u6bd4\u5982 Span \u3002 template concept has_data_size = requires (Arr arr) { { std::data(arr) } -> std::convertible_to; { std::size(arr) } -> std::same_as; // \u4f7f\u7528 std::data \u800c\u4e0d\u662f .data() \u7684\u597d\u5904\uff1a // std::data \u5bf9\u4e8e char (&buf)[N] \u8fd9\u79cd\u6570\u7ec4\u7c7b\u578b\u4e5f\u6709\u91cd\u8f7d\uff01 // \u4f8b\u5982 std::size(buf) \u4f1a\u5f97\u5230 int buf[N] \u7684\u6b63\u786e\u957f\u5ea6 N // \u800c sizeof buf \u4f1a\u5f97\u5230 N * sizeof(int) // \u7c7b\u4f3c\u4e8e sizeof(buf) / sizeof(buf[0]) \u7684\u6548\u679c // \u4e0d\u8fc7\u5982\u679c buf \u662f\u666e\u901a int * \u6307\u9488\uff0c\u4f1a\u91cd\u8f7d\u5931\u8d25\uff0c\u76f4\u63a5\u62a5\u9519\uff0c\u6ca1\u6709\u5b89\u5168\u9690\u60a3 }; template struct Span { T *data; size_t size; template Arr> Span(Arr &&arr) : data(std::data(arr)), size(std::size(arr)) {} // \ud83d\udc46 \u540c\u65f6\u56ca\u62ec\u4e86 vector\u3001string\u3001array\u3001\u539f\u59cb\u6570\u7ec4 }; template Span(Arr &&t) -> Span()))>>;","title":"—"},{"location":"type_rich_api/#_23","text":"Span \u8868\u793a\u53ef\u8bfb\u5199\u7684\u6570\u7ec4\u3002 \u5bf9\u4e8e\u53ea\u8bfb\u7684\u6570\u7ec4\uff0c\u7528 Span \u5c31\u53ef\u4ee5\u3002 ssize_t read(FileHandle fd, Span buf); // buf \u53ef\u8bfb\u5199\uff01 ssize_t write(FileHandle fd, Span buf); // buf \u53ea\u8bfb\uff01","title":"—"},{"location":"type_rich_api/#_24","text":"\u597d\u6d88\u606f\uff01\u8fd9\u4e1c\u897f\u5728 C++20 \u5df2\u7ecf\u5b9e\u88c5\uff0c\u90a3\u5c31\u662f std::span\u3002 \u6ca1\u6709 C++20 \u5f00\u53d1\u73af\u5883\u7684\u540c\u5b66\uff0c\u4e5f\u53ef\u4ee5\u7528 GSL \u5e93\u7684 gsl::span\uff0c\u6216\u8005 ABSL \u5e93\u7684 absl::Span \u6765\u4f53\u9a8c\u3002 C++17 \u8fd8\u6709\u4e13\u95e8\u9488\u5bf9\u5b57\u7b26\u4e32\u7684\u533a\u95f4\u7c7b std::string_view\uff0c\u53ef\u4ee5\u4ece std::string \u9690\u5f0f\u6784\u9020\uff0c\u7528\u6cd5\u7c7b\u4f3c\uff0c\u4e0d\u8fc7\u5207\u7247\u51fd\u6570\u662f substr\uff0c\u8fd8\u652f\u6301 find\u3001find_first_of \u7b49 std::string \u6709\u7684\u5b57\u7b26\u4e32\u4e13\u5c5e\u51fd\u6570\u3002 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ef\u8bfb\u53ef\u5199\u6570\u7ec4 std::span - \u4efb\u610f\u7c7b\u578b T \u7684\u53ea\u8bfb\u6570\u7ec4 std::string_view - \u4efb\u610f\u5b57\u7b26\u4e32 \u5728 read \u51fd\u6570\u5185\u90e8\uff0c\u53ef\u4ee5\u7528 .data() \u548c .size() \u91cd\u65b0\u53d6\u51fa\u72ec\u7acb\u7684\u9996\u5730\u5740\u6307\u9488\u548c\u7f13\u51b2\u533a\u957f\u5ea6\uff0c\u7528\u4e8e\u4f3a\u5019 C \u8bed\u8a00\u7684\u8001\u51fd\u6570\uff1a ssize_t read(FileHandle fd, std::span buf) { memset(buf.data(), 0, buf.size()); // \u8bfe\u540e\u4f5c\u4e1a\uff0c\u7528\u6240\u5b66\u77e5\u8bc6\uff0c\u4f18\u5316 C \u8bed\u8a00\u7684 memset \u51fd\u6570\u5427\uff01 ... } \u4e5f\u53ef\u4ee5\u7528 range-based for \u5faa\u73af\u6765\u904d\u5386\uff1a ssize_t read(FileHandle fd, std::span buf) { for (auto & c : buf) { // \u6ce8\u610f\u8fd9\u91cc\u4e00\u5b9a\u8981\u7528 auto & \u54e6\uff01\u5426\u5219\u65e0\u6cd5\u4fee\u6539 buf \u5185\u5bb9 c = 'c'; ... } }","title":"—"},{"location":"type_rich_api/#_25","text":"","title":"—"},{"location":"type_rich_api/#_26","text":"","title":"\u7a7a\u503c\u8bed\u4e49"},{"location":"type_rich_api/#_27","text":"\u6709\u7684\u51fd\u6570\uff0c\u6bd4\u5982\u521a\u624d\u7684 foo\uff0c\u4f1a\u9700\u8981\u8868\u793a\u201c\u53ef\u80fd\u627e\u4e0d\u5230\u8be5\u4e66\u672c\u201d\u7684\u60c5\u51b5\u3002 \u7c97\u7cd9\u7684 API \u8bbe\u8ba1\u8005\u4f1a\u8fd4\u56de\u4e00\u4e2a\u6307\u9488\uff0c\u7136\u540e\u5728\u6587\u6863\u91cc\u8bf4\u201c\u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u8fd4\u56de NULL\uff01\u201d BookInfo *foo(ISBN isbn); \u5982\u679c\u662f\u8fd9\u6837\u7684\u51fd\u6570\u7b7e\u540d\uff0c\u662f\u4e0d\u662f\u4f60\u5f88\u5bb9\u6613\u5fd8\u8bb0 foo \u6709\u53ef\u80fd\u8fd4\u56de NULL \u8868\u793a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\uff1f \u6bd4\u5982 malloc \u51fd\u6570\u5728\u5206\u914d\u5931\u8d25\u65f6\uff0c\u5c31\u4f1a\u8fd4\u56de NULL \u5e76\u8bbe\u7f6e errno \u4e3a ENOMEM\u3002 \u5728 man malloc \u6587\u6863\u4e2d\u5199\u7684\u6e05\u6e05\u695a\u695a\uff0c\u4f46\u662f\u8c01\u4f1a\u8bb0\u5f97\u8fd9\u4e2a\u8bbe\u5b9a\uff1f malloc \u5b8c\u968f\u624b\u5c31\u76f4\u63a5\u8bbf\u95ee\u4e86\uff08\u7a7a\u6307\u9488\u89e3\u5f15\u7528\u5c5e\u672a\u5b9a\u4e49\u884c\u4e3a\uff09\u3002 \u5728\u73b0\u4ee3 C++17 \u4e2d\u5f15\u5165\u4e86 optional\uff0c\u4ed6\u662f\u4e2a\u6a21\u677f\u7c7b\u578b\u3002 \u5f62\u5982 optional \u7684\u7c7b\u578b\u6709\u4e24\u79cd\u53ef\u80fd\u7684\u72b6\u6001\uff1a \u4e3a\u7a7a\uff08nullopt\uff09 \u6709\u503c\uff08T\uff09 \u5982\u679c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u6210\u529f\u8fd4\u56de T\uff0c\u4e5f\u53ef\u80fd\u5931\u8d25\uff0c\u90a3\u5c31\u53ef\u4ee5\u8ba9\u4ed6\u8fd4\u56de optional \uff0c\u7528 nullopt \u6765\u8868\u793a\u5931\u8d25\u3002 std::optional foo(ISBN isbn) { if (\u627e\u5230\u4e86) { return BookInfo(...); } else { return std::nullopt; } } nullopt \u548c\u6307\u9488\u7684 nullptr \u7c7b\u4f3c\uff0c\u4f46 optional \u7684\u7528\u9014\u66f4\u52a0\u5355\u4e00\uff0c\u66f4\u5177\u8bf4\u660e\u6027\u3002 \u5982\u679c\u4f60\u8fd4\u56de\u4e2a\u6307\u9488\u4eba\u5bb6\u4e0d\u4e00\u5b9a\u77e5\u9053\u4f60\u7684\u610f\u601d\u662f\u53ef\u80fd\u8fd4\u56de nullptr\uff0c\u53ef\u80fd\u8fd8\u4ee5\u4e3a\u4f60\u662f\u4e3a\u4e86\u8fd4\u56de\u4e2a new \u51fa\u6765\u7684\u6570\u7ec4\uff0c\u8bed\u4e49\u4e0d\u660e\u786e\u3002 \u8c03\u7528\u7684\u5730\u65b9\u8fd9\u6837\u5199\uff1a auto book = foo(isbn); if (book.has_value()) { // book.has_vlaue() \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u7c7b\u578b\u53ef\u4ee5\u5728 if \u6761\u4ef6\u4e2d\u81ea\u52a8\u8f6c\u6362\u4e3a bool\uff0c\u5224\u65ad\u662f\u5426\u6709\u503c\uff0c\u7b49\u4ef7\u4e8e .has_value() \uff1a auto book = foo(isbn); if (book) { // (bool)book \u4e3a true\uff0c\u5219\u8868\u793a\u6709\u503c BookInfo realBook = book.value(); print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u53ef\u4ee5\u901a\u8fc7 * \u8fd0\u7b97\u7b26\u8bfb\u53d6\u5176\u4e2d\u7684\u503c\uff0c\u7b49\u4ef7\u4e8e .value() \uff09\uff1a auto book = foo(isbn); if (book) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u8fd0\u7528 C++17 \u7684\u5c31\u5730 if \u8bed\u6cd5\uff1a if (auto book = foo(isbn); book.has_value()) { BookInfo realBook = *book; print(\"\u627e\u5230\u4e86:\", realBook); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } \u7531\u4e8e auto \u51fa\u6765\u7684 optional \u53d8\u91cf\u53ef\u4ee5\u8f6c\u6362\u4e3a bool\uff0c\u5206\u53f7\u540e\u9762\u7684\u6761\u4ef6\u53ef\u4ee5\u7701\u7565\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", *book); } else { print(\"\u627e\u4e0d\u5230\u8fd9\u672c\u4e66\"); } optional \u4e5f\u652f\u6301 -> \u8fd0\u7b97\u7b26\u8bbf\u95ee\u6210\u5458\uff1a if (auto book = foo(isbn)) { print(\"\u627e\u5230\u4e86:\", book->name); book->readOnline(); } optional \u7684 .value() \uff0c\u5982\u679c\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa std::bad_optional_access \u5f02\u5e38\u3002 \u7528\u8fd9\u4e2a\u65b9\u6cd5\u53ef\u4ee5\u4fbf\u6377\u5730\u628a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u8f6c\u6362\u4e3a\u5f02\u5e38\u629b\u51fa\u7ed9\u4e0a\u6e38\u8c03\u7528\u8005\uff0c\u800c\u4e0d\u7528\u6210\u5806\u7684 if \u5224\u65ad\u548c\u8fd4\u56de\u3002 BookInfo book = foo(isbn).value(); \u4e5f\u53ef\u4ee5\u901a\u8fc7 .value_or(\u9ed8\u8ba4\u503c) \u6307\u5b9a\u201c\u627e\u4e0d\u5230\u4e66\u672c\u201d\u65f6\u7684\u9ed8\u8ba4\u503c\uff1a BookInfo defaultBook; BookInfo book = foo(isbn).value_or(defaultBook);","title":"—"},{"location":"type_rich_api/#_28","text":"\u4f60\u63a5\u624b\u4e86\u4e00\u4e2a\u5b57\u7b26\u4e32\u8f6c\u6574\u6570\uff08\u53ef\u80fd\u8f6c\u6362\u5931\u8d25\uff09\u7684\u51fd\u6570 API\uff1a // \u6587\u6863\uff1a\u5982\u679c\u5b57\u7b26\u4e32\u89e3\u6790\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de -1 \u5e76\u8bbe\u7f6e errno \u4e3a EINVAL\uff01\u8bb0\u5f97\u68c0\u67e5\uff01\u82e5\u4f60\u5fd8\u8bb0\u68c0\u67e5\u540e\u679c\u81ea\u8d1f\uff01 // \u5f53\u6307\u5b9a n \u4e3a 0 \u65f6\uff0cstr \u4e3a C \u8bed\u8a00\u7ecf\u5178\u6b3e 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u3002 // \u5f53\u6307\u5b9a n \u4e0d\u4e3a 0 \u65f6\uff0cstr \u7684\u957f\u5ea6\u56fa\u5b9a\u4e3a n\uff0c\u7528\u4e8e\u7167\u987e\u53c2\u6570\u53ef\u80fd\u4e0d\u4e3a 0 \u7ed3\u5c3e\u5b57\u7b26\u4e32\u7684\u60c5\u51b5\u3002 int parseInt(const char *str, size_t n); \u90a3\u4e48\u6211\u5982\u679c\u68c0\u6d4b\u5230 -1\uff0c\u9b3c\u77e5\u9053\u662f\u5b57\u7b26\u4e32\u91cc\u7684\u6570\u5b57\u5c31\u662f -1\uff0c\u8fd8\u662f\u56e0\u4e3a\u51fa\u9519\u624d\u8fd4\u56de -1\uff1f\u8fd8\u8981\u6211\u53bb\u68c0\u67e5 errno\uff0c\u4e07\u4e00\u4e0a\u4e00\u4e2a\u51fd\u6570\u51fa\u9519\u7559\u4e0b\u7684 EINVAL \u5462\uff1f\u4e07\u4e00\u6211\u5fd8\u8bb0\u68c0\u67e5\u5462\uff1f \u8fd0\u7528\u672c\u671f\u8bfe\u7a0b\u6240\u5b66\u77e5\u8bc6\u4f18\u5316\uff1a std::optional parseInt(std::string_view str); \u662f\u4e0d\u662f\u529f\u80fd\uff0c\u8fd4\u56de\u503c\uff0c\u53ef\u80fd\u5b58\u5728\u7684\u9519\u8bef\u60c5\u51b5\uff0c\u4e00\u76ee\u4e86\u7136\u4e86\uff1f\u6839\u672c\u4e0d\u9700\u8981\u4ec0\u4e48\u96be\u61c2\u7684\u6ce8\u91ca\uff0c\u6587\u6863\u3002 \u5982\u679c\u8c03\u7528\u8005\u60f3\u5047\u5b9a\u5b57\u7b26\u4e32\u89e3\u6790\u4e0d\u4f1a\u51fa\u9519\uff1a parseInt(\"233\").value(); \u5982\u679c\u8c03\u7528\u8005\u60f3\u5f53\u51fa\u9519\u65f6\u9ed8\u8ba4\u8fd4\u56de 0\uff1a parseInt(\"233\").value_or(0); parseInt \u5185\u90e8\u5b9e\u73b0\u53ef\u80fd\u5982\u4e0b\uff1a std::optional parseInt(std::string_view str) { int value; auto result = std::from_chars(str.data(), str.data() + str.size(), std::ref(value)); if (result.ec == std::errc()) return value; else return std::nullopt; }","title":"—"},{"location":"type_rich_api/#_29","text":"\u8c03\u7528\u8005\u7684\u53c2\u6570\u4e0d\u8bba\u662f string \u8fd8\u662f C \u8bed\u8a00\u98ce\u683c\u7684 const char *\uff0c\u90fd\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a\u901a\u7528\u7684 string_view\u3002 parseInt(\"-1\"); string s; cin >> s; parseInt(s); char perfGeek[2] = {'-', '1'}; parseInt(std::string_view{perfGeek, 2}); \u7b11\u70b9\u89e3\u6790\uff1a\u4e0a\u9762\u7684\u4ee3\u7801\u6709\u4e00\u5904\u9519\u8bef\uff0c\u4f60\u80fd\u53d1\u89c9\u5417\uff1f","title":"—"},{"location":"type_rich_api/#_30","text":"cin >> s; cin >> \u53ef\u80fd\u4f1a\u5931\u8d25\uff01\u6ca1 \u60f3 \u5230 \u5427 \u8981\u662f int \u7b49 POD \u7c7b\u578b\uff0c\u5982\u679c\u4e0d\u68c0\u6d4b\uff0c\u4f1a\u51fa\u73b0\u672a\u521d\u59cb\u5316\u7684 int \u503c\uff0c\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 int i; cin >> i; return i; // \u5982\u679c\u7528\u6237\u7684\u8f93\u5165\u503c\u4e0d\u662f\u5408\u6cd5\u7684\u6574\u6570\uff0c\u8fd9\u91cc\u4f1a\u4ea7\u751f\u5178\u4e2d\u5178\u4e4b\u5185\u5b58\u4e2d\u7684\u968f\u673a\u6570\u70eb\u70eb\u70eb\u70e4\u9984\u9968\uff01 \u5b98\u65b9\u63a8\u8350\u7684\u505a\u6cd5\u662f\u6bcf\u6b21\u90fd\u8981\u68c0\u6d4b\u662f\u5426\u5931\u8d25\uff01 int i; if (!(cin >> i)) { throw std::runtime_error(\"\u8bfb\u5165 int \u53d8\u91cf\u5931\u8d25\uff01\"); } return i; \u4f46\u662f\u8c01\u8bb0\u5f97\u4f4f\uff1f\u6240\u4ee5\u4ece\u4e00\u5f00\u59cb\u5c31\u4e0d\u8981\u8bbe\u8ba1\u8fd9\u79cd\u7cdf\u7cd5\u7684 API\u3002 \u7279\u522b\u662f cin >> \u8fd9\u79cd\u901a\u8fc7\u5f15\u7528\u8fd4\u56de i\uff0c\u5374\u8981\u4eba\u8bb0\u5f97\u5224\u65ad\u8fd4\u56de bool \u8868\u793a\u6210\u8d25\uff0c\u5fd8\u8bb0\u5224\u65ad\u8fd8\u4f1a\u7ed9\u4f60\u7559\u7740\u672a\u521d\u59cb\u5316\u7684\u715e\u7b14\u8bbe\u8ba1\u3002 \u5982\u679c\u8ba9\u6211\u6765\u8bbe\u8ba1 cin \u7684\u8bdd\uff1a std::optional readInt(); int i = cin.readInt().value(); \u8fd9\u6837\u5982\u679c\u7528\u6237\u8981\u8bfb\u53d6\u5230\u503c\u7684\u8bdd\uff0c\u5fc5\u7136\u8981 .value() \uff0c\u4ece\u800c\u5982\u679c readInt \u5931\u8d25\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5c31\u5fc5\u7136\u629b\u51fa\u5f02\u5e38\uff0c\u907f\u514d\u4e86\u7528\u6237\u5fd8\u8bb0\u5224\u65ad\u9519\u8bef\u7684\u53ef\u80fd\u3002 \u5728\u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684\u4e00\u6b3e co_async \u534f\u7a0b\u5e93\u4e2d\uff0c\u5c31\u91cd\u65b0\u8bbe\u8ba1\u4e86\u81ea\u5df1\u7684\u5f02\u6b65\u5b57\u7b26\u6d41\u7c7b\uff0c\u4f8b\u5982\u5176\u4e2d getline \u51fd\u6570\u4f1a\u8fd4\u56de std::expected \u3002 \u5728 \u9519\u8bef\u5904\u7406\u4e13\u9898 \u4e2d\u6709\u8fdb\u4e00\u6b65\u7684\u8be6\u89e3\u3002","title":"—"},{"location":"type_rich_api/#_31","text":"BookInfo * foo(ISBN isbn); \u8fd9\u662f\u4e2a\u8fd4\u56de\u667a\u80fd\u6307\u9488\u7684\u51fd\u6570\uff0c\u5355\u4ece\u51fd\u6570\u58f0\u660e\u6765\u770b\uff0c\u4f60\u80fd\u5426\u77e5\u9053\u4ed6\u6709\u6ca1\u6709\u53ef\u80fd\u8fd4\u56de\u7a7a\u6307\u9488\uff1f\u4e0d\u786e\u5b9a\u3002 std::optional foo(ISBN isbn); \u73b0\u5728\u662f\u4e0d\u662f\u5f88\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo *\uff0c\u5927\u6982\u662f\u4e0d\u4f1a\u4e3a NULL \u7684\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e0b\u66f4\u660e\u786e\u4e86\uff0c\u5982\u679c\u8fd4\u56de\u7684\u662f nullopt\uff0c\u5219\u8868\u793a\u7a7a\uff0c\u7136\u540e optional \u5185\u90e8\u7684 BookInfo * \u56e0\u4e3a\u5957\u4e86\u4e00\u5c42 gsl::not_null\uff0c\u5fc5\u5b9a\u4e0d\u80fd\u4e3a NULL\uff08\u5426\u5219\u4f1a\u88ab gsl::not_null \u7684\u65ad\u8a00\u68c0\u6d4b\u5230\uff09\uff0c\u51fd\u6570\u7684\u4f5c\u8005\u662f\u7edd\u5bf9\u4e0d\u4f1a\u6545\u610f\u8fd4\u56de\u4e2a NULL \u7684\u3002 \u5982\u679c\u5931\u8d25\uff0c\u4f1a\u8fd4\u56de nullopt\uff0c\u800c\u4e0d\u662f\u610f\u4e49\u4e0d\u660e\u8fd8\u5bb9\u6613\u5fd8\u8bb0\u7684\u7a7a\u6307\u9488\u3002","title":"—"},{"location":"type_rich_api/#_32","text":"\u8fd8\u662f\u4e0d\u5efa\u8bae\u76f4\u63a5\u7528\u539f\u59cb\u6307\u9488\uff0c\u5efa\u8bae\u7528\u667a\u80fd\u6307\u9488\u6216\u5f15\u7528\u3002 std::optional>> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4eab\u6709\u6240\u6709\u6743\u7684\u72ec\u5360\u6307\u9488\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 \u5c0f\u5f6d\u8001\u5e08\uff0c\u6211 optional \u51fa\u9519\u4e86\u600e\u4e48\u529e\uff1f std::optional> foo(ISBN isbn); \u8fd9\u4e2a\u51fd\u6570\u53ef\u80fd\u8fd4\u56de nullopt \u8868\u793a\u5931\u8d25\uff0c\u6210\u529f\u5219\u8fd4\u56de\u4e00\u4e2a\u4e0d\u4eab\u6709\u6240\u6709\u6743\u7684\u5f15\u7528\uff0c\u6307\u5411\u5355\u4e2a\u5bf9\u8c61\u3002 reference_wrapper \u662f\u5bf9\u5f15\u7528\u7684\u5305\u88c5\uff0c\u53ef\u9690\u5f0f\u8f6c\u6362\u4e3a\u5f15\u7528\uff1a int i; std::reference_wrapper ref = i; int &r = ref; // r \u6307\u5411 i \u4f7f\u5f15\u7528\u53ef\u4ee5\u5b58\u5230\u5404\u79cd\u5bb9\u5668\u91cc\uff1a \u4e14\u9047\u5230 auto \u4e0d\u4f1a\u81ea\u52a8\u9000\u5316\uff08decay\uff09\uff1a int i; std::reference_wrapper ref = i; auto ref2 = ref; // ref2 \u63a8\u5bfc\u4e3a std::reference_wrapper int &r = i; auto r2 = r; // r2 \u63a8\u5bfc\u4e3a int \u4e14\u6c38\u8fdc\u4e0d\u4f1a\u4e3a NULL\uff1a std::reference_wrapper ref; // \u7f16\u8bd1\u9519\u8bef\uff1a\u5f15\u7528\u5fc5\u987b\u521d\u59cb\u5316\uff0creference_wrapper \u5f53\u7136\u4e5f\u5fc5\u987b\u521d\u59cb\u5316 \u4e5f\u53ef\u4ee5\u901a\u8fc7 * \u6216 -> \u89e3\u5f15\u7528\uff1a BookInfo book; std::reference_wrapper refBook = book; refBook->readOnline(); BookInfo deepCopyBook = *refBook;","title":"—"},{"location":"type_rich_api/#_33","text":"\u6ce8\u610f .value() \u548c * \u662f\u6709\u533a\u522b\u7684\uff0c * \u4e0d\u4f1a\u68c0\u6d4b\u662f\u5426\u4e3a\u7a7a\uff0c\u4e0d\u4f1a\u629b\u51fa\u5f02\u5e38\uff0c\u4f46\u66f4\u9ad8\u6548\u3002 o.value(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38 *o; // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 o->readOnline(); // \u5982\u679c o \u91cc\u6ca1\u6709\u503c\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff01 \u56e0\u6b64\u4e00\u822c\u4f1a\u5728\u5224\u65ad\u4e86 optional \u4e0d\u4e3a\u7a7a\u4ee5\u540e\u624d\u4f1a\u53bb\u8bbf\u95ee * \u548c -> \u3002\u800c .value() \u53ef\u4ee5\u76f4\u63a5\u8bbf\u95ee\u3002 print(foo().value()); // .value() \u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\uff0c\u4e0d\u7528\u5224\u65ad if (auto o = foo()) { // \u5224\u65ad\u8fc7\u786e\u8ba4\u4e0d\u4e3a\u7a7a\u4e86\uff0c\u624d\u80fd\u8bbf\u95ee *o // \u5728\u5df2\u7ecf\u5224\u65ad\u8fc7\u4e0d\u4e3a\u7a7a\u7684 if \u5206\u652f\u4e2d\uff0c\u7528 * \u6bd4 .value() \u66f4\u9ad8\u6548 print(*o); } \u5171\u4eab\u6240\u6709\u6743 * n - shared_ptr * 1 - shared_ptr \u72ec\u5360\u6240\u6709\u6743 * n - vector , unique_ptr * 1 - unique_ptr \u6ca1\u6240\u6709\u6743 * n - span * 1 - reference_wrapper , T &","title":"—"},{"location":"type_rich_api/#_34","text":"\u63a5\u4e0b\u6765\u4ecb\u7ecd optional \u7684\u4e00\u4e9b\u8fdb\u9636\u7528\u6cd5\u3002 std::optional o = BookInfo(1, 2, 3); // \u521d\u59cb\u5316\u4e3a BookInfo \u503c std::optional o; // \u4e0d\u5199\u65f6\u9ed8\u8ba4\u521d\u59cb\u5316\u4e3a\u7a7a\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt o.emplace(1, 2, 3); // \u5c31\u5730\u6784\u9020\uff0c\u7b49\u4ef7\u4e8e o = BookInfo(1, 2, 3); \u4f46\u4e0d\u9700\u8981\u79fb\u52a8 BookInfo \u4e86 o.reset(); // \u5c31\u5730\u9500\u6bc1\uff0c\u7b49\u4ef7\u4e8e o = std::nullopt;","title":"—"},{"location":"type_rich_api/#_35","text":"\u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 int \u503c\u52a0 1\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readInt(); if (o) { o = *o + 1; } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 transform\uff1a std::optional o = cin.readInt(); o = o.transform([] (int n) { return n + 1; });","title":"—"},{"location":"type_rich_api/#_36","text":"\u5f53\u4e0d\u4e3a\u7a7a\u65f6\u5c06\u5176\u4e2d\u7684 string \u503c\u89e3\u6790\u4e3a int\uff0c\u5426\u5219\u4fdd\u6301\u4e3a\u7a7a\u4e0d\u53d8\u3002\u4e14\u89e3\u6790\u51fd\u6570\u53ef\u80fd\u5931\u8d25\uff0c\u5931\u8d25\u5219\u4e5f\u8981\u5c06 optional \u7f6e\u4e3a\u7a7a\uff0c\u600e\u4e48\u5199\uff1f std::optional o = cin.readLine(); std::optional o2; if (o) { o2 = parseInt(*o); } std::optional parseInt(std::string_view sv) { ... } \u8fd0\u7528 C++23 \u5f15\u5165\u7684\u65b0\u51fd\u6570 and_then\uff1a auto o = cin.readLine().and_then(parseInt);","title":"—"},{"location":"type_rich_api/#_37","text":"\u5f53\u627e\u4e0d\u5230\u6307\u5b9a\u4e66\u7c4d\u65f6\uff0c\u8fd4\u56de\u4e00\u672c\u9ed8\u8ba4\u4e66\u7c4d\u4f5c\u4e3a\u66ff\u4ee3\uff1a auto o = findBook(isbn).value_or(getDefaultBook()); \u7f3a\u70b9\uff1a\u7531\u4e8e value_or \u7684\u53c2\u6570\u4f1a\u63d0\u524d\u88ab\u6c42\u503c\uff0c\u5373\u4f7f findBook \u6210\u529f\u627e\u5230\u4e86\u4e66\u7c4d\uff0c\u4e5f\u4f1a\u6267\u884c getDefaultBook \u51fd\u6570\uff0c\u7136\u540e\u5c06\u5176\u4f5c\u4e3a\u6b7b\u4ea1\u53f3\u503c\u4e22\u5f03\u3002\u5982\u679c\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\u7684\u8fc7\u7a0b\u5f88\u6162\uff0c\u90a3\u4e48\u5c31\u975e\u5e38\u4f4e\u6548\u3002 \u4e3a\u6b64\uff0cC++23 \u5f15\u5165\u4e86 or_else \u51fd\u6570\u3002 \u53ea\u6709 findBook \u627e\u4e0d\u5230\u65f6\u624d\u4f1a\u6267\u884c lambda \u4e2d\u7684\u51fd\u6570\u4f53\uff1a auto o = findBook(isbn).or_else([] -> std::optional { cout << \"findBook \u51fa\u9519\u4e86\uff0c\u73b0\u5728\u5f00\u59cb\u521b\u5efa\u9ed8\u8ba4\u4e66\u7c4d\uff0c\u975e\u5e38\u6162\\n\"; return getDefaultBook(); });","title":"—"},{"location":"type_rich_api/#_38","text":"\u6b64\u7c7b\u51fd\u6570\u90fd\u53ef\u4ee5\u53cd\u590d\u5d4c\u5957\uff1a int i = cin.readLine() .or_else(getDefaultLine) .and_then(parseInt) .transform([] (auto i) { return i * 2; }) .value_or(0); \u52a0\u5165\u51fd\u6570\u5f0f\u795e\u6559\u5427\uff0c\u51fd\u95e8\uff01","title":"—"},{"location":"type_rich_api/#_39","text":"","title":"—"},{"location":"type_rich_api/#stl","text":"","title":"\u70b9\u540d\u6279\u8bc4\u7684 STL \u8bbe\u8ba1"},{"location":"type_rich_api/#_40","text":"\u4f8b\u5982 std::stack \u7684\u8bbe\u8ba1\u5c31\u975e\u5e38\u5931\u8d25\uff1a if (!stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u6211\u4eec\u5fc5\u987b\u5224\u65ad stack \u4e0d\u4e3a\u7a7a\uff0c\u624d\u80fd\u5f39\u51fa\u6808\u9876\u5143\u7d20\u3002\u5bf9\u7740\u4e00\u4e2a\u7a7a\u7684\u6808 pop \u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u800c pop() \u53c8\u662f\u4e00\u4e2a\u8fd4\u56de void \u7684\u51fd\u6570\uff0c\u4ed6\u53ea\u662f\u5220\u9664\u6808\u9876\u5143\u7d20\uff0c\u5e76\u4e0d\u4f1a\u8fd4\u56de\u5143\u7d20\u3002 \u6211\u4eec\u5fc5\u987b\u5148\u8c03\u7528 top() \u628a\u6808\u9876\u53d6\u51fa\u6765\uff0c\u7136\u540e\u624d\u80fd pop\uff01 \u660e\u660e\u662f\u540c\u4e00\u4e2a\u64cd\u4f5c\uff0c\u5374\u8981\u62c6\u6210\u4e09\u4e2a\u51fd\u6570\u6765\u5b8c\u6210\uff0c\u5f88\u70c2\u3002\u5982\u679c\u4f60\u4e0d\u614e\u628a\u5224\u65ad\u6761\u4ef6\u5199\u53cd\uff1a if (stack.empty()) { auto val = std::move(stack.top()); stack.pop(); } \u5c31\u4e00\u4e2a Segmentation Fault \u8e66\u4f60\u8138\u4e0a\uff0c\u4f60\u627e\u534a\u5929\u90fd\u627e\u4e0d\u5230\u81ea\u5df1\u54ea\u9519\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u91cd\u65b0\u8bbe\u8ba1\uff0c\u6574\u5408\u6210\u4e00\u4e2a\u51fd\u6570\uff1a std::optional pop(); \u8bed\u4e49\u660e\u786e\uff0c\u7528\u8d77\u6765\u4e5f\u65b9\u4fbf\uff0c\u7528\u6237\u4e0d\u5bb9\u6613\u72af\u9519\u3002 if (auto val = stack.pop()) { ... } \u628a\u591a\u4e2a\u672c\u5c31\u5c5e\u4e8e\u540c\u4e00\u4ef6\u4e8b\u7684\u51fd\u6570\uff0c\u6574\u5408\u6210\u4e00\u4e2a\uff0c\u907f\u514d\u7528\u6237\u4e2d\u95f4\u51fa\u7eb0\u6f0f\u3002 \u4ece\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7684\u7c7b\u578b\u4e0a\uff0c\u9650\u5b9a\u81ea\u7531\u5ea6\uff0c\u51cf\u8f7b\u7528\u6237\u601d\u8003\u8d1f\u62c5\u3002","title":"—"},{"location":"type_rich_api/#_41","text":"\u4f17\u6240\u5468\u77e5\uff0cvector \u6709\u4e24\u4e2a\u51fd\u6570\u7528\u4e8e\u8bbf\u95ee\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\u3002 int &operator[](size_t index); int &at(size_t index); vec[3]; // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u53d1\u751f\u6570\u7ec4\u8d8a\u754c\uff01\u8fd9\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vec.at(3); // \u5982\u679c vec \u7684\u5927\u5c0f\u4e0d\u8db3 3\uff0c\u4f1a\u629b\u51fa out_of_range \u5f02\u5e38 \u7528\u6237\u901a\u5e38\u4f1a\u6839\u636e\u81ea\u5df1\u7684\u9700\u8981\uff0c\u5982\u679c\u4ed6\u4eec\u975e\u5e38\u81ea\u4fe1\u81ea\u5df1\u7684\u7d22\u5f15\u4e0d\u4f1a\u8d8a\u754c\uff0c\u53ef\u4ee5\u7528\u9ad8\u6548\u7684 []\uff0c\u4e0d\u505a\u68c0\u6d4b\u3002 \u5982\u679c\u4e0d\u786e\u5b9a\uff0c\u53ef\u4ee5\u7528\u66f4\u5b89\u5168\u7684 at()\uff0c\u4e00\u65e6\u8d8a\u754c\u81ea\u52a8\u629b\u51fa\u5f02\u5e38\uff0c\u65b9\u4fbf\u8c03\u8bd5\u3002 \u6211\u4eec\u53ef\u4ee5\u91cd\u65b0\u8bbe\u8ba1\u4e00\u4e2a .get() \u51fd\u6570\uff1a std::optional get(size_t index); \u5f53\u68c0\u6d4b\u5230\u6570\u7ec4\u8d8a\u754c\u65f6\uff0c\u8fd4\u56de nullopt\u3002 *vec.get(3); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u6027\u80fd\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u4ece\u800c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u4f18\u5316\u6389\u8d8a\u754c\u7684\u8def\u5f84 vec.get(3).value(); // \u5982\u679c\u7528\u6237\u8ffd\u6c42\u5b89\u5168\uff0c\u53ef\u4ee5\u628a\u6570\u7ec4\u8d8a\u754c\u8f6c\u5316\u4e3a\u4e00\u4e2a\u5f02\u5e38 vec.get(3).value_or(0); // \u5982\u679c\u7528\u6237\u60f3\u8981\u5728\u8d8a\u754c\u65f6\u83b7\u5f97\u9ed8\u8ba4\u503c 0 \u8fd9\u6837\u5c31\u53ea\u9700\u8981\u4e00\u4e2a\u51fd\u6570\uff0c\u4e0d\u8bba\u7528\u6237\u60f3\u8981\u7684\u662f\u4ec0\u4e48\uff0c\u90fd\u53ea\u9700\u8981\u8fd9\u4e00\u4e2a\u7edf\u4e00\u7684 get() \u51fd\u6570\u3002","title":"—"},{"location":"type_rich_api/#_42","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u4f60\u8fd9\u4e2a\u53ea\u80fd get\uff0c\u8981\u5982\u4f55 set \u5440\uff1f std::optional get(size_t index); bool set(size_t index, int value); // \u5982\u679c\u8d8a\u754c\uff0c\u8fd4\u56de false \u7f3a\u70b91\uff1a\u8fd4\u56de bool \u65e0\u6cd5\u8fd0\u7528 optional \u7684\u5c0f\u6280\u5de7\uff1a\u901a\u8fc7 value() \u8f6c\u5316\u4e3a\u5f02\u5e38\uff0c\u4e14\u7528\u6237\u5bb9\u6613\u5fd8\u8bb0\u68c0\u67e5\u8fd4\u56de\u503c\u3002 \u7f3a\u70b92\uff1a\u4e24\u4e2a\u53c2\u6570\uff0c\u4e00\u4e2a\u662f size_t \u4e00\u4e2a\u662f int\uff0c\u8fd8\u662f\u5f88\u5bb9\u6613\u987a\u5e8f\u641e\u6df7\u3002 std::optional> get(size_t index); auto x = **vec.get(3); // \u6027\u80fd\u8bfb auto x = *vec.get(3).value(); // \u5b89\u5168\u8bfb *vec.get(3) = 42; // \u6027\u80fd\u5199 vec.get(3).value() = 42; // \u5b89\u5168\u5199","title":"—"},{"location":"type_rich_api/#_43","text":"","title":"—"},{"location":"type_rich_api/#stl_1","text":"","title":"\u70b9\u540d\u8868\u626c\u7684 STL \u90e8\u5206"},{"location":"type_rich_api/#_44","text":"void Sleep(int delay); \u8c01\u77e5\u9053\u8fd9\u4e2a delay \u7684\u5355\u4f4d\u662f\u4ec0\u4e48\uff1f\u79d2\uff1f\u6beb\u79d2\uff1f void Sleep(int ms); \u597d\u5427\uff0c\u662f\u6beb\u79d2\u3002\u53ef\u662f\u9664\u975e\u770b\u4e00\u773c\u51fd\u6570\u5b9a\u4e49\u6216\u6587\u6863\uff0c\u8c01\u60f3\u5f97\u5230\u8fd9\u662f\u4e2a\u6beb\u79d2\uff1f \u4e00\u4e2a\u7528\u6237\u60f3\u8981\u7761 3 \u79d2\uff0c\u4ed6\u5199\u9053\uff1a Sleep(3); \u7f16\u8bd1\u5668\u6ca1\u6709\u4efb\u4f55\u62a5\u9519\uff0c\u4e00\u8fd0\u884c\u53ea\u7761\u4e86 3 \u6beb\u79d2\u3002 \u7528\u6237\u5927\u53d1\u96f7\u9706\u4ee5\u4e3a\u4f60\u7684 Sleep \u51fd\u6570\u6709 BUG\uff0c\u6211\u8ba9\u4ed6\u7761 3 \u79d2\u600e\u4e48\u597d\u50cf\u6839\u672c\u6ca1\u7761\u554a\u3002","title":"—"},{"location":"type_rich_api/#_45","text":"void SleepMilliSeconds(int ms); \u6539\u4e2a\u51fd\u6570\u540d\u53ef\u4ee5\u89e3\u51b3\u4e00\u90e8\u5206\u95ee\u9898\uff0c\u5f53\u7528\u6237\u8c03\u7528\u65f6\uff0c\u4ed6\u9700\u8981\u624b\u52a8\u6253\u51fa MilliSeconds \uff0c\u4ece\u800c\u5f3a\u8feb\u4ed6\u6e05\u9192\u4e00\u4e0b\uff0c\u81ea\u5df1\u7ed9\u7684 3 \u5230\u5e95\u662f\u4e0d\u662f\u81ea\u5df1\u60f3\u8981\u7684\u3002","title":"—"},{"location":"type_rich_api/#_46","text":"struct MilliSeconds { int count; explicit MilliSeconds(int count) : count(count) {} }; void Sleep(MilliSeconds delay); \u73b0\u5728\uff0c\u5982\u679c\u7528\u6237\u5199\u51fa Sleep(3); \u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\u3002 \u4ed6\u5fc5\u987b\u660e\u786e\u5199\u51fa Sleep(MilliSeconds(3)); \u624d\u80fd\u901a\u8fc7\u7f16\u8bd1\u3002","title":"—"},{"location":"type_rich_api/#_47","text":"\u6807\u51c6\u5e93\u7684 chrono \u6a21\u5757\u5c31\u5927\u91cf\u8fd0\u7528\u4e86\u8fd9\u79cd\u5f3a\u7c7b\u578b\u5c01\u88c5\uff1a this_thread::sleep_for(chrono::seconds(3)); \u5982\u679c\u4f60 using namespace std::literials; \u8fd8\u53ef\u4ee5\u8fd9\u6837\u5feb\u6377\u5730\u521b\u5efa\u5b57\u9762\u91cf\uff1a this_thread::sleep_for(3ms); // 3 \u6beb\u79d2 this_thread::sleep_for(3s); // 3 \u79d2 this_thread::sleep_for(3m); // 3 \u5206\u949f this_thread::sleep_for(3h); // 3 \u5c0f\u65f6 \u4e14\u652f\u6301\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff0c\u4e0d\u540c\u5355\u4f4d\u4e4b\u95f4\u8fd8\u53ef\u4ee5\u4e92\u76f8\u8f6c\u6362\uff1a this_thread::sleep_for(1s + 200ms); chrono::minutes three_minutes = 180s;","title":"—"},{"location":"type_rich_api/#_48","text":"chrono \u662f\u4e00\u4e2a\u4f18\u79c0\u7684\u7c7b\u578b\u5c01\u88c5\u6848\u4f8b\uff0c\u628a time_t \u7c7b\u578b\u5c01\u88c5\u6210\u4e86\u5f3a\u7c7b\u578b\u7684 duration \u548c time_point\u3002 \u65f6\u95f4\u70b9\uff08time_point\uff09\u8868\u793a\u67d0\u4e2a\u5177\u4f53\u7684\u65f6\u95f4\uff0c\u4f8b\u5982 2024 \u5e74 5 \u6708 16 \u65e5 18:06:28\u3002 \u65f6\u95f4\u6bb5\uff08duration\uff09\u8868\u793a\u4e00\u6bb5\u65f6\u95f4\u7684\u957f\u5ea6\uff0c\u4f8b\u5982 1 \u5929\uff0c2 \u5c0f\u65f6\uff0c3 \u5206\u949f\uff0c4 \u79d2\u3002 \u65f6\u95f4\u6bb5\u5f88\u5bb9\u6613\u8868\u793a\uff0c\u53ea\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u5355\u4f4d\uff0c\u6bd4\u5982\u79d2\uff0c\u7136\u540e\u7528\u4e00\u4e2a\u6570\u5b57\u5c31\u53ef\u4ee5\u8868\u793a\u591a\u5c11\u79d2\u7684\u65f6\u95f4\u6bb5\u3002 \u4f46\u662f\u65f6\u95f4\u70b9\u5c31\u5f88\u96be\u8868\u793a\u4e86\uff0c\u4f8b\u5982\u4f60\u65e0\u6cd5 Unix \u65f6\u95f4\u6233\u7528\u4e00\u4e2a\u6570\u5b57\u6765\u8868\u793a\u65f6\u95f4\u70b9\uff0c\u6570\u5b57\u7684\u542b\u4e49\u662f\u4ece\u5f53\u524d\u65f6\u95f4\u5230 1970 \u5e74 1 \u6708 1 \u65e5 00:00:00 \u7684\u79d2\u6570\u3002 \u4f8b\u5982\u5199\u4f5c\u8fd9\u7bc7\u6587\u7ae0\u7684\u65f6\u95f4\u6233\u662f 1715853968 (2024/5/16 18:06)\u3002 C \u8bed\u8a00\u7528\u4e00\u4e2a time_t \uff0c\u5b9e\u9645\u4e0a\u662f long \u7684\u7c7b\u578b\u522b\u540d\u6765\u8868\u793a\u65f6\u95f4\u6233\uff0c\u4f46\u5b83\u6709\u4e00\u4e2a\u4e25\u91cd\u7684\u95ee\u9898\uff1a \u5b83\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u70b9\uff0c\u4e5f\u53ef\u4ee5\u88ab\u5f53\u6210\u65f6\u95f4\u6bb5\uff0c\u8fd9\u5c31\u9020\u6210\u4e86\u5de8\u5927\u7684\u6df7\u4e71\u3002 time_t t0 = time(NULL); // \u65f6\u95f4\u70b9 ... time_t t1 = time(NULL); // \u65f6\u95f4\u70b9 time_t dt = t1 - t0; // \u65f6\u95f4\u6bb5 \u75db\u70b9\uff1a\u5982\u679c\u8fd9\u91cc\u7684\u8d1f\u53f7\u5199\u9519\uff0c\u5199\u6210 t1 + t0 \uff0c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u62a5\u9519\uff0c\u4f60\u53ef\u80fd\u6839\u672c\u6ca1\u53d1\u73b0\uff0c\u6d6a\u8d39\u5927\u91cf\u65f6\u95f4\u8c03\u8bd5\u6700\u540e\u53ea\u53d1\u73b0\u4e00\u4e2a\u4f4e\u7ea7\u9519\u8bef\u3002 \u6a21\u7cca\uff1a\u65f6\u95f4\u70b9\uff08t0\u3001t1\uff09\u548c\u65f6\u95f4\u6bb5\uff08dt\uff09\u90fd\u662f time_t\uff0c\u521d\u6b21\u9605\u8bfb\u4ee3\u7801\u5f88\u5bb9\u6613\u5206\u4e0d\u6e05\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5\u3002 \u5982\u679c\u4e0d\u614e\u628a\u201c\u65f6\u95f4\u70b9\u201d\u7684 time_t \u4f20\u5165\u5230\u672c\u5e94\u53ea\u652f\u6301\u201c\u65f6\u95f4\u6bb5\u201d\u7684 sleep \u51fd\u6570\uff0c\u4f1a\u51fa\u73b0\u201c\u7761\u7f8e\u4eba\u201d\u7684\u5947\u89c2\uff1a time_t t = time(NULL); // \u8fd4\u56de 1715853968 \u8868\u793a\u5f53\u524d\u65f6\u95f4\u70b9 sleep(t); // \u4e0d\u5c0f\u5fc3\u628a\u65f6\u95f4\u70b9\u5f53\u6210\u65f6\u95f4\u6bb5\u6765\u7528\u4e86\uff01 \u8fd9\u4e2a\u7a0b\u5e8f\u4f1a\u7761 1715853968 \u79d2\u540e\u624d\u9192\uff0c\u5373 54 \u5e74\u540e\uff01 chrono::system_clock::time_point last = chrono::system_clock::now(); ... chrono::system_clock::time_point now = chrono::system_clock::now(); chrono::system_clock::duration dt = now - last; cout << \"\u7528\u4e86 \" << duration_cast(dt).count() << \" \u79d2\\n\"; \u4e00\u770b\u5c31\u77e5\u9053\u54ea\u4e2a\u662f\u65f6\u95f4\u70b9\uff0c\u54ea\u4e2a\u662f\u65f6\u95f4\u6bb5 \u7528\u9519\u4e86\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519 \u5355\u4f4d\u8f6c\u6362\u4e0d\u4f1a\u6df7\u6dc6 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u70b9 = \u7f16\u8bd1\u51fa\u9519\uff01\u56e0\u4e3a\u65f6\u95f4\u70b9\u4e4b\u95f4\u4e0d\u5141\u8bb8\u76f8\u52a0\uff0c2024 + 2024\uff0c\u4f60\u662f\u60f3\u52a0\u5230 4048 \u5e74\u53bb\u5417\uff1f \u65f6\u95f4\u70b9 - \u65f6\u95f4\u70b9 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u70b9 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u70b9 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u70b9 \u65f6\u95f4\u6bb5 + \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 - \u65f6\u95f4\u6bb5 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 \u00d7 \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u65f6\u95f4\u6bb5 / \u5e38\u6570 = \u65f6\u95f4\u6bb5 \u8fd9\u5c31\u662f\u672c\u671f\u8bfe\u7a0b\u7684\u4e3b\u9898\uff0c\u901a\u8fc7\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u5bf9\u53ef\u80fd\u7684\u7528\u6cd5\u52a0\u4ee5\u4e25\u683c\u7684\u9650\u5236\uff0c\u6700\u5927\u9650\u5ea6\u963b\u6b62\u7528\u6237\u4e0d\u7ecf\u610f\u95f4\u5199\u51fa\u9519\u8bef\u7684\u4ee3\u7801\u3002","title":"—"},{"location":"type_rich_api/#_49","text":"","title":"—"},{"location":"type_rich_api/#_50","text":"","title":"\u679a\u4e3e\u7c7b\u578b"},{"location":"type_rich_api/#_51","text":"\u4f60\u7684\u8001\u677f\u8981\u6c42\u4e00\u4e2a\u8bbe\u5b9a\u5ba2\u6237\u6027\u522b\u7684\u51fd\u6570\uff1a void foo(int sex); \u8001\u677f\u53e3\u5934\u548c\u5458\u5de5\u7ea6\u5b9a\u8bf4\uff0c0\u8868\u793a\u5973\uff0c1\u8868\u793a\u7537\uff0c2\u8868\u793a\u81ea\u5b9a\u4e49\u3002 \u8fd9\u8c01\u8bb0\u5f97\u4f4f\uff1f\u8bbe\u60f3\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\u4e0b\u9762\u7684\u4ee3\u7801\uff1a foo(1); \u4f60\u80fd\u731c\u5230\u8fd9\u4e2a 1 \u662f\u4ec0\u4e48\u610f\u601d\u5417\uff1f \u89e3\u51b3\u65b9\u6cd5\u662f\u4f7f\u7528\u679a\u4e3e\u7c7b\u578b\uff0c\u7ed9\u6bcf\u4e2a\u6570\u503c\u4e00\u4e2a\u552f\u4e00\u7684\u540d\u5b57\uff1a enum Sex { Female = 0, Male = 1, Custom = 2, }; void foo(Sex sex); \u518d\u5047\u8bbe\u4f60\u662f\u4e00\u4e2a\u65b0\u6765\u7684\u5458\u5de5\uff0c\u770b\u5230\uff1a foo(Male); \u662f\u4e0d\u662f\u5c31\u4e00\u76ee\u4e86\u7136\u5566\uff1f","title":"—"},{"location":"type_rich_api/#_52","text":"\u679a\u4e3e\u7684\u503c\u4e5f\u53ef\u4ee5\u4e0d\u7528\u5199\uff0c\u8ba9\u7f16\u8bd1\u5668\u81ea\u52a8\u6309 0\u30011\u30012 \u7684\u987a\u5e8f\u5206\u914d\u503c\uff1a enum Sex { Female, // 0 Male, // 1 Custom, // 2 }; \u53ef\u4ee5\u6307\u5b9a\u4ece 1 \u5f00\u59cb\u8ba1\u6570\uff1a enum Sex { Female = 1, Male, // 2 Custom, // 3 };","title":"—"},{"location":"type_rich_api/#_53","text":"\u4f46\u679a\u4e3e\u7c7b\u578b\u8fd8\u662f\u53ef\u4ee5\u9a97\u4eba\uff0c\u518d\u5047\u8bbe\u4f60\u662f\u65b0\u6765\u7684\uff0c\u770b\u5230\uff1a foo(Male, 24); \u662f\u4e0d\u662f\u60f3\u5f53\u7136\u7684\u611f\u89c9\u8fd9\u4e2a\u4ee3\u7801\u6ca1\u95ee\u9898\uff1f \u4f46\u5f53\u4f60\u770b\u5230 foo \u51c6\u786e\u7684\u51fd\u6570\u5b9a\u4e49\u65f6\uff0c\u50bb\u773c\u4e86\uff1a void foo(int age, Sex sex); \u76f8\u5f53\u4e8e\u6ce8\u518c\u4e86\u4e00\u4e2a 1 \u5c81\uff0c\u6027\u522b\u662f 24 \u7684\u4f2a\u4eba\u3002\u4e14\u7a0b\u5e8f\u5458\u5f88\u5bb9\u6613\u770b\u4e0d\u51fa\u95ee\u9898\uff0c\u7f16\u8bd1\u5668\u4e5f\u4e0d\u62a5\u9519\u3002 \u4e3a\u6b64\uff0cC++11 \u5f15\u5165\u4e86 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff1a enum class Sex { Female = 0, Male = 1, Custom = 2, }; \u73b0\u5728\uff0c\u5982\u679c\u4f60\u518d\u4e0d\u5c0f\u5fc3\u628a sex \u4f20\u5165 age \u7684\u8bdd\uff0c\u7f16\u8bd1\u5668\u4f1a\u62a5\u9519\uff01\u56e0\u4e3a\u5f3a\u7c7b\u578b\u679a\u4e3e\u4e0d\u5141\u8bb8\u4e0e int \u9690\u5f0f\u8f6c\u6362\u3002 \u800c\u4e14\u5f3a\u7c7b\u578b\u679a\u4e3e\u4f1a\u9700\u8981\u663e\u5f0f\u5199\u51fa Sex:: \u7c7b\u578b\u524d\u7f00\uff0c\u5f53\u4f60\u6709\u5f88\u591a\u679a\u4e3e\u7c7b\u578b\u65f6\u4e0d\u5bb9\u6613\u6df7\u6dc6\uff1a foo(24, Sex::Male); \u5982\u679c\u4f60\u7684 Sex \u8303\u56f4\u5f88\u5c0f\uff0c\u53ea\u9700\u8981 uint8_t \u7684\u5185\u5b58\u5c31\u591f\uff0c\u53ef\u4ee5\u7528\u8fd9\u4e2a\u8bed\u6cd5\u6307\u5b9a\u679a\u4e3e\u7684\u201c\u540e\u53f0\u7c7b\u578b\u201d\uff1a enum class Sex : uint8_t { Female = 0, Male = 1, Custom = 2, }; static_assert(sizeof(Sex) == 1);","title":"—"},{"location":"type_rich_api/#_54","text":"\u5047\u5982\u4f60\u7684\u6240\u6709 age \u90fd\u662f int \u7c7b\u578b\u7684\uff0c\u4f46\u662f\u73b0\u5728\uff0c\u8001\u677f\u7a81\u7136\u5fc3\u8840\u6765\u6f6e\uff1a \u8bf4\u4e3a\u4e86\u201c\u4f18\u5316\u5b58\u50a8\u7a7a\u95f4\u201d\uff0c\u60f3\u8981\u628a\u6240\u6709 age \u6539\u6210 uint8_t \u7c7b\u578b\u7684\uff01 \u4e3a\u4e86\u9884\u9632\u672a\u6765\u53ef\u80fd\u9700\u8981\u6539\u53d8\u7c7b\u578b\u7684\u9700\u6c42\uff0c\u4e5f\u662f\u4e3a\u4e86\u53ef\u8bfb\u6027\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\u7c7b\u578b\u522b\u540d\uff1a using Age = int; void foo(Age age, Sex sex); \u8fd9\u6837\u5f53\u8001\u677f\u9700\u8981\u6539\u53d8\u5e95\u5c42\u7c7b\u578b\u65f6\uff0c\u53ea\u9700\u8981\u6539\u52a8\u4e00\u884c\uff1a using Age = uint8_t; \u5c31\u80fd\u81ea\u52a8\u8ba9\u6240\u6709\u4ee3\u7801\u90fd\u4f7f\u7528 uint8_t \u4f5c\u4e3a age \u4e86\u3002","title":"—"},{"location":"type_rich_api/#_55","text":"\u4f46\u662f\u7c7b\u578b\u522b\u540d\u6bd5\u7adf\u53ea\u662f\u522b\u540d\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u4fdd\u969c\uff1a using Age = int; using Phone = int; foo(Age age, Phone phone); void bar() { Age age = 42; Phone phone = 12345; foo(phone, age); // \u4e0d\u5c0f\u5fc3\u5199\u53cd\u4e86\uff01\u800c\u7f16\u8bd1\u5668\u4e0d\u4f1a\u63d0\u9192\u4f60\uff01 } \u56e0\u4e3a Age \u548c Phone \u53ea\u662f\u7c7b\u578b\u522b\u540d\uff0c\u5b9e\u9645\u4e0a\u8fd8\u662f\u540c\u6837\u7684 int \u7c7b\u578b\u2026\u6240\u4ee5\u7f16\u8bd1\u5668\u751a\u81f3\u4e0d\u4f1a\u6709\u4efb\u4f55\u8b66\u544a\u3002 \u6709\u4e00\u79cd\u5f88\u6781\u7aef\u7684\u505a\u6cd5\u662f\u628a Age \u548c Phone \u4e5f\u505a\u6210\u679a\u4e3e\uff0c\u4f46\u6ca1\u6709\u5b9a\u4e49\u4efb\u4f55\u503c\uff1a enum class Age : int {}; enum class Phone : int {}; \u8fd9\u6837\u7528\u5230\u7684\u65f6\u5019\u5c31\u53ea\u80fd\u901a\u8fc7\u5f3a\u5236\u8f6c\u6362\u7684\u8bed\u6cd5\uff1a foo(Age(42), Phone(12345)); \u5e76\u4e14\u5982\u679c\u5199\u9519\u987a\u5e8f\uff0c\u5c1d\u8bd5\u628a Phone \u4f20\u5165 Age \u7c7b\u578b\u7684\u53c2\u6570\uff0c\u7f16\u8bd1\u5668\u4f1a\u7acb\u5373\u62a5\u9519\uff0c\u963b\u6b62\u4f60\u57cb\u4e0b BUG \u9690\u60a3\u3002","title":"—"},{"location":"type_rich_api/#_56","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u7684\u65b9\u6cd5\u4ee5\u540e\uff0c\u4e0d\u80fd\u505a\u52a0\u6cd5\u4e86\u600e\u4e48\u529e\uff1f Age(42) + Age(1) // \u7f16\u8bd1\u5668\u9519\u8bef\uff01 \u8fd9\u662f\u56e0\u4e3a Age \u662f\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u4e0d\u80fd\u9690\u5f0f\u8f6c\u6362\u4e3a int \u540e\u505a\u52a0\u6cd5\u3002 \u53ef\u4ee5\u5b9a\u4e49\u4e00\u4e2a\u8fd0\u7b97\u7b26\u91cd\u8f7d\uff1a enum class Age : int {}; inline Age operator+(Age a, Age b) { return Age((int)a + (int)b); } \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff0c\u76f4\u63a5\u8ba9\u52a0\u6cd5\u8fd0\u7b97\u7b26\u5bf9\u4e8e\u6240\u6709\u679a\u4e3e\u7c7b\u578b\u90fd\u9ed8\u8ba4\u751f\u6548\uff1a template requires std::is_enum_v T operator+(T a, T b) { using U = std::underlying_type_t; return T((U)a + (U)b); } \u6709\u65f6\u8fd9\u53cd\u800c\u662f\u4e2a\u4f18\u70b9\uff0c\u6bd4\u5982\u4f60\u53ef\u4ee5\u53ea\u5b9a\u4e49\u52a0\u6cd5\u8fd0\u7b97\u7b26\uff0c\u5c31\u53ef\u4ee5\u8ba9 Age \u4e0d\u652f\u6301\u4e58\u6cd5\uff0c\u9700\u8981\u624b\u52a8\u8f6c\u6362\u540e\u624d\u80fd\u4e58\uff0c\u907f\u514d\u65e0\u610f\u4e2d\u72af\u9519\u7684\u53ef\u80fd\u3002","title":"—"},{"location":"type_rich_api/#_57","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7528\u4e86\u4f60\u63a8\u8350\u7684 \u5f3a\u7c7b\u578b\u679a\u4e3e \uff0c\u4e0d\u652f\u6301\u6211\u6700\u7231\u7684\u6216\u8fd0\u7b97 | \u4e86\u600e\u4e48\u529e\uff1f enum class OpenFlag { Create = 1, Read = 2, Write = 4, Truncate = 8, Append = 16, Binary = 32, }; inline OpenFlag operator|(OpenFlag a, OpenFlag b) { return OpenFlag((int)a | (int)b); } inline OpenFlag operator&(OpenFlag a, OpenFlag b) { return OpenFlag((int)a & (int)b); } inline OpenFlag operator~(OpenFlag a) { return OpenFlag(~(int)a); }","title":"—"},{"location":"type_rich_api/#_58","text":"","title":"—"},{"location":"type_rich_api/#_59","text":"","title":"\u5176\u4ed6\u7c7b\u578b\u5957\u76ae"},{"location":"type_rich_api/#_60","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u5f88\u559c\u6b22\u5f3a\u7c7b\u578b\u679a\u4e3e\u8fd9\u4e00\u5957\uff0c\u4f46\u6211\u7684\u53c2\u6570\u4e0d\u662f\u6574\u6570\u7c7b\u578b\uff0c\u800c\u662f double\u3001string \u7b49\u7c7b\u578b\uff0c\u600e\u4e48\u529e\uff1f struct Name { private: std::string value; public: explicit operator std::string() const { return value; } explicit Name(std::string value) : value(value) {} }; \u8fd9\u91cc\u6211\u4eec\u5199 explicit \u5c31\u53ef\u4ee5\u963b\u6b62\u9690\u5f0f\u7c7b\u578b\u8f6c\u6362\uff0c\u8d77\u5230\u4e0e\u5f3a\u7c7b\u578b\u679a\u4e3e\u7c7b\u4f3c\u7684\u4f5c\u7528\u3002 \u6216\u8005\u8fd0\u7528\u6a21\u677f\u5143\u7f16\u7a0b\uff1a // \u6b64\u5904\u4f7f\u7528 CRTP \u6a21\u5f0f\u662f\u4e3a\u4e86\u8ba9 Typed \u6bcf\u6b21\u90fd\u5b9e\u4f8b\u5316\u51fa\u4e0d\u540c\u7684\u57fa\u7c7b\uff0c\u963b\u6b62 object-slicing template struct Typed { protected: T value; public: explicit operator T() const { return value; } explicit Typed(T value) : value(value) {} }; struct Name : Typed {}; struct Meter : Typed { using Typed::Typed; }; struct Kilometer : Typed { using Typed::Typed; operator Meter() const { // \u5141\u8bb8\u9690\u5f0f\u8f6c\u6362\u4e3a\u7c73 return Meter(value * 1000); } }; Meter m = Kilometer(1); // m = Meter(1000); foo(m);","title":"—"},{"location":"type_rich_api/#_61","text":"","title":"—"},{"location":"type_rich_api/#raii","text":"","title":"RAII \u5c01\u88c5"},{"location":"type_rich_api/#_62","text":"\u5c0f\u5f6d\u8001\u5e08\uff0c\u6211\u7684\u51fd\u6570\u5c31\u662f\u6d89\u53ca\u201c\u5f00\u59cb\u201d\u548c\u201c\u7ed3\u675f\u201d\u4e24\u4e2a\u64cd\u4f5c\uff0c\u7528\u6237\u7684\u64cd\u4f5c\u9700\u8981\u7a7f\u63d2\u5728\u5176\u4e2d\u95f4\uff0c\u600e\u4e48\u6574\u5408\u5462\uff1f mysql_connection *conn = mysql_connect(\"127.0.0.1\"); mysql_execute(conn, \"drop database paolu\"); mysql_close(conn); // \u7528\u6237\u53ef\u80fd\u5fd8\u8bb0\u5173\u95ed\u8fde\u63a5\uff01\u7834\u574f\u5e93\u8bbe\u8ba1\u8005\u60f3\u8981\u7684\u7528\u6cd5 \u8fd9\u79cd\u5927\u591a\u662f\u83b7\u53d6\u8d44\u6e90\uff0c\u548c\u91ca\u653e\u8d44\u6e90\u4e24\u4e2a\u64cd\u4f5c\u3002 \u56e0\u4e3a mysql \u662f\u4e2a C \u8bed\u8a00\u7684\u5e93\uff0c\u4ed6\u6ca1\u6709 RAII \u5c01\u88c5\uff0c\u8ba9\u4ed6\u624b\u52a8\u5c01\u88c5\u6709\u7684\u540c\u5b66\u53c8\u5acc\u5f03\u9ebb\u70e6\u3002 \u8fd9\u65f6\u6211\u4f1a\u544a\u8bc9\u4ed6\u4eec\u4e00\u4e2a shared_ptr \u5c0f\u5999\u62db\uff1a\u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u6307\u5b9a\u91ca\u653e\u51fd\u6570\uff0c\u4ee3\u66ff\u9ed8\u8ba4\u7684 delete auto conn = std::shared_ptr(mysql_connect(\"127.0.0.1\"), mysql_close); mysql_execute(conn.get(), \"drop database paolu\"); // conn \u79bb\u5f00\u4f5c\u7528\u57df\u65f6\uff0c\u4f1a\u81ea\u52a8\u8c03\u7528 mysql_close\uff0c\u675c\u7edd\u4e86\u4e00\u4e2a\u51fa\u9519\u7684\u53ef\u80fd","title":"—"},{"location":"type_rich_api/#_63","text":"\u4ee5\u5c01\u88c5 C \u8bed\u8a00\u7684 FILE \u4e3a\u4f8b\u3002 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *file); \u8fd9\u4e2a size \u548c nmemb \u771f\u662f\u592a\u7cdf\u7cd5\u4e86\uff0c\u672c\u610f\u662f\u4e3a\u4e86\u652f\u6301\u4e0d\u540c\u5143\u7d20\u7c7b\u578b\u7684\u6570\u7ec4\u3002 size \u662f\u5143\u7d20\u672c\u8eab\u5927\u5c0f\uff0cnmemb \u662f\u5143\u7d20\u6570\u91cf\u3002\u5b9e\u9645\u8bfb\u53d6\u7684\u5b57\u8282\u6570\u662f size * nmemb\u3002 \u6211\u5c31\u7ecf\u5e38\u628a ptr \u548c file \u987a\u5e8f\u5199\u53cd\uff0c\u8fd9\u4e2a\u83ab\u540d\u5176\u5999\u7684\u53c2\u6570\u987a\u5e8f\u592a\u53cd\u76f4\u89c9\u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u8fd0\u7528\u73b0\u4ee3 C++ \u601d\u60f3\u5c01\u88c5\u4e4b\uff1a using FileHandle = std::shared_ptr; enum class OpenMode { Read, Write, Append, }; inline OpenMode operator|(OpenMode a, OpenMode b) { return OpenMode((int)a | (int)b); } auto modeLut = std::map{ {OpenMode::Read, \"r\"}, {OpenMode::Write, \"w\"}, {OpenMode::Append, \"a\"}, {OpenMode::Read | OpenMode::Write, \"w+\"}, {OpenMode::Read | OpenMode::Append, \"a+\"}, }; FileHandle file_open(std::filesystem::path path, OpenMode mode) { #ifdef _WIN32 return std::shared_ptr(_wfopen(path.wstring().c_str(), modeLut.at(mode).c_str()), fclose); #else return std::shared_ptr(fopen(path.string().c_str(), modeLut.at(mode).c_str()), fclose); #endif } struct [[nodiscard]] FileResult { std::optional numElements; std::errc errorCode; // std::errc \u662f\u4e2a\u5f3a\u7c7b\u578b\u679a\u4e3e\uff0c\u7528\u4e8e\u53d6\u4ee3 C \u8bed\u8a00 errno \u7684 int \u7c7b\u578b bool isEndOfFile; }; template FileResult file_read(FileHandle file, std::span elements) { auto n = fread(elements.data(), sizeof(T), elements.size(), file.get()); return { .numElements = n == 0 ? std::optional(n) : std::nullopt, .errorCode = std::errc(ferror(file.get())), .isEndOfFile = (bool)feof(file.get()), }; } \u662f\u4e0d\u662f\u63a5\u53e3\u66f4\u52a0\u7b80\u5355\u6613\u61c2\uff0c\u6ca1\u6709\u72af\u9519\u7684\u673a\u4f1a\u4e86\uff1f FileHandle file = file_open(\"hello.txt\", OpenMode::Read); int arr[32]; file_read(file, arr).numElements.value(); // \u5982\u679c\u6ca1\u6709\u8bfb\u5230\u4e1c\u897f\uff0c\u8fd9\u91cc\u4f1a\u629b\u51fa\u5f02\u5e38 // \u9000\u51fa\u4f5c\u7528\u57df\u65f6\uff0cshared_ptr \u4f1a\u81ea\u52a8\u4e3a\u4f60\u5173\u95ed\u6587\u4ef6\uff0c\u65e0\u9700\u518d\u63d0\u4f9b file_close \u51fd\u6570","title":"—"},{"location":"type_rich_api/#_64","text":"","title":"—"},{"location":"type_rich_api/#mutex","text":"","title":"Mutex \u5c01\u88c5"},{"location":"type_rich_api/#_65","text":"","title":"—"},{"location":"type_rich_api/#_66","text":"","title":"—"},{"location":"type_rich_api/#cuda","text":"","title":"\u5f69\u86cb\uff1aCUDA \u5c01\u88c5\u5b9e\u6218"},{"location":"type_rich_api/#_67","text":"","title":"—"},{"location":"type_rich_api/#_68","text":"","title":"\u53d8\u91cf\u540d\u4e0e\u4f5c\u7528\u57df\u9650\u5236"},{"location":"type_rich_api/#_69","text":"","title":"—"},{"location":"type_rich_api/#_70","text":"","title":"—"},{"location":"type_rich_api/#getset","text":"","title":"\u4f60\u771f\u7684\u9700\u8981 get/set \u5417\uff1f"},{"location":"type_rich_api/#_71","text":"TODO","title":"—"},{"location":"undef/","text":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f \u9664\u6570\u4e0d\u80fd\u4e3a 0 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 \u603b\u7ed3 CppCon \u76f8\u5173\u89c6\u9891 \u5982\u6709\u758f\u6f0f\uff0c\u53ef\u4ee5\u5728 GitHub \u8865\u5145\u3002 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u53ef\u4ee5\u5e2e\u52a9\u4f60\u76d1\u6d4b\u672a\u5b9a\u4e49\u884c\u4e3a msvc: Debug \u914d\u7f6e gcc: \u5b9a\u4e49 _GLIBCXX_DEBUG \u5b8f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u53ea\u8981\u89e3\u5f15\u7528\u5c31\u9519\u4e86\uff0c\u65e0\u8bba\u662f\u5426\u8bfb\u53d6\u6216\u5199\u5165 int *p = nullptr; *p; // \u9519\uff01 &*p; // \u9519\uff01 *p = 0; // \u9519\uff01 int i = *p; // \u9519\uff01 unique_ptr p = nullptr; p.get(); // \u53ef\u4ee5 &*p; // \u9519\uff01 \u4f8b\u5982\u5728 Debug \u914d\u7f6e\u7684 MSVC STL \u4e2d\uff0c &*p \u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38\uff0c\u800c p.get() \u4e0d\u4f1a\u3002 if (&*p != nullptr) { // \u53ef\u80fd\u88ab\u4f18\u5316\u4e3a if (1)\uff0c\u56e0\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u88ab\u6392\u9664\u4e86 } if (p != nullptr) { // \u4e0d\u4f1a\u88ab\u4f18\u5316\uff0c\u6b63\u5e38\u5224\u65ad } \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 std::vector v = {1, 2, 3, 4}; int *begin = &*v.begin(); int *end = &*v.end(); // \u9519\uff01 std::vector v = {}; int *begin = &*v.begin(); // \u9519! int *end = &*v.end(); // \u9519\uff01 \u5efa\u8bae\u6539\u7528 data \u548c size std::vector v = {1, 2, 3, 4}; int *begin = v.data(); int *end = v.data() + v.size(); this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a struct C { void print() { if (this == nullptr) { // \u6b64\u5206\u652f\u53ef\u80fd\u4f1a\u88ab\u4f18\u5316\u4e3a if (0) { ... } \u4ece\u800c\u6c38\u4e0d\u751f\u6548 std::cout << \"this \u662f\u7a7a\\n\"; } } }; void func() { C *c = nullptr; c->print(); // \u9519\uff01 } \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 struct C{ void f() {} static void f2() {} }; void func(){ C* c = nullptr; c->f(); // \u884c\u4e3a\u672a\u5b9a\u4e49 c->f2(); // \u884c\u4e3a\u672a\u5b9a\u4e49 } \u672c\u8d28\u4e0a\u662f\u56e0\u4e3a \u7a7a\u6307\u9488\u89e3\u5f15\u7528 \u3002\u5bf9\u4e8e\u5185\u5efa\u7c7b\u578b\uff0c\u8868\u8fbe\u5f0f E1->E2 \u4e0e (*E1).E2 \u4e25\u683c\u7b49\u4ef7\uff0c\u4efb\u4f55\u6307\u9488\u7c7b\u578b\u90fd\u662f\u5185\u5efa\u7c7b\u578b\u3002 c->f() \u3001 c->f2() \u7b49\u4ef7\u4e8e\uff1a (*c).f(); (*c).f2(); \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee int i; float f = *(float *)&i; // \u9519\uff01 \u4f8b\u5916\uff1achar\u3001signed char\u3001unsigned char \u548c std::byte \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b int i; char *buf = (char *)&i; // \u53ef\u4ee5 buf[0] = 1; // \u53ef\u4ee5 uint8_t \u662f unsigned char \u7684\u522b\u540d\uff0c\u6240\u4ee5\u4e5f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b \u4f8b\u5916\uff1aint \u548c unsigned int \u4e92\u76f8\u517c\u5bb9 int i; unsigned int f = *(unsigned int *)&i; // \u53ef\u4ee5 \u4f8b\u5916\uff1aconst int * \u548c int * \u4e92\u76f8\u517c\u5bb9\uff08\u4e8c\u7ea7\u6307\u9488\u5f3a\u8f6c\uff09 const int *cp; int *p = *(int **)&cp; // \u53ef\u4ee5 \u6ce8\u610f\uff1a\u53ea\u53d6\u51b3\u4e8e\u8bbf\u95ee\u65f6\u7684\u7c7b\u578b\u662f\u5426\u6b63\u786e\uff0c\u4e2d\u95f4\u53ef\u4ee5\u8f6c\u6362\u4e3a\u522b\u7684\u7c7b\u578b\uff08\u5982 void * \u548c uintptr_t\uff09\uff0c\u53ea\u9700\u6700\u540e\u8bbf\u95ee\u65f6\u8f6c\u6362\u56de\u6b63\u786e\u7684\u6307\u9488\u7c7b\u578b\u5373\u53ef int i; *(int *)(uintptr_t)&i; // \u53ef\u4ee5 *(int *)(void *)&i; // \u53ef\u4ee5 *(int *)(float *)&i; // \u53ef\u4ee5 union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 float bitCast(int i) { union { int i; float f; } u; u.i = i; return u.f; // \u9519\uff01 } \u7279\u4f8b\uff1a\u516c\u5171\u7684\u524d\u7f00\u6210\u5458\u53ef\u4ee5\u5b89\u5168\u5730\u8bbf\u95ee int foo(int i) { union { struct { int tag; int value; } m1; struct { int tag; float value; } m2; } u; u.m1.tag = i; return u.m2.tag; // \u53ef\u4ee5 } \u5982\u9700\u5728 float \u548c int \u4e4b\u95f4\u6309\u4f4d\u8f6c\u6362\uff0c\u5efa\u8bae\u6539\u7528 memcpy\uff0c\u56e0\u4e3a memcpy \u5185\u90e8\u88ab\u8ba4\u4e3a\u662f\u4ee5 char \u6307\u9488\u8bbf\u95ee\u7684\uff0cchar \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b float bitCast(int i) { float f; memcpy(&f, &i, sizeof(i)); return f; } \u6216 C++20 \u7684 std::bit_cast float bitCast(int i) { float f = std::bit_cast(i); return f; } T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) struct alignas(64) C { // \u5047\u8bbe alignof(int) \u662f 4 int i; char c; }; C *p = (C *)malloc(sizeof(C)); // \u9519\uff01malloc \u4ea7\u751f\u7684\u6307\u9488\u53ea\u4fdd\u8bc1\u5bf9\u9f50\u5230 max_align_t\uff08GCC \u4e0a\u662f 16 \u5b57\u8282\uff09\u5927\u5c0f\uff0c\u5e76\u4e0d\u4fdd\u8bc1\u5bf9\u9f50\u5230 C \u6240\u9700\u7684 64 \u5b57\u8282 C *p = new C; // \u53ef\u4ee5\uff0cnew T \u603b\u662f\u4fdd\u8bc1\u5bf9\u9f50\u5230 alignof(T) char buf[sizeof(int)]; int *p = (int *)buf; // \u9519\uff01 alignas(alignof(int)) char buf[sizeof(int)]; int *p = (int *)buf; // \u53ef\u4ee5 char buf[sizeof(int) * 2]; int *p = (int *)(((uintptr_t)buf + sizeof(int) - 1) & ~(alignof(int) - 1)); // \u53ef\u4ee5 \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee struct Base {}; struct Derived : Base {}; Base b; Derived d = *(Derived *)&b; // \u9519\uff01 Derived d = *static_cast(&b); // \u9519\uff01 Derived d = static_cast(b); // \u9519\uff01 Derived obj; Base *bp = &obj; Derived d = *(Derived *)bp; // \u53ef\u4ee5 Derived d = *static_cast(bp); // \u53ef\u4ee5 Derived d = static_cast(*bp); // \u53ef\u4ee5 bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u5e03\u5c14\u7c7b\u578b bool\uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 char c = 0; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = false char c = 1; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = true char c = 2; bool b = *(bool *)&c; // \u672a\u5b9a\u4e49\u884c\u4e3a \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa int i = INT_MAX; i + 1; // \u9519\uff01 \u4f46\u65e0\u7b26\u53f7\u53ef\u4ee5\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u4fdd\u8bc1\uff1a\u6ea2\u51fa\u5fc5\u5b9a\u56de\u73af (wrap-around) unsigned int i = UINT_MAX; i + 1; // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230 0 \u5982\u9700\u5bf9\u6709\u7b26\u53f7\u6574\u6570\u505a\u56de\u73af\uff0c\u53ef\u4ee5\u5148\u8f6c\u6362\u4e3a\u76f8\u5e94\u7684 unsigned \u7c7b\u578b\uff0c\u7b97\u5b8c\u540e\u518d\u8f6c\u56de\u6765 int i = INT_MAX; (int)((unsigned int)i + 1); // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u8d1f\u6570 INT_MIN \u5982\u4e0b\u5199\u6cd5\u66f4\u5177\u6709\u53ef\u79fb\u690d\u6027\uff0c\u56e0\u4e3a\u65e0\u7b26\u53f7\u6570\u5411\u6709\u7b26\u53f7\u6570\u8f6c\u578b\u65f6\u82e5\u8d85\u51fa\u6709\u7b26\u53f7\u6570\u7684\u8868\u793a\u8303\u56f4\u5219\u4e3a\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff08\u7f16\u8bd1\u5668\u5382\u5546\u51b3\u5b9a\u7ed3\u679c\uff0c\u4f46\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff09 std::bit_cast((unsigned int)i + i); \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u8fd0\u7b97\u7ed3\u679c\u7ed3\u679c\u5fc5\u987b\u5728\u8868\u793a\u8303\u56f4\u5185\uff1a\u4f8b\u5982\u5bf9\u4e8e int a \u548c int b\uff0c\u82e5 a/b \u7684\u7ed3\u679c\u4e0d\u53ef\u7528 int \u8868\u793a\uff0c\u90a3\u4e48 a/b \u548c a%b \u5747\u672a\u5b9a\u4e49 INT_MIN % -1; // \u9519\uff01 INT_MIN / -1; // \u9519\uff01 \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f unsigned int i = 0; i << 31; // \u53ef\u4ee5 i << 32; // \u9519\uff01 i << 0; // \u53ef\u4ee5 i << -1; // \u9519\uff01 \u5bf9\u4e8e\u6709\u7b26\u53f7\u6574\u6570\uff0c\u5de6\u79fb\u8fd8\u4e0d\u5f97\u7834\u574f\u7b26\u53f7\u4f4d int i = 0; i << 1; // \u53ef\u4ee5 i << 31; // \u9519\uff01 unsigned int u = 0; u << 31; // \u53ef\u4ee5 \u5982\u9700\u5904\u7406\u6765\u81ea\u7528\u6237\u8f93\u5165\u7684\u4f4d\u79fb\u6570\u91cf\uff0c\u53ef\u4ee5\u5148\u505a\u8303\u56f4\u68c0\u6d4b int shift; cin >> shift; unsigned int u = 0; int i = 0; (shift > 0 && shift < 32) ? (u << shift) : 0; // \u53ef\u4ee5 (shift > 0 && shift < 31) ? (i << shift) : 0; // \u53ef\u4ee5 \u9664\u6570\u4e0d\u80fd\u4e3a 0 int i = 42; int j = 0; i / j; // \u9519\uff01 i % j; // \u9519\uff01 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 int i = 5; int j = (++i) + (++i); // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int a[10] = {}; int j = a[i++] + a[i++]; // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int j = (++i) + i; // j \u7684\u503c\u672a\u5b9a\u4e49 int i1 = 5; int i2 = 5; int j = (++i1) + (++i2); // \u6b63\u786e\uff0cj \u4f1a\u5f97\u5230 12 \u8f6c\u53d1\u7ed9\u4f60\u8eab\u8fb9\u7684\u8c2d\u6d69\u5f3a\u53d7\u5bb3\u8005\u770b\uff08 i+++++i \uff09\u3002 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u5728\u6807\u51c6\u770b\u6765\uff0c+ \u8fd0\u7b97\u7b26\u4e24\u4fa7\u662f\u201c\u540c\u65f6\u201d\u6c42\u503c\u7684\uff0c\u5373\u201cinterleaved\u201d\uff0c\u5b9e\u9645\u6267\u884c\u987a\u5e8f\u5e76\u4e0d\u786e\u5b9a\u3002 \u5bf9\u4e8e a + b\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u5b9a\u603b\u662f\u5de6\u4fa7\u8868\u8fbe\u5f0f a \u5148\u6c42\u503c\u3002 \u4e0d\u8fc7\uff0c\u867d\u7136\u8fd0\u7b97\u7b26\u4e24\u4e2a\u53c2\u6570\u7684\u6c42\u503c\u987a\u5e8f\u201c\u672a\u6307\u5b9a(unspecified)\u201d\uff0c\u4f46\u5e76\u4e0d\u662f\u201c\u672a\u5b9a\u4e49(undefined)\u201d\u3002 \u4f46\u5de6\u53f3\u4e24\u4fa7\u6d89\u53ca\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97\u7b26\u7684\u60c5\u51b5\u4ecd\u7136\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } int j = f1() + f2(); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1\uff0c\u4f46 j \u6700\u7ec8\u7684\u7ed3\u679c\u4e00\u5b9a\u662f 3 \u672a\u6307\u5b9a\u548c\u672a\u5b9a\u4e49\u662f\u4e0d\u540c\u7684\uff01\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u7a0b\u5e8f\u662f\u975e\u6cd5(ill-formed)\u7684\uff0c\u4f46\u672a\u6307\u5b9a\u53ea\u662f\u4f1a\u8ba9\u7ed3\u679c\u65e0\u6cd5\u786e\u5b9a\uff0c\u4f46\u4e00\u5b9a\u80fd\u6b63\u5e38\u8fd0\u884c\uff1a\u8981\u4e48 f1 \u5148\u8fd0\u884c\uff0c\u8981\u4e48 f2 \u5148\u8fd0\u884c\u3002 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { printf(\"%d %d\\n\", i, j); } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2 1 2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 1 2 \u4ee3\u7801\u4e2d\uff0cf1 \u548c f2 \u7684\u6c42\u503c\u987a\u5e8f\u867d\u7136\u672a\u6307\u5b9a\uff0c\u4f46\u53ef\u4ee5\u4fdd\u8bc1 foo \u51fd\u6570\u4f53\u4e00\u5b9a\u5728\u6267\u884c\u5b8c\u6bd5\u540e\u624d\u4f1a\u5f00\u59cb\u3002 \u540c\u4e00\u6761\u8bed\u53e5\u4e2d\u6240\u6709\u5b50\u8868\u8fbe\u5f0f\u7684\u6267\u884c\u987a\u5e8f\u5c31\u50cf\u4e00\u9897\u6811\uff0c\u6811\u4e2d\u4e24\u4e2a\u5b50\u8282\u70b9\u6267\u884c\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684\uff1b\u4f46\u53ef\u4ee5\u80af\u5b9a\u7684\u662f\uff0c\u6811\u7684\u5b50\u8282\u70b9\u4e00\u5b9a\u5148\u4e8e\u4ed6\u4eec\u7684\u7236\u8282\u70b9\u6267\u884c\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u53ea\u662f\u672a\u6307\u5b9a(unspecified)\u884c\u4e3a\u800c\u4e0d\u662f\u672a\u5b9a\u4e49(undefined)\u884c\u4e3a\uff0c\u7ed3\u679c\u5fc5\u7136\u662f f1 f2 \u6216 f2 f1 \u4e24\u79cd\u53ef\u80fd\u4e4b\u4e00\uff0c\u4e0d\u4f1a\u8ba9\u7a0b\u5e8f\u51fa\u73b0\u672a\u5b9a\u4e49\u503c\u7684\u60c5\u51b5\u3002 \u6ce8\u610f\uff0c\u6c42\u503c\u987a\u5e8f\u672a\u6307\u5b9a\u4ec5\u9650\u540c\u4e00\u8bed\u53e5\uff08\u201c\u540c\u4e00\u884c\u201d\uff09\u5185\uff0c\u5bf9\u4e8e\u4e92\u76f8\u72ec\u7acb\u7684\u591a\u6761\u8bed\u53e5\uff0c\u4f9d\u7136\u662f\u6709\u5f3a\u5148\u540e\u987a\u5e8f\u7684\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 f1(); f2(); // \u5fc5\u7136\u6253\u5370 f1 f2 \u4e0d\u8fc7\uff0c\u6d89\u53ca\u81ea\u589e\u7684\u8bdd\uff0c\u5c31\u8fd8\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u800c\u4e0d\u662f\u672a\u6307\u5b9a\u4e86\u3002 int i = 5; foo(i++, i++); // \u4f1a\u6253\u5370\u51fa\u4ec0\u4e48\uff1f\u672a\u5b9a\u4e49\u884c\u4e3a int i = 5; int j = 5; foo(i++, j++); // \u5fc5\u7136\u6253\u5370\u51fa 5 5 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 int func() { int i = 42; // \u9519\uff01\u4f1a\u5bfc\u81f4 func \u8fd4\u56de\u65f6\u7a0b\u5e8f\u5d29\u6e83\uff0c\u4e14\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\uff0c\u4e0d\u62a5\u9519 } int func() { int i = 42; return i; // \u6b63\u786e } void func() { int i = 42; // \u8fd4\u56de void \u7684\u51fd\u6570\uff0creturn \u8bed\u53e5\u53ef\u4ee5\u7701\u7565 } \u5751\u4eba\u4e4b\u5904\u5728\u4e8e\uff0c\u5fd8\u8bb0\u5199\uff0c\u4e0d\u4f1a\u62a5\u9519\uff0c\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\u3002 \u4e3a\u4e86\u907f\u514d\u5fd8\u8bb0\u5199 return \u8bed\u53e5\uff0c\u5efa\u8bae gcc \u7f16\u8bd1\u5668\u5f00\u542f -Werror=return-type \u9009\u9879\uff0c\u5c06\u4e0d\u5199\u8fd4\u56de\u8bed\u53e5\u7684\u8b66\u544a\u8f6c\u5316\u4e3a\u9519\u8bef \u6ce8\u610f\uff0c\u5728\u6709\u5206\u652f\u7684\u975e void \u51fd\u6570\u4e2d\uff0c\u5fc5\u987b\u6240\u6709\u53ef\u8fbe\u5206\u652f\u90fd\u6709 return \u8bed\u53e5 int func(int x) { if (x < 0) return -x; if (x > 0) return x; // \u5982\u679c\u8c03\u7528\u4e86 func(0)\uff0c\u90a3\u4e48\u4f1a\u62b5\u8fbe\u6ca1\u6709 return \u7684\u5206\u652f\uff0c\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a } \u6ca1\u6709 return \u7684\u5206\u652f\u76f8\u5f53\u4e8e\u5199\u4e86\u4e00\u4e2a std::unreachable() \u4f46\u4e5f\u6709\u4f8b\u5916\uff1a \u4e3b\u51fd\u6570 main \u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u81ea\u5e26 return 0; \u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6709 co_return \u6216\u8005\u534f\u7a0b\u8fd4\u56de\u7c7b\u578b\u4e3a void \u4e14\u5177\u6709\u81f3\u5c11\u4e00\u4e2a co_await \u51fa\u73b0 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a typedef void (*func_t)(); func_t func = nullptr; func(); // \u9519\uff01 \u300a\u7ecf\u5178\u518d\u73b0\u300b #include static void func() { printf(\"func called\\n\"); } typedef void (*func_t)(); static func_t fp = nullptr; extern void set_fp() { // \u5bfc\u51fa\u7b26\u53f7\uff0c\u867d\u7136\u6ca1\u4eba\u8c03\u7528\uff0c\u5374\u5f71\u54cd\u4e86 clang \u7684\u4f18\u5316\u51b3\u7b56 fp = func; } int main() { fp(); // Release \u65f6\uff0cclang \u4f1a\u628a\u8fd9\u4e00\u884c\u76f4\u63a5\u4f18\u5316\u6210 func() return 0; } \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d void f1(int *p) { printf(\"f1(%p)\", p); } void (*fp)(const int *); fp = (void (*)(const int *)) f1; // \u9519\u8bef int i; fp = (void (*)(const int *)) &i; // \u9519\u8bef \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c struct Class { void mf() { printf(\"\u6210\u5458\u51fd\u6570\\n\"); } }; union { void (Class::*member_func)(); void (*free_func)(Class *); } u; u.member_func = &Class::mf; Class c; u.free_func(&c); // \u9519\u8bef \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf int i; cout << i; // \u9519\uff01 int i = 0; cout << i; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 int arr[10]; cout << arr[0]; // \u9519\uff01 int arr[10] = {}; cout << arr[0]; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c int arr[10]; int *p = &arr[0]; p + 1; // \u53ef\u4ee5 p + 10; // \u53ef\u4ee5 p + 11; // \u9519\uff01 \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 int arr[10]; int *p = &arr[0]; int *end = p + 10; // \u53ef\u4ee5 *end; // \u9519\uff01 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 int *p; *p; // \u9519\uff01 struct Dog { int age; }; struct Person { Dog *dog; }; Person *p = new Person; cout << p->dog->age; // \u9519\uff01 p->dog = new Dog; cout << p->dog->age; // \u53ef\u4ee5 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 int *p = new int; *p; // \u53ef\u4ee5 delete p; *p; // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); *p; // \u53ef\u4ee5 free(p); *p; // \u9519\uff01 int *func() { int arr[10]; return arr; // \u9519\uff01 } int main() { int *p = func(); p[0]; // \u9519\uff01arr \u5df2\u7ecf\u6790\u6784\uff0c\u4e0d\u80fd\u901a\u8fc7\u7a7a\u60ac\u6307\u9488 / \u7a7a\u60ac\u5f15\u7528\u7ee7\u7eed\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 } \u5efa\u8bae\u6539\u7528\u66f4\u5b89\u5168\u7684 array \u6216 vector \u5bb9\u5668 array func() { array arr; return arr; } int main() { auto arr = func(); arr[0]; // \u53ef\u4ee5\uff0c\u8bbf\u95ee\u5230\u7684\u662f main \u51fd\u6570\u5c40\u90e8\u53d8\u91cf arr\uff0c\u662f\u5bf9 func \u4e2d\u539f arr \u7684\u4e00\u4efd\u62f7\u8d1d } new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d int *p = new int; free(p); // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); free(p); // \u6b63\u786e int *p = new int[3]; delete p; // \u9519\uff01 int *p = new int[3]; delete[] p; // \u6b63\u786e vector a(3); unique_ptr a = make_unique(42); \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 struct C { int i; ~C() { i = 0; } }; C *c = (C *)malloc(sizeof(C)); cout << c->i; // \u53ef\u4ee5 c->~C(); cout << c->i; // \u9519\uff01 free(c); std::string func() { std::string s = \"hello\"; std::string s2 = std::move(s); return s; // \u8bed\u8a00\uff1aOK\uff0c\u6807\u51c6\u5e93\u4f5c\u8005\uff1as \u4e0d\u4e00\u5b9a\u662f\u7a7a\u5b57\u7b26\u4e32 } \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 void func() {} printf(\"*func = %d\\n\", *((int *)func)); // \u9519\u8bef C++ \u5185\u5b58\u6a21\u578b\u662f\u54c8\u4f5b\u67b6\u6784\uff08\u4ee3\u7801\u4e0e\u6570\u636e\u5206\u79bb\uff09\uff0c\u4e0d\u662f\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\uff08\u4ee3\u7801\u4e5f\u662f\u6570\u636e\uff09 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 isdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true isdigit('a'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false isdigit('\\xef'); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u5728 MSVC \u7684 Debug \u6a21\u5f0f\u4e0b\u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38 char s[] = \"\u4f60\u597dA\"; // UTF-8 \u7f16\u7801\u7684\u4e2d\u6587 // \"\u4f60\u597da\"\uff1f std::transform(std::begin(s), std::end(s), std::begin(s), ::tolower); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u56e0\u4e3a UTF-8 \u7f16\u7801\u4f1a\u4ea7\u751f\u5927\u4e8e 128 \u7684\u5b57\u8282 MSVC STL \u4e2d is \u7cfb\u5217\u51fd\u6570\u7684\u65ad\u8a00\uff1a assert(-1 <= c && c < 256); \u7406\u8bba\u4e0a\u53ef\u4ee5\u8fd9\u6837\u65ad\u8a00\uff1a assert(0 <= c && c <= 127); \u89e3\u51b3\u65b9\u6cd5\uff1a\u8981\u4e48\u6539\u7528 iswdigit\uff08MSVC\uff1a0-65536\uff0cGCC\uff1a0-0x010ffff\uff09 iswdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true iswdigit('\\xef'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false iswspace(L'\\ufeff'); // \u53ef\u4ee5\uff0cUTF-8 locale \u65f6\u8fd4\u56de true\uff0cASCII locale \u65f6\u8fd4\u56de false \u8981\u4e48\u81ea\u5df1\u5b9e\u73b0\u5224\u65ad if ('0' <= c && c <= '9') // \u4ee3\u66ff isdigit(c) if (strchr(\" \\n\\t\\r\", c)) // \u4ee3\u66ff isspace(c) memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 void *dst = nullptr; void *src = nullptr; size_t size = 0; memcpy(dst, src, size); // \u9519\uff01\u5373\u4f7f size \u4e3a 0\uff0csrc \u548c dst \u4e5f\u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 \u53ef\u4ee5\u7ed9 size \u52a0\u4e2a\u5224\u65ad void *dst = nullptr; void *src = nullptr; size_t size = 0; if (size != 0) // \u53ef\u4ee5 memcpy(dst, src, size); memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst char arr[10]; memcpy(arr, arr + 1, 9); // \u9519\uff01\u6709\u7684\u540c\u5b66\uff0c\u4ee5\u4e3a\u8fd9\u4e2a\u662f\u5bf9\u7684\uff1f\u9519\u4e86\uff0cmemcpy \u7684 src \u548c dst memcpy(arr + 1, arr, 9); // \u9519\uff01 memcpy(arr + 5, arr, 5); // \u53ef\u4ee5 memcpy(arr, arr + 5, 5); // \u53ef\u4ee5 \u5982\u9700\u62f7\u8d1d\u5e26\u91cd\u590d\u533a\u95f4\u7684\u5185\u5b58\uff0c\u53ef\u4ee5\u7528 memmove char arr[10]; memmove(arr, arr + 1, 9); // \u53ef\u4ee5 memmove(arr + 1, arr, 9); // \u53ef\u4ee5 memmove(arr + 5, arr, 5); // \u53ef\u4ee5 memmove(arr, arr + 5, 5); // \u53ef\u4ee5 \u4ece memcpy \u7684 src \u548c dst \u6307\u9488\u53c2\u6570\u662f restrict \u4fee\u9970\u7684\uff0c\u800c memmove \u6ca1\u6709\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\u6765\uff0cmemcpy \u4e0d\u5141\u8bb8\u4efb\u4f55\u5f62\u5f0f\u7684\u6307\u9488\u91cd\u53e0\uff0c\u65e0\u8bba\u5148\u540e\u987a\u5e8f v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a std::vector v = {}; int i = v.back(); // \u9519\uff01back() \u5e76\u4e0d\u4f1a\u5bf9 v \u662f\u5426\u6709\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u505a\u68c0\u67e5\uff0c\u6b64\u5904\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 int i = v.empty() ? 0 : v.back(); // \u66f4\u5b89\u5168\uff0c\u5f53 v \u4e3a\u7a7a\u65f6\u8fd4\u56de 0 vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a std::vector v = { 1, 2, 3 }; v[3]; // \u9519\uff01\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 \u53ef\u4ee5\u7528 at \u6210\u5458\u51fd\u6570 std::vector v = { 1, 2, 3 }; v.at(3); // \u5b89\u5168\uff0c\u4f1a\u68c0\u6d4b\u5230\u8d8a\u754c\uff0c\u629b\u51fa std::out_of_range \u5f02\u5e38 \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 std::vector v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 v.begin() \u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u8fed\u4ee3\u5668\u4e0d\u5931\u6548\u3002 std::deque v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u53ef\u4ee5 https://www.geeksforgeeks.org/iterator-invalidation-cpp https://en.cppreference.com/w/cpp/container \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 std::vector v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f7f\u5143\u7d20\u5168\u90e8\u79fb\u52a8\u5230\u4e86\u65b0\u7684\u4e00\u6bb5\u5185\u5b58\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 ref \u5f15\u7528\u5931\u6548 ref = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u5f15\u7528\u4e0d\u5931\u6548\u3002 std::deque v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u5143\u7d20\u79fb\u52a8\uff0c\u4f7f\u5f15\u7528\u5931\u6548 ref = 0; // \u53ef\u4ee5 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { cout << s.size(); // \u8bfb\u8bbf\u95ee } std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { s.push_back('b'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } \u66f4\u51c6\u786e\u7684\u8bf4\u6cd5\u662f\uff1a\u591a\u4e2a\u7ebf\u7a0b\uff08\u65e0 happens before \u5173\u7cfb\u5730\uff09\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u5e26\u6709\u526f\u4f5c\u7528\uff08\u5199\u8bbf\u95ee\u6216\u5e26\u6709volatile\u7684\u8bfb\u8bbf\u95ee\uff09\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a // \u516b\u80a1\u6587\u6559\u6750\u5e38\u89c1\u7684\u9519\u8bef\u5199\u6cd5\uff01volatile \u5e76\u4e0d\u4fdd\u8bc1\u539f\u5b50\u6027\u548c\u5185\u5b58\u5e8f\uff0c\u8fd9\u6837\u5199\u662f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u6539\u7528 std::atomic volatile int ready = 0; int data; void t1() { data = 42; ready = 1; } void t2() { while (ready == 0) ; printf(\"%d\\n\", data); } \u5efa\u8bae\u5229\u7528 mutex\uff0ccounting_semaphore\uff0catomic \u7b49\u591a\u7ebf\u7a0b\u540c\u6b65\u5de5\u5177\uff0c\u4fdd\u8bc1\u591a\u4e2a\u7ebf\u7a0b\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\u65f6\uff0c\u987a\u5e8f\u6709\u5148\u6709\u540e\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u53d1\u751f\uff0c\u90a3\u5c31\u662f\u5b89\u5168\u7684 std::string s; std::mutex m; void t1() { std::lock_guard l(m); s.push_back('a'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } void t2() { std::lock_guard l(m); s.push_back('b'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e92\u65a5\u9501\u4fdd\u8bc1\u4e86\u8981\u4e48 t1 happens before t2\uff0c\u8981\u4e48 t2 happens before t1\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::counting_semaphore<1> sem(1); void t1() { s.push_back('a'); sem.release(); // \u4ee4 t2 \u5fc5\u987b\u53d1\u751f\u5728 t1 \u4e4b\u540e } void t2() { sem.acquire(); // t2 \u5fc5\u987b\u7b49\u5f85 t1 release \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4fe1\u53f7\u91cf\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::atomic ready{false}; void t1() { s.push_back('a'); ready.store(true, std::memory_order_release); // \u4ee4 s \u7684\u4fee\u6539\u5bf9\u5176\u4ed6 acquire \u4e86 ready \u7684\u7ebf\u7a0b\u53ef\u89c1 } void t2() { while (!ready.load(std::memory_order_acquire)) // t2 \u5fc5\u987b\u7b49\u5f85 t1 store \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c ; s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u539f\u5b50\u53d8\u91cf\u7684 acquire/release \u5185\u5b58\u5e8f\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); // \u9519\uff01 m2.unlock(); m1.unlock(); } void t2() { m2.lock(); m1.lock(); // \u9519\uff01 m1.unlock(); m2.unlock(); } \u89e3\u51b3\u65b9\u6cd5\uff1a\u4e0d\u8981\u5728\u591a\u4e2a mutex \u4e0a\u540c\u65f6\u4e0a\u9501\uff0c\u5982\u679c\u786e\u5b9e\u8981\u591a\u4e2a mutex\uff0c\u4fdd\u8bc1\u987a\u5e8f\u4e00\u81f4 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } void t2() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } \u6216\u4f7f\u7528 std::lock std::mutex m1, m2; void t1() { std::lock(m1, m2); std::unlock(m1, m2); } void t2() { std::lock(m2, m1); std::unlock(m2, m1); } \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 std::mutex m; void t1() { m.lock(); m.lock(); // \u9519\uff01 m.try_lock(); // \u9519\uff01try_lock \u4e5f\u4e0d\u5141\u8bb8\uff01 m.unlock(); m.unlock(); } void t2() { m.try_lock(); // \u53ef\u4ee5 } \u89e3\u51b3\u65b9\u6cd5\uff1a\u6539\u7528 recursive_mutex\uff0c\u6216\u4f7f\u7528\u9002\u5f53\u7684\u6761\u4ef6\u53d8\u91cf std::recursive_mutex m; void t1() { m.lock(); m.lock(); // \u53ef\u4ee5 m.try_lock(); // \u53ef\u4ee5\uff0c\u8fd4\u56de true m.unlock(); m.unlock(); m.unlock(); } \u603b\u7ed3 \u4e0d\u8981\u73a9\u7a7a\u6307\u9488 \u4e0d\u8981\u8d8a\u754c\uff0c\u7528\u66f4\u5b89\u5168\u7684 at\uff0csubspan \u7b49 \u4e0d\u8981\u4e0d\u521d\u59cb\u5316\u53d8\u91cf\uff08auto-idiom\uff09 \u5f00\u542f -Werror=return-type \u4e0d\u8981\u91cd\u590d\u4e0a\u9501 mutex \u4ed4\u7ec6\u770b\u5e93\u51fd\u6570\u7684\u6587\u6863 \u7528\u667a\u80fd\u6307\u9488\u7ba1\u7406\u5355\u4e2a\u5bf9\u8c61 \u7528 vector \u7ba1\u7406\u591a\u4e2a\u5bf9\u8c61\u7ec4\u6210\u7684\u8fde\u7eed\u5185\u5b58 \u907f\u514d\u7a7a\u60ac\u5f15\u7528 \u5f00 Debug \u6a21\u5f0f\u7684 STL \u6307\u5b9a CMake \u7684\u6a21\u5f0f\uff1a cmake -B build -DCMAKE_BUILD_TYPE=Debug Debug: -O0 -g \u7f16\u8bd1\u9009\u9879 Release: -O3 -DNDEBUG \u7f16\u8bd1\u9009\u9879 \u6307\u5b9a MSVC \u7684\u6a21\u5f0f\uff1a cmake --build build --config Debug Debug: \u751f\u6210 zenod.dll \uff0c\u94fe\u63a5 Debug \u7684 ABI Release: \u751f\u6210 zeno.dll \uff0c\u94fe\u63a5 Release \u7684 ABI CppCon \u76f8\u5173\u89c6\u9891 \u987a\u4fbf\u63a8\u4e2a CppCon \u5c0f\u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=ehyHyAIa5so \u6807\u9898\u662f\u300aCppCon 2017: Piotr Padlewski \u201cUndefined Behaviour is awesome!\u201d\u300b\uff08\u7206\u5b5d\uff09","title":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868"},{"location":"undef/#_1","text":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868 \u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f \u7a7a\u6307\u9488\u7c7b \u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09 \u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668 this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a \u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570 \u6307\u9488\u522b\u540d\u7c7b reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458 T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T) \u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c \u7b97\u6570\u7c7b \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa \u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f \u9664\u6570\u4e0d\u80fd\u4e3a 0 \u6c42\u503c\u987a\u5e8f\u7c7b \u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97 \u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684 \u51fd\u6570\u7c7b \u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5 \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a \u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d \u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c \u751f\u547d\u5468\u671f\u7c7b \u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf \u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c \u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528 \u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488 \u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58 new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d \u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 \u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528 \u5e93\u51fd\u6570\u7c7b ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09 memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a \u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548 \u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548 \u591a\u7ebf\u7a0b\u7c7b \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09 \u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09 \u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09 \u603b\u7ed3 CppCon \u76f8\u5173\u89c6\u9891 \u5982\u6709\u758f\u6f0f\uff0c\u53ef\u4ee5\u5728 GitHub \u8865\u5145\u3002","title":"\u672a\u5b9a\u4e49\u884c\u4e3a\u5b8c\u6574\u5217\u8868"},{"location":"undef/#_2","text":"\u53ef\u4ee5\u5e2e\u52a9\u4f60\u76d1\u6d4b\u672a\u5b9a\u4e49\u884c\u4e3a msvc: Debug \u914d\u7f6e gcc: \u5b9a\u4e49 _GLIBCXX_DEBUG \u5b8f","title":"\u5efa\u8bae\u5f00\u542f\u6807\u51c6\u5e93\u7684\u8c03\u8bd5\u6a21\u5f0f"},{"location":"undef/#_3","text":"","title":"\u7a7a\u6307\u9488\u7c7b"},{"location":"undef/#_4","text":"\u53ea\u8981\u89e3\u5f15\u7528\u5c31\u9519\u4e86\uff0c\u65e0\u8bba\u662f\u5426\u8bfb\u53d6\u6216\u5199\u5165 int *p = nullptr; *p; // \u9519\uff01 &*p; // \u9519\uff01 *p = 0; // \u9519\uff01 int i = *p; // \u9519\uff01 unique_ptr p = nullptr; p.get(); // \u53ef\u4ee5 &*p; // \u9519\uff01 \u4f8b\u5982\u5728 Debug \u914d\u7f6e\u7684 MSVC STL \u4e2d\uff0c &*p \u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38\uff0c\u800c p.get() \u4e0d\u4f1a\u3002 if (&*p != nullptr) { // \u53ef\u80fd\u88ab\u4f18\u5316\u4e3a if (1)\uff0c\u56e0\u4e3a\u672a\u5b9a\u4e49\u884c\u4e3a\u88ab\u6392\u9664\u4e86 } if (p != nullptr) { // \u4e0d\u4f1a\u88ab\u4f18\u5316\uff0c\u6b63\u5e38\u5224\u65ad }","title":"\u4e0d\u80fd\u89e3\u5f15\u7528\u7a7a\u6307\u9488\uff08\u901a\u5e38\u4f1a\u4ea7\u751f\u5d29\u6e83\uff0c\u4f46\u4e5f\u53ef\u80fd\u88ab\u4f18\u5316\u4ea7\u751f\u5947\u602a\u7684\u73b0\u8c61\uff09"},{"location":"undef/#end","text":"std::vector v = {1, 2, 3, 4}; int *begin = &*v.begin(); int *end = &*v.end(); // \u9519\uff01 std::vector v = {}; int *begin = &*v.begin(); // \u9519! int *end = &*v.end(); // \u9519\uff01 \u5efa\u8bae\u6539\u7528 data \u548c size std::vector v = {1, 2, 3, 4}; int *begin = v.data(); int *end = v.data() + v.size();","title":"\u4e0d\u80fd\u89e3\u5f15\u7528 end \u8fed\u4ee3\u5668"},{"location":"undef/#this","text":"struct C { void print() { if (this == nullptr) { // \u6b64\u5206\u652f\u53ef\u80fd\u4f1a\u88ab\u4f18\u5316\u4e3a if (0) { ... } \u4ece\u800c\u6c38\u4e0d\u751f\u6548 std::cout << \"this \u662f\u7a7a\\n\"; } } }; void func() { C *c = nullptr; c->print(); // \u9519\uff01 }","title":"this \u6307\u9488\u4e0d\u80fd\u4e3a\u7a7a"},{"location":"undef/#_5","text":"struct C{ void f() {} static void f2() {} }; void func(){ C* c = nullptr; c->f(); // \u884c\u4e3a\u672a\u5b9a\u4e49 c->f2(); // \u884c\u4e3a\u672a\u5b9a\u4e49 } \u672c\u8d28\u4e0a\u662f\u56e0\u4e3a \u7a7a\u6307\u9488\u89e3\u5f15\u7528 \u3002\u5bf9\u4e8e\u5185\u5efa\u7c7b\u578b\uff0c\u8868\u8fbe\u5f0f E1->E2 \u4e0e (*E1).E2 \u4e25\u683c\u7b49\u4ef7\uff0c\u4efb\u4f55\u6307\u9488\u7c7b\u578b\u90fd\u662f\u5185\u5efa\u7c7b\u578b\u3002 c->f() \u3001 c->f2() \u7b49\u4ef7\u4e8e\uff1a (*c).f(); (*c).f2();","title":"\u7a7a\u6307\u9488\u4e0d\u80fd\u8c03\u7528\u6210\u5458\u51fd\u6570"},{"location":"undef/#_6","text":"","title":"\u6307\u9488\u522b\u540d\u7c7b"},{"location":"undef/#reinterpret_cast","text":"int i; float f = *(float *)&i; // \u9519\uff01 \u4f8b\u5916\uff1achar\u3001signed char\u3001unsigned char \u548c std::byte \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b int i; char *buf = (char *)&i; // \u53ef\u4ee5 buf[0] = 1; // \u53ef\u4ee5 uint8_t \u662f unsigned char \u7684\u522b\u540d\uff0c\u6240\u4ee5\u4e5f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b \u4f8b\u5916\uff1aint \u548c unsigned int \u4e92\u76f8\u517c\u5bb9 int i; unsigned int f = *(unsigned int *)&i; // \u53ef\u4ee5 \u4f8b\u5916\uff1aconst int * \u548c int * \u4e92\u76f8\u517c\u5bb9\uff08\u4e8c\u7ea7\u6307\u9488\u5f3a\u8f6c\uff09 const int *cp; int *p = *(int **)&cp; // \u53ef\u4ee5 \u6ce8\u610f\uff1a\u53ea\u53d6\u51b3\u4e8e\u8bbf\u95ee\u65f6\u7684\u7c7b\u578b\u662f\u5426\u6b63\u786e\uff0c\u4e2d\u95f4\u53ef\u4ee5\u8f6c\u6362\u4e3a\u522b\u7684\u7c7b\u578b\uff08\u5982 void * \u548c uintptr_t\uff09\uff0c\u53ea\u9700\u6700\u540e\u8bbf\u95ee\u65f6\u8f6c\u6362\u56de\u6b63\u786e\u7684\u6307\u9488\u7c7b\u578b\u5373\u53ef int i; *(int *)(uintptr_t)&i; // \u53ef\u4ee5 *(int *)(void *)&i; // \u53ef\u4ee5 *(int *)(float *)&i; // \u53ef\u4ee5","title":"reinterpret_cast \u540e\u4ee5\u4e0d\u517c\u5bb9\u7684\u7c7b\u578b\u8bbf\u95ee"},{"location":"undef/#union","text":"float bitCast(int i) { union { int i; float f; } u; u.i = i; return u.f; // \u9519\uff01 } \u7279\u4f8b\uff1a\u516c\u5171\u7684\u524d\u7f00\u6210\u5458\u53ef\u4ee5\u5b89\u5168\u5730\u8bbf\u95ee int foo(int i) { union { struct { int tag; int value; } m1; struct { int tag; float value; } m2; } u; u.m1.tag = i; return u.m2.tag; // \u53ef\u4ee5 } \u5982\u9700\u5728 float \u548c int \u4e4b\u95f4\u6309\u4f4d\u8f6c\u6362\uff0c\u5efa\u8bae\u6539\u7528 memcpy\uff0c\u56e0\u4e3a memcpy \u5185\u90e8\u88ab\u8ba4\u4e3a\u662f\u4ee5 char \u6307\u9488\u8bbf\u95ee\u7684\uff0cchar \u603b\u662f\u517c\u5bb9\u4efb\u4f55\u7c7b\u578b float bitCast(int i) { float f; memcpy(&f, &i, sizeof(i)); return f; } \u6216 C++20 \u7684 std::bit_cast float bitCast(int i) { float f = std::bit_cast(i); return f; }","title":"union \u8bbf\u95ee\u4e0d\u662f\u6fc0\u6d3b\u7684\u6210\u5458"},{"location":"undef/#t-alignoft","text":"struct alignas(64) C { // \u5047\u8bbe alignof(int) \u662f 4 int i; char c; }; C *p = (C *)malloc(sizeof(C)); // \u9519\uff01malloc \u4ea7\u751f\u7684\u6307\u9488\u53ea\u4fdd\u8bc1\u5bf9\u9f50\u5230 max_align_t\uff08GCC \u4e0a\u662f 16 \u5b57\u8282\uff09\u5927\u5c0f\uff0c\u5e76\u4e0d\u4fdd\u8bc1\u5bf9\u9f50\u5230 C \u6240\u9700\u7684 64 \u5b57\u8282 C *p = new C; // \u53ef\u4ee5\uff0cnew T \u603b\u662f\u4fdd\u8bc1\u5bf9\u9f50\u5230 alignof(T) char buf[sizeof(int)]; int *p = (int *)buf; // \u9519\uff01 alignas(alignof(int)) char buf[sizeof(int)]; int *p = (int *)buf; // \u53ef\u4ee5 char buf[sizeof(int) * 2]; int *p = (int *)(((uintptr_t)buf + sizeof(int) - 1) & ~(alignof(int) - 1)); // \u53ef\u4ee5","title":"T \u7c7b\u578b\u6307\u9488\u5fc5\u987b\u5bf9\u9f50\u5230 alignof(T)"},{"location":"undef/#static_cast","text":"struct Base {}; struct Derived : Base {}; Base b; Derived d = *(Derived *)&b; // \u9519\uff01 Derived d = *static_cast(&b); // \u9519\uff01 Derived d = static_cast(b); // \u9519\uff01 Derived obj; Base *bp = &obj; Derived d = *(Derived *)bp; // \u53ef\u4ee5 Derived d = *static_cast(bp); // \u53ef\u4ee5 Derived d = static_cast(*bp); // \u53ef\u4ee5","title":"\u4ece\u7236\u7c7b static_cast \u5230\u4e0d\u7b26\u5408\u7684\u5b50\u7c7b\u540e\u8bbf\u95ee"},{"location":"undef/#bool-0-1","text":"\u5e03\u5c14\u7c7b\u578b bool\uff0c\u53ea\u6709 true \u548c false \u4e24\u79cd\u53d6\u503c\u3002 bool \u867d\u7136\u5360\u636e 1 \u5b57\u8282\uff088 \u4f4d\uff09\u5185\u5b58\u7a7a\u95f4\uff0c\u4f46\u5176\u4e2d\u53ea\u6709\u4e00\u4e2a\u6709\u6548\u4f4d\uff0c\u4e5f\u5c31\u662f\u6700\u4f4e\u4f4d\u3002 \u53ea\u6709\u8fd9\u4e2a\u6700\u4f4e\u4f4d\u53ef\u4ee5\u662f 0 \u6216 1\uff0c\u5176\u4f59 7 \u4f4d\u5fc5\u987b\u59cb\u7ec8\u4fdd\u6301\u4e3a 0\u3002 \u5982\u679c\u5176\u4f59\u4f4d\u4e2d\u51fa\u73b0\u4e86\u975e 0 \u7684\u4f4d\uff0c\u4e5f\u5c31\u662f\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u53d6\u503c\uff0c\u5219\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 char c = 0; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = false char c = 1; bool b = *(bool *)&c; // \u53ef\u4ee5\uff0cb = true char c = 2; bool b = *(bool *)&c; // \u672a\u5b9a\u4e49\u884c\u4e3a","title":"bool \u7c7b\u578b\u4e0d\u5f97\u51fa\u73b0 0 \u548c 1 \u4ee5\u5916\u7684\u503c"},{"location":"undef/#_7","text":"","title":"\u7b97\u6570\u7c7b"},{"location":"undef/#_8","text":"int i = INT_MAX; i + 1; // \u9519\uff01 \u4f46\u65e0\u7b26\u53f7\u53ef\u4ee5\uff0c\u65e0\u7b26\u53f7\u6574\u6570\u4fdd\u8bc1\uff1a\u6ea2\u51fa\u5fc5\u5b9a\u56de\u73af (wrap-around) unsigned int i = UINT_MAX; i + 1; // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230 0 \u5982\u9700\u5bf9\u6709\u7b26\u53f7\u6574\u6570\u505a\u56de\u73af\uff0c\u53ef\u4ee5\u5148\u8f6c\u6362\u4e3a\u76f8\u5e94\u7684 unsigned \u7c7b\u578b\uff0c\u7b97\u5b8c\u540e\u518d\u8f6c\u56de\u6765 int i = INT_MAX; (int)((unsigned int)i + 1); // \u53ef\u4ee5\uff0c\u4f1a\u5f97\u5230\u4e00\u4e2a\u8d1f\u6570 INT_MIN \u5982\u4e0b\u5199\u6cd5\u66f4\u5177\u6709\u53ef\u79fb\u690d\u6027\uff0c\u56e0\u4e3a\u65e0\u7b26\u53f7\u6570\u5411\u6709\u7b26\u53f7\u6570\u8f6c\u578b\u65f6\u82e5\u8d85\u51fa\u6709\u7b26\u53f7\u6570\u7684\u8868\u793a\u8303\u56f4\u5219\u4e3a\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff08\u7f16\u8bd1\u5668\u5382\u5546\u51b3\u5b9a\u7ed3\u679c\uff0c\u4f46\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff09 std::bit_cast((unsigned int)i + i); \u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u8fd0\u7b97\u7ed3\u679c\u7ed3\u679c\u5fc5\u987b\u5728\u8868\u793a\u8303\u56f4\u5185\uff1a\u4f8b\u5982\u5bf9\u4e8e int a \u548c int b\uff0c\u82e5 a/b \u7684\u7ed3\u679c\u4e0d\u53ef\u7528 int \u8868\u793a\uff0c\u90a3\u4e48 a/b \u548c a%b \u5747\u672a\u5b9a\u4e49 INT_MIN % -1; // \u9519\uff01 INT_MIN / -1; // \u9519\uff01","title":"\u6709\u7b26\u53f7\u6574\u6570\u7684\u52a0\u51cf\u4e58\u9664\u6a21\u4e0d\u80fd\u6ea2\u51fa"},{"location":"undef/#_9","text":"unsigned int i = 0; i << 31; // \u53ef\u4ee5 i << 32; // \u9519\uff01 i << 0; // \u53ef\u4ee5 i << -1; // \u9519\uff01 \u5bf9\u4e8e\u6709\u7b26\u53f7\u6574\u6570\uff0c\u5de6\u79fb\u8fd8\u4e0d\u5f97\u7834\u574f\u7b26\u53f7\u4f4d int i = 0; i << 1; // \u53ef\u4ee5 i << 31; // \u9519\uff01 unsigned int u = 0; u << 31; // \u53ef\u4ee5 \u5982\u9700\u5904\u7406\u6765\u81ea\u7528\u6237\u8f93\u5165\u7684\u4f4d\u79fb\u6570\u91cf\uff0c\u53ef\u4ee5\u5148\u505a\u8303\u56f4\u68c0\u6d4b int shift; cin >> shift; unsigned int u = 0; int i = 0; (shift > 0 && shift < 32) ? (u << shift) : 0; // \u53ef\u4ee5 (shift > 0 && shift < 31) ? (i << shift) : 0; // \u53ef\u4ee5","title":"\u5de6\u79fb\u6216\u53f3\u79fb\u7684\u4f4d\u6570\uff0c\u4e0d\u5f97\u8d85\u8fc7\u6574\u6570\u7c7b\u578b\u4e0a\u9650\uff0c\u4e0d\u5f97\u4e3a\u8d1f"},{"location":"undef/#0","text":"int i = 42; int j = 0; i / j; // \u9519\uff01 i % j; // \u9519\uff01","title":"\u9664\u6570\u4e0d\u80fd\u4e3a 0"},{"location":"undef/#_10","text":"","title":"\u6c42\u503c\u987a\u5e8f\u7c7b"},{"location":"undef/#_11","text":"int i = 5; int j = (++i) + (++i); // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int a[10] = {}; int j = a[i++] + a[i++]; // j \u7684\u503c\u672a\u5b9a\u4e49 int i = 5; int j = (++i) + i; // j \u7684\u503c\u672a\u5b9a\u4e49 int i1 = 5; int i2 = 5; int j = (++i1) + (++i2); // \u6b63\u786e\uff0cj \u4f1a\u5f97\u5230 12 \u8f6c\u53d1\u7ed9\u4f60\u8eab\u8fb9\u7684\u8c2d\u6d69\u5f3a\u53d7\u5bb3\u8005\u770b\uff08 i+++++i \uff09\u3002","title":"\u540c\u4e00\u8868\u8fbe\u5f0f\u5185\uff0c\u5bf9\u540c\u4e00\u4e2a\u53d8\u91cf\u6709\u591a\u4e2a\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97"},{"location":"undef/#_12","text":"\u5728\u6807\u51c6\u770b\u6765\uff0c+ \u8fd0\u7b97\u7b26\u4e24\u4fa7\u662f\u201c\u540c\u65f6\u201d\u6c42\u503c\u7684\uff0c\u5373\u201cinterleaved\u201d\uff0c\u5b9e\u9645\u6267\u884c\u987a\u5e8f\u5e76\u4e0d\u786e\u5b9a\u3002 \u5bf9\u4e8e a + b\uff0c\u6211\u4eec\u4e0d\u80fd\u5047\u5b9a\u603b\u662f\u5de6\u4fa7\u8868\u8fbe\u5f0f a \u5148\u6c42\u503c\u3002 \u4e0d\u8fc7\uff0c\u867d\u7136\u8fd0\u7b97\u7b26\u4e24\u4e2a\u53c2\u6570\u7684\u6c42\u503c\u987a\u5e8f\u201c\u672a\u6307\u5b9a(unspecified)\u201d\uff0c\u4f46\u5e76\u4e0d\u662f\u201c\u672a\u5b9a\u4e49(undefined)\u201d\u3002 \u4f46\u5de6\u53f3\u4e24\u4fa7\u6d89\u53ca\u81ea\u589e/\u81ea\u51cf\u8fd0\u7b97\u7b26\u7684\u60c5\u51b5\u4ecd\u7136\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } int j = f1() + f2(); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1\uff0c\u4f46 j \u6700\u7ec8\u7684\u7ed3\u679c\u4e00\u5b9a\u662f 3 \u672a\u6307\u5b9a\u548c\u672a\u5b9a\u4e49\u662f\u4e0d\u540c\u7684\uff01\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u7a0b\u5e8f\u662f\u975e\u6cd5(ill-formed)\u7684\uff0c\u4f46\u672a\u6307\u5b9a\u53ea\u662f\u4f1a\u8ba9\u7ed3\u679c\u65e0\u6cd5\u786e\u5b9a\uff0c\u4f46\u4e00\u5b9a\u80fd\u6b63\u5e38\u8fd0\u884c\uff1a\u8981\u4e48 f1 \u5148\u8fd0\u884c\uff0c\u8981\u4e48 f2 \u5148\u8fd0\u884c\u3002","title":"\u5185\u5efa\u7c7b\u578b\u7684\u4e8c\u5143\u8fd0\u7b97\u7b26\uff0c\u5176\u5de6\u53f3\u4e24\u4e2a\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684"},{"location":"undef/#_13","text":"int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { printf(\"%d %d\\n\", i, j); } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2 1 2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 1 2 \u4ee3\u7801\u4e2d\uff0cf1 \u548c f2 \u7684\u6c42\u503c\u987a\u5e8f\u867d\u7136\u672a\u6307\u5b9a\uff0c\u4f46\u53ef\u4ee5\u4fdd\u8bc1 foo \u51fd\u6570\u4f53\u4e00\u5b9a\u5728\u6267\u884c\u5b8c\u6bd5\u540e\u624d\u4f1a\u5f00\u59cb\u3002 \u540c\u4e00\u6761\u8bed\u53e5\u4e2d\u6240\u6709\u5b50\u8868\u8fbe\u5f0f\u7684\u6267\u884c\u987a\u5e8f\u5c31\u50cf\u4e00\u9897\u6811\uff0c\u6811\u4e2d\u4e24\u4e2a\u5b50\u8282\u70b9\u6267\u884c\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684\uff1b\u4f46\u53ef\u4ee5\u80af\u5b9a\u7684\u662f\uff0c\u6811\u7684\u5b50\u8282\u70b9\u4e00\u5b9a\u5148\u4e8e\u4ed6\u4eec\u7684\u7236\u8282\u70b9\u6267\u884c\u3002 \u540c\u6837\u5730\uff0c\u8fd9\u53ea\u662f\u672a\u6307\u5b9a(unspecified)\u884c\u4e3a\u800c\u4e0d\u662f\u672a\u5b9a\u4e49(undefined)\u884c\u4e3a\uff0c\u7ed3\u679c\u5fc5\u7136\u662f f1 f2 \u6216 f2 f1 \u4e24\u79cd\u53ef\u80fd\u4e4b\u4e00\uff0c\u4e0d\u4f1a\u8ba9\u7a0b\u5e8f\u51fa\u73b0\u672a\u5b9a\u4e49\u503c\u7684\u60c5\u51b5\u3002 \u6ce8\u610f\uff0c\u6c42\u503c\u987a\u5e8f\u672a\u6307\u5b9a\u4ec5\u9650\u540c\u4e00\u8bed\u53e5\uff08\u201c\u540c\u4e00\u884c\u201d\uff09\u5185\uff0c\u5bf9\u4e8e\u4e92\u76f8\u72ec\u7acb\u7684\u591a\u6761\u8bed\u53e5\uff0c\u4f9d\u7136\u662f\u6709\u5f3a\u5148\u540e\u987a\u5e8f\u7684\u3002 int f1() { printf(\"f1\\n\"); return 1; } int f2() { printf(\"f2\\n\"); return 2; } void foo(int i, int j) { } foo(f1(), f2()); // \u53ef\u80fd\u6253\u5370 f1 f2\uff0c\u4e5f\u53ef\u80fd\u6253\u5370 f2 f1 f1(); f2(); // \u5fc5\u7136\u6253\u5370 f1 f2 \u4e0d\u8fc7\uff0c\u6d89\u53ca\u81ea\u589e\u7684\u8bdd\uff0c\u5c31\u8fd8\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u800c\u4e0d\u662f\u672a\u6307\u5b9a\u4e86\u3002 int i = 5; foo(i++, i++); // \u4f1a\u6253\u5370\u51fa\u4ec0\u4e48\uff1f\u672a\u5b9a\u4e49\u884c\u4e3a int i = 5; int j = 5; foo(i++, j++); // \u5fc5\u7136\u6253\u5370\u51fa 5 5","title":"\u51fd\u6570\u53c2\u6570\u6c42\u503c\u7684\u987a\u5e8f\u662f\u4e0d\u786e\u5b9a\u7684"},{"location":"undef/#_14","text":"","title":"\u51fd\u6570\u7c7b"},{"location":"undef/#void-return","text":"int func() { int i = 42; // \u9519\uff01\u4f1a\u5bfc\u81f4 func \u8fd4\u56de\u65f6\u7a0b\u5e8f\u5d29\u6e83\uff0c\u4e14\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\uff0c\u4e0d\u62a5\u9519 } int func() { int i = 42; return i; // \u6b63\u786e } void func() { int i = 42; // \u8fd4\u56de void \u7684\u51fd\u6570\uff0creturn \u8bed\u53e5\u53ef\u4ee5\u7701\u7565 } \u5751\u4eba\u4e4b\u5904\u5728\u4e8e\uff0c\u5fd8\u8bb0\u5199\uff0c\u4e0d\u4f1a\u62a5\u9519\uff0c\u7f16\u8bd1\u5668\u53ea\u662f\u8b66\u544a\u3002 \u4e3a\u4e86\u907f\u514d\u5fd8\u8bb0\u5199 return \u8bed\u53e5\uff0c\u5efa\u8bae gcc \u7f16\u8bd1\u5668\u5f00\u542f -Werror=return-type \u9009\u9879\uff0c\u5c06\u4e0d\u5199\u8fd4\u56de\u8bed\u53e5\u7684\u8b66\u544a\u8f6c\u5316\u4e3a\u9519\u8bef \u6ce8\u610f\uff0c\u5728\u6709\u5206\u652f\u7684\u975e void \u51fd\u6570\u4e2d\uff0c\u5fc5\u987b\u6240\u6709\u53ef\u8fbe\u5206\u652f\u90fd\u6709 return \u8bed\u53e5 int func(int x) { if (x < 0) return -x; if (x > 0) return x; // \u5982\u679c\u8c03\u7528\u4e86 func(0)\uff0c\u90a3\u4e48\u4f1a\u62b5\u8fbe\u6ca1\u6709 return \u7684\u5206\u652f\uff0c\u89e6\u53d1\u672a\u5b9a\u4e49\u884c\u4e3a } \u6ca1\u6709 return \u7684\u5206\u652f\u76f8\u5f53\u4e8e\u5199\u4e86\u4e00\u4e2a std::unreachable() \u4f46\u4e5f\u6709\u4f8b\u5916\uff1a \u4e3b\u51fd\u6570 main \u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u9ed8\u8ba4\u81ea\u5e26 return 0; \u534f\u7a0b\u51fd\u6570\u53ef\u4ee5\u4e0d\u5199 return \u8bed\u53e5\uff0c\u5982\u679c\u6709 co_return \u6216\u8005\u534f\u7a0b\u8fd4\u56de\u7c7b\u578b\u4e3a void \u4e14\u5177\u6709\u81f3\u5c11\u4e00\u4e2a co_await \u51fa\u73b0","title":"\u8fd4\u56de\u7c7b\u578b\u4e0d\u4e3a void \u7684\u51fd\u6570\uff0c\u5fc5\u987b\u6709 return \u8bed\u53e5"},{"location":"undef/#_15","text":"typedef void (*func_t)(); func_t func = nullptr; func(); // \u9519\uff01 \u300a\u7ecf\u5178\u518d\u73b0\u300b #include static void func() { printf(\"func called\\n\"); } typedef void (*func_t)(); static func_t fp = nullptr; extern void set_fp() { // \u5bfc\u51fa\u7b26\u53f7\uff0c\u867d\u7136\u6ca1\u4eba\u8c03\u7528\uff0c\u5374\u5f71\u54cd\u4e86 clang \u7684\u4f18\u5316\u51b3\u7b56 fp = func; } int main() { fp(); // Release \u65f6\uff0cclang \u4f1a\u628a\u8fd9\u4e00\u884c\u76f4\u63a5\u4f18\u5316\u6210 func() return 0; }","title":"\u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u4e0d\u80fd\u4e3a\u7a7a"},{"location":"undef/#_16","text":"void f1(int *p) { printf(\"f1(%p)\", p); } void (*fp)(const int *); fp = (void (*)(const int *)) f1; // \u9519\u8bef int i; fp = (void (*)(const int *)) &i; // \u9519\u8bef","title":"\u51fd\u6570\u6307\u9488\u88ab\u8c03\u7528\u65f6\uff0c\u53c2\u6570\u5217\u8868\u6216\u8fd4\u56de\u503c\u5fc5\u987b\u5339\u914d"},{"location":"undef/#_17","text":"struct Class { void mf() { printf(\"\u6210\u5458\u51fd\u6570\\n\"); } }; union { void (Class::*member_func)(); void (*free_func)(Class *); } u; u.member_func = &Class::mf; Class c; u.free_func(&c); // \u9519\u8bef","title":"\u666e\u901a\u51fd\u6570\u6307\u9488\u4e0e\u6210\u5458\u51fd\u6570\u6307\u9488\u4e0d\u80fd\u4e92\u8f6c"},{"location":"undef/#_18","text":"","title":"\u751f\u547d\u5468\u671f\u7c7b"},{"location":"undef/#_19","text":"int i; cout << i; // \u9519\uff01 int i = 0; cout << i; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0 int arr[10]; cout << arr[0]; // \u9519\uff01 int arr[10] = {}; cout << arr[0]; // \u53ef\u4ee5\uff0c\u4f1a\u8bfb\u5230 0","title":"\u4e0d\u80fd\u8bfb\u53d6\u672a\u521d\u59cb\u5316\u7684\u53d8\u91cf"},{"location":"undef/#_20","text":"int arr[10]; int *p = &arr[0]; p + 1; // \u53ef\u4ee5 p + 10; // \u53ef\u4ee5 p + 11; // \u9519\uff01","title":"\u6307\u9488\u7684\u52a0\u51cf\u6cd5\u4e0d\u80fd\u8d85\u8d8a\u6570\u7ec4\u8fb9\u754c"},{"location":"undef/#end_1","text":"int arr[10]; int *p = &arr[0]; int *end = p + 10; // \u53ef\u4ee5 *end; // \u9519\uff01","title":"\u53ef\u4ee5\u6709\u6307\u5411\u6570\u7ec4\u5c3e\u90e8\u7684\u6307\u9488\uff08\u7c7b\u4f3c end \u8fed\u4ee3\u5668\uff09\uff0c\u4f46\u4e0d\u80fd\u89e3\u5f15\u7528"},{"location":"undef/#_21","text":"int *p; *p; // \u9519\uff01 struct Dog { int age; }; struct Person { Dog *dog; }; Person *p = new Person; cout << p->dog->age; // \u9519\uff01 p->dog = new Dog; cout << p->dog->age; // \u53ef\u4ee5","title":"\u4e0d\u80fd\u8bbf\u95ee\u672a\u521d\u59cb\u5316\u7684\u6307\u9488"},{"location":"undef/#_22","text":"int *p = new int; *p; // \u53ef\u4ee5 delete p; *p; // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); *p; // \u53ef\u4ee5 free(p); *p; // \u9519\uff01 int *func() { int arr[10]; return arr; // \u9519\uff01 } int main() { int *p = func(); p[0]; // \u9519\uff01arr \u5df2\u7ecf\u6790\u6784\uff0c\u4e0d\u80fd\u901a\u8fc7\u7a7a\u60ac\u6307\u9488 / \u7a7a\u60ac\u5f15\u7528\u7ee7\u7eed\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61 } \u5efa\u8bae\u6539\u7528\u66f4\u5b89\u5168\u7684 array \u6216 vector \u5bb9\u5668 array func() { array arr; return arr; } int main() { auto arr = func(); arr[0]; // \u53ef\u4ee5\uff0c\u8bbf\u95ee\u5230\u7684\u662f main \u51fd\u6570\u5c40\u90e8\u53d8\u91cf arr\uff0c\u662f\u5bf9 func \u4e2d\u539f arr \u7684\u4e00\u4efd\u62f7\u8d1d }","title":"\u4e0d\u80fd\u8bbf\u95ee\u5df2\u91ca\u653e\u7684\u5185\u5b58"},{"location":"undef/#new-new-malloc-delete-delete-free","text":"int *p = new int; free(p); // \u9519\uff01 int *p = (int *)malloc(sizeof(int)); free(p); // \u6b63\u786e int *p = new int[3]; delete p; // \u9519\uff01 int *p = new int[3]; delete[] p; // \u6b63\u786e vector a(3); unique_ptr a = make_unique(42);","title":"new / new[] / malloc \u548c delete / delete[] / free \u5fc5\u987b\u5339\u914d"},{"location":"undef/#_23","text":"struct C { int i; ~C() { i = 0; } }; C *c = (C *)malloc(sizeof(C)); cout << c->i; // \u53ef\u4ee5 c->~C(); cout << c->i; // \u9519\uff01 free(c); std::string func() { std::string s = \"hello\"; std::string s2 = std::move(s); return s; // \u8bed\u8a00\uff1aOK\uff0c\u6807\u51c6\u5e93\u4f5c\u8005\uff1as \u4e0d\u4e00\u5b9a\u662f\u7a7a\u5b57\u7b26\u4e32 }","title":"\u4e0d\u8981\u8bbf\u95ee\u5df2\u7ecf\u6790\u6784\u7684\u5bf9\u8c61"},{"location":"undef/#_24","text":"void func() {} printf(\"*func = %d\\n\", *((int *)func)); // \u9519\u8bef C++ \u5185\u5b58\u6a21\u578b\u662f\u54c8\u4f5b\u67b6\u6784\uff08\u4ee3\u7801\u4e0e\u6570\u636e\u5206\u79bb\uff09\uff0c\u4e0d\u662f\u51af\u8bfa\u4f9d\u66fc\u67b6\u6784\uff08\u4ee3\u7801\u4e5f\u662f\u6570\u636e\uff09","title":"\u4e0d\u80fd\u628a\u51fd\u6570\u6307\u9488\u8f6c\u6362\u4e3a\u666e\u901a\u7c7b\u578b\u6307\u9488\u89e3\u5f15\u7528"},{"location":"undef/#_25","text":"","title":"\u5e93\u51fd\u6570\u7c7b"},{"location":"undef/#ctypeh-0127-ascii","text":"isdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true isdigit('a'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false isdigit('\\xef'); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u5728 MSVC \u7684 Debug \u6a21\u5f0f\u4e0b\u4f1a\u4ea7\u751f\u65ad\u8a00\u5f02\u5e38 char s[] = \"\u4f60\u597dA\"; // UTF-8 \u7f16\u7801\u7684\u4e2d\u6587 // \"\u4f60\u597da\"\uff1f std::transform(std::begin(s), std::end(s), std::begin(s), ::tolower); // \u9519\uff01\u7ed3\u679c\u672a\u5b9a\u4e49\uff0c\u56e0\u4e3a UTF-8 \u7f16\u7801\u4f1a\u4ea7\u751f\u5927\u4e8e 128 \u7684\u5b57\u8282 MSVC STL \u4e2d is \u7cfb\u5217\u51fd\u6570\u7684\u65ad\u8a00\uff1a assert(-1 <= c && c < 256); \u7406\u8bba\u4e0a\u53ef\u4ee5\u8fd9\u6837\u65ad\u8a00\uff1a assert(0 <= c && c <= 127); \u89e3\u51b3\u65b9\u6cd5\uff1a\u8981\u4e48\u6539\u7528 iswdigit\uff08MSVC\uff1a0-65536\uff0cGCC\uff1a0-0x010ffff\uff09 iswdigit('0'); // \u53ef\u4ee5\uff0c\u8fd4\u56de true iswdigit('\\xef'); // \u53ef\u4ee5\uff0c\u8fd4\u56de false iswspace(L'\\ufeff'); // \u53ef\u4ee5\uff0cUTF-8 locale \u65f6\u8fd4\u56de true\uff0cASCII locale \u65f6\u8fd4\u56de false \u8981\u4e48\u81ea\u5df1\u5b9e\u73b0\u5224\u65ad if ('0' <= c && c <= '9') // \u4ee3\u66ff isdigit(c) if (strchr(\" \\n\\t\\r\", c)) // \u4ee3\u66ff isspace(c)","title":"ctype.h \u4e2d\u4e00\u7cfb\u5217\u51fd\u6570\u7684\u5b57\u7b26\u53c2\u6570\uff0c\u5fc5\u987b\u5728 0~127 \u8303\u56f4\u5185\uff08\u5373\u53ea\u652f\u6301 ASCII \u5b57\u7b26\uff09"},{"location":"undef/#memcpy-src-dst","text":"void *dst = nullptr; void *src = nullptr; size_t size = 0; memcpy(dst, src, size); // \u9519\uff01\u5373\u4f7f size \u4e3a 0\uff0csrc \u548c dst \u4e5f\u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488 \u53ef\u4ee5\u7ed9 size \u52a0\u4e2a\u5224\u65ad void *dst = nullptr; void *src = nullptr; size_t size = 0; if (size != 0) // \u53ef\u4ee5 memcpy(dst, src, size);","title":"memcpy \u51fd\u6570\u7684 src \u548c dst \u4e0d\u80fd\u4e3a\u7a7a\u6307\u9488"},{"location":"undef/#memcpy-src-dst_1","text":"char arr[10]; memcpy(arr, arr + 1, 9); // \u9519\uff01\u6709\u7684\u540c\u5b66\uff0c\u4ee5\u4e3a\u8fd9\u4e2a\u662f\u5bf9\u7684\uff1f\u9519\u4e86\uff0cmemcpy \u7684 src \u548c dst memcpy(arr + 1, arr, 9); // \u9519\uff01 memcpy(arr + 5, arr, 5); // \u53ef\u4ee5 memcpy(arr, arr + 5, 5); // \u53ef\u4ee5 \u5982\u9700\u62f7\u8d1d\u5e26\u91cd\u590d\u533a\u95f4\u7684\u5185\u5b58\uff0c\u53ef\u4ee5\u7528 memmove char arr[10]; memmove(arr, arr + 1, 9); // \u53ef\u4ee5 memmove(arr + 1, arr, 9); // \u53ef\u4ee5 memmove(arr + 5, arr, 5); // \u53ef\u4ee5 memmove(arr, arr + 5, 5); // \u53ef\u4ee5 \u4ece memcpy \u7684 src \u548c dst \u6307\u9488\u53c2\u6570\u662f restrict \u4fee\u9970\u7684\uff0c\u800c memmove \u6ca1\u6709\uff0c\u5c31\u53ef\u4ee5\u770b\u51fa\u6765\uff0cmemcpy \u4e0d\u5141\u8bb8\u4efb\u4f55\u5f62\u5f0f\u7684\u6307\u9488\u91cd\u53e0\uff0c\u65e0\u8bba\u5148\u540e\u987a\u5e8f","title":"memcpy \u4e0d\u80fd\u63a5\u53d7\u5e26\u6709\u91cd\u53e0\u7684 src \u548c dst"},{"location":"undef/#vback-v","text":"std::vector v = {}; int i = v.back(); // \u9519\uff01back() \u5e76\u4e0d\u4f1a\u5bf9 v \u662f\u5426\u6709\u6700\u540e\u4e00\u4e2a\u5143\u7d20\u505a\u68c0\u67e5\uff0c\u6b64\u5904\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 int i = v.empty() ? 0 : v.back(); // \u66f4\u5b89\u5168\uff0c\u5f53 v \u4e3a\u7a7a\u65f6\u8fd4\u56de 0","title":"v.back() \u5f53 v \u4e3a\u7a7a\u65f6\u662f\u672a\u5b9a\u4e49\u884c\u4e3a"},{"location":"undef/#vector-operator-i","text":"std::vector v = { 1, 2, 3 }; v[3]; // \u9519\uff01\u76f8\u5f53\u4e8e\u89e3\u5f15\u7528\u4e86\u8d8a\u754c\u7684\u6307\u9488 \u53ef\u4ee5\u7528 at \u6210\u5458\u51fd\u6570 std::vector v = { 1, 2, 3 }; v.at(3); // \u5b89\u5168\uff0c\u4f1a\u68c0\u6d4b\u5230\u8d8a\u754c\uff0c\u629b\u51fa std::out_of_range \u5f02\u5e38","title":"vector \u7684 operator[] \u5f53 i \u8d8a\u754c\u65f6\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a"},{"location":"undef/#_26","text":"std::vector v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 v.begin() \u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u8fed\u4ee3\u5668\u4e0d\u5931\u6548\u3002 std::deque v = { 1, 2, 3 }; auto it = v.begin(); v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u8fed\u4ee3\u5668\u5931\u6548 *it = 0; // \u53ef\u4ee5 https://www.geeksforgeeks.org/iterator-invalidation-cpp https://en.cppreference.com/w/cpp/container","title":"\u5bb9\u5668\u8fed\u4ee3\u5668\u5931\u6548"},{"location":"undef/#_27","text":"std::vector v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // push_back \u53ef\u80fd\u5bfc\u81f4\u6269\u5bb9\uff0c\u4f7f\u5143\u7d20\u5168\u90e8\u79fb\u52a8\u5230\u4e86\u65b0\u7684\u4e00\u6bb5\u5185\u5b58\uff0c\u4f1a\u4f7f\u4e4b\u524d\u4fdd\u5b58\u7684 ref \u5f15\u7528\u5931\u6548 ref = 0; // \u9519\uff01 \u5982\u679c\u4e0d\u9700\u8981\u8fde\u7eed\u5185\u5b58\uff0c\u53ef\u4ee5\u6539\u7528\u5206\u6bb5\u5185\u5b58\u7684 deque \u5bb9\u5668\uff0c\u5176\u53ef\u4ee5\u4fdd\u8bc1\u5143\u7d20\u4e0d\u88ab\u79fb\u52a8\uff0c\u5f15\u7528\u4e0d\u5931\u6548\u3002 std::deque v = {1, 2, 3}; int &ref = v[0]; v.push_back(4); // deque \u7684 push_back \u4e0d\u4f1a\u5bfc\u81f4\u5143\u7d20\u79fb\u52a8\uff0c\u4f7f\u5f15\u7528\u5931\u6548 ref = 0; // \u53ef\u4ee5","title":"\u5bb9\u5668\u5143\u7d20\u5f15\u7528\u5931\u6548"},{"location":"undef/#_28","text":"","title":"\u591a\u7ebf\u7a0b\u7c7b"},{"location":"undef/#_29","text":"std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { cout << s.size(); // \u8bfb\u8bbf\u95ee } std::string s; void t1() { s.push_back('a'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } void t2() { s.push_back('b'); // \u5199\u8bbf\u95ee\uff0c\u51fa\u9519\uff01 } \u66f4\u51c6\u786e\u7684\u8bf4\u6cd5\u662f\uff1a\u591a\u4e2a\u7ebf\u7a0b\uff08\u65e0 happens before \u5173\u7cfb\u5730\uff09\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u5e26\u6709\u526f\u4f5c\u7528\uff08\u5199\u8bbf\u95ee\u6216\u5e26\u6709volatile\u7684\u8bfb\u8bbf\u95ee\uff09\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a // \u516b\u80a1\u6587\u6559\u6750\u5e38\u89c1\u7684\u9519\u8bef\u5199\u6cd5\uff01volatile \u5e76\u4e0d\u4fdd\u8bc1\u539f\u5b50\u6027\u548c\u5185\u5b58\u5e8f\uff0c\u8fd9\u6837\u5199\u662f\u6709\u672a\u5b9a\u4e49\u884c\u4e3a\u7684\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u6539\u7528 std::atomic volatile int ready = 0; int data; void t1() { data = 42; ready = 1; } void t2() { while (ready == 0) ; printf(\"%d\\n\", data); } \u5efa\u8bae\u5229\u7528 mutex\uff0ccounting_semaphore\uff0catomic \u7b49\u591a\u7ebf\u7a0b\u540c\u6b65\u5de5\u5177\uff0c\u4fdd\u8bc1\u591a\u4e2a\u7ebf\u7a0b\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\u65f6\uff0c\u987a\u5e8f\u6709\u5148\u6709\u540e\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u53d1\u751f\uff0c\u90a3\u5c31\u662f\u5b89\u5168\u7684 std::string s; std::mutex m; void t1() { std::lock_guard l(m); s.push_back('a'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } void t2() { std::lock_guard l(m); s.push_back('b'); // \u6709 mutex \u4fdd\u62a4\uff0c\u53ef\u4ee5 } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4e92\u65a5\u9501\u4fdd\u8bc1\u4e86\u8981\u4e48 t1 happens before t2\uff0c\u8981\u4e48 t2 happens before t1\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::counting_semaphore<1> sem(1); void t1() { s.push_back('a'); sem.release(); // \u4ee4 t2 \u5fc5\u987b\u53d1\u751f\u5728 t1 \u4e4b\u540e } void t2() { sem.acquire(); // t2 \u5fc5\u987b\u7b49\u5f85 t1 release \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u4fe1\u53f7\u91cf\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684 std::string s; std::atomic ready{false}; void t1() { s.push_back('a'); ready.store(true, std::memory_order_release); // \u4ee4 s \u7684\u4fee\u6539\u5bf9\u5176\u4ed6 acquire \u4e86 ready \u7684\u7ebf\u7a0b\u53ef\u89c1 } void t2() { while (!ready.load(std::memory_order_acquire)) // t2 \u5fc5\u987b\u7b49\u5f85 t1 store \u540e\uff0c\u624d\u80fd\u5f00\u59cb\u6267\u884c ; s.push_back('b'); } \u5728\u4e0a\u9762\u7684\u4f8b\u5b50\u4e2d\uff0c\u539f\u5b50\u53d8\u91cf\u7684 acquire/release \u5185\u5b58\u5e8f\u4fdd\u8bc1\u4e86 t1 happens before t2\uff0c\u4e0d\u4f1a\u201c\u540c\u65f6\u201d\u8bbf\u95ee\uff0c\u662f\u5b89\u5168\u7684","title":"\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u8bbf\u95ee\u540c\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5176\u4e2d\u81f3\u5c11\u4e00\u4e2a\u7ebf\u7a0b\u7684\u8bbf\u95ee\u4e3a\u5199\u8bbf\u95ee\uff0c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6570\u636e\u7ade\u4e89\uff09"},{"location":"undef/#mutex","text":"std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); // \u9519\uff01 m2.unlock(); m1.unlock(); } void t2() { m2.lock(); m1.lock(); // \u9519\uff01 m1.unlock(); m2.unlock(); } \u89e3\u51b3\u65b9\u6cd5\uff1a\u4e0d\u8981\u5728\u591a\u4e2a mutex \u4e0a\u540c\u65f6\u4e0a\u9501\uff0c\u5982\u679c\u786e\u5b9e\u8981\u591a\u4e2a mutex\uff0c\u4fdd\u8bc1\u987a\u5e8f\u4e00\u81f4 std::mutex m1, m2; void t1() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } void t2() { m1.lock(); m2.lock(); m2.unlock(); m1.unlock(); } \u6216\u4f7f\u7528 std::lock std::mutex m1, m2; void t1() { std::lock(m1, m2); std::unlock(m1, m2); } void t2() { std::lock(m2, m1); std::unlock(m2, m1); }","title":"\u591a\u4e2a\u7ebf\u7a0b\u540c\u65f6\u5bf9\u4e24\u4e2a mutex \u4e0a\u9501\uff0c\u4f46\u987a\u5e8f\u76f8\u53cd\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u6b7b\u9501\uff09"},{"location":"undef/#recursive_mutex-mutex","text":"std::mutex m; void t1() { m.lock(); m.lock(); // \u9519\uff01 m.try_lock(); // \u9519\uff01try_lock \u4e5f\u4e0d\u5141\u8bb8\uff01 m.unlock(); m.unlock(); } void t2() { m.try_lock(); // \u53ef\u4ee5 } \u89e3\u51b3\u65b9\u6cd5\uff1a\u6539\u7528 recursive_mutex\uff0c\u6216\u4f7f\u7528\u9002\u5f53\u7684\u6761\u4ef6\u53d8\u91cf std::recursive_mutex m; void t1() { m.lock(); m.lock(); // \u53ef\u4ee5 m.try_lock(); // \u53ef\u4ee5\uff0c\u8fd4\u56de true m.unlock(); m.unlock(); m.unlock(); }","title":"\u5bf9\u4e8e\u975e recursive_mutex\uff0c\u540c\u4e00\u4e2a\u7ebf\u7a0b\u5bf9\u540c\u4e00\u4e2a mutex \u91cd\u590d\u4e0a\u9501\uff0c\u4f1a\u4ea7\u751f\u672a\u5b9a\u4e49\u884c\u4e3a\uff08\u4fd7\u79f0\u9012\u5f52\u6b7b\u9501\uff09"},{"location":"undef/#_30","text":"\u4e0d\u8981\u73a9\u7a7a\u6307\u9488 \u4e0d\u8981\u8d8a\u754c\uff0c\u7528\u66f4\u5b89\u5168\u7684 at\uff0csubspan \u7b49 \u4e0d\u8981\u4e0d\u521d\u59cb\u5316\u53d8\u91cf\uff08auto-idiom\uff09 \u5f00\u542f -Werror=return-type \u4e0d\u8981\u91cd\u590d\u4e0a\u9501 mutex \u4ed4\u7ec6\u770b\u5e93\u51fd\u6570\u7684\u6587\u6863 \u7528\u667a\u80fd\u6307\u9488\u7ba1\u7406\u5355\u4e2a\u5bf9\u8c61 \u7528 vector \u7ba1\u7406\u591a\u4e2a\u5bf9\u8c61\u7ec4\u6210\u7684\u8fde\u7eed\u5185\u5b58 \u907f\u514d\u7a7a\u60ac\u5f15\u7528 \u5f00 Debug \u6a21\u5f0f\u7684 STL \u6307\u5b9a CMake \u7684\u6a21\u5f0f\uff1a cmake -B build -DCMAKE_BUILD_TYPE=Debug Debug: -O0 -g \u7f16\u8bd1\u9009\u9879 Release: -O3 -DNDEBUG \u7f16\u8bd1\u9009\u9879 \u6307\u5b9a MSVC \u7684\u6a21\u5f0f\uff1a cmake --build build --config Debug Debug: \u751f\u6210 zenod.dll \uff0c\u94fe\u63a5 Debug \u7684 ABI Release: \u751f\u6210 zeno.dll \uff0c\u94fe\u63a5 Release \u7684 ABI","title":"\u603b\u7ed3"},{"location":"undef/#cppcon","text":"\u987a\u4fbf\u63a8\u4e2a CppCon \u5c0f\u89c6\u9891\uff1ahttps://www.youtube.com/watch?v=ehyHyAIa5so \u6807\u9898\u662f\u300aCppCon 2017: Piotr Padlewski \u201cUndefined Behaviour is awesome!\u201d\u300b\uff08\u7206\u5b5d\uff09","title":"CppCon \u76f8\u5173\u89c6\u9891"},{"location":"unicode/","text":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u96c6 ASCII Latin-1 Unicode \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801 UTF-32 UTF-8 \u517c\u5bb9 ASCII \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d UTF-16 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 BOM \u6807\u8bb0 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u7684\u7f3a\u9677 GBK GB18030 \u603b\u7ed3 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 UTF-8 \u9635\u8425 UTF-16 \u9635\u8425 UTF-32 \u9635\u8425 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale UTF \u4e4b\u95f4\u4e92\u8f6c GBK \u548c UTF \u4e92\u8f6c UTF \u548c ANSI \u4e92\u8f6c \u5927\u603b\u7ed3 GBK \u548c Shift-JIS \u4e92\u8f6c \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u66f4\u591a\u529f\u80fd\uff1f\uff01 Windows \u7528\u6237\uff1aMultiByteToWideChar MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b Linux \u7528\u6237\uff1aiconv iconv \u547d\u4ee4\u884c\u5de5\u5177 \u672c\u5730\u5316 (locale) \u533a\u5206\u5b57\u7b26\u7c7b\u578b \u5bbd\u5b57\u7b26\u7c7b\u578b wchar_t \u5e94\u7528\u6848\u4f8b \u533a\u57df\u8bbe\u7f6e\u4e0e locale locale \u7684\u547d\u540d\u89c4\u8303 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7279\u6b8a locale\uff1a\"C\" LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801 LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 std::locale \u5bf9\u8c61 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale \u5bbd\u5b57\u7b26\u6d41 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 Windows \u4e13\u9898 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 TCHAR \u6d41\u6d3e UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 Qt QString QTextCodec from/toLocal8Bits/Utf8/Latin1/Ascii \u5b57\u7b26\u4e32\u5e38\u91cf QTextStream Python 3 str Rust &str \u548c String Java String COW \u5b57\u7b26\u4e32 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 Grapheme \u6b63\u89c4\u5316 \u96f6\u5bbd\u7a7a\u683c \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 UniFont \u5b57\u4f53 \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f Latin-1 \u7684\u8f6c\u6362 Latin-1 \u7684\u5999\u7528 Base64 \u9632\u4e71\u7801 UTF-7 \u5b57\u7b26\u7f16\u7801\u731c\u6d4b \u5b57\u7b26\u96c6 \u8ba1\u7b97\u673a\u4e0d\u80fd\u76f4\u63a5\u5b58\u50a8\u5b57\u7b26\uff0c\u800c\u662f\u7528\u6570\u5b57\u6765\u4ee3\u66ff\uff0c\u8fd9\u5c31\u662f\u5b57\u7b26\u96c6\uff0c\u4e3a\u6bcf\u4e2a\u5b57\u7b26\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57\u3002 ASCII ASCII \u4e3a\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u7ec4\u3001\u6807\u70b9\u7b26\u53f7\u7b49 128 \u4e2a\u5b57\u7b26\uff0c\u6bcf\u4e2a\u90fd\u7528\u4e00\u4e2a 0 \u5230 127 \u8303\u56f4\u5185\u7684\u6570\u5b57\u5bf9\u5e94\u3002 \u5982\u679c\u4f60\u60f3\u8981\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u5c31\u5728\u8fd9\u4e2a\u8868\u91cc\u5bfb\u627e\u5230\u76f8\u5e94\u7684\u6570\u5b57\u7f16\u53f7\uff0c\u7136\u540e\u5b58\u8fd9\u4e2a\u7f16\u53f7\u5373\u53ef\u3002 \u4f8b\u5982\u4e0b\u9762\u7684\u4e00\u4e32\u6570\u5b57\uff1a 80 101 110 103 \u5728 ASCII \u8868\u4e2d\u67e5\u627e\uff0c\u53d1\u73b0\u8fd9\u4e9b\u6570\u5b57\u5206\u522b\u5bf9\u5e94 P \u3001 e \u3001 n \u3001 g \u56db\u4e2a\u5b57\u6bcd\uff0c\u8fde\u8d77\u6765\u5c31\u8fd8\u539f\u5f97\u5230\u4e86\u539f\u672c\u7684\u5b57\u7b26\u4e32\u201cPeng\u201d\u3002 Latin-1 Latin-1 \u6269\u5145\u4e86 ASCII \u5b57\u7b26\u96c6\uff0c\u4fdd\u6301 ASCII \u539f\u6709 0 \u5230 127 \u7684\u90e8\u5206\u6620\u5c04\u4e0d\u53d8\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 128 \u5230 255 \u7684\u6620\u5c04\u5173\u7cfb\u3002\u56e0\u6b64\u4e5f\u88ab\u79f0\u4e3a EASCII\uff08\u6269\u5c55 ASCII\uff09\u3002 Unicode Unicode \u5b57\u7b26\u96c6\u4e3a\u5168\u4e16\u754c\u7684\u6240\u6709\u5b57\u7b26\u90fd\u5bf9\u5e94\u4e86\u4e00\u4e2a\u6574\u6570\u3002 \u5b57\u7b26 \u7f16\u53f7 \u6211 25105 \u6212 25106 \u6213 25107 \u6214 25108 \u6215 25109 \u6216 25110 \u6217 25111 \u6218 25112 \u6219 25113 \u621a 25114 \u51fa\u4e8e\u5386\u53f2\u517c\u5bb9\u6027\u8003\u8651\uff0cUnicode \u5728 0 \u5230 256 \u533a\u95f4\u5185\u7684\u6620\u5c04\u548c ASCII\u3001Latin-1 \u662f\u5b8c\u5168\u76f8\u540c\u7684\u3002 \u5b57\u7b26 \u7f16\u53f7 P 80 e 101 n 110 g 103 Unicode \u7ecf\u8fc7\u4e86\u8bb8\u591a\u7248\u672c\u7684\u53d1\u5c55\uff0c\u65e9\u671f\u7684 Unicode \u53ea\u6536\u5f55\u4e86 65536 (0x10000) \u4e2a\u5b57\u7b26\uff0c\u540e\u6765\u6269\u5145\u5230\u4e86 1114112 (0x110000) \u4e2a\u5b57\u7b26\u3002 \u603b\u4e4b\uff0c\u73b0\u5728 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u867d\u7136\u5360\u7528\u4e86 1114112 \u8fd9\u591a\u683c\u7801\u70b9\u7a7a\u95f4\uff0c\u4e0d\u8fc7\u5176\u4e2d\u5f88\u591a\u90fd\u662f\u7a7a\u53f7\uff0c\u7559\u5f85\u672a\u6765\u6269\u5145\u4f7f\u7528\u3002 Unicode \u5b57\u7b26\u6620\u5c04\u8868\u53ef\u4ee5\u5728\u7f51\u4e0a\u627e\u5230\uff1a https://symbl.cc/en/unicode-table/ https://www.compart.com/en/unicode/ \u603b\u7ed3 \u5b57\u7b26\u96c6: \u4ece\u5b57\u7b26\u5230\u6574\u6570\u7684\u4e00\u4e00\u6620\u5c04\u3002 ASCII: \u53ea\u6536\u5f55\u4e86\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 Latin-1: \u5728 ASCII \u57fa\u7840\u4e0a\u8ffd\u52a0\u4e86\u6ce8\u97f3\u5b57\u6bcd\uff0c\u6ee1\u8db3\u6b27\u6d32\u7528\u6237\u9700\u8981\u3002 Unicode: \u6536\u5f55\u4e86\u5168\u4e16\u754c\u6240\u6709\u6587\u5b57\u548c\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 \u8ba1\u7b97\u673a\u5b58\u50a8\u5b57\u7b26\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u5b58\u50a8\u4e86\u90a3\u4e2a\u5bf9\u5e94\u7684\u6574\u6570\u3002 \u8fd9\u4e9b\u6574\u6570\u5c31\u88ab\u79f0\u4e3a \u7801\u70b9 (code point) \uff0c\u6bcf\u4e2a\u5b57\u7b26\u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002 \u4e0d\u8fc7\uff0c\u7a0b\u5e8f\u5458\u901a\u5e38\u559c\u6b22\u7528\u5341\u516d\u8fdb\u5236\u4e66\u5199\u6570\u5b57\uff1a \u5b57\u7b26 \u7f16\u53f7 \u6211 0x6211 \u6212 0x6212 \u6213 0x6213 \u6214 0x6214 \u6215 0x6215 \u6216 0x6216 \u6217 0x6217 \u6218 0x6218 \u6219 0x6219 \u621a 0x621A \u4f8b\u5982\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\uff0c\u5728 Unicode \u8868\u4e2d\u7f16\u53f7\u4e3a 0x6211\u3002\u4e8e\u662f\u5f53\u8ba1\u7b97\u673a\u9700\u8981\u8868\u793a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\u65f6\uff0c\u5c31\u7528 0x6211 \u8fd9\u4e2a\u6574\u6570\u4ee3\u66ff\u3002 \u5982\u679c\u8981\u8868\u793a\u591a\u4e2a\u5b57\u7b26\uff0c\u90a3\u5c31\u7528\u4e00\u4e2a\u6574\u6570\u7684\u6570\u7ec4\u5427\uff01 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5904\u7406\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a 0x6211 0x7231 0x30EDE 0x30EDE 0x9762 0x21 \u8fd9\u4e00\u4e32\u6570\u5b57\u4ee3\u66ff\u3002 \u5982\u679c\u4f60\u8fd9\u91cc\u770b\u5230\u7684\u662f\u201c\u6211\u7231\u53e3\u53e3\u9762!\u201d\u8bf4\u660e\u4f60\u7684\u5b57\u4f53\u4e0d\u652f\u6301\u201cbi\u00e1ng\u201d\u8fd9\u4e2a\u5b57\u3002\u5f53\u6d4f\u89c8\u5668\u9047\u5230\u5f53\u524d\u5b57\u4f53\u4e0d\u652f\u6301\u7684 Unicode \u5b57\u7b26\u65f6\uff0c\u5c31\u4f1a\u66ff\u6362\u4e3a\u65b9\u5757\u3002\u5efa\u8bae\u5b89\u88c5\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u8f83\u591a\u7684 \u201cNoto Sans CJK SC\u201d \u5b57\u4f53\uff0c\u4e5f\u53ef\u4ee5\u5b89\u88c5\u652f\u6301\u4e00\u5207 Unicode \u5b57\u7b26\u7684 \u201cUniFonts\u201d\u3002 sudo apt-get install -y fonts-noto-cjk \u201c\ud883\udede(bi\u00e1ng)\ud883\udede(bi\u00e1ng)\u9762\u201d\u662f\u6d41\u884c\u4e8e\u4e2d\u56fd\u9655\u897f\u5173\u4e2d\u5730\u533a\u7684\u4e00\u79cd\u77e5\u540d\u4f20\u7edf\u98ce\u5473\u9762\u98df\uff0c\u5c5e\u4e8e\u626f\u9762\uff0c\u901a\u8fc7\u63c9\u3001\u62bb\u3001\u7529\u3001\u626f\u7b49\u6b65\u9aa4\u5236\u4f5c\uff0c\u9762\u5bbd\u800c\u539a\uff0c\u72b9\u5982\u201c\u88e4\u8170\u5e26\u201d\uff0c\u53e3\u611f\u52b2\u9053\uff0c\u98df\u7528\u524d\u52a0\u5165\u5404\u8272\u81ca\u5b50\u6216\u6cb9\u6cfc\u8fa3\u5b50\u3002\u4f46\u662f\uff0c\u5c0f\u5f6d\u8001\u5e08\u5176\u5b9e\u5e76\u6ca1\u6709\u5403\u8fc7\uff0c\u53ea\u662f\u56e0\u4e3a\u7a00\u6709\u5b57\u4f53\u770b\u8d77\u6765\u6bd4\u8f83\u597d\u73a9\u3002 \u5b57\u7b26\u7f16\u7801 Unicode \u53ea\u662f\u6307\u5b9a\u4e86\u6574\u6570\uff0c\u6ca1\u6709\u89c4\u5b9a\u6574\u6570\u5982\u4f55\u5728\u5185\u5b58\u4e2d\u5b58\u5728\u3002 \u5b57\u7b26\u7f16\u7801: \u5c06\u5b57\u7b26\u7684\u6574\u6570\u7f16\u53f7\u5e8f\u5217\u5316\u4e3a\u8ba1\u7b97\u673a\u53ef\u76f4\u63a5\u5b58\u50a8\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u5b9e\u9645\u5b58\u5728\u7684\u6574\u6570\u7c7b\u578b\u3002 Unicode \u5b57\u7b26\u53ef\u4ee5\u9009\u7528\u4ee5\u4e0b\u8fd9\u4e9b\u5b57\u7b26\u7f16\u7801\u6765\u5e8f\u5217\u5316\uff1a UTF-32: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u4e2a uint32_t \u6574\u6570\u5b58\u50a8\u3002 UTF-16: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 2 \u4e2a uint16_t \u6574\u6570\u5b58\u50a8\u3002 UTF-8: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u5b58\u50a8\u3002 \u7ffb\u8bd1\u51fa\u6765\u7684\u8fd9\u4e9b\u5c0f\u6574\u6570\u53eb \u7801\u4f4d (code unit) \u3002\u4f8b\u5982\u5bf9\u4e8e UTF-8 \u800c\u8a00\uff0c\u6bcf\u4e2a uint8_t \u5c31\u662f\u4ed6\u7684\u7801\u4f4d\u3002 UTF-32 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u6700\u5927\u503c 0x10FFFF \u6709 21 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0cC \u8bed\u8a00\u4e2d uint32_t \u80fd\u5bb9\u7eb3 32 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0c\u6240\u4ee5\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u662f\u76f4\u63a5\u7528 uint32_t \u6570\u7ec4\u6765\u4e00\u4e2a\u4e2a\u5bb9\u7eb3 Unicode \u5b57\u7b26\u7801\u70b9\u3002\u867d\u7136\u6d6a\u8d39\u4e86 11 \u4f4d\uff0c\u4f46\u81f3\u5c11\u6240\u6709 Unicode \u5b57\u7b26\u90fd\u80fd\u5b89\u5168\u5bb9\u7eb3\u3002 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a std::vector s = { 0x00006211, // \u6211 0x00007231, // \u7231 0x00030EDE, // \ud883\udede 0x00030EDE, // \ud883\udede 0x00009762, // \u9762 0x00000021, // ! }; \u8fd9\u4e2a\u6570\u7ec4\u8868\u793a\u3002 UTF-32 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u56fa\u5b9a\u5bf9\u5e94\u4e00\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-32 \u662f \u5b9a\u957f\u7f16\u7801 \u3002\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5c31\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002 \u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u6570\u7ec4\u7684\u7d22\u5f15\u64cd\u4f5c\u3002 \u65e0\u8bba\u5bf9\u6570\u7ec4\u5982\u4f55\u5207\u7247\uff0c\u90fd\u4e0d\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u7834\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u5c31\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u53cd\u8f6c\uff0c\u4e0d\u4f1a\u4ea7\u751f\u7834\u574f\u5b57\u7b26\u7684\u95ee\u9898\u3002 \u7f3a\u70b9\u662f\uff1a \u6d6a\u8d39\u5b58\u50a8\u7a7a\u95f4\u3002 \u5b9a\u957f\u7f16\u7801\u5f88\u65b9\u4fbf\uff0c\u6211\u4eec\u63a8\u8350\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\uff0c\u7edf\u4e00\u91c7\u7528 UTF-32 \u5f62\u5f0f\u5904\u7406\u6587\u5b57\u3002 UTF-32 \u4e5f\u88ab\u79f0\u4e3a UCS-4\uff0c\u4ed6\u4fe9\u662f\u540c\u4e49\u8bcd\u3002 UTF-8 UTF-32 \u867d\u7136\u65b9\u4fbf\u4e86\u6587\u5b57\u5904\u7406\uff0c\u7136\u800c\uff0c\u5374\u6d6a\u8d39\u4e86\u5927\u91cf\u7684\u5b58\u50a8\u7a7a\u95f4\uff0c\u4e0d\u5229\u4e8e\u6587\u5b57\u5b58\u50a8\uff01\u4e00\u4e2a\u5b57\u7b26\uff0c\u65e0\u8bba\u4ed6\u662f\u5e38\u7528\u8fd8\u662f\u4e0d\u5e38\u7528\uff0c\u90fd\u8981\u9738\u5360 4 \u4e2a\u5b57\u8282\u7684\u7a7a\u95f4\u3002 Unicode \u7f16\u7801\u5b57\u7b26\u65f6\uff0c\u7279\u610f\u628a\u5e38\u7528\u7684\u5b57\u7b26\u9760\u524d\u6392\u5217\u4e86\u3002 \u4e16\u754c\u4e0a\u5e38\u7528\u8bed\u8a00\u6587\u5b57\u90fd\u88ab\u523b\u610f\u7f16\u7801\u5728\u4e86 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u8d85\u8fc7 0x10000 \u7684\u57fa\u672c\u90fd\u662f\u4e0d\u5e38\u7528\u7684\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\uff0c\u5f88\u591a\u90fd\u662f\u5df2\u7ecf\u65e0\u4eba\u4f7f\u7528\u7684\u53e4\u4ee3\u6587\u5b57\u548c\u751f\u50fb\u5b57\uff0c\u4f8b\u5982\u201c\ud883\udede\u201d\u3002\u4ec5\u4ec5\u662f\u4e3a\u4e86\u8fd9\u4e9b\u5076\u5c14\u4f7f\u7528\u7684\u7f55\u89c1\u6587\u5b57\uff0c\u5c31\u8981\u6c42\u6240\u6709\u6587\u5b57\u90fd\u7528\u540c\u6837\u7684 4 \u5b57\u8282\u5bbd\u5ea6\u5b58\u50a8\uff0c\u5b9e\u5728\u662f\u6709\u70b9\u6d6a\u8d39\u3002 \u5728 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u540c\u6837\u6709\u6309\u7167\u5e38\u7528\u5ea6\u6392\u5e8f\uff1a 0 \u5230 0x7F \u662f\uff08\u6b27\u7f8e\u7528\u6237\uff09\u6700\u5e38\u7528\u7684\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u534a\u89d2\u6807\u70b9\u3002 0x80 \u5230 0x7FF \u662f\u8868\u97f3\u6587\u5b57\u533a\uff0c\u5e38\u7528\u7684\u6ce8\u97f3\u5b57\u6bcd\u3001\u62c9\u4e01\u5b57\u6bcd\u3001\u5e0c\u814a\u5b57\u6bcd\u3001\u897f\u91cc\u5c14\u5b57\u6bcd\u3001\u5e0c\u4f2f\u6765\u5b57\u6bcd\u7b49\u3002 0x800 \u5230 0xFFFF \u662f\u8868\u610f\u6587\u5b57\uff0c\u7b80\u7e41\u4e2d\u6587\u3001\u65e5\u6587\u3001\u97e9\u6587\u3001\u6cf0\u6587\u3001\u9a6c\u6765\u6587\u3001\u963f\u62c9\u4f2f\u6587\u7b49\u3002 0x10000 \u5230 0x10FFFF \u662f\u4e0d\u5e38\u7528\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\u3002 UTF-8 \u5c31\u662f\u4e3a\u4e86\u89e3\u51b3\u538b\u7f29\u95ee\u9898\u800c\u8bde\u751f\u7684\u3002 UTF-8 \u628a\u4e00\u4e2a\u7801\u70b9\u5e8f\u5217\u5316\u4e3a\u4e00\u4e2a\u6216\u591a\u4e2a\u7801\u4f4d\uff0c\u4e00\u4e2a\u7801\u4f4d\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u8868\u793a\u3002 0 \u5230 0x7F \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 1 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 2 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 3 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 4 \u4e2a\u5b57\u8282\u8868\u793a\u3002 \u5e8f\u5217\u5316\u89c4\u5219\u5982\u4e0b\uff1a \u517c\u5bb9 ASCII \u5bf9\u4e8e 0 \u5230 0x7F \u7684\u5b57\u7b26\uff0c\u8fd9\u4e2a\u8303\u56f4\u7684\u5b57\u7b26\u9700\u8981 7 \u4f4d\u5b58\u50a8\u3002 \u6211\u4eec\u9009\u62e9\u76f4\u63a5\u5b58\u50a8\u5176\u503c\u3002 \u4f8b\u5982 \u2018P\u2019 \u4f1a\u88ab\u76f4\u63a5\u5b58\u50a8\u5176 Unicode \u503c\u7684 80\uff080x50\uff09\uff1a 01010000 \u7531\u4e8e Unicode \u5728 0 \u5230 0x7F \u8303\u56f4\u5185\u4e0e ASCII \u8868\u76f8\u540c\uff0c\u800c UTF-8 \u53c8\u628a 0 \u5230 0x7F \u7684\u503c\u76f4\u63a5\u5b58\u50a8\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u517c\u5bb9 ASCII\u3002\u8fd9\u4f7f\u5f97\u539f\u672c\u8bbe\u8ba1\u4e8e\u5904\u7406 ASCII \u7684 C \u8bed\u8a00\u51fd\u6570\uff0c\u4f8b\u5982 strlen\u3001strcat\u3001sprintf \u7b49\uff0c\u90fd\u53ef\u4ee5\u76f4\u63a5\u65e0\u7f1d\u5207\u6362\u5230 UTF-8\u3002\u53cd\u4e4b\u4ea6\u7136\uff0c\u4efb\u4f55\u8bbe\u8ba1\u7528\u4e8e UTF-8 \u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u5b8c\u5168\u63a5\u53d7 ASCII \u683c\u5f0f\u7684\u8f93\u5165\u6587\u672c\u3002 \u4f46\u90e8\u5206\u6d89\u53ca\u5b57\u7b26\u957f\u5ea6\u7684\u51fd\u6570\u4f1a\u6709\u4e9b\u8bb8\u4e0d\u517c\u5bb9\uff0c\u4f8b\u5982 strlen \u6c42\u51fa\u7684\u957f\u5ea6\u4f1a\u53d8\u6210\u5b57\u8282\u7684\u6570\u91cf\u800c\u4e0d\u662f\u5b57\u7b26\u7684\u6570\u91cf\u4e86\uff0c\u4f8b\u5982 strlen(\"\u6211\u4eec\") \u4f1a\u5f97\u5230 6 \u800c\u4e0d\u662f 2\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6784\u9020\u5c31\u50cf\u4e00\u5217\u5c0f\u706b\u8f66\u4e00\u6837\uff0c\u4e0d\u540c\u8303\u56f4\u5185\u7684\u7801\u4f4d\u4f1a\u88ab\u7f16\u7801\u6210\u4e0d\u540c\u957f\u5ea6\u7684\u5217\u8f66\uff0c\u4f46\u4ed6\u4eec\u90fd\u6709\u4e00\u4e2a\u8f66\u5934\u3002 \u6839\u636e\u706b\u8f66\u5934\u7684\u201c\u7b49\u7ea7\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u540e\u9762\u62c9\u7740\u51e0\u8282\u8f66\u53a2\u3002 \u706b\u8f66\u5934\u662f\u4ec0\u4e48\u7b49\u7ea7\u7531\u4ed6\u7684\u4e8c\u8fdb\u5236\u524d\u7f00\u51b3\u5b9a\uff1a \u5982\u679c\u662f 0 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u662f\u5355\u72ec\u4e00\u53f0\u706b\u8f66\u5934\uff0c\u540e\u9762\u6ca1\u6709\u8f66\u53a2\u4e86\uff0c\u8fd9\u8868\u793a\u8f66\u5934\u91cc\u9762\u76f4\u63a5\u88c5\u7740 0 \u5230 0x7F \u8303\u56f4\u7684\u666e\u901a ASCII \u5b57\u7b26\u3002 \u5982\u679c\u662f 110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e00\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u6b27\u6d32\u5b57\u7b26\u3002 \u5982\u679c\u662f 1110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e24\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u4e16\u754c\u5e38\u7528\u5b57\u7b26\u3002 \u5982\u679c\u662f 11110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e09\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u751f\u50fb\u5b57\u7b26\u3002 \u5982\u679c\u662f 10 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u8fd9\u662f\u4e00\u8282\u8f66\u53a2\uff0c\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002\u5982\u679c\u4f60\u770b\u5230\u4e00\u8282\u5355\u72ec\u7684\u8f66\u53a2\u5728\u524d\u9762\u65e0\u5934\u9a7e\u9a76\uff0c\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\u3002 \u5c0f\u670b\u53cb\u7528\u5c0f\u53f7\u5217\u8f66\u88c5\uff0c\u5927\u670b\u53cb\u7528\u5927\u53f7\u5217\u8f66\u88c5\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u4e32\u4e8c\u8fdb\u5236\uff1a 11100110 10000010 10000001 \u9996\u5148\uff0c\u770b\u5230\u7b2c\u4e00\u4e2a\u5b57\u8282\uff0c\u662f 1110 \u5f00\u5934\u7684\u4e09\u7ea7\u8f66\u5934\uff01\u8bf4\u660e\u540e\u9762\u8fd8\u6709\u4e24\u8282\u8f66\u53a2\u662f\u5c5e\u4e8e\u4ed6\u7684\u3002\u706b\u8f66\u5934\u4e2d 4 \u4f4d\u7528\u4e8e\u8868\u793a\u8f66\u5934\u7b49\u7ea7\u4e86\uff0c\u5269\u4e0b\u8fd8\u6709 4 \u4f4d\u7528\u4e8e\u88c5\u4e58\u5ba2\u3002 \u8f66\u53a2\u4e5f\u6709\u56fa\u5b9a\u7684\u524d\u7f00\uff0c\u6240\u6709\u7684\u8f66\u53a2\u90fd\u5fc5\u987b\u662f 10 \u5f00\u5934\u7684\u3002\u53bb\u9664\u8fd9\u5f00\u5934\u7684 2 \u4f4d\uff0c\u5269\u4e0b\u7684 6 \u4f4d\u5c31\u662f\u4e58\u5ba2\u3002 \u5bf9\u4e8e\u8fd9\u79cd\u4e09\u7ea7\u5217\u8f66\uff0c4 + 6 + 6 \u603b\u5171 16 \u4f4d\u4e8c\u8fdb\u5236\uff0c\u521a\u597d\u53ef\u4ee5\u88c5\u5f97\u4e0b 0xFFFF \u5185\u7684\u4e58\u5ba2\u3002 0110 000010 000001 \u7f16\u7801\u65f6\u5219\u662f\u53cd\u8fc7\u6765\u3002 \u4e58\u5ba2\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e09\u7247\uff0c\u4f8b\u5982\u5bf9\u4e8e\u201c\u6211\u201d\u8fd9\u4e2a\u4e58\u5ba2\uff0c\u201c\u6211\u201d\u7684\u7801\u70b9\u662f 0x6211\uff0c\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u662f\uff1a 110001000010001 \u628a\u4e58\u5ba2\u5207\u5206\u6210\u9ad8 4 \u4f4d\u3001\u4e2d 6 \u4f4d\u548c\u4f4e 6 \u4f4d\uff08\u4e0d\u8db3\u65f6\u5728\u524d\u9762\u8865\u96f6\uff09\uff1a 0110 001000 010001 \u52a0\u4e0a 1110 \u3001 10 \u548c 10 \u524d\u7f00\u540e\uff0c\u5f62\u6210\u4e00\u5217\u706b\u8f66\uff1a 11100110 10001000 10010001 \u8fd9\u6837\uff0c\u6211\u4eec\u5c31\u628a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\uff0c\u7f16\u7801\u6210\u4e86\u4e09\u8282\u5217\u8f66\uff0c\u585e\u8fdb\u5b57\u8282\u6d41\u7684\u7f51\u7edc\u96a7\u9053\u91cc\u4e86\u3002 \u603b\u7ed3\uff1a \u524d\u7f00\u662f 0 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 7 \u540d\u3002 \u524d\u7f00\u662f 10 \u7684\u662f\u8f66\u53a2\uff1a\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002 \u524d\u7f00\u662f 110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 5 \u540d + 1 \u8282\u8f66\u53a2\u8f7d\u5ba2 6 \u540d = \u5171 11 \u540d\u3002 \u524d\u7f00\u662f 1110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 4 \u540d + 2 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 16 \u540d\u3002 \u524d\u7f00\u662f 11110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 3 \u540d + 3 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 21 \u540d\u3002 \u9ad8\u7ea7\u8f66\u5934\u88c5\u4e86\u9632\u5f39\u94a2\u677f\uff0c\u8f7d\u5ba2\u7a7a\u95f4\u53d8\u5c11\uff0c\u53ea\u597d\u5300\u5230\u540e\u9762\u7684\u8f66\u53a2\u3002 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u5982\u679c\u53d1\u73b0 10 \u5f00\u5934\u7684\u72ec\u7acb\u8f66\u53a2\uff0c\u5c31\u8bf4\u660e\u51fa\u95ee\u9898\u4e86\uff0c\u53ef\u80fd\u662f\u706b\u8f66\u88ab\u9519\u8bef\u62e6\u8170\u622a\u65ad\uff0c\u4e5f\u53ef\u80fd\u662f\u5b57\u7b26\u4e32\u88ab\u9519\u8bef\u5730\u53cd\u8f6c\u3002\u56e0\u4e3a 10 \u53ea\u53ef\u80fd\u662f\u706b\u8f66\u8f66\u53a2\uff0c\u4e0d\u53ef\u80fd\u51fa\u73b0\u5728\u706b\u8f66\u5934\u90e8\u3002\u6b64\u65f6\u89e3\u7801\u5668\u5e94\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u66ff\u6362\u3002 10000010 10000001 \u5728\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u5982\u679c\u4f60\u4e0d\u59a5\u5584\u5904\u7406 TCP \u7c98\u5305\u95ee\u9898\uff0c\u5c31\u53ef\u80fd\u706b\u8f66\u5934\u8fdb\u53bb\u4e86\uff0c\u706b\u8f66\u5c3e\u5df4\u8fd8\u9732\u5728\u96a7\u9053\u5916\u9762\uff0c\u4e00\u6bb5\u5b8c\u6574\u7684\u5217\u8f66\u88ab\u5207\u65ad\uff0c\u5bfc\u81f4 UTF-8 \u89e3\u8bfb\u7684\u65f6\u5019\u51fa\u9519\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u8bbe\u7acb\u4e00\u4e2a\u72b6\u6001\u673a\u6765\u89e3\u7801 UTF-8\u3002C \u8bed\u8a00\u7684 mbstate_t \u5c31\u662f\u8fd9\u79cd\u72b6\u6001\u673a\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u9664\u6b64\u4e4b\u5916\uff0c\u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\uff0c\u5374\u53d1\u73b0\u91cc\u9762\u88c5\u7740 0x394 (\u201c\u0394\u201d)\uff0c\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u5c31\u80fd\u88c5\u4e0b\u7684\u6b27\u6d32\u5b57\u7b26\uff0c\u5374\u7528\u4e86\u4e09\u7ea7\u706b\u8f66\u5934\u88c5\uff0c\u8bf4\u660e\u88c5\u7bb1\u90a3\u8fb9\u7684\u4eba\u5077\u61d2\u6ee5\u7528\u8d44\u6e90\u4e86\uff01\u8fd9\u79cd\u60c5\u51b5\u4e0b UTF-8 \u89e3\u7801\u5668\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u8981\u4fdd\u8bc1\u7f16\u7801\u7684\u552f\u4e00\u6027\uff0c0x394 \u662f 0x7F \u5230 0x7FF \u8303\u56f4\u7684\uff0c\u5c31\u5e94\u8be5\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u88c5\u3002 \u4ee5\u53ca\uff0c\u5982\u679c\u53d1\u73b0 11111 \u5f00\u5934\u7684\u4e94\u7ea7\u706b\u8f66\u5934\uff0c\u4e5f\u8981\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u6700\u591a\u53ea\u652f\u6301\u56db\u7ea7\u706b\u8f66\u5934\u3002 \u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u56db\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u7684\u5b57\u7b26\u8303\u56f4\u8d85\u8fc7\u4e86 0x10FFFF\uff0c\u8fd9\u8d85\u51fa\u4e86 Unicode \u7684\u8303\u56f4\uff0c\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\u3002\u5982\u679c\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u53d1\u73b0\u5b57\u7b26\u8303\u56f4\u5904\u5728\u4fdd\u7559\u533a 0xD800 \u5230 0xDFFF \u5185\uff0c\u8fd9\u662f Unicode \u627f\u8bfa\u6c38\u4e0d\u52a0\u5165\u5b57\u7b26\u7684\u533a\u95f4\uff08\u7a0d\u540e\u8bb2\u89e3 UTF-16 \u65f6\u4f1a\u89e3\u91ca\u4e3a\u4ec0\u4e48\uff09\uff0c\u4e5f\u8981\u62a5\u9519\u3002\u603b\u4e4b Unicode \u7801\u70b9\u7684\u5408\u6cd5\u8303\u56f4\u662f 0x0 \u5230 0xD7FF\uff0c0xE000 \u5230 0x10FFFF\u3002 \u603b\u4e4b\uff0cUTF-8 \u5177\u6709\u4e00\u5b9a\u7684\u5197\u4f59\u548c\u81ea\u7ea0\u9519\u80fd\u529b\uff0c\u5982\u679c\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u5dee\u9519\uff0c\u53ef\u80fd\u4f1a\u7206\u51fa\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u3002\u8fd9\u4e2a\u7279\u6b8a\u5b57\u7b26\u662f Unicode \u5b98\u65b9\u89c4\u5b9a\u7684\uff0c\u7801\u70b9\u4e3a 0xFFFD\uff0c\u51fa\u73b0\u4ed6\u5c31\u610f\u5473\u7740 UTF-8 \u89e3\u7801\u5931\u8d25\u4e86\u3002 \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u4ee5 UTF-8 \u683c\u5f0f\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff1a std::vector s = { 0xE6, 0x88, 0x91, // \u6211\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xE7, 0x88, 0xB1, // \u7231\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xE9, 0x9D, 0xA2, // \u9762\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0x21, // !\uff0c\u8fd9\u662f\u4e2a ASCII \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u76f4\u63a5\u7528\u5355\u4e2a\u706b\u8f66\u5934\u88c5 }; UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u53ef\u80fd\u5bf9\u5e94\u591a\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u662f\u4e00\u79cd \u53d8\u957f\u7f16\u7801 \u3002\u53d8\u957f\u7f16\u7801\u7684\u7f3a\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4e0d\u4e00\u5b9a\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002\u56e0\u6b64\uff0c\u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\u3002 \u6570\u7ec4\u7684\u5355\u4e2a\u5143\u7d20\u7d22\u5f15\uff0c\u65e0\u6cd5\u4fdd\u8bc1\u53d6\u51fa\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u3002 \u5bf9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u53ef\u80fd\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u5207\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u4e0d\u4e00\u5b9a\u80fd\u628a\u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\uff0c\u56e0\u4e3a\u53ef\u80fd\u4e0d\u614e\u628a\u4e00\u4e2a\u5b57\u7b26\u7684\u591a\u4e2a\u7801\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u5b57\u7b26\u7834\u574f\u3002 \u4f18\u70b9\u662f\uff1a \u8282\u7ea6\u5b58\u50a8\u7a7a\u95f4\u3002 \u6211\u4eec\u63a8\u8350\u53ea\u5728\u7f51\u7edc\u901a\u4fe1\u3001\u786c\u76d8\u5b58\u50a8\u65f6\uff0c\u91c7\u7528 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u6587\u5b57\u3002 \u603b\u7ed3\uff1a UTF-8 \u9002\u5408\u5b58\u50a8\uff0cUTF-32 \u9002\u5408\u5904\u7406 \u3002 \u6211\u4eec\u5efa\u8bae\u8ba1\u7b97\u673a\u4ece\u786c\u76d8\u6216\u7f51\u7edc\u4e2d\u8bfb\u51fa UTF-8 \u5b57\u7b26\u4e32\u540e\uff0c\u7acb\u5373\u5c06\u5176\u8f6c\u6362\u4e3a UTF-32\uff0c\u4ee5\u65b9\u4fbf\u540e\u7eed\u6587\u5b57\u5904\u7406\u3002\u5f53\u9700\u8981\u5199\u5165\u786c\u76d8\u6216\u7f51\u7edc\u65f6\uff0c\u518d\u8f6c\u6362\u56de UTF-8\uff0c\u907f\u514d\u786c\u76d8\u5bb9\u91cf\u548c\u7f51\u7edc\u5e26\u5bbd\u7684\u6d6a\u8d39\u3002 \u8ba1\u7b97\u673a\u9700\u8981\u5916\u7801\u548c\u5185\u7801\u4e24\u79cd\uff1a \u5916\u7801=\u786c\u76d8\u4e2d\u7684\u6587\u672c=UTF-8 \u5185\u7801=\u5185\u5b58\u4e2d\u7684\u6587\u672c=UTF-32 UTF-16 UTF-16 \u7684\u7b56\u7565\u662f\uff1a\u65e2\u7136\u5927\u591a\u6570\u5e38\u7528\u5b57\u7b26\u7684\u7801\u70b9\u90fd\u5728 0x0 \u5230 0xFFFF \u5185\uff0c\u7528 uint32_t \u6765\u5b58\u50a8\u4e5f\u592a\u6d6a\u8d39\u4e86\u3002\u4ed6\u7684\u65b9\u6848\u5982\u4e0b\uff1a \u5bf9\u4e8e 0x0 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u5c31\u7528\u4e00\u4e2a uint16_t \u76f4\u63a5\u5b58\u3002 \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u53cd\u6b63\u4e0d\u5e38\u89c1\uff0c\u5c31\u62c6\u6210\u4e24\u4e2a uint16_t \u5b58\u3002\u8fd9\u4e2a\u62c6\u7684\u65b9\u6848\u5f88\u6709\u8bb2\u7a76\uff0c\u5982\u679c\u53ea\u662f\u666e\u901a\u7684\u62c6\uff0c\u7531\u4e8e\u89e3\u7801\u65f6\u6536\u5230\u7684\u662f\u4e2a\u6ca1\u5934\u6ca1\u5c3e\u7684\u5b57\u8282\u5e8f\u5217\uff0c\u65e0\u6cd5\u5206\u8fa8\u8fd9\u5230\u5e95\u662f\u4e24\u4e2a uint16_t \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u8fd8\u662f\u4e00\u4e2a uint16_t \u7684\u666e\u901a\u5b57\u7b26\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u628a\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u201c\ud883\udede\u201d\uff0c0x30EDE\u3002\u62c6\u6210\u4e24\u4e2a uint16_t \uff0c\u5f97\u5230 0x3 \u548c 0x0EDE\u3002\u5982\u679c\u76f4\u63a5\u5b58\u50a8\u8fd9\u4e24\u4e2a uint16_t \uff1a 0x0003 0x0EDE \u4e4b\u540e\u89e3\u7801\u65f6\uff0c\u5148\u8bfb\u5230 0x0003\uff0c\u8fd8\u4f1a\u4ee5\u4e3a\u4ed6\u662f\u5355\u72ec\u7684\u4e00\u4e2a uint16_t \uff0c\u8868\u793a 3 \u53f7\u5b57\u7b26\u201c\u201d\u3002\u540e\u9762\u7684 0x0EDE \u5c31\u53d8\u6210\u4e86\u4e00\u4e2a\u5355\u72ec\u7684 0x0EDE\uff0c\u53d8\u6210\u4e86 0x0EDE \u53f7\u5b57\u7b26 \u201c\u0ede\u201d\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u201c\ud883\udede\u201d\u5c31\u53d8\u6210\u4e86\u4e24\u4e2a\u6beb\u4e0d\u76f8\u5e72\u7684\u5b57\u7b26\uff0c\u201c\u0ede\u201d\u4e86\u3002 \u4e3a\u4e86\u907f\u514d\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u4e24\u4e2a uint16_t \u9700\u8981\u91c7\u7528\u4e00\u79cd\u7279\u6b8a\u7684\u65b9\u5f0f\u4ee5\u793a\u533a\u5206\u3002\u8ba9\u89e3\u7801\u5668\u4e00\u770b\u5230\uff0c\u5c31\u80fd\u786e\u5b9a\u8fd9\u4e24\u4e2a uint16_t \u9700\u8981\u7ec4\u88c5\u6210\u540c\u4e00\u4e2a\u5b57\u7b26\u3002 \u8fd9\u5c31\u7528\u5230\u4e86\u4e00\u4e2a\u201c\u6f0f\u6d1e\u201d\uff1aUnicode \u5e76\u6ca1\u6709\u628a\u7801\u70b9\u5206\u914d\u7684\u6ee1\u6ee1\u5f53\u5f53\uff0c\u6216\u8bb8\u662f\u51fa\u4e8e\u5148\u89c1\u4e4b\u660e\uff0c\u5728 0xD800 \u5230 0xDFFF \u4e4b\u95f4\u9884\u7559\u4e86\u4e00\u5927\u6bb5\u7a7a\u53f7\uff1a UTF-16 \u5c31\u662f\u5229\u7528\u4e86\u8fd9\u4e00\u6bb5\u7a7a\u95f4\uff0c\u4ed6\u89c4\u5b9a\uff1a0xD800 \u5230 0xDFFF \u4e4b\u95f4\u7684\u7801\u70b9\u5c06\u6c38\u8fdc\u4e0d\u7528\u6765\u8868\u793a\u5b57\u7b26\uff0c\u800c\u662f\u4f5c\u4e3a \u4ee3\u7406\u5bf9 (surrogate-pair) \u3002\u5176\u4e2d 0xD800 \u5230 0xDBFF \u662f \u9ad8\u4f4d\u4ee3\u7406 (high surrogate) \uff0c0xDC00 \u5230 0xDFFF \u662f \u4f4e\u4f4d\u4ee3\u7406 (low surrogate) \u3002\u9ad8\u4ee3\u7406\u5728\u524d\uff0c\u4f4e\u4ee3\u7406\u5728\u540e\u3002 \u4e00\u4e2a\u8d85\u8fc7 0xFFFF \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f1a\u88ab\u62c6\u6210\u4e24\u6bb5\uff0c\u4e00\u6bb5\u653e\u5728\u9ad8\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u6bb5\u653e\u5728\u4f4e\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u524d\u4e00\u540e\u653e\u5165 uint16_t \u5e8f\u5217\u4e2d\u3002 \u642d\u8f7d\u8d85\u5bbd\u8d85\u9650\u8d27\u7269\u7684\u8f66\u8f86\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e24\u6bb5\u518d\u8fdb\u5165\u96a7\u9053\u3002 \u5177\u4f53\u62c6\u5206\u65b9\u6cd5\u5982\u4e0b\uff1a \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7801\u70b9\uff0c\u9996\u5148\u5c06\u5176\u503c\u51cf\u53bb 0x10000\uff0c\u53d8\u6210\u4e00\u4e2a\u8303\u56f4 0x0 \u5230 0xFFFFF \u8303\u56f4\u5185\u7684\u6570\u5b57\uff0c\u8fd9\u80fd\u4fdd\u8bc1\u4ed6\u4eec\u53ea\u9700 20 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u53ef\u8868\u793a\u3002 \u4f8b\u5982\u201c\ud883\udede\u201d\u5bf9\u5e94\u7684\u7801\u70b9 0x30EDE\uff0c\u51cf\u53bb\u540e\u5c31\u53d8\u6210 0x20EDE\u3002 \u7136\u540e\uff0c\u5199\u51fa 0x20EDE \u7684\u4e8c\u8fdb\u5236\u8868\u793a\uff1a 00100000111011011110 \u603b\u5171 20 \u4f4d\uff0c\u6211\u4eec\u5c06\u5176\u62c6\u6210\u9ad8\u4f4e\u5404 10 \u4f4d\uff1a 0010000011 1011011110 \u5404\u81ea\u5199\u51fa\u76f8\u5e94\u7684\u5341\u516d\u8fdb\u5236\u6570\uff1a 0x083 0x2DE \u56e0\u4e3a\u6700\u591a\u53ea\u6709 10 \u4f4d\uff0c\u8fd9\u4e24\u4e2a\u6570\u90fd\u4f1a\u5728 0 \u5230 0x3FF \u7684\u8303\u56f4\u5185\u3002 \u800c 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u9884\u7559\u7684\u7a7a\u95f4\uff0c\u521a\u597d\u53ef\u4ee5\u5206\u522b\u5bb9\u7eb3 0x400 \u4e2a\u6570\uff01 \u6240\u4ee5\uff0c\u6211\u4eec\u5c06\u62c6\u5206\u51fa\u6765\u7684\u4e24\u4e2a 10 \u4f4d\u6570\uff0c\u5206\u522b\u52a0\u4e0a 0xD800 \u548c 0xDC00\uff1a 0xD800+0x083=0xD883 0xDC00+0x2DE=0xDFDE \u8fd9\u4e24\u4e2a\u6570\uff0c\u5fc5\u5b9a\u662f 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u6570\u3002\u800c\u8fd9\u4e24\u4e2a\u8303\u56f4\u90fd\u662f Unicode \u59d4\u5458\u4f1a\u9884\u7559\u7684\u4ee3\u7406\u5bf9\u533a\u95f4\uff0c\u7edd\u5bf9\u6ca1\u6709\u666e\u901a\u5b57\u7b26\u3002\u6240\u4ee5\uff0c\u751f\u6210\u7684\u4e24\u4e2a\u4ee3\u7406\u5bf9\u4e0d\u4f1a\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u53ef\u4ee5\u653e\u5fc3\u653e\u8fdb uint16_t \u6570\u7ec4\uff0c\u89e3\u7801\u5668\u5982\u679c\u68c0\u6d4b\u5230\u4ee3\u7406\u5bf9\uff0c\u5c31\u8bf4\u660e\u662f\u4e24\u8282\u8f66\u53a2\uff0c\u53ef\u4ee5\u653e\u5fc3\u8fde\u7eed\u8bfb\u53d6\u4e24\u4e2a uint16_t \u3002 \u6240\u4ee5\uff0c 0xD883 0xDFDE \u5c31\u662f\u201c\ud883\udede\u201d\u7528 UTF-16 \u7f16\u7801\u540e\u7684\u7ed3\u679c\u3002 \u4ee3\u7406\u5b57\u7b26\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\uff0c\u5f53\u89e3\u7801\u5668\u68c0\u6d4b\u5230\u4e00\u4e2a 0xD800 \u5230 0xDBFF \u8303\u56f4\u5185\u7684\u9ad8\u4ee3\u7406\u65f6\uff0c\u5c31\u9884\u793a\u7740\u8fd8\u9700\u8981\u518d\u8bfb\u53d6\u4e00\u4e2a\u4f4e\u4ee3\u7406\uff0c\u624d\u80fd\u62fc\u63a5\u6210\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u3002 \u5982\u679c\u63a5\u4e0b\u6765\u8bfb\u5230\u7684\u4e0d\u662f 0xDC00 \u5230 0xDFFF \u8303\u56f4\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u800c\u662f\u666e\u901a\u5b57\u7b26\u7684\u8bdd\uff0c\u90a3\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u53ef\u80fd\u662f\u4e2d\u95f4\u88ab\u4eba\u4e22\u5305\u4e86\uff0c\u9700\u8981\u62a5\u9519\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u9876\u66ff\u3002 \u53e6\u5916\uff0c\u5982\u679c\u8bfb\u5230\u4e86\u4e00\u4e2a\u5355\u72ec\u5b58\u5728\u7684 0xD800 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u90a3\u4e5f\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u56e0\u4e3a\u4ee3\u7406\u5b57\u7b26\u53ea\u6709\u6210\u5bf9\u51fa\u73b0\u624d\u6709\u610f\u4e49\uff0c\u4f4e\u4ee3\u7406\u5b57\u7b26\u4e0d\u53ef\u80fd\u5355\u72ec\u5728\u5f00\u5934\u51fa\u73b0\u3002 \u53ef\u89c1\uff0cUTF-16 \u548c UTF-8 \u4e00\u6837\uff0c\u90fd\u662f\u201c\u5c0f\u706b\u8f66\u201d\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0cUTF-16 \u540c\u6837\u4e5f\u6709\u7740\u7c7b\u4f3c\u4e8e UTF-8 \u7684\u6297\u5e72\u6270\u673a\u5236\u3002 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 \u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u591a\u5b57\u8282\u7684\u6574\u6570\u7c7b\u578b\uff08\u5982 uint16_t \u548c uint32_t \uff09\u9700\u8981\u88ab\u62c6\u6210\u591a\u4e2a\u5b57\u8282\u6765\u5b58\u50a8\u3002\u62c6\u5f00\u540e\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u6309\u4ec0\u4e48\u987a\u5e8f\u5b58\u5165\u5185\u5b58\uff1f\u4e0d\u540c\u7684\u786c\u4ef6\u67b6\u6784\u4ea7\u751f\u4e86\u4e89\u6267\uff1a \u5927\u7aef\u6d3e (bit endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u4e5f\u5c31\u662f\u5927\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5c0f\u7aef\u6d3e (little endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u4e5f\u5c31\u662f\u5c0f\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u8ba1\u7b97\u673a\u7535\u8def\u7684\u8ba1\u7b97\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x78 0x56 0x34 0x12 \u4f8b\u5982\uff0cIntel \u7684 x86 \u67b6\u6784\u548c ARM \u516c\u53f8\u7684 ARM \u67b6\u6784\u90fd\u662f\u5c0f\u7aef\u6d3e\uff0c\u800c Motorola \u516c\u53f8\u7684 68k \u67b6\u6784\u548c Sun \u516c\u53f8\u7684 SPARC \u67b6\u6784\u90fd\u662f\u5927\u7aef\u6d3e\u3002 \u8fd9\u5176\u5b9e\u662f\u5f88\u65e0\u804a\u7684\u4e89\u6267\uff0c\u4e3a\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u6539\u53d8\u8ba1\u7b97\u673a\u7684\u8bbe\u8ba1\u6beb\u65e0\u9053\u7406\uff0c\u6bd5\u7adf\u4e16\u754c\u4e0a\u4e5f\u6709\u4ece\u53f3\u5f80\u5de6\u4e66\u5199\u7684\u6587\u5b57\u548c\u4ece\u4e0a\u5f80\u4e0b\u4e66\u5199\u7684\u6587\u5b57\uff0c\u751a\u81f3\u6709\u5de6\u53f3\u6765\u56de\u4e66\u5199\u7684\u6587\u5b57\u2026\u2026\u5982\u679c\u8981\u4f3a\u5019\u4eba\u7c7b\uff0c\u4f60\u600e\u4e48\u4e0d\u6539\u6210\u5341\u8fdb\u5236\u5462\uff1f\u603b\u4e4b\uff0c\u6211\u8ba4\u4e3a\u5c0f\u7aef\u624d\u662f\u6700\u9002\u5408\u8ba1\u7b97\u673a\u7684\uff0c\u5e02\u9762\u4e0a\u5927\u591a\u6570\u4e3b\u6d41\u786c\u4ef6\u90fd\u662f\u5c0f\u7aef\u67b6\u6784\u3002 \u5728\u7f51\u7edc\u901a\u4fe1\u65f6\uff0c\u53d1\u6d88\u606f\u548c\u6536\u6d88\u606f\u7684\u53ef\u80fd\u662f\u4e0d\u540c\u7684\u67b6\u6784\uff0c\u5982\u679c\u53d1\u6d88\u606f\u7684\u662f\u5c0f\u7aef\u67b6\u6784\uff0c\u6536\u6d88\u606f\u7684\u662f\u5927\u7aef\u67b6\u6784\uff0c\u90a3\u4e48\u53d1\u51fa\u53bb\u7684\u662f 0x12345678\uff0c\u6536\u5230\u7684\u5c31\u4f1a\u53d8\u6210 0x78563421 \u4e86\u3002 \u56e0\u6b64\u4e92\u8054\u7f51\u4e00\u822c\u89c4\u5b9a\uff0c\u6240\u6709\u591a\u5b57\u8282\u7684\u6570\u636e\u5728\u7f51\u7edc\u5305\u4e2d\u7edf\u4e00\u91c7\u7528\u5927\u7aef\u3002\u5bf9\u4e8e\u5927\u7aef\u67b6\u6784\uff0c\u4ed6\u4eec\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u5bf9\u4e8e\u5c0f\u7aef\u67b6\u6784\uff0c\u5728\u53d1\u5305\u524d\u9700\u8981\u628a\u81ea\u5df1\u7684\u5c0f\u7aef\u6570\u636e\u505a\u5b57\u8282\u5e8f\u53cd\u8f6c\uff0c\u53d8\u6210\u5927\u7aef\u7684\u4ee5\u540e\uff0c\u518d\u53d1\u9001\u3002\u4e4b\u540e\u7684\u7f51\u7edc\u4e13\u9898\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u89e3\u8fd9\u4e00\u5757\u3002 \u57fa\u4e8e\u5b57\u8282\u7801\u7684\u865a\u62df\u673a\u8bed\u8a00\u901a\u5e38\u4f1a\u89c4\u5b9a\u4e00\u4e2a\u5b57\u8282\u5e8f\uff1a\u50cf Java \u8fd9\u79cd\u9762\u5411\u4e92\u8054\u7f51\u8bed\u8a00\uff0c\u7d22\u6027\u4e5f\u89c4\u5b9a\u4e86\u7edf\u4e00\u91c7\u7528\u5927\u7aef\uff0c\u65e0\u8bba JVM \u8fd0\u884c\u5728\u5927\u7aef\u673a\u5668\u8fd8\u662f\u5c0f\u7aef\u673a\u5668\u4e0a\u3002\u8fd9\u4f7f\u5f97\u4ed6\u4e0e\u4e92\u8054\u7f51\u901a\u4fe1\u6bd4\u8f83\u65b9\u4fbf\uff0c\u800c\u5728 x86 \u548c ARM \u67b6\u6784\u4e0a\uff0c\u4e0e\u672c\u5730\u53ea\u63a5\u53d7\u5c0f\u7aef\u6570\u636e\u7684 API\uff0c\u4f8b\u5982 OpenGL\uff0c\u6c9f\u901a\u8f83\u4e3a\u56f0\u96be\uff0c\u9700\u8981\u505a\u989d\u5916\u7684\u5b57\u8282\u5e8f\u8f6c\u6362\u3002\u800c C# \u4e3b\u6253\u6e38\u620f\u4e1a\u52a1\uff08\u4f8b\u5982 Unity\uff09\uff0c\u9700\u8981\u8003\u8651\u6027\u80fd\uff0c\u6240\u4ee5\u89c4\u5b9a\u5168\u90e8\u91c7\u7528\u5c0f\u7aef\u3002\u4f5c\u4e3a\u5e95\u5c42\u7f16\u7a0b\u8bed\u8a00\u7684 C++ \u5219\u662f\u5165\u4e61\u968f\u4fd7\uff0c\u4f60\u7684\u786c\u4ef6\u662f\u4ec0\u4e48\u7aef\uff0c\u4ed6\u5c31\u662f\u4ec0\u4e48\u7aef\uff0c\u4e0d\u4e3b\u52a8\u505a\u4efb\u4f55\u989d\u5916\u7684\u8f6c\u6362\u3002 UTF-16 \u548c UTF-32 \u7684\u7801\u4f4d\u90fd\u662f\u591a\u5b57\u8282\u7684\uff0c\u4e5f\u4f1a\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u3002\u4f8b\u5982\uff0cUTF-16 \u4e2d\u7684 uint16_t \u5e8f\u5217\uff1a 0x1234 0x5678 \u5728\u5927\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5728\u5c0f\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x34 0x12 0x78 0x56 \u8fd9\u6837\u4e00\u6765\uff0cUTF-16 \u548c UTF-32 \u7684\u5b57\u8282\u6d41\uff0c\u5728\u4e0d\u540c\u7684\u673a\u5668\u4e0a\uff0c\u53ef\u80fd\u4f1a\u6709\u4e0d\u540c\u7684\u987a\u5e8f\u3002\u8fd9\u7ed9\u8de8\u5e73\u53f0\u7684\u6587\u672c\u5904\u7406\u5e26\u6765\u4e86\u9ebb\u70e6\u3002 \u6240\u4ee5\u5f53\u4f60\u9700\u8981\u628a UTF-16 \u5b58\u5165\u786c\u76d8\u548c\u5728\u7f51\u7edc\u53d1\u9001\u65f6\uff0c\u8fd8\u9700\u8981\u989d\u5916\u6307\u660e\u4f60\u7528\u7684\u662f\u5927\u7aef\u7684 UTF-16 \u8fd8\u662f\u5c0f\u7aef\u7684 UTF-16\u3002 \u56e0\u6b64 UTF-16 \u548c UTF-32 \u8fdb\u4e00\u6b65\u5206\u88c2\u4e3a\uff1a UTF-16LE\uff1a\u5c0f\u7aef\u7684 UTF-16 UTF-16BE\uff1a\u5927\u7aef\u7684 UTF-16 UTF-32LE\uff1a\u5c0f\u7aef\u7684 UTF-32 UTF-32BE\uff1a\u5927\u7aef\u7684 UTF-32 \u5982\u679c\u53ea\u5728\u5185\u5b58\u7684 wchar_t \u4e2d\u4f7f\u7528\u5c31\u4e0d\u7528\u533a\u5206\uff0c\u9ed8\u8ba4\u8ddf\u968f\u5f53\u524d\u673a\u5668\u7684\u5927\u5c0f\u7aef\u3002\u6240\u4ee5 UTF-16 \u548c UTF-32 \u901a\u5e38\u53ea\u4f1a\u51fa\u73b0\u5728\u5185\u5b58\u4e2d\u7528\u4e8e\u5feb\u901f\u5904\u7406\u548c\u8ba1\u7b97\uff0c\u5f88\u5c11\u7528\u5728\u5b58\u50a8\u548c\u901a\u4fe1\u4e2d\u3002 UTF-8 \u662f\u57fa\u4e8e\u5355\u5b57\u8282\u7684\u7801\u4f4d\uff0c\u706b\u8f66\u5934\u7684\u987a\u5e8f\u4e5f\u6709\u4e25\u683c\u89c4\u5b9a\uff0c\u706b\u8f66\u5934\u603b\u662f\u5728\u6700\u524d\uff0c\u6839\u672c\u4e0d\u53d7\u5b57\u8282\u5e8f\u5927\u5c0f\u7aef\u5f71\u54cd\uff0c\u4e5f\u5c31\u6ca1\u6709\u5f71\u54cd\u3002 \u7531\u4e8e\u538b\u7f29\u7387\u4f4e\uff0c\u53c8\u5b58\u5728\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u800c\u4e92\u8054\u7f51\u6570\u636e\u9700\u8981\u4fdd\u8bc1\u76f8\u540c\u7684\u5927\u5c0f\u7aef\uff0c\u5728\u6536\u53d1\u5305\u65f6\u9700\u8981\u989d\u5916\u8f6c\u6362\uff0c\u56e0\u800c\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u7f51\u7edc\u3002\u800c UTF-8 \u7684\u5b58\u50a8\u5355\u4f4d\u662f\u5b57\u8282\uff0c\u5929\u751f\u6ca1\u6709\u5927\u5c0f\u7aef\u56f0\u6270\u3002\u66f4\u5999\u7684\u662f\uff0c\u4ed6\u4e14\u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u800c\u4e92\u8054\u7f51\u53c8\u662f\u53e4\u8463\u4e2d\u95f4\u4ef6\u6700\u591a\u7684\u5730\u65b9\u2026\u2026 \u603b\u4e4b\uff0c\u5b8c\u5168\u57fa\u4e8e\u5b57\u8282\u7684 UTF-8 \u662f\u6700\u9002\u5408\u7f51\u7edc\u901a\u4fe1\u548c\u786c\u76d8\u5b58\u50a8\u7684\u6587\u672c\u7f16\u7801\u683c\u5f0f\uff0c\u800c UTF-32 \u662f\u6700\u9002\u5408\u5728\u5185\u5b58\u4e2d\u5904\u7406\u7684\u683c\u5f0f\u3002 BOM \u6807\u8bb0 0xFEFF \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u4e0d\u53ef\u89c1\u5b57\u7b26\u201c\ufeff\u201d\uff0c\u8fd9\u662f\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u6ca1\u6709\u4efb\u4f55\u6548\u679c\u3002 \u4f60\u53ef\u4ee5\u628a\u8fd9\u4e2a\u5b57\u7b26\u52a0\u5728\u6587\u672c\u6587\u4ef6\u7684\u5934\u90e8\uff0c\u544a\u8bc9\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\uff0c\u8fd9\u4e2a\u6587\u4ef6\u662f\u7528\u4ec0\u4e48\u7f16\u7801\u7684\u3002 \u5982\u679c\u662f UTF-16 \u548c UTF-32\uff0c\u56e0\u4e3a 0xFEFF \u4e0d\u5bf9\u79f0\uff0c\u4ed6\u8fd8\u80fd\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\u3002\u56e0\u6b64 0xFEFF \u88ab\u79f0\u4e3a\u5b57\u8282\u5e8f\u6807\u5fd7\uff08Byte-order-mark\uff0cBOM\uff09\u3002 \u5982\u679c\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u90a3\u4e48\u4ed6\u7167\u5e38\u8bfb\u51fa 0xFEFF\uff0c\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u5728\u6587\u672c\u4e2d\u4e0d\u663e\u793a\uff0c\u4e0d\u5f71\u54cd\u89c6\u89c9\u7ed3\u679c\u3002 \u4e00\u4e9b\u8001\u7684\u7f16\u8bd1\u5668\uff08\u8fdc\u53e4 MinGW\uff0c\u73b0\u5728\u5df2\u7ecf\u6ca1\u6709\u4e86\uff09\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u4f1a\u628a\u5e26\u6709 BOM \u7684 UTF-8 \u7684 .cpp \u6e90\u7801\u6587\u4ef6\uff0c\u5f53\u4f5c\u5934\u90e8\u5e26\u6709\u9519\u8bef\u5b57\u7b26\u7684\u4e71\u7801\u6587\u4ef6\uff0c\u4ece\u800c\u62a5\u9519\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u7684\u8bb0\u4e8b\u672c\u4fdd\u5b58\u4e3a UTF-8 \u65f6\uff0c\u603b\u662f\u4f1a\u52a0\u4e0a BOM\u3002\u5982\u679c\u8bb0\u4e8b\u672c\u53d1\u73b0\u4e00\u4e2a\u6587\u4ef6\u6ca1\u6709 BOM\uff0c\u4f1a\u5f53\u4f5c ANSI\uff08GBK\uff09\u6765\u8bfb\u53d6\u3002 0xFEFF \u5728\u4e0d\u540c\u7684\u7f16\u7801\u4e0b\u4f1a\u4ea7\u751f\u4e0d\u540c\u7684\u7ed3\u679c\uff1a UTF-8\uff1a 0xEF 0xBB 0xBF \uff0c\u4ed6\u4f1a\u5360\u7528 3 \u5b57\u8282\uff0c\u800c\u4e14\u4e0d\u4f1a\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\uff0c\u56e0\u4e3a UTF-8 \u662f\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u7684\u3002 UTF-16\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE \u3002 UTF-32\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0x00 0x00 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE 0x00 0x00 \u3002 \u56e0\u6b64\uff0c\u5728\u6587\u672c\u5934\u90e8\u52a0\u4e0a BOM \u6709\u52a9\u4e8e\u8f6f\u4ef6\u63a8\u6d4b\u8be5\u6587\u4ef6\u662f\u4ec0\u4e48\u7f16\u7801\u7684\uff08\u5982\u679c\u90a3\u8f6f\u4ef6\u652f\u6301\u89e3\u6790 BOM \u7684\u8bdd\uff09\u3002 \u4f8b\u5982 Windows \u73af\u5883\u4e2d\uff0c\u6240\u6709\u7684\u6587\u672c\u6587\u4ef6\u90fd\u88ab\u9ed8\u8ba4\u5047\u5b9a\u4e3a ANSI\uff08GBK\uff09\u7f16\u7801\uff0c\u5982\u679c\u4f60\u8981\u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u4e3a UTF-8 \u7f16\u7801\uff0c\u5c31\u9700\u8981\u52a0\u4e0a BOM \u6807\u5fd7\u3002\u5f53 MSVC \u8bfb\u53d6\u65f6\uff0c\u770b\u5230\u5f00\u5934\u662f 0xEF 0xBB 0xBF \uff0c\u5c31\u660e\u767d\u8fd9\u662f\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u6587\u4ef6\u3002\u8fd9\u6837\uff0cMSVC \u5c31\u80fd\u6b63\u786e\u5730\u5904\u7406\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4e86\u3002\u5982\u679c MSVC \u6ca1\u770b\u5230 BOM\uff0c\u4f1a\u9ed8\u8ba4\u4ee5\u4e3a\u662f ANSI\uff08GBK\uff09\u7f16\u7801\u7684\uff0c\u4ece\u800c\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4f1a\u4e71\u7801\u3002\u5f00\u542f /utf-8 \u9009\u9879\u4e5f\u80fd\u8ba9 MSVC \u628a\u6ca1\u6709 BOM \u7684\u6e90\u7801\u6587\u4ef6\u5f53\u4f5c UTF-8 \u6765\u89e3\u6790\uff0c\u9002\u5408\u8de8\u5e73\u53f0\u5b9d\u5b9d\u4f53\u8d28\u3002 \u5176\u5b9e Windows \u7528\u6237\u53ef\u4ee5\u5728\u63a7\u5236\u9762\u677f\u7684\u201c\u65f6\u949f\u548c\u533a\u57df\u201d\u91cc\uff0c\u627e\u5230\u201c\u533a\u57df\u201d\u9009\u9879\u3002\u5728\u201c\u533a\u57df\u201d\u9009\u9879\u5361\u91cc\uff0c\u70b9\u51fb\u201c\u66f4\u6539\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u7136\u540e\u5f39\u51fa\u7684\u5bf9\u8bdd\u6846\u91cc\uff0c\u52fe\u9009\u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u63d0\u4f9b\u5168\u7403\u8bed\u8a00\u652f\u6301\u201d\uff0c\u91cd\u542f\u540e\uff0c\u5c31\u53ef\u4ee5\u5728\u7a0b\u5e8f\u4e2d\u9ed8\u8ba4\u4f7f\u7528 UTF-8\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684 GBK \u4e86\u3002\u8fd9\u4f1a\u628a ANSI \u53d8\u6210 UTF-8\uff0c\u8ba9\u8bb0\u4e8b\u672c\u7b49\u8f6f\u4ef6\u628a\u65e0 BOM \u7684\u6587\u4ef6\u90fd\u5f53\u4f5c UTF-8\uff0c\u8ba9\u5404\u79cd\u8f6f\u4ef6\u90fd\u8ba4\u4e3a\u5b57\u7b26\u4e32\u662f UTF-8 \u7b49\u7b49\u3002\u8fd9\u53ef\u4ee5\u89e3\u51b3\u90e8\u5206\u7f8e\u56fd\u8f6f\u4ef6\u65e0\u6cd5\u5904\u7406\u4e2d\u6587\u3001\u4e71\u7801\u7b49\u95ee\u9898\uff0c\u56e0\u4e3a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u5e38\u5e38\u65e0\u610f\u8bc6\u5730\u7528 UTF-8 \u5b57\u7b26\u4e32\u672a\u7ecf\u5904\u7406\u76f4\u63a5\u8c03\u7528 A \u51fd\u6570\u3002\u4e0d\u8fc7\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4f60\u8fd0\u884c\u5176\u4ed6\u5047\u5b9a\u4e86 GBK \u7684\u4e2d\u56fd\u7279\u4f9b\u7a0b\u5e8f\u4e71\u7801\uff0c\u4e5f\u4f1a\u5bfc\u81f4\u4f60\u7684\u6bd5\u4e1a\u7b54\u8fa9\u5bfc\u5e08\u53d1\u6765\u7684 ZIP \u53d8\u6210\u4e71\u7801\u3002\u800c\u4e14\u6211\u4eec\u4f5c\u4e3a\u5ba2\u6237\u7aef\u7684\u5f00\u53d1\u8005\uff0c\u6211\u4eec\u603b\u4e0d\u80fd\u5f3a\u6c42\u6240\u6709\u5ba2\u6237\u7528\u6211\u4eec\u7684\u8f6f\u4ef6\u524d\uff0c\u6539\u53d8\u4ed6\u4eec\u7684\u63a7\u5236\u9762\u677f\u6765\u9002\u5e94\u6211\u4eec\u7684\u7a0b\u5e8f\u5427\uff1f\u6240\u4ee5\u8fd8\u662f\u9700\u8981\u7ed5\u5f00 GBK\uff0c\u76f4\u63a5\u8c03\u7528 UTF-16 \u7684 W \u7c7b API\u3002 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u53d1\u5e03\u4e8e 1980 \u5e74\uff0c\u662f\u4e00\u4e2a\u53e4\u8001\u7684\u6c49\u5b57\u7f16\u7801\u6807\u51c6\uff0c\u517c\u5bb9 ASCII\u3002 \u201cGB\u201d \u8868\u793a Guo Biao\uff08\u56fd\u6807\uff09\u7684\u610f\u601d\u3002 GB2312 \u89c4\u5b9a\u4e86 6763 \u4e2a\u6c49\u5b57\u548c 682 \u4e2a\u7279\u6b8a\u7b26\u53f7\uff0c\u5171 7445 \u4e2a\u5b57\u7b26\u3002 GB2312 \u8ba9\u82f1\u6587\u548c\u6570\u5b57\u91c7\u7528\u548c ASCII \u76f8\u540c\u7684\u5355\u5b57\u8282\u7f16\u7801\uff0c\u800c\u5bf9\u4e8e\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u91c7\u7528\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u5176\u4e2d\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u7684\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u4e24\u4e2a\u5b57\u8282\u90fd\u5728 0xA1 \u5230 0xFE \u7684\u8303\u56f4\u5185\uff0c\u907f\u514d\u4e86\u4e0e\u5355\u5b57\u8282\u7684 ASCII \u7f16\u7801\u7a7a\u95f4\u51b2\u7a81\u3002 H i \u5f6d \u5b9d 0x48 0x69 0xC5 0xED 0xB1 0xA6 2 \u4e2a\u5b57\u8282\u5206\u522b\u88ab\u79f0\u4e3a\u201c\u533a\u7801\u201d\u548c\u201c\u4f4d\u7801\u201d\uff0c\u8303\u56f4\u90fd\u662f\u5728 0xA1 \u5230 0xFE \u533a\u95f4\u5185\u3002 \u201c\u7279\u6b8a\u7b26\u53f7\u201d\uff0c\u5171 682 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xA1A1 \u5230 0xA9FE\u3002 \u201c\u4e00\u7ea7\u6c49\u5b57\u201d\uff0c\u90fd\u662f\u6bd4\u8f83\u5e38\u7528\u7684\u6c49\u5b57\uff0c\u6309\u62fc\u97f3\u987a\u5e8f\u6392\u5e8f\uff0c\u5171 3755 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xB0A1 \u5230 0xF7FE\u3002 \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u662f\u4e00\u4e9b\u751f\u50fb\u5b57\uff0c\u6309\u90e8\u9996/\u7b14\u753b\u6392\u5e8f\uff0c\u5171 3008 \u4e2a\uff0c\u8fd9\u4e9b\u6c49\u5b57\u7684\u5b57\u7b26\u4ece 0x8140 \u5230 0xA0FE\u3002 GBK \u4e2d\u6c49\u5b57\u7684\u7f16\u53f7\u548c Unicode \u5e76\u4e0d\u662f\u76f8\u540c\u7684\uff0c\u8fd9\u4e5f\u662f GB2312 \u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6\u7528 UTF-8 \u6216 UTF-16 \u6253\u5f00\u4f1a\u4ea7\u751f\u4e71\u7801\u7684\u6839\u672c\u539f\u56e0\u3002 \u4f8b\u5982\u6c49\u5b57 \u201c\u5f6d\u201d \u5c31\u5c5e\u4e8e \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u5728 GB2312 \u4e2d\u7f16\u53f7\u4e3a 0xC5ED\uff0cUnicode \u4e2d\u7f16\u53f7\u4e3a 0x5F6D\u3002 \u5168\u89d2\u7a7a\u683c \u201c\u3000\u201d\uff0c\u5728 GB2312 \u4e2d\u7684\u7f16\u53f7\u4e3a 0xA1A1\uff0cUnicode \u4e2d\u7684\u7f16\u53f7\u4e3a 0x3000\u3002 GB2312 \u7684\u7f3a\u9677 GBK \u548c UTF-8 \u7684\u5171\u540c\u70b9\u5728\u4e8e\uff0c\u4ed6\u4eec\u90fd\u907f\u5f00\u4e86 0 ~ 127 \u7684 ASCII \u7a7a\u95f4\uff0c\u6240\u4ee5\u5b8c\u5168\u517c\u5bb9 ASCII\u3002 \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u5982\u679c\u5728\u4e00\u4e2a GBK \u7f16\u7801\u7684\u4e2d\u6587\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u4e2d\u6587\uff0c\u53ef\u80fd\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\uff0c\u800c UTF-8 \u4e0d\u4f1a\u3002\u8fd9\u662f\u56e0\u4e3a GBK \u6ca1\u6709\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u4ed6\u524d\u540e\u4e24\u4e2a\u8f66\u53a2\u5e76\u6ca1\u6709\u4e0d\u540c\u3002 \u5f53 GBK \u88ab\u5207\u7247\u65f6\uff0c\u5c31\u5bb9\u6613\u51fa\u73b0\u8fde\u9501\u53cd\u5e94\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.substr(1); // \"\u64a9\u683d\u91c7\ufffd\" // \u590d\u73b0\u65b9\u5f0f: MSVC \u4e2d\u56fd\u533a Windows\uff0c/std:c++17\uff0c\u4e0d\u5f00\u542f /utf-8 \u53c2\u6570\uff08\u8fd9\u65f6\u5b57\u7b26\u4e32\u5e38\u91cf\u90fd\u662f GBK \u7f16\u7801\u7684\uff09 \u6838\u53cd\u5e94\u5806\uff0c\u542f\u52a8\uff01 \u7279\u522b\u662f\u5f53\u4f60\u8bd5\u56fe find \u4e00\u4e2a\u4e2d\u6587\u5b50\u5b57\u7b26\u4e32\u65f6\uff0cGBK \u7f16\u7801\u7684\u591a\u5b57\u8282\u5b57\u7b26\u4e32\u53ef\u80fd\u4ea7\u751f\u627e\u5230\u4e86\u7684\u5047\u8c61\u3002\u5b9e\u9645\u4e0a\u627e\u5230\u7684\u4f4d\u7f6e\u6839\u672c\u662f\u5207\u65ad\u4e86\u5355\u4e2a\u5b8c\u6574\u7684\u4e2d\u6587\u5b57\u7b26\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.find(\"\u91c7\"); // 5\uff0c\u628a\u201c\u5706\u201d\u7684\u540e\u534a\u6bb5 0xAD \u548c\u201c\u795e\u201d\u7684\u524d\u534a\u6bb5 0xC9 \u5f53\u6210\u4e00\u4e2a\u5b57\u201c\u91c7\u201d (0xAD 0xC9) \u4e86 \u800c UTF-8 \u5219\u80fd\u6709\u6548\u9650\u5236\u9519\u8bef\u7684\u4f20\u64ad\u3002 std::string u8s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xE6 0xB2 0x89 0xE8 0xBF 0xB7 0xE5 0x9C 0x86 0xE7 0xA5 0x9E std::cout << u8s.substr(1); // \"\ufffd\u8ff7\u5706\u795e\" std::cout << u8s.find(\"\u91c7\"); // \u627e\u4e0d\u5230\uff0c\u8fd4\u56de -1 \u56e0\u4e3a UTF-8 \u7684\u5934\u90e8\u5c0f\u706b\u8f66\u548c\u5c3e\u90e8\u8f66\u53a2\u91c7\u7528\u4e86\u72ec\u7acb\u7684\u7f16\u7801\uff0cfind \u4e0d\u53ef\u80fd\u901a\u8fc7\u4efb\u4f55\u5408\u6cd5\u7684 UTF-8 \u5b50\u5b57\u7b26\u4e32\u5b9a\u4f4d\u5230\u9519\u8bef\u7684\u4e2d\u95f4\u4f4d\u7f6e\u3002 GB2312 \u548c GBK \u7684\u7279\u6b8a\u6027\uff1a\u4ed6\u65e2\u662f\u5b57\u7b26\u96c6\uff0c\u53c8\u662f\u5b57\u7b26\u7f16\u7801\u3002\u9664 Unicode \u5916\u5927\u591a\u6570\u5b57\u7b26\u96c6\u90fd\u662f\u8fd9\u6837\uff0c\u81ea\u5df1\u5c31\u662f\u81ea\u5df1\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u6ca1\u6709\u5176\u4ed6\u7f16\u7801\u65b9\u5f0f\u3002\u53ea\u6709 Unicode \u628a\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u7684\u6982\u5ff5\u5206\u7684\u5f88\u6e05\u695a\uff0c\u56e0\u4e3a Unicode \u5b57\u7b26\u96c6\u6709 UTF-8\u3001UTF-\u3002 GBK GBK \u540c\u6837\u662f\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u662f\u5bf9 GB2312 \u7684\u6269\u5c55\u3002 GBK \u5728\u4fdd\u6301 GB2312 \u90e8\u5206\u4e0d\u53d8\u7684\u57fa\u7840\u4e0a\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u6536\u5f55\u7684\u6709\uff1a GB2312 \u4e2d\u7684\u5168\u90e8\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7 BIG-5\uff08\u7e41\u4f53\u4e2d\u6587\u7684\u7f16\u7801\uff09\u4e2d\u7684\u5168\u90e8\u6c49\u5b57 GB13000\uff08\u5373 Unicode\uff09\u4e2d\u7684\u5176\u4ed6\u4e2d\u65e5\u97e9\u6c49\u5b57 \u5176\u4ed6\u5c1a\u672a\u6536\u5f55\u7684\u7279\u6b8a\u6c49\u5b57\u3001\u90e8\u9996\u3001\u7b26\u53f7\u7b49 \u201cK\u201d \u8868\u793a Kuo\uff08\u6269\u5c55\uff09\u7684\u610f\u601d\u3002 GB2312\uff1a\u9996\u5b57\u8282 0xA1 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282 0xA1 \u5230 0xFE\u3002 GBK\uff1a\u9996\u5b57\u8282 0x81 \u5230 0xFE \uff0c\u5c3e\u5b57\u8282 0x40 \u5230 0xFE \u3002 \u6ce8\u610f\u5230 GBK \u7684\u5c3e\u5b57\u8282\u8fdb\u5165\u4e86 0x40\uff0cASCII \u7684\u8303\u56f4\u3002 \u8fd9\u4f7f\u5f97 GBK \u6bd4 GB2312 \u66f4\u5371\u9669\uff0c\u4f8b\u5982 \u201c\u4fb0\u201d \u8fd9\u4e2a\u5b57\uff0c\u4f1a\u88ab\u7f16\u7801\u6210 0x82 0x43\u3002 \u800c 0x43 \u521a\u597d\u662f ASCII \u5b57\u7b26 \u201cC\u201d \u7684\u7f16\u7801\u3002\u5982\u679c\u53d1\u751f\u5b57\u7b26\u4e32\u5207\u7247\uff0c\u53ef\u80fd\u5bfc\u81f4 \u201c\u4fb0\u201d \u53d8\u6210 \u201c\ufffdC\u201d\u3002\u5e76\u4e14\u5982\u679c\u521a\u597d\u7a0b\u5e8f\u5728 .find('C') \uff0c\u90a3\u4e48 \u201c\u4fb0\u201d \u7684\u540e\u534a\u4e2a\u5b57\u8282\u4f1a\u88ab\u5f53\u4f5c \u201cC\u201d \u800c\u627e\u5230\u3002 \u4e0d\u8fc7\uff0cGBK \u8bbe\u8ba1\u65f6\u7279\u610f\u907f\u5f00\u4e86 0x40 \u4ee5\u4e0b\u7684 ASCII \u5b57\u7b26\uff0c\u4f8b\u5982 0x2F \u662f \u201c/\u201d \u7684 ASCII \u7f16\u7801\uff0c\u5e38\u7528\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7684\u8def\u5f84\u5206\u9694\u7b26\u3002 \u7136\u800c\uff0cWindows \u6240\u7528\u7684\u8def\u5f84\u5206\u9694\u7b26\u662f\u53cd\u659c\u6760 \u201c\\\u201d\uff0c\u4ed6\u7684 ASCII \u7f16\u7801\u662f 0x5C\u3002 \u4f8b\u5982 \u201c\u4fd3\u201d\uff0cGBK \u7f16\u7801 0x82 0x5C\uff0c\u8fd9\u4e2a\u5b57\u5c31\u53ef\u80fd\u88ab\u9519\u8bef\u89e3\u8bfb\u6210 \u201c\ufffd\\\u201d\uff0c\u4f7f\u7a0b\u5e8f\u8bef\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u6587\u4ef6\u5939\u7684\u8def\u5f84\uff0c\u4ece\u800c\u5bfc\u81f4\u7a0b\u5e8f\u51fa\u9519\uff0c\u6216\u7559\u4e0b\u88ab\u9ed1\u5ba2\u653b\u51fb\u7684\u9690\u60a3\u3002 \u867d\u7136 Windows \u7cfb\u7edf\u5185\u90e8\u7edf\u4e00\u91c7\u7528 Unicode\uff08UTF-16\uff09\u6765\u5b58\u50a8\u548c\u5904\u7406\u8def\u5f84\uff0c\u4f46\u603b\u67b6\u4e0d\u4f4f\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\uff0c\u4f9d\u7136\u6267\u7740\u4e8e ANSI\uff08GBK\uff09\uff0c\u5982\u679c\u7528\u6237\u65e0\u610f\u6216\u6076\u610f\u8f93\u5165\u201c\u4fd3\u554a.txt\u201d\uff0c\u5c31\u6709\u53ef\u80fd\u4ea7\u751f\u9690\u60a3\u3002 \u800c UTF-8 \u540c\u6837\u517c\u5bb9 ASCII\uff0c\u5f97\u76ca\u4e8e\u5197\u4f59\u7684\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u5c31\u6ca1\u6709\u8fd9\u6837\u7684\u95ee\u9898\u3002 \u201cGBK\u201d \u867d\u7136\u51a0\u4ee5\u201c\u56fd\u6807\u201d\u4e4b\u540d\uff0c\u4f46\u5b9e\u9645\u4e0a\u662f\u5fae\u8f6f\u64c5\u81ea\u63a8\u51fa\u7684\uff01\u6839\u672c\u4e0d\u662f\u4ec0\u4e48\u56fd\u5bb6\u6807\u51c6\uff08\u4f60\u731c\u4ed6\u4e3a\u4ec0\u4e48\u6ca1\u6709\u56fd\u5bb6\u6587\u4ef6\u7f16\u53f7\uff09\u3002\u672c\u6765\u6211\u56fd\u5b98\u65b9\u90fd\u6253\u7b97\u63a8\u51fa GB13000 \u4e86\uff0c\u76f4\u63a5\u5b8c\u5168\u517c\u5bb9 Unicode \u5b57\u7b26\u96c6\u3002\u7136\u800c\u5fae\u8f6f\u81ea\u4f5c\u4e3b\u5f20\u628a\u4ed6 Wendous \u7684 GB2312 \u5347\u7ea7\u5230 GBK\uff08\u6bd4\u5c14\u76d6\u5b50\u4ee5\u4e3a\u81ea\u5df1\u517c\u5bb9\u538b\u5012\u4e00\u5207\uff0c\u62fd\u6b7b\u4e86\uff09\uff0c\u672c\u6765\u597d\u597d\u7684 GB13000 \u6807\u51c6\u53ea\u597d\u4f5c\u7f62\u3002\u4e3a\u4e86\u517c\u5bb9\u5df2\u7ecf\u5347\u7ea7\u6210 GBK \u7684 Wendous \u7cfb\u7edf\uff0c\u56fd\u5bb6\u53ea\u597d\u91cd\u65b0\u5236\u4f5c\u4e86\u4e00\u4efd GB18030 \u6807\u51c6\uff0c\u517c\u5bb9 GBK \u548c GB2312\u3002 GB18030 \u4e8e 2000 \u5e74 3 \u6708\u53d1\u5e03\u7684\u6c49\u5b57\u7f16\u7801\u56fd\u5bb6\u6807\u51c6\uff0c\u5b8c\u5168\u517c\u5bb9 GBK \u548c GB2312\u3002 \u91c7\u7528\u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u53ef\u4ee5\u7f16\u7801\u4e3a 1 \u5b57\u8282\u30012 \u5b57\u8282\u3001\u6216 4 \u5b57\u8282\u3002 \u5176\u4e2d 1 \u5b57\u8282\u7684\u90e8\u5206\u53d6\u503c\u8303\u56f4\u662f 0 \u5230 0x7F\uff0c\u548c ASCII \u76f8\u540c\u3002 2 \u5b57\u8282\u7684\u90e8\u5206\u9996\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282\u8303\u56f4 0x40 \u5230 0xFE\uff0c\u548c GBK \u76f8\u540c\u3002 4 \u5b57\u8282\u7684\u90e8\u5206\u7b2c\u4e00\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u4e8c\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\uff0c\u7b2c\u4e09\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u56db\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\u3002 \u5b57\u7b26\u5904\u7406\u8f6f\u4ef6\u5728\u5904\u7406 GB18030 \u7684\u6587\u672c\u65f6\uff0c\u4ece\u5de6\u5f80\u53f3\u4f9d\u6b21\u626b\u63cf\u6bcf\u4e2a\u5b57\u8282\uff1a \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u53ea\u5360\u7528\u4e86\u4e00\u4e2a\u5b57\u8282 \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 1\uff0c\u90a3\u4e48\u8be5\u5b57\u7b26\u53ef\u80fd\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282\uff0c\u4e5f\u53ef\u80fd\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282\uff0c\u4e0d\u80fd\u5984\u4e0b\u65ad\u8bba\uff0c\u6240\u4ee5\u8fd8\u8981\u7ee7\u7eed\u5f80\u540e\u626b\u63cf\uff1a \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6709\u4e24\u4e2a\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282 \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6ca1\u6709\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282 \u5f53\u5b57\u7b26\u5360\u7528\u4e24\u4e2a\u6216\u8005\u56db\u4e2a\u5b57\u8282\u65f6\uff0cGB18030 \u7f16\u7801\u603b\u8981\u68c0\u6d4b\u4e24\u6b21\uff0c\u5904\u7406\u6548\u7387\u6bd4 GB2312 \u548c GBK \u90fd\u4f4e\u3002\u800c\u4e14\u548c GBK \u4e00\u6837\uff0c\u6709\u7740\u4e0d\u80fd\u81ea\u7ea0\u9519\uff0c\u5bb9\u6613\u4f7f\u7f16\u7801\u9519\u8bef\u8fde\u9501\u53cd\u5e94\u7684\u95ee\u9898\u3002 GB18030 \u7f16\u7801\u7a7a\u95f4\u5de8\u5927\uff0c\u4e0d\u4ec5\u56ca\u62ec\u4e86\u4e2d\u65e5\u97e9\u6c49\u5b57\uff0c\u6240\u6709 Unicode \u4e2d\u7684\u5b57\u7b26\u4e5f\u90fd\u88ab\u7eb3\u5165\u5176\u4e2d\uff01\u4e5f\u5c31\u662f\u8bf4\uff0cUnicode \u5b57\u7b26\u7528 GB18030 \u7f16\u7801\u662f\u65e0\u635f\u7684\uff0c\u548c UTF-8 \u4e00\u6837\uff0c\u800c\u4e14\u8fd8\u5b8c\u5168\u517c\u5bb9\u4e86 GBK\uff08\u4e2d\u56fd\u533a Windows \u7684\u9ed8\u8ba4\u7f16\u7801\uff09\u3002 \u6240\u4ee5\uff0cGB18030 \u5b57\u7b26\u7f16\u7801\u5bf9\u5e94\u7684\u5b57\u7b26\u96c6\u5b9e\u9645\u4e0a\u662f Unicode\u3002 \u5c3d\u7ba1\u5982\u6b64\uff0cWindows \u81f3\u4eca\uff08\u6211\u6d4b\u7684\u662f Win10\uff0c\u4e0d\u77e5\u9053 Win11 \u5b83\u4eec\u6539\u8fdb\u6ca1\u6709\uff09\u91c7\u7528\u7684\u4f9d\u7136\u662f GBK \u7f16\u7801\uff1a A \u7cfb API \u65e0\u6cd5\u6b63\u786e\u8bc6\u522b GB18030 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff0c\u6587\u4ef6\u8def\u5f84\u540d\u3002\u660e\u660e\u4e2d\u56fd\u653f\u5e9c\u90fd\u7ed9\u4f60\u505a\u5b8c\u5168\u517c\u5bb9\u4f60\u7684 GBK \u4e86\uff0c\u8fd8\u6536\u5f55\u6240\u6709 Unicode \u5b57\u7b26\u4e86\uff0c\u5b8c\u5168\u53ef\u4ee5\u65e0\u7f1d\u589e\u91cf\u5347\u7ea7\u7684\u4e1c\u897f\uff0c\u6ce5\u7801\u6c9f\u69fd\u7684\u6bd4\u5c14\u76d6\u5b50\u8fd8\u4e0d\u5feb\u70b9\u9ed8\u8ba4\u5207\u6362\u5230 GB18030\uff0c\u60f3\u4e0d\u901a\uff08\u81f4\u656c\u4f20\u5947\u9634\u4e95\u76d6\u6bd4\u5c14\u76d6\u5b50\uff09 \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801\u517c\u5bb9\u6027\uff1aUTF-8 != GB18030 > GBK > GB2312 > ASCII \u5b57\u7b26\u96c6\u5927\u5c0f\uff1aUnicode = GB18030 > GBK > GB2312 > ASCII \u603b\u4e4b\uff0cGB \u7cfb\u5217\u7f16\u7801\u9762\u5bf9\u5207\u7247\u548c\u67e5\u627e\u5b58\u5728\u4e00\u5b9a\u7684\u95ee\u9898\uff0c\u6709\u6761\u4ef6\u7684\u8bdd\uff0c\u5efa\u8bae Windows \u7a0b\u5e8f\u5c3d\u5feb\u5347\u7ea7\u5230 UTF-8 \u5916\u7801\u3001UTF-16 \u5185\u7801\u7684\u5de5\u4f5c\u6d41\u4e0a\u6765\uff0c\u56de\u907f\u6389\u53f2\u5c71\u7684\u5f71\u54cd\u3002 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u7c7b\u578b \u5927\u5c0f \u7f16\u7801 \u5b57\u9762\u91cf Linux char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e $LC_ALL \u201chello\u201d Windows char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e \u201chello\u201d Linux wchar_t 4 \u5b57\u8282 UTF-32 L\u201dhello\u201d Windows wchar_t 2 \u5b57\u8282 UTF-16LE L\u201dhello\u201d char8_t 1 \u5b57\u8282 UTF-8 u8\u201dhello\u201d char16_t 2 \u5b57\u8282 UTF-16 u\u201dhello\u201d char32_t 4 \u5b57\u8282 UTF-32 U\u201dhello\u201d \u7531\u6b64\u53ef\u89c1\uff0c char \u548c wchar_t \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f GBK\u3002\u5bf9\u4e8e\u7f8e\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\u3002 \u5bf9\u4e8e Linux \u7528\u6237\u6765\u8bf4\uff0c\u5982\u679c\u4f60\u6ca1\u6709\u4e13\u95e8\u4fee\u6539\u8fc7\uff0c $LC_ALL \u9ed8\u8ba4\u662f en_US.UTF-8 \u6216 C.UTF-8 \u3002 \u8fd9\u5e26\u6765\u4e86\u5de8\u5927\u7684\u6df7\u6dc6\uff01\u5f88\u591a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u6f5c\u610f\u8bc6\u91cc\u4f1a\u60f3\u5f53\u7136\u5730\u628a char \u5f53\u4f5c UTF-8 \u6765\u7528\u3002\u5f88\u591a\u5f00\u6e90\u9879\u76ee\uff0c\u7b2c\u4e09\u65b9\u5e93\uff0c\u751a\u81f3\u5f88\u591a\u56fd\u4eba\u505a\u7684\u9879\u76ee\uff0c\u90fd\u88ab\u8fd9\u79cd\u201c\u60f3\u5f53\u7136\u201d\u4f20\u67d3\u4e86\u3002 \u597d\u6d88\u606f\u662f\u65e0\u8bba\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u662f\u4ec0\u4e48\uff0c\u80af\u5b9a\u517c\u5bb9 ASCII\u3002\u4f8b\u5982 GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u5426\u5219\u5c31\u548c\u6240\u6709\u7684 C \u8bed\u8a00\u7ecf\u5178\u51fd\u6570\u5982 strlen \uff0c\u6362\u884c\u7b26 '\\n' \uff0c\u8def\u5f84\u5206\u9694\u7b26 '/' \u548c '\\\\' \u51b2\u7a81\u4e86\u3002 wchar_t \u5c31\u597d\u4e00\u4e9b\uff0c\u867d\u7136\u5728 Windows \u7cfb\u7edf\u4e0a\u662f\u7cdf\u7cd5\u7684 UTF-16\uff0c\u4f46\u81f3\u5c11\u7a33\u5b9a\u4e86\uff0c\u4e0d\u4f1a\u968f\u7740\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u800c\u968f\u610f\u6539\u53d8\uff0c\u53ea\u8981\u4f60\u4e0d\u6253\u7b97\u8de8\u5e73\u53f0\uff0c wchar_t \u5c31\u662f Windows \u7a0b\u5e8f\u7684\u6807\u914d\u3002 \u6839\u636e Windows \u5b98\u65b9\u6587\u6863\u7684\u8bf4\u6cd5\uff0c wchar_t \u662f UTF-16LE\u3002 \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u7684\u706b\u8f66\u5934\u548c\u8f66\u53a2\uff0c\u90fd\u662f 1 \u5f00\u5934\u7684\uff0c\u800c ASCII \u7684\u5355\u4f53\u706b\u8f66\u5934\u6c38\u8fdc\u662f 0 \u5f00\u5934\u3002\u8fd9\u5f88\u91cd\u8981\uff0c\u4e0d\u4ec5\u706b\u8f66\u5934\u9700\u8981\u548c ASCII \u533a\u5206\u5f00\u6765\uff0c\u8f66\u53a2\u4e5f\u9700\u8981\u3002\u8003\u8651\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff1a std::u32string path = \"\u4e00\u4e2a\u8001\u4f2f.txt\"; \u201c\u4e00\u4e2a\u8001\u4f2f\u201d \u8f6c\u6362\u4e3a Unicode \u7801\u70b9\u5206\u522b\u662f\uff1a 0x4E00 0x4E2A 0x8001 0x4F2F \u5982\u679c\u8ba9\u4ed6\u4eec\u539f\u5c01\u4e0d\u52a8\u76f4\u63a5\u5b58\u50a8\u8fdb char \u6570\u7ec4\u91cc\uff1a 0x4E 0x00 0x4E 0x2A 0x80 0x01 0x4F 0x2F \u5c31\u51fa\u95ee\u9898\u4e86\uff01\u9996\u5148\uff0c\u8fd9\u91cc 0x4E00 \u7684 0x00 \u90e8\u5206\uff0c\u4f1a\u88ab C \u8bed\u8a00\u5f53\u4f5c\u662f\u5b57\u7b26\u4e32\u7684\u7ed3\u5c3e\u3002\u5982\u679c\u62ff\u8fd9\u6837\u7684\u5b57\u7b26\u4e32\u53bb\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u7684 open \u51fd\u6570\uff0c\u4ed6\u4f1a\u4ee5\u4e3a\u4f60\u5728\u6253\u5f00 0x4E \u5355\u4e2a\u5b57\u7b26\u7684\u6587\u4ef6\u540d\uff0c\u4e5f\u5c31\u662f \"N\" \u3002 \u66f4\u7cdf\u7cd5\u7684\u662f\uff0c0x2F \u5bf9\u5e94\u7684 ASCII \u5b57\u7b26\u662f '/' \uff0c\u662f\u8def\u5f84\u5206\u9694\u7b26\u3002\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u4ee5\u4e3a\u4f60\u8981\u521b\u5efa\u4e00\u4e2a\u5b50\u6587\u4ef6\u5939\u4e0b\u7684\u6587\u4ef6 \"N\\x00N*\\x80\\x01O/.txt\" \uff0c\u6587\u4ef6\u5939\u540d\u5b57\u53eb \"N\\x00N*\\x80\\x01O\" \u800c\u6587\u4ef6\u53eb \".txt\" \u3002 \u4e3a\u4e86\u80fd\u8ba9\u9488\u5bf9 ASCII \u8bbe\u8ba1\u7684\u64cd\u4f5c\u7cfb\u7edf API \u652f\u6301\u4e2d\u6587\u6587\u4ef6\u540d\uff0c\u5c31\u53ea\u80fd\u7ed5\u5f00\u6240\u6709 0x7F \u4ee5\u4e0b\u7684\u503c\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 UTF-8 \u5bf9\u8f66\u53a2\u4e5f\u5168\u90e8\u62ac\u9ad8\u5230 0x80 \u4ee5\u4e0a\uff0c\u907f\u514d\u64cd\u4f5c\u7cfb\u7edf\u4e0d\u614e\u628a\u8f66\u53a2\u5f53\u4f5c\u662f '/' \u6216 '\\0' \u3002 UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u7531\u4e8e\u5de8\u5927\u7684\u60ef\u6027\uff0c\u5f88\u591a\u4eba\u90fd\u60f3\u5f53\u7136\u7684\u628a std::string \u5f53\u4f5c UTF-8 \u6765\u4f7f\u7528\u3002\u5bf9\u4e8e\u7b80\u5355\u7684\u6253\u5370\uff0c\u5e38\u89c4\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u5b57\u7b26\u4e32\u64cd\u4f5c\u6709\u4e0b\u9762\u8fd9\u51e0\u79cd\uff0c\u5f97\u76ca\u4e8e UTF-8 \u4f18\u79c0\u7684\u5e8f\u5217\u5316\u6d89\u53ca\u548c\u5197\u4f59\u6297\u5e72\u6270\u673a\u5236\uff0c\u7edd\u5927\u591a\u6570 ASCII \u652f\u6301\u7684\u64cd\u4f5c\uff0cUTF-8 \u5b57\u7b26\u4e32\u90fd\u80fd\u8f7b\u677e\u80dc\u4efb\uff0c\u552f\u72ec\u5176\u4e2d \u6d89\u53ca\u201c\u7d22\u5f15\u201d\u548c\u201c\u957f\u5ea6\u201d\u7684 \u4e00\u90e8\u5206\u64cd\u4f5c\u4e0d\u884c\u3002\u8fd9\u662f\u7531\u4e8e\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff0c\u5982\u679c\u9700\u8981\u505a\u201c\u7d22\u5f15\u201d\u7c7b\u64cd\u4f5c\uff0c\u8fd8\u662f\u5efa\u8bae\u5148\u8f6c\u6362\u6210\u5b9a\u957f\u7684 UTF-32 \u7f16\u7801\u3002 \u64cd\u4f5c UTF-8 UTF-32 GBK \u6c42\u5b57\u7b26\u4e32\u957f\u5ea6 \u00d7 \u221a \u00d7 \u5224\u65ad\u76f8\u7b49 \u221a \u221a \u221a \u5b57\u5178\u5e8f\u7684\u5927\u5c0f\u6bd4\u8f83 \u221a \u221a \u00d7 \u5b57\u7b26\u4e32\u62fc\u63a5 \u221a \u221a \u221a \u641c\u7d22\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u641c\u7d22\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u4e0b\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u83b7\u53d6\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u904d\u5386\u6240\u6709\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u5b50\u5b57\u7b26\u4e32\u5207\u7247 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u7247 \u00d7 \u221a \u00d7 \u67e5\u627e\u5e76\u66ff\u6362\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u67e5\u627e\u5e76\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u5220\u9664\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u4e3a\u4ec0\u4e48\uff1f\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u5b9e\u9a8c\uff1a std::string s = \"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \uff08\u4f7f\u7528 /utf-8 \u7f16\u8bd1\uff09\u8fd0\u884c\u540e\uff0c\u4f1a\u5f97\u5230 6\u3002 \u56e0\u4e3a std::string \u7684 size() \u8fd4\u56de\u7684\u662f char \u7684\u6570\u91cf\uff0c\u800c\u4e0d\u662f\u771f\u6b63\u5b57\u7b26\u7684\u6570\u91cf\u3002\u5728 UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u975e ASCII \u7684\u5b57\u7b26\u4f1a\u88ab\u7f16\u7801\u4e3a\u591a\u4e2a char \uff0c\u5bf9\u4e8e\u4e2d\u6587\u800c\u8a00\uff0c\u4e2d\u6587\u90fd\u5728 0x2E80 \u5230 0x9FFF \u8303\u56f4\u5185\uff0c\u5c5e\u4e8e\u4e09\u7ea7\u5217\u8f66\uff0c\u4e5f\u5c31\u662f\u6bcf\u4e2a\u6c49\u5b57\u4f1a\u88ab\u7f16\u7801\u6210 3 \u4e2a char \u3002 char \u662f\u5b57\u8282\uff08\u7801\u4f4d\uff09\u800c\u4e0d\u662f\u771f\u6b63\u7684\u5b57\u7b26\uff08\u7801\u70b9\uff09\u3002\u771f\u6b63\u7684 Unicode \u5b57\u7b26\u5e94\u8be5\u662f char32_t \u7c7b\u578b\u7684\u3002\u8c03\u7528 std::string \u7684 size() \u6216\u8005 strlen \u5f97\u5230\u7684\u53ea\u662f\u201c\u5b57\u8282\u6570\u91cf\u201d\u3002 \u800c UTF-32 \u4e2d\uff0c\u6bcf\u4e2a\u5b57\u7b26\uff08\u7801\u70b9\uff09\u90fd\u5bf9\u5e94\u4e00\u4e2a\u72ec\u7acb\u7684 char32_t \uff08\u7801\u4f4d\uff09\uff0c size() \u5c31\u662f\u771f\u6b63\u7684\u201c\u5b57\u7b26\u6570\u91cf\u201d\uff0c\u8fd9\u5c31\u662f\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 std::u32string s = U\"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \u5982\u679c\u4f60\u7684\u64cd\u4f5c\u53ea\u6d89\u53ca\u5b57\u7b26\u4e32\u67e5\u62fc\u63a5\u4e0e\u67e5\u627e\uff0c\u90a3\u5c31\u53ef\u4ee5\u7528 UTF-8\u3002\u5982\u679c\u5927\u91cf\u6d89\u53ca\u7d22\u5f15\uff0c\u5207\u7247\uff0c\u5355\u4e2a\u5b57\u7b26\u7684\u64cd\u4f5c\uff0c\u90a3\u5c31\u5fc5\u987b\u7528 UTF-32\uff08\u5426\u5219\u4e00\u9047\u5230\u6c49\u5b57\u5c31\u4f1a\u51fa\u9519\uff09\u3002 std::vector slogan = { \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\", \"\u5168\u4e16\u754c\u7a0b\u5e8f\u5458\u5927\u56e2\u7ed3\u4e07\u5c81\", }; std::string joined; for (auto const &s: slogan) { joined += s; // \u53ea\u662f\u62fc\u63a5\u800c\u5df2\uff0cUTF-8 \u6ca1\u95ee\u9898 } UTF-8 \u6309\u7d22\u5f15\u5207\u7247\u7684\u51fa\u9519\u6848\u4f8b\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-8 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u8282\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\ufffd\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-32 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u7b26\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u53ea\u6709\u5f53\u7d22\u5f15\u662f\u6765\u81ea find \u7684\u7ed3\u679c\u65f6\uff0cUTF-8 \u5b57\u7b26\u4e32\u7684\u5207\u7247\u624d\u80fd\u6b63\u5e38\u5de5\u4f5c\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(\"\u516c\"); // pos = 12 fmt::println(\"UTF-8 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u8282\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(U'\u516c'); // pos = 4 fmt::println(\"UTF-32 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u7b26\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u6ce8\u610f\u5230\u8fd9\u91cc UTF-8 \u7684 \"\u516c\" \u9700\u8981\u662f\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u5b57\u7b26\u3002 UTF-8 \u65e0\u6cd5\u53d6\u51fa\u5355\u4e2a\u975e ASCII \u5b57\u7b26\uff0c\u5bf9\u4e8e\u5355\u4e2a\u4e2d\u6587\u5b57\u7b26\uff0c\u4ecd\u7136\u53ea\u80fd\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u8868\u8fbe\uff08\u7531\u591a\u4e2a\u5b57\u8282\u7ec4\u6210\uff09\u3002 std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-8 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u8282\uff1a{}\", s[0]); // \u53ef\u80fd\u4f1a\u6253\u5370 \u2018\u00e5\u2019 (0xE5)\uff0c\u56e0\u4e3a\u201c\u5c0f\u201d\u7684 UTF-8 \u7f16\u7801\u662f 0xE5 0xB0 0x8F // \u4e5f\u53ef\u80fd\u662f\u4e71\u7801\u201c\ufffd\u201d\uff0c\u53d6\u51b3\u4e8e\u7ec8\u7aef\u7406\u89e3\u7684\u7f16\u7801\u683c\u5f0f std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-32 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u7b26\uff1a{}\", s[0]); // \u4f1a\u6253\u5370 \u2018\u5c0f\u2019 UTF-8 \u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\u4e5f\u4f1a\u51fa\u95ee\u9898\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u4e71\u7801 std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u628a\u6309\u5b57\u7b26\u6b63\u5e38\u53cd\u8f6c\uff0c\u5f97\u5230 \u201c\u5c81\u4e07\u8bfe\u5f00\u516c\u5e08\u8001\u5f6d\u5c0f\u201d \u603b\u7ed3\uff1aUTF-8 \u53ea\u80fd\u62fc\u63a5\u3001\u67e5\u627e\u3001\u6253\u5370\u3002\u4e0d\u80fd\u7d22\u5f15\u3001\u5207\u7247\u3001\u53cd\u8f6c\u3002 \u6309\u7d22\u5f15\u5207\u7247\u4e0d\u884c\uff0c\u4f46\u5982\u679c\u7d22\u5f15\u662f find \u51fa\u6765\u7684\u5c31\u6ca1\u95ee\u9898\u3002 \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5728 Windows \u5b98\u65b9\u7684\u8bf4\u8f9e\u4e2d\uff0c\u6709\u201cUnicode \u7f16\u7801\u201d\u548c\u201cANSI \u7f16\u7801\u201d\u7684\u8bf4\u6cd5\u3002\u5f53\u4f60\u4f7f\u7528 Windows \u81ea\u5e26\u7684\u8bb0\u4e8b\u672c\u7a0b\u5e8f ( notepad.exe ) \u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u65f6\uff0c\u5c31\u4f1a\u770b\u5230\u8fd9\u6837\u7684\u9009\u5355\uff1a \u7ffb\u8bd1\u4e00\u4e0b\uff1a \u201cANSI\u201d\u6307\u7684\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u8bbe\u7f6e\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\u3002 \u6240\u8c13\u201cUnicode\u201d\u5176\u5b9e\u6307\u7684\u662f UTF-16\u3002 \u6240\u8c13\u201cUnicode big endian\u201d\u6307\u7684\u662f\u5927\u7aef UTF-16\u3002 \u201cUTF-8\u201d\u6307\u7684\u662f UTF-8 with BOM \u800c\u4e0d\u662f\u6b63\u5e38\u7684 UTF-8\u3002 \u5b9e\u9645\u4e0a Unicode \u53ea\u662f\u4e00\u4e2a\u5b57\u7b26\u96c6\uff0c\u53ea\u662f\u628a\u5b57\u7b26\u6620\u5c04\u5230\u6574\u6570\uff0c\u66f4\u6ca1\u6709\u4ec0\u4e48\u5927\u7aef\u5c0f\u7aef\uff0cUTF-16 \u624d\u662f\u7f16\u7801\u683c\u5f0f\u3002 \u800c ANSI \u672c\u6765\u5e94\u8be5\u662f ASCII \u7684\u610f\u601d\uff0c char \u672c\u6765\u5c31\u53ea\u652f\u6301 ASCII\u3002 \u4f46\u7531\u4e8e\u5f53\u65f6\u5404\u56fd\u8feb\u5207\u9700\u8981\u652f\u6301\u81ea\u5df1\u672c\u56fd\u7684\u6587\u5b57\uff0c\u5c31\u5728\u517c\u5bb9 ASCII \u7684\u57fa\u7840\u4e0a\uff0c\u53d1\u5c55\u51fa\u4e86\u81ea\u5df1\u7684\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u3002\u8fd9\u4e9b\u5f53\u5730\u7279\u4f9b\u7684\u5b57\u7b26\u96c6\u91cc\u53ea\u5305\u542b\u4e86\u672c\u56fd\u6587\u5b57\uff0c\u6240\u6709\u8fd9\u4e9b\u5404\u56fd\u7684\u5b57\u7b26\u7f16\u7801\u4e5f\u90fd\u548c UTF-8 \u7c7b\u4f3c\uff0c\u91c7\u7528\u706b\u8f66\u5934\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0c\u5bf9 0 \u5f00\u5934\u7684 ASCII \u90e8\u5206\u4e5f\u90fd\u662f\u517c\u5bb9\u3002\u6240\u4ee5 Windows \u7d22\u6027\u628a ANSI \u5f53\u4f5c\u201c\u5404\u56fd\u672c\u5730\u6587\u5b57\u7f16\u7801\u201d\u7684\u7b80\u79f0\u4e86\u3002\u4f46\u540e\u6765\u4e92\u8054\u7f51\u7684\u51fa\u73b0\uff0c\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u5e26\u6765\u4e86\u5de8\u5927\u7684\u4fe1\u606f\u4ea4\u6362\u56f0\u96be\u3002 \u4f8b\u5982\u4f60\u5728\u73a9\u4e00\u4e9b\u65e5\u672c\u7684 galgame \u65f6\uff0c\u4f1a\u53d1\u73b0\u91cc\u9762\u6587\u5b57\u5168\u90e8\u4e71\u7801\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u5728\u5404\u4e2a\u5730\u533a\u53d1\u884c\u7684\u662f\u201c\u7279\u4f9b\u7248\u201d\uff1a\u5728\u4e2d\u56fd\u5927\u9646\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 GBK \u5b57\u7b26\u96c6\uff0c\u5728\u65e5\u672c\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 Shift-JIS \u5b57\u7b26\u96c6\u3002\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u7a0b\u5e8f\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u5b58\u50a8\u7684\u662f Shift-JIS \u7684\u90a3\u4e9b\u201c\u6574\u6570\u201d\u3002\u8fd9\u5bfc\u81f4\u65e5\u672c\u7684 galgame \u5728\u4e2d\u56fd\u5927\u9646\u7279\u4f9b\u7684 Windows \u4e2d\uff0c\u628a Shift-JIS \u7684\u201c\u6574\u6570\u201d\u7528 GBK \u7684\u8868\u6765\u89e3\u8bfb\u4e86\uff0c\u4ece\u800c\u4e71\u7801\uff08GBK \u91cc\u7684\u65e5\u6587\u533a\u57df\u5e76\u6ca1\u6709\u548c Shift-JIS \u91cd\u53e0\uff09\u3002\u9700\u8981\u7528 Locale Emulator \u628a Shift-JIS \u7ffb\u8bd1\u6210 Unicode \u8bfb\u7ed9 Windows \u542c\u3002\u5982\u679c\u65e5\u672c\u7a0b\u5e8f\u5458\u4ece\u4e00\u5f00\u59cb\u5c31\u7edf\u4e00\u7528 Unicode \u6765\u5b58\u50a8\uff0c\u4e2d\u56fd\u533a\u73a9\u5bb6\u7684 Windows \u4e5f\u7edf\u4e00\u7528 Unicode \u89e3\u6790\uff0c\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cUnicode \u7ec4\u7ec7\u51fa\u73b0\u4e86\uff0c\u4ed6\u7684\u4f7f\u547d\u5c31\u662f\u7edf\u4e00\u5168\u4e16\u754c\u7684\u5b57\u7b26\u96c6\uff0c\u4fdd\u8bc1\u5168\u4e16\u754c\u6240\u6709\u7684\u6587\u5b57\u90fd\u80fd\u5728\u5168\u4e16\u754c\u6240\u6709\u7684\u8ba1\u7b97\u673a\u4e0a\u663e\u793a\u51fa\u6765\u3002\u9996\u5148\u521b\u529e\u4e86 Unicode \u5b57\u7b26\u96c6\uff0c\u7136\u540e\u89c4\u5b9a\u4e86 UTF-8\u3001UTF-16\u3001UTF-32 \u4e09\u79cd\u5b57\u7b26\u7f16\u7801\uff0c\u6700\u7ec8 UTF-8 \u6210\u4e3a\u5916\u7801\u7684\u4e3b\u6d41\uff0cUTF-32 \u6210\u4e3a\u5185\u7801\u7684\u4e3b\u6d41\u3002 \u63a5\u4e0b\u6765\u4e3a\u4e86\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u6211\u4eec\u7d22\u6027\u5c31\u987a\u7740\u5fae\u8f6f\u7684\u8fd9\u4e2a\u8bf4\u6cd5\uff1a \u7ba1 char \u53eb ANSI\uff1a\u968f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002 \u7ba1 wchar_t \u53eb Unicode\uff1a\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u5728 Linux \u4e0a\u662f UTF-32\u3002 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5fae\u8f6f\u7ba1 UTF-16 \u53eb Unicode \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u95ee\u9898\uff1a \u56e0\u4e3a\u5f53\u5e74 Unicode 5.0 \u7684\u65f6\u5019\u53ea\u6709 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff0c16 \u4f4d\u5c31\u88c5\u5f97\u4e0b\uff0c\u6240\u4ee5\u5f53\u65f6 UTF-16 \u8fd8\u662f\u4e00\u4e2a \u5b9a\u957f\u7f16\u7801 \u3002\u5fae\u8f6f\u4e8e\u662f\u51b3\u5b9a\u628a wchar_t \u5b9a\u4e49\u6210 2 \u5b57\u8282\uff0c\u5e76\u5728 NT \u5185\u6838\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u7cfb\u7edf\u8c03\u7528\u90fd\u5347\u7ea7\u6210\u4e86\u57fa\u4e8e wchar_t \u5b57\u7b26\u4e32\u7684 \u201cW \u7cfb\u201d API\u3002 \u6bd4\u5c14\u76d6\u5b50\u5f53\u65f6\u4ee5\u4e3a\u8fd9\u6837 UTF-16 \u5b9a\u957f\u5185\u7801\u5c31\u4e00\u52b3\u6c38\u9038\u4e86\uff0c\u5e76\u53f7\u53ec\u6240\u6709\u7a0b\u5e8f\u90fd\u6539\u7528 UTF-16 \u505a\u5185\u7801\uff0c\u522b\u7528 \u201cA \u7cfb\u201d API \u4e86\u3002 \u8d77\u521d\uff0c\u6240\u6709\u4eba\u90fd\u4ee5\u4e3a UTF-16 \u5c31\u662f\u6700\u7ec8\u7b54\u6848\u3002 \u6ca1\u60f3\u5230\u540e\u6765 Unicode \u59d4\u5458\u4f1a\u201c\u80cc\u523a\u201d\u4e86\u6bd4\u5c14\u76d6\u5b50\uff01\u5077\u5077\u628a\u8303\u56f4\u66f4\u65b0\u5230\u4e86 0x10FFFF\uff0c\u7a81\u7834\u4e86 16 \u4f4d\u6574\u6570\u7684\u5bb9\u91cf\u3002\u539f\u6765\u7684 UTF-16 \u5df2\u7ecf\u5bb9\u7eb3\u4e0d\u4e0b\uff0c\u53ea\u597d\u5229\u7528\u4e4b\u524d\u9884\u7559\u7684 0xD800 \u5230 0xDFFF \u7a7a\u53f7\u533a\u95f4\u4e11\u964b\u5730\u5b9e\u73b0\u4e86\u53d8\u957f\u7f16\u7801\u3002 \u76f4\u5230 UTF-16 \u4e00\u591c\u4e4b\u95f4\u6210\u4e86\u4e11\u964b\u7684 \u53d8\u957f\u7f16\u7801 \u3002 \u95f9\u4e86\u534a\u5929\uff0cWindows \u8d39\u5fc3\u8d39\u529b\u66ff Unicode \u59d4\u5458\u4f1a\u597d\u4e0d\u5bb9\u6613\u63a8\u5e7f\u7684 wchar_t \uff0c\u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801 \u7684\u597d\u5904\u3002\u53ef \u201cW \u7cfb\u201d API \u5374\u53c8\u710a\u6b7b\u5728\u4e86 NT \u5185\u6838\u6700\u5e95\u5c42\uff0c\u53cd\u590d\u6765\u5751\u7b2c\u4e00\u6b21\u7528 Windows \u7f16\u7a0b\u7684\u521d\u5b66\u8005\u3002 \u6bd4\u5c14\u76d6\u5b50\uff1a\u4f60\u8fd9\u6837\u663e\u5f97\u6211\u5f88\u5c0f\u4e11\u8bf6\uff1f \u9664 Windows \u5916\uff0cJava \u4e5f\u662f\u201cUTF-16 \u80cc\u523a\u201d\u7684\u53d7\u5bb3\u8005\uff0c\u4ed6\u4eec\u60f3\u5f53\u7136\u7684\u628a char \u5b9a\u4e49\u4e3a UTF-16\uff0c\u4ee5\u4e3a\u8fd9\u5c31\u662f\u672a\u6765\u6c38\u4e45\u7684\u5b9a\u957f\u5185\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u2026\u2026 \u76f4\u5230 Unicode \u52a0\u5165\u4e86 0x10FFFF\uff0cJava \u4e0d\u5f97\u4e0d\u91cd\u65b0\u5b9a\u4e49\u4e86\u4e2a Character \u4f5c\u4e3a UTF-32 \u5b57\u7b26\uff0c\u8fd8\u5f04\u4e2a char \u5230 Character \u7684\u8f6c\u6362\uff0c\u597d\u4e0d\u5c34\u5c2c\uff01 Linux \u6210\u7acb\u4e8e 1991 \u5e74\uff0c\u5f53\u65f6 Unicode \u4e5f\u624d\u521a\u521a\u51fa\u73b0\u3002Unicode \u5ba3\u5e03\u52a0\u5165 0x10FFFF \u540e\uff0cLinux \u624d\u5f00\u59cb\u5f15\u5165\u652f\u6301 Unicode\u3002\u5728\u77e5\u9053\u4e86 Unicode \u5305\u542b 0x10FFFF \u540e\uff0c\u4ed6\u4eec\u4e00\u5f00\u59cb\u5c31\u628a wchar_t \u5b9a\u4e49\u6210 4 \u5b57\u8282\uff0c\u9003\u8fc7\u4e86 UTF-16 \u7684\u80cc\u523a\u3002 \u540e\u6765\u65b0\u51fa\u7684\u8bed\u8a00\uff0c\u5982 Python 3\u3001Go\u3001Rust\u3001Swift\u3001Kotlin\uff0c\u628a\u5b57\u7b26\u94a6\u5b9a\u4e3a UTF-32 \u4e86\u3002\u4ed6\u4eec\u53ea\u6709\u5728\u8c03\u7528 Windows API \u65f6\uff0c\u624d\u4f1a\u4e34\u65f6\u8f6c\u6362\u4e3a UTF-16 \u6765\u8c03\u7528\uff0c\u9664\u6b64\u4e4b\u5916\u518d\u65e0 UTF-16 \u51fa\u73b0\u3002 \u8bb8\u591a\u7cdf\u7cd5\u7684\u535a\u5ba2\u58f0\u79f0\uff1a\u662f\u56e0\u4e3a\u201cUTF-16 \u6700\u6709\u5229\u4e8e\u4e2d\u6587\u538b\u7f29\u201d\uff0c\u6240\u4ee5 Java \u548c Windows \u624d\u91c7\u7528\u7684\uff1f\u7136\u800c\u5c31\u6211\u4e86\u89e3\u5230\u7684\u5b9e\u9645\u60c5\u51b5\u662f\u56e0\u4e3a\u4ed6\u4eec\u9519\u8bef\u7684\u4ee5\u4e3a 0xFFFF \u662f Unicode \u7684\u4e0a\u9650\u624d\u9519\u8bef\u91c7\u7528\u4e86\uff0c\u4e0d\u7136\u4e3a\u4ec0\u4e48\u540e\u6765\u7684\u65b0\u8bed\u8a00\u90fd\u91c7\u7528\u4e86 UTF-32 \u5185\u7801 + UTF-8 \u5916\u7801\u7684\u7ec4\u5408\uff1f\u800c\u4e14\u5728\u5916\u7801\u4e2d\u91c7\u7528 UTF-8 \u6216 UTF-16 \u538b\u7f29\u786e\u5b9e\u6ca1\u95ee\u9898\uff0c\u4f46\u662f Java \u548c Windows \u7684\u5931\u8bef\u5728\u4e8e\u628a UTF-16 \u5f53\u4f5c\u5185\u7801\u4e86\uff01\u5185\u7801\u5c31\u7406\u5e94\u662f\u5b9a\u957f\u7f16\u7801\u7684\u624d\u65b9\u4fbf\uff0c\u5982\u679c\u4f60\u6709\u4e0d\u540c\u60f3\u6cd5\uff0c\u6b22\u8fce\u7559\u8a00\u8ba8\u8bba\u3002 \u603b\u4e4b\uff0cUTF-16 \u662f\u7cdf\u7c95\uff0c\u4f46\u4ed6\u662f Windows \u552f\u4e00\u5b8c\u6574\u652f\u6301\u7684 Unicode \u63a5\u53e3\u3002\u4e0d\u5efa\u8bae\u8f6f\u4ef6\u5185\u90e8\u7528 UTF-16 \u5b58\u50a8\u6587\u5b57\uff0c\u4f60\u53ef\u4ee5\u7528\u66f4\u7d27\u51d1\u7684 UTF-8 \u6216\u66f4\u65b9\u4fbf\u5207\u7247\u7684 UTF-32\uff0c\u53ea\u9700\u5728\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u524d\u4e34\u65f6\u8f6c\u6362\u6210 UTF-16 \u5c31\u884c\u3002 \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u5fc5\u987b\u6307\u51fa\uff1a\u5728 std::string \u4e2d\u88c5 UTF-8 \u5e76\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5728 std::u8string \u91cc\u540c\u6837\u53ef\u4ee5\u88c5 GBK\u3002\u8fd9\u5c31\u597d\u6bd4\u4e00\u4e2a\u540d\u53eb Age \u7684\u679a\u4e3e\u7c7b\u578b\uff0c\u5b9e\u9645\u5374\u88c5\u7740\u6027\u522b\u4e00\u6837\u3002 enum Age { // \u9519\u8bef\u793a\u8303 Male, Female, Custom, }; // \u9664\u4e86\u8ff7\u60d1\u540c\u4e8b\u5916\uff0c\u628a\u5e74\u9f84\u548c\u6027\u522b\u7684\u7c7b\u578b\u6df7\u7528\u6ca1\u6709\u597d\u5904 void registerStudent(Age age, Age sex); \u533a\u5206\u7c7b\u578b\u53ea\u662f\u5927\u591a\u6570\u4eba\u8bbe\u8ba1\u63a5\u53e3\u7684\u89c4\u8303\uff0c\u53ea\u662f\u65b9\u4fbf\u4f60\u901a\u8fc7\u770b\u51fd\u6570\u63a5\u53e3\u4e00\u773c\u533a\u5206\u8fd9\u4e2a\u51fd\u6570\u63a5\u53d7\u7684\u662f\u4ec0\u4e48\u683c\u5f0f\u7684\u5b57\u7b26\u4e32\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u6027\u3002\u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4e00\u770b\u5c31\u77e5\u9053\u8fd9\u4e9b\u51fd\u6570\u9700\u8981\u7684\u662f\u4ec0\u4e48\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 void thisFuncAcceptsANSI(std::string msg); void thisFuncAcceptsUTF8(std::u8string msg); void thisFuncAcceptsUTF16(std::u16string msg); void thisFuncAcceptsUnicode(std::wstring msg); void thisFuncAcceptsUTF32(std::u32string msg); \u6ca1\u6709 char8_t \u4e4b\u524d\uff0c\u7528\u7c7b\u578b\u522b\u540d\u540c\u6837\u53ef\u4ee5\u8d77\u5230\u5dee\u4e0d\u591a\u7684\u8bf4\u660e\u6548\u679c\uff08\u7f3a\u70b9\u662f\u65e0\u6cd5\u91cd\u8f7d\uff09\uff1a using ANSIString = std::string; using UTF8String = std::string; using UTF16String = std::vector; void thisFuncAcceptsANSI(ANSIString msg); void thisFuncAcceptsUTF8(UTF8String msg); void thisFuncAcceptsUTF16(UTF16String msg); \u4e4b\u6240\u4ee5\u6211\u4f1a\u8bf4\uff0c std::string \u5e94\u8be5\u88c5 ANSI \u5b57\u7b26\u4e32\uff0c\u662f\u56e0\u4e3a\u6240\u6709\u6807\u51c6\u5e93\u5b98\u65b9\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u4f1a\u5047\u5b9a std::string \u7c7b\u578b\u662f ANSI \u7f16\u7801\u683c\u5f0f\uff08GBK\uff09\u3002\u5e76\u4e0d\u662f\u8bf4\uff0c\u4f60\u4e0d\u80fd\u7528 std::string \u5b58\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\u7684\u5185\u5bb9\u3002 \u5982\u679c\u4f60\u5c31\u662f\u60f3\u7528 std::string \u88c5 UTF-8 \u4e5f\u53ef\u4ee5\uff0c\u53ea\u4e0d\u8fc7\u4f60\u8981\u6ce8\u610f\u5728\u4f20\u5165\u6240\u6709\u4f7f\u7528\u4e86\u6587\u4ef6\u8def\u5f84\u7684\u51fd\u6570\uff0c\u5982 fopen \uff0c std::ifstream \u7684\u6784\u9020\u51fd\u6570\u524d\uff0c\u9700\u8981\u505a\u4e00\u4e2a\u8f6c\u6362\uff0c\u8f6c\u6210 GBK \u7684 std::string \u6216 UTF-16 \u7684 std::wstring \u540e\uff0c\u624d\u80fd\u4f7f\u7528\uff0c\u5f88\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u5982\u679c\u4f60\u59cb\u7ec8\u7528 std::u8string \u88c5 UTF-8\uff0c\u90a3\u4e48\u5f53\u4f60\u628a\u5b83\u8f93\u5165\u4e00\u4e2a\u63a5\u53d7 ANSI \u7684\u666e\u901a std::string \u53c2\u6570\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7c7b\u578b\u4e0d\u5339\u914d\u9519\u8bef\uff0c\u5f3a\u8feb\u4f60\u91cd\u65b0\u6e05\u9192\uff0c\u6216\u662f\u5f3a\u8feb\u4f60\u4f7f\u7528\u4e00\u4e2a\u8f6c\u6362\u51fd\u6570\uff0c\u7a0d\u540e\u4f1a\u4ecb\u7ecd\u8fd9\u4e2a\u8f6c\u6362\u51fd\u6570\u7684\u5199\u6cd5\u3002 \u4f8b\u5982\u5f53\u4f60\u4f7f\u7528 std::cout << u8string \u65f6\u4f1a\u62a5\u9519\uff0c\u8feb\u4f7f\u4f60\u6539\u4e3a std::cout << u8toansi(u8string) \u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff0c\u4ece\u800c\u907f\u514d\u4e86\u628a UTF-8 \u7684\u5b57\u7b26\u4e32\u6253\u5370\u5230\u4e86\u53ea\u652f\u6301 GBK \u7684\u63a7\u5236\u53f0\u4e0a\u3002 \u5176\u4e2d\u8f6c\u6362\u51fd\u6570\u7b7e\u540d\u4e3a std::string u8toansi(std::u8string s) \uff0c\u5f88\u53ef\u60dc\uff0c\u6807\u51c6\u5e93\u5e76\u6ca1\u6709\u63d0\u4f9b\u8fd9\u4e2a\u51fd\u6570\uff0c\u76f4\u5230 C++26 \u524d\uff0c\u6807\u51c6\u5e93\u5bf9\u5b57\u7b26\u7f16\u7801\u652f\u6301\u4e00\u76f4\u5f88\u5dee\uff0c\u4f60\u4e0d\u5f97\u4e0d\u81ea\u5df1\u5b9e\u73b0\u6216\u4f9d\u8d56\u7b2c\u4e09\u65b9\u5e93\u3002 \u603b\u4e4b\uff0c char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u5411\u8c03\u7528\u8005\u6697\u793a\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\u8fd9\u6837\u4e00\u4e2a\u51fd\u6570\uff1a thisFuncAcceptUTF8(std::u8string msg); \u5982\u679c\u8c03\u7528\u8005\u559c\u6b22\u7528 std::string \u88c5 UTF-8 \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528\uff1a std::string msg; // \u8c03\u7528\u8005\u786e\u4fe1\uff0c\u8fd9\u4e2a msg \u867d\u7136\u662f `std::string`\uff0c\u4f46\u91cc\u9762\u7684\u5185\u5bb9\u5c31\u662f UTF-8 // \u90a3\u4e48\u4ed6\u53ef\u4ee5\u5f3a\u5236\u8f6c\u6362\u4e3a u8string\uff0c\u6765\u8bc1\u660e\u81ea\u5df1\u5934\u8111\u6e05\u9192 thisFuncAcceptUTF8(std::u8string((char8_t *)msg.data(), msg.size())); \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 C++ \u5b98\u65b9\u5b9a\u4e49\u4e2d\uff0c\u5b58\u5728\u4e24\u79cd\u5b57\u7b26\u96c6\u3002\u4e00\u79cd\u662f \u6e90\u7801\u5b57\u7b26\u96c6 (source charset) \uff0c\u4e00\u79cd\u662f \u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u3002 \u8fd9\u771f\u662f\u7cdf\u7cd5\u7684\u672f\u8bed\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u8fd9\u4e2a\u540d\u5b57\u5177\u6709\u8bef\u5bfc\u6027\uff0c\u4ed6\u548c\u8fd0\u884c\u65f6\u6839\u672c\u6ca1\u6709\u5173\u7cfb\uff0c\u660e\u660e\u662f\u7f16\u8bd1\u671f\u5c31\u786e\u5b9a\u7684\u3002\u6240\u4ee5\u5c0f\u5f6d\u8001\u5e08\u66ff\u4ed6\u6539\u4e2a\u540d\u5b57\uff0c\u5b9e\u9645\u5e94\u8be5\u53eb\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u96c6\u201d\u3002 \u800c\u4e14\u4ed6\u4eec\u53eb\u5b57\u7b26\u96c6\u4e5f\u4e0d\u5408\u7406\uff0c\u5e94\u8be5\u53eb\u5b57\u7b26\u7f16\u7801\u624d\u5bf9\uff0cUTF-8 \u548c UTF-16 \u90fd\u662f Unicode \u5b57\u7b26\u96c6\u7684\u4e24\u79cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u4f46\u4ed6\u4eec\u660e\u663e\u662f\u4e0d\u540c\u7684\u3002 \u7136\u540e\uff0c\u518d\u5f15\u5165\u4e00\u4e2a\u771f\u6b63\u7684\uff0c\u8fd0\u884c\u65f6\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u8f6f\u4ef6\u5ba2\u6237\u7535\u8111\u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u6700\u7ec8\uff0c\u7ecf\u8fc7\u5c0f\u5f6d\u8001\u5e08\u6539\u826f\u7684\u672f\u8bed\u5982\u4e0b\uff1a \u6e90\u7801\u5b57\u7b26\u7f16\u7801: .cpp \u6e90\u7801\u6587\u4ef6\u65f6\u7528\u7684\u5b57\u7b26\u7f16\u7801\u3002\u4f8b\u5982\u7a0b\u5e8f\u5458\u7528\u8bb0\u4e8b\u672c\u4fdd\u5b58 .cpp \u6e90\u7801\u6587\u4ef6\u65f6\uff0c\u9009\u62e9 \u201cUTF-8\u201d \u4fdd\u5b58\u5c31\u662f UTF-8\uff0c\u9009\u62e9 \u201cANSI\u201d \u4fdd\u5b58\u5c31\u662f GBK\u3002 \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f char \u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u7684\u5b57\u7b26\u7f16\u7801\u3002\u9ed8\u8ba4\u662f\u6211\u4eec\u7a0b\u5e8f\u5458\uff08\u5f00\u53d1\u8005\uff09\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f\u6211\u4eec\u7684\u7a0b\u5e8f\u5728\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u8fd0\u884c\u65f6\uff0c\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf API \u7684 const char * \u671f\u671b\u63a5\u53d7\u600e\u6837\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002\u9ed8\u8ba4\u662f\u5ba2\u6237\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd9\u4e09\u4e2a\u53ef\u4ee5\u5404\u6709\u4e0d\u540c\u3002 \u5176\u4e2d \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801 \u548c \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801 \u7684\u4e0d\u5339\u914d\uff0c\u662f Windows \u8f6f\u4ef6\u51fa\u73b0\u4e71\u7801\u7684\u4e3b\u8981\u539f\u56e0\u3002 \u800c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u53ea\u4e8b\u5173\u4f60\u5982\u4f55\u4fdd\u5b58\u6e90\u7801\uff0c\u53ea\u662f\u8ba9\u7f16\u8bd1\u5668\u80fd\u591f\u6210\u529f\u8bfb\u53d6\u4f60\u7684\u6e90\u7801\uff0c\u5bf9\u8fd0\u884c\u65f6\u7684\u4e71\u7801\u95ee\u9898\u6ca1\u6709\u5f71\u54cd\u3002\u7f16\u8bd1\u5668\u8bfb\u5b8c\u6e90\u7801\u540e\uff0c\u8981\u5728\u5e38\u91cf\u533a\u751f\u6210\u5b57\u7b26\u4e32\u5e38\u91cf\u65f6\uff0c\u8fd8\u662f\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u7684\u3002 \u4f8b\u5982\u4e4b\u524d\u8bf4\u7684\u65e5\u672c galgame \u5728\u4e2d\u56fd\u7535\u8111\u4e0a\u6253\u5f00\u7206\u51fa\u4e71\u7801\uff0c\u5c31\u662f\u56e0\u4e3a\u662f\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u4e86 galgame\uff08\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u4e3a Shift-JIS\uff09\uff0c\u5728\u4e2d\u56fd\u5ba2\u6237\u7535\u8111\u4e0a\u6253\u5f00\uff08\u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801\u4e3a GBK\uff09\u5bfc\u81f4\u7684\u3002 \u65e5\u672c\u7a0b\u5e8f\u5458\u4f7f\u7528\u4ec0\u4e48\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u6839\u672c\u65e0\u5173\u7d27\u8981\u2026\u2026\u54ea\u6015\u4ed6\u4eec\u4f7f\u7528\u4e86 UTF-8 \u4fdd\u5b58\u6e90\u7801\uff0cMSVC \u7f16\u8bd1\u65f6\u4ecd\u7136\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a Shift-JIS \u7f16\u7801\u7684\u5b57\u9762\u91cf\u6765\u5b58\u50a8\u5728\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5e38\u91cf\u533a\u4e2d\u3002 \u4f60\u53ef\u80fd\u4f1a\u95ee\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u628a\u8fd9\u4e9b\u82b1\u91cc\u80e1\u54e8\u73a9\u5e94\u7edf\u4e00\u4e3a UTF-8\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u8f6c\u6362\u6765\u8f6c\u6362\u53bb\u4e86\uff1f\u8fd8\u4e0d\u662f\u56e0\u4e3a\u5386\u53f2\u9057\u7559\uff0c\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\u5458\u4e0d\u80af\u628a\u4ed6\u4eec GBK \u7f16\u7801\u7684\u6e90\u7801\u6539\u6210 UTF-8 \u4fdd\u5b58\uff0c\u800c\u4e14\uff0cWindows \u4e5f\u5b8c\u5168\u4e0d\u63d0\u4f9b\u57fa\u4e8e UTF-8 \u7684\u8de8\u5e73\u53f0 API\uff08\u53ea\u63d0\u4f9b GBK \u548c UTF-16 \u4e24\u79cd\uff0c\u5c31\u662f\u4e0d\u7ed9 UTF-8 \u7684\uff0c\u975e\u5e38\u6076\u5fc3\u4eba\uff09\u3002\u6240\u4ee5 MSVC \u81f3\u4eca\u4ecd\u7136\u9ed8\u8ba4\u662f GBK \u7f16\u7801\u7684\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f ANSI\uff0c\u8ddf\u968f\u4f60\u7cfb\u7edf\u7684\u533a\u57df\u8bbe\u7f6e\u800c\u53d8\uff0c\u5728\u4e2d\u56fd\u5c31 GBK\uff0c\u5728\u7f8e\u56fd\u5c31 UTF-8\uff0c\u5728\u6b27\u6d32\u5c31 Latin-1\uff0c\u975e\u5e38\u7684\u53cc\u6807\uff09\u3002\u5fae\u8f6f\u5404\u79cd\u626f\u76ae\u6548\u7387\u4f4e\u4e0b\uff0cAPI \u5f04\u4e86\u4e00\u5957\u53c8\u4e00\u5957\u4e92\u76f8\u6781\u9650\u62c9\u626f\uff0c\u800c\u6211\u4eec Linux \u548c GCC \u65e9\u5df2\u9ed8\u8ba4\u5c31\u662f UTF-8\u2026\u2026 \u6211\u7406\u89e3\u4f60\u73b0\u5728\u5927\u8111\u5e72\u70e7\u7684\u5fc3\u60c5\u3002\u4f3a\u5019\u8fd9\u4e9b\u5386\u53f2\u7b54\u8fa9\u5f88\u590d\u6742\uff0c\u4e5f\u5f88\u65e0\u804a\uff0c\u6beb\u65e0\u610f\u4e49\uff01\u53ea\u662f\u4e3a\u4e86\u64e6\u53cd Unicode \u52b3\u4fdd\u7684\u5c41\u80a1\u3002 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a \u5bf9\u4e8e\u8de8\u5e73\u53f0\u8f6f\u4ef6\u6765\u8bf4\uff0c\u6211\u63a8\u8350\u5927\u5bb6\u628a\u4e09\u4e2a\u5168\u90e8\u8bbe\u4e3a UTF-8\uff01\uff08\u8981\u505a\u5230\u8fd9\u4e00\u70b9\uff0c\u4e3b\u8981\u662f\u4f3a\u5019 MSVC\uff09 Linux + GCC \u7528\u6237\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u4f60\u4eec\u6240\u6709\u5b57\u7b26\u96c6\u9ed8\u8ba4\u7684\u8bbe\u5b9a\u5c31\u662f UTF-8\u3002 Windows + MSVC \u7528\u6237\u8bf7\u5f00\u542f /utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\uff0c\u73b0\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u90fd\u662f UTF-8 \u4e86\u3002 Windows + MinGW \u7528\u6237\u8bf7\u5f00\u542f -finput-charset=utf-8 \u548c -fexec-charset=utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\u3002 \u6240\u6709\u6e90\u7801\u6587\u4ef6\u7edf\u4e00\u4ee5 UTF-8 \u7f16\u7801\u4fdd\u5b58\uff0c\u4e14\u5c3d\u91cf\u5728\u6700\u524d\u9762\u52a0\u4e0a 0xFEFF \u8fd9\u4e2a BOM \u6807\u8bb0\uff0c\u9632\u6b62 MSVC \u8111\u62bd\u5f53\u4f5c GBK \u6765\u8bfb\u53d6\u3002 \u5728 main \u51fd\u6570\u524d\uff0c\u52a0\u4e24\u884c\uff1a // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 return 0; } \u8fd9\u6837\u4e00\u5957\u6253\u4e0b\u6765\uff0c\u5c31\u53ef\u4ee5\u4fdd\u8bc1\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u64cd\u4f5c\u7cfb\u7edf\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u6587\u672c\u7f16\u8f91\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u7801\uff0c\u4f60\u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u8bfb\u53d6\u6e90\u7801\uff0c\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u5b58\u50a8\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6b63\u786e\u7684\u628a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u8def\u5f84\u8f6c\u4e3a UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u3002 \u5728 CMake \u4e2d\uff0c\u53ea\u5bf9 MSVC \u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8fd9\u6837\u5199\uff1a if (MSVC) target_compile_options(\u4f60\u7684\u7a0b\u5e8f PRIVATE /utf-8) else() \u4e5f\u53ef\u4ee5\u5728\u6700\u524d\u9762 add_compile_options \uff0c\u5b9e\u73b0\u5bf9\u6240\u6709\u4e4b\u540e\u5b9a\u4e49\u7684\u7a0b\u5e8f\u5168\u5c40\u542f\u7528\u8be5\u9009\u9879\u3002 \u5728\u6211\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\uff0c\u6211\u90fd\u4f1a\u8fd9\u6837\u5f00\u542f\uff0c\u89e3\u51b3 MSVC \u4e0d\u8de8\u5e73\u53f0\u7684\u95ee\u9898\uff1a if (MSVC) add_compile_options(/Zc:preprocessor /utf-8 /DNOMINMAX /D_USE_MATH_DEFINES /EHsc /bigobj) else() if (WIN32) add_compile_options(-finput-charset=utf-8 -fexec-charset=utf-8) endif() add_compile_options(-Wall -Wextra -Werror=return-type) endif() add_executable(\u4f60\u7684\u7a0b\u5e8f \u4f60\u7684\u6587\u4ef6.cpp) # \u81ea\u52a8\u7ee7\u627f\u4e86\u4e0a\u9762\u6240\u6709\u7684\u7f16\u8bd1\u5668\u9009\u9879 .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 Windows \u5b98\u65b9\u63d0\u4f9b\u7684\u771f\u6b63 API \u662f _wfopen \u3002 fopen \u53ea\u662f\u4ed6\u4eec\u63d0\u4f9b\u7684\u201cPOSIX \u517c\u5bb9\u5c42\u201d \u5305\u88c5\uff0c\u5176\u4f1a\u628a\u8f93\u5165\u7684\u5b57\u7b26\u4e32\u53c2\u6570\u901a\u8fc7 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u540e\uff0c\u8f6c\u53d1\u7ed9 _wfopen \u3002 \u51fa\u4e8e\u8de8\u5e73\u53f0\u7684\u8981\u6c42\uff0c\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528 _wfopen \u8fd9\u79cd\u5176\u4ed6\u5e73\u53f0\u6ca1\u6709\u7684\u51fd\u6570\uff0c\u4e5f\u4e0d\u60f3\u7528\u90a3\u8fde 2 \u5b57\u8282 4 \u5b57\u8282\u90fd\u98d8\u5ffd\u4e0d\u5b9a\u7684 wchar_t \uff0c\u66f4\u4e0d\u60f3\u8ba9 std::string \u5b58\u6839\u672c\u4e0d\u80fd\u8de8\u5e73\u53f0\u7684 GBK\u3002 \u53ea\u8981\u8ba9 fopen \u7684 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u51fd\u6570\u66ff\u6362\u6210 \u201cUTF-8 \u5230 UTF-16\u201d \u5c31\u884c\u4e86\u3002\u8fc7\u53bb\uff0c\u6211\u4eec\u65e0\u6cd5\u66ff\u6362\uff0c\u6700\u65b0\u7684 Windows \u5728\u4e00\u6b21\u66f4\u65b0\u4e2d\uff0c\u652f\u6301\u4e86 \".utf-8\" locale \u8fd9\u4e00\u9ed1\u79d1\u6280\uff0c\u4e13\u95e8\u6ee1\u8db3\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u7684\u9700\u8981\u3002 // \u9ed8\u8ba4 locale fopen(\"\u4f60\u597d.txt\") == _wfopen(gbk_to_utf16(\"\u4f60\u597d.txt\")); // \u8bbe\u7f6e\u4e86 utf-8 locale \u540e fopen(\"\u4f60\u597d.txt\") == _wfopen(utf8_to_utf16(\"\u4f60\u597d.txt\")); \u82e5\u4e0d\u8bbe\u7f6e setlocale(LC_ALL, \".utf-8\") \uff0c\u5219 fopen \u548c ifstream \u9ed8\u8ba4\u4f1a\u628a\u4f60\u63d0\u4f9b\u7684 const char * \u6587\u4ef6\u8def\u5f84\uff0c\u5f53\u4f5c GBK \u7f16\u7801\u7684\uff0c\u800c\u6211\u4eec\u8bbe\u7f6e\u4e86 /utf-8 \u6216 -fexec-charset=utf-8 \u540e\uff0c\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u7f16\u7801\u5df2\u7ecf\u662f UTF-8 \u4e86\uff0c\u8fd9\u6837 UTF-8 \u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u8f93\u5165\u8fdb\u671f\u671b const char * \u7684 fopen \u53c2\u6570\uff0c\u5c31\u4f1a\u51fa\u4e71\u7801\u95ee\u9898\u4e86\u3002 \u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c .utf-8 locale \u53ea\u662f\u5f71\u54cd\u4e86\u6807\u51c6\u5e93\uff01\u5e76\u4e0d\u6539\u53d8\u7cfb\u7edf API\u3002 \u76f4\u63a5\u8c03\u7528\u7cfb\u7edf API \u65f6\uff0cA \u7cfb API \u4ecd\u7136\u6709\u95ee\u9898\u3002 MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u63d0\u793a\", MB_OK); // \u4e0d\u884c\uff0c.utf-8 \u53ea\u662f\u8ba9\u6807\u51c6\u5e93\u53d8\u6210 UTF-8 \u63a5\u53e3\u4e86\uff0cA \u7cfb Windows API \u4ecd\u7136\u662f GBK MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u63d0\u793a\", MB_OK); // \u6ca1\u95ee\u9898\uff01\u7528 UTF-16 \u7684 wchar_t \u5b57\u9762\u91cf\u6765\u8c03\u7528 W \u63a5\u53e3\u603b\u662f\u6ca1\u95ee\u9898\u7684 \u8fd8\u662f\u9700\u8981\u6211\u4eec\u624b\u52a8\u8f6c\u6362 UTF-8 \u5230 UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u2026\u2026\u4f46\u662f\u53cd\u6b63\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u5f88\u5c11\u9700\u8981\u76f4\u63a5\u8c03\u7528 Windows API\uff0c\u90fd\u662f\u901a\u8fc7\u901a\u7528\u7684 C/C++ \u6807\u51c6\u5e93\uff0c\u56e0\u6b64 .utf-8 locale \u53ef\u80fd\u662f\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u60f3\u8fdb\u519b UTF-8 \u7684\u6700\u4f73\u9009\u62e9\u3002 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e \u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\uff0c\u90fd\u662f\u9488\u5bf9 char \u7684\uff0c\u53ea\u6709 char \u88ab\u6545\u610f\u9488\u5bf9\u4e86\uff0c\u5b58\u5728\u5b57\u7b26\u7f16\u7801\u4e0d\u7edf\u4e00\u7684\u95ee\u9898\u3002 \u5982\u679c\u5168\u90e8\u7528 wchar_t \u7684\u8bdd\uff0c\u867d\u7136\u5728 Linux \u4e0a\u662f UTF-32\uff0c\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u4e0d\u7edf\u4e00\u4e86\u3002\u4f46\u81f3\u5c11\u5728\u540c\u4e00\u4e2a Windows \u64cd\u4f5c\u7cfb\u7edf\u4e0a\uff0c\u90fd\u662f\u7edf\u4e00\u7684 UTF-16\u3002 \u6240\u4ee5\u8fd8\u6709\u4e00\u79cd\u65b9\u5f0f\u662f\u5168\u9762\u91c7\u7528 wchar_t \u548c std::wstring \uff0c\u8fd9\u6837\u65e0\u8bba\u4f60\u7684\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\u5982\u4f55\uff0c\u90fd\u5bf9 wchar_t \u548c\u57fa\u4e8e const wchar_t * \u7684\u51fd\u6570\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\u3002 C \u8bed\u8a00\u6807\u51c6\u6ca1\u6709 _wfopen \uff0c\u4f46\u662f std::ifstream \u6709\u57fa\u4e8e std::wstring \u7684\u6784\u9020\u51fd\u6570\uff0c\u5c31 C++ \u6807\u51c6\u5e93\u6765\u770b std::wstring \u7684\u652f\u6301\u8fd8\u662f\u5f88\u4e30\u5bcc\u7684\uff0c\u57fa\u672c std::string \u6709\u7684 std::wstring \u90fd\u6709\uff0c\u4f8b\u5982 std::to_string \u548c std::to_wstring \uff0c std::cout \u548c std::wcout \u3002\u672c\u7ae0\u8282\u6700\u540e\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u5bbd\u5b57\u7b26\u6d41\u7684\u7528\u6cd5\u3002 \u7f3a\u70b9\u662f\uff0c\u9996\u5148\u6bcf\u6b21\u90fd\u9700\u8981\u5199 L\"\u4f60\u597d\" \u8fd9\u4e2a L \u524d\u7f00\u5f88\u9ebb\u70e6\uff0c\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u4e14\u5f88\u591a\u7b2c\u4e09\u65b9\u5e93\u90fd\u5728\u7528 std::string \uff0c\u5e76\u6ca1\u6709\u63d0\u4f9b std::wstring \u7684 API\u3002 \u4f8b\u5982 openvdb \u7684\u6587\u4ef6\u5199\u5165\u51fd\u6570\uff1a void openvdb::io::File::write(std::string const &filename); \u8fd9\u6837\u5c31\u5f88\u9ebb\u70e6\u4e86\uff0c\u5982\u679c\u4f60\u5185\u90e8\u5168\u662f UTF-16 \u7684 std::wstring \u6765\u8868\u793a\u5b57\u7b26\u4e32\uff0c\u8c03\u7528\u7b2c\u4e09\u65b9\u5e93\u524d\u5c31\u9700\u8981\u8f6c\u6210 GBK \u7684 std::string \u3002\u53ef\u4ee5\u7528 boost::locale::conv::to_utf \u8fd9\u4e2a\u51fd\u6570\u8f6c\u6362\uff0c\u4f46\u4e5f\u5f88\u9ebb\u70e6\uff0c\u800c\u4e14\u5982\u679c std::wstring \u542b\u6709 GBK \u8303\u56f4\u4e4b\u5916\u7684 \u201c\ud883\udede\u201d\uff0cGBK \u65e0\u6cd5\u8868\u793a\uff0c\u53c8\u4f1a\u6709\u7f16\u7801\u5931\u8d25\u7684\u95ee\u9898\u3002 \u8fd8\u6709 stbi_load \u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u662f\u53ea\u63d0\u4f9b\u4e86 const char * \u7684\u63a5\u53e3\uff0c\u591a\u4e86\u53bb\u4e86\u3002 setlocale(LC_ALL, \".utf-8\") \u7684\u597d\u5904\u662f\u53ef\u4ee5\u8ba9\u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u5168\u81ea\u52a8\u90fd\u4ece GBK \u65e0\u7f1d\u5207\u6362\u5230 UTF-8\uff0c\u800c\u4e0d\u7528\u5bf9\u4ed6\u4eec\u7684\u6e90\u7801\u505a\u4efb\u4f55\u66f4\u6539\u3002\u56e0\u4e3a\u4ed6\u4eec\u5185\u90e8\u90fd\u662f\u8c03\u7528\u7684 fopen \u548c ifstream \u3002 u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u4e2d\u56fd\u533a Windows\uff0cMSVC\uff0c\u7f16\u8bd1\u9009\u9879\uff1a /std:c++17 std::string s = \"\u4f60\u597d\"; hexdump(s); // C4 E3 BA C3 (GBK) std::string s = u8\"\u4f60\u597d\"; hexdump(s); // E4 BD A0 E5 A5 BD (UTF-8) u8 \u524d\u7f00\u544a\u8bc9\u7f16\u8bd1\u5668\uff0c\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u7f16\u7801\u5b58\u50a8\u3002\u65e0\u8bba\u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u662f\u4e0d\u662f UTF-8\u3002 \u7f16\u8bd1\u5668\u4fdd\u8bc1\u4f1a\u628a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u8f6c\u6362\u4e3a UTF-8 \u7f16\u7801\u7684 char \u5b57\u8282\u5e8f\u5217\uff0c\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u533a\u3002 \u8fd9\u5bf9\u4e8e\u5df2\u7ecf\u8bbe\u7f6e\u4e86 /utf-8 \u9009\u9879\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u5df2\u7ecf\u4fdd\u8bc1\u662f UTF-8 \u7684\u6211\u4eec\u6765\u8bf4\u6beb\u65e0\u4f5c\u7528\u3002\u53ea\u662f\u5bf9\u4e8e\u4e0d\u7528 /utf-8 \u7684\u540c\u5b66\uff0c\u4ed6\u4eec\u60f3\u8981\u4e34\u65f6\u521b\u5efa\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5c31\u53ef\u4ee5\u7528 u8 \u524d\u7f00\u3002 \u5728 C++17 \u548c\u4e4b\u524d\uff0c u8\"\u4f60\u597d\" \u4ea7\u751f\u7684\u662f const char [] \u7c7b\u578b\u7684\u5e38\u91cf\u3002 \u5728 C++20 \u4e2d\uff0c\u5f15\u5165\u4e86 char8_t \u3002\u7136\u540e\uff0c\u4ed6\u4eec\u89c4\u5b9a\uff0c u8\"\u4f60\u597d\" \u73b0\u5728\u4ea7\u751f\u7684\u662f const char8_t [] \u7c7b\u578b\u7684\u5e38\u91cf\u4e86\u3002 \u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u517c\u5bb9\u6027\u95ee\u9898\uff0c\u6bd4\u5982\u4ee5\u524d\u4f60\u5199\u7684\uff1a std::string s = u8\"\u4f60\u597d\"; \u73b0\u5728\u65e0\u6cd5\u7f16\u8bd1\u901a\u8fc7\u4e86\uff0c\u56e0\u4e3a const char8_t [] \u65e0\u6cd5\u7528\u4e8e\u6784\u9020\u53ea\u652f\u6301 const char [] \u7684 std::string \u3002 \u597d\u5728 C++23 \u53c8\u4fee\u590d\u4e86\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u4eec\u5141\u8bb8 const char8_t [] \u9690\u5f0f\u8f6c\u6362\u4e3a const char [] \uff0cC++17 \u4e4b\u524d\u7684\u8fd9\u79cd\u4ee3\u7801\u53c8\u80fd\u6b63\u5e38\u901a\u8fc7\u7f16\u8bd1\u3002\u6240\u4ee5\uff0c\u5982\u679c\u60f3\u5feb\u4e50\u5730\u7528 u8 \u5b57\u9762\u91cf\uff0c\u8981\u4e48 C++17\uff0c\u8981\u4e48 C++23\uff0c\u8df3\u8fc7 C++20 \u6bd4\u8f83\u597d\u3002 \u4f60\u53ef\u4ee5\u770b\u5230\uff0cC++ \u7248\u672c\u7684\u66f4\u65b0\u5e76\u4e0d\u662f 100% \u5b8c\u5168\u5411\u524d\u517c\u5bb9\u7684\uff0c\u6709\u65f6\u4e5f\u4f1a\u6709\u7834\u574f\u6027\u7684\u53d8\u66f4\uff0c\u4f46\u6bd4\u8f83\u5c11\uff0c\u5e73\u65f6\u611f\u89c9\u4e0d\u5230\u3002\u6bd4\u5982 C++11 \u4e4b\u524d auto \u5c31\u6709\u5176\u4ed6\u7684\u529f\u80fd\uff0c\u540e\u6765\u51b3\u5b9a\u8fd9\u4e2a\u529f\u80fd\u6ca1\u4ec0\u4e48\u7528\uff0c\u5c31\u628a auto \u6539\u6210\u53e6\u4e00\u4e2a\u610f\u601d\u4e86\u3002 \u9664\u4e86 u8 \u4ee5\u5916\uff0c\u8fd8\u6709\u8fd9\u4e9b\uff1a \u524d\u7f00 \u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u201c\u4f60\u597d\u201d \u8fd0\u884c\u5b57\u7b26\u96c6 (\u9ed8\u8ba4\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7684) const char [] L\u201d\u4f60\u597d\u201d Windows \u4e0a UTF-16\uff1bLinux \u4e0a UTF-32 const wchar_t [] u8\u201d\u4f60\u597d\u201d UTF-8 const char8_t [] u\u201d\u4f60\u597d\u201d UTF-16 const char16_t [] U\u201d\u4f60\u597d\u201d UTF-32 const char32_t [] \u53ea\u4e0d\u8fc7\u662f\u5f00\u53d1\u8005\u548c\u5ba2\u6237\u5f80\u5f80\u5904\u4e8e\u540c\u4e00\u4e2a\u5730\u533a\uff0c\u6240\u4ee5 \"\u4f60\u597d\" \u770b\u8d77\u6765\u597d\u50cf\u53ef\u4ee5\u76f4\u63a5\u8f93\u5165\u5230 std::cout \u4e2d\u4e00\u6837\u3002\u5b9e\u9645\u4e0a\u4ed6\u53ea\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684 ANSI\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7535\u8111\u7684 ANSI\uff0c\u5982\u679c\u76f4\u63a5\u62ff\u6765\u6253\u5370\uff0c\u4f1a\u5bfc\u81f4\u4ee5 \"\" \u5e38\u91cf\u5f62\u5f0f\u5199\u6b7b\u7684\u5b57\u7b26\u4e32\u4f1a\u5728\u5ba2\u6237\u7535\u8111\u4e0a\u51fa\u73b0\u4e71\u7801\u3002\u9664\u975e\u8fd9\u4e2a\u5b57\u7b26\u4e32\u53ea\u5305\u542b ASCII\uff0c\u56e0\u4e3a\u6240\u6709 ANSI \u90fd\u517c\u5bb9 ASCII\uff0c\u624d\u6070\u597d\u907f\u514d\u4e86\u4e71\u7801\u3002 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 \u628a\u5b57\u7b26\u4e32\u5f53\u4f5c\u7eaf\u7cb9\u7684\u201c\u5b57\u8282\u6d41\u201d\uff0c\u65e0\u89c6\u5b57\u7b26\u7f16\u7801\u3002\u6216\u8005\u8bf4\uff0c\u4f60\u4ece\u7cfb\u7edf\u8f93\u5165\u8fdb\u6765\u7684\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u6211\u5c31\u5b58\u50a8\u7684\u4ec0\u4e48\u7f16\u7801\u3002\u5bf9\u4e8e Unicode \u5219\u91c7\u53d6\u5b8c\u5168\u6446\u70c2\u7684\u6001\u5ea6\uff0c\u5b8c\u5168\u65e0\u89c6 Unicode \u7684\u5b58\u5728\u3002 \u9002\u7528\u573a\u666f\uff1a\u901a\u5e38\u4e0e\u6587\u5b57\u5904\u7406\u9886\u57df\u65e0\u5173\u7684\u8f6f\u4ef6\u4f1a\u91c7\u53d6\u8fd9\u79cd\u65b9\u6848\u3002 \u4f18\u70b9\uff1a\u65b9\u4fbf\uff0c\u4e14\u5185\u90e8\u5bf9\u5b57\u7b26\u4e32\u65e0\u4efb\u4f55\u8f6c\u6362\u548c\u5224\u65ad\uff0c\u6548\u7387\u6700\u9ad8\u3002 \u7f3a\u70b9\uff1a\u5728\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u8bfb\u5199\u5e26\u6709\u4e2d\u6587\u7684\u6587\u4ef6\u8def\u5f84\u65f6\uff0c\u4f1a\u9971\u53d7\u4e71\u7801\u548c\u627e\u4e0d\u5230\u6587\u4ef6\u7684\u56f0\u6270\u3002 \u65b9\u6cd5\uff1a\u5b8c\u5168\u4f7f\u7528 const char * \u548c std::string \u3002 \u4ee3\u8868\u4f5c\uff1aLinux \u6587\u4ef6\u7cfb\u7edf ext4\u3001Lua \u7f16\u7a0b\u8bed\u8a00\u3001\u73b0\u4ee3 Python \u4e2d\u7684 bytes \u7c7b\u578b\u3001HTTP \u7684 ? \u53c2\u6570\u3001\u65e9\u671f FAT32 \u6587\u4ef6\u7cfb\u7edf\u7b49\u3002 \u8fd9\u7c7b\u8f6f\u4ef6\u662f\u6700\u5e38\u89c1\u7684\u521d\u5b66\u8005\u5199\u6cd5\uff0c\u5982\u679c\u4f60\u4ece\u672a\u60f3\u8fc7\u5b57\u7b26\u7f16\u7801\u95ee\u9898\uff0c\u4ece\u4e0d\u4e86\u89e3 wchar_t \u3001 char32_t \u4e4b\u95f4\u7684\u6218\u4e89\uff0c\u53ea\u77e5\u9053 char \uff0c\u90a3\u4e48\u4f60\u5df2\u7ecf\u81ea\u52a8\u5728\u6b64\u9635\u8425\u91cc\u3002 \u6709\u4eba\u8bf4 Linux \u6587\u4ef6\u7cfb\u7edf\u662f UTF-8\uff1f\u5e76\u4e0d\u662f\uff01Linux \u6587\u4ef6\u7cfb\u7edf\u6839\u672c\u4e0d\u4f1a\u68c0\u9a8c\u4f60\u7684\u6587\u4ef6\u540d\u662f\u4e0d\u662f\u5408\u6cd5\u7684 UTF-8\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u4f60\u8bbe\u5b9a\u4e86 export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u4f1a\u4f7f\u6240\u6709\u7a0b\u5e8f\uff08\u5305\u62ec\u7ec8\u7aef\u6a21\u62df\u5668\uff09\u5047\u5b9a\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u5185\u5bb9\u90fd\u6309 UTF-8 \u7f16\u7801\uff0c\u4ece\u800c\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u5404\u7c7b API \u65f6\uff08\u5982 open\u3001write\uff09\u90fd\u4f1a\u4f7f\u7528 UTF-8 \u7f16\u7801\u7684 const char * \u8f93\u5165\uff0c\u5728 Linux \u7cfb\u7edf API \u770b\u6765\uff0c\u6240\u8c13\u201c\u6587\u4ef6\u540d\u201d\u53ea\u662f\u7eaf\u7cb9\u7684\u5b57\u8282\u6d41\uff0c\u53ea\u8981\u4fdd\u8bc1\u4e0d\u5305\u542b '/' \u548c '\\0' \uff0c\u65e0\u8bba\u4f60\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4ed6\u90fd\u4e0d\u5728\u4e4e\u3002\u800c\u6240\u6709\u7684 locale \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u7edd\u4e0d\u4f1a\u51fa\u73b0\u4e00\u4e2a\u4e2d\u6587\u6c49\u5b57\u7f16\u7801\u540e\u4ea7\u751f '/' \u7684\u60c5\u51b5\uff08\u4f8b\u5982 GB2312 \u4f1a\u628a\u4e00\u4e2a\u4e2d\u6587\u7f16\u7801\u6210\u4e24\u4e2a 0x80 \u5230 0xFF \u533a\u95f4\u7684\u5b57\u8282\uff0c\u548c ASCII \u7684\u8303\u56f4\u6ca1\u6709\u91cd\u53e0\uff0c\u66f4\u4e0d\u53ef\u80fd\u51fa\u73b0 '/' \uff09\uff0c\u5373\u4f7f\u6362\u6210 export LC_ALL=zh_CN.GB2312 \uff0cLinux \u6587\u4ef6\u7cfb\u7edf\u4e00\u6837\u80fd\u6b63\u5e38\u5de5\u4f5c\uff0c\u53ea\u4e0d\u8fc7\u8bfb\u53d6\u4f60\u4e4b\u524d\u4ee5 UTF-8 \u5199\u5165\u7684\u6587\u4ef6\u4f1a\u53d8\u6210\u4e71\u7801\u800c\u5df2\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a\u7684 Windows \u800c\u8a00\uff0c\u4ed6\u7684\u6240\u6709 A \u51fd\u6570\u53ea\u652f\u6301 GBK \u7f16\u7801\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u4f60 Lua \u4e2d\u628a\u5b57\u7b26\u4e32\u201c\u5f53\u4f5c\u201d UTF-8 \u6765\u7528\u3002\u90a3\u4e48\u5f53\u4f60\u5728\u8c03\u7528 Lua \u7684 io.open \u524d\uff0c\u9700\u8981\u5148\u505a\u4e00\u4e2a UTF-8 \u5230 GBK \u7684\u8f6c\u6362\uff0c\u8fd9\u8fd8\u4f1a\u5bfc\u81f4\u4e22\u5931\u90e8\u5206\u4e0d\u5728 GBK \u5185\u7684\u5b57\u7b26\uff0c\u6bd4\u5982\u5982\u679c\u4f60\u7684\u6587\u4ef6\u540d\u5305\u542b Emoji\uff0c\u90a3\u5c31\u4f1a\u53d8\u6210 ??? \u4e71\u7801\u3002\u800c\u4f7f\u7528 W \u51fd\u6570\u7684 UTF-16 \u5c31\u4e0d\u4f1a\uff0c\u56e0\u4e3a UTF-16 \u80fd\u5bb9\u7eb3\u5b8c\u6574\u7684 Unicode \u6620\u5c04\u3002\u800c\u5b8c\u5168\u6446\u70c2\u7684 Lua\uff0c\u5176 io.open \u53ea\u662f\u4f7f\u7528 C \u8bed\u8a00\u5e93\u51fd\u6570 fopen \uff0c fopen \u53c8\u662f\u57fa\u4e8e Windows \u7684 A \u7cfb\u5217\u51fd\u6570\uff0cLua \u53c8\u6ca1\u6709\u63d0\u4f9b\u5bf9 Windows C \u8fd0\u884c\u65f6\u5e93\u7279\u6709\u7684 _wfopen \u51fd\u6570\u7684\u5c01\u88c5\uff0c\u4ece\u800c\u6c38\u8fdc\u4e0d\u53ef\u80fd\u6253\u5f00\u4e00\u4e2a\u5e26\u6709 Emoji \u7684\u6587\u4ef6\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 ANSI \u9635\u8425\uff0c\u4f60\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0cchar \u6ee1\u5929\u98de\u6446\u70c2\u3002 UTF-8 \u9635\u8425 \u652f\u6301 Unicode\uff0c\u5b57\u7b26\u4e32\u7edf\u4e00\u4ee5 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u3001\u5904\u7406\u548c\u4f20\u8f93\u3002 \u5e94\u7528\u573a\u666f\uff1a\u5e38\u89c1\u4e8e\u6587\u5b57\u5904\u7406\u9700\u6c42\u4e0d\u5927\uff0c\u4f46\u6709\u5f3a\u70c8\u7684\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u7279\u522b\u662f\u4e92\u8054\u7f51\u65b9\u9762\u7684\u8f6f\u4ef6\u3002\u4ed6\u4eec\u901a\u5e38\u53ea\u7528\u5230\u5b57\u7b26\u4e32\u7684\u62fc\u63a5\u3001\u67e5\u627e\u3001\u5207\u7247\u901a\u5e38\u4e5f\u53ea\u662f\u5728\u56fa\u5b9a\u7684\u4f4d\u7f6e\uff08\u4f8b\u5982\u6587\u4ef6\u5206\u9694\u7b26 '/' \uff09\u3002\u4e5f\u975e\u5e38\u9002\u5408\u4e3b\u8981\u9762\u5bf9\u7684\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0cUTF-8 \u662f\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u6700\u9ad8\u7684\uff0c\u6240\u4ee5\u4e5f\u5e7f\u6cdb\u7528\u4e8e\u7f16\u8bd1\u5668\u3001\u6570\u636e\u5e93\u4e4b\u7c7b\u7684\u573a\u666f\u3002\u540c\u65f6\u56e0\u4e3a UTF-8 \u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u4f7f\u5f97\u4ed6\u80fd\u8f7b\u6613\u9002\u914d\u8fdc\u53e4\u7684 C \u8bed\u8a00\u7a0b\u5e8f\u548c\u5e93\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-8 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8de8\u5e73\u53f0\uff0c\u5728\u7f51\u7edc\u4f20\u8f93\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u7801\uff0cUTF-8 \u662f\u4e92\u8054\u7f51\u7684\u4e3b\u6d41\u7f16\u7801\u683c\u5f0f\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a\u8fd0\u884c\u7684 UTF-8 \u8f6f\u4ef6\u53ef\u4ee5\u968f\u610f\u5171\u4eab\u6587\u672c\u6570\u636e\u3002\u517c\u5bb9 ASCII\uff0c\u65b9\u4fbf\u590d\u7528\u73b0\u6709\u5e93\u548c\u751f\u6001\u3002\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u9ad8\uff0c\u5bf9\u4e2d\u6587\u6587\u672c\u4e5f\u4e0d\u7b97\u592a\u5dee\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e\u5e95\u5c42 API \u5747\u91c7\u7528 UTF-16 \u7684 Windows \u7cfb\u7edf\uff0c\u9700\u8981\u8fdb\u884c\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u635f\u5931\u3002\u4e14\u5b57\u7b26\u4e32\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4f1a\u53d8\u6210 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002 \u4ee3\u8868\u4f5c\uff1aRust \u8bed\u8a00\u3001Go \u8bed\u8a00\u3001CMake \u6784\u5efa\u7cfb\u7edf\u3001Julia \u8bed\u8a00\u7b49\u3002 \u5728 C++ \u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7 u8\"\u4f60\u597d\" \u521b\u5efa\u4e00\u4e2a\u4fdd\u8bc1\u5185\u90e8\u662f UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u7c7b\u578b\u4e3a char8_t [] \u3002 \u5982\u679c\u7528\u65e0\u524d\u7f00\u7684 \"\u4f60\u597d\" \u521b\u5efa\uff0c\u5219 MSVC \u9ed8\u8ba4\u4f1a\u4ee5\u7f16\u8bd1\u8005\u6240\u5728\u7cfb\u7edf\u7684\u201c\u533a\u57df\u8bbe\u7f6e (locale)\u201d \u4f5c\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7f16\u7801\u683c\u5f0f\uff08\u800c\u4e0d\u662f\u8fd0\u884c\u8005\u7684\u533a\u57df\u8bbe\u7f6e\uff01\uff09\uff0c\u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8ba9 MSVC \u7f16\u8bd1\u5668\u9ed8\u8ba4\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u5373\u8ba9 \"\u4f60\u597d\" \u548c u8\"\u4f60\u597d\" \u4e00\u6837\u91c7\u7528 UTF-8\u3002\u800c GCC \u9ed8\u8ba4\u5c31\u662f UTF-8\uff0c\u9664\u975e\u624b\u52a8\u6307\u5b9a -fexec-charset=GBK \u6765\u5207\u6362\u5230 GBK\u3002\u7a0d\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u7f16\u8bd1\u5668\u7684\u5b57\u7b26\u7f16\u7801\u95ee\u9898\u3002 \u5047\u8bbe\u4f60\u901a\u8fc7 /utf-8 \u6216 -fexec-charset=utf-8 \u641e\u5b9a\u4e86\u7f16\u8bd1\u671f\u5e38\u91cf\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u3002\u63a5\u4e0b\u6765\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u6587\u4ef6\u7cfb\u7edf\u3002 Linux \u6587\u4ef6\u7cfb\u7edf\u5185\u90e8\uff0c\u5747\u4f7f\u7528 8 \u4f4d\u7c7b\u578b char \u5b58\u50a8\uff0c\u5c06\u6587\u4ef6\u540d\u5f53\u4f5c\u5e73\u51e1\u7684\u5b57\u8282\u6d41\uff0c\u4e0d\u4f1a\u505a\u4efb\u4f55\u8f6c\u6362\u3002\u56e0\u6b64\u4f60\u7528 UTF-8 \u521b\u5efa\u548c\u6253\u5f00\u7684\u6587\u4ef6\uff0c\u5176\u4ed6\u4f7f\u7528 UTF-8 \u533a\u57df\u8bbe\u7f6e\u7684\u8f6f\u4ef6\u90fd\u53ef\u4ee5\u7167\u5e38\u6253\u5f00\uff0c\u4e0d\u4f1a\u6709\u4e71\u7801\u95ee\u9898\u3002 \u5176\u5b9e Windows \u4e0a\u4ee5 GBK \u7f16\u7801\u7684\u538b\u7f29\u6587\u4ef6\u6216\u6587\u672c\u6587\u4ef6\uff0c\u62f7\u8d1d\u5230 Linux \u4e0a\u6253\u5f00\u51fa\u73b0\u4e71\u7801\u95ee\u9898\uff0c\u5c31\u662f\u56e0\u4e3a Linux \u7684\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u90fd\u662f UTF-8 \u7684\u3002\u5b9e\u9645\u4e0a\u5982\u679c\u628a\u4f60\u7684\u6587\u4ef6\u62f7\u7ed9\u4e00\u4e2a\u7f8e\u56fd\u7684 Windows \u7528\u6237\uff0c\u4ed6\u4e5f\u4f1a\u770b\u5230\u4e71\u7801\uff0c\u56e0\u4e3a\u7f8e\u56fd\u5927\u533a\u7684 Windows \u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\uff0c\u800c\u4e2d\u56fd\u5927\u533a\u7684\u662f GBK\uff0c\u7a0d\u540e\u6211\u4eec\u4f1a\u8bb2\u5230\u89e3\u51b3\u65b9\u6848\u3002 \u800c Windows \u7684 NTFS \u6587\u4ef6\u7cfb\u7edf\uff0c\u91c7\u7528 16 \u4f4d\u7684 wchar_t \u5b58\u50a8\uff0cWindows \u7684\u6240\u6709 API\uff0c\u4e5f\u90fd\u662f\u57fa\u4e8e wchar_t \u7684\uff0cWindows \u5185\u6838\u5185\u90e8\u4e5f\u90fd\u7528 wchar_t \u50a8\u5b58\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u53ea\u6709\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6d41\u4f1a\u7528 char \u5b58\u50a8\u3002\u8fd9\u7c7b\u57fa\u4e8e wchar_t \u7684\u7cfb\u7edf API \u90fd\u6709\u4e00\u4e2a W \u540e\u7f00\uff0c\u4f8b\u5982\uff1a MessageBoxW(NULL, L\"\u4f60\u597d\", L\"\u6807\u9898\", MB_OK); \u8fd9\u4e2a MessageBoxW \u51fd\u6570\uff0c\u53ea\u63a5\u53d7 const wchar_t * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 L\"\u4f60\u597d\" \u662f\u4e00\u4e2a wchar_t [] \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5b83\u7684\u5185\u90e8\u7f16\u7801\u7c7b\u578b\u56fa\u5b9a\u662f UTF-16\uff0c\u4e0d\u4f1a\u968f\u7740\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002\u4e4b\u540e\u7684\u4e00\u8282\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3 W \u548c A \u51fd\u6570\u7684\u95ee\u9898\u3002 \u867d\u7136\u4e5f\u6709\u63d0\u4f9b A \u540e\u7f00\u7684\u7cfb\u5217\u51fd\u6570\uff0c\u4ed6\u4eec\u548c W \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u63a5\u53d7 const char * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002\u95ee\u9898\u5728\u4e8e\uff0c\u8fd9\u4e9b\u5b57\u7b26\u4e32\u90fd\u5fc5\u987b\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u4e5f\u5c31\u662f GBK \u7f16\u7801\uff01\u800c\u4e14\u65e0\u6cd5\u4fee\u6539\u3002 \u5f53\u8c03\u7528 A \u7cfb\u51fd\u6570\u65f6\uff0c\u4ed6\u4eec\u5185\u90e8\u4f1a\u628a GBK \u7f16\u7801\u8f6c\u6362\u4e3a UTF-16 \u7f16\u7801\uff0c\u7136\u540e\u8c03\u7528 Windows \u5185\u6838\u3002 \u8fd9\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\uff0c\u800c\u6240\u6709\u7684 C/C++ \u6807\u51c6\u5e93\u90fd\u662f\u57fa\u4e8e A \u51fd\u6570\u7684\uff01\u5982\u679c\u4f60\u7528 const char * \u5b57\u7b26\u4e32\u8c03\u7528 C \u6807\u51c6\u5e93\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u4e86 A \u51fd\u6570\u3002\u800c A \u51fd\u6570\u53ea\u63a5\u53d7 GBK\uff0c\u4f46\u4f60\u5374\u8f93\u5165\u4e86 UTF-8\uff01\u4ece\u800c UTF-8 \u4e2d\u6240\u6709\u9664 ASCII \u4ee5\u5916\u7684\uff0c\u5404\u79cd\u4e2d\u6587\u5b57\u7b26\u3001Emoji \u90fd\u4f1a\u53d8\u6210\u4e71\u7801\u3002 \u4f8b\u5982 fopen \u51fd\u6570\uff0c\u53ea\u6709 fopen(const char *path, const char *mode) \u8fd9\u4e00\u4e2a\u57fa\u4e8e char \u7684\u7248\u672c\uff0c\u91cc\u9762\u4e5f\u662f\u76f4\u63a5\u8c03\u7528\u7684 A \u51fd\u6570\uff0c\u5b8c\u5168\u4e0d\u7ed9\u6211\u9009\u62e9\u7684\u7a7a\u95f4\u3002\u867d\u7136 Windows \u4e5f\u63d0\u4f9b\u4e86 _wfopen(const wchar_t *path, const wchar_t *mode) \uff0c\u4f46\u90a3\u65e2\u4e0d\u662f POSIX \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f C \u8bed\u8a00\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f7f\u7528\u8fd9\u6837\u7684\u51fd\u6570\u5c31\u610f\u5473\u7740\u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 Windows \u5b98\u65b9\u8ba4\u4e3a\uff1a W \u51fd\u6570\u624d\u662f\u771f\u6b63\u7684 API\uff0c A \u51fd\u6570\u53ea\u662f\u5e94\u4ed8\u4e0d\u542c\u8bdd\u7684\u5b9d\u5b9d\u3002\u53ef\u4f60\u5c31\u6ca1\u53d1\u73b0\u4f60\u81ea\u5df1\u7684 C/C++ \u6807\u51c6\u5e93\u4e5f\u5168\u90e8\u5728\u8c03\u7528\u7684 A \u51fd\u6570\u4e48\uff1f \u603b\u4e4b\uff0c A \u51fd\u6570\u662f\u6b8b\u5e9f\u7684\uff0c\u6211\u4eec\u53ea\u80fd\u7528 W \u51fd\u6570\uff0c\u5c3d\u7ba1 UTF-16 \u662f\u5386\u53f2\u503a\uff0c\u4f46\u6211\u4eec\u522b\u65e0\u9009\u62e9\uff0c W \u51fd\u6570\u662f\u552f\u4e00\u80fd\u652f\u6301\u5b8c\u6574 Unicode \u5b57\u7b26\u8f93\u5165\u7684\u65b9\u5f0f\u3002 // \u5047\u8bbe\u8fd9\u6bb5 C++ \u4ee3\u7801\u4f7f\u7528 /utf-8 \u9009\u9879\u7f16\u8bd1\uff1a std::ifstream f(\"\u4f60\u597d.txt\"); // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5373\u4f7f\u201c\u4f60\u597d.txt\u201d\u5b58\u5728 std::ofstream f(\"\u4f60\u597d.txt\"); // \u4f1a\u521b\u5efa\u4e00\u4e2a\u4e71\u7801\u6587\u4ef6 \u6b63\u786e\u7684\u505a\u6cd5\u662f\u91c7\u7528 std::filesystem::u8path \u8fd9\u4e2a\u51fd\u6570\u505a UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\uff1a // C++17\uff0c\u9700\u8981\u7528 u8path \u8fd9\u4e2a\u51fd\u6570\u6784\u9020 path \u5bf9\u8c61\uff1a std::ifstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); // C++20 \u5f15\u5165 char8_t\uff0c\u533a\u5206\u4e8e\u666e\u901a char\uff0cpath \u7c7b\u4e5f\u6709\u4e86\u9488\u5bf9 const char8_t * \u7684\u6784\u9020\u51fd\u6570\u91cd\u8f7d\uff1a std::ifstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::filesystem::path \u7c7b\u7684 c_str() \u5728 Windows \u4e0a\u8fd4\u56de const wchar_t * \uff0c\u5728 Linux \u4e0a\u8fd4\u56de const char * \u3002\u8fd9\u5f88\u5408\u7406\uff0c\u56e0\u4e3a Windows \u6587\u4ef6\u7cfb\u7edf\u786e\u5b9e\u4ee5 wchar_t \u5b58\u50a8\u8def\u5f84\u540d\uff0c\u800c Linux \u6587\u4ef6\u7cfb\u7edf\u5b8c\u5168\u7528 char \u3002 \u6bcf\u6b21\u9700\u8981\u52a0 std::filesystem::u8path \u4e5f\u633a\u9ebb\u70e6\u7684\uff0c\u5bb9\u6613\u5fd8\u8bb0\uff0c\u4e00\u5fd8\u8bb0\u5c31\u65e0\u6cd5\u8bbf\u95ee\u4e2d\u6587\u76ee\u5f55\u3002 \u5f88\u591a\u8f6f\u4ef6\u5728 Windows \u4e0a\u65e0\u6cd5\u652f\u6301\u4e2d\u6587\u8def\u5f84\u540d\uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u4eec\u4e60\u60ef\u4e86 Linux \u6216 MacOS \u7684\u5168 UTF-8 \u73af\u5883\uff0c\u5bf9\u6587\u4ef6\u8def\u5f84\u6ca1\u6709\u4efb\u4f55\u8f6c\u6362\u3002\u800c Windows \u5e95\u5c42\u5168\u662f UTF-16\uff0c\u6839\u672c\u6ca1\u6709\u63d0\u4f9b UTF-8 \u7684 API\uff0c\u4f60 UTF-8 \u53ea\u80fd\u8f6c\u6362\u6210 UTF-16 \u624d\u80fd\u907f\u514d\u4e2d\u6587\u4e71\u7801\u3002\u4e2a\u4eba\u8ba4\u4e3a\uff0c\u6b7b\u6d3b\u4e0d\u80af\u63a5\u53d7\u660e\u6446\u7740\u5df2\u7ecf\u662f\u56fd\u9645\u901a\u7528\u6807\u51c6\u7684 UTF-8\uff0cA \u51fd\u6570\u7684\u7f16\u7801\u8fde\u5f53\u524d\u8fdb\u7a0b\u5207\u6362\u7684\u65b9\u6cd5\u90fd\u4e0d\u7ed9\u4e00\u4e2a\uff0c\u8fd9\u4e2a\u5e94\u8be5\u7531 Windows \u5168\u8d23\u627f\u62c5\u3002 \u597d\u6d88\u606f\u662f\uff0c\u6700\u8fd1 MSVC \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u4e00\u79cd\u65b9\u6848\uff0c\u5728\u4f60\u7684\u7a0b\u5e8f\u5f00\u5934\uff0c\u52a0\u4e0a setlocale(LC_ALL, \".utf-8\") \u5c31\u53ef\u4ee5\u8ba9 C \u548c C++ \u6807\u51c6\u5e93\u8fdb\u5165 UTF-8 \u6a21\u5f0f\uff1a\u4e0d\u518d\u8c03\u7528 A \u7cfb\u51fd\u6570\u64cd\u4f5c\u6587\u4ef6\uff0c\u800c\u662f\u4f1a\u628a\u6587\u4ef6\u540d\u4ece UTF-8 \u8f6c\u6362\u6210 UTF-16 \u540e\u518d\u8c03\u7528\u771f\u6b63\u7a33\u5b9a\u7684 W \u7cfb\u51fd\u6570\u3002 setlocale(LC_ALL, \".utf-8\"); // \u53ea\u9700\u8981\u8fd9\u4e00\u884c FILE *fp = fopen(u8\"\u4f60\u597d.txt\", \"r\"); // \u53ef\u4ee5\u4e86 std::ifstream fin(u8\"\u4f60\u597d.txt\"); // \u53ef\u4ee5\u4e86 setlocale(LC_ALL, \".utf-8\"); \u53ea\u662f\u628a C \u6807\u51c6\u5e93\u7684 const char * \u53c2\u6570\u53d8\u6210\u4e86\u63a5\u53d7 UTF-8\uff0c\u5e76\u4e0d\u4f1a\u8ba9\u7cfb\u7edf\u7684 A \u51fd\u6570\u4e5f\u53d8\u6210 UTF-8 \u54e6\uff0c\u8c03\u7528\u672c\u5730 API \u65f6\u4ecd\u9700 UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-8 \u9635\u8425\uff0c\u5f00\u542f /utf-8 \uff0c\u7a0b\u5e8f\u5f00\u5934\u5199 setlocale(LC_ALL, \".utf-8\") \u3002Linux \u7528\u6237\u5219\u4ec0\u4e48\u90fd\u4e0d\u7528\u505a\u3002 \u770b\u770b\u5404\u5927\u8f6f\u4ef6\u7ad9\u5728 UTF-8 \u9635\u8425\u7684\u7406\u7531\uff1a CMake\uff1a\u4f5c\u4e3a\u8de8\u5e73\u53f0\u7684\u6784\u5efa\u7cfb\u7edf\uff0c\u4e3a\u4e86\u8ba9\u9879\u76ee\u7684 CMakeLists.txt \u80fd\u8de8\u5e73\u53f0\u5171\u7528\u800c\u4e0d\u5fc5\u91cd\u5199\uff0c\u4ed6\u7406\u6240\u5f53\u7136\u5730\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\uff1a\u6240\u6709 CMakeLists.txt \u90fd\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u4e66\u5199\uff0c\u4e14\u7edf\u4e00\u4f7f\u7528\u6b63\u659c\u6760 '/' \u8def\u5f84\u5206\u9694\u7b26\u3002 CMake \u4f1a\u81ea\u52a8\u5728 Windows \u7cfb\u7edf\u4e0a\uff0c\u5c06 UTF-8 \u5b57\u7b26\u4e32\u8f6c\u6362\u6210 UTF-16 \u540e\uff0c\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u5728 Linux \u7cfb\u7edf\u4e0a\u5219\u4e0d\u505a\u8f6c\u6362\u3002\u5728 Windows \u7cfb\u7edf\u4e0a\u8fd8\u4f1a\u81ea\u52a8\u628a\u6587\u4ef6\u8def\u5f84\u4e2d\u7684\u6b63\u659c\u6760 '/' \u8f6c\u6362\u6210 Windows \u4e13\u5c5e\u7684\u53cd\u659c\u6760 '\\\\' \uff0c\u65e0\u9700\u7528\u6237\u64cd\u5fc3\u3002 \u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u8282\u70b9\u4eff\u771f\u8f6f\u4ef6\uff1a\u7531\u4e8e\u4fdd\u5b58\u7684\u9879\u76ee\u5de5\u7a0b\u6587\u4ef6\u9700\u8981\u5728 Linux \u548c Windows \u5e73\u53f0\u4e0a\u4e92\u901a\uff0c\u4e0d\u80fd\u91c7\u7528 Windows \u5404\u81ea\u4e3a\u653f\u7684 GBK \u683c\u5f0f\uff0c\u4e14\u5de5\u7a0b\u6587\u4ef6\u5185\u5bb9\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\u4e2d\u3002 Rust \u548c Go\uff1a\u4e25\u683c\u533a\u5206\u201c\u5b57\u7b26 (32 \u4f4d)\u201d\u548c\u201c\u5b57\u8282 (8 \u4f4d)\u201d\u7684\u6982\u5ff5\u3002\u5728\u5b57\u7b26\u4e32\u7c7b\u578b\u4e2d\u5b58\u50a8\u5b57\u8282\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u4ee5\u5b57\u8282\u65b9\u5f0f\u8bfb\u53d6\u6216\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-8 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5904\u7406\u5207\u7247\u548c\u7d22\u5f15\u65f6\u4e0d\u65b9\u4fbf\u3002 \u7f16\u7a0b\u8bed\u8a00 \u5b57\u7b26\u7c7b\u578b (32 \u4f4d) \u5b57\u8282\u7c7b\u578b (8 \u4f4d) Rust char u8 Go rune byte Julia Char UInt8 \u4e3a\u6b64\uff0c\u8fd9\u4e9b\u8bed\u8a00\u90fd\u4e3a\u5b57\u7b26\u4e32\u63d0\u4f9b\u4e86\u4e24\u5957 API\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u8282\u7d22\u5f15\u3002\u6309\u5b57\u7b26\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ece\u5934\u5f00\u59cb\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\uff0c\u76f4\u5230\u89e3\u6790\u5230\u60f3\u8981\u7684\u5b57\u7b26\u4e3a\u6b62\uff0c\u590d\u6742\u5ea6 O(N) O(N) \u3002\u6309\u5b57\u8282\u7d22\u5f15\u65f6\uff0c\u76f4\u63a5\u8df3\u5230\u6307\u5b9a\u5b57\u8282\uff0c\u65e0\u9700\u89e3\u6790\uff0c\u590d\u6742\u5ea6 O(1) O(1) \u3002 let s = \"\u4f60\u597d\"; // \u6309\u5b57\u7b26\u904d\u5386 for c in s.chars() { // c: char println!(\"{}\", c); } // \u6309\u5b57\u8282\u904d\u5386 for b in s.bytes() { // b: u8 println!(\"{:02x}\", b); } \u5728 C++ \u4e2d\uff0c\u82e5\u8981\u91c7\u7528\u8fd9\u79cd UTF-8 \u65b9\u6848\uff0c\u53ef\u4ee5\u4f7f\u7528 utfcpp \u8fd9\u4e2a\u5e93\uff1a https://github.com/nemtrif/utfcpp \u7a0d\u540e\u6211\u4eec\u4f1a\u4ee5\u6848\u4f8b\u8be6\u7ec6\u6f14\u793a\u8fd9\u4e2a\u5e93\u7684\u7528\u6cd5\uff0c\u4e5f\u4f1a\u5c1d\u8bd5\u81ea\u5df1\u624b\u6413\u3002 \u65b9\u6cd51\uff1a\u4f7f\u7528 utf8to32 \u4e00\u6b21\u6027\u5b8c\u6210\u8f6c\u6362\uff0c\u7528\u5b8c\u540e\u518d\u8f6c\u56de\u53bb\u3002 std::string s = \"\u4f60\u597d\"; std::u32string u32 = utf8::utf8to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\u574f'; s = utf8::utf32to8(u32); fmt::println(\"{}\", s); // \u4f60\u574f \u65b9\u6cd52\uff1a utfcpp \u4e5f\u5c01\u88c5\u4e86\u4e00\u4e2a utf8::iterator \u8fed\u4ee3\u5668\u9002\u914d\u5668\uff0c\u6548\u679c\u7c7b\u4f3c\u4e8e Rust \u7684 .chars() \uff0c\u53ef\u4ee5\u5b57\u7b26\u800c\u4e0d\u662f\u5b57\u8282\u904d\u5386\u5b57\u7b26\u4e32\u5bb9\u5668\u3002 char s[] = \"\u4f60\u597d\"; utf8::unchecked::iterator bit(s); utf8::unchecked::iterator eit(s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u5b89\u5168\uff08\u5e26\u8fb9\u754c\u68c0\u6d4b\uff09\u7684\u7248\u672c char s[] = \"\u4f60\u597d\"; utf8::iterator bit(s, s, s + strlen(s)); utf8::iterator eit(s + strlen(s), s, s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u57fa\u4e8e std::string \u7684\u7248\u672c std::string s = \"\u4f60\u597d\"; utf8::iterator bit(s.begin(), s.begin(), s.end()); utf8::iterator eit(s.end(), s.begin(), s.end()); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } \u7531\u4e8e\u8fed\u4ee3\u5668\u63a5\u53e3\u590d\u6742\u96be\u61c2\uff0c\u5efa\u8bae\u5148\u5c01\u88c5\u6210\u5e26\u6709 begin() \u548c end() \u7684 range \u5bf9\u8c61\uff0c\u65b9\u4fbf\u4f7f\u7528 C++17 range-based loop \u8bed\u6cd5\u76f4\u89c2\u904d\u5386\uff1a template struct Utf8Range { utf8::iterator bit; utf8::iterator eit; template Utf8Range(T &&t) : bit(std::begin(t), std::begin(t), std::end(t)) , eit(std::end(t), std::begin(t), std::end(t)) {} auto begin() const { return bit; } auto end() const { return eit; } }; template Utf8Range(T &&t) -> Utf8Range; // \u4ee5\u4e0b\u662f\u65b0\u7c7b\u7684\u4f7f\u7528\u65b9\u6cd5 std::string s = \"\u4f60\u597d\"; for (char32_t c : Utf8Range(s)) { fmt::println(\"U+{:04X}\", c); } UTF-16 \u9635\u8425 \u652f\u6301 Unicode \u8fc7\u65e9\uff0c\u8bef\u4ee5\u4e3a 0xFFFF \u5c31\u662f Unicode \u7684\u4e0a\u9650\u3002 \u4e00\u5f00\u59cb\uff0c\u4eba\u4eec\u9519\u8bef\u5730\u628a UTF-16 \u5f53\u6210\u6c38\u8fdc\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u89e3\u51b3\u4e71\u7801\u95ee\u9898\uff0c\u6240\u4ee5\u90a3\u6bb5\u65f6\u671f\u7684\u8f6f\u4ef6\u90fd\u5927\u4e3e\u4f7f\u7528 UTF-16 \u4f5c\u4e3a\u5185\u7801\u3002\u6ca1\u60f3\u5230\u540e\u6765 Unicode \u53c8\u5f15\u5165 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u800c\u73b0\u6709\u7684\u5df2\u7ecf\u91c7\u7528\u4e86 16 \u4f4d\u5185\u7801\u7684\u8f6f\u4ef6\u53c8\u5df2\u7ecf\u65e0\u6cd5\u6839\u9664\uff0c\u53ea\u597d\u4f7f\u7528\u201c\u4ee3\u7406\u5bf9\u201d\u673a\u5236\uff0c\u589e\u91cf\u66f4\u65b0\u4fee\u590d\u4e86\u73b0\u6709\u7684 16 \u4f4d\u5185\u7801\u8f6f\u4ef6\u3002UTF-16 \u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u597d\u5904\uff0c\u7559\u4e0b\u5386\u53f2\u503a\u3002 \u4e8b\u5b9e\u4e0a\uff0cUnicode \u5df2\u7ecf\u65e0\u6cd5\u7ee7\u7eed\u6269\u5bb9\u7a81\u7834 0x10FFFF\uff0c\u5c31\u662f\u56e0\u4e3a\u53cc uint16_t \u7f16\u7801\u7684\u4ee3\u7406\u5bf9\u6700\u591a\u53ea\u80fd\u5bb9\u7eb3\u989d\u5916 0x100000 \u4e2a\u5b57\u7b26\u7684\u7a7a\u95f4\u3002\u672c\u6765 UTF-8 \u4e00\u5f00\u59cb\u7684\u8349\u6848\u662f\u6253\u7b97\u6700\u591a\u652f\u6301 8 \u8282\u5217\u8f66\uff0c\u5b8c\u5168\u5bb9\u7eb3\u9ad8\u8fbe 0x7FFFFFFF \u8303\u56f4\u7684\u5b57\u7b26\u3002\u4e3a\u4e86\u8ba9 Windows \u8fd8\u80fd\u7ee7\u7eed\u7528\uff0cUnicode \u624d\u88ab\u8feb\u6b62\u6b65 0x10FFFF\uff0cUTF-8 \u4e5f\u7ec8\u7ed3\u4e8e 4 \u8282\u5217\u8f66\u3002 \u5e94\u7528\u573a\u666f\uff1a\u901a\u5e38\u8ba4\u4e3a\uff0cUTF-16 \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff0c\u65b0\u8f6f\u4ef6\u4e0d\u5e94\u8be5\u518d\u4f7f\u7528 UTF-16\u3002\u53ea\u6709\u5728\u548c\u8fd9\u4e9b\u7cdf\u7c95\u8f6f\u4ef6\u7684 API \u6253\u4ea4\u9053\u65f6\uff0c\u624d\u5fc5\u987b\u8f6c\u6362\u4e3a UTF-16\u3002\u4f46\u4e5f\u6709\u4eba\u6307\u51fa\uff1aUTF-16 \u662f\u7eaf\u4e2d\u6587\u538b\u7f29\u7387\u6700\u9ad8\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u6240\u4ee5 UTF-16 \u8fd8\u6bd4\u8f83\u9002\u5408\u7eaf\u4e2d\u6587\u6216\u4ee5\u4e2d\u6587\u5185\u5bb9\u4e3a\u4e3b\u7684\u6587\u672c\u6570\u636e\u538b\u7f29\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-16 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8c03\u7528 Windows \u7cfb\u7edf API \u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u76f4\u63a5\u5c31\u80fd\u8c03\u7528\uff0c\u6700\u9002\u5408 Windows \u672c\u5730\u5f00\u53d1\uff0c\u975e\u8de8\u5e73\u53f0\u3002\u4e14\u5bf9\u7eaf\u4e2d\u6587\u5185\u5bb9\u53ef\u6bd4 UTF-8 \u989d\u5916\u8282\u7701 33% \u7a7a\u95f4\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e Windows \u4ee5\u5916\u7684\u7cfb\u7edf\u5c31\u9700\u8981\u8f6c\u6362\u56de UTF-8\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u5f00\u9500\u3002\u4e14\u5982\u679c\u5b58\u50a8\u7684\u5185\u5bb9\u4e3b\u8981\u662f\u7eaf\u82f1\u6587\uff0c\u5982 XML \u4ee3\u7801\u7b49\uff0c\u5185\u5b58\u5360\u7528\u4f1a\u6bd4 UTF-8 \u7ffb\u500d\u3002\u800c\u4e14 UTF-16 \u4ecd\u7136\u662f\u53d8\u957f\u7f16\u7801\uff0c\u867d\u7136\u51fa\u73b0\u53d8\u957f\u7684\u6982\u7387\u8f83\u4f4e\uff0c\u4f46\u4e0d\u4e3a 0\uff0c\u4ecd\u9700\u8981\u5f00\u53d1\u8005\u505a\u7279\u6b8a\u5904\u7406\u3002\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u4f1a\u5bfc\u81f4\u751f\u50fb\u5b57\u7b26\u51fa\u9519\uff0c\u5b57\u7b26\u4e32\u4ee5\u7801\u70b9\u4e3a\u5355\u4f4d\u7684\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4ecd\u7136 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002\u5e76\u4e14 UTF-16 \u6709\u5927\u5c0f\u7aef\u8f6c\u6362\u7684\u95ee\u9898\u3002 \u4ee3\u8868\u4f5c\uff1aWindows \u7cfb\u7edf API\u3001Java \u8bed\u8a00\u3001Windows \u6587\u4ef6\u7cfb\u7edf (NTFS)\u3001Qt\u3001Word\u3001JSON\uff0c\u4ed6\u4eec\u90fd\u662f UTF-16 \u7684\u53d7\u5bb3\u8005\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-16 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-16 \u4f9d\u7136\u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5904\u7406\u6ca1\u95ee\u9898\uff0c\u751f\u50fb\u5b57\u5c31\u5bb9\u6613\u51fa\u95ee\u9898\uff0c\u4e14\u56e0\u4e3a\u51fa\u73b0\u6982\u7387\u4f4e\uff0c\u5f88\u5bb9\u6613\u4e0d\u53d1\u73b0\uff0c\u57cb\u4e0b\u9690\u60a3\u3002 Java \u5c31\u662f\u53d7\u5230\u4e86 UTF-16 \u5386\u53f2\u503a\u5f71\u54cd\uff0c char \u662f 16 \u4f4d\u7684\u7801\u4f4d\uff0c\u800c\u4e0d\u662f\u5b57\u7b26\uff0c\u771f\u6b63\u7684\u4e00\u4e2a\u5b57\u7b26\u662f 32 \u4f4d\u7684 Character \u7c7b\u578b\u3002 \u7f16\u7a0b\u8bed\u8a00 \u7801\u70b9\u7c7b\u578b (32 \u4f4d) \u7801\u4f4d\u7c7b\u578b (16 \u4f4d) Java Character char Java \u7684 Character \u7c7b\u578b\u662f\u4e00\u4e2a 32 \u4f4d\u7684\u503c\uff0c\u8fd9\u4e2a\u503c\u5305\u542b\u4e86\u4e00\u4e2a Unicode \u7801\u4f4d\u3002 char \u7c7b\u578b\u662f\u4e00\u4e2a 16 \u4f4d\u7684\u503c\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a UTF-16 \u7f16\u7801\u7684\u7801\u70b9\u3002 String \u7684 charAt() \u65b9\u6cd5\u8fd4\u56de\u7684\u662f char \u7c7b\u578b\u7684\u7801\u4f4d\uff08\u7c7b\u4f3c\u4e8e\u5b57\u8282\uff09\uff0c\u5982\u679c\u8981\u83b7\u53d6 Character \u7c7b\u578b\u7684\u5b8c\u6574\u5b57\u7b26\uff0c\u5fc5\u987b\u4f7f\u7528 codePointAt() \u65b9\u6cd5\u3002\u8fd9\u662f Java \u8bed\u8a00\u8bbe\u8ba1\u4e0a\u7684\u4e00\u4e2a\u5931\u8bef\uff0c\u5df2\u7ecf\u65e0\u6cd5\u6539\u53d8\u3002 \u800c\u540e\u7eed\u65b0\u51fa\u7684 Kotlin \u662f Java \u7684\u5408\u6cd5\u7ee7\u627f\u8005\uff0c\u4ed6\u679c\u65ad\u653e\u5f03 UTF-16\uff0c\u52a0\u5165\u4e86 UTF-32 \u9635\u8425\u3002\u53ef\u89c1\uff0c\u8001\u8f6f\u4ef6\u575a\u6301\u7528 UTF-16 \u662f\u56e0\u4e3a\u4ed6\u4eec\u79ef\u91cd\u96be\u8fd4\uff0c\u65b0\u8f6f\u4ef6\u518d\u7528 UTF-16 \u5c31\u662f\u81ea\u4f5c\u5b7d\u4e86\uff01 \u603b\u7ed3\uff1a\u4e0d\u8981\u652f\u6301 UTF-16 \u9635\u8425\uff0c\u9664\u975e\u4f60\u88ab\u8feb\u7ef4\u62a4\u53f2\u5c71\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u53d1\u5fae\u4fe1\u670b\u53cb\u5708\u65f6\uff0c\u8f93\u5165 Emoji \u8868\u60c5\u540e\u526a\u5207\uff0c\u518d\u7c98\u8d34\uff0c\u5c31\u548c\u53d1\u73b0\u4e00\u4e2a Emoji \u88ab\u5207\u65ad\u6210\u4e86\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4e71\u7801\u7684\u5f62\u5f0f\u663e\u73b0\u3002\u4f30\u8ba1\u662f\u56e0\u4e3a\u5fae\u4fe1\u57fa\u4e8e Java \u7f16\u5199\uff0c\u75bc\u900a\u7a0b\u5e8f\u5458\u5bf9 UTF-16 \u4ee3\u7406\u5bf9\u5904\u7406\u7684\u4e0d\u5229\u7d22\u3002 Java \u4e2d\u4ee5\u7801\u70b9\u904d\u5386\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5199\u6cd5\uff1a String s = \"\u4f60\u597d\"; // \u6309\u7801\u70b9\u904d\u5386 for (int i = 0; i < s.length();) { Character c = s.codePointAt(i); System.out.println(String.format(\"U+%04X\", c)); i += Character.charCount(c); } // \u6309\u7801\u4f4d\u904d\u5386 for (char c : s.toCharArray()) { System.out.println(String.format(\"U+%04X\", (int) c)); } \u7531\u4e8e JSON \u662f\u548c Java \u4e00\u5757\u53d1\u660e\u7684\u3002\u5bf9\u4e8e\u8d85\u51fa 0xFFFF \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u91c7\u7528\u7684\u8f6c\u4e49\uff0c\u4e5f\u662f\u57fa\u4e8e UTF-16 \u7f16\u7801\u3002\u5373\u540c\u4e00\u4e2a\u5b57\u4f1a\u53d8\u6210\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4fdd\u8bc1 JSON \u6587\u4ef6\u603b\u662f ASCII \u683c\u5f0f\uff0c\u907f\u514d Windows \u7684 GBK \u7f16\u7801\u4e71\u505a\u989d\u5916\u7684\u5e72\u6270\u3002 // \u4ee5\u4e0b\u4e24\u79cd\u5199\u6cd5\u7b49\u4ef7 {\"name\": \"\ud883\udede\"} {\"name\": \"\\ud883\\udfde\"} \u5728\u521a\u521a\u4ecb\u7ecd\u7684 C++ \u5e93 utfcpp \u4e2d\uff0c\u4e5f\u6709\u9488\u5bf9 UTF-16 \u7684\u8f6c\u6362\u51fd\u6570\uff0c\u5982 utf16to32 \uff1a std::u16string s = u\"\u4f60\u597d\"; std::u32string u32 = utf16::utf16to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\ud883\udede'; s = utf16::utf32to16(u32); fmt::println(\"{}\", s); // \u4f60\ud883\udede fmt::println(\"{}\", u32.size()); // 2 fmt::println(\"{}\", s.size()); // 3 UTF-32 \u9635\u8425 \u652f\u6301 Unicode\uff0c\u6bcf\u4e2a\u7801\u70b9\u90fd\u7528\u4e00\u4e2a uint32_t \u6216 char32_t \u8868\u793a\u3002 \u5e94\u7528\u573a\u666f\uff1a\u9002\u5408\u9700\u8981\u7ecf\u5e38\u5904\u7406\u6587\u5b57\u7684\u9886\u57df\uff0c\u5982\u6587\u672c\u7f16\u8f91\u5668\u3001\u6d4f\u89c8\u5668\u7b49\u3002\u4f46\u4e0d\u9002\u5408\u5b58\u50a8\u548c\u4f20\u8f93\uff0c\u56e0\u4e3a\u6d6a\u8d39\u786c\u76d8\u548c\u7f51\u7edc\u5e26\u5bbd\u3002\u5b57\u7b26\u4e32\u4e00\u822c\u90fd\u957f\u671f\u4ee5 UTF-8 \u5b58\u50a8\uff0c\u53ea\u6709\u5728\u9700\u8981\u9891\u7e41\u7d22\u5f15\u7801\u4f4d\u65f6\uff0c\u624d\u9700\u8981\u8f6c\u6362\u4e3a UTF-32\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-32 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u3001\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u90fd\u662f O(1) O(1) \u7684\u590d\u6742\u5ea6\uff0c\u53ef\u4ee5\u5f53\u4f5c\u666e\u901a\u6570\u7ec4\u4e00\u6837\uff0c\u968f\u610f\u5904\u7406\u3002\u4f8b\u5982\u4f60\u53ef\u4ee5\u8bbe\u60f3\u4e00\u4e2a\u6587\u672c\u7f16\u8f91\u6846\uff0c\u9700\u8981\u652f\u6301\u201c\u9000\u683c\u201d\u64cd\u4f5c\uff0c\u5982\u679c\u662f UTF-8 \u548c UTF-16 \u5c31\u9700\u8981\u7e41\u7410\u7684\u5224\u65ad\u4ee3\u7406\u5bf9\u3001\u5404\u79cd\u8f66\u53a2\uff0c\u800c UTF-32 \u7684\u5b57\u7b26\u4e32\u53ea\u9700\u8981\u4e00\u6b21 pop_back \u5c31\u641e\u5b9a\u4e86\u3002 \u7f3a\u70b9\uff1a\u6d6a\u8d39\u7a7a\u95f4\u5927\uff0c\u901a\u5e38\u5728\u4fdd\u5b58\u65f6\uff0c\u4ecd\u7136\u9700\u8981\u8f6c\u6362\u56de UTF-8 \u540e\u518d\u5199\u5165\u6587\u4ef6\uff0c\u6709\u4e00\u5b9a\u6027\u80fd\u5f00\u9500\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-32 \u9635\u8425\uff0c\u8bf7\u5168\u90e8\u4f7f\u7528 char32_t \u548c std::u32string \u3002\u5b57\u9762\u91cf\u5168\u7528 U\"\u4f60\u597d\" \u7684\u5f62\u5f0f\u4e66\u5199\uff0c\u8bfb\u6587\u4ef6\u65f6\u8f6c\u4e3a UTF-32\uff0c\u5199\u6587\u4ef6\u65f6\u8f6c\u56de UTF-8\u3002 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u7531\u4e8e C++26 \u524d\u6807\u51c6\u5e93\u5bf9\u7f16\u7801\u8f6c\u6362\u51e0\u4e4e\u6ca1\u6709\u652f\u6301\uff0c\u5728 C++ \u4e2d\u8f6c\u6362\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u5e38\u90fd\u9700\u8981\u7b2c\u4e09\u65b9\u5e93\u3002 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1a utfcpp \u5982\u679c\u4f60\u53ea\u662f\u9700\u8981\u4e0d\u540c UTF \u683c\u5f0f\u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u6ca1\u6709\u5904\u7406 GBK \u7b49\u7684\u9700\u6c42\uff1a\u90a3\u4e48\u4e4b\u524d\u5df2\u7ecf\u4ecb\u7ecd\u4e86 utfcpp \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5e93\uff0c\u5df2\u7ecf\u591f\u7528\u3002 #include \"utf8/cpp20.h\" std::u8string s8 = u8\"\u4f60\u597d\"; std::u16string s16 = utf8::utf8to16(s8); std::u32string s32 = utf8::utf8to32(s8); std::string s = utf8::utf16to8(s16); s8 = utf8::utf16tou8(s16); \u6700\u540e\u8fd9\u4e24\u4e2a\u533a\u522b\u5728\u4e8e\uff0c utf16to8 \u8fd4\u56de std::string \uff0c utf16tou8 \u8fd4\u56de std::u8string \uff0c\u91cc\u9762\u90fd\u662f UTF-8 \u7f16\u7801\u7684\uff0c\u4e0d\u8fc7\u6709\u7684\u4eba\u559c\u6b22\u7528 std::string \u6765\u5b58\u50a8 UTF-8\uff0c\u4e0d\u559c\u6b22 std::u8string \uff0c\u6216\u8005\u8bf4\u4ed6\u4eec\u6ca1\u6709 C++20\uff0c\u4e0d\u652f\u6301 std::u8string \uff0c\u56e0\u6b64\u8fd9\u4e2a\u5e93\u6ee1\u8db3\u4ed6\u4eec\u7684\u4e0d\u540c\u9700\u8981\u3002\u4f46\u662f std::u8string \u4f5c\u4e3a\u53c2\u6570\u65f6\u4e0d\u9700\u8981\uff0c\u56e0\u4e3a\u53c2\u6570\u53ef\u4ee5\u81ea\u52a8\u91cd\u8f7d\uff0c\u800c\u8fd4\u56de\u503c\u4e0d\u884c\u3002 \u7f3a\u70b9\u662f\u4ed6\u4e0d\u80fd\u5904\u7406 GBK\u3001Shift-JIS \u7b49\u975e Unicode \u7f16\u7801\uff0c\u4e5f\u4e0d\u80fd\u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u7684 ANSI \u533a\u57df\u8bbe\u7f6e\u3002 \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1a boost::locale \u5982\u679c\u4f60\u8fd8\u8981\u652f\u6301\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u6bd4\u5982 GBK\u3001Shift-JIS\u3001Latin-1\u3002 \u4e00\u79cd\u662f C \u8bed\u8a00\u7684 iconv \uff0c\u53e6\u4e00\u79cd\u662f\u73b0\u4ee3 C++ \u7684 boost::locale \u3002 \u867d\u7136\u529f\u80fd\u5dee\u4e0d\u591a\uff0c\u5e95\u5c42\u90fd\u662f\u8c03\u7528 icu \u7684\u3002 boost::locale \u7684 API \u66f4\u52a0\u53cb\u597d\uff0c\u800c\u4e14\u662f\u73b0\u4ee3 C++ \u98ce\u683c\u7684\u3002 # Ubuntu \u7528\u6237\u5b89\u88c5 Boost.locale \u65b9\u6cd5\uff1a $ sudo apt-get install libboost-locale-dev # Arch Linux \u7528\u6237\u5b89\u88c5 Boost \u5168\u5bb6\u6876\u65b9\u6cd5\uff1a $ sudo pacman -S boost \u4e0d\u559c\u6b22 Boost \u7684\u4eba\u6709\u96be\u4e86\u3002 UTF \u4e4b\u95f4\u4e92\u8f6c \u4f7f\u7528 boost::locale::conv::utf_to_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::utf_to_utf; int main() { std::string s8 = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c UTF-32\uff1a std::u32string s32 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-16\uff1a std::u16string s16 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-8\uff1a s8 = utf_to_utf(s32); std::cout << s8 << '\\n'; return 0; } \u6a21\u677f\u53c2\u6570\u4e2d\uff0c\u53ea\u9700\u6307\u5b9a\u8f6c\u6362\u5230\u7684\u662f\u4ec0\u4e48\u7c7b\u578b\u5c31\u884c\uff0c\u6765\u81ea\u4ec0\u4e48\u7c7b\u578b\uff0c\u4ed6\u81ea\u5df1\u4f1a\u91cd\u8f7d\u7684\u3002 \u6bd4\u5982\u4ece char32_t \u8f6c\u5230 char16_t \uff0c\u53ea\u9700\u8981 utf_to_utf \u5c31\u53ef\u4ee5\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7f16\u8bd1\uff1a $ g++ -std=c++17 -lboost_locale main.cpp \u8f93\u51fa\uff1a \u4f60\u597d \u5efa\u8bae\u7528\u540c\u6837\u8de8\u5e73\u53f0\u7684 CMake \u94fe\u63a5 Boost\uff0c\u5426\u5219 Windows \u7528\u6237\u8981\u6709\u96be\u4e86\u2026\u2026 find_package(Boost REQUIRED COMPONENTS locale) target_link_libraries(\u4f60\u7684\u7a0b\u5e8f Boost::locale) \u4e0d\u8fc7 boost::locale \u6709\u4e00\u4e2a\u7f3a\u70b9\uff0c\u90a3\u5c31\u662f\u4e0d\u652f\u6301 char8_t \u548c std::u8string \u3002 char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff01 \u7531\u4e8e Boost \u8f83\u8001\uff0c\u6ca1\u6709\u53ca\u65f6\u8ddf\u8fdb\uff0c\u6240\u4ee5\u4ed6\u5e76\u6ca1\u6709\u5b9e\u73b0\u9488\u5bf9 char8_t \u7684\u7279\u5316\uff0c\u5982\u679c\u4f7f\u7528\u4e86 utf_to_utf \u4f1a\u62a5 undefined reference \u9519\u8bef\uff0c\u5373\u627e\u4e0d\u5230\u7b26\u53f7\u3002\u6539\u6210 utf_to_utf \u5c31\u6ca1\u95ee\u9898\u4e86\u3002 GBK \u548c UTF \u4e92\u8f6c \u4f7f\u7528 boost::locale::conv::to/from_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::to_utf; using boost::locale::conv::from_utf; int main() { std::string s = \"\u4f60\u597d\"; // \u4ece GBK \u8f6c\u5230 UTF-16 std::wstring ws = to_utf(s, \"GBK\"); std::wcout << ws << '\\n'; // \u4ece UTF-16 \u8f6c\u56de GBK s = from_utf(ws, \"GBK\"); std::wcout << s << '\\n'; return 0; } \u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f GBK \u3001 Shift-JIS \u3001 Latin1 \u7b49\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u5b8c\u6574\u7684\u5217\u8868\u53ef\u4ee5\u5728\u770b\u5230\u3002 \u8fd9\u91cc to_utf \u4f1a\u81ea\u52a8\u5224\u65ad wchar_t \u7684\u5927\u5c0f\u3002\u5982\u679c\u662f 2 \u5b57\u8282\uff08Windows \u5e73\u53f0\u60c5\u51b5\uff09\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-16\uff0c\u5982\u679c\u662f 4 \u5b57\u8282\uff08Linux \u5e73\u53f0\u60c5\u51b5\uff09\uff0c\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-32\u3002 \u800c to_char \u5219\u662f\u65e0\u8bba\u4ec0\u4e48\u5e73\u53f0\uff0c\u90fd\u4f1a\u8f6c\u4e3a UTF-16\u3002 from_utf \u4e0d\u9700\u8981\u6307\u5b9a\u4efb\u4f55\u6a21\u677f\u53c2\u6570\uff0c\u56e0\u4e3a\u4ed6\u603b\u662f\u8fd4\u56de std::string \uff08ANSI \u6216 GBK \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff09\uff0c\u53c2\u6570\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4f1a\u81ea\u52a8\u901a\u8fc7\u91cd\u8f7d\u5224\u65ad\uff0c\u4f8b\u5982 from_utf(ws, \"GBK\") \u8fd9\u91cc\u7684\u53c2\u6570\u662f wchar_t \uff0c\u90a3\u4e48\u5728 Windows \u4e0a\uff0c\u4ed6\u4f1a\u68c0\u6d4b\u5230 wchar_t \u662f 2 \u5b57\u8282\uff0c\u5c31\u8ba4\u4e3a\u662f UTF-16 \u5230 GBK \u7684\u8f6c\u6362\u3002 UTF \u548c ANSI \u4e92\u8f6c \u6211\u4eec\u7a0b\u5e8f\u7684\u7528\u6237\u4e0d\u4e00\u5b9a\u662f\u4e2d\u56fd\u7528\u6237\uff08GBK\uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4fc4\u7f57\u65af\u7528\u6237\uff08CP1251\uff09\u3001\u65e5\u672c\u7528\u6237\uff08Shift-JIS\uff09\u3001\u897f\u73ed\u7259\u7528\u6237\uff08CP1252\uff09\u7b49\u3002 \u5982\u679c\u8981\u91c7\u7528\u7528\u6237\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u5373\u201cANSI\u201d\uff0c\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u7559\u7a7a\uff08 \"\" \uff09\u3002 \u7a7a\u5b57\u7b26\u4e32\u5c31\u8868\u793a\u91c7\u7528\u5f53\u524d\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e86\uff0c\u5728\u4e2d\u56fd\u5927\u533a\u7b49\u4ef7\u4e8e \"GBK\" \uff0c\u4fc4\u7f57\u65af\u5927\u533a\u7b49\u4ef7\u4e8e \"CP1251\" \u7b49\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::to_utf; int main() { setlocale(LC_ALL, \"\"); // \u5982\u679c\u4f60\u60f3\u7ed9 Boost \u7528\u7a7a\u5b57\u7b26\u4e32\uff0c\u9996\u5148\u9700\u8981\u8bbe\u7f6e\u4e00\u4e0b\u8fd9\u4e00\u884c std::string u8s = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c ANSI std::string s = from_utf(u8s, \"\"); // ANSI \u8f6c UTF-8 u8s = to_utf(s, \"\"); return 0; } setlocale(LC_ALL, \"\"); \u4e2d\u7684\u7a7a\u5b57\u7b26\u4e32\u8868\u793a \u5927\u603b\u7ed3 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-16 utf_to_utf UTF-x UTF-32 utf_to_utf UTF-x Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 UTF-x \u8868\u793a\u53d6\u51b3\u4e8e\u53c2\u6570\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u5982\u679c\u53c2\u6570\u662f char16_t \u7684\u5b57\u7b26\u4e32 std::u16string \uff0c\u90a3 x \u5c31\u662f 16\u3002 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-16 to_utf(\"GBK\", string) GBK UTF-32 to_utf(\"GBK\", string) GBK Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-32 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 from_utf(\"GBK\", string) UTF-8 GBK from_utf(\"GBK\", u16string) UTF-16 GBK from_utf(\"GBK\", u32string) UTF-32 GBK from_utf(\"GBK\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 GBK from_utf(\"\", string) UTF-8 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u16string) UTF-16 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u32string) UTF-32 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u533a\u57df\u8bbe\u7f6e GBK \u548c Shift-JIS \u4e92\u8f6c #include #include using boost::locale::conv::between; using boost::locale::conv::from_utf; int main() { // \u521b\u5efa\u4e00\u4e2a Shift-JIS \u5b57\u7b26\u4e32 std::string jis = from_utf(u8\"\u65e5\u672c\u8a9e\", \"Shift-JIS\"); // \u4ece Shift-JIS \u8f6c\u5230 GBK std::string gbk = between(jis, \"GBK\", \"Shift-JIS\"); std::cout << gbk << '\\n'; // \u4ece GBK \u8f6c\u56de Shift-JIS jis = between(gbk, \"Shift-JIS\", \"GBK\"); std::cout << jis << '\\n'; return 0; } \u6ce8\u610f\uff01\u662f\u76ee\u6807\u7f16\u7801\u5728\u524d\uff01\u5982\u679c\u4f60\u8981\u4ece Shift-JIS \u8f6c\u6210 GBK\uff0c\u90a3\u4e48\u9700\u8981 between(jis, \"GBK\", \"Shift-JIS\") \uff0c\u8fd9\u771f\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\u3002\u4e0d\u4ec5 GBK \u548c Shift-JIS \u53ef\u80fd\u4e0d\u5c0f\u5fc3\u5f04\u53cd\u4e86\uff0c\u7f16\u8bd1\u5668\uff0c\u4e00\u70b9\u63d0\u793a\u90fd\u6ca1\u6709\uff0c\u800c\u4e14 jis \u548c \u201cGBK\u201d \u90fd\u662f\u5b57\u7b26\u4e32\uff0c\u5f88\u5bb9\u6613\u5927\u8111\u641e\u6df7\u3002\u8ba9\u6211\u6765\u8bbe\u8ba1\u7684\u8bdd\uff0c\u6211\u4f1a\u8fd9\u6837\u63d0\u4f9b API\uff1a decode(jis, Encoding::ShiftJIS).encode(Encoding::GBK) \uff0c\u5176\u4e2d Encoding \u662f\u4e00\u4e2a\u679a\u4e3e\uff0c\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u4e0d\u4ec5\u907f\u514d\u72af\u9519\u7684\u673a\u4f1a\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u8f7b\u677e\u3002\u4e4b\u540e\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e13\u9898\u8bfe\u4e2d\uff0c\u4f1a\u518d\u8be6\u7ec6\u8bb2\u89e3\u4ec0\u4e48\u662f\u597d\u7684 API \u8bbe\u8ba1\u3002 \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u5982\u679c\u9047\u5230\u65e0\u6cd5\u7f16\u7801\u7684\u5b57\u7b26\uff0c\u8be5\u5982\u4f55\u5904\u7f6e\uff1f \u9ed8\u8ba4\u60c5\u51b5\u4e0b Boost \u4f1a\u5ffd\u89c6\u9519\u8bef\uff0c\u7f16\u7801\u5931\u8d25\u7684\u5b57\u7b26\u4f1a\u88ab\u4e22\u5f03\u3002 #include #include using boost::locale::conv::from_utf; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\"); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 std::cout << gbk << '\\n'; // \u5728 Windows \u7684 GBK \u7ec8\u7aef\u4e0a\uff0c\u53ea\u663e\u793a\u201c\u6211\u7231\u9762\u201d return 0; } \u53ef\u4ee5\u7528 method_type \u8fd9\u4e2a\u679a\u4e3e\u6765\u6307\u5b9a\u9519\u8bef\u5904\u7406\u7684\u65b9\u5f0f\u3002 \u9ed8\u8ba4\u662f skip \uff0c\u8df3\u8fc7\u6240\u6709\u89e3\u7801\u51fa\u9519\u7684\u5730\u65b9\uff08\u5bfc\u81f4\u201c\ud883\udede\u201d\u4e22\u5931\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230 stop \uff0c\u5f53\u9047\u5230\u89e3\u7801\u9519\u8bef\u65f6\uff0c\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\uff0c\u7ec8\u6b62\u7a0b\u5e8f\u6267\u884c\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\", method_type::stop); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 // from_utf \u4f1a\u629b\u51fa `conversion_error` \u5f02\u5e38 std::cout << gbk << '\\n'; return 0; } \u4e3e\u4f8b\uff1a\u5c1d\u8bd5\u4ee5 GBK \u4fdd\u5b58\uff0c\u5982\u679c\u5931\u8d25\uff0c\u5219\u6539\u4e3a\u5e26\u6709 BOM \u7684 UTF-8\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; using boost::locale::conv::conversion_error; void try_save(std::u32string content, std::wstring path) { std::string binary; try { // \u5c1d\u8bd5\u5c06 UTF-32 \u8f6c\u6210 GBK \u7f16\u7801 binary = from_utf(content, \"GBK\", method_type::stop); } catch (conversion_error const &e) { // \u82e5 GBK \u65e0\u6cd5\u8868\u793a // \u6539\u7528\u524d\u9762\u5e26\u6709 BOM \u7684 UTF-8 \u7f16\u7801 binary = \"\\xEF\\xBB\\xBF\" + utf_to_utf(content); } std::ofstream(path) << binary; } \u4e3e\u4f8b\uff1a\u652f\u6301 UTF-8 \u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f ANSI \u5b57\u7b26\u4e32\uff09\u7684\u6253\u5370\u51fd\u6570\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::utf_to_utf; static int dummy_init = (setlocale(LC_ALL, \"\"), 0); // \u9700\u8981\u8bbe\u7f6e\u8fc7 setlocale(LC_ALL, \"\") \u540e\uff0c\u624d\u80fd\u4f7f\u7528 Boost \u7684\u7a7a\u5b57\u7b26\u4e32\u5199\u6cd5 void u8print(std::string msg) { std::cout << from_utf(msg, \"\"); // \u6216\u8005\uff1a // std::wcout << utf_to_utf(msg); } \u6b64\u5904 static int dummy_init = \u662f\u4e00\u79cd\u9759\u6001\u521d\u59cb\u5316\u94a9\u5b50\u7684\u5c0f\u6280\u5de7\uff0c\u4e4b\u540e\u8bbe\u8ba1\u6a21\u5f0f\u8bfe\u7a0b\u7684\u5355\u4f8b\u6a21\u5f0f\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3\u3002 \u66f4\u591a\u529f\u80fd\uff1f\uff01 \u51fd\u6570 \u4ece \u5230 utf_to_utf UTF \u7cfb\u5217 UTF \u7cfb\u5217 from_utf UTF \u7cfb\u5217 \u6742\u724c\u5b57\u7b26\u7f16\u7801 to_utf \u6742\u724c\u5b57\u7b26\u7f16\u7801 UTF \u7cfb\u5217 between \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u66f4\u591a\u7ec6\u8282\u7528\u6cd5\u89c1\u5b98\u65b9\u6587\u6863\uff1ahttps://www.boost.org/doc/libs/1_81_0/libs/locale/doc/html/group__codepage.html \u4e0d\u53ef\u601d\u8bae\u7684\u662f\uff1a\u7f16\u7801\u8f6c\u6362\u53ea\u662f boost::locale::conv \u8fd9\u4e2a\u5b50\u6a21\u5757\u4e0b\u7684\u4e00\u4e2a\u5c0f\u529f\u80fd\u800c\u5df2\uff01 boost::locale \u8fd8\u63d0\u4f9b\u4e86\u66f4\u591a\u529f\u80fd\uff0c\u5982\u6309\u7167\u5730\u57df\u8bed\u8a00\u89c4\u8303\u683c\u5f0f\u5316\u6570\u5b57\u3001\u8d27\u5e01\u3001\u65e5\u671f\u3001\u65f6\u95f4\u7b49\uff0c\u4e0b\u4e00\u5c0f\u8282\u4e2d\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd\u3002\u5b8c\u5168\u662f std::locale \u7684\u4e0a\u4f4d\u66ff\u4ee3\u3002 Boost \u54ea\u91cc\u90fd\u597d\uff0c\u4f60\u60f3\u8981\u7684\u529f\u80fd\u5e94\u6709\u5c3d\u6709\u3002\u800c\u4e14\u4e0d\u9700\u8981 C++20\uff0c\u5f88\u4f4e\u7248\u672c\u7684 C++ \u4e5f\u80fd\u7528\u3002\u552f\u4e00\u7f3a\u70b9\u53ef\u80fd\u5c31\u662f\u592a\u80a5\u4e86\uff0c\u7f16\u8bd1\u6162\u3002 Windows \u7528\u6237\uff1aMultiByteToWideChar \u5982\u679c\u4f60\u662f Windows \u7a0b\u5e8f\u5458\uff0c\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u4e14\u9700\u8981\u5728 Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u89c4\u5b9a\u7684 ANSI\uff08\u5728\u4e2d\u56fd\u533a\u662f GBK\uff09\u7f16\u7801\u548c UTF-16 \u4e4b\u95f4\u8f6c\u6362\uff1a \u53ef\u4ee5\u7528 Windows \u5b98\u65b9\u63d0\u4f9b\u7684 MultiByteToWideChar \u548c WideCharToMultiByte \u51fd\u6570\u3002 \u8fd9\u4e24\u4e2a\u51fd\u6570\u56e0\u4e3a C \u8bed\u8a00\u7279\u8272\u7684\u7f18\u6545\uff0c\u53c2\u6570\u6bd4\u8f83\u591a\u800c\u6742\uff0c\u5efa\u8bae\u81ea\u5df1\u52a8\u624b\u5c01\u88c5\u6210\u66f4\u6613\u7528\u7684 C++ \u51fd\u6570\uff1a std::wstring ansi_to_wstring(const std::string &s) { // ACP = ANSI Code Page\uff0c\u544a\u8bc9\u4ed6\u5b57\u7b26\u4e32\u91cc\u7684\u662f\u5f53\u524d\u533a\u57df\u8bbe\u7f6e\u6307\u5b9a\u7684\u7f16\u7801\uff08\u5728\u4e2d\u56fd\u533a\uff0cANSI \u5c31\u662f GBK \u4e86\uff09 int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_ansi(const std::wstring &ws) { int len = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } std::wstring utf8_to_wstring(const std::string &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_utf8(const std::wstring &ws) { int len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } C \u8bed\u8a00\u7279\u8272\uff1a\u6240\u6709\u8981\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u90fd\u9700\u8981\u8c03\u7528\u4e24\u904d\uff0c\u7b2c\u4e00\u6ce2\u5148\u6c42\u51fa\u957f\u5ea6\uff0c\u7b2c\u4e8c\u6ce2\u624d\u5199\u5165\u3002\u8fd9\u662f\u4e3a\u4e86\u907f\u514d\u4e0e\u5185\u5b58\u5206\u914d\u5668\u8026\u5408\uff0c\u6240\u6709\u7684 C \u98ce\u683c API \u90fd\u662f\u8fd9\u6837\u3002 MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b \u590d\u73b0\u6761\u4ef6\uff1a Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e3a\u4e2d\u6587 (GBK)\u3002 \u4f7f\u7528 MSVC \u7684 /utf-8 \u9009\u9879\u7f16\u8bd1\u3002 #include int main() { MessageBoxA(nullptr, \"\u6211\u7231\ud883\udede\ud883\udede\u9762\", \"\u6807\u9898\", MB_OK); // \u4f1a\u53d8\u6210\u4e71\u7801 return 0; } Linux \u7528\u6237\uff1a iconv \u5982\u679c\u4f60\u662f Linux \u7528\u6237\uff0c\u4e14\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 iconv \u5e93\u3002 iconv \u4e5f\u6709 Windows \u7684\u7248\u672c\uff0c\u4f46\u5b89\u88c5\u6bd4\u8f83\u56f0\u96be\u3002\u5982\u679c\u4f60\u8fde iconv \u90fd\u641e\u5f97\u5b9a\uff0c\u6ca1\u7406\u7531 Boost \u641e\u4e0d\u5b9a\u3002 #include #include std::string convert(std::string const &s, char const *from, char const *to) { iconv_t cd = iconv_open(to, from); if (cd == (iconv_t)-1) { throw std::runtime_error(\"iconv_open failed\"); } auto in = s.data(); auto inbytesleft = s.size(); size_t outbytesleft = inbytesleft * 4; std::string buffer(outbytesleft, 0); auto out = buffer.data(); iconv(cd, &in, &inbytesleft, &out, &outbytesleft); iconv_close(cd); buffer.resize(buffer.size() - outbytesleft); return buffer; } // \u4e3e\u4f8b\uff1aUTF-8 \u8f6c GBK std::string utf8_to_gbk(std::string const &s) { return convert(s, \"UTF-8\", \"GBK\"); } // \u4e3e\u4f8b\uff1aGBK \u8f6c UTF-8 std::string gbk_to_utf8(std::string const &s) { return convert(s, \"GBK\", \"UTF-8\"); } iconv \u547d\u4ee4\u884c\u5de5\u5177 iconv \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u4e5f\u662f\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177\uff08\u5927\u591a Linux \u53d1\u884c\u7248\u90fd\u81ea\u5e26\u4e86\uff09\u3002\u7528\u6cd5\u5982\u4e0b\uff1a iconv -f \u6765\u81ea\u4ec0\u4e48\u7f16\u7801 -t \u5230\u4ec0\u4e48\u7f16\u7801 (\u8f93\u5165\u6587\u4ef6\u540d...) > \u8f93\u51fa\u6587\u4ef6\u540d \u5982\u4e0d\u6307\u5b9a\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u9ed8\u8ba4\u4ece\u7ec8\u7aef\u8f93\u5165\u6d41\u8bfb\u53d6\u3002 \u5982\u4e0d\u4f7f\u7528 > \u8f93\u51fa\u6587\u4ef6\u540d \u91cd\u5b9a\u5411\u8f93\u51fa\uff0c\u5219\u9ed8\u8ba4\u8f93\u51fa\u5230\u7ec8\u7aef\u3002 \u53ef\u4ee5\u7528 echo \u914d\u5408\u7ba1\u9053\u6765\u521b\u5efa\u8f93\u5165\u6d41\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 \u6b64\u5904\u663e\u793a\u4e71\u7801\u662f\u56e0\u4e3a\u6211\u7684\u7ec8\u7aef\u662f UTF-8 \u683c\u5f0f\uff0c\u65e0\u6cd5\u6b63\u786e\u89e3\u6790 iconv \u8f93\u51fa\u7684 GBK \u683c\u5f0f\u6570\u636e\u3002 \u628a\u201c\u6211\u7231\u5c0f\u5f6d\u8001\u5e08\u201d\u8f6c\u6362\u4e3a GBK \u683c\u5f0f\u5199\u5165 gbk.txt \uff0c\u7136\u540e\u518d\u91cd\u65b0\u8fd8\u539f\u56de UTF-8 \u683c\u5f0f\u67e5\u770b\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK > gbk.txt $ cat gbk.txt \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 $ iconv -f GBK -t UTF-8 gbk.txt \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 Windows \u53ef\u80fd\u4e5f\u6709\u7c7b\u4f3c\u7684\u5de5\u5177\uff0c\u6bd4\u5982 iconv.exe \uff0c\u4f46\u6211\u6ca1\u627e\u5230\u3002 \u672c\u5730\u5316 (locale) \u672c\u5730\u5316\u662f\u6307\u6839\u636e\u7528\u6237\u7684\u8bed\u8a00\u3001\u5730\u533a\u7b49\u73af\u5883\uff0c\u663e\u793a\u4e0d\u540c\u7684\u754c\u9762\u3002\u6bd4\u5982\u8bf4\uff0c\u540c\u6837\u662f\u6587\u4ef6\u83dc\u5355\uff0c\u4e2d\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201c\u6587\u4ef6\u201d\u3001\u82f1\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201cFile\u201d\u3002 \u533a\u5206\u5b57\u7b26\u7c7b\u578b C \u8bed\u8a00\u63d0\u4f9b\u4e86 \u5934\u6587\u4ef6\uff0c\u91cc\u9762\u5c01\u88c5\u4e86\u5927\u91cf\u5f62\u5982 isspace \u3001 isdigit \u8fd9\u6837\u7684\u5224\u65ad\u5b57\u7b26\u5206\u7c7b\u7684\u51fd\u6570\u3002 #include C++ \u5bf9\u5176\u5b9e\u65bd\u4e86\u518d\u5c01\u88c5\uff0c\u6539\u540d\u4e3a \u3002\u82e5\u4f60\u5bfc\u5165\u7684\u662f\u8be5\u5934\u6587\u4ef6\uff0c\u90a3\u4e48\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5e26\u6709 std \u540d\u5b57\u7a7a\u95f4\u524d\u7f00\u7684\u65b9\u5f0f std::isspace \uff0c std::isdigit \u8bbf\u95ee\u4e86\uff0c\u770b\u8d77\u6765\u66f4\u52a0\u4e13\u4e1a\uff08\u786e\u4fe1\uff09\u3002 #include \u51fd\u6570\u6e05\u5355\uff1a \u51fd\u6570\u540d\u79f0 \u5224\u65ad\u7684\u5b57\u7b26\u7c7b\u578b isascii 0 \u5230 0x7F \u7684\u6240\u6709 ASCII \u5b57\u7b26 isalpha \u5927\u5c0f\u5199\u5b57\u6bcd A-Z a-z isupper \u5927\u5199\u5b57\u6bcd A-Z islower \u5c0f\u5199\u5b57\u6bcd a-z isdigit \u6570\u5b57 0-9 isxdigit \u5341\u516d\u8fdb\u5236\u6570\u5b57 A-F a-f 0-9 isprint \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u5305\u62ec\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u6807\u70b9\u7b49 isgraph \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u4e0d\u5305\u62ec\u7a7a\u683c iscntrl \u63a7\u5236\u5b57\u7b26\uff0c\u9664\u53ef\u6253\u5370\u5b57\u7b26\u5916\u7684\u5168\u90e8 isspace \u7a7a\u767d\u5b57\u7b26\uff0c\u5982\u7a7a\u683c\u3001\u6362\u884c\u3001\u56de\u8f66\u3001\u5236\u8868\u7b26\u7b49 ispunct \u6807\u70b9\u7b26\u53f7 isalnum \u5b57\u6bcd\u6216\u6570\u5b57 \u66f4\u8be6\u7ec6\u7684\u8868\u683c\u53ef\u4ee5\u770b\uff1ahttps://en.cppreference.com/w/cpp/string/byte/isspace \u5bbd\u5b57\u7b26\u7c7b\u578b \u4e4b\u524d\u63d0\u5230\u7684\u5b57\u7b26\u90fd\u662f char \u7c7b\u578b\u7684 ASCII \u5b57\u7b26\uff0c\u8303\u56f4\u6700\u591a\u5728 0 \u5230 0x7F \u5185\u3002 \u5bf9\u53ea\u63a5\u53d7 char \u7684 isspace \uff0c ispunct \u7cfb\u5217\u51fd\u6570\uff0c\u53c2\u6570\u5982\u679c\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\uff0c\u7ed3\u679c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8981\u652f\u6301\u66f4\u5927\u8303\u56f4\u7684\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u7528 wchar_t \u7c7b\u578b\uff0c\u6216\u8005 char16_t \u548c char32_t \u3002 \u4e0e\u5b57\u7b26\u4e32\u5e38\u91cf\u4e00\u6837\uff0c\u5355\u4e2a\u5b57\u7b26\u4e5f\u53ef\u4ee5\u7528 L \u3001 u \u3001 U \u6765\u5206\u522b\u4ea7\u751f wchar_t \u3001 char16_t \u3001 char32_t \u7c7b\u578b\u7684\u5b57\u7b26\u3002 char c = '\u6211'; // \u7f16\u8bd1\u51fa\u9519\uff01char \u7c7b\u578b\u65e0\u6cd5\u5bb9\u7eb3\u6211 (0x6211) wchar_t wc = L'\u6211'; // \u7f16\u8bd1\u901a\u8fc7\uff0c\u7b49\u4ef7\u4e8e wc = 0x6211 \u548c const char * \u4e00\u6837\uff0c\u4e5f\u6709 const wchar_t \u8868\u793a\u8fd9\u79cd\u7531 Unicode \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff1a const wchar_t *ws = L\"\u4f60\u597d\uff0c\u4e16\u754c\"; assert(ws[2] == L'\uff0c'); wchar_t \u7684\u63d0\u51fa\u8d77\u521d\u662f\u4e3a\u4e86\u907f\u514d char \u7684\u533a\u57df\u8bbe\u7f6e\u5404\u81ea\u4e3a\u653f\uff0c\u7f16\u7801\u6df7\u4e71\u7684\u95ee\u9898\uff0c\u56e0\u4e3a wchar_t \u59cb\u7ec8\u662f UTF-16 (Windows) \u6216 UTF-32 (Linux)\u3002 wchar_t \u5e94\u7528\u6848\u4f8b std::string str = \"hello,world,universe\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, ',')) { std::cout << line << '\\n'; } \u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u5b57\u7b26\u4e32\u5206\u5272\u51fd\u6570\uff0c\u5b83\u4f1a\u628a hello \u6309\u7167\u9017\u53f7 \u201c,\u201d (0x2C) \u5206\u5272\uff0c\u7136\u540e\u8f93\u51fa\u3002 \u4f46\u662f\uff0c\u5b83\u65e0\u6cd5\u5904\u7406 Unicode \u5b57\u7b26 \u201c\uff0c\u201d (0xFF0C)\uff0c\u8fd9\u662f\u4e00\u4e2a\u5168\u89d2\u7684\u9017\u53f7\u3002\u56e0\u4e3a \u201c\uff0c\u201d \u4f1a\u88ab UTF-8 \u7f16\u7801\u6210\u4e09\u4e2a char \uff1a0xEF 0xBC 0x8C\u3002 std::string str = \"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, '\uff0c')) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u7b49\u4ef7\u4e8e '\\xEF\\xBC\\x8C'\uff0c\u4e00\u4e2a char \u5e38\u91cf\u91cc\u4e0d\u5f97\u5305\u542b\u4e09\u4e2a char\uff01 std::cout << line << '\\n'; } \u800c wchar_t \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a \u201c\uff0c\u201d \u5728 0xFFFF \u8303\u56f4\u5185\uff0c\u5373\u4f7f\u8003\u8651\u5230 Windows \u662f UTF-16 \u7f16\u7801\uff0c\u201c\uff0c\u201d \u53ea\u4f1a\u4ea7\u751f\u4e00\u4e2a wchar_t \u3002\u8fd9\u5bf9\u4ee5\u5355\u4e2a wchar_t \u4e3a\u5355\u4f4d\u7684 std::getline \u6765\u8bf4\u6ca1\u6709\u95ee\u9898\u3002 std::wstring str = L\"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::wstringstream ss(str); std::wstring line; while (std::getline(ss, line, L'\uff0c')) { // \u7f16\u8bd1\u901a\u8fc7\uff0c'\uff0c' \u662f\u5355\u4e2a UTF-16 \u7801\u4f4d std::wcout << line << L'\\n'; } \u533a\u57df\u8bbe\u7f6e\u4e0e locale \u8981\u8ba9 iswspace \u548c iswpunct \u8bc6\u522b\u4e2d\u6587\u9017\u53f7\u548c\u4e2d\u6587\u7a7a\u683c\uff0c\u6211\u4eec\u9700\u8981\u5148\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e00\u884c\u4ee3\u7801\uff1a setlocale(LC_ALL, \"C.utf-8\"); \u8fd9\u4f1a\u542f\u7528 Unicode \u5b57\u7b26\u96c6\uff0c\u4f7f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u80fd\u591f\u57fa\u4e8e Unicode \u5b57\u7b26\u96c6\u53bb\u5224\u65ad\u5b57\u7b26\u7c7b\u578b\uff0c\u800c\u4e0d\u662f\u9ed8\u8ba4\u7684 ASCII \u5b57\u7b26\u96c6\u3002 assert(ispunct(',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f ispunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L'\uff0c') == true);// 0xFF0C \u5bf9\u5e94\u7684\u5168\u89d2\u9017\u53f7\u4e5f\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 \u6bcf\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u4e00\u5f00\u59cb\uff0c\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \u3002\u9700\u8981\u8bbe\u7f6e\u4e3a \"C.UTF-8\" \u6216\u8005 \"zh_CN.UTF-8\" \uff0c\u603b\u4e4b\u662f\u652f\u6301 Unicode \u5b57\u7b26\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u624d\u80fd\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u8bc6\u522b\u8d85\u8fc7 ASCII \u8303\u56f4\u7684\u5b57\u7b26\u7684\u7c7b\u578b\u3002 fmt::println(\"\u9ed8\u8ba4: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C\"); fmt::println(\"C: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C.UTF-8\"); fmt::println(\"C.UTF-8: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"zh_CN.UTF-8\"); fmt::println(\"zh_CN.UTF-8: {}\", iswpunct(L'\uff0c')); \u8f93\u51fa\uff1a \u9ed8\u8ba4: 0 C: 0 C.UTF-8: 1 zh_CN.UTF-8: 1 \u603b\u4e4b\uff0c isw***** \u7cfb\u5217\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570 wchar_t \u8868\u793a\u8303\u56f4\u66f4\u5e7f\uff0c\u5728 Linux \u4e0a\u80fd\u8868\u793a\u6240\u6709 Unicode \u5b57\u7b26\uff0c\u5728 Windows \u4e0a\u80fd\u8868\u793a\u6240\u6709 0xFFFF \u4ee5\u5185\u7684\u5e38\u7528 Unicode \u5b57\u7b26\u3002 is***** \u7cfb\u5217\u51fd\u6570\u9047\u5230\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\u7684 char \u8fd8\u4f1a\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u975e\u5e38\u70e6\u4eba\u3002\u65e2\u7136 char \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a wchar_t \uff0c\u6240\u4ee5\u6211\u7684\u5efa\u8bae\u662f\u8bbe\u7f6e\u4e86 \".utf-8\" locale \u540e\uff0c\u5168\u90e8\u7528 isw***** \u53d6\u4ee3 is***** \u3002 locale \u7684\u547d\u540d\u89c4\u8303 \"zh_CN.UTF-8\" \u8fd9\u6837\u7684\u5b57\u7b26\u4e32\uff0c\u5c31\u662f locale \u7684\u540d\u5b57\uff0clocale \u540d\u5b57\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5206\u522b\u662f\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\u3002 \u8bed\u8a00.\u5b57\u7b26\u7f16\u7801 \"zh_CN.UTF-8\" \u5c31\u8868\u793a\uff0c\u4e00\u4e2a\u8bed\u8a00\u4e3a\u7b80\u4f53\u4e2d\u6587\uff0c\u7f16\u7801\u683c\u5f0f\u4e3a UTF-8 \u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u8981\u6ce8\u610f\u7684\u662f\uff0c\u7528\u6237\u5fc5\u987b\u5df2\u7ecf\u5b89\u88c5\u8fc7\u8be5\u533a\u57df\u8bbe\u7f6e\uff0c\u7a0b\u5e8f\u624d\u80fd\u4f7f\u7528 setlocale \u8bbe\u7f6e\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u627e\u4e0d\u5230 locale \u7684\u9519\u8bef\u3002 \u8fd9\u51e0\u4e4e\u5bfc\u81f4\u4f60\u6ca1\u6cd5\u7528\u9664\u9ed8\u8ba4\u5916\u7684\u4efb\u4f55 locale\uff0c\u6bd4\u5982 \"zh_CN.UTF-8\" \uff0c\u56e0\u4e3a\u4f60\u4e0d\u80fd\u786e\u5b9a\u7528\u6237\u6709\u6ca1\u6709\u5b89\u88c5\u4ed6\u3002\u4f46\u4f60\u53ef\u4ee5\u7528 boost::locale::generator \u51ed\u7a7a\u751f\u6210\u4e00\u4e2a\u7cfb\u7edf\u91cc\u6ca1\u6709\u5b89\u88c5\u8fc7\u7684 locale\uff0c\u7ed5\u5f00\u6807\u51c6\u5e93\u7684\u9650\u5236\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 Linux \u7528\u6237\u53ef\u4ee5\u901a\u8fc7 \u4fee\u6539 /etc/locale.gen \u53d6\u6d88\u6ce8\u91ca\u8981\u542f\u7528\u7684\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\uff0c\u4fdd\u5b58\u540e\uff0c\u8fd0\u884c locale-gen \u5373\u53ef\u5b89\u88c5\u6240\u6709\u6ca1\u6ce8\u91ca\u7684\u8bed\u8a00\u3002 sudo vim /etc/locale.gen sudo locale-gen \u53ef\u4ee5\u7528 locale -a \u547d\u4ee4\u67e5\u770b\u5df2\u7ecf\u5b89\u88c5\u4e86\u54ea\u4e9b locale\uff1a $ locale -a C C.utf8 POSIX en_US en_US.iso88591 en_US.utf8 zh_CN.gb18030 zh_CN.gbk zh_CN.utf8 \u6ce8\u610f\u5230\uff0clocale \u4e2d '.' \u53f7\u53f3\u8fb9\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u65e0\u89c6\u5927\u5c0f\u5199\u7684\uff0c\u800c\u4e14\u53ef\u4ee5\u7701\u7565\u6389 '-' \u3002\u6240\u4ee5 ISO-8859-1 \u53ef\u4ee5\u88ab\u7b80\u5199\u6210 iso88591 \uff0c UTF-8 \u88ab\u7b80\u5199\u6210 utf8 \u3002 \u5de6\u8fb9\u7684\u8bed\u8a00\u4e5f\u662f\u7528 '_' \u4e00\u5206\u4e3a\u4e8c\uff0c\u56fa\u5b9a\u662f '\u8bed\u8a00_\u5730\u533a' \u7684\u5199\u6cd5\u3002\u6bd4\u5982\u52a0\u62ff\u5927\u65e2\u6709\u82f1\u8bed\u7528\u6237\u53c8\u6709\u6cd5\u8bed\u7528\u6237\uff0c\u82f1\u8bed\u7684\u4ee3\u53f7\u662f 'en' \uff0c\u6cd5\u8bed\u7684\u4ee3\u53f7\u662f 'fr' \uff0c\u52a0\u62ff\u5927\u7684\u4ee3\u53f7\u662f 'CA' \uff0c\u6240\u4ee5\u5c31\u5b58\u5728\u7740 'en_CA' \u548c 'fr_CA' \u4e24\u79cd locale\u3002 \u4e5f\u6709\u4e00\u79cd\u8bed\u8a00\u88ab\u591a\u4e2a\u5730\u533a\u4f7f\u7528\u7684\u60c5\u51b5\uff0c\u4f8b\u5982\u4e2d\u6587\u7684\u4ee3\u53f7\u662f 'zh' \uff0c\u4ed6\u88ab\u4e2d\u56fd\u5927\u9646\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_CN' \uff0c\u88ab\u9999\u6e2f\u4f7f\u7528\u65f6\u53eb 'zh_HK' \uff0c\u88ab\u53f0\u6e7e\u7701\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_TW' \uff0c\u88ab\u65b0\u52a0\u5761\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_SG' \u3002 Windows \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b89\u88c5\u8bed\u8a00\u548c\u5730\u533a\u7684\u9009\u9879\uff0c\u4f46\u6bd4\u5c14\u76d6\u5b50\u5bf9 locale \u547d\u540d\u7684\u8bed\u6cd5\u7a0d\u6709\u4e0d\u540c\uff1a setlocale(LC_ALL, \"Chinese_China.936\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4ee3\u7801\u9875 936\uff08\u4e5f\u5c31\u662f GBK\uff09 \u4ed6\u7684\u8bed\u8a00\u540d\u4e0d\u662f\u6309\u7167\u56fd\u9645\u89c4\u8303\u7684 zh_CN \u8fd9\u6837\u7684\u7b80\u5199\uff0c\u800c\u662f Chinese_China \u3002 \u800c\u4e14\u540e\u9762\u7684 936 \u662f Windows \u79c1\u81ea\u5b9a\u4e49\u7684\u4e00\u5957\u6240\u8c13\u7684\u201c\u4ee3\u7801\u9875\u201d\uff0c\u8fd9\u91cc 936 \u5176\u5b9e\u5c31\u662f \u4e2d\u5b8f CP_GBK \u7684\u503c\uff0c\u8868\u793a GBK \u4ee3\u7801\u9875\u3002\u540c\u6837\u5730\u8fd8\u6709 65001 \u8868\u793a UTF-8 \u4ee3\u7801\u9875\u3002 setlocale(LC_ALL, \"Chinese_China.65001\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4f46\u662f\u542f\u7528 UTF-8 \u652f\u6301 setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 .65001 \u53ef\u4ee5\u7528\u522b\u540d .UTF-8 \u53d6\u4ee3\u3002\u4f46\u53ea\u6709 .UTF-8 \u652f\u6301\u8fd9\u4e2a\u522b\u540d\uff0c\u4f8b\u5982 .GBK \u4ed6\u5c31\u4e0d\u80fd\u8bc6\u522b\u3002 \u8bbe\u7f6e\u4e86 \"Chinese_China.utf-8\" \u6548\u679c\u548c\u4f60\u5728\u63a7\u5236\u9762\u677f\u5168\u5c40\u5f00\u4e86\u90a3\u4e2a \u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u5168\u7403\u8bed\u8a00\u5b9e\u9a8c\u652f\u6301\u201d \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u662f\u4ec5\u9650\u5f53\u524d\u8fdb\u7a0b\u7684 C/C++ \u6807\u51c6\u5e93\u3002 \u800c\u4e14\u7531\u4e8e argv \u5728\u4f60\u6765\u5f97\u53ca setlocale \u4e4b\u524d\u5c31\u5df2\u7ecf\u521d\u59cb\u5316\uff0c\u6240\u4ee5 main \u7684 argv \u53c2\u6570\u4f9d\u7136\u662f GBK \u7f16\u7801\u7684\uff0c\u9664\u975e\u4f60\u4f7f\u7528\u7684\u662f _wmain \uff0c\u90a3\u5c06\u80fd\u6536\u5230 UTF-16 \u7684 argv \uff0c\u7136\u540e\u4f60\u81ea\u5df1\u8f6c\u6362\u56de UTF-8\u3002 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u63a5\u53d7\u73af\u5883\u4e2d\u7684\u8bbe\u7f6e\uff0c\u5bf9\u4e8e Linux \u800c\u8a00\u662f $LC_ALL \u73af\u5883\u53d8\u91cf\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f\u63a7\u5236\u9762\u677f\u4e2d\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 setlocale(LC_ALL, \"\"); // \u662f\u7684\uff0c\u7a7a\u7684\u5b57\u7b26\u4e32 \u6ce8\u610f\u662f\u7a7a\u5b57\u7b26\u4e32 \"\" \u624d\u6709\u8fd9\u6837\u7684\u6548\u679c\uff0c\u800c\u4e0d\u662f NULL\uff01 setlocale(LC_ALL, NULL) \u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u4ed6\u7684\u6548\u679c\u662f\u8fd4\u56de\u5f53\u524d\u7684 locale\uff08\u6ca1\u60f3\u5230\u5427\uff1fsetlocale \u6709\u8fd4\u56de\u503c\uff09\u3002\u8fd9\u5c31\u662f C \u8bed\u8a00\u7684\u9b45\u529b\uff0c\u540c\u4e00\u4e2a\u51fd\u6570\u62c6\u6210\u597d\u51e0\u5206\u7528\uff0c\u53c8\u80fd set \u53c8\u80fd get\uff0c\u5c41\u80a1\u5341\u5206\u7075\u6d3b\u3002 \u4e5f\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u90e8\u5206\u4e3a\u7a7a\u7684 locale \u540d\u5b57\uff0c\u6bd4\u5982 \".utf-8\" \uff0c\u4ed6\u8868\u793a\u4fdd\u7559\u5f53\u524d\u73af\u5883\u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\uff0c\u4f46\u201c\u7f16\u7801\u201d\u90e8\u5206\u66ff\u6362\u4e3a\u201c.utf-8\u201d\u3002 setlocale(LC_ALL, \".utf-8\"); // \u5728\u4e2d\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u5728\u7f8e\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"English_United States.utf-8\"); \u7279\u6b8a locale\uff1a \"C\" \u4e0d\u559c\u6b22\u672c\u5730\u5316\u8fd9\u4e00\u5957\u8bbe\u5b9a\uff1f \u4f60\u53ef\u4ee5\u8bbe\u7f6e LC_ALL \u4e3a \"C\" \u6216 \"POSIX\" \uff0c\u8fd9\u662f\u6807\u51c6\u5e93\u9884\u5148\u5b9a\u4e49\u597d\u7684\u4e24\u4e2a locale\uff0c\u4ed6\u4eec\u7684\u7279\u70b9\u662f\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u672c\u5730\u5316\uff0c\u800c\u662f\u59cb\u7ec8\u4ee5\u82f1\u6587\u663e\u793a\u3002\u8fd9\u5728\u8c03\u8bd5\u7a0b\u5e8f\u65f6\u975e\u5e38\u6709\u7528\uff0c\u56e0\u4e3a\u8fd9\u6837\u4f60\u53ef\u4ee5\u786e\u5b9a\u8f93\u51fa\u7684\u683c\u5f0f\u662f\u56fa\u5b9a\u7684\uff0c\u4e0d\u4f1a\u88ab\u7528\u6237\u7684\u73af\u5883\u548c\u672c\u5730\u5316\u7684\u4fe1\u606f\u800c\u6539\u53d8\u3002 \u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u4f60\u6ca1\u6709 setlocale \u8fc7\uff0cC \u8bed\u8a00\u9ed8\u8ba4\u5c31\u662f \"C\" locale\uff0c\u4e0d\u4f1a\u53d7\u5230\u7528\u6237\u73af\u5883\u53d8\u91cf\u7684\u4efb\u4f55\u5f71\u54cd\uff08Windows \u7684\u6587\u4ef6\u7cfb\u7edf API \u9664\u5916\uff0c\u786e\u5b9e\u4f1a\u53d7\u5230 GBK \u5f71\u54cd\uff09\u3002 setlocale(LC_ALL, \"C\"); setlocale(LC_ALL, \"POSIX\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 \u4e0d\u8fc7\uff0c \"C\" \u610f\u5473\u7740\u4ed6\u5047\u5b9a\u5b57\u7b26\u4e32\u662f\u5b8c\u5168\u7684 ASCII\uff0c\u8d85\u8fc7 ASCII \u7684\u90e8\u5206\u662f\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff1a\u5bf9\u4e8e Linux \u800c\u8a00\u662f UTF-8\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u4e0d\u505a\u4efb\u4f55\u5904\u7406\uff0c\u56e0\u4e3a Linux \u7684 ext4 \u6587\u4ef6\u7cfb\u7edf\u6ca1\u6709\u5b57\u7b26\u7f16\u7801\u7684\u533a\u5206\uff09\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f GBK\uff08\u4e2d\u56fd\u533a\uff09\u3002 \u56e0\u6b64\uff0c\u4e5f\u6709 \"C.utf-8\" \u8fd9\u6837\u7684 locale\uff0c\u4ed6\u8868\u793a\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u53ef\u4ee5\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u652f\u6301 Unicode \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u4e5f\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6253\u5370 ASCII \u4ee5\u5916\u7684\u5b57\u7b26\u4e86\u3002\u53ea\u662f\u6ca1\u6709\u6307\u5b9a\u8bed\u8a00\uff0c\u901a\u5e38\u6765\u8bf4\u8fd9\u65f6 strerror \u4e00\u7c7b\u51fd\u6570\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u82f1\u8bed\u7684\u6d88\u606f\u3002 \u4f46\u4f3c\u4e4e\u53ea\u5728 Linux \u4e0a\u6709\u6548\uff0cWindows \u53ea\u652f\u6301 \"C\" \u800c\u4e0d\u652f\u6301 \"C.utf-8\" \u3002 LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf locale \u5206\u4e3a\u8bb8\u591a\u4e2a\u201c\u65b9\u9762 (facet)\u201d\uff0c\u4e0d\u540c\u7684\u65b9\u9762\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u53d6\u503c\uff08\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u662f\u4e00\u6837\u7684\uff09\uff0c\u53ef\u4ee5\u5ba2\u5236\u5316\u6807\u51c6\u5e93\u4e0d\u540c\u90e8\u5206\u6d89\u53ca\u8bed\u8a00\u548c\u7f16\u7801\u76f8\u5173\u7684\u884c\u4e3a\u3002\u8fd9\u4e9b\u65b9\u9762\u5728 C \u8bed\u8a00\u4e2d\u90fd\u6709\u4e00\u4e2a LC_ \u5f00\u5934\u7684\u679a\u4e3e\u6765\u8868\u793a\u3002 LC_CTYPE \u53ea\u5f71\u54cd ctype.h \u4e2d\u7684\u51fd\u6570\uff0c\u4e5f\u5c31\u662f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u8fd8\u6709 toupper \uff0c tolower \u7b49\uff0c\u4ed6\u8fd8\u5f71\u54cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\u65b9\u9762\u3002 LC_TIME \u5f71\u54cd\u65f6\u95f4\u548c\u65e5\u671f\u7684\u683c\u5f0f\u5316\uff0c\u4f8b\u5982 asctime \u7b49\u3002 LC_NUMERIC \u5f71\u54cd\u6570\u5b57\u7684\u683c\u5f0f\u5316\u3002 LC_MONETARY \u5f71\u54cd\u8d27\u5e01\u7684\u683c\u5f0f\u5316\u3002 LC_MESSAGES \u5f71\u54cd strerror \u7b49\u4fe1\u606f\u7c7b\u51fd\u6570\u8fd4\u56de\u7684\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\u5728\u4e2d\u6587 locale \u4e0b strerror(EPERM) \u4f1a\u8fd4\u56de \"\u6743\u9650\u4e0d\u591f\" \uff0c\u800c\u5728\u82f1\u6587 locale \u4e0b\u8fd4\u56de \"Permission denied.\" \u3002 LC_ALL \u662f\u5168\u5c40 locale\uff0c\u5b83\u4f1a\u5f71\u54cd\u4ee5\u4e0a\u6240\u6709\u6807\u51c6\u5e93\u51fd\u6570\u7684\u884c\u4e3a\u3002\u8bbe\u7f6e LC_ALL \u4e3a\u4e00\u4e2a\u503c\uff0c\u7b49\u540c\u4e8e\u4e3a\u4ee5\u4e0a\u6240\u6709\u90fd\u8d4b\u4e88\u7edf\u4e00\u7684\u503c\u3002 \u4f60\u53ef\u4ee5\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u8bbe\u7f6e $LC_ALL \u3001`$LC_CTYPE \u6240\u6709 GNU/Linux \u81ea\u5e26\u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u90fd\u5728 main \u51fd\u6570\u5f00\u5934\uff0c\u914d\u5907\u4e86 setlocale(LC_ALL, \"\"); \u3002\u8fd9\u4f1a\u8bfb\u53d6\u7528\u6237\u914d\u7f6e\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u533a\u57df\u504f\u597d\u8bbe\u7f6e\uff0c\u5e76\u8bbe\u4e3a\u5168\u5c40\u7684 locale\u3002 \u53ef\u4ee5\u7406\u89e3\u4e3a locale \u662f\u4e00\u4e2a\u9690\u85cf\u5728\u6807\u51c6\u5e93\u4e2d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u6240\u6709\u7684 iswpunct \u3001 asctime \u3001 strerror \u90fd\u4f1a\u8bfb\u53d6\u8be5\u5168\u5c40\u53d8\u91cf\u91cc\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u6765\u51b3\u5b9a\u81ea\u5df1\u7684\u8fd0\u884c\u65f6\u884c\u4e3a\u3002 LC_MESSAGES \uff1a\u62a5\u9519\u4fe1\u606f \u4f8b\u5982 touch \u8fd9\u4e9b\u547d\u4ee4\uff0c\u90fd\u662f\u57fa\u4e8e strerror \u6253\u5370\u62a5\u9519\u6d88\u606f\u7684\uff0c\u800c strerror \u53c8\u57fa\u4e8e\u533a\u57df\u8bbe\u7f6e\u7684 LC_MESSAGES \u65b9\u9762\u3002 \u8fd9\u4e9b\u547d\u4ee4\u884c\u7a0b\u5e8f\u7684\u4f5c\u8005\u65e0\u9700\u61c2\u5f97\u6240\u6709\u8bed\u8a00\uff0c\u4ed6\u4eec\u53ea\u9700\u8981\u8c03\u7528 strerror \u548c\u5404\u79cd messages \u67e5\u627e\u51fd\u6570\uff0c\u83b7\u5f97\u76f8\u5e94\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u540e\uff0c\u8f93\u51fa\u5373\u53ef\u81ea\u52a8\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7528\u6237\u7684\u9700\u6c42\u3002 \u53ea\u9700\u8981\u8bed\u8a00\u7684\u7528\u6237\uff0c\u5728\u4ed6\u7684\u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u8bbe\u7f6e LC_ALL=zh_CN.UTF-8 \u5c31\u53ef\u4ee5\u8ba9\u547d\u4ee4\u884c\u7a0b\u5e8f\u4eec\u59cb\u7ec8\u8f93\u51fa\u4e2d\u6587\u6d88\u606f\u4e86\u3002 $ export LC_MESSAGES=en_US.UTF-8 $ touch /root/a touch: cannot touch '/root/a': Permission denied $ export LC_MESSAGES=zh_CN.UTF-8 $ touch /root/a touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f \u4f8b\u5982 GCC \u7684\u62a5\u9519\u4fe1\u606f\uff0c\u5c31\u662f\u57fa\u4e8e\u4f60\u7684 $LC_MESSAGES \u73af\u5883\u53d8\u91cf\u6765\u51b3\u5b9a\u8f93\u51fa\u4f55\u79cd\u8bed\u8a00\u7684\u4fe1\u606f\u7684\u3002 \u4f60\u4e5f\u53ef\u4ee5\u53ea\u8bbe\u7f6e\u4e00\u4e2a export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u6837\u5c31\u65e0\u9700\u8bbe\u7f6e\u5176\u4ed6\u6240\u6709\u7684\u65b9\u9762 (facet)\uff0c\u5982\u65e0\u5355\u72ec\u8bbe\u7f6e\uff0c\u5176\u4ed6\u65b9\u9762\u4f1a\u81ea\u52a8\u53d8\u5f97\u548c $LC_ALL \u4e00\u6837\u3002 LC_CTYPE \uff1a\u5b57\u7b26\u7f16\u7801 \u8fd9\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\uff0c\u4ed6\u51b3\u5b9a\u4e86\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u683c\u5f0f\u3002 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u5185\u90e8\u90fd\u4ee5\u5185\u7801\uff08 const wchar_t * \u6216 std::wstring \uff09\u6765\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u5f53\u8f93\u51fa\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u7684\u5185\u7801\u5b57\u7b26\u4e32\uff08 wchar_t * \uff09\u4f1a\u4ee5 LC_CTYPE \u6307\u5b9a\u7684\u7f16\u7801\u683c\u5f0f\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6d41\uff08 const char * \u6216 std::string \uff09\u540e\u8f93\u51fa\u5230\u63a7\u5236\u53f0\u3002 \u56e0\u6b64\uff0c LC_CTYPE \u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\u662f\u65e0\u5173\u7d27\u8981\u7684\uff0c\u91cd\u8981\u7684\u662f\u540e\u534a\u6bb5\uff0c\u4f8b\u5982 \"zh_CN.UTF-8\" \uff0c\u90a3\u6709\u5f71\u54cd\u7684\u5c31\u53ea\u662f\u540e\u9762\u8fd9\u6bb5 \".UTF-8\" \u3002 \u52a1\u5fc5\u4f7f\u7528\u548c\u4f60\u7ec8\u7aef\u914d\u7f6e\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u4e71\u7801\u3002\u4f8b\u5982\u5f53\u6211\u6b3a\u9a97 touch \uff0c\u8ba9\u4ed6\u8bef\u4ee5\u4e3a\u6211\u7684\u7ec8\u7aef\u8f93\u51fa\u9700\u8981\u662f GBK \u7f16\u7801\uff1a $ export LC_MESSAGES=zh_CN.UTF-8 $ export LC_CTYPE=zh_CN.GBK # \u6b3a\u9a97 touch\uff01\u597d\u574f $ touch /root/a touch: \ufffd\u07b7\ufffd touch '/root/a': \u0228\ufffd\u07b2\ufffd\ufffd\ufffd \u4ed6\u5c31\u8f93\u51fa\u4e86\u8be1\u5f02\u7684\u4e71\u7801\u3002\u8fd9\u4e0d\u662f touch \u7684\u95ee\u9898\uff0ctouch \u53ea\u662f\u6309\u7167\u4f60\u73af\u5883\u53d8\u91cf $LC_CTYPE \u8bf4\u7684 GBK \u7f16\u7801\uff0c\u8f93\u51fa\u4e86 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u3002\u800c\u7ec8\u7aef\u7684\u8bbe\u7f6e\u5374\u662f UTF-8\uff0c\u7528 UTF-8 \u89e3\u7801 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u5f53\u7136\u51fa\u9519\u4e86\uff0c\u4e0d\u8fc7\u7531\u4e8e GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u8fd9\u91cc\u9762\u82f1\u6587\u90e8\u5206\u624d\u4fa5\u5e78\u6b63\u5e38\u663e\u793a\u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\u8981\u4e48\u4f60 $LC_CTYPE \u8bbe\u56de UTF-8\uff0c\u8981\u4e48\u628a\u7ec8\u7aef\u6539\u6210 GBK\uff0c\u603b\u4e4b $LC_CTYPE \u5fc5\u987b\u548c\u7ec8\u7aef\u5b57\u7b26\u7f16\u7801\u914d\u7f6e\u4e00\u6837\u3002\u4e5f\u53ef\u4ee5\u8c03\u7528 iconv \u628a touch \u7684 GBK \u8f93\u51fa\u8f6c\u6362\u56de UTF-8\uff0c\u4f9b UTF-8 \u7684\u7ec8\u7aef\u8bfb\u53d6\uff1a $ touch /root/a 2>&1 | iconv -f GBK -t UTF-8 touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f LC_TIME \uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 LC_TIME \u5f71\u54cd\u7684\u662f\u548c\u65f6\u95f4\u6709\u5173\u51fd\u6570\u7684\u8f93\u51fa\u683c\u5f0f\uff0c\u56e0\u4e3a\u4e0d\u540c\u7684\u5730\u533a\u6709\u4e0d\u540c\u7684\u65f6\u95f4\u663e\u793a\u4e60\u60ef\uff0c\u6bd4\u5982\u82f1\u6587\u662f Jan 1 00:00 \uff0c\u4e2d\u6587\u662f 1\u6708 1\u65e5 00\u65f600\u5206 \uff0c\u800c\u65e5\u672c\u4eba\u5219\u662f 1\u67081\u65e5 0\u66420\u5206 \u3002 $ export LC_TIME=en_US.UTF-8 $ date Fri Jul 19 04:01:49 PM CST 2024 $ export LC_TIME=zh_CN.UTF-8 $ date 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16:01:07 CST \u5728 C \u8bed\u8a00\u4e2d\uff0c\u4f60\u53ef\u4ee5\u7528\u8fd9\u6837\u683c\u5f0f\u5316\u65f6\u95f4\u548c\u65e5\u671f\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); struct tm *tm = localtime(&t); char buf[32]; strftime(buf, sizeof(buf), \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\", tm); puts(buf); } C++ \u63d0\u4f9b\u4e86\u57fa\u4e8e\u6d41\u7684\uff0c\u66f4\u201c\u65f6\u5c1a\u201d\u7684\u5199\u6cd5\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); tm *tm = localtime(&t); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 std::locale \u5bf9\u8c61 C \u8bed\u8a00\u7684 setlocale \u8bbe\u7f6e\u7684\u662f\u5168\u5c40 locale\uff0c\u5168\u5c40 locale \u53ea\u6709\u4e00\u4e2a\uff0c\u4e00\u8bbe\u5c31\u5f71\u54cd\u6240\u6709\u7ebf\u7a0b\uff0c\u975e\u5e38\u6c99\u96d5\u3002\u56e0\u6b64\u63d0\u5021\u201c\u4e0d\u8981\u72b6\u6001\u673a\u8981\u5bf9\u8c61\u201d\u7684 C++\uff0c\u5c01\u88c5\u4e86 std::locale \u5bf9\u8c61\u3002 std::locale \u7684\u6784\u9020\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u548c setlocale \u7684\u60c5\u51b5\u4e00\u6837\uff0c\u6709\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u73af\u5883 locale\uff0c \"C\" \u8868\u793a POSIX locale\uff0c\u8fd8\u6709\u81ea\u5b9a\u4e49\u5b57\u7b26\u4e32\u6bd4\u5982 \"zh_CN.UTF-8\" \u7684 locale\u3002 \u7136\u540e\uff0cC++ \u7684\u6d41\u7c7b\u578b\uff0c\u5982 std::cout \uff0c\u90fd\u6709\u4e00\u4e2a .imbue \u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u5c40\u90e8 locale\uff08\u53ea\u5bf9 std::cout \u751f\u6548\u7684\uff09\uff0c\u63a5\u53d7\u7684\u5c31\u662f\u8fd9\u4e2a std::locale \u5bf9\u8c61\u3002 #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 2024\u5e74 07\u6708 19\u65e5 Fri 16\u65f6 01\u5206 \u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\u53ea\u6709\u661f\u671f\u7684\u5b57\u7b26\u4e32\u53d7\u5230\u4e86\u5f71\u54cd\u3002\u5982\u679c\u8981\u4f7f\u6574\u4e2a\u65e5\u671f\u683c\u5f0f\u90fd\u8ddf\u968f LC_TIME \u7684\u8bbe\u5b9a\uff0c\u53ef\u7528 \"%c\" \uff1a #include #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%c\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%c\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e7407\u670819\u65e5 \u661f\u671f\u4e94 16\u65f633\u520639\u79d2 Fri 19 Jul 2024 04:33:39 PM CST \u5173\u4e8e \"%c\" \u3001 \"%Y\" \u8fd9\u4e9b\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u7684\u66f4\u591a\u8be6\u7ec6\u7528\u6cd5\uff0c\u53c2\u89c1 man strftime \u3002\u6211\u4eec\u4f5c\u4e3a\u5b57\u7b26\u7f16\u7801\u7684\u8bfe\u7a0b\u4e0d\u518d\u8d58\u8ff0\uff0c\u4e4b\u540e\u7684\u65f6\u95f4\u4e0e\u65e5\u671f\u4e13\u9898\u8bfe\u4e5f\u4f1a\u7a0d\u5fae\u8bb2\u4e00\u4e0b\u3002 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale boost::locale::generator gen; auto loc = gen(\"zh_CN.UTF-8\"); boost::locale::date_time dt = boost::locale::date_time::now(loc); std::cout << boost::locale::as::date(dt) << '\\n'; \u5bbd\u5b57\u7b26\u6d41 \u4e4b\u6240\u4ee5\u628a\u5bbd\u5b57\u7b26\u6d41\u653e\u5230\u6700\u540e\uff0c\u662f\u56e0\u4e3a\uff0c\u9996\u5148 iostream \u672c\u6765\u5c31\u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728\u672c\u4e66\u5f00\u5934\u5c31\u591a\u6b21\u5f3a\u8c03\u8fc7\u4ed6\u662f format \u5b5d\u5b50\u3002 \u800c\u5bbd\u5b57\u7b26 wchar_t \u672c\u8eab\u5c31\u5145\u65a5\u7740\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff08\u4f8b\u5982 Windows \u88ab UTF-16 \u80cc\u523a\uff09\u3002 \u73b0\u5728 iostream \u4e0e wchar_t \u4e00\u8d77\u51fa\u73b0\u5728\u6211\u9762\u524d\uff0c\u4e0d\u80fd\u8bf4\u662f\u68a6\u5e7b\u8054\u52a8\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u7b54\u8fa9\u8d85\u4eba\u4e86\u3002 \u603b\u4e4b\uff0c\u6211\u4e2a\u4eba\u8fd8\u662f\u63a8\u8350\u7a0b\u5e8f\u5185\u90e8\u4ee5 UTF-8\uff08 char8_t \uff09\u6216 UTF-32\uff08 char32_t \uff09\u7684\u5b57\u7b26\u4e32\u6765\u5904\u7406\u4e07\u7269\u3002 UTF-8 \u6216 UTF-32 \u7684\u9009\u62e9\u53d6\u51b3\u4e8e\u4f60\u7684\u4e2d\u6587\u5904\u7406\u9700\u6c42\u662f\u5426\u65fa\u76db\uff0c\u662f\u5426\u5728\u4e4e\u7a7a\u95f4\uff0c\u662f\u5426\u9700\u8981\u5207\u7247\u548c\u7d22\u5f15\u7b49\u3002 \u5f53\u9700\u8981\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u8bfb\u5199\u6587\u4ef6\u65f6\uff0c\u518d\u7528 boost::locale \u3001 utfcpp \u7b49\u5de5\u5177\u8f6c\u6362\u6210 ANSI\uff08 char \uff09\u6216 UTF-16\uff08 wchar_t \uff09\u3002 \u5bf9\u4e8e Linux \u7528\u6237\uff0c\u4e5f\u53ef\u4ee5\u68c0\u6d4b\u5982\u679c\u662f Linux \u7cfb\u7edf\uff0c\u5219\u4ec0\u4e48\u8f6c\u6362\u90fd\u4e0d\u505a\uff0c\u56e0\u4e3a Linux \u7528\u6237\u51e0\u4e4e\u90fd\u662f UTF-8\uff0c\u90a3\u4e48 const char8_t * \u53ef\u4ee5\u5f3a\u8f6c\u4e3a const char * \u800c\u4e0d\u7528\u4efb\u4f55\u989d\u5916\u5f00\u9500\u3002 std::string to_os_string(std::string const &u8s) { #if _WIN32 // UTF-8 \u5230 ANSI return boost::locale::conv::from_utf(u8s, \"\"); #elif __linux__ // \u4e0d\u8f6c\u6362 return u8s; #else #error \"Unsupported system.\" #endif } \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u5b9e\u5728\u8981\u5b66\u7cdf\u7cd5\u7684\u5bbd\u5b57\u7b26\u6d41\uff0c\u90a3\u6211\u4e5f\u5949\u966a\u5230\u5e95\u3002 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring \u5728\u4ed6\u4eec\u770b\u6765\uff0c std::string \u662f\u5df2\u7ecf\u5e9f\u5f03\u7684\u3002\u4ed6\u4eec\u8ba4\u4e3a std::wstring \u624d\u662f\u771f\u6b63\u8de8\u5e73\u53f0\u7684\u5b57\u7b26\u4e32\u3002 std::wstring : \u5b57\u7b26\u4e32 std::string : \u5b57\u8282\u6570\u7ec4 std::wifstream : \u6587\u672c\u6d41 std::ifstream : \u4e8c\u8fdb\u5236\u6d41 \u770b\u8d77\u6765\u53ea\u8981\u5168\u90e8\u7edf\u4e00 wchar_t \u5c31\u80fd\u5b9e\u73b0\u8de8\u5e73\u53f0\u4e86\uff1f\u662f\u7684\uff0c\u9664\u4e86 Windows\u2026\u2026 \u6807\u51c6\u8ba4\u4e3a wchar_t \u5e94\u8be5\u5305\u542b 0 \u5230 0x10FFFF \u7684\u6240\u6709\u7684 Unicode \u5b57\u7b26\u7801\u70b9\uff0c\u9700\u8981\u662f 32 \u4f4d\u7684\u3002\u7136\u800c Windows \u7684 wchar_t \u7531\u4e8e\u5386\u53f2\u539f\u56e0\uff0c\u662f 16 \u4f4d\u7684\uff0c\u9700\u8981\u7528\u4ee3\u7406\u5bf9\u624d\u80fd\u8868\u793a\u7a00\u6709\u5b57\u7b26\uff0c\u5e76\u4e0d\u80fd\u4e00\u4e2a wchar_t \u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002\u8fd9\u5bfc\u81f4\u5373\u4f7f\u7528\u4e86 wchar_t \u8fd8\u662f\u5b58\u5728\u8de8\u5e73\u53f0\u56f0\u96be\u7684\u95ee\u9898\uff1a\u4e00\u4e2a Linux \u7a0b\u5e8f\u7528 wchar_t \u53ef\u80fd\u4f1a\u5229\u7528 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u7279\u6027\uff0c\u65b9\u4fbf\u4e86\u6587\u672c\u5904\u7406\uff0c\u4f46\u79fb\u690d\u5230 Windows \u65f6\uff0c\u53d1\u73b0\u53d8\u6210\u4e86 UTF-16\uff0c\u9700\u8981\u5bf9\u4ee3\u7406\u5bf9\u505a\u7279\u6b8a\u5224\u65ad\u2026\u2026\u6ca1\u6709\u6ee1\u8db3\u8de8\u5e73\u53f0\u7684\u521d\u8877\uff0c\u4e5f\u505a\u4e0d\u5230\u5b9a\u957f\u7f16\u7801\u3002 char32_t \u505a\u5230\u4e86\u8de8\u5e73\u53f0\u7684 UTF-32\uff0c\u4e5f\u80fd\u5bb9\u7eb3\u5168\u90e8 Unicode \u7801\u70b9\uff0c\u53ef\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::to_wstring \uff0c\u5374\u6839\u672c\u6ca1\u6709 std::to_u32string \uff1b\u63d0\u4f9b\u4e86 std::wcout \uff0c\u5374\u6ca1\u6709\u63d0\u4f9b std::u32cout \u2026\u2026 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u5bbd\u5b57\u7b26\u6d41\u5f88\u7cdf\u7cd5\uff0c\u8bf4\u662f\u8de8\u5e73\u53f0\uff0c\u8de8\u4e86\u4e2a\u5bc2\u5bde\u3002 std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 \u8981\u4f7f\u7528 std::wcout \u4e4b\u524d\uff0c\u9700\u8981\u7528 .imbue \u8bbe\u7f6e\u5e26\u6709\u6b63\u786e LC_CTYPE \u65b9\u9762\u7684 locale\uff0c\u6216\u8005\u8bbe\u7f6e\u4e86 C \u8bed\u8a00\u7684\u5168\u5c40\u7684 setlocale \uff0c\u5426\u5219\u4e2d\u6587\u5b57\u7b26\u4f1a\u88ab\u4e22\u6389\u3002 int main() { std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u9519\u8bef\uff01\u4f60\u8fd8\u6ca1\u8bbe\u7f6e locale \u5462\uff01 return 0; } \u8f93\u51fa\uff1a Hello, ??! \u8fd9\u662f\u56e0\u4e3a\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \uff0c\u4ed6\u53ea\u652f\u6301 ASCII \u7684\u3002\u800c\u5f53 std::wcout \u9047\u5230\u8d85\u51fa\u5f53\u524d locale \u5b57\u7b26\u96c6\u8868\u793a\u8303\u56f4\u7684\u5b57\u7b26\u65f6\uff0c\u4f1a\u4e22\u5f03\uff0c\u66ff\u6362\u4e3a ? \u5b57\u7b26\uff0c\u8868\u793a\u51fa\u9519\u4e86\u3002 \u56e0\u6b64\uff0c std::wcout \u7684\u6b63\u786e\u7528\u6cd5\u5fc5\u987b\u662f\u5728\u4f60\u6253\u5370\u7b2c\u4e00\u6761\u8f93\u51fa\u524d\uff0c\u5c31 setlocale(LC_ALL, \"\") \uff0c\u9ed8\u8ba4\u7684 \"C\" \u80af\u5b9a\u662f\u4e0d\u884c\u7684\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u8f93\u51fa\uff1a Hello, \u4f60\u597d! \u6216\u8005\u7528 std::wcout \u7684 .imbue \u4e5f\u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u6837\u5bf9\u4e8e std::wcerr \u548c std::wclog \u4f60\u4e5f\u9700\u8981\u505a\u540c\u6837\u7684\u52a8\u4f5c\uff0c\u611f\u89c9\u4e0d\u5982\u7d22\u6027\u5168\u5c40\u8bbe\u7f6e\u4e86 setlocale \u65b9\u4fbf\u3002 int main() { std::wcout.imbue(std::locale(\"\")); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u5982\u679c\u4f60\u662f UTF-8 \u6d41\u6d3e\uff0c\u9009\u62e9 setlocale(LC_ALL, \".utf-8\") \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u53ea\u8981\u662f\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u7684 locale \u5c31\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6b63\u5e38\u8f93\u51fa\u4e2d\u6587\uff0c\u53ea\u8981\u4f60\u7ec8\u7aef\u7684\u8bbe\u7f6e\u4e5f\u662f\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\u7edd\u5bf9\u4e0d\u4f1a\u4e71\u7801\u3002 \u4f8b\u5982\u5f53\u4f60 setlocale(LC_ALL, \".utf-8\") \u540e\u5c31\u9700\u8981 system(\"chcp 65001\") \uff1b\u5f53\u4f60 setlocale(LC_ALL, \"Chinese_China.936\") \u540e\u5c31\u9700\u8981 system(\"chcp 936\") \u3002\u603b\u4e4b\uff0c\u59cb\u7ec8\u4fdd\u8bc1\u7ec8\u7aef\uff08 cmd \u6216 xfce4-terminal \uff09\u8bbe\u7f6e\u7684\u7f16\u7801\u548c\u4f60\u7a0b\u5e8f\u91cc setlocale(LC_CTYPE, ...) \u8bbe\u7f6e\u7684\u7f16\u7801\u4e00\u81f4\u3002 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u6709\u7684\u4eba\u4f1a\u7528 std::wcout \u4f3c\u4e4e\u4e5f\u80fd\u6253\u5370 char \u7684\u5b57\u7b26\u4e32\uff1f int main() { setlocale(LC_ALL, \"\"); std::wcout << \"Hello, \u4f60\u597d!\\n\"; // \u4e0d\u4e00\u5b9a\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587\uff01 std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // OK\uff0c\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587 return 0; } \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u7528\u6cd5\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u5e94\u8be5\u8981\u62a5\u9519\uff0c\u4f46\u662f\u7cdf\u7cd5\u7684\u6807\u51c6\u5e93\u5374\u6ca1\u6709\uff0c\u8bbe\u8ba1\u7684\u5931\u8bef\u3002 \u8bbe\u8ba1\u7684\u521d\u8877\u662f\uff0c\u53ef\u4ee5\u5728\u6253\u5370\u5e26\u4e2d\u6587\u7684\u5b57\u7b26\u4e32\u540e\uff0c\u65b9\u4fbf\u4f60\u4e34\u65f6\u6253\u5370\u4e00\u4e9b char \u7684\u5b57\u7b26\u4e32\u548c\u5b57\u7b26\uff0c\u4f8b\u5982 '\\n' \uff08\u56e0\u4e3a\u603b\u662f\u6709\u7684\u4eba\u60f3\u5077\u61d2\u4e0d\u5199 L\"\" \u524d\u7f00\uff09 std::wcout \u652f\u6301\u6253\u5370 char \u548c const char * \uff0c\u4ed6\u4f1a\u81ea\u52a8\u5e2e\u4f60\u628a\u8fd9\u90e8\u5206 char \u8f6c\u6210 wchar_t \u518d\u6253\u5370\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\" << L'\\n'; // \u6b63\u5e38\u5199\u6cd5 std::wcout << L\"Hello, \u4f60\u597d!\" << '\\n'; // \u61d2\u60f0\u72d7\u72d7\u5199\u6cd5 return 0; } \u4f46\u662f\uff0c\u8fd9\u90e8\u5206 char \u5e94\u5f53\u53ea\u5305\u542b ASCII \u5b57\u7b26\uff0c\u4e0d\u5e94\u8be5\u6709\u4e2d\u6587\u5b57\u7b26\uff0c\u5426\u5219\u53ef\u80fd\u53c8\u8981\u51fa\u73b0\u4e4b\u524d\u63d0\u5230\u7684 \u201cgalgame\u201d \u4e71\u7801\u95ee\u9898\u4e86\u3002 \u8d85\u7ea7\u5751\u70b9\uff1a std::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 \u975e\u5e38\u5751\u7684\u4e00\u4e2a\u70b9\uff1a\u4e00\u65e6\u4f60\u51b3\u5b9a\u7528 std::wcout \u540e\uff0c\u5c31\u4e0d\u80fd\u518d\u7528 std::cout \u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u5b9e\u6d4b\u7528\u8fc7 std::wcout \u540e\uff0c\u4f60\u7684 std::cout \u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4e0d\u51fa\u4efb\u4f55\u4e1c\u897f\u3002 \u4e0a\u4e86\u8d3c\u8239\u5c31\u4e0a\u5230\u5e95\u5427\uff01\u5982\u679c\u786e\u5b9e\u9700\u8981\u4e34\u65f6\u6253\u5370\u4e00\u4e9b std::string \uff0c\u5e76\u4e14\u786e\u4fdd\u91cc\u9762\u662f ASCII \u7684\u8bdd\uff0c\u53ef\u4ee5\u5229\u7528\u4e0a\u9762\u4e00\u8282\u8bf4\u7684\u201c\u61d2\u60f0\u72d7\u72d7\u5199\u6cd5\u201d\u7cca\u5f04\u4e0b\uff0c\u5982\u679c\u662f GBK \u6216 UTF-8 \u7684 std::string \u9700\u8981\u6253\u5370\u5230 std::wcout \uff0c\u5c31\u53ec\u5524\u4e00\u4e0b boost::locale \u5427\u3002 std::wprintf \u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5f53\u4f60\u7b2c\u4e00\u6b21\u4f7f\u7528 FILE * \u7684 wchar_t \u7cfb\u5217\u51fd\u6570\u540e\uff0c\u8fd9\u4e2a\u6587\u4ef6\u6d41\u4f1a\u88ab\u201c\u5bbd\u5316\u201d ( fwiden )\uff0c\u7528\u6211\u4eec\u7684\u8bdd\u8bf4\u53eb \u4e0a\u8d3c\u8239 \uff0c\u4e0a\u4e86\u5c31\u4e0b\u4e0d\u6765\uff0c\u518d\u4e5f\u65e0\u6cd5\u5f53\u4f5c\u201c\u7a84\u201d\u6d41\u7528\u4e86\u3002 \u53cd\u4e4b\u4ea6\u7136\uff0c\u4e00\u65e6\u4f60\u7528\u8fc7\u4e00\u6b21 std::cout \u540e\uff0c std::wcout \u5c31\u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4efb\u4f55\u4e1c\u897f\u90fd\u6253\u5370\u4e0d\u51fa\u6765\u3002\u53d6\u51b3\u4e8e\u4f60\u7b2c\u4e00\u6b21\u8c03\u7528\u8f93\u51fa\u6d41\u7528\u7684\u662f\u5bbd\u5b57\u7b26\u8fd8\u662f\u7a84\u5b57\u7b26\uff0c\u4e4b\u540e\u5c31\u53ea\u80fd\u4e00\u76f4\u7528\u90a3\u4e2a\u5bbd\u6216\u7a84\u4e86\uff0c\u4e0d\u8ba9\u8df3\u8239\u3002 \u4e0a\u8d3c\u8239\u4e0d\u884c\uff0c\u4e0a\u8b66\u8239\u4e5f\u4e0d\u884c\uff0c\u4e0a\u5b9a\u4e00\u4e2a\u5c31\u6ca1\u6cd5\u53d8\uff0c\u771f\u6076\u5fc3\u5440\uff01 // \u5148 wcout int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; std::cout << \"\u6211\u662f cout!\" << '\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f wcout! // \u5148 cout int main() { setlocale(LC_ALL, \"\"); std::cout << \"\u6211\u662f cout!\" << '\\n'; std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f cout! / wcout! \u8fd9\u91cc / wcout! \u597d\u50cf\u662f\u51fa BUG \u4e86\u2026\u2026\u4f30\u8ba1\u662f\u8d3c\u88ab\u8b66\u5bdf\u6253\u6389\u4e00\u534a\u8033\u6735\u53d8\u6210 / \u4e86\uff1f\u603b\u4e4b\u5404\u79cd\u6df7\u4e71\uff0c\u8bb0\u4f4f\u4e0d\u8981\u6df7\u7528\u8d3c\u8239\u548c\u8b66\u8239\u5c31\u884c\u4e86\u3002 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 \u6709\u540c\u5b66\u53cd\u6620\uff0cPython \u4e2d\u53ef\u4ee5\u901a\u8fc7 open('path.txt', encoding='gbk') \u6765\u7528\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u800c C++ \u4f3c\u4e4e\u6ca1\u6709\u7b49\u6548\u7684\u66ff\u4ee3\u54c1\u3002 \u5176\u5b9e\u4e00\u76f4\u90fd\u6709\uff0c\u4e0d\u8fc7\u4f60\u4e00\u76f4\u7528\u7684\u662f std::ifstream \u5b9e\u9645\u4e0a\u662f\u4e2a\u201c\u4e8c\u8fdb\u5236\u6d41\u201d\uff01\u8fd9\u79cd\u7eaf\u4e8c\u8fdb\u5236\u7684\u6d41\u6839\u672c\u5c31\u6ca1\u6253\u7b97\u652f\u6301\u5b57\u7b26\u7f16\u7801\u3002\u5373\u4f7f\u6307\u5b9a .imbue \u4e5f\u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u56e0\u4e3a .imbue \u7684\u524d\u63d0\u662f\u5b58\u5728\u201c\u5916\u7801 ( char ) \u5230\u5185\u7801 ( wchar_t ) \u7684\u8f6c\u6362\u201d\uff0c\u4f60\u4e8c\u8fdb\u5236\u6d41\u81f3\u59cb\u81f3\u7ec8\u90fd\u662f\u5916\u7801\uff0c\u54ea\u6765\u7684\u8f6c\u6362\uff1f\u53c8\u6ca1\u6709\u89c4\u5b9a char \u5fc5\u987b\u662f UTF-8\u3002 C++ \u771f\u6b63\u7684\u6587\u672c\u6d41\u5b9e\u9645\u4e0a\u662f\u5bbd\u5b57\u7b26\u6d41 std::wifstream \uff0c\u800c\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u7528 .imbue(std::locale(\"zh_CN.GBK\")) \u2026\u2026\u8bfb\u53d6\u65f6\u4f1a\u8c03\u7528 std::locale \u7c7b\u7684 std::codecvt \uff08\u662f LC_CTYPE \u7684\u4e00\u90e8\u5206\uff09\u65b9\u9762\uff0c\u8f6c\u6362\u4e3a wchar_t \uff0c\u7136\u540e\u8f93\u5165\u4f60\u7684 std::wstring \u3002 C \u548c C++ \u59d4\u5458\u4f1a\u5b98\u65b9\u5c31\u8ba4\u4e3a char * \u662f\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c wchar_t * \u624d\u662f\u6587\u672c\u6d41\uff01\u6240\u6709 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u91cc\u90fd\u662f\u7528 wchar_t \u6765\u5904\u7406\u6587\u672c\u6027\u8d28\u7684\u5b57\u7b26\u4e32\uff0c\u5305\u62ec GCC \u4e5f\u662f\u5927\u91cf\u4f7f\u7528 wchar_t \u4f5c\u4e3a\u5b57\u7b26\u5185\u90e8\u8868\u793a\u3002GCC \u8bfb\u53d6\u6e90\u7801\u6587\u4ef6\u5c31\u662f\u7528\u5bbd\u5b57\u7b26\u6d41\u8bfb\u53d6\u548c\u89e3\u7801\u5230\u5185\u5b58\u4e2d\u7684 UTF-32 \u5b57\u7b26\u4e32 std::wstring \u7684\u3002 \u7406\u8bba\u4e0a\u6240\u6709\u7684\u7a0b\u5e8f\u90fd\u5e94\u8be5\u50cf\u8fd9\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u52b3\u4fdd\u6559\u6750\u4ece\u6765\u4e0d\u63d0\uff0c\u4e00\u53e3\u4e00\u4e2a char [] \u5c31\u662f\u5b57\u7b26\u4e32\uff0c\u641e\u5f97 wchar_t \u5728\u9664\u4e86 GNU \u8fd9\u79cd\u201c\u4f53\u5236\u5185\u201d\u73af\u5883\u4e4b\u5916\uff0c\u6839\u672c\u6ca1\u4eba\u7528\u4e86\u3002\u73b0\u5728\u4e3a\u4e86\u5904\u7406\u4e2d\u6587\u5b57\u7b26\uff0c\u624d\u95f9\u51fa\u4e86 char \u5f53 UTF-8 \u4f7f\u8fd9\u79cd\u62db\u6570\uff0c\u4ee4\u4eba\u550f\u5618\u3002 \u603b\u4e4b\uff0c .imbue(std::locale(\"zh_CN.GBK\")) \u53ef\u4ee5\u628a GBK \u8bbe\u4e3a\u5f53\u524d\u6587\u672c\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5bbd\u6587\u4ef6\u6d41\u5c06\u4f1a\u6309\u7167\u8fd9\u4e2a\u7f16\u7801\u548c\u89e3\u7801\u6240\u6709\u7684\u5b57\u7b26\u4e32\u3002 std::locale \u7684\u5b57\u7b26\u4e32\u6784\u9020\u51fd\u6570\uff0c\u4ed6\u7684\u53c2\u6570\u5fc5\u987b\u662f\u7528\u6237\u7cfb\u7edf\u91cc\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684 locale\uff08\u901a\u8fc7\u4fee\u6539 /etc/locale.gen \u548c locale-gen \u547d\u4ee4\u5b89\u88c5\uff09\u3002\u4f46\u662f\uff0c\u4f60\u65e0\u6cd5\u786e\u4fdd\u7528\u6237\u7684\u7cfb\u7edf\u5b89\u88c5\u4e86 \"GBK\" locale\u3002 std::locale(\"zh_CN.GBK\") \u5728\u6ca1\u6709\u5b89\u88c5 GBK \u7684\u7528\u6237\u7535\u8111\u4e0a\u8fd0\u884c\u5c31\u4f1a\u629b\u51fa\u9519\u8bef\u8868\u793a\u627e\u4e0d\u5230\u8be5 locale\u3002\u56e0\u6b64\uff0c\u5982\u679c\u8981\u6307\u5b9a\u6309 GBK \u8bfb\u53d6\u6587\u4ef6\uff0c\u4e0d\u5efa\u8bae\u4f9d\u8d56\u7cfb\u7edf\u4e2d\u81ea\u5e26\u7684 std::locale(\"zh_CN.GBK\")) \uff0c\u800c\u662f\u8c03\u7528 boost::locale::generator \u5c31\u5730\u751f\u6210\u4e00\u4e2a locale\uff0c\u8fd9\u6837\u7a0b\u5e8f\u65e0\u8bba\u7cfb\u7edf\u6709\u6ca1\u6709\u5b89\u88c5\u90fd\u80fd\u8fd0\u884c\u4e86\uff1a #include #include int main() { std::wofstream fout; boost::locale::generator gen; std::locale loc = gen(\"zh_CN.GBK\"); fout.imbue(loc); fout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4ee5 GBK \u7f16\u7801\u5199\u51fa\u6587\u672c\u6587\u4ef6 } $ cat build/\u4f60\u597d.txt \ufffd\ufffd\u00e3\ufffd\ufffd\ufffd $ cat build/\u4f60\u597d.txt | iconv -f GBK -t UTF-8 \u4f60\u597d\uff0c\u4e16\u754c $ \u8fd9\u662f\u56e0\u4e3a boost_locale \u94fe\u63a5\u4e86 icu \uff0c\u5176\u5185\u90e8\u5305\u542b\u4e86\u6240\u6709\u7f16\u7801\u683c\u5f0f\u7684\u5b57\u7b26\u6620\u5c04\u8868\u3002 boost::locale::generator \u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a std::locale \uff0c\u7136\u540e\u901a\u8fc7\u865a\u51fd\u6570\u91cd\u8f7d\u7684\u65b9\u5f0f\u628a std::locale \u5bf9\u8c61\u4e2d\u7684 std::codecvt \u66ff\u6362\u6210 icu \u7684\u6620\u5c04\u8868\u3002\u4ece\u800c\u8ba9 std::wofstream \u8c03\u7528\u8fd9\u4e2a icu \u7684\u6620\u5c04\u51fd\u6570\uff0c\u5b9e\u73b0\u4e86 UTF-32 \u5230 GBK \u7684\u8f6c\u6362\u3002 \u6b64\u5916\uff0c\u4f60\u8fd8\u53ef\u4ee5\u9009\u62e9\u8986\u76d6 locale \u7684\u90e8\u5206\u65b9\u9762 (facet)\uff0c\u6bd4\u5982\u5728\u6587\u4ef6\u7f16\u7801\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u8981\u7528 \"zh_CN.GBK\" \u7684 LC_CTYPE \u65b9\u9762\u5c31\u53ef\u4ee5\u4e86\uff0c\u5176\u4ed6\u7684\u4f8b\u5982\u65f6\u95f4\u683c\u5f0f\u3001\u8bed\u8a00\u4fe1\u606f\u7b49\uff0c\u6211\u4eec\u8fd8\u662f\u60f3\u4fdd\u7559\u9ed8\u8ba4\u7684\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528 locale \u7684\u201c\u6742\u4ea4\u201d\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u4fdd\u7559\u8001 locale \u7684\u7edd\u5927\u90e8\u5206\u65b9\u9762\uff0c\u53ea\u66ff\u6362\u4e00\u4e2a\u65b9\u9762\u4e3a\u65b0 locale \u7684\uff1a std::locale old_loc = std::locale(\"\"); // \u73af\u5883 locale boost::locale::generator gen; std::locale new_loc = gen(\"zh_CN.GBK\"); // \u5168 GBK locale std::locale loc = std::locale(old_loc, new_loc, std::locale::ctype); // \u6742\u4ea4\uff1a\u7ee7\u627f old_loc \u7684\u5176\u4f59\u5168\u90e8\uff0c\u53ea\u66ff\u6362\u6389 LC_CTYPE \u90e8\u5206\u4e3a new_loc \u7684 fout.imbue(loc); locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5185\u7801\u7f16\u7801\u6210\u5916\u7801 std::string narrow(std::locale const &loc, std::wstring const &wstr) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::string str(wstr.size() * 4, '\\0'); // \u9884\u7559 4 \u500d\u7a7a\u95f4 wchar_t const *from_next; char *to_next; std::mbstate_t state{}; auto res = cvt.in(state, wstr.data(), wstr.data() + wstr.size(), from_next, str.data(), str.data() + str.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f str.resize(to_next - str.data()); return str; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f str.resize(to_next - str.data()); return str; } else { // \u8f6c\u6362\u5931\u8d25 return \"\"; } } // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5916\u7801\u89e3\u7801\u6210\u5185\u7801 std::wstring widen(std::locale const &loc, std::string const &str) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::wstring wstr(str.size(), L'\\0'); // \u9884\u7559\u7a7a\u95f4 char const *from_next; wchar_t *to_next; std::mbstate_t state{}; auto res = cvt.out(state, str.data(), str.data() + str.size(), from_next, wstr.data(), wstr.data() + wstr.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else { // \u8f6c\u6362\u5931\u8d25 return L\"\"; } } std::wstring wstr = L\"\u4f60\u597d\"; std::cout << narrow(std::locale(\"zh_CN.GBK\"), wstr); \u4e0d\u8fc7\uff0c\u6211\u4eec\u90fd\u6709\u66f4\u65b9\u4fbf\u7684 boost::locale::conv \u4e86\uff0c\u8fd8\u4f55\u5fc5\u8fd8\u7528\u8fd9\u4e48\u7e41\u7410\u7684 std::locale \u5462\uff1f\u6240\u4ee5\u6211\u662f\u4e0d\u63a8\u8350\u518d\u7528\u8fd9\u7834\u73a9\u610f\uff0c\u65e0\u8bba\u662f\u6613\u7528\u6027\u8fd8\u662f\u6269\u5c55\u6027\u90fd\u662f Boost \u5b8c\u80dc\u3002 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 \u5bf9\u4e8e\u6240\u6709\u7684 strcpy \u3001 strcmp \u3001 strlen \u8fd9\u7c7b str*** \u7cfb\u51fd\u6570\uff0c\u90fd\u6709\u4e00\u4e2a\u76f8\u5e94\u7684 wcs*** \u51fd\u6570\u3002 \u4f8b\u5982 wcscpy \u3001 wcscmp \u3001 wcslen \u3002 \u5b83\u4eec\u7684\u539f\u578b\u5982\u4e0b\uff1a wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); int wcscmp(const wchar_t *s1, const wchar_t *s2); size_t wcslen(const wchar_t *s); \u5b83\u4eec\u7684\u4f5c\u7528\u548c str*** \u7cfb\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u662f\u5b83\u4eec\u64cd\u4f5c\u7684\u662f wchar_t \u5b57\u7b26\u4e32\u3002 \u5bf9\u4e8e\u6240\u6709\u7684 fputc \u3001 printf \uff0c fprintf \uff0c fgets \u8fd9\u7c7b\u64cd\u4f5c\u6587\u4ef6\u7684\u51fd\u6570\uff0c\u4e5f\u90fd\u6709\u4e00\u4e2a\u914d\u5957\u7684 fw*** \u51fd\u6570\u3002 \u7b2c\u4e00\u6b21\u4f7f\u7528\u8fc7\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c FILE * \u5c06\u4f1a\u88ab\u201c\u5bbd\u5316\u201d\uff08 fwiden \uff09\u3002\u5bbd\u5316\u7684\u6587\u4ef6\u6d41\u4eca\u540e\u5c06\u53ea\u80fd\u8f93\u5165\u5bbd\u5b57\u7b26\u4e32\u3002 \u4f46\u662f\uff0c\u65e2\u7136 C++ \u5df2\u7ecf\u6709 std::wstring \uff0c\u5c31\u4e0d\u5efa\u8bae\u518d\u5b66 C \u8bed\u8a00 L'\\0' \u7ed3\u5c3e\u5b57\u7b26\u4e32\u4e86\u3002 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 TODO C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 wchar_t \u3001 char16_t \u3001 char32_t \u4e0e char \u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 std::mbrtoc16 \u3001 std::mbrtoc32 \u3001 std::c16rtomb \u3001 std::c32rtomb \u51fd\u6570\u3002 \u7136\u800c\uff0c\u53c8\u81ed\u53c8\u957f\uff0c\u7528\u5c01\u88c5\u597d\u7684 boost::locale::utf_to_utf/from_utf/to_utf/between \u4e0d\u9999\u5417\uff1f Windows \u4e13\u9898 \u9047\u5230\u5b57\u7b26\u7f16\u7801\u96be\u9898\u7684\uff0c\u4e3b\u8981\u662f Windows \u7a0b\u5e8f\u5458\u3002 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 \u4ece Windows NT \u7248\u672c\u5f00\u59cb\uff0c\u5bf9\u4e8e\u6240\u6709\u6d89\u53ca\u5b57\u7b26\u4e32\u7684\uff0c\u5176\u64cd\u4f5c\u7cfb\u7edf API \u63d0\u4f9b\u4e86\u4e24\u5957\u51fd\u6570\u3002 \u4e00\u5957\u662f A \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 A \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileA \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 ANSI\uff08\u5373 GBK\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u53e6\u4e00\u5957\u662f W \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 W \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileW \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 Unicode\uff08\u5373 UTF-16\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u5176\u4e2d CreateFileW \u624d\u662f Windows \u7cfb\u7edf\u771f\u6b63\u7684 API\u3002 \u800c CreateFileA \u662f\u4e3a\u4e86\u517c\u5bb9\u57fa\u4e8e ANSI \u7684\u8001\u7a0b\u5e8f. \u7531\u4e8e ANSI \u5728\u4e0d\u540c\u5730\u533a\u4f1a\u53d8\u5f97\u4e0d\u540c\uff0c\u4f7f\u7528\u8fd9\u7c7b\u51fd\u6570\u5199\u51fa\u7684\u7a0b\u5e8f\u4e0d\u5177\u6709\u56fd\u9645\u901a\u7528\u6027\u3002 \u5176\u5185\u90e8\u7684\u5b9e\u73b0\u53ea\u662f\u7b80\u7b80\u5355\u5355\u5730\u7ed9 const char * \u505a\u4e2a\u8f6c\u6362\uff0c\u4ece GBK \u8f6c\u5230 UTF-16\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528 CreateFileW\u3002 HANDLE CreateFileA(const char *lpFileName) { return CreateFileW(gbk_to_utf16(lpFileName)); } TCHAR \u6d41\u6d3e \u9664\u4e86\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5b8f\uff0c\u8fd9\u4e2a\u5b8f\u6ca1\u6709\u4efb\u4f55\u540e\u7f00\uff0c\u4f8b\u5982 CreateFile \u3002 \u5176\u5b9a\u4e49\u5982\u4e0b\uff1a #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif \u8fd9\u6837\u505a\u7684\u521d\u8877\u662f\uff0c\u7a0b\u5e8f\u5458\u53ea\u53ef\u4ee5\u5199\u51fa\u4e00\u5957\u9488\u5bf9 MessageBox \u7684\u4ee3\u7801\u3002 \u5f53\u8001\u677f\u60f3\u8981\u57fa\u4e8e Unicode \u65f6\uff0c\u4ed6\u5c31 #define UNICODE \uff0c\u8fd9\u6837 MessageBox \u5c31\u53d8\u6210\u4e86 MessageBoxW \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u5c31\u4f1a\u81ea\u52a8\u53d8\u6210 Unicode \u7684\uff0c\u56fd\u9645\u901a\u7528\u3002 \u5f53\u52b3\u4fdd\u8001\u677f\u60f3\u8981\u57fa\u4e8e ANSI \u65f6\uff0c\u4ed6\u5c31\u4e0d\u5b9a\u4e49 UNICODE \u5b8f\uff0c\u8fd9\u6837\u6240\u6709\u7684 MessageBox \u53c8\u53d8\u56de\u4e86 MessageBoxA \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u53c8\u53d8\u6210 ANSI \u7684\u4e86\u3002 \u6240\u6709\u6709 A/W \u533a\u5206\u7684\u7684 Windows API \u90fd\u6709\u8fd9\u6837\u4e00\u4e2a\u5b8f\uff0c\u6839\u636e UNICODE \u5b8f\u662f\u5426\u5b9a\u4e49\uff0c\u51b3\u5b9a\u91c7\u53d6\u54ea\u5957 API\u3002 \u6211\u4eec\u4f1f\u5927\u7684 Linux \u7cfb\u7edf\u5c31\u6ca1\u6709\u8fd9\u4e2a\u82e6\u607c\uff0c\u65e9\u5c31\u7edf\u4e00 UTF-8 \u4e86\u3002 \u9664\u6b64\u4e4b\u5916\uff0c \u4e2d\u8fd8\u5b9a\u4e49\u4e86 TEXT \u8fd9\u4e2a\u5b8f\u51fd\u6570\u3002 #ifdef UNICODE #define TEXT(s) L##s #else #define TEXT(s) s #endif \u7528\u6cd5\uff1a\u8981\u6c42\u7a0b\u5e8f\u5458\u628a\u6240\u6709\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u90fd\u7528 TEXT \u5b8f\u5305\u88f9\u3002 Qt \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b8f\u5305\u88f9\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u505a\u6cd5\uff0c tr \uff0c\u4f46\u5b83\u5e76\u4e0d\u662f\u4e3a\u4e86\u89e3\u51b3\u7f16\u7801\u95ee\u9898\uff0c\u800c\u662f\u4e3a\u4e86\u89e3\u51b3\u591a\u8bed\u8a00\u7ffb\u8bd1\u95ee\u9898\uff0c\u7a0d\u540e\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u4e00\u4e0b Qt \u4e2d\u7684\u5b57\u7b26\u4e32\u3002 \u5f53 UNICODE \u5b8f\u5b9a\u4e49\u65f6\uff0c TEXT \u4f1a\u81ea\u52a8\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u6dfb\u52a0 L \u524d\u7f00\uff0c\u4f7f\u5f97\u5b57\u7b26\u4e32\u53d8\u6210 Unicode \u7684\u3002\u5982\u679c\u6ca1\u6709\u5b9a\u4e49\uff0c\u5219\u53c8\u53d8\u56de ANSI \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff08\u8ddf\u968f\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\u7684\u8bbe\u5b9a\uff09\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff1a #include int main() { MessageBox(NULL, TEXT(\"\u4f60\u597d\uff0c\u4e16\u754c\"), TEXT(\"\u6807\u9898\"), MB_OK); } \u5f53\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u6807\u9898\", MB_OK); } \u5f53\u6ca1\u6709\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u6807\u9898\", MB_OK); } \u6b64\u5916\uff0c\u8fd8\u5b9a\u4e49\u4e86 TCHAR \u8fd9\u4e2a\u7c7b\u578b\u522b\u540d\uff0c\u540c\u6837\u662f\u9488\u5bf9\u662f\u5426\u5b9a\u4e49 UNICODE \u5b8f\u800c\u5b9a\u4e49\u4e86\u4e24\u5957\u7248\u672c\u3002 #ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif \u8fd8\u4e3a printf \u548c wprintf \u5b9a\u4e49\u4e86 TCHAR \u7248\u672c\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709 strlen \u548c wcslen \uff0c strcpy \u548c wcscpy \uff0c\u7b49\u7b49\u3002 #ifdef UNICODE #define _tprintf wprintf #define _tcscpy wcscpy #define _tcslen wcslen #else #define _tprintf printf #define _tcscpy strcpy #define _tcslen strlen #endif \u4e0d\u89c9\u5f97\u8fd9\u5f88\u9177\u5417\uff1f\u5f88\u7b26\u5408\u6211\u5bf9\u5f3a\u8feb\u75c7\u7684\u60f3\u8c61\uff0c\u79d1\u6280\u5e76\u4e14\u5e26\u7740\u81ed\u5473\u3002 int main() { TCHAR str[] = TEXT(\"\u6bd4\u5c14\u76d6\u5b50\u6211\u6d4b\u8bd5\u4f60\u7684\u7801\"); } (* \u54e6\uff0c\u6211\u662f\u8bf4\uff0c\u6211\u8981\u6d4b\u8bd5\u4f60\u7684\u7f16\u7801\u683c\u5f0f *) \u9700\u8981\u5207\u6362\u65f6\uff0c\u5728 MSVC \u4e2d\uff0c\u6253\u5f00\u6216\u5173\u95ed /DUNICODE \u7f16\u8bd1\u9009\u9879\u5373\u53ef\u3002 \u4e0d\u8981\u89c9\u5f97\u8fd9\u662f\u4ec0\u4e48\u597d\u4e3b\u610f\uff0c\u8fd9\u6837\u505a\u7684\u540e\u679c\u662f\uff0c\u4f60\u5199\u51fa\u7684\u4ee3\u7801\u53ea\u80fd\u5728 Windows \u4e0b\u7f16\u8bd1\u3002 \u5199\u8d77\u6765\u7d2f\u6b7b\u4eba\uff0c\u5b9e\u9645\u54ea\u6709\u90a3\u4e48\u591a\u4e00\u76f4\u5728 ANSI \u548c Unicode \u4e4b\u95f4\u6765\u56de\u5207\u6362\u7684\u9700\u6c42\uff1f \u6211\u7684\u5efa\u8bae\u662f\uff0c\u7edf\u4e00 wchar_t \uff0c\u7edf\u4e00\u5168\u7528 W \u51fd\u6570\uff0c\u618b\u62a0\u62a0\u7d22\u7d22\u7684\u534a\u8fdb\u534a\u9000\u3002 UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f \u4e4b\u524d\u8bf4\u8fc7\u4e86\uff0cWindows \u5e73\u53f0\u5230\u5904\u90fd\u9ed8\u8ba4 GBK \u975e\u5e38\u9ebb\u70e6\uff0c\u8981\u5207\u6362\u5230 UTF-8 \u5de5\u4f5c\u6d41\uff1a \u7f16\u8bd1\u5668\u5f00\u542f /utf-8 \u9009\u9879 \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c system(\"chcp 65001\") \u8bbe\u7f6e\u6587\u4ef6\u7cfb\u7edf\u5b57\u7b26\u4e32\u7f16\u7801\uff0c setlocale(LC_ALL, \".utf-8\") // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 SetConsoleCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u5165\u7f16\u7801\uff0c\u7528\u4e8e std::cin #elif __unix__ // \u53cd\u6b63 Unix \u7cfb\u7edf\u9ed8\u8ba4\u90fd\u662f UTF-8\uff0c\u4e0d\u8bbe\u7f6e\u4e5f\u884c\uff0c\u8fd9\u91cc\u8bbe\u7f6e\u5168\u5c40 locale \u662f\u4e3a\u4e86\u8ba9 iswspace \u63a5\u53d7\u5168\u89d2\u7a7a\u683c\u3001iswpunct \u63a5\u53d7\u5168\u89d2\u9017\u53f7 L'\uff0c' \u7b49 //setlocale(LC_ALL, \"zh_CN.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u4e2d\u6587\u672c\u5730\u5316\uff0c\u53ef\u4f7f strerror \u8f93\u51fa\u4e2d\u6587\uff08\u4f46\u7528\u6237\u5fc5\u987b locale-gen \u8fc7\u4e2d\u6587\uff01\uff09 //setlocale(LC_ALL, \"C.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u8bed\u8a00\u4e2d\u6027 locale\uff0c\u53ea\u5f71\u54cd iswspace\u3001iswpunct \u7b49\u51fd\u6570\uff0c\u4e0d\u4f1a\u4f7f strerror \u7b49\u8f93\u51fa\u4e2d\u6587 setlocale(LC_ALL, \".utf-8\"); // \u82e5\u4e0d\u5e26\u4efb\u4f55\u524d\u7f00\uff08\u63a8\u8350\uff09\uff0c\u5219\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u8bed\u8a00 $LANG\uff0c\u4f7f strerror \u81ea\u52a8\u9002\u5e94 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 std::wcout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4f60\u90fd\u7edf\u4e00 UTF-8 \u4e86\uff0c\u8fd9\u7834 UTF-16 \u548c UTF-32 \u4e4b\u95f4\u6765\u56de\u8df3\u7684\u7834 wchar_t \u5c31\u522b\u7528\u4e86\u5457\uff01 return 0; } WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == false \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::cout << char(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f GBK \u7f16\u7801\u7684 char \u5e8f\u5217 // \u5982\u679c\u662f\u4e2d\u6587\u5b57\u7b26\uff0cWndProc(WM_CHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u5b57\u8282\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u5df1\u5224\u65ad\u548c\u62fc\u63a5 GBK \u5b57\u7b26\u4e32 return 0; case WM_UNICHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == true \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::wcout << wchar_t(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f UTF-16 \u7f16\u7801\u7684 wchar_t \u5e8f\u5217 // \u5982\u679c\u662f\u4ee3\u7406\u5bf9\uff0cWndProc(WM_UNICHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u7801\u4f4d\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u884c\u628a\u4ee3\u7406\u5bf9\u7ec4\u88c5\u6210\u5b8c\u6574\u7684 Unicode \u7801\u70b9 return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } \u628a WndProc \u7684\u8f93\u5165\u5b58\u5165 std::u32string \u7684\u6848\u4f8b\uff1a std::u32string result; std::string ansi_buf; std::wstring utf16_buf; std::optional try_ansi_to_utf32(std::string const &s) { try { return boost::locale::conv::to_utf(s, \"\"); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } std::optional try_utf16_to_utf32(std::wstring const &s) { try { return boost::locale::conv::utf_to_utf(s); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: ansi_buf.push_back(char(wParam)); if (auto u = try_ansi_to_utf32(ansi_buf)) { result += u.value(); ansi_buf.clear(); } return 0; case WM_UNICHAR: utf16_buf.push_back(wchar_t(wParam)); if (auto u = try_utf16_to_utf32(utf16_buf)) { result += u.value(); utf16_buf.clear(); } return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); }; \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 \u6807\u51c6\u5e93\u7684 std::string \u6211\u4eec\u4e0d\u518d\u8d58\u8ff0\uff0c\u521a\u624d\u5728\u201c\u5bbd\u5b57\u7b26\u6d41\u201d\u4e2d\u4e5f\u4ecb\u7ecd\u4e86\u5b98\u65b9\u7684\u60f3\u6cd5\uff0c\u4e4b\u540e\u7684\u5b57\u7b26\u4e32\u4e13\u9898\u8bfe\u4f1a\u7ee7\u7eed\u8be6\u89e3\u3002 \u8fd9\u91cc\u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u5173\u4e8e\u5b57\u7b26\u7f16\u7801\u7684\u95ee\u9898\uff0c\u63a2\u7d22\u5404\u5927\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u5e93\uff0c\u662f\u5982\u4f55\u5c01\u88c5\u5b57\u7b26\u4e32\u7c7b\uff0c\u5982\u4f55\u89e3\u51b3 UTF-8 \u53d8\u957f\u7f16\u7801\uff0cUTF-32 \u538b\u7f29\u7387\u4f4e\u7684\u95ee\u9898\u7684\uff0c\u5e0c\u671b\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u63d0\u4f9b\u4e00\u70b9\u7075\u611f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u597d\u7684\u5e93\u6216\u8bed\u8a00\uff0c\u90fd\u8981\u660e\u786e\u533a\u5206\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u6982\u5ff5\uff0c\u524d\u8005\u662f\u6587\u672c\u5185\u5bb9\uff0c\u540e\u8005\u662f\u7eaf\u4e8c\u8fdb\u5236\u5185\u5bb9\u3002 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7\u201c\u7f16\u7801\u201d\u5f97\u5230\u7eaf\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6570\u7ec4\uff0c\u800c\u5b57\u8282\u6570\u7ec4\u53ef\u4ee5\u201c\u89e3\u7801\u201d\u5f97\u5230\u539f\u59cb\u5b57\u7b26\u4e32\u3002 \u65e9\u671f\u7684 C \u8bed\u8a00\u5c31\u662f\u56e0\u4e3a\u628a\u5b57\u7b26\u548c\u5b57\u8282\u6df7\u4e3a\u4e00\u8c08\uff0c\u90fd\u4f7f\u7528\u4e86 char \u7c7b\u578b\uff0c\u624d\u4ea7\u751f\u4e86\u540e\u6765\u8fd9\u4e48\u591a\u4e71\u8c61\u3002\u540e\u6765\u901a\u8fc7\u6253\u8865\u4e01\u6253\u4e0a\u771f\u6b63\u7684\u5b57\u7b26 wchar_t \uff0c\u5374\u6ca1\u4ec0\u4e48\u4eba\u7528\uff0c\u800c\u4e14\u8fd8\u88ab Windows \u641e\u6210 16 \u4f4d\uff0c\u53cd\u800c\u4e0d\u8de8\u5e73\u53f0\u4e86\u3002 \u6b64\u5904\u5148\u5217\u4e00\u4e2a\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u773c\u4e2d\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u8868\uff0c\u65b9\u4fbf\u4f60\u7406\u89e3\u3002 \u8bed\u8a00 \u5b57\u7b26 \u5b57\u7b26\u4e32 \u6587\u672c\u6d41 \u5b57\u8282\u6570\u7ec4 \u4e8c\u8fdb\u5236\u6d41 \u7f16\u7801/\u89e3\u7801 C char wchar_t * FILE * + fgetwc char * FILE * + fgetc wcstomb / mbstowc C++ wchar_t std::wstring std::wistream std::string / std::vector std::istream std::codecvt Qt QChar QString QTextStream QByteArray QDataStream QTextCodec Python3 str str open('r') bytes open('rb') str.encode() Python2 unicode unicode \u65e0 str open('r') unicode.encode() Java Character String Reader byte[] InputStream Charset.encode C# char string StreamReader byte[] Stream Encoding Rust char String BufRead u8 Read str::from_utf8 JS char String ReadableStream Uint8Array ReadableStream TextEncoder Go rune string Reader byte Reader utf8.DecodeRune PHP string string fopen string fopen mb_convert_encoding Swift Character String String.UnicodeScalarView UInt8 Data String.Encoding Kotlin Char String Reader ByteArray InputStream Charset.encode Obj-C unichar NSString NSInputStream uint8_t NSInputStream NSStringEncoding Lua integer table \u65e0 string io.open require'utf8' \u672c\u8bfe\u4e0d\u4f1a\u8bb2\u89e3\u8fd9\u4e9b\u8bed\u8a00\u7684\u5b57\u7b26\u4e32\u5177\u4f53\u7528\u6cd5\uff0c\u53ea\u63d0\u4f9b\u4e00\u4e9b\u6982\u5ff5\uff0c\u8ba9\u4f60\u77e5\u9053\u5927\u5bb6\u90fd\u662f\u600e\u4e48\u5b9e\u73b0\u7684\uff0c\u89e6\u7c7b\u65c1\u901a\u3002 Lua \u4e2d UTF-32 \u7684\u5b9a\u957f\u7f16\u7801\uff0c\u8981\u8fd9\u6837\u5b9e\u73b0\uff1a {80, 101, 110, 103} \u3002\u800c\u4ed6\u6240\u8c13\u7684 utf8 \u5e93\uff0c\u5c31\u662f\u8d1f\u8d23\u628a Lua \u81ea\u5df1\u7684 string \u5047\u8bbe\u4e3a utf8 \u7f16\u7801\uff0c\u89e3\u7801\u51fa\u4e00\u4e2a\u4e2a Unicode \u7801\u70b9\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fd9\u6837\u7684\u6570\u7ec4\u3002\u4ed6\u751a\u81f3\u4e0d\u662f Lua \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u662f\u4e2a\u7b2c\u4e09\u65b9\u7684\u5e93\uff0c\u8fd8\u662f\u9700\u8981\u7f16\u8bd1\u7684 C \u8bed\u8a00 .so \u6587\u4ef6\u3002\u8fd8\u6709 Lua \u5b5d\u5b50\u501f\u6b64\u786c\u8bf4\u6211\u4eec Lua \u662f\u5929\u751f UTF-8\uff01\u7136\u800c\u62ff\u7740\u4e2a UTF-8 \u7f16\u7801\u7684\u201c\u5b57\u8282\u6570\u7ec4\u201d string \u6765\u6253\u5f00 io.open \u6587\u4ef6\uff0c\u5c31\u4f1a\u62a5\u9519\u627e\u4e0d\u5230\u6587\u4ef6\uff08\u56e0\u4e3a\u4e2d\u56fd\u533a Windows \u7684 GBK\uff09\uff0c\u662f\u4e0d\u662f\u5f88\u597d\u7b11\u5462\uff1f Qt QString Qt \u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 Qt \u7684\u5b57\u8282\u6570\u7ec4\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 \u5b83\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u4e0a\u662f\u4e2a QChar \u6570\u7ec4\uff0c\u800c QChar \u662f unsigned short \uff0c\u5373 16 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\uff0c\u4e5f\u5c31\u662f UTF-16 \u7f16\u7801\u7684\u7801\u4f4d\u3002 QString str = \"\u4f60\u597d\uff0c\u4e16\u754c\"; // str.size() = 5 // str[0] = QChar(0x4f60) = u'\u4f60' // str[1] = QChar(0x597d) = u'\u597d' // str[2] = QChar(0xff0c) = u'\uff0c' // str[3] = QChar(0x4e16) = u'\u4e16' // str[4] = QChar(0x754c) = u'\u754c' \u53ef\u89c1\uff0c QString \u662f UTF-16 \u7f16\u7801\u7684\uff0c\u5c31\u548c Java \u4e00\u6837\uff0cQt \u4e5f\u662f UTF-16 \u6f6e\u7684\u53d7\u5bb3\u8005\u3002 \u6240\u4ee5\uff0cQString \u4e5f\u5b58\u5728\u7740\u4ee3\u7406\u5bf9\u53d8\u957f\u7f16\u7801\u7684\u95ee\u9898\u3002\u4f46\u81f3\u5c11\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5b57\u7b26\u6765\u8bf4\uff0c\u4e00\u4e2a 16 \u4f4d\u7684 QChar \u90fd\u5bb9\u7eb3\u7684\u4e0b\u4e86\u3002 QTextCodec Qt \u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u7684\u7f16\u7801\u8f6c\u6362\u51fd\u6570\uff0c\u7528\u4e8e\u5c06 QString \u8f6c\u6362\u6210 QByteArray \uff0c\u6216\u8005\u4ece QByteArray \u8f6c\u6362\u6210 QString \uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u90fd\u662f\u4ee5 to \u6216\u8005 from \u5f00\u5934\u7684\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u540d\uff0c\u4f8b\u5982 fromUtf8 \u3001 toUtf8 \u3001 toLocal8Bits \u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u5185\u90e8\uff0c\u90fd\u662f\u8c03\u7528 QTextCodec \u7c7b\u5b9e\u73b0\u7684\u8f6c\u6362\u3002 QTextCodec \u662f Qt \u7528\u4e8e\u5904\u7406\u5404\u79cd\u6587\u672c\u7f16\u7801\u4e4b\u95f4\u8f6c\u6362\u7684\u7c7b\u3002\u5b83\u7684\u9759\u6001\u65b9\u6cd5 codecForLocale \u8fd4\u56de\u4e86\u5f53\u524d\u7cfb\u7edf\u7684\u7f16\u7801\uff0c toUnicode \u548c fromUnicode \u5206\u522b\u662f\u5c06 QByteArray \u8f6c\u6362\u6210 QString \uff0c\u6216\u8005\u5c06 QString \u8f6c\u6362\u6210 QByteArray \u3002 QTextCodec *codec = QTextCodec::codecForLocale(); // \u8fd4\u56de\u5f53\u524d\u7cfb\u7edf\u7f16\u7801 QByteArray bytes = codec->fromUnicode(str); // \u5c06 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u5373 char[] QString str = codec->toUnicode(bytes); // \u5c06 QByteArray \u8f6c\u6362\u6210 QString QTextCodec \u8fd8\u63d0\u4f9b\u4e86\u4e00\u4e9b\u66f4\u52a0\u7ec6\u7c92\u5ea6\u7684\u8f6c\u6362\u63a5\u53e3\uff0c\u4f8b\u5982 fromUnicode \u9664\u4e86\u63a5\u53d7 QString \uff0c\u8fd8\u63a5\u53d7 QChar \u6570\u7ec4\uff0c\u53ef\u4ee5\u6307\u5b9a\u8f6c\u6362\u8303\u56f4\u3002 from/toLocal8Bits/Utf8/Latin1/Ascii \u4e3a\u4e86\u65b9\u4fbf\u4f7f\u7528\uff0cQt \u5c01\u88c5\u4e86\u4e00\u4e9b\u5e38\u7528\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362\u51fd\u6570\uff0c\u8fd9\u6837\u4f60\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u521b\u5efa\u4e00\u4e2a QTextCodec\u3002\u90fd\u662f to \u548c from \u5f00\u5934\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u7684\u540d\u79f0\u3002 Local8Bits \u8868\u793a\u8fd0\u884c\u65f6\u68c0\u6d4b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u5ba2\u6237\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 QByteArray bytes = str.toLocal8Bits(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801 QString::fromLocal8Bits(bytes); // \u518d\u4ece\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForLocale(); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Utf8 \u8868\u793a\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002 QByteArray bytes = str.toUtf8(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 UTF-8 \u7f16\u7801 QString::fromUtf8(bytes); // \u518d\u4ece UTF-8 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"UTF-8\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Latin1 \u8868\u793a ISO-8859-1 \u7f16\u7801\uff0c\u53c8\u79f0\u4e3a\u897f\u6b27\u7f16\u7801\uff0c\u5b83\u662f\u4e00\u4e2a\u5355\u5b57\u8282\u7f16\u7801\uff0c\u548c ASCII \u7f16\u7801\u76f8\u4f3c\uff0c\u4f46\u662f\u591a\u4e86 128-255 \u7684\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u6cd5\u8bed\u3001\u5fb7\u8bed\u3001\u897f\u73ed\u7259\u8bed\u3001\u8461\u8404\u7259\u8bed\u7b49\u5b57\u7b26\u3002 QByteArray bytes = str.toLatin1(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 Latin1 \u7f16\u7801 QString::fromLatin1(bytes); // \u518d\u4ece Latin1 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ISO-8859-1\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Ascii \u8868\u793a ASCII \u7f16\u7801\uff0c\u548c Latin1 \u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u4ed6\u65e0\u6cd5\u5904\u7406 128-255 \u8fd9\u4e00\u6bb5\u7684\u5b57\u7b26\u3002 QByteArray bytes = str.toAscii(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 ASCII \u7f16\u7801 QString::fromAscii(bytes); // \u518d\u4ece ASCII \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ASCII\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); \u5b57\u7b26\u4e32\u5e38\u91cf QString str = QStringLiterial(\"\u4f60\u597d\uff0c\u4e16\u754c\"); QStringLiterial \u53ef\u4ee5\u4fdd\u8bc1\uff0c\u8f6c\u6362\u65f6\u91c7\u7528\u7684\u662f\u6240\u8c13\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\uff08\u5b9e\u9645\u5e94\u8be5\u53eb\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\uff09\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u5f00\u53d1\u8005\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u662f\u7f16\u8bd1\u671f\u786e\u5b9a\u7684\u3002\u800c\u5982\u679c\u5199 QString::fromLocal8Bits(\"\") \u5c31\u53d8\u6210 \u201cANSI\u201d\uff0c\u5ba2\u6237\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u4e86\u3002\u8fd9\u4e24\u4e2a\u5b57\u7b26\u7f16\u7801\uff0c\u6bd4\u5982\u5728\u4e4b\u524d\u8de8\u56fd galgame \u7684\u6848\u4f8b\u4e2d\uff0c\u5c31\u662f\u4e0d\u540c\u7684\u3002 QTextStream QTextStream \u662f Qt \u63d0\u4f9b\u7684\u6587\u672c\u6d41\u7c7b\uff08\u5e26\u6709\u7f13\u51b2\uff09\uff0c\u5b83\u53ef\u4ee5\u5c06\u6587\u672c\u5199\u5165\u5230\u6587\u4ef6\u3001\u5957\u63a5\u5b57\u3001\u6807\u51c6\u8f93\u51fa\u7b49\u8bbe\u5907\u3002 \u6587\u672c\u6d41\u548c\u4e8c\u8fdb\u5236\u6d41\u4e0d\u540c\uff0c\u4ed6\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u8fc7 QTextStream \u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u3002 \u5f53\u4f60\u5f80 QTextStream \u5199\u5165 QString \u65f6\uff0c\u4f1a\u8c03\u7528\u8fd9\u4e2a\u7f16\u7801\u683c\u5f0f\u81ea\u52a8\u8f6c\u6362\u4e3a QByteArray \uff0c\u7136\u540e\u624d\u5199\u5165\u3002 \u8bfb\u53d6\u65f6\u4e5f\u540c\u7406\uff0c\u4f1a\u628a\u8bfb\u5230\u7684 QByteArray \u901a\u8fc7\u7f16\u7801\u683c\u5f0f\u89e3\u7801\uff0c\u5f97\u5230 QString \u5b57\u7b26\u4e32\u3002 Qt \u503c\u5f97\u79f0\u9053\u7684\u4e00\u70b9\u662f\uff1a\u4ed6\u628a\u6587\u4ef6\u548c\u6587\u4ef6\u6d41\u533a\u5206\u5f00\u6765\uff0c\u6587\u4ef6 QFile \u53ea\u9700\u8981\u8d1f\u8d23\u6253\u5f00\u6587\u4ef6\u5c31\u53ef\u4ee5\u4e86\uff1b\u800c\u6587\u672c\u6d41 QTextStream \u624d\u771f\u6b63\u8d1f\u8d23\u6570\u636e\u7684\u7f13\u51b2\uff0c\u89e3\u7801\u7b49\u64cd\u4f5c\u3002\u4f53\u73b0\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u804c\u8d23\u5355\u4e00\u539f\u5219\u3002 QFile file(\"hello.txt\"); file.open(QIODevice::ReadWrite); QTextStream stream(&file); stream.setCodec(\"UTF-8\"); // \u8bbe\u7f6e\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f stream << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u5199\u5165 QString\uff0cQTextStream \u4f1a\u81ea\u52a8\u5c06\u5176\u7528 UTF-8 \u7f16\u7801\u4e3a QByteArray \u540e\u5199\u5165 QFile \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u76f4\u63a5\u5199\u5165\u4e8c\u8fdb\u5236\u7684 QByteArray \uff0cQt \u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a QDataStream \u7c7b\uff0c\u65b9\u4fbf\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u8bfb\u5199\u3002 \u5982\u6b64\u628a\u4e8c\u8fdb\u5236\u548c\u6587\u672c\u4e25\u683c\u533a\u5206\uff0c\u800c\u4e0d\u662f\u50cf\u53e4\u4ee3 C \u8bed\u8a00\u90a3\u6837\u5b57\u8282\u4e0e\u5b57\u7b26\u6df7\u6dc6\u4e0d\u6e05\uff0c\u5168\u7528\u7cdf\u7cd5\u7684 char \u6765\u8868\u793a\uff0c\u5145\u5206\u4f53\u73b0\u4e86\u5f3a\u7c7b\u578b\u7684\u5b89\u5168\u3002 Python 3 str \u5982\u4f55\u89e3\u51b3 UTF-32 \u5360\u7528\u7a7a\u95f4\u5927\u7684\u75db\u70b9\uff1fPython \u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u7edd\u5bf9\u503c\u5f97\u4e00\u770b\uff01 \u4e3a\u4e86\u65b9\u4fbf\u6587\u672c\u5904\u7406\uff0c\u6700\u597d\u4ee5\u5b9a\u957f\u7f16\u7801\uff0c\u4e5f\u5c31\u662f UTF-32\uff0c\u5b58\u50a8\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7528 UTF-8 \u6216 UTF-16 \u6765\u5b58\u50a8\u7684\u8bdd\uff0c\u4f1a\u9047\u5230\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff1a \u4f8b\u5982\u50cf\u5b57\u7b26\u4e32\u7d22\u5f15\uff0c\u5b57\u7b26\u4e32\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\uff0c\u8981\u4e48\u7d22\u5f15\u51fa\u6765\u7684\u662f\u5b57\u8282\u800c\u4e0d\u662f\u5b57\u7b26\u4e86\uff1b\u8981\u4e48\u5c31\u9700\u8981 O(N) O(N) \u7684\u590d\u6742\u5ea6\uff0c\u9010\u4e00\u904d\u5386\u6bcf\u4e2a\u5b57\u8282\uff0c\u624d\u80fd\u786e\u5b9a\u771f\u6b63\u7684\u4f4d\u7f6e\uff1b\u54ea\u6015\u5168\u662f ASCII \u4e5f\u5f97\u8fd9\u4e48\u505a\uff0c\u56e0\u4e3a\u4e07\u4e00\u521a\u597d\u6709\u4e00\u4e2a\u662f\u4e2d\u6587\u5b57\u7b26\u5462\uff1f \u6240\u4ee5\uff0c\u5bf9\u4e8e\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684 Python \u6765\u8bf4\uff0cUTF-8 \u662f\u65e0\u6cd5\u63a5\u53d7\u7684\uff0c\u4f3c\u4e4e\u53ea\u80fd\u4ee5 UTF-32 \u6765\u5b58\u50a8\uff1f Python \u60f3\u5230\u4e86\u4e00\u4e2a\u5c0f\u5999\u62db\uff1a enum PyUnicodeType { PyUnicodeType_Latin1, PyUnicodeType_UCS2, PyUnicodeType_UCS4, }; struct PyUnicodeString { PyUnicodeType type; union { uint8_t *latin1; uint16_t *ucs2; uint32_t *ucs4; }; }; \u8fd9\u91cc\u7684 union \u662f\u4e00\u4e2a C \u8bed\u8a00\u7279\u6027\uff0c\u4ed6\u5141\u8bb8\u4f60\u628a\u591a\u4e2a\u6210\u5458\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u5e38\u6765\u8bf4\u9700\u8981\u914d\u5408\u4e00\u4e2a enum \u8868\u793a\u7c7b\u578b\uff0c\u624d\u80fd\u5b89\u5168\u4f7f\u7528\u3002\u73b0\u4ee3 C++ \u7684 std::variant \u66f4\u5b89\u5168\u7684\u53d6\u4ee3\u4e86\u4ed6\uff0c\u800c\u4e14\u4e0d\u9700\u8981\u5916\u6302\u4e00\u4e2a enum \u3002CPython \u89e3\u91ca\u5668\u56e0\u4e3a\u662f C \u8bed\u8a00\u5b9e\u73b0\uff0c\u53ea\u80fd\u7528 union \u6a21\u62df std::variant \u7684\u6548\u679c\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFF \u7684\u5b57\u7b26\uff08Latin-1 \u8303\u56f4\uff09\u65f6\uff0c\u5b9e\u9645\u4e0a\u6ca1\u5fc5\u8981\u5168\u7528\u8d85\u5927\u7684 uint32_t \u6765\u5b58\u50a8\u3002\u5b8c\u5168\u53ef\u4ee5\u53ea\u53d6\u51fa\u4f4e 8 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a\u66f4\u7d27\u51d1\u7684 uint8_t \u6570\u7ec4\uff0c\u5c31\u50cf Latin-1 \u7f16\u7801\u4e00\u6837\u3002 \u4f46\u662f\u5f53\u6309\u7d22\u5f15\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u4f1a\u5224\u65ad\u5f53\u524d union \u91cc\u88c5\u7684\u662f\u54ea\u79cd\u7c7b\u578b\uff0c\u5982\u679c\u662f Latin-1 \u7684\uff0c\u90a3\u5c31\u4f1a\u7528\u7ed3\u6784\u4f53\u91cc\u7684 uint8_t * \u6307\u9488\u6765\u7d22\u5f15\u3002 \u8fd9\u6837\uff0c\u5bf9\u4e8e\u5168 ASCII \u7684\u5b57\u7b26\u4e32\uff0c\u76f8\u6bd4\u8001\u8001\u5b9e\u5b9e\u5b58 UTF-32 \u5185\u5b58\u5360\u7528\u76f4\u63a5\u51cf\u5c11\u4e86 75%\uff01\u552f\u4e00\u7684\u4ee3\u4ef7\u662f\u6309\u7d22\u5f15\u8bfb\u5b57\u7b26\u5143\u7d20\u65f6\u9700\u8981\u505a\u4e2a if-else \u5224\u65ad\u3002\u540c\u65f6\u53c8\u4e0d\u5931\u53bb\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff08\u65e9\u671f Unicode \u8303\u56f4\uff09\u65f6\uff0c\u5219\u662f\u53d6\u51fa\u4f4e 16 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a uint16_t \u7684\u6570\u7ec4\uff0c\u8fd9\u79cd\u5b58\u50a8\u65b9\u6848\u4e5f\u79f0\u4e3a UCS-2\u3002 \u6ce8\u610f UCS-2 \u5e76\u4e0d\u7b49\u540c\u4e8e UTF-16\uff0cUTF-16 \u662f\u80fd\u591f\u8868\u793a\u5b8c\u6574\u7684 Unicode \u7684\u53d8\u957f\u7f16\u7801\uff08\u6709\u4ee3\u7406\u5bf9\uff09\uff1b\u800c UCS-2 \u662f\u6ca1\u6709\u4ee3\u7406\u5bf9\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u7f3a\u70b9\u662f\u53ea\u80fd\u8868\u793a 0xFFFF \u7684\u8303\u56f4\u3002 \u5bf9\u4e8e\u5927\u90e8\u5206\u4e2d\u6587\u5b57\u7b26\u4e32\uff0c\u5185\u5b58\u5360\u7528\u5c31\u51cf\u5c11\u4e86 50%\uff0c\u4e5f\u4e0d\u4e8f\u3002 \u5982\u679c\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0\u201c\ud883\udede\u201d\u8fd9\u6837\u7684\uff0c\u8d85\u8fc7 0xFFFF \u7684\u5b57\u7b26\uff0c\u624d\u4f1a\u91c7\u7528 uint32_t \u8001\u8001\u5b9e\u5b9e\u5b58\u50a8\u771f\u6b63\u7684 UTF-32\uff0c\u53c8\u79f0 UCS-4\u3002 \u8fd9\u4e24\u79cd\u53eb\u6cd5\u662f\u7b49\u4ef7\u7684\uff0c\u53cd\u6b63 Unicode \u4ece\u6765\u6ca1\u6709\u8d85\u8fc7 0xFFFFFFFF \u7684\uff0c\u73b0\u5728\u4ed6\u4eec\u90fd\u662f\u5b9a\u957f\u7f16\u7801\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u62df\u673a\u8bed\u8a00\u6765\u8bf4\uff0c\u53cd\u6b63\u672c\u6765\u5c31\u4e0d\u5728\u4e4e if-else \u5206\u652f\u8fd9\u70b9\u5c0f\u5f00\u9500\uff0c\u8fd9\u786e\u5b9e\u662f\u6700\u597d\u7684\u65b9\u6848\u3002 \u7f3a\u70b9\u5c31\u662f\uff0c\u5f53\u4f60\u5f80\u4e00\u4e2a\u5b8c\u5168\u662f ASCII \u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u7a81\u7136\u63d2\u5165\u4e00\u4e2a\u201c\ud883\udede\u201d\u65f6\uff0c\u4f1a\u4ea7\u751f\u5de8\u5927\u7684\u5185\u5b58\u91cd\u5206\u914d\u3002\u867d\u7136\u53ea\u6709\u4e00\u4e2a\u201c\ud883\udede\u201d\uff0c\u4f46\u4e3a\u6b64\uff0c\u5176\u4ed6\u6240\u6709 ASCII \u5b57\u7b26\u90fd\u5f97\u4e3a\u4ed6\u6269\u5f20\u5230 32 \u4f4d\u7684\u5927\u5c0f\u3002\u800c UTF-8 \u548c\u4f20\u7edf\u7684 UTF-32 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u6b64\u6211\u4e5f\u4e0d\u5efa\u8bae C++ \u7a0b\u5e8f\u5458\u81ea\u5df1\u624b\u6413\u4e2a\u8fd9\u6837\u7684 union \u5b57\u7b26\u4e32\u3002 Rust &str \u548c String \u800c Rust \u5219\u91c7\u7528\u4e86\u5b57\u7b26\u4e32\u5168\u5458 UTF-8 \u7684\u7b56\u7565\uff0c\u8fd9\u662f\u56e0\u4e3a Rust \u6700\u5e38\u7528\u4e8e\u4e92\u8054\u7f51\u65b9\u9762\u7684\u5e95\u5c42\u7cfb\u7edf\u8f6f\u4ef6\uff0c\u4e92\u8054\u7f51\u6700\u5e38\u7528\u7684\u6587\u672c\u7f16\u7801\u5c31\u662f UTF-8\uff0c\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\uff0c\u4e14\u56fd\u9645\u901a\u7528\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u4e92\u8054\u7f51\u57fa\u5efa\u6700\u5e38\u89c1\u7684\u5e73\u53f0\u5c31\u662f Linux\uff0c\u4f7f\u7528 UTF-8 \u5b58\u50a8\u5b57\u7b26\u4e32\uff0c\u8c03\u7528 Linux \u7cfb\u7edf API \u65e0\u9700\u4efb\u4f55\u8f6c\u6362\u3002\u4e14\u6587\u672c\u6587\u4ef6\u57fa\u672c\u90fd\u53ef\u4ee5\u5047\u5b9a\u662f UTF-8 \u7f16\u7801\uff0c\u5199\u5165\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u3002\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u8fd9\u5bfc\u81f4\u6587\u672c\u5904\u7406\u4e0a\u7684\u4e00\u4e9b\u56f0\u96be\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u7684\u7d22\u5f15\uff0c\u9700\u8981\u533a\u5206\u662f\u6309\u5b57\u8282\u7d22\u5f15\u8fd8\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u5982\u679c\u786e\u5b9e\u9700\u8981\u6309\u5b57\u7b26\u7d22\u5f15\u7684\u8bdd\uff0c\u590d\u6742\u5ea6\u5c31\u4f1a\u662f O(N) O(N) \u4e86\u3002 \u65e0\u8bba\u5982\u4f55\uff0c\u5982\u679c\u4f60\u9009\u62e9\u4e86 UTF-8 \u6d41\u6d3e\u7684\u8bdd\uff0cRust \u5b57\u7b26\u4e32\u7684\u201c\u8fed\u4ee3\u5668\u53cc\u8f68\u5236\u201d\u786e\u5b9e\u503c\u5f97\u79f0\u9053\uff1a let s = \"\u4f60\u597d\uff0c\u4e16\u754c\"; for c in s.chars() { // \u6309\u5b57\u7b26\u8fed\u4ee3 println!(\"{}\", c); } for b in s.bytes() { // \u6309\u5b57\u8282\u8fed\u4ee3 println!(\"{:02X}\", b); // \u6253\u5370\uff1aE4 BD A0 E5 A5 BD EF BC 8C E4 B8 96 E7 95 8C } Java String Java \u4e5f\u662f UTF-16 \u7684\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u4eae\u70b9\uff1a\u4ed6\u7684 String \u7c7b\u578b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u4f60\u65e0\u6cd5\u5c31\u5730\u4fee\u6539\u4e00\u4e2a String \u5bf9\u8c61\uff0c\u6bcf\u6b21\u4ea7\u751f\u4f60\u8c03\u7528 += \u7684\u90fd\u662f\u4e00\u4e2a\u65b0 String\uff0c\u800c\u4e0d\u4f1a\u8986\u76d6\u3002 \u4e5f\u5c31\u662f\u8bf4\uff1aJava \u7684 String \u867d\u7136\u662f\u201c\u5806\u201d\u4e2d\u7684\u5bf9\u8c61\uff0c\u5374\u65e0\u6cd5\u4ee5\u5f15\u7528\u4f20\u9012\u3002 \u8fd9\u907f\u514d\u4e86\u4ee5\u4e0b\u8fd9\u79cd\u60c5\u51b5\uff1a void registerStudent(String name) { name += \".txt\"; File file(name); file.write(...); } void myTransaction() { String name = \"\u5c0f\u5f6d\"; lib.registerStudent(name); office.registerStudent(name); // \u8fd9\u91cc name \u662f\u5426\u88ab\u4fee\u6539\uff1f } \u5982\u679c Java \u7684 String \u548c\u666e\u901a\u5bf9\u8c61\u4e00\u6837\uff0c\u88ab\u8c03\u7528\u8005\u7684\u4fee\u6539\u53ef\u4ee5\u5bf9\u5916\u90e8\u53ef\u89c1\uff0c\u90a3\u5c82\u4e0d\u662f\u6211\u6bcf\u6b21\u8c03\u7528\u4e00\u4e2a\u4ee5 String \u4e3a\u53c2\u6570\u7684\u51fd\u6570\u65f6\uff0c\u90fd\u9700\u8981\u64cd\u5fc3\uff1a\u8fd9\u4e2a\u51fd\u6570\u4f1a\u4e0d\u4f1a\u628a\u6211\u7684\u5b57\u7b26\u4e32\u4fee\u6539\u6389\uff1f \u6240\u4ee5\uff0cJava \u7ed9\u4ed6\u7684\u5bf9\u8c61\u6a21\u578b\u5f00\u4e86\u4e2a\u540e\u95e8\uff1a\u89c4\u5b9a\u6240\u6709\u5bf9\u8c61\u90fd\u662f\u6309\u5f15\u7528\u4f20\u9012\uff0c\u9664\u4e86 String \uff01\u5c31\u53ea\u6709 String \u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u8005\u5185\u90e8\u7684\u4fee\u6539\u5bf9\u5916\u4e0d\u53ef\u89c1\u3002 C++ \u548c Rust \u53ea\u9700\u8981\u52a0\u4e2a\u5e38\u5f15\u7528\u5c31\u884c\uff0c\u800c Java \u53d7\u5bb3\u8005\u8981\u8003\u8651\u7684\u5c31\u591a\u4e86\u3002 \u603b\u4e4b\uff0c\u8fd9\u5c31\u662f\u6ca1\u6709 const \u7684\u5783\u573e\u8bed\u8a00\u7684\u4e11\u6001\uff0c\u9700\u8981\u9760\u5404\u79cd\u8bed\u6cd5\u89c4\u5219\u4e0a\u5f00\u6d1e\u624d\u80fd\u5f25\u8865\u8bbe\u8ba1\u65f6\u8003\u8651\u4e0d\u5468\u7684\u7f3a\u9677\uff0c\u5c31\u4e3a\u4e86\u4f3a\u5019\u8fd9\u5e2e\u5f15\u7528\u90fd\u5f04\u4e0d\u660e\u767d\u7684\u5783\u573e\u5c0f\u767d\u3002 \u6211\u662f\u8bf4\u5783\u573e\u56de\u6536 (garbage-collect) \u8bed\u8a00\uff0c\u7b80\u79f0\u5783\u573e\u8bed\u8a00\u3002\u6ca1\u6709\u8bf4 Java \u5783\u573e\u7684\u610f\u601d\uff0c\u4f60\u8bf4\u5bf9\u5427\uff1f\u5783\u573e\u8bed\u8a00\u3002 COW \u5b57\u7b26\u4e32 \u62c5\u5fe7\uff1a\u90a3\u5c82\u4e0d\u662f\u6bcf\u6b21\u6211 += \u5b9e\u9645\u4e0a\u90fd\u767d\u767d\u6df1\u62f7\u8d1d\u4e86\u4e00\u4efd\u65b0\u7684 String \uff1f\u522b\u62c5\u5fc3\uff0c\u56e0\u4e3a\u5177\u4f53\u5b9e\u73b0\u4e0a\uff0cJava \u7684 String \u5728\u5e95\u5c42\u91c7\u7528\u4e86\u548c Qt \u7684 QString \u4e00\u6837\u7684 COW \u673a\u5236\uff1a \u5f53\u4e00\u4e2a QString \u88ab\u62f7\u8d1d\u6784\u9020\u65f6\uff0c\u5e76\u4e0d\u4f1a\u5bf9\u5176\u4e2d\u7684 QByteArray \u8fdb\u884c\u6df1\u62f7\u8d1d\uff0c\u800c\u662f\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u3002\u53ea\u6709\u5f53\u5176\u4e2d\u4e00\u4e2a QString \u88ab += \u7b49\u5e26\u6709\u526f\u4f5c\u7528\u64cd\u4f5c\u4fee\u6539\u65f6\uff0c\u624d\u4f1a\u6df1\u62f7\u8d1d\u4e00\u4efd\u65b0\u7684\uff0c\u8ba9\u4f60\u4fee\u6539\u3002\u8fd9\u6837\u5927\u5927\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\u548c\u6027\u80fd\u5f00\u9500\u3002 COW \u5b57\u7b26\u4e32\u7684\u7f3a\u70b9\u662f\uff1a\u5f53\u4f60\u5199\u591a\u7ebf\u7a0b\u5e76\u53d1\u65f6\uff0c\u672c\u6765\u591a\u7ebf\u7a0b\u53ea\u8bfb\u8bbf\u95ee\u540c\u4e00\u4e2a\u5b57\u7b26\u4e32\u662f\u5b89\u5168\u7684\uff0c\u4f46\u5982\u679c\u5b57\u7b26\u4e32\u6709 COW\uff0c\u8fde\u53ea\u8bfb\u8bbf\u95ee\u90fd\u4f1a\u4e0d\u5b89\u5168\u4e86\u3002\u4e4b\u540e\u6211\u4eec\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4f1a\u8be6\u7ec6\u5206\u6790\u8fd9\u662f\u4e3a\u4ec0\u4e48\u3002 \u5176\u5b9e\u65e9\u671f\u7684 C++98 \u4e2d\uff0c std::string \u4e5f\u91c7\u7528\u4e86 COW \u673a\u5236\uff0c\u4f46\u540e\u6765\u56e0\u4e3a\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u8981\u6c42\uff0c\u88ab\u8ffd\u6c42\u591a\u7ebf\u7a0b\u7684 C++11 \u8d23\u4ee4\u6539\u6b63\uff0c\u624d\u6709\u4e86\u540e\u6765 std::__cxx11::basic_string \u7684 ABI \u4e0d\u517c\u5bb9\u95ee\u9898\u3002\u6bd5\u7adf\u7ebf\u7a0b\u4e0d\u5b89\u5168\u5b9e\u5728\u592a\u4f24\u4e86\uff0c\u57fa\u672c\u610f\u5473\u7740\u591a\u7ebf\u7a0b\u5c31\u6ca1\u6cd5\u5171\u4eab std::string \u3002\u4e8b\u5b9e\u4e0a\uff0cQt \u6240\u6709\u7684\u5bf9\u8c61 QObject \uff0c\u5305\u62ec QString \u5728\u591a\u7ebf\u7a0b\u4e2d\u4f20\u9012\u65f6\uff0c\u5c31\u9700\u8981\u8c03\u7528 moveTo(QThread) \u8f6c\u79fb\u6240\u6709\u6743\uff0c\u624d\u80fd\u5b89\u5168\u5730\u4f20\u9012\u7ed9\u53e6\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u5c31\u662f\u56e0\u4e3a Qt \u5927\u91cf\u4f7f\u7528\u4e86 COW \u673a\u5236\u3002 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 TODO Grapheme TODO \u6b63\u89c4\u5316 TODO \u96f6\u5bbd\u7a7a\u683c TODO \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 TODO \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 \u201c\ud883\udede\u201d\u7684 Unicode \u7f16\u53f7\u662f 0x30EDE\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0c\u901a\u5e38\u53ef\u4ee5\u8f93\u5165 Ctrl+Shift+U \u7136\u540e\u8f93\u5165\u5341\u516d\u8fdb\u5236\u7f16\u53f7\uff0c3 0 E D E\uff0c\u7136\u540e Enter\uff0c\u5c31\u8f93\u5165\u4e86\u201c\ud883\udede\u201d\u3002 \u5728 Windows \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Win+R\uff0c\u7136\u540e\u8f93\u5165 charmap \uff0c\u6253\u5f00\u5b57\u7b26\u6620\u5c04\u8868\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u53cc\u51fb\u53ef\u4ee5\u590d\u5236\u5230\u526a\u8d34\u677f\u3002 \u5728 macOS \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Ctrl+Cmd+\u7a7a\u683c\uff0c\u6253\u5f00\u7279\u6b8a\u5b57\u7b26\u8f93\u5165\u9762\u677f\uff0c\u9009\u62e9\u201cUnicode\u201d\u5206\u7c7b\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u7136\u540e\u53cc\u51fb\u5c31\u8f93\u5165\u5230\u5149\u6807\u5904\u3002 UniFont \u5b57\u4f53 TODO \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f \u72ed\u4e49\u7684\u6c49\u5b57\uff1a0x4E00 \u5230 0x9FA5\uff08\u201c\u4e00\u201d\u5230\u201c\u9fa5\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\uff1a0x2E80 \u5230 0x9FFF\uff08\u201c\u2e80\u201d\u5230\u201c\u9fff\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\u5305\u542b\u4e86\u51e0\u4e4e\u6240\u6709\u4e2d\u65e5\u97e9\u4f7f\u7528\u7684\u6c49\u5b57\u5b57\u7b26\uff0c\u800c\u72ed\u4e49\u7684\u6c49\u5b57\u53ea\u662f\u4e2d\u6587\u91cc\u6700\u5e38\u7528\u7684\u4e00\u90e8\u5206\u3002 TODO Latin-1 \u7684\u8f6c\u6362 Latin-1 \u662f\u4e00\u4e2a 8 \u4f4d\u7f16\u7801\uff0c\u80fd\u8868\u793a 256 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u62c9\u4e01\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u3001\u5e38\u7528\u7684\u897f\u6b27\u5b57\u7b26\uff0c\u4ee5\u53ca\u4e00\u4e9b\u7279\u6b8a\u5b57\u7b26\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u4f60\u9700\u8981\u628a\u4e00\u4e2a Latin-1 \u7f16\u7801\u7684 char \u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a wchar_t \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fed\u4ee3\u5668\u63a5\u53e3\u6784\u9020 std::wstring \uff0c\u8fd9\u6837 char \u4f1a\u88ab\u9010\u4e2a\u8f6c\u6362\u4e3a wchar_t \u3002 std::string latin1 = \"I love P\\xE9ng\"; // 0xE9: \u00e9 std::wstring wstr(latin1.begin(), latin1.end()); std::wcout << wstr << '\\n'; \u8f93\u51fa\uff1a I love P\u00e9ng \u5e76\u4e0d\u6807\u51c6\u7684\u505a\u6cd5\uff0c\u8fd8\u662f\u5efa\u8bae\u7528 boost::locale::conv::to_utf(latin1, \"Latin-1\") \u3002 Latin-1 \u7684\u5999\u7528 \u7531\u4e8e Latin-1 \u8986\u76d6\u4e86\u6240\u6709\u7684 256 \u4e2a char \u7684\u53ef\u80fd\u503c\uff0c\u4efb\u4f55\u5b57\u8282\u6d41\u90fd\u53ef\u4ee5\u6210\u529f\u89e3\u7801\u3002 GBK \u548c UTF-8 \u6709\u81ea\u7ea0\u9519\u6027\uff0c\u6709\u4e9b\u8f93\u5165\u4f1a\u88ab\u584c\u7f29\u6210\u9519\u8bef\u201c\ufffd\u201d\u3002Latin-1 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u7167\u5355\u5168\u6536\uff01 \u56e0\u6b64\u6709\u65f6\uff0c\u4eba\u4eec\u53ef\u4ee5\u6b3a\u9a97\u4e00\u4e2a\u7f16\u7801\u5668\u8bf4\u201c\u6211\u91c7\u7528\u7684\u5b57\u7b26\u7f16\u7801\u662f Latin-1\u201d\uff01\u8fd9\u6837\u7f16\u7801\u5668\u5c31\u4e0d\u4f1a\u5bf9\u8f93\u5165\u7684\u5b57\u8282\u6d41\u505a\u4efb\u4f55\u8f6c\u6362\uff0c\u4ece\u800c\u53ef\u4ee5\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5f53\u6587\u672c\u6765\u4f20\uff0c\u89e3\u7801\u65f6\u4e5f\u6307\u5b9a Latin-1\uff0c\u539f\u539f\u672c\u672c\u7684\u53d6\u51fa\u6570\u636e\u3002 Base64 \u9632\u4e71\u7801 \u5982\u679c\u8981\u628a\u4e00\u4e32\u4e2d\u6587\u8f93\u5165\u4e00\u4e2a\u4e0d\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\uff0c\u53d1\u9001\u8ba9\u5bf9\u65b9\u6536\u5230\uff0c\u600e\u4e48\u529e\uff1f \u53ef\u4ee5\u7528 Latin-1 \u7f16\u7801\uff0c\u9a97\u8fd9\u4e2a\u8f6f\u4ef6\uff0c\u8ba9\u4ed6\u4ee5\u4e3a\u81ea\u5df1\u6536\u5230\u7684\u662f Latin-1 \u5b57\u7b26\u4e32\uff0c\u53cd\u6b63\u4ed6\u4e5f\u4e0d\u770b\u5185\u5bb9\uff0c\u4ece\u800c\u8ba9\u4ed6\u4e0d\u8981\u505a\u4efb\u4f55\u8f6c\u6362\u64cd\u4f5c\u3002 \u4e0d\u8fc7\u6709\u65f6\u5019\uff0c\u6587\u672c\u6846\u65e0\u6cd5\u8f93\u5165\u90e8\u5206\u7279\u6b8a\u7684\u63a7\u5236\u5b57\u7b26\uff0c\u800c UTF-8 \u5b57\u7b26\u4e32\u7f16\u7801\u51fa\u6765\u7684\u6587\u672c\uff0c\u8d85\u8fc7 0x80 \u7684\u90e8\u5206\uff0c\u53ef\u80fd\u843d\u5165 Latin-1 \u7684\u63a7\u5236\u5b57\u7b26\u4e2d\uff0c\u88ab\u8fd9\u4e2a\u8f6f\u4ef6\u9519\u8bef\u5730\u505a\u4e86\u7279\u6b8a\u5904\u7406\u3002 \u4e3a\u4e86\u907f\u514d\u53ea\u517c\u5bb9\u4e86 ASCII \u7684\u843d\u540e\u8f6f\u4ef6\u7834\u574f\u6211\u4eec\u7684\u5b57\u7b26\uff0c\u5bf9\u4e8e\u8fd9\u79cd\u53ea\u652f\u6301 ASCII \u6587\u672c\u7684\u7f16\u8f91\u6846\uff0c\u6211\u4eec\u53ef\u4ee5\u7528 Base64 \u7f16\u7801\u5148\u628a\u4efb\u610f\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u3002 Base64 \u662f\u4e00\u79cd\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u7684\u7b97\u6cd5\uff0c\u539f\u7406\u5f88\u7b80\u5355\uff0c\u5c31\u662f\u628a\u6bcf 6 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u8f6c\u6362\u4e3a\u4e00\u4e2a\u53ef\u6253\u5370\u7684 ASCII \u5b57\u7b26\uff08\u7528 A-Z a-z 0-9 - / \u8fd9 64 \u4e2a\u5b57\u7b26\u8868\u793a\uff09\u3002\u56e0\u6b64\uff0cBase64 \u7f16\u7801\u540e\u7684\u6587\u672c\uff0c\u6bcf 4 \u4e2a\u5b57\u7b26\u5c31\u6709 3 \u4e2a\u662f\u6709\u6548\u5b57\u7b26\uff0c\u5269\u4e0b\u7684 1 \u4e2a\u5b57\u7b26\u662f\u586b\u5145\u5b57\u7b26 = \u3002 \u4f8b\u5982\uff0c\u5b57\u7b26\u4e32 \"\u5c0f\u5f6d\u8001\u5e08\" \uff0c\u4f60\u53ef\u80fd\u60f3\u8981\u628a\u5b83\u901a\u8fc7\u90ae\u4ef6\u53d1\u51fa\u53bb\u3002\u800c\u8fd9\u4e2a\u90ae\u4ef6\u670d\u52a1\u5668\u4e0d\u652f\u6301 UTF-8 \u4e5f\u4e0d\u652f\u6301 GBK\uff0c\u53ea\u652f\u6301 ASCII\uff01 \u9996\u5148\u6211\u4eec\u7528 UTF-8 \u7f16\u7801\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff1a 0xE5 0xB0 0x8F 0xE5 0xBD 0xAD 0xE8 0x80 0x81 0xE5 0xB8 0x88 \u7136\u540e\u518d\u7528 Base64 \u4e8c\u6b21\u7f16\u7801\u6210\u666e\u901a\u7684\u53ef\u6253\u5370\u5b57\u6bcd\u548c\u6570\u5b57\u5e8f\u5217\uff1a 5bCP5b2t6ICB5biI \u5bf9\u65b9\u6536\u5230\u8fd9\u4e32\u795e\u79d8\u5b57\u7b26\u540e\uff0c\u518d\u7528 base64 \u89e3\u7801\uff0c\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c\u518d\u7528\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\u89e3\u7801\uff0c\u5c31\u80fd\u770b\u5230\u672c\u6765\u7684\u4e2d\u6587\u4e86\u3002 # \u53d1\u9001\u8005\uff1a import base64 secret = base64.b64encode(\"\u5c0f\u5f6d\u8001\u5e08\".encode()) # \u63a5\u6536\u8005\uff1a base64.b64decode(secret).decode() \u8fd9\u4e2a\u65b9\u6cd5\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u7801 UTF-8 \u5b57\u7b26\u4e32\uff0c\u8fd8\u53ef\u4ee5\u4f20\u8f93\u4efb\u610f\u975e\u6587\u672c\u7684\u6587\u4ef6\uff01\u4f8b\u5982\uff0c\u6709\u4eba\u5229\u7528 Base64 \u7f16\u7801\uff0c\u628a jpg \u56fe\u50cf\u6587\u4ef6\u76f4\u63a5\u5185\u5d4c\u5728 md \u6587\u4ef6\u91cc\uff01\uff08md \u6587\u4ef6\u53ea\u652f\u6301\u5305\u542b\u5408\u6cd5\u7684 UTF-8 \u6587\u672c\uff0c\u4e0d\u53ef\u80fd\u5305\u542b jpg \u7684\u4efb\u610f\u5b57\u8282\u6d41\uff0c\u56e0\u6b64\u53ea\u80fd\u7528 Base64 \u5148\u7f16\u7801\u6210 ASCII \u8303\u56f4\u5185\u7684\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u9632\u6b62 md \u7f16\u8bd1\u5668\u62a5 UTF-8 \u89e3\u7801\u9519\u8bef\uff09 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u8f93\u5165\u4e2d\u6587\u5b9e\u5728\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u8003\u8651\u5148 Base64 \u8f6c\u6362\u6210\u7eaf\u82f1\u6587\u8bd5\u8bd5\u770b\uff0c\u53cd\u6b63\u65e0\u8bba\u8c01\u90fd\u517c\u5bb9 ASCII\u3002\u5982\u679c\u8fd9\u4e2a\u6587\u672c\u6846\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff0c\u8fd8\u53ef\u4ee5\u8bd5\u8bd5\u770b\u53ea\u6709 A-Z 0-9 \u7684 Base32 \u7f16\u7801\u3002 UTF-7 TODO \u5b57\u7b26\u7f16\u7801\u731c\u6d4b TODO","title":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b"},{"location":"unicode/#_1","text":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b \u5b57\u7b26\u96c6 ASCII Latin-1 Unicode \u603b\u7ed3 \u5b57\u7b26\u7f16\u7801 UTF-32 UTF-8 \u517c\u5bb9 ASCII \u89e3\u7801\u89c4\u5219 UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b \u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d UTF-16 \u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89 BOM \u6807\u8bb0 GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb GB2312 GB2312 \u7684\u7f3a\u9677 GBK GB18030 \u603b\u7ed3 C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c \u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48 \u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a \u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae \u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6 \u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a .utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684 \u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528 \u9009\u62e9\u4f60\u7684\u9635\u8425\uff01 ANSI \u9635\u8425 UTF-8 \u9635\u8425 UTF-16 \u9635\u8425 UTF-32 \u9635\u8425 \u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362 \u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp \u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale UTF \u4e4b\u95f4\u4e92\u8f6c GBK \u548c UTF \u4e92\u8f6c UTF \u548c ANSI \u4e92\u8f6c \u5927\u603b\u7ed3 GBK \u548c Shift-JIS \u4e92\u8f6c \u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5 \u66f4\u591a\u529f\u80fd\uff1f\uff01 Windows \u7528\u6237\uff1aMultiByteToWideChar MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b Linux \u7528\u6237\uff1aiconv iconv \u547d\u4ee4\u884c\u5de5\u5177 \u672c\u5730\u5316 (locale) \u533a\u5206\u5b57\u7b26\u7c7b\u578b \u5bbd\u5b57\u7b26\u7c7b\u578b wchar_t \u5e94\u7528\u6848\u4f8b \u533a\u57df\u8bbe\u7f6e\u4e0e locale locale \u7684\u547d\u540d\u89c4\u8303 \u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32 \u7279\u6b8a locale\uff1a\"C\" LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801 LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316 std::locale \u5bf9\u8c61 boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale \u5bbd\u5b57\u7b26\u6d41 \u5b98\u65b9\u773c\u4e2d\u7684 std::wstring std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528 std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string \u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01 std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6 locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570 C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 Windows \u4e13\u9898 Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570 TCHAR \u6d41\u6d3e UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165 \u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76 Qt QString QTextCodec from/toLocal8Bits/Utf8/Latin1/Ascii \u5b57\u7b26\u4e32\u5e38\u91cf QTextStream Python 3 str Rust &str \u548c String Java String COW \u5b57\u7b26\u4e32 Unicode \u77e5\u8bc6\u8fdb\u9636 \u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97 Grapheme \u6b63\u89c4\u5316 \u96f6\u5bbd\u7a7a\u683c \u7279\u6b8a\u63a7\u5236\u5b57\u7b26 \u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26 UniFont \u5b57\u4f53 \u9ed1\u6697\u5c0f\u6280\u5de7 \u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f Latin-1 \u7684\u8f6c\u6362 Latin-1 \u7684\u5999\u7528 Base64 \u9632\u4e71\u7801 UTF-7 \u5b57\u7b26\u7f16\u7801\u731c\u6d4b","title":"\u5b57\u7b26\u7f16\u7801\u90a3\u4e9b\u4e8b"},{"location":"unicode/#_2","text":"\u8ba1\u7b97\u673a\u4e0d\u80fd\u76f4\u63a5\u5b58\u50a8\u5b57\u7b26\uff0c\u800c\u662f\u7528\u6570\u5b57\u6765\u4ee3\u66ff\uff0c\u8fd9\u5c31\u662f\u5b57\u7b26\u96c6\uff0c\u4e3a\u6bcf\u4e2a\u5b57\u7b26\u6307\u5b9a\u4e00\u4e2a\u6570\u5b57\u3002","title":"\u5b57\u7b26\u96c6"},{"location":"unicode/#ascii","text":"ASCII \u4e3a\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u7ec4\u3001\u6807\u70b9\u7b26\u53f7\u7b49 128 \u4e2a\u5b57\u7b26\uff0c\u6bcf\u4e2a\u90fd\u7528\u4e00\u4e2a 0 \u5230 127 \u8303\u56f4\u5185\u7684\u6570\u5b57\u5bf9\u5e94\u3002 \u5982\u679c\u4f60\u60f3\u8981\u8868\u793a\u4e00\u4e2a\u5b57\u7b26\uff0c\u5c31\u5728\u8fd9\u4e2a\u8868\u91cc\u5bfb\u627e\u5230\u76f8\u5e94\u7684\u6570\u5b57\u7f16\u53f7\uff0c\u7136\u540e\u5b58\u8fd9\u4e2a\u7f16\u53f7\u5373\u53ef\u3002 \u4f8b\u5982\u4e0b\u9762\u7684\u4e00\u4e32\u6570\u5b57\uff1a 80 101 110 103 \u5728 ASCII \u8868\u4e2d\u67e5\u627e\uff0c\u53d1\u73b0\u8fd9\u4e9b\u6570\u5b57\u5206\u522b\u5bf9\u5e94 P \u3001 e \u3001 n \u3001 g \u56db\u4e2a\u5b57\u6bcd\uff0c\u8fde\u8d77\u6765\u5c31\u8fd8\u539f\u5f97\u5230\u4e86\u539f\u672c\u7684\u5b57\u7b26\u4e32\u201cPeng\u201d\u3002","title":"ASCII"},{"location":"unicode/#latin-1","text":"Latin-1 \u6269\u5145\u4e86 ASCII \u5b57\u7b26\u96c6\uff0c\u4fdd\u6301 ASCII \u539f\u6709 0 \u5230 127 \u7684\u90e8\u5206\u6620\u5c04\u4e0d\u53d8\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 128 \u5230 255 \u7684\u6620\u5c04\u5173\u7cfb\u3002\u56e0\u6b64\u4e5f\u88ab\u79f0\u4e3a EASCII\uff08\u6269\u5c55 ASCII\uff09\u3002","title":"Latin-1"},{"location":"unicode/#unicode","text":"Unicode \u5b57\u7b26\u96c6\u4e3a\u5168\u4e16\u754c\u7684\u6240\u6709\u5b57\u7b26\u90fd\u5bf9\u5e94\u4e86\u4e00\u4e2a\u6574\u6570\u3002 \u5b57\u7b26 \u7f16\u53f7 \u6211 25105 \u6212 25106 \u6213 25107 \u6214 25108 \u6215 25109 \u6216 25110 \u6217 25111 \u6218 25112 \u6219 25113 \u621a 25114 \u51fa\u4e8e\u5386\u53f2\u517c\u5bb9\u6027\u8003\u8651\uff0cUnicode \u5728 0 \u5230 256 \u533a\u95f4\u5185\u7684\u6620\u5c04\u548c ASCII\u3001Latin-1 \u662f\u5b8c\u5168\u76f8\u540c\u7684\u3002 \u5b57\u7b26 \u7f16\u53f7 P 80 e 101 n 110 g 103 Unicode \u7ecf\u8fc7\u4e86\u8bb8\u591a\u7248\u672c\u7684\u53d1\u5c55\uff0c\u65e9\u671f\u7684 Unicode \u53ea\u6536\u5f55\u4e86 65536 (0x10000) \u4e2a\u5b57\u7b26\uff0c\u540e\u6765\u6269\u5145\u5230\u4e86 1114112 (0x110000) \u4e2a\u5b57\u7b26\u3002 \u603b\u4e4b\uff0c\u73b0\u5728 Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u867d\u7136\u5360\u7528\u4e86 1114112 \u8fd9\u591a\u683c\u7801\u70b9\u7a7a\u95f4\uff0c\u4e0d\u8fc7\u5176\u4e2d\u5f88\u591a\u90fd\u662f\u7a7a\u53f7\uff0c\u7559\u5f85\u672a\u6765\u6269\u5145\u4f7f\u7528\u3002 Unicode \u5b57\u7b26\u6620\u5c04\u8868\u53ef\u4ee5\u5728\u7f51\u4e0a\u627e\u5230\uff1a https://symbl.cc/en/unicode-table/ https://www.compart.com/en/unicode/","title":"Unicode"},{"location":"unicode/#_3","text":"\u5b57\u7b26\u96c6: \u4ece\u5b57\u7b26\u5230\u6574\u6570\u7684\u4e00\u4e00\u6620\u5c04\u3002 ASCII: \u53ea\u6536\u5f55\u4e86\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 Latin-1: \u5728 ASCII \u57fa\u7840\u4e0a\u8ffd\u52a0\u4e86\u6ce8\u97f3\u5b57\u6bcd\uff0c\u6ee1\u8db3\u6b27\u6d32\u7528\u6237\u9700\u8981\u3002 Unicode: \u6536\u5f55\u4e86\u5168\u4e16\u754c\u6240\u6709\u6587\u5b57\u548c\u7b26\u53f7\u7684\u5b57\u7b26\u96c6\u3002 \u8ba1\u7b97\u673a\u5b58\u50a8\u5b57\u7b26\u65f6\uff0c\u5b9e\u9645\u4e0a\u662f\u5b58\u50a8\u4e86\u90a3\u4e2a\u5bf9\u5e94\u7684\u6574\u6570\u3002 \u8fd9\u4e9b\u6574\u6570\u5c31\u88ab\u79f0\u4e3a \u7801\u70b9 (code point) \uff0c\u6bcf\u4e2a\u5b57\u7b26\u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002 \u4e0d\u8fc7\uff0c\u7a0b\u5e8f\u5458\u901a\u5e38\u559c\u6b22\u7528\u5341\u516d\u8fdb\u5236\u4e66\u5199\u6570\u5b57\uff1a \u5b57\u7b26 \u7f16\u53f7 \u6211 0x6211 \u6212 0x6212 \u6213 0x6213 \u6214 0x6214 \u6215 0x6215 \u6216 0x6216 \u6217 0x6217 \u6218 0x6218 \u6219 0x6219 \u621a 0x621A \u4f8b\u5982\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\uff0c\u5728 Unicode \u8868\u4e2d\u7f16\u53f7\u4e3a 0x6211\u3002\u4e8e\u662f\u5f53\u8ba1\u7b97\u673a\u9700\u8981\u8868\u793a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\u65f6\uff0c\u5c31\u7528 0x6211 \u8fd9\u4e2a\u6574\u6570\u4ee3\u66ff\u3002 \u5982\u679c\u8981\u8868\u793a\u591a\u4e2a\u5b57\u7b26\uff0c\u90a3\u5c31\u7528\u4e00\u4e2a\u6574\u6570\u7684\u6570\u7ec4\u5427\uff01 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5904\u7406\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a 0x6211 0x7231 0x30EDE 0x30EDE 0x9762 0x21 \u8fd9\u4e00\u4e32\u6570\u5b57\u4ee3\u66ff\u3002 \u5982\u679c\u4f60\u8fd9\u91cc\u770b\u5230\u7684\u662f\u201c\u6211\u7231\u53e3\u53e3\u9762!\u201d\u8bf4\u660e\u4f60\u7684\u5b57\u4f53\u4e0d\u652f\u6301\u201cbi\u00e1ng\u201d\u8fd9\u4e2a\u5b57\u3002\u5f53\u6d4f\u89c8\u5668\u9047\u5230\u5f53\u524d\u5b57\u4f53\u4e0d\u652f\u6301\u7684 Unicode \u5b57\u7b26\u65f6\uff0c\u5c31\u4f1a\u66ff\u6362\u4e3a\u65b9\u5757\u3002\u5efa\u8bae\u5b89\u88c5\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u8f83\u591a\u7684 \u201cNoto Sans CJK SC\u201d \u5b57\u4f53\uff0c\u4e5f\u53ef\u4ee5\u5b89\u88c5\u652f\u6301\u4e00\u5207 Unicode \u5b57\u7b26\u7684 \u201cUniFonts\u201d\u3002 sudo apt-get install -y fonts-noto-cjk \u201c\ud883\udede(bi\u00e1ng)\ud883\udede(bi\u00e1ng)\u9762\u201d\u662f\u6d41\u884c\u4e8e\u4e2d\u56fd\u9655\u897f\u5173\u4e2d\u5730\u533a\u7684\u4e00\u79cd\u77e5\u540d\u4f20\u7edf\u98ce\u5473\u9762\u98df\uff0c\u5c5e\u4e8e\u626f\u9762\uff0c\u901a\u8fc7\u63c9\u3001\u62bb\u3001\u7529\u3001\u626f\u7b49\u6b65\u9aa4\u5236\u4f5c\uff0c\u9762\u5bbd\u800c\u539a\uff0c\u72b9\u5982\u201c\u88e4\u8170\u5e26\u201d\uff0c\u53e3\u611f\u52b2\u9053\uff0c\u98df\u7528\u524d\u52a0\u5165\u5404\u8272\u81ca\u5b50\u6216\u6cb9\u6cfc\u8fa3\u5b50\u3002\u4f46\u662f\uff0c\u5c0f\u5f6d\u8001\u5e08\u5176\u5b9e\u5e76\u6ca1\u6709\u5403\u8fc7\uff0c\u53ea\u662f\u56e0\u4e3a\u7a00\u6709\u5b57\u4f53\u770b\u8d77\u6765\u6bd4\u8f83\u597d\u73a9\u3002","title":"\u603b\u7ed3"},{"location":"unicode/#_4","text":"Unicode \u53ea\u662f\u6307\u5b9a\u4e86\u6574\u6570\uff0c\u6ca1\u6709\u89c4\u5b9a\u6574\u6570\u5982\u4f55\u5728\u5185\u5b58\u4e2d\u5b58\u5728\u3002 \u5b57\u7b26\u7f16\u7801: \u5c06\u5b57\u7b26\u7684\u6574\u6570\u7f16\u53f7\u5e8f\u5217\u5316\u4e3a\u8ba1\u7b97\u673a\u53ef\u76f4\u63a5\u5b58\u50a8\u7684\u4e00\u4e2a\u6216\u591a\u4e2a\u5b9e\u9645\u5b58\u5728\u7684\u6574\u6570\u7c7b\u578b\u3002 Unicode \u5b57\u7b26\u53ef\u4ee5\u9009\u7528\u4ee5\u4e0b\u8fd9\u4e9b\u5b57\u7b26\u7f16\u7801\u6765\u5e8f\u5217\u5316\uff1a UTF-32: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u4e2a uint32_t \u6574\u6570\u5b58\u50a8\u3002 UTF-16: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 2 \u4e2a uint16_t \u6574\u6570\u5b58\u50a8\u3002 UTF-8: \u6bcf\u4e2a Unicode \u5b57\u7b26\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u5b58\u50a8\u3002 \u7ffb\u8bd1\u51fa\u6765\u7684\u8fd9\u4e9b\u5c0f\u6574\u6570\u53eb \u7801\u4f4d (code unit) \u3002\u4f8b\u5982\u5bf9\u4e8e UTF-8 \u800c\u8a00\uff0c\u6bcf\u4e2a uint8_t \u5c31\u662f\u4ed6\u7684\u7801\u4f4d\u3002","title":"\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#utf-32","text":"Unicode \u5b57\u7b26\u6620\u5c04\u7684\u6574\u6570\u8303\u56f4\u662f 0x0 \u5230 0x10FFFF\u3002 \u6700\u5927\u503c 0x10FFFF \u6709 21 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0cC \u8bed\u8a00\u4e2d uint32_t \u80fd\u5bb9\u7eb3 32 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\uff0c\u6240\u4ee5\u6700\u7b80\u5355\u7684\u65b9\u6cd5\u662f\u76f4\u63a5\u7528 uint32_t \u6570\u7ec4\u6765\u4e00\u4e2a\u4e2a\u5bb9\u7eb3 Unicode \u5b57\u7b26\u7801\u70b9\u3002\u867d\u7136\u6d6a\u8d39\u4e86 11 \u4f4d\uff0c\u4f46\u81f3\u5c11\u6240\u6709 Unicode \u5b57\u7b26\u90fd\u80fd\u5b89\u5168\u5bb9\u7eb3\u3002 \u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff0c\u5c31\u53ef\u4ee5\u7528\uff1a std::vector s = { 0x00006211, // \u6211 0x00007231, // \u7231 0x00030EDE, // \ud883\udede 0x00030EDE, // \ud883\udede 0x00009762, // \u9762 0x00000021, // ! }; \u8fd9\u4e2a\u6570\u7ec4\u8868\u793a\u3002 UTF-32 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u56fa\u5b9a\u5bf9\u5e94\u4e00\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-32 \u662f \u5b9a\u957f\u7f16\u7801 \u3002\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u5c31\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002 \u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u53ef\u4ee5\u76f4\u63a5\u7528\u6570\u7ec4\u7684\u7d22\u5f15\u64cd\u4f5c\u3002 \u65e0\u8bba\u5bf9\u6570\u7ec4\u5982\u4f55\u5207\u7247\uff0c\u90fd\u4e0d\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u7834\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u5c31\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u53cd\u8f6c\uff0c\u4e0d\u4f1a\u4ea7\u751f\u7834\u574f\u5b57\u7b26\u7684\u95ee\u9898\u3002 \u7f3a\u70b9\u662f\uff1a \u6d6a\u8d39\u5b58\u50a8\u7a7a\u95f4\u3002 \u5b9a\u957f\u7f16\u7801\u5f88\u65b9\u4fbf\uff0c\u6211\u4eec\u63a8\u8350\u5728\u8ba1\u7b97\u673a\u5185\u5b58\u4e2d\uff0c\u7edf\u4e00\u91c7\u7528 UTF-32 \u5f62\u5f0f\u5904\u7406\u6587\u5b57\u3002 UTF-32 \u4e5f\u88ab\u79f0\u4e3a UCS-4\uff0c\u4ed6\u4fe9\u662f\u540c\u4e49\u8bcd\u3002","title":"UTF-32"},{"location":"unicode/#utf-8","text":"UTF-32 \u867d\u7136\u65b9\u4fbf\u4e86\u6587\u5b57\u5904\u7406\uff0c\u7136\u800c\uff0c\u5374\u6d6a\u8d39\u4e86\u5927\u91cf\u7684\u5b58\u50a8\u7a7a\u95f4\uff0c\u4e0d\u5229\u4e8e\u6587\u5b57\u5b58\u50a8\uff01\u4e00\u4e2a\u5b57\u7b26\uff0c\u65e0\u8bba\u4ed6\u662f\u5e38\u7528\u8fd8\u662f\u4e0d\u5e38\u7528\uff0c\u90fd\u8981\u9738\u5360 4 \u4e2a\u5b57\u8282\u7684\u7a7a\u95f4\u3002 Unicode \u7f16\u7801\u5b57\u7b26\u65f6\uff0c\u7279\u610f\u628a\u5e38\u7528\u7684\u5b57\u7b26\u9760\u524d\u6392\u5217\u4e86\u3002 \u4e16\u754c\u4e0a\u5e38\u7528\u8bed\u8a00\u6587\u5b57\u90fd\u88ab\u523b\u610f\u7f16\u7801\u5728\u4e86 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u8d85\u8fc7 0x10000 \u7684\u57fa\u672c\u90fd\u662f\u4e0d\u5e38\u7528\u7684\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\uff0c\u5f88\u591a\u90fd\u662f\u5df2\u7ecf\u65e0\u4eba\u4f7f\u7528\u7684\u53e4\u4ee3\u6587\u5b57\u548c\u751f\u50fb\u5b57\uff0c\u4f8b\u5982\u201c\ud883\udede\u201d\u3002\u4ec5\u4ec5\u662f\u4e3a\u4e86\u8fd9\u4e9b\u5076\u5c14\u4f7f\u7528\u7684\u7f55\u89c1\u6587\u5b57\uff0c\u5c31\u8981\u6c42\u6240\u6709\u6587\u5b57\u90fd\u7528\u540c\u6837\u7684 4 \u5b57\u8282\u5bbd\u5ea6\u5b58\u50a8\uff0c\u5b9e\u5728\u662f\u6709\u70b9\u6d6a\u8d39\u3002 \u5728 0 \u5230 0xFFFF \u533a\u95f4\u5185\uff0c\u540c\u6837\u6709\u6309\u7167\u5e38\u7528\u5ea6\u6392\u5e8f\uff1a 0 \u5230 0x7F \u662f\uff08\u6b27\u7f8e\u7528\u6237\uff09\u6700\u5e38\u7528\u7684\u82f1\u6587\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u534a\u89d2\u6807\u70b9\u3002 0x80 \u5230 0x7FF \u662f\u8868\u97f3\u6587\u5b57\u533a\uff0c\u5e38\u7528\u7684\u6ce8\u97f3\u5b57\u6bcd\u3001\u62c9\u4e01\u5b57\u6bcd\u3001\u5e0c\u814a\u5b57\u6bcd\u3001\u897f\u91cc\u5c14\u5b57\u6bcd\u3001\u5e0c\u4f2f\u6765\u5b57\u6bcd\u7b49\u3002 0x800 \u5230 0xFFFF \u662f\u8868\u610f\u6587\u5b57\uff0c\u7b80\u7e41\u4e2d\u6587\u3001\u65e5\u6587\u3001\u97e9\u6587\u3001\u6cf0\u6587\u3001\u9a6c\u6765\u6587\u3001\u963f\u62c9\u4f2f\u6587\u7b49\u3002 0x10000 \u5230 0x10FFFF \u662f\u4e0d\u5e38\u7528\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f8b\u5982\u7532\u9aa8\u6587\u3001\u57c3\u53ca\u8c61\u5f62\u6587\u5b57\u3001Emoji \u7b49\u3002 UTF-8 \u5c31\u662f\u4e3a\u4e86\u89e3\u51b3\u538b\u7f29\u95ee\u9898\u800c\u8bde\u751f\u7684\u3002 UTF-8 \u628a\u4e00\u4e2a\u7801\u70b9\u5e8f\u5217\u5316\u4e3a\u4e00\u4e2a\u6216\u591a\u4e2a\u7801\u4f4d\uff0c\u4e00\u4e2a\u7801\u4f4d\u7528 1 \u81f3 4 \u4e2a uint8_t \u6574\u6570\u8868\u793a\u3002 0 \u5230 0x7F \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 1 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 2 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 3 \u4e2a\u5b57\u8282\u8868\u793a\u3002 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u7528 4 \u4e2a\u5b57\u8282\u8868\u793a\u3002 \u5e8f\u5217\u5316\u89c4\u5219\u5982\u4e0b\uff1a","title":"UTF-8"},{"location":"unicode/#ascii_1","text":"\u5bf9\u4e8e 0 \u5230 0x7F \u7684\u5b57\u7b26\uff0c\u8fd9\u4e2a\u8303\u56f4\u7684\u5b57\u7b26\u9700\u8981 7 \u4f4d\u5b58\u50a8\u3002 \u6211\u4eec\u9009\u62e9\u76f4\u63a5\u5b58\u50a8\u5176\u503c\u3002 \u4f8b\u5982 \u2018P\u2019 \u4f1a\u88ab\u76f4\u63a5\u5b58\u50a8\u5176 Unicode \u503c\u7684 80\uff080x50\uff09\uff1a 01010000 \u7531\u4e8e Unicode \u5728 0 \u5230 0x7F \u8303\u56f4\u5185\u4e0e ASCII \u8868\u76f8\u540c\uff0c\u800c UTF-8 \u53c8\u628a 0 \u5230 0x7F \u7684\u503c\u76f4\u63a5\u5b58\u50a8\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u517c\u5bb9 ASCII\u3002\u8fd9\u4f7f\u5f97\u539f\u672c\u8bbe\u8ba1\u4e8e\u5904\u7406 ASCII \u7684 C \u8bed\u8a00\u51fd\u6570\uff0c\u4f8b\u5982 strlen\u3001strcat\u3001sprintf \u7b49\uff0c\u90fd\u53ef\u4ee5\u76f4\u63a5\u65e0\u7f1d\u5207\u6362\u5230 UTF-8\u3002\u53cd\u4e4b\u4ea6\u7136\uff0c\u4efb\u4f55\u8bbe\u8ba1\u7528\u4e8e UTF-8 \u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u5b8c\u5168\u63a5\u53d7 ASCII \u683c\u5f0f\u7684\u8f93\u5165\u6587\u672c\u3002 \u4f46\u90e8\u5206\u6d89\u53ca\u5b57\u7b26\u957f\u5ea6\u7684\u51fd\u6570\u4f1a\u6709\u4e9b\u8bb8\u4e0d\u517c\u5bb9\uff0c\u4f8b\u5982 strlen \u6c42\u51fa\u7684\u957f\u5ea6\u4f1a\u53d8\u6210\u5b57\u8282\u7684\u6570\u91cf\u800c\u4e0d\u662f\u5b57\u7b26\u7684\u6570\u91cf\u4e86\uff0c\u4f8b\u5982 strlen(\"\u6211\u4eec\") \u4f1a\u5f97\u5230 6 \u800c\u4e0d\u662f 2\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002","title":"\u517c\u5bb9 ASCII"},{"location":"unicode/#_5","text":"UTF-8 \u7684\u6784\u9020\u5c31\u50cf\u4e00\u5217\u5c0f\u706b\u8f66\u4e00\u6837\uff0c\u4e0d\u540c\u8303\u56f4\u5185\u7684\u7801\u4f4d\u4f1a\u88ab\u7f16\u7801\u6210\u4e0d\u540c\u957f\u5ea6\u7684\u5217\u8f66\uff0c\u4f46\u4ed6\u4eec\u90fd\u6709\u4e00\u4e2a\u8f66\u5934\u3002 \u6839\u636e\u706b\u8f66\u5934\u7684\u201c\u7b49\u7ea7\u201d\uff0c\u6211\u4eec\u53ef\u4ee5\u63a8\u65ad\u51fa\u540e\u9762\u62c9\u7740\u51e0\u8282\u8f66\u53a2\u3002 \u706b\u8f66\u5934\u662f\u4ec0\u4e48\u7b49\u7ea7\u7531\u4ed6\u7684\u4e8c\u8fdb\u5236\u524d\u7f00\u51b3\u5b9a\uff1a \u5982\u679c\u662f 0 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u662f\u5355\u72ec\u4e00\u53f0\u706b\u8f66\u5934\uff0c\u540e\u9762\u6ca1\u6709\u8f66\u53a2\u4e86\uff0c\u8fd9\u8868\u793a\u8f66\u5934\u91cc\u9762\u76f4\u63a5\u88c5\u7740 0 \u5230 0x7F \u8303\u56f4\u7684\u666e\u901a ASCII \u5b57\u7b26\u3002 \u5982\u679c\u662f 110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e00\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x80 \u5230 0x7FF \u8303\u56f4\u5185\u7684\u6b27\u6d32\u5b57\u7b26\u3002 \u5982\u679c\u662f 1110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e24\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x800 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u4e16\u754c\u5e38\u7528\u5b57\u7b26\u3002 \u5982\u679c\u662f 11110 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u540e\u9762\u62d6\u7740\u4e09\u8282\u8f66\u53a2\uff0c\u91cc\u9762\u88c5\u7740 0x10000 \u5230 0x10FFFF \u8303\u56f4\u5185\u7684\u751f\u50fb\u5b57\u7b26\u3002 \u5982\u679c\u662f 10 \u5f00\u5934\uff0c\u5c31\u8bf4\u660e\u8fd9\u662f\u4e00\u8282\u8f66\u53a2\uff0c\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002\u5982\u679c\u4f60\u770b\u5230\u4e00\u8282\u5355\u72ec\u7684\u8f66\u53a2\u5728\u524d\u9762\u65e0\u5934\u9a7e\u9a76\uff0c\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\u3002 \u5c0f\u670b\u53cb\u7528\u5c0f\u53f7\u5217\u8f66\u88c5\uff0c\u5927\u670b\u53cb\u7528\u5927\u53f7\u5217\u8f66\u88c5\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u4e32\u4e8c\u8fdb\u5236\uff1a 11100110 10000010 10000001 \u9996\u5148\uff0c\u770b\u5230\u7b2c\u4e00\u4e2a\u5b57\u8282\uff0c\u662f 1110 \u5f00\u5934\u7684\u4e09\u7ea7\u8f66\u5934\uff01\u8bf4\u660e\u540e\u9762\u8fd8\u6709\u4e24\u8282\u8f66\u53a2\u662f\u5c5e\u4e8e\u4ed6\u7684\u3002\u706b\u8f66\u5934\u4e2d 4 \u4f4d\u7528\u4e8e\u8868\u793a\u8f66\u5934\u7b49\u7ea7\u4e86\uff0c\u5269\u4e0b\u8fd8\u6709 4 \u4f4d\u7528\u4e8e\u88c5\u4e58\u5ba2\u3002 \u8f66\u53a2\u4e5f\u6709\u56fa\u5b9a\u7684\u524d\u7f00\uff0c\u6240\u6709\u7684\u8f66\u53a2\u90fd\u5fc5\u987b\u662f 10 \u5f00\u5934\u7684\u3002\u53bb\u9664\u8fd9\u5f00\u5934\u7684 2 \u4f4d\uff0c\u5269\u4e0b\u7684 6 \u4f4d\u5c31\u662f\u4e58\u5ba2\u3002 \u5bf9\u4e8e\u8fd9\u79cd\u4e09\u7ea7\u5217\u8f66\uff0c4 + 6 + 6 \u603b\u5171 16 \u4f4d\u4e8c\u8fdb\u5236\uff0c\u521a\u597d\u53ef\u4ee5\u88c5\u5f97\u4e0b 0xFFFF \u5185\u7684\u4e58\u5ba2\u3002 0110 000010 000001 \u7f16\u7801\u65f6\u5219\u662f\u53cd\u8fc7\u6765\u3002 \u4e58\u5ba2\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e09\u7247\uff0c\u4f8b\u5982\u5bf9\u4e8e\u201c\u6211\u201d\u8fd9\u4e2a\u4e58\u5ba2\uff0c\u201c\u6211\u201d\u7684\u7801\u70b9\u662f 0x6211\uff0c\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u662f\uff1a 110001000010001 \u628a\u4e58\u5ba2\u5207\u5206\u6210\u9ad8 4 \u4f4d\u3001\u4e2d 6 \u4f4d\u548c\u4f4e 6 \u4f4d\uff08\u4e0d\u8db3\u65f6\u5728\u524d\u9762\u8865\u96f6\uff09\uff1a 0110 001000 010001 \u52a0\u4e0a 1110 \u3001 10 \u548c 10 \u524d\u7f00\u540e\uff0c\u5f62\u6210\u4e00\u5217\u706b\u8f66\uff1a 11100110 10001000 10010001 \u8fd9\u6837\uff0c\u6211\u4eec\u5c31\u628a\u201c\u6211\u201d\u8fd9\u4e2a\u5b57\u7b26\uff0c\u7f16\u7801\u6210\u4e86\u4e09\u8282\u5217\u8f66\uff0c\u585e\u8fdb\u5b57\u8282\u6d41\u7684\u7f51\u7edc\u96a7\u9053\u91cc\u4e86\u3002 \u603b\u7ed3\uff1a \u524d\u7f00\u662f 0 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 7 \u540d\u3002 \u524d\u7f00\u662f 10 \u7684\u662f\u8f66\u53a2\uff1a\u8f66\u53a2\u4e0d\u4f1a\u5355\u72ec\u51fa\u73b0\uff0c\u53ea\u4f1a\u8ddf\u5728\u706b\u8f66\u5934\u5c41\u80a1\u540e\u9762\u3002 \u524d\u7f00\u662f 110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 5 \u540d + 1 \u8282\u8f66\u53a2\u8f7d\u5ba2 6 \u540d = \u5171 11 \u540d\u3002 \u524d\u7f00\u662f 1110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 4 \u540d + 2 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 16 \u540d\u3002 \u524d\u7f00\u662f 11110 \u7684\u706b\u8f66\u5934\uff1a\u706b\u8f66\u5934\u76f4\u63a5\u8f7d\u5ba2 3 \u540d + 3 \u8282\u8f66\u53a2\u5404\u8f7d\u5ba2 6 \u540d = \u5171 21 \u540d\u3002 \u9ad8\u7ea7\u8f66\u5934\u88c5\u4e86\u9632\u5f39\u94a2\u677f\uff0c\u8f7d\u5ba2\u7a7a\u95f4\u53d8\u5c11\uff0c\u53ea\u597d\u5300\u5230\u540e\u9762\u7684\u8f66\u53a2\u3002","title":"\u89e3\u7801\u89c4\u5219"},{"location":"unicode/#utf-8_1","text":"\u5982\u679c\u53d1\u73b0 10 \u5f00\u5934\u7684\u72ec\u7acb\u8f66\u53a2\uff0c\u5c31\u8bf4\u660e\u51fa\u95ee\u9898\u4e86\uff0c\u53ef\u80fd\u662f\u706b\u8f66\u88ab\u9519\u8bef\u62e6\u8170\u622a\u65ad\uff0c\u4e5f\u53ef\u80fd\u662f\u5b57\u7b26\u4e32\u88ab\u9519\u8bef\u5730\u53cd\u8f6c\u3002\u56e0\u4e3a 10 \u53ea\u53ef\u80fd\u662f\u706b\u8f66\u8f66\u53a2\uff0c\u4e0d\u53ef\u80fd\u51fa\u73b0\u5728\u706b\u8f66\u5934\u90e8\u3002\u6b64\u65f6\u89e3\u7801\u5668\u5e94\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u66ff\u6362\u3002 10000010 10000001 \u5728\u7f51\u7edc\u6536\u53d1\u5305\u65f6\uff0c\u5982\u679c\u4f60\u4e0d\u59a5\u5584\u5904\u7406 TCP \u7c98\u5305\u95ee\u9898\uff0c\u5c31\u53ef\u80fd\u706b\u8f66\u5934\u8fdb\u53bb\u4e86\uff0c\u706b\u8f66\u5c3e\u5df4\u8fd8\u9732\u5728\u96a7\u9053\u5916\u9762\uff0c\u4e00\u6bb5\u5b8c\u6574\u7684\u5217\u8f66\u88ab\u5207\u65ad\uff0c\u5bfc\u81f4 UTF-8 \u89e3\u8bfb\u7684\u65f6\u5019\u51fa\u9519\u3002\u6b63\u786e\u7684\u505a\u6cd5\u662f\u8bbe\u7acb\u4e00\u4e2a\u72b6\u6001\u673a\u6765\u89e3\u7801 UTF-8\u3002C \u8bed\u8a00\u7684 mbstate_t \u5c31\u662f\u8fd9\u79cd\u72b6\u6001\u673a\uff0c\u7a0d\u540e\u8bb2\u89e3\u3002 \u9664\u6b64\u4e4b\u5916\uff0c\u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\uff0c\u5374\u53d1\u73b0\u91cc\u9762\u88c5\u7740 0x394 (\u201c\u0394\u201d)\uff0c\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u5c31\u80fd\u88c5\u4e0b\u7684\u6b27\u6d32\u5b57\u7b26\uff0c\u5374\u7528\u4e86\u4e09\u7ea7\u706b\u8f66\u5934\u88c5\uff0c\u8bf4\u660e\u88c5\u7bb1\u90a3\u8fb9\u7684\u4eba\u5077\u61d2\u6ee5\u7528\u8d44\u6e90\u4e86\uff01\u8fd9\u79cd\u60c5\u51b5\u4e0b UTF-8 \u89e3\u7801\u5668\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u8981\u4fdd\u8bc1\u7f16\u7801\u7684\u552f\u4e00\u6027\uff0c0x394 \u662f 0x7F \u5230 0x7FF \u8303\u56f4\u7684\uff0c\u5c31\u5e94\u8be5\u7528\u4e8c\u7ea7\u706b\u8f66\u5934\u88c5\u3002 \u4ee5\u53ca\uff0c\u5982\u679c\u53d1\u73b0 11111 \u5f00\u5934\u7684\u4e94\u7ea7\u706b\u8f66\u5934\uff0c\u4e5f\u8981\u62a5\u9519\uff0c\u56e0\u4e3a UTF-8 \u6700\u591a\u53ea\u652f\u6301\u56db\u7ea7\u706b\u8f66\u5934\u3002 \u5982\u679c\u68c0\u6d4b\u5230\u4e00\u4e2a\u56db\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u7684\u5b57\u7b26\u8303\u56f4\u8d85\u8fc7\u4e86 0x10FFFF\uff0c\u8fd9\u8d85\u51fa\u4e86 Unicode \u7684\u8303\u56f4\uff0c\u4e5f\u8981\u4ea7\u751f\u4e00\u4e2a\u62a5\u9519\u3002\u5982\u679c\u4e00\u4e2a\u4e09\u7ea7\u706b\u8f66\u5934\u62c6\u5f00\u540e\u53d1\u73b0\u5b57\u7b26\u8303\u56f4\u5904\u5728\u4fdd\u7559\u533a 0xD800 \u5230 0xDFFF \u5185\uff0c\u8fd9\u662f Unicode \u627f\u8bfa\u6c38\u4e0d\u52a0\u5165\u5b57\u7b26\u7684\u533a\u95f4\uff08\u7a0d\u540e\u8bb2\u89e3 UTF-16 \u65f6\u4f1a\u89e3\u91ca\u4e3a\u4ec0\u4e48\uff09\uff0c\u4e5f\u8981\u62a5\u9519\u3002\u603b\u4e4b Unicode \u7801\u70b9\u7684\u5408\u6cd5\u8303\u56f4\u662f 0x0 \u5230 0xD7FF\uff0c0xE000 \u5230 0x10FFFF\u3002 \u603b\u4e4b\uff0cUTF-8 \u5177\u6709\u4e00\u5b9a\u7684\u5197\u4f59\u548c\u81ea\u7ea0\u9519\u80fd\u529b\uff0c\u5982\u679c\u4f20\u8f93\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u5dee\u9519\uff0c\u53ef\u80fd\u4f1a\u7206\u51fa\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u3002\u8fd9\u4e2a\u7279\u6b8a\u5b57\u7b26\u662f Unicode \u5b98\u65b9\u89c4\u5b9a\u7684\uff0c\u7801\u70b9\u4e3a 0xFFFD\uff0c\u51fa\u73b0\u4ed6\u5c31\u610f\u5473\u7740 UTF-8 \u89e3\u7801\u5931\u8d25\u4e86\u3002","title":"UTF-8 \u7684\u6297\u5e72\u6270\u80fd\u529b"},{"location":"unicode/#_6","text":"\u4f8b\u5982\u5f53\u8ba1\u7b97\u673a\u8981\u4ee5 UTF-8 \u683c\u5f0f\u5b58\u50a8\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d\u8fd9\u6bb5\u6587\u5b57\uff1a std::vector s = { 0xE6, 0x88, 0x91, // \u6211\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xE7, 0x88, 0xB1, // \u7231\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xF0, 0xB0, 0xAF, 0x9B, // \ud883\udede\uff0c\u9700\u8981\u56db\u7ea7\u5217\u8f66 0xE9, 0x9D, 0xA2, // \u9762\uff0c\u9700\u8981\u4e09\u7ea7\u5217\u8f66 0x21, // !\uff0c\u8fd9\u662f\u4e2a ASCII \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u76f4\u63a5\u7528\u5355\u4e2a\u706b\u8f66\u5934\u88c5 }; UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u7801\u70b9\u53ef\u80fd\u5bf9\u5e94\u591a\u4e2a\u7801\u4f4d\uff0c\u6240\u4ee5\u8bf4 UTF-8 \u662f\u4e00\u79cd \u53d8\u957f\u7f16\u7801 \u3002\u53d8\u957f\u7f16\u7801\u7684\u7f3a\u70b9\u662f\uff1a \u6570\u7ec4\u7684\u957f\u5ea6\uff0c\u4e0d\u4e00\u5b9a\u662f\u5b57\u7b26\u4e32\u4e2d\u5b9e\u9645\u5b57\u7b26\u7684\u4e2a\u6570\u3002\u56e0\u6b64\uff0c\u8981\u53d6\u51fa\u5355\u4e2a\u5b57\u7b26\uff0c\u9700\u8981\u904d\u5386\u6570\u7ec4\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\u3002 \u6570\u7ec4\u7684\u5355\u4e2a\u5143\u7d20\u7d22\u5f15\uff0c\u65e0\u6cd5\u4fdd\u8bc1\u53d6\u51fa\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\u3002 \u5bf9\u6570\u7ec4\u7684\u5207\u7247\uff0c\u53ef\u80fd\u4f1a\u628a\u4e00\u4e2a\u72ec\u7acb\u7684\u5b57\u7b26\u5207\u574f\u3002 \u53cd\u8f6c\u6570\u7ec4\uff0c\u4e0d\u4e00\u5b9a\u80fd\u628a\u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\uff0c\u56e0\u4e3a\u53ef\u80fd\u4e0d\u614e\u628a\u4e00\u4e2a\u5b57\u7b26\u7684\u591a\u4e2a\u7801\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u5b57\u7b26\u7834\u574f\u3002 \u4f18\u70b9\u662f\uff1a \u8282\u7ea6\u5b58\u50a8\u7a7a\u95f4\u3002 \u6211\u4eec\u63a8\u8350\u53ea\u5728\u7f51\u7edc\u901a\u4fe1\u3001\u786c\u76d8\u5b58\u50a8\u65f6\uff0c\u91c7\u7528 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u6587\u5b57\u3002 \u603b\u7ed3\uff1a UTF-8 \u9002\u5408\u5b58\u50a8\uff0cUTF-32 \u9002\u5408\u5904\u7406 \u3002 \u6211\u4eec\u5efa\u8bae\u8ba1\u7b97\u673a\u4ece\u786c\u76d8\u6216\u7f51\u7edc\u4e2d\u8bfb\u51fa UTF-8 \u5b57\u7b26\u4e32\u540e\uff0c\u7acb\u5373\u5c06\u5176\u8f6c\u6362\u4e3a UTF-32\uff0c\u4ee5\u65b9\u4fbf\u540e\u7eed\u6587\u5b57\u5904\u7406\u3002\u5f53\u9700\u8981\u5199\u5165\u786c\u76d8\u6216\u7f51\u7edc\u65f6\uff0c\u518d\u8f6c\u6362\u56de UTF-8\uff0c\u907f\u514d\u786c\u76d8\u5bb9\u91cf\u548c\u7f51\u7edc\u5e26\u5bbd\u7684\u6d6a\u8d39\u3002 \u8ba1\u7b97\u673a\u9700\u8981\u5916\u7801\u548c\u5185\u7801\u4e24\u79cd\uff1a \u5916\u7801=\u786c\u76d8\u4e2d\u7684\u6587\u672c=UTF-8 \u5185\u7801=\u5185\u5b58\u4e2d\u7684\u6587\u672c=UTF-32","title":"\u201c\u6211\u7231\ud883\udede\ud883\udede\u9762!\u201d"},{"location":"unicode/#utf-16","text":"UTF-16 \u7684\u7b56\u7565\u662f\uff1a\u65e2\u7136\u5927\u591a\u6570\u5e38\u7528\u5b57\u7b26\u7684\u7801\u70b9\u90fd\u5728 0x0 \u5230 0xFFFF \u5185\uff0c\u7528 uint32_t \u6765\u5b58\u50a8\u4e5f\u592a\u6d6a\u8d39\u4e86\u3002\u4ed6\u7684\u65b9\u6848\u5982\u4e0b\uff1a \u5bf9\u4e8e 0x0 \u5230 0xFFFF \u8303\u56f4\u5185\u7684\u5b57\u7b26\uff0c\u5c31\u7528\u4e00\u4e2a uint16_t \u76f4\u63a5\u5b58\u3002 \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u53cd\u6b63\u4e0d\u5e38\u89c1\uff0c\u5c31\u62c6\u6210\u4e24\u4e2a uint16_t \u5b58\u3002\u8fd9\u4e2a\u62c6\u7684\u65b9\u6848\u5f88\u6709\u8bb2\u7a76\uff0c\u5982\u679c\u53ea\u662f\u666e\u901a\u7684\u62c6\uff0c\u7531\u4e8e\u89e3\u7801\u65f6\u6536\u5230\u7684\u662f\u4e2a\u6ca1\u5934\u6ca1\u5c3e\u7684\u5b57\u8282\u5e8f\u5217\uff0c\u65e0\u6cd5\u5206\u8fa8\u8fd9\u5230\u5e95\u662f\u4e24\u4e2a uint16_t \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u8fd8\u662f\u4e00\u4e2a uint16_t \u7684\u666e\u901a\u5b57\u7b26\u3002 \u4f8b\u5982\uff0c\u6211\u4eec\u628a\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u201c\ud883\udede\u201d\uff0c0x30EDE\u3002\u62c6\u6210\u4e24\u4e2a uint16_t \uff0c\u5f97\u5230 0x3 \u548c 0x0EDE\u3002\u5982\u679c\u76f4\u63a5\u5b58\u50a8\u8fd9\u4e24\u4e2a uint16_t \uff1a 0x0003 0x0EDE \u4e4b\u540e\u89e3\u7801\u65f6\uff0c\u5148\u8bfb\u5230 0x0003\uff0c\u8fd8\u4f1a\u4ee5\u4e3a\u4ed6\u662f\u5355\u72ec\u7684\u4e00\u4e2a uint16_t \uff0c\u8868\u793a 3 \u53f7\u5b57\u7b26\u201c\u201d\u3002\u540e\u9762\u7684 0x0EDE \u5c31\u53d8\u6210\u4e86\u4e00\u4e2a\u5355\u72ec\u7684 0x0EDE\uff0c\u53d8\u6210\u4e86 0x0EDE \u53f7\u5b57\u7b26 \u201c\u0ede\u201d\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u201c\ud883\udede\u201d\u5c31\u53d8\u6210\u4e86\u4e24\u4e2a\u6beb\u4e0d\u76f8\u5e72\u7684\u5b57\u7b26\uff0c\u201c\u0ede\u201d\u4e86\u3002 \u4e3a\u4e86\u907f\u514d\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u4e24\u4e2a uint16_t \u9700\u8981\u91c7\u7528\u4e00\u79cd\u7279\u6b8a\u7684\u65b9\u5f0f\u4ee5\u793a\u533a\u5206\u3002\u8ba9\u89e3\u7801\u5668\u4e00\u770b\u5230\uff0c\u5c31\u80fd\u786e\u5b9a\u8fd9\u4e24\u4e2a uint16_t \u9700\u8981\u7ec4\u88c5\u6210\u540c\u4e00\u4e2a\u5b57\u7b26\u3002 \u8fd9\u5c31\u7528\u5230\u4e86\u4e00\u4e2a\u201c\u6f0f\u6d1e\u201d\uff1aUnicode \u5e76\u6ca1\u6709\u628a\u7801\u70b9\u5206\u914d\u7684\u6ee1\u6ee1\u5f53\u5f53\uff0c\u6216\u8bb8\u662f\u51fa\u4e8e\u5148\u89c1\u4e4b\u660e\uff0c\u5728 0xD800 \u5230 0xDFFF \u4e4b\u95f4\u9884\u7559\u4e86\u4e00\u5927\u6bb5\u7a7a\u53f7\uff1a UTF-16 \u5c31\u662f\u5229\u7528\u4e86\u8fd9\u4e00\u6bb5\u7a7a\u95f4\uff0c\u4ed6\u89c4\u5b9a\uff1a0xD800 \u5230 0xDFFF \u4e4b\u95f4\u7684\u7801\u70b9\u5c06\u6c38\u8fdc\u4e0d\u7528\u6765\u8868\u793a\u5b57\u7b26\uff0c\u800c\u662f\u4f5c\u4e3a \u4ee3\u7406\u5bf9 (surrogate-pair) \u3002\u5176\u4e2d 0xD800 \u5230 0xDBFF \u662f \u9ad8\u4f4d\u4ee3\u7406 (high surrogate) \uff0c0xDC00 \u5230 0xDFFF \u662f \u4f4e\u4f4d\u4ee3\u7406 (low surrogate) \u3002\u9ad8\u4ee3\u7406\u5728\u524d\uff0c\u4f4e\u4ee3\u7406\u5728\u540e\u3002 \u4e00\u4e2a\u8d85\u8fc7 0xFFFF \u7684\u7a00\u6709\u5b57\u7b26\uff0c\u4f1a\u88ab\u62c6\u6210\u4e24\u6bb5\uff0c\u4e00\u6bb5\u653e\u5728\u9ad8\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u6bb5\u653e\u5728\u4f4e\u4f4d\u4ee3\u7406\u91cc\uff0c\u4e00\u524d\u4e00\u540e\u653e\u5165 uint16_t \u5e8f\u5217\u4e2d\u3002 \u642d\u8f7d\u8d85\u5bbd\u8d85\u9650\u8d27\u7269\u7684\u8f66\u8f86\u9700\u8981\u88ab\u62c6\u5206\u6210\u4e24\u6bb5\u518d\u8fdb\u5165\u96a7\u9053\u3002 \u5177\u4f53\u62c6\u5206\u65b9\u6cd5\u5982\u4e0b\uff1a \u5bf9\u4e8e 0xFFFF \u5230 0x10FFFF \u8303\u56f4\u7684\u7801\u70b9\uff0c\u9996\u5148\u5c06\u5176\u503c\u51cf\u53bb 0x10000\uff0c\u53d8\u6210\u4e00\u4e2a\u8303\u56f4 0x0 \u5230 0xFFFFF \u8303\u56f4\u5185\u7684\u6570\u5b57\uff0c\u8fd9\u80fd\u4fdd\u8bc1\u4ed6\u4eec\u53ea\u9700 20 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u5373\u53ef\u8868\u793a\u3002 \u4f8b\u5982\u201c\ud883\udede\u201d\u5bf9\u5e94\u7684\u7801\u70b9 0x30EDE\uff0c\u51cf\u53bb\u540e\u5c31\u53d8\u6210 0x20EDE\u3002 \u7136\u540e\uff0c\u5199\u51fa 0x20EDE \u7684\u4e8c\u8fdb\u5236\u8868\u793a\uff1a 00100000111011011110 \u603b\u5171 20 \u4f4d\uff0c\u6211\u4eec\u5c06\u5176\u62c6\u6210\u9ad8\u4f4e\u5404 10 \u4f4d\uff1a 0010000011 1011011110 \u5404\u81ea\u5199\u51fa\u76f8\u5e94\u7684\u5341\u516d\u8fdb\u5236\u6570\uff1a 0x083 0x2DE \u56e0\u4e3a\u6700\u591a\u53ea\u6709 10 \u4f4d\uff0c\u8fd9\u4e24\u4e2a\u6570\u90fd\u4f1a\u5728 0 \u5230 0x3FF \u7684\u8303\u56f4\u5185\u3002 \u800c 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u9884\u7559\u7684\u7a7a\u95f4\uff0c\u521a\u597d\u53ef\u4ee5\u5206\u522b\u5bb9\u7eb3 0x400 \u4e2a\u6570\uff01 \u6240\u4ee5\uff0c\u6211\u4eec\u5c06\u62c6\u5206\u51fa\u6765\u7684\u4e24\u4e2a 10 \u4f4d\u6570\uff0c\u5206\u522b\u52a0\u4e0a 0xD800 \u548c 0xDC00\uff1a 0xD800+0x083=0xD883 0xDC00+0x2DE=0xDFDE \u8fd9\u4e24\u4e2a\u6570\uff0c\u5fc5\u5b9a\u662f 0xD800 \u5230 0xDBFF\uff0c\u548c 0xDC00 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u6570\u3002\u800c\u8fd9\u4e24\u4e2a\u8303\u56f4\u90fd\u662f Unicode \u59d4\u5458\u4f1a\u9884\u7559\u7684\u4ee3\u7406\u5bf9\u533a\u95f4\uff0c\u7edd\u5bf9\u6ca1\u6709\u666e\u901a\u5b57\u7b26\u3002\u6240\u4ee5\uff0c\u751f\u6210\u7684\u4e24\u4e2a\u4ee3\u7406\u5bf9\u4e0d\u4f1a\u4e0e\u666e\u901a\u5b57\u7b26\u4ea7\u751f\u6b67\u4e49\uff0c\u53ef\u4ee5\u653e\u5fc3\u653e\u8fdb uint16_t \u6570\u7ec4\uff0c\u89e3\u7801\u5668\u5982\u679c\u68c0\u6d4b\u5230\u4ee3\u7406\u5bf9\uff0c\u5c31\u8bf4\u660e\u662f\u4e24\u8282\u8f66\u53a2\uff0c\u53ef\u4ee5\u653e\u5fc3\u8fde\u7eed\u8bfb\u53d6\u4e24\u4e2a uint16_t \u3002 \u6240\u4ee5\uff0c 0xD883 0xDFDE \u5c31\u662f\u201c\ud883\udede\u201d\u7528 UTF-16 \u7f16\u7801\u540e\u7684\u7ed3\u679c\u3002 \u4ee3\u7406\u5b57\u7b26\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684\u5b57\u7b26\uff0c\u5f53\u89e3\u7801\u5668\u68c0\u6d4b\u5230\u4e00\u4e2a 0xD800 \u5230 0xDBFF \u8303\u56f4\u5185\u7684\u9ad8\u4ee3\u7406\u65f6\uff0c\u5c31\u9884\u793a\u7740\u8fd8\u9700\u8981\u518d\u8bfb\u53d6\u4e00\u4e2a\u4f4e\u4ee3\u7406\uff0c\u624d\u80fd\u62fc\u63a5\u6210\u4e00\u4e2a\u7a00\u6709\u5b57\u7b26\u3002 \u5982\u679c\u63a5\u4e0b\u6765\u8bfb\u5230\u7684\u4e0d\u662f 0xDC00 \u5230 0xDFFF \u8303\u56f4\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u800c\u662f\u666e\u901a\u5b57\u7b26\u7684\u8bdd\uff0c\u90a3\u5c31\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u53ef\u80fd\u662f\u4e2d\u95f4\u88ab\u4eba\u4e22\u5305\u4e86\uff0c\u9700\u8981\u62a5\u9519\u6216\u8005\u7528\u9519\u8bef\u5b57\u7b26\u201c\ufffd\u201d\u9876\u66ff\u3002 \u53e6\u5916\uff0c\u5982\u679c\u8bfb\u5230\u4e86\u4e00\u4e2a\u5355\u72ec\u5b58\u5728\u7684 0xD800 \u5230 0xDFFF \u8303\u56f4\u5185\u7684\u4f4e\u4ee3\u7406\u5b57\u7b26\uff0c\u90a3\u4e5f\u8bf4\u660e\u51fa\u9519\u4e86\uff0c\u56e0\u4e3a\u4ee3\u7406\u5b57\u7b26\u53ea\u6709\u6210\u5bf9\u51fa\u73b0\u624d\u6709\u610f\u4e49\uff0c\u4f4e\u4ee3\u7406\u5b57\u7b26\u4e0d\u53ef\u80fd\u5355\u72ec\u5728\u5f00\u5934\u51fa\u73b0\u3002 \u53ef\u89c1\uff0cUTF-16 \u548c UTF-8 \u4e00\u6837\uff0c\u90fd\u662f\u201c\u5c0f\u706b\u8f66\u201d\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0cUTF-16 \u540c\u6837\u4e5f\u6709\u7740\u7c7b\u4f3c\u4e8e UTF-8 \u7684\u6297\u5e72\u6270\u673a\u5236\u3002","title":"UTF-16"},{"location":"unicode/#_7","text":"\u5728\u8ba1\u7b97\u673a\u4e2d\uff0c\u591a\u5b57\u8282\u7684\u6574\u6570\u7c7b\u578b\uff08\u5982 uint16_t \u548c uint32_t \uff09\u9700\u8981\u88ab\u62c6\u6210\u591a\u4e2a\u5b57\u8282\u6765\u5b58\u50a8\u3002\u62c6\u5f00\u540e\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u6309\u4ec0\u4e48\u987a\u5e8f\u5b58\u5165\u5185\u5b58\uff1f\u4e0d\u540c\u7684\u786c\u4ef6\u67b6\u6784\u4ea7\u751f\u4e86\u4e89\u6267\uff1a \u5927\u7aef\u6d3e (bit endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u4e5f\u5c31\u662f\u5927\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5c0f\u7aef\u6d3e (little endian)\uff1a\u4f4e\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u4f4e\u4f4d\uff0c\u9ad8\u5730\u5740\u5b58\u653e\u6574\u6570\u7684\u9ad8\u4f4d\uff0c\u4e5f\u5c31\u662f\u5c0f\u6570\u9760\u524d\uff01\u8fd9\u6837\u6570\u503c\u7684\u9ad8\u4f4d\u548c\u4f4e\u4f4d\u548c\u8ba1\u7b97\u673a\u7535\u8def\u7684\u8ba1\u7b97\u4e60\u60ef\u4e00\u81f4\u3002\u4f8b\u5982\uff0c0x12345678\uff0c\u5728\u5185\u5b58\u4e2d\u5c31\u662f\uff1a 0x78 0x56 0x34 0x12 \u4f8b\u5982\uff0cIntel \u7684 x86 \u67b6\u6784\u548c ARM \u516c\u53f8\u7684 ARM \u67b6\u6784\u90fd\u662f\u5c0f\u7aef\u6d3e\uff0c\u800c Motorola \u516c\u53f8\u7684 68k \u67b6\u6784\u548c Sun \u516c\u53f8\u7684 SPARC \u67b6\u6784\u90fd\u662f\u5927\u7aef\u6d3e\u3002 \u8fd9\u5176\u5b9e\u662f\u5f88\u65e0\u804a\u7684\u4e89\u6267\uff0c\u4e3a\u4eba\u7c7b\u7684\u4e66\u5199\u4e60\u60ef\u6539\u53d8\u8ba1\u7b97\u673a\u7684\u8bbe\u8ba1\u6beb\u65e0\u9053\u7406\uff0c\u6bd5\u7adf\u4e16\u754c\u4e0a\u4e5f\u6709\u4ece\u53f3\u5f80\u5de6\u4e66\u5199\u7684\u6587\u5b57\u548c\u4ece\u4e0a\u5f80\u4e0b\u4e66\u5199\u7684\u6587\u5b57\uff0c\u751a\u81f3\u6709\u5de6\u53f3\u6765\u56de\u4e66\u5199\u7684\u6587\u5b57\u2026\u2026\u5982\u679c\u8981\u4f3a\u5019\u4eba\u7c7b\uff0c\u4f60\u600e\u4e48\u4e0d\u6539\u6210\u5341\u8fdb\u5236\u5462\uff1f\u603b\u4e4b\uff0c\u6211\u8ba4\u4e3a\u5c0f\u7aef\u624d\u662f\u6700\u9002\u5408\u8ba1\u7b97\u673a\u7684\uff0c\u5e02\u9762\u4e0a\u5927\u591a\u6570\u4e3b\u6d41\u786c\u4ef6\u90fd\u662f\u5c0f\u7aef\u67b6\u6784\u3002 \u5728\u7f51\u7edc\u901a\u4fe1\u65f6\uff0c\u53d1\u6d88\u606f\u548c\u6536\u6d88\u606f\u7684\u53ef\u80fd\u662f\u4e0d\u540c\u7684\u67b6\u6784\uff0c\u5982\u679c\u53d1\u6d88\u606f\u7684\u662f\u5c0f\u7aef\u67b6\u6784\uff0c\u6536\u6d88\u606f\u7684\u662f\u5927\u7aef\u67b6\u6784\uff0c\u90a3\u4e48\u53d1\u51fa\u53bb\u7684\u662f 0x12345678\uff0c\u6536\u5230\u7684\u5c31\u4f1a\u53d8\u6210 0x78563421 \u4e86\u3002 \u56e0\u6b64\u4e92\u8054\u7f51\u4e00\u822c\u89c4\u5b9a\uff0c\u6240\u6709\u591a\u5b57\u8282\u7684\u6570\u636e\u5728\u7f51\u7edc\u5305\u4e2d\u7edf\u4e00\u91c7\u7528\u5927\u7aef\u3002\u5bf9\u4e8e\u5927\u7aef\u67b6\u6784\uff0c\u4ed6\u4eec\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u5bf9\u4e8e\u5c0f\u7aef\u67b6\u6784\uff0c\u5728\u53d1\u5305\u524d\u9700\u8981\u628a\u81ea\u5df1\u7684\u5c0f\u7aef\u6570\u636e\u505a\u5b57\u8282\u5e8f\u53cd\u8f6c\uff0c\u53d8\u6210\u5927\u7aef\u7684\u4ee5\u540e\uff0c\u518d\u53d1\u9001\u3002\u4e4b\u540e\u7684\u7f51\u7edc\u4e13\u9898\u8bfe\u4e2d\u6211\u4eec\u4f1a\u8be6\u89e3\u8fd9\u4e00\u5757\u3002 \u57fa\u4e8e\u5b57\u8282\u7801\u7684\u865a\u62df\u673a\u8bed\u8a00\u901a\u5e38\u4f1a\u89c4\u5b9a\u4e00\u4e2a\u5b57\u8282\u5e8f\uff1a\u50cf Java \u8fd9\u79cd\u9762\u5411\u4e92\u8054\u7f51\u8bed\u8a00\uff0c\u7d22\u6027\u4e5f\u89c4\u5b9a\u4e86\u7edf\u4e00\u91c7\u7528\u5927\u7aef\uff0c\u65e0\u8bba JVM \u8fd0\u884c\u5728\u5927\u7aef\u673a\u5668\u8fd8\u662f\u5c0f\u7aef\u673a\u5668\u4e0a\u3002\u8fd9\u4f7f\u5f97\u4ed6\u4e0e\u4e92\u8054\u7f51\u901a\u4fe1\u6bd4\u8f83\u65b9\u4fbf\uff0c\u800c\u5728 x86 \u548c ARM \u67b6\u6784\u4e0a\uff0c\u4e0e\u672c\u5730\u53ea\u63a5\u53d7\u5c0f\u7aef\u6570\u636e\u7684 API\uff0c\u4f8b\u5982 OpenGL\uff0c\u6c9f\u901a\u8f83\u4e3a\u56f0\u96be\uff0c\u9700\u8981\u505a\u989d\u5916\u7684\u5b57\u8282\u5e8f\u8f6c\u6362\u3002\u800c C# \u4e3b\u6253\u6e38\u620f\u4e1a\u52a1\uff08\u4f8b\u5982 Unity\uff09\uff0c\u9700\u8981\u8003\u8651\u6027\u80fd\uff0c\u6240\u4ee5\u89c4\u5b9a\u5168\u90e8\u91c7\u7528\u5c0f\u7aef\u3002\u4f5c\u4e3a\u5e95\u5c42\u7f16\u7a0b\u8bed\u8a00\u7684 C++ \u5219\u662f\u5165\u4e61\u968f\u4fd7\uff0c\u4f60\u7684\u786c\u4ef6\u662f\u4ec0\u4e48\u7aef\uff0c\u4ed6\u5c31\u662f\u4ec0\u4e48\u7aef\uff0c\u4e0d\u4e3b\u52a8\u505a\u4efb\u4f55\u989d\u5916\u7684\u8f6c\u6362\u3002 UTF-16 \u548c UTF-32 \u7684\u7801\u4f4d\u90fd\u662f\u591a\u5b57\u8282\u7684\uff0c\u4e5f\u4f1a\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u3002\u4f8b\u5982\uff0cUTF-16 \u4e2d\u7684 uint16_t \u5e8f\u5217\uff1a 0x1234 0x5678 \u5728\u5927\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x12 0x34 0x56 0x78 \u5728\u5c0f\u7aef\u6d3e\u7684\u673a\u5668\u4e2d\uff0c\u5c31\u662f\uff1a 0x34 0x12 0x78 0x56 \u8fd9\u6837\u4e00\u6765\uff0cUTF-16 \u548c UTF-32 \u7684\u5b57\u8282\u6d41\uff0c\u5728\u4e0d\u540c\u7684\u673a\u5668\u4e0a\uff0c\u53ef\u80fd\u4f1a\u6709\u4e0d\u540c\u7684\u987a\u5e8f\u3002\u8fd9\u7ed9\u8de8\u5e73\u53f0\u7684\u6587\u672c\u5904\u7406\u5e26\u6765\u4e86\u9ebb\u70e6\u3002 \u6240\u4ee5\u5f53\u4f60\u9700\u8981\u628a UTF-16 \u5b58\u5165\u786c\u76d8\u548c\u5728\u7f51\u7edc\u53d1\u9001\u65f6\uff0c\u8fd8\u9700\u8981\u989d\u5916\u6307\u660e\u4f60\u7528\u7684\u662f\u5927\u7aef\u7684 UTF-16 \u8fd8\u662f\u5c0f\u7aef\u7684 UTF-16\u3002 \u56e0\u6b64 UTF-16 \u548c UTF-32 \u8fdb\u4e00\u6b65\u5206\u88c2\u4e3a\uff1a UTF-16LE\uff1a\u5c0f\u7aef\u7684 UTF-16 UTF-16BE\uff1a\u5927\u7aef\u7684 UTF-16 UTF-32LE\uff1a\u5c0f\u7aef\u7684 UTF-32 UTF-32BE\uff1a\u5927\u7aef\u7684 UTF-32 \u5982\u679c\u53ea\u5728\u5185\u5b58\u7684 wchar_t \u4e2d\u4f7f\u7528\u5c31\u4e0d\u7528\u533a\u5206\uff0c\u9ed8\u8ba4\u8ddf\u968f\u5f53\u524d\u673a\u5668\u7684\u5927\u5c0f\u7aef\u3002\u6240\u4ee5 UTF-16 \u548c UTF-32 \u901a\u5e38\u53ea\u4f1a\u51fa\u73b0\u5728\u5185\u5b58\u4e2d\u7528\u4e8e\u5feb\u901f\u5904\u7406\u548c\u8ba1\u7b97\uff0c\u5f88\u5c11\u7528\u5728\u5b58\u50a8\u548c\u901a\u4fe1\u4e2d\u3002 UTF-8 \u662f\u57fa\u4e8e\u5355\u5b57\u8282\u7684\u7801\u4f4d\uff0c\u706b\u8f66\u5934\u7684\u987a\u5e8f\u4e5f\u6709\u4e25\u683c\u89c4\u5b9a\uff0c\u706b\u8f66\u5934\u603b\u662f\u5728\u6700\u524d\uff0c\u6839\u672c\u4e0d\u53d7\u5b57\u8282\u5e8f\u5927\u5c0f\u7aef\u5f71\u54cd\uff0c\u4e5f\u5c31\u6ca1\u6709\u5f71\u54cd\u3002 \u7531\u4e8e\u538b\u7f29\u7387\u4f4e\uff0c\u53c8\u5b58\u5728\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\u4e0d\u540c\u7684\u95ee\u9898\u3002\u800c\u4e92\u8054\u7f51\u6570\u636e\u9700\u8981\u4fdd\u8bc1\u76f8\u540c\u7684\u5927\u5c0f\u7aef\uff0c\u5728\u6536\u53d1\u5305\u65f6\u9700\u8981\u989d\u5916\u8f6c\u6362\uff0c\u56e0\u800c\u53ef\u80fd\u4e0d\u592a\u9002\u5408\u7f51\u7edc\u3002\u800c UTF-8 \u7684\u5b58\u50a8\u5355\u4f4d\u662f\u5b57\u8282\uff0c\u5929\u751f\u6ca1\u6709\u5927\u5c0f\u7aef\u56f0\u6270\u3002\u66f4\u5999\u7684\u662f\uff0c\u4ed6\u4e14\u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u800c\u4e92\u8054\u7f51\u53c8\u662f\u53e4\u8463\u4e2d\u95f4\u4ef6\u6700\u591a\u7684\u5730\u65b9\u2026\u2026 \u603b\u4e4b\uff0c\u5b8c\u5168\u57fa\u4e8e\u5b57\u8282\u7684 UTF-8 \u662f\u6700\u9002\u5408\u7f51\u7edc\u901a\u4fe1\u548c\u786c\u76d8\u5b58\u50a8\u7684\u6587\u672c\u7f16\u7801\u683c\u5f0f\uff0c\u800c UTF-32 \u662f\u6700\u9002\u5408\u5728\u5185\u5b58\u4e2d\u5904\u7406\u7684\u683c\u5f0f\u3002","title":"\u5b57\u8282\u5e8f\u95ee\u9898\uff0c\u5927\u5c0f\u7aef\u4e4b\u4e89"},{"location":"unicode/#bom","text":"0xFEFF \u662f\u4e00\u4e2a\u7279\u6b8a\u7684\u4e0d\u53ef\u89c1\u5b57\u7b26\u201c\ufeff\u201d\uff0c\u8fd9\u662f\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u6ca1\u6709\u4efb\u4f55\u6548\u679c\u3002 \u4f60\u53ef\u4ee5\u628a\u8fd9\u4e2a\u5b57\u7b26\u52a0\u5728\u6587\u672c\u6587\u4ef6\u7684\u5934\u90e8\uff0c\u544a\u8bc9\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\uff0c\u8fd9\u4e2a\u6587\u4ef6\u662f\u7528\u4ec0\u4e48\u7f16\u7801\u7684\u3002 \u5982\u679c\u662f UTF-16 \u548c UTF-32\uff0c\u56e0\u4e3a 0xFEFF \u4e0d\u5bf9\u79f0\uff0c\u4ed6\u8fd8\u80fd\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\u3002\u56e0\u6b64 0xFEFF \u88ab\u79f0\u4e3a\u5b57\u8282\u5e8f\u6807\u5fd7\uff08Byte-order-mark\uff0cBOM\uff09\u3002 \u5982\u679c\u8bfb\u53d6\u8be5\u6587\u4ef6\u7684\u8f6f\u4ef6\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u90a3\u4e48\u4ed6\u7167\u5e38\u8bfb\u51fa 0xFEFF\uff0c\u4e00\u4e2a\u96f6\u5bbd\u7a7a\u683c\uff0c\u5728\u6587\u672c\u4e2d\u4e0d\u663e\u793a\uff0c\u4e0d\u5f71\u54cd\u89c6\u89c9\u7ed3\u679c\u3002 \u4e00\u4e9b\u8001\u7684\u7f16\u8bd1\u5668\uff08\u8fdc\u53e4 MinGW\uff0c\u73b0\u5728\u5df2\u7ecf\u6ca1\u6709\u4e86\uff09\u4e0d\u652f\u6301\u89e3\u6790 BOM\uff0c\u4f1a\u628a\u5e26\u6709 BOM \u7684 UTF-8 \u7684 .cpp \u6e90\u7801\u6587\u4ef6\uff0c\u5f53\u4f5c\u5934\u90e8\u5e26\u6709\u9519\u8bef\u5b57\u7b26\u7684\u4e71\u7801\u6587\u4ef6\uff0c\u4ece\u800c\u62a5\u9519\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u7684\u8bb0\u4e8b\u672c\u4fdd\u5b58\u4e3a UTF-8 \u65f6\uff0c\u603b\u662f\u4f1a\u52a0\u4e0a BOM\u3002\u5982\u679c\u8bb0\u4e8b\u672c\u53d1\u73b0\u4e00\u4e2a\u6587\u4ef6\u6ca1\u6709 BOM\uff0c\u4f1a\u5f53\u4f5c ANSI\uff08GBK\uff09\u6765\u8bfb\u53d6\u3002 0xFEFF \u5728\u4e0d\u540c\u7684\u7f16\u7801\u4e0b\u4f1a\u4ea7\u751f\u4e0d\u540c\u7684\u7ed3\u679c\uff1a UTF-8\uff1a 0xEF 0xBB 0xBF \uff0c\u4ed6\u4f1a\u5360\u7528 3 \u5b57\u8282\uff0c\u800c\u4e14\u4e0d\u4f1a\u544a\u8bc9\u4f60\u662f\u5927\u7aef\u8fd8\u662f\u5c0f\u7aef\uff0c\u56e0\u4e3a UTF-8 \u662f\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\u7684\u3002 UTF-16\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE \u3002 UTF-32\uff1a\u5982\u679c\u662f\u5927\u7aef\uff0c\u5c31\u662f 0x00 0x00 0xFE 0xFF \uff0c\u5982\u679c\u662f\u5c0f\u7aef\uff0c\u5c31\u662f 0xFF 0xFE 0x00 0x00 \u3002 \u56e0\u6b64\uff0c\u5728\u6587\u672c\u5934\u90e8\u52a0\u4e0a BOM \u6709\u52a9\u4e8e\u8f6f\u4ef6\u63a8\u6d4b\u8be5\u6587\u4ef6\u662f\u4ec0\u4e48\u7f16\u7801\u7684\uff08\u5982\u679c\u90a3\u8f6f\u4ef6\u652f\u6301\u89e3\u6790 BOM \u7684\u8bdd\uff09\u3002 \u4f8b\u5982 Windows \u73af\u5883\u4e2d\uff0c\u6240\u6709\u7684\u6587\u672c\u6587\u4ef6\u90fd\u88ab\u9ed8\u8ba4\u5047\u5b9a\u4e3a ANSI\uff08GBK\uff09\u7f16\u7801\uff0c\u5982\u679c\u4f60\u8981\u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u4e3a UTF-8 \u7f16\u7801\uff0c\u5c31\u9700\u8981\u52a0\u4e0a BOM \u6807\u5fd7\u3002\u5f53 MSVC \u8bfb\u53d6\u65f6\uff0c\u770b\u5230\u5f00\u5934\u662f 0xEF 0xBB 0xBF \uff0c\u5c31\u660e\u767d\u8fd9\u662f\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u6587\u4ef6\u3002\u8fd9\u6837\uff0cMSVC \u5c31\u80fd\u6b63\u786e\u5730\u5904\u7406\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4e86\u3002\u5982\u679c MSVC \u6ca1\u770b\u5230 BOM\uff0c\u4f1a\u9ed8\u8ba4\u4ee5\u4e3a\u662f ANSI\uff08GBK\uff09\u7f16\u7801\u7684\uff0c\u4ece\u800c\u4e2d\u6587\u5b57\u7b26\u4e32\u5e38\u91cf\u4f1a\u4e71\u7801\u3002\u5f00\u542f /utf-8 \u9009\u9879\u4e5f\u80fd\u8ba9 MSVC \u628a\u6ca1\u6709 BOM \u7684\u6e90\u7801\u6587\u4ef6\u5f53\u4f5c UTF-8 \u6765\u89e3\u6790\uff0c\u9002\u5408\u8de8\u5e73\u53f0\u5b9d\u5b9d\u4f53\u8d28\u3002 \u5176\u5b9e Windows \u7528\u6237\u53ef\u4ee5\u5728\u63a7\u5236\u9762\u677f\u7684\u201c\u65f6\u949f\u548c\u533a\u57df\u201d\u91cc\uff0c\u627e\u5230\u201c\u533a\u57df\u201d\u9009\u9879\u3002\u5728\u201c\u533a\u57df\u201d\u9009\u9879\u5361\u91cc\uff0c\u70b9\u51fb\u201c\u66f4\u6539\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u7136\u540e\u5f39\u51fa\u7684\u5bf9\u8bdd\u6846\u91cc\uff0c\u52fe\u9009\u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u63d0\u4f9b\u5168\u7403\u8bed\u8a00\u652f\u6301\u201d\uff0c\u91cd\u542f\u540e\uff0c\u5c31\u53ef\u4ee5\u5728\u7a0b\u5e8f\u4e2d\u9ed8\u8ba4\u4f7f\u7528 UTF-8\uff0c\u800c\u4e0d\u662f\u7cdf\u7cd5\u7684 GBK \u4e86\u3002\u8fd9\u4f1a\u628a ANSI \u53d8\u6210 UTF-8\uff0c\u8ba9\u8bb0\u4e8b\u672c\u7b49\u8f6f\u4ef6\u628a\u65e0 BOM \u7684\u6587\u4ef6\u90fd\u5f53\u4f5c UTF-8\uff0c\u8ba9\u5404\u79cd\u8f6f\u4ef6\u90fd\u8ba4\u4e3a\u5b57\u7b26\u4e32\u662f UTF-8 \u7b49\u7b49\u3002\u8fd9\u53ef\u4ee5\u89e3\u51b3\u90e8\u5206\u7f8e\u56fd\u8f6f\u4ef6\u65e0\u6cd5\u5904\u7406\u4e2d\u6587\u3001\u4e71\u7801\u7b49\u95ee\u9898\uff0c\u56e0\u4e3a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u5e38\u5e38\u65e0\u610f\u8bc6\u5730\u7528 UTF-8 \u5b57\u7b26\u4e32\u672a\u7ecf\u5904\u7406\u76f4\u63a5\u8c03\u7528 A \u51fd\u6570\u3002\u4e0d\u8fc7\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4f60\u8fd0\u884c\u5176\u4ed6\u5047\u5b9a\u4e86 GBK \u7684\u4e2d\u56fd\u7279\u4f9b\u7a0b\u5e8f\u4e71\u7801\uff0c\u4e5f\u4f1a\u5bfc\u81f4\u4f60\u7684\u6bd5\u4e1a\u7b54\u8fa9\u5bfc\u5e08\u53d1\u6765\u7684 ZIP \u53d8\u6210\u4e71\u7801\u3002\u800c\u4e14\u6211\u4eec\u4f5c\u4e3a\u5ba2\u6237\u7aef\u7684\u5f00\u53d1\u8005\uff0c\u6211\u4eec\u603b\u4e0d\u80fd\u5f3a\u6c42\u6240\u6709\u5ba2\u6237\u7528\u6211\u4eec\u7684\u8f6f\u4ef6\u524d\uff0c\u6539\u53d8\u4ed6\u4eec\u7684\u63a7\u5236\u9762\u677f\u6765\u9002\u5e94\u6211\u4eec\u7684\u7a0b\u5e8f\u5427\uff1f\u6240\u4ee5\u8fd8\u662f\u9700\u8981\u7ed5\u5f00 GBK\uff0c\u76f4\u63a5\u8c03\u7528 UTF-16 \u7684 W \u7c7b API\u3002","title":"BOM \u6807\u8bb0"},{"location":"unicode/#gb2312gbkgb18030","text":"","title":"GB2312\u3001GBK\u3001GB18030 \u7684\u5173\u7cfb"},{"location":"unicode/#gb2312","text":"GB2312 \u53d1\u5e03\u4e8e 1980 \u5e74\uff0c\u662f\u4e00\u4e2a\u53e4\u8001\u7684\u6c49\u5b57\u7f16\u7801\u6807\u51c6\uff0c\u517c\u5bb9 ASCII\u3002 \u201cGB\u201d \u8868\u793a Guo Biao\uff08\u56fd\u6807\uff09\u7684\u610f\u601d\u3002 GB2312 \u89c4\u5b9a\u4e86 6763 \u4e2a\u6c49\u5b57\u548c 682 \u4e2a\u7279\u6b8a\u7b26\u53f7\uff0c\u5171 7445 \u4e2a\u5b57\u7b26\u3002 GB2312 \u8ba9\u82f1\u6587\u548c\u6570\u5b57\u91c7\u7528\u548c ASCII \u76f8\u540c\u7684\u5355\u5b57\u8282\u7f16\u7801\uff0c\u800c\u5bf9\u4e8e\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u91c7\u7528\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u5176\u4e2d\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7\u7684\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u4e24\u4e2a\u5b57\u8282\u90fd\u5728 0xA1 \u5230 0xFE \u7684\u8303\u56f4\u5185\uff0c\u907f\u514d\u4e86\u4e0e\u5355\u5b57\u8282\u7684 ASCII \u7f16\u7801\u7a7a\u95f4\u51b2\u7a81\u3002 H i \u5f6d \u5b9d 0x48 0x69 0xC5 0xED 0xB1 0xA6 2 \u4e2a\u5b57\u8282\u5206\u522b\u88ab\u79f0\u4e3a\u201c\u533a\u7801\u201d\u548c\u201c\u4f4d\u7801\u201d\uff0c\u8303\u56f4\u90fd\u662f\u5728 0xA1 \u5230 0xFE \u533a\u95f4\u5185\u3002 \u201c\u7279\u6b8a\u7b26\u53f7\u201d\uff0c\u5171 682 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xA1A1 \u5230 0xA9FE\u3002 \u201c\u4e00\u7ea7\u6c49\u5b57\u201d\uff0c\u90fd\u662f\u6bd4\u8f83\u5e38\u7528\u7684\u6c49\u5b57\uff0c\u6309\u62fc\u97f3\u987a\u5e8f\u6392\u5e8f\uff0c\u5171 3755 \u4e2a\uff0c\u8fd9\u4e9b\u5b57\u7b26\u7684\u7f16\u7801\u4ece 0xB0A1 \u5230 0xF7FE\u3002 \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u662f\u4e00\u4e9b\u751f\u50fb\u5b57\uff0c\u6309\u90e8\u9996/\u7b14\u753b\u6392\u5e8f\uff0c\u5171 3008 \u4e2a\uff0c\u8fd9\u4e9b\u6c49\u5b57\u7684\u5b57\u7b26\u4ece 0x8140 \u5230 0xA0FE\u3002 GBK \u4e2d\u6c49\u5b57\u7684\u7f16\u53f7\u548c Unicode \u5e76\u4e0d\u662f\u76f8\u540c\u7684\uff0c\u8fd9\u4e5f\u662f GB2312 \u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6\u7528 UTF-8 \u6216 UTF-16 \u6253\u5f00\u4f1a\u4ea7\u751f\u4e71\u7801\u7684\u6839\u672c\u539f\u56e0\u3002 \u4f8b\u5982\u6c49\u5b57 \u201c\u5f6d\u201d \u5c31\u5c5e\u4e8e \u201c\u4e8c\u7ea7\u6c49\u5b57\u201d\uff0c\u5728 GB2312 \u4e2d\u7f16\u53f7\u4e3a 0xC5ED\uff0cUnicode \u4e2d\u7f16\u53f7\u4e3a 0x5F6D\u3002 \u5168\u89d2\u7a7a\u683c \u201c\u3000\u201d\uff0c\u5728 GB2312 \u4e2d\u7684\u7f16\u53f7\u4e3a 0xA1A1\uff0cUnicode \u4e2d\u7684\u7f16\u53f7\u4e3a 0x3000\u3002","title":"GB2312"},{"location":"unicode/#gb2312_1","text":"GBK \u548c UTF-8 \u7684\u5171\u540c\u70b9\u5728\u4e8e\uff0c\u4ed6\u4eec\u90fd\u907f\u5f00\u4e86 0 ~ 127 \u7684 ASCII \u7a7a\u95f4\uff0c\u6240\u4ee5\u5b8c\u5168\u517c\u5bb9 ASCII\u3002 \u4e0d\u540c\u70b9\u5728\u4e8e\uff0c\u5982\u679c\u5728\u4e00\u4e2a GBK \u7f16\u7801\u7684\u4e2d\u6587\u5b57\u7b26\u4e32\u4e2d\u67e5\u627e\u4e2d\u6587\uff0c\u53ef\u80fd\u5f97\u5230\u9519\u8bef\u7684\u7ed3\u679c\uff0c\u800c UTF-8 \u4e0d\u4f1a\u3002\u8fd9\u662f\u56e0\u4e3a GBK \u6ca1\u6709\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u4ed6\u524d\u540e\u4e24\u4e2a\u8f66\u53a2\u5e76\u6ca1\u6709\u4e0d\u540c\u3002 \u5f53 GBK \u88ab\u5207\u7247\u65f6\uff0c\u5c31\u5bb9\u6613\u51fa\u73b0\u8fde\u9501\u53cd\u5e94\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.substr(1); // \"\u64a9\u683d\u91c7\ufffd\" // \u590d\u73b0\u65b9\u5f0f: MSVC \u4e2d\u56fd\u533a Windows\uff0c/std:c++17\uff0c\u4e0d\u5f00\u542f /utf-8 \u53c2\u6570\uff08\u8fd9\u65f6\u5b57\u7b26\u4e32\u5e38\u91cf\u90fd\u662f GBK \u7f16\u7801\u7684\uff09 \u6838\u53cd\u5e94\u5806\uff0c\u542f\u52a8\uff01 \u7279\u522b\u662f\u5f53\u4f60\u8bd5\u56fe find \u4e00\u4e2a\u4e2d\u6587\u5b50\u5b57\u7b26\u4e32\u65f6\uff0cGBK \u7f16\u7801\u7684\u591a\u5b57\u8282\u5b57\u7b26\u4e32\u53ef\u80fd\u4ea7\u751f\u627e\u5230\u4e86\u7684\u5047\u8c61\u3002\u5b9e\u9645\u4e0a\u627e\u5230\u7684\u4f4d\u7f6e\u6839\u672c\u662f\u5207\u65ad\u4e86\u5355\u4e2a\u5b8c\u6574\u7684\u4e2d\u6587\u5b57\u7b26\u3002 std::string s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xB3 0xC1 0xC3 0xD4 0xD4 0xAD 0xC9 0xF1 std::cout << s.find(\"\u91c7\"); // 5\uff0c\u628a\u201c\u5706\u201d\u7684\u540e\u534a\u6bb5 0xAD \u548c\u201c\u795e\u201d\u7684\u524d\u534a\u6bb5 0xC9 \u5f53\u6210\u4e00\u4e2a\u5b57\u201c\u91c7\u201d (0xAD 0xC9) \u4e86 \u800c UTF-8 \u5219\u80fd\u6709\u6548\u9650\u5236\u9519\u8bef\u7684\u4f20\u64ad\u3002 std::string u8s = \"\u6c89\u8ff7\u5706\u795e\"; // 0xE6 0xB2 0x89 0xE8 0xBF 0xB7 0xE5 0x9C 0x86 0xE7 0xA5 0x9E std::cout << u8s.substr(1); // \"\ufffd\u8ff7\u5706\u795e\" std::cout << u8s.find(\"\u91c7\"); // \u627e\u4e0d\u5230\uff0c\u8fd4\u56de -1 \u56e0\u4e3a UTF-8 \u7684\u5934\u90e8\u5c0f\u706b\u8f66\u548c\u5c3e\u90e8\u8f66\u53a2\u91c7\u7528\u4e86\u72ec\u7acb\u7684\u7f16\u7801\uff0cfind \u4e0d\u53ef\u80fd\u901a\u8fc7\u4efb\u4f55\u5408\u6cd5\u7684 UTF-8 \u5b50\u5b57\u7b26\u4e32\u5b9a\u4f4d\u5230\u9519\u8bef\u7684\u4e2d\u95f4\u4f4d\u7f6e\u3002 GB2312 \u548c GBK \u7684\u7279\u6b8a\u6027\uff1a\u4ed6\u65e2\u662f\u5b57\u7b26\u96c6\uff0c\u53c8\u662f\u5b57\u7b26\u7f16\u7801\u3002\u9664 Unicode \u5916\u5927\u591a\u6570\u5b57\u7b26\u96c6\u90fd\u662f\u8fd9\u6837\uff0c\u81ea\u5df1\u5c31\u662f\u81ea\u5df1\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u6ca1\u6709\u5176\u4ed6\u7f16\u7801\u65b9\u5f0f\u3002\u53ea\u6709 Unicode \u628a\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u7684\u6982\u5ff5\u5206\u7684\u5f88\u6e05\u695a\uff0c\u56e0\u4e3a Unicode \u5b57\u7b26\u96c6\u6709 UTF-8\u3001UTF-\u3002","title":"GB2312 \u7684\u7f3a\u9677"},{"location":"unicode/#gbk","text":"GBK \u540c\u6837\u662f\u53cc\u5b57\u8282\u7f16\u7801\uff0c\u662f\u5bf9 GB2312 \u7684\u6269\u5c55\u3002 GBK \u5728\u4fdd\u6301 GB2312 \u90e8\u5206\u4e0d\u53d8\u7684\u57fa\u7840\u4e0a\uff0c\u989d\u5916\u8ffd\u52a0\u4e86 21886 \u4e2a\u6c49\u5b57\u3002\u6536\u5f55\u7684\u6709\uff1a GB2312 \u4e2d\u7684\u5168\u90e8\u6c49\u5b57\u548c\u7279\u6b8a\u7b26\u53f7 BIG-5\uff08\u7e41\u4f53\u4e2d\u6587\u7684\u7f16\u7801\uff09\u4e2d\u7684\u5168\u90e8\u6c49\u5b57 GB13000\uff08\u5373 Unicode\uff09\u4e2d\u7684\u5176\u4ed6\u4e2d\u65e5\u97e9\u6c49\u5b57 \u5176\u4ed6\u5c1a\u672a\u6536\u5f55\u7684\u7279\u6b8a\u6c49\u5b57\u3001\u90e8\u9996\u3001\u7b26\u53f7\u7b49 \u201cK\u201d \u8868\u793a Kuo\uff08\u6269\u5c55\uff09\u7684\u610f\u601d\u3002 GB2312\uff1a\u9996\u5b57\u8282 0xA1 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282 0xA1 \u5230 0xFE\u3002 GBK\uff1a\u9996\u5b57\u8282 0x81 \u5230 0xFE \uff0c\u5c3e\u5b57\u8282 0x40 \u5230 0xFE \u3002 \u6ce8\u610f\u5230 GBK \u7684\u5c3e\u5b57\u8282\u8fdb\u5165\u4e86 0x40\uff0cASCII \u7684\u8303\u56f4\u3002 \u8fd9\u4f7f\u5f97 GBK \u6bd4 GB2312 \u66f4\u5371\u9669\uff0c\u4f8b\u5982 \u201c\u4fb0\u201d \u8fd9\u4e2a\u5b57\uff0c\u4f1a\u88ab\u7f16\u7801\u6210 0x82 0x43\u3002 \u800c 0x43 \u521a\u597d\u662f ASCII \u5b57\u7b26 \u201cC\u201d \u7684\u7f16\u7801\u3002\u5982\u679c\u53d1\u751f\u5b57\u7b26\u4e32\u5207\u7247\uff0c\u53ef\u80fd\u5bfc\u81f4 \u201c\u4fb0\u201d \u53d8\u6210 \u201c\ufffdC\u201d\u3002\u5e76\u4e14\u5982\u679c\u521a\u597d\u7a0b\u5e8f\u5728 .find('C') \uff0c\u90a3\u4e48 \u201c\u4fb0\u201d \u7684\u540e\u534a\u4e2a\u5b57\u8282\u4f1a\u88ab\u5f53\u4f5c \u201cC\u201d \u800c\u627e\u5230\u3002 \u4e0d\u8fc7\uff0cGBK \u8bbe\u8ba1\u65f6\u7279\u610f\u907f\u5f00\u4e86 0x40 \u4ee5\u4e0b\u7684 ASCII \u5b57\u7b26\uff0c\u4f8b\u5982 0x2F \u662f \u201c/\u201d \u7684 ASCII \u7f16\u7801\uff0c\u5e38\u7528\u4e8e\u6587\u4ef6\u7cfb\u7edf\u7684\u8def\u5f84\u5206\u9694\u7b26\u3002 \u7136\u800c\uff0cWindows \u6240\u7528\u7684\u8def\u5f84\u5206\u9694\u7b26\u662f\u53cd\u659c\u6760 \u201c\\\u201d\uff0c\u4ed6\u7684 ASCII \u7f16\u7801\u662f 0x5C\u3002 \u4f8b\u5982 \u201c\u4fd3\u201d\uff0cGBK \u7f16\u7801 0x82 0x5C\uff0c\u8fd9\u4e2a\u5b57\u5c31\u53ef\u80fd\u88ab\u9519\u8bef\u89e3\u8bfb\u6210 \u201c\ufffd\\\u201d\uff0c\u4f7f\u7a0b\u5e8f\u8bef\u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u6587\u4ef6\u5939\u7684\u8def\u5f84\uff0c\u4ece\u800c\u5bfc\u81f4\u7a0b\u5e8f\u51fa\u9519\uff0c\u6216\u7559\u4e0b\u88ab\u9ed1\u5ba2\u653b\u51fb\u7684\u9690\u60a3\u3002 \u867d\u7136 Windows \u7cfb\u7edf\u5185\u90e8\u7edf\u4e00\u91c7\u7528 Unicode\uff08UTF-16\uff09\u6765\u5b58\u50a8\u548c\u5904\u7406\u8def\u5f84\uff0c\u4f46\u603b\u67b6\u4e0d\u4f4f\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\uff0c\u4f9d\u7136\u6267\u7740\u4e8e ANSI\uff08GBK\uff09\uff0c\u5982\u679c\u7528\u6237\u65e0\u610f\u6216\u6076\u610f\u8f93\u5165\u201c\u4fd3\u554a.txt\u201d\uff0c\u5c31\u6709\u53ef\u80fd\u4ea7\u751f\u9690\u60a3\u3002 \u800c UTF-8 \u540c\u6837\u517c\u5bb9 ASCII\uff0c\u5f97\u76ca\u4e8e\u5197\u4f59\u7684\u81ea\u7ea0\u9519\u673a\u5236\uff0c\u5c31\u6ca1\u6709\u8fd9\u6837\u7684\u95ee\u9898\u3002 \u201cGBK\u201d \u867d\u7136\u51a0\u4ee5\u201c\u56fd\u6807\u201d\u4e4b\u540d\uff0c\u4f46\u5b9e\u9645\u4e0a\u662f\u5fae\u8f6f\u64c5\u81ea\u63a8\u51fa\u7684\uff01\u6839\u672c\u4e0d\u662f\u4ec0\u4e48\u56fd\u5bb6\u6807\u51c6\uff08\u4f60\u731c\u4ed6\u4e3a\u4ec0\u4e48\u6ca1\u6709\u56fd\u5bb6\u6587\u4ef6\u7f16\u53f7\uff09\u3002\u672c\u6765\u6211\u56fd\u5b98\u65b9\u90fd\u6253\u7b97\u63a8\u51fa GB13000 \u4e86\uff0c\u76f4\u63a5\u5b8c\u5168\u517c\u5bb9 Unicode \u5b57\u7b26\u96c6\u3002\u7136\u800c\u5fae\u8f6f\u81ea\u4f5c\u4e3b\u5f20\u628a\u4ed6 Wendous \u7684 GB2312 \u5347\u7ea7\u5230 GBK\uff08\u6bd4\u5c14\u76d6\u5b50\u4ee5\u4e3a\u81ea\u5df1\u517c\u5bb9\u538b\u5012\u4e00\u5207\uff0c\u62fd\u6b7b\u4e86\uff09\uff0c\u672c\u6765\u597d\u597d\u7684 GB13000 \u6807\u51c6\u53ea\u597d\u4f5c\u7f62\u3002\u4e3a\u4e86\u517c\u5bb9\u5df2\u7ecf\u5347\u7ea7\u6210 GBK \u7684 Wendous \u7cfb\u7edf\uff0c\u56fd\u5bb6\u53ea\u597d\u91cd\u65b0\u5236\u4f5c\u4e86\u4e00\u4efd GB18030 \u6807\u51c6\uff0c\u517c\u5bb9 GBK \u548c GB2312\u3002","title":"GBK"},{"location":"unicode/#gb18030","text":"\u4e8e 2000 \u5e74 3 \u6708\u53d1\u5e03\u7684\u6c49\u5b57\u7f16\u7801\u56fd\u5bb6\u6807\u51c6\uff0c\u5b8c\u5168\u517c\u5bb9 GBK \u548c GB2312\u3002 \u91c7\u7528\u591a\u5b57\u8282\u7f16\u7801\uff0c\u6bcf\u4e2a\u5b57\u7b26\u53ef\u4ee5\u7f16\u7801\u4e3a 1 \u5b57\u8282\u30012 \u5b57\u8282\u3001\u6216 4 \u5b57\u8282\u3002 \u5176\u4e2d 1 \u5b57\u8282\u7684\u90e8\u5206\u53d6\u503c\u8303\u56f4\u662f 0 \u5230 0x7F\uff0c\u548c ASCII \u76f8\u540c\u3002 2 \u5b57\u8282\u7684\u90e8\u5206\u9996\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u5c3e\u5b57\u8282\u8303\u56f4 0x40 \u5230 0xFE\uff0c\u548c GBK \u76f8\u540c\u3002 4 \u5b57\u8282\u7684\u90e8\u5206\u7b2c\u4e00\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u4e8c\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\uff0c\u7b2c\u4e09\u5b57\u8282\u8303\u56f4 0x81 \u5230 0xFE\uff0c\u7b2c\u56db\u5b57\u8282\u8303\u56f4 0x30 \u5230 0x39\u3002 \u5b57\u7b26\u5904\u7406\u8f6f\u4ef6\u5728\u5904\u7406 GB18030 \u7684\u6587\u672c\u65f6\uff0c\u4ece\u5de6\u5f80\u53f3\u4f9d\u6b21\u626b\u63cf\u6bcf\u4e2a\u5b57\u8282\uff1a \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u53ea\u5360\u7528\u4e86\u4e00\u4e2a\u5b57\u8282 \u5982\u679c\u9047\u5230\u7684\u5b57\u8282\u7684\u6700\u9ad8\u4f4d\u662f 1\uff0c\u90a3\u4e48\u8be5\u5b57\u7b26\u53ef\u80fd\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282\uff0c\u4e5f\u53ef\u80fd\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282\uff0c\u4e0d\u80fd\u5984\u4e0b\u65ad\u8bba\uff0c\u6240\u4ee5\u8fd8\u8981\u7ee7\u7eed\u5f80\u540e\u626b\u63cf\uff1a \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6709\u4e24\u4e2a\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u56db\u4e2a\u5b57\u8282 \u5982\u679c\u7b2c\u4e8c\u4e2a\u5b57\u8282\u7684\u9ad8\u4f4d\u6ca1\u6709\u8fde\u7eed\u7684 0\uff0c\u90a3\u4e48\u5c31\u4f1a\u65ad\u5b9a\u8be5\u5b57\u7b26\u5360\u7528\u4e86\u4e24\u4e2a\u5b57\u8282 \u5f53\u5b57\u7b26\u5360\u7528\u4e24\u4e2a\u6216\u8005\u56db\u4e2a\u5b57\u8282\u65f6\uff0cGB18030 \u7f16\u7801\u603b\u8981\u68c0\u6d4b\u4e24\u6b21\uff0c\u5904\u7406\u6548\u7387\u6bd4 GB2312 \u548c GBK \u90fd\u4f4e\u3002\u800c\u4e14\u548c GBK \u4e00\u6837\uff0c\u6709\u7740\u4e0d\u80fd\u81ea\u7ea0\u9519\uff0c\u5bb9\u6613\u4f7f\u7f16\u7801\u9519\u8bef\u8fde\u9501\u53cd\u5e94\u7684\u95ee\u9898\u3002 GB18030 \u7f16\u7801\u7a7a\u95f4\u5de8\u5927\uff0c\u4e0d\u4ec5\u56ca\u62ec\u4e86\u4e2d\u65e5\u97e9\u6c49\u5b57\uff0c\u6240\u6709 Unicode \u4e2d\u7684\u5b57\u7b26\u4e5f\u90fd\u88ab\u7eb3\u5165\u5176\u4e2d\uff01\u4e5f\u5c31\u662f\u8bf4\uff0cUnicode \u5b57\u7b26\u7528 GB18030 \u7f16\u7801\u662f\u65e0\u635f\u7684\uff0c\u548c UTF-8 \u4e00\u6837\uff0c\u800c\u4e14\u8fd8\u5b8c\u5168\u517c\u5bb9\u4e86 GBK\uff08\u4e2d\u56fd\u533a Windows \u7684\u9ed8\u8ba4\u7f16\u7801\uff09\u3002 \u6240\u4ee5\uff0cGB18030 \u5b57\u7b26\u7f16\u7801\u5bf9\u5e94\u7684\u5b57\u7b26\u96c6\u5b9e\u9645\u4e0a\u662f Unicode\u3002 \u5c3d\u7ba1\u5982\u6b64\uff0cWindows \u81f3\u4eca\uff08\u6211\u6d4b\u7684\u662f Win10\uff0c\u4e0d\u77e5\u9053 Win11 \u5b83\u4eec\u6539\u8fdb\u6ca1\u6709\uff09\u91c7\u7528\u7684\u4f9d\u7136\u662f GBK \u7f16\u7801\uff1a A \u7cfb API \u65e0\u6cd5\u6b63\u786e\u8bc6\u522b GB18030 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff0c\u6587\u4ef6\u8def\u5f84\u540d\u3002\u660e\u660e\u4e2d\u56fd\u653f\u5e9c\u90fd\u7ed9\u4f60\u505a\u5b8c\u5168\u517c\u5bb9\u4f60\u7684 GBK \u4e86\uff0c\u8fd8\u6536\u5f55\u6240\u6709 Unicode \u5b57\u7b26\u4e86\uff0c\u5b8c\u5168\u53ef\u4ee5\u65e0\u7f1d\u589e\u91cf\u5347\u7ea7\u7684\u4e1c\u897f\uff0c\u6ce5\u7801\u6c9f\u69fd\u7684\u6bd4\u5c14\u76d6\u5b50\u8fd8\u4e0d\u5feb\u70b9\u9ed8\u8ba4\u5207\u6362\u5230 GB18030\uff0c\u60f3\u4e0d\u901a\uff08\u81f4\u656c\u4f20\u5947\u9634\u4e95\u76d6\u6bd4\u5c14\u76d6\u5b50\uff09","title":"GB18030"},{"location":"unicode/#_8","text":"\u5b57\u7b26\u7f16\u7801\u517c\u5bb9\u6027\uff1aUTF-8 != GB18030 > GBK > GB2312 > ASCII \u5b57\u7b26\u96c6\u5927\u5c0f\uff1aUnicode = GB18030 > GBK > GB2312 > ASCII \u603b\u4e4b\uff0cGB \u7cfb\u5217\u7f16\u7801\u9762\u5bf9\u5207\u7247\u548c\u67e5\u627e\u5b58\u5728\u4e00\u5b9a\u7684\u95ee\u9898\uff0c\u6709\u6761\u4ef6\u7684\u8bdd\uff0c\u5efa\u8bae Windows \u7a0b\u5e8f\u5c3d\u5feb\u5347\u7ea7\u5230 UTF-8 \u5916\u7801\u3001UTF-16 \u5185\u7801\u7684\u5de5\u4f5c\u6d41\u4e0a\u6765\uff0c\u56de\u907f\u6389\u53f2\u5c71\u7684\u5f71\u54cd\u3002","title":"\u603b\u7ed3"},{"location":"unicode/#cc","text":"","title":"C/C++ \u4e2d\u7684\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#_9","text":"\u7c7b\u578b \u5927\u5c0f \u7f16\u7801 \u5b57\u9762\u91cf Linux char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e $LC_ALL \u201chello\u201d Windows char 1 \u5b57\u8282 \u53d6\u51b3\u4e8e\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e \u201chello\u201d Linux wchar_t 4 \u5b57\u8282 UTF-32 L\u201dhello\u201d Windows wchar_t 2 \u5b57\u8282 UTF-16LE L\u201dhello\u201d char8_t 1 \u5b57\u8282 UTF-8 u8\u201dhello\u201d char16_t 2 \u5b57\u8282 UTF-16 u\u201dhello\u201d char32_t 4 \u5b57\u8282 UTF-32 U\u201dhello\u201d \u7531\u6b64\u53ef\u89c1\uff0c char \u548c wchar_t \u662f\u4e0d\u8de8\u5e73\u53f0\u7684\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f GBK\u3002\u5bf9\u4e8e\u7f8e\u56fd\u533a Windows \u6765\u8bf4\uff0c\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\u3002 \u5bf9\u4e8e Linux \u7528\u6237\u6765\u8bf4\uff0c\u5982\u679c\u4f60\u6ca1\u6709\u4e13\u95e8\u4fee\u6539\u8fc7\uff0c $LC_ALL \u9ed8\u8ba4\u662f en_US.UTF-8 \u6216 C.UTF-8 \u3002 \u8fd9\u5e26\u6765\u4e86\u5de8\u5927\u7684\u6df7\u6dc6\uff01\u5f88\u591a\u7f8e\u56fd\u7a0b\u5e8f\u5458\u6f5c\u610f\u8bc6\u91cc\u4f1a\u60f3\u5f53\u7136\u5730\u628a char \u5f53\u4f5c UTF-8 \u6765\u7528\u3002\u5f88\u591a\u5f00\u6e90\u9879\u76ee\uff0c\u7b2c\u4e09\u65b9\u5e93\uff0c\u751a\u81f3\u5f88\u591a\u56fd\u4eba\u505a\u7684\u9879\u76ee\uff0c\u90fd\u88ab\u8fd9\u79cd\u201c\u60f3\u5f53\u7136\u201d\u4f20\u67d3\u4e86\u3002 \u597d\u6d88\u606f\u662f\u65e0\u8bba\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u662f\u4ec0\u4e48\uff0c\u80af\u5b9a\u517c\u5bb9 ASCII\u3002\u4f8b\u5982 GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u5426\u5219\u5c31\u548c\u6240\u6709\u7684 C \u8bed\u8a00\u7ecf\u5178\u51fd\u6570\u5982 strlen \uff0c\u6362\u884c\u7b26 '\\n' \uff0c\u8def\u5f84\u5206\u9694\u7b26 '/' \u548c '\\\\' \u51b2\u7a81\u4e86\u3002 wchar_t \u5c31\u597d\u4e00\u4e9b\uff0c\u867d\u7136\u5728 Windows \u7cfb\u7edf\u4e0a\u662f\u7cdf\u7cd5\u7684 UTF-16\uff0c\u4f46\u81f3\u5c11\u7a33\u5b9a\u4e86\uff0c\u4e0d\u4f1a\u968f\u7740\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u800c\u968f\u610f\u6539\u53d8\uff0c\u53ea\u8981\u4f60\u4e0d\u6253\u7b97\u8de8\u5e73\u53f0\uff0c wchar_t \u5c31\u662f Windows \u7a0b\u5e8f\u7684\u6807\u914d\u3002 \u6839\u636e Windows \u5b98\u65b9\u6587\u6863\u7684\u8bf4\u6cd5\uff0c wchar_t \u662f UTF-16LE\u3002","title":"\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#utf-8-ascii","text":"UTF-8 \u7684\u706b\u8f66\u5934\u548c\u8f66\u53a2\uff0c\u90fd\u662f 1 \u5f00\u5934\u7684\uff0c\u800c ASCII \u7684\u5355\u4f53\u706b\u8f66\u5934\u6c38\u8fdc\u662f 0 \u5f00\u5934\u3002\u8fd9\u5f88\u91cd\u8981\uff0c\u4e0d\u4ec5\u706b\u8f66\u5934\u9700\u8981\u548c ASCII \u533a\u5206\u5f00\u6765\uff0c\u8f66\u53a2\u4e5f\u9700\u8981\u3002\u8003\u8651\u8fd9\u6837\u4e00\u4e2a\u573a\u666f\uff1a std::u32string path = \"\u4e00\u4e2a\u8001\u4f2f.txt\"; \u201c\u4e00\u4e2a\u8001\u4f2f\u201d \u8f6c\u6362\u4e3a Unicode \u7801\u70b9\u5206\u522b\u662f\uff1a 0x4E00 0x4E2A 0x8001 0x4F2F \u5982\u679c\u8ba9\u4ed6\u4eec\u539f\u5c01\u4e0d\u52a8\u76f4\u63a5\u5b58\u50a8\u8fdb char \u6570\u7ec4\u91cc\uff1a 0x4E 0x00 0x4E 0x2A 0x80 0x01 0x4F 0x2F \u5c31\u51fa\u95ee\u9898\u4e86\uff01\u9996\u5148\uff0c\u8fd9\u91cc 0x4E00 \u7684 0x00 \u90e8\u5206\uff0c\u4f1a\u88ab C \u8bed\u8a00\u5f53\u4f5c\u662f\u5b57\u7b26\u4e32\u7684\u7ed3\u5c3e\u3002\u5982\u679c\u62ff\u8fd9\u6837\u7684\u5b57\u7b26\u4e32\u53bb\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u7684 open \u51fd\u6570\uff0c\u4ed6\u4f1a\u4ee5\u4e3a\u4f60\u5728\u6253\u5f00 0x4E \u5355\u4e2a\u5b57\u7b26\u7684\u6587\u4ef6\u540d\uff0c\u4e5f\u5c31\u662f \"N\" \u3002 \u66f4\u7cdf\u7cd5\u7684\u662f\uff0c0x2F \u5bf9\u5e94\u7684 ASCII \u5b57\u7b26\u662f '/' \uff0c\u662f\u8def\u5f84\u5206\u9694\u7b26\u3002\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u4ee5\u4e3a\u4f60\u8981\u521b\u5efa\u4e00\u4e2a\u5b50\u6587\u4ef6\u5939\u4e0b\u7684\u6587\u4ef6 \"N\\x00N*\\x80\\x01O/.txt\" \uff0c\u6587\u4ef6\u5939\u540d\u5b57\u53eb \"N\\x00N*\\x80\\x01O\" \u800c\u6587\u4ef6\u53eb \".txt\" \u3002 \u4e3a\u4e86\u80fd\u8ba9\u9488\u5bf9 ASCII \u8bbe\u8ba1\u7684\u64cd\u4f5c\u7cfb\u7edf API \u652f\u6301\u4e2d\u6587\u6587\u4ef6\u540d\uff0c\u5c31\u53ea\u80fd\u7ed5\u5f00\u6240\u6709 0x7F \u4ee5\u4e0b\u7684\u503c\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 UTF-8 \u5bf9\u8f66\u53a2\u4e5f\u5168\u90e8\u62ac\u9ad8\u5230 0x80 \u4ee5\u4e0a\uff0c\u907f\u514d\u64cd\u4f5c\u7cfb\u7edf\u4e0d\u614e\u628a\u8f66\u53a2\u5f53\u4f5c\u662f '/' \u6216 '\\0' \u3002","title":"\u601d\u8003\uff1aUTF-8 \u4e3a\u4ec0\u4e48\u5b8c\u7f8e\u80fd\u517c\u5bb9 ASCII"},{"location":"unicode/#utf-8_2","text":"\u7531\u4e8e\u5de8\u5927\u7684\u60ef\u6027\uff0c\u5f88\u591a\u4eba\u90fd\u60f3\u5f53\u7136\u7684\u628a std::string \u5f53\u4f5c UTF-8 \u6765\u4f7f\u7528\u3002\u5bf9\u4e8e\u7b80\u5355\u7684\u6253\u5370\uff0c\u5e38\u89c4\u7684\u5b57\u7b26\u4e32\u64cd\u4f5c\uff0c\u662f\u6ca1\u95ee\u9898\u7684\u3002 \u5b57\u7b26\u4e32\u64cd\u4f5c\u6709\u4e0b\u9762\u8fd9\u51e0\u79cd\uff0c\u5f97\u76ca\u4e8e UTF-8 \u4f18\u79c0\u7684\u5e8f\u5217\u5316\u6d89\u53ca\u548c\u5197\u4f59\u6297\u5e72\u6270\u673a\u5236\uff0c\u7edd\u5927\u591a\u6570 ASCII \u652f\u6301\u7684\u64cd\u4f5c\uff0cUTF-8 \u5b57\u7b26\u4e32\u90fd\u80fd\u8f7b\u677e\u80dc\u4efb\uff0c\u552f\u72ec\u5176\u4e2d \u6d89\u53ca\u201c\u7d22\u5f15\u201d\u548c\u201c\u957f\u5ea6\u201d\u7684 \u4e00\u90e8\u5206\u64cd\u4f5c\u4e0d\u884c\u3002\u8fd9\u662f\u7531\u4e8e\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff0c\u5982\u679c\u9700\u8981\u505a\u201c\u7d22\u5f15\u201d\u7c7b\u64cd\u4f5c\uff0c\u8fd8\u662f\u5efa\u8bae\u5148\u8f6c\u6362\u6210\u5b9a\u957f\u7684 UTF-32 \u7f16\u7801\u3002 \u64cd\u4f5c UTF-8 UTF-32 GBK \u6c42\u5b57\u7b26\u4e32\u957f\u5ea6 \u00d7 \u221a \u00d7 \u5224\u65ad\u76f8\u7b49 \u221a \u221a \u221a \u5b57\u5178\u5e8f\u7684\u5927\u5c0f\u6bd4\u8f83 \u221a \u221a \u00d7 \u5b57\u7b26\u4e32\u62fc\u63a5 \u221a \u221a \u221a \u641c\u7d22\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u641c\u7d22\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u4e0b\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u6309\u7d22\u5f15\u83b7\u53d6\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u904d\u5386\u6240\u6709\u5b57\u7b26 \u00d7 \u221a \u00d7 \u6309\u5b50\u5b57\u7b26\u4e32\u5207\u7247 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5207\u7247 \u00d7 \u221a \u00d7 \u67e5\u627e\u5e76\u66ff\u6362\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u67e5\u627e\u5e76\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u221a \u221a \u00d7 \u6309\u7d22\u5f15\u5220\u9664\u5b50\u5b57\u7b26\u4e32 \u00d7 \u221a \u00d7 \u5220\u9664\u5355\u4e2a\u5b57\u7b26 \u00d7 \u221a \u00d7 \u4e3a\u4ec0\u4e48\uff1f\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u5b9e\u9a8c\uff1a std::string s = \"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \uff08\u4f7f\u7528 /utf-8 \u7f16\u8bd1\uff09\u8fd0\u884c\u540e\uff0c\u4f1a\u5f97\u5230 6\u3002 \u56e0\u4e3a std::string \u7684 size() \u8fd4\u56de\u7684\u662f char \u7684\u6570\u91cf\uff0c\u800c\u4e0d\u662f\u771f\u6b63\u5b57\u7b26\u7684\u6570\u91cf\u3002\u5728 UTF-8 \u4e2d\uff0c\u4e00\u4e2a\u975e ASCII \u7684\u5b57\u7b26\u4f1a\u88ab\u7f16\u7801\u4e3a\u591a\u4e2a char \uff0c\u5bf9\u4e8e\u4e2d\u6587\u800c\u8a00\uff0c\u4e2d\u6587\u90fd\u5728 0x2E80 \u5230 0x9FFF \u8303\u56f4\u5185\uff0c\u5c5e\u4e8e\u4e09\u7ea7\u5217\u8f66\uff0c\u4e5f\u5c31\u662f\u6bcf\u4e2a\u6c49\u5b57\u4f1a\u88ab\u7f16\u7801\u6210 3 \u4e2a char \u3002 char \u662f\u5b57\u8282\uff08\u7801\u4f4d\uff09\u800c\u4e0d\u662f\u771f\u6b63\u7684\u5b57\u7b26\uff08\u7801\u70b9\uff09\u3002\u771f\u6b63\u7684 Unicode \u5b57\u7b26\u5e94\u8be5\u662f char32_t \u7c7b\u578b\u7684\u3002\u8c03\u7528 std::string \u7684 size() \u6216\u8005 strlen \u5f97\u5230\u7684\u53ea\u662f\u201c\u5b57\u8282\u6570\u91cf\u201d\u3002 \u800c UTF-32 \u4e2d\uff0c\u6bcf\u4e2a\u5b57\u7b26\uff08\u7801\u70b9\uff09\u90fd\u5bf9\u5e94\u4e00\u4e2a\u72ec\u7acb\u7684 char32_t \uff08\u7801\u4f4d\uff09\uff0c size() \u5c31\u662f\u771f\u6b63\u7684\u201c\u5b57\u7b26\u6570\u91cf\u201d\uff0c\u8fd9\u5c31\u662f\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 std::u32string s = U\"\u4f60\u597d\"; fmt::println(\"s \u7684\u957f\u5ea6\uff1a{}\", s.size()); \u5982\u679c\u4f60\u7684\u64cd\u4f5c\u53ea\u6d89\u53ca\u5b57\u7b26\u4e32\u67e5\u62fc\u63a5\u4e0e\u67e5\u627e\uff0c\u90a3\u5c31\u53ef\u4ee5\u7528 UTF-8\u3002\u5982\u679c\u5927\u91cf\u6d89\u53ca\u7d22\u5f15\uff0c\u5207\u7247\uff0c\u5355\u4e2a\u5b57\u7b26\u7684\u64cd\u4f5c\uff0c\u90a3\u5c31\u5fc5\u987b\u7528 UTF-32\uff08\u5426\u5219\u4e00\u9047\u5230\u6c49\u5b57\u5c31\u4f1a\u51fa\u9519\uff09\u3002 std::vector slogan = { \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\", \"\u5168\u4e16\u754c\u7a0b\u5e8f\u5458\u5927\u56e2\u7ed3\u4e07\u5c81\", }; std::string joined; for (auto const &s: slogan) { joined += s; // \u53ea\u662f\u62fc\u63a5\u800c\u5df2\uff0cUTF-8 \u6ca1\u95ee\u9898 } UTF-8 \u6309\u7d22\u5f15\u5207\u7247\u7684\u51fa\u9519\u6848\u4f8b\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-8 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u8282\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\ufffd\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::println(\"UTF-32 \u4e0b\uff0c\u524d\u56db\u4e2a\u5b57\u7b26\uff1a{}\", s.substr(0, 4)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u53ea\u6709\u5f53\u7d22\u5f15\u662f\u6765\u81ea find \u7684\u7ed3\u679c\u65f6\uff0cUTF-8 \u5b57\u7b26\u4e32\u7684\u5207\u7247\u624d\u80fd\u6b63\u5e38\u5de5\u4f5c\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(\"\u516c\"); // pos = 12 fmt::println(\"UTF-8 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u8282\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; size_t pos = s.find(U'\u516c'); // pos = 4 fmt::println(\"UTF-32 \u4e0b\uff0c\u201c\u516c\u201d\u524d\u7684\u6240\u6709\u5b57\u7b26\uff1a{}\", s.substr(0, pos)); // \u4f1a\u6253\u5370 \u201c\u5c0f\u5f6d\u8001\u5e08\u201d \u6ce8\u610f\u5230\u8fd9\u91cc UTF-8 \u7684 \"\u516c\" \u9700\u8981\u662f\u5b57\u7b26\u4e32\uff0c\u800c\u4e0d\u662f\u5355\u4e2a\u5b57\u7b26\u3002 UTF-8 \u65e0\u6cd5\u53d6\u51fa\u5355\u4e2a\u975e ASCII \u5b57\u7b26\uff0c\u5bf9\u4e8e\u5355\u4e2a\u4e2d\u6587\u5b57\u7b26\uff0c\u4ecd\u7136\u53ea\u80fd\u4ee5\u5b57\u7b26\u4e32\u5f62\u5f0f\u8868\u8fbe\uff08\u7531\u591a\u4e2a\u5b57\u8282\u7ec4\u6210\uff09\u3002 std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-8 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u8282\uff1a{}\", s[0]); // \u53ef\u80fd\u4f1a\u6253\u5370 \u2018\u00e5\u2019 (0xE5)\uff0c\u56e0\u4e3a\u201c\u5c0f\u201d\u7684 UTF-8 \u7f16\u7801\u662f 0xE5 0xB0 0x8F // \u4e5f\u53ef\u80fd\u662f\u4e71\u7801\u201c\ufffd\u201d\uff0c\u53d6\u51b3\u4e8e\u7ec8\u7aef\u7406\u89e3\u7684\u7f16\u7801\u683c\u5f0f std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; fmt::print(\"UTF-32 \u4e0b\u7b2c\u4e00\u4e2a\u5b57\u7b26\uff1a{}\", s[0]); // \u4f1a\u6253\u5370 \u2018\u5c0f\u2019 UTF-8 \u5b57\u7b26\u4e32\u7684\u53cd\u8f6c\u4e5f\u4f1a\u51fa\u95ee\u9898\uff1a std::string s = \"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u4ee5\u5b57\u8282\u4e3a\u5355\u4f4d\u53cd\u8f6c\uff0c\u5bfc\u81f4\u4e71\u7801 std::u32string s = U\"\u5c0f\u5f6d\u8001\u5e08\u516c\u5f00\u8bfe\u4e07\u5c81\"; strrev(s.data()); // \u4f1a\u628a\u6309\u5b57\u7b26\u6b63\u5e38\u53cd\u8f6c\uff0c\u5f97\u5230 \u201c\u5c81\u4e07\u8bfe\u5f00\u516c\u5e08\u8001\u5f6d\u5c0f\u201d \u603b\u7ed3\uff1aUTF-8 \u53ea\u80fd\u62fc\u63a5\u3001\u67e5\u627e\u3001\u6253\u5370\u3002\u4e0d\u80fd\u7d22\u5f15\u3001\u5207\u7247\u3001\u53cd\u8f6c\u3002 \u6309\u7d22\u5f15\u5207\u7247\u4e0d\u884c\uff0c\u4f46\u5982\u679c\u7d22\u5f15\u662f find \u51fa\u6765\u7684\u5c31\u6ca1\u95ee\u9898\u3002","title":"UTF-8 \u786e\u5b9e\u51e0\u4e4e\u5b8c\u7f8e\u652f\u6301\u5b57\u7b26\u4e32\u6240\u6709\u64cd\u4f5c"},{"location":"unicode/#ansi-unicode","text":"\u5728 Windows \u5b98\u65b9\u7684\u8bf4\u8f9e\u4e2d\uff0c\u6709\u201cUnicode \u7f16\u7801\u201d\u548c\u201cANSI \u7f16\u7801\u201d\u7684\u8bf4\u6cd5\u3002\u5f53\u4f60\u4f7f\u7528 Windows \u81ea\u5e26\u7684\u8bb0\u4e8b\u672c\u7a0b\u5e8f ( notepad.exe ) \u4fdd\u5b58\u6587\u672c\u6587\u4ef6\u65f6\uff0c\u5c31\u4f1a\u770b\u5230\u8fd9\u6837\u7684\u9009\u5355\uff1a \u7ffb\u8bd1\u4e00\u4e0b\uff1a \u201cANSI\u201d\u6307\u7684\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u8bbe\u7f6e\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\u3002 \u6240\u8c13\u201cUnicode\u201d\u5176\u5b9e\u6307\u7684\u662f UTF-16\u3002 \u6240\u8c13\u201cUnicode big endian\u201d\u6307\u7684\u662f\u5927\u7aef UTF-16\u3002 \u201cUTF-8\u201d\u6307\u7684\u662f UTF-8 with BOM \u800c\u4e0d\u662f\u6b63\u5e38\u7684 UTF-8\u3002 \u5b9e\u9645\u4e0a Unicode \u53ea\u662f\u4e00\u4e2a\u5b57\u7b26\u96c6\uff0c\u53ea\u662f\u628a\u5b57\u7b26\u6620\u5c04\u5230\u6574\u6570\uff0c\u66f4\u6ca1\u6709\u4ec0\u4e48\u5927\u7aef\u5c0f\u7aef\uff0cUTF-16 \u624d\u662f\u7f16\u7801\u683c\u5f0f\u3002 \u800c ANSI \u672c\u6765\u5e94\u8be5\u662f ASCII \u7684\u610f\u601d\uff0c char \u672c\u6765\u5c31\u53ea\u652f\u6301 ASCII\u3002 \u4f46\u7531\u4e8e\u5f53\u65f6\u5404\u56fd\u8feb\u5207\u9700\u8981\u652f\u6301\u81ea\u5df1\u672c\u56fd\u7684\u6587\u5b57\uff0c\u5c31\u5728\u517c\u5bb9 ASCII \u7684\u57fa\u7840\u4e0a\uff0c\u53d1\u5c55\u51fa\u4e86\u81ea\u5df1\u7684\u5b57\u7b26\u96c6\u548c\u5b57\u7b26\u7f16\u7801\u3002\u8fd9\u4e9b\u5f53\u5730\u7279\u4f9b\u7684\u5b57\u7b26\u96c6\u91cc\u53ea\u5305\u542b\u4e86\u672c\u56fd\u6587\u5b57\uff0c\u6240\u6709\u8fd9\u4e9b\u5404\u56fd\u7684\u5b57\u7b26\u7f16\u7801\u4e5f\u90fd\u548c UTF-8 \u7c7b\u4f3c\uff0c\u91c7\u7528\u706b\u8f66\u5934\u5f0f\u7684\u53d8\u957f\u7f16\u7801\uff0c\u5bf9 0 \u5f00\u5934\u7684 ASCII \u90e8\u5206\u4e5f\u90fd\u662f\u517c\u5bb9\u3002\u6240\u4ee5 Windows \u7d22\u6027\u628a ANSI \u5f53\u4f5c\u201c\u5404\u56fd\u672c\u5730\u6587\u5b57\u7f16\u7801\u201d\u7684\u7b80\u79f0\u4e86\u3002\u4f46\u540e\u6765\u4e92\u8054\u7f51\u7684\u51fa\u73b0\uff0c\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u5e26\u6765\u4e86\u5de8\u5927\u7684\u4fe1\u606f\u4ea4\u6362\u56f0\u96be\u3002 \u4f8b\u5982\u4f60\u5728\u73a9\u4e00\u4e9b\u65e5\u672c\u7684 galgame \u65f6\uff0c\u4f1a\u53d1\u73b0\u91cc\u9762\u6587\u5b57\u5168\u90e8\u4e71\u7801\u3002\u8fd9\u662f\u56e0\u4e3a Windows \u5728\u5404\u4e2a\u5730\u533a\u53d1\u884c\u7684\u662f\u201c\u7279\u4f9b\u7248\u201d\uff1a\u5728\u4e2d\u56fd\u5927\u9646\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 GBK \u5b57\u7b26\u96c6\uff0c\u5728\u65e5\u672c\u5730\u533a\uff0c\u4ed6\u53d1\u884c\u7684 Windows \u91c7\u7528 Shift-JIS \u5b57\u7b26\u96c6\u3002\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u7a0b\u5e8f\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u5b58\u50a8\u7684\u662f Shift-JIS \u7684\u90a3\u4e9b\u201c\u6574\u6570\u201d\u3002\u8fd9\u5bfc\u81f4\u65e5\u672c\u7684 galgame \u5728\u4e2d\u56fd\u5927\u9646\u7279\u4f9b\u7684 Windows \u4e2d\uff0c\u628a Shift-JIS \u7684\u201c\u6574\u6570\u201d\u7528 GBK \u7684\u8868\u6765\u89e3\u8bfb\u4e86\uff0c\u4ece\u800c\u4e71\u7801\uff08GBK \u91cc\u7684\u65e5\u6587\u533a\u57df\u5e76\u6ca1\u6709\u548c Shift-JIS \u91cd\u53e0\uff09\u3002\u9700\u8981\u7528 Locale Emulator \u628a Shift-JIS \u7ffb\u8bd1\u6210 Unicode \u8bfb\u7ed9 Windows \u542c\u3002\u5982\u679c\u65e5\u672c\u7a0b\u5e8f\u5458\u4ece\u4e00\u5f00\u59cb\u5c31\u7edf\u4e00\u7528 Unicode \u6765\u5b58\u50a8\uff0c\u4e2d\u56fd\u533a\u73a9\u5bb6\u7684 Windows \u4e5f\u7edf\u4e00\u7528 Unicode \u89e3\u6790\uff0c\u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\u3002 \u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0cUnicode \u7ec4\u7ec7\u51fa\u73b0\u4e86\uff0c\u4ed6\u7684\u4f7f\u547d\u5c31\u662f\u7edf\u4e00\u5168\u4e16\u754c\u7684\u5b57\u7b26\u96c6\uff0c\u4fdd\u8bc1\u5168\u4e16\u754c\u6240\u6709\u7684\u6587\u5b57\u90fd\u80fd\u5728\u5168\u4e16\u754c\u6240\u6709\u7684\u8ba1\u7b97\u673a\u4e0a\u663e\u793a\u51fa\u6765\u3002\u9996\u5148\u521b\u529e\u4e86 Unicode \u5b57\u7b26\u96c6\uff0c\u7136\u540e\u89c4\u5b9a\u4e86 UTF-8\u3001UTF-16\u3001UTF-32 \u4e09\u79cd\u5b57\u7b26\u7f16\u7801\uff0c\u6700\u7ec8 UTF-8 \u6210\u4e3a\u5916\u7801\u7684\u4e3b\u6d41\uff0cUTF-32 \u6210\u4e3a\u5185\u7801\u7684\u4e3b\u6d41\u3002 \u63a5\u4e0b\u6765\u4e3a\u4e86\u65b9\u4fbf\u8bb0\u5fc6\uff0c\u6211\u4eec\u7d22\u6027\u5c31\u987a\u7740\u5fae\u8f6f\u7684\u8fd9\u4e2a\u8bf4\u6cd5\uff1a \u7ba1 char \u53eb ANSI\uff1a\u968f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002 \u7ba1 wchar_t \u53eb Unicode\uff1a\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u5728 Linux \u4e0a\u662f UTF-32\u3002","title":"\u8f76\u4e8b\uff1a\u201cANSI\u201d \u4e0e \u201cUnicode\u201d \u662f\u4ec0\u4e48"},{"location":"unicode/#utf-16_1","text":"\u5fae\u8f6f\u7ba1 UTF-16 \u53eb Unicode \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u95ee\u9898\uff1a \u56e0\u4e3a\u5f53\u5e74 Unicode 5.0 \u7684\u65f6\u5019\u53ea\u6709 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff0c16 \u4f4d\u5c31\u88c5\u5f97\u4e0b\uff0c\u6240\u4ee5\u5f53\u65f6 UTF-16 \u8fd8\u662f\u4e00\u4e2a \u5b9a\u957f\u7f16\u7801 \u3002\u5fae\u8f6f\u4e8e\u662f\u51b3\u5b9a\u628a wchar_t \u5b9a\u4e49\u6210 2 \u5b57\u8282\uff0c\u5e76\u5728 NT \u5185\u6838\u4e2d\uff0c\u4e3a\u6bcf\u4e2a\u7cfb\u7edf\u8c03\u7528\u90fd\u5347\u7ea7\u6210\u4e86\u57fa\u4e8e wchar_t \u5b57\u7b26\u4e32\u7684 \u201cW \u7cfb\u201d API\u3002 \u6bd4\u5c14\u76d6\u5b50\u5f53\u65f6\u4ee5\u4e3a\u8fd9\u6837 UTF-16 \u5b9a\u957f\u5185\u7801\u5c31\u4e00\u52b3\u6c38\u9038\u4e86\uff0c\u5e76\u53f7\u53ec\u6240\u6709\u7a0b\u5e8f\u90fd\u6539\u7528 UTF-16 \u505a\u5185\u7801\uff0c\u522b\u7528 \u201cA \u7cfb\u201d API \u4e86\u3002 \u8d77\u521d\uff0c\u6240\u6709\u4eba\u90fd\u4ee5\u4e3a UTF-16 \u5c31\u662f\u6700\u7ec8\u7b54\u6848\u3002 \u6ca1\u60f3\u5230\u540e\u6765 Unicode \u59d4\u5458\u4f1a\u201c\u80cc\u523a\u201d\u4e86\u6bd4\u5c14\u76d6\u5b50\uff01\u5077\u5077\u628a\u8303\u56f4\u66f4\u65b0\u5230\u4e86 0x10FFFF\uff0c\u7a81\u7834\u4e86 16 \u4f4d\u6574\u6570\u7684\u5bb9\u91cf\u3002\u539f\u6765\u7684 UTF-16 \u5df2\u7ecf\u5bb9\u7eb3\u4e0d\u4e0b\uff0c\u53ea\u597d\u5229\u7528\u4e4b\u524d\u9884\u7559\u7684 0xD800 \u5230 0xDFFF \u7a7a\u53f7\u533a\u95f4\u4e11\u964b\u5730\u5b9e\u73b0\u4e86\u53d8\u957f\u7f16\u7801\u3002 \u76f4\u5230 UTF-16 \u4e00\u591c\u4e4b\u95f4\u6210\u4e86\u4e11\u964b\u7684 \u53d8\u957f\u7f16\u7801 \u3002 \u95f9\u4e86\u534a\u5929\uff0cWindows \u8d39\u5fc3\u8d39\u529b\u66ff Unicode \u59d4\u5458\u4f1a\u597d\u4e0d\u5bb9\u6613\u63a8\u5e7f\u7684 wchar_t \uff0c\u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801 \u7684\u597d\u5904\u3002\u53ef \u201cW \u7cfb\u201d API \u5374\u53c8\u710a\u6b7b\u5728\u4e86 NT \u5185\u6838\u6700\u5e95\u5c42\uff0c\u53cd\u590d\u6765\u5751\u7b2c\u4e00\u6b21\u7528 Windows \u7f16\u7a0b\u7684\u521d\u5b66\u8005\u3002 \u6bd4\u5c14\u76d6\u5b50\uff1a\u4f60\u8fd9\u6837\u663e\u5f97\u6211\u5f88\u5c0f\u4e11\u8bf6\uff1f \u9664 Windows \u5916\uff0cJava \u4e5f\u662f\u201cUTF-16 \u80cc\u523a\u201d\u7684\u53d7\u5bb3\u8005\uff0c\u4ed6\u4eec\u60f3\u5f53\u7136\u7684\u628a char \u5b9a\u4e49\u4e3a UTF-16\uff0c\u4ee5\u4e3a\u8fd9\u5c31\u662f\u672a\u6765\u6c38\u4e45\u7684\u5b9a\u957f\u5185\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u2026\u2026 \u76f4\u5230 Unicode \u52a0\u5165\u4e86 0x10FFFF\uff0cJava \u4e0d\u5f97\u4e0d\u91cd\u65b0\u5b9a\u4e49\u4e86\u4e2a Character \u4f5c\u4e3a UTF-32 \u5b57\u7b26\uff0c\u8fd8\u5f04\u4e2a char \u5230 Character \u7684\u8f6c\u6362\uff0c\u597d\u4e0d\u5c34\u5c2c\uff01 Linux \u6210\u7acb\u4e8e 1991 \u5e74\uff0c\u5f53\u65f6 Unicode \u4e5f\u624d\u521a\u521a\u51fa\u73b0\u3002Unicode \u5ba3\u5e03\u52a0\u5165 0x10FFFF \u540e\uff0cLinux \u624d\u5f00\u59cb\u5f15\u5165\u652f\u6301 Unicode\u3002\u5728\u77e5\u9053\u4e86 Unicode \u5305\u542b 0x10FFFF \u540e\uff0c\u4ed6\u4eec\u4e00\u5f00\u59cb\u5c31\u628a wchar_t \u5b9a\u4e49\u6210 4 \u5b57\u8282\uff0c\u9003\u8fc7\u4e86 UTF-16 \u7684\u80cc\u523a\u3002 \u540e\u6765\u65b0\u51fa\u7684\u8bed\u8a00\uff0c\u5982 Python 3\u3001Go\u3001Rust\u3001Swift\u3001Kotlin\uff0c\u628a\u5b57\u7b26\u94a6\u5b9a\u4e3a UTF-32 \u4e86\u3002\u4ed6\u4eec\u53ea\u6709\u5728\u8c03\u7528 Windows API \u65f6\uff0c\u624d\u4f1a\u4e34\u65f6\u8f6c\u6362\u4e3a UTF-16 \u6765\u8c03\u7528\uff0c\u9664\u6b64\u4e4b\u5916\u518d\u65e0 UTF-16 \u51fa\u73b0\u3002 \u8bb8\u591a\u7cdf\u7cd5\u7684\u535a\u5ba2\u58f0\u79f0\uff1a\u662f\u56e0\u4e3a\u201cUTF-16 \u6700\u6709\u5229\u4e8e\u4e2d\u6587\u538b\u7f29\u201d\uff0c\u6240\u4ee5 Java \u548c Windows \u624d\u91c7\u7528\u7684\uff1f\u7136\u800c\u5c31\u6211\u4e86\u89e3\u5230\u7684\u5b9e\u9645\u60c5\u51b5\u662f\u56e0\u4e3a\u4ed6\u4eec\u9519\u8bef\u7684\u4ee5\u4e3a 0xFFFF \u662f Unicode \u7684\u4e0a\u9650\u624d\u9519\u8bef\u91c7\u7528\u4e86\uff0c\u4e0d\u7136\u4e3a\u4ec0\u4e48\u540e\u6765\u7684\u65b0\u8bed\u8a00\u90fd\u91c7\u7528\u4e86 UTF-32 \u5185\u7801 + UTF-8 \u5916\u7801\u7684\u7ec4\u5408\uff1f\u800c\u4e14\u5728\u5916\u7801\u4e2d\u91c7\u7528 UTF-8 \u6216 UTF-16 \u538b\u7f29\u786e\u5b9e\u6ca1\u95ee\u9898\uff0c\u4f46\u662f Java \u548c Windows \u7684\u5931\u8bef\u5728\u4e8e\u628a UTF-16 \u5f53\u4f5c\u5185\u7801\u4e86\uff01\u5185\u7801\u5c31\u7406\u5e94\u662f\u5b9a\u957f\u7f16\u7801\u7684\u624d\u65b9\u4fbf\uff0c\u5982\u679c\u4f60\u6709\u4e0d\u540c\u60f3\u6cd5\uff0c\u6b22\u8fce\u7559\u8a00\u8ba8\u8bba\u3002 \u603b\u4e4b\uff0cUTF-16 \u662f\u7cdf\u7c95\uff0c\u4f46\u4ed6\u662f Windows \u552f\u4e00\u5b8c\u6574\u652f\u6301\u7684 Unicode \u63a5\u53e3\u3002\u4e0d\u5efa\u8bae\u8f6f\u4ef6\u5185\u90e8\u7528 UTF-16 \u5b58\u50a8\u6587\u5b57\uff0c\u4f60\u53ef\u4ee5\u7528\u66f4\u7d27\u51d1\u7684 UTF-8 \u6216\u66f4\u65b9\u4fbf\u5207\u7247\u7684 UTF-32\uff0c\u53ea\u9700\u5728\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u524d\u4e34\u65f6\u8f6c\u6362\u6210 UTF-16 \u5c31\u884c\u3002","title":"\u5c0f\u7b11\u8bdd\uff1aUTF-16 \u7684\u80cc\u523a"},{"location":"unicode/#stdu8string","text":"\u5fc5\u987b\u6307\u51fa\uff1a\u5728 std::string \u4e2d\u88c5 UTF-8 \u5e76\u4e0d\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u5728 std::u8string \u91cc\u540c\u6837\u53ef\u4ee5\u88c5 GBK\u3002\u8fd9\u5c31\u597d\u6bd4\u4e00\u4e2a\u540d\u53eb Age \u7684\u679a\u4e3e\u7c7b\u578b\uff0c\u5b9e\u9645\u5374\u88c5\u7740\u6027\u522b\u4e00\u6837\u3002 enum Age { // \u9519\u8bef\u793a\u8303 Male, Female, Custom, }; // \u9664\u4e86\u8ff7\u60d1\u540c\u4e8b\u5916\uff0c\u628a\u5e74\u9f84\u548c\u6027\u522b\u7684\u7c7b\u578b\u6df7\u7528\u6ca1\u6709\u597d\u5904 void registerStudent(Age age, Age sex); \u533a\u5206\u7c7b\u578b\u53ea\u662f\u5927\u591a\u6570\u4eba\u8bbe\u8ba1\u63a5\u53e3\u7684\u89c4\u8303\uff0c\u53ea\u662f\u65b9\u4fbf\u4f60\u901a\u8fc7\u770b\u51fd\u6570\u63a5\u53e3\u4e00\u773c\u533a\u5206\u8fd9\u4e2a\u51fd\u6570\u63a5\u53d7\u7684\u662f\u4ec0\u4e48\u683c\u5f0f\u7684\u5b57\u7b26\u4e32\uff0c\u5e76\u6ca1\u6709\u5f3a\u5236\u6027\u3002\u4f8b\u5982\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\u4e00\u770b\u5c31\u77e5\u9053\u8fd9\u4e9b\u51fd\u6570\u9700\u8981\u7684\u662f\u4ec0\u4e48\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 void thisFuncAcceptsANSI(std::string msg); void thisFuncAcceptsUTF8(std::u8string msg); void thisFuncAcceptsUTF16(std::u16string msg); void thisFuncAcceptsUnicode(std::wstring msg); void thisFuncAcceptsUTF32(std::u32string msg); \u6ca1\u6709 char8_t \u4e4b\u524d\uff0c\u7528\u7c7b\u578b\u522b\u540d\u540c\u6837\u53ef\u4ee5\u8d77\u5230\u5dee\u4e0d\u591a\u7684\u8bf4\u660e\u6548\u679c\uff08\u7f3a\u70b9\u662f\u65e0\u6cd5\u91cd\u8f7d\uff09\uff1a using ANSIString = std::string; using UTF8String = std::string; using UTF16String = std::vector; void thisFuncAcceptsANSI(ANSIString msg); void thisFuncAcceptsUTF8(UTF8String msg); void thisFuncAcceptsUTF16(UTF16String msg); \u4e4b\u6240\u4ee5\u6211\u4f1a\u8bf4\uff0c std::string \u5e94\u8be5\u88c5 ANSI \u5b57\u7b26\u4e32\uff0c\u662f\u56e0\u4e3a\u6240\u6709\u6807\u51c6\u5e93\u5b98\u65b9\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u4f1a\u5047\u5b9a std::string \u7c7b\u578b\u662f ANSI \u7f16\u7801\u683c\u5f0f\uff08GBK\uff09\u3002\u5e76\u4e0d\u662f\u8bf4\uff0c\u4f60\u4e0d\u80fd\u7528 std::string \u5b58\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\u7684\u5185\u5bb9\u3002 \u5982\u679c\u4f60\u5c31\u662f\u60f3\u7528 std::string \u88c5 UTF-8 \u4e5f\u53ef\u4ee5\uff0c\u53ea\u4e0d\u8fc7\u4f60\u8981\u6ce8\u610f\u5728\u4f20\u5165\u6240\u6709\u4f7f\u7528\u4e86\u6587\u4ef6\u8def\u5f84\u7684\u51fd\u6570\uff0c\u5982 fopen \uff0c std::ifstream \u7684\u6784\u9020\u51fd\u6570\u524d\uff0c\u9700\u8981\u505a\u4e00\u4e2a\u8f6c\u6362\uff0c\u8f6c\u6210 GBK \u7684 std::string \u6216 UTF-16 \u7684 std::wstring \u540e\uff0c\u624d\u80fd\u4f7f\u7528\uff0c\u5f88\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u5982\u679c\u4f60\u59cb\u7ec8\u7528 std::u8string \u88c5 UTF-8\uff0c\u90a3\u4e48\u5f53\u4f60\u628a\u5b83\u8f93\u5165\u4e00\u4e2a\u63a5\u53d7 ANSI \u7684\u666e\u901a std::string \u53c2\u6570\u65f6\uff0c\u5c31\u4f1a\u53d1\u751f\u7c7b\u578b\u4e0d\u5339\u914d\u9519\u8bef\uff0c\u5f3a\u8feb\u4f60\u91cd\u65b0\u6e05\u9192\uff0c\u6216\u662f\u5f3a\u8feb\u4f60\u4f7f\u7528\u4e00\u4e2a\u8f6c\u6362\u51fd\u6570\uff0c\u7a0d\u540e\u4f1a\u4ecb\u7ecd\u8fd9\u4e2a\u8f6c\u6362\u51fd\u6570\u7684\u5199\u6cd5\u3002 \u4f8b\u5982\u5f53\u4f60\u4f7f\u7528 std::cout << u8string \u65f6\u4f1a\u62a5\u9519\uff0c\u8feb\u4f7f\u4f60\u6539\u4e3a std::cout << u8toansi(u8string) \u624d\u80fd\u7f16\u8bd1\u901a\u8fc7\uff0c\u4ece\u800c\u907f\u514d\u4e86\u628a UTF-8 \u7684\u5b57\u7b26\u4e32\u6253\u5370\u5230\u4e86\u53ea\u652f\u6301 GBK \u7684\u63a7\u5236\u53f0\u4e0a\u3002 \u5176\u4e2d\u8f6c\u6362\u51fd\u6570\u7b7e\u540d\u4e3a std::string u8toansi(std::u8string s) \uff0c\u5f88\u53ef\u60dc\uff0c\u6807\u51c6\u5e93\u5e76\u6ca1\u6709\u63d0\u4f9b\u8fd9\u4e2a\u51fd\u6570\uff0c\u76f4\u5230 C++26 \u524d\uff0c\u6807\u51c6\u5e93\u5bf9\u5b57\u7b26\u7f16\u7801\u652f\u6301\u4e00\u76f4\u5f88\u5dee\uff0c\u4f60\u4e0d\u5f97\u4e0d\u81ea\u5df1\u5b9e\u73b0\u6216\u4f9d\u8d56\u7b2c\u4e09\u65b9\u5e93\u3002 \u603b\u4e4b\uff0c char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u5411\u8c03\u7528\u8005\u6697\u793a\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u4f8b\u5982\u8fd9\u6837\u4e00\u4e2a\u51fd\u6570\uff1a thisFuncAcceptUTF8(std::u8string msg); \u5982\u679c\u8c03\u7528\u8005\u559c\u6b22\u7528 std::string \u88c5 UTF-8 \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u7528\uff1a std::string msg; // \u8c03\u7528\u8005\u786e\u4fe1\uff0c\u8fd9\u4e2a msg \u867d\u7136\u662f `std::string`\uff0c\u4f46\u91cc\u9762\u7684\u5185\u5bb9\u5c31\u662f UTF-8 // \u90a3\u4e48\u4ed6\u53ef\u4ee5\u5f3a\u5236\u8f6c\u6362\u4e3a u8string\uff0c\u6765\u8bc1\u660e\u81ea\u5df1\u5934\u8111\u6e05\u9192 thisFuncAcceptUTF8(std::u8string((char8_t *)msg.data(), msg.size()));","title":"\u5f3a\u7c7b\u578b\u7684 std::u8string \u53ea\u662f\u541b\u5b50\u534f\u8bae"},{"location":"unicode/#_10","text":"C++ \u5b98\u65b9\u5b9a\u4e49\u4e2d\uff0c\u5b58\u5728\u4e24\u79cd\u5b57\u7b26\u96c6\u3002\u4e00\u79cd\u662f \u6e90\u7801\u5b57\u7b26\u96c6 (source charset) \uff0c\u4e00\u79cd\u662f \u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u3002 \u8fd9\u771f\u662f\u7cdf\u7cd5\u7684\u672f\u8bed\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u8fd9\u4e2a\u540d\u5b57\u5177\u6709\u8bef\u5bfc\u6027\uff0c\u4ed6\u548c\u8fd0\u884c\u65f6\u6839\u672c\u6ca1\u6709\u5173\u7cfb\uff0c\u660e\u660e\u662f\u7f16\u8bd1\u671f\u5c31\u786e\u5b9a\u7684\u3002\u6240\u4ee5\u5c0f\u5f6d\u8001\u5e08\u66ff\u4ed6\u6539\u4e2a\u540d\u5b57\uff0c\u5b9e\u9645\u5e94\u8be5\u53eb\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u96c6\u201d\u3002 \u800c\u4e14\u4ed6\u4eec\u53eb\u5b57\u7b26\u96c6\u4e5f\u4e0d\u5408\u7406\uff0c\u5e94\u8be5\u53eb\u5b57\u7b26\u7f16\u7801\u624d\u5bf9\uff0cUTF-8 \u548c UTF-16 \u90fd\u662f Unicode \u5b57\u7b26\u96c6\u7684\u4e24\u79cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u4f46\u4ed6\u4eec\u660e\u663e\u662f\u4e0d\u540c\u7684\u3002 \u7136\u540e\uff0c\u518d\u5f15\u5165\u4e00\u4e2a\u771f\u6b63\u7684\uff0c\u8fd0\u884c\u65f6\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u8f6f\u4ef6\u5ba2\u6237\u7535\u8111\u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u6700\u7ec8\uff0c\u7ecf\u8fc7\u5c0f\u5f6d\u8001\u5e08\u6539\u826f\u7684\u672f\u8bed\u5982\u4e0b\uff1a \u6e90\u7801\u5b57\u7b26\u7f16\u7801: .cpp \u6e90\u7801\u6587\u4ef6\u65f6\u7528\u7684\u5b57\u7b26\u7f16\u7801\u3002\u4f8b\u5982\u7a0b\u5e8f\u5458\u7528\u8bb0\u4e8b\u672c\u4fdd\u5b58 .cpp \u6e90\u7801\u6587\u4ef6\u65f6\uff0c\u9009\u62e9 \u201cUTF-8\u201d \u4fdd\u5b58\u5c31\u662f UTF-8\uff0c\u9009\u62e9 \u201cANSI\u201d \u4fdd\u5b58\u5c31\u662f GBK\u3002 \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f char \u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u7684\u5b57\u7b26\u7f16\u7801\u3002\u9ed8\u8ba4\u662f\u6211\u4eec\u7a0b\u5e8f\u5458\uff08\u5f00\u53d1\u8005\uff09\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801: \u6307\u7684\u662f\u6211\u4eec\u7684\u7a0b\u5e8f\u5728\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf\u4e2d\u8fd0\u884c\u65f6\uff0c\u5ba2\u6237\u7684\u64cd\u4f5c\u7cfb\u7edf API \u7684 const char * \u671f\u671b\u63a5\u53d7\u600e\u6837\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002\u9ed8\u8ba4\u662f\u5ba2\u6237\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 \u8fd9\u4e09\u4e2a\u53ef\u4ee5\u5404\u6709\u4e0d\u540c\u3002 \u5176\u4e2d \u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801 \u548c \u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801 \u7684\u4e0d\u5339\u914d\uff0c\u662f Windows \u8f6f\u4ef6\u51fa\u73b0\u4e71\u7801\u7684\u4e3b\u8981\u539f\u56e0\u3002 \u800c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u53ea\u4e8b\u5173\u4f60\u5982\u4f55\u4fdd\u5b58\u6e90\u7801\uff0c\u53ea\u662f\u8ba9\u7f16\u8bd1\u5668\u80fd\u591f\u6210\u529f\u8bfb\u53d6\u4f60\u7684\u6e90\u7801\uff0c\u5bf9\u8fd0\u884c\u65f6\u7684\u4e71\u7801\u95ee\u9898\u6ca1\u6709\u5f71\u54cd\u3002\u7f16\u8bd1\u5668\u8bfb\u5b8c\u6e90\u7801\u540e\uff0c\u8981\u5728\u5e38\u91cf\u533a\u751f\u6210\u5b57\u7b26\u4e32\u5e38\u91cf\u65f6\uff0c\u8fd8\u662f\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u7684\u3002 \u4f8b\u5982\u4e4b\u524d\u8bf4\u7684\u65e5\u672c galgame \u5728\u4e2d\u56fd\u7535\u8111\u4e0a\u6253\u5f00\u7206\u51fa\u4e71\u7801\uff0c\u5c31\u662f\u56e0\u4e3a\u662f\u65e5\u672c\u7a0b\u5e8f\u5458\u7f16\u8bd1\u4e86 galgame\uff08\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u4e3a Shift-JIS\uff09\uff0c\u5728\u4e2d\u56fd\u5ba2\u6237\u7535\u8111\u4e0a\u6253\u5f00\uff08\u8fd0\u884c\u65f6\u5b57\u7b26\u7f16\u7801\u4e3a GBK\uff09\u5bfc\u81f4\u7684\u3002 \u65e5\u672c\u7a0b\u5e8f\u5458\u4f7f\u7528\u4ec0\u4e48\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u6839\u672c\u65e0\u5173\u7d27\u8981\u2026\u2026\u54ea\u6015\u4ed6\u4eec\u4f7f\u7528\u4e86 UTF-8 \u4fdd\u5b58\u6e90\u7801\uff0cMSVC \u7f16\u8bd1\u65f6\u4ecd\u7136\u4f1a\u5c06\u5176\u8f6c\u6362\u4e3a Shift-JIS \u7f16\u7801\u7684\u5b57\u9762\u91cf\u6765\u5b58\u50a8\u5728\u53ef\u6267\u884c\u6587\u4ef6\u7684\u5e38\u91cf\u533a\u4e2d\u3002 \u4f60\u53ef\u80fd\u4f1a\u95ee\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u628a\u8fd9\u4e9b\u82b1\u91cc\u80e1\u54e8\u73a9\u5e94\u7edf\u4e00\u4e3a UTF-8\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u8f6c\u6362\u6765\u8f6c\u6362\u53bb\u4e86\uff1f\u8fd8\u4e0d\u662f\u56e0\u4e3a\u5386\u53f2\u9057\u7559\uff0c\u4e00\u4e9b\u52b3\u4fdd\u7a0b\u5e8f\u5458\u4e0d\u80af\u628a\u4ed6\u4eec GBK \u7f16\u7801\u7684\u6e90\u7801\u6539\u6210 UTF-8 \u4fdd\u5b58\uff0c\u800c\u4e14\uff0cWindows \u4e5f\u5b8c\u5168\u4e0d\u63d0\u4f9b\u57fa\u4e8e UTF-8 \u7684\u8de8\u5e73\u53f0 API\uff08\u53ea\u63d0\u4f9b GBK \u548c UTF-16 \u4e24\u79cd\uff0c\u5c31\u662f\u4e0d\u7ed9 UTF-8 \u7684\uff0c\u975e\u5e38\u6076\u5fc3\u4eba\uff09\u3002\u6240\u4ee5 MSVC \u81f3\u4eca\u4ecd\u7136\u9ed8\u8ba4\u662f GBK \u7f16\u7801\u7684\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f ANSI\uff0c\u8ddf\u968f\u4f60\u7cfb\u7edf\u7684\u533a\u57df\u8bbe\u7f6e\u800c\u53d8\uff0c\u5728\u4e2d\u56fd\u5c31 GBK\uff0c\u5728\u7f8e\u56fd\u5c31 UTF-8\uff0c\u5728\u6b27\u6d32\u5c31 Latin-1\uff0c\u975e\u5e38\u7684\u53cc\u6807\uff09\u3002\u5fae\u8f6f\u5404\u79cd\u626f\u76ae\u6548\u7387\u4f4e\u4e0b\uff0cAPI \u5f04\u4e86\u4e00\u5957\u53c8\u4e00\u5957\u4e92\u76f8\u6781\u9650\u62c9\u626f\uff0c\u800c\u6211\u4eec Linux \u548c GCC \u65e9\u5df2\u9ed8\u8ba4\u5c31\u662f UTF-8\u2026\u2026 \u6211\u7406\u89e3\u4f60\u73b0\u5728\u5927\u8111\u5e72\u70e7\u7684\u5fc3\u60c5\u3002\u4f3a\u5019\u8fd9\u4e9b\u5386\u53f2\u7b54\u8fa9\u5f88\u590d\u6742\uff0c\u4e5f\u5f88\u65e0\u804a\uff0c\u6beb\u65e0\u610f\u4e49\uff01\u53ea\u662f\u4e3a\u4e86\u64e6\u53cd Unicode \u52b3\u4fdd\u7684\u5c41\u80a1\u3002","title":"\u6e90\u7801\u5b57\u7b26\u96c6\u4e0e\u8fd0\u884c\u5b57\u7b26\u96c6"},{"location":"unicode/#_11","text":"\u5bf9\u4e8e\u8de8\u5e73\u53f0\u8f6f\u4ef6\u6765\u8bf4\uff0c\u6211\u63a8\u8350\u5927\u5bb6\u628a\u4e09\u4e2a\u5168\u90e8\u8bbe\u4e3a UTF-8\uff01\uff08\u8981\u505a\u5230\u8fd9\u4e00\u70b9\uff0c\u4e3b\u8981\u662f\u4f3a\u5019 MSVC\uff09 Linux + GCC \u7528\u6237\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0c\u4f60\u4eec\u6240\u6709\u5b57\u7b26\u96c6\u9ed8\u8ba4\u7684\u8bbe\u5b9a\u5c31\u662f UTF-8\u3002 Windows + MSVC \u7528\u6237\u8bf7\u5f00\u542f /utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\uff0c\u73b0\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u5728\u5185\u5b58\u4e2d\u90fd\u662f UTF-8 \u4e86\u3002 Windows + MinGW \u7528\u6237\u8bf7\u5f00\u542f -finput-charset=utf-8 \u548c -fexec-charset=utf-8 \uff0c\u8fd9\u4f1a\u628a\u201c\u6e90\u7801\u5b57\u7b26\u7f16\u7801\u201d\u548c\u201c\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\u201d\u90fd\u8bbe\u4e3a UTF-8\u3002 \u6240\u6709\u6e90\u7801\u6587\u4ef6\u7edf\u4e00\u4ee5 UTF-8 \u7f16\u7801\u4fdd\u5b58\uff0c\u4e14\u5c3d\u91cf\u5728\u6700\u524d\u9762\u52a0\u4e0a 0xFEFF \u8fd9\u4e2a BOM \u6807\u8bb0\uff0c\u9632\u6b62 MSVC \u8111\u62bd\u5f53\u4f5c GBK \u6765\u8bfb\u53d6\u3002 \u5728 main \u51fd\u6570\u524d\uff0c\u52a0\u4e24\u884c\uff1a // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 return 0; } \u8fd9\u6837\u4e00\u5957\u6253\u4e0b\u6765\uff0c\u5c31\u53ef\u4ee5\u4fdd\u8bc1\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u8bd1\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u64cd\u4f5c\u7cfb\u7edf\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u6587\u672c\u7f16\u8f91\u5668\uff0c\u65e0\u8bba\u4f60\u4f7f\u7528\u4ec0\u4e48\u7f16\u7801\uff0c\u4f60\u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u8bfb\u53d6\u6e90\u7801\uff0c\u6b63\u786e\u7684\u4ee5 UTF-8 \u7f16\u7801\u6765\u5b58\u50a8\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u6b63\u786e\u7684\u628a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u8def\u5f84\u8f6c\u4e3a UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u3002 \u5728 CMake \u4e2d\uff0c\u53ea\u5bf9 MSVC \u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8fd9\u6837\u5199\uff1a if (MSVC) target_compile_options(\u4f60\u7684\u7a0b\u5e8f PRIVATE /utf-8) else() \u4e5f\u53ef\u4ee5\u5728\u6700\u524d\u9762 add_compile_options \uff0c\u5b9e\u73b0\u5bf9\u6240\u6709\u4e4b\u540e\u5b9a\u4e49\u7684\u7a0b\u5e8f\u5168\u5c40\u542f\u7528\u8be5\u9009\u9879\u3002 \u5728\u6211\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\uff0c\u6211\u90fd\u4f1a\u8fd9\u6837\u5f00\u542f\uff0c\u89e3\u51b3 MSVC \u4e0d\u8de8\u5e73\u53f0\u7684\u95ee\u9898\uff1a if (MSVC) add_compile_options(/Zc:preprocessor /utf-8 /DNOMINMAX /D_USE_MATH_DEFINES /EHsc /bigobj) else() if (WIN32) add_compile_options(-finput-charset=utf-8 -fexec-charset=utf-8) endif() add_compile_options(-Wall -Wextra -Werror=return-type) endif() add_executable(\u4f60\u7684\u7a0b\u5e8f \u4f60\u7684\u6587\u4ef6.cpp) # \u81ea\u52a8\u7ee7\u627f\u4e86\u4e0a\u9762\u6240\u6709\u7684\u7f16\u8bd1\u5668\u9009\u9879","title":"\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5e94\u8be5\u600e\u4e48\u505a"},{"location":"unicode/#utf-8-locale","text":"Windows \u5b98\u65b9\u63d0\u4f9b\u7684\u771f\u6b63 API \u662f _wfopen \u3002 fopen \u53ea\u662f\u4ed6\u4eec\u63d0\u4f9b\u7684\u201cPOSIX \u517c\u5bb9\u5c42\u201d \u5305\u88c5\uff0c\u5176\u4f1a\u628a\u8f93\u5165\u7684\u5b57\u7b26\u4e32\u53c2\u6570\u901a\u8fc7 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u540e\uff0c\u8f6c\u53d1\u7ed9 _wfopen \u3002 \u51fa\u4e8e\u8de8\u5e73\u53f0\u7684\u8981\u6c42\uff0c\u6211\u4eec\u4e0d\u80fd\u4f7f\u7528 _wfopen \u8fd9\u79cd\u5176\u4ed6\u5e73\u53f0\u6ca1\u6709\u7684\u51fd\u6570\uff0c\u4e5f\u4e0d\u60f3\u7528\u90a3\u8fde 2 \u5b57\u8282 4 \u5b57\u8282\u90fd\u98d8\u5ffd\u4e0d\u5b9a\u7684 wchar_t \uff0c\u66f4\u4e0d\u60f3\u8ba9 std::string \u5b58\u6839\u672c\u4e0d\u80fd\u8de8\u5e73\u53f0\u7684 GBK\u3002 \u53ea\u8981\u8ba9 fopen \u7684 \u201cGBK \u5230 UTF-16\u201d \u8f6c\u6362\u51fd\u6570\u66ff\u6362\u6210 \u201cUTF-8 \u5230 UTF-16\u201d \u5c31\u884c\u4e86\u3002\u8fc7\u53bb\uff0c\u6211\u4eec\u65e0\u6cd5\u66ff\u6362\uff0c\u6700\u65b0\u7684 Windows \u5728\u4e00\u6b21\u66f4\u65b0\u4e2d\uff0c\u652f\u6301\u4e86 \".utf-8\" locale \u8fd9\u4e00\u9ed1\u79d1\u6280\uff0c\u4e13\u95e8\u6ee1\u8db3\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u7684\u9700\u8981\u3002 // \u9ed8\u8ba4 locale fopen(\"\u4f60\u597d.txt\") == _wfopen(gbk_to_utf16(\"\u4f60\u597d.txt\")); // \u8bbe\u7f6e\u4e86 utf-8 locale \u540e fopen(\"\u4f60\u597d.txt\") == _wfopen(utf8_to_utf16(\"\u4f60\u597d.txt\")); \u82e5\u4e0d\u8bbe\u7f6e setlocale(LC_ALL, \".utf-8\") \uff0c\u5219 fopen \u548c ifstream \u9ed8\u8ba4\u4f1a\u628a\u4f60\u63d0\u4f9b\u7684 const char * \u6587\u4ef6\u8def\u5f84\uff0c\u5f53\u4f5c GBK \u7f16\u7801\u7684\uff0c\u800c\u6211\u4eec\u8bbe\u7f6e\u4e86 /utf-8 \u6216 -fexec-charset=utf-8 \u540e\uff0c\u5b57\u7b26\u4e32\u5b57\u9762\u91cf\u7f16\u7801\u5df2\u7ecf\u662f UTF-8 \u4e86\uff0c\u8fd9\u6837 UTF-8 \u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u8f93\u5165\u8fdb\u671f\u671b const char * \u7684 fopen \u53c2\u6570\uff0c\u5c31\u4f1a\u51fa\u4e71\u7801\u95ee\u9898\u4e86\u3002 \u4e0d\u8fc7\u8981\u6ce8\u610f\uff0c .utf-8 locale \u53ea\u662f\u5f71\u54cd\u4e86\u6807\u51c6\u5e93\uff01\u5e76\u4e0d\u6539\u53d8\u7cfb\u7edf API\u3002 \u76f4\u63a5\u8c03\u7528\u7cfb\u7edf API \u65f6\uff0cA \u7cfb API \u4ecd\u7136\u6709\u95ee\u9898\u3002 MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u63d0\u793a\", MB_OK); // \u4e0d\u884c\uff0c.utf-8 \u53ea\u662f\u8ba9\u6807\u51c6\u5e93\u53d8\u6210 UTF-8 \u63a5\u53e3\u4e86\uff0cA \u7cfb Windows API \u4ecd\u7136\u662f GBK MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u63d0\u793a\", MB_OK); // \u6ca1\u95ee\u9898\uff01\u7528 UTF-16 \u7684 wchar_t \u5b57\u9762\u91cf\u6765\u8c03\u7528 W \u63a5\u53e3\u603b\u662f\u6ca1\u95ee\u9898\u7684 \u8fd8\u662f\u9700\u8981\u6211\u4eec\u624b\u52a8\u8f6c\u6362 UTF-8 \u5230 UTF-16 \u540e\u8c03\u7528 W \u7cfb API\u2026\u2026\u4f46\u662f\u53cd\u6b63\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u5f88\u5c11\u9700\u8981\u76f4\u63a5\u8c03\u7528 Windows API\uff0c\u90fd\u662f\u901a\u8fc7\u901a\u7528\u7684 C/C++ \u6807\u51c6\u5e93\uff0c\u56e0\u6b64 .utf-8 locale \u53ef\u80fd\u662f\u8de8\u5e73\u53f0\u7a0b\u5e8f\u5458\u60f3\u8fdb\u519b UTF-8 \u7684\u6700\u4f73\u9009\u62e9\u3002","title":".utf-8 locale \u662f\u5982\u4f55\u5de5\u4f5c\u7684"},{"location":"unicode/#b-wchar_t","text":"\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\uff0c\u90fd\u662f\u9488\u5bf9 char \u7684\uff0c\u53ea\u6709 char \u88ab\u6545\u610f\u9488\u5bf9\u4e86\uff0c\u5b58\u5728\u5b57\u7b26\u7f16\u7801\u4e0d\u7edf\u4e00\u7684\u95ee\u9898\u3002 \u5982\u679c\u5168\u90e8\u7528 wchar_t \u7684\u8bdd\uff0c\u867d\u7136\u5728 Linux \u4e0a\u662f UTF-32\uff0c\u5728 Windows \u4e0a\u662f UTF-16\uff0c\u4e0d\u7edf\u4e00\u4e86\u3002\u4f46\u81f3\u5c11\u5728\u540c\u4e00\u4e2a Windows \u64cd\u4f5c\u7cfb\u7edf\u4e0a\uff0c\u90fd\u662f\u7edf\u4e00\u7684 UTF-16\u3002 \u6240\u4ee5\u8fd8\u6709\u4e00\u79cd\u65b9\u5f0f\u662f\u5168\u9762\u91c7\u7528 wchar_t \u548c std::wstring \uff0c\u8fd9\u6837\u65e0\u8bba\u4f60\u7684\u8fd0\u884c\u5b57\u7b26\u96c6\u548c\u533a\u57df\u8bbe\u7f6e\u5982\u4f55\uff0c\u90fd\u5bf9 wchar_t \u548c\u57fa\u4e8e const wchar_t * \u7684\u51fd\u6570\u6ca1\u6709\u4efb\u4f55\u5f71\u54cd\u3002 C \u8bed\u8a00\u6807\u51c6\u6ca1\u6709 _wfopen \uff0c\u4f46\u662f std::ifstream \u6709\u57fa\u4e8e std::wstring \u7684\u6784\u9020\u51fd\u6570\uff0c\u5c31 C++ \u6807\u51c6\u5e93\u6765\u770b std::wstring \u7684\u652f\u6301\u8fd8\u662f\u5f88\u4e30\u5bcc\u7684\uff0c\u57fa\u672c std::string \u6709\u7684 std::wstring \u90fd\u6709\uff0c\u4f8b\u5982 std::to_string \u548c std::to_wstring \uff0c std::cout \u548c std::wcout \u3002\u672c\u7ae0\u8282\u6700\u540e\u6211\u4eec\u4f1a\u8be6\u7ec6\u4ecb\u7ecd\u5bbd\u5b57\u7b26\u6d41\u7684\u7528\u6cd5\u3002 \u7f3a\u70b9\u662f\uff0c\u9996\u5148\u6bcf\u6b21\u90fd\u9700\u8981\u5199 L\"\u4f60\u597d\" \u8fd9\u4e2a L \u524d\u7f00\u5f88\u9ebb\u70e6\uff0c\u5bb9\u6613\u5fd8\u8bb0\u3002 \u800c\u4e14\u5f88\u591a\u7b2c\u4e09\u65b9\u5e93\u90fd\u5728\u7528 std::string \uff0c\u5e76\u6ca1\u6709\u63d0\u4f9b std::wstring \u7684 API\u3002 \u4f8b\u5982 openvdb \u7684\u6587\u4ef6\u5199\u5165\u51fd\u6570\uff1a void openvdb::io::File::write(std::string const &filename); \u8fd9\u6837\u5c31\u5f88\u9ebb\u70e6\u4e86\uff0c\u5982\u679c\u4f60\u5185\u90e8\u5168\u662f UTF-16 \u7684 std::wstring \u6765\u8868\u793a\u5b57\u7b26\u4e32\uff0c\u8c03\u7528\u7b2c\u4e09\u65b9\u5e93\u524d\u5c31\u9700\u8981\u8f6c\u6210 GBK \u7684 std::string \u3002\u53ef\u4ee5\u7528 boost::locale::conv::to_utf \u8fd9\u4e2a\u51fd\u6570\u8f6c\u6362\uff0c\u4f46\u4e5f\u5f88\u9ebb\u70e6\uff0c\u800c\u4e14\u5982\u679c std::wstring \u542b\u6709 GBK \u8303\u56f4\u4e4b\u5916\u7684 \u201c\ud883\udede\u201d\uff0cGBK \u65e0\u6cd5\u8868\u793a\uff0c\u53c8\u4f1a\u6709\u7f16\u7801\u5931\u8d25\u7684\u95ee\u9898\u3002 \u8fd8\u6709 stbi_load \u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u63d0\u4f9b\u7684\u51fd\u6570\uff0c\u90fd\u662f\u53ea\u63d0\u4f9b\u4e86 const char * \u7684\u63a5\u53e3\uff0c\u591a\u4e86\u53bb\u4e86\u3002 setlocale(LC_ALL, \".utf-8\") \u7684\u597d\u5904\u662f\u53ef\u4ee5\u8ba9\u8fd9\u4e9b\u7b2c\u4e09\u65b9\u5e93\u5168\u81ea\u52a8\u90fd\u4ece GBK \u65e0\u7f1d\u5207\u6362\u5230 UTF-8\uff0c\u800c\u4e0d\u7528\u5bf9\u4ed6\u4eec\u7684\u6e90\u7801\u505a\u4efb\u4f55\u66f4\u6539\u3002\u56e0\u4e3a\u4ed6\u4eec\u5185\u90e8\u90fd\u662f\u8c03\u7528\u7684 fopen \u548c ifstream \u3002","title":"\u65b9\u6848 B\uff1a\u6295\u5954 wchar_t \u6d41\u6d3e"},{"location":"unicode/#u8","text":"\u4e2d\u56fd\u533a Windows\uff0cMSVC\uff0c\u7f16\u8bd1\u9009\u9879\uff1a /std:c++17 std::string s = \"\u4f60\u597d\"; hexdump(s); // C4 E3 BA C3 (GBK) std::string s = u8\"\u4f60\u597d\"; hexdump(s); // E4 BD A0 E5 A5 BD (UTF-8) u8 \u524d\u7f00\u544a\u8bc9\u7f16\u8bd1\u5668\uff0c\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u7f16\u7801\u5b58\u50a8\u3002\u65e0\u8bba\u8fd0\u884c\u5b57\u7b26\u96c6 (execution charset) \u662f\u4e0d\u662f UTF-8\u3002 \u7f16\u8bd1\u5668\u4fdd\u8bc1\u4f1a\u628a\u8fd9\u4e2a\u5b57\u7b26\u4e32\u5e38\u91cf\u8f6c\u6362\u4e3a UTF-8 \u7f16\u7801\u7684 char \u5b57\u8282\u5e8f\u5217\uff0c\u5b58\u50a8\u5728\u5b57\u7b26\u4e32\u5e38\u91cf\u533a\u3002 \u8fd9\u5bf9\u4e8e\u5df2\u7ecf\u8bbe\u7f6e\u4e86 /utf-8 \u9009\u9879\uff0c\u8fd0\u884c\u5b57\u7b26\u96c6\u5df2\u7ecf\u4fdd\u8bc1\u662f UTF-8 \u7684\u6211\u4eec\u6765\u8bf4\u6beb\u65e0\u4f5c\u7528\u3002\u53ea\u662f\u5bf9\u4e8e\u4e0d\u7528 /utf-8 \u7684\u540c\u5b66\uff0c\u4ed6\u4eec\u60f3\u8981\u4e34\u65f6\u521b\u5efa\u4e00\u4e2a UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5c31\u53ef\u4ee5\u7528 u8 \u524d\u7f00\u3002 \u5728 C++17 \u548c\u4e4b\u524d\uff0c u8\"\u4f60\u597d\" \u4ea7\u751f\u7684\u662f const char [] \u7c7b\u578b\u7684\u5e38\u91cf\u3002 \u5728 C++20 \u4e2d\uff0c\u5f15\u5165\u4e86 char8_t \u3002\u7136\u540e\uff0c\u4ed6\u4eec\u89c4\u5b9a\uff0c u8\"\u4f60\u597d\" \u73b0\u5728\u4ea7\u751f\u7684\u662f const char8_t [] \u7c7b\u578b\u7684\u5e38\u91cf\u4e86\u3002 \u8fd9\u5bfc\u81f4\u4e86\u4e00\u4e9b\u517c\u5bb9\u6027\u95ee\u9898\uff0c\u6bd4\u5982\u4ee5\u524d\u4f60\u5199\u7684\uff1a std::string s = u8\"\u4f60\u597d\"; \u73b0\u5728\u65e0\u6cd5\u7f16\u8bd1\u901a\u8fc7\u4e86\uff0c\u56e0\u4e3a const char8_t [] \u65e0\u6cd5\u7528\u4e8e\u6784\u9020\u53ea\u652f\u6301 const char [] \u7684 std::string \u3002 \u597d\u5728 C++23 \u53c8\u4fee\u590d\u4e86\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u4eec\u5141\u8bb8 const char8_t [] \u9690\u5f0f\u8f6c\u6362\u4e3a const char [] \uff0cC++17 \u4e4b\u524d\u7684\u8fd9\u79cd\u4ee3\u7801\u53c8\u80fd\u6b63\u5e38\u901a\u8fc7\u7f16\u8bd1\u3002\u6240\u4ee5\uff0c\u5982\u679c\u60f3\u5feb\u4e50\u5730\u7528 u8 \u5b57\u9762\u91cf\uff0c\u8981\u4e48 C++17\uff0c\u8981\u4e48 C++23\uff0c\u8df3\u8fc7 C++20 \u6bd4\u8f83\u597d\u3002 \u4f60\u53ef\u4ee5\u770b\u5230\uff0cC++ \u7248\u672c\u7684\u66f4\u65b0\u5e76\u4e0d\u662f 100% \u5b8c\u5168\u5411\u524d\u517c\u5bb9\u7684\uff0c\u6709\u65f6\u4e5f\u4f1a\u6709\u7834\u574f\u6027\u7684\u53d8\u66f4\uff0c\u4f46\u6bd4\u8f83\u5c11\uff0c\u5e73\u65f6\u611f\u89c9\u4e0d\u5230\u3002\u6bd4\u5982 C++11 \u4e4b\u524d auto \u5c31\u6709\u5176\u4ed6\u7684\u529f\u80fd\uff0c\u540e\u6765\u51b3\u5b9a\u8fd9\u4e2a\u529f\u80fd\u6ca1\u4ec0\u4e48\u7528\uff0c\u5c31\u628a auto \u6539\u6210\u53e6\u4e00\u4e2a\u610f\u601d\u4e86\u3002 \u9664\u4e86 u8 \u4ee5\u5916\uff0c\u8fd8\u6709\u8fd9\u4e9b\uff1a \u524d\u7f00 \u7f16\u7801 \u5b57\u7b26\u7c7b\u578b \u201c\u4f60\u597d\u201d \u8fd0\u884c\u5b57\u7b26\u96c6 (\u9ed8\u8ba4\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7684) const char [] L\u201d\u4f60\u597d\u201d Windows \u4e0a UTF-16\uff1bLinux \u4e0a UTF-32 const wchar_t [] u8\u201d\u4f60\u597d\u201d UTF-8 const char8_t [] u\u201d\u4f60\u597d\u201d UTF-16 const char16_t [] U\u201d\u4f60\u597d\u201d UTF-32 const char32_t [] \u53ea\u4e0d\u8fc7\u662f\u5f00\u53d1\u8005\u548c\u5ba2\u6237\u5f80\u5f80\u5904\u4e8e\u540c\u4e00\u4e2a\u5730\u533a\uff0c\u6240\u4ee5 \"\u4f60\u597d\" \u770b\u8d77\u6765\u597d\u50cf\u53ef\u4ee5\u76f4\u63a5\u8f93\u5165\u5230 std::cout \u4e2d\u4e00\u6837\u3002\u5b9e\u9645\u4e0a\u4ed6\u53ea\u662f\u5f00\u53d1\u8005\u7535\u8111\u7684 ANSI\uff0c\u800c\u4e0d\u662f\u5ba2\u6237\u7535\u8111\u7684 ANSI\uff0c\u5982\u679c\u76f4\u63a5\u62ff\u6765\u6253\u5370\uff0c\u4f1a\u5bfc\u81f4\u4ee5 \"\" \u5e38\u91cf\u5f62\u5f0f\u5199\u6b7b\u7684\u5b57\u7b26\u4e32\u4f1a\u5728\u5ba2\u6237\u7535\u8111\u4e0a\u51fa\u73b0\u4e71\u7801\u3002\u9664\u975e\u8fd9\u4e2a\u5b57\u7b26\u4e32\u53ea\u5305\u542b ASCII\uff0c\u56e0\u4e3a\u6240\u6709 ANSI \u90fd\u517c\u5bb9 ASCII\uff0c\u624d\u6070\u597d\u907f\u514d\u4e86\u4e71\u7801\u3002","title":"u8 \u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u4f5c\u7528"},{"location":"unicode/#_12","text":"","title":"\u9009\u62e9\u4f60\u7684\u9635\u8425\uff01"},{"location":"unicode/#ansi","text":"\u628a\u5b57\u7b26\u4e32\u5f53\u4f5c\u7eaf\u7cb9\u7684\u201c\u5b57\u8282\u6d41\u201d\uff0c\u65e0\u89c6\u5b57\u7b26\u7f16\u7801\u3002\u6216\u8005\u8bf4\uff0c\u4f60\u4ece\u7cfb\u7edf\u8f93\u5165\u8fdb\u6765\u7684\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u6211\u5c31\u5b58\u50a8\u7684\u4ec0\u4e48\u7f16\u7801\u3002\u5bf9\u4e8e Unicode \u5219\u91c7\u53d6\u5b8c\u5168\u6446\u70c2\u7684\u6001\u5ea6\uff0c\u5b8c\u5168\u65e0\u89c6 Unicode \u7684\u5b58\u5728\u3002 \u9002\u7528\u573a\u666f\uff1a\u901a\u5e38\u4e0e\u6587\u5b57\u5904\u7406\u9886\u57df\u65e0\u5173\u7684\u8f6f\u4ef6\u4f1a\u91c7\u53d6\u8fd9\u79cd\u65b9\u6848\u3002 \u4f18\u70b9\uff1a\u65b9\u4fbf\uff0c\u4e14\u5185\u90e8\u5bf9\u5b57\u7b26\u4e32\u65e0\u4efb\u4f55\u8f6c\u6362\u548c\u5224\u65ad\uff0c\u6548\u7387\u6700\u9ad8\u3002 \u7f3a\u70b9\uff1a\u5728\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u8bfb\u5199\u5e26\u6709\u4e2d\u6587\u7684\u6587\u4ef6\u8def\u5f84\u65f6\uff0c\u4f1a\u9971\u53d7\u4e71\u7801\u548c\u627e\u4e0d\u5230\u6587\u4ef6\u7684\u56f0\u6270\u3002 \u65b9\u6cd5\uff1a\u5b8c\u5168\u4f7f\u7528 const char * \u548c std::string \u3002 \u4ee3\u8868\u4f5c\uff1aLinux \u6587\u4ef6\u7cfb\u7edf ext4\u3001Lua \u7f16\u7a0b\u8bed\u8a00\u3001\u73b0\u4ee3 Python \u4e2d\u7684 bytes \u7c7b\u578b\u3001HTTP \u7684 ? \u53c2\u6570\u3001\u65e9\u671f FAT32 \u6587\u4ef6\u7cfb\u7edf\u7b49\u3002 \u8fd9\u7c7b\u8f6f\u4ef6\u662f\u6700\u5e38\u89c1\u7684\u521d\u5b66\u8005\u5199\u6cd5\uff0c\u5982\u679c\u4f60\u4ece\u672a\u60f3\u8fc7\u5b57\u7b26\u7f16\u7801\u95ee\u9898\uff0c\u4ece\u4e0d\u4e86\u89e3 wchar_t \u3001 char32_t \u4e4b\u95f4\u7684\u6218\u4e89\uff0c\u53ea\u77e5\u9053 char \uff0c\u90a3\u4e48\u4f60\u5df2\u7ecf\u81ea\u52a8\u5728\u6b64\u9635\u8425\u91cc\u3002 \u6709\u4eba\u8bf4 Linux \u6587\u4ef6\u7cfb\u7edf\u662f UTF-8\uff1f\u5e76\u4e0d\u662f\uff01Linux \u6587\u4ef6\u7cfb\u7edf\u6839\u672c\u4e0d\u4f1a\u68c0\u9a8c\u4f60\u7684\u6587\u4ef6\u540d\u662f\u4e0d\u662f\u5408\u6cd5\u7684 UTF-8\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u4f60\u8bbe\u5b9a\u4e86 export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u4f1a\u4f7f\u6240\u6709\u7a0b\u5e8f\uff08\u5305\u62ec\u7ec8\u7aef\u6a21\u62df\u5668\uff09\u5047\u5b9a\u6587\u4ef6\u540d\u548c\u6587\u4ef6\u5185\u5bb9\u90fd\u6309 UTF-8 \u7f16\u7801\uff0c\u4ece\u800c\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u5404\u7c7b API \u65f6\uff08\u5982 open\u3001write\uff09\u90fd\u4f1a\u4f7f\u7528 UTF-8 \u7f16\u7801\u7684 const char * \u8f93\u5165\uff0c\u5728 Linux \u7cfb\u7edf API \u770b\u6765\uff0c\u6240\u8c13\u201c\u6587\u4ef6\u540d\u201d\u53ea\u662f\u7eaf\u7cb9\u7684\u5b57\u8282\u6d41\uff0c\u53ea\u8981\u4fdd\u8bc1\u4e0d\u5305\u542b '/' \u548c '\\0' \uff0c\u65e0\u8bba\u4f60\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4ed6\u90fd\u4e0d\u5728\u4e4e\u3002\u800c\u6240\u6709\u7684 locale \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u7edd\u4e0d\u4f1a\u51fa\u73b0\u4e00\u4e2a\u4e2d\u6587\u6c49\u5b57\u7f16\u7801\u540e\u4ea7\u751f '/' \u7684\u60c5\u51b5\uff08\u4f8b\u5982 GB2312 \u4f1a\u628a\u4e00\u4e2a\u4e2d\u6587\u7f16\u7801\u6210\u4e24\u4e2a 0x80 \u5230 0xFF \u533a\u95f4\u7684\u5b57\u8282\uff0c\u548c ASCII \u7684\u8303\u56f4\u6ca1\u6709\u91cd\u53e0\uff0c\u66f4\u4e0d\u53ef\u80fd\u51fa\u73b0 '/' \uff09\uff0c\u5373\u4f7f\u6362\u6210 export LC_ALL=zh_CN.GB2312 \uff0cLinux \u6587\u4ef6\u7cfb\u7edf\u4e00\u6837\u80fd\u6b63\u5e38\u5de5\u4f5c\uff0c\u53ea\u4e0d\u8fc7\u8bfb\u53d6\u4f60\u4e4b\u524d\u4ee5 UTF-8 \u5199\u5165\u7684\u6587\u4ef6\u4f1a\u53d8\u6210\u4e71\u7801\u800c\u5df2\u3002 \u5bf9\u4e8e\u4e2d\u56fd\u533a\u7684 Windows \u800c\u8a00\uff0c\u4ed6\u7684\u6240\u6709 A \u51fd\u6570\u53ea\u652f\u6301 GBK \u7f16\u7801\u3002\u8fd9\u610f\u5473\u7740\u5982\u679c\u4f60 Lua \u4e2d\u628a\u5b57\u7b26\u4e32\u201c\u5f53\u4f5c\u201d UTF-8 \u6765\u7528\u3002\u90a3\u4e48\u5f53\u4f60\u5728\u8c03\u7528 Lua \u7684 io.open \u524d\uff0c\u9700\u8981\u5148\u505a\u4e00\u4e2a UTF-8 \u5230 GBK \u7684\u8f6c\u6362\uff0c\u8fd9\u8fd8\u4f1a\u5bfc\u81f4\u4e22\u5931\u90e8\u5206\u4e0d\u5728 GBK \u5185\u7684\u5b57\u7b26\uff0c\u6bd4\u5982\u5982\u679c\u4f60\u7684\u6587\u4ef6\u540d\u5305\u542b Emoji\uff0c\u90a3\u5c31\u4f1a\u53d8\u6210 ??? \u4e71\u7801\u3002\u800c\u4f7f\u7528 W \u51fd\u6570\u7684 UTF-16 \u5c31\u4e0d\u4f1a\uff0c\u56e0\u4e3a UTF-16 \u80fd\u5bb9\u7eb3\u5b8c\u6574\u7684 Unicode \u6620\u5c04\u3002\u800c\u5b8c\u5168\u6446\u70c2\u7684 Lua\uff0c\u5176 io.open \u53ea\u662f\u4f7f\u7528 C \u8bed\u8a00\u5e93\u51fd\u6570 fopen \uff0c fopen \u53c8\u662f\u57fa\u4e8e Windows \u7684 A \u7cfb\u5217\u51fd\u6570\uff0cLua \u53c8\u6ca1\u6709\u63d0\u4f9b\u5bf9 Windows C \u8fd0\u884c\u65f6\u5e93\u7279\u6709\u7684 _wfopen \u51fd\u6570\u7684\u5c01\u88c5\uff0c\u4ece\u800c\u6c38\u8fdc\u4e0d\u53ef\u80fd\u6253\u5f00\u4e00\u4e2a\u5e26\u6709 Emoji \u7684\u6587\u4ef6\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 ANSI \u9635\u8425\uff0c\u4f60\u4ec0\u4e48\u90fd\u4e0d\u9700\u8981\u505a\uff0cchar \u6ee1\u5929\u98de\u6446\u70c2\u3002","title":"ANSI \u9635\u8425"},{"location":"unicode/#utf-8_3","text":"\u652f\u6301 Unicode\uff0c\u5b57\u7b26\u4e32\u7edf\u4e00\u4ee5 UTF-8 \u5f62\u5f0f\u5b58\u50a8\u3001\u5904\u7406\u548c\u4f20\u8f93\u3002 \u5e94\u7528\u573a\u666f\uff1a\u5e38\u89c1\u4e8e\u6587\u5b57\u5904\u7406\u9700\u6c42\u4e0d\u5927\uff0c\u4f46\u6709\u5f3a\u70c8\u7684\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u7279\u522b\u662f\u4e92\u8054\u7f51\u65b9\u9762\u7684\u8f6f\u4ef6\u3002\u4ed6\u4eec\u901a\u5e38\u53ea\u7528\u5230\u5b57\u7b26\u4e32\u7684\u62fc\u63a5\u3001\u67e5\u627e\u3001\u5207\u7247\u901a\u5e38\u4e5f\u53ea\u662f\u5728\u56fa\u5b9a\u7684\u4f4d\u7f6e\uff08\u4f8b\u5982\u6587\u4ef6\u5206\u9694\u7b26 '/' \uff09\u3002\u4e5f\u975e\u5e38\u9002\u5408\u4e3b\u8981\u9762\u5bf9\u7684\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0cUTF-8 \u662f\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u6700\u9ad8\u7684\uff0c\u6240\u4ee5\u4e5f\u5e7f\u6cdb\u7528\u4e8e\u7f16\u8bd1\u5668\u3001\u6570\u636e\u5e93\u4e4b\u7c7b\u7684\u573a\u666f\u3002\u540c\u65f6\u56e0\u4e3a UTF-8 \u5b8c\u5168\u517c\u5bb9 ASCII\uff0c\u4f7f\u5f97\u4ed6\u80fd\u8f7b\u6613\u9002\u914d\u8fdc\u53e4\u7684 C \u8bed\u8a00\u7a0b\u5e8f\u548c\u5e93\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-8 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8de8\u5e73\u53f0\uff0c\u5728\u7f51\u7edc\u4f20\u8f93\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u7801\uff0cUTF-8 \u662f\u4e92\u8054\u7f51\u7684\u4e3b\u6d41\u7f16\u7801\u683c\u5f0f\uff0c\u4e0d\u540c\u5e73\u53f0\u4e0a\u8fd0\u884c\u7684 UTF-8 \u8f6f\u4ef6\u53ef\u4ee5\u968f\u610f\u5171\u4eab\u6587\u672c\u6570\u636e\u3002\u517c\u5bb9 ASCII\uff0c\u65b9\u4fbf\u590d\u7528\u73b0\u6709\u5e93\u548c\u751f\u6001\u3002\u5bf9\u82f1\u6587\u7c7b\u6587\u672c\u538b\u7f29\u7387\u9ad8\uff0c\u5bf9\u4e2d\u6587\u6587\u672c\u4e5f\u4e0d\u7b97\u592a\u5dee\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e\u5e95\u5c42 API \u5747\u91c7\u7528 UTF-16 \u7684 Windows \u7cfb\u7edf\uff0c\u9700\u8981\u8fdb\u884c\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u635f\u5931\u3002\u4e14\u5b57\u7b26\u4e32\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4f1a\u53d8\u6210 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002 \u4ee3\u8868\u4f5c\uff1aRust \u8bed\u8a00\u3001Go \u8bed\u8a00\u3001CMake \u6784\u5efa\u7cfb\u7edf\u3001Julia \u8bed\u8a00\u7b49\u3002 \u5728 C++ \u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7 u8\"\u4f60\u597d\" \u521b\u5efa\u4e00\u4e2a\u4fdd\u8bc1\u5185\u90e8\u662f UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u7c7b\u578b\u4e3a char8_t [] \u3002 \u5982\u679c\u7528\u65e0\u524d\u7f00\u7684 \"\u4f60\u597d\" \u521b\u5efa\uff0c\u5219 MSVC \u9ed8\u8ba4\u4f1a\u4ee5\u7f16\u8bd1\u8005\u6240\u5728\u7cfb\u7edf\u7684\u201c\u533a\u57df\u8bbe\u7f6e (locale)\u201d \u4f5c\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u7f16\u7801\u683c\u5f0f\uff08\u800c\u4e0d\u662f\u8fd0\u884c\u8005\u7684\u533a\u57df\u8bbe\u7f6e\uff01\uff09\uff0c\u5f00\u542f /utf-8 \u9009\u9879\u53ef\u4ee5\u8ba9 MSVC \u7f16\u8bd1\u5668\u9ed8\u8ba4\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u5373\u8ba9 \"\u4f60\u597d\" \u548c u8\"\u4f60\u597d\" \u4e00\u6837\u91c7\u7528 UTF-8\u3002\u800c GCC \u9ed8\u8ba4\u5c31\u662f UTF-8\uff0c\u9664\u975e\u624b\u52a8\u6307\u5b9a -fexec-charset=GBK \u6765\u5207\u6362\u5230 GBK\u3002\u7a0d\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u7f16\u8bd1\u5668\u7684\u5b57\u7b26\u7f16\u7801\u95ee\u9898\u3002 \u5047\u8bbe\u4f60\u901a\u8fc7 /utf-8 \u6216 -fexec-charset=utf-8 \u641e\u5b9a\u4e86\u7f16\u8bd1\u671f\u5e38\u91cf\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u3002\u63a5\u4e0b\u6765\u8fd8\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u6587\u4ef6\u7cfb\u7edf\u3002 Linux \u6587\u4ef6\u7cfb\u7edf\u5185\u90e8\uff0c\u5747\u4f7f\u7528 8 \u4f4d\u7c7b\u578b char \u5b58\u50a8\uff0c\u5c06\u6587\u4ef6\u540d\u5f53\u4f5c\u5e73\u51e1\u7684\u5b57\u8282\u6d41\uff0c\u4e0d\u4f1a\u505a\u4efb\u4f55\u8f6c\u6362\u3002\u56e0\u6b64\u4f60\u7528 UTF-8 \u521b\u5efa\u548c\u6253\u5f00\u7684\u6587\u4ef6\uff0c\u5176\u4ed6\u4f7f\u7528 UTF-8 \u533a\u57df\u8bbe\u7f6e\u7684\u8f6f\u4ef6\u90fd\u53ef\u4ee5\u7167\u5e38\u6253\u5f00\uff0c\u4e0d\u4f1a\u6709\u4e71\u7801\u95ee\u9898\u3002 \u5176\u5b9e Windows \u4e0a\u4ee5 GBK \u7f16\u7801\u7684\u538b\u7f29\u6587\u4ef6\u6216\u6587\u672c\u6587\u4ef6\uff0c\u62f7\u8d1d\u5230 Linux \u4e0a\u6253\u5f00\u51fa\u73b0\u4e71\u7801\u95ee\u9898\uff0c\u5c31\u662f\u56e0\u4e3a Linux \u7684\u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u90fd\u662f UTF-8 \u7684\u3002\u5b9e\u9645\u4e0a\u5982\u679c\u628a\u4f60\u7684\u6587\u4ef6\u62f7\u7ed9\u4e00\u4e2a\u7f8e\u56fd\u7684 Windows \u7528\u6237\uff0c\u4ed6\u4e5f\u4f1a\u770b\u5230\u4e71\u7801\uff0c\u56e0\u4e3a\u7f8e\u56fd\u5927\u533a\u7684 Windows \u533a\u57df\u8bbe\u7f6e\u9ed8\u8ba4\u662f UTF-8\uff0c\u800c\u4e2d\u56fd\u5927\u533a\u7684\u662f GBK\uff0c\u7a0d\u540e\u6211\u4eec\u4f1a\u8bb2\u5230\u89e3\u51b3\u65b9\u6848\u3002 \u800c Windows \u7684 NTFS \u6587\u4ef6\u7cfb\u7edf\uff0c\u91c7\u7528 16 \u4f4d\u7684 wchar_t \u5b58\u50a8\uff0cWindows \u7684\u6240\u6709 API\uff0c\u4e5f\u90fd\u662f\u57fa\u4e8e wchar_t \u7684\uff0cWindows \u5185\u6838\u5185\u90e8\u4e5f\u90fd\u7528 wchar_t \u50a8\u5b58\u6587\u672c\u5b57\u7b26\u4e32\uff0c\u53ea\u6709\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6d41\u4f1a\u7528 char \u5b58\u50a8\u3002\u8fd9\u7c7b\u57fa\u4e8e wchar_t \u7684\u7cfb\u7edf API \u90fd\u6709\u4e00\u4e2a W \u540e\u7f00\uff0c\u4f8b\u5982\uff1a MessageBoxW(NULL, L\"\u4f60\u597d\", L\"\u6807\u9898\", MB_OK); \u8fd9\u4e2a MessageBoxW \u51fd\u6570\uff0c\u53ea\u63a5\u53d7 const wchar_t * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002 L\"\u4f60\u597d\" \u662f\u4e00\u4e2a wchar_t [] \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u5b83\u7684\u5185\u90e8\u7f16\u7801\u7c7b\u578b\u56fa\u5b9a\u662f UTF-16\uff0c\u4e0d\u4f1a\u968f\u7740\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u800c\u53d8\u3002\u4e4b\u540e\u7684\u4e00\u8282\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3 W \u548c A \u51fd\u6570\u7684\u95ee\u9898\u3002 \u867d\u7136\u4e5f\u6709\u63d0\u4f9b A \u540e\u7f00\u7684\u7cfb\u5217\u51fd\u6570\uff0c\u4ed6\u4eec\u548c W \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u63a5\u53d7 const char * \u7c7b\u578b\u7684\u5b57\u7b26\u4e32\u3002\u95ee\u9898\u5728\u4e8e\uff0c\u8fd9\u4e9b\u5b57\u7b26\u4e32\u90fd\u5fc5\u987b\u662f\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u91cc\u7684\u90a3\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u4e5f\u5c31\u662f GBK \u7f16\u7801\uff01\u800c\u4e14\u65e0\u6cd5\u4fee\u6539\u3002 \u5f53\u8c03\u7528 A \u7cfb\u51fd\u6570\u65f6\uff0c\u4ed6\u4eec\u5185\u90e8\u4f1a\u628a GBK \u7f16\u7801\u8f6c\u6362\u4e3a UTF-16 \u7f16\u7801\uff0c\u7136\u540e\u8c03\u7528 Windows \u5185\u6838\u3002 \u8fd9\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\uff0c\u800c\u6240\u6709\u7684 C/C++ \u6807\u51c6\u5e93\u90fd\u662f\u57fa\u4e8e A \u51fd\u6570\u7684\uff01\u5982\u679c\u4f60\u7528 const char * \u5b57\u7b26\u4e32\u8c03\u7528 C \u6807\u51c6\u5e93\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\u4e86 A \u51fd\u6570\u3002\u800c A \u51fd\u6570\u53ea\u63a5\u53d7 GBK\uff0c\u4f46\u4f60\u5374\u8f93\u5165\u4e86 UTF-8\uff01\u4ece\u800c UTF-8 \u4e2d\u6240\u6709\u9664 ASCII \u4ee5\u5916\u7684\uff0c\u5404\u79cd\u4e2d\u6587\u5b57\u7b26\u3001Emoji \u90fd\u4f1a\u53d8\u6210\u4e71\u7801\u3002 \u4f8b\u5982 fopen \u51fd\u6570\uff0c\u53ea\u6709 fopen(const char *path, const char *mode) \u8fd9\u4e00\u4e2a\u57fa\u4e8e char \u7684\u7248\u672c\uff0c\u91cc\u9762\u4e5f\u662f\u76f4\u63a5\u8c03\u7528\u7684 A \u51fd\u6570\uff0c\u5b8c\u5168\u4e0d\u7ed9\u6211\u9009\u62e9\u7684\u7a7a\u95f4\u3002\u867d\u7136 Windows \u4e5f\u63d0\u4f9b\u4e86 _wfopen(const wchar_t *path, const wchar_t *mode) \uff0c\u4f46\u90a3\u65e2\u4e0d\u662f POSIX \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4e5f\u4e0d\u662f C \u8bed\u8a00\u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u4f7f\u7528\u8fd9\u6837\u7684\u51fd\u6570\u5c31\u610f\u5473\u7740\u65e0\u6cd5\u8de8\u5e73\u53f0\u3002 Windows \u5b98\u65b9\u8ba4\u4e3a\uff1a W \u51fd\u6570\u624d\u662f\u771f\u6b63\u7684 API\uff0c A \u51fd\u6570\u53ea\u662f\u5e94\u4ed8\u4e0d\u542c\u8bdd\u7684\u5b9d\u5b9d\u3002\u53ef\u4f60\u5c31\u6ca1\u53d1\u73b0\u4f60\u81ea\u5df1\u7684 C/C++ \u6807\u51c6\u5e93\u4e5f\u5168\u90e8\u5728\u8c03\u7528\u7684 A \u51fd\u6570\u4e48\uff1f \u603b\u4e4b\uff0c A \u51fd\u6570\u662f\u6b8b\u5e9f\u7684\uff0c\u6211\u4eec\u53ea\u80fd\u7528 W \u51fd\u6570\uff0c\u5c3d\u7ba1 UTF-16 \u662f\u5386\u53f2\u503a\uff0c\u4f46\u6211\u4eec\u522b\u65e0\u9009\u62e9\uff0c W \u51fd\u6570\u662f\u552f\u4e00\u80fd\u652f\u6301\u5b8c\u6574 Unicode \u5b57\u7b26\u8f93\u5165\u7684\u65b9\u5f0f\u3002 // \u5047\u8bbe\u8fd9\u6bb5 C++ \u4ee3\u7801\u4f7f\u7528 /utf-8 \u9009\u9879\u7f16\u8bd1\uff1a std::ifstream f(\"\u4f60\u597d.txt\"); // \u627e\u4e0d\u5230\u6587\u4ef6\uff0c\u5373\u4f7f\u201c\u4f60\u597d.txt\u201d\u5b58\u5728 std::ofstream f(\"\u4f60\u597d.txt\"); // \u4f1a\u521b\u5efa\u4e00\u4e2a\u4e71\u7801\u6587\u4ef6 \u6b63\u786e\u7684\u505a\u6cd5\u662f\u91c7\u7528 std::filesystem::u8path \u8fd9\u4e2a\u51fd\u6570\u505a UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\uff1a // C++17\uff0c\u9700\u8981\u7528 u8path \u8fd9\u4e2a\u51fd\u6570\u6784\u9020 path \u5bf9\u8c61\uff1a std::ifstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::u8path(\"\u4f60\u597d.txt\")); // C++20 \u5f15\u5165 char8_t\uff0c\u533a\u5206\u4e8e\u666e\u901a char\uff0cpath \u7c7b\u4e5f\u6709\u4e86\u9488\u5bf9 const char8_t * \u7684\u6784\u9020\u51fd\u6570\u91cd\u8f7d\uff1a std::ifstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::ofstream f(std::filesystem::path(u8\"\u4f60\u597d.txt\")); std::filesystem::path \u7c7b\u7684 c_str() \u5728 Windows \u4e0a\u8fd4\u56de const wchar_t * \uff0c\u5728 Linux \u4e0a\u8fd4\u56de const char * \u3002\u8fd9\u5f88\u5408\u7406\uff0c\u56e0\u4e3a Windows \u6587\u4ef6\u7cfb\u7edf\u786e\u5b9e\u4ee5 wchar_t \u5b58\u50a8\u8def\u5f84\u540d\uff0c\u800c Linux \u6587\u4ef6\u7cfb\u7edf\u5b8c\u5168\u7528 char \u3002 \u6bcf\u6b21\u9700\u8981\u52a0 std::filesystem::u8path \u4e5f\u633a\u9ebb\u70e6\u7684\uff0c\u5bb9\u6613\u5fd8\u8bb0\uff0c\u4e00\u5fd8\u8bb0\u5c31\u65e0\u6cd5\u8bbf\u95ee\u4e2d\u6587\u76ee\u5f55\u3002 \u5f88\u591a\u8f6f\u4ef6\u5728 Windows \u4e0a\u65e0\u6cd5\u652f\u6301\u4e2d\u6587\u8def\u5f84\u540d\uff0c\u5c31\u662f\u56e0\u4e3a\u4ed6\u4eec\u4e60\u60ef\u4e86 Linux \u6216 MacOS \u7684\u5168 UTF-8 \u73af\u5883\uff0c\u5bf9\u6587\u4ef6\u8def\u5f84\u6ca1\u6709\u4efb\u4f55\u8f6c\u6362\u3002\u800c Windows \u5e95\u5c42\u5168\u662f UTF-16\uff0c\u6839\u672c\u6ca1\u6709\u63d0\u4f9b UTF-8 \u7684 API\uff0c\u4f60 UTF-8 \u53ea\u80fd\u8f6c\u6362\u6210 UTF-16 \u624d\u80fd\u907f\u514d\u4e2d\u6587\u4e71\u7801\u3002\u4e2a\u4eba\u8ba4\u4e3a\uff0c\u6b7b\u6d3b\u4e0d\u80af\u63a5\u53d7\u660e\u6446\u7740\u5df2\u7ecf\u662f\u56fd\u9645\u901a\u7528\u6807\u51c6\u7684 UTF-8\uff0cA \u51fd\u6570\u7684\u7f16\u7801\u8fde\u5f53\u524d\u8fdb\u7a0b\u5207\u6362\u7684\u65b9\u6cd5\u90fd\u4e0d\u7ed9\u4e00\u4e2a\uff0c\u8fd9\u4e2a\u5e94\u8be5\u7531 Windows \u5168\u8d23\u627f\u62c5\u3002 \u597d\u6d88\u606f\u662f\uff0c\u6700\u8fd1 MSVC \u6807\u51c6\u5e93\u63d0\u4f9b\u4e86\u4e00\u79cd\u65b9\u6848\uff0c\u5728\u4f60\u7684\u7a0b\u5e8f\u5f00\u5934\uff0c\u52a0\u4e0a setlocale(LC_ALL, \".utf-8\") \u5c31\u53ef\u4ee5\u8ba9 C \u548c C++ \u6807\u51c6\u5e93\u8fdb\u5165 UTF-8 \u6a21\u5f0f\uff1a\u4e0d\u518d\u8c03\u7528 A \u7cfb\u51fd\u6570\u64cd\u4f5c\u6587\u4ef6\uff0c\u800c\u662f\u4f1a\u628a\u6587\u4ef6\u540d\u4ece UTF-8 \u8f6c\u6362\u6210 UTF-16 \u540e\u518d\u8c03\u7528\u771f\u6b63\u7a33\u5b9a\u7684 W \u7cfb\u51fd\u6570\u3002 setlocale(LC_ALL, \".utf-8\"); // \u53ea\u9700\u8981\u8fd9\u4e00\u884c FILE *fp = fopen(u8\"\u4f60\u597d.txt\", \"r\"); // \u53ef\u4ee5\u4e86 std::ifstream fin(u8\"\u4f60\u597d.txt\"); // \u53ef\u4ee5\u4e86 setlocale(LC_ALL, \".utf-8\"); \u53ea\u662f\u628a C \u6807\u51c6\u5e93\u7684 const char * \u53c2\u6570\u53d8\u6210\u4e86\u63a5\u53d7 UTF-8\uff0c\u5e76\u4e0d\u4f1a\u8ba9\u7cfb\u7edf\u7684 A \u51fd\u6570\u4e5f\u53d8\u6210 UTF-8 \u54e6\uff0c\u8c03\u7528\u672c\u5730 API \u65f6\u4ecd\u9700 UTF-8 \u5230 UTF-16 \u7684\u8f6c\u6362\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-8 \u9635\u8425\uff0c\u5f00\u542f /utf-8 \uff0c\u7a0b\u5e8f\u5f00\u5934\u5199 setlocale(LC_ALL, \".utf-8\") \u3002Linux \u7528\u6237\u5219\u4ec0\u4e48\u90fd\u4e0d\u7528\u505a\u3002 \u770b\u770b\u5404\u5927\u8f6f\u4ef6\u7ad9\u5728 UTF-8 \u9635\u8425\u7684\u7406\u7531\uff1a CMake\uff1a\u4f5c\u4e3a\u8de8\u5e73\u53f0\u7684\u6784\u5efa\u7cfb\u7edf\uff0c\u4e3a\u4e86\u8ba9\u9879\u76ee\u7684 CMakeLists.txt \u80fd\u8de8\u5e73\u53f0\u5171\u7528\u800c\u4e0d\u5fc5\u91cd\u5199\uff0c\u4ed6\u7406\u6240\u5f53\u7136\u5730\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\uff1a\u6240\u6709 CMakeLists.txt \u90fd\u5fc5\u987b\u4ee5 UTF-8 \u683c\u5f0f\u4e66\u5199\uff0c\u4e14\u7edf\u4e00\u4f7f\u7528\u6b63\u659c\u6760 '/' \u8def\u5f84\u5206\u9694\u7b26\u3002 CMake \u4f1a\u81ea\u52a8\u5728 Windows \u7cfb\u7edf\u4e0a\uff0c\u5c06 UTF-8 \u5b57\u7b26\u4e32\u8f6c\u6362\u6210 UTF-16 \u540e\uff0c\u8c03\u7528 Windows \u7cfb\u7edf API\uff0c\u5728 Linux \u7cfb\u7edf\u4e0a\u5219\u4e0d\u505a\u8f6c\u6362\u3002\u5728 Windows \u7cfb\u7edf\u4e0a\u8fd8\u4f1a\u81ea\u52a8\u628a\u6587\u4ef6\u8def\u5f84\u4e2d\u7684\u6b63\u659c\u6760 '/' \u8f6c\u6362\u6210 Windows \u4e13\u5c5e\u7684\u53cd\u659c\u6760 '\\\\' \uff0c\u65e0\u9700\u7528\u6237\u64cd\u5fc3\u3002 \u5c0f\u5f6d\u8001\u5e08\u81ea\u4e3b\u7814\u53d1\u7684 Zeno \u8282\u70b9\u4eff\u771f\u8f6f\u4ef6\uff1a\u7531\u4e8e\u4fdd\u5b58\u7684\u9879\u76ee\u5de5\u7a0b\u6587\u4ef6\u9700\u8981\u5728 Linux \u548c Windows \u5e73\u53f0\u4e0a\u4e92\u901a\uff0c\u4e0d\u80fd\u91c7\u7528 Windows \u5404\u81ea\u4e3a\u653f\u7684 GBK \u683c\u5f0f\uff0c\u4e14\u5de5\u7a0b\u6587\u4ef6\u5185\u5bb9\u662f\u4ee5 ASCII \u4e3a\u4e3b\u7684\u201c\u4ee3\u7801\u201d\u7c7b\u6587\u672c\uff0c\u6240\u4ee5\u6211\u4eec\u4e5f\u7ad9\u5728\u4e86 UTF-8 \u9635\u8425\u4e2d\u3002 Rust \u548c Go\uff1a\u4e25\u683c\u533a\u5206\u201c\u5b57\u7b26 (32 \u4f4d)\u201d\u548c\u201c\u5b57\u8282 (8 \u4f4d)\u201d\u7684\u6982\u5ff5\u3002\u5728\u5b57\u7b26\u4e32\u7c7b\u578b\u4e2d\u5b58\u50a8\u5b57\u8282\uff0c\u4f46\u53ef\u4ee5\u9009\u62e9\u4ee5\u5b57\u8282\u65b9\u5f0f\u8bfb\u53d6\u6216\u4ee5\u5b57\u7b26\u65b9\u5f0f\u8bfb\u53d6\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-8 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-8 \u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5904\u7406\u5207\u7247\u548c\u7d22\u5f15\u65f6\u4e0d\u65b9\u4fbf\u3002 \u7f16\u7a0b\u8bed\u8a00 \u5b57\u7b26\u7c7b\u578b (32 \u4f4d) \u5b57\u8282\u7c7b\u578b (8 \u4f4d) Rust char u8 Go rune byte Julia Char UInt8 \u4e3a\u6b64\uff0c\u8fd9\u4e9b\u8bed\u8a00\u90fd\u4e3a\u5b57\u7b26\u4e32\u63d0\u4f9b\u4e86\u4e24\u5957 API\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u4e00\u79cd\u662f\u6309\u5b57\u8282\u7d22\u5f15\u3002\u6309\u5b57\u7b26\u7d22\u5f15\u65f6\uff0c\u4f1a\u4ece\u5934\u5f00\u59cb\uff0c\u9010\u4e2a\u89e3\u6790\u7801\u4f4d\uff0c\u76f4\u5230\u89e3\u6790\u5230\u60f3\u8981\u7684\u5b57\u7b26\u4e3a\u6b62\uff0c\u590d\u6742\u5ea6 O(N) O(N) \u3002\u6309\u5b57\u8282\u7d22\u5f15\u65f6\uff0c\u76f4\u63a5\u8df3\u5230\u6307\u5b9a\u5b57\u8282\uff0c\u65e0\u9700\u89e3\u6790\uff0c\u590d\u6742\u5ea6 O(1) O(1) \u3002 let s = \"\u4f60\u597d\"; // \u6309\u5b57\u7b26\u904d\u5386 for c in s.chars() { // c: char println!(\"{}\", c); } // \u6309\u5b57\u8282\u904d\u5386 for b in s.bytes() { // b: u8 println!(\"{:02x}\", b); } \u5728 C++ \u4e2d\uff0c\u82e5\u8981\u91c7\u7528\u8fd9\u79cd UTF-8 \u65b9\u6848\uff0c\u53ef\u4ee5\u4f7f\u7528 utfcpp \u8fd9\u4e2a\u5e93\uff1a https://github.com/nemtrif/utfcpp \u7a0d\u540e\u6211\u4eec\u4f1a\u4ee5\u6848\u4f8b\u8be6\u7ec6\u6f14\u793a\u8fd9\u4e2a\u5e93\u7684\u7528\u6cd5\uff0c\u4e5f\u4f1a\u5c1d\u8bd5\u81ea\u5df1\u624b\u6413\u3002 \u65b9\u6cd51\uff1a\u4f7f\u7528 utf8to32 \u4e00\u6b21\u6027\u5b8c\u6210\u8f6c\u6362\uff0c\u7528\u5b8c\u540e\u518d\u8f6c\u56de\u53bb\u3002 std::string s = \"\u4f60\u597d\"; std::u32string u32 = utf8::utf8to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\u574f'; s = utf8::utf32to8(u32); fmt::println(\"{}\", s); // \u4f60\u574f \u65b9\u6cd52\uff1a utfcpp \u4e5f\u5c01\u88c5\u4e86\u4e00\u4e2a utf8::iterator \u8fed\u4ee3\u5668\u9002\u914d\u5668\uff0c\u6548\u679c\u7c7b\u4f3c\u4e8e Rust \u7684 .chars() \uff0c\u53ef\u4ee5\u5b57\u7b26\u800c\u4e0d\u662f\u5b57\u8282\u904d\u5386\u5b57\u7b26\u4e32\u5bb9\u5668\u3002 char s[] = \"\u4f60\u597d\"; utf8::unchecked::iterator bit(s); utf8::unchecked::iterator eit(s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u5b89\u5168\uff08\u5e26\u8fb9\u754c\u68c0\u6d4b\uff09\u7684\u7248\u672c char s[] = \"\u4f60\u597d\"; utf8::iterator bit(s, s, s + strlen(s)); utf8::iterator eit(s + strlen(s), s, s + strlen(s)); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } // \u57fa\u4e8e std::string \u7684\u7248\u672c std::string s = \"\u4f60\u597d\"; utf8::iterator bit(s.begin(), s.begin(), s.end()); utf8::iterator eit(s.end(), s.begin(), s.end()); for (auto it = bit; it != eit; ++it) { // *it: char32_t fmt::println(\"U+{:04X}\", *it); } \u7531\u4e8e\u8fed\u4ee3\u5668\u63a5\u53e3\u590d\u6742\u96be\u61c2\uff0c\u5efa\u8bae\u5148\u5c01\u88c5\u6210\u5e26\u6709 begin() \u548c end() \u7684 range \u5bf9\u8c61\uff0c\u65b9\u4fbf\u4f7f\u7528 C++17 range-based loop \u8bed\u6cd5\u76f4\u89c2\u904d\u5386\uff1a template struct Utf8Range { utf8::iterator bit; utf8::iterator eit; template Utf8Range(T &&t) : bit(std::begin(t), std::begin(t), std::end(t)) , eit(std::end(t), std::begin(t), std::end(t)) {} auto begin() const { return bit; } auto end() const { return eit; } }; template Utf8Range(T &&t) -> Utf8Range; // \u4ee5\u4e0b\u662f\u65b0\u7c7b\u7684\u4f7f\u7528\u65b9\u6cd5 std::string s = \"\u4f60\u597d\"; for (char32_t c : Utf8Range(s)) { fmt::println(\"U+{:04X}\", c); }","title":"UTF-8 \u9635\u8425"},{"location":"unicode/#utf-16_2","text":"\u652f\u6301 Unicode \u8fc7\u65e9\uff0c\u8bef\u4ee5\u4e3a 0xFFFF \u5c31\u662f Unicode \u7684\u4e0a\u9650\u3002 \u4e00\u5f00\u59cb\uff0c\u4eba\u4eec\u9519\u8bef\u5730\u628a UTF-16 \u5f53\u6210\u6c38\u8fdc\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u4e00\u52b3\u6c38\u9038\u89e3\u51b3\u4e71\u7801\u95ee\u9898\uff0c\u6240\u4ee5\u90a3\u6bb5\u65f6\u671f\u7684\u8f6f\u4ef6\u90fd\u5927\u4e3e\u4f7f\u7528 UTF-16 \u4f5c\u4e3a\u5185\u7801\u3002\u6ca1\u60f3\u5230\u540e\u6765 Unicode \u53c8\u5f15\u5165 0x10FFFF \u8303\u56f4\u7684\u7a00\u6709\u5b57\u7b26\uff0c\u800c\u73b0\u6709\u7684\u5df2\u7ecf\u91c7\u7528\u4e86 16 \u4f4d\u5185\u7801\u7684\u8f6f\u4ef6\u53c8\u5df2\u7ecf\u65e0\u6cd5\u6839\u9664\uff0c\u53ea\u597d\u4f7f\u7528\u201c\u4ee3\u7406\u5bf9\u201d\u673a\u5236\uff0c\u589e\u91cf\u66f4\u65b0\u4fee\u590d\u4e86\u73b0\u6709\u7684 16 \u4f4d\u5185\u7801\u8f6f\u4ef6\u3002UTF-16 \u65e2\u6ca1\u6709 UTF-8 \u517c\u5bb9 ASCII \u7684\u597d\u5904\uff0c\u53c8\u6ca1\u6709 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u597d\u5904\uff0c\u7559\u4e0b\u5386\u53f2\u503a\u3002 \u4e8b\u5b9e\u4e0a\uff0cUnicode \u5df2\u7ecf\u65e0\u6cd5\u7ee7\u7eed\u6269\u5bb9\u7a81\u7834 0x10FFFF\uff0c\u5c31\u662f\u56e0\u4e3a\u53cc uint16_t \u7f16\u7801\u7684\u4ee3\u7406\u5bf9\u6700\u591a\u53ea\u80fd\u5bb9\u7eb3\u989d\u5916 0x100000 \u4e2a\u5b57\u7b26\u7684\u7a7a\u95f4\u3002\u672c\u6765 UTF-8 \u4e00\u5f00\u59cb\u7684\u8349\u6848\u662f\u6253\u7b97\u6700\u591a\u652f\u6301 8 \u8282\u5217\u8f66\uff0c\u5b8c\u5168\u5bb9\u7eb3\u9ad8\u8fbe 0x7FFFFFFF \u8303\u56f4\u7684\u5b57\u7b26\u3002\u4e3a\u4e86\u8ba9 Windows \u8fd8\u80fd\u7ee7\u7eed\u7528\uff0cUnicode \u624d\u88ab\u8feb\u6b62\u6b65 0x10FFFF\uff0cUTF-8 \u4e5f\u7ec8\u7ed3\u4e8e 4 \u8282\u5217\u8f66\u3002 \u5e94\u7528\u573a\u666f\uff1a\u901a\u5e38\u8ba4\u4e3a\uff0cUTF-16 \u662f\u7eaf\u7cb9\u7684\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff0c\u65b0\u8f6f\u4ef6\u4e0d\u5e94\u8be5\u518d\u4f7f\u7528 UTF-16\u3002\u53ea\u6709\u5728\u548c\u8fd9\u4e9b\u7cdf\u7c95\u8f6f\u4ef6\u7684 API \u6253\u4ea4\u9053\u65f6\uff0c\u624d\u5fc5\u987b\u8f6c\u6362\u4e3a UTF-16\u3002\u4f46\u4e5f\u6709\u4eba\u6307\u51fa\uff1aUTF-16 \u662f\u7eaf\u4e2d\u6587\u538b\u7f29\u7387\u6700\u9ad8\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u6240\u4ee5 UTF-16 \u8fd8\u6bd4\u8f83\u9002\u5408\u7eaf\u4e2d\u6587\u6216\u4ee5\u4e2d\u6587\u5185\u5bb9\u4e3a\u4e3b\u7684\u6587\u672c\u6570\u636e\u538b\u7f29\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-16 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u8c03\u7528 Windows \u7cfb\u7edf API \u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u76f4\u63a5\u5c31\u80fd\u8c03\u7528\uff0c\u6700\u9002\u5408 Windows \u672c\u5730\u5f00\u53d1\uff0c\u975e\u8de8\u5e73\u53f0\u3002\u4e14\u5bf9\u7eaf\u4e2d\u6587\u5185\u5bb9\u53ef\u6bd4 UTF-8 \u989d\u5916\u8282\u7701 33% \u7a7a\u95f4\u3002 \u7f3a\u70b9\uff1a\u5bf9\u4e8e Windows \u4ee5\u5916\u7684\u7cfb\u7edf\u5c31\u9700\u8981\u8f6c\u6362\u56de UTF-8\uff0c\u6709\u5c11\u91cf\u6027\u80fd\u5f00\u9500\u3002\u4e14\u5982\u679c\u5b58\u50a8\u7684\u5185\u5bb9\u4e3b\u8981\u662f\u7eaf\u82f1\u6587\uff0c\u5982 XML \u4ee3\u7801\u7b49\uff0c\u5185\u5b58\u5360\u7528\u4f1a\u6bd4 UTF-8 \u7ffb\u500d\u3002\u800c\u4e14 UTF-16 \u4ecd\u7136\u662f\u53d8\u957f\u7f16\u7801\uff0c\u867d\u7136\u51fa\u73b0\u53d8\u957f\u7684\u6982\u7387\u8f83\u4f4e\uff0c\u4f46\u4e0d\u4e3a 0\uff0c\u4ecd\u9700\u8981\u5f00\u53d1\u8005\u505a\u7279\u6b8a\u5904\u7406\u3002\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u4f1a\u5bfc\u81f4\u751f\u50fb\u5b57\u7b26\u51fa\u9519\uff0c\u5b57\u7b26\u4e32\u4ee5\u7801\u70b9\u4e3a\u5355\u4f4d\u7684\u7684\u6b63\u786e\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u7684\u590d\u6742\u5ea6\u4ecd\u7136 O(N) O(N) \u800c\u4e0d\u662f\u901a\u5e38\u7684 O(1) O(1) \u3002\u5e76\u4e14 UTF-16 \u6709\u5927\u5c0f\u7aef\u8f6c\u6362\u7684\u95ee\u9898\u3002 \u4ee3\u8868\u4f5c\uff1aWindows \u7cfb\u7edf API\u3001Java \u8bed\u8a00\u3001Windows \u6587\u4ef6\u7cfb\u7edf (NTFS)\u3001Qt\u3001Word\u3001JSON\uff0c\u4ed6\u4eec\u90fd\u662f UTF-16 \u7684\u53d7\u5bb3\u8005\u3002 \u8fd9\u76f8\u5f53\u4e8e\u662f\u628a UTF-16 \u5f53\u4f5c\u4e86\u5185\u7801\uff0c\u4f46 UTF-16 \u4f9d\u7136\u662f\u4e00\u79cd\u53d8\u957f\u7f16\u7801\uff0c\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5904\u7406\u6ca1\u95ee\u9898\uff0c\u751f\u50fb\u5b57\u5c31\u5bb9\u6613\u51fa\u95ee\u9898\uff0c\u4e14\u56e0\u4e3a\u51fa\u73b0\u6982\u7387\u4f4e\uff0c\u5f88\u5bb9\u6613\u4e0d\u53d1\u73b0\uff0c\u57cb\u4e0b\u9690\u60a3\u3002 Java \u5c31\u662f\u53d7\u5230\u4e86 UTF-16 \u5386\u53f2\u503a\u5f71\u54cd\uff0c char \u662f 16 \u4f4d\u7684\u7801\u4f4d\uff0c\u800c\u4e0d\u662f\u5b57\u7b26\uff0c\u771f\u6b63\u7684\u4e00\u4e2a\u5b57\u7b26\u662f 32 \u4f4d\u7684 Character \u7c7b\u578b\u3002 \u7f16\u7a0b\u8bed\u8a00 \u7801\u70b9\u7c7b\u578b (32 \u4f4d) \u7801\u4f4d\u7c7b\u578b (16 \u4f4d) Java Character char Java \u7684 Character \u7c7b\u578b\u662f\u4e00\u4e2a 32 \u4f4d\u7684\u503c\uff0c\u8fd9\u4e2a\u503c\u5305\u542b\u4e86\u4e00\u4e2a Unicode \u7801\u4f4d\u3002 char \u7c7b\u578b\u662f\u4e00\u4e2a 16 \u4f4d\u7684\u503c\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u4e2a UTF-16 \u7f16\u7801\u7684\u7801\u70b9\u3002 String \u7684 charAt() \u65b9\u6cd5\u8fd4\u56de\u7684\u662f char \u7c7b\u578b\u7684\u7801\u4f4d\uff08\u7c7b\u4f3c\u4e8e\u5b57\u8282\uff09\uff0c\u5982\u679c\u8981\u83b7\u53d6 Character \u7c7b\u578b\u7684\u5b8c\u6574\u5b57\u7b26\uff0c\u5fc5\u987b\u4f7f\u7528 codePointAt() \u65b9\u6cd5\u3002\u8fd9\u662f Java \u8bed\u8a00\u8bbe\u8ba1\u4e0a\u7684\u4e00\u4e2a\u5931\u8bef\uff0c\u5df2\u7ecf\u65e0\u6cd5\u6539\u53d8\u3002 \u800c\u540e\u7eed\u65b0\u51fa\u7684 Kotlin \u662f Java \u7684\u5408\u6cd5\u7ee7\u627f\u8005\uff0c\u4ed6\u679c\u65ad\u653e\u5f03 UTF-16\uff0c\u52a0\u5165\u4e86 UTF-32 \u9635\u8425\u3002\u53ef\u89c1\uff0c\u8001\u8f6f\u4ef6\u575a\u6301\u7528 UTF-16 \u662f\u56e0\u4e3a\u4ed6\u4eec\u79ef\u91cd\u96be\u8fd4\uff0c\u65b0\u8f6f\u4ef6\u518d\u7528 UTF-16 \u5c31\u662f\u81ea\u4f5c\u5b7d\u4e86\uff01 \u603b\u7ed3\uff1a\u4e0d\u8981\u652f\u6301 UTF-16 \u9635\u8425\uff0c\u9664\u975e\u4f60\u88ab\u8feb\u7ef4\u62a4\u53f2\u5c71\u3002 \u4f8b\u5982\u5c0f\u5f6d\u8001\u5e08\u53d1\u5fae\u4fe1\u670b\u53cb\u5708\u65f6\uff0c\u8f93\u5165 Emoji \u8868\u60c5\u540e\u526a\u5207\uff0c\u518d\u7c98\u8d34\uff0c\u5c31\u548c\u53d1\u73b0\u4e00\u4e2a Emoji \u88ab\u5207\u65ad\u6210\u4e86\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4e71\u7801\u7684\u5f62\u5f0f\u663e\u73b0\u3002\u4f30\u8ba1\u662f\u56e0\u4e3a\u5fae\u4fe1\u57fa\u4e8e Java \u7f16\u5199\uff0c\u75bc\u900a\u7a0b\u5e8f\u5458\u5bf9 UTF-16 \u4ee3\u7406\u5bf9\u5904\u7406\u7684\u4e0d\u5229\u7d22\u3002 Java \u4e2d\u4ee5\u7801\u70b9\u904d\u5386\u4e00\u4e2a\u5b57\u7b26\u4e32\u7684\u5199\u6cd5\uff1a String s = \"\u4f60\u597d\"; // \u6309\u7801\u70b9\u904d\u5386 for (int i = 0; i < s.length();) { Character c = s.codePointAt(i); System.out.println(String.format(\"U+%04X\", c)); i += Character.charCount(c); } // \u6309\u7801\u4f4d\u904d\u5386 for (char c : s.toCharArray()) { System.out.println(String.format(\"U+%04X\", (int) c)); } \u7531\u4e8e JSON \u662f\u548c Java \u4e00\u5757\u53d1\u660e\u7684\u3002\u5bf9\u4e8e\u8d85\u51fa 0xFFFF \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u91c7\u7528\u7684\u8f6c\u4e49\uff0c\u4e5f\u662f\u57fa\u4e8e UTF-16 \u7f16\u7801\u3002\u5373\u540c\u4e00\u4e2a\u5b57\u4f1a\u53d8\u6210\u4e24\u4e2a\u4ee3\u7406\u5bf9\uff0c\u4ee5\u4fdd\u8bc1 JSON \u6587\u4ef6\u603b\u662f ASCII \u683c\u5f0f\uff0c\u907f\u514d Windows \u7684 GBK \u7f16\u7801\u4e71\u505a\u989d\u5916\u7684\u5e72\u6270\u3002 // \u4ee5\u4e0b\u4e24\u79cd\u5199\u6cd5\u7b49\u4ef7 {\"name\": \"\ud883\udede\"} {\"name\": \"\\ud883\\udfde\"} \u5728\u521a\u521a\u4ecb\u7ecd\u7684 C++ \u5e93 utfcpp \u4e2d\uff0c\u4e5f\u6709\u9488\u5bf9 UTF-16 \u7684\u8f6c\u6362\u51fd\u6570\uff0c\u5982 utf16to32 \uff1a std::u16string s = u\"\u4f60\u597d\"; std::u32string u32 = utf16::utf16to32(s); fmt::println(\"U+{:04X}\", u32[0]); fmt::println(\"U+{:04X}\", u32[1]); u32[1] = U'\ud883\udede'; s = utf16::utf32to16(u32); fmt::println(\"{}\", s); // \u4f60\ud883\udede fmt::println(\"{}\", u32.size()); // 2 fmt::println(\"{}\", s.size()); // 3","title":"UTF-16 \u9635\u8425"},{"location":"unicode/#utf-32_1","text":"\u652f\u6301 Unicode\uff0c\u6bcf\u4e2a\u7801\u70b9\u90fd\u7528\u4e00\u4e2a uint32_t \u6216 char32_t \u8868\u793a\u3002 \u5e94\u7528\u573a\u666f\uff1a\u9002\u5408\u9700\u8981\u7ecf\u5e38\u5904\u7406\u6587\u5b57\u7684\u9886\u57df\uff0c\u5982\u6587\u672c\u7f16\u8f91\u5668\u3001\u6d4f\u89c8\u5668\u7b49\u3002\u4f46\u4e0d\u9002\u5408\u5b58\u50a8\u548c\u4f20\u8f93\uff0c\u56e0\u4e3a\u6d6a\u8d39\u786c\u76d8\u548c\u7f51\u7edc\u5e26\u5bbd\u3002\u5b57\u7b26\u4e32\u4e00\u822c\u90fd\u957f\u671f\u4ee5 UTF-8 \u5b58\u50a8\uff0c\u53ea\u6709\u5728\u9700\u8981\u9891\u7e41\u7d22\u5f15\u7801\u4f4d\u65f6\uff0c\u624d\u9700\u8981\u8f6c\u6362\u4e3a UTF-32\u3002 \u65b9\u6cd5\uff1a\u59cb\u7ec8\u4ee5 UTF-32 \u7f16\u7801\u5b58\u50a8\u548c\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u4f18\u70b9\uff1a\u5b57\u7b26\u4e32\u7684\u6309\u7801\u4f4d\u53cd\u8f6c\u3001\u5207\u7247\u3001\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\u90fd\u662f O(1) O(1) \u7684\u590d\u6742\u5ea6\uff0c\u53ef\u4ee5\u5f53\u4f5c\u666e\u901a\u6570\u7ec4\u4e00\u6837\uff0c\u968f\u610f\u5904\u7406\u3002\u4f8b\u5982\u4f60\u53ef\u4ee5\u8bbe\u60f3\u4e00\u4e2a\u6587\u672c\u7f16\u8f91\u6846\uff0c\u9700\u8981\u652f\u6301\u201c\u9000\u683c\u201d\u64cd\u4f5c\uff0c\u5982\u679c\u662f UTF-8 \u548c UTF-16 \u5c31\u9700\u8981\u7e41\u7410\u7684\u5224\u65ad\u4ee3\u7406\u5bf9\u3001\u5404\u79cd\u8f66\u53a2\uff0c\u800c UTF-32 \u7684\u5b57\u7b26\u4e32\u53ea\u9700\u8981\u4e00\u6b21 pop_back \u5c31\u641e\u5b9a\u4e86\u3002 \u7f3a\u70b9\uff1a\u6d6a\u8d39\u7a7a\u95f4\u5927\uff0c\u901a\u5e38\u5728\u4fdd\u5b58\u65f6\uff0c\u4ecd\u7136\u9700\u8981\u8f6c\u6362\u56de UTF-8 \u540e\u518d\u5199\u5165\u6587\u4ef6\uff0c\u6709\u4e00\u5b9a\u6027\u80fd\u5f00\u9500\u3002 \u603b\u7ed3\uff1a\u8981\u652f\u6301 UTF-32 \u9635\u8425\uff0c\u8bf7\u5168\u90e8\u4f7f\u7528 char32_t \u548c std::u32string \u3002\u5b57\u9762\u91cf\u5168\u7528 U\"\u4f60\u597d\" \u7684\u5f62\u5f0f\u4e66\u5199\uff0c\u8bfb\u6587\u4ef6\u65f6\u8f6c\u4e3a UTF-32\uff0c\u5199\u6587\u4ef6\u65f6\u8f6c\u56de UTF-8\u3002","title":"UTF-32 \u9635\u8425"},{"location":"unicode/#_13","text":"\u7531\u4e8e C++26 \u524d\u6807\u51c6\u5e93\u5bf9\u7f16\u7801\u8f6c\u6362\u51e0\u4e4e\u6ca1\u6709\u652f\u6301\uff0c\u5728 C++ \u4e2d\u8f6c\u6362\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u5e38\u90fd\u9700\u8981\u7b2c\u4e09\u65b9\u5e93\u3002","title":"\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362"},{"location":"unicode/#utf-utfcpp","text":"\u5982\u679c\u4f60\u53ea\u662f\u9700\u8981\u4e0d\u540c UTF \u683c\u5f0f\u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u6ca1\u6709\u5904\u7406 GBK \u7b49\u7684\u9700\u6c42\uff1a\u90a3\u4e48\u4e4b\u524d\u5df2\u7ecf\u4ecb\u7ecd\u4e86 utfcpp \u8fd9\u4e2a\u65b9\u4fbf\u7684\u5e93\uff0c\u5df2\u7ecf\u591f\u7528\u3002 #include \"utf8/cpp20.h\" std::u8string s8 = u8\"\u4f60\u597d\"; std::u16string s16 = utf8::utf8to16(s8); std::u32string s32 = utf8::utf8to32(s8); std::string s = utf8::utf16to8(s16); s8 = utf8::utf16tou8(s16); \u6700\u540e\u8fd9\u4e24\u4e2a\u533a\u522b\u5728\u4e8e\uff0c utf16to8 \u8fd4\u56de std::string \uff0c utf16tou8 \u8fd4\u56de std::u8string \uff0c\u91cc\u9762\u90fd\u662f UTF-8 \u7f16\u7801\u7684\uff0c\u4e0d\u8fc7\u6709\u7684\u4eba\u559c\u6b22\u7528 std::string \u6765\u5b58\u50a8 UTF-8\uff0c\u4e0d\u559c\u6b22 std::u8string \uff0c\u6216\u8005\u8bf4\u4ed6\u4eec\u6ca1\u6709 C++20\uff0c\u4e0d\u652f\u6301 std::u8string \uff0c\u56e0\u6b64\u8fd9\u4e2a\u5e93\u6ee1\u8db3\u4ed6\u4eec\u7684\u4e0d\u540c\u9700\u8981\u3002\u4f46\u662f std::u8string \u4f5c\u4e3a\u53c2\u6570\u65f6\u4e0d\u9700\u8981\uff0c\u56e0\u4e3a\u53c2\u6570\u53ef\u4ee5\u81ea\u52a8\u91cd\u8f7d\uff0c\u800c\u8fd4\u56de\u503c\u4e0d\u884c\u3002 \u7f3a\u70b9\u662f\u4ed6\u4e0d\u80fd\u5904\u7406 GBK\u3001Shift-JIS \u7b49\u975e Unicode \u7f16\u7801\uff0c\u4e5f\u4e0d\u80fd\u81ea\u52a8\u68c0\u6d4b\u5f53\u524d\u7684 ANSI \u533a\u57df\u8bbe\u7f6e\u3002","title":"\u4e0d\u540c UTF \u4e4b\u95f4\u4e92\u8f6c\uff1autfcpp"},{"location":"unicode/#boostlocale","text":"\u5982\u679c\u4f60\u8fd8\u8981\u652f\u6301\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u6bd4\u5982 GBK\u3001Shift-JIS\u3001Latin-1\u3002 \u4e00\u79cd\u662f C \u8bed\u8a00\u7684 iconv \uff0c\u53e6\u4e00\u79cd\u662f\u73b0\u4ee3 C++ \u7684 boost::locale \u3002 \u867d\u7136\u529f\u80fd\u5dee\u4e0d\u591a\uff0c\u5e95\u5c42\u90fd\u662f\u8c03\u7528 icu \u7684\u3002 boost::locale \u7684 API \u66f4\u52a0\u53cb\u597d\uff0c\u800c\u4e14\u662f\u73b0\u4ee3 C++ \u98ce\u683c\u7684\u3002 # Ubuntu \u7528\u6237\u5b89\u88c5 Boost.locale \u65b9\u6cd5\uff1a $ sudo apt-get install libboost-locale-dev # Arch Linux \u7528\u6237\u5b89\u88c5 Boost \u5168\u5bb6\u6876\u65b9\u6cd5\uff1a $ sudo pacman -S boost \u4e0d\u559c\u6b22 Boost \u7684\u4eba\u6709\u96be\u4e86\u3002","title":"\u8de8\u5e73\u53f0\u7684\u4efb\u610f\u7f16\u7801\u8f6c\u6362\uff1aboost::locale"},{"location":"unicode/#utf","text":"\u4f7f\u7528 boost::locale::conv::utf_to_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::utf_to_utf; int main() { std::string s8 = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c UTF-32\uff1a std::u32string s32 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-16\uff1a std::u16string s16 = utf_to_utf(s8); // UTF-32 \u8f6c UTF-8\uff1a s8 = utf_to_utf(s32); std::cout << s8 << '\\n'; return 0; } \u6a21\u677f\u53c2\u6570\u4e2d\uff0c\u53ea\u9700\u6307\u5b9a\u8f6c\u6362\u5230\u7684\u662f\u4ec0\u4e48\u7c7b\u578b\u5c31\u884c\uff0c\u6765\u81ea\u4ec0\u4e48\u7c7b\u578b\uff0c\u4ed6\u81ea\u5df1\u4f1a\u91cd\u8f7d\u7684\u3002 \u6bd4\u5982\u4ece char32_t \u8f6c\u5230 char16_t \uff0c\u53ea\u9700\u8981 utf_to_utf \u5c31\u53ef\u4ee5\uff0c\u975e\u5e38\u65b9\u4fbf\u3002 \u7f16\u8bd1\uff1a $ g++ -std=c++17 -lboost_locale main.cpp \u8f93\u51fa\uff1a \u4f60\u597d \u5efa\u8bae\u7528\u540c\u6837\u8de8\u5e73\u53f0\u7684 CMake \u94fe\u63a5 Boost\uff0c\u5426\u5219 Windows \u7528\u6237\u8981\u6709\u96be\u4e86\u2026\u2026 find_package(Boost REQUIRED COMPONENTS locale) target_link_libraries(\u4f60\u7684\u7a0b\u5e8f Boost::locale) \u4e0d\u8fc7 boost::locale \u6709\u4e00\u4e2a\u7f3a\u70b9\uff0c\u90a3\u5c31\u662f\u4e0d\u652f\u6301 char8_t \u548c std::u8string \u3002 char8_t \u662f C++20 \u5f15\u5165\u7684\u65b0\u5b57\u7b26\u7c7b\u578b\uff0c\u7528\u4e8e\u5f3a\u7c7b\u578b\u7684\u541b\u5b50\u534f\u8bae\uff0c\u548c char \u5e76\u6ca1\u6709\u5b9e\u9645\u533a\u522b\u3002\u53ea\u662f\u65b9\u4fbf\u4e86\u51fd\u6570\u7c7b\u578b\u7b7e\u540d\u66f4\u52a0\u4e00\u76ee\u4e86\u7136\uff0c\u8fd9\u4e2a\u53c2\u6570\u53ea\u80fd\u63a5\u53d7 UTF-8 \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff01 \u7531\u4e8e Boost \u8f83\u8001\uff0c\u6ca1\u6709\u53ca\u65f6\u8ddf\u8fdb\uff0c\u6240\u4ee5\u4ed6\u5e76\u6ca1\u6709\u5b9e\u73b0\u9488\u5bf9 char8_t \u7684\u7279\u5316\uff0c\u5982\u679c\u4f7f\u7528\u4e86 utf_to_utf \u4f1a\u62a5 undefined reference \u9519\u8bef\uff0c\u5373\u627e\u4e0d\u5230\u7b26\u53f7\u3002\u6539\u6210 utf_to_utf \u5c31\u6ca1\u95ee\u9898\u4e86\u3002","title":"UTF \u4e4b\u95f4\u4e92\u8f6c"},{"location":"unicode/#gbk-utf","text":"\u4f7f\u7528 boost::locale::conv::to/from_utf \u5c31\u80fd\u8f7b\u6613\u505a\u5230\u3002 #include #include using boost::locale::conv::to_utf; using boost::locale::conv::from_utf; int main() { std::string s = \"\u4f60\u597d\"; // \u4ece GBK \u8f6c\u5230 UTF-16 std::wstring ws = to_utf(s, \"GBK\"); std::wcout << ws << '\\n'; // \u4ece UTF-16 \u8f6c\u56de GBK s = from_utf(ws, \"GBK\"); std::wcout << s << '\\n'; return 0; } \u7b2c\u4e8c\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f GBK \u3001 Shift-JIS \u3001 Latin1 \u7b49\u5176\u4ed6\u7f16\u7801\u683c\u5f0f\uff0c\u5b8c\u6574\u7684\u5217\u8868\u53ef\u4ee5\u5728\u770b\u5230\u3002 \u8fd9\u91cc to_utf \u4f1a\u81ea\u52a8\u5224\u65ad wchar_t \u7684\u5927\u5c0f\u3002\u5982\u679c\u662f 2 \u5b57\u8282\uff08Windows \u5e73\u53f0\u60c5\u51b5\uff09\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-16\uff0c\u5982\u679c\u662f 4 \u5b57\u8282\uff08Linux \u5e73\u53f0\u60c5\u51b5\uff09\uff0c\u4f1a\u8ba4\u4e3a\u4f60\u8981\u8f6c\u4e3a UTF-32\u3002 \u800c to_char \u5219\u662f\u65e0\u8bba\u4ec0\u4e48\u5e73\u53f0\uff0c\u90fd\u4f1a\u8f6c\u4e3a UTF-16\u3002 from_utf \u4e0d\u9700\u8981\u6307\u5b9a\u4efb\u4f55\u6a21\u677f\u53c2\u6570\uff0c\u56e0\u4e3a\u4ed6\u603b\u662f\u8fd4\u56de std::string \uff08ANSI \u6216 GBK \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff09\uff0c\u53c2\u6570\u662f\u4ec0\u4e48\u7f16\u7801\uff0c\u4f1a\u81ea\u52a8\u901a\u8fc7\u91cd\u8f7d\u5224\u65ad\uff0c\u4f8b\u5982 from_utf(ws, \"GBK\") \u8fd9\u91cc\u7684\u53c2\u6570\u662f wchar_t \uff0c\u90a3\u4e48\u5728 Windows \u4e0a\uff0c\u4ed6\u4f1a\u68c0\u6d4b\u5230 wchar_t \u662f 2 \u5b57\u8282\uff0c\u5c31\u8ba4\u4e3a\u662f UTF-16 \u5230 GBK \u7684\u8f6c\u6362\u3002","title":"GBK \u548c UTF \u4e92\u8f6c"},{"location":"unicode/#utf-ansi","text":"\u6211\u4eec\u7a0b\u5e8f\u7684\u7528\u6237\u4e0d\u4e00\u5b9a\u662f\u4e2d\u56fd\u7528\u6237\uff08GBK\uff09\uff0c\u4e5f\u53ef\u80fd\u662f\u4fc4\u7f57\u65af\u7528\u6237\uff08CP1251\uff09\u3001\u65e5\u672c\u7528\u6237\uff08Shift-JIS\uff09\u3001\u897f\u73ed\u7259\u7528\u6237\uff08CP1252\uff09\u7b49\u3002 \u5982\u679c\u8981\u91c7\u7528\u7528\u6237\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u5373\u201cANSI\u201d\uff0c\u53ef\u4ee5\u628a\u5b57\u7b26\u4e32\u7559\u7a7a\uff08 \"\" \uff09\u3002 \u7a7a\u5b57\u7b26\u4e32\u5c31\u8868\u793a\u91c7\u7528\u5f53\u524d\u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e86\uff0c\u5728\u4e2d\u56fd\u5927\u533a\u7b49\u4ef7\u4e8e \"GBK\" \uff0c\u4fc4\u7f57\u65af\u5927\u533a\u7b49\u4ef7\u4e8e \"CP1251\" \u7b49\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::to_utf; int main() { setlocale(LC_ALL, \"\"); // \u5982\u679c\u4f60\u60f3\u7ed9 Boost \u7528\u7a7a\u5b57\u7b26\u4e32\uff0c\u9996\u5148\u9700\u8981\u8bbe\u7f6e\u4e00\u4e0b\u8fd9\u4e00\u884c std::string u8s = u8\"\u4f60\u597d\"; // UTF-8 \u8f6c ANSI std::string s = from_utf(u8s, \"\"); // ANSI \u8f6c UTF-8 u8s = to_utf(s, \"\"); return 0; } setlocale(LC_ALL, \"\"); \u4e2d\u7684\u7a7a\u5b57\u7b26\u4e32\u8868\u793a","title":"UTF \u548c ANSI \u4e92\u8f6c"},{"location":"unicode/#_14","text":"\u51fd\u6570\u540d\u79f0 \u4ece \u5230 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-8 utf_to_utf UTF-x UTF-16 utf_to_utf UTF-x UTF-32 utf_to_utf UTF-x Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 UTF-x \u8868\u793a\u53d6\u51b3\u4e8e\u53c2\u6570\u7c7b\u578b\u7684\u5927\u5c0f\uff0c\u5982\u679c\u53c2\u6570\u662f char16_t \u7684\u5b57\u7b26\u4e32 std::u16string \uff0c\u90a3 x \u5c31\u662f 16\u3002 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-8 to_utf(\"GBK\", string) GBK UTF-16 to_utf(\"GBK\", string) GBK UTF-32 to_utf(\"GBK\", string) GBK Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-8 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-16 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e UTF-32 to_utf(\"\", string) \u533a\u57df\u8bbe\u7f6e Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u51fd\u6570\u540d\u79f0 \u4ece \u5230 from_utf(\"GBK\", string) UTF-8 GBK from_utf(\"GBK\", u16string) UTF-16 GBK from_utf(\"GBK\", u32string) UTF-32 GBK from_utf(\"GBK\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 GBK from_utf(\"\", string) UTF-8 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u16string) UTF-16 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", u32string) UTF-32 \u533a\u57df\u8bbe\u7f6e from_utf(\"\", wstring) Linux \u4e0a UTF-32\uff1bWin \u4e0a UTF-16 \u533a\u57df\u8bbe\u7f6e","title":"\u5927\u603b\u7ed3"},{"location":"unicode/#gbk-shift-jis","text":"#include #include using boost::locale::conv::between; using boost::locale::conv::from_utf; int main() { // \u521b\u5efa\u4e00\u4e2a Shift-JIS \u5b57\u7b26\u4e32 std::string jis = from_utf(u8\"\u65e5\u672c\u8a9e\", \"Shift-JIS\"); // \u4ece Shift-JIS \u8f6c\u5230 GBK std::string gbk = between(jis, \"GBK\", \"Shift-JIS\"); std::cout << gbk << '\\n'; // \u4ece GBK \u8f6c\u56de Shift-JIS jis = between(gbk, \"Shift-JIS\", \"GBK\"); std::cout << jis << '\\n'; return 0; } \u6ce8\u610f\uff01\u662f\u76ee\u6807\u7f16\u7801\u5728\u524d\uff01\u5982\u679c\u4f60\u8981\u4ece Shift-JIS \u8f6c\u6210 GBK\uff0c\u90a3\u4e48\u9700\u8981 between(jis, \"GBK\", \"Shift-JIS\") \uff0c\u8fd9\u771f\u662f\u4e00\u4e2a\u7cdf\u7cd5\u7684\u8bbe\u8ba1\u3002\u4e0d\u4ec5 GBK \u548c Shift-JIS \u53ef\u80fd\u4e0d\u5c0f\u5fc3\u5f04\u53cd\u4e86\uff0c\u7f16\u8bd1\u5668\uff0c\u4e00\u70b9\u63d0\u793a\u90fd\u6ca1\u6709\uff0c\u800c\u4e14 jis \u548c \u201cGBK\u201d \u90fd\u662f\u5b57\u7b26\u4e32\uff0c\u5f88\u5bb9\u6613\u5927\u8111\u641e\u6df7\u3002\u8ba9\u6211\u6765\u8bbe\u8ba1\u7684\u8bdd\uff0c\u6211\u4f1a\u8fd9\u6837\u63d0\u4f9b API\uff1a decode(jis, Encoding::ShiftJIS).encode(Encoding::GBK) \uff0c\u5176\u4e2d Encoding \u662f\u4e00\u4e2a\u679a\u4e3e\uff0c\u5f3a\u5927\u7684\u7c7b\u578b\u7cfb\u7edf\uff0c\u4e0d\u4ec5\u907f\u514d\u72af\u9519\u7684\u673a\u4f1a\uff0c\u770b\u8d77\u6765\u4e5f\u66f4\u8f7b\u677e\u3002\u4e4b\u540e\u7684\u8bbe\u8ba1\u6a21\u5f0f\u4e13\u9898\u8bfe\u4e2d\uff0c\u4f1a\u518d\u8be6\u7ec6\u8bb2\u89e3\u4ec0\u4e48\u662f\u597d\u7684 API \u8bbe\u8ba1\u3002","title":"GBK \u548c Shift-JIS \u4e92\u8f6c"},{"location":"unicode/#_15","text":"\u5982\u679c\u9047\u5230\u65e0\u6cd5\u7f16\u7801\u7684\u5b57\u7b26\uff0c\u8be5\u5982\u4f55\u5904\u7f6e\uff1f \u9ed8\u8ba4\u60c5\u51b5\u4e0b Boost \u4f1a\u5ffd\u89c6\u9519\u8bef\uff0c\u7f16\u7801\u5931\u8d25\u7684\u5b57\u7b26\u4f1a\u88ab\u4e22\u5f03\u3002 #include #include using boost::locale::conv::from_utf; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\"); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 std::cout << gbk << '\\n'; // \u5728 Windows \u7684 GBK \u7ec8\u7aef\u4e0a\uff0c\u53ea\u663e\u793a\u201c\u6211\u7231\u9762\u201d return 0; } \u53ef\u4ee5\u7528 method_type \u8fd9\u4e2a\u679a\u4e3e\u6765\u6307\u5b9a\u9519\u8bef\u5904\u7406\u7684\u65b9\u5f0f\u3002 \u9ed8\u8ba4\u662f skip \uff0c\u8df3\u8fc7\u6240\u6709\u89e3\u7801\u51fa\u9519\u7684\u5730\u65b9\uff08\u5bfc\u81f4\u201c\ud883\udede\u201d\u4e22\u5931\uff09\u3002 \u6211\u4eec\u53ef\u4ee5\u5207\u6362\u5230 stop \uff0c\u5f53\u9047\u5230\u89e3\u7801\u9519\u8bef\u65f6\uff0c\u4f1a\u76f4\u63a5\u629b\u51fa\u5f02\u5e38\uff0c\u7ec8\u6b62\u7a0b\u5e8f\u6267\u884c\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; int main() { std::string utf8 = u8\"\u6211\u7231\ud883\udede\ud883\udede\u9762\"; // UTF-8 \u8f6c GBK std::string gbk = from_utf(utf8, \"GBK\", method_type::stop); // \u9519\u8bef\uff0c\u201c\ud883\udede\u201d\u65e0\u6cd5\u7528 GBK \u8868\u793a\uff01 // from_utf \u4f1a\u629b\u51fa `conversion_error` \u5f02\u5e38 std::cout << gbk << '\\n'; return 0; } \u4e3e\u4f8b\uff1a\u5c1d\u8bd5\u4ee5 GBK \u4fdd\u5b58\uff0c\u5982\u679c\u5931\u8d25\uff0c\u5219\u6539\u4e3a\u5e26\u6709 BOM \u7684 UTF-8\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::method_type; using boost::locale::conv::conversion_error; void try_save(std::u32string content, std::wstring path) { std::string binary; try { // \u5c1d\u8bd5\u5c06 UTF-32 \u8f6c\u6210 GBK \u7f16\u7801 binary = from_utf(content, \"GBK\", method_type::stop); } catch (conversion_error const &e) { // \u82e5 GBK \u65e0\u6cd5\u8868\u793a // \u6539\u7528\u524d\u9762\u5e26\u6709 BOM \u7684 UTF-8 \u7f16\u7801 binary = \"\\xEF\\xBB\\xBF\" + utf_to_utf(content); } std::ofstream(path) << binary; } \u4e3e\u4f8b\uff1a\u652f\u6301 UTF-8 \u5b57\u7b26\u4e32\uff08\u800c\u4e0d\u662f ANSI \u5b57\u7b26\u4e32\uff09\u7684\u6253\u5370\u51fd\u6570\u3002 #include #include using boost::locale::conv::from_utf; using boost::locale::conv::utf_to_utf; static int dummy_init = (setlocale(LC_ALL, \"\"), 0); // \u9700\u8981\u8bbe\u7f6e\u8fc7 setlocale(LC_ALL, \"\") \u540e\uff0c\u624d\u80fd\u4f7f\u7528 Boost \u7684\u7a7a\u5b57\u7b26\u4e32\u5199\u6cd5 void u8print(std::string msg) { std::cout << from_utf(msg, \"\"); // \u6216\u8005\uff1a // std::wcout << utf_to_utf(msg); } \u6b64\u5904 static int dummy_init = \u662f\u4e00\u79cd\u9759\u6001\u521d\u59cb\u5316\u94a9\u5b50\u7684\u5c0f\u6280\u5de7\uff0c\u4e4b\u540e\u8bbe\u8ba1\u6a21\u5f0f\u8bfe\u7a0b\u7684\u5355\u4f8b\u6a21\u5f0f\u4e2d\u4f1a\u8be6\u7ec6\u8bb2\u89e3\u3002","title":"\u6307\u5b9a\u5904\u7406\u9519\u8bef\u7684\u65b9\u6cd5"},{"location":"unicode/#_16","text":"\u51fd\u6570 \u4ece \u5230 utf_to_utf UTF \u7cfb\u5217 UTF \u7cfb\u5217 from_utf UTF \u7cfb\u5217 \u6742\u724c\u5b57\u7b26\u7f16\u7801 to_utf \u6742\u724c\u5b57\u7b26\u7f16\u7801 UTF \u7cfb\u5217 between \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u6742\u724c\u5b57\u7b26\u7f16\u7801 \u66f4\u591a\u7ec6\u8282\u7528\u6cd5\u89c1\u5b98\u65b9\u6587\u6863\uff1ahttps://www.boost.org/doc/libs/1_81_0/libs/locale/doc/html/group__codepage.html \u4e0d\u53ef\u601d\u8bae\u7684\u662f\uff1a\u7f16\u7801\u8f6c\u6362\u53ea\u662f boost::locale::conv \u8fd9\u4e2a\u5b50\u6a21\u5757\u4e0b\u7684\u4e00\u4e2a\u5c0f\u529f\u80fd\u800c\u5df2\uff01 boost::locale \u8fd8\u63d0\u4f9b\u4e86\u66f4\u591a\u529f\u80fd\uff0c\u5982\u6309\u7167\u5730\u57df\u8bed\u8a00\u89c4\u8303\u683c\u5f0f\u5316\u6570\u5b57\u3001\u8d27\u5e01\u3001\u65e5\u671f\u3001\u65f6\u95f4\u7b49\uff0c\u4e0b\u4e00\u5c0f\u8282\u4e2d\u6211\u4eec\u7ee7\u7eed\u4ecb\u7ecd\u3002\u5b8c\u5168\u662f std::locale \u7684\u4e0a\u4f4d\u66ff\u4ee3\u3002 Boost \u54ea\u91cc\u90fd\u597d\uff0c\u4f60\u60f3\u8981\u7684\u529f\u80fd\u5e94\u6709\u5c3d\u6709\u3002\u800c\u4e14\u4e0d\u9700\u8981 C++20\uff0c\u5f88\u4f4e\u7248\u672c\u7684 C++ \u4e5f\u80fd\u7528\u3002\u552f\u4e00\u7f3a\u70b9\u53ef\u80fd\u5c31\u662f\u592a\u80a5\u4e86\uff0c\u7f16\u8bd1\u6162\u3002","title":"\u66f4\u591a\u529f\u80fd\uff1f\uff01"},{"location":"unicode/#windows-multibytetowidechar","text":"\u5982\u679c\u4f60\u662f Windows \u7a0b\u5e8f\u5458\uff0c\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u4e14\u9700\u8981\u5728 Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u89c4\u5b9a\u7684 ANSI\uff08\u5728\u4e2d\u56fd\u533a\u662f GBK\uff09\u7f16\u7801\u548c UTF-16 \u4e4b\u95f4\u8f6c\u6362\uff1a \u53ef\u4ee5\u7528 Windows \u5b98\u65b9\u63d0\u4f9b\u7684 MultiByteToWideChar \u548c WideCharToMultiByte \u51fd\u6570\u3002 \u8fd9\u4e24\u4e2a\u51fd\u6570\u56e0\u4e3a C \u8bed\u8a00\u7279\u8272\u7684\u7f18\u6545\uff0c\u53c2\u6570\u6bd4\u8f83\u591a\u800c\u6742\uff0c\u5efa\u8bae\u81ea\u5df1\u52a8\u624b\u5c01\u88c5\u6210\u66f4\u6613\u7528\u7684 C++ \u51fd\u6570\uff1a std::wstring ansi_to_wstring(const std::string &s) { // ACP = ANSI Code Page\uff0c\u544a\u8bc9\u4ed6\u5b57\u7b26\u4e32\u91cc\u7684\u662f\u5f53\u524d\u533a\u57df\u8bbe\u7f6e\u6307\u5b9a\u7684\u7f16\u7801\uff08\u5728\u4e2d\u56fd\u533a\uff0cANSI \u5c31\u662f GBK \u4e86\uff09 int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_ansi(const std::wstring &ws) { int len = WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_ACP, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } std::wstring utf8_to_wstring(const std::string &s) { int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), nullptr, 0); std::wstring ws(len, 0); MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), ws.data(), ws.size()); return ws; } std::string wstring_to_utf8(const std::wstring &ws) { int len = WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), nullptr, 0, nullptr, nullptr); std::string s(len, 0); WideCharToMultiByte(CP_UTF8, 0, ws.c_str(), ws.size(), s.data(), s.size(), nullptr, nullptr); return s; } C \u8bed\u8a00\u7279\u8272\uff1a\u6240\u6709\u8981\u8fd4\u56de\u5b57\u7b26\u4e32\u7684\u51fd\u6570\uff0c\u90fd\u9700\u8981\u8c03\u7528\u4e24\u904d\uff0c\u7b2c\u4e00\u6ce2\u5148\u6c42\u51fa\u957f\u5ea6\uff0c\u7b2c\u4e8c\u6ce2\u624d\u5199\u5165\u3002\u8fd9\u662f\u4e3a\u4e86\u907f\u514d\u4e0e\u5185\u5b58\u5206\u914d\u5668\u8026\u5408\uff0c\u6240\u6709\u7684 C \u98ce\u683c API \u90fd\u662f\u8fd9\u6837\u3002","title":"Windows \u7528\u6237\uff1aMultiByteToWideChar"},{"location":"unicode/#messageboxa","text":"\u590d\u73b0\u6761\u4ef6\uff1a Windows \u7cfb\u7edf\u533a\u57df\u8bbe\u7f6e\u4e3a\u4e2d\u6587 (GBK)\u3002 \u4f7f\u7528 MSVC \u7684 /utf-8 \u9009\u9879\u7f16\u8bd1\u3002 #include int main() { MessageBoxA(nullptr, \"\u6211\u7231\ud883\udede\ud883\udede\u9762\", \"\u6807\u9898\", MB_OK); // \u4f1a\u53d8\u6210\u4e71\u7801 return 0; }","title":"MessageBoxA \u51fa\u73b0\u4e71\u7801\u95ee\u9898\u89e3\u51b3\u6848\u4f8b"},{"location":"unicode/#linux-iconv","text":"\u5982\u679c\u4f60\u662f Linux \u7528\u6237\uff0c\u4e14\u6ca1\u6709\u8de8\u5e73\u53f0\u9700\u6c42\uff0c\u4e0d\u60f3\u7528 Boost\uff0c\u53ef\u4ee5\u4f7f\u7528 C \u8bed\u8a00\u7684 iconv \u5e93\u3002 iconv \u4e5f\u6709 Windows \u7684\u7248\u672c\uff0c\u4f46\u5b89\u88c5\u6bd4\u8f83\u56f0\u96be\u3002\u5982\u679c\u4f60\u8fde iconv \u90fd\u641e\u5f97\u5b9a\uff0c\u6ca1\u7406\u7531 Boost \u641e\u4e0d\u5b9a\u3002 #include #include std::string convert(std::string const &s, char const *from, char const *to) { iconv_t cd = iconv_open(to, from); if (cd == (iconv_t)-1) { throw std::runtime_error(\"iconv_open failed\"); } auto in = s.data(); auto inbytesleft = s.size(); size_t outbytesleft = inbytesleft * 4; std::string buffer(outbytesleft, 0); auto out = buffer.data(); iconv(cd, &in, &inbytesleft, &out, &outbytesleft); iconv_close(cd); buffer.resize(buffer.size() - outbytesleft); return buffer; } // \u4e3e\u4f8b\uff1aUTF-8 \u8f6c GBK std::string utf8_to_gbk(std::string const &s) { return convert(s, \"UTF-8\", \"GBK\"); } // \u4e3e\u4f8b\uff1aGBK \u8f6c UTF-8 std::string gbk_to_utf8(std::string const &s) { return convert(s, \"GBK\", \"UTF-8\"); }","title":"Linux \u7528\u6237\uff1aiconv"},{"location":"unicode/#iconv","text":"iconv \u4e0d\u4ec5\u662f\u4e00\u4e2a\u5e93\uff0c\u4e5f\u662f\u4e00\u4e2a\u547d\u4ee4\u884c\u5de5\u5177\uff08\u5927\u591a Linux \u53d1\u884c\u7248\u90fd\u81ea\u5e26\u4e86\uff09\u3002\u7528\u6cd5\u5982\u4e0b\uff1a iconv -f \u6765\u81ea\u4ec0\u4e48\u7f16\u7801 -t \u5230\u4ec0\u4e48\u7f16\u7801 (\u8f93\u5165\u6587\u4ef6\u540d...) > \u8f93\u51fa\u6587\u4ef6\u540d \u5982\u4e0d\u6307\u5b9a\u8f93\u5165\u6587\u4ef6\u540d\uff0c\u9ed8\u8ba4\u4ece\u7ec8\u7aef\u8f93\u5165\u6d41\u8bfb\u53d6\u3002 \u5982\u4e0d\u4f7f\u7528 > \u8f93\u51fa\u6587\u4ef6\u540d \u91cd\u5b9a\u5411\u8f93\u51fa\uff0c\u5219\u9ed8\u8ba4\u8f93\u51fa\u5230\u7ec8\u7aef\u3002 \u53ef\u4ee5\u7528 echo \u914d\u5408\u7ba1\u9053\u6765\u521b\u5efa\u8f93\u5165\u6d41\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 \u6b64\u5904\u663e\u793a\u4e71\u7801\u662f\u56e0\u4e3a\u6211\u7684\u7ec8\u7aef\u662f UTF-8 \u683c\u5f0f\uff0c\u65e0\u6cd5\u6b63\u786e\u89e3\u6790 iconv \u8f93\u51fa\u7684 GBK \u683c\u5f0f\u6570\u636e\u3002 \u628a\u201c\u6211\u7231\u5c0f\u5f6d\u8001\u5e08\u201d\u8f6c\u6362\u4e3a GBK \u683c\u5f0f\u5199\u5165 gbk.txt \uff0c\u7136\u540e\u518d\u91cd\u65b0\u8fd8\u539f\u56de UTF-8 \u683c\u5f0f\u67e5\u770b\uff1a $ echo \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 | iconv -f UTF-8 -t GBK > gbk.txt $ cat gbk.txt \ufffd\u04b0\ufffd\u0421\ufffd\ufffd\ufffd\ufffd\u02a6 $ iconv -f GBK -t UTF-8 gbk.txt \u6211\u7231\u5c0f\u5f6d\u8001\u5e08 Windows \u53ef\u80fd\u4e5f\u6709\u7c7b\u4f3c\u7684\u5de5\u5177\uff0c\u6bd4\u5982 iconv.exe \uff0c\u4f46\u6211\u6ca1\u627e\u5230\u3002","title":"iconv \u547d\u4ee4\u884c\u5de5\u5177"},{"location":"unicode/#locale","text":"\u672c\u5730\u5316\u662f\u6307\u6839\u636e\u7528\u6237\u7684\u8bed\u8a00\u3001\u5730\u533a\u7b49\u73af\u5883\uff0c\u663e\u793a\u4e0d\u540c\u7684\u754c\u9762\u3002\u6bd4\u5982\u8bf4\uff0c\u540c\u6837\u662f\u6587\u4ef6\u83dc\u5355\uff0c\u4e2d\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201c\u6587\u4ef6\u201d\u3001\u82f1\u6587\u7528\u6237\u770b\u5230\u7684\u662f\u201cFile\u201d\u3002","title":"\u672c\u5730\u5316 (locale)"},{"location":"unicode/#_17","text":"C \u8bed\u8a00\u63d0\u4f9b\u4e86 \u5934\u6587\u4ef6\uff0c\u91cc\u9762\u5c01\u88c5\u4e86\u5927\u91cf\u5f62\u5982 isspace \u3001 isdigit \u8fd9\u6837\u7684\u5224\u65ad\u5b57\u7b26\u5206\u7c7b\u7684\u51fd\u6570\u3002 #include C++ \u5bf9\u5176\u5b9e\u65bd\u4e86\u518d\u5c01\u88c5\uff0c\u6539\u540d\u4e3a \u3002\u82e5\u4f60\u5bfc\u5165\u7684\u662f\u8be5\u5934\u6587\u4ef6\uff0c\u90a3\u4e48\u8fd9\u4e9b\u51fd\u6570\u53ef\u4ee5\u5e26\u6709 std \u540d\u5b57\u7a7a\u95f4\u524d\u7f00\u7684\u65b9\u5f0f std::isspace \uff0c std::isdigit \u8bbf\u95ee\u4e86\uff0c\u770b\u8d77\u6765\u66f4\u52a0\u4e13\u4e1a\uff08\u786e\u4fe1\uff09\u3002 #include \u51fd\u6570\u6e05\u5355\uff1a \u51fd\u6570\u540d\u79f0 \u5224\u65ad\u7684\u5b57\u7b26\u7c7b\u578b isascii 0 \u5230 0x7F \u7684\u6240\u6709 ASCII \u5b57\u7b26 isalpha \u5927\u5c0f\u5199\u5b57\u6bcd A-Z a-z isupper \u5927\u5199\u5b57\u6bcd A-Z islower \u5c0f\u5199\u5b57\u6bcd a-z isdigit \u6570\u5b57 0-9 isxdigit \u5341\u516d\u8fdb\u5236\u6570\u5b57 A-F a-f 0-9 isprint \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u5305\u62ec\u5b57\u6bcd\u3001\u6570\u5b57\u548c\u6807\u70b9\u7b49 isgraph \u53ef\u6253\u5370\u5b57\u7b26\uff0c\u4e0d\u5305\u62ec\u7a7a\u683c iscntrl \u63a7\u5236\u5b57\u7b26\uff0c\u9664\u53ef\u6253\u5370\u5b57\u7b26\u5916\u7684\u5168\u90e8 isspace \u7a7a\u767d\u5b57\u7b26\uff0c\u5982\u7a7a\u683c\u3001\u6362\u884c\u3001\u56de\u8f66\u3001\u5236\u8868\u7b26\u7b49 ispunct \u6807\u70b9\u7b26\u53f7 isalnum \u5b57\u6bcd\u6216\u6570\u5b57 \u66f4\u8be6\u7ec6\u7684\u8868\u683c\u53ef\u4ee5\u770b\uff1ahttps://en.cppreference.com/w/cpp/string/byte/isspace","title":"\u533a\u5206\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#_18","text":"\u4e4b\u524d\u63d0\u5230\u7684\u5b57\u7b26\u90fd\u662f char \u7c7b\u578b\u7684 ASCII \u5b57\u7b26\uff0c\u8303\u56f4\u6700\u591a\u5728 0 \u5230 0x7F \u5185\u3002 \u5bf9\u53ea\u63a5\u53d7 char \u7684 isspace \uff0c ispunct \u7cfb\u5217\u51fd\u6570\uff0c\u53c2\u6570\u5982\u679c\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\uff0c\u7ed3\u679c\u662f\u672a\u5b9a\u4e49\u884c\u4e3a\u3002 \u8981\u652f\u6301\u66f4\u5927\u8303\u56f4\u7684\u5b57\u7b26\uff0c\u6211\u4eec\u9700\u8981\u7528 wchar_t \u7c7b\u578b\uff0c\u6216\u8005 char16_t \u548c char32_t \u3002 \u4e0e\u5b57\u7b26\u4e32\u5e38\u91cf\u4e00\u6837\uff0c\u5355\u4e2a\u5b57\u7b26\u4e5f\u53ef\u4ee5\u7528 L \u3001 u \u3001 U \u6765\u5206\u522b\u4ea7\u751f wchar_t \u3001 char16_t \u3001 char32_t \u7c7b\u578b\u7684\u5b57\u7b26\u3002 char c = '\u6211'; // \u7f16\u8bd1\u51fa\u9519\uff01char \u7c7b\u578b\u65e0\u6cd5\u5bb9\u7eb3\u6211 (0x6211) wchar_t wc = L'\u6211'; // \u7f16\u8bd1\u901a\u8fc7\uff0c\u7b49\u4ef7\u4e8e wc = 0x6211 \u548c const char * \u4e00\u6837\uff0c\u4e5f\u6709 const wchar_t \u8868\u793a\u8fd9\u79cd\u7531 Unicode \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff1a const wchar_t *ws = L\"\u4f60\u597d\uff0c\u4e16\u754c\"; assert(ws[2] == L'\uff0c'); wchar_t \u7684\u63d0\u51fa\u8d77\u521d\u662f\u4e3a\u4e86\u907f\u514d char \u7684\u533a\u57df\u8bbe\u7f6e\u5404\u81ea\u4e3a\u653f\uff0c\u7f16\u7801\u6df7\u4e71\u7684\u95ee\u9898\uff0c\u56e0\u4e3a wchar_t \u59cb\u7ec8\u662f UTF-16 (Windows) \u6216 UTF-32 (Linux)\u3002","title":"\u5bbd\u5b57\u7b26\u7c7b\u578b"},{"location":"unicode/#wchar_t","text":"std::string str = \"hello,world,universe\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, ',')) { std::cout << line << '\\n'; } \u8fd9\u662f\u4e00\u4e2a\u7b80\u5355\u7684\u5b57\u7b26\u4e32\u5206\u5272\u51fd\u6570\uff0c\u5b83\u4f1a\u628a hello \u6309\u7167\u9017\u53f7 \u201c,\u201d (0x2C) \u5206\u5272\uff0c\u7136\u540e\u8f93\u51fa\u3002 \u4f46\u662f\uff0c\u5b83\u65e0\u6cd5\u5904\u7406 Unicode \u5b57\u7b26 \u201c\uff0c\u201d (0xFF0C)\uff0c\u8fd9\u662f\u4e00\u4e2a\u5168\u89d2\u7684\u9017\u53f7\u3002\u56e0\u4e3a \u201c\uff0c\u201d \u4f1a\u88ab UTF-8 \u7f16\u7801\u6210\u4e09\u4e2a char \uff1a0xEF 0xBC 0x8C\u3002 std::string str = \"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::stringstream ss(str); std::string line; while (std::getline(ss, line, '\uff0c')) { // \u7f16\u8bd1\u9519\u8bef\uff1a\u7b49\u4ef7\u4e8e '\\xEF\\xBC\\x8C'\uff0c\u4e00\u4e2a char \u5e38\u91cf\u91cc\u4e0d\u5f97\u5305\u542b\u4e09\u4e2a char\uff01 std::cout << line << '\\n'; } \u800c wchar_t \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u4e3a \u201c\uff0c\u201d \u5728 0xFFFF \u8303\u56f4\u5185\uff0c\u5373\u4f7f\u8003\u8651\u5230 Windows \u662f UTF-16 \u7f16\u7801\uff0c\u201c\uff0c\u201d \u53ea\u4f1a\u4ea7\u751f\u4e00\u4e2a wchar_t \u3002\u8fd9\u5bf9\u4ee5\u5355\u4e2a wchar_t \u4e3a\u5355\u4f4d\u7684 std::getline \u6765\u8bf4\u6ca1\u6709\u95ee\u9898\u3002 std::wstring str = L\"\u4f60\u597d\uff0c\u4e16\u754c\uff0c\u5b87\u5b99\"; std::wstringstream ss(str); std::wstring line; while (std::getline(ss, line, L'\uff0c')) { // \u7f16\u8bd1\u901a\u8fc7\uff0c'\uff0c' \u662f\u5355\u4e2a UTF-16 \u7801\u4f4d std::wcout << line << L'\\n'; }","title":"wchar_t \u5e94\u7528\u6848\u4f8b"},{"location":"unicode/#locale_1","text":"\u8981\u8ba9 iswspace \u548c iswpunct \u8bc6\u522b\u4e2d\u6587\u9017\u53f7\u548c\u4e2d\u6587\u7a7a\u683c\uff0c\u6211\u4eec\u9700\u8981\u5148\u4f7f\u7528\u4e0b\u9762\u8fd9\u4e00\u884c\u4ee3\u7801\uff1a setlocale(LC_ALL, \"C.utf-8\"); \u8fd9\u4f1a\u542f\u7528 Unicode \u5b57\u7b26\u96c6\uff0c\u4f7f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u80fd\u591f\u57fa\u4e8e Unicode \u5b57\u7b26\u96c6\u53bb\u5224\u65ad\u5b57\u7b26\u7c7b\u578b\uff0c\u800c\u4e0d\u662f\u9ed8\u8ba4\u7684 ASCII \u5b57\u7b26\u96c6\u3002 assert(ispunct(',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f ispunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L',') == true); // 0x2C \u5bf9\u5e94\u7684\u534a\u89d2\u9017\u53f7\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 assert(iswpunct(L'\uff0c') == true);// 0xFF0C \u5bf9\u5e94\u7684\u5168\u89d2\u9017\u53f7\u4e5f\u662f iswpunct \u8ba4\u540c\u7684\u6807\u70b9\u7b26\u53f7 \u6bcf\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u4e00\u5f00\u59cb\uff0c\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \u3002\u9700\u8981\u8bbe\u7f6e\u4e3a \"C.UTF-8\" \u6216\u8005 \"zh_CN.UTF-8\" \uff0c\u603b\u4e4b\u662f\u652f\u6301 Unicode \u5b57\u7b26\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u624d\u80fd\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u8bc6\u522b\u8d85\u8fc7 ASCII \u8303\u56f4\u7684\u5b57\u7b26\u7684\u7c7b\u578b\u3002 fmt::println(\"\u9ed8\u8ba4: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C\"); fmt::println(\"C: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"C.UTF-8\"); fmt::println(\"C.UTF-8: {}\", iswpunct(L'\uff0c')); setlocale(LC_ALL, \"zh_CN.UTF-8\"); fmt::println(\"zh_CN.UTF-8: {}\", iswpunct(L'\uff0c')); \u8f93\u51fa\uff1a \u9ed8\u8ba4: 0 C: 0 C.UTF-8: 1 zh_CN.UTF-8: 1 \u603b\u4e4b\uff0c isw***** \u7cfb\u5217\u51fd\u6570\u63a5\u53d7\u7684\u53c2\u6570 wchar_t \u8868\u793a\u8303\u56f4\u66f4\u5e7f\uff0c\u5728 Linux \u4e0a\u80fd\u8868\u793a\u6240\u6709 Unicode \u5b57\u7b26\uff0c\u5728 Windows \u4e0a\u80fd\u8868\u793a\u6240\u6709 0xFFFF \u4ee5\u5185\u7684\u5e38\u7528 Unicode \u5b57\u7b26\u3002 is***** \u7cfb\u5217\u51fd\u6570\u9047\u5230\u8d85\u8fc7 0 \u5230 0x7F \u8303\u56f4\u7684 char \u8fd8\u4f1a\u51fa\u73b0\u672a\u5b9a\u4e49\u884c\u4e3a\uff0c\u975e\u5e38\u70e6\u4eba\u3002\u65e2\u7136 char \u53ef\u4ee5\u9690\u5f0f\u8f6c\u6362\u4e3a wchar_t \uff0c\u6240\u4ee5\u6211\u7684\u5efa\u8bae\u662f\u8bbe\u7f6e\u4e86 \".utf-8\" locale \u540e\uff0c\u5168\u90e8\u7528 isw***** \u53d6\u4ee3 is***** \u3002","title":"\u533a\u57df\u8bbe\u7f6e\u4e0e locale"},{"location":"unicode/#locale_2","text":"\"zh_CN.UTF-8\" \u8fd9\u6837\u7684\u5b57\u7b26\u4e32\uff0c\u5c31\u662f locale \u7684\u540d\u5b57\uff0clocale \u540d\u5b57\u7531\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5206\u522b\u662f\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\u3002 \u8bed\u8a00.\u5b57\u7b26\u7f16\u7801 \"zh_CN.UTF-8\" \u5c31\u8868\u793a\uff0c\u4e00\u4e2a\u8bed\u8a00\u4e3a\u7b80\u4f53\u4e2d\u6587\uff0c\u7f16\u7801\u683c\u5f0f\u4e3a UTF-8 \u7684\u533a\u57df\u8bbe\u7f6e\u3002 \u8981\u6ce8\u610f\u7684\u662f\uff0c\u7528\u6237\u5fc5\u987b\u5df2\u7ecf\u5b89\u88c5\u8fc7\u8be5\u533a\u57df\u8bbe\u7f6e\uff0c\u7a0b\u5e8f\u624d\u80fd\u4f7f\u7528 setlocale \u8bbe\u7f6e\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u627e\u4e0d\u5230 locale \u7684\u9519\u8bef\u3002 \u8fd9\u51e0\u4e4e\u5bfc\u81f4\u4f60\u6ca1\u6cd5\u7528\u9664\u9ed8\u8ba4\u5916\u7684\u4efb\u4f55 locale\uff0c\u6bd4\u5982 \"zh_CN.UTF-8\" \uff0c\u56e0\u4e3a\u4f60\u4e0d\u80fd\u786e\u5b9a\u7528\u6237\u6709\u6ca1\u6709\u5b89\u88c5\u4ed6\u3002\u4f46\u4f60\u53ef\u4ee5\u7528 boost::locale::generator \u51ed\u7a7a\u751f\u6210\u4e00\u4e2a\u7cfb\u7edf\u91cc\u6ca1\u6709\u5b89\u88c5\u8fc7\u7684 locale\uff0c\u7ed5\u5f00\u6807\u51c6\u5e93\u7684\u9650\u5236\uff0c\u7a0d\u540e\u4ecb\u7ecd\u3002 Linux \u7528\u6237\u53ef\u4ee5\u901a\u8fc7 \u4fee\u6539 /etc/locale.gen \u53d6\u6d88\u6ce8\u91ca\u8981\u542f\u7528\u7684\u8bed\u8a00\u548c\u7f16\u7801\u683c\u5f0f\uff0c\u4fdd\u5b58\u540e\uff0c\u8fd0\u884c locale-gen \u5373\u53ef\u5b89\u88c5\u6240\u6709\u6ca1\u6ce8\u91ca\u7684\u8bed\u8a00\u3002 sudo vim /etc/locale.gen sudo locale-gen \u53ef\u4ee5\u7528 locale -a \u547d\u4ee4\u67e5\u770b\u5df2\u7ecf\u5b89\u88c5\u4e86\u54ea\u4e9b locale\uff1a $ locale -a C C.utf8 POSIX en_US en_US.iso88591 en_US.utf8 zh_CN.gb18030 zh_CN.gbk zh_CN.utf8 \u6ce8\u610f\u5230\uff0clocale \u4e2d '.' \u53f7\u53f3\u8fb9\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u65e0\u89c6\u5927\u5c0f\u5199\u7684\uff0c\u800c\u4e14\u53ef\u4ee5\u7701\u7565\u6389 '-' \u3002\u6240\u4ee5 ISO-8859-1 \u53ef\u4ee5\u88ab\u7b80\u5199\u6210 iso88591 \uff0c UTF-8 \u88ab\u7b80\u5199\u6210 utf8 \u3002 \u5de6\u8fb9\u7684\u8bed\u8a00\u4e5f\u662f\u7528 '_' \u4e00\u5206\u4e3a\u4e8c\uff0c\u56fa\u5b9a\u662f '\u8bed\u8a00_\u5730\u533a' \u7684\u5199\u6cd5\u3002\u6bd4\u5982\u52a0\u62ff\u5927\u65e2\u6709\u82f1\u8bed\u7528\u6237\u53c8\u6709\u6cd5\u8bed\u7528\u6237\uff0c\u82f1\u8bed\u7684\u4ee3\u53f7\u662f 'en' \uff0c\u6cd5\u8bed\u7684\u4ee3\u53f7\u662f 'fr' \uff0c\u52a0\u62ff\u5927\u7684\u4ee3\u53f7\u662f 'CA' \uff0c\u6240\u4ee5\u5c31\u5b58\u5728\u7740 'en_CA' \u548c 'fr_CA' \u4e24\u79cd locale\u3002 \u4e5f\u6709\u4e00\u79cd\u8bed\u8a00\u88ab\u591a\u4e2a\u5730\u533a\u4f7f\u7528\u7684\u60c5\u51b5\uff0c\u4f8b\u5982\u4e2d\u6587\u7684\u4ee3\u53f7\u662f 'zh' \uff0c\u4ed6\u88ab\u4e2d\u56fd\u5927\u9646\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_CN' \uff0c\u88ab\u9999\u6e2f\u4f7f\u7528\u65f6\u53eb 'zh_HK' \uff0c\u88ab\u53f0\u6e7e\u7701\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_TW' \uff0c\u88ab\u65b0\u52a0\u5761\u4f7f\u7528\u65f6\u5c31\u53eb 'zh_SG' \u3002 Windows \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b89\u88c5\u8bed\u8a00\u548c\u5730\u533a\u7684\u9009\u9879\uff0c\u4f46\u6bd4\u5c14\u76d6\u5b50\u5bf9 locale \u547d\u540d\u7684\u8bed\u6cd5\u7a0d\u6709\u4e0d\u540c\uff1a setlocale(LC_ALL, \"Chinese_China.936\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4ee3\u7801\u9875 936\uff08\u4e5f\u5c31\u662f GBK\uff09 \u4ed6\u7684\u8bed\u8a00\u540d\u4e0d\u662f\u6309\u7167\u56fd\u9645\u89c4\u8303\u7684 zh_CN \u8fd9\u6837\u7684\u7b80\u5199\uff0c\u800c\u662f Chinese_China \u3002 \u800c\u4e14\u540e\u9762\u7684 936 \u662f Windows \u79c1\u81ea\u5b9a\u4e49\u7684\u4e00\u5957\u6240\u8c13\u7684\u201c\u4ee3\u7801\u9875\u201d\uff0c\u8fd9\u91cc 936 \u5176\u5b9e\u5c31\u662f \u4e2d\u5b8f CP_GBK \u7684\u503c\uff0c\u8868\u793a GBK \u4ee3\u7801\u9875\u3002\u540c\u6837\u5730\u8fd8\u6709 65001 \u8868\u793a UTF-8 \u4ee3\u7801\u9875\u3002 setlocale(LC_ALL, \"Chinese_China.65001\"); // \u8868\u793a\u7b80\u4f53\u4e2d\u6587\uff0c\u4f46\u662f\u542f\u7528 UTF-8 \u652f\u6301 setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 .65001 \u53ef\u4ee5\u7528\u522b\u540d .UTF-8 \u53d6\u4ee3\u3002\u4f46\u53ea\u6709 .UTF-8 \u652f\u6301\u8fd9\u4e2a\u522b\u540d\uff0c\u4f8b\u5982 .GBK \u4ed6\u5c31\u4e0d\u80fd\u8bc6\u522b\u3002 \u8bbe\u7f6e\u4e86 \"Chinese_China.utf-8\" \u6548\u679c\u548c\u4f60\u5728\u63a7\u5236\u9762\u677f\u5168\u5c40\u5f00\u4e86\u90a3\u4e2a \u201cBeta \u7248\uff1a\u4f7f\u7528 Unicode UTF-8 \u5168\u7403\u8bed\u8a00\u5b9e\u9a8c\u652f\u6301\u201d \u4e00\u6837\uff0c\u53ea\u4e0d\u8fc7\u8fd9\u662f\u4ec5\u9650\u5f53\u524d\u8fdb\u7a0b\u7684 C/C++ \u6807\u51c6\u5e93\u3002 \u800c\u4e14\u7531\u4e8e argv \u5728\u4f60\u6765\u5f97\u53ca setlocale \u4e4b\u524d\u5c31\u5df2\u7ecf\u521d\u59cb\u5316\uff0c\u6240\u4ee5 main \u7684 argv \u53c2\u6570\u4f9d\u7136\u662f GBK \u7f16\u7801\u7684\uff0c\u9664\u975e\u4f60\u4f7f\u7528\u7684\u662f _wmain \uff0c\u90a3\u5c06\u80fd\u6536\u5230 UTF-16 \u7684 argv \uff0c\u7136\u540e\u4f60\u81ea\u5df1\u8f6c\u6362\u56de UTF-8\u3002","title":"locale \u7684\u547d\u540d\u89c4\u8303"},{"location":"unicode/#locale_3","text":"\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u63a5\u53d7\u73af\u5883\u4e2d\u7684\u8bbe\u7f6e\uff0c\u5bf9\u4e8e Linux \u800c\u8a00\u662f $LC_ALL \u73af\u5883\u53d8\u91cf\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f\u63a7\u5236\u9762\u677f\u4e2d\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 setlocale(LC_ALL, \"\"); // \u662f\u7684\uff0c\u7a7a\u7684\u5b57\u7b26\u4e32 \u6ce8\u610f\u662f\u7a7a\u5b57\u7b26\u4e32 \"\" \u624d\u6709\u8fd9\u6837\u7684\u6548\u679c\uff0c\u800c\u4e0d\u662f NULL\uff01 setlocale(LC_ALL, NULL) \u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u4ed6\u7684\u6548\u679c\u662f\u8fd4\u56de\u5f53\u524d\u7684 locale\uff08\u6ca1\u60f3\u5230\u5427\uff1fsetlocale \u6709\u8fd4\u56de\u503c\uff09\u3002\u8fd9\u5c31\u662f C \u8bed\u8a00\u7684\u9b45\u529b\uff0c\u540c\u4e00\u4e2a\u51fd\u6570\u62c6\u6210\u597d\u51e0\u5206\u7528\uff0c\u53c8\u80fd set \u53c8\u80fd get\uff0c\u5c41\u80a1\u5341\u5206\u7075\u6d3b\u3002 \u4e5f\u53ef\u4ee5\u6307\u5b9a\u4e00\u4e2a\u90e8\u5206\u4e3a\u7a7a\u7684 locale \u540d\u5b57\uff0c\u6bd4\u5982 \".utf-8\" \uff0c\u4ed6\u8868\u793a\u4fdd\u7559\u5f53\u524d\u73af\u5883\u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\uff0c\u4f46\u201c\u7f16\u7801\u201d\u90e8\u5206\u66ff\u6362\u4e3a\u201c.utf-8\u201d\u3002 setlocale(LC_ALL, \".utf-8\"); // \u5728\u4e2d\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"Chinese_China.utf-8\"); // \u5728\u7f8e\u56fd\u533a Windows \u4e0a\uff0c\u7b49\u4ef7\u4e8e setlocale(LC_ALL, \"English_United States.utf-8\");","title":"\u7279\u6b8a locale\uff1a\u7a7a\u5b57\u7b26\u4e32"},{"location":"unicode/#localec","text":"\u4e0d\u559c\u6b22\u672c\u5730\u5316\u8fd9\u4e00\u5957\u8bbe\u5b9a\uff1f \u4f60\u53ef\u4ee5\u8bbe\u7f6e LC_ALL \u4e3a \"C\" \u6216 \"POSIX\" \uff0c\u8fd9\u662f\u6807\u51c6\u5e93\u9884\u5148\u5b9a\u4e49\u597d\u7684\u4e24\u4e2a locale\uff0c\u4ed6\u4eec\u7684\u7279\u70b9\u662f\u6c38\u8fdc\u4e0d\u4f1a\u88ab\u672c\u5730\u5316\uff0c\u800c\u662f\u59cb\u7ec8\u4ee5\u82f1\u6587\u663e\u793a\u3002\u8fd9\u5728\u8c03\u8bd5\u7a0b\u5e8f\u65f6\u975e\u5e38\u6709\u7528\uff0c\u56e0\u4e3a\u8fd9\u6837\u4f60\u53ef\u4ee5\u786e\u5b9a\u8f93\u51fa\u7684\u683c\u5f0f\u662f\u56fa\u5b9a\u7684\uff0c\u4e0d\u4f1a\u88ab\u7528\u6237\u7684\u73af\u5883\u548c\u672c\u5730\u5316\u7684\u4fe1\u606f\u800c\u6539\u53d8\u3002 \u4e8b\u5b9e\u4e0a\uff0c\u53ea\u8981\u4f60\u6ca1\u6709 setlocale \u8fc7\uff0cC \u8bed\u8a00\u9ed8\u8ba4\u5c31\u662f \"C\" locale\uff0c\u4e0d\u4f1a\u53d7\u5230\u7528\u6237\u73af\u5883\u53d8\u91cf\u7684\u4efb\u4f55\u5f71\u54cd\uff08Windows \u7684\u6587\u4ef6\u7cfb\u7edf API \u9664\u5916\uff0c\u786e\u5b9e\u4f1a\u53d7\u5230 GBK \u5f71\u54cd\uff09\u3002 setlocale(LC_ALL, \"C\"); setlocale(LC_ALL, \"POSIX\"); // \u7b49\u4ef7\u7684\u5199\u6cd5 \u4e0d\u8fc7\uff0c \"C\" \u610f\u5473\u7740\u4ed6\u5047\u5b9a\u5b57\u7b26\u4e32\u662f\u5b8c\u5168\u7684 ASCII\uff0c\u8d85\u8fc7 ASCII \u7684\u90e8\u5206\u662f\u5b9e\u73b0\u5b9a\u4e49\u884c\u4e3a\uff1a\u5bf9\u4e8e Linux \u800c\u8a00\u662f UTF-8\uff08\u66f4\u51c6\u786e\u7684\u8bf4\u662f\u4e0d\u505a\u4efb\u4f55\u5904\u7406\uff0c\u56e0\u4e3a Linux \u7684 ext4 \u6587\u4ef6\u7cfb\u7edf\u6ca1\u6709\u5b57\u7b26\u7f16\u7801\u7684\u533a\u5206\uff09\uff0c\u5bf9\u4e8e Windows \u800c\u8a00\u662f GBK\uff08\u4e2d\u56fd\u533a\uff09\u3002 \u56e0\u6b64\uff0c\u4e5f\u6709 \"C.utf-8\" \u8fd9\u6837\u7684 locale\uff0c\u4ed6\u8868\u793a\u91c7\u7528 UTF-8 \u7f16\u7801\uff0c\u53ef\u4ee5\u8ba9 isw***** \u7cfb\u5217\u51fd\u6570\u652f\u6301 Unicode \u8303\u56f4\u7684\u5b57\u7b26\uff0c\u4e5f\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6253\u5370 ASCII \u4ee5\u5916\u7684\u5b57\u7b26\u4e86\u3002\u53ea\u662f\u6ca1\u6709\u6307\u5b9a\u8bed\u8a00\uff0c\u901a\u5e38\u6765\u8bf4\u8fd9\u65f6 strerror \u4e00\u7c7b\u51fd\u6570\u4f1a\u9ed8\u8ba4\u8fd4\u56de\u82f1\u8bed\u7684\u6d88\u606f\u3002 \u4f46\u4f3c\u4e4e\u53ea\u5728 Linux \u4e0a\u6709\u6548\uff0cWindows \u53ea\u652f\u6301 \"C\" \u800c\u4e0d\u652f\u6301 \"C.utf-8\" \u3002","title":"\u7279\u6b8a locale\uff1a\"C\""},{"location":"unicode/#lc_","text":"locale \u5206\u4e3a\u8bb8\u591a\u4e2a\u201c\u65b9\u9762 (facet)\u201d\uff0c\u4e0d\u540c\u7684\u65b9\u9762\u53ef\u4ee5\u6709\u4e0d\u540c\u7684\u53d6\u503c\uff08\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u662f\u4e00\u6837\u7684\uff09\uff0c\u53ef\u4ee5\u5ba2\u5236\u5316\u6807\u51c6\u5e93\u4e0d\u540c\u90e8\u5206\u6d89\u53ca\u8bed\u8a00\u548c\u7f16\u7801\u76f8\u5173\u7684\u884c\u4e3a\u3002\u8fd9\u4e9b\u65b9\u9762\u5728 C \u8bed\u8a00\u4e2d\u90fd\u6709\u4e00\u4e2a LC_ \u5f00\u5934\u7684\u679a\u4e3e\u6765\u8868\u793a\u3002 LC_CTYPE \u53ea\u5f71\u54cd ctype.h \u4e2d\u7684\u51fd\u6570\uff0c\u4e5f\u5c31\u662f isw***** \u7cfb\u5217\u51fd\u6570\uff0c\u8fd8\u6709 toupper \uff0c tolower \u7b49\uff0c\u4ed6\u8fd8\u5f71\u54cd\u5b57\u7b26\u7f16\u7801\u683c\u5f0f\uff0c\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\u65b9\u9762\u3002 LC_TIME \u5f71\u54cd\u65f6\u95f4\u548c\u65e5\u671f\u7684\u683c\u5f0f\u5316\uff0c\u4f8b\u5982 asctime \u7b49\u3002 LC_NUMERIC \u5f71\u54cd\u6570\u5b57\u7684\u683c\u5f0f\u5316\u3002 LC_MONETARY \u5f71\u54cd\u8d27\u5e01\u7684\u683c\u5f0f\u5316\u3002 LC_MESSAGES \u5f71\u54cd strerror \u7b49\u4fe1\u606f\u7c7b\u51fd\u6570\u8fd4\u56de\u7684\u5b57\u7b26\u4e32\u3002\u4f8b\u5982\u5728\u4e2d\u6587 locale \u4e0b strerror(EPERM) \u4f1a\u8fd4\u56de \"\u6743\u9650\u4e0d\u591f\" \uff0c\u800c\u5728\u82f1\u6587 locale \u4e0b\u8fd4\u56de \"Permission denied.\" \u3002 LC_ALL \u662f\u5168\u5c40 locale\uff0c\u5b83\u4f1a\u5f71\u54cd\u4ee5\u4e0a\u6240\u6709\u6807\u51c6\u5e93\u51fd\u6570\u7684\u884c\u4e3a\u3002\u8bbe\u7f6e LC_ALL \u4e3a\u4e00\u4e2a\u503c\uff0c\u7b49\u540c\u4e8e\u4e3a\u4ee5\u4e0a\u6240\u6709\u90fd\u8d4b\u4e88\u7edf\u4e00\u7684\u503c\u3002 \u4f60\u53ef\u4ee5\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u8bbe\u7f6e $LC_ALL \u3001`$LC_CTYPE \u6240\u6709 GNU/Linux \u81ea\u5e26\u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u90fd\u5728 main \u51fd\u6570\u5f00\u5934\uff0c\u914d\u5907\u4e86 setlocale(LC_ALL, \"\"); \u3002\u8fd9\u4f1a\u8bfb\u53d6\u7528\u6237\u914d\u7f6e\u5728\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u533a\u57df\u504f\u597d\u8bbe\u7f6e\uff0c\u5e76\u8bbe\u4e3a\u5168\u5c40\u7684 locale\u3002 \u53ef\u4ee5\u7406\u89e3\u4e3a locale \u662f\u4e00\u4e2a\u9690\u85cf\u5728\u6807\u51c6\u5e93\u4e2d\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u6240\u6709\u7684 iswpunct \u3001 asctime \u3001 strerror \u90fd\u4f1a\u8bfb\u53d6\u8be5\u5168\u5c40\u53d8\u91cf\u91cc\u7684\u533a\u57df\u8bbe\u7f6e\uff0c\u6765\u51b3\u5b9a\u81ea\u5df1\u7684\u8fd0\u884c\u65f6\u884c\u4e3a\u3002","title":"LC_*** \u7cfb\u5217\u73af\u5883\u53d8\u91cf"},{"location":"unicode/#lc_messages","text":"\u4f8b\u5982 touch \u8fd9\u4e9b\u547d\u4ee4\uff0c\u90fd\u662f\u57fa\u4e8e strerror \u6253\u5370\u62a5\u9519\u6d88\u606f\u7684\uff0c\u800c strerror \u53c8\u57fa\u4e8e\u533a\u57df\u8bbe\u7f6e\u7684 LC_MESSAGES \u65b9\u9762\u3002 \u8fd9\u4e9b\u547d\u4ee4\u884c\u7a0b\u5e8f\u7684\u4f5c\u8005\u65e0\u9700\u61c2\u5f97\u6240\u6709\u8bed\u8a00\uff0c\u4ed6\u4eec\u53ea\u9700\u8981\u8c03\u7528 strerror \u548c\u5404\u79cd messages \u67e5\u627e\u51fd\u6570\uff0c\u83b7\u5f97\u76f8\u5e94\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\u540e\uff0c\u8f93\u51fa\u5373\u53ef\u81ea\u52a8\u9002\u5e94\u4e0d\u540c\u8bed\u8a00\u7528\u6237\u7684\u9700\u6c42\u3002 \u53ea\u9700\u8981\u8bed\u8a00\u7684\u7528\u6237\uff0c\u5728\u4ed6\u7684\u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u8bbe\u7f6e LC_ALL=zh_CN.UTF-8 \u5c31\u53ef\u4ee5\u8ba9\u547d\u4ee4\u884c\u7a0b\u5e8f\u4eec\u59cb\u7ec8\u8f93\u51fa\u4e2d\u6587\u6d88\u606f\u4e86\u3002 $ export LC_MESSAGES=en_US.UTF-8 $ touch /root/a touch: cannot touch '/root/a': Permission denied $ export LC_MESSAGES=zh_CN.UTF-8 $ touch /root/a touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f \u4f8b\u5982 GCC \u7684\u62a5\u9519\u4fe1\u606f\uff0c\u5c31\u662f\u57fa\u4e8e\u4f60\u7684 $LC_MESSAGES \u73af\u5883\u53d8\u91cf\u6765\u51b3\u5b9a\u8f93\u51fa\u4f55\u79cd\u8bed\u8a00\u7684\u4fe1\u606f\u7684\u3002 \u4f60\u4e5f\u53ef\u4ee5\u53ea\u8bbe\u7f6e\u4e00\u4e2a export LC_ALL=zh_CN.UTF-8 \uff0c\u8fd9\u6837\u5c31\u65e0\u9700\u8bbe\u7f6e\u5176\u4ed6\u6240\u6709\u7684\u65b9\u9762 (facet)\uff0c\u5982\u65e0\u5355\u72ec\u8bbe\u7f6e\uff0c\u5176\u4ed6\u65b9\u9762\u4f1a\u81ea\u52a8\u53d8\u5f97\u548c $LC_ALL \u4e00\u6837\u3002","title":"LC_MESSAGES\uff1a\u62a5\u9519\u4fe1\u606f"},{"location":"unicode/#lc_ctype","text":"\u8fd9\u662f\u6700\u91cd\u8981\u7684\u4e00\u4e2a\uff0c\u4ed6\u51b3\u5b9a\u4e86\u5b57\u7b26\u4e32\u7684\u7f16\u7801\u683c\u5f0f\u3002 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u5185\u90e8\u90fd\u4ee5\u5185\u7801\uff08 const wchar_t * \u6216 std::wstring \uff09\u6765\u5904\u7406\u5b57\u7b26\u4e32\u3002 \u5f53\u8f93\u51fa\u65f6\uff0c\u7a0b\u5e8f\u5185\u90e8\u7684\u5185\u7801\u5b57\u7b26\u4e32\uff08 wchar_t * \uff09\u4f1a\u4ee5 LC_CTYPE \u6307\u5b9a\u7684\u7f16\u7801\u683c\u5f0f\u7f16\u7801\u6210\u4e8c\u8fdb\u5236\u6d41\uff08 const char * \u6216 std::string \uff09\u540e\u8f93\u51fa\u5230\u63a7\u5236\u53f0\u3002 \u56e0\u6b64\uff0c LC_CTYPE \u4e2d\u7684\u201c\u8bed\u8a00\u201d\u90e8\u5206\u662f\u65e0\u5173\u7d27\u8981\u7684\uff0c\u91cd\u8981\u7684\u662f\u540e\u534a\u6bb5\uff0c\u4f8b\u5982 \"zh_CN.UTF-8\" \uff0c\u90a3\u6709\u5f71\u54cd\u7684\u5c31\u53ea\u662f\u540e\u9762\u8fd9\u6bb5 \".UTF-8\" \u3002 \u52a1\u5fc5\u4f7f\u7528\u548c\u4f60\u7ec8\u7aef\u914d\u7f6e\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5426\u5219\u4f1a\u51fa\u73b0\u4e71\u7801\u3002\u4f8b\u5982\u5f53\u6211\u6b3a\u9a97 touch \uff0c\u8ba9\u4ed6\u8bef\u4ee5\u4e3a\u6211\u7684\u7ec8\u7aef\u8f93\u51fa\u9700\u8981\u662f GBK \u7f16\u7801\uff1a $ export LC_MESSAGES=zh_CN.UTF-8 $ export LC_CTYPE=zh_CN.GBK # \u6b3a\u9a97 touch\uff01\u597d\u574f $ touch /root/a touch: \ufffd\u07b7\ufffd touch '/root/a': \u0228\ufffd\u07b2\ufffd\ufffd\ufffd \u4ed6\u5c31\u8f93\u51fa\u4e86\u8be1\u5f02\u7684\u4e71\u7801\u3002\u8fd9\u4e0d\u662f touch \u7684\u95ee\u9898\uff0ctouch \u53ea\u662f\u6309\u7167\u4f60\u73af\u5883\u53d8\u91cf $LC_CTYPE \u8bf4\u7684 GBK \u7f16\u7801\uff0c\u8f93\u51fa\u4e86 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u3002\u800c\u7ec8\u7aef\u7684\u8bbe\u7f6e\u5374\u662f UTF-8\uff0c\u7528 UTF-8 \u89e3\u7801 GBK \u7684\u4e8c\u8fdb\u5236\u6d41\u5f53\u7136\u51fa\u9519\u4e86\uff0c\u4e0d\u8fc7\u7531\u4e8e GBK \u548c UTF-8 \u90fd\u517c\u5bb9 ASCII\uff0c\u6240\u4ee5\u8fd9\u91cc\u9762\u82f1\u6587\u90e8\u5206\u624d\u4fa5\u5e78\u6b63\u5e38\u663e\u793a\u3002 \u89e3\u51b3\u65b9\u6cd5\u662f\u8981\u4e48\u4f60 $LC_CTYPE \u8bbe\u56de UTF-8\uff0c\u8981\u4e48\u628a\u7ec8\u7aef\u6539\u6210 GBK\uff0c\u603b\u4e4b $LC_CTYPE \u5fc5\u987b\u548c\u7ec8\u7aef\u5b57\u7b26\u7f16\u7801\u914d\u7f6e\u4e00\u6837\u3002\u4e5f\u53ef\u4ee5\u8c03\u7528 iconv \u628a touch \u7684 GBK \u8f93\u51fa\u8f6c\u6362\u56de UTF-8\uff0c\u4f9b UTF-8 \u7684\u7ec8\u7aef\u8bfb\u53d6\uff1a $ touch /root/a 2>&1 | iconv -f GBK -t UTF-8 touch: \u65e0\u6cd5 touch '/root/a': \u6743\u9650\u4e0d\u591f","title":"LC_CTYPE\uff1a\u5b57\u7b26\u7f16\u7801"},{"location":"unicode/#lc_time","text":"LC_TIME \u5f71\u54cd\u7684\u662f\u548c\u65f6\u95f4\u6709\u5173\u51fd\u6570\u7684\u8f93\u51fa\u683c\u5f0f\uff0c\u56e0\u4e3a\u4e0d\u540c\u7684\u5730\u533a\u6709\u4e0d\u540c\u7684\u65f6\u95f4\u663e\u793a\u4e60\u60ef\uff0c\u6bd4\u5982\u82f1\u6587\u662f Jan 1 00:00 \uff0c\u4e2d\u6587\u662f 1\u6708 1\u65e5 00\u65f600\u5206 \uff0c\u800c\u65e5\u672c\u4eba\u5219\u662f 1\u67081\u65e5 0\u66420\u5206 \u3002 $ export LC_TIME=en_US.UTF-8 $ date Fri Jul 19 04:01:49 PM CST 2024 $ export LC_TIME=zh_CN.UTF-8 $ date 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16:01:07 CST \u5728 C \u8bed\u8a00\u4e2d\uff0c\u4f60\u53ef\u4ee5\u7528\u8fd9\u6837\u683c\u5f0f\u5316\u65f6\u95f4\u548c\u65e5\u671f\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); struct tm *tm = localtime(&t); char buf[32]; strftime(buf, sizeof(buf), \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\", tm); puts(buf); } C++ \u63d0\u4f9b\u4e86\u57fa\u4e8e\u6d41\u7684\uff0c\u66f4\u201c\u65f6\u5c1a\u201d\u7684\u5199\u6cd5\uff1a #include #include #include int main() { setlocale(LC_ALL, \"zh_CN.UTF-8\"); time_t t = time(NULL); tm *tm = localtime(&t); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206","title":"LC_TIME\uff1a\u65f6\u95f4\u65e5\u671f\u683c\u5f0f\u5316"},{"location":"unicode/#stdlocale","text":"C \u8bed\u8a00\u7684 setlocale \u8bbe\u7f6e\u7684\u662f\u5168\u5c40 locale\uff0c\u5168\u5c40 locale \u53ea\u6709\u4e00\u4e2a\uff0c\u4e00\u8bbe\u5c31\u5f71\u54cd\u6240\u6709\u7ebf\u7a0b\uff0c\u975e\u5e38\u6c99\u96d5\u3002\u56e0\u6b64\u63d0\u5021\u201c\u4e0d\u8981\u72b6\u6001\u673a\u8981\u5bf9\u8c61\u201d\u7684 C++\uff0c\u5c01\u88c5\u4e86 std::locale \u5bf9\u8c61\u3002 std::locale \u7684\u6784\u9020\u51fd\u6570\u63a5\u53d7\u4e00\u4e2a\u5b57\u7b26\u4e32\uff0c\u548c setlocale \u7684\u60c5\u51b5\u4e00\u6837\uff0c\u6709\u7a7a\u5b57\u7b26\u4e32\u8868\u793a\u73af\u5883 locale\uff0c \"C\" \u8868\u793a POSIX locale\uff0c\u8fd8\u6709\u81ea\u5b9a\u4e49\u5b57\u7b26\u4e32\u6bd4\u5982 \"zh_CN.UTF-8\" \u7684 locale\u3002 \u7136\u540e\uff0cC++ \u7684\u6d41\u7c7b\u578b\uff0c\u5982 std::cout \uff0c\u90fd\u6709\u4e00\u4e2a .imbue \u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e2a\u5c40\u90e8 locale\uff08\u53ea\u5bf9 std::cout \u751f\u6548\u7684\uff09\uff0c\u63a5\u53d7\u7684\u5c31\u662f\u8fd9\u4e2a std::locale \u5bf9\u8c61\u3002 #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%Y\u5e74 %m\u6708 %d\u65e5 %A %H\u65f6 %M\u5206\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e74 07\u6708 19\u65e5 \u661f\u671f\u4e94 16\u65f6 01\u5206 2024\u5e74 07\u6708 19\u65e5 Fri 16\u65f6 01\u5206 \u53ef\u4ee5\u770b\u5230\u8fd9\u91cc\u53ea\u6709\u661f\u671f\u7684\u5b57\u7b26\u4e32\u53d7\u5230\u4e86\u5f71\u54cd\u3002\u5982\u679c\u8981\u4f7f\u6574\u4e2a\u65e5\u671f\u683c\u5f0f\u90fd\u8ddf\u968f LC_TIME \u7684\u8bbe\u5b9a\uff0c\u53ef\u7528 \"%c\" \uff1a #include #include #include #include int main() { time_t t = time(NULL); tm *tm = localtime(&t); auto locale_zh = std::locale(\"zh_CN.UTF-8\"); std::cout.imbue(locale_zh); std::cout << std::put_time(tm, \"%c\") << '\\n'; auto locale_en = std::locale(\"en_US.UTF-8\"); std::cout.imbue(locale_en); std::cout << std::put_time(tm, \"%c\") << '\\n'; } \u8f93\u51fa\uff1a 2024\u5e7407\u670819\u65e5 \u661f\u671f\u4e94 16\u65f633\u520639\u79d2 Fri 19 Jul 2024 04:33:39 PM CST \u5173\u4e8e \"%c\" \u3001 \"%Y\" \u8fd9\u4e9b\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\u7684\u66f4\u591a\u8be6\u7ec6\u7528\u6cd5\uff0c\u53c2\u89c1 man strftime \u3002\u6211\u4eec\u4f5c\u4e3a\u5b57\u7b26\u7f16\u7801\u7684\u8bfe\u7a0b\u4e0d\u518d\u8d58\u8ff0\uff0c\u4e4b\u540e\u7684\u65f6\u95f4\u4e0e\u65e5\u671f\u4e13\u9898\u8bfe\u4e5f\u4f1a\u7a0d\u5fae\u8bb2\u4e00\u4e0b\u3002","title":"std::locale \u5bf9\u8c61"},{"location":"unicode/#boostlocalegenerator-locale","text":"boost::locale::generator gen; auto loc = gen(\"zh_CN.UTF-8\"); boost::locale::date_time dt = boost::locale::date_time::now(loc); std::cout << boost::locale::as::date(dt) << '\\n';","title":"boost::locale::generator \u51ed\u7a7a\u521b\u5efa\u4e00\u4e2a\u7528\u6237\u6ca1\u5b89\u88c5\u8fc7\u7684 locale"},{"location":"unicode/#_19","text":"\u4e4b\u6240\u4ee5\u628a\u5bbd\u5b57\u7b26\u6d41\u653e\u5230\u6700\u540e\uff0c\u662f\u56e0\u4e3a\uff0c\u9996\u5148 iostream \u672c\u6765\u5c31\u662f\u4e00\u4e2a\u5931\u8d25\u7684\u8bbe\u8ba1\u3002 \u5c0f\u5f6d\u8001\u5e08\u5728\u672c\u4e66\u5f00\u5934\u5c31\u591a\u6b21\u5f3a\u8c03\u8fc7\u4ed6\u662f format \u5b5d\u5b50\u3002 \u800c\u5bbd\u5b57\u7b26 wchar_t \u672c\u8eab\u5c31\u5145\u65a5\u7740\u5386\u53f2\u9057\u7559\u7cdf\u7c95\uff08\u4f8b\u5982 Windows \u88ab UTF-16 \u80cc\u523a\uff09\u3002 \u73b0\u5728 iostream \u4e0e wchar_t \u4e00\u8d77\u51fa\u73b0\u5728\u6211\u9762\u524d\uff0c\u4e0d\u80fd\u8bf4\u662f\u68a6\u5e7b\u8054\u52a8\u5427\uff0c\u81f3\u5c11\u4e5f\u53ef\u4ee5\u8bf4\u662f\u7b54\u8fa9\u8d85\u4eba\u4e86\u3002 \u603b\u4e4b\uff0c\u6211\u4e2a\u4eba\u8fd8\u662f\u63a8\u8350\u7a0b\u5e8f\u5185\u90e8\u4ee5 UTF-8\uff08 char8_t \uff09\u6216 UTF-32\uff08 char32_t \uff09\u7684\u5b57\u7b26\u4e32\u6765\u5904\u7406\u4e07\u7269\u3002 UTF-8 \u6216 UTF-32 \u7684\u9009\u62e9\u53d6\u51b3\u4e8e\u4f60\u7684\u4e2d\u6587\u5904\u7406\u9700\u6c42\u662f\u5426\u65fa\u76db\uff0c\u662f\u5426\u5728\u4e4e\u7a7a\u95f4\uff0c\u662f\u5426\u9700\u8981\u5207\u7247\u548c\u7d22\u5f15\u7b49\u3002 \u5f53\u9700\u8981\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf API \u8bfb\u5199\u6587\u4ef6\u65f6\uff0c\u518d\u7528 boost::locale \u3001 utfcpp \u7b49\u5de5\u5177\u8f6c\u6362\u6210 ANSI\uff08 char \uff09\u6216 UTF-16\uff08 wchar_t \uff09\u3002 \u5bf9\u4e8e Linux \u7528\u6237\uff0c\u4e5f\u53ef\u4ee5\u68c0\u6d4b\u5982\u679c\u662f Linux \u7cfb\u7edf\uff0c\u5219\u4ec0\u4e48\u8f6c\u6362\u90fd\u4e0d\u505a\uff0c\u56e0\u4e3a Linux \u7528\u6237\u51e0\u4e4e\u90fd\u662f UTF-8\uff0c\u90a3\u4e48 const char8_t * \u53ef\u4ee5\u5f3a\u8f6c\u4e3a const char * \u800c\u4e0d\u7528\u4efb\u4f55\u989d\u5916\u5f00\u9500\u3002 std::string to_os_string(std::string const &u8s) { #if _WIN32 // UTF-8 \u5230 ANSI return boost::locale::conv::from_utf(u8s, \"\"); #elif __linux__ // \u4e0d\u8f6c\u6362 return u8s; #else #error \"Unsupported system.\" #endif } \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u5b9e\u5728\u8981\u5b66\u7cdf\u7cd5\u7684\u5bbd\u5b57\u7b26\u6d41\uff0c\u90a3\u6211\u4e5f\u5949\u966a\u5230\u5e95\u3002","title":"\u5bbd\u5b57\u7b26\u6d41"},{"location":"unicode/#stdwstring","text":"\u5728\u4ed6\u4eec\u770b\u6765\uff0c std::string \u662f\u5df2\u7ecf\u5e9f\u5f03\u7684\u3002\u4ed6\u4eec\u8ba4\u4e3a std::wstring \u624d\u662f\u771f\u6b63\u8de8\u5e73\u53f0\u7684\u5b57\u7b26\u4e32\u3002 std::wstring : \u5b57\u7b26\u4e32 std::string : \u5b57\u8282\u6570\u7ec4 std::wifstream : \u6587\u672c\u6d41 std::ifstream : \u4e8c\u8fdb\u5236\u6d41 \u770b\u8d77\u6765\u53ea\u8981\u5168\u90e8\u7edf\u4e00 wchar_t \u5c31\u80fd\u5b9e\u73b0\u8de8\u5e73\u53f0\u4e86\uff1f\u662f\u7684\uff0c\u9664\u4e86 Windows\u2026\u2026 \u6807\u51c6\u8ba4\u4e3a wchar_t \u5e94\u8be5\u5305\u542b 0 \u5230 0x10FFFF \u7684\u6240\u6709\u7684 Unicode \u5b57\u7b26\u7801\u70b9\uff0c\u9700\u8981\u662f 32 \u4f4d\u7684\u3002\u7136\u800c Windows \u7684 wchar_t \u7531\u4e8e\u5386\u53f2\u539f\u56e0\uff0c\u662f 16 \u4f4d\u7684\uff0c\u9700\u8981\u7528\u4ee3\u7406\u5bf9\u624d\u80fd\u8868\u793a\u7a00\u6709\u5b57\u7b26\uff0c\u5e76\u4e0d\u80fd\u4e00\u4e2a wchar_t \u5bf9\u5e94\u4e00\u4e2a\u7801\u70b9\u3002\u8fd9\u5bfc\u81f4\u5373\u4f7f\u7528\u4e86 wchar_t \u8fd8\u662f\u5b58\u5728\u8de8\u5e73\u53f0\u56f0\u96be\u7684\u95ee\u9898\uff1a\u4e00\u4e2a Linux \u7a0b\u5e8f\u7528 wchar_t \u53ef\u80fd\u4f1a\u5229\u7528 UTF-32 \u5b9a\u957f\u7f16\u7801\u7684\u7279\u6027\uff0c\u65b9\u4fbf\u4e86\u6587\u672c\u5904\u7406\uff0c\u4f46\u79fb\u690d\u5230 Windows \u65f6\uff0c\u53d1\u73b0\u53d8\u6210\u4e86 UTF-16\uff0c\u9700\u8981\u5bf9\u4ee3\u7406\u5bf9\u505a\u7279\u6b8a\u5224\u65ad\u2026\u2026\u6ca1\u6709\u6ee1\u8db3\u8de8\u5e73\u53f0\u7684\u521d\u8877\uff0c\u4e5f\u505a\u4e0d\u5230\u5b9a\u957f\u7f16\u7801\u3002 char32_t \u505a\u5230\u4e86\u8de8\u5e73\u53f0\u7684 UTF-32\uff0c\u4e5f\u80fd\u5bb9\u7eb3\u5168\u90e8 Unicode \u7801\u70b9\uff0c\u53ef\u6807\u51c6\u5e93\u63d0\u4f9b\u4e86 std::to_wstring \uff0c\u5374\u6839\u672c\u6ca1\u6709 std::to_u32string \uff1b\u63d0\u4f9b\u4e86 std::wcout \uff0c\u5374\u6ca1\u6709\u63d0\u4f9b std::u32cout \u2026\u2026 \u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48\u5bbd\u5b57\u7b26\u6d41\u5f88\u7cdf\u7cd5\uff0c\u8bf4\u662f\u8de8\u5e73\u53f0\uff0c\u8de8\u4e86\u4e2a\u5bc2\u5bde\u3002","title":"\u5b98\u65b9\u773c\u4e2d\u7684 std::wstring"},{"location":"unicode/#stdwcout","text":"","title":"std::wcout \u7684\u4f7f\u7528\u5751\u70b9\u79d1\u666e"},{"location":"unicode/#stdwcout-locale","text":"\u8981\u4f7f\u7528 std::wcout \u4e4b\u524d\uff0c\u9700\u8981\u7528 .imbue \u8bbe\u7f6e\u5e26\u6709\u6b63\u786e LC_CTYPE \u65b9\u9762\u7684 locale\uff0c\u6216\u8005\u8bbe\u7f6e\u4e86 C \u8bed\u8a00\u7684\u5168\u5c40\u7684 setlocale \uff0c\u5426\u5219\u4e2d\u6587\u5b57\u7b26\u4f1a\u88ab\u4e22\u6389\u3002 int main() { std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u9519\u8bef\uff01\u4f60\u8fd8\u6ca1\u8bbe\u7f6e locale \u5462\uff01 return 0; } \u8f93\u51fa\uff1a Hello, ??! \u8fd9\u662f\u56e0\u4e3a\u9ed8\u8ba4\u7684\u5168\u5c40 locale \u662f \"C\" \uff0c\u4ed6\u53ea\u652f\u6301 ASCII \u7684\u3002\u800c\u5f53 std::wcout \u9047\u5230\u8d85\u51fa\u5f53\u524d locale \u5b57\u7b26\u96c6\u8868\u793a\u8303\u56f4\u7684\u5b57\u7b26\u65f6\uff0c\u4f1a\u4e22\u5f03\uff0c\u66ff\u6362\u4e3a ? \u5b57\u7b26\uff0c\u8868\u793a\u51fa\u9519\u4e86\u3002 \u56e0\u6b64\uff0c std::wcout \u7684\u6b63\u786e\u7528\u6cd5\u5fc5\u987b\u662f\u5728\u4f60\u6253\u5370\u7b2c\u4e00\u6761\u8f93\u51fa\u524d\uff0c\u5c31 setlocale(LC_ALL, \"\") \uff0c\u9ed8\u8ba4\u7684 \"C\" \u80af\u5b9a\u662f\u4e0d\u884c\u7684\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u8f93\u51fa\uff1a Hello, \u4f60\u597d! \u6216\u8005\u7528 std::wcout \u7684 .imbue \u4e5f\u53ef\u4ee5\uff0c\u4f46\u662f\u8fd9\u6837\u5bf9\u4e8e std::wcerr \u548c std::wclog \u4f60\u4e5f\u9700\u8981\u505a\u540c\u6837\u7684\u52a8\u4f5c\uff0c\u611f\u89c9\u4e0d\u5982\u7d22\u6027\u5168\u5c40\u8bbe\u7f6e\u4e86 setlocale \u65b9\u4fbf\u3002 int main() { std::wcout.imbue(std::locale(\"\")); std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // \u53ef\u4ee5\u6210\u529f\u8f93\u51fa\u4e2d\u6587\u4e86 return 0; } \u5982\u679c\u4f60\u662f UTF-8 \u6d41\u6d3e\uff0c\u9009\u62e9 setlocale(LC_ALL, \".utf-8\") \u4e5f\u662f\u53ef\u4ee5\u7684\uff0c\u53ea\u8981\u662f\u652f\u6301\u4e2d\u6587\u5b57\u7b26\u7684 locale \u5c31\u53ef\u4ee5\u8ba9 std::wcout \u80fd\u6b63\u5e38\u8f93\u51fa\u4e2d\u6587\uff0c\u53ea\u8981\u4f60\u7ec8\u7aef\u7684\u8bbe\u7f6e\u4e5f\u662f\u76f8\u540c\u7684\u7f16\u7801\u683c\u5f0f\u7edd\u5bf9\u4e0d\u4f1a\u4e71\u7801\u3002 \u4f8b\u5982\u5f53\u4f60 setlocale(LC_ALL, \".utf-8\") \u540e\u5c31\u9700\u8981 system(\"chcp 65001\") \uff1b\u5f53\u4f60 setlocale(LC_ALL, \"Chinese_China.936\") \u540e\u5c31\u9700\u8981 system(\"chcp 936\") \u3002\u603b\u4e4b\uff0c\u59cb\u7ec8\u4fdd\u8bc1\u7ec8\u7aef\uff08 cmd \u6216 xfce4-terminal \uff09\u8bbe\u7f6e\u7684\u7f16\u7801\u548c\u4f60\u7a0b\u5e8f\u91cc setlocale(LC_CTYPE, ...) \u8bbe\u7f6e\u7684\u7f16\u7801\u4e00\u81f4\u3002","title":"std::wcout \u5fc5\u987b\u8bbe\u4e86 locale \u624d\u80fd\u7528"},{"location":"unicode/#stdwcout-stdstring","text":"\u6709\u7684\u4eba\u4f1a\u7528 std::wcout \u4f3c\u4e4e\u4e5f\u80fd\u6253\u5370 char \u7684\u5b57\u7b26\u4e32\uff1f int main() { setlocale(LC_ALL, \"\"); std::wcout << \"Hello, \u4f60\u597d!\\n\"; // \u4e0d\u4e00\u5b9a\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587\uff01 std::wcout << L\"Hello, \u4f60\u597d!\\n\"; // OK\uff0c\u80fd\u7a33\u5b9a\u6253\u5370\u51fa\u4e2d\u6587 return 0; } \u8fd9\u662f\u4e00\u79cd\u9519\u8bef\u7684\u7528\u6cd5\uff0c\u7406\u60f3\u60c5\u51b5\u4e0b\u5e94\u8be5\u8981\u62a5\u9519\uff0c\u4f46\u662f\u7cdf\u7cd5\u7684\u6807\u51c6\u5e93\u5374\u6ca1\u6709\uff0c\u8bbe\u8ba1\u7684\u5931\u8bef\u3002 \u8bbe\u8ba1\u7684\u521d\u8877\u662f\uff0c\u53ef\u4ee5\u5728\u6253\u5370\u5e26\u4e2d\u6587\u7684\u5b57\u7b26\u4e32\u540e\uff0c\u65b9\u4fbf\u4f60\u4e34\u65f6\u6253\u5370\u4e00\u4e9b char \u7684\u5b57\u7b26\u4e32\u548c\u5b57\u7b26\uff0c\u4f8b\u5982 '\\n' \uff08\u56e0\u4e3a\u603b\u662f\u6709\u7684\u4eba\u60f3\u5077\u61d2\u4e0d\u5199 L\"\" \u524d\u7f00\uff09 std::wcout \u652f\u6301\u6253\u5370 char \u548c const char * \uff0c\u4ed6\u4f1a\u81ea\u52a8\u5e2e\u4f60\u628a\u8fd9\u90e8\u5206 char \u8f6c\u6210 wchar_t \u518d\u6253\u5370\u3002 int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"Hello, \u4f60\u597d!\" << L'\\n'; // \u6b63\u5e38\u5199\u6cd5 std::wcout << L\"Hello, \u4f60\u597d!\" << '\\n'; // \u61d2\u60f0\u72d7\u72d7\u5199\u6cd5 return 0; } \u4f46\u662f\uff0c\u8fd9\u90e8\u5206 char \u5e94\u5f53\u53ea\u5305\u542b ASCII \u5b57\u7b26\uff0c\u4e0d\u5e94\u8be5\u6709\u4e2d\u6587\u5b57\u7b26\uff0c\u5426\u5219\u53ef\u80fd\u53c8\u8981\u51fa\u73b0\u4e4b\u524d\u63d0\u5230\u7684 \u201cgalgame\u201d \u4e71\u7801\u95ee\u9898\u4e86\u3002","title":"std::wcout \u4e0d\u5e94\u7528\u4e8e\u6253\u5370 std::string"},{"location":"unicode/#stdwcout-stdcout","text":"\u975e\u5e38\u5751\u7684\u4e00\u4e2a\u70b9\uff1a\u4e00\u65e6\u4f60\u51b3\u5b9a\u7528 std::wcout \u540e\uff0c\u5c31\u4e0d\u80fd\u518d\u7528 std::cout \u4e86\uff01 \u5c0f\u5f6d\u8001\u5e08\u5b9e\u6d4b\u7528\u8fc7 std::wcout \u540e\uff0c\u4f60\u7684 std::cout \u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4e0d\u51fa\u4efb\u4f55\u4e1c\u897f\u3002 \u4e0a\u4e86\u8d3c\u8239\u5c31\u4e0a\u5230\u5e95\u5427\uff01\u5982\u679c\u786e\u5b9e\u9700\u8981\u4e34\u65f6\u6253\u5370\u4e00\u4e9b std::string \uff0c\u5e76\u4e14\u786e\u4fdd\u91cc\u9762\u662f ASCII \u7684\u8bdd\uff0c\u53ef\u4ee5\u5229\u7528\u4e0a\u9762\u4e00\u8282\u8bf4\u7684\u201c\u61d2\u60f0\u72d7\u72d7\u5199\u6cd5\u201d\u7cca\u5f04\u4e0b\uff0c\u5982\u679c\u662f GBK \u6216 UTF-8 \u7684 std::string \u9700\u8981\u6253\u5370\u5230 std::wcout \uff0c\u5c31\u53ec\u5524\u4e00\u4e0b boost::locale \u5427\u3002 std::wprintf \u4e5f\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u5f53\u4f60\u7b2c\u4e00\u6b21\u4f7f\u7528 FILE * \u7684 wchar_t \u7cfb\u5217\u51fd\u6570\u540e\uff0c\u8fd9\u4e2a\u6587\u4ef6\u6d41\u4f1a\u88ab\u201c\u5bbd\u5316\u201d ( fwiden )\uff0c\u7528\u6211\u4eec\u7684\u8bdd\u8bf4\u53eb \u4e0a\u8d3c\u8239 \uff0c\u4e0a\u4e86\u5c31\u4e0b\u4e0d\u6765\uff0c\u518d\u4e5f\u65e0\u6cd5\u5f53\u4f5c\u201c\u7a84\u201d\u6d41\u7528\u4e86\u3002 \u53cd\u4e4b\u4ea6\u7136\uff0c\u4e00\u65e6\u4f60\u7528\u8fc7\u4e00\u6b21 std::cout \u540e\uff0c std::wcout \u5c31\u4f1a\u5e9f\u6389\uff0c\u6253\u5370\u4efb\u4f55\u4e1c\u897f\u90fd\u6253\u5370\u4e0d\u51fa\u6765\u3002\u53d6\u51b3\u4e8e\u4f60\u7b2c\u4e00\u6b21\u8c03\u7528\u8f93\u51fa\u6d41\u7528\u7684\u662f\u5bbd\u5b57\u7b26\u8fd8\u662f\u7a84\u5b57\u7b26\uff0c\u4e4b\u540e\u5c31\u53ea\u80fd\u4e00\u76f4\u7528\u90a3\u4e2a\u5bbd\u6216\u7a84\u4e86\uff0c\u4e0d\u8ba9\u8df3\u8239\u3002 \u4e0a\u8d3c\u8239\u4e0d\u884c\uff0c\u4e0a\u8b66\u8239\u4e5f\u4e0d\u884c\uff0c\u4e0a\u5b9a\u4e00\u4e2a\u5c31\u6ca1\u6cd5\u53d8\uff0c\u771f\u6076\u5fc3\u5440\uff01 // \u5148 wcout int main() { setlocale(LC_ALL, \"\"); std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; std::cout << \"\u6211\u662f cout!\" << '\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f wcout! // \u5148 cout int main() { setlocale(LC_ALL, \"\"); std::cout << \"\u6211\u662f cout!\" << '\\n'; std::wcout << L\"\u6211\u662f wcout!\" << L'\\n'; return 0; } \u8f93\u51fa\uff1a \u6211\u662f cout! / wcout! \u8fd9\u91cc / wcout! \u597d\u50cf\u662f\u51fa BUG \u4e86\u2026\u2026\u4f30\u8ba1\u662f\u8d3c\u88ab\u8b66\u5bdf\u6253\u6389\u4e00\u534a\u8033\u6735\u53d8\u6210 / \u4e86\uff1f\u603b\u4e4b\u5404\u79cd\u6df7\u4e71\uff0c\u8bb0\u4f4f\u4e0d\u8981\u6df7\u7528\u8d3c\u8239\u548c\u8b66\u8239\u5c31\u884c\u4e86\u3002","title":"\u8d85\u7ea7\u5751\u70b9\uff1astd::wcout \u548c std::cout \u53ea\u80fd\u7528\u4e00\u4e2a\uff01"},{"location":"unicode/#stdwfstream","text":"\u6709\u540c\u5b66\u53cd\u6620\uff0cPython \u4e2d\u53ef\u4ee5\u901a\u8fc7 open('path.txt', encoding='gbk') \u6765\u7528\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u800c C++ \u4f3c\u4e4e\u6ca1\u6709\u7b49\u6548\u7684\u66ff\u4ee3\u54c1\u3002 \u5176\u5b9e\u4e00\u76f4\u90fd\u6709\uff0c\u4e0d\u8fc7\u4f60\u4e00\u76f4\u7528\u7684\u662f std::ifstream \u5b9e\u9645\u4e0a\u662f\u4e2a\u201c\u4e8c\u8fdb\u5236\u6d41\u201d\uff01\u8fd9\u79cd\u7eaf\u4e8c\u8fdb\u5236\u7684\u6d41\u6839\u672c\u5c31\u6ca1\u6253\u7b97\u652f\u6301\u5b57\u7b26\u7f16\u7801\u3002\u5373\u4f7f\u6307\u5b9a .imbue \u4e5f\u6ca1\u6709\u4efb\u4f55\u6548\u679c\uff0c\u56e0\u4e3a .imbue \u7684\u524d\u63d0\u662f\u5b58\u5728\u201c\u5916\u7801 ( char ) \u5230\u5185\u7801 ( wchar_t ) \u7684\u8f6c\u6362\u201d\uff0c\u4f60\u4e8c\u8fdb\u5236\u6d41\u81f3\u59cb\u81f3\u7ec8\u90fd\u662f\u5916\u7801\uff0c\u54ea\u6765\u7684\u8f6c\u6362\uff1f\u53c8\u6ca1\u6709\u89c4\u5b9a char \u5fc5\u987b\u662f UTF-8\u3002 C++ \u771f\u6b63\u7684\u6587\u672c\u6d41\u5b9e\u9645\u4e0a\u662f\u5bbd\u5b57\u7b26\u6d41 std::wifstream \uff0c\u800c\u6307\u5b9a\u7f16\u7801\u683c\u5f0f\uff0c\u5b9e\u9645\u4e0a\u5c31\u662f\u7528 .imbue(std::locale(\"zh_CN.GBK\")) \u2026\u2026\u8bfb\u53d6\u65f6\u4f1a\u8c03\u7528 std::locale \u7c7b\u7684 std::codecvt \uff08\u662f LC_CTYPE \u7684\u4e00\u90e8\u5206\uff09\u65b9\u9762\uff0c\u8f6c\u6362\u4e3a wchar_t \uff0c\u7136\u540e\u8f93\u5165\u4f60\u7684 std::wstring \u3002 C \u548c C++ \u59d4\u5458\u4f1a\u5b98\u65b9\u5c31\u8ba4\u4e3a char * \u662f\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c wchar_t * \u624d\u662f\u6587\u672c\u6d41\uff01\u6240\u6709 GNU/Linux \u7684\u547d\u4ee4\u884c\u7a0b\u5e8f\u91cc\u90fd\u662f\u7528 wchar_t \u6765\u5904\u7406\u6587\u672c\u6027\u8d28\u7684\u5b57\u7b26\u4e32\uff0c\u5305\u62ec GCC \u4e5f\u662f\u5927\u91cf\u4f7f\u7528 wchar_t \u4f5c\u4e3a\u5b57\u7b26\u5185\u90e8\u8868\u793a\u3002GCC \u8bfb\u53d6\u6e90\u7801\u6587\u4ef6\u5c31\u662f\u7528\u5bbd\u5b57\u7b26\u6d41\u8bfb\u53d6\u548c\u89e3\u7801\u5230\u5185\u5b58\u4e2d\u7684 UTF-32 \u5b57\u7b26\u4e32 std::wstring \u7684\u3002 \u7406\u8bba\u4e0a\u6240\u6709\u7684\u7a0b\u5e8f\u90fd\u5e94\u8be5\u50cf\u8fd9\u6837\uff0c\u53ea\u4e0d\u8fc7\u662f\u56e0\u4e3a\u52b3\u4fdd\u6559\u6750\u4ece\u6765\u4e0d\u63d0\uff0c\u4e00\u53e3\u4e00\u4e2a char [] \u5c31\u662f\u5b57\u7b26\u4e32\uff0c\u641e\u5f97 wchar_t \u5728\u9664\u4e86 GNU \u8fd9\u79cd\u201c\u4f53\u5236\u5185\u201d\u73af\u5883\u4e4b\u5916\uff0c\u6839\u672c\u6ca1\u4eba\u7528\u4e86\u3002\u73b0\u5728\u4e3a\u4e86\u5904\u7406\u4e2d\u6587\u5b57\u7b26\uff0c\u624d\u95f9\u51fa\u4e86 char \u5f53 UTF-8 \u4f7f\u8fd9\u79cd\u62db\u6570\uff0c\u4ee4\u4eba\u550f\u5618\u3002 \u603b\u4e4b\uff0c .imbue(std::locale(\"zh_CN.GBK\")) \u53ef\u4ee5\u628a GBK \u8bbe\u4e3a\u5f53\u524d\u6587\u672c\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f\uff0c\u5bbd\u6587\u4ef6\u6d41\u5c06\u4f1a\u6309\u7167\u8fd9\u4e2a\u7f16\u7801\u548c\u89e3\u7801\u6240\u6709\u7684\u5b57\u7b26\u4e32\u3002 std::locale \u7684\u5b57\u7b26\u4e32\u6784\u9020\u51fd\u6570\uff0c\u4ed6\u7684\u53c2\u6570\u5fc5\u987b\u662f\u7528\u6237\u7cfb\u7edf\u91cc\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684 locale\uff08\u901a\u8fc7\u4fee\u6539 /etc/locale.gen \u548c locale-gen \u547d\u4ee4\u5b89\u88c5\uff09\u3002\u4f46\u662f\uff0c\u4f60\u65e0\u6cd5\u786e\u4fdd\u7528\u6237\u7684\u7cfb\u7edf\u5b89\u88c5\u4e86 \"GBK\" locale\u3002 std::locale(\"zh_CN.GBK\") \u5728\u6ca1\u6709\u5b89\u88c5 GBK \u7684\u7528\u6237\u7535\u8111\u4e0a\u8fd0\u884c\u5c31\u4f1a\u629b\u51fa\u9519\u8bef\u8868\u793a\u627e\u4e0d\u5230\u8be5 locale\u3002\u56e0\u6b64\uff0c\u5982\u679c\u8981\u6307\u5b9a\u6309 GBK \u8bfb\u53d6\u6587\u4ef6\uff0c\u4e0d\u5efa\u8bae\u4f9d\u8d56\u7cfb\u7edf\u4e2d\u81ea\u5e26\u7684 std::locale(\"zh_CN.GBK\")) \uff0c\u800c\u662f\u8c03\u7528 boost::locale::generator \u5c31\u5730\u751f\u6210\u4e00\u4e2a locale\uff0c\u8fd9\u6837\u7a0b\u5e8f\u65e0\u8bba\u7cfb\u7edf\u6709\u6ca1\u6709\u5b89\u88c5\u90fd\u80fd\u8fd0\u884c\u4e86\uff1a #include #include int main() { std::wofstream fout; boost::locale::generator gen; std::locale loc = gen(\"zh_CN.GBK\"); fout.imbue(loc); fout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4ee5 GBK \u7f16\u7801\u5199\u51fa\u6587\u672c\u6587\u4ef6 } $ cat build/\u4f60\u597d.txt \ufffd\ufffd\u00e3\ufffd\ufffd\ufffd $ cat build/\u4f60\u597d.txt | iconv -f GBK -t UTF-8 \u4f60\u597d\uff0c\u4e16\u754c $ \u8fd9\u662f\u56e0\u4e3a boost_locale \u94fe\u63a5\u4e86 icu \uff0c\u5176\u5185\u90e8\u5305\u542b\u4e86\u6240\u6709\u7f16\u7801\u683c\u5f0f\u7684\u5b57\u7b26\u6620\u5c04\u8868\u3002 boost::locale::generator \u9996\u5148\u521b\u5efa\u4e86\u4e00\u4e2a std::locale \uff0c\u7136\u540e\u901a\u8fc7\u865a\u51fd\u6570\u91cd\u8f7d\u7684\u65b9\u5f0f\u628a std::locale \u5bf9\u8c61\u4e2d\u7684 std::codecvt \u66ff\u6362\u6210 icu \u7684\u6620\u5c04\u8868\u3002\u4ece\u800c\u8ba9 std::wofstream \u8c03\u7528\u8fd9\u4e2a icu \u7684\u6620\u5c04\u51fd\u6570\uff0c\u5b9e\u73b0\u4e86 UTF-32 \u5230 GBK \u7684\u8f6c\u6362\u3002 \u6b64\u5916\uff0c\u4f60\u8fd8\u53ef\u4ee5\u9009\u62e9\u8986\u76d6 locale \u7684\u90e8\u5206\u65b9\u9762 (facet)\uff0c\u6bd4\u5982\u5728\u6587\u4ef6\u7f16\u7801\u65f6\uff0c\u6211\u4eec\u53ea\u9700\u8981\u7528 \"zh_CN.GBK\" \u7684 LC_CTYPE \u65b9\u9762\u5c31\u53ef\u4ee5\u4e86\uff0c\u5176\u4ed6\u7684\u4f8b\u5982\u65f6\u95f4\u683c\u5f0f\u3001\u8bed\u8a00\u4fe1\u606f\u7b49\uff0c\u6211\u4eec\u8fd8\u662f\u60f3\u4fdd\u7559\u9ed8\u8ba4\u7684\u3002\u4e3a\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u5229\u7528 locale \u7684\u201c\u6742\u4ea4\u201d\u62f7\u8d1d\u6784\u9020\u51fd\u6570\uff0c\u4fdd\u7559\u8001 locale \u7684\u7edd\u5927\u90e8\u5206\u65b9\u9762\uff0c\u53ea\u66ff\u6362\u4e00\u4e2a\u65b9\u9762\u4e3a\u65b0 locale \u7684\uff1a std::locale old_loc = std::locale(\"\"); // \u73af\u5883 locale boost::locale::generator gen; std::locale new_loc = gen(\"zh_CN.GBK\"); // \u5168 GBK locale std::locale loc = std::locale(old_loc, new_loc, std::locale::ctype); // \u6742\u4ea4\uff1a\u7ee7\u627f old_loc \u7684\u5176\u4f59\u5168\u90e8\uff0c\u53ea\u66ff\u6362\u6389 LC_CTYPE \u90e8\u5206\u4e3a new_loc \u7684 fout.imbue(loc);","title":"std::wfstream \u8bfb\u53d6\u4efb\u610f\u7f16\u7801\u7684\u6587\u672c\u6587\u4ef6"},{"location":"unicode/#locale_4","text":"// \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5185\u7801\u7f16\u7801\u6210\u5916\u7801 std::string narrow(std::locale const &loc, std::wstring const &wstr) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::string str(wstr.size() * 4, '\\0'); // \u9884\u7559 4 \u500d\u7a7a\u95f4 wchar_t const *from_next; char *to_next; std::mbstate_t state{}; auto res = cvt.in(state, wstr.data(), wstr.data() + wstr.size(), from_next, str.data(), str.data() + str.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f str.resize(to_next - str.data()); return str; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f str.resize(to_next - str.data()); return str; } else { // \u8f6c\u6362\u5931\u8d25 return \"\"; } } // \u4ee5 loc \u89c4\u5b9a\u7684\u7f16\u7801\uff0c\u628a\u5916\u7801\u89e3\u7801\u6210\u5185\u7801 std::wstring widen(std::locale const &loc, std::string const &str) { // use_facet \u51fd\u6570\u83b7\u5f97 locale \u5728\u5b57\u7b26\u8f6c\u6362 \u65b9\u9762\u7684 facet auto const &cvt = std::use_facet(loc); std::wstring wstr(str.size(), L'\\0'); // \u9884\u7559\u7a7a\u95f4 char const *from_next; wchar_t *to_next; std::mbstate_t state{}; auto res = cvt.out(state, str.data(), str.data() + str.size(), from_next, wstr.data(), wstr.data() + wstr.size(), to_next); if (res == Codecvt::ok) { // \u8f6c\u6362\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else if (res == Codecvt::partial) { // \u8f6c\u6362\u90e8\u5206\u6210\u529f wstr.resize(to_next - wstr.data()); return wstr; } else { // \u8f6c\u6362\u5931\u8d25 return L\"\"; } } std::wstring wstr = L\"\u4f60\u597d\"; std::cout << narrow(std::locale(\"zh_CN.GBK\"), wstr); \u4e0d\u8fc7\uff0c\u6211\u4eec\u90fd\u6709\u66f4\u65b9\u4fbf\u7684 boost::locale::conv \u4e86\uff0c\u8fd8\u4f55\u5fc5\u8fd8\u7528\u8fd9\u4e48\u7e41\u7410\u7684 std::locale \u5462\uff1f\u6240\u4ee5\u6211\u662f\u4e0d\u63a8\u8350\u518d\u7528\u8fd9\u7834\u73a9\u610f\uff0c\u65e0\u8bba\u662f\u6613\u7528\u6027\u8fd8\u662f\u6269\u5c55\u6027\u90fd\u662f Boost \u5b8c\u80dc\u3002","title":"locale \u7528\u4e8e\u5b57\u7b26\u7f16\u7801\u8f6c\u6362"},{"location":"unicode/#c-wchar_t","text":"\u5bf9\u4e8e\u6240\u6709\u7684 strcpy \u3001 strcmp \u3001 strlen \u8fd9\u7c7b str*** \u7cfb\u51fd\u6570\uff0c\u90fd\u6709\u4e00\u4e2a\u76f8\u5e94\u7684 wcs*** \u51fd\u6570\u3002 \u4f8b\u5982 wcscpy \u3001 wcscmp \u3001 wcslen \u3002 \u5b83\u4eec\u7684\u539f\u578b\u5982\u4e0b\uff1a wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); int wcscmp(const wchar_t *s1, const wchar_t *s2); size_t wcslen(const wchar_t *s); \u5b83\u4eec\u7684\u4f5c\u7528\u548c str*** \u7cfb\u51fd\u6570\u4e00\u6837\uff0c\u4f46\u662f\u5b83\u4eec\u64cd\u4f5c\u7684\u662f wchar_t \u5b57\u7b26\u4e32\u3002 \u5bf9\u4e8e\u6240\u6709\u7684 fputc \u3001 printf \uff0c fprintf \uff0c fgets \u8fd9\u7c7b\u64cd\u4f5c\u6587\u4ef6\u7684\u51fd\u6570\uff0c\u4e5f\u90fd\u6709\u4e00\u4e2a\u914d\u5957\u7684 fw*** \u51fd\u6570\u3002 \u7b2c\u4e00\u6b21\u4f7f\u7528\u8fc7\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c FILE * \u5c06\u4f1a\u88ab\u201c\u5bbd\u5316\u201d\uff08 fwiden \uff09\u3002\u5bbd\u5316\u7684\u6587\u4ef6\u6d41\u4eca\u540e\u5c06\u53ea\u80fd\u8f93\u5165\u5bbd\u5b57\u7b26\u4e32\u3002 \u4f46\u662f\uff0c\u65e2\u7136 C++ \u5df2\u7ecf\u6709 std::wstring \uff0c\u5c31\u4e0d\u5efa\u8bae\u518d\u5b66 C \u8bed\u8a00 L'\\0' \u7ed3\u5c3e\u5b57\u7b26\u4e32\u4e86\u3002","title":"C \u8bed\u8a00\u4e2d\u7684 wchar_t \u7cfb\u5217\u51fd\u6570"},{"location":"unicode/#c","text":"TODO","title":"C \u8bed\u8a00\u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362"},{"location":"unicode/#c-codecvt","text":"wchar_t \u3001 char16_t \u3001 char32_t \u4e0e char \u4e4b\u95f4\u7684\u8f6c\u6362\uff0c\u53ef\u4ee5\u7528 std::mbrtoc16 \u3001 std::mbrtoc32 \u3001 std::c16rtomb \u3001 std::c32rtomb \u51fd\u6570\u3002 \u7136\u800c\uff0c\u53c8\u81ed\u53c8\u957f\uff0c\u7528\u5c01\u88c5\u597d\u7684 boost::locale::utf_to_utf/from_utf/to_utf/between \u4e0d\u9999\u5417\uff1f","title":"C++ \u6807\u51c6\u5e93\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362 <codecvt>"},{"location":"unicode/#windows","text":"\u9047\u5230\u5b57\u7b26\u7f16\u7801\u96be\u9898\u7684\uff0c\u4e3b\u8981\u662f Windows \u7a0b\u5e8f\u5458\u3002","title":"Windows \u4e13\u9898"},{"location":"unicode/#windows-api-w","text":"\u4ece Windows NT \u7248\u672c\u5f00\u59cb\uff0c\u5bf9\u4e8e\u6240\u6709\u6d89\u53ca\u5b57\u7b26\u4e32\u7684\uff0c\u5176\u64cd\u4f5c\u7cfb\u7edf API \u63d0\u4f9b\u4e86\u4e24\u5957\u51fd\u6570\u3002 \u4e00\u5957\u662f A \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 A \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileA \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 ANSI\uff08\u5373 GBK\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u53e6\u4e00\u5957\u662f W \u7cfb\u5217\u51fd\u6570\uff0c\u4ee5 W \u7ed3\u5c3e\uff0c\u4f8b\u5982 CreateFileW \uff0c\u8fd9\u4e9b\u51fd\u6570\u63a5\u6536 Unicode\uff08\u5373 UTF-16\uff09\u7f16\u7801\u7684\u5b57\u7b26\u4e32\u3002 \u5176\u4e2d CreateFileW \u624d\u662f Windows \u7cfb\u7edf\u771f\u6b63\u7684 API\u3002 \u800c CreateFileA \u662f\u4e3a\u4e86\u517c\u5bb9\u57fa\u4e8e ANSI \u7684\u8001\u7a0b\u5e8f. \u7531\u4e8e ANSI \u5728\u4e0d\u540c\u5730\u533a\u4f1a\u53d8\u5f97\u4e0d\u540c\uff0c\u4f7f\u7528\u8fd9\u7c7b\u51fd\u6570\u5199\u51fa\u7684\u7a0b\u5e8f\u4e0d\u5177\u6709\u56fd\u9645\u901a\u7528\u6027\u3002 \u5176\u5185\u90e8\u7684\u5b9e\u73b0\u53ea\u662f\u7b80\u7b80\u5355\u5355\u5730\u7ed9 const char * \u505a\u4e2a\u8f6c\u6362\uff0c\u4ece GBK \u8f6c\u5230 UTF-16\uff0c\u7136\u540e\u76f4\u63a5\u8c03\u7528 CreateFileW\u3002 HANDLE CreateFileA(const char *lpFileName) { return CreateFileW(gbk_to_utf16(lpFileName)); }","title":"Windows API \u7684\u672c\u6e90\u662f W \u7cfb\u51fd\u6570"},{"location":"unicode/#tchar","text":"\u9664\u4e86\u53c8\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5b8f\uff0c\u8fd9\u4e2a\u5b8f\u6ca1\u6709\u4efb\u4f55\u540e\u7f00\uff0c\u4f8b\u5982 CreateFile \u3002 \u5176\u5b9a\u4e49\u5982\u4e0b\uff1a #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif \u8fd9\u6837\u505a\u7684\u521d\u8877\u662f\uff0c\u7a0b\u5e8f\u5458\u53ea\u53ef\u4ee5\u5199\u51fa\u4e00\u5957\u9488\u5bf9 MessageBox \u7684\u4ee3\u7801\u3002 \u5f53\u8001\u677f\u60f3\u8981\u57fa\u4e8e Unicode \u65f6\uff0c\u4ed6\u5c31 #define UNICODE \uff0c\u8fd9\u6837 MessageBox \u5c31\u53d8\u6210\u4e86 MessageBoxW \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u5c31\u4f1a\u81ea\u52a8\u53d8\u6210 Unicode \u7684\uff0c\u56fd\u9645\u901a\u7528\u3002 \u5f53\u52b3\u4fdd\u8001\u677f\u60f3\u8981\u57fa\u4e8e ANSI \u65f6\uff0c\u4ed6\u5c31\u4e0d\u5b9a\u4e49 UNICODE \u5b8f\uff0c\u8fd9\u6837\u6240\u6709\u7684 MessageBox \u53c8\u53d8\u56de\u4e86 MessageBoxA \uff0c\u7a0b\u5e8f\u5458\u7684\u4ee3\u7801\u53c8\u53d8\u6210 ANSI \u7684\u4e86\u3002 \u6240\u6709\u6709 A/W \u533a\u5206\u7684\u7684 Windows API \u90fd\u6709\u8fd9\u6837\u4e00\u4e2a\u5b8f\uff0c\u6839\u636e UNICODE \u5b8f\u662f\u5426\u5b9a\u4e49\uff0c\u51b3\u5b9a\u91c7\u53d6\u54ea\u5957 API\u3002 \u6211\u4eec\u4f1f\u5927\u7684 Linux \u7cfb\u7edf\u5c31\u6ca1\u6709\u8fd9\u4e2a\u82e6\u607c\uff0c\u65e9\u5c31\u7edf\u4e00 UTF-8 \u4e86\u3002 \u9664\u6b64\u4e4b\u5916\uff0c \u4e2d\u8fd8\u5b9a\u4e49\u4e86 TEXT \u8fd9\u4e2a\u5b8f\u51fd\u6570\u3002 #ifdef UNICODE #define TEXT(s) L##s #else #define TEXT(s) s #endif \u7528\u6cd5\uff1a\u8981\u6c42\u7a0b\u5e8f\u5458\u628a\u6240\u6709\u7684\u5b57\u7b26\u4e32\u5e38\u91cf\uff0c\u90fd\u7528 TEXT \u5b8f\u5305\u88f9\u3002 Qt \u4e5f\u6709\u7c7b\u4f3c\u7684\u5b8f\u5305\u88f9\u5b57\u7b26\u4e32\u5e38\u91cf\u7684\u505a\u6cd5\uff0c tr \uff0c\u4f46\u5b83\u5e76\u4e0d\u662f\u4e3a\u4e86\u89e3\u51b3\u7f16\u7801\u95ee\u9898\uff0c\u800c\u662f\u4e3a\u4e86\u89e3\u51b3\u591a\u8bed\u8a00\u7ffb\u8bd1\u95ee\u9898\uff0c\u7a0d\u540e\u4f1a\u4e13\u95e8\u4ecb\u7ecd\u4e00\u4e0b Qt \u4e2d\u7684\u5b57\u7b26\u4e32\u3002 \u5f53 UNICODE \u5b8f\u5b9a\u4e49\u65f6\uff0c TEXT \u4f1a\u81ea\u52a8\u4e3a\u5b57\u7b26\u4e32\u5e38\u91cf\u6dfb\u52a0 L \u524d\u7f00\uff0c\u4f7f\u5f97\u5b57\u7b26\u4e32\u53d8\u6210 Unicode \u7684\u3002\u5982\u679c\u6ca1\u6709\u5b9a\u4e49\uff0c\u5219\u53c8\u53d8\u56de ANSI \u7f16\u7801\u7684\u5b57\u7b26\u4e32\uff08\u8ddf\u968f\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\u7684\u8bbe\u5b9a\uff09\u3002 \u4f8b\u5982\u4e0b\u9762\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff1a #include int main() { MessageBox(NULL, TEXT(\"\u4f60\u597d\uff0c\u4e16\u754c\"), TEXT(\"\u6807\u9898\"), MB_OK); } \u5f53\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxW(NULL, L\"\u4f60\u597d\uff0c\u4e16\u754c\", L\"\u6807\u9898\", MB_OK); } \u5f53\u6ca1\u6709\u5b9a\u4e49 UNICODE \u65f6\uff0c\u7b49\u4ef7\u4e8e\uff1a #include int main() { MessageBoxA(NULL, \"\u4f60\u597d\uff0c\u4e16\u754c\", \"\u6807\u9898\", MB_OK); } \u6b64\u5916\uff0c\u8fd8\u5b9a\u4e49\u4e86 TCHAR \u8fd9\u4e2a\u7c7b\u578b\u522b\u540d\uff0c\u540c\u6837\u662f\u9488\u5bf9\u662f\u5426\u5b9a\u4e49 UNICODE \u5b8f\u800c\u5b9a\u4e49\u4e86\u4e24\u5957\u7248\u672c\u3002 #ifdef UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif \u8fd8\u4e3a printf \u548c wprintf \u5b9a\u4e49\u4e86 TCHAR \u7248\u672c\uff0c\u4e0d\u4ec5\u5982\u6b64\uff0c\u8fd8\u6709 strlen \u548c wcslen \uff0c strcpy \u548c wcscpy \uff0c\u7b49\u7b49\u3002 #ifdef UNICODE #define _tprintf wprintf #define _tcscpy wcscpy #define _tcslen wcslen #else #define _tprintf printf #define _tcscpy strcpy #define _tcslen strlen #endif \u4e0d\u89c9\u5f97\u8fd9\u5f88\u9177\u5417\uff1f\u5f88\u7b26\u5408\u6211\u5bf9\u5f3a\u8feb\u75c7\u7684\u60f3\u8c61\uff0c\u79d1\u6280\u5e76\u4e14\u5e26\u7740\u81ed\u5473\u3002 int main() { TCHAR str[] = TEXT(\"\u6bd4\u5c14\u76d6\u5b50\u6211\u6d4b\u8bd5\u4f60\u7684\u7801\"); } (* \u54e6\uff0c\u6211\u662f\u8bf4\uff0c\u6211\u8981\u6d4b\u8bd5\u4f60\u7684\u7f16\u7801\u683c\u5f0f *) \u9700\u8981\u5207\u6362\u65f6\uff0c\u5728 MSVC \u4e2d\uff0c\u6253\u5f00\u6216\u5173\u95ed /DUNICODE \u7f16\u8bd1\u9009\u9879\u5373\u53ef\u3002 \u4e0d\u8981\u89c9\u5f97\u8fd9\u662f\u4ec0\u4e48\u597d\u4e3b\u610f\uff0c\u8fd9\u6837\u505a\u7684\u540e\u679c\u662f\uff0c\u4f60\u5199\u51fa\u7684\u4ee3\u7801\u53ea\u80fd\u5728 Windows \u4e0b\u7f16\u8bd1\u3002 \u5199\u8d77\u6765\u7d2f\u6b7b\u4eba\uff0c\u5b9e\u9645\u54ea\u6709\u90a3\u4e48\u591a\u4e00\u76f4\u5728 ANSI \u548c Unicode \u4e4b\u95f4\u6765\u56de\u5207\u6362\u7684\u9700\u6c42\uff1f \u6211\u7684\u5efa\u8bae\u662f\uff0c\u7edf\u4e00 wchar_t \uff0c\u7edf\u4e00\u5168\u7528 W \u51fd\u6570\uff0c\u618b\u62a0\u62a0\u7d22\u7d22\u7684\u534a\u8fdb\u534a\u9000\u3002","title":"TCHAR \u6d41\u6d3e"},{"location":"unicode/#utf-8_4","text":"\u4e4b\u524d\u8bf4\u8fc7\u4e86\uff0cWindows \u5e73\u53f0\u5230\u5904\u90fd\u9ed8\u8ba4 GBK \u975e\u5e38\u9ebb\u70e6\uff0c\u8981\u5207\u6362\u5230 UTF-8 \u5de5\u4f5c\u6d41\uff1a \u7f16\u8bd1\u5668\u5f00\u542f /utf-8 \u9009\u9879 \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c system(\"chcp 65001\") \u8bbe\u7f6e\u6587\u4ef6\u7cfb\u7edf\u5b57\u7b26\u4e32\u7f16\u7801\uff0c setlocale(LC_ALL, \".utf-8\") // \u7f16\u8bd1\u9009\u9879\uff1a/std:c++17 /utf-8 int main() { #if _WIN32 // \u70ed\u77e5\u8bc6\uff1a64 \u4f4d Windows \u4e5f\u4f1a\u5b9a\u4e49 _WIN32 \u5b8f\uff0c\u6240\u4ee5 _WIN32 \u53ef\u4ee5\u7528\u4e8e\u68c0\u6d4b\u662f\u5426\u662f Windows \u7cfb\u7edf setlocale(LC_ALL, \".utf-8\"); // \u8bbe\u7f6e\u6807\u51c6\u5e93\u8c03\u7528\u7cfb\u7edf API \u6240\u7528\u7684\u7f16\u7801\uff0c\u7528\u4e8e fopen\uff0cifstream \u7b49\u51fd\u6570 SetConsoleOutputCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u51fa\u7f16\u7801\uff0c\u6216\u8005\u5199 system(\"chcp 65001\") \u4e5f\u884c\uff0c\u8fd9\u91cc CP_UTF8 = 65001 SetConsoleCP(CP_UTF8); // \u8bbe\u7f6e\u63a7\u5236\u53f0\u8f93\u5165\u7f16\u7801\uff0c\u7528\u4e8e std::cin #elif __unix__ // \u53cd\u6b63 Unix \u7cfb\u7edf\u9ed8\u8ba4\u90fd\u662f UTF-8\uff0c\u4e0d\u8bbe\u7f6e\u4e5f\u884c\uff0c\u8fd9\u91cc\u8bbe\u7f6e\u5168\u5c40 locale \u662f\u4e3a\u4e86\u8ba9 iswspace \u63a5\u53d7\u5168\u89d2\u7a7a\u683c\u3001iswpunct \u63a5\u53d7\u5168\u89d2\u9017\u53f7 L'\uff0c' \u7b49 //setlocale(LC_ALL, \"zh_CN.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u4e2d\u6587\u672c\u5730\u5316\uff0c\u53ef\u4f7f strerror \u8f93\u51fa\u4e2d\u6587\uff08\u4f46\u7528\u6237\u5fc5\u987b locale-gen \u8fc7\u4e2d\u6587\uff01\uff09 //setlocale(LC_ALL, \"C.utf-8\"); // \u8bbe\u7f6e\u4f7f\u7528\u8bed\u8a00\u4e2d\u6027 locale\uff0c\u53ea\u5f71\u54cd iswspace\u3001iswpunct \u7b49\u51fd\u6570\uff0c\u4e0d\u4f1a\u4f7f strerror \u7b49\u8f93\u51fa\u4e2d\u6587 setlocale(LC_ALL, \".utf-8\"); // \u82e5\u4e0d\u5e26\u4efb\u4f55\u524d\u7f00\uff08\u63a8\u8350\uff09\uff0c\u5219\u9ed8\u8ba4\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u4e2d\u7684\u8bed\u8a00 $LANG\uff0c\u4f7f strerror \u81ea\u52a8\u9002\u5e94 #endif // \u8fd9\u91cc\u5f00\u59cb\u5199\u4f60\u7684\u4e3b\u7a0b\u5e8f\u5427\uff01 // ... std::cout << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u6ca1\u95ee\u9898\uff01 std::ifstream fin(\"\u4f60\u597d.txt\"); // \u6ca1\u95ee\u9898\uff01 std::wcout << L\"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u4f60\u90fd\u7edf\u4e00 UTF-8 \u4e86\uff0c\u8fd9\u7834 UTF-16 \u548c UTF-32 \u4e4b\u95f4\u6765\u56de\u8df3\u7684\u7834 wchar_t \u5c31\u522b\u7528\u4e86\u5457\uff01 return 0; }","title":"UTF-8 \u6d3e\u7684\u8de8\u5e73\u53f0\u8f6f\u4ef6\u4f55\u53bb\u4f55\u4ece\uff1f"},{"location":"unicode/#wndproc","text":"LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == false \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::cout << char(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f GBK \u7f16\u7801\u7684 char \u5e8f\u5217 // \u5982\u679c\u662f\u4e2d\u6587\u5b57\u7b26\uff0cWndProc(WM_CHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u5b57\u8282\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u5df1\u5224\u65ad\u548c\u62fc\u63a5 GBK \u5b57\u7b26\u4e32 return 0; case WM_UNICHAR: // \u5bf9\u4e8e IsWindowUnicode(hwnd) == true \u7684\u7a97\u53e3\uff0c\u4f1a\u8fdb\u5165\u8fd9\u91cc std::wcout << wchar_t(wParam); // \u6b64\u65f6 wParam \u8f93\u5165\u7684\u662f UTF-16 \u7f16\u7801\u7684 wchar_t \u5e8f\u5217 // \u5982\u679c\u662f\u4ee3\u7406\u5bf9\uff0cWndProc(WM_UNICHAR) \u4f1a\u88ab\u8c03\u7528\u591a\u6b21\uff0c\u6bcf\u6b21\u4e00\u4e2a\u7801\u4f4d\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u81ea\u884c\u628a\u4ee3\u7406\u5bf9\u7ec4\u88c5\u6210\u5b8c\u6574\u7684 Unicode \u7801\u70b9 return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } } \u628a WndProc \u7684\u8f93\u5165\u5b58\u5165 std::u32string \u7684\u6848\u4f8b\uff1a std::u32string result; std::string ansi_buf; std::wstring utf16_buf; std::optional try_ansi_to_utf32(std::string const &s) { try { return boost::locale::conv::to_utf(s, \"\"); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } std::optional try_utf16_to_utf32(std::wstring const &s) { try { return boost::locale::conv::utf_to_utf(s); } catch (boost::locale::conv::conversion_error const &) { return std::nullopt; } } LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CHAR: ansi_buf.push_back(char(wParam)); if (auto u = try_ansi_to_utf32(ansi_buf)) { result += u.value(); ansi_buf.clear(); } return 0; case WM_UNICHAR: utf16_buf.push_back(wchar_t(wParam)); if (auto u = try_utf16_to_utf32(utf16_buf)) { result += u.value(); utf16_buf.clear(); } return 0; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); };","title":"WndProc \u63a5\u53d7\u8f93\u5165\u6cd5\u7684\u4e2d\u6587\u8f93\u5165"},{"location":"unicode/#_20","text":"\u6807\u51c6\u5e93\u7684 std::string \u6211\u4eec\u4e0d\u518d\u8d58\u8ff0\uff0c\u521a\u624d\u5728\u201c\u5bbd\u5b57\u7b26\u6d41\u201d\u4e2d\u4e5f\u4ecb\u7ecd\u4e86\u5b98\u65b9\u7684\u60f3\u6cd5\uff0c\u4e4b\u540e\u7684\u5b57\u7b26\u4e32\u4e13\u9898\u8bfe\u4f1a\u7ee7\u7eed\u8be6\u89e3\u3002 \u8fd9\u91cc\u6211\u4eec\u4e3b\u8981\u63a2\u7a76\u5173\u4e8e\u5b57\u7b26\u7f16\u7801\u7684\u95ee\u9898\uff0c\u63a2\u7d22\u5404\u5927\u5e38\u89c1\u7684\u7f16\u7a0b\u8bed\u8a00\u548c\u5e93\uff0c\u662f\u5982\u4f55\u5c01\u88c5\u5b57\u7b26\u4e32\u7c7b\uff0c\u5982\u4f55\u89e3\u51b3 UTF-8 \u53d8\u957f\u7f16\u7801\uff0cUTF-32 \u538b\u7f29\u7387\u4f4e\u7684\u95ee\u9898\u7684\uff0c\u5e0c\u671b\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u63d0\u4f9b\u4e00\u70b9\u7075\u611f\u3002 \u901a\u5e38\u6765\u8bf4\uff0c\u4e00\u4e2a\u597d\u7684\u5e93\u6216\u8bed\u8a00\uff0c\u90fd\u8981\u660e\u786e\u533a\u5206\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u6982\u5ff5\uff0c\u524d\u8005\u662f\u6587\u672c\u5185\u5bb9\uff0c\u540e\u8005\u662f\u7eaf\u4e8c\u8fdb\u5236\u5185\u5bb9\u3002 \u5b57\u7b26\u4e32\u53ef\u4ee5\u901a\u8fc7\u201c\u7f16\u7801\u201d\u5f97\u5230\u7eaf\u4e8c\u8fdb\u5236\u7684\u5b57\u8282\u6570\u7ec4\uff0c\u800c\u5b57\u8282\u6570\u7ec4\u53ef\u4ee5\u201c\u89e3\u7801\u201d\u5f97\u5230\u539f\u59cb\u5b57\u7b26\u4e32\u3002 \u65e9\u671f\u7684 C \u8bed\u8a00\u5c31\u662f\u56e0\u4e3a\u628a\u5b57\u7b26\u548c\u5b57\u8282\u6df7\u4e3a\u4e00\u8c08\uff0c\u90fd\u4f7f\u7528\u4e86 char \u7c7b\u578b\uff0c\u624d\u4ea7\u751f\u4e86\u540e\u6765\u8fd9\u4e48\u591a\u4e71\u8c61\u3002\u540e\u6765\u901a\u8fc7\u6253\u8865\u4e01\u6253\u4e0a\u771f\u6b63\u7684\u5b57\u7b26 wchar_t \uff0c\u5374\u6ca1\u4ec0\u4e48\u4eba\u7528\uff0c\u800c\u4e14\u8fd8\u88ab Windows \u641e\u6210 16 \u4f4d\uff0c\u53cd\u800c\u4e0d\u8de8\u5e73\u53f0\u4e86\u3002 \u6b64\u5904\u5148\u5217\u4e00\u4e2a\u4e0d\u540c\u7f16\u7a0b\u8bed\u8a00\u773c\u4e2d\u5b57\u7b26\u4e32\u548c\u5b57\u8282\u6570\u7ec4\u7684\u8868\uff0c\u65b9\u4fbf\u4f60\u7406\u89e3\u3002 \u8bed\u8a00 \u5b57\u7b26 \u5b57\u7b26\u4e32 \u6587\u672c\u6d41 \u5b57\u8282\u6570\u7ec4 \u4e8c\u8fdb\u5236\u6d41 \u7f16\u7801/\u89e3\u7801 C char wchar_t * FILE * + fgetwc char * FILE * + fgetc wcstomb / mbstowc C++ wchar_t std::wstring std::wistream std::string / std::vector std::istream std::codecvt Qt QChar QString QTextStream QByteArray QDataStream QTextCodec Python3 str str open('r') bytes open('rb') str.encode() Python2 unicode unicode \u65e0 str open('r') unicode.encode() Java Character String Reader byte[] InputStream Charset.encode C# char string StreamReader byte[] Stream Encoding Rust char String BufRead u8 Read str::from_utf8 JS char String ReadableStream Uint8Array ReadableStream TextEncoder Go rune string Reader byte Reader utf8.DecodeRune PHP string string fopen string fopen mb_convert_encoding Swift Character String String.UnicodeScalarView UInt8 Data String.Encoding Kotlin Char String Reader ByteArray InputStream Charset.encode Obj-C unichar NSString NSInputStream uint8_t NSInputStream NSStringEncoding Lua integer table \u65e0 string io.open require'utf8' \u672c\u8bfe\u4e0d\u4f1a\u8bb2\u89e3\u8fd9\u4e9b\u8bed\u8a00\u7684\u5b57\u7b26\u4e32\u5177\u4f53\u7528\u6cd5\uff0c\u53ea\u63d0\u4f9b\u4e00\u4e9b\u6982\u5ff5\uff0c\u8ba9\u4f60\u77e5\u9053\u5927\u5bb6\u90fd\u662f\u600e\u4e48\u5b9e\u73b0\u7684\uff0c\u89e6\u7c7b\u65c1\u901a\u3002 Lua \u4e2d UTF-32 \u7684\u5b9a\u957f\u7f16\u7801\uff0c\u8981\u8fd9\u6837\u5b9e\u73b0\uff1a {80, 101, 110, 103} \u3002\u800c\u4ed6\u6240\u8c13\u7684 utf8 \u5e93\uff0c\u5c31\u662f\u8d1f\u8d23\u628a Lua \u81ea\u5df1\u7684 string \u5047\u8bbe\u4e3a utf8 \u7f16\u7801\uff0c\u89e3\u7801\u51fa\u4e00\u4e2a\u4e2a Unicode \u7801\u70b9\uff0c\u8fd4\u56de\u4e00\u4e2a\u8fd9\u6837\u7684\u6570\u7ec4\u3002\u4ed6\u751a\u81f3\u4e0d\u662f Lua \u6807\u51c6\u7684\u4e00\u90e8\u5206\uff0c\u662f\u4e2a\u7b2c\u4e09\u65b9\u7684\u5e93\uff0c\u8fd8\u662f\u9700\u8981\u7f16\u8bd1\u7684 C \u8bed\u8a00 .so \u6587\u4ef6\u3002\u8fd8\u6709 Lua \u5b5d\u5b50\u501f\u6b64\u786c\u8bf4\u6211\u4eec Lua \u662f\u5929\u751f UTF-8\uff01\u7136\u800c\u62ff\u7740\u4e2a UTF-8 \u7f16\u7801\u7684\u201c\u5b57\u8282\u6570\u7ec4\u201d string \u6765\u6253\u5f00 io.open \u6587\u4ef6\uff0c\u5c31\u4f1a\u62a5\u9519\u627e\u4e0d\u5230\u6587\u4ef6\uff08\u56e0\u4e3a\u4e2d\u56fd\u533a Windows \u7684 GBK\uff09\uff0c\u662f\u4e0d\u662f\u5f88\u597d\u7b11\u5462\uff1f","title":"\u5e38\u89c1\u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u63a2\u7a76"},{"location":"unicode/#qt-qstring","text":"Qt \u7684\u5b57\u7b26\u4e32\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 Qt \u7684\u5b57\u8282\u6570\u7ec4\u7c7b\u578b\u662f QString \u3002\u5b83\u53ef\u4ee5\u5bb9\u7eb3\u4efb\u610f Unicode \u5b57\u7b26\u96c6\u7684\u5b57\u7b26\u4e32\u3002 \u5b83\u7684\u6570\u636e\u7ed3\u6784\u5b9e\u9645\u4e0a\u662f\u4e2a QChar \u6570\u7ec4\uff0c\u800c QChar \u662f unsigned short \uff0c\u5373 16 \u4f4d\u65e0\u7b26\u53f7\u6574\u6570\uff0c\u4e5f\u5c31\u662f UTF-16 \u7f16\u7801\u7684\u7801\u4f4d\u3002 QString str = \"\u4f60\u597d\uff0c\u4e16\u754c\"; // str.size() = 5 // str[0] = QChar(0x4f60) = u'\u4f60' // str[1] = QChar(0x597d) = u'\u597d' // str[2] = QChar(0xff0c) = u'\uff0c' // str[3] = QChar(0x4e16) = u'\u4e16' // str[4] = QChar(0x754c) = u'\u754c' \u53ef\u89c1\uff0c QString \u662f UTF-16 \u7f16\u7801\u7684\uff0c\u5c31\u548c Java \u4e00\u6837\uff0cQt \u4e5f\u662f UTF-16 \u6f6e\u7684\u53d7\u5bb3\u8005\u3002 \u6240\u4ee5\uff0cQString \u4e5f\u5b58\u5728\u7740\u4ee3\u7406\u5bf9\u53d8\u957f\u7f16\u7801\u7684\u95ee\u9898\u3002\u4f46\u81f3\u5c11\u5bf9\u5e38\u89c1\u7684\u4e2d\u6587\u5b57\u7b26\u6765\u8bf4\uff0c\u4e00\u4e2a 16 \u4f4d\u7684 QChar \u90fd\u5bb9\u7eb3\u7684\u4e0b\u4e86\u3002","title":"Qt QString"},{"location":"unicode/#qtextcodec","text":"Qt \u5b9a\u4e49\u4e86\u4e00\u7cfb\u5217\u7684\u7f16\u7801\u8f6c\u6362\u51fd\u6570\uff0c\u7528\u4e8e\u5c06 QString \u8f6c\u6362\u6210 QByteArray \uff0c\u6216\u8005\u4ece QByteArray \u8f6c\u6362\u6210 QString \uff0c\u8fd9\u4e9b\u51fd\u6570\u540d\u90fd\u662f\u4ee5 to \u6216\u8005 from \u5f00\u5934\u7684\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u540d\uff0c\u4f8b\u5982 fromUtf8 \u3001 toUtf8 \u3001 toLocal8Bits \u3002 \u8fd9\u4e9b\u51fd\u6570\u7684\u5185\u90e8\uff0c\u90fd\u662f\u8c03\u7528 QTextCodec \u7c7b\u5b9e\u73b0\u7684\u8f6c\u6362\u3002 QTextCodec \u662f Qt \u7528\u4e8e\u5904\u7406\u5404\u79cd\u6587\u672c\u7f16\u7801\u4e4b\u95f4\u8f6c\u6362\u7684\u7c7b\u3002\u5b83\u7684\u9759\u6001\u65b9\u6cd5 codecForLocale \u8fd4\u56de\u4e86\u5f53\u524d\u7cfb\u7edf\u7684\u7f16\u7801\uff0c toUnicode \u548c fromUnicode \u5206\u522b\u662f\u5c06 QByteArray \u8f6c\u6362\u6210 QString \uff0c\u6216\u8005\u5c06 QString \u8f6c\u6362\u6210 QByteArray \u3002 QTextCodec *codec = QTextCodec::codecForLocale(); // \u8fd4\u56de\u5f53\u524d\u7cfb\u7edf\u7f16\u7801 QByteArray bytes = codec->fromUnicode(str); // \u5c06 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u5373 char[] QString str = codec->toUnicode(bytes); // \u5c06 QByteArray \u8f6c\u6362\u6210 QString QTextCodec \u8fd8\u63d0\u4f9b\u4e86\u4e00\u4e9b\u66f4\u52a0\u7ec6\u7c92\u5ea6\u7684\u8f6c\u6362\u63a5\u53e3\uff0c\u4f8b\u5982 fromUnicode \u9664\u4e86\u63a5\u53d7 QString \uff0c\u8fd8\u63a5\u53d7 QChar \u6570\u7ec4\uff0c\u53ef\u4ee5\u6307\u5b9a\u8f6c\u6362\u8303\u56f4\u3002","title":"QTextCodec"},{"location":"unicode/#fromtolocal8bitsutf8latin1ascii","text":"\u4e3a\u4e86\u65b9\u4fbf\u4f7f\u7528\uff0cQt \u5c01\u88c5\u4e86\u4e00\u4e9b\u5e38\u7528\u5b57\u7b26\u7f16\u7801\u7684\u8f6c\u6362\u51fd\u6570\uff0c\u8fd9\u6837\u4f60\u4e0d\u5fc5\u6bcf\u6b21\u90fd\u521b\u5efa\u4e00\u4e2a QTextCodec\u3002\u90fd\u662f to \u548c from \u5f00\u5934\uff0c\u540e\u9762\u8ddf\u7740\u7f16\u7801\u7684\u540d\u79f0\u3002 Local8Bits \u8868\u793a\u8fd0\u884c\u65f6\u68c0\u6d4b\u5230\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\uff0c\u4e5f\u5c31\u662f\u5ba2\u6237\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u3002 QByteArray bytes = str.toLocal8Bits(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801 QString::fromLocal8Bits(bytes); // \u518d\u4ece\u5f53\u524d\u7cfb\u7edf\u7684\u5b57\u7b26\u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForLocale(); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Utf8 \u8868\u793a\u4f7f\u7528 UTF-8 \u7f16\u7801\u3002 QByteArray bytes = str.toUtf8(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 UTF-8 \u7f16\u7801 QString::fromUtf8(bytes); // \u518d\u4ece UTF-8 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"UTF-8\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Latin1 \u8868\u793a ISO-8859-1 \u7f16\u7801\uff0c\u53c8\u79f0\u4e3a\u897f\u6b27\u7f16\u7801\uff0c\u5b83\u662f\u4e00\u4e2a\u5355\u5b57\u8282\u7f16\u7801\uff0c\u548c ASCII \u7f16\u7801\u76f8\u4f3c\uff0c\u4f46\u662f\u591a\u4e86 128-255 \u7684\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u6cd5\u8bed\u3001\u5fb7\u8bed\u3001\u897f\u73ed\u7259\u8bed\u3001\u8461\u8404\u7259\u8bed\u7b49\u5b57\u7b26\u3002 QByteArray bytes = str.toLatin1(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 Latin1 \u7f16\u7801 QString::fromLatin1(bytes); // \u518d\u4ece Latin1 \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ISO-8859-1\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes); Ascii \u8868\u793a ASCII \u7f16\u7801\uff0c\u548c Latin1 \u7684\u60c5\u51b5\u7c7b\u4f3c\uff0c\u53ea\u4e0d\u8fc7\u4ed6\u65e0\u6cd5\u5904\u7406 128-255 \u8fd9\u4e00\u6bb5\u7684\u5b57\u7b26\u3002 QByteArray bytes = str.toAscii(); // \u5c06 UTF-16 \u7684 QString \u8f6c\u6362\u6210 QByteArray\uff0c\u4f7f\u7528 ASCII \u7f16\u7801 QString::fromAscii(bytes); // \u518d\u4ece ASCII \u7f16\u7801\u8f6c\u6362\u56de UTF-16 \u7684 QString // \u7b49\u4ef7\u4e8e\uff1a QTextCodec *codec = QTextCodec::codecForName(\"ASCII\"); QByteArray bytes = codec->fromUnicode(str); QString str = codec->toUnicode(bytes);","title":"from/toLocal8Bits/Utf8/Latin1/Ascii"},{"location":"unicode/#_21","text":"QString str = QStringLiterial(\"\u4f60\u597d\uff0c\u4e16\u754c\"); QStringLiterial \u53ef\u4ee5\u4fdd\u8bc1\uff0c\u8f6c\u6362\u65f6\u91c7\u7528\u7684\u662f\u6240\u8c13\u201c\u8fd0\u884c\u5b57\u7b26\u96c6\u201d\uff08\u5b9e\u9645\u5e94\u8be5\u53eb\u5b57\u9762\u91cf\u5b57\u7b26\u7f16\u7801\uff09\uff0c\u4e5f\u5c31\u662f\u6211\u4eec\u5f00\u53d1\u8005\u7535\u8111\u4e0a\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\uff0c\u662f\u7f16\u8bd1\u671f\u786e\u5b9a\u7684\u3002\u800c\u5982\u679c\u5199 QString::fromLocal8Bits(\"\") \u5c31\u53d8\u6210 \u201cANSI\u201d\uff0c\u5ba2\u6237\u7684\u201c\u533a\u57df\u8bbe\u7f6e\u201d\u4e86\u3002\u8fd9\u4e24\u4e2a\u5b57\u7b26\u7f16\u7801\uff0c\u6bd4\u5982\u5728\u4e4b\u524d\u8de8\u56fd galgame \u7684\u6848\u4f8b\u4e2d\uff0c\u5c31\u662f\u4e0d\u540c\u7684\u3002","title":"\u5b57\u7b26\u4e32\u5e38\u91cf"},{"location":"unicode/#qtextstream","text":"QTextStream \u662f Qt \u63d0\u4f9b\u7684\u6587\u672c\u6d41\u7c7b\uff08\u5e26\u6709\u7f13\u51b2\uff09\uff0c\u5b83\u53ef\u4ee5\u5c06\u6587\u672c\u5199\u5165\u5230\u6587\u4ef6\u3001\u5957\u63a5\u5b57\u3001\u6807\u51c6\u8f93\u51fa\u7b49\u8bbe\u5907\u3002 \u6587\u672c\u6d41\u548c\u4e8c\u8fdb\u5236\u6d41\u4e0d\u540c\uff0c\u4ed6\u9700\u8981\u6307\u5b9a\u4e00\u4e2a\u7f16\u7801\u683c\u5f0f\uff0c\u901a\u8fc7 QTextStream \u6784\u9020\u51fd\u6570\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u6307\u5b9a\u3002 \u5f53\u4f60\u5f80 QTextStream \u5199\u5165 QString \u65f6\uff0c\u4f1a\u8c03\u7528\u8fd9\u4e2a\u7f16\u7801\u683c\u5f0f\u81ea\u52a8\u8f6c\u6362\u4e3a QByteArray \uff0c\u7136\u540e\u624d\u5199\u5165\u3002 \u8bfb\u53d6\u65f6\u4e5f\u540c\u7406\uff0c\u4f1a\u628a\u8bfb\u5230\u7684 QByteArray \u901a\u8fc7\u7f16\u7801\u683c\u5f0f\u89e3\u7801\uff0c\u5f97\u5230 QString \u5b57\u7b26\u4e32\u3002 Qt \u503c\u5f97\u79f0\u9053\u7684\u4e00\u70b9\u662f\uff1a\u4ed6\u628a\u6587\u4ef6\u548c\u6587\u4ef6\u6d41\u533a\u5206\u5f00\u6765\uff0c\u6587\u4ef6 QFile \u53ea\u9700\u8981\u8d1f\u8d23\u6253\u5f00\u6587\u4ef6\u5c31\u53ef\u4ee5\u4e86\uff1b\u800c\u6587\u672c\u6d41 QTextStream \u624d\u771f\u6b63\u8d1f\u8d23\u6570\u636e\u7684\u7f13\u51b2\uff0c\u89e3\u7801\u7b49\u64cd\u4f5c\u3002\u4f53\u73b0\u4e86\u9762\u5411\u5bf9\u8c61\u7684\u804c\u8d23\u5355\u4e00\u539f\u5219\u3002 QFile file(\"hello.txt\"); file.open(QIODevice::ReadWrite); QTextStream stream(&file); stream.setCodec(\"UTF-8\"); // \u8bbe\u7f6e\u6587\u4ef6\u7684\u7f16\u7801\u683c\u5f0f stream << \"\u4f60\u597d\uff0c\u4e16\u754c\\n\"; // \u5199\u5165 QString\uff0cQTextStream \u4f1a\u81ea\u52a8\u5c06\u5176\u7528 UTF-8 \u7f16\u7801\u4e3a QByteArray \u540e\u5199\u5165 QFile \u5982\u679c\u4f60\u786e\u5b9e\u9700\u8981\u76f4\u63a5\u5199\u5165\u4e8c\u8fdb\u5236\u7684 QByteArray \uff0cQt \u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a QDataStream \u7c7b\uff0c\u65b9\u4fbf\u4e8c\u8fdb\u5236\u6587\u4ef6\u7684\u8bfb\u5199\u3002 \u5982\u6b64\u628a\u4e8c\u8fdb\u5236\u548c\u6587\u672c\u4e25\u683c\u533a\u5206\uff0c\u800c\u4e0d\u662f\u50cf\u53e4\u4ee3 C \u8bed\u8a00\u90a3\u6837\u5b57\u8282\u4e0e\u5b57\u7b26\u6df7\u6dc6\u4e0d\u6e05\uff0c\u5168\u7528\u7cdf\u7cd5\u7684 char \u6765\u8868\u793a\uff0c\u5145\u5206\u4f53\u73b0\u4e86\u5f3a\u7c7b\u578b\u7684\u5b89\u5168\u3002","title":"QTextStream"},{"location":"unicode/#python-3-str","text":"\u5982\u4f55\u89e3\u51b3 UTF-32 \u5360\u7528\u7a7a\u95f4\u5927\u7684\u75db\u70b9\uff1fPython \u7684\u5b57\u7b26\u4e32\u5b9e\u73b0\u7edd\u5bf9\u503c\u5f97\u4e00\u770b\uff01 \u4e3a\u4e86\u65b9\u4fbf\u6587\u672c\u5904\u7406\uff0c\u6700\u597d\u4ee5\u5b9a\u957f\u7f16\u7801\uff0c\u4e5f\u5c31\u662f UTF-32\uff0c\u5b58\u50a8\u5b57\u7b26\u4e32\u3002 \u5982\u679c\u7528 UTF-8 \u6216 UTF-16 \u6765\u5b58\u50a8\u7684\u8bdd\uff0c\u4f1a\u9047\u5230\u53d8\u957f\u7f16\u7801\u7684\u56fa\u6709\u7f3a\u9677\uff1a \u4f8b\u5982\u50cf\u5b57\u7b26\u4e32\u7d22\u5f15\uff0c\u5b57\u7b26\u4e32\u6c42\u957f\u5ea6\u7b49\u64cd\u4f5c\uff0c\u8981\u4e48\u7d22\u5f15\u51fa\u6765\u7684\u662f\u5b57\u8282\u800c\u4e0d\u662f\u5b57\u7b26\u4e86\uff1b\u8981\u4e48\u5c31\u9700\u8981 O(N) O(N) \u7684\u590d\u6742\u5ea6\uff0c\u9010\u4e00\u904d\u5386\u6bcf\u4e2a\u5b57\u8282\uff0c\u624d\u80fd\u786e\u5b9a\u771f\u6b63\u7684\u4f4d\u7f6e\uff1b\u54ea\u6015\u5168\u662f ASCII \u4e5f\u5f97\u8fd9\u4e48\u505a\uff0c\u56e0\u4e3a\u4e07\u4e00\u521a\u597d\u6709\u4e00\u4e2a\u662f\u4e2d\u6587\u5b57\u7b26\u5462\uff1f \u6240\u4ee5\uff0c\u5bf9\u4e8e\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684 Python \u6765\u8bf4\uff0cUTF-8 \u662f\u65e0\u6cd5\u63a5\u53d7\u7684\uff0c\u4f3c\u4e4e\u53ea\u80fd\u4ee5 UTF-32 \u6765\u5b58\u50a8\uff1f Python \u60f3\u5230\u4e86\u4e00\u4e2a\u5c0f\u5999\u62db\uff1a enum PyUnicodeType { PyUnicodeType_Latin1, PyUnicodeType_UCS2, PyUnicodeType_UCS4, }; struct PyUnicodeString { PyUnicodeType type; union { uint8_t *latin1; uint16_t *ucs2; uint32_t *ucs4; }; }; \u8fd9\u91cc\u7684 union \u662f\u4e00\u4e2a C \u8bed\u8a00\u7279\u6027\uff0c\u4ed6\u5141\u8bb8\u4f60\u628a\u591a\u4e2a\u6210\u5458\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u7a7a\u95f4\u3002\u901a\u5e38\u6765\u8bf4\u9700\u8981\u914d\u5408\u4e00\u4e2a enum \u8868\u793a\u7c7b\u578b\uff0c\u624d\u80fd\u5b89\u5168\u4f7f\u7528\u3002\u73b0\u4ee3 C++ \u7684 std::variant \u66f4\u5b89\u5168\u7684\u53d6\u4ee3\u4e86\u4ed6\uff0c\u800c\u4e14\u4e0d\u9700\u8981\u5916\u6302\u4e00\u4e2a enum \u3002CPython \u89e3\u91ca\u5668\u56e0\u4e3a\u662f C \u8bed\u8a00\u5b9e\u73b0\uff0c\u53ea\u80fd\u7528 union \u6a21\u62df std::variant \u7684\u6548\u679c\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFF \u7684\u5b57\u7b26\uff08Latin-1 \u8303\u56f4\uff09\u65f6\uff0c\u5b9e\u9645\u4e0a\u6ca1\u5fc5\u8981\u5168\u7528\u8d85\u5927\u7684 uint32_t \u6765\u5b58\u50a8\u3002\u5b8c\u5168\u53ef\u4ee5\u53ea\u53d6\u51fa\u4f4e 8 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a\u66f4\u7d27\u51d1\u7684 uint8_t \u6570\u7ec4\uff0c\u5c31\u50cf Latin-1 \u7f16\u7801\u4e00\u6837\u3002 \u4f46\u662f\u5f53\u6309\u7d22\u5f15\u8bfb\u53d6\u5143\u7d20\u65f6\uff0c\u4f1a\u5224\u65ad\u5f53\u524d union \u91cc\u88c5\u7684\u662f\u54ea\u79cd\u7c7b\u578b\uff0c\u5982\u679c\u662f Latin-1 \u7684\uff0c\u90a3\u5c31\u4f1a\u7528\u7ed3\u6784\u4f53\u91cc\u7684 uint8_t * \u6307\u9488\u6765\u7d22\u5f15\u3002 \u8fd9\u6837\uff0c\u5bf9\u4e8e\u5168 ASCII \u7684\u5b57\u7b26\u4e32\uff0c\u76f8\u6bd4\u8001\u8001\u5b9e\u5b9e\u5b58 UTF-32 \u5185\u5b58\u5360\u7528\u76f4\u63a5\u51cf\u5c11\u4e86 75%\uff01\u552f\u4e00\u7684\u4ee3\u4ef7\u662f\u6309\u7d22\u5f15\u8bfb\u5b57\u7b26\u5143\u7d20\u65f6\u9700\u8981\u505a\u4e2a if-else \u5224\u65ad\u3002\u540c\u65f6\u53c8\u4e0d\u5931\u53bb\u5b9a\u957f\u7f16\u7801\u7684\u4f18\u52bf\u3002 \u5f53\u4e00\u4e2a\u5b57\u7b26\u4e32\u4e2d\u53ea\u5305\u542b 0 \u5230 0xFFFF \u7684\u5b57\u7b26\uff08\u65e9\u671f Unicode \u8303\u56f4\uff09\u65f6\uff0c\u5219\u662f\u53d6\u51fa\u4f4e 16 \u4f4d\uff0c\u5b58\u5165\u4e00\u4e2a uint16_t \u7684\u6570\u7ec4\uff0c\u8fd9\u79cd\u5b58\u50a8\u65b9\u6848\u4e5f\u79f0\u4e3a UCS-2\u3002 \u6ce8\u610f UCS-2 \u5e76\u4e0d\u7b49\u540c\u4e8e UTF-16\uff0cUTF-16 \u662f\u80fd\u591f\u8868\u793a\u5b8c\u6574\u7684 Unicode \u7684\u53d8\u957f\u7f16\u7801\uff08\u6709\u4ee3\u7406\u5bf9\uff09\uff1b\u800c UCS-2 \u662f\u6ca1\u6709\u4ee3\u7406\u5bf9\u7684\u5b9a\u957f\u7f16\u7801\uff0c\u7f3a\u70b9\u662f\u53ea\u80fd\u8868\u793a 0xFFFF \u7684\u8303\u56f4\u3002 \u5bf9\u4e8e\u5927\u90e8\u5206\u4e2d\u6587\u5b57\u7b26\u4e32\uff0c\u5185\u5b58\u5360\u7528\u5c31\u51cf\u5c11\u4e86 50%\uff0c\u4e5f\u4e0d\u4e8f\u3002 \u5982\u679c\u5b57\u7b26\u4e32\u4e2d\u51fa\u73b0\u201c\ud883\udede\u201d\u8fd9\u6837\u7684\uff0c\u8d85\u8fc7 0xFFFF \u7684\u5b57\u7b26\uff0c\u624d\u4f1a\u91c7\u7528 uint32_t \u8001\u8001\u5b9e\u5b9e\u5b58\u50a8\u771f\u6b63\u7684 UTF-32\uff0c\u53c8\u79f0 UCS-4\u3002 \u8fd9\u4e24\u79cd\u53eb\u6cd5\u662f\u7b49\u4ef7\u7684\uff0c\u53cd\u6b63 Unicode \u4ece\u6765\u6ca1\u6709\u8d85\u8fc7 0xFFFFFFFF \u7684\uff0c\u73b0\u5728\u4ed6\u4eec\u90fd\u662f\u5b9a\u957f\u7f16\u7801\u3002 \u5bf9\u4e8e\u4e00\u4e2a\u7ecf\u5e38\u9700\u8981\u5904\u7406\u5b57\u7b26\u4e32\u7684\u865a\u62df\u673a\u8bed\u8a00\u6765\u8bf4\uff0c\u53cd\u6b63\u672c\u6765\u5c31\u4e0d\u5728\u4e4e if-else \u5206\u652f\u8fd9\u70b9\u5c0f\u5f00\u9500\uff0c\u8fd9\u786e\u5b9e\u662f\u6700\u597d\u7684\u65b9\u6848\u3002 \u7f3a\u70b9\u5c31\u662f\uff0c\u5f53\u4f60\u5f80\u4e00\u4e2a\u5b8c\u5168\u662f ASCII \u7684\u5b57\u7b26\u4e32\u4e2d\uff0c\u7a81\u7136\u63d2\u5165\u4e00\u4e2a\u201c\ud883\udede\u201d\u65f6\uff0c\u4f1a\u4ea7\u751f\u5de8\u5927\u7684\u5185\u5b58\u91cd\u5206\u914d\u3002\u867d\u7136\u53ea\u6709\u4e00\u4e2a\u201c\ud883\udede\u201d\uff0c\u4f46\u4e3a\u6b64\uff0c\u5176\u4ed6\u6240\u6709 ASCII \u5b57\u7b26\u90fd\u5f97\u4e3a\u4ed6\u6269\u5f20\u5230 32 \u4f4d\u7684\u5927\u5c0f\u3002\u800c UTF-8 \u548c\u4f20\u7edf\u7684 UTF-32 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u56e0\u6b64\u6211\u4e5f\u4e0d\u5efa\u8bae C++ \u7a0b\u5e8f\u5458\u81ea\u5df1\u624b\u6413\u4e2a\u8fd9\u6837\u7684 union \u5b57\u7b26\u4e32\u3002","title":"Python 3 str"},{"location":"unicode/#rust-str-string","text":"\u800c Rust \u5219\u91c7\u7528\u4e86\u5b57\u7b26\u4e32\u5168\u5458 UTF-8 \u7684\u7b56\u7565\uff0c\u8fd9\u662f\u56e0\u4e3a Rust \u6700\u5e38\u7528\u4e8e\u4e92\u8054\u7f51\u65b9\u9762\u7684\u5e95\u5c42\u7cfb\u7edf\u8f6f\u4ef6\uff0c\u4e92\u8054\u7f51\u6700\u5e38\u7528\u7684\u6587\u672c\u7f16\u7801\u5c31\u662f UTF-8\uff0c\u6ca1\u6709\u5927\u5c0f\u7aef\u95ee\u9898\uff0c\u4e14\u56fd\u9645\u901a\u7528\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u4e92\u8054\u7f51\u57fa\u5efa\u6700\u5e38\u89c1\u7684\u5e73\u53f0\u5c31\u662f Linux\uff0c\u4f7f\u7528 UTF-8 \u5b58\u50a8\u5b57\u7b26\u4e32\uff0c\u8c03\u7528 Linux \u7cfb\u7edf API \u65e0\u9700\u4efb\u4f55\u8f6c\u6362\u3002\u4e14\u6587\u672c\u6587\u4ef6\u57fa\u672c\u90fd\u53ef\u4ee5\u5047\u5b9a\u662f UTF-8 \u7f16\u7801\uff0c\u5199\u5165\u65f6\u65e0\u9700\u4efb\u4f55\u8f6c\u6362\uff0c\u590d\u6742\u5ea6\u4f4e\u81f3 O(1) O(1) \u3002\u4f5c\u4e3a\u4ee3\u4ef7\uff0c\u8fd9\u5bfc\u81f4\u6587\u672c\u5904\u7406\u4e0a\u7684\u4e00\u4e9b\u56f0\u96be\uff0c\u4f8b\u5982\u5b57\u7b26\u4e32\u7684\u7d22\u5f15\uff0c\u9700\u8981\u533a\u5206\u662f\u6309\u5b57\u8282\u7d22\u5f15\u8fd8\u662f\u6309\u5b57\u7b26\u7d22\u5f15\uff0c\u5982\u679c\u786e\u5b9e\u9700\u8981\u6309\u5b57\u7b26\u7d22\u5f15\u7684\u8bdd\uff0c\u590d\u6742\u5ea6\u5c31\u4f1a\u662f O(N) O(N) \u4e86\u3002 \u65e0\u8bba\u5982\u4f55\uff0c\u5982\u679c\u4f60\u9009\u62e9\u4e86 UTF-8 \u6d41\u6d3e\u7684\u8bdd\uff0cRust \u5b57\u7b26\u4e32\u7684\u201c\u8fed\u4ee3\u5668\u53cc\u8f68\u5236\u201d\u786e\u5b9e\u503c\u5f97\u79f0\u9053\uff1a let s = \"\u4f60\u597d\uff0c\u4e16\u754c\"; for c in s.chars() { // \u6309\u5b57\u7b26\u8fed\u4ee3 println!(\"{}\", c); } for b in s.bytes() { // \u6309\u5b57\u8282\u8fed\u4ee3 println!(\"{:02X}\", b); // \u6253\u5370\uff1aE4 BD A0 E5 A5 BD EF BC 8C E4 B8 96 E7 95 8C }","title":"Rust &str \u548c String"},{"location":"unicode/#java-string","text":"Java \u4e5f\u662f UTF-16 \u7684\u53cc\u5b57\u8282\u7f16\u7801\u3002 \u4eae\u70b9\uff1a\u4ed6\u7684 String \u7c7b\u578b\u662f\u4e0d\u53ef\u53d8\u7684\uff0c\u4e5f\u5c31\u662f\u8bf4\uff0c\u4f60\u65e0\u6cd5\u5c31\u5730\u4fee\u6539\u4e00\u4e2a String \u5bf9\u8c61\uff0c\u6bcf\u6b21\u4ea7\u751f\u4f60\u8c03\u7528 += \u7684\u90fd\u662f\u4e00\u4e2a\u65b0 String\uff0c\u800c\u4e0d\u4f1a\u8986\u76d6\u3002 \u4e5f\u5c31\u662f\u8bf4\uff1aJava \u7684 String \u867d\u7136\u662f\u201c\u5806\u201d\u4e2d\u7684\u5bf9\u8c61\uff0c\u5374\u65e0\u6cd5\u4ee5\u5f15\u7528\u4f20\u9012\u3002 \u8fd9\u907f\u514d\u4e86\u4ee5\u4e0b\u8fd9\u79cd\u60c5\u51b5\uff1a void registerStudent(String name) { name += \".txt\"; File file(name); file.write(...); } void myTransaction() { String name = \"\u5c0f\u5f6d\"; lib.registerStudent(name); office.registerStudent(name); // \u8fd9\u91cc name \u662f\u5426\u88ab\u4fee\u6539\uff1f } \u5982\u679c Java \u7684 String \u548c\u666e\u901a\u5bf9\u8c61\u4e00\u6837\uff0c\u88ab\u8c03\u7528\u8005\u7684\u4fee\u6539\u53ef\u4ee5\u5bf9\u5916\u90e8\u53ef\u89c1\uff0c\u90a3\u5c82\u4e0d\u662f\u6211\u6bcf\u6b21\u8c03\u7528\u4e00\u4e2a\u4ee5 String \u4e3a\u53c2\u6570\u7684\u51fd\u6570\u65f6\uff0c\u90fd\u9700\u8981\u64cd\u5fc3\uff1a\u8fd9\u4e2a\u51fd\u6570\u4f1a\u4e0d\u4f1a\u628a\u6211\u7684\u5b57\u7b26\u4e32\u4fee\u6539\u6389\uff1f \u6240\u4ee5\uff0cJava \u7ed9\u4ed6\u7684\u5bf9\u8c61\u6a21\u578b\u5f00\u4e86\u4e2a\u540e\u95e8\uff1a\u89c4\u5b9a\u6240\u6709\u5bf9\u8c61\u90fd\u662f\u6309\u5f15\u7528\u4f20\u9012\uff0c\u9664\u4e86 String \uff01\u5c31\u53ea\u6709 String \u662f\u4e0d\u53ef\u53d8\u5bf9\u8c61\uff0c\u88ab\u8c03\u7528\u8005\u5185\u90e8\u7684\u4fee\u6539\u5bf9\u5916\u4e0d\u53ef\u89c1\u3002 C++ \u548c Rust \u53ea\u9700\u8981\u52a0\u4e2a\u5e38\u5f15\u7528\u5c31\u884c\uff0c\u800c Java \u53d7\u5bb3\u8005\u8981\u8003\u8651\u7684\u5c31\u591a\u4e86\u3002 \u603b\u4e4b\uff0c\u8fd9\u5c31\u662f\u6ca1\u6709 const \u7684\u5783\u573e\u8bed\u8a00\u7684\u4e11\u6001\uff0c\u9700\u8981\u9760\u5404\u79cd\u8bed\u6cd5\u89c4\u5219\u4e0a\u5f00\u6d1e\u624d\u80fd\u5f25\u8865\u8bbe\u8ba1\u65f6\u8003\u8651\u4e0d\u5468\u7684\u7f3a\u9677\uff0c\u5c31\u4e3a\u4e86\u4f3a\u5019\u8fd9\u5e2e\u5f15\u7528\u90fd\u5f04\u4e0d\u660e\u767d\u7684\u5783\u573e\u5c0f\u767d\u3002 \u6211\u662f\u8bf4\u5783\u573e\u56de\u6536 (garbage-collect) \u8bed\u8a00\uff0c\u7b80\u79f0\u5783\u573e\u8bed\u8a00\u3002\u6ca1\u6709\u8bf4 Java \u5783\u573e\u7684\u610f\u601d\uff0c\u4f60\u8bf4\u5bf9\u5427\uff1f\u5783\u573e\u8bed\u8a00\u3002","title":"Java String"},{"location":"unicode/#cow","text":"\u62c5\u5fe7\uff1a\u90a3\u5c82\u4e0d\u662f\u6bcf\u6b21\u6211 += \u5b9e\u9645\u4e0a\u90fd\u767d\u767d\u6df1\u62f7\u8d1d\u4e86\u4e00\u4efd\u65b0\u7684 String \uff1f\u522b\u62c5\u5fc3\uff0c\u56e0\u4e3a\u5177\u4f53\u5b9e\u73b0\u4e0a\uff0cJava \u7684 String \u5728\u5e95\u5c42\u91c7\u7528\u4e86\u548c Qt \u7684 QString \u4e00\u6837\u7684 COW \u673a\u5236\uff1a \u5f53\u4e00\u4e2a QString \u88ab\u62f7\u8d1d\u6784\u9020\u65f6\uff0c\u5e76\u4e0d\u4f1a\u5bf9\u5176\u4e2d\u7684 QByteArray \u8fdb\u884c\u6df1\u62f7\u8d1d\uff0c\u800c\u662f\u5171\u4eab\u540c\u4e00\u7247\u5185\u5b58\u3002\u53ea\u6709\u5f53\u5176\u4e2d\u4e00\u4e2a QString \u88ab += \u7b49\u5e26\u6709\u526f\u4f5c\u7528\u64cd\u4f5c\u4fee\u6539\u65f6\uff0c\u624d\u4f1a\u6df1\u62f7\u8d1d\u4e00\u4efd\u65b0\u7684\uff0c\u8ba9\u4f60\u4fee\u6539\u3002\u8fd9\u6837\u5927\u5927\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\u548c\u6027\u80fd\u5f00\u9500\u3002 COW \u5b57\u7b26\u4e32\u7684\u7f3a\u70b9\u662f\uff1a\u5f53\u4f60\u5199\u591a\u7ebf\u7a0b\u5e76\u53d1\u65f6\uff0c\u672c\u6765\u591a\u7ebf\u7a0b\u53ea\u8bfb\u8bbf\u95ee\u540c\u4e00\u4e2a\u5b57\u7b26\u4e32\u662f\u5b89\u5168\u7684\uff0c\u4f46\u5982\u679c\u5b57\u7b26\u4e32\u6709 COW\uff0c\u8fde\u53ea\u8bfb\u8bbf\u95ee\u90fd\u4f1a\u4e0d\u5b89\u5168\u4e86\u3002\u4e4b\u540e\u6211\u4eec\u7684\u591a\u7ebf\u7a0b\u4e13\u9898\u8bfe\u4f1a\u8be6\u7ec6\u5206\u6790\u8fd9\u662f\u4e3a\u4ec0\u4e48\u3002 \u5176\u5b9e\u65e9\u671f\u7684 C++98 \u4e2d\uff0c std::string \u4e5f\u91c7\u7528\u4e86 COW \u673a\u5236\uff0c\u4f46\u540e\u6765\u56e0\u4e3a\u4e0d\u7b26\u5408\u7ebf\u7a0b\u5b89\u5168\u8981\u6c42\uff0c\u88ab\u8ffd\u6c42\u591a\u7ebf\u7a0b\u7684 C++11 \u8d23\u4ee4\u6539\u6b63\uff0c\u624d\u6709\u4e86\u540e\u6765 std::__cxx11::basic_string \u7684 ABI \u4e0d\u517c\u5bb9\u95ee\u9898\u3002\u6bd5\u7adf\u7ebf\u7a0b\u4e0d\u5b89\u5168\u5b9e\u5728\u592a\u4f24\u4e86\uff0c\u57fa\u672c\u610f\u5473\u7740\u591a\u7ebf\u7a0b\u5c31\u6ca1\u6cd5\u5171\u4eab std::string \u3002\u4e8b\u5b9e\u4e0a\uff0cQt \u6240\u6709\u7684\u5bf9\u8c61 QObject \uff0c\u5305\u62ec QString \u5728\u591a\u7ebf\u7a0b\u4e2d\u4f20\u9012\u65f6\uff0c\u5c31\u9700\u8981\u8c03\u7528 moveTo(QThread) \u8f6c\u79fb\u6240\u6709\u6743\uff0c\u624d\u80fd\u5b89\u5168\u5730\u4f20\u9012\u7ed9\u53e6\u4e00\u4e2a\u7ebf\u7a0b\uff0c\u5c31\u662f\u56e0\u4e3a Qt \u5927\u91cf\u4f7f\u7528\u4e86 COW \u673a\u5236\u3002","title":"COW \u5b57\u7b26\u4e32"},{"location":"unicode/#unicode_1","text":"","title":"Unicode \u77e5\u8bc6\u8fdb\u9636"},{"location":"unicode/#_22","text":"TODO","title":"\u5b57\u7b26\u7684\u663e\u793a\u5bbd\u5ea6\u8ba1\u7b97"},{"location":"unicode/#grapheme","text":"TODO","title":"Grapheme"},{"location":"unicode/#_23","text":"TODO","title":"\u6b63\u89c4\u5316"},{"location":"unicode/#_24","text":"TODO","title":"\u96f6\u5bbd\u7a7a\u683c"},{"location":"unicode/#_25","text":"TODO","title":"\u7279\u6b8a\u63a7\u5236\u5b57\u7b26"},{"location":"unicode/#unicode_2","text":"\u201c\ud883\udede\u201d\u7684 Unicode \u7f16\u53f7\u662f 0x30EDE\u3002 \u5728 Linux \u7cfb\u7edf\u4e2d\uff0c\u901a\u5e38\u53ef\u4ee5\u8f93\u5165 Ctrl+Shift+U \u7136\u540e\u8f93\u5165\u5341\u516d\u8fdb\u5236\u7f16\u53f7\uff0c3 0 E D E\uff0c\u7136\u540e Enter\uff0c\u5c31\u8f93\u5165\u4e86\u201c\ud883\udede\u201d\u3002 \u5728 Windows \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Win+R\uff0c\u7136\u540e\u8f93\u5165 charmap \uff0c\u6253\u5f00\u5b57\u7b26\u6620\u5c04\u8868\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u53cc\u51fb\u53ef\u4ee5\u590d\u5236\u5230\u526a\u8d34\u677f\u3002 \u5728 macOS \u7cfb\u7edf\u4e2d\uff0c\u53ef\u4ee5\u6309 Ctrl+Cmd+\u7a7a\u683c\uff0c\u6253\u5f00\u7279\u6b8a\u5b57\u7b26\u8f93\u5165\u9762\u677f\uff0c\u9009\u62e9\u201cUnicode\u201d\u5206\u7c7b\uff0c\u627e\u5230\u201c\ud883\udede\u201d\uff0c\u7136\u540e\u53cc\u51fb\u5c31\u8f93\u5165\u5230\u5149\u6807\u5904\u3002","title":"\u6839\u636e\u7f16\u53f7\u8f93\u5165 Unicode \u5b57\u7b26"},{"location":"unicode/#unifont","text":"TODO","title":"UniFont \u5b57\u4f53"},{"location":"unicode/#_26","text":"","title":"\u9ed1\u6697\u5c0f\u6280\u5de7"},{"location":"unicode/#_27","text":"\u72ed\u4e49\u7684\u6c49\u5b57\uff1a0x4E00 \u5230 0x9FA5\uff08\u201c\u4e00\u201d\u5230\u201c\u9fa5\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\uff1a0x2E80 \u5230 0x9FFF\uff08\u201c\u2e80\u201d\u5230\u201c\u9fff\u201d\uff09 \u5e7f\u4e49\u7684\u6c49\u5b57\u5305\u542b\u4e86\u51e0\u4e4e\u6240\u6709\u4e2d\u65e5\u97e9\u4f7f\u7528\u7684\u6c49\u5b57\u5b57\u7b26\uff0c\u800c\u72ed\u4e49\u7684\u6c49\u5b57\u53ea\u662f\u4e2d\u6587\u91cc\u6700\u5e38\u7528\u7684\u4e00\u90e8\u5206\u3002 TODO","title":"\u6b63\u5219\u8868\u8fbe\u5f0f\u5339\u914d\u6c49\u5b57\uff1f"},{"location":"unicode/#latin-1_1","text":"Latin-1 \u662f\u4e00\u4e2a 8 \u4f4d\u7f16\u7801\uff0c\u80fd\u8868\u793a 256 \u4e2a\u5b57\u7b26\uff0c\u5305\u62ec\u4e86\u62c9\u4e01\u5b57\u6bcd\u3001\u963f\u62c9\u4f2f\u6570\u5b57\u3001\u6807\u70b9\u7b26\u53f7\u3001\u5e38\u7528\u7684\u897f\u6b27\u5b57\u7b26\uff0c\u4ee5\u53ca\u4e00\u4e9b\u7279\u6b8a\u5b57\u7b26\u3002 \u56e0\u6b64\uff0c\u5982\u679c\u4f60\u9700\u8981\u628a\u4e00\u4e2a Latin-1 \u7f16\u7801\u7684 char \u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a wchar_t \u5b57\u7b26\u4e32\uff0c\u53ef\u4ee5\u901a\u8fc7\u8fed\u4ee3\u5668\u63a5\u53e3\u6784\u9020 std::wstring \uff0c\u8fd9\u6837 char \u4f1a\u88ab\u9010\u4e2a\u8f6c\u6362\u4e3a wchar_t \u3002 std::string latin1 = \"I love P\\xE9ng\"; // 0xE9: \u00e9 std::wstring wstr(latin1.begin(), latin1.end()); std::wcout << wstr << '\\n'; \u8f93\u51fa\uff1a I love P\u00e9ng \u5e76\u4e0d\u6807\u51c6\u7684\u505a\u6cd5\uff0c\u8fd8\u662f\u5efa\u8bae\u7528 boost::locale::conv::to_utf(latin1, \"Latin-1\") \u3002","title":"Latin-1 \u7684\u8f6c\u6362"},{"location":"unicode/#latin-1_2","text":"\u7531\u4e8e Latin-1 \u8986\u76d6\u4e86\u6240\u6709\u7684 256 \u4e2a char \u7684\u53ef\u80fd\u503c\uff0c\u4efb\u4f55\u5b57\u8282\u6d41\u90fd\u53ef\u4ee5\u6210\u529f\u89e3\u7801\u3002 GBK \u548c UTF-8 \u6709\u81ea\u7ea0\u9519\u6027\uff0c\u6709\u4e9b\u8f93\u5165\u4f1a\u88ab\u584c\u7f29\u6210\u9519\u8bef\u201c\ufffd\u201d\u3002Latin-1 \u5c31\u6ca1\u6709\u8fd9\u4e2a\u95ee\u9898\uff0c\u4ed6\u7167\u5355\u5168\u6536\uff01 \u56e0\u6b64\u6709\u65f6\uff0c\u4eba\u4eec\u53ef\u4ee5\u6b3a\u9a97\u4e00\u4e2a\u7f16\u7801\u5668\u8bf4\u201c\u6211\u91c7\u7528\u7684\u5b57\u7b26\u7f16\u7801\u662f Latin-1\u201d\uff01\u8fd9\u6837\u7f16\u7801\u5668\u5c31\u4e0d\u4f1a\u5bf9\u8f93\u5165\u7684\u5b57\u8282\u6d41\u505a\u4efb\u4f55\u8f6c\u6362\uff0c\u4ece\u800c\u53ef\u4ee5\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u5f53\u6587\u672c\u6765\u4f20\uff0c\u89e3\u7801\u65f6\u4e5f\u6307\u5b9a Latin-1\uff0c\u539f\u539f\u672c\u672c\u7684\u53d6\u51fa\u6570\u636e\u3002","title":"Latin-1 \u7684\u5999\u7528"},{"location":"unicode/#base64","text":"\u5982\u679c\u8981\u628a\u4e00\u4e32\u4e2d\u6587\u8f93\u5165\u4e00\u4e2a\u4e0d\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\uff0c\u53d1\u9001\u8ba9\u5bf9\u65b9\u6536\u5230\uff0c\u600e\u4e48\u529e\uff1f \u53ef\u4ee5\u7528 Latin-1 \u7f16\u7801\uff0c\u9a97\u8fd9\u4e2a\u8f6f\u4ef6\uff0c\u8ba9\u4ed6\u4ee5\u4e3a\u81ea\u5df1\u6536\u5230\u7684\u662f Latin-1 \u5b57\u7b26\u4e32\uff0c\u53cd\u6b63\u4ed6\u4e5f\u4e0d\u770b\u5185\u5bb9\uff0c\u4ece\u800c\u8ba9\u4ed6\u4e0d\u8981\u505a\u4efb\u4f55\u8f6c\u6362\u64cd\u4f5c\u3002 \u4e0d\u8fc7\u6709\u65f6\u5019\uff0c\u6587\u672c\u6846\u65e0\u6cd5\u8f93\u5165\u90e8\u5206\u7279\u6b8a\u7684\u63a7\u5236\u5b57\u7b26\uff0c\u800c UTF-8 \u5b57\u7b26\u4e32\u7f16\u7801\u51fa\u6765\u7684\u6587\u672c\uff0c\u8d85\u8fc7 0x80 \u7684\u90e8\u5206\uff0c\u53ef\u80fd\u843d\u5165 Latin-1 \u7684\u63a7\u5236\u5b57\u7b26\u4e2d\uff0c\u88ab\u8fd9\u4e2a\u8f6f\u4ef6\u9519\u8bef\u5730\u505a\u4e86\u7279\u6b8a\u5904\u7406\u3002 \u4e3a\u4e86\u907f\u514d\u53ea\u517c\u5bb9\u4e86 ASCII \u7684\u843d\u540e\u8f6f\u4ef6\u7834\u574f\u6211\u4eec\u7684\u5b57\u7b26\uff0c\u5bf9\u4e8e\u8fd9\u79cd\u53ea\u652f\u6301 ASCII \u6587\u672c\u7684\u7f16\u8f91\u6846\uff0c\u6211\u4eec\u53ef\u4ee5\u7528 Base64 \u7f16\u7801\u5148\u628a\u4efb\u610f\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u3002 Base64 \u662f\u4e00\u79cd\u628a\u4e8c\u8fdb\u5236\u6570\u636e\u8f6c\u6362\u4e3a ASCII \u5b57\u7b26\u4e32\u7684\u7b97\u6cd5\uff0c\u539f\u7406\u5f88\u7b80\u5355\uff0c\u5c31\u662f\u628a\u6bcf 6 \u4e2a\u4e8c\u8fdb\u5236\u4f4d\u8f6c\u6362\u4e3a\u4e00\u4e2a\u53ef\u6253\u5370\u7684 ASCII \u5b57\u7b26\uff08\u7528 A-Z a-z 0-9 - / \u8fd9 64 \u4e2a\u5b57\u7b26\u8868\u793a\uff09\u3002\u56e0\u6b64\uff0cBase64 \u7f16\u7801\u540e\u7684\u6587\u672c\uff0c\u6bcf 4 \u4e2a\u5b57\u7b26\u5c31\u6709 3 \u4e2a\u662f\u6709\u6548\u5b57\u7b26\uff0c\u5269\u4e0b\u7684 1 \u4e2a\u5b57\u7b26\u662f\u586b\u5145\u5b57\u7b26 = \u3002 \u4f8b\u5982\uff0c\u5b57\u7b26\u4e32 \"\u5c0f\u5f6d\u8001\u5e08\" \uff0c\u4f60\u53ef\u80fd\u60f3\u8981\u628a\u5b83\u901a\u8fc7\u90ae\u4ef6\u53d1\u51fa\u53bb\u3002\u800c\u8fd9\u4e2a\u90ae\u4ef6\u670d\u52a1\u5668\u4e0d\u652f\u6301 UTF-8 \u4e5f\u4e0d\u652f\u6301 GBK\uff0c\u53ea\u652f\u6301 ASCII\uff01 \u9996\u5148\u6211\u4eec\u7528 UTF-8 \u7f16\u7801\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff1a 0xE5 0xB0 0x8F 0xE5 0xBD 0xAD 0xE8 0x80 0x81 0xE5 0xB8 0x88 \u7136\u540e\u518d\u7528 Base64 \u4e8c\u6b21\u7f16\u7801\u6210\u666e\u901a\u7684\u53ef\u6253\u5370\u5b57\u6bcd\u548c\u6570\u5b57\u5e8f\u5217\uff1a 5bCP5b2t6ICB5biI \u5bf9\u65b9\u6536\u5230\u8fd9\u4e32\u795e\u79d8\u5b57\u7b26\u540e\uff0c\u518d\u7528 base64 \u89e3\u7801\uff0c\u5f97\u5230\u4e8c\u8fdb\u5236\u5b57\u8282\u6d41\uff0c\u518d\u7528\u652f\u6301 UTF-8 \u7684\u8f6f\u4ef6\u89e3\u7801\uff0c\u5c31\u80fd\u770b\u5230\u672c\u6765\u7684\u4e2d\u6587\u4e86\u3002 # \u53d1\u9001\u8005\uff1a import base64 secret = base64.b64encode(\"\u5c0f\u5f6d\u8001\u5e08\".encode()) # \u63a5\u6536\u8005\uff1a base64.b64decode(secret).decode() \u8fd9\u4e2a\u65b9\u6cd5\u4e0d\u4ec5\u53ef\u4ee5\u7f16\u7801 UTF-8 \u5b57\u7b26\u4e32\uff0c\u8fd8\u53ef\u4ee5\u4f20\u8f93\u4efb\u610f\u975e\u6587\u672c\u7684\u6587\u4ef6\uff01\u4f8b\u5982\uff0c\u6709\u4eba\u5229\u7528 Base64 \u7f16\u7801\uff0c\u628a jpg \u56fe\u50cf\u6587\u4ef6\u76f4\u63a5\u5185\u5d4c\u5728 md \u6587\u4ef6\u91cc\uff01\uff08md \u6587\u4ef6\u53ea\u652f\u6301\u5305\u542b\u5408\u6cd5\u7684 UTF-8 \u6587\u672c\uff0c\u4e0d\u53ef\u80fd\u5305\u542b jpg \u7684\u4efb\u610f\u5b57\u8282\u6d41\uff0c\u56e0\u6b64\u53ea\u80fd\u7528 Base64 \u5148\u7f16\u7801\u6210 ASCII \u8303\u56f4\u5185\u7684\u5b57\u6bcd\u548c\u6570\u5b57\uff0c\u9632\u6b62 md \u7f16\u8bd1\u5668\u62a5 UTF-8 \u89e3\u7801\u9519\u8bef\uff09 \u603b\u4e4b\uff0c\u5982\u679c\u4f60\u8f93\u5165\u4e2d\u6587\u5b9e\u5728\u6709\u95ee\u9898\uff0c\u53ef\u4ee5\u8003\u8651\u5148 Base64 \u8f6c\u6362\u6210\u7eaf\u82f1\u6587\u8bd5\u8bd5\u770b\uff0c\u53cd\u6b63\u65e0\u8bba\u8c01\u90fd\u517c\u5bb9 ASCII\u3002\u5982\u679c\u8fd9\u4e2a\u6587\u672c\u6846\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff0c\u8fd8\u53ef\u4ee5\u8bd5\u8bd5\u770b\u53ea\u6709 A-Z 0-9 \u7684 Base32 \u7f16\u7801\u3002","title":"Base64 \u9632\u4e71\u7801"},{"location":"unicode/#utf-7","text":"TODO","title":"UTF-7"},{"location":"unicode/#_28","text":"TODO","title":"\u5b57\u7b26\u7f16\u7801\u731c\u6d4b"},{"location":"variable_types/","text":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) \u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) TODO","title":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5)"},{"location":"variable_types/#_1","text":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5) TODO","title":"\u53d8\u91cf\u4e0e\u7c7b\u578b (\u672a\u5b8c\u5de5)"}]} \ No newline at end of file