当前位置: 技术问答>linux和unix
一个简单的C++编译问题
来源: 互联网 发布时间:2016-06-26
本文导语: //////////// test.h /////////////// #ifndef __TEST_H__ #define __TEST_H__ ...
//////////// test.h ///////////////
#ifndef __TEST_H__
#define __TEST_H__
template
class Test
{
public:
int a(const char *str);
};
#endif
//////////// test.cpp ///////////////
#include
#include "test.h"
template
int Test::a(const char *str)
{
printf("%sn", str);
return 0;
}
//////////// main.cpp ///////////////
#include
#include
#include "test.h"
int main(void)
{
Test t;
t.a("Cricket");
return 0;
}
//////////// Makefile ///////////////
CC = g++
SRC = main.cpp test.cpp
HEADER = test.h
EXEC = m.o
$(EXEC):$(SRC) $(HEADER)
$(CC) $(SRC) -o $(EXEC)
编译时出错:
# make
g++ main.cpp test.cpp -o m.o
/tmp/ccAvYTLK.o(.text+0x1d): In function `main':
: undefined reference to `Test::a(char const*)'
collect2: ld returned 1 exit status
make: *** [m.o] Error 1
要是不用模板类的话就没问题, 这个该怎么解决啊?
|
模板的分离编译为什么不行呢(而类的分离编译模型却可以)?
这是一个链接错误,它指出错误发生在main函数中(main.cpp文件中),引用`Test::a(char const*)'是未定义的。
分析:
在main.cpp这个编译单元中,当编译器看到t.a("Cricket")调用,知道了模板实参是int(因为前面创建t时已经给出T是int),于是产生一个到Test::a(char const*)的引用。当编译器处理到文件test.cpp时,由于这是另外一个编译单元,编译器不知道用什么实参来进行实例化以产生函数定义。因此就不可能有实例出来的Test::a(char const*)函数定义(在这个编译单元中你又没有指定int给T,是吧),到链接时,就立即指出引用`Test::a(char const*)'是未定义的。
这就是为什么模板的分离编译行不通。在test.h和test.cpp中的template之前均加一export就可以指出这些模板被导出,可以跨越多个编译单元,那当然就可以了。但C++标准的这种export template编译模型几乎就只是成了理论,在实践中很少有编译器支持export模板编译模型。
这是一个链接错误,它指出错误发生在main函数中(main.cpp文件中),引用`Test::a(char const*)'是未定义的。
分析:
在main.cpp这个编译单元中,当编译器看到t.a("Cricket")调用,知道了模板实参是int(因为前面创建t时已经给出T是int),于是产生一个到Test::a(char const*)的引用。当编译器处理到文件test.cpp时,由于这是另外一个编译单元,编译器不知道用什么实参来进行实例化以产生函数定义。因此就不可能有实例出来的Test::a(char const*)函数定义(在这个编译单元中你又没有指定int给T,是吧),到链接时,就立即指出引用`Test::a(char const*)'是未定义的。
这就是为什么模板的分离编译行不通。在test.h和test.cpp中的template之前均加一export就可以指出这些模板被导出,可以跨越多个编译单元,那当然就可以了。但C++标准的这种export template编译模型几乎就只是成了理论,在实践中很少有编译器支持export模板编译模型。
|
编译器暂时不支持模版的定义与实现分离,将test.cpp的东西也放在test.h中就好了
|
对于不支持模版编译的分离模式的编译器
乖乖把声明与定义放一块吧
也有其他方法 但是实质是一样的 就是让使用模版的代码处对模版定义可见
比如test.h 中include "test.cpp"
乖乖把声明与定义放一块吧
也有其他方法 但是实质是一样的 就是让使用模版的代码处对模版定义可见
比如test.h 中include "test.cpp"
|
楼主,首先不应该使用分离模板。声明跟定义都放在.h里即可。
可以看看export关键字。
可以看看export关键字。
|
分离需要export关键字,可惜的是你用的编译器不支持.
|
谢谢!我编译的结果如下:
g++ main.cpp test.cpp -o m.o
/tmp/ccE2ZzVl.o: In function `main':
main.cpp:(.text+0x20): undefined reference to `Test::a(char const*)'
collect2: ld 返回 1
make: *** [m.o] 错误 1
|
http://topic.csdn.net/t/20061221/22/5247963.html