免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3491 | 回复: 5
打印 上一主题 下一主题

[C++] 关于 inside the c++ object model 7.1 [复制链接]

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-09 09:47 |只看该作者 |倒序浏览
30可用积分
偶然间看到 inside the c++ object model 7.1
参见 http://www.blogbus.com/fxl-logs/3600446.html
说是 scope of the template definiton 和 scope of the template instantiation 有区别
我写段代码
  1. extern double foo(double); // 1)

  2. template<class type>
  3. class ScopeRules
  4. {
  5. public:
  6.     void invariant() {
  7.         _member = foo(_val);
  8.     }
  9.     type type_dependent(){
  10.         return foo(_member);
  11.     }
  12. private:
  13.     int _val;
  14.     type _member;
  15. };

  16. int main()
  17. {
  18.     extern int foo(int); //2)

  19.     ScopeRules<int> sr0;
  20.     sr0.invariant();
  21.     sr0.type_dependent();

  22.     return 0;
  23. }

  24. #include <iostream>
  25. using namespace std;

  26. double foo(double)
  27. {
  28.     cout << "double" << endl;
  29.     return 1.2;
  30. }
  31. int foo(int)
  32. {
  33.     cout << "int" << endl;
  34.     return 3;
  35. }
复制代码
在VC++9.0上测试,发现都调用的是int foo(int)。这个虽然不对,但我明白是怎么回事。(因为VC++当初使用了一个自以为聪明的手段,后来才发现这个手段有些根本性的bug无法解决,但一直没有痛下决心去重写。)

在MinGW4.8.1上,发现都调用的是double foo(double)。这个结果和《inside the c++ object model 7.1》讲的不符合呀,怎么回事?

当然,我也看到有人挺G++,说若《inside the c++ object model 7.1》正确,则会导致
  1. ScopeRules<int> a;

  2. extern int foo(int);
  3. ScopeRules<int> b;
复制代码
中 a 和 b 为两个不同的类型,因为它们的成员函数 type type_dependent() 不同。

请问,这属于g++的bug,还是《inside the c++ object model 7.1》说的本身就不对?也有可能是我理解错了?

最佳答案

查看完整内容

Inside The C++ Object Model这本书在1996年就写成了,而那时还没有正式的C++规范出现。模板这块内容在标准化过程中变化是非常大的。参与“C++ Templates"这本书的9.5章后记中有如下记载:“非依赖型名称和9.4.2小节讨论的依赖型基类“的名称查找规则是C++标准委员会在1993年引入的。Bjarne Stroustrup在1994年初出版的[StroustrupDnE]首次给出了这些内容。而惠普wcngd1997年初才把它引入C++编译器。”,根据以上内容推断Inside The ...

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
2 [报告]
发表于 2013-11-09 09:47 |只看该作者
Inside The C++ Object Model这本书在1996年就写成了,而那时还没有正式的C++规范出现。模板这块内容在标准化过程中变化是非常大的。参与“C++ Templates"这本书的9.5章后记中有如下记载:“非依赖型名称和9.4.2小节讨论的依赖型基类“的名称查找规则是C++标准委员会在1993年引入的。Bjarne Stroustrup在1994年初出版的[StroustrupDnE]首次给出了这些内容。而惠普wcngd1997年初才把它引入C++编译器。”,根据以上内容推断Inside The C++ Object Model关于你说的这个问题的描述应该是不准确的。书中至少没有准确描述涉及name lookup时的"Two Phase Lookup"问题。

"Two Phase Lookup"在第1阶段,当使用普通查找规则对模板进行解析时,就会查找非依赖型名称。另外,非受限的依赖型名称(诸如函数调用中的函数名称,之所以说它是依赖型,是因为该名称具有一个依赖型实参)也会在这个阶段进行查找。第2阶段发生在模板被实例化的时候,非受限的依赖型名称在此阶段也会再次执行ADL查找(基本类型int,double等没有关联的名字空间,因此不会发生ADL查找)。

楼主的例子的情况是典型的“依赖型非受限名称”问题,根据之前的描述以及C++标准中相关说明g++中的行为才是符合标准的

而C++2003标准对部分的规定有如下内容:

14.6.4.2 Candidate functions
For a function call that depends on a template parameter, if the function name is an unqualified-id but not a template-id, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:
For the part of the lookup using unqualified name lookup (3.4.1), only function declarations with external linkage from the template definition context are found.
— For the part of the lookup using associated namespaces (3.4.2), only function declarations with external linkage found in either the template definition context or the template instantiation context are found.

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
3 [报告]
发表于 2013-11-09 10:03 |只看该作者
收回
  1. 当然,我也看到有人挺G++,说若《inside the c++ object model 7.1》正确,则会导致
  2.     ScopeRules<int> a;
  3.     extern int foo(int);
  4.     ScopeRules<int> b;
  5. 中 a 和 b 为两个不同的类型,因为它们的成员函数 type type_dependent() 不同。
复制代码
这一段,因为
ScopeRules<int> a; 出现后,ScopeRules<int> 就已经确定了,其后的 extern int foo(int); 等等将不再会影响到 ScopeRules<int> 的实例化

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2013-11-09 17:03 |只看该作者
这个到底谁是正确的?

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
5 [报告]
发表于 2013-11-09 17:19 |只看该作者
回复 4# 群雄逐鹿中原


    VC++的不正确,历来有不遵守规范的恶名,而且默认启用为了方便但违反规定的语言扩展。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP