高手指教关于函数特化和类模板偏特化的疑问

rovoboy 2010-03-03 12:02:38
如下代码,compare()是使用了类模板偏特化,结果在接受compare(x4, y4);调用时最后的堆栈如下:

> DataCreater.exe!comp_impl<double>::operator()(double lhs=10.000000000000000, double rhs=11.000000000000000) 行66 C++
DataCreater.exe!comp_impl<double *>::operator()(double * lhs=0x0022f8dc, double * rhs=0x0022f8cc) 行79 C++
DataCreater.exe!comp_impl<double * *>::operator()(double * * lhs=0x0022f8c0, double * * rhs=0x0022f8b4) 行79 C++
DataCreater.exe!compare<double * *>(double * * * lhs=0x0022f8a8, double * * * rhs=0x0022f89c) 行84 C++
DataCreater.exe!wmain(int argc=1, wchar_t * * argv=0x00664f70) 行114 + 0xd 字节 C++

可以看到函数调用被编译器“递归”处理掉了,将double*** 一直展开了3层,直到展开成为double,然后double和int operator()(T lhs, T rhs)匹配掉了。
而compare2()使用了函数模板和特化(我是这么理解的),但编译器只简单展开了一次,将double*** 处理成 double** 然后就调用template<typename T> int compare2(T lhs, T rhs) 去了,即double** 和template<typename T> int compare2(T lhs, T rhs)匹配掉了。堆栈如下

> DataCreater.exe!compare2<double * *>(double * * lhs=0x0040fcc4, double * * rhs=0x0040fcb8) 行86 C++
DataCreater.exe!compare2<double * *>(double * * * lhs=0x0040fcac, double * * * rhs=0x0040fca0) 行104 + 0x11 字节 C++
DataCreater.exe!wmain(int argc=1, wchar_t * * argv=0x00744f70) 行113 + 0xd 字节 C++

为什么看上去很类似的代码,编译器处理逻辑完全不同呢?或者是函数模板特化概念我的理解有问题,如果要使用函数方式实现第一种的功能,应该怎么写?请各位高手指教。



template<typename T>
struct comp_impl
{
int operator()(T lhs, T rhs) {
if(lhs==rhs)
return 0;
if(lhs>rhs)
return 1;
if(lhs<rhs)
return -1;
}
};
template<typename T>
struct comp_impl<T*>
{
int operator()(T* lhs, T* rhs) {
return comp_impl<T>()(*lhs, *rhs);
}
};

template<typename T> int compare(T* lhs, T* rhs) {
return comp_impl<T>()(*lhs, *rhs);
}

template<typename T> int compare2(T lhs, T rhs) {
if(lhs==rhs)
return 0;
if(lhs>rhs)
return 1;
if(lhs<rhs)
return -1;
}

template<typename T> int compare2(T* lhs, T* rhs) {
return compare2<T>(*lhs, *rhs);
}

int _tmain(int argc, _TCHAR* argv[])
{
double x1 = 10, y1 = 11;
double *x2 = &x1, *y2 = &y1;
double **x3 = &x2, **y3 = &y2;
double ***x4 = &x3, ***y4 = &y3;
compare(x4, y4);
compare2(x4, y4);
}
...全文
90 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
baihacker 2010-03-03
  • 打赏
  • 举报
回复
主函数中的compare2(x4, y4);会调用第二个模板,因为第二个要特殊一些。
在第二个中,return compare2<T>(*lhs, *rhs);会调用第一个模板,因为这里指定了T。
这个时候T = double**
compare2<double**>(*lhs, *rhs)也就是
compare2<double**>(double**, double**)所以只能调用第一个模板。
如果是
compare2(double**, double**)会继续调用第二个模板,因为第二个特殊。
直到
compare2(double, double)只能调用第一个模板为止。
baihacker 2010-03-03
  • 打赏
  • 举报
回复
template<typename T> int compare2(T lhs, T rhs) {
if(lhs==rhs)
return 0;
if(lhs>rhs)
return 1;
if(lhs<rhs)
return -1;
}

template<typename T> int compare2(T* lhs, T* rhs) {
return compare2(*lhs, *rhs);
}
cattycat 2010-03-03
  • 打赏
  • 举报
回复
up飞雪,说的很好了。
pengzhixi 2010-03-03
  • 打赏
  • 举报
回复
mark !

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