C++模板必須是定義(給出了完整的函數體)在相同的翻譯單元(.cpp文件中加所有包含的頭文件)在哪裏使用。在你的頭文件中,你所做的全部是,聲明爲(給出了函數的名字和簽名)。其結果是,當你有base.h
,所有的編譯器看到的是:
class Base {
template <typename T> void test(T a);
}
此聲明,但沒有定義的功能。要定義它,你必須包含一個函數體:
class Base {
template <typename T> void test(T a)
{
// do something cool with a here
}
}
爲什麼這是必需的是,C++編譯器生成基於「按需」基礎模板代碼的原因。例如,如果您撥打:
Base obj;
obj.test<int>(1);
obj.test<char>('c');
編譯器將基於該Base::test
模板兩套機器代碼,一個用於int
和一個用於char
。此處的侷限性是Base::test
模板的定義必須位於相同的翻譯單元(.CPP文件)中,否則編譯器將不知道如何爲Base::test
函數的每個版本構建機器碼。編譯器一次只能在一個翻譯單元上運行,因此不知道您是否在其他某個CPP文件中定義了Base::test<T>
。它只能用它現有的東西來工作。
這與泛型在C#,Java和類似語言中的工作方式截然不同。就我個人而言,我喜歡將模板視爲文本宏,並由編譯器根據需要進行擴展。這迫使我記住,模板函數的完整主體需要包含在使用它的任何CPP文件中。
發佈更多代碼。你怎麼稱呼它?什麼是錯誤? – Nawaz
我沒有問題。模板函數是否在頭文件中聲明瞭_and_? – sje397
通常,閱讀編譯器錯誤消息可以提供有用的信息,幫助您瞭解問題所在。 – Hugh