天天看點

泛型程式設計注意不能将模闆類的成員函數放在獨立的實作檔案中

泛型程式設計中,編寫的類和函數可以多态地用于跨越編譯時不相關的類型。一個類或函數可以用來操縱多種類型的對象。标準庫中的容器、疊代器和算法都是很好地泛型程式設計的執行個體。在C++中,模闆是泛型程式設計的基礎。模闆是建立類或者函數的藍圖或公式。

需要注意的是普通函數、類與模闆函數、類的差別:

        當編譯器看到模闆定義時,不立即産生代碼。隻有用到模闆時,如調用了函數模闆或調用了類模闆對象的時候,編譯器才會産生特定類型的模闆執行個體。一般而言,當調用函數的時候,編譯器隻需要看到函數的聲明。類似地,定義類類型對象的時候,類定義必須可用,但是成員函數定義不是必須的。是以,應該将類定義和函數聲明放在頭檔案中,而普通函數和類成員的定義放在源檔案中。模闆則不同:要進行執行個體化,編譯器必須能夠通路定義模闆的源代碼。當調用函數模闆或類模闆的成員函數的時候,編譯器需要函數定義,需要那些通常放在源檔案中的代碼。

        是以,不能将模闆成員函數放在獨立的實作檔案中(在C++11标準前,C++标準确實提供了關鍵字export,使得模闆成員函數放在獨立的實作檔案中,但是支援該關鍵字的編譯器不多;C++11不再這樣使用export,而将其保留用于替他用途)。由于模闆不是函數,它們不能獨立編譯。模闆必須與特定的模闆執行個體化請求一起使用。為此,最簡單的方法是将所有模闆資訊放在一個頭檔案中,并在要使用這些模闆的檔案中包含該頭檔案。

        例如,在之前的文章《二叉堆的插入删除等操作C++實作》中,所使用的是類模闆,那麼,我試着嘗試将模闆類成員函數的定義寫在單獨的.cpp檔案中,将模闆類定義放在.h檔案中,就像普通類的實作一樣,則編譯出錯。