C Template標頭檔案和定義分開編譯的問題

2021-06-04 21:00:57 字數 1193 閱讀 5369

(1)

// foo.h

template

class foo

;// foo.cpp

#include

#include "foo.h"

template

void foo::f()

// main.cpp

#include "foo.h"

int main()

如上組織,會編譯出錯。

而如果把foo.h和foo.cpp合併在一起,就不會出現編譯錯誤了。

#include

template

class foo

;template

void foo::f()

int main()

這是正確的。

為什麼呢?

(2)由於現在還沒有支援template分離編譯的編譯器(記得目前還沒有),因此我們常見的template標頭檔案(例如)會把宣告和實現都放到一起 (而不像我們通常做法只把宣告放入標頭檔案中)。

這便帶來了乙個問題,例如:

1.c:

#include

...2.c:

#include

...gcc 1.c 2.c

問題就是為什麼可以順利通過呢(呵呵,這個和#ifdef | #define | #endif 預處理無關的)?

依照前邊所述,相當於1.c和2.c中各有乙份vector的實現,應該沒法link通過的啊。

呵呵,這個時候可能就像你猜想的那樣,輪到我們的編譯器出馬了,編譯器為了保證template標頭檔案也能夠和其他的標頭檔案(只包含宣告)有相同的行為,它會為template作相應的暗中處理,以保證template只被實現一次 。

(3)在(1)的例子裡面為了能夠讓定義和宣告分開,將宣告放到了foo.h中,而定義放到了foo.cpp中,這和非模板型別的函式是一樣的。但是可惜這麼做是無法通過的,因為模板型別函式不能夠(由於沒有export支援)單獨編譯。 為了讓編譯通過,將foo.cpp給include進了foo.h,這樣實際上是將兩個檔案整合成乙個檔案了。這樣編譯就沒有問題了,但是得小心需要把foo.cpp分離出專案,因為它不可以被編譯;或者將其副檔名從.cpp改為.hpp。

實在是不推薦這麼分開的寫,說實話這算不上是什麼標準的做法,而且這樣並沒有太大的意義。如果非要分開,可以將定義字尾到宣告後面,在乙個檔案裡。但是分開確實沒太大意義。可以研讀一下boost裡面的做法。

glibc標頭檔案和巨集定義

標頭檔案沒啥好說的,無非就是 和 的區別,這估計只要是學過c c 的人都明白。現在的編譯器對頭檔案的包含順序沒有要求,但老的c實現則不一樣。當然,我們現在無需關心標頭檔案順序了。我們為啥要包含標頭檔案呢?標頭檔案裡面有定義嘛,使用任何函式之前都必須定義該函式。所以我們並不強求包含標頭檔案,只要你自己...

OpenMAX IL 標頭檔案的定義

il v1.1.2 中每個標頭檔案的作用是什麼 omx types.h data types used in the openmax il omx core.h openmax il core api omx component.h openmax il component api omx audi...

標頭檔案中定義變數

在標頭檔案中定義了乙個變數,若另乙個檔案再 int 變數名 則會再產生乙個相同變數的定義,在linux環境中編譯時會發生如 menu.o sbss 0x0 multiple definition of is refresh living time thread created main.o sbss...