老沫白 发表于 2023-5-28 14:48:35

函数模板实例化中的类型匹配

template<typename T> string func(const T &t);
string s("hi");
const string *ps = &s;
func(ps);//(const string *&)
func(&s);//(const string *&)为何如此实例,看第二段。      鱼油们。对于第一个调用《C++ primer》上说是将func实例化为func( const string *&),T绑定到string*,我开始觉得应该是func(const string const*&),毕竟引用是底层const的,传给他一个非顶层const的指针应该转换为顶层const,但毕竟没有双重const{:5_104:},所以它这么实例化的话引用的底层const,指针的顶层const没有了啊,还有个人认为T应该绑定到const string *。

      至于第二个调用,实例化为func(const string*&),文字部分却又说的确进行了指针的由非顶层const到顶层const的转化,也就是说"const string*&"要这样看"const(string*)&。这样解释的话对于第一个调用的顶层const没有的问题我没有了,但"const(string*)&"ps的底层const没有了啊!

学习编程中的Ben 发表于 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:49:25

第一个调用实例化为func(const string *&t),引用是底层const的,传递参数是一个指向非常量string对象的指针,因此没有顶层const。

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

歌者文明清理员 发表于 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引用。

学习编程中的Ben 发表于 2023-5-28 14:50:33

求给个最佳答案

歌者文明清理员 发表于 2023-5-28 22:30:23

学习编程中的Ben 发表于 2023-5-28 14:50
求给个最佳答案

{:10_266:}

老沫白 发表于 2023-6-1 10:28:27

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

忽略什么啊忽略,没忽略,输错了,歌兄你到底知不知道啊,不知道就别回答了{:5_107:}

老沫白 发表于 2023-6-1 10:28:47

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

书是错的

老沫白 发表于 2023-6-1 10:29:26

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

有指针的顶层const,大哥
页: [1]
查看完整版本: 函数模板实例化中的类型匹配