模板显示实例化有什么好处?

xxc19812 2012-03-31 10:27:44
既然模板在在实际被使用的时候, 可以隐式实例化, 那手工的显示实例化有什么好处呢?



template<typename T> T add(T a, T b)
{
return a+b;
}

template int add<int>(int a, int b); //这一句有什么好处吗?


int _tmain(int argc, _TCHAR* argv[])
{
int c= add(5,6);
return 0;
}

求真相!
...全文
1389 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
方紫涵 2014-02-24
  • 打赏
  • 举报
回复
引用 15 楼 adlay 的回复:
是只有用到的时候才会实例化, 但是你在多个 cpp 中用了多次的时候就会在每一个用到的 cpp 中实例化一次, 每个 cpp 实例化出来的都编译到对应的 obj 中去了. 把多个 obj 链接成 exe 后 exe 中就会有多次了.
编译器会不会优化掉重复的code bloat?
snake_xiongyang 2013-07-09
  • 打赏
  • 举报
回复
引用 20 楼 xxc19812 的回复:
刚才打错了, 我是问 "如果在一个.h文件里面分开写了, 又会怎么样呢? 会只实例化一次吗?" 比如: template<typename T> T add(T a, T b); template<typename T> T add(T a, T b) { return a+b; } template int add<int>(int a, int b);
按照我的理解 每包含一次这个头文件,会以int为参数实例化一次 vs2008 链接器会报告多重定义,并表示会忽略掉除去第一次实例化的后续定义 今天写一个类的模板方法遇到重定义的警告。靠extern+显示实例化到cpp文件中解决了这个警告
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
刚才打错了, 我是问 "如果在一个.h文件里面分开写了, 又会怎么样呢? 会只实例化一次吗?"

比如:

template<typename T> T add(T a, T b);

template<typename T> T add(T a, T b)
{
return a+b;
}

template int add<int>(int a, int b);
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
我对c++不了解, 原来每个cpp都会有一个obj啊. 明白了.
adlay 真是牛人啊, 对原理了解的这么透彻.

如果在一个一个.h文件里面分开写了, 又会怎么样呢? 会只实例化一次吗?

比如:

template<typename T> T add(T a, T b);

template<typename T> T add(T a, T b)
{
return a+b;
}

template int add<int>(int a, int b);



www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
你的一个工程只有一个 obj 啊?? 恐怕只有学习那些的工程才会这么小吧. 实际的工程很少会有一个 cpp 的情况吧.如果只有一个 cpp 文件, 就只会实例化一次了.

要把实现单独写到一个 cpp 文件中才能让多个 cpp 引用也只实例化一次.
显示实例化只是让你能够分开写, 如果没有分开写还是把实现内联到里面的话一样会实例化多次.
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
此外, 如果虽然申明和定义写在一起, 但还是显示的实例化了, 是不是也可以避免你说的多次实例化问题?
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
回复:adlay

你说的是在多个工程中引用同一个模板的情况把. 如果只用一个工程, 是不是只有一个obj, 就不会实例化多次了?
www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
是只有用到的时候才会实例化, 但是你在多个 cpp 中用了多次的时候就会在每一个用到的 cpp 中实例化一次, 每个 cpp 实例化出来的都编译到对应的 obj 中去了. 把多个 obj 链接成 exe 后 exe 中就会有多次了.
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
回复:adlay

即使写在一起, 应当也是在用到的时候才会隐式实例化吧? 怎么会生成的 exe 里会有重复的函数实现代码.
比如我只用到了add<int> 那应当不会自动生产add<double>的吧, 看说明里面说, 用到的时候才实例化, 而且一样类型的只会实例化一次.
www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

回复:adlay

就是说如果模板的申明和定义分离的情况下.
我用到的每个模板实例, 都必须显示实例化, 而不能隐式实例化了吗?
那这个好像挺麻烦的. 不够智能啊.
[/Quote]

是的.
很麻烦的.
所以模版通常都是把实现和声明写在一起的. 但是这样虽然方便, 会影响编译速度. 而且生成的 exe 里会有重复的函数实现代码.
www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
特化的语法应该是:
template<> int add<int>(int a, int b);
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
回复:adlay

就是说如果模板的申明和定义分离的情况下.
我用到的每个模板实例, 都必须显示实例化, 而不能隐式实例化了吗?
那这个好像挺麻烦的. 不够智能啊.
酱油党 2012-03-31
  • 打赏
  • 举报
回复
感觉问题是特化的好处,编译器完全不会有类型推导的过程…
www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

引用 4 楼 的回复:

通过显示实例化你可以把模版的实现放在 cpp 里, 要不然的话模版实现必须放在 .h 里面.


好像不显示实例化, 我把模板放在main.cpp里面也没报错啊, 比如你把刚才我那句注释掉, 也可以运行的.
[/Quote]

你是只有一个 cpp 的情况. 如果有多个 cpp 文件再使用这个模版, 你必须把它放在头文件里, 然后每个 cpp 都要 #include 这个头文件. 显示实例化之后头文件里只需要声明, 然后在其中一个 cpp 里面实现并显示实例化, 其它的 cpp 就可以直接用了.
具体可以 google 一下 "模版声明实现分离"
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
回复: maguiwa
那总归还是有一次类型替换与编译过程啊. 好像也没优化什么.
酱油党 2012-03-31
  • 打赏
  • 举报
回复
应该是当模板类型是int时会,调用会直接调用template int add<int>(int a, int b);
避免类型替换与编译过程,增强性能。
注:为猜测,没实验,坐等大牛 + 标记
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

通过显示实例化你可以把模版的实现放在 cpp 里, 要不然的话模版实现必须放在 .h 里面.
[/Quote]

好像不显示实例化, 我把模板放在main.cpp里面也没报错啊, 比如你把刚才我那句注释掉, 也可以运行的.
xxc19812 2012-03-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

我觉得你那个 感觉就是特殊化啊。
显示实例化 应该是
int c= add<int>(5,6);
[/Quote]

你这个应当是隐式实例化.
www_adintr_com 2012-03-31
  • 打赏
  • 举报
回复
通过显示实例化你可以把模版的实现放在 cpp 里, 要不然的话模版实现必须放在 .h 里面.
大海啊全是水 2012-03-31
  • 打赏
  • 举报
回复
我觉得你那个 感觉就是特殊化啊。
显示实例化 应该是
int c= add<int>(5,6);
加载更多回复(2)

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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