8

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

据我所知,该函数max<const char*>(x, y)比前者更适合,xaconst char* const&ya 也是如此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);
}
4

1 回答 1

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*。对于 type 的参数,模板和非模板重载都是可行的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 是函数模板特化,根据 14.5.6.2 中描述的偏序规则,F1 的函数模板比​​ F2 的模板更特化。

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

于 2013-03-23T12:05:37.737 回答