Bel*_*loc 8 c++ templates overloading
为什么下面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);
}
Run Code Online (Sandbox Code Playgroud)
\n\n\n\n
max(x, y)为什么下面表达式中的调用的重载决策return max(max(x, y), z);会导致对非模板函数的调用char const* max(char const*, char const*)?
调用该函数时:
\n\ntemplate <typename T>\nT const& max (T const& x, T const& y, T const& z)\n{\n return max (max(x, y), z);\n}\nRun Code Online (Sandbox Code Playgroud)\n\nT推论为const char*. 因此,这个签名被实例化:
const char* const& max (\n const char* const& x, \n const char* const& y, \n const char* const& z\n )\nRun Code Online (Sandbox Code Playgroud)\n\n该函数在内部调用二进制版本,max()参数类型为const char*。模板和非模板重载对于 类型的参数都是可行的const char*。
但是,当两个函数可用于解析调用并且其中一个函数不是模板时,非模板版本被认为是最合适的。
\n\n根据 C++11 标准第 13.3.3/1 段:
\n\n\n\n\n给定这些定义,** 可行函数 F1 被定义为比另一个可行函数更好的函数\n F2 如果** 对于所有参数 i,ICSi(F1) 不是比 ICSi(F2) 更差的转换序列,然后
\n\n\xe2\x80\x94 对于某些参数 j,ICSj(F1) 是比 ICSj(F2) 更好的转换序列,或者,如果不是这样,
\n\n\xe2\x80\x94 上下文是通过用户定义的转换(参见 8.5、13.3.1.5 和 13.3.1.6)和从 F1 的返回类型到目标类型(即,正在初始化的实体的类型)是比从 F2 返回类型到目标类型的标准转换序列更好的转换序列。[ ... ] 或者,如果不是这样,
\n\n\xe2\x80\x94 F1 是一个非模板函数,F2 是一个函数模板特化,或者,如果不是这样,
\n\n\xe2\x80\x94 F1 和 F2 是函数模板特化,根据 14.5.6.2 中描述的部分排序规则,F1 的函数模板比 F2 的模板更特化。
\n
这解释了为什么选择非模板重载。
\n