C++ template Day Day Up 第一天 模板編譯模式

癡迷於OO設計,在C++的應用中運用模式或者設計的時候卻總是畏首畏腳的,怕沒有回收內存,怕產生臨時變量,懷念java和C#帶給我們的方便,C++真的不行麼?Linus那臭小子真的言中了?我不信,他的言論只是利用他的技術權威在進行的商業行爲。
那麼C++程序到底應該怎麼設計和編碼纔是優雅的、方便的呢? 無意間看了 Modern C++ design, 才明白原來template + OO 纔是真正的Cpp-Style design,之後放下手中的其它技術,潛心研究template,希望也能輕鬆駕馭template於項目之中,作出更優秀的設計。
Cpper手中兩把最鋒利的武器是OO和template。 OO我們已經很熟悉了,而template的高級應用對於大多數C++程序員(至少我瞭解到的是)來講還是挺遙遠的,用且用得少(像boost,loki, STL也只用了一小部分),更何況作出漂亮的設計呢。
So,準備寫一篇長篇科普blog,與Cpper共同進步。能力有限,水平有限,諒解 my mistakes。
 
Action!
Today's attention!
編譯最簡單的模板函數 Max
寫一個比較int類型的Max
int Max(int l, int r)
{
    return l > r? l : r;
}
像很多書中介紹的一樣,有了template我們可以寫出這樣的程序:
template <typename T>
T Max(T a, T b)
{
    return a > b ? a : b;
}
很好~ 這段程序不準備介紹,本篇的重點是如何編譯template程序。
直接編譯不就得了? 實際上這裏面是有學問的。
下面將介紹編譯C++ template的兩種模式
無論函數或者類,傳統C++是分爲頭文件(h, hpp…)和定義文件(cpp…)來定義一個函數。
在頭文件中寫上聲明,在實現文件中寫明定義。類似如下形式:
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
//Max.cpp
 
#include “Max.h”
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
//
Max(1, 2);
編譯上面的程序的時候compile會通過,link會失敗。這說明編譯器不能像對待普通函數或者類一樣對待template。
Template 編譯模式一:
Inclusion Model
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
或者
//Max.cpp
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
///////////////////////////////
// Max.h
template <typename Type>
Type Max(Type a, Type b);
#include “Max.cpp”
////
當然你也可以直接寫出函數定義。
// Max.h
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
實際上Inclusion Model就是將定義和實現全都放到頭文件中,這對於template class的定義也是一樣的,讓我們前瞻一下template class
 
template <typename T>
class TryDef
{
public:
     T getDefaultObject();
};
 
template<typename T>
T TryDef<T>::getDefaultObject()
{
     return T();
}
 
恩~ 這個就是Inclusion Model,大多數情況我們就用這種模式。
 
Template 編譯模式二:
Explicit Instantiation
 
這種模式隱含着C++一個語法。
 
template int Max(int a, int b);
看上面這行語句,這是定義了一個模版的實例,編譯期間會根據這條語句直接生成一個int的Max函數,而不是通過使用者調用int版的Max函數在生成實例。
 
假如我們想要完成這樣一個需求: 對於一個模版函數或類,我們只想生成我們指定的類型的版本,對於其他類型的版本一概不給出實現,如果用戶調用就會出現連接錯誤。
 
這時候Explicit Instantiation 模式就派上用場了,我們這樣組織源程序:
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
//Max.cpp
 
#include “Max.h”
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
//MaxInst.cpp
 
#include “Max.cpp”
 
template float Max(float, float);
 
假如我們這樣調用函數,
#include “Max.h”
Max(1, 2);
編譯器會給出連接錯誤。
想讓它編譯通過的話需要加上int版本的Max函數,在MaxInst.cpp中加入:
template int Max(int,int);
 
還有一種編譯模式常用的編譯器都沒有實現,叫做Separation Model,它利用export關鍵字,沒法嘗試所以偶就保持沉默了。
 
 
Summary
 
以上示例程序在Visual Studio 2005 g++ 3.4.2下通過驗證。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章