來讓你的程式庫支援C++20 Module吧! 如何快速支援C++ Module?

208天前 · 程式設計 · c++ · 732次阅读

引言

C++ 20標準已經發佈6年時間了。
其中最重要的一項標準就是 ⌈模塊⌋ 這個特性。

什麼是模塊? 怎麼用模塊? 如何快速讓你的已有代碼支援模塊?
—— 本文都將爲你講解。

什麼是模塊 & 如何使用模塊

在模塊誕生之前,我們如何編譯我們的C++專案?

  • 一個標頭 hello.hpp
  • 一個翻譯單元 hello.cpp

標頭用於在多個翻譯單元間共享聲明和定義。
它也有諸多限制和不好的地方:
你需要在標頭中聲明共享的對象,並在翻譯單元中定義它。

//hello.hpp
void func(); // 聲明一個函式

//hello.cpp
void func(){} //定義它

—— 就像一件事我們需要做兩遍一樣。

由於include機制非常古老和簡單,如果你在標頭中定義對象就很有可能發生重複定義,畢竟include 只是把你匯入的內容完整粘貼一份罷了

模塊是一種跨翻譯單元共享聲明和定義的方法,通常後綴爲 .cppm , .ixx等 。

// hello.cppm

import std; // 匯入標準庫(注意,截止文章發佈,所有標準庫仍未很好的支援模塊)
import <iostream>; // 匯入標頭(次選方法)

export module hello; // 聲明匯出的模塊

void world () { // 一個模塊內部的函式(僅內部可見)
    std::cout << " World\n";
}
export void hello()  // 在函式前加入export以匯出(外部可見)
{
    std::cout << "Hello";
    world();
}

// main.cpp
import hello; //匯入模塊

int main(){
    hello();
}

只需要加上關鍵詞 export 你就可以輕鬆的控制匯出內容,這非常的方便。

如何快速讓你的已有代碼支援模塊

在瞭解模塊與標頭的不同後,我們就可以輕鬆的實現對模塊的支援,只需要把想匯出的內容在 export中定義即可。

Header-only支援的方法

// test.hpp
inline void test(){} // 一個inline方法

// test.cppm
module; // 聲明全局模塊(可用預處理指令)

export module test;

export {
// 匯入你的標頭
#include "test.hpp"
}

使用:

import test;

int main(){
    test();
}

有些小夥伴可能會遇到重複定義的問題。

這是因爲我們在 export {} 體中匯出了整個header-only檔案,包括預處理指令 #include
所以自然也會將這些內容匯出。
作爲解決方法,我建議添加一個宏來控制檔案不要匯入標頭。
列如 XXX_ENABLE_MODULE 激活模塊模式(不要匯入標頭):

// test.hpp

#if !defined(TEST_ENABLE_MODULE)
// 未定義 TEST_ENABLE_MODULE 時才匯入標頭(header-only模式)
#include <iostream>
#endif

inline void test(){
    std::cout<< "Test\n";
}

// test.cppm 
...

// 在全局模塊匯入依賴
#include <iostream>

#define TEST_ENABLE_MODULE true

export {
#include "test.hpp" // 不會再次匯入iostream
}

這樣就不會破壞現有內容(原來的標頭檔header-only模式仍可正常使用)並支援了現代C++ Module。

具有內部鏈接屬性的方法無法被匯出

範例:

export {
    static void func(){ // 內部鏈接,無法匯出
    }
    inline int x = 0; // inline變數也無法匯出
}

如果在你的標頭中有定義inline變數(C++17起),也要一起處理,在Module下不要加入inline聲明,而是直接在export中匯出。

// hello.hpp
struct X {
}
#ifndef HELLO_ENABLE_MODULE
inline
#endif
x;

// hello.cppm
#define HELLO_ENABLE_MODULE
export {
#include "hello.hpp"
}

非Header-only的支援方法

非header-only的支援方法也類似
我們直接在 export {}#include hpp,並在外部#includecpp檔案即可:

// test.cppm
...
export {
#include "test.hpp"
}
#include "test.cpp" // 注意,這是一個違反C++模塊界面建議,但確實可以工作的技巧

這是在你不額外專門編寫cpp模塊下,直接支援模塊的方法。

注意,你仍可能需要加入一個模塊控制宏以以免重複匯入標頭,如同Header-only中的方法一樣。

定義(.cpp的內容)最佳做法是加入到爲普通翻譯單元,這裏是爲了方便而使用的技巧。

結語

模塊目前還未完全成熟,各種第三方程式庫和標準庫都未很好的支援模塊。
但作爲Modern C++的特性,可以相信Module是比傳統#include方法更佳的實作方法。

如果你想要透過import匯入std(C++23起),請記得檢查__cpp_lib_modules

參閱:

👍 2

cpp module cpp-module modern-cpp

最后修改于111天前

评论

贴吧 狗头 原神 小黄脸
收起

贴吧

  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡
  • 贴吧泡泡

狗头

  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头
  • 狗头

原神

  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神
  • 原神

小黄脸

  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  • 小黄脸
  1. Anfsity 186天前

    可惜现在各大编译器对 module 的支持都不友好 🙁,lsp 的支持也不完善,很难有良好的开发体验。

    之前看到许传奇在他的博客里详细介绍了 modules

    https://chuanqixu9.github.io/c++/2025/08/14/C++20-Modules.html

  2. Elainafan 204天前

    有种Python的既视感 [doge]

    1. Hina 204天前

      沒辦法,C++標準委員會太慢了,早就該進標準的東西。反而這些新語言先用上了。 救救我

目录

avatar

Hina

曇花一現

20

文章

98

评论

8

分类

初见

⌈你連死都不怕,還怕活著嗎?⌋

28天前

OwO

33

網站正在更新中...
站點正在更新功能與樣式,如有樣式錯誤,請嘗試刷新緩存