日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++20】vs2019使用modules的实际操作

發布時間:2024/9/30 c/c++ 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++20】vs2019使用modules的实际操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????????

目錄

一、什么是modules

二、vs版本要求

三、項目配置

四、標準庫模塊引入方式

五、兼容舊式寫法

六、導出類與變量

七、文件后綴

八、實現與主接口分開

九、模塊命名與分區

十、引入模塊

十一、模塊分區? ? ? ?

十一、模塊私有部分

十二、結語


????????大家好,我是略游。今天講一講我在vs上操作C++20新標準模塊(modules)的經驗。此文章具有時效性,只代表當前實驗結果,也可作為一個基本寫法入門,將來的編譯器一定會完善得更好。

一、什么是modules

????????modules是C++20標準的源碼組織方式,以替代#include等傳統的源碼組織方式。與它相關的基本知識網上有很多文章,廢話不多說直接實際操作。

二、vs版本要求

????????官方文檔說16.10版本以上,更新最新版本即可。使用vs2022也可,不過需要注意的是需要安裝以下工具:

????????雖然在隨后的實驗中,我沒有成功使用上標準庫的模塊接口,但這個工具是否必須安裝,我暫時懶得測試了,在這里獲取工具:

三、項目配置

? ? ? ? 首先設置C++語言標準為/std:c++ latest,并且啟用標準庫模塊

? ? ? ? ?在定義使用最新特性的命令行/await

? ? ? ? ?在鏈接器中關閉使用增量鏈接,同時使用程序數據庫,這二者是配套的,如果不關閉增量鏈接,會與模塊編譯有沖突,后者不能正常識別修改。

四、標準庫模塊引入方式

? ? ? ? 按照微軟文檔的說法,如下即可導入標準庫模塊:

import std.core; import std.filesystem; //...

? ? ? ? ?但實際操作中很困難,會提示一些編譯選項沖突。除了/EHsc和/MD選項,還有一些其他的定義沖突,例如_DEBUG宏。

? ? ? ? 文檔鏈接如下:

Overview of modules in C++ | Microsoft Docs

五、兼容舊式寫法

? ? ? ? 要以#include包含舊式頭文件,可以如下寫:

module; #include "Head.h" export module Test;

? ? ? ? 這里包含了一個頭文件Head.h,然后導出了一個模塊叫Test。但是此處有一些局限性,Head.h不能是預編譯頭,預編譯頭是msvc的一種加快編譯速度的方式,但是這里是不能兼容的。

? ? ? ? 在Head.h里面我包含了一大串頭文件,這樣我們也能使用上標準庫。當前這樣的寫法,缺點是每次修改都需要重新編譯所包含的頭文件內容。預編譯頭可以解決這個問題,等完全使用上模塊后,也能解決這個問題。現在只是兼容的寫法。

//Head.h #pragma once #include <array> //!< 數組 #include <list> //!< 鏈表 //more...

? ? ? ? ?值得一提的是,我在包含windows頭文件時,遇到一些報錯無法解決,最后只好不直接包含windows頭文件了,暫時使用傳統方法隱藏起來。

? ? ? ? 語法很簡明,在“module;”和“export module Test;”之間就是舊式的包含頭文件方式。

六、導出類與變量

? ? ? ? 前面加export即可導出類與全局變量,如下:

module; #include "Head.h" export module Test;export class Test {//... };export Test g_test;

? ? ? ? ?這里就不用再像以往一樣,害怕變量重定義,不能直接放置到頭文件。在以前的寫法就是這樣的:

//--------------Test.h #include "Head.h"class Test {//... };extern Test g_test;//--------------Test.cpp Test g_test;

? ? ? ? 另外constexpr常量并不能直接導出,因為它是不變量,在編譯期就會替換為數值,并不會真實存在這個變量,只能通過命名空間間接導出。

//-----------failed export constexpr size_t DEFINE_NUM_GOODS_00 = 16 * 22;//-----------ok export namespace Define {constexpr size_t NUM_GOODS_00 = 16 * 22; }

七、文件后綴

? ? ? ? C++標準沒有規定文件的后綴名必須是什么,但是到目前為止,msvc必須使用.ixx后綴名,否則編譯器會報錯。

? ? ? ? 同時還應該設置文件項類型為C/C++編譯器?,如下圖所示:

