免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2922 | 回复: 6

[C++] 隐式类型转换失败, 帮我看看是什么错误 [复制链接]

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
发表于 2016-06-29 09:36 |显示全部楼层
我自己写了一小段代码:

  1. #include<type_traits>
  2. using namespace std;
  3. template<typename T>
  4. struct M{
  5.     /*explicit*/ M(const T*){}
  6. };
  7. template<typename T>
  8. M<T> f(const M<T>&){return M<T>();}

  9. int main()
  10. {
  11.     M<char> s1=f<char>("Hello");//OK
  12.     M<char> s2=f("Hello");//error
  13.     M<char> s3=f(decay<char*>("Hello"));//error
  14.     return 0;
  15. }
复制代码
在main函数里面,只有s1这个构造是OK的(当然如果M里面加上了explicit关键字的话,也不行), 通过隐式类型转换构造成功。
但是后面两个s2/s3,当我使用模板函数f而没有显示指定模板实例化类型的时候,两个都编译不过,我尝试了decay<char*>也不行。

这是为什么呢,背后的机理是?
谢谢

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2016-06-29 09:53 |显示全部楼层
编译器怎么知道如何从"hello" deduce出const M<T>&,这两个东西的类型根本不匹配嘛。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
发表于 2016-06-29 11:08 |显示全部楼层
windoze 发表于 2016-06-29 09:53
编译器怎么知道如何从"hello" deduce出const M&,这两个东西的类型根本不匹配嘛。


不太明白大侠的这句话,模板形参T既然可以匹配任意类型,那么hello无论是char [6]还是char*,是不是都会有机会去匹配一次。
那么找你说的,什么样的类型才能匹配?

我把main函数改成了下面这样:

  1. int main()
  2. {
  3.     M<char> s1=f<char>("Hello");//OK
  4.     const char* p="hello";
  5.     M<char> s2=f(p);//error
  6.     M<char> s3=f(decay<const char*>("Hello"));//error
  7.     return 0;
  8. }
复制代码
s2还是不能通过编译。我想现在f的参数是const char*, 可以匹配M的构造函数了吧?
很奇怪,s1可以编译成功,s2还是不行。具体的区别到底在哪里?

论坛徽章:
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
发表于 2016-06-29 11:11 |显示全部楼层
假如不是个模板,那么在类型a和类型b之间的隐式转换或隐式构造就几种,每个尝试一下是可行的
但如果是个模板,那么就是要找一个类型a和一个百搭类型之间的隐式转换或隐式构造,这可能性太野了,工作量太大,而且匹配出的路径就是用户期望的可能性太低。所以,模板是不会去

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2016-06-29 11:57 |显示全部楼层
本帖最后由 windoze 于 2016-06-29 11:59 编辑

回复 3# cdsfiui

看你的代码

  1. template<typename T> M<T> f(const M<T>&)
复制代码
这里编译器首先要deduce,需要从给它的参数类型反推出模板里未定的类型
你给它了一个(const char)[6]&,你自己看看它怎么match声明里的M<T> const&  (把const写在后面你看得清楚一点)
在这里你必须给它一个const M<xxx>&编译器才能正确的match,match到了才能选择正确的转型/构造之类的操作。

如果这一步的match不成功,那么<typename T>就是一个non-deducible context,编译器不会尝试自动匹配,你必须手工标明T的类型,就像第一行编译通过的那个。

@bruceteen

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
发表于 2016-06-29 13:32 |显示全部楼层
windoze 发表于 2016-06-29 11:57
回复 3# cdsfiui

看你的代码这里编译器首先要deduce,需要从给它的参数类型反推出模板里未定的类型


你的意识是说,对于需要deduce的场景,编译器先要做模式匹配,然后再做重载解析,最后是隐式类型转换?
是这样的顺序吗?

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
发表于 2016-06-29 14:12 |显示全部楼层
回复 6# cdsfiui

当然是啦,要不然还能怎么办,总不能把所有M*N种可能性统统试一遍。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP