c – 从重载的模板函数中选择什么规则?
给定下面的代码,为什么选择foo(T *)函数?
如果我删除它(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; } 解决方法
正式地,当比较转换序列时,忽略左值变换.转换被分为几个类别,如资格调整(T * – > T const *),左值转换(int [N] – > int *,void() – > void(*)())和其他.
你的两个候选人之间唯一的区别是一个左派变革.字符串文字是转换为指针的数组.第一个候选人通过引用接受数组,因此不需要一个左值变换.第二个候选人需要一个左值变换. 因此,如果有两个候选人通过仅查看转换来同时实现模板专业化,那么规则就是通过对两者的部分排序来选择更专业的一个. 我们来比较两者,看看他们的功能参数列表的签名 void(T const&); void(T*); 如果我们为第一个参数列表选择一些唯一的类型Q,并尝试匹配第二个参数列表,则我们将Q与T *匹配.这将失败,因为Q不是一个指针.因此,第二个至少与第一个专门一样. 如果我们相反,我们将Q *与T const&引用被删除,高级限定符被忽略,剩余的T成为Q *.这是为了部分排序的目的的精确匹配,因此对第一候选者的变换参数列表的扣除成功.由于另一个方向(相对于第二个)没有成功,所以第二个候选人比第一个候选人更专业 – 因此,如果否则会有歧义,超负荷分解将更喜欢第二个. 在13.3.3.2/3:
然后13.3.3 / 1
最后,这里是13.3.3.1.1 / 3可能参与标准转换序列的隐式转换表. Conversion sequences http://img259.imageshack.us/img259/851/convs.png (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |