我正在尝试编译一个实例化的最小示例 模板类。该示例在某个订单时编译良好 声明保留,但不然。否则。
temp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
temp.cpp:
#include "temp.h"
template <bool display>
void test<display>::sayHi () {
if (display) std::cout << "Hi";
}
main.cpp中:
#include <iostream>
#include "temp.h"
int main () {
test<true> myobject;
myobject.sayHi();
return 0;
}
这是如何包含类的标准。 在GCC 4.4.6中,这失败并出现错误 main.cpp :(。text + 0x3a):未定义引用`test :: sayHi()'
但是,当我在main.cpp中执行#include“temp.cpp”而不是#include“temp.h”时,该示例会编译 文件,以便编译器首先读取temp.h中的类声明 看到temp.cpp的内容,然后才看到main.cpp的内容。
当我使用非模板类时,它只能包含.h文件 在main.cpp中 - 这里出了什么问题?请注意,包含temp.cpp 在我的Makefile中,所以编译器绝对不应该忘记它。 谢谢你的帮助。
答案 0 :(得分:3)
请参阅C ++ FAQ Lite条目[35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?。
sayHi()
方法的定义(又称主体)必须在temp.h头文件中,或者在另一个包含文件中;实例化test<true>
时需要完整的代码。
答案 1 :(得分:1)
对于模板,声明和定义必须位于同一文件中。您可以通过将所有代码放在一个文件中(并使函数定义内联或不符合,取决于您),或者使声明和定义分离,但包括底部的定义文件来实现此目的。 .h文件。
所以它会是
tmp.h:
#include <iostream>
template <bool display>
class test {
public:
void sayHi();
};
#include "tmp.cpp"
和tmp.cpp和main.cpp保持不变(但是你没有给编译器编译tmp.cpp,因为它包含在tmp.h中)。
许多人将带有模板函数定义的文件命名为.template扩展名而不是.cpp扩展名(它让你知道它不能被编译,加上它看起来不像包含.cpp文件那么奇怪),但是你没必要。