除了可以計算數值,編譯期更具有價值的是類型計算。我們可以將編譯期常量和類型都看做是編譯期的可計算對象。
我們知道模板的所有形參被實參替換后,模板自身就具現化為一個具體的類型了。但是模板自身具現化的這個類型對于我們想要的編譯期類型計算來說缺少抽象能力。模板的類型計算結果如果保存在模板內部定義的嵌套類型中,這將會為模板計算提供封裝性和信息隱藏的能力。
模板內部定義類型的方法除了可以直接在模板內部定義嵌套類,更多的是使用typedef。
如下我們定義了一個類模板,它的入參是類型T,內部通過Type定義了T的指針類型T*
。
template<typename T>
struct PointerOf
{
typedef T* Type;
};
我們可以像下面這樣使用該模板:
PointerOf<const char>::Type s = "Hello world!";
std::cout << s << std::endl;
如同前面數值計算一樣,我們可以這樣理解PointerOf
:PointerOf
是一個編譯期的函數,它使用<typename T>
聲明了它有一個類型形參T。我們通過訪問Type
可以獲得該函數的返回值,它也是一個類型。這個函數的功能是在C++編譯期將一個輸入類型轉變為它對應的指針類型。所以調用PointerOf<const char>::Type
其實是和const char *
本質上一樣。
我們定義的這個PointerOf
似乎有些無聊,但這卻是類型計算的基礎。后面當我們把這種類型計算的小函數組合起來,會逐漸看到它們的威力。
最后,C++11標準擴展了using關鍵字來專門定義類型別名,它的用法和定義變量的習慣類似,且功能也比typedef強大得多,所以我們后續類型計算統一用using關鍵字定義類型別名。PointerOf
的定義修改如下:
template<typename T>
struct PointerOf
{
using Type = T*;
};