優化Cereal宏 一行聲明序列化函數

Cereal序列化庫中宏遞歸展開的優化方案及技術解析

未優化:參考nlohmann json設計Cereal宏 一行聲明序列化函數

宏實現

#include <cereal/cereal.hpp>// 強制二次展開
#define CEREAL_EXPAND( x ) x// 獲取宏參數的數量,對應的CEREAL_PASTEn宏NAME
#define CEREAL_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15,	\_16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28,	\_29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41,	\_42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54,	\_55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME// 參數拼接宏(支持1-64個參數)
#define CEREAL_PASTE(...) CEREAL_EXPAND(CEREAL_GET_MACRO(__VA_ARGS__, \CEREAL_PASTE64, CEREAL_PASTE63, CEREAL_PASTE62, CEREAL_PASTE61, \CEREAL_PASTE60, CEREAL_PASTE59, CEREAL_PASTE58, CEREAL_PASTE57, \CEREAL_PASTE56, CEREAL_PASTE55, CEREAL_PASTE54, CEREAL_PASTE53, \CEREAL_PASTE52, CEREAL_PASTE51, CEREAL_PASTE50, CEREAL_PASTE49, \CEREAL_PASTE48, CEREAL_PASTE47, CEREAL_PASTE46, CEREAL_PASTE45, \CEREAL_PASTE44, CEREAL_PASTE43, CEREAL_PASTE42, CEREAL_PASTE41, \CEREAL_PASTE40, CEREAL_PASTE39, CEREAL_PASTE38, CEREAL_PASTE37, \CEREAL_PASTE36, CEREAL_PASTE35, CEREAL_PASTE34, CEREAL_PASTE33, \CEREAL_PASTE32, CEREAL_PASTE31, CEREAL_PASTE30, CEREAL_PASTE29, \CEREAL_PASTE28, CEREAL_PASTE27, CEREAL_PASTE26, CEREAL_PASTE25, \CEREAL_PASTE24, CEREAL_PASTE23, CEREAL_PASTE22, CEREAL_PASTE21, \CEREAL_PASTE20, CEREAL_PASTE19, CEREAL_PASTE18, CEREAL_PASTE17, \CEREAL_PASTE16, CEREAL_PASTE15, CEREAL_PASTE14, CEREAL_PASTE13, \CEREAL_PASTE12, CEREAL_PASTE11, CEREAL_PASTE10, CEREAL_PASTE9,  \CEREAL_PASTE8,  CEREAL_PASTE7,  CEREAL_PASTE6,  CEREAL_PASTE5,  \CEREAL_PASTE4,  CEREAL_PASTE3,  CEREAL_PASTE2,  CEREAL_PASTE1)(__VA_ARGS__))// 定義PASTE宏(1-64個參數)
#define CEREAL_PASTE2(func, param) func(param)
#define CEREAL_PASTE3(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
#define CEREAL_PASTE4(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE3(func, __VA_ARGS__))
#define CEREAL_PASTE5(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE4(func, __VA_ARGS__))
#define CEREAL_PASTE6(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE5(func, __VA_ARGS__))
#define CEREAL_PASTE7(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE6(func, __VA_ARGS__))
#define CEREAL_PASTE8(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE7(func, __VA_ARGS__))
#define CEREAL_PASTE9(func, param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE8(func, __VA_ARGS__))
#define CEREAL_PASTE10(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE9(func, __VA_ARGS__))
#define CEREAL_PASTE11(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE10(func, __VA_ARGS__))
#define CEREAL_PASTE12(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE11(func, __VA_ARGS__))
#define CEREAL_PASTE13(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE12(func, __VA_ARGS__))
#define CEREAL_PASTE14(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE13(func, __VA_ARGS__))
#define CEREAL_PASTE15(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE14(func, __VA_ARGS__))
#define CEREAL_PASTE16(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE15(func, __VA_ARGS__))
#define CEREAL_PASTE17(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE16(func, __VA_ARGS__))
#define CEREAL_PASTE18(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE17(func, __VA_ARGS__))
#define CEREAL_PASTE19(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE18(func, __VA_ARGS__))
#define CEREAL_PASTE20(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE19(func, __VA_ARGS__))
#define CEREAL_PASTE21(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE20(func, __VA_ARGS__))
#define CEREAL_PASTE22(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE21(func, __VA_ARGS__))
#define CEREAL_PASTE23(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE22(func, __VA_ARGS__))
#define CEREAL_PASTE24(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE23(func, __VA_ARGS__))
#define CEREAL_PASTE25(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE24(func, __VA_ARGS__))
#define CEREAL_PASTE26(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE25(func, __VA_ARGS__))
#define CEREAL_PASTE27(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE26(func, __VA_ARGS__))
#define CEREAL_PASTE28(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE27(func, __VA_ARGS__))
#define CEREAL_PASTE29(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE28(func, __VA_ARGS__))
#define CEREAL_PASTE30(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE29(func, __VA_ARGS__))
#define CEREAL_PASTE31(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE30(func, __VA_ARGS__))
#define CEREAL_PASTE32(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE31(func, __VA_ARGS__))
#define CEREAL_PASTE33(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE32(func, __VA_ARGS__))
#define CEREAL_PASTE34(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE33(func, __VA_ARGS__))
#define CEREAL_PASTE35(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE34(func, __VA_ARGS__))
#define CEREAL_PASTE36(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE35(func, __VA_ARGS__))
#define CEREAL_PASTE37(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE36(func, __VA_ARGS__))
#define CEREAL_PASTE38(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE37(func, __VA_ARGS__))
#define CEREAL_PASTE39(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE38(func, __VA_ARGS__))
#define CEREAL_PASTE40(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE39(func, __VA_ARGS__))
#define CEREAL_PASTE41(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE40(func, __VA_ARGS__))
#define CEREAL_PASTE42(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE41(func, __VA_ARGS__))
#define CEREAL_PASTE43(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE42(func, __VA_ARGS__))
#define CEREAL_PASTE44(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE43(func, __VA_ARGS__))
#define CEREAL_PASTE45(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE44(func, __VA_ARGS__))
#define CEREAL_PASTE46(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE45(func, __VA_ARGS__))
#define CEREAL_PASTE47(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE46(func, __VA_ARGS__))
#define CEREAL_PASTE48(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE47(func, __VA_ARGS__))
#define CEREAL_PASTE49(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE48(func, __VA_ARGS__))
#define CEREAL_PASTE50(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE49(func, __VA_ARGS__))
#define CEREAL_PASTE51(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE50(func, __VA_ARGS__))
#define CEREAL_PASTE52(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE51(func, __VA_ARGS__))
#define CEREAL_PASTE53(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE52(func, __VA_ARGS__))
#define CEREAL_PASTE54(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE53(func, __VA_ARGS__))
#define CEREAL_PASTE55(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE54(func, __VA_ARGS__))
#define CEREAL_PASTE56(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE55(func, __VA_ARGS__))
#define CEREAL_PASTE57(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE56(func, __VA_ARGS__))
#define CEREAL_PASTE58(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE57(func, __VA_ARGS__))
#define CEREAL_PASTE59(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE58(func, __VA_ARGS__))
#define CEREAL_PASTE60(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE59(func, __VA_ARGS__))
#define CEREAL_PASTE61(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE60(func, __VA_ARGS__))
#define CEREAL_PASTE62(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE61(func, __VA_ARGS__))
#define CEREAL_PASTE63(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE62(func, __VA_ARGS__))
#define CEREAL_PASTE64(func,param, ...) func(param), CEREAL_EXPAND(CEREAL_PASTE63(func, __VA_ARGS__))// 成員處理宏
#define CEREAL_MEMBER_NVP_NON_INTRUSIVE(member) ::cereal::make_nvp(#member, t.member)// 主序列化宏:非侵入的
#define CEREAL_SERIALIZE_NON_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar, const Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}\
template <class Archive> \
void serialize(Archive& ar, Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}// 主序列化宏:侵入的
#define CEREAL_SERIALIZE_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar) { \ar( CEREAL_PASTE(CEREAL_NVP, __VA_ARGS__) ); \
}

