C ++模板声明顺序

时间:2011-11-02 14:25:12

标签: c++ templates gcc

我正在尝试编译一个实例化的最小示例 模板类。该示例在某个订单时编译良好 声明保留,但不然。否则。

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中,所以编译器绝对不应该忘记它。 谢谢你的帮助。

2 个答案:

答案 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文件那么奇怪),但是你没必要。