显式实例化和显式具体化

q8515620 2013-08-22 04:17:12
大家好~!!
我在看 C++ Primer Plus ,作者在介绍函数模板的显式实例化和显式具体化的时候,有下面这样的一句话:


对句话不太理解,是不是不能像下面这样做?
template<typename T> //template
void foo(T t)
{
cout << t << endl;
return;
}

template void foo<double>(double); //Instantiation

template <> void foo<double>(double d) //Specialization
{
cout << "this is " << d << endl;
}

int main(int argv, char **argc)
{
foo(1.0);
return 0;
}

上面的g++和VS都报错了:
g++:error: specialization of 'void foo(T) [with T = double]' after instantiation
VS:error C2908: 显式专用化;已实例化“void foo<double>(double)”

按照g++的意思,难到instantiation放到specialization前面就可以了吗?

template<typename T> //template
void foo(T t)
{
cout << t << endl;
return;
}

template <> void foo<double>(double d) //Specialization
{
cout << "this is " << d << endl;
}

template void foo<double>(double); //Instantiation

int main(int argv, char **argc)
{
foo(1.0);
return 0;
}

结果,g++确实不报错了,也没有警告,而VS依然报错:
error C3416: “foo”: 显式专用化可能无法显式实例化

我想,那句话就是这个意思。而g++不报错,是不是因为模板函数在匹配类型的时候,具体化是优先于常规模板的,编译到Specialization的时候,找到匹配的了,然后就把Instantiation优化掉了??不作处理了??而且VS的错误信息有“可能”二字。。。

这只是我的胡乱猜想,请大家多多指教! 谢谢!!

...全文
763 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
q8515620 2013-08-23
  • 打赏
  • 举报
回复
引用 7 楼 ri_aje 的回复:
你要是看不懂 #1 的解释,那我也帮不上忙了。
嗯!谢谢你,我慢慢消化一下. 另外,你能不能帮我解释一下#5说的"隐式特例化"? 我google过找不到这东西. 隐式具体化,implicit specialization什么的,都没有找到.
ri_aje 2013-08-23
  • 打赏
  • 举报
回复
引用 3 楼 q8515620 的回复:
主楼上面的2段代码应该都是错的才对,我就是不懂为什么第二段g++没Error
你要是看不懂 #1 的解释,那我也帮不上忙了。
q8515620 2013-08-23
  • 打赏
  • 举报
回复
引用 5 楼 supermegaboy 的回复:
这个不叫显式实例化,叫显式模板实参,就是不需要编译器进行模板实参推演,由客户直接提供模板实参,提供显式模板实参会产生隐式实例化,同时也是隐式特例化。
隐式特例化? 请问有这个概念吗? 怎么特例的? 并没有另外定义函数体啊?!
飞天御剑流 2013-08-22
  • 打赏
  • 举报
回复
引用 4 楼 q8515620 的回复:
还有一个疑问:这种也是“显式实例化”吗?它是在哪个位置生成了实例呢?
这个不叫显式实例化,叫显式模板实参,就是不需要编译器进行模板实参推演,由客户直接提供模板实参,提供显式模板实参会产生隐式实例化,同时也是隐式特例化。
q8515620 2013-08-22
  • 打赏
  • 举报
回复


还有一个疑问:这种也是“显式实例化”吗?它是在哪个位置生成了实例呢?
q8515620 2013-08-22
  • 打赏
  • 举报
回复
主楼上面的2段代码应该都是错的才对,我就是不懂为什么第二段g++没Error
q8515620 2013-08-22
  • 打赏
  • 举报
回复
引用 1 楼 ri_aje 的回复:
最好能把你的编译器版本和编译选项说清楚,因为新旧标准在这个问题上处理的不一样。
mingw32-g++ (tdm-1) 4.7.1 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 我用的是CodeBlocks 编译选项是默认的: mingw32-g++.exe -Wall -fexceptions -g 至于VS是2012版的(Update1~3都没更新)
ri_aje 2013-08-22
  • 打赏
  • 举报
回复
最好能把你的编译器版本和编译选项说清楚,因为新旧标准在这个问题上处理的不一样。 c++03 14.7/5 说: No program shall explicitly instantiate any template more than once, both explicitly instantiate and explicitly specialize a template, or specialize a template more than once for a given set of template-arguments. An implementation is not required to diagnose a violation of this rule. 根据这个说法,主楼的两种写法都是错误的,目测你 VS 的编译器执行的是旧标准。 c++11 14.7/5 说: For a given template and a given set of template-arguments, — an explicit instantiation definition shall appear at most once in a program, — an explicit specialization shall be defined at most once in a program (according to 3.2), and — both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization. An implementation is not required to diagnose a violation of this rule. 根据这种定义,主楼第一种写法不满足第三条 unless 给出的条件,所以是错误;但是第二种写法则能够满足,所以编译无误,目测你的 g++ 编译器是按照新标准解释的。 另外,在 explicit specialization 和 explicit instantiation 同时存在的情况下,后者没有作用。

65,198

社区成员

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

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