我想在一個文件中定義一個模板函數,並在許多文件中使用。這是否與常規函數原型的工作方式一樣?所以我可以定義一次,並將原型包含在其他文件中?我對類有同樣的問題,我是否必須在每個頭文件中包含模板類的完整定義,就像我爲一個類一樣?如果我在單獨的文件中定義了一個模板函數兩次,或者這會被取消選中,會導致錯誤嗎?不同文件中的模板函數和類的使用
還有一個問題,模板函數原型的格式是什麼?
我想在一個文件中定義一個模板函數,並在許多文件中使用。這是否與常規函數原型的工作方式一樣?所以我可以定義一次,並將原型包含在其他文件中?我對類有同樣的問題,我是否必須在每個頭文件中包含模板類的完整定義,就像我爲一個類一樣?如果我在單獨的文件中定義了一個模板函數兩次,或者這會被取消選中,會導致錯誤嗎?不同文件中的模板函數和類的使用
還有一個問題,模板函數原型的格式是什麼?
不,它與普通功能不一樣。與常規功能,你可以在頭聲明
void foo(int);
void foo(double);
,在一些源文件中定義的功能,如foo.cc
,在#包括有使用這些功能的任何源文件的標題,如bar.cc
,並讓鏈接器完成剩下的工作。編譯器將編譯bar.cc
並生成bar.o
,確信你已經在某處定義了函數,如果你沒有,那麼你會得到一個鏈接時錯誤。
但是如果你使用模板:
template <typename T>
void foo(T) ...
試着想象,將如何工作。源文件foo.cc
和bar.cc
是獨立的,彼此之間一無所知,只是他們同意他們都包括頭文件中包含的內容(這是整個想法)。所以bar.cc
不知道如何foo.cc
實現的東西,而foo.cc
不知道bar.cc
將如何處理這些功能。在這種情況下,foo.cc
不知道什麼類型的bar.cc
將爲T指定。那麼foo.cc
怎麼可能有太陽下每個類型名稱的定義?
它不能,所以這種做法是不允許的。您必須在標題中包含整個模板,以便編譯器可以定義爲foo(int)
或foo(string)
或foo(myWeirdClass)
或任何bar.cc
要求的定義,並將其構建爲bar.o
(或者如果模板對此沒有意義類型)。
類也是一樣。
這些規則對於模板專業化有點不同,但在嘗試高級技術之前,您應該掌握基本知識。
只是爲了確定是否我在兩個不同的文件中定義它們的方式不同,我們可以說即使這樣做是錯誤的嗎?對於實例化模板的文件,每個定義都是本地的嗎?爲什麼我不能定義一個原型,如template
@rubix - 你絕對不允許有不同的定義。通常你可以通過將它放在一個頭文件中來解決這個問題,並且在你使用該模板的任何地方都包含它 – 2011-04-25 05:32:06
@rubixibuc:是的,每個定義都適用於可以看到它的源文件。只有當一個消息來源看到時,纔會有衝突。編譯器可能會允許這樣的原型(我不知道爲什麼),但是如果您嘗試使用該函數而不提供調用源可以看到它的定義,那麼編譯器將會抱怨(如果沒有,請讓我知道)。 – Beta 2011-04-25 05:34:54
看到這個FAQ。特別是,items 12, 13 and 14涉及分離模板函數的聲明和定義。
http://stackoverflow.com/questions/3368883/how-does-this-size-of-array-template-function-work顯示一個模板原型的例子,其中定義實際上並不需要在這一天,鏈接器不會抱怨。 – QuentinUK 2016-02-28 11:22:53