模板问题之一:模板函数,把声明和定义都放在.h文件和分别放在.h文件和.cpp文件有什么区别啊?

flamingheart 2005-07-22 09:55:51
为什么我写了一个模板函数,把声明和定义分别放在.h文件和.cpp文件种,如果不调用这个函数的话,编译连接都能通过,但是如果调用这个函数的话,连接就有错误如下:

--------------------Configuration: IRSEG - Win32 Release--------------------
Compiling...
Location.cpp
Linking...
Location.obj : error LNK2001: unresolved external symbol "void __cdecl output_vector(class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct s
td::char_traits<char>,class std::allocator<char> > > > &)" (?output_vector@@YAXAAV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@@Z)
Release/IRSEG.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

IRSEG.exe - 2 error(s), 0 warning(s)


这个怎么回事?
...全文
1392 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
foochow 2005-09-17
  • 打赏
  • 举报
回复
你可以把声明和定义放一起,也可以显示的实例化...
shineryu 2005-09-17
  • 打赏
  • 举报
回复
C++ Primer 第三版 中文版
10.5 模板编译模式:
"C++支持两种模板编译模式包含模式Inclusion Model 和分离模式Separation Model"
10.5.1 包含编译模式
"在包含编译模式下我们在每个模板被实例化的文件中包含函数模板的定义并且往往把定义放在头文件中像对内联函数所做的那样"
10.5.2 分离编译模式
"在分离编译模式下函数模板的声明被放在头文件中"
"在模板定义中有一个关键字export"
"关键字export 告诉编译器在生成被其他文件使用的函数模板实例时可能需要这个模板定义编译器必须保证在生成这些实例时该模板定义是可见的"
"关键字export 不需要出现在头文件的模板声明中"
"分离模式使我们能够很好地将函数模板的接口同其实现分开进而组织好程序以便把函数模板的接口放到头文件中而把实现放在文本文件中但是并不是所有的编译器都支持分离模式即使支持也未必总能支持得很好支持分离模式需要更复杂的程序设计环境所以它们不能在所有C++编译器实现中提供"
"Inside the C++ Object Model 描述了一个C++编译器the Edison Design Group compiler支持的模板实例化机制"

很遗憾,目前VC的任何版本(visual studio 2005未知)皆不支持分离模式!
SammyLan 2005-09-03
  • 打赏
  • 举报
回复
只要是模板
声明和定义就要放在头文件里面
除非特化
VC不支持export关键字
过客猫2022 2005-09-03
  • 打赏
  • 举报
回复
模板类及函数,大部分的编译都要求放在头文件!
zxwl 2005-09-03
  • 打赏
  • 举报
回复
mark
playboxer 2005-07-28
  • 打赏
  • 举报
回复
要实例化一个函数模板就必须要知道这个函数模板的定义
JohnTitor 2005-07-28
  • 打赏
  • 举报
回复
temp.h:
void fun(T);

temp.cpp:
#include "temp.h"
void fun(T){}

main.cpp:
#include "temp.h"
void main()
{
int a;
fun(a);
}

由于main.cpp用到了fun(a),所以在编译main.cpp的时候,
编译器知道它要用int来实例化fun(T)中的T,也就是要实例化fun(int),而要实例化一个函数模板就必须要知道这个函数模板的定义,但是由于main.cpp和包含函数模板定义的temp.cpp是分开编译的,所以编译器在编译main.cpp的时候就不能够用int来实例化fun(T),这样编译器就只能够把
fun<int>(a)当成一个外部符号,交由linker来resolve。
另外编译器在编译temp.cpp的时候,同样因为temp.cpp和main.cpp是分开编译的,所以此时编译器并不知道main.cpp中用到了fun<int>(a),所以此时编译器虽然知道函数模板的定义,但也不会去实例化任何fun,当然就不会用int来实例化fun<T>了。
结果就是,你在main.obj引用了外部符号fun<int>,但是在temp.obj中不存在fun<int>,
所以linker就会报告无法解析的外部符号了
lxk_cool 2005-07-28
  • 打赏
  • 举报
回复
up!
luhanwenboy 2005-07-28
  • 打赏
  • 举报
回复
如果要把.h文件和.cpp文件分开,需要使用export关键字
请看<<C++ Primer>>
xzgyb 2005-07-22
  • 打赏
  • 举报
回复
大部分编译器在编译模板时都使用包含模式
也就是一般使用的把模板放到头文件中在包含

当你不使用这个模版函数或模版类
编译器并不实例化它
当你使用时,编译器需要实例化它,
因为编译器是一次只能处理一个编译单元
也就是一次处理一个cpp文件
所以实例化时需要看到该模板的完整定义
所以都放在头文件中


这不同于普通的函数,
在使用普通的函数时,编译时只需看到该函数的声明即可编译
而在链接时由链接器来确定该函数的实体


flamingheart 2005-07-22
  • 打赏
  • 举报
回复
为什么只能放在头文件中,谁能给解释一下原因?
Jagen在路上 2005-07-22
  • 打赏
  • 举报
回复
模板函数只能放在头文件中。
Jagen在路上 2005-07-22
  • 打赏
  • 举报
回复
模板函数只能放在头文件中。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