在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

講解消息分發的一種編譯期實現法

CPP開發者 ? 來源:CppMore ? 2023-08-23 14:38 ? 次閱讀

今天講消息分發的一種編譯期實現法。

編程是一門非常依賴邏輯的學科,邏輯分為形式邏輯和非形式邏輯,編程就屬于形式邏輯。形式邏輯指的是用數學的方式去抽象地分析命題,它有一套嚴謹的標準和公理系統,對錯分明;而日常生活中使用的是非形式邏輯,它不存在標準和公理,也沒有絕對的對與錯。

根據哲學家大衛·休謨在《人性論》中對于觀念之間連接的分類,我們能夠把邏輯關系分成三大類:相似關系、因果關系、承接關系。相似關系表示兩個組件結構相同,去掉其中一個組件,也只會使功能不夠全面,并不會影響程序;因果關系表示兩個組件之間依賴性極強,沒有第一個組件,就沒有第二個組件,第二個組件依賴于第一個組件;承接關系表示兩個組件都是局部,只有組合起來,才能構成一個整體。

消息分發就屬于因果關系,我們需要依賴 A,去執行 B,沒有 A 就沒有 B。同樣屬于因果關系的術語還有邏輯分派、模式匹配、定制點的表示方式等等,它們本質都是在描述一類東西,只是有時候側重點不同。

條件關系也屬于因果關系的范疇,是編程中邏輯最重的關系。試想沒有if else,你還能寫出多少程序?世界是復雜的,問題也是復雜的,因果關系必不可少。

消息分發,或稱邏輯分派,就是一種簡化條件關系表達方式的技術。它適用于存在大量因果的情境,此時若是使用原始的if else,則無法適應動態發展的世界。

C++ 中,最典型、也非常有用的一種方式就是采用map,因作為 key,果作為 value,因是標識符,果是回調函數。由于這種方式發生于運行期,所以也稱為動態消息分發。

本文要講的,是 C++20 才得以實現的另外一種方式,發生于編譯期的靜態消息分發技術。

稱為消息分發,一般是在網絡通信的情境下。正常情境下,程序是順序執行的,所以完全可以使用if else來實現因果邏輯,因為組件與組件之間距離較近,屬于同一模塊;而網絡情境下,一個組件可以瞬間跳躍到距離非常遠的另一個組件,這兩個組件甚至不在同一臺設備上,一臺設備可能在上海,另一臺在北京,此時如何讓這兩個組件進行溝通?也就是說,A 組件里面的某個函數執行條件不滿足,如何簡單地跳到 B、C、D、E…… 這些組件的某個函數中去處理?這種遠距離的程序因果邏輯,通過消息分發組件能夠非常絲滑地表示。

消息分發的標識符一般采用字符串表示,到了 C++20 支持 string literal NTTP 才得以在編譯期實現一套可用的相關組件。

因此首先,我們得實現一個 string literal 以在編譯期使用。


		1template<std::size_tN> 2structstring_literal{ 3//strisareferencetoanarrayNofconstantchar 4constexprstring_literal(charconst(&str)[N]){ 5std::copy_n(str,N,value); 6} 7 8charvalue[N]; 9};
通過這種方式,我們定義了編譯期能夠使用的字符串組件,它能夠直接當作模板參數使用。
然后,定義我們的分發器。

		1template  2structdispatcher{  3template  4constexprautoexecute_if(charconst*cause)const{  5if(C==cause)handler();  6}  7  8constexprautoexecute(charconst*cause)const{  9(execute_if(cause),...); 10} 11};
代碼非常精簡,分發器可以包含很多「因」,使用可變模板參數 Cs 進行表示。如果得到一個具體的「因」,我們需要找到對應的「果」,因此免不了遍歷 Cs,借助 Fold expressions,一行代碼優雅地搞定。通過 execute_if 來查找是否存在對應的「因」,也就是對比字符串是否相等,查找到則調用相應的「果」,也就是具體的處理函數 handler()
接著,需要定義一個默認的因果,即如果沒有定義相應的處理函數時,所調用的一個默認處理函數。

		1//defaultimplementation 2template 3inlineconstexprautohandler=[]{std::cout<"defaulteffect ";};
因為是模板參數,所以它能夠處理所有的「因」。
通過特化,我們能夠在任何地方,定義任何因果。比如:

		1//opt-incustomizationpoints 2template<>inlineconstexprautohandler<"cause1">=[]{std::cout<"customizationpointseffect1 ";}; 3template<>inlineconstexprautohandler<"cause2">=[]{std::cout<"customizationpointseffect2 ";};
默認版本和定制版本之間是相似關系,即便不提供定制版本,也會不影響程序的功能。
由于特化更加特殊,所以決議時會首先考慮這些因果對。但是,此時有巨大的重復,我們通過宏來自動生成重復代碼:

		1#define_(name)template<>inlineconstexprautohandler<#name> 2 3//opt-incustomizationpoints 4_(cause1)=[]{std::cout<"customizationpointseffect1 ";}; 5_(cause2)=[]{std::cout<"customizationpointseffect2 ";};
現在定制起來就更加方便、簡潔。 最后,具體使用。

		1intmain(){ 2constexprstring_literalcause_1{"cause1"}; 3constexprdispatcher"cause2","cause3">dispatch; 4dispatch.execute(cause_1); 5dispatch.execute("cause2"); 6dispatch.execute("cause3"); 7}
相比動態消息分發,這種方式有兩個巨大的優勢,其一是編譯期,其二是定制時可以在任何地方。動態消息分發一般需要調用 dispatch.add_handler(cause, effect),因為是成員函數,所以限制了定制地方,必須得在對象所在模塊,而靜態消息分發這種全局定義特化的方式,則沒有這種限制。
目前其實還存在兩個問題,第一是 C == cause 并沒有相應的比較操作符,第二是 dispatch.execute(cause_1) 并不能直接傳遞,因為 char const*string_literal 畢竟不是同一種類型。可以通過添加運算符重載和隱式轉換來解決:

		1template<std::size_tN>  2structstring_literal{  3//...  4  5friendbooloperator==(string_literalconst&s,charconst*cause){  6returnstd::strncmp(s.value,cause,N)==0;  7}  8  9operatorcharconst*()const{ 10returnvalue; 11} 12 13//... 14};
			現在以上靜態消息分發組件就能夠正常使用了。完整的代碼如下:

		1template<std::size_tN>  2structstring_literal{  3constexprstring_literal(charconst(&str)[N]){  4std::copy_n(str,N,value);  5}  6  7friendbooloperator==(string_literalconst&s,charconst*cause){  8returnstd::strncmp(s.value,cause,N)==0;  9} 10 11operatorcharconst*()const{ 12returnvalue; 13} 14 15charvalue[N]; 16}; 17 18//defaultimplementation 19template 20inlineconstexprautohandler=[]{std::cout<"defaulteffect ";}; 21 22#define_(name)template<>inlineconstexprautohandler<#name> 23 24//opt-incustomizationpoints 25_(cause1)=[]{std::cout<"customizationpointseffect1 ";}; 26_(cause2)=[]{std::cout<"customizationpointseffect2 ";}; 27 28 29template 30structdispatcher{ 31template 32constexprautoexecute_if(charconst*cause)const{ 33if(C==cause)handler(); 34} 35 36constexprautoexecute(charconst*cause)const{ 37(execute_if(cause),...); 38} 39}; 40 41intmain(){ 42constexprstring_literalcause_1{"cause1"}; 43constexprdispatcher"cause2","cause3">dispatch; 44dispatch.execute(cause_1); 45dispatch.execute("cause2"); 46dispatch.execute("cause3"); 47}
短短數十行代碼,便實現了一個威力強大的靜態消息分發組件,This is modern C++。
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編程
    +關注

    關注

    88

    文章

    3639

    瀏覽量

    94031
  • 字符串
    +關注

    關注

    1

    文章

    585

    瀏覽量

    20612
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73885
  • 代碼
    +關注

    關注

    30

    文章

    4835

    瀏覽量

    69117
  • 編譯
    +關注

    關注

    0

    文章

    662

    瀏覽量

    33066

原文標題:編譯期消息分發?C++20 已能優雅實現!

文章出處:【微信號:CPP開發者,微信公眾號:CPP開發者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    一種高性能多通道通用DMA設計與實現

    為充分發揮異構多核DSP芯片的實時計算能力,設計并實現一種高性能多通道的通用DMA,該DMA最大支持64個通道的數據搬運,并支持維、二維、轉置以及級聯描述符等多種傳輸模式。芯片實測
    的頭像 發表于 11-20 15:52 ?1064次閱讀
    <b class='flag-5'>一種</b>高性能多通道通用DMA設計與<b class='flag-5'>實現</b>

    介紹一種使用WSL來編譯nodemcu固件的方法

    本文將介紹一種使用WSL來編譯nodemcu固件的方法。
    發表于 02-15 07:34

    如何去實現一種RK3308系統交叉編譯的設計

    如何去實現一種RK3308系統交叉編譯的設計?有哪些編譯步驟?
    發表于 03-09 07:57

    一種用于反編譯代碼與源代碼的比較算法

    現有反編譯器產生的代碼與對應的源代碼之間存在差異,找到并理解差異有助于改進并完善反編譯器的設計。該文給出一種適用于C 語言反編譯代碼與源代碼的比較算法。該算法以語
    發表于 03-21 15:08 ?10次下載

    一種健壯的計算安全的分布式密鑰分發方案

    對基于Decisional Diffie-Hellmen 假設計算安全的分布式密鑰分發方案進行改進,在其基礎上利用可驗證秘密共享和知識證明,提出一種健壯的計算安全的分布式密鑰分發方案,以抵抗主動
    發表于 06-17 09:39 ?22次下載

    一種分布式編譯系統的設計與實現

    本文針對當前大型軟件生成時間過長的問題,在MSBuild 生成引擎的基礎上,提出并實現一種利用集群進行分布式編譯的系統,以降低在MSBuild 平臺上的產品每次編譯所需要的時間
    發表于 01-15 14:16 ?18次下載

    一種6_25Gb_s帶預加重結構的低壓差分發送器_陳浩

    一種6_25Gb_s帶預加重結構的低壓差分發送器_陳浩
    發表于 01-07 22:14 ?1次下載

    一種EPCCL理論編譯算法

    to knowledge compilation based on hyper extension rule).該算法適合難解類SAT問題的知識編譯,也是一種可并行的知識編譯算法.研究了如何
    發表于 12-26 10:39 ?0次下載

    一種支持單雙模式選擇的SIMD編譯優化算法

    和SIMD指令來實現,然而現有的編譯框架無法對這些特殊的SIMD指令提供支持。由于BWDSPlOO擁有豐富的SIMD向量化資源,且其所運用的雷達數字信號處理領域對程序的性能要求極高,因此針對BWDSPlOO結構的特點,在傳統Open64
    發表于 01-05 10:28 ?0次下載
    <b class='flag-5'>一種</b>支持單雙模式選擇的SIMD<b class='flag-5'>編譯</b>優化算法

    一種短波軟件無線電臺的實現講解

    一種短波軟件無線電臺的實現講解說明。
    發表于 03-25 09:30 ?11次下載
    <b class='flag-5'>一種</b>短波軟件無線電臺的<b class='flag-5'>實現</b><b class='flag-5'>講解</b>

    一種基于公交系統的任務差異化分發方法

    、參與數量、感知區域類型等帶來的挑戰。基于此,該文利用城市中公交載體的軌跡可預測、活動覆蓋范圍大、乘客節點自主聚集且交互時間有保證等優勢,提出了一種基于公交系統的任務差異化分發方法。首先,利用泰森多邊形的劃
    發表于 03-31 09:11 ?4次下載
    <b class='flag-5'>一種</b>基于公交系統的任務差異化<b class='flag-5'>分發</b>方法

    FPGA_ASIC-一種改進的2D-DCT的FPGA實現

    FPGA_ASIC-一種改進的2D-DCT的FPGA實現(核達中遠通電源技術有限公司招聘文員嗎?)-該文檔為FPGA_ASIC-一種改進的2D-DCT的FPGA實現
    發表于 09-16 10:35 ?4次下載
    FPGA_ASIC-<b class='flag-5'>一種</b>改進的2D-DCT的FPGA<b class='flag-5'>實現</b>

    電子學報第七一種可配置的CNN協加速器的FPGA實現方法》

    電子學報第七一種可配置的CNN協加速器的FPGA實現方法》
    發表于 11-18 16:31 ?15次下載

    如何通過poly實現C++編譯多態

      而folly::poly出來的晚些,主要使用c++的新特性來實現相關的功能,依賴比較少,所以本文將更多的以poly的實現來分析編譯
    的頭像 發表于 12-05 09:10 ?717次閱讀

    分享一種路由重分發的標準解決方案

    路由重分發技術在現網環境中是一種很常見的技術,所以其地位也非常重要。很多教程在在講路由重分發的時候,只講了重分發的操作卻沒有說現網環境中
    的頭像 發表于 05-05 08:59 ?1192次閱讀
    分享<b class='flag-5'>一種</b>路由重<b class='flag-5'>分發</b>的標準解決方案
    主站蜘蛛池模板: 男人j桶进女人免费视频 | 精品亚洲国产国拍 | 日本韩国做暖暖小视频 | 黄色综合| 午夜两性网 | 国产剧情麻豆三级在线观看 | 嫩草影院入口一二三免费 | 日本黄色高清视频网站 | 天天躁狠狠躁夜躁2021 | 国产精品天天干 | 欧美伦理影院 | 美女被啪到哭网站在线观看 | 久久久久国产精品免费免费不卡 | 国产在线精品一区二区夜色 | 天天看天天摸色天天综合网 | 伊人久操| 男人的j桶女人的j视频 | 久久永久视频 | 506rr亚洲欧美 | 1000部啪啪勿入十八免费 | 成片免费的禁v影片 | 欧美极品xxxxⅹ另类 | 女人的天堂网站 | 天天干夜夜噜 | 国产亚洲欧美日本一二三本道 | 亚洲国产欧美精品一区二区三区 | 亚洲午夜久久久精品影院 | 三级理论在线播放大全 | 日韩中文字幕第一页 | 黄色顶级视频 | 一区二区三区四区国产精品 | 欧美性生活一级 | 天天做天天爽天天谢 | 成人牲交一极毛片 | 午夜剧场操一操 | 特黄黄三级视频在线观看 | 亚洲欧美人成网站综合在线 | 国产成人影院在线观看 | 免费大片黄日本在线观看 | 日本人zzzwww| 久久免费看 |