2016-05-05 70 views
3

我正在開發一個大量使用模板的C++庫。對於大多數類,所有代碼都駐留在一些.hpp文件中,該文件將直接由客戶端代碼執行#include d。有兩件事我很擔心:縮小模板標題的大小

  1. 是否有一些將實現代碼移動到「背景」的設計模式?當我設計非模板類時,我經常將「接口」類和實現類分開,前者通過執行諸如getImpl()->foo()之類的操作將委託給後者,以便實現代碼可以動態鏈接到。我不知道如何爲模板做到這一點。 可能動態鏈接對模板沒有意義,我想呢?

  2. 大模板標題(> 1000行)是否通用?還是那麼糟糕?如果不好,我可以用它做什麼?

我知道這個問題How to reduce output size of template-heavy C++ code?的,但我認爲我們是想詢問不同的事情:這個問題的任擇議定書試圖降低輸出的大小,而我想,以減少大小我的庫標題本身。

UPDATE:舉例來說,如果你要設計std::vector,你將如何組織其接口&實現(如果需要的話)?

+0

你到底我一個_reduce sizes_?爲了避免應用太多種模板參數的膨脹代碼實例化? –

+0

@πάνταῥεῖ按尺寸我主要是指代碼行。將千行標題暴露給客戶聽起來對我來說是個不好的主意(至少對於非模板代碼)。 –

+0

如果您的非模板代碼不依賴於模板參數,請將其移出到單獨的編譯單元。 –

回答

0

不要太擔心標題大小。模板幾乎總是將所有代碼放在標題中,因爲每個客戶端都必須知道如何創建一個全新的版本(使用不同的模板參數)以實例化該類。

如果你擔心1000行,請看矢量。在Visual Studio 2013中,它是3000行。如此說來,你確實只需要在任何地方提供可用的類的聲明,並且只需定義一次,就像任何普通的類一樣。因此,可以在沒有實現的情況下創建模板頭,然後使用實現創建一個.cpp。這個.cpp將不得不強制生成你需要的所有模板類型。

在下面的例子中,B.cpp的作者必須知道所有將被使用的模板參數。你不需要這麼多文件,但我認爲這應該涵蓋所有情況。

B.h:

template<class T> 
struct B 
{ 
    B(); 
}; 

B_impl.h:

#include "B.h" 
template<class T> 
B<T>::B() {} 

B.cpp:

#include "B_impl.h" 
template struct B<int>; 
template struct B<short>; 

main.cpp中:

#include "B.h" 
B<int> b; 
+0

*所以有可能沒有實現的模板頭,然後用實現創建一個.cpp。這個.cpp將不得不強制生成你需要的所有模板類型。*這是用於客戶端代碼還是庫代碼? –

+0

我用完整的代碼示例編輯了答案(並且我用模板替換了typedef,因爲typedef沒有實例化模板化類)。這對於圖書館代碼來說是相當危險的,因爲你可能不知道你的客戶將使用你的圖書館的每一種類型。如果你釋放編譯的二進制文件,你的二進制文件也必須包含所有的實例。想象一下你不能使用自己的類型的std :: vector。 – Ian

+0

您可以在庫中運送B.h和B_impl.h以避免這些問題,但我從未見過它已完成。另外,假設B類有20個函數,main.cpp只使用其中的一個。我認爲編譯器只需編譯1函數。但是,如果使用上面的模板結構B ,則編譯器必須編譯所有20個函數(也許鏈接器將刪除其中的19個函數)。 – Ian