繁体   English   中英

C ++模板声明顺序

[英]C++ Templates Declaration Order

我正在尝试编译一个实例化模板类的最小示例。 当保留声明的特定顺序时,该示例编译良好,但否则失败。

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的内容。

当我使用非模板类时,在main.cpp中仅包含.h文件可以很好地工作-这里出了什么问题? 注意,temp.cpp包含在我的Makefile中,因此编译器绝对不应忘记它。 谢谢你的帮助。

请参阅C ++ FAQ Lite条目[35.12]为什么不能将模板类的定义与其声明分开,然后将其放入.cpp文件中?

sayHi()方法的定义(aka主体)必须在temp.h标头中,或在另一个包含的文件中; 实例化test<true>时需要完整的代码。

对于模板,声明和定义都必须在同一文件中。 您可以通过将所有代码放在一个文件中(并使函数定义内联或不内联,由您自己决定),或将声明和定义分开,但将定义文件包括在.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文件更奇怪),但是您却不这样做。不必。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM