为什么下面的重载分辨率调用非模板函数?

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)是一个比以前更好的贴合,因为xconst char* const&yconst 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)

And*_*owl 4

\n

max(x, y)为什么下面表达式中的调用的重载决策return max(max(x, y), z);会导致对非模板函数的调用char const* max(char const*, char const*)

\n
\n\n

调用该函数时:

\n\n
template <typename T>\nT const& max (T const& x, T const& y, T const& z)\n{\n    return max (max(x, y), z);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

T推论为const char*. 因此,这个签名被实例化:

\n\n
const char* const& max (\n    const char* const& x, \n    const char* const& y, \n    const char* const& z\n    )\n
Run Code Online (Sandbox Code Playgroud)\n\n

该函数在内部调用二进制版本,max()参数类型为const char*。模板和非模板重载对于 类型的参数都是可行的const char*

\n\n

但是,当两个函数可用于解析调用并且其中一个函数不是模板时,非模板版本被认为是最合适的

\n\n

根据 C++11 标准第 13.3.3/1 段:

\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\n

这解释了为什么选择非模板重载。

\n