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

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;
}

求真相!
...全文
982 22 打赏 收藏 举报
写回复
22 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
方紫涵 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 里面.
  • 打赏
  • 举报
回复
我觉得你那个 感觉就是特殊化啊。
显示实例化 应该是
int c= add<int>(5,6);
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C++ 语言
加入

6.1w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2012-03-31 10:27
社区公告
暂无公告