一个问题引发的一点思考

 
模板类、模板函数声明和定义都要放在一个文件中!!!!
"C++支持两种模板编译模式:包含模式Inclusion Model 和分离模式Separation Model "
包含编译模式
"在包含编译模式下我们在每个模板被实例化的文件中包含函数模板的定义并且往往把定义放在头文件中像对内联函数所做的那样 "
分离编译模式
"在分离编译模式下函数模板的声明被放在头文件中 " "在模板定义中有一个关键字export " "关键字export 告诉编译器在生成被其他文件使用的函数模板实例时可能需要这个模板定义编译器必须保证在生成这些实例时该模板定义是可见的 " "关键字export 不需要出现在头文件的模板声明中 "
"分离模式使我们能够很好地将函数模板的接口同其实现分开进而组织好程序以便把函数模板的接口放到头文件中而把实现放在文本文件中但是并不是所有的编译器都支持分离模式即使支持也未必总能支持得很好支持分离模式需要更复杂的程序设计环境所以它们不能在所有C++编译器实现中提供 "
以上是引用(C++ primer)的概念,

 
其实,VC到目前都不支持分离模式,gcc没试过,据说大多数编译器不支持。
当不使用模版函数或模版类,编译器并不实例化它,所以分离了也无所谓,不会有错误。但如果使用到了模板函数或者模板类,编译器就需要实例化它,这就需要找到定义,而声明和定义如果分开两个文件的话,编译器就找不到定义,无法进行实例化,(编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件。)只能交给连接器去处理。而编译器处理模板定义的文件时并不知道需要使用到,所以正常编译通过。这样就导致连接器找不到实例化的模板函数或者类,包凑提示外部符号。
比方说,声明了一个template<class T> void somefun(T t)在somefun.h中,定义在somefun.cpp中,main.cpp中包含了somefun.h并且主函数中用到了这个模板函数,int t = 0; somefun(t)。编译时,编译器需要用int来实例化一个模板函数即生成一个void somefun<int>(int t),但是定义不在main.cpp中,也不再somefun.h中,编译器无法实例化,交给连接器处理(编译器会觉得连接器能够找到);然后编译器会继续处理somefun.cpp,这时它不知道谁用到了这个模板函数所以不会实例化,编译顺利完成。但运行时主函数需要一个int型的模板函数,而连接器却找不到,只能报错说主函数中使用的这个int型的模板函数实例是外部符号,无法解析。
 
本来发生问题时我试过将定义放到头文件里去,OK了,但是就想着为啥不能分开,上网一顿搜索才知道为什么。这里就隐藏着一个问题,是一定要知其然更知其所以然还是一笔带过专注在自己本来的那个问题域里。没有什么答案啊。前者会让你的一个问题不断展开扩散到一堆问题,但是也可以收获很多;后者可以减少浪费的时间,在自己本来的问题域里前行。。。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值