C++-C++ 函数模版实例化疑问
//本人C++初学者..自学啃书中,如题目太过于简单,望各位大神见谅。
//以下函数模版
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
inline T const& max(T const& a, T const& b)//传入引用比较 ,命名为 模版1
{
cout << "inline T const & max(T const& a, T const& b)" <<endl;
return a < b ? b : a;
}
template <typename T>
inline const T* & max(const T* &a , const T* &b)//传入某一类指向常量的指针,解引用比较 命名为 模版2
{
cout << "inline T* const& max(T* const& a , T* const& b)" <<endl;
return *a < *b ? b : a;
}
//以下是函数调用
void Chapter_1::play_1() const
{
int a = 7;
int b = 42;
int *p = &a;
int *p1 = &b;
cout << "最大值为:"<<*::max(p,p1)<<endl;
}
//出来的结果是调用引用类型形参的模版(模版1),而并非使用指向常量的指针类型的模版(模版2)
//但是如果我改为指向非常量的常量指针为形参时,是可以调用到的,如下模版3
template <typename T>
inline T* const & max(T* const& a , T* const& b)//传入某一类常量指针,解引用比较,命名为 模版3
//再 调用函数中把 p 和p1的指针声明为一个指向常量的指针时(const int *p ,const int *p1),也是可以调到指向常量的指针类型形参的模版(模版2)的。
//现在我的问题就是 1:当传入一个指向非常量的非常量指针时,模版2为什么不能匹配,而选择了引用的模版?
//我个人想法是,这么理解:int *p 和 const int *p 是不同类型的需要经过const强转类型才可以匹配,但是模版函数是不能
//做隐式转换的,所以模版不符合 int *p 的类型。最后模版1的形参为引用类型的,指针为一种特殊的引用所以符合条件,
//所以实例化了模版1,至于模版1中引用形参修饰符 const 仅仅是做只读理解,而不是一种类型限定?
//望各位能大神解一下惑!
//接下来注意看模版4
template <typename T>
inline T* const max(T* const a , T* const b)//传入某一类常量指针,解引用比较,命名为 模版4
//调用 效果与模版3一样,但是仔细观察发现模版3和模版4差别在于传递参数类型不一样,模版3为传递了一个 T* const&
//模版4为 一个T* const 。
//问题2:这是不是说明了引用是一种特殊的指针?
//我的理由是:因为从语法来讲 int* (&p3) = p1;完全是合理的,那么对p3的操作正如对p1的操作。
//
//模版5
template <typename T>
inline T* const max(T* a , T* b)//传入某一类指针,命名为 模版5
//问题3:因为语法上 模版5和模版4是一致,所以同时存在这两个函数模版时是编译不过的?是不是这个理由
//第一次发帖有点乱,望谅解。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
其实都是一个问题,函数模板的参数推断(C.13.4)和重载解析(13.3.2),
这个在TCPL中有答案,章节已经标记在括号。
不过你把两个方面混在一起,问题复杂化了。
简单的说,你记住几个原则,一是参数推断不进行类型转换,模板参数的类型是根据实参类型唯一确定。二是函数模板不直接进行重载解析,而是特化(完成参数推断)后与函数一起进行解析。
大体上优先级从低到高为:一般函数模板,更特化的函数模板,函数。
问题1中,实参一般认为int,其实完整的应该是int const&,也可以认为是int* const, 函数模板T const不能推断,T const&能推断出, T=int,
问题2中,T * const, 可以推断T=int。
最后那个问题不是不能同时存在,而是实例化时,无法重载解析:
因为类型T const&, T*a,特化程度一样,特化结果都可以满足调用,重载时有两个的函数模板特化结果,认为是错误。