技術解析:

🔧 優化后的宏定義

#define CEREAL_EXPAND(x) x  // 強制二次展開
#define CEREAL_PASTE2(func, x) func(x)
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
#define CEREAL_PASTE4(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE3(func, __VA_ARGS__))
#define CEREAL_PASTE5(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE4(func, __VA_ARGS__))

🔁 方案1:CEREAL_EXPAND的作用

1. 強制二次展開
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_EXPAND(CEREAL_PASTE2(func, __VA_ARGS__))
  • 展開流程(以CEREAL_PASTE3(F, a, b, c)為例):

    1. 首次展開:F(a), CEREAL_EXPAND(CEREAL_PASTE2(F, b, c))
    2. CEREAL_EXPAND強制展開其參數:CEREAL_PASTE2(F, b, c) → F(b), F(c)
    3. 最終結果:F(a), F(b), F(c)
2. 必要性分析
  • CEREAL_EXPAND
    CEREAL_PASTE2(func, __VA_ARGS__)作為文本保留,后續不再展開。

  • CEREAL_EXPAND
    通過CEREAL_EXPAND包裹,預處理器會立即展開內層宏,確保遞歸鏈繼續。

?? 方案2缺陷(無CEREAL_EXPAND

1.沒有二次展開
// 原方案(錯誤示例)
#define CEREAL_PASTE3(func, x, ...) func(x), CEREAL_PASTE2(func, __VA_ARGS__)
  • 問題:當調用CEREAL_PASTE3(func, x, y, z)時:
    • 首次展開:func(x), CEREAL_PASTE2(func, y, z)
    • 由于預處理器不會自動展開嵌套宏CEREAL_PASTE2(func, y, z)被視為整體而非宏調用。
    • 結果:func(x), CEREAL_PASTE2(func, y, z) → 后續參數未展開,導致編譯錯誤。
2. 關鍵機制:宏展開的惰性
  • 預處理器展開規則:
    • 當宏參數包含其他宏(如__VA_ARGS__中的CEREAL_PASTE2)時,不會立即展開,而是作為文本保留。
    • 只有當前層宏完全展開后,才會處理嵌套宏(若未被###修飾)。

📊 技術方案對比

場景方案1(含CEREAL_EXPAND方案2(無CEREAL_EXPAND
CEREAL_PASTE3(F, a, b)F(a), F(b)F(a), CEREAL_PASTE2(F, b)
CEREAL_PASTE4(F, a,b,c)F(a), F(b), F(c)F(a), CEREAL_PASTE3(F, b,c)
嵌套宏展開遞歸展開至最內層停止于第一層

🧠 技術原理:預處理器展開規則

  1. 遞歸展開條件:
    • 宏必須完全獨立(未被#/##修飾)。
    • 每輪掃描只展開當前層的宏標識符,嵌套宏需等待外層展開完成。
  2. CEREAL_EXPAND的突破性
    • 通過中間層宏(CEREAL_EXPAND)隔離,使內層宏(如CEREAL_PASTE2)滿足“獨立標識符”條件,觸發其展開。

💻 實際應用示例

1. 序列化宏實現
// 成員處理宏
#define CEREAL_MEMBER_NVP_NON_INTRUSIVE(member) ::cereal::make_nvp(#member, t.member)// 主序列化宏:非侵入的
#define CEREAL_SERIALIZE_NON_INTRUSIVE(Type, ...) \
template <class Archive> \
void serialize(Archive& ar, const Type& t) { \ar( CEREAL_PASTE(CEREAL_MEMBER_NVP_NON_INTRUSIVE, __VA_ARGS__) ); \
}// 主序列化宏:侵入的
#define CEREAL_SERIALIZE_INTRUSIVE(...) \
template <class Archive> \
void serialize(Archive& ar) { \ar( CEREAL_PASTE(CEREAL_NVP, __VA_ARGS__) ); \
}
2. 展開過程演示
struct Point
{float x, y, z;CEREAL_SERIALIZE_INTRUSIVE(x, y, z)
};

調用:CEREAL_SERIALIZE_INTRUSIVE(Point, x, y, z)
逐步展開:

// 步驟1: 替換為PASTE4宏
ar( CEREAL_PASTE4(CEREAL_NVP, x, y, z) );// 步驟2: 展開PASTE4
ar( CEREAL_NVP(x), CEREAL_EXPAND(CEREAL_PASTE3(CEREAL_NVP, y, z)) );// 步驟3: 展開內層EXPAND → 觸發PASTE3
ar( ::cereal::make_nvp("x", t.x), CEREAL_PASTE3(CEREAL_NVP, y, z) );// 步驟4: 繼續展開PASTE3
ar( ::cereal::make_nvp("x", t.x), ::cereal::make_nvp("y", t.y), ::cereal::make_nvp("z", t.z) );

?? 注意事項

  1. 遞歸深度限制:

    • 預處理器遞歸層數通常為64層(編譯器相關),超限需拆分參數或減少嵌套。
    • 更多層需要開啟編譯警告忽略。
  2. 兼容性:

    • __VA_ARGS__為C++11特性,需確保編譯器支持。
  3. 調試技巧:

    • 使用gcc -E查看預處理結果,驗證展開邏輯:
    g++ -E -P test.cpp | grep -A 10 "serialize"
    

💎 總結

通過引入CEREAL_EXPAND強制展開嵌套宏,解決了原方案中遞歸鏈斷裂的問題。其核心原理是繞過預處理器的惰性展開機制,使內層宏作為獨立標識符被處理。此方案在保持代碼簡潔性的同時,確保了任意數量參數的遞歸展開可靠性,為Cereal等庫的宏封裝提供了健壯基礎。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88961.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88961.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88961.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

14-C#的彈出的窗口輸入與輸出

C#的彈出的窗口輸入與輸出 1.文件名輸入 string fileName Interaction.InputBox("輸入保存的文件名", "保存");2.彈窗信息輸出 MessageBox.Show("請選擇輪詢!", "Error", MessageBoxButtons.OK);catch (Exception ex){MessageBox.S…

多模態大語言模型arxiv論文略讀(141)

Mini-InternVL: A Flexible-Transfer Pocket Multimodal Model with 5% Parameters and 90% Performance ?? 論文標題&#xff1a;Mini-InternVL: A Flexible-Transfer Pocket Multimodal Model with 5% Parameters and 90% Performance ?? 論文作者&#xff1a;Zhangwei …

VScode使用usb轉網口遠程開發rk3588

我使用的是魯班貓的板&#xff0c;只有一個網口&#xff0c;需要接雷達&#xff0c;因此另外弄了一個usb轉網口來連接電腦開發。 在使用vscode或MobaXterm連接板子時&#xff0c;使用主機名與用戶名來連接&#xff1a; ssh catlubancat rk那邊就直接插入usb轉網口以及網線&a…

AUTOSAR圖解==>AUTOSAR_AP_EXP_SOVD

AUTOSAR服務導向車輛診斷詳解 面向現代化車輛架構的診斷方案 目錄 1. 引言 1.1 ASAM SOVD簡介1.2 SOVD產生的動機 2. SOVD參考架構 2.1 SOVD網關2.2 診斷管理器2.3 SOVD到UDS轉換2.4 后端連接 3. SOVD用例 3.1 SOVD和UDS的共同用例3.2 SOVD特定用例 3.2.1 訪問權限3.2.2 軟件更…

第八講:STL簡介

1. 什么是STL STL(standard template libaray-標準模板庫)&#xff1a;是C標準庫的重要組成部分&#xff0c;不僅是一個可復的 組件庫&#xff0c;而且是一個包羅數據結構與算法的軟件框架。 2. STL的版本 a. 原始版本 Alexander Stepanov、Meng Lee 在惠普實驗室完成的原始版本…

高彈性、高可靠!騰訊云 TDMQ RabbitMQ Serverless 版全新發布

導語 2025年6月起&#xff0c;騰訊云 TDMQ RabbitMQ 版正式推出 Serverless 版本&#xff0c;該版本基于自研的存算分離架構&#xff0c;兼容 AMQP 0-9-1 協議和開源 RabbitMQ 的各個組件與概念&#xff0c;且能夠規避開源版本固有的不抗消息堆積、腦裂等穩定性缺陷&#xff0…

Linux 內存調優之 BPF 分析用戶態小內存分配

寫在前面 博文內容為 使用 BPF 工具跟蹤 Linux 用戶態小內存分配(brk,sbrk)理解不足小伙伴幫忙指正 ??,生活加油我看遠山,遠山悲憫 持續分享技術干貨,感興趣小伙伴可以關注下 _ brk 內存分配簡單概述 一般來說,應用程序的數據存放于堆內存中,堆內存通過brk(2)系統調用進…

心理測評app心理測試系統框架設計

一、邏輯分析 用戶管理邏輯 新用戶注冊&#xff1a;需要收集用戶的基本信息&#xff0c;如用戶名、密碼、郵箱等&#xff0c;并且要對輸入信息進行合法性校驗&#xff0c;確保信息完整且符合格式要求。同時&#xff0c;為每個新用戶生成唯一的標識符&#xff0c;方便后續數據管…

配置有nvlink的H20A800使用pytorch報錯

背景 裝有nvlink的h20機器上配置好驅動和cuda之后使用pytorch報錯 A800機器同樣 (pytorch2.4) rootxx-dev-H20:~# python Python 3.12.0 | packaged by Anaconda, Inc. | (main, Oct 2 2023, 17:29:18) [GCC 11.2.0] on linux Type “help”, “copyright”, “credits” or …

sql的語句執行過程

第一步&#xff1a;客戶端把語句發給服務器端執行 當我們在客戶端執行SQL語句時&#xff0c;客戶端會把這條SQL語句發送給服務器端&#xff0c;讓服務器端的進程來處理這語句。也就是說&#xff0c;Oracle 客戶端是不會做任何的操作&#xff0c;他的主要任務就是把客戶端產生的…

深度學習-分類

深度學習-分類方式 &#xff08;重點&#xff09;一、按數據類型與處理邏輯分類1. 序列數據&#xff08;時序/順序相關&#xff09;2. 網格狀數據&#xff08;空間相關&#xff09;3. 圖結構數據&#xff08;非歐幾里得結構&#xff09;4. 其他特殊類型數據 &#xff08;重點&a…

C語言---常見的字符函數和字符串函數介紹

目錄 前言 1 字符分類函數 2 字符轉換函數 3 strlen的使用和模擬實現 3.1 strlen的模擬實現 4 strcpy的使用和模擬實現 4.1 strcpy的模擬實現 5 strcat的使用和模擬實現 5.1 strcat的模擬實現 6 strcmp的使用和模擬實現 6.1 strcmp的模擬實現 7 strncpy函數的使用…

Minio入門+適配器模式(實戰教程)

一、安裝Minio 1.1 拉取鏡像 docker pull minio/minio docker images 1.2創建掛載目錄 1.2.1 創建數據目錄 mkdir -p /docker-minio/data 1.2.2 創建配置文件目錄 mkdir -p /docker-minio/config 1.2.3 設置權限 chmod -R 777 /docker-minio/data /docker-minio/config …

LLaMA-Factory 對 omnisql 進行 ppo dpo grpo nl2sql任務 實現難度 時間 全面對比

在LLaMA-Factory框架下&#xff0c;針對omnisql任務&#xff08;自然語言到SQL生成&#xff09;應用PPO、DPO、GRPO三種算法的實現難度、時間及全面對比如下&#xff1a; 一、實現難度對比 1. PPO&#xff08;近端策略優化&#xff09; 難度&#xff1a;★★☆☆☆&#xff…

Kingbase 數據庫中的 sys_guid() 函數報錯

解決 Kingbase 數據庫中的 sys_guid() 函數報錯問題 問題背景 Kingbase 數據庫在遷移或使用過程中&#xff0c;可能會遇到 select sys_guid() 函數報錯 , 提示函數不存在的情況&#xff0c;這通常是由于以下幾種原因造成的&#xff1a; 函數未正確安裝或未啟用函數參數不符合…

零基礎RT-thread第五節:電容按鍵(2)

上一章的電容按鍵完全使用的HAL庫的代碼&#xff0c;并沒有使用線程。這里嘗試使用線程來控制電容按鍵。 依舊是 F767 本來以為會很容易實現&#xff0c;沒想到嘗試了很久&#xff0c;電容按鍵一直沒有反應。 static rt_uint32_t measure_charge_time(void) {// 步驟1: 放電 …

華為云Flexus+DeepSeek征文|單機部署 與 CCE 高可用部署下 Dify 性能實測

引言 在當今的 AI 應用開發領域&#xff0c;選擇合適的部署方式對于應用的性能表現、資源利用和成本控制至關重要。華為云為開發者提供了多樣化的部署選擇&#xff0c;其中基于單機 Flexus 實例的基礎版部署和基于 CCE 容器的高可用版部署是兩種常見的方式。本文將深入對比這兩…

釘釘小程序框架:Pinia 狀態管理與持久化存儲封裝

上一篇文章完成了 Pinia 在釘釘小程序中的引入與基礎配置 文章地址&#xff1a;釘釘小程序框架引入 Pinia 狀態管理-CSDN博客 本文將深入探討如何通過Pinia 結合持久化存儲 實現用戶狀態 在上一章節中&#xff0c;我們已經完成了 Pinia 在釘釘小程序中的引入與基礎配置。本章將…

云計算產業鏈

一、云計算定義與分類體系 本質特征 按需服務模式&#xff1a;以網絡化方式提供可配置的計算資源共享池&#xff08;網絡/服務器/存儲/應用&#xff09;。核心能力&#xff1a;快速彈性擴容、資源池化共享、按使用量付費、低管理開銷。技術原理&#xff1a;通過分布式計算將大型…

git使用詳解和示例

什么是 Git&#xff1f; Git 是一個 分布式版本控制系統&#xff08;DVCS&#xff09;&#xff0c;用于跟蹤文件的變化&#xff0c;協調多人協作開發。由 Linus Torvalds 開發&#xff0c;用于管理 Linux 內核代碼。 Git 的核心概念 名稱說明工作區 (Working Directory)你看到…