[英]Proper organization for a mixture of templated and non-templated functions not accessible to the end-user
在我正在開發的項目中,我目前正在實現一個模板化的算法。 我在組織我的函數聲明和定義時遇到了一些問題,因為涉及模板(我在這里問了一個關於如何處理非模板化函數的問題“與模板化函數一起分組”)。 然而,這讓我想知道這些文件的一般正確組織。
我想將所有定義與所有聲明分開(僅出於可讀性的目的,即使我必須將模板化定義包含在聲明中)。
我得到的答案建議組織如下:
algo.h
algo.tpp
將包含在algo.h
(模板需要在編譯時聲明) algo.cpp
不包含在任何地方。 如果所有定義的函數都應該對最終用戶可見(即所有聲明都在algo.h
文件中),這種方法algo.h
。 但是,有時我喜歡將我的大功能分解為更小的功能,但我希望最終用戶只能訪問“大功能”,而不能訪問他們的子功能。 在非模板化設置中 ,我會這樣做:
algo.h
將僅包含針對最終用戶的聲明 (可通過include訪問) algo.cpp
algo.cpp
,允許我在algo.cpp
( algo.h
聲明的algo.h
)中的大函數使用它們,但不能使它們可以訪問-用戶。 如果這些子功能本身不是模板化的,而是由模板化函數使用,則這不再起作用。 模板化的子功能可以進入.tpp
文件,被模板化的“大功能”使用,一切都很好。
但是,如果這些功能是非模板化的,如果放在.tpp
文件中,它們會導致多個定義錯誤(這是我之前的問題所在 )。 另一方面,如果它們位於單獨的.cpp
文件中,它們或者最終用戶可以訪問(如果我將聲明放在.h
文件中),或者對於要使用它們的大函數是不可訪問的(如果我沒有把聲明放在.cpp
文件之外)。
組織函數的正確方法是什么,有些是模板化的, 有些不是 ,有些應該是最終用戶可以訪問的,有些則不是,可以訪問多個文件?
理想情況下,(為了完整性),我正在尋找的答案將解決以下的位置(在.h
, .tpp
, .cpp
或其他適當的文件中):
我想要的功能的短幾乎偽代碼示例 (沒有文件分離)
// Templated sub-functionality, used by bigFunctionality,
// but ideally not accessible to the end-user
// This might not be possible since it is templated,
// so I am content with putting it in the .tpp file
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
// Non-templated sub-functionality, used by
// bigFunctionality, but NOT accessible to the end-user
void moreSubFunctionality(.. args ..) { /* impl */ }
// the main functionality, meant to be
// accessible to everybody across all files:
template <typename Compare>
void bigFunctionality( .. non-templated args ..., Compare order){
subFunctionality(order, .. args ..);
moreSubFun(.. args ..);
// more stuff
}
再一次,我正在研究如何將其分成多個文件(即使它們彼此包含在一起,因為必須使用模板),部分用於可讀性目的,部分用於可訪問性。
僅僅是為了澄清, 這些是算法 - >函數,而不是類 。 (我知道將模板化和非模板化函數放入相同的模板類可以解決我的問題)。
PS:我知道這個問題的標題是非常大而且很長,所以如果有人想要縮短它,我會非常高興的建議/編輯
這是C ++中缺少模塊的一個不幸的副作用:聲明的內容必然是可見的。
通常,指南是簡單地使用“私有”命名空間(嵌套在用戶可見的命名空間中):
internal
) .tpp
文件中的那個命名空間中聲明這些輔助函數 然后,您記錄此命名空間是內部的,不適合客戶端調用者。 如果可能,還要注釋命名空間/函數,以便不為它們生成文檔。
在這一點上,這些功能顯然是私人和隱藏 。
如果你想更進一步,你可以簡單地在class
(*)中聲明它們是private
,然后只有你的函數成為這個類的friend
。 然后,任何使用它們的嘗試都會導致編譯器發出錯誤:它們是可見的,但是不可訪問 。 但是,大多數人(從Boost開發人員開始)只是不打擾,我當然也不會。
(*) class
本質上取代了私有命名空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.