考虑以下两个重载:
template <T> void foo(T * d);
template <T> void foo(const T & d);
如果这样使用:
foo<double>(0);
将调用哪个重载?你能指点我定义这种行为的spec段落吗?
ps:从一些快速测试看来,文字零点与nullptr匹配,因此选择了指针重载,但我想从语言规范中知道。
(编辑)添加了const引用,这是实际案例。
答案 0 :(得分:4)
来自http://en.cppreference.com/w/cpp/language/overload_resolution
最佳可行功能:
1)至少有一个F1的参数,其隐式转换优于F2的该参数的相应隐式转换 2)或。如果不是这样,(仅在通过转换进行非类初始化的上下文中),从返回类型F1到正在初始化的类型的标准转换序列优于来自返回类型F2的标准转换序列。 3)或者,如果不是,则F1是非模板函数,而F2是模板特化
4)或者,如果没有,F1和F2都是模板特化,F1根据模板特化的部分排序规则更加专业化
隐式转换序列的排名
每种类型的标准转换序列都分配了三个等级之一:
1)完全匹配:不需要转换,左值到右值转换,限定转换,函数指针转换,(从C ++ 17开始)用户定义的类类型转换为同一类
2)推广:整体推广,浮点推广 3)转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔转换,派生类到其基础的用户定义转换
所以
f(double*); // null pointer conversion
f(const double&); // Floating–integral conversions
f(0); // Ambiguous call
使用模板
template <T> void foo(T*); // #1 // null pointer conversion
template <T> void foo(const T&); // #2 // Floating–integral conversions
foo<double>(0); // #1
因为#1比#2更专业。