问题来自于c++ primer 5th的练习16.49
template<typename T> void g(T);
template<typename T> void g(T*);
int i = 42, *p = &i;
g(p); //调用的哪个版本?
上述问题有两个候选函数, 都为精确匹配, 个人理解的答案是此调用有歧义.
实际编译器选择的是第二个实例void g<int>(int*)
, 请问为什么? 结果没有歧义的话, 只能说明选用的是更特例化的版本, 但是第二个实例哪里比第一个实例更特例化了?
void g<int*>(int*);
void g<int>(int*);
更特例化指的是形参类型更接近于实参类型吗?
C++ 标准有一章讲模板函数重载时怎么排序:
temp.func.order
问题里是比较简单的情况,可以用两个模板版函数互相推导来判断。如果一个成功、一个失败,那么就可以确定谁更特化了。
具体就是
对于
template<typename T> void g(T);
,生成一个虚拟函数调用g(class foo);
,然后推导template<typename T> void g(T*)
中的 T ,失败;对于
template<typename T> void g(T*);
,生成一个虚拟函数调用g(class bar*);
,然后推导template<typename T> void g(T)
中的 T ,成功(T=class bar*
);于是认为,
template<typename T> void g(T*)
更特化。通俗一点讲,就是能使用
template<typename T> void g(T*)
的函数调用,都可以使用template<typename T> void g(T)
; 但是反过来就不行。于是template<typename T> void g(T*)
更特化。