g ++生成空对象文件

JT *_*ies 3 c++ compiler-construction linker g++ c++11

我试图将基本数组包装器模板类编译成.o文件,试图找出如何制作动态库.但是,在编译源代码时

g++ -std=c++0x -c array.cpp
Run Code Online (Sandbox Code Playgroud)

生成的文件只有~650字节.我用nm检查了文件,发现它包含的唯一符号是

00000001 r _ZStL13allocator_arg
00000000 r _ZStL19piecewise_construct
Run Code Online (Sandbox Code Playgroud)

这似乎是C++ 11编译的特性,因为在没有-std = c ++ 0x标志的情况下编译时它们就消失了.

尝试使用命令编译程序测试代码

g++ -std=c++0x -o tester tester.cpp array.cpp
Run Code Online (Sandbox Code Playgroud)

为array.cpp中的所有内容生成链接器错误,但否则会干净地编译.

老实说,我不知道这是怎么回事.如果您怀疑这是我的代码本身的问题,而不是我如何编译它,我可以发布array.cpp和array.hpp的内容.

Rob*_*edy 8

这很正常.模板仅在实例化时生成代码,而您尚未执行此操作.您只提供了模板.当编译器正在编译模板时,它没有理由生成模板的任何特定实例,并为模板参数填充实际类型.

稍后,编译器将编译其他源文件,您可以在其中使用模板类型.这也不会导致实例化.它只是告诉编译器它应该期望在别处找到模板的实例.编译器在对象文件中注明.然后链接器查找编译器应该找到的定义,但它失败了.

这就是为什么总是建议您在标题中提供与声明一致的模板定义.这样,当编译器看到您使用模板时,它可以使用它在标头中看到的定义立即实例化模板.如果您在多个源文件中使用该模板,您最终可能会多次实例化模板,但这是允许的,并且链接器知道如何处理它.

另一种方法是显式实例化array.cpp文件中的模板,但更简单地定义内联模板成员.