鱼C论坛

 找回密码
 立即注册
查看: 671|回复: 9

[已解决]函数模板实例化中的类型匹配

[复制链接]
发表于 2023-5-28 14:48:35 | 显示全部楼层 |阅读模式
10鱼币
  1. template<typename T> string func(const T &t);
  2. string s("hi");
  3. const string *ps = &s;
  4. func(ps);//(const string *&)
  5. func(&s);//(const string *&)为何如此实例,看第二段。
复制代码
       鱼油们。对于第一个调用《C++ primer》上说是将func实例化为func( const string *&),T绑定到string*,我开始觉得应该是func(const string const*&),毕竟引用是底层const的,传给他一个非顶层const的指针应该转换为顶层const,但毕竟没有双重const,所以它这么实例化的话引用的底层const,指针的顶层const没有了啊,还有个人认为T应该绑定到const string *。

        至于第二个调用,实例化为func(const string*&),文字部分却又说的确进行了指针的由非顶层const到顶层const的转化,也就是说"const string*&"要这样看"const(string*)&。这样解释的话对于第一个调用的顶层const没有的问题我没有了,但"const(string*)&"ps的底层const没有了啊!
最佳答案
2023-5-28 14:48:36
对于第一个调用,使用const string *&的原因是因为参数ps是一个指向常量string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要将该指针转换为一个指向常量的引用,以便模板函数可以使用该常量string对象。这样做也保留了指向常量的属性。

至于第二个调用,它实例化为func(const string *&)是因为&s返回的是一个指向非常量的string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要将该指针转换为一个常量指针引用,以便模板函数可以使用该常量string对象。因此,该指针具有顶层const属性。

对于顶层const和底层const的问题,您提到的是正确的,在第一个调用中,由于没有双重const,因此只有底层const被保留。在第二个调用中,由于存在双重const,因此顶层const和底层const被保留。

最佳答案

查看完整内容

对于第一个调用,使用const string *&的原因是因为参数ps是一个指向常量string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要将该指针转换为一个指向常量的引用,以便模板函数可以使用该常量string对象。这样做也保留了指向常量的属性。 至于第二个调用,它实例化为func(const string *&)是因为&s返回的是一个指向非常量的string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 14:48:36 | 显示全部楼层    本楼为最佳答案   
对于第一个调用,使用const string *&的原因是因为参数ps是一个指向常量string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要将该指针转换为一个指向常量的引用,以便模板函数可以使用该常量string对象。这样做也保留了指向常量的属性。

至于第二个调用,它实例化为func(const string *&)是因为&s返回的是一个指向非常量的string对象的指针,而不是指向常量的指针。因此,在调用模板函数时,编译器需要将该指针转换为一个常量指针引用,以便模板函数可以使用该常量string对象。因此,该指针具有顶层const属性。

对于顶层const和底层const的问题,您提到的是正确的,在第一个调用中,由于没有双重const,因此只有底层const被保留。在第二个调用中,由于存在双重const,因此顶层const和底层const被保留。

点评

欢迎加入【抢最佳】小组!  发表于 2023-5-28 14:50
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 14:49:25 | 显示全部楼层
第一个调用实例化为func(const string *&t),引用是底层const的,传递参数是一个指向非常量string对象的指针,因此没有顶层const。

对于第二个调用,实例化为func(const string *&t)。文字部分提到,“进行了指针的由非顶层const到顶层const的转化”,这是因为传递给函数的是一个指向非常量的string对象的地址,而编译器将其隐式转换为一个指向常量的string的指针。因此,t是一个指向常量的指针,它具有底层const属性。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 14:49:38 | 显示全部楼层
对于第一个调用func(ps),由于ps是一个const string *类型,所以使用const T &t模板参数,T被推导为const string *类型,进而将func实例化为string * const &func(const string *&)。这里的引用是底层const的,因为我们传入的是一个指向常量字符串对象的地址,所以被绑定的类型是该指针的顶层const属性被忽略了。

对于第二个调用func(&s),由于s是一个string对象,取它的地址得到的是一个const string *类型的指针。同样使用const T &t模板参数,T被推导为const string *类型,进而将func实例化为const string *&func(const string *&)。在这种情况下,我们的指针是一个非常量指针,但是在传递给func时,它会被转化为指向常量对象的指针,即底层const。因此,推导出来的模板参数为const string *,而函数参数类型为const string *&,其中的引用是指向指针的引用,即指针本身是引用类型,而且是底层const引用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 14:50:33 | 显示全部楼层
求给个最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-28 22:30:23 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-6-1 10:28:27 | 显示全部楼层
歌者文明清理员 发表于 2023-5-28 14:49
对于第一个调用func(ps),由于ps是一个const string *类型,所以使用const T &t模板参数,T被推导为const s ...

忽略什么啊忽略,没忽略,输错了,歌兄你到底知不知道啊,不知道就别回答了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-6-1 10:28:47 | 显示全部楼层
歌者文明清理员 发表于 2023-5-28 14:49
对于第一个调用func(ps),由于ps是一个const string *类型,所以使用const T &t模板参数,T被推导为const s ...

书是错的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-6-1 10:29:26 | 显示全部楼层
陶远航 发表于 2023-5-28 14:49
第一个调用实例化为func(const string *&t),引用是底层const的,传递参数是一个指向非常量string对象的指 ...

有指针的顶层const,大哥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 19:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表