首先。編譯器僅在實例化模板時生成代碼(在您的示例中,由於沒有實例化,因此不生成代碼)。其次,你傳遞一個類型模板參數。這裏編譯器將被允許安全地創建一個實例。 在你的例子中,你不會在某處使用這個類型,但是如果你願意,爲了定義一個函數,我的第一句話將再次適用,並且該函數只是在某個地方實例化時生成的。 就在這時,編譯器必須具備所有知識才能生成代碼。
// Example program
#include <iostream>
template <typename T> struct Template
{
void someFunc(); //defined in the .cpp file
};
class A;
Template<A> foo;
但是,如果您創建了一個採用非類型參數的模板。如您所擔心的那樣,它會失敗,因爲類型定義不完整。
// Example program
#include <iostream>
#include <string>
class A;
template <A parm> struct Template
{
void someFunc() {
parm.foo();
}
};
A a;
using foo = Template<a>;
這個例子也是一樣的。在這裏,您將創建一個對象a
,當然編譯器需要更多地瞭解類型。這就是它失敗的原因。
// Example program
#include <iostream>
template <typename T> struct Template
{
T a;
};
class A;
Template<A> foo;
希望這會有所幫助。
只是不要分割模板並將其全部定義在頭文件中。 – NathanOliver
沒有使用'A',要求它在這裏完整,所以沒有問題。 – Quentin
@Quentin:謝謝你的回答。如果此代碼是庫的一部分,那麼模板 :: someFunc()符號將在lib中導出,並且在定義A時不會導致未解析的外部錯誤? – Michel