免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: OwnWaterloo

[C++] 名字空间、重载候选与lambda。。。 这是g++的bug吗。。。 [复制链接]

论坛徽章:
4
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:11
发表于 2016-01-05 17:42 |显示全部楼层
@OwnWaterloo太过分了,下次发帖的时候上微信跟我说一声啊,这问题我知道。

首先,我没看标准,所以这是不是bug我不知道,但是,从实现的角度上来说,按照旧的标准解释,这个行为是合理的。

为什么呢?这就需要看闭包到底是什么了。闭包是一个对象,确切的说,是一个函数对象(Functor),也就是说,闭包实际上是一个匿名的,实现了operator()的一个struct的一个实例而已,问题就在于这个实例是在哪儿声明的。

你using 了::ns::f,那么这两个函数都参与了重载,这个OK,然后,你调用了::ns::f([]{}),那么,ns::f这个模版关于这个匿名类的对应实例被特化出来了,然后调用了f(0),则int ::f(int)被特化出来了。现在问题是第三个调用了。

假设C++11对目前的ADL规则没有打补丁,那么,如果存在int ::f(main()::lambda());这样一个函数,那么它显然会参与重载决策,而::ns::f又被特化出来了,那必然会导致重载失败。

现在问题就成了“当我通过使用的方式特化某个函数时,编译器有没有权力自行特化其他函数”,貌似这个权力是有的(吧?)

这里的问题在于,首先lambda是函数对象,其次这个对象声明在main()作用域,然后就算using了::ns::f,f仍然在作用域,如果曾经特化过f的某个版本,而根据ADT肯定能找到::f(::f是main()的上层),那么重载失败就是可能的。

论坛徽章:
4
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:11
发表于 2016-01-05 17:44 |显示全部楼层
本帖最后由 starwing83 于 2016-01-05 17:44 编辑

可能都不需要ADL了,根本两个都是可见的,只要针对main()::lambda()类型的f被特化,就肯定会出现这个错儿,你自己试一下在clang里面手动特化某个模版看看还能不能编译过。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2016-01-15 22:18 |显示全部楼层
本帖最后由 OwnWaterloo 于 2016-01-15 22:18 编辑

回复 20# starwing83

@ 你是因为fender0107401提到lua
我怎么知道你这个纯C控还会继续研究C++

你的意思是说。。。

  1. f([]{})
复制代码

  1. struct X {} x;
  2. f(x);
复制代码
是类似的问题? 就看标准对x应该出现在哪是怎么定义的?

  1. template<typename T> int f(T const&) { return 0; }
  2. namespace ns {
  3. template<typename T> int f(T const&) { return 1; } }

  4. #ifdef X1
  5. struct X {} x;
  6. #endif
  7. int main()
  8. {
  9. #ifdef X2
  10. struct X {} x;
  11. #endif
  12.       using ::ns::f;
  13. #ifdef X3
  14. struct X {} x;
  15. #endif
  16.       f(x);
  17. }
复制代码
clang, X1是歧义, X2和X3可以。
g++。。。 3处都是歧义。。。
怎么看怎么都是g++的(又一个)bug。。。

论坛徽章:
0
发表于 2016-01-18 14:32 |显示全部楼层
从来不用use namespace xxx;
这玩意容易引起歧义,编译器受不了,你更受不了。

论坛徽章:
4
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:11
发表于 2016-01-21 13:13 |显示全部楼层
回复 22# OwnWaterloo


    虽然我是纯C控,但是作为世界上最复杂的编程语言,我就算不用,也得研究研究更新一下知识库嘛。

嗯,本质上是一类问题。我不知道对于模版的实例化有没有什么标准的规定,我建议你查一下(关于模版何时可以实例化的问题)。而且,函数模版在没有实例化的时候是否参与ADL也有关系的,万一是个Unspecified啥的估计就不是Bug了。

你只需要把lambda当作匿名结构体处理就OK了,这里跟lambda关系不大,主要还是函数模版实例化和函数重载选择的问题。

论坛徽章:
6
数据库技术版块每日发帖之星
日期:2015-11-27 06:20:00程序设计版块每日发帖之星
日期:2015-12-01 06:20:00每日论坛发贴之星
日期:2015-12-01 06:20:0015-16赛季CBA联赛之佛山
日期:2017-03-26 23:38:0315-16赛季CBA联赛之江苏
日期:2017-07-17 10:08:4415-16赛季CBA联赛之北京
日期:2018-03-04 17:01:50
发表于 2016-01-22 17:56 |显示全部楼层
这个史大温
不错呀!
比这个瓦特路
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。




----------------------------------------

大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP