[{"data":1,"prerenderedAt":6725},["ShallowReactive",2],{"wiki-page-\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1500-future-async-promise":3,"wiki-doc-items-2023-10-05-cplusplus-jiao-xue":6167,"wiki:author-members":6713},{"id":4,"title":5,"authors":6,"body":8,"chapterDepth":67,"chapterOrder":6154,"date":6155,"description":6156,"docKey":6157,"docRoot":6158,"docTitle":6159,"extension":6160,"isWikiDoc":295,"isWikiIndex":6161,"meta":6162,"navigation":295,"path":6163,"seo":6164,"stem":6165,"wikiDepth":56,"__hash__":6166},"wiki\u002Fwiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1500-future-async-promise.md","future、async、promise 与 packaged_task",[7],"董佳辉",{"type":9,"value":10,"toc":6077},"minimark",[11,19,29,32,38,45,97,100,109,112,118,121,126,134,139,146,149,165,168,174,177,191,193,197,203,206,213,216,222,225,231,233,249,252,258,260,267,270,494,497,503,506,550,552,558,561,577,580,583,602,605,619,622,628,631,637,639,650,652,662,665,681,683,731,734,740,743,749,752,769,772,774,778,784,789,804,806,842,845,852,855,861,864,870,873,885,888,893,899,903,909,911,917,920,936,938,974,977,979,986,988,1215,1217,1223,1226,1232,1235,1241,1243,1253,1256,1262,1265,1271,1273,1279,1281,1285,1288,1310,1313,1319,1322,1337,1340,1346,1349,1354,1357,1371,1373,1407,1409,1413,1419,1428,1449,1452,1458,1460,1529,1532,1538,1541,1547,1549,1556,1558,1622,1624,1636,1639,1642,1656,1659,1665,1670,1677,1683,1686,1707,1713,1725,1727,1733,1736,1749,1752,1757,1759,1862,1864,1870,1872,1883,1886,1892,1895,1901,1903,1909,1912,1917,1920,1934,1936,1986,1988,1999,2002,2005,2008,2020,2023,2029,2031,2038,2041,2044,2056,2059,2062,2065,2077,2080,2082,2088,2090,2096,2099,2142,2145,2183,2186,2192,2195,2419,2422,2428,2431,2437,2439,2445,2448,2460,2463,2478,2481,2486,2489,2491,2525,2528,2575,2578,2581,2587,2589,2593,2599,2601,2789,2791,2797,2800,2812,2815,2818,2824,2826,2838,2841,2847,2850,2856,2859,2865,2867,2873,2876,2887,2890,2893,2899,2902,2923,2926,2933,2936,2942,2945,2951,2953,2959,2962,2978,2981,3007,3010,3013,3019,3022,3024,3028,3231,3233,3239,3242,3248,3250,3257,3263,3266,3272,3274,3309,3312,3314,3320,3323,3329,3332,3334,3340,3343,3361,3363,3368,3371,3377,3380,3392,3395,3398,3411,3414,3416,3429,3431,3436,3438,3442,3444,3473,3476,3479,3482,3497,3500,3503,3514,3517,3527,3530,3536,3538,3544,3547,3561,3564,3589,3592,3700,3703,3715,3718,3724,3726,3730,4041,4043,4049,4052,4058,4060,4064,4067,4122,4125,4131,4134,4137,4144,4147,4153,4156,4158,4170,4173,4183,4186,4191,4193,4197,4200,4211,4214,4220,4223,4229,4231,4237,4242,4245,4289,4292,4298,4301,4312,4314,4321,4323,4327,4503,4505,4511,4513,4538,4540,4546,4548,4587,4590,4609,4612,4618,4620,4624,4629,4636,4638,4654,4659,4666,4668,4674,4676,4682,4685,4724,4727,4756,4759,4770,4780,4782,4794,4797,4800,4806,4809,4815,4817,4823,4826,4998,5000,5005,5007,5034,5036,5042,5044,5048,5054,5064,5067,5070,5086,5089,5095,5098,5100,5104,5107,5113,5116,5126,5129,5132,5138,5141,5143,5151,5154,5159,5162,5168,5170,5182,5185,5187,5191,5193,5199,5201,5229,5232,5242,5245,5248,5254,5256,5262,5265,5282,5285,5291,5294,5306,5309,5311,5316,5318,5336,5338,5342,5344,5418,5421,5451,5454,5456,5460,5463,5469,5472,5478,5480,5486,5488,5494,5496,5499,5502,5508,5514,5516,5522,5524,5531,5534,5540,5542,5560,5562,5568,5570,5572,5578,5580,5597,5599,5605,5607,5613,5616,5626,5629,5635,5638,5641,5647,5650,5656,5659,5674,5676,5679,5687,5689,5703,5706,5712,5715,5744,5746,5752,5755,5776,5781,5783,5790,5792,5839,5842,5845,5887,5889,5893,5896,5902,5905,5910,5912,5916,5919,5924,5927,5942,5944,5948,5950,6010,6013,6019,6022,6033,6036,6038,6041,6044,6050,6052,6058,6061,6067,6073],[12,13,14,18],"p",{},[15,16,17],"code",{},"std::thread"," 很适合表达：",[20,21,27],"pre",{"className":22,"code":24,"language":25,"meta":26},[23],"language-text","启动一个线程\n↓\n在线程里执行某个函数\n","text","",[15,28,24],{"__ignoreMap":26},[12,30,31],{},"但它本身并不直接解决：",[20,33,36],{"className":34,"code":35,"language":25,"meta":26},[23],"线程函数怎么把返回值交回来？\n\n线程里抛出的异常怎么传回来？\n\n主线程怎么知道结果准备好了？\n\n多个线程之间怎么建立“结果通道”？\n",[15,37,35],{"__ignoreMap":26},[12,39,40,41,44],{},"C++11 在 ",[15,42,43],{},"\u003Cfuture>"," 中提供了一组更偏向“任务与结果”的并发工具：",[20,46,50],{"className":47,"code":48,"language":49,"meta":26,"style":26},"language-cpp shiki shiki-themes github-light github-dark","std::future\nstd::async\nstd::promise\nstd::packaged_task\nstd::shared_future\n","cpp",[15,51,52,65,73,81,89],{"__ignoreMap":26},[53,54,57,61],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sScJk","std",[53,62,64],{"class":63},"sVt8B","::future\n",[53,66,68,70],{"class":55,"line":67},2,[53,69,60],{"class":59},[53,71,72],{"class":63},"::async\n",[53,74,76,78],{"class":55,"line":75},3,[53,77,60],{"class":59},[53,79,80],{"class":63},"::promise\n",[53,82,84,86],{"class":55,"line":83},4,[53,85,60],{"class":59},[53,87,88],{"class":63},"::packaged_task\n",[53,90,92,94],{"class":55,"line":91},5,[53,93,60],{"class":59},[53,95,96],{"class":63},"::shared_future\n",[12,98,99],{},"它们的核心思想可以概括成一句话：",[101,102,103],"blockquote",{},[12,104,105],{},[106,107,108],"strong",{},"结果现在还没有，但未来会产生；先拿到一个 future，之后再等待或取得结果。",[12,110,111],{},"所以：",[20,113,116],{"className":114,"code":115,"language":25,"meta":26},[23],"std::thread\n→ 更关心“线程本身”\n\nstd::future \u002F std::async \u002F std::promise\n→ 更关心“任务最终产生什么结果”\n",[15,117,115],{"__ignoreMap":26},[119,120],"hr",{},[122,123,125],"h2",{"id":124},"future-和-async-基础","future 和 async 基础",[127,128,130,133],"h3",{"id":129},"stdfuturet-是什么",[15,131,132],{},"std::future\u003CT>"," 是什么",[12,135,136,138],{},[15,137,132],{}," 可以理解成：",[101,140,141],{},[12,142,143],{},[106,144,145],{},"一个“未来结果”的读取端。",[12,147,148],{},"例如：",[20,150,152],{"className":47,"code":151,"language":49,"meta":26,"style":26},"std::future\u003Cint>\n",[15,153,154],{"__ignoreMap":26},[53,155,156,158,161],{"class":55,"line":56},[53,157,60],{"class":59},[53,159,160],{"class":63},"::future",[53,162,164],{"class":163},"szBVR","\u003Cint>\n",[12,166,167],{},"表示：",[20,169,172],{"className":170,"code":171,"language":25,"meta":26},[23],"未来某个时刻\n会有一个 int 结果\n",[15,173,171],{"__ignoreMap":26},[12,175,176],{},"如果任务没有返回值，则可以使用：",[20,178,180],{"className":47,"code":179,"language":49,"meta":26,"style":26},"std::future\u003Cvoid>\n",[15,181,182],{"__ignoreMap":26},[53,183,184,186,188],{"class":55,"line":56},[53,185,60],{"class":59},[53,187,160],{"class":63},[53,189,190],{"class":163},"\u003Cvoid>\n",[119,192],{},[127,194,196],{"id":195},"future-背后其实有一个-shared-state","future 背后其实有一个 shared state",[12,198,199,202],{},[15,200,201],{},"future"," 本身并不是结果，也不是线程。",[12,204,205],{},"它关联的是一个：",[101,207,208],{},[12,209,210],{},[106,211,212],{},"共享状态（shared state）",[12,214,215],{},"可以理解成：",[20,217,220],{"className":218,"code":219,"language":25,"meta":26},[23],"生产者\n写入结果 \u002F 异常\n      ↓\n shared state\n      ↓\n   future\n读取结果 \u002F 异常\n",[15,221,219],{"__ignoreMap":26},[12,223,224],{},"共享状态里可能保存：",[20,226,229],{"className":227,"code":228,"language":25,"meta":26},[23],"任务返回值\n\n任务抛出的异常\n\n结果是否已经准备好\n\n等待和同步所需的信息\n",[15,230,228],{"__ignoreMap":26},[12,232,111],{},[20,234,236],{"className":47,"code":235,"language":49,"meta":26,"style":26},"future.get();\n",[15,237,238],{"__ignoreMap":26},[53,239,240,243,246],{"class":55,"line":56},[53,241,242],{"class":63},"future.",[53,244,245],{"class":59},"get",[53,247,248],{"class":63},"();\n",[12,250,251],{},"真正做的事情可以理解成：",[20,253,256],{"className":254,"code":255,"language":25,"meta":26},[23],"如果结果还没准备好\n→ 等待\n\n结果准备好以后\n→ 取出结果\n\n如果任务保存的是异常\n→ 在这里重新抛出\n",[15,257,255],{"__ignoreMap":26},[119,259],{},[127,261,263,264],{"id":262},"最简单的-stdasync","最简单的 ",[15,265,266],{},"std::async",[12,268,269],{},"来看一个最简单的例子：",[20,271,273],{"className":47,"code":272,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n\nint calculate(int a, int b)\n{\n    return a + b;\n}\n\nint main()\n{\n    std::future\u003Cint> result = std::async(\n        std::launch::async,\n        calculate,\n        10,\n        20);\n\n    std::println(\"main continues\");\n\n    std::println(\"{}\", result.get());\n}\n",[15,274,275,284,291,297,325,330,345,351,356,367,372,401,415,421,431,440,445,462,467,489],{"__ignoreMap":26},[53,276,277,280],{"class":55,"line":56},[53,278,279],{"class":163},"#include",[53,281,283],{"class":282},"sZZnC"," \u003Cfuture>\n",[53,285,286,288],{"class":55,"line":67},[53,287,279],{"class":163},[53,289,290],{"class":282}," \u003Cprint>\n",[53,292,293],{"class":55,"line":75},[53,294,296],{"emptyLinePlaceholder":295},true,"\n",[53,298,299,302,305,308,310,314,317,319,322],{"class":55,"line":83},[53,300,301],{"class":163},"int",[53,303,304],{"class":59}," calculate",[53,306,307],{"class":63},"(",[53,309,301],{"class":163},[53,311,313],{"class":312},"s4XuR"," a",[53,315,316],{"class":63},", ",[53,318,301],{"class":163},[53,320,321],{"class":312}," b",[53,323,324],{"class":63},")\n",[53,326,327],{"class":55,"line":91},[53,328,329],{"class":63},"{\n",[53,331,333,336,339,342],{"class":55,"line":332},6,[53,334,335],{"class":163},"    return",[53,337,338],{"class":63}," a ",[53,340,341],{"class":163},"+",[53,343,344],{"class":63}," b;\n",[53,346,348],{"class":55,"line":347},7,[53,349,350],{"class":63},"}\n",[53,352,354],{"class":55,"line":353},8,[53,355,296],{"emptyLinePlaceholder":295},[53,357,359,361,364],{"class":55,"line":358},9,[53,360,301],{"class":163},[53,362,363],{"class":59}," main",[53,365,366],{"class":63},"()\n",[53,368,370],{"class":55,"line":369},10,[53,371,329],{"class":63},[53,373,375,378,380,383,386,389,392,395,398],{"class":55,"line":374},11,[53,376,377],{"class":59},"    std",[53,379,160],{"class":63},[53,381,382],{"class":163},"\u003Cint>",[53,384,385],{"class":63}," result ",[53,387,388],{"class":163},"=",[53,390,391],{"class":59}," std",[53,393,394],{"class":63},"::",[53,396,397],{"class":59},"async",[53,399,400],{"class":63},"(\n",[53,402,404,407,409,412],{"class":55,"line":403},12,[53,405,406],{"class":59},"        std",[53,408,394],{"class":63},[53,410,411],{"class":59},"launch",[53,413,414],{"class":63},"::async,\n",[53,416,418],{"class":55,"line":417},13,[53,419,420],{"class":63},"        calculate,\n",[53,422,424,428],{"class":55,"line":423},14,[53,425,427],{"class":426},"sj4cs","        10",[53,429,430],{"class":63},",\n",[53,432,434,437],{"class":55,"line":433},15,[53,435,436],{"class":426},"        20",[53,438,439],{"class":63},");\n",[53,441,443],{"class":55,"line":442},16,[53,444,296],{"emptyLinePlaceholder":295},[53,446,448,450,452,455,457,460],{"class":55,"line":447},17,[53,449,377],{"class":59},[53,451,394],{"class":63},[53,453,454],{"class":59},"println",[53,456,307],{"class":63},[53,458,459],{"class":282},"\"main continues\"",[53,461,439],{"class":63},[53,463,465],{"class":55,"line":464},18,[53,466,296],{"emptyLinePlaceholder":295},[53,468,470,472,474,476,478,481,484,486],{"class":55,"line":469},19,[53,471,377],{"class":59},[53,473,394],{"class":63},[53,475,454],{"class":59},[53,477,307],{"class":63},[53,479,480],{"class":282},"\"{}\"",[53,482,483],{"class":63},", result.",[53,485,245],{"class":59},[53,487,488],{"class":63},"());\n",[53,490,492],{"class":55,"line":491},20,[53,493,350],{"class":63},[12,495,496],{},"可能输出：",[20,498,501],{"className":499,"code":500,"language":25,"meta":26},[23],"main continues\n30\n",[15,502,500],{"__ignoreMap":26},[12,504,505],{},"这里：",[20,507,509],{"className":47,"code":508,"language":49,"meta":26,"style":26},"std::async(\n    std::launch::async,\n    calculate,\n    10,\n    20);\n",[15,510,511,521,531,536,543],{"__ignoreMap":26},[53,512,513,515,517,519],{"class":55,"line":56},[53,514,60],{"class":59},[53,516,394],{"class":63},[53,518,397],{"class":59},[53,520,400],{"class":63},[53,522,523,525,527,529],{"class":55,"line":67},[53,524,377],{"class":59},[53,526,394],{"class":63},[53,528,411],{"class":59},[53,530,414],{"class":63},[53,532,533],{"class":55,"line":75},[53,534,535],{"class":63},"    calculate,\n",[53,537,538,541],{"class":55,"line":83},[53,539,540],{"class":426},"    10",[53,542,430],{"class":63},[53,544,545,548],{"class":55,"line":91},[53,546,547],{"class":426},"    20",[53,549,439],{"class":63},[12,551,215],{},[20,553,556],{"className":554,"code":555,"language":25,"meta":26},[23],"提交 calculate(10, 20) 这个任务\n↓\n让它异步执行\n↓\n返回一个 future\u003Cint>\n",[15,557,555],{"__ignoreMap":26},[12,559,560],{},"这个：",[20,562,564],{"className":47,"code":563,"language":49,"meta":26,"style":26},"std::future\u003Cint> result\n",[15,565,566],{"__ignoreMap":26},[53,567,568,570,572,574],{"class":55,"line":56},[53,569,60],{"class":59},[53,571,160],{"class":63},[53,573,382],{"class":163},[53,575,576],{"class":63}," result\n",[12,578,579],{},"就是未来结果的读取端。",[12,581,582],{},"主线程继续执行：",[20,584,586],{"className":47,"code":585,"language":49,"meta":26,"style":26},"std::println(\"main continues\");\n",[15,587,588],{"__ignoreMap":26},[53,589,590,592,594,596,598,600],{"class":55,"line":56},[53,591,60],{"class":59},[53,593,394],{"class":63},[53,595,454],{"class":59},[53,597,307],{"class":63},[53,599,459],{"class":282},[53,601,439],{"class":63},[12,603,604],{},"直到：",[20,606,608],{"className":47,"code":607,"language":49,"meta":26,"style":26},"result.get();\n",[15,609,610],{"__ignoreMap":26},[53,611,612,615,617],{"class":55,"line":56},[53,613,614],{"class":63},"result.",[53,616,245],{"class":59},[53,618,248],{"class":63},[12,620,621],{},"如果任务已经完成：",[20,623,626],{"className":624,"code":625,"language":25,"meta":26},[23],"直接取得结果\n",[15,627,625],{"__ignoreMap":26},[12,629,630],{},"如果任务还没完成：",[20,632,635],{"className":633,"code":634,"language":25,"meta":26},[23],"当前线程在这里等待\n",[15,636,634],{"__ignoreMap":26},[12,638,111],{},[101,640,641],{},[12,642,643,645,646,649],{},[15,644,266],{}," 负责“提交任务”，",[15,647,648],{},"std::future"," 负责“以后拿结果”。",[119,651],{},[127,653,655,657,658,661],{"id":654},"async-的参数和-thread-很像",[15,656,397],{}," 的参数和 ",[15,659,660],{},"thread"," 很像",[12,663,664],{},"基本形式：",[20,666,668],{"className":47,"code":667,"language":49,"meta":26,"style":26},"std::async(policy, callable, arg1, arg2, ...);\n",[15,669,670],{"__ignoreMap":26},[53,671,672,674,676,678],{"class":55,"line":56},[53,673,60],{"class":59},[53,675,394],{"class":63},[53,677,397],{"class":59},[53,679,680],{"class":63},"(policy, callable, arg1, arg2, ...);\n",[12,682,148],{},[20,684,686],{"className":47,"code":685,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::async,\n    calculate,\n    10,\n    20);\n",[15,687,688,705,715,719,725],{"__ignoreMap":26},[53,689,690,693,695,697,699,701,703],{"class":55,"line":56},[53,691,692],{"class":163},"auto",[53,694,385],{"class":63},[53,696,388],{"class":163},[53,698,391],{"class":59},[53,700,394],{"class":63},[53,702,397],{"class":59},[53,704,400],{"class":63},[53,706,707,709,711,713],{"class":55,"line":67},[53,708,377],{"class":59},[53,710,394],{"class":63},[53,712,411],{"class":59},[53,714,414],{"class":63},[53,716,717],{"class":55,"line":75},[53,718,535],{"class":63},[53,720,721,723],{"class":55,"line":83},[53,722,540],{"class":426},[53,724,430],{"class":63},[53,726,727,729],{"class":55,"line":91},[53,728,547],{"class":426},[53,730,439],{"class":63},[12,732,733],{},"其中：",[20,735,738],{"className":736,"code":737,"language":25,"meta":26},[23],"policy\n→ 任务怎么启动\n\ncallable\n→ 要执行的函数 \u002F lambda \u002F 函数对象\n\narg1, arg2...\n→ 传给这个可调用对象的参数\n",[15,739,737],{"__ignoreMap":26},[12,741,742],{},"可调用对象可以是：",[20,744,747],{"className":745,"code":746,"language":25,"meta":26},[23],"普通函数\n\nlambda\n\n函数对象\n\n成员函数\n",[15,748,746],{"__ignoreMap":26},[12,750,751],{},"如果需要传引用，同样需要考虑：",[20,753,755],{"className":47,"code":754,"language":49,"meta":26,"style":26},"std::ref(x)\n",[15,756,757],{"__ignoreMap":26},[53,758,759,761,763,766],{"class":55,"line":56},[53,760,60],{"class":59},[53,762,394],{"class":63},[53,764,765],{"class":59},"ref",[53,767,768],{"class":63},"(x)\n",[12,770,771],{},"以及引用对象的生命周期问题。",[119,773],{},[122,775,777],{"id":776},"async-启动策略","async 启动策略",[127,779,781],{"id":780},"stdlaunchasync",[15,782,783],{},"std::launch::async",[12,785,786,788],{},[15,787,266],{}," 最常用的启动策略之一是：",[20,790,792],{"className":47,"code":791,"language":49,"meta":26,"style":26},"std::launch::async\n",[15,793,794],{"__ignoreMap":26},[53,795,796,798,800,802],{"class":55,"line":56},[53,797,60],{"class":59},[53,799,394],{"class":63},[53,801,411],{"class":59},[53,803,72],{"class":63},[12,805,148],{},[20,807,809],{"className":47,"code":808,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::async,\n    task);\n",[15,810,811,827,837],{"__ignoreMap":26},[53,812,813,815,817,819,821,823,825],{"class":55,"line":56},[53,814,692],{"class":163},[53,816,385],{"class":63},[53,818,388],{"class":163},[53,820,391],{"class":59},[53,822,394],{"class":63},[53,824,397],{"class":59},[53,826,400],{"class":63},[53,828,829,831,833,835],{"class":55,"line":67},[53,830,377],{"class":59},[53,832,394],{"class":63},[53,834,411],{"class":59},[53,836,414],{"class":63},[53,838,839],{"class":55,"line":75},[53,840,841],{"class":63},"    task);\n",[12,843,844],{},"它表示：",[101,846,847],{},[12,848,849],{},[106,850,851],{},"要求这个任务异步执行。",[12,853,854],{},"可以先直观理解成：",[20,856,859],{"className":857,"code":858,"language":25,"meta":26},[23],"现在把任务安排出去执行\n\n当前线程继续干自己的事\n\n以后通过 future 等结果\n",[15,860,858],{"__ignoreMap":26},[12,862,863],{},"重点是：",[20,865,868],{"className":866,"code":867,"language":25,"meta":26},[23],"调用方关心的是任务和结果\n而不是手动管理 thread 对象\n",[15,869,867],{"__ignoreMap":26},[12,871,872],{},"所以它和：",[20,874,876],{"className":47,"code":875,"language":49,"meta":26,"style":26},"std::thread\n",[15,877,878],{"__ignoreMap":26},[53,879,880,882],{"class":55,"line":56},[53,881,60],{"class":59},[53,883,884],{"class":63},"::thread\n",[12,886,887],{},"的使用视角不一样。",[12,889,890,892],{},[15,891,17],{}," 更像：",[20,894,897],{"className":895,"code":896,"language":25,"meta":26},[23],"我要创建并管理一个线程\n",[15,898,896],{"__ignoreMap":26},[12,900,901,892],{},[15,902,266],{},[20,904,907],{"className":905,"code":906,"language":25,"meta":26},[23],"我要提交一个任务\n最后拿它的结果\n",[15,908,906],{"__ignoreMap":26},[119,910],{},[127,912,914],{"id":913},"stdlaunchdeferred",[15,915,916],{},"std::launch::deferred",[12,918,919],{},"另一个启动策略是：",[20,921,923],{"className":47,"code":922,"language":49,"meta":26,"style":26},"std::launch::deferred\n",[15,924,925],{"__ignoreMap":26},[53,926,927,929,931,933],{"class":55,"line":56},[53,928,60],{"class":59},[53,930,394],{"class":63},[53,932,411],{"class":59},[53,934,935],{"class":63},"::deferred\n",[12,937,148],{},[20,939,941],{"className":47,"code":940,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::deferred,\n    task);\n",[15,942,943,959,970],{"__ignoreMap":26},[53,944,945,947,949,951,953,955,957],{"class":55,"line":56},[53,946,692],{"class":163},[53,948,385],{"class":63},[53,950,388],{"class":163},[53,952,391],{"class":59},[53,954,394],{"class":63},[53,956,397],{"class":59},[53,958,400],{"class":63},[53,960,961,963,965,967],{"class":55,"line":67},[53,962,377],{"class":59},[53,964,394],{"class":63},[53,966,411],{"class":59},[53,968,969],{"class":63},"::deferred,\n",[53,971,972],{"class":55,"line":75},[53,973,841],{"class":63},[12,975,976],{},"它并不会立刻把任务放到后台执行。",[12,978,844],{},[101,980,981],{},[12,982,983],{},[106,984,985],{},"先把这个任务记下来，等真正有人等待结果时再执行。",[12,987,148],{},[20,989,991],{"className":47,"code":990,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cthread>\n\nint task()\n{\n    std::println(\n        \"task thread: {}\",\n        std::this_thread::get_id());\n\n    return 42;\n}\n\nint main()\n{\n    std::println(\n        \"main thread: {}\",\n        std::this_thread::get_id());\n\n    auto result = std::async(\n        std::launch::deferred,\n        task);\n\n    std::println(\"before get\");\n\n    std::println(\"{}\", result.get());\n}\n",[15,992,993,999,1005,1012,1016,1025,1029,1039,1046,1062,1066,1076,1080,1084,1092,1096,1106,1113,1127,1131,1148,1159,1165,1170,1186,1191,1210],{"__ignoreMap":26},[53,994,995,997],{"class":55,"line":56},[53,996,279],{"class":163},[53,998,283],{"class":282},[53,1000,1001,1003],{"class":55,"line":67},[53,1002,279],{"class":163},[53,1004,290],{"class":282},[53,1006,1007,1009],{"class":55,"line":75},[53,1008,279],{"class":163},[53,1010,1011],{"class":282}," \u003Cthread>\n",[53,1013,1014],{"class":55,"line":83},[53,1015,296],{"emptyLinePlaceholder":295},[53,1017,1018,1020,1023],{"class":55,"line":91},[53,1019,301],{"class":163},[53,1021,1022],{"class":59}," task",[53,1024,366],{"class":63},[53,1026,1027],{"class":55,"line":332},[53,1028,329],{"class":63},[53,1030,1031,1033,1035,1037],{"class":55,"line":347},[53,1032,377],{"class":59},[53,1034,394],{"class":63},[53,1036,454],{"class":59},[53,1038,400],{"class":63},[53,1040,1041,1044],{"class":55,"line":353},[53,1042,1043],{"class":282},"        \"task thread: {}\"",[53,1045,430],{"class":63},[53,1047,1048,1050,1052,1055,1057,1060],{"class":55,"line":358},[53,1049,406],{"class":59},[53,1051,394],{"class":63},[53,1053,1054],{"class":59},"this_thread",[53,1056,394],{"class":63},[53,1058,1059],{"class":59},"get_id",[53,1061,488],{"class":63},[53,1063,1064],{"class":55,"line":369},[53,1065,296],{"emptyLinePlaceholder":295},[53,1067,1068,1070,1073],{"class":55,"line":374},[53,1069,335],{"class":163},[53,1071,1072],{"class":426}," 42",[53,1074,1075],{"class":63},";\n",[53,1077,1078],{"class":55,"line":403},[53,1079,350],{"class":63},[53,1081,1082],{"class":55,"line":417},[53,1083,296],{"emptyLinePlaceholder":295},[53,1085,1086,1088,1090],{"class":55,"line":423},[53,1087,301],{"class":163},[53,1089,363],{"class":59},[53,1091,366],{"class":63},[53,1093,1094],{"class":55,"line":433},[53,1095,329],{"class":63},[53,1097,1098,1100,1102,1104],{"class":55,"line":442},[53,1099,377],{"class":59},[53,1101,394],{"class":63},[53,1103,454],{"class":59},[53,1105,400],{"class":63},[53,1107,1108,1111],{"class":55,"line":447},[53,1109,1110],{"class":282},"        \"main thread: {}\"",[53,1112,430],{"class":63},[53,1114,1115,1117,1119,1121,1123,1125],{"class":55,"line":464},[53,1116,406],{"class":59},[53,1118,394],{"class":63},[53,1120,1054],{"class":59},[53,1122,394],{"class":63},[53,1124,1059],{"class":59},[53,1126,488],{"class":63},[53,1128,1129],{"class":55,"line":469},[53,1130,296],{"emptyLinePlaceholder":295},[53,1132,1133,1136,1138,1140,1142,1144,1146],{"class":55,"line":491},[53,1134,1135],{"class":163},"    auto",[53,1137,385],{"class":63},[53,1139,388],{"class":163},[53,1141,391],{"class":59},[53,1143,394],{"class":63},[53,1145,397],{"class":59},[53,1147,400],{"class":63},[53,1149,1151,1153,1155,1157],{"class":55,"line":1150},21,[53,1152,406],{"class":59},[53,1154,394],{"class":63},[53,1156,411],{"class":59},[53,1158,969],{"class":63},[53,1160,1162],{"class":55,"line":1161},22,[53,1163,1164],{"class":63},"        task);\n",[53,1166,1168],{"class":55,"line":1167},23,[53,1169,296],{"emptyLinePlaceholder":295},[53,1171,1173,1175,1177,1179,1181,1184],{"class":55,"line":1172},24,[53,1174,377],{"class":59},[53,1176,394],{"class":63},[53,1178,454],{"class":59},[53,1180,307],{"class":63},[53,1182,1183],{"class":282},"\"before get\"",[53,1185,439],{"class":63},[53,1187,1189],{"class":55,"line":1188},25,[53,1190,296],{"emptyLinePlaceholder":295},[53,1192,1194,1196,1198,1200,1202,1204,1206,1208],{"class":55,"line":1193},26,[53,1195,377],{"class":59},[53,1197,394],{"class":63},[53,1199,454],{"class":59},[53,1201,307],{"class":63},[53,1203,480],{"class":282},[53,1205,483],{"class":63},[53,1207,245],{"class":59},[53,1209,488],{"class":63},[53,1211,1213],{"class":55,"line":1212},27,[53,1214,350],{"class":63},[12,1216,215],{},[20,1218,1221],{"className":1219,"code":1220,"language":25,"meta":26},[23],"创建 async\n↓\ntask 此时还没执行\n↓\nmain 继续运行\n↓\n执行 result.get()\n↓\n就在调用 get() 的线程中执行 task()\n↓\n得到结果\n",[15,1222,1220],{"__ignoreMap":26},[12,1224,1225],{},"所以 deferred 并不是：",[20,1227,1230],{"className":1228,"code":1229,"language":25,"meta":26},[23],"后台线程晚一点执行\n",[15,1231,1229],{"__ignoreMap":26},[12,1233,1234],{},"而更接近：",[20,1236,1239],{"className":1237,"code":1238,"language":25,"meta":26},[23],"延迟到真正需要结果时\n再由等待结果的线程执行\n",[15,1240,1238],{"__ignoreMap":26},[119,1242],{},[127,1244,1246,1248,1249,1252],{"id":1245},"async-和-deferred-的区别",[15,1247,397],{}," 和 ",[15,1250,1251],{},"deferred"," 的区别",[12,1254,1255],{},"可以简单记成：",[20,1257,1260],{"className":1258,"code":1259,"language":25,"meta":26},[23],"std::launch::async\n\n→ 任务异步执行\n→ 当前线程可以继续\n→ future 以后取结果\n",[15,1261,1259],{"__ignoreMap":26},[12,1263,1264],{},"而：",[20,1266,1269],{"className":1267,"code":1268,"language":25,"meta":26},[23],"std::launch::deferred\n\n→ 任务先不执行\n→ 第一次 get()\u002Fwait() 时才执行\n→ 由调用等待函数的线程执行\n",[15,1270,1268],{"__ignoreMap":26},[12,1272,111],{},[20,1274,1277],{"className":1275,"code":1276,"language":25,"meta":26},[23],"async\n≈ “现在就安排执行”\n\ndeferred\n≈ “先记下来，用到结果时再执行”\n",[15,1278,1276],{"__ignoreMap":26},[119,1280],{},[127,1282,1284],{"id":1283},"不写-launch-policy-会怎样","不写 launch policy 会怎样",[12,1286,1287],{},"可以这样写：",[20,1289,1291],{"className":47,"code":1290,"language":49,"meta":26,"style":26},"auto result = std::async(task);\n",[15,1292,1293],{"__ignoreMap":26},[53,1294,1295,1297,1299,1301,1303,1305,1307],{"class":55,"line":56},[53,1296,692],{"class":163},[53,1298,385],{"class":63},[53,1300,388],{"class":163},[53,1302,391],{"class":59},[53,1304,394],{"class":63},[53,1306,397],{"class":59},[53,1308,1309],{"class":63},"(task);\n",[12,1311,1312],{},"但这种情况下，标准允许实现自己选择：",[20,1314,1317],{"className":1315,"code":1316,"language":25,"meta":26},[23],"async\n\n或者\n\ndeferred\n",[15,1318,1316],{"__ignoreMap":26},[12,1320,1321],{},"所以不要把：",[20,1323,1325],{"className":47,"code":1324,"language":49,"meta":26,"style":26},"std::async(task);\n",[15,1326,1327],{"__ignoreMap":26},[53,1328,1329,1331,1333,1335],{"class":55,"line":56},[53,1330,60],{"class":59},[53,1332,394],{"class":63},[53,1334,397],{"class":59},[53,1336,1309],{"class":63},[12,1338,1339],{},"自动理解成：",[20,1341,1344],{"className":1342,"code":1343,"language":25,"meta":26},[23],"一定立刻创建后台线程并发执行\n",[15,1345,1343],{"__ignoreMap":26},[12,1347,1348],{},"如果你明确要求：",[101,1350,1351],{},[12,1352,1353],{},"我就是想让任务真正异步执行。",[12,1355,1356],{},"那最好显式写：",[20,1358,1359],{"className":47,"code":791,"language":49,"meta":26,"style":26},[15,1360,1361],{"__ignoreMap":26},[53,1362,1363,1365,1367,1369],{"class":55,"line":56},[53,1364,60],{"class":59},[53,1366,394],{"class":63},[53,1368,411],{"class":59},[53,1370,72],{"class":63},[12,1372,148],{},[20,1374,1375],{"className":47,"code":808,"language":49,"meta":26,"style":26},[15,1376,1377,1393,1403],{"__ignoreMap":26},[53,1378,1379,1381,1383,1385,1387,1389,1391],{"class":55,"line":56},[53,1380,692],{"class":163},[53,1382,385],{"class":63},[53,1384,388],{"class":163},[53,1386,391],{"class":59},[53,1388,394],{"class":63},[53,1390,397],{"class":59},[53,1392,400],{"class":63},[53,1394,1395,1397,1399,1401],{"class":55,"line":67},[53,1396,377],{"class":59},[53,1398,394],{"class":63},[53,1400,411],{"class":59},[53,1402,414],{"class":63},[53,1404,1405],{"class":55,"line":75},[53,1406,841],{"class":63},[119,1408],{},[122,1410,1412],{"id":1411},"future-等待与异常","future 等待与异常",[127,1414,1416],{"id":1415},"futureget",[15,1417,1418],{},"future::get()",[12,1420,1421,1424,1425,1427],{},[15,1422,1423],{},"get()"," 是 ",[15,1426,201],{}," 最重要的函数之一：",[20,1429,1431],{"className":47,"code":1430,"language":49,"meta":26,"style":26},"auto value = future.get();\n",[15,1432,1433],{"__ignoreMap":26},[53,1434,1435,1437,1440,1442,1445,1447],{"class":55,"line":56},[53,1436,692],{"class":163},[53,1438,1439],{"class":63}," value ",[53,1441,388],{"class":163},[53,1443,1444],{"class":63}," future.",[53,1446,245],{"class":59},[53,1448,248],{"class":63},[12,1450,1451],{},"它做两件事：",[20,1453,1456],{"className":1454,"code":1455,"language":25,"meta":26},[23],"1. 等待结果准备好\n\n2. 取得结果\n",[15,1457,1455],{"__ignoreMap":26},[12,1459,148],{},[20,1461,1463],{"className":47,"code":1462,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::async,\n    [] {\n        return 42;\n    });\n\nint value = result.get();\n",[15,1464,1465,1481,1491,1496,1505,1510,1514],{"__ignoreMap":26},[53,1466,1467,1469,1471,1473,1475,1477,1479],{"class":55,"line":56},[53,1468,692],{"class":163},[53,1470,385],{"class":63},[53,1472,388],{"class":163},[53,1474,391],{"class":59},[53,1476,394],{"class":63},[53,1478,397],{"class":59},[53,1480,400],{"class":63},[53,1482,1483,1485,1487,1489],{"class":55,"line":67},[53,1484,377],{"class":59},[53,1486,394],{"class":63},[53,1488,411],{"class":59},[53,1490,414],{"class":63},[53,1492,1493],{"class":55,"line":75},[53,1494,1495],{"class":63},"    [] {\n",[53,1497,1498,1501,1503],{"class":55,"line":83},[53,1499,1500],{"class":163},"        return",[53,1502,1072],{"class":426},[53,1504,1075],{"class":63},[53,1506,1507],{"class":55,"line":91},[53,1508,1509],{"class":63},"    });\n",[53,1511,1512],{"class":55,"line":332},[53,1513,296],{"emptyLinePlaceholder":295},[53,1515,1516,1518,1520,1522,1525,1527],{"class":55,"line":347},[53,1517,301],{"class":163},[53,1519,1439],{"class":63},[53,1521,388],{"class":163},[53,1523,1524],{"class":63}," result.",[53,1526,245],{"class":59},[53,1528,248],{"class":63},[12,1530,1531],{},"如果任务还没执行完：",[20,1533,1536],{"className":1534,"code":1535,"language":25,"meta":26},[23],"get()\n→ 等\n",[15,1537,1535],{"__ignoreMap":26},[12,1539,1540],{},"任务结束以后：",[20,1542,1545],{"className":1543,"code":1544,"language":25,"meta":26},[23],"get()\n→ 返回 42\n",[15,1546,1544],{"__ignoreMap":26},[119,1548],{},[127,1550,1552,1553,1555],{"id":1551},"普通-futureget-通常只能调用一次","普通 ",[15,1554,1418],{}," 通常只能调用一次",[12,1557,148],{},[20,1559,1560],{"className":47,"code":1462,"language":49,"meta":26,"style":26},[15,1561,1562,1578,1588,1592,1600,1604,1608],{"__ignoreMap":26},[53,1563,1564,1566,1568,1570,1572,1574,1576],{"class":55,"line":56},[53,1565,692],{"class":163},[53,1567,385],{"class":63},[53,1569,388],{"class":163},[53,1571,391],{"class":59},[53,1573,394],{"class":63},[53,1575,397],{"class":59},[53,1577,400],{"class":63},[53,1579,1580,1582,1584,1586],{"class":55,"line":67},[53,1581,377],{"class":59},[53,1583,394],{"class":63},[53,1585,411],{"class":59},[53,1587,414],{"class":63},[53,1589,1590],{"class":55,"line":75},[53,1591,1495],{"class":63},[53,1593,1594,1596,1598],{"class":55,"line":83},[53,1595,1500],{"class":163},[53,1597,1072],{"class":426},[53,1599,1075],{"class":63},[53,1601,1602],{"class":55,"line":91},[53,1603,1509],{"class":63},[53,1605,1606],{"class":55,"line":332},[53,1607,296],{"emptyLinePlaceholder":295},[53,1609,1610,1612,1614,1616,1618,1620],{"class":55,"line":347},[53,1611,301],{"class":163},[53,1613,1439],{"class":63},[53,1615,388],{"class":163},[53,1617,1524],{"class":63},[53,1619,245],{"class":59},[53,1621,248],{"class":63},[12,1623,505],{},[20,1625,1626],{"className":47,"code":607,"language":49,"meta":26,"style":26},[15,1627,1628],{"__ignoreMap":26},[53,1629,1630,1632,1634],{"class":55,"line":56},[53,1631,614],{"class":63},[53,1633,245],{"class":59},[53,1635,248],{"class":63},[12,1637,1638],{},"把这个 future 里的结果取走了。",[12,1640,1641],{},"之后：",[20,1643,1645],{"className":47,"code":1644,"language":49,"meta":26,"style":26},"result.valid()\n",[15,1646,1647],{"__ignoreMap":26},[53,1648,1649,1651,1654],{"class":55,"line":56},[53,1650,614],{"class":63},[53,1652,1653],{"class":59},"valid",[53,1655,366],{"class":63},[12,1657,1658],{},"通常会变成：",[20,1660,1663],{"className":1661,"code":1662,"language":25,"meta":26},[23],"false\n",[15,1664,1662],{"__ignoreMap":26},[12,1666,1667,1668,138],{},"所以普通 ",[15,1669,648],{},[101,1671,1672],{},[12,1673,1674],{},[106,1675,1676],{},"一次性的取件凭证。",[20,1678,1681],{"className":1679,"code":1680,"language":25,"meta":26},[23],"结果准备好\n↓\nget()\n↓\n结果被取走\n↓\nfuture 不再关联有效共享状态\n",[15,1682,1680],{"__ignoreMap":26},[12,1684,1685],{},"因此不要这样写：",[20,1687,1689],{"className":47,"code":1688,"language":49,"meta":26,"style":26},"result.get();\nresult.get();\n",[15,1690,1691,1699],{"__ignoreMap":26},[53,1692,1693,1695,1697],{"class":55,"line":56},[53,1694,614],{"class":63},[53,1696,245],{"class":59},[53,1698,248],{"class":63},[53,1700,1701,1703,1705],{"class":55,"line":67},[53,1702,614],{"class":63},[53,1704,245],{"class":59},[53,1706,248],{"class":63},[12,1708,1709,1710,1712],{},"第二次 ",[15,1711,1423],{}," 会对无效 future 操作，通常会抛出：",[20,1714,1716],{"className":47,"code":1715,"language":49,"meta":26,"style":26},"std::future_error\n",[15,1717,1718],{"__ignoreMap":26},[53,1719,1720,1722],{"class":55,"line":56},[53,1721,60],{"class":59},[53,1723,1724],{"class":63},"::future_error\n",[119,1726],{},[127,1728,1730],{"id":1729},"futurevalid",[15,1731,1732],{},"future::valid()",[12,1734,1735],{},"可以通过：",[20,1737,1739],{"className":47,"code":1738,"language":49,"meta":26,"style":26},"future.valid()\n",[15,1740,1741],{"__ignoreMap":26},[53,1742,1743,1745,1747],{"class":55,"line":56},[53,1744,242],{"class":63},[53,1746,1653],{"class":59},[53,1748,366],{"class":63},[12,1750,1751],{},"查询：",[101,1753,1754],{},[12,1755,1756],{},"这个 future 当前是否还关联着有效的共享状态。",[12,1758,148],{},[20,1760,1762],{"className":47,"code":1761,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::async,\n    [] {\n        return 42;\n    });\n\nstd::println(\"{}\", result.valid());\n\nresult.get();\n\nstd::println(\"{}\", result.valid());\n",[15,1763,1764,1780,1790,1794,1802,1806,1810,1828,1832,1840,1844],{"__ignoreMap":26},[53,1765,1766,1768,1770,1772,1774,1776,1778],{"class":55,"line":56},[53,1767,692],{"class":163},[53,1769,385],{"class":63},[53,1771,388],{"class":163},[53,1773,391],{"class":59},[53,1775,394],{"class":63},[53,1777,397],{"class":59},[53,1779,400],{"class":63},[53,1781,1782,1784,1786,1788],{"class":55,"line":67},[53,1783,377],{"class":59},[53,1785,394],{"class":63},[53,1787,411],{"class":59},[53,1789,414],{"class":63},[53,1791,1792],{"class":55,"line":75},[53,1793,1495],{"class":63},[53,1795,1796,1798,1800],{"class":55,"line":83},[53,1797,1500],{"class":163},[53,1799,1072],{"class":426},[53,1801,1075],{"class":63},[53,1803,1804],{"class":55,"line":91},[53,1805,1509],{"class":63},[53,1807,1808],{"class":55,"line":332},[53,1809,296],{"emptyLinePlaceholder":295},[53,1811,1812,1814,1816,1818,1820,1822,1824,1826],{"class":55,"line":347},[53,1813,60],{"class":59},[53,1815,394],{"class":63},[53,1817,454],{"class":59},[53,1819,307],{"class":63},[53,1821,480],{"class":282},[53,1823,483],{"class":63},[53,1825,1653],{"class":59},[53,1827,488],{"class":63},[53,1829,1830],{"class":55,"line":353},[53,1831,296],{"emptyLinePlaceholder":295},[53,1833,1834,1836,1838],{"class":55,"line":358},[53,1835,614],{"class":63},[53,1837,245],{"class":59},[53,1839,248],{"class":63},[53,1841,1842],{"class":55,"line":369},[53,1843,296],{"emptyLinePlaceholder":295},[53,1845,1846,1848,1850,1852,1854,1856,1858,1860],{"class":55,"line":374},[53,1847,60],{"class":59},[53,1849,394],{"class":63},[53,1851,454],{"class":59},[53,1853,307],{"class":63},[53,1855,480],{"class":282},[53,1857,483],{"class":63},[53,1859,1653],{"class":59},[53,1861,488],{"class":63},[12,1863,215],{},[20,1865,1868],{"className":1866,"code":1867,"language":25,"meta":26},[23],"get() 前\n→ future 还关联共享状态\n\nget() 后\n→ 普通 future 的结果已经被消费\n",[15,1869,1867],{"__ignoreMap":26},[12,1871,111],{},[20,1873,1875],{"className":47,"code":1874,"language":49,"meta":26,"style":26},"valid()\n",[15,1876,1877],{"__ignoreMap":26},[53,1878,1879,1881],{"class":55,"line":56},[53,1880,1653],{"class":59},[53,1882,366],{"class":63},[12,1884,1885],{},"不是：",[20,1887,1890],{"className":1888,"code":1889,"language":25,"meta":26},[23],"“任务成功了吗？”\n",[15,1891,1889],{"__ignoreMap":26},[12,1893,1894],{},"而是：",[20,1896,1899],{"className":1897,"code":1898,"language":25,"meta":26},[23],"“这个 future 现在还有没有关联一个有效共享状态？”\n",[15,1900,1898],{"__ignoreMap":26},[119,1902],{},[127,1904,1906],{"id":1905},"futurewait",[15,1907,1908],{},"future::wait()",[12,1910,1911],{},"如果你只想：",[101,1913,1914],{},[12,1915,1916],{},"等任务结束，但暂时不取结果。",[12,1918,1919],{},"可以：",[20,1921,1923],{"className":47,"code":1922,"language":49,"meta":26,"style":26},"future.wait();\n",[15,1924,1925],{"__ignoreMap":26},[53,1926,1927,1929,1932],{"class":55,"line":56},[53,1928,242],{"class":63},[53,1930,1931],{"class":59},"wait",[53,1933,248],{"class":63},[12,1935,148],{},[20,1937,1939],{"className":47,"code":1938,"language":49,"meta":26,"style":26},"result.wait();\n\nstd::println(\"task finished\");\n\nint value = result.get();\n",[15,1940,1941,1949,1953,1968,1972],{"__ignoreMap":26},[53,1942,1943,1945,1947],{"class":55,"line":56},[53,1944,614],{"class":63},[53,1946,1931],{"class":59},[53,1948,248],{"class":63},[53,1950,1951],{"class":55,"line":67},[53,1952,296],{"emptyLinePlaceholder":295},[53,1954,1955,1957,1959,1961,1963,1966],{"class":55,"line":75},[53,1956,60],{"class":59},[53,1958,394],{"class":63},[53,1960,454],{"class":59},[53,1962,307],{"class":63},[53,1964,1965],{"class":282},"\"task finished\"",[53,1967,439],{"class":63},[53,1969,1970],{"class":55,"line":83},[53,1971,296],{"emptyLinePlaceholder":295},[53,1973,1974,1976,1978,1980,1982,1984],{"class":55,"line":91},[53,1975,301],{"class":163},[53,1977,1439],{"class":63},[53,1979,388],{"class":163},[53,1981,1524],{"class":63},[53,1983,245],{"class":59},[53,1985,248],{"class":63},[12,1987,505],{},[20,1989,1991],{"className":47,"code":1990,"language":49,"meta":26,"style":26},"wait()\n",[15,1992,1993],{"__ignoreMap":26},[53,1994,1995,1997],{"class":55,"line":56},[53,1996,1931],{"class":59},[53,1998,366],{"class":63},[12,2000,2001],{},"只负责等待。",[12,2003,2004],{},"它不会把结果取走。",[12,2006,2007],{},"所以之后仍然可以：",[20,2009,2010],{"className":47,"code":607,"language":49,"meta":26,"style":26},[15,2011,2012],{"__ignoreMap":26},[53,2013,2014,2016,2018],{"class":55,"line":56},[53,2015,614],{"class":63},[53,2017,245],{"class":59},[53,2019,248],{"class":63},[12,2021,2022],{},"可以记成：",[20,2024,2027],{"className":2025,"code":2026,"language":25,"meta":26},[23],"wait()\n→ 等待，但不消费结果\n\nget()\n→ 等待 + 取走结果\n",[15,2028,2026],{"__ignoreMap":26},[119,2030],{},[127,2032,2034,2037],{"id":2033},"wait-不会把任务异常直接抛出来",[15,2035,2036],{},"wait()"," 不会把任务异常直接抛出来",[12,2039,2040],{},"假设异步任务抛出了异常。",[12,2042,2043],{},"调用：",[20,2045,2046],{"className":47,"code":1922,"language":49,"meta":26,"style":26},[15,2047,2048],{"__ignoreMap":26},[53,2049,2050,2052,2054],{"class":55,"line":56},[53,2051,242],{"class":63},[53,2053,1931],{"class":59},[53,2055,248],{"class":63},[12,2057,2058],{},"只是等待共享状态变为 ready。",[12,2060,2061],{},"它不会在这里重新抛出任务异常。",[12,2063,2064],{},"异常通常是在：",[20,2066,2067],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,2068,2069],{"__ignoreMap":26},[53,2070,2071,2073,2075],{"class":55,"line":56},[53,2072,242],{"class":63},[53,2074,245],{"class":59},[53,2076,248],{"class":63},[12,2078,2079],{},"时重新抛出。",[12,2081,111],{},[20,2083,2086],{"className":2084,"code":2085,"language":25,"meta":26},[23],"wait()\n→ 确认任务已经结束\n\nget()\n→ 真正取得“结果或者异常”\n",[15,2087,2085],{"__ignoreMap":26},[119,2089],{},[127,2091,2093],{"id":2092},"futurewait_for",[15,2094,2095],{},"future::wait_for()",[12,2097,2098],{},"可以等待一段时间：",[20,2100,2102],{"className":47,"code":2101,"language":49,"meta":26,"style":26},"auto status = result.wait_for(\n    std::chrono::milliseconds(100));\n",[15,2103,2104,2120],{"__ignoreMap":26},[53,2105,2106,2108,2111,2113,2115,2118],{"class":55,"line":56},[53,2107,692],{"class":163},[53,2109,2110],{"class":63}," status ",[53,2112,388],{"class":163},[53,2114,1524],{"class":63},[53,2116,2117],{"class":59},"wait_for",[53,2119,400],{"class":63},[53,2121,2122,2124,2126,2129,2131,2134,2136,2139],{"class":55,"line":67},[53,2123,377],{"class":59},[53,2125,394],{"class":63},[53,2127,2128],{"class":59},"chrono",[53,2130,394],{"class":63},[53,2132,2133],{"class":59},"milliseconds",[53,2135,307],{"class":63},[53,2137,2138],{"class":426},"100",[53,2140,2141],{"class":63},"));\n",[12,2143,2144],{},"返回值可能是：",[20,2146,2148],{"className":47,"code":2147,"language":49,"meta":26,"style":26},"std::future_status::ready\nstd::future_status::timeout\nstd::future_status::deferred\n",[15,2149,2150,2162,2173],{"__ignoreMap":26},[53,2151,2152,2154,2156,2159],{"class":55,"line":56},[53,2153,60],{"class":59},[53,2155,394],{"class":63},[53,2157,2158],{"class":59},"future_status",[53,2160,2161],{"class":63},"::ready\n",[53,2163,2164,2166,2168,2170],{"class":55,"line":67},[53,2165,60],{"class":59},[53,2167,394],{"class":63},[53,2169,2158],{"class":59},[53,2171,2172],{"class":63},"::timeout\n",[53,2174,2175,2177,2179,2181],{"class":55,"line":75},[53,2176,60],{"class":59},[53,2178,394],{"class":63},[53,2180,2158],{"class":59},[53,2182,935],{"class":63},[12,2184,2185],{},"分别表示：",[20,2187,2190],{"className":2188,"code":2189,"language":25,"meta":26},[23],"ready\n→ 结果已经准备好了\n\ntimeout\n→ 等待时间到了，但结果还没准备好\n\ndeferred\n→ 这个任务使用 deferred 策略\n",[15,2191,2189],{"__ignoreMap":26},[12,2193,2194],{},"示例：",[20,2196,2198],{"className":47,"code":2197,"language":49,"meta":26,"style":26},"#include \u003Cchrono>\n#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cthread>\n\nusing namespace std::chrono_literals;\n\nint main()\n{\n    auto result = std::async(\n        std::launch::async,\n        [] {\n            std::this_thread::sleep_for(1s);\n            return 42;\n        });\n\n    if (result.wait_for(100ms)\n        == std::future_status::timeout)\n    {\n        std::println(\"not ready yet\");\n    }\n\n    std::println(\"{}\", result.get());\n}\n",[15,2199,2200,2207,2213,2219,2225,2229,2246,2250,2258,2262,2278,2288,2293,2317,2326,2331,2335,2354,2368,2373,2388,2393,2397,2415],{"__ignoreMap":26},[53,2201,2202,2204],{"class":55,"line":56},[53,2203,279],{"class":163},[53,2205,2206],{"class":282}," \u003Cchrono>\n",[53,2208,2209,2211],{"class":55,"line":67},[53,2210,279],{"class":163},[53,2212,283],{"class":282},[53,2214,2215,2217],{"class":55,"line":75},[53,2216,279],{"class":163},[53,2218,290],{"class":282},[53,2220,2221,2223],{"class":55,"line":83},[53,2222,279],{"class":163},[53,2224,1011],{"class":282},[53,2226,2227],{"class":55,"line":91},[53,2228,296],{"emptyLinePlaceholder":295},[53,2230,2231,2234,2237,2239,2241,2244],{"class":55,"line":332},[53,2232,2233],{"class":163},"using",[53,2235,2236],{"class":163}," namespace",[53,2238,391],{"class":59},[53,2240,394],{"class":63},[53,2242,2243],{"class":59},"chrono_literals",[53,2245,1075],{"class":63},[53,2247,2248],{"class":55,"line":347},[53,2249,296],{"emptyLinePlaceholder":295},[53,2251,2252,2254,2256],{"class":55,"line":353},[53,2253,301],{"class":163},[53,2255,363],{"class":59},[53,2257,366],{"class":63},[53,2259,2260],{"class":55,"line":358},[53,2261,329],{"class":63},[53,2263,2264,2266,2268,2270,2272,2274,2276],{"class":55,"line":369},[53,2265,1135],{"class":163},[53,2267,385],{"class":63},[53,2269,388],{"class":163},[53,2271,391],{"class":59},[53,2273,394],{"class":63},[53,2275,397],{"class":59},[53,2277,400],{"class":63},[53,2279,2280,2282,2284,2286],{"class":55,"line":374},[53,2281,406],{"class":59},[53,2283,394],{"class":63},[53,2285,411],{"class":59},[53,2287,414],{"class":63},[53,2289,2290],{"class":55,"line":403},[53,2291,2292],{"class":63},"        [] {\n",[53,2294,2295,2298,2300,2302,2304,2307,2309,2312,2315],{"class":55,"line":417},[53,2296,2297],{"class":59},"            std",[53,2299,394],{"class":63},[53,2301,1054],{"class":59},[53,2303,394],{"class":63},[53,2305,2306],{"class":59},"sleep_for",[53,2308,307],{"class":63},[53,2310,2311],{"class":426},"1",[53,2313,2314],{"class":163},"s",[53,2316,439],{"class":63},[53,2318,2319,2322,2324],{"class":55,"line":423},[53,2320,2321],{"class":163},"            return",[53,2323,1072],{"class":426},[53,2325,1075],{"class":63},[53,2327,2328],{"class":55,"line":433},[53,2329,2330],{"class":63},"        });\n",[53,2332,2333],{"class":55,"line":442},[53,2334,296],{"emptyLinePlaceholder":295},[53,2336,2337,2340,2343,2345,2347,2349,2352],{"class":55,"line":447},[53,2338,2339],{"class":163},"    if",[53,2341,2342],{"class":63}," (result.",[53,2344,2117],{"class":59},[53,2346,307],{"class":63},[53,2348,2138],{"class":426},[53,2350,2351],{"class":163},"ms",[53,2353,324],{"class":63},[53,2355,2356,2359,2361,2363,2365],{"class":55,"line":464},[53,2357,2358],{"class":163},"        ==",[53,2360,391],{"class":59},[53,2362,394],{"class":63},[53,2364,2158],{"class":59},[53,2366,2367],{"class":63},"::timeout)\n",[53,2369,2370],{"class":55,"line":469},[53,2371,2372],{"class":63},"    {\n",[53,2374,2375,2377,2379,2381,2383,2386],{"class":55,"line":491},[53,2376,406],{"class":59},[53,2378,394],{"class":63},[53,2380,454],{"class":59},[53,2382,307],{"class":63},[53,2384,2385],{"class":282},"\"not ready yet\"",[53,2387,439],{"class":63},[53,2389,2390],{"class":55,"line":1150},[53,2391,2392],{"class":63},"    }\n",[53,2394,2395],{"class":55,"line":1161},[53,2396,296],{"emptyLinePlaceholder":295},[53,2398,2399,2401,2403,2405,2407,2409,2411,2413],{"class":55,"line":1167},[53,2400,377],{"class":59},[53,2402,394],{"class":63},[53,2404,454],{"class":59},[53,2406,307],{"class":63},[53,2408,480],{"class":282},[53,2410,483],{"class":63},[53,2412,245],{"class":59},[53,2414,488],{"class":63},[53,2416,2417],{"class":55,"line":1172},[53,2418,350],{"class":63},[12,2420,2421],{},"输出：",[20,2423,2426],{"className":2424,"code":2425,"language":25,"meta":26},[23],"not ready yet\n42\n",[15,2427,2425],{"__ignoreMap":26},[12,2429,2430],{},"整个过程是：",[20,2432,2435],{"className":2433,"code":2434,"language":25,"meta":26},[23],"任务开始\n↓\nmain 最多等 100ms\n↓\n任务还没完成\n↓\nwait_for() 返回 timeout\n↓\nmain 继续\n↓\n最后 get() 等待并取得结果\n",[15,2436,2434],{"__ignoreMap":26},[119,2438],{},[127,2440,2442],{"id":2441},"future_statusdeferred",[15,2443,2444],{},"future_status::deferred",[12,2446,2447],{},"如果：",[20,2449,2451],{"className":47,"code":2450,"language":49,"meta":26,"style":26},"wait_for(...)\n",[15,2452,2453],{"__ignoreMap":26},[53,2454,2455,2457],{"class":55,"line":56},[53,2456,2117],{"class":59},[53,2458,2459],{"class":63},"(...)\n",[12,2461,2462],{},"返回：",[20,2464,2466],{"className":47,"code":2465,"language":49,"meta":26,"style":26},"std::future_status::deferred\n",[15,2467,2468],{"__ignoreMap":26},[53,2469,2470,2472,2474,2476],{"class":55,"line":56},[53,2471,60],{"class":59},[53,2473,394],{"class":63},[53,2475,2158],{"class":59},[53,2477,935],{"class":63},[12,2479,2480],{},"说明：",[101,2482,2483],{},[12,2484,2485],{},"这个任务根本不是正在后台慢慢执行。",[12,2487,2488],{},"它只是一个延迟任务。",[12,2490,148],{},[20,2492,2493],{"className":47,"code":940,"language":49,"meta":26,"style":26},[15,2494,2495,2511,2521],{"__ignoreMap":26},[53,2496,2497,2499,2501,2503,2505,2507,2509],{"class":55,"line":56},[53,2498,692],{"class":163},[53,2500,385],{"class":63},[53,2502,388],{"class":163},[53,2504,391],{"class":59},[53,2506,394],{"class":63},[53,2508,397],{"class":59},[53,2510,400],{"class":63},[53,2512,2513,2515,2517,2519],{"class":55,"line":67},[53,2514,377],{"class":59},[53,2516,394],{"class":63},[53,2518,411],{"class":59},[53,2520,969],{"class":63},[53,2522,2523],{"class":55,"line":75},[53,2524,841],{"class":63},[12,2526,2527],{},"此时不断写：",[20,2529,2531],{"className":47,"code":2530,"language":49,"meta":26,"style":26},"result.wait_for(100ms);\nresult.wait_for(100ms);\nresult.wait_for(100ms);\n",[15,2532,2533,2547,2561],{"__ignoreMap":26},[53,2534,2535,2537,2539,2541,2543,2545],{"class":55,"line":56},[53,2536,614],{"class":63},[53,2538,2117],{"class":59},[53,2540,307],{"class":63},[53,2542,2138],{"class":426},[53,2544,2351],{"class":163},[53,2546,439],{"class":63},[53,2548,2549,2551,2553,2555,2557,2559],{"class":55,"line":67},[53,2550,614],{"class":63},[53,2552,2117],{"class":59},[53,2554,307],{"class":63},[53,2556,2138],{"class":426},[53,2558,2351],{"class":163},[53,2560,439],{"class":63},[53,2562,2563,2565,2567,2569,2571,2573],{"class":55,"line":75},[53,2564,614],{"class":63},[53,2566,2117],{"class":59},[53,2568,307],{"class":63},[53,2570,2138],{"class":426},[53,2572,2351],{"class":163},[53,2574,439],{"class":63},[12,2576,2577],{},"并不会让它“等着等着就在后台完成”。",[12,2579,2580],{},"因为 deferred 的逻辑是：",[20,2582,2585],{"className":2583,"code":2584,"language":25,"meta":26},[23],"真正执行 get()\u002Fwait()\n↓\n调用这些函数的线程亲自执行任务\n",[15,2586,2584],{"__ignoreMap":26},[119,2588],{},[127,2590,2592],{"id":2591},"异步任务里的异常会通过-future-传回来","异步任务里的异常会通过 future 传回来",[12,2594,2595,2596,2598],{},"这是 ",[15,2597,201],{}," 很重要的能力。",[12,2600,148],{},[20,2602,2604],{"className":47,"code":2603,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cstdexcept>\n\nint main()\n{\n    auto result = std::async(\n        std::launch::async,\n        []() -> int {\n            throw std::runtime_error(\"task failed\");\n        });\n\n    try\n    {\n        std::println(\"{}\", result.get());\n    }\n    catch (const std::exception& e)\n    {\n        std::println(\"{}\", e.what());\n    }\n}\n",[15,2605,2606,2612,2618,2625,2629,2637,2641,2657,2667,2677,2696,2700,2704,2709,2713,2731,2735,2757,2761,2781,2785],{"__ignoreMap":26},[53,2607,2608,2610],{"class":55,"line":56},[53,2609,279],{"class":163},[53,2611,283],{"class":282},[53,2613,2614,2616],{"class":55,"line":67},[53,2615,279],{"class":163},[53,2617,290],{"class":282},[53,2619,2620,2622],{"class":55,"line":75},[53,2621,279],{"class":163},[53,2623,2624],{"class":282}," \u003Cstdexcept>\n",[53,2626,2627],{"class":55,"line":83},[53,2628,296],{"emptyLinePlaceholder":295},[53,2630,2631,2633,2635],{"class":55,"line":91},[53,2632,301],{"class":163},[53,2634,363],{"class":59},[53,2636,366],{"class":63},[53,2638,2639],{"class":55,"line":332},[53,2640,329],{"class":63},[53,2642,2643,2645,2647,2649,2651,2653,2655],{"class":55,"line":347},[53,2644,1135],{"class":163},[53,2646,385],{"class":63},[53,2648,388],{"class":163},[53,2650,391],{"class":59},[53,2652,394],{"class":63},[53,2654,397],{"class":59},[53,2656,400],{"class":63},[53,2658,2659,2661,2663,2665],{"class":55,"line":353},[53,2660,406],{"class":59},[53,2662,394],{"class":63},[53,2664,411],{"class":59},[53,2666,414],{"class":63},[53,2668,2669,2672,2674],{"class":55,"line":358},[53,2670,2671],{"class":63},"        []() -> ",[53,2673,301],{"class":163},[53,2675,2676],{"class":63}," {\n",[53,2678,2679,2682,2684,2686,2689,2691,2694],{"class":55,"line":369},[53,2680,2681],{"class":163},"            throw",[53,2683,391],{"class":59},[53,2685,394],{"class":63},[53,2687,2688],{"class":59},"runtime_error",[53,2690,307],{"class":63},[53,2692,2693],{"class":282},"\"task failed\"",[53,2695,439],{"class":63},[53,2697,2698],{"class":55,"line":374},[53,2699,2330],{"class":63},[53,2701,2702],{"class":55,"line":403},[53,2703,296],{"emptyLinePlaceholder":295},[53,2705,2706],{"class":55,"line":417},[53,2707,2708],{"class":163},"    try\n",[53,2710,2711],{"class":55,"line":423},[53,2712,2372],{"class":63},[53,2714,2715,2717,2719,2721,2723,2725,2727,2729],{"class":55,"line":433},[53,2716,406],{"class":59},[53,2718,394],{"class":63},[53,2720,454],{"class":59},[53,2722,307],{"class":63},[53,2724,480],{"class":282},[53,2726,483],{"class":63},[53,2728,245],{"class":59},[53,2730,488],{"class":63},[53,2732,2733],{"class":55,"line":442},[53,2734,2392],{"class":63},[53,2736,2737,2740,2743,2746,2748,2751,2754],{"class":55,"line":447},[53,2738,2739],{"class":163},"    catch",[53,2741,2742],{"class":63}," (",[53,2744,2745],{"class":163},"const",[53,2747,391],{"class":59},[53,2749,2750],{"class":63},"::exception",[53,2752,2753],{"class":163},"&",[53,2755,2756],{"class":63}," e)\n",[53,2758,2759],{"class":55,"line":464},[53,2760,2372],{"class":63},[53,2762,2763,2765,2767,2769,2771,2773,2776,2779],{"class":55,"line":469},[53,2764,406],{"class":59},[53,2766,394],{"class":63},[53,2768,454],{"class":59},[53,2770,307],{"class":63},[53,2772,480],{"class":282},[53,2774,2775],{"class":63},", e.",[53,2777,2778],{"class":59},"what",[53,2780,488],{"class":63},[53,2782,2783],{"class":55,"line":491},[53,2784,2392],{"class":63},[53,2786,2787],{"class":55,"line":1150},[53,2788,350],{"class":63},[12,2790,2421],{},[20,2792,2795],{"className":2793,"code":2794,"language":25,"meta":26},[23],"task failed\n",[15,2796,2794],{"__ignoreMap":26},[12,2798,2799],{},"这里任务线程抛出的：",[20,2801,2803],{"className":47,"code":2802,"language":49,"meta":26,"style":26},"std::runtime_error\n",[15,2804,2805],{"__ignoreMap":26},[53,2806,2807,2809],{"class":55,"line":56},[53,2808,60],{"class":59},[53,2810,2811],{"class":63},"::runtime_error\n",[12,2813,2814],{},"不会直接从工作线程“跳到”主线程。",[12,2816,2817],{},"实际逻辑是：",[20,2819,2822],{"className":2820,"code":2821,"language":25,"meta":26},[23],"异步任务抛异常\n↓\n异常被保存到 shared state\n↓\nmain 调用 future.get()\n↓\nget() 发现共享状态里保存的是异常\n↓\n在 main 这里重新抛出\n",[15,2823,2821],{"__ignoreMap":26},[12,2825,111],{},[20,2827,2828],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,2829,2830],{"__ignoreMap":26},[53,2831,2832,2834,2836],{"class":55,"line":56},[53,2833,242],{"class":63},[53,2835,245],{"class":59},[53,2837,248],{"class":63},[12,2839,2840],{},"取得的不一定是：",[20,2842,2845],{"className":2843,"code":2844,"language":25,"meta":26},[23],"正常返回值\n",[15,2846,2844],{"__ignoreMap":26},[12,2848,2849],{},"也可能是：",[20,2851,2854],{"className":2852,"code":2853,"language":25,"meta":26},[23],"任务失败时保存的异常\n",[15,2855,2853],{"__ignoreMap":26},[12,2857,2858],{},"这使得异步任务的错误处理很像普通函数：",[20,2860,2863],{"className":2861,"code":2862,"language":25,"meta":26},[23],"普通函数\n→ 调用处 catch\n\n异步任务\n→ future.get() 处 catch\n",[15,2864,2862],{"__ignoreMap":26},[119,2866],{},[122,2868,2870],{"id":2869},"stdpromiset",[15,2871,2872],{},"std::promise\u003CT>",[12,2874,2875],{},"前面的：",[20,2877,2879],{"className":47,"code":2878,"language":49,"meta":26,"style":26},"std::async\n",[15,2880,2881],{"__ignoreMap":26},[53,2882,2883,2885],{"class":55,"line":56},[53,2884,60],{"class":59},[53,2886,72],{"class":63},[12,2888,2889],{},"会自动创建结果通道。",[12,2891,2892],{},"但有时候我们想自己控制：",[20,2894,2897],{"className":2895,"code":2896,"language":25,"meta":26},[23],"什么时候写入结果\n\n在哪个线程写入结果\n\n写入正常值还是异常\n",[15,2898,2896],{"__ignoreMap":26},[12,2900,2901],{},"这时可以使用：",[20,2903,2905],{"className":47,"code":2904,"language":49,"meta":26,"style":26},"std::promise\u003CT>\n",[15,2906,2907],{"__ignoreMap":26},[53,2908,2909,2911,2914,2917,2920],{"class":55,"line":56},[53,2910,60],{"class":59},[53,2912,2913],{"class":63},"::promise",[53,2915,2916],{"class":163},"\u003C",[53,2918,2919],{"class":63},"T",[53,2921,2922],{"class":163},">\n",[12,2924,2925],{},"它可以理解成：",[101,2927,2928],{},[12,2929,2930],{},[106,2931,2932],{},"future 对应结果通道的“写入端”。",[12,2934,2935],{},"关系是：",[20,2937,2940],{"className":2938,"code":2939,"language":25,"meta":26},[23],"promise\u003CT>\n   │\n   │ set_value()\n   │ set_exception()\n   ↓\nshared state\n   ↓\nfuture\u003CT>\n   │\n   │ get()\n   ↓\n读取结果\n",[15,2941,2939],{"__ignoreMap":26},[12,2943,2944],{},"所以最简单的记忆方式是：",[20,2946,2949],{"className":2947,"code":2948,"language":25,"meta":26},[23],"promise\n→ 写\n\nfuture\n→ 读\n",[15,2950,2948],{"__ignoreMap":26},[119,2952],{},[127,2954,2956],{"id":2955},"promiseget_future",[15,2957,2958],{},"promise::get_future()",[12,2960,2961],{},"创建：",[20,2963,2965],{"className":47,"code":2964,"language":49,"meta":26,"style":26},"std::promise\u003Cint> promise;\n",[15,2966,2967],{"__ignoreMap":26},[53,2968,2969,2971,2973,2975],{"class":55,"line":56},[53,2970,60],{"class":59},[53,2972,2913],{"class":63},[53,2974,382],{"class":163},[53,2976,2977],{"class":63}," promise;\n",[12,2979,2980],{},"以后，可以通过：",[20,2982,2984],{"className":47,"code":2983,"language":49,"meta":26,"style":26},"std::future\u003Cint> future = promise.get_future();\n",[15,2985,2986],{"__ignoreMap":26},[53,2987,2988,2990,2992,2994,2997,2999,3002,3005],{"class":55,"line":56},[53,2989,60],{"class":59},[53,2991,160],{"class":63},[53,2993,382],{"class":163},[53,2995,2996],{"class":63}," future ",[53,2998,388],{"class":163},[53,3000,3001],{"class":63}," promise.",[53,3003,3004],{"class":59},"get_future",[53,3006,248],{"class":63},[12,3008,3009],{},"获得和这个 promise 关联的读取端。",[12,3011,3012],{},"于是：",[20,3014,3017],{"className":3015,"code":3016,"language":25,"meta":26},[23],"promise\n和\nfuture\n",[15,3018,3016],{"__ignoreMap":26},[12,3020,3021],{},"通过同一个 shared state 连接起来。",[119,3023],{},[127,3025,3027],{"id":3026},"promise-最简单的例子","promise 最简单的例子",[20,3029,3031],{"className":47,"code":3030,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cthread>\n\nvoid producer(std::promise\u003Cint> promise)\n{\n    promise.set_value(42);\n}\n\nint main()\n{\n    std::promise\u003Cint> promise;\n\n    std::future\u003Cint> future =\n        promise.get_future();\n\n    std::thread thread(\n        producer,\n        std::move(promise));\n\n    std::println(\"{}\", future.get());\n\n    thread.join();\n}\n",[15,3032,3033,3039,3045,3051,3055,3083,3087,3102,3106,3110,3118,3122,3132,3136,3149,3158,3162,3173,3178,3190,3194,3213,3217,3227],{"__ignoreMap":26},[53,3034,3035,3037],{"class":55,"line":56},[53,3036,279],{"class":163},[53,3038,283],{"class":282},[53,3040,3041,3043],{"class":55,"line":67},[53,3042,279],{"class":163},[53,3044,290],{"class":282},[53,3046,3047,3049],{"class":55,"line":75},[53,3048,279],{"class":163},[53,3050,1011],{"class":282},[53,3052,3053],{"class":55,"line":83},[53,3054,296],{"emptyLinePlaceholder":295},[53,3056,3057,3060,3063,3065,3067,3069,3072,3074,3076,3079,3081],{"class":55,"line":91},[53,3058,3059],{"class":163},"void",[53,3061,3062],{"class":59}," producer",[53,3064,307],{"class":63},[53,3066,60],{"class":59},[53,3068,394],{"class":63},[53,3070,3071],{"class":59},"promise",[53,3073,2916],{"class":63},[53,3075,301],{"class":163},[53,3077,3078],{"class":63},"> ",[53,3080,3071],{"class":312},[53,3082,324],{"class":63},[53,3084,3085],{"class":55,"line":332},[53,3086,329],{"class":63},[53,3088,3089,3092,3095,3097,3100],{"class":55,"line":347},[53,3090,3091],{"class":63},"    promise.",[53,3093,3094],{"class":59},"set_value",[53,3096,307],{"class":63},[53,3098,3099],{"class":426},"42",[53,3101,439],{"class":63},[53,3103,3104],{"class":55,"line":353},[53,3105,350],{"class":63},[53,3107,3108],{"class":55,"line":358},[53,3109,296],{"emptyLinePlaceholder":295},[53,3111,3112,3114,3116],{"class":55,"line":369},[53,3113,301],{"class":163},[53,3115,363],{"class":59},[53,3117,366],{"class":63},[53,3119,3120],{"class":55,"line":374},[53,3121,329],{"class":63},[53,3123,3124,3126,3128,3130],{"class":55,"line":403},[53,3125,377],{"class":59},[53,3127,2913],{"class":63},[53,3129,382],{"class":163},[53,3131,2977],{"class":63},[53,3133,3134],{"class":55,"line":417},[53,3135,296],{"emptyLinePlaceholder":295},[53,3137,3138,3140,3142,3144,3146],{"class":55,"line":423},[53,3139,377],{"class":59},[53,3141,160],{"class":63},[53,3143,382],{"class":163},[53,3145,2996],{"class":63},[53,3147,3148],{"class":163},"=\n",[53,3150,3151,3154,3156],{"class":55,"line":433},[53,3152,3153],{"class":63},"        promise.",[53,3155,3004],{"class":59},[53,3157,248],{"class":63},[53,3159,3160],{"class":55,"line":442},[53,3161,296],{"emptyLinePlaceholder":295},[53,3163,3164,3166,3169,3171],{"class":55,"line":447},[53,3165,377],{"class":59},[53,3167,3168],{"class":63},"::thread ",[53,3170,660],{"class":59},[53,3172,400],{"class":63},[53,3174,3175],{"class":55,"line":464},[53,3176,3177],{"class":63},"        producer,\n",[53,3179,3180,3182,3184,3187],{"class":55,"line":469},[53,3181,406],{"class":59},[53,3183,394],{"class":63},[53,3185,3186],{"class":59},"move",[53,3188,3189],{"class":63},"(promise));\n",[53,3191,3192],{"class":55,"line":491},[53,3193,296],{"emptyLinePlaceholder":295},[53,3195,3196,3198,3200,3202,3204,3206,3209,3211],{"class":55,"line":1150},[53,3197,377],{"class":59},[53,3199,394],{"class":63},[53,3201,454],{"class":59},[53,3203,307],{"class":63},[53,3205,480],{"class":282},[53,3207,3208],{"class":63},", future.",[53,3210,245],{"class":59},[53,3212,488],{"class":63},[53,3214,3215],{"class":55,"line":1161},[53,3216,296],{"emptyLinePlaceholder":295},[53,3218,3219,3222,3225],{"class":55,"line":1167},[53,3220,3221],{"class":63},"    thread.",[53,3223,3224],{"class":59},"join",[53,3226,248],{"class":63},[53,3228,3229],{"class":55,"line":1172},[53,3230,350],{"class":63},[12,3232,2421],{},[20,3234,3237],{"className":3235,"code":3236,"language":25,"meta":26},[23],"42\n",[15,3238,3236],{"__ignoreMap":26},[12,3240,3241],{},"整个过程可以理解成：",[20,3243,3246],{"className":3244,"code":3245,"language":25,"meta":26},[23],"main 创建 promise\n↓\nmain 从 promise 拿到 future\n↓\nmain 把 promise 移动给 worker\n↓\nworker 调用 set_value(42)\n↓\n42 被写入 shared state\n↓\nmain 的 future.get()\n↓\n读出 42\n",[15,3247,3245],{"__ignoreMap":26},[119,3249],{},[127,3251,3253,3254],{"id":3252},"为什么-promise-要-stdmove","为什么 promise 要 ",[15,3255,3256],{},"std::move",[12,3258,3259,3262],{},[15,3260,3261],{},"std::promise"," 不能随意复制。",[12,3264,3265],{},"它是：",[20,3267,3270],{"className":3268,"code":3269,"language":25,"meta":26},[23],"move-only\n",[15,3271,3269],{"__ignoreMap":26},[12,3273,111],{},[20,3275,3277],{"className":47,"code":3276,"language":49,"meta":26,"style":26},"std::thread thread(\n    producer,\n    std::move(promise));\n",[15,3278,3279,3292,3299],{"__ignoreMap":26},[53,3280,3281,3283,3285,3287,3290],{"class":55,"line":56},[53,3282,60],{"class":59},[53,3284,394],{"class":63},[53,3286,660],{"class":59},[53,3288,3289],{"class":59}," thread",[53,3291,400],{"class":63},[53,3293,3294,3297],{"class":55,"line":67},[53,3295,3296],{"class":59},"    producer",[53,3298,430],{"class":63},[53,3300,3301,3303,3305,3307],{"class":55,"line":75},[53,3302,377],{"class":59},[53,3304,394],{"class":63},[53,3306,3186],{"class":59},[53,3308,3189],{"class":63},[12,3310,3311],{},"是在把 promise 的所有权移动给工作线程。",[12,3313,215],{},[20,3315,3318],{"className":3316,"code":3317,"language":25,"meta":26},[23],"main\n→ 保留 future，负责读\n\nworker\n→ 拿走 promise，负责写\n",[15,3319,3317],{"__ignoreMap":26},[12,3321,3322],{},"这样：",[20,3324,3327],{"className":3325,"code":3326,"language":25,"meta":26},[23],"worker 写结果\n↓\nshared state\n↓\nmain 读结果\n",[15,3328,3326],{"__ignoreMap":26},[12,3330,3331],{},"就建立起来了。",[119,3333],{},[127,3335,3337],{"id":3336},"promiseset_value",[15,3338,3339],{},"promise::set_value()",[12,3341,3342],{},"生产端可以：",[20,3344,3346],{"className":47,"code":3345,"language":49,"meta":26,"style":26},"promise.set_value(42);\n",[15,3347,3348],{"__ignoreMap":26},[53,3349,3350,3353,3355,3357,3359],{"class":55,"line":56},[53,3351,3352],{"class":63},"promise.",[53,3354,3094],{"class":59},[53,3356,307],{"class":63},[53,3358,3099],{"class":426},[53,3360,439],{"class":63},[12,3362,844],{},[101,3364,3365],{},[12,3366,3367],{},"把最终结果写入共享状态。",[12,3369,3370],{},"写入以后：",[20,3372,3375],{"className":3373,"code":3374,"language":25,"meta":26},[23],"future\n→ ready\n",[15,3376,3374],{"__ignoreMap":26},[12,3378,3379],{},"等待中的：",[20,3381,3382],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,3383,3384],{"__ignoreMap":26},[53,3385,3386,3388,3390],{"class":55,"line":56},[53,3387,242],{"class":63},[53,3389,245],{"class":59},[53,3391,248],{"class":63},[12,3393,3394],{},"就可以继续执行。",[12,3396,3397],{},"对于：",[20,3399,3401],{"className":47,"code":3400,"language":49,"meta":26,"style":26},"std::promise\u003Cvoid>\n",[15,3402,3403],{"__ignoreMap":26},[53,3404,3405,3407,3409],{"class":55,"line":56},[53,3406,60],{"class":59},[53,3408,2913],{"class":63},[53,3410,190],{"class":163},[12,3412,3413],{},"没有具体返回值。",[12,3415,1919],{},[20,3417,3419],{"className":47,"code":3418,"language":49,"meta":26,"style":26},"promise.set_value();\n",[15,3420,3421],{"__ignoreMap":26},[53,3422,3423,3425,3427],{"class":55,"line":56},[53,3424,3352],{"class":63},[53,3426,3094],{"class":59},[53,3428,248],{"class":63},[12,3430,167],{},[101,3432,3433],{},[12,3434,3435],{},"任务已经成功完成。",[119,3437],{},[127,3439,3441],{"id":3440},"promise-的结果通常只能设置一次","promise 的结果通常只能设置一次",[12,3443,148],{},[20,3445,3447],{"className":47,"code":3446,"language":49,"meta":26,"style":26},"promise.set_value(42);\npromise.set_value(100);\n",[15,3448,3449,3461],{"__ignoreMap":26},[53,3450,3451,3453,3455,3457,3459],{"class":55,"line":56},[53,3452,3352],{"class":63},[53,3454,3094],{"class":59},[53,3456,307],{"class":63},[53,3458,3099],{"class":426},[53,3460,439],{"class":63},[53,3462,3463,3465,3467,3469,3471],{"class":55,"line":67},[53,3464,3352],{"class":63},[53,3466,3094],{"class":59},[53,3468,307],{"class":63},[53,3470,2138],{"class":426},[53,3472,439],{"class":63},[12,3474,3475],{},"是不对的。",[12,3477,3478],{},"同一个共享状态只能完成一次。",[12,3480,3481],{},"第一次：",[20,3483,3485],{"className":47,"code":3484,"language":49,"meta":26,"style":26},"set_value(42);\n",[15,3486,3487],{"__ignoreMap":26},[53,3488,3489,3491,3493,3495],{"class":55,"line":56},[53,3490,3094],{"class":59},[53,3492,307],{"class":63},[53,3494,3099],{"class":426},[53,3496,439],{"class":63},[12,3498,3499],{},"已经把结果确定了。",[12,3501,3502],{},"第二次再次：",[20,3504,3506],{"className":47,"code":3505,"language":49,"meta":26,"style":26},"set_value(...)\n",[15,3507,3508],{"__ignoreMap":26},[53,3509,3510,3512],{"class":55,"line":56},[53,3511,3094],{"class":59},[53,3513,2459],{"class":63},[12,3515,3516],{},"通常会抛：",[20,3518,3519],{"className":47,"code":1715,"language":49,"meta":26,"style":26},[15,3520,3521],{"__ignoreMap":26},[53,3522,3523,3525],{"class":55,"line":56},[53,3524,60],{"class":59},[53,3526,1724],{"class":63},[12,3528,3529],{},"所以可以理解成：",[20,3531,3534],{"className":3532,"code":3533,"language":25,"meta":26},[23],"一个 promise\n→ 最终只能提交一次最终结果\n",[15,3535,3533],{"__ignoreMap":26},[119,3537],{},[127,3539,3541],{"id":3540},"promiseset_exception",[15,3542,3543],{},"promise::set_exception()",[12,3545,3546],{},"promise 不仅能写正常值：",[20,3548,3550],{"className":47,"code":3549,"language":49,"meta":26,"style":26},"promise.set_value(result);\n",[15,3551,3552],{"__ignoreMap":26},[53,3553,3554,3556,3558],{"class":55,"line":56},[53,3555,3352],{"class":63},[53,3557,3094],{"class":59},[53,3559,3560],{"class":63},"(result);\n",[12,3562,3563],{},"也可以写异常：",[20,3565,3567],{"className":47,"code":3566,"language":49,"meta":26,"style":26},"promise.set_exception(\n    std::current_exception());\n",[15,3568,3569,3578],{"__ignoreMap":26},[53,3570,3571,3573,3576],{"class":55,"line":56},[53,3572,3352],{"class":63},[53,3574,3575],{"class":59},"set_exception",[53,3577,400],{"class":63},[53,3579,3580,3582,3584,3587],{"class":55,"line":67},[53,3581,377],{"class":59},[53,3583,394],{"class":63},[53,3585,3586],{"class":59},"current_exception",[53,3588,488],{"class":63},[12,3590,3591],{},"常见写法：",[20,3593,3595],{"className":47,"code":3594,"language":49,"meta":26,"style":26},"void producer(std::promise\u003Cint> promise)\n{\n    try\n    {\n        int result = do_work();\n\n        promise.set_value(result);\n    }\n    catch (...)\n    {\n        promise.set_exception(\n            std::current_exception());\n    }\n}\n",[15,3596,3597,3621,3625,3629,3633,3647,3651,3659,3663,3670,3674,3682,3692,3696],{"__ignoreMap":26},[53,3598,3599,3601,3603,3605,3607,3609,3611,3613,3615,3617,3619],{"class":55,"line":56},[53,3600,3059],{"class":163},[53,3602,3062],{"class":59},[53,3604,307],{"class":63},[53,3606,60],{"class":59},[53,3608,394],{"class":63},[53,3610,3071],{"class":59},[53,3612,2916],{"class":63},[53,3614,301],{"class":163},[53,3616,3078],{"class":63},[53,3618,3071],{"class":312},[53,3620,324],{"class":63},[53,3622,3623],{"class":55,"line":67},[53,3624,329],{"class":63},[53,3626,3627],{"class":55,"line":75},[53,3628,2708],{"class":163},[53,3630,3631],{"class":55,"line":83},[53,3632,2372],{"class":63},[53,3634,3635,3638,3640,3642,3645],{"class":55,"line":91},[53,3636,3637],{"class":163},"        int",[53,3639,385],{"class":63},[53,3641,388],{"class":163},[53,3643,3644],{"class":59}," do_work",[53,3646,248],{"class":63},[53,3648,3649],{"class":55,"line":332},[53,3650,296],{"emptyLinePlaceholder":295},[53,3652,3653,3655,3657],{"class":55,"line":347},[53,3654,3153],{"class":63},[53,3656,3094],{"class":59},[53,3658,3560],{"class":63},[53,3660,3661],{"class":55,"line":353},[53,3662,2392],{"class":63},[53,3664,3665,3667],{"class":55,"line":358},[53,3666,2739],{"class":163},[53,3668,3669],{"class":63}," (...)\n",[53,3671,3672],{"class":55,"line":369},[53,3673,2372],{"class":63},[53,3675,3676,3678,3680],{"class":55,"line":374},[53,3677,3153],{"class":63},[53,3679,3575],{"class":59},[53,3681,400],{"class":63},[53,3683,3684,3686,3688,3690],{"class":55,"line":403},[53,3685,2297],{"class":59},[53,3687,394],{"class":63},[53,3689,3586],{"class":59},[53,3691,488],{"class":63},[53,3693,3694],{"class":55,"line":417},[53,3695,2392],{"class":63},[53,3697,3698],{"class":55,"line":423},[53,3699,350],{"class":63},[12,3701,3702],{},"这样 consumer：",[20,3704,3705],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,3706,3707],{"__ignoreMap":26},[53,3708,3709,3711,3713],{"class":55,"line":56},[53,3710,242],{"class":63},[53,3712,245],{"class":59},[53,3714,248],{"class":63},[12,3716,3717],{},"会：",[20,3719,3722],{"className":3720,"code":3721,"language":25,"meta":26},[23],"任务成功\n→ 返回结果\n\n任务失败\n→ 重新抛出保存的异常\n",[15,3723,3721],{"__ignoreMap":26},[119,3725],{},[127,3727,3729],{"id":3728},"完整的-promise-异常示例","完整的 promise 异常示例",[20,3731,3733],{"className":47,"code":3732,"language":49,"meta":26,"style":26},"#include \u003Cexception>\n#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cstdexcept>\n#include \u003Cthread>\n\nvoid producer(std::promise\u003Cint> promise)\n{\n    try\n    {\n        throw std::runtime_error(\"failed\");\n    }\n    catch (...)\n    {\n        promise.set_exception(\n            std::current_exception());\n    }\n}\n\nint main()\n{\n    std::promise\u003Cint> promise;\n\n    auto future = promise.get_future();\n\n    std::thread thread(\n        producer,\n        std::move(promise));\n\n    try\n    {\n        std::println(\"{}\", future.get());\n    }\n    catch (const std::exception& e)\n    {\n        std::println(\"{}\", e.what());\n    }\n\n    thread.join();\n}\n",[15,3734,3735,3742,3748,3754,3760,3766,3770,3794,3798,3802,3806,3824,3828,3834,3838,3846,3856,3860,3864,3868,3876,3880,3890,3894,3908,3912,3922,3926,3937,3942,3947,3952,3971,3976,3993,3998,4017,4022,4027,4036],{"__ignoreMap":26},[53,3736,3737,3739],{"class":55,"line":56},[53,3738,279],{"class":163},[53,3740,3741],{"class":282}," \u003Cexception>\n",[53,3743,3744,3746],{"class":55,"line":67},[53,3745,279],{"class":163},[53,3747,283],{"class":282},[53,3749,3750,3752],{"class":55,"line":75},[53,3751,279],{"class":163},[53,3753,290],{"class":282},[53,3755,3756,3758],{"class":55,"line":83},[53,3757,279],{"class":163},[53,3759,2624],{"class":282},[53,3761,3762,3764],{"class":55,"line":91},[53,3763,279],{"class":163},[53,3765,1011],{"class":282},[53,3767,3768],{"class":55,"line":332},[53,3769,296],{"emptyLinePlaceholder":295},[53,3771,3772,3774,3776,3778,3780,3782,3784,3786,3788,3790,3792],{"class":55,"line":347},[53,3773,3059],{"class":163},[53,3775,3062],{"class":59},[53,3777,307],{"class":63},[53,3779,60],{"class":59},[53,3781,394],{"class":63},[53,3783,3071],{"class":59},[53,3785,2916],{"class":63},[53,3787,301],{"class":163},[53,3789,3078],{"class":63},[53,3791,3071],{"class":312},[53,3793,324],{"class":63},[53,3795,3796],{"class":55,"line":353},[53,3797,329],{"class":63},[53,3799,3800],{"class":55,"line":358},[53,3801,2708],{"class":163},[53,3803,3804],{"class":55,"line":369},[53,3805,2372],{"class":63},[53,3807,3808,3811,3813,3815,3817,3819,3822],{"class":55,"line":374},[53,3809,3810],{"class":163},"        throw",[53,3812,391],{"class":59},[53,3814,394],{"class":63},[53,3816,2688],{"class":59},[53,3818,307],{"class":63},[53,3820,3821],{"class":282},"\"failed\"",[53,3823,439],{"class":63},[53,3825,3826],{"class":55,"line":403},[53,3827,2392],{"class":63},[53,3829,3830,3832],{"class":55,"line":417},[53,3831,2739],{"class":163},[53,3833,3669],{"class":63},[53,3835,3836],{"class":55,"line":423},[53,3837,2372],{"class":63},[53,3839,3840,3842,3844],{"class":55,"line":433},[53,3841,3153],{"class":63},[53,3843,3575],{"class":59},[53,3845,400],{"class":63},[53,3847,3848,3850,3852,3854],{"class":55,"line":442},[53,3849,2297],{"class":59},[53,3851,394],{"class":63},[53,3853,3586],{"class":59},[53,3855,488],{"class":63},[53,3857,3858],{"class":55,"line":447},[53,3859,2392],{"class":63},[53,3861,3862],{"class":55,"line":464},[53,3863,350],{"class":63},[53,3865,3866],{"class":55,"line":469},[53,3867,296],{"emptyLinePlaceholder":295},[53,3869,3870,3872,3874],{"class":55,"line":491},[53,3871,301],{"class":163},[53,3873,363],{"class":59},[53,3875,366],{"class":63},[53,3877,3878],{"class":55,"line":1150},[53,3879,329],{"class":63},[53,3881,3882,3884,3886,3888],{"class":55,"line":1161},[53,3883,377],{"class":59},[53,3885,2913],{"class":63},[53,3887,382],{"class":163},[53,3889,2977],{"class":63},[53,3891,3892],{"class":55,"line":1167},[53,3893,296],{"emptyLinePlaceholder":295},[53,3895,3896,3898,3900,3902,3904,3906],{"class":55,"line":1172},[53,3897,1135],{"class":163},[53,3899,2996],{"class":63},[53,3901,388],{"class":163},[53,3903,3001],{"class":63},[53,3905,3004],{"class":59},[53,3907,248],{"class":63},[53,3909,3910],{"class":55,"line":1188},[53,3911,296],{"emptyLinePlaceholder":295},[53,3913,3914,3916,3918,3920],{"class":55,"line":1193},[53,3915,377],{"class":59},[53,3917,3168],{"class":63},[53,3919,660],{"class":59},[53,3921,400],{"class":63},[53,3923,3924],{"class":55,"line":1212},[53,3925,3177],{"class":63},[53,3927,3929,3931,3933,3935],{"class":55,"line":3928},28,[53,3930,406],{"class":59},[53,3932,394],{"class":63},[53,3934,3186],{"class":59},[53,3936,3189],{"class":63},[53,3938,3940],{"class":55,"line":3939},29,[53,3941,296],{"emptyLinePlaceholder":295},[53,3943,3945],{"class":55,"line":3944},30,[53,3946,2708],{"class":163},[53,3948,3950],{"class":55,"line":3949},31,[53,3951,2372],{"class":63},[53,3953,3955,3957,3959,3961,3963,3965,3967,3969],{"class":55,"line":3954},32,[53,3956,406],{"class":59},[53,3958,394],{"class":63},[53,3960,454],{"class":59},[53,3962,307],{"class":63},[53,3964,480],{"class":282},[53,3966,3208],{"class":63},[53,3968,245],{"class":59},[53,3970,488],{"class":63},[53,3972,3974],{"class":55,"line":3973},33,[53,3975,2392],{"class":63},[53,3977,3979,3981,3983,3985,3987,3989,3991],{"class":55,"line":3978},34,[53,3980,2739],{"class":163},[53,3982,2742],{"class":63},[53,3984,2745],{"class":163},[53,3986,391],{"class":59},[53,3988,2750],{"class":63},[53,3990,2753],{"class":163},[53,3992,2756],{"class":63},[53,3994,3996],{"class":55,"line":3995},35,[53,3997,2372],{"class":63},[53,3999,4001,4003,4005,4007,4009,4011,4013,4015],{"class":55,"line":4000},36,[53,4002,406],{"class":59},[53,4004,394],{"class":63},[53,4006,454],{"class":59},[53,4008,307],{"class":63},[53,4010,480],{"class":282},[53,4012,2775],{"class":63},[53,4014,2778],{"class":59},[53,4016,488],{"class":63},[53,4018,4020],{"class":55,"line":4019},37,[53,4021,2392],{"class":63},[53,4023,4025],{"class":55,"line":4024},38,[53,4026,296],{"emptyLinePlaceholder":295},[53,4028,4030,4032,4034],{"class":55,"line":4029},39,[53,4031,3221],{"class":63},[53,4033,3224],{"class":59},[53,4035,248],{"class":63},[53,4037,4039],{"class":55,"line":4038},40,[53,4040,350],{"class":63},[12,4042,2421],{},[20,4044,4047],{"className":4045,"code":4046,"language":25,"meta":26},[23],"failed\n",[15,4048,4046],{"__ignoreMap":26},[12,4050,4051],{},"流程是：",[20,4053,4056],{"className":4054,"code":4055,"language":25,"meta":26},[23],"worker 发生异常\n↓\ncatch 捕获异常\n↓\npromise.set_exception(...)\n↓\n异常进入 shared state\n↓\nmain 调用 future.get()\n↓\n异常在 main 中重新抛出\n",[15,4057,4055],{"__ignoreMap":26},[119,4059],{},[127,4061,4063],{"id":4062},"什么是-broken-promise","什么是 broken promise",[12,4065,4066],{},"假设：",[20,4068,4070],{"className":47,"code":4069,"language":49,"meta":26,"style":26},"std::future\u003Cint> future;\n\n{\n    std::promise\u003Cint> promise;\n\n    future = promise.get_future();\n}\n",[15,4071,4072,4083,4087,4091,4101,4105,4118],{"__ignoreMap":26},[53,4073,4074,4076,4078,4080],{"class":55,"line":56},[53,4075,60],{"class":59},[53,4077,160],{"class":63},[53,4079,382],{"class":163},[53,4081,4082],{"class":63}," future;\n",[53,4084,4085],{"class":55,"line":67},[53,4086,296],{"emptyLinePlaceholder":295},[53,4088,4089],{"class":55,"line":75},[53,4090,329],{"class":63},[53,4092,4093,4095,4097,4099],{"class":55,"line":83},[53,4094,377],{"class":59},[53,4096,2913],{"class":63},[53,4098,382],{"class":163},[53,4100,2977],{"class":63},[53,4102,4103],{"class":55,"line":91},[53,4104,296],{"emptyLinePlaceholder":295},[53,4106,4107,4110,4112,4114,4116],{"class":55,"line":332},[53,4108,4109],{"class":63},"    future ",[53,4111,388],{"class":163},[53,4113,3001],{"class":63},[53,4115,3004],{"class":59},[53,4117,248],{"class":63},[53,4119,4120],{"class":55,"line":347},[53,4121,350],{"class":63},[12,4123,4124],{},"这里 promise 离开作用域时：",[20,4126,4129],{"className":4127,"code":4128,"language":25,"meta":26},[23],"没有 set_value()\n\n也没有 set_exception()\n",[15,4130,4128],{"__ignoreMap":26},[12,4132,4133],{},"但 future 还在等待结果。",[12,4135,4136],{},"这种情况叫：",[101,4138,4139],{},[12,4140,4141],{},[106,4142,4143],{},"broken promise",[12,4145,4146],{},"也就是：",[20,4148,4151],{"className":4149,"code":4150,"language":25,"meta":26},[23],"原本负责生产结果的人已经消失\n\n但结果还没有产生\n",[15,4152,4150],{"__ignoreMap":26},[12,4154,4155],{},"标准库不会让 future 永远傻等。",[12,4157,1641],{},[20,4159,4160],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,4161,4162],{"__ignoreMap":26},[53,4163,4164,4166,4168],{"class":55,"line":56},[53,4165,242],{"class":63},[53,4167,245],{"class":59},[53,4169,248],{"class":63},[12,4171,4172],{},"会得到一个对应的：",[20,4174,4175],{"className":47,"code":1715,"language":49,"meta":26,"style":26},[15,4176,4177],{"__ignoreMap":26},[53,4178,4179,4181],{"class":55,"line":56},[53,4180,60],{"class":59},[53,4182,1724],{"class":63},[12,4184,4185],{},"可以把它理解成：",[101,4187,4188],{},[12,4189,4190],{},"“结果生产端已经断了，不会再有正常结果了。”",[119,4192],{},[127,4194,4196],{"id":4195},"promise-的所有结束路径都应该有明确结果","promise 的所有结束路径都应该有明确结果",[12,4198,4199],{},"如果使用：",[20,4201,4203],{"className":47,"code":4202,"language":49,"meta":26,"style":26},"std::promise\n",[15,4204,4205],{"__ignoreMap":26},[53,4206,4207,4209],{"class":55,"line":56},[53,4208,60],{"class":59},[53,4210,80],{"class":63},[12,4212,4213],{},"生产端最好认真处理：",[20,4215,4218],{"className":4216,"code":4217,"language":25,"meta":26},[23],"成功\n→ set_value()\n\n失败\n→ set_exception()\n\n提前退出 \u002F 取消\n→ 也要设计清楚最终结果\n",[15,4219,4217],{"__ignoreMap":26},[12,4221,4222],{},"否则就容易出现：",[20,4224,4227],{"className":4225,"code":4226,"language":25,"meta":26},[23],"broken promise\n",[15,4228,4226],{"__ignoreMap":26},[119,4230],{},[122,4232,4234],{"id":4233},"stdpackaged_task",[15,4235,4236],{},"std::packaged_task",[12,4238,4239,4241],{},[15,4240,4236],{}," 解决的是另一类问题。",[12,4243,4244],{},"假设已经有：",[20,4246,4248],{"className":47,"code":4247,"language":49,"meta":26,"style":26},"int add(int a, int b)\n{\n    return a + b;\n}\n",[15,4249,4250,4271,4275,4285],{"__ignoreMap":26},[53,4251,4252,4254,4257,4259,4261,4263,4265,4267,4269],{"class":55,"line":56},[53,4253,301],{"class":163},[53,4255,4256],{"class":59}," add",[53,4258,307],{"class":63},[53,4260,301],{"class":163},[53,4262,313],{"class":312},[53,4264,316],{"class":63},[53,4266,301],{"class":163},[53,4268,321],{"class":312},[53,4270,324],{"class":63},[53,4272,4273],{"class":55,"line":67},[53,4274,329],{"class":63},[53,4276,4277,4279,4281,4283],{"class":55,"line":75},[53,4278,335],{"class":163},[53,4280,338],{"class":63},[53,4282,341],{"class":163},[53,4284,344],{"class":63},[53,4286,4287],{"class":55,"line":83},[53,4288,350],{"class":63},[12,4290,4291],{},"现在想把它变成：",[20,4293,4296],{"className":4294,"code":4295,"language":25,"meta":26},[23],"一个“执行以后自动把结果写到 future”的任务\n",[15,4297,4295],{"__ignoreMap":26},[12,4299,4300],{},"可以使用：",[20,4302,4304],{"className":47,"code":4303,"language":49,"meta":26,"style":26},"std::packaged_task\n",[15,4305,4306],{"__ignoreMap":26},[53,4307,4308,4310],{"class":55,"line":56},[53,4309,60],{"class":59},[53,4311,88],{"class":63},[12,4313,2925],{},[101,4315,4316],{},[12,4317,4318],{},[106,4319,4320],{},"把一个可调用对象包装成一个“自带 future 结果通道”的任务对象。",[119,4322],{},[127,4324,4326],{"id":4325},"packaged_task-最简单的例子","packaged_task 最简单的例子",[20,4328,4330],{"className":47,"code":4329,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n\nint add(int a, int b)\n{\n    return a + b;\n}\n\nint main()\n{\n    std::packaged_task\u003Cint(int, int)> task(add);\n\n    std::future\u003Cint> result =\n        task.get_future();\n\n    task(10, 20);\n\n    std::println(\"{}\", result.get());\n}\n",[15,4331,4332,4338,4344,4348,4368,4372,4382,4386,4390,4398,4402,4431,4435,4447,4456,4460,4477,4481,4499],{"__ignoreMap":26},[53,4333,4334,4336],{"class":55,"line":56},[53,4335,279],{"class":163},[53,4337,283],{"class":282},[53,4339,4340,4342],{"class":55,"line":67},[53,4341,279],{"class":163},[53,4343,290],{"class":282},[53,4345,4346],{"class":55,"line":75},[53,4347,296],{"emptyLinePlaceholder":295},[53,4349,4350,4352,4354,4356,4358,4360,4362,4364,4366],{"class":55,"line":83},[53,4351,301],{"class":163},[53,4353,4256],{"class":59},[53,4355,307],{"class":63},[53,4357,301],{"class":163},[53,4359,313],{"class":312},[53,4361,316],{"class":63},[53,4363,301],{"class":163},[53,4365,321],{"class":312},[53,4367,324],{"class":63},[53,4369,4370],{"class":55,"line":91},[53,4371,329],{"class":63},[53,4373,4374,4376,4378,4380],{"class":55,"line":332},[53,4375,335],{"class":163},[53,4377,338],{"class":63},[53,4379,341],{"class":163},[53,4381,344],{"class":63},[53,4383,4384],{"class":55,"line":347},[53,4385,350],{"class":63},[53,4387,4388],{"class":55,"line":353},[53,4389,296],{"emptyLinePlaceholder":295},[53,4391,4392,4394,4396],{"class":55,"line":358},[53,4393,301],{"class":163},[53,4395,363],{"class":59},[53,4397,366],{"class":63},[53,4399,4400],{"class":55,"line":369},[53,4401,329],{"class":63},[53,4403,4404,4406,4409,4412,4414,4416,4418,4420,4423,4426,4428],{"class":55,"line":374},[53,4405,377],{"class":59},[53,4407,4408],{"class":63},"::packaged_task",[53,4410,4411],{"class":163},"\u003Cint",[53,4413,307],{"class":63},[53,4415,301],{"class":163},[53,4417,316],{"class":63},[53,4419,301],{"class":163},[53,4421,4422],{"class":63},")",[53,4424,4425],{"class":163},">",[53,4427,1022],{"class":59},[53,4429,4430],{"class":63},"(add);\n",[53,4432,4433],{"class":55,"line":403},[53,4434,296],{"emptyLinePlaceholder":295},[53,4436,4437,4439,4441,4443,4445],{"class":55,"line":417},[53,4438,377],{"class":59},[53,4440,160],{"class":63},[53,4442,382],{"class":163},[53,4444,385],{"class":63},[53,4446,3148],{"class":163},[53,4448,4449,4452,4454],{"class":55,"line":423},[53,4450,4451],{"class":63},"        task.",[53,4453,3004],{"class":59},[53,4455,248],{"class":63},[53,4457,4458],{"class":55,"line":433},[53,4459,296],{"emptyLinePlaceholder":295},[53,4461,4462,4465,4467,4470,4472,4475],{"class":55,"line":442},[53,4463,4464],{"class":59},"    task",[53,4466,307],{"class":63},[53,4468,4469],{"class":426},"10",[53,4471,316],{"class":63},[53,4473,4474],{"class":426},"20",[53,4476,439],{"class":63},[53,4478,4479],{"class":55,"line":447},[53,4480,296],{"emptyLinePlaceholder":295},[53,4482,4483,4485,4487,4489,4491,4493,4495,4497],{"class":55,"line":464},[53,4484,377],{"class":59},[53,4486,394],{"class":63},[53,4488,454],{"class":59},[53,4490,307],{"class":63},[53,4492,480],{"class":282},[53,4494,483],{"class":63},[53,4496,245],{"class":59},[53,4498,488],{"class":63},[53,4500,4501],{"class":55,"line":469},[53,4502,350],{"class":63},[12,4504,2421],{},[20,4506,4509],{"className":4507,"code":4508,"language":25,"meta":26},[23],"30\n",[15,4510,4508],{"__ignoreMap":26},[12,4512,505],{},[20,4514,4516],{"className":47,"code":4515,"language":49,"meta":26,"style":26},"std::packaged_task\u003Cint(int, int)>\n",[15,4517,4518],{"__ignoreMap":26},[53,4519,4520,4522,4524,4526,4528,4530,4532,4534,4536],{"class":55,"line":56},[53,4521,60],{"class":59},[53,4523,4408],{"class":63},[53,4525,4411],{"class":163},[53,4527,307],{"class":63},[53,4529,301],{"class":163},[53,4531,316],{"class":63},[53,4533,301],{"class":163},[53,4535,4422],{"class":63},[53,4537,2922],{"class":163},[12,4539,167],{},[20,4541,4544],{"className":4542,"code":4543,"language":25,"meta":26},[23],"这个任务：\n\n接收两个 int\n返回一个 int\n",[15,4545,4543],{"__ignoreMap":26},[12,4547,2961],{},[20,4549,4551],{"className":47,"code":4550,"language":49,"meta":26,"style":26},"std::packaged_task\u003Cint(int, int)> task(add);\n",[15,4552,4553],{"__ignoreMap":26},[53,4554,4555,4557,4559,4562,4564,4566,4568,4570,4572,4574,4577,4580,4582,4585],{"class":55,"line":56},[53,4556,60],{"class":59},[53,4558,394],{"class":63},[53,4560,4561],{"class":59},"packaged_task",[53,4563,2916],{"class":63},[53,4565,301],{"class":163},[53,4567,307],{"class":63},[53,4569,301],{"class":163},[53,4571,316],{"class":63},[53,4573,301],{"class":163},[53,4575,4576],{"class":63},")> ",[53,4578,4579],{"class":59},"task",[53,4581,307],{"class":63},[53,4583,4584],{"class":59},"add",[53,4586,439],{"class":63},[12,4588,4589],{},"以后：",[20,4591,4593],{"className":47,"code":4592,"language":49,"meta":26,"style":26},"task(10, 20);\n",[15,4594,4595],{"__ignoreMap":26},[53,4596,4597,4599,4601,4603,4605,4607],{"class":55,"line":56},[53,4598,4579],{"class":59},[53,4600,307],{"class":63},[53,4602,4469],{"class":426},[53,4604,316],{"class":63},[53,4606,4474],{"class":426},[53,4608,439],{"class":63},[12,4610,4611],{},"实际上会：",[20,4613,4616],{"className":4614,"code":4615,"language":25,"meta":26},[23],"调用 add(10, 20)\n↓\n得到返回值 30\n↓\n自动把 30 写入 shared state\n↓\nresult.get() 取得 30\n",[15,4617,4615],{"__ignoreMap":26},[119,4619],{},[127,4621,4623],{"id":4622},"packaged_task-和-promise-最大的区别","packaged_task 和 promise 最大的区别",[12,4625,4626,4628],{},[15,4627,3071],{}," 是：",[101,4630,4631],{},[12,4632,4633],{},[106,4634,4635],{},"你自己决定什么时候写结果。",[12,4637,148],{},[20,4639,4640],{"className":47,"code":3345,"language":49,"meta":26,"style":26},[15,4641,4642],{"__ignoreMap":26},[53,4643,4644,4646,4648,4650,4652],{"class":55,"line":56},[53,4645,3352],{"class":63},[53,4647,3094],{"class":59},[53,4649,307],{"class":63},[53,4651,3099],{"class":426},[53,4653,439],{"class":63},[12,4655,4656,4657,4628],{},"而 ",[15,4658,4561],{},[101,4660,4661],{},[12,4662,4663],{},[106,4664,4665],{},"你给它一个函数，执行这个函数时，它自动把函数的返回值写入结果通道。",[12,4667,111],{},[20,4669,4672],{"className":4670,"code":4671,"language":25,"meta":26},[23],"promise\n→ 手动写结果\n\npackaged_task\n→ 执行函数，自动写结果\n",[15,4673,4671],{"__ignoreMap":26},[119,4675],{},[127,4677,4679,4681],{"id":4678},"packaged_task-会自动传递异常",[15,4680,4561],{}," 会自动传递异常",[12,4683,4684],{},"假设被包装的函数：",[20,4686,4688],{"className":47,"code":4687,"language":49,"meta":26,"style":26},"int work()\n{\n    throw std::runtime_error(\"failed\");\n}\n",[15,4689,4690,4699,4703,4720],{"__ignoreMap":26},[53,4691,4692,4694,4697],{"class":55,"line":56},[53,4693,301],{"class":163},[53,4695,4696],{"class":59}," work",[53,4698,366],{"class":63},[53,4700,4701],{"class":55,"line":67},[53,4702,329],{"class":63},[53,4704,4705,4708,4710,4712,4714,4716,4718],{"class":55,"line":75},[53,4706,4707],{"class":163},"    throw",[53,4709,391],{"class":59},[53,4711,394],{"class":63},[53,4713,2688],{"class":59},[53,4715,307],{"class":63},[53,4717,3821],{"class":282},[53,4719,439],{"class":63},[53,4721,4722],{"class":55,"line":83},[53,4723,350],{"class":63},[12,4725,4726],{},"包装成：",[20,4728,4730],{"className":47,"code":4729,"language":49,"meta":26,"style":26},"std::packaged_task\u003Cint()> task(work);\n",[15,4731,4732],{"__ignoreMap":26},[53,4733,4734,4736,4738,4740,4742,4744,4747,4749,4751,4754],{"class":55,"line":56},[53,4735,60],{"class":59},[53,4737,394],{"class":63},[53,4739,4561],{"class":59},[53,4741,2916],{"class":63},[53,4743,301],{"class":163},[53,4745,4746],{"class":63},"()> ",[53,4748,4579],{"class":59},[53,4750,307],{"class":63},[53,4752,4753],{"class":59},"work",[53,4755,439],{"class":63},[12,4757,4758],{},"执行：",[20,4760,4762],{"className":47,"code":4761,"language":49,"meta":26,"style":26},"task();\n",[15,4763,4764],{"__ignoreMap":26},[53,4765,4766,4768],{"class":55,"line":56},[53,4767,4579],{"class":59},[53,4769,248],{"class":63},[12,4771,4772,4773,4776,4777,4779],{},"如果 ",[15,4774,4775],{},"work()"," 抛异常，",[15,4778,4561],{}," 会把异常保存到共享状态。",[12,4781,1641],{},[20,4783,4784],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,4785,4786],{"__ignoreMap":26},[53,4787,4788,4790,4792],{"class":55,"line":56},[53,4789,242],{"class":63},[53,4791,245],{"class":59},[53,4793,248],{"class":63},[12,4795,4796],{},"会重新抛出这个异常。",[12,4798,4799],{},"所以它不只会自动处理：",[20,4801,4804],{"className":4802,"code":4803,"language":25,"meta":26},[23],"返回值\n",[15,4805,4803],{"__ignoreMap":26},[12,4807,4808],{},"也会自动处理：",[20,4810,4813],{"className":4811,"code":4812,"language":25,"meta":26},[23],"异常\n",[15,4814,4812],{"__ignoreMap":26},[119,4816],{},[127,4818,4820,4822],{"id":4819},"packaged_task-和-thread-配合",[15,4821,4561],{}," 和 thread 配合",[12,4824,4825],{},"可以把 packaged task 交给线程执行：",[20,4827,4829],{"className":47,"code":4828,"language":49,"meta":26,"style":26},"#include \u003Cfuture>\n#include \u003Cprint>\n#include \u003Cthread>\n\nint calculate()\n{\n    return 42;\n}\n\nint main()\n{\n    std::packaged_task\u003Cint()> task(calculate);\n\n    std::future\u003Cint> result =\n        task.get_future();\n\n    std::thread thread(\n        std::move(task));\n\n    std::println(\"{}\", result.get());\n\n    thread.join();\n}\n",[15,4830,4831,4837,4843,4849,4853,4861,4865,4873,4877,4881,4889,4893,4911,4915,4927,4935,4939,4949,4960,4964,4982,4986,4994],{"__ignoreMap":26},[53,4832,4833,4835],{"class":55,"line":56},[53,4834,279],{"class":163},[53,4836,283],{"class":282},[53,4838,4839,4841],{"class":55,"line":67},[53,4840,279],{"class":163},[53,4842,290],{"class":282},[53,4844,4845,4847],{"class":55,"line":75},[53,4846,279],{"class":163},[53,4848,1011],{"class":282},[53,4850,4851],{"class":55,"line":83},[53,4852,296],{"emptyLinePlaceholder":295},[53,4854,4855,4857,4859],{"class":55,"line":91},[53,4856,301],{"class":163},[53,4858,304],{"class":59},[53,4860,366],{"class":63},[53,4862,4863],{"class":55,"line":332},[53,4864,329],{"class":63},[53,4866,4867,4869,4871],{"class":55,"line":347},[53,4868,335],{"class":163},[53,4870,1072],{"class":426},[53,4872,1075],{"class":63},[53,4874,4875],{"class":55,"line":353},[53,4876,350],{"class":63},[53,4878,4879],{"class":55,"line":358},[53,4880,296],{"emptyLinePlaceholder":295},[53,4882,4883,4885,4887],{"class":55,"line":369},[53,4884,301],{"class":163},[53,4886,363],{"class":59},[53,4888,366],{"class":63},[53,4890,4891],{"class":55,"line":374},[53,4892,329],{"class":63},[53,4894,4895,4897,4899,4901,4904,4906,4908],{"class":55,"line":403},[53,4896,377],{"class":59},[53,4898,4408],{"class":63},[53,4900,4411],{"class":163},[53,4902,4903],{"class":63},"()",[53,4905,4425],{"class":163},[53,4907,1022],{"class":59},[53,4909,4910],{"class":63},"(calculate);\n",[53,4912,4913],{"class":55,"line":417},[53,4914,296],{"emptyLinePlaceholder":295},[53,4916,4917,4919,4921,4923,4925],{"class":55,"line":423},[53,4918,377],{"class":59},[53,4920,160],{"class":63},[53,4922,382],{"class":163},[53,4924,385],{"class":63},[53,4926,3148],{"class":163},[53,4928,4929,4931,4933],{"class":55,"line":433},[53,4930,4451],{"class":63},[53,4932,3004],{"class":59},[53,4934,248],{"class":63},[53,4936,4937],{"class":55,"line":442},[53,4938,296],{"emptyLinePlaceholder":295},[53,4940,4941,4943,4945,4947],{"class":55,"line":447},[53,4942,377],{"class":59},[53,4944,3168],{"class":63},[53,4946,660],{"class":59},[53,4948,400],{"class":63},[53,4950,4951,4953,4955,4957],{"class":55,"line":464},[53,4952,406],{"class":59},[53,4954,394],{"class":63},[53,4956,3186],{"class":59},[53,4958,4959],{"class":63},"(task));\n",[53,4961,4962],{"class":55,"line":469},[53,4963,296],{"emptyLinePlaceholder":295},[53,4965,4966,4968,4970,4972,4974,4976,4978,4980],{"class":55,"line":491},[53,4967,377],{"class":59},[53,4969,394],{"class":63},[53,4971,454],{"class":59},[53,4973,307],{"class":63},[53,4975,480],{"class":282},[53,4977,483],{"class":63},[53,4979,245],{"class":59},[53,4981,488],{"class":63},[53,4983,4984],{"class":55,"line":1150},[53,4985,296],{"emptyLinePlaceholder":295},[53,4987,4988,4990,4992],{"class":55,"line":1161},[53,4989,3221],{"class":63},[53,4991,3224],{"class":59},[53,4993,248],{"class":63},[53,4995,4996],{"class":55,"line":1167},[53,4997,350],{"class":63},[12,4999,2421],{},[20,5001,5003],{"className":5002,"code":3236,"language":25,"meta":26},[23],[15,5004,3236],{"__ignoreMap":26},[12,5006,505],{},[20,5008,5010],{"className":47,"code":5009,"language":49,"meta":26,"style":26},"std::thread thread(\n    std::move(task));\n",[15,5011,5012,5024],{"__ignoreMap":26},[53,5013,5014,5016,5018,5020,5022],{"class":55,"line":56},[53,5015,60],{"class":59},[53,5017,394],{"class":63},[53,5019,660],{"class":59},[53,5021,3289],{"class":59},[53,5023,400],{"class":63},[53,5025,5026,5028,5030,5032],{"class":55,"line":67},[53,5027,377],{"class":59},[53,5029,394],{"class":63},[53,5031,3186],{"class":59},[53,5033,4959],{"class":63},[12,5035,167],{},[20,5037,5040],{"className":5038,"code":5039,"language":25,"meta":26},[23],"把 task 移动给新线程\n↓\n新线程执行 task()\n↓\ntask 内部调用 calculate()\n↓\n返回值写入 shared state\n↓\nresult.get() 得到 42\n",[15,5041,5039],{"__ignoreMap":26},[119,5043],{},[127,5045,5047],{"id":5046},"packaged_task-也是-move-only","packaged_task 也是 move-only",[12,5049,5050,5051,5053],{},"和 ",[15,5052,3071],{}," 类似：",[20,5055,5056],{"className":47,"code":4303,"language":49,"meta":26,"style":26},[15,5057,5058],{"__ignoreMap":26},[53,5059,5060,5062],{"class":55,"line":56},[53,5061,60],{"class":59},[53,5063,88],{"class":63},[12,5065,5066],{},"也不能随意复制。",[12,5068,5069],{},"通常需要：",[20,5071,5073],{"className":47,"code":5072,"language":49,"meta":26,"style":26},"std::move(task)\n",[15,5074,5075],{"__ignoreMap":26},[53,5076,5077,5079,5081,5083],{"class":55,"line":56},[53,5078,60],{"class":59},[53,5080,394],{"class":63},[53,5082,3186],{"class":59},[53,5084,5085],{"class":63},"(task)\n",[12,5087,5088],{},"把它移动到：",[20,5090,5093],{"className":5091,"code":5092,"language":25,"meta":26},[23],"线程\n\n任务队列\n\nworker\n",[15,5094,5092],{"__ignoreMap":26},[12,5096,5097],{},"中。",[119,5099],{},[127,5101,5103],{"id":5102},"为什么-packaged_task-很适合任务队列","为什么 packaged_task 很适合任务队列",[12,5105,5106],{},"线程池通常会有这种思想：",[20,5108,5111],{"className":5109,"code":5110,"language":25,"meta":26},[23],"用户提交函数\n↓\n包装成任务对象\n↓\n放进任务队列\n↓\nworker 线程取任务\n↓\n执行任务\n↓\n结果写进 shared state\n↓\n用户拿 future 等结果\n",[15,5112,5110],{"__ignoreMap":26},[12,5114,5115],{},"这正好和：",[20,5117,5118],{"className":47,"code":4303,"language":49,"meta":26,"style":26},[15,5119,5120],{"__ignoreMap":26},[53,5121,5122,5124],{"class":55,"line":56},[53,5123,60],{"class":59},[53,5125,88],{"class":63},[12,5127,5128],{},"的设计非常契合。",[12,5130,5131],{},"因为 packaged task 本身已经把：",[20,5133,5136],{"className":5134,"code":5135,"language":25,"meta":26},[23],"怎么执行任务\n+\n结果写到哪里\n",[15,5137,5135],{"__ignoreMap":26},[12,5139,5140],{},"绑定在一起了。",[119,5142],{},[127,5144,5146,1248,5148,5150],{"id":5145},"promise-和-packaged_task-怎么选",[15,5147,3071],{},[15,5149,4561],{}," 怎么选",[12,5152,5153],{},"可以这样记：",[5155,5156,5157],"h4",{"id":3071},[15,5158,3071],{},[12,5160,5161],{},"适合：",[20,5163,5166],{"className":5164,"code":5165,"language":25,"meta":26},[23],"我自己决定结果什么时候产生\n\n结果不一定直接来自某个函数返回值\n\n生产过程可能分很多步骤\n",[15,5167,5165],{"__ignoreMap":26},[12,5169,148],{},[20,5171,5172],{"className":47,"code":3549,"language":49,"meta":26,"style":26},[15,5173,5174],{"__ignoreMap":26},[53,5175,5176,5178,5180],{"class":55,"line":56},[53,5177,3352],{"class":63},[53,5179,3094],{"class":59},[53,5181,3560],{"class":63},[12,5183,5184],{},"由你自己控制。",[119,5186],{},[5155,5188,5189],{"id":4561},[15,5190,4561],{},[12,5192,5161],{},[20,5194,5197],{"className":5195,"code":5196,"language":25,"meta":26},[23],"我已经有一个函数 \u002F lambda\n\n我就想把它包装成一个“执行后有 future 结果”的任务\n",[15,5198,5196],{"__ignoreMap":26},[12,5200,148],{},[20,5202,5204],{"className":47,"code":5203,"language":49,"meta":26,"style":26},"std::packaged_task\u003Cint()> task(calculate);\n",[15,5205,5206],{"__ignoreMap":26},[53,5207,5208,5210,5212,5214,5216,5218,5220,5222,5224,5227],{"class":55,"line":56},[53,5209,60],{"class":59},[53,5211,394],{"class":63},[53,5213,4561],{"class":59},[53,5215,2916],{"class":63},[53,5217,301],{"class":163},[53,5219,4746],{"class":63},[53,5221,4579],{"class":59},[53,5223,307],{"class":63},[53,5225,5226],{"class":59},"calculate",[53,5228,439],{"class":63},[12,5230,5231],{},"然后：",[20,5233,5234],{"className":47,"code":4761,"language":49,"meta":26,"style":26},[15,5235,5236],{"__ignoreMap":26},[53,5237,5238,5240],{"class":55,"line":56},[53,5239,4579],{"class":59},[53,5241,248],{"class":63},[12,5243,5244],{},"自动把返回值送进 future。",[12,5246,5247],{},"所以最简单的区别是：",[20,5249,5252],{"className":5250,"code":5251,"language":25,"meta":26},[23],"promise\n→ 手动生产结果\n\npackaged_task\n→ 包装可调用对象，自动生产结果\n",[15,5253,5251],{"__ignoreMap":26},[119,5255],{},[122,5257,5259],{"id":5258},"stdshared_future",[15,5260,5261],{},"std::shared_future",[12,5263,5264],{},"普通：",[20,5266,5268],{"className":47,"code":5267,"language":49,"meta":26,"style":26},"std::future\u003CT>\n",[15,5269,5270],{"__ignoreMap":26},[53,5271,5272,5274,5276,5278,5280],{"class":55,"line":56},[53,5273,60],{"class":59},[53,5275,160],{"class":63},[53,5277,2916],{"class":163},[53,5279,2919],{"class":63},[53,5281,2922],{"class":163},[12,5283,5284],{},"更适合：",[20,5286,5289],{"className":5287,"code":5288,"language":25,"meta":26},[23],"一个消费者\n",[15,5290,5288],{"__ignoreMap":26},[12,5292,5293],{},"因为：",[20,5295,5296],{"className":47,"code":235,"language":49,"meta":26,"style":26},[15,5297,5298],{"__ignoreMap":26},[53,5299,5300,5302,5304],{"class":55,"line":56},[53,5301,242],{"class":63},[53,5303,245],{"class":59},[53,5305,248],{"class":63},[12,5307,5308],{},"通常只能消费一次。",[12,5310,2447],{},[101,5312,5313],{},[12,5314,5315],{},"多个线程都需要读取同一个异步结果",[12,5317,4300],{},[20,5319,5321],{"className":47,"code":5320,"language":49,"meta":26,"style":26},"std::shared_future\u003CT>\n",[15,5322,5323],{"__ignoreMap":26},[53,5324,5325,5327,5330,5332,5334],{"class":55,"line":56},[53,5326,60],{"class":59},[53,5328,5329],{"class":63},"::shared_future",[53,5331,2916],{"class":163},[53,5333,2919],{"class":63},[53,5335,2922],{"class":163},[119,5337],{},[127,5339,5341],{"id":5340},"future-转成-shared_future","future 转成 shared_future",[12,5343,148],{},[20,5345,5347],{"className":47,"code":5346,"language":49,"meta":26,"style":26},"auto future = std::async(\n    std::launch::async,\n    [] {\n        return 42;\n    });\n\nstd::shared_future\u003Cint> shared =\n    future.share();\n",[15,5348,5349,5365,5375,5379,5387,5391,5395,5408],{"__ignoreMap":26},[53,5350,5351,5353,5355,5357,5359,5361,5363],{"class":55,"line":56},[53,5352,692],{"class":163},[53,5354,2996],{"class":63},[53,5356,388],{"class":163},[53,5358,391],{"class":59},[53,5360,394],{"class":63},[53,5362,397],{"class":59},[53,5364,400],{"class":63},[53,5366,5367,5369,5371,5373],{"class":55,"line":67},[53,5368,377],{"class":59},[53,5370,394],{"class":63},[53,5372,411],{"class":59},[53,5374,414],{"class":63},[53,5376,5377],{"class":55,"line":75},[53,5378,1495],{"class":63},[53,5380,5381,5383,5385],{"class":55,"line":83},[53,5382,1500],{"class":163},[53,5384,1072],{"class":426},[53,5386,1075],{"class":63},[53,5388,5389],{"class":55,"line":91},[53,5390,1509],{"class":63},[53,5392,5393],{"class":55,"line":332},[53,5394,296],{"emptyLinePlaceholder":295},[53,5396,5397,5399,5401,5403,5406],{"class":55,"line":347},[53,5398,60],{"class":59},[53,5400,5329],{"class":63},[53,5402,382],{"class":163},[53,5404,5405],{"class":63}," shared ",[53,5407,3148],{"class":163},[53,5409,5410,5413,5416],{"class":55,"line":353},[53,5411,5412],{"class":63},"    future.",[53,5414,5415],{"class":59},"share",[53,5417,248],{"class":63},[12,5419,5420],{},"之后可以：",[20,5422,5424],{"className":47,"code":5423,"language":49,"meta":26,"style":26},"shared.get();\nshared.get();\nshared.get();\n",[15,5425,5426,5435,5443],{"__ignoreMap":26},[53,5427,5428,5431,5433],{"class":55,"line":56},[53,5429,5430],{"class":63},"shared.",[53,5432,245],{"class":59},[53,5434,248],{"class":63},[53,5436,5437,5439,5441],{"class":55,"line":67},[53,5438,5430],{"class":63},[53,5440,245],{"class":59},[53,5442,248],{"class":63},[53,5444,5445,5447,5449],{"class":55,"line":75},[53,5446,5430],{"class":63},[53,5448,245],{"class":59},[53,5450,248],{"class":63},[12,5452,5453],{},"多个地方都可以读取同一个结果。",[119,5455],{},[127,5457,5459],{"id":5458},"shared_future-更像共享查看","shared_future 更像“共享查看”",[12,5461,5462],{},"普通 future：",[20,5464,5467],{"className":5465,"code":5466,"language":25,"meta":26},[23],"get()\n→ 把结果取走\n→ future 失效\n",[15,5468,5466],{"__ignoreMap":26},[12,5470,5471],{},"而 shared future：",[20,5473,5476],{"className":5474,"code":5475,"language":25,"meta":26},[23],"get()\n→ 查看共享结果\n→ 不会因为这次 get() 就把结果消费掉\n",[15,5477,5475],{"__ignoreMap":26},[12,5479,111],{},[20,5481,5484],{"className":5482,"code":5483,"language":25,"meta":26},[23],"future\n→ 单消费者\n\nshared_future\n→ 多消费者\n",[15,5485,5483],{"__ignoreMap":26},[12,5487,148],{},[20,5489,5492],{"className":5490,"code":5491,"language":25,"meta":26},[23],"一次性加载配置\n↓\n得到 shared_future\u003CConfig>\n↓\n多个线程等待同一份配置\n↓\n全部读取同一个结果\n",[15,5493,5491],{"__ignoreMap":26},[119,5495],{},[122,5497,5498],{"id":5498},"关系与选择",[127,5500,5501],{"id":5501},"这几个东西到底是什么关系",[12,5503,5504,5505,5507],{},"可以把整个 ",[15,5506,43],{}," 体系理解成：",[20,5509,5512],{"className":5510,"code":5511,"language":25,"meta":26},[23],"                 shared state\n                     │\n       ┌─────────────┴─────────────┐\n       │                           │\n     写入端                      读取端\n       │                           │\n       │                        future\n       │                    shared_future\n       │\n       ├─ promise\n       │   → 手动写结果\n       │\n       ├─ packaged_task\n       │   → 执行函数后自动写结果\n       │\n       └─ async\n           → 提交任务并自动管理结果通道\n",[15,5513,5511],{"__ignoreMap":26},[12,5515,733],{},[20,5517,5520],{"className":5518,"code":5519,"language":25,"meta":26},[23],"future\n→ 负责以后读取结果\n\npromise\n→ 负责手动写结果\n\npackaged_task\n→ 把函数包装成“执行后自动写结果”的任务\n\nasync\n→ 最方便的高级接口，直接提交任务并得到 future\n\nshared_future\n→ 允许多个消费者读取同一个结果\n",[15,5521,5519],{"__ignoreMap":26},[119,5523],{},[127,5525,5527,1248,5529,5150],{"id":5526},"async-和-thread-怎么选",[15,5528,397],{},[15,5530,660],{},[12,5532,5533],{},"如果你关注的是：",[20,5535,5538],{"className":5536,"code":5537,"language":25,"meta":26},[23],"我需要一个长期存在的线程\n\n线程里面一直循环\n\n我要控制它什么时候停止\n\n我要管理生命周期\n",[15,5539,5537],{"__ignoreMap":26},[12,5541,5284],{},[20,5543,5545],{"className":47,"code":5544,"language":49,"meta":26,"style":26},"std::thread\nstd::jthread\n",[15,5546,5547,5553],{"__ignoreMap":26},[53,5548,5549,5551],{"class":55,"line":56},[53,5550,60],{"class":59},[53,5552,884],{"class":63},[53,5554,5555,5557],{"class":55,"line":67},[53,5556,60],{"class":59},[53,5558,5559],{"class":63},"::jthread\n",[12,5561,148],{},[20,5563,5566],{"className":5564,"code":5565,"language":25,"meta":26},[23],"串口接收线程\n\n传感器采集线程\n\n机器人后台 worker\n\n长期循环任务\n",[15,5567,5565],{"__ignoreMap":26},[119,5569],{},[12,5571,5533],{},[20,5573,5576],{"className":5574,"code":5575,"language":25,"meta":26},[23],"我有一个任务\n\n它会算出一个结果\n\n我以后要取得这个结果\n\n任务中的异常也要传回来\n",[15,5577,5575],{"__ignoreMap":26},[12,5579,5284],{},[20,5581,5583],{"className":47,"code":5582,"language":49,"meta":26,"style":26},"std::async\nstd::future\n",[15,5584,5585,5591],{"__ignoreMap":26},[53,5586,5587,5589],{"class":55,"line":56},[53,5588,60],{"class":59},[53,5590,72],{"class":63},[53,5592,5593,5595],{"class":55,"line":67},[53,5594,60],{"class":59},[53,5596,64],{"class":63},[12,5598,148],{},[20,5600,5603],{"className":5601,"code":5602,"language":25,"meta":26},[23],"并行计算一段结果\n\n后台加载文件\n\n异步计算某个值\n",[15,5604,5602],{"__ignoreMap":26},[119,5606],{},[127,5608,5610,5612],{"id":5609},"async-不是线程池",[15,5611,397],{}," 不是线程池",[12,5614,5615],{},"不要把：",[20,5617,5618],{"className":47,"code":2878,"language":49,"meta":26,"style":26},[15,5619,5620],{"__ignoreMap":26},[53,5621,5622,5624],{"class":55,"line":56},[53,5623,60],{"class":59},[53,5625,72],{"class":63},[12,5627,5628],{},"理解成：",[20,5630,5633],{"className":5631,"code":5632,"language":25,"meta":26},[23],"C++ 标准线程池\n",[15,5634,5632],{"__ignoreMap":26},[12,5636,5637],{},"它并不是标准线程池接口。",[12,5639,5640],{},"如果你需要：",[20,5642,5645],{"className":5643,"code":5644,"language":25,"meta":26},[23],"固定数量 worker\n\n不断提交大量小任务\n\n任务队列\n\n长期后台执行\n\n可控停止\n",[15,5646,5644],{"__ignoreMap":26},[12,5648,5649],{},"通常应该考虑：",[20,5651,5654],{"className":5652,"code":5653,"language":25,"meta":26},[23],"线程池\n\nstd::jthread\n\n专门的任务系统\n\n更完整的异步框架\n",[15,5655,5653],{"__ignoreMap":26},[12,5657,5658],{},"而不是不断：",[20,5660,5662],{"className":47,"code":5661,"language":49,"meta":26,"style":26},"std::async(...)\n",[15,5663,5664],{"__ignoreMap":26},[53,5665,5666,5668,5670,5672],{"class":55,"line":56},[53,5667,60],{"class":59},[53,5669,394],{"class":63},[53,5671,397],{"class":59},[53,5673,2459],{"class":63},[119,5675],{},[122,5677,5678],{"id":5678},"常见错误",[127,5680,5682,5683,5686],{"id":5681},"错误认为-stdasync-一定创建新线程","错误：认为 ",[15,5684,5685],{},"std::async()"," 一定创建新线程",[12,5688,148],{},[20,5690,5691],{"className":47,"code":1324,"language":49,"meta":26,"style":26},[15,5692,5693],{"__ignoreMap":26},[53,5694,5695,5697,5699,5701],{"class":55,"line":56},[53,5696,60],{"class":59},[53,5698,394],{"class":63},[53,5700,397],{"class":59},[53,5702,1309],{"class":63},[12,5704,5705],{},"如果不指定 policy，标准允许选择：",[20,5707,5710],{"className":5708,"code":5709,"language":25,"meta":26},[23],"async\n或\ndeferred\n",[15,5711,5709],{"__ignoreMap":26},[12,5713,5714],{},"如果明确要求真正异步：",[20,5716,5718],{"className":47,"code":5717,"language":49,"meta":26,"style":26},"std::async(\n    std::launch::async,\n    task);\n",[15,5719,5720,5730,5740],{"__ignoreMap":26},[53,5721,5722,5724,5726,5728],{"class":55,"line":56},[53,5723,60],{"class":59},[53,5725,394],{"class":63},[53,5727,397],{"class":59},[53,5729,400],{"class":63},[53,5731,5732,5734,5736,5738],{"class":55,"line":67},[53,5733,377],{"class":59},[53,5735,394],{"class":63},[53,5737,411],{"class":59},[53,5739,414],{"class":63},[53,5741,5742],{"class":55,"line":75},[53,5743,841],{"class":63},[119,5745],{},[127,5747,5749,5750],{"id":5748},"错误对普通-future-重复-get","错误：对普通 future 重复 ",[15,5751,1423],{},[12,5753,5754],{},"错误：",[20,5756,5758],{"className":47,"code":5757,"language":49,"meta":26,"style":26},"future.get();\nfuture.get();\n",[15,5759,5760,5768],{"__ignoreMap":26},[53,5761,5762,5764,5766],{"class":55,"line":56},[53,5763,242],{"class":63},[53,5765,245],{"class":59},[53,5767,248],{"class":63},[53,5769,5770,5772,5774],{"class":55,"line":67},[53,5771,242],{"class":63},[53,5773,245],{"class":59},[53,5775,248],{"class":63},[12,5777,1552,5778,5780],{},[15,5779,201],{}," 的结果通常只能消费一次。",[119,5782],{},[127,5784,5786,5787,5789],{"id":5785},"错误忘记-get-还会重新抛出异常","错误：忘记 ",[15,5788,1423],{}," 还会重新抛出异常",[12,5791,148],{},[20,5793,5795],{"className":47,"code":5794,"language":49,"meta":26,"style":26},"auto result = std::async(\n    std::launch::async,\n    task);\n\nresult.get();\n",[15,5796,5797,5813,5823,5827,5831],{"__ignoreMap":26},[53,5798,5799,5801,5803,5805,5807,5809,5811],{"class":55,"line":56},[53,5800,692],{"class":163},[53,5802,385],{"class":63},[53,5804,388],{"class":163},[53,5806,391],{"class":59},[53,5808,394],{"class":63},[53,5810,397],{"class":59},[53,5812,400],{"class":63},[53,5814,5815,5817,5819,5821],{"class":55,"line":67},[53,5816,377],{"class":59},[53,5818,394],{"class":63},[53,5820,411],{"class":59},[53,5822,414],{"class":63},[53,5824,5825],{"class":55,"line":75},[53,5826,841],{"class":63},[53,5828,5829],{"class":55,"line":83},[53,5830,296],{"emptyLinePlaceholder":295},[53,5832,5833,5835,5837],{"class":55,"line":91},[53,5834,614],{"class":63},[53,5836,245],{"class":59},[53,5838,248],{"class":63},[12,5840,5841],{},"这里不仅可能拿到返回值，也可能抛出任务里的异常。",[12,5843,5844],{},"所以必要时要：",[20,5846,5848],{"className":47,"code":5847,"language":49,"meta":26,"style":26},"try\n{\n    result.get();\n}\ncatch (...)\n{\n}\n",[15,5849,5850,5855,5859,5868,5872,5879,5883],{"__ignoreMap":26},[53,5851,5852],{"class":55,"line":56},[53,5853,5854],{"class":163},"try\n",[53,5856,5857],{"class":55,"line":67},[53,5858,329],{"class":63},[53,5860,5861,5864,5866],{"class":55,"line":75},[53,5862,5863],{"class":63},"    result.",[53,5865,245],{"class":59},[53,5867,248],{"class":63},[53,5869,5870],{"class":55,"line":83},[53,5871,350],{"class":63},[53,5873,5874,5877],{"class":55,"line":91},[53,5875,5876],{"class":163},"catch",[53,5878,3669],{"class":63},[53,5880,5881],{"class":55,"line":332},[53,5882,329],{"class":63},[53,5884,5885],{"class":55,"line":347},[53,5886,350],{"class":63},[119,5888],{},[127,5890,5892],{"id":5891},"错误promise-没写结果就被销毁","错误：promise 没写结果就被销毁",[12,5894,5895],{},"如果 promise：",[20,5897,5900],{"className":5898,"code":5899,"language":25,"meta":26},[23],"既没有 set_value()\n\n也没有 set_exception()\n",[15,5901,5899],{"__ignoreMap":26},[12,5903,5904],{},"就消失了，future 会得到：",[20,5906,5908],{"className":5907,"code":4226,"language":25,"meta":26},[23],[15,5909,4226],{"__ignoreMap":26},[119,5911],{},[127,5913,5915],{"id":5914},"错误把-promise-packaged_task-当可复制对象","错误：把 promise \u002F packaged_task 当可复制对象",[12,5917,5918],{},"它们通常是：",[20,5920,5922],{"className":5921,"code":3269,"language":25,"meta":26},[23],[15,5923,3269],{"__ignoreMap":26},[12,5925,5926],{},"跨线程转移时经常需要：",[20,5928,5930],{"className":47,"code":5929,"language":49,"meta":26,"style":26},"std::move(...)\n",[15,5931,5932],{"__ignoreMap":26},[53,5933,5934,5936,5938,5940],{"class":55,"line":56},[53,5935,60],{"class":59},[53,5937,394],{"class":63},[53,5939,3186],{"class":59},[53,5941,2459],{"class":63},[119,5943],{},[127,5945,5947],{"id":5946},"错误用-async-做长期后台循环","错误：用 async 做长期后台循环",[12,5949,148],{},[20,5951,5953],{"className":47,"code":5952,"language":49,"meta":26,"style":26},"std::async(\n    std::launch::async,\n    [] {\n        while (true)\n        {\n            ...\n        }\n    });\n",[15,5954,5955,5965,5975,5979,5991,5996,6001,6006],{"__ignoreMap":26},[53,5956,5957,5959,5961,5963],{"class":55,"line":56},[53,5958,60],{"class":59},[53,5960,394],{"class":63},[53,5962,397],{"class":59},[53,5964,400],{"class":63},[53,5966,5967,5969,5971,5973],{"class":55,"line":67},[53,5968,377],{"class":59},[53,5970,394],{"class":63},[53,5972,411],{"class":59},[53,5974,414],{"class":63},[53,5976,5977],{"class":55,"line":75},[53,5978,1495],{"class":63},[53,5980,5981,5984,5986,5989],{"class":55,"line":83},[53,5982,5983],{"class":163},"        while",[53,5985,2742],{"class":63},[53,5987,5988],{"class":426},"true",[53,5990,324],{"class":63},[53,5992,5993],{"class":55,"line":91},[53,5994,5995],{"class":63},"        {\n",[53,5997,5998],{"class":55,"line":332},[53,5999,6000],{"class":63},"            ...\n",[53,6002,6003],{"class":55,"line":347},[53,6004,6005],{"class":63},"        }\n",[53,6007,6008],{"class":55,"line":353},[53,6009,1509],{"class":63},[12,6011,6012],{},"如果这个任务需要：",[20,6014,6017],{"className":6015,"code":6016,"language":25,"meta":26},[23],"明确停止\n\n长期运行\n\n生命周期管理\n",[15,6018,6016],{"__ignoreMap":26},[12,6020,6021],{},"通常：",[20,6023,6025],{"className":47,"code":6024,"language":49,"meta":26,"style":26},"std::jthread\n",[15,6026,6027],{"__ignoreMap":26},[53,6028,6029,6031],{"class":55,"line":56},[53,6030,60],{"class":59},[53,6032,5559],{"class":63},[12,6034,6035],{},"更符合语义。",[119,6037],{},[122,6039,6040],{"id":6040},"最后总结",[12,6042,6043],{},"这组工具最核心的区别可以记成：",[20,6045,6048],{"className":6046,"code":6047,"language":25,"meta":26},[23],"std::future\n→ “以后我要读结果”\n\nstd::promise\n→ “我手动把结果写进去”\n\nstd::packaged_task\n→ “我执行这个函数，结果自动写进去”\n\nstd::async\n→ “帮我提交任务，并直接给我 future”\n\nstd::shared_future\n→ “多个地方都要读同一个结果”\n",[15,6049,6047],{"__ignoreMap":26},[12,6051,733],{},[20,6053,6056],{"className":6054,"code":6055,"language":25,"meta":26},[23],"std::thread \u002F std::jthread\n→ 更偏线程生命周期\n\nstd::future \u002F std::async\n→ 更偏任务与结果\n",[15,6057,6055],{"__ignoreMap":26},[12,6059,6060],{},"如果只记一张图：",[20,6062,6065],{"className":6063,"code":6064,"language":25,"meta":26},[23],"          生产结果\n             ↓\n promise \u002F packaged_task \u002F async\n             ↓\n        shared state\n             ↓\n   future \u002F shared_future\n             ↓\n          读取结果\n",[15,6066,6064],{"__ignoreMap":26},[12,6068,6069,6070,6072],{},"这就是整个 ",[15,6071,43],{}," 体系最核心的逻辑。",[6074,6075,6076],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":26,"searchDepth":67,"depth":67,"links":6078},[6079,6088,6095,6107,6119,6131,6135,6142,6153],{"id":124,"depth":67,"text":125,"children":6080},[6081,6083,6084,6086],{"id":129,"depth":75,"text":6082},"std::future\u003CT> 是什么",{"id":195,"depth":75,"text":196},{"id":262,"depth":75,"text":6085},"最简单的 std::async",{"id":654,"depth":75,"text":6087},"async 的参数和 thread 很像",{"id":776,"depth":67,"text":777,"children":6089},[6090,6091,6092,6094],{"id":780,"depth":75,"text":783},{"id":913,"depth":75,"text":916},{"id":1245,"depth":75,"text":6093},"async 和 deferred 的区别",{"id":1283,"depth":75,"text":1284},{"id":1411,"depth":67,"text":1412,"children":6096},[6097,6098,6100,6101,6102,6104,6105,6106],{"id":1415,"depth":75,"text":1418},{"id":1551,"depth":75,"text":6099},"普通 future::get() 通常只能调用一次",{"id":1729,"depth":75,"text":1732},{"id":1905,"depth":75,"text":1908},{"id":2033,"depth":75,"text":6103},"wait() 不会把任务异常直接抛出来",{"id":2092,"depth":75,"text":2095},{"id":2441,"depth":75,"text":2444},{"id":2591,"depth":75,"text":2592},{"id":2869,"depth":67,"text":2872,"children":6108},[6109,6110,6111,6113,6114,6115,6116,6117,6118],{"id":2955,"depth":75,"text":2958},{"id":3026,"depth":75,"text":3027},{"id":3252,"depth":75,"text":6112},"为什么 promise 要 std::move",{"id":3336,"depth":75,"text":3339},{"id":3440,"depth":75,"text":3441},{"id":3540,"depth":75,"text":3543},{"id":3728,"depth":75,"text":3729},{"id":4062,"depth":75,"text":4063},{"id":4195,"depth":75,"text":4196},{"id":4233,"depth":67,"text":4236,"children":6120},[6121,6122,6123,6125,6127,6128,6129],{"id":4325,"depth":75,"text":4326},{"id":4622,"depth":75,"text":4623},{"id":4678,"depth":75,"text":6124},"packaged_task 会自动传递异常",{"id":4819,"depth":75,"text":6126},"packaged_task 和 thread 配合",{"id":5046,"depth":75,"text":5047},{"id":5102,"depth":75,"text":5103},{"id":5145,"depth":75,"text":6130},"promise 和 packaged_task 怎么选",{"id":5258,"depth":67,"text":5261,"children":6132},[6133,6134],{"id":5340,"depth":75,"text":5341},{"id":5458,"depth":75,"text":5459},{"id":5498,"depth":67,"text":5498,"children":6136},[6137,6138,6140],{"id":5501,"depth":75,"text":5501},{"id":5526,"depth":75,"text":6139},"async 和 thread 怎么选",{"id":5609,"depth":75,"text":6141},"async 不是线程池",{"id":5678,"depth":67,"text":5678,"children":6143},[6144,6146,6148,6150,6151,6152],{"id":5681,"depth":75,"text":6145},"错误：认为 std::async() 一定创建新线程",{"id":5748,"depth":75,"text":6147},"错误：对普通 future 重复 get()",{"id":5785,"depth":75,"text":6149},"错误：忘记 get() 还会重新抛出异常",{"id":5891,"depth":75,"text":5892},{"id":5914,"depth":75,"text":5915},{"id":5946,"depth":75,"text":5947},{"id":6040,"depth":67,"text":6040},"2000-1900-1500","2023-10-05","std::thread 很适合表达：","2023-10-05-cplusplus-jiao-xue","\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue","Cplusplus教学","md",false,{},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1500-future-async-promise",{"title":5,"description":6156},"wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1500-future-async-promise","1Vnt_iSWbRvED5GWIcTElSM8gtYLOHBE19KUv2lThQM",[6168,6175,6181,6187,6193,6199,6205,6211,6217,6223,6229,6235,6241,6247,6253,6259,6265,6271,6277,6283,6289,6295,6301,6307,6313,6319,6325,6331,6337,6343,6349,6355,6361,6367,6373,6379,6385,6391,6397,6403,6408,6414,6419,6425,6431,6437,6443,6449,6455,6461,6467,6473,6479,6485,6491,6497,6503,6509,6515,6521,6527,6533,6538,6544,6550,6556,6558,6564,6570,6576,6582,6588,6594,6600,6606,6612,6618,6624,6630,6636,6642,6648,6654,6660,6666,6672,6678,6684,6690,6696,6702,6708],{"path":6169,"stem":6170,"title":6171,"authors":6172,"date":6155,"chapterOrder":6173,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0100-c-kai-fa-huan-jing-da-jian-yu-ce-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F0100-C++开发环境搭建与测试","C++开发环境搭建与测试",[7],"0100",0,{"path":6176,"stem":6177,"title":6178,"authors":6179,"date":6155,"chapterOrder":6180,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0200-c-ji-chu-chu-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F0200-C++基础初识","C++基础初识",[7],"0200",{"path":6182,"stem":6183,"title":6184,"authors":6185,"date":6155,"chapterOrder":6186,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0300-shu-ju-lei-xing-yu-shu-ju-cun-fang","wiki\u002F2023-10-05-Cplusplus教学\u002F0300-数据类型与数据存放","数据类型与数据存放",[7],"0300",{"path":6188,"stem":6189,"title":6190,"authors":6191,"date":6155,"chapterOrder":6192,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0400-shu-ru-shu-chu","wiki\u002F2023-10-05-Cplusplus教学\u002F0400-输入输出","输入输出",[7],"0400",{"path":6194,"stem":6195,"title":6196,"authors":6197,"date":6155,"chapterOrder":6198,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0500-yun-suan-fu","wiki\u002F2023-10-05-Cplusplus教学\u002F0500-运算符","运算符",[7],"0500",{"path":6200,"stem":6201,"title":6202,"authors":6203,"date":6155,"chapterOrder":6204,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0600-cheng-xu-liu-cheng-jie-gou","wiki\u002F2023-10-05-Cplusplus教学\u002F0600-程序流程结构","程序流程结构",[7],"0600",{"path":6206,"stem":6207,"title":6208,"authors":6209,"date":6155,"chapterOrder":6210,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0700-shu-zu","wiki\u002F2023-10-05-Cplusplus教学\u002F0700-数组","数组",[7],"0700",{"path":6212,"stem":6213,"title":6214,"authors":6215,"date":6155,"chapterOrder":6216,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0800-han-shu-yu-tou-wen-jian","wiki\u002F2023-10-05-Cplusplus教学\u002F0800-函数与头文件","函数与头文件",[7],"0800",{"path":6218,"stem":6219,"title":6220,"authors":6221,"date":6155,"chapterOrder":6222,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F0900-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F0900-指针","指针",[7],"0900",{"path":6224,"stem":6225,"title":6226,"authors":6227,"date":6155,"chapterOrder":6228,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1000-jie-gou-ti-yu-gong-yong-ti","wiki\u002F2023-10-05-Cplusplus教学\u002F1000-结构体与共用体","结构体与共用体",[7],"1000",{"path":6230,"stem":6231,"title":6232,"authors":6233,"date":6155,"chapterOrder":6234,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1100-nei-cun-fen-qu-yu-sheng-ming-zhou-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1100-内存分区与生命周期","内存分区与生命周期",[7],"1100",{"path":6236,"stem":6237,"title":6238,"authors":6239,"date":6155,"chapterOrder":6240,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1200-yin-yong","wiki\u002F2023-10-05-Cplusplus教学\u002F1200-引用","引用",[7],"1200",{"path":6242,"stem":6243,"title":6244,"authors":6245,"date":6155,"chapterOrder":6246,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1300-han-shu-ti-gao","wiki\u002F2023-10-05-Cplusplus教学\u002F1300-函数提高","函数提高",[7],"1300",{"path":6248,"stem":6249,"title":6250,"authors":6251,"date":6155,"chapterOrder":6252,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1350-ming-ming-kong-jian","wiki\u002F2023-10-05-Cplusplus教学\u002F1350-命名空间","命名空间",[7],"1350",{"path":6254,"stem":6255,"title":6256,"authors":6257,"date":6155,"chapterOrder":6258,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0100-feng-zhuang","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0100-封装","封装",[7],"1400-0100",{"path":6260,"stem":6261,"title":6262,"authors":6263,"date":6155,"chapterOrder":6264,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0200-dui-xiang-chu-shi-hua-he-qing-li","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0200-对象初始化和清理","对象初始化和清理",[7],"1400-0200",{"path":6266,"stem":6267,"title":6268,"authors":6269,"date":6155,"chapterOrder":6270,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0300-dui-xiang-mo-xing-yu-this-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0300-对象模型与this指针","对象模型与this指针",[7],"1400-0300",{"path":6272,"stem":6273,"title":6274,"authors":6275,"date":6155,"chapterOrder":6276,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0400-you-yuan-yu-yun-suan-fu-zhong-zai","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0400-友元与运算符重载","友元与运算符重载",[7],"1400-0400",{"path":6278,"stem":6279,"title":6280,"authors":6281,"date":6155,"chapterOrder":6282,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0500-ji-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0500-继承","继承",[7],"1400-0500",{"path":6284,"stem":6285,"title":6286,"authors":6287,"date":6155,"chapterOrder":6288,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-0600-duo-tai","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-0600-多态","多态",[7],"1400-0600",{"path":6290,"stem":6291,"title":6292,"authors":6293,"date":6155,"chapterOrder":6294,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1400-lei-he-dui-xiang","wiki\u002F2023-10-05-Cplusplus教学\u002F1400-类和对象","类和对象",[7],"1400",{"path":6296,"stem":6297,"title":6298,"authors":6299,"date":6155,"chapterOrder":6300,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1450-han-shu-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F1450-函数指针","函数指针",[7],"1450",{"path":6302,"stem":6303,"title":6304,"authors":6305,"date":6155,"chapterOrder":6306,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1500-wen-jian-cao-zuo","wiki\u002F2023-10-05-Cplusplus教学\u002F1500-文件操作","文件操作",[7],"1500",{"path":6308,"stem":6309,"title":6310,"authors":6311,"date":6155,"chapterOrder":6312,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1600-yi-chang-chu-li-yu-cuo-wu-ma","wiki\u002F2023-10-05-Cplusplus教学\u002F1600-异常处理与错误码","异常处理",[7],"1600",{"path":6314,"stem":6315,"title":6316,"authors":6317,"date":6155,"chapterOrder":6318,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1700-mu-ban","wiki\u002F2023-10-05-Cplusplus教学\u002F1700-模板","模板",[7],"1700",{"path":6320,"stem":6321,"title":6322,"authors":6323,"date":6155,"chapterOrder":6324,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0100-stl-chu-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0100-STL初识","STL初识",[7],"1800-0100",{"path":6326,"stem":6327,"title":6328,"authors":6329,"date":6155,"chapterOrder":6330,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0200-std-array","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0200-std-array","std::array",[7],"1800-0200",{"path":6332,"stem":6333,"title":6334,"authors":6335,"date":6155,"chapterOrder":6336,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0300-string-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0300-string容器","string容器",[7],"1800-0300",{"path":6338,"stem":6339,"title":6340,"authors":6341,"date":6155,"chapterOrder":6342,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0400-vector-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0400-vector容器","vector 容器",[7],"1800-0400",{"path":6344,"stem":6345,"title":6346,"authors":6347,"date":6155,"chapterOrder":6348,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0500-deque-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0500-deque容器","deque 容器",[7],"1800-0500",{"path":6350,"stem":6351,"title":6352,"authors":6353,"date":6155,"chapterOrder":6354,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0600-stack-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0600-stack容器","stack 容器",[7],"1800-0600",{"path":6356,"stem":6357,"title":6358,"authors":6359,"date":6155,"chapterOrder":6360,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0700-queue-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0700-queue容器","queue 容器",[7],"1800-0700",{"path":6362,"stem":6363,"title":6364,"authors":6365,"date":6155,"chapterOrder":6366,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0800-list-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0800-list容器","list 容器",[7],"1800-0800",{"path":6368,"stem":6369,"title":6370,"authors":6371,"date":6155,"chapterOrder":6372,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-0900-set-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-0900-set容器","set \u002F multiset 容器",[7],"1800-0900",{"path":6374,"stem":6375,"title":6376,"authors":6377,"date":6155,"chapterOrder":6378,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1000-map-rong-qi","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1000-map容器","map \u002F multimap 容器",[7],"1800-1000",{"path":6380,"stem":6381,"title":6382,"authors":6383,"date":6155,"chapterOrder":6384,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1100-han-shu-dui-xiang-yu-wei-ci","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1100-函数对象与谓词","函数对象与谓词",[7],"1800-1100",{"path":6386,"stem":6387,"title":6388,"authors":6389,"date":6155,"chapterOrder":6390,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-1200-chang-yong-suan-fa","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-1200-常用算法","常用算法",[7],"1800-1200",{"path":6392,"stem":6393,"title":6394,"authors":6395,"date":6155,"chapterOrder":6396,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1800-stl-ti-gao-bian-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F1800-STL提高编程","STL提高编程",[7],"1800",{"path":6398,"stem":6399,"title":6400,"authors":6401,"date":6155,"chapterOrder":6402,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F1900-c-lei-xing-zhuan-huan","wiki\u002F2023-10-05-Cplusplus教学\u002F1900-C++类型转换","C++类型转换",[7],"1900",{"path":6404,"stem":6405,"title":692,"authors":6406,"date":6155,"chapterOrder":6407,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0100-auto","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0100-auto",[7],"2000-0100",{"path":6409,"stem":6410,"title":6411,"authors":6412,"date":6155,"chapterOrder":6413,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0200-nullptr","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0200-nullptr","nullptr",[7],"2000-0200",{"path":6415,"stem":6416,"title":2233,"authors":6417,"date":6155,"chapterOrder":6418,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0300-using","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0300-using",[7],"2000-0300",{"path":6420,"stem":6421,"title":6422,"authors":6423,"date":6155,"chapterOrder":6424,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0400-enum-class","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0400-enum-class","enum class",[7],"2000-0400",{"path":6426,"stem":6427,"title":6428,"authors":6429,"date":6155,"chapterOrder":6430,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0500-fan-wei-for-xun-huan","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0500-范围for循环","范围 for 循环",[7],"2000-0500",{"path":6432,"stem":6433,"title":6434,"authors":6435,"date":6155,"chapterOrder":6436,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0600-jie-gou-hua-bang-ding","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0600-结构化绑定","结构化绑定",[7],"2000-0600",{"path":6438,"stem":6439,"title":6440,"authors":6441,"date":6155,"chapterOrder":6442,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0700-constexpr","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0700-constexpr","constexpr",[7],"2000-0700",{"path":6444,"stem":6445,"title":6446,"authors":6447,"date":6155,"chapterOrder":6448,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0800-raii","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0800-RAII","RAII",[7],"2000-0800",{"path":6450,"stem":6451,"title":6452,"authors":6453,"date":6155,"chapterOrder":6454,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-0900-zhi-neng-zhi-zhen","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-0900-智能指针","智能指针",[7],"2000-0900",{"path":6456,"stem":6457,"title":6458,"authors":6459,"date":6155,"chapterOrder":6460,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1000-you-zhi-yin-yong-he-yi-dong-yu-yi","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1000-右值引用和移动语义","右值引用和移动语义",[7],"2000-1000",{"path":6462,"stem":6463,"title":6464,"authors":6465,"date":6155,"chapterOrder":6466,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1100-lambda-biao-da-shi","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1100-Lambda表达式","Lambda 表达式",[7],"2000-1100",{"path":6468,"stem":6469,"title":6470,"authors":6471,"date":6155,"chapterOrder":6472,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1200-std-function","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1200-std-function","std::function",[7],"2000-1200",{"path":6474,"stem":6475,"title":6476,"authors":6477,"date":6155,"chapterOrder":6478,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1300-std-bind","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1300-std-bind","std::bind",[7],"2000-1300",{"path":6480,"stem":6481,"title":6482,"authors":6483,"date":6155,"chapterOrder":6484,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1400-std-optional","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1400-std-optional","std::optional",[7],"2000-1400",{"path":6486,"stem":6487,"title":6488,"authors":6489,"date":6155,"chapterOrder":6490,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1500-std-variant","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1500-std-variant","std::variant",[7],"2000-1500",{"path":6492,"stem":6493,"title":6494,"authors":6495,"date":6155,"chapterOrder":6496,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1600-std-span","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1600-std-span","std::span",[7],"2000-1600",{"path":6498,"stem":6499,"title":6500,"authors":6501,"date":6155,"chapterOrder":6502,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1700-std-format-print","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1700-std-format-print","std::format \u002F std::print",[7],"2000-1700",{"path":6504,"stem":6505,"title":6506,"authors":6507,"date":6155,"chapterOrder":6508,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1800-std-chrono","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1800-std-chrono","std::chrono",[7],"2000-1800",{"path":6510,"stem":6511,"title":6512,"authors":6513,"date":6155,"chapterOrder":6514,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0100-bing-fa-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0100-并发是什么","并发是什么",[7],"2000-1900-0100",{"path":6516,"stem":6517,"title":6518,"authors":6519,"date":6155,"chapterOrder":6520,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0200-bing-xing-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0200-并行是什么","并行是什么",[7],"2000-1900-0200",{"path":6522,"stem":6523,"title":6524,"authors":6525,"date":6155,"chapterOrder":6526,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-0300-xie-cheng-shi-shen-me","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-0300-协程是什么","协程是什么",[7],"2000-1900-0300",{"path":6528,"stem":6529,"title":6530,"authors":6531,"date":6155,"chapterOrder":6532,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1000-bing-fa-bian-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1000-并发编程","并发编程",[7],"2000-1900-1000",{"path":6534,"stem":6535,"title":17,"authors":6536,"date":6155,"chapterOrder":6537,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1100-std-thread","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1100-std-thread",[7],"2000-1900-1100",{"path":6539,"stem":6540,"title":6541,"authors":6542,"date":6155,"chapterOrder":6543,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1200-mutex-lock-guard","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1200-mutex-lock-guard","mutex 与 RAII 锁",[7],"2000-1900-1200",{"path":6545,"stem":6546,"title":6547,"authors":6548,"date":6155,"chapterOrder":6549,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1300-std-atomic","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1300-std-atomic","std::atomic",[7],"2000-1900-1300",{"path":6551,"stem":6552,"title":6553,"authors":6554,"date":6155,"chapterOrder":6555,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1400-condition-variable","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1400-condition-variable","condition_variable",[7],"2000-1900-1400",{"path":6163,"stem":6165,"title":5,"authors":6557,"date":6155,"chapterOrder":6154,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},[7],{"path":6559,"stem":6560,"title":6561,"authors":6562,"date":6155,"chapterOrder":6563,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1600-jthread-stop-token","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1600-jthread-stop-token","jthread 与 stop_token",[7],"2000-1900-1600",{"path":6565,"stem":6566,"title":6567,"authors":6568,"date":6155,"chapterOrder":6569,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-1700-semaphore-latch-barrier","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-1700-semaphore-latch-barrier","semaphore、latch 与 barrier",[7],"2000-1900-1700",{"path":6571,"stem":6572,"title":6573,"authors":6574,"date":6155,"chapterOrder":6575,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-1900-bing-fa-bing-xing-yu-xie-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-1900-并发并行与协程","并发、并行与协程",[7],"2000-1900",{"path":6577,"stem":6578,"title":6579,"authors":6580,"date":6155,"chapterOrder":6581,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2000-std-filesystem","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-2000-std-filesystem","std::filesystem",[7],"2000-2000",{"path":6583,"stem":6584,"title":6585,"authors":6586,"date":6155,"chapterOrder":6587,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-2100-modules-jian-jie","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-2100-modules简介","modules 简介",[7],"2000-2100",{"path":6589,"stem":6590,"title":6591,"authors":6592,"date":6155,"chapterOrder":6593,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2000-xian-dai-c","wiki\u002F2023-10-05-Cplusplus教学\u002F2000-现代C++","现代C++",[7],"2000",{"path":6595,"stem":6596,"title":6597,"authors":6598,"date":6155,"chapterOrder":6599,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0100-ding-shi-qi-yu-yi-bu-io","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0100-定时器与异步IO","定时器与异步 IO",[7],"2100-0100-0100",{"path":6601,"stem":6602,"title":6603,"authors":6604,"date":6155,"chapterOrder":6605,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0200-boost-asio-ji-chu","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0200-Boost.Asio基础","Boost.Asio 基础",[7],"2100-0100-0200",{"path":6607,"stem":6608,"title":6609,"authors":6610,"date":6155,"chapterOrder":6611,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0300-chuan-kou-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0300-串口通信","串口通信教学",[7],"2100-0100-0300",{"path":6613,"stem":6614,"title":6615,"authors":6616,"date":6155,"chapterOrder":6617,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0350-chuan-kou-tong-xin-chuan-kou-bao-xie-yi-shi-li","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0350-串口通信串口包协议实例","串口通信串口包协议实例",[7],"2100-0100-0350",{"path":6619,"stem":6620,"title":6621,"authors":6622,"date":6155,"chapterOrder":6623,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0400-tcp-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0400-TCP通信","TCP 通信",[7],"2100-0100-0400",{"path":6625,"stem":6626,"title":6627,"authors":6628,"date":6155,"chapterOrder":6629,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0500-udp-tong-xin","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0500-UDP通信","UDP 通信",[7],"2100-0100-0500",{"path":6631,"stem":6632,"title":6633,"authors":6634,"date":6155,"chapterOrder":6635,"chapterDepth":67,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-0600-ji-qi-ren-gong-cheng-xie-fa-yu-ros2-ji-cheng","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-0600-机器人工程写法与ROS2集成","机器人工程写法与 ROS2 集成",[7],"2100-0100-0600",{"path":6637,"stem":6638,"title":6639,"authors":6640,"date":6155,"chapterOrder":6641,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0100-boost-asio-yi-bu-io-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0100-Boost.Asio异步IO库","Boost.Asio异步IO库",[7],"2100-0100",{"path":6643,"stem":6644,"title":6645,"authors":6646,"date":6155,"chapterOrder":6647,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0200-eigen-xian-xing-dai-shu-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0200-Eigen线性代数库","Eigen线性代数库",[7],"2100-0200",{"path":6649,"stem":6650,"title":6651,"authors":6652,"date":6155,"chapterOrder":6653,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0300-opencv-ji-suan-ji-shi-jue-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0300-OpenCV计算机视觉库","OpenCV计算机视觉库",[7],"2100-0300",{"path":6655,"stem":6656,"title":6657,"authors":6658,"date":6155,"chapterOrder":6659,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0400-pcl-dian-yun-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0400-PCL点云库","PCL点云库",[7],"2100-0400",{"path":6661,"stem":6662,"title":6663,"authors":6664,"date":6155,"chapterOrder":6665,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-0500-sophus-li-qun-li-dai-shu-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-0500-Sophus李群李代数库","Sophus 李群李代数库",[7],"2100-0500",{"path":6667,"stem":6668,"title":6669,"authors":6670,"date":6155,"chapterOrder":6671,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2100-chang-yong-ku","wiki\u002F2023-10-05-Cplusplus教学\u002F2100-常用库","常用库学习",[7],"2100",{"path":6673,"stem":6674,"title":6675,"authors":6676,"date":6155,"chapterOrder":6677,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0100-cmakepresets-yu-gou-jian-an-zhuang","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0100-CMakePresets与构建安装","CMakePresets与构建安装",[7],"2200-0100",{"path":6679,"stem":6680,"title":6681,"authors":6682,"date":6155,"chapterOrder":6683,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0200-ding-ceng-cmake-yu-gong-gong-bian-yi-xuan-xiang","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0200-顶层CMake与公共编译选项","顶层CMake与公共编译选项",[7],"2200-0200",{"path":6685,"stem":6686,"title":6687,"authors":6688,"date":6155,"chapterOrder":6689,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0300-src-yu-lib-mo-kuai-cmake-xiang-jie","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0300-src与lib模块CMake详解","src与lib模块CMake详解",[7],"2200-0300",{"path":6691,"stem":6692,"title":6693,"authors":6694,"date":6155,"chapterOrder":6695,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0400-di-san-fang-ku-yi-lai-xie-fa","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0400-第三方库依赖写法","第三方库依赖写法",[7],"2200-0400",{"path":6697,"stem":6698,"title":6699,"authors":6700,"date":6155,"chapterOrder":6701,"chapterDepth":56,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-0500-mu-ban-kuo-zhan-yu-chang-jian-wen-ti","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-0500-模板扩展与常见问题","模板扩展与常见问题",[7],"2200-0500",{"path":6703,"stem":6704,"title":6705,"authors":6706,"date":6155,"chapterOrder":6707,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":6161},"\u002Fwiki\u002F2023-10-05-cplusplus-jiao-xue\u002F2200-cmake-gong-cheng-mu-ban","wiki\u002F2023-10-05-Cplusplus教学\u002F2200-CMake工程模板","CMake工程模板",[7],"2200",{"path":6158,"stem":6709,"title":6710,"authors":6711,"date":6155,"chapterOrder":6712,"chapterDepth":6174,"docKey":6157,"docRoot":6158,"docTitle":6159,"isWikiDoc":295,"isWikiIndex":295},"wiki\u002F2023-10-05-Cplusplus教学\u002Findex","C\u002FC++教程",[7],null,[6714,6716,6719,6722],{"name":7,"image":6715},"\u002Fimages\u002Fmember_photo\u002F董佳辉.jpg",{"name":6717,"image":6718},"宫金良","\u002Fimages\u002Fmember_photo\u002F宫金良.jpg",{"name":6720,"image":6721},"巩丽","\u002Fimages\u002Fmember_photo\u002F巩丽.png",{"name":6723,"image":6724},"张彦斐","\u002Fimages\u002Fmember_photo\u002F张彦斐.jpg",1792431899225]