我正在創建一個庫,并且在 C 20 模塊中有一個類模板,我想添加一個實體化以減少每個使用我的庫的專案的編譯時間。
這些不同的實作是等效的,還是有更好的方法來實作它?
1)
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
export template class mystruct<int>;
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
template class mystruct<int>;
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
export extern template class mystruct<int>;
//mod_impl.cpp
module mod;
template class mystruct<int>;
編輯:這個答案只說 2. 有效,但我的觀點是如果 1. 和 3. 也等于 2.
uj5u.com熱心網友回復:
模塊影響兩件事:名稱的范圍和宣告的可達性。僅當它們在模塊的范圍內(即:在匯入的模塊介面 TU 中而不在全域模塊片段中)時,這兩者才重要。
在模塊范圍內宣告的名稱只能在該模塊之外使用,前提是它們export由該模塊編輯。在顯式模板實體化的情況下,模板本身已經被匯出,因此模塊之外的用戶已經可以使用該名稱。
但是,顯式模板實體化定義也是一個宣告。模塊控制宣告的可達性。問題是,伸手可及能力的申報規則,實際上并不關心有關export:
如果對于實體化背景關系 ([module.context]) 中的任何點 P,宣告 D 是可達的,
- 在同一翻譯單元中 D 出現在 P 之前,或
- D 未被丟棄([module.global.frag]),出現在可從 P 到達的翻譯單元中,并且不出現在私有模塊片段中。
[注:報關單是否匯出與是否可達無關。——尾注]
重點補充。
這些規則只關心匯入了哪些 TU(以及宣告是否在全域/私有模塊片段中)。
因此,如果主模板宣告被export編輯,則任何匯入它的代碼都可以訪問其中一個匯入的模塊檔案中的顯式模板實體化(不在全域/私有模塊片段中)。
因此,如果您export顯式模板實體化并不重要。如果主模板已經被export編輯,它的名字可能已經被使用,所以唯一重要的是顯式模板實體化是否可見。
所以你的 #1 和 2 在功能上是等效的。最好不要export做你不需要的事情。
至于 的行為extern template,這很有趣。
雖然externnormalize 表示外部鏈接,但這不適用于extern template. 所以我們沒有鏈接問題。而且由于extern template模塊的進口商可以訪問宣告(如前所述),他們會看到并尊重它。
所以唯一的問題是你的“mod_impl.cpp”中的顯式定義是否也可以訪問。除了這不是一個問題,因為只有定義的宣告部分是“可達的”。也就是說,可達性只對宣告很重要。
顯式實體化定義在不同的 TU 中。因此,它只會在那個 TU 中被實體化;匯入模塊的代碼只到達宣告。因此,它不會實體化模板。
所以,是的,你可以進行extern template體操(雖然同樣,export沒關系)。但這與將顯式實體化放在模塊介面中沒有什么不同,這樣做更簡潔。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/407748.html
標籤:
上一篇:CPP:這是實作執行緒安全FIFIO訊息佇列的合理方式嗎
下一篇:要加載的腳本串列存盤在哪里?
