为什么以下表达式max(x, y)
中的调用return max(max(x, y), z);
的重载解析会导致调用非模板函数char const* max(char const*, char const*)
?
据我所知,函数max<const char*>(x, y)
比前者更合适,因为x
是const char* const&
而y
是const char* const&
}!
#include <iostream>
template <typename T>
T const& max (T const& x, T const& y)
{
return x < y ? y : x;
}
char const* max (char const* x, char const* y)
{
return std::strcmp(x, y) < 0 ? y : x;
}
template <typename T>
T const& max (T const& x, T const& y, T const& z)
{
return max (max(x, y), z);
}
int main ()
{
const char* sx = "String_x";
const char* sy = "String_y";
const char* sz = "String_z";
max(sx, sy, sz);
}
答案 0 :(得分:4)
为什么以下表达式
max(x, y)
中的调用return max(max(x, y), z);
的重载解析会导致调用非模板函数char const* max(char const*, char const*)
?
调用此函数时:
template <typename T>
T const& max (T const& x, T const& y, T const& z)
{
return max (max(x, y), z);
}
T
推断为const char*
。因此,此签名被实例化:
const char* const& max (
const char* const& x,
const char* const& y,
const char* const& z
)
该函数在内部调用max()
的二进制版本,其参数类型为const char*
。模板和非模板重载都适用于const char*
类型的参数。
但是,当两个函数可用于解析调用和时,其中一个不是模板,非模板版本被认为是最合适的。
根据C ++ 11标准的第13.3.3 / 1段:
鉴于这些定义,**可行函数F1被定义为比另一个可行函数更好的函数 F2如果**对于所有参数i,ICSi(F1)不是比ICSi(F2)更差的转换序列,然后
- 对于某些参数j,ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是,
- 上下文是用户定义转换的初始化(见8.5,13.3.1.5和13.3.1.6)和 从返回类型F1到目标类型的标准转换序列(即,类型的 正在初始化的实体)是比标准转换序列更好的转换序列 F2的返回类型到目标类型。 [...]或者,如果不是那样,
- F1是非模板功能,F2是功能模板专业化,或者,如果不是,
- F1和F2是功能模板专精,F1的功能模板更专业 根据14.5.6.2中描述的偏序规则,比F2的模板。
这解释了为什么选择非模板重载。
答案 1 :(得分:0)
Argument Matching - 为当前范围内的函数声明的最佳匹配选择了重载函数。
如果模板参数推断成功,则生成函数 与其他函数进行比较以确定最佳匹配, 遵循重载决策的规则
找到了完全匹配。
进行了一次微不足道的转换。
进行了整体推广。
存在标准转换为所需的参数类型。
存在用户定义的转换(转换运算符或构造函数)到所需的参数类型。
找到省略号代表的参数。