传递0文字时,指针和引用之间的重载选择为double参数

时间:2017-10-27 08:47:09

标签: c++ c++11

考虑以下两个重载:

template <T> void foo(T * d);
template <T> void foo(const T & d);

如果这样使用:

foo<double>(0);

将调用哪个重载?你能指点我定义这种行为的spec段落吗?

ps:从一些快速测试看来,文字零点与nullptr匹配,因此选择了指针重载,但我想从语言规范中知道。

(编辑)添加了const引用,这是实际案例。

1 个答案:

答案 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更专业。