? ? ? ? ?為了區分主接口文件,我們可以讓實現文件后綴為.cpp,但仍然注意屬性頁里的項類型也要是C/C++編譯器。

? ? ? ? 直接右鍵添加一個模塊文件,這樣也是正確的:

八、實現與主接口分開

? ? ? ? 我們可以直接在主接口文件實現Test::Init成員函數的定義,但也可以分開文件存放。例如以下文件Test.cpp,在兼容舊寫法的同時,還需表明自己是Test模塊的一部分。

module; #include "Head.h" module Test;void Test::Init() { }

? ? ? ? 在以前的寫法,將函數定義在頭文件的嚴重缺點就是,修改此函數就會導致整個文件被修改,然后所有包含此文件的源碼都需要重新編譯。而模板函數必須放在頭文件,不但編譯速度極慢,而且無法規避這個問題。而使用模塊后便可以改進這個缺點,同時我們還能保持文件分開以保證代碼的整潔性。

九、模塊命名與分區

? ? ? ? 在一些示例中我們可以看到用點來分隔名字,比如export module Test.A,但實際上Test.A就是一個模塊的名字,它是一個整體,并不代表Test模塊的A分區(點在這里沒有任何意義,只是為了好看)。正規的分區寫法如下:

//Test.A是一個獨立的模塊 export module Test.A;//A是Test的分區 export module Test:A;

? ? ? ? 另外微軟推薦文件名命名與模塊名相似,假設一個模塊叫Test.Point:Draw,那么它的文件名應該是Test.Point-Draw.ixx,實現文件可以叫Test.Point-Draw.cpp。即用-來代替:。

十、引入模塊

? ? ? ? 很簡單,如下寫即可:

import Test;

? ? ? ? 如果想要“轉發”模塊,在自己引入X的時候,同時引入自己的地方也會引入X,如下所示:

export module Test;export import Test.Image; export import Test.Sprite; export import Test.Tex; export import Test.Text; export import Test.UI;

? ? ? ? ?當另一個文件引入Test時,就不需要再引入Test.Image等了,只需import Test就會import Test.Image等。注意這里的.只是名字的一部分,而不是模塊分區,只是為了好看。

? ? ? ? 如果只是Test自己使用,去掉export則不會轉發:

export module Test;import Test.Image; import Test.Sprite; import Test.Tex; import Test.Text; import Test.UI;

十一、模塊分區? ? ? ?

????????前面用“.”來分隔名字只是一種權宜手段,它們本質上是單獨的模塊,其余文件不需要通過Test來導入Test.Image,可以直接導入Test.Image。而分區模塊如果主接口沒有導出,則其他文件是使用不了的。

? ? ? ? 假設有個Test:Struct分區,在Main.cpp想要導入。那么這么寫是無效的:

import Test:Struct; //error

? ? ? ? ?而用.的話,就可以:

import Test.Image; //ok

? ? ? ? ?所以用分區的區別在于此,并且從定義上來說Test:Image是真正屬于Test的。

????????要定義一個模塊分區,如下:

export module Test:Struct;export struct A {//... };

????????在上面的代碼,在Test:Struct分區導出了一個類A。在Test主接口文件,同樣可以選擇import或者export import。這決定了Test:Struct是否對外界可見。

//導出模塊Test export module Test;//導入Define import Define;//導入Test.Image并且使導入Test的自動導入Test.Image export import Test.Image;//導入Test.Ui供自己使用 import Test.UI;//導入分區,但是不導出,也可以前面加export導出 import :Struct;

? ? ? ? 注意import模塊分區時,則必須省略冒號前面的模塊名, 想必編譯器也是由此判斷的。因為不屬于Test的模塊會import Test:Struct,然而這是不允許的。而屬于Test的模塊,是知道自己在Test的,所以可以省略“:”前的Test。

十一、模塊私有部分

? ? ? ? 在聲明module :private之后的內容只對自己文件可見,當然這是對于實現文件模塊分區來說的。因為一個類或變量是否導出,取決于前面是否有export關鍵字。

module :private;

十二、結語

????????如果你覺得此文章有幫到你,可以點擊收藏,然后點擊關注,這可以極大的支持我發更多的文章。

? ? ? ? 你還可以加我的QQ群討論:游戲編程星云閣?170100866

?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的【C++20】vs2019使用modules的实际操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。