如果我删除它(foo(T *)),代码仍然编译和正常工作,但是G v4.4.0(也可能是其他编译器)将生成两个foo()函数:一个用于char [4],一个用于炭[7].
#include <iostream> using namespace std; template< typename T > void foo( const T& ) { cout << "foo(const T&)" << endl; } template< typename T > void foo( T* ) { cout << "foo(T*)" << endl; } int main() { foo( "bar" ); foo( "foobar" ); return 0; }
解决方法
你的两个候选人之间唯一的区别是一个左派变革.字符串文字是转换为指针的数组.第一个候选人通过引用接受数组,因此不需要一个左值变换.第二个候选人需要一个左值变换.
因此,如果有两个候选人通过仅查看转换来同时实现模板专业化,那么规则就是通过对两者的部分排序来选择更专业的一个.
我们来比较两者,看看他们的功能参数列表的签名
void(T const&); void(T*);
如果我们为第一个参数列表选择一些唯一的类型Q,并尝试匹配第二个参数列表,则我们将Q与T *匹配.这将失败,因为Q不是一个指针.因此,第二个至少与第一个专门一样.
如果我们相反,我们将Q *与T const&引用被删除,高级限定符被忽略,剩余的T成为Q *.这是为了部分排序的目的的精确匹配,因此对第一候选者的变换参数列表的扣除成功.由于另一个方向(相对于第二个)没有成功,所以第二个候选人比第一个候选人更专业 – 因此,如果否则会有歧义,超负荷分解将更喜欢第二个.
在13.3.3.2/3:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if […]
- S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form
defined by 13.3.3.1.1,excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or,if not that […]
然后13.3.3 / 1
- let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and 13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.
Given these definitions,a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i,ICSi(F1) is not a worse conversion sequence than ICSi(F2),and then […]
- F1 and F2 are function template specializations,and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.5.2,or,if not that,[…]
最后,这里是13.3.3.1.1 / 3可能参与标准转换序列的隐式转换表.
Conversion sequences http://img259.imageshack.us/img259/851/convs.png