2013-03-23 51 views
8

为什么在下面的表达式return max(max(x, y), z);中调用max(x, y)的重载分辨率会导致调用非模板函数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); 
} 
+0

@BoPersson这个例子中的两个功能不具有相同的签名。 – Belloc 2013-03-23 12:20:32

回答

4

Why the overload resolution for the call max(x, y) in the expression return max(max(x, y), z); below results in a call to the non-template function 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:

Given these definitions,** a viable function F1 is defined to be a better function than another viable function F2 if** for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then

— for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,

— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type. [ ... ] or, if not that,

F1 is a non-template function and F2 is a function template specialization, or, if not that,

— F1 and F2 are function template specializations, and the function template for F1 is more specialized than the template for F2 according to the partial ordering rules described in 14.5.6.2.

这就解释了为什么非模板过载被拾取。

+0

模板函数 – Belloc 2013-03-23 12:12:25

+0

@ user1042389没有转换:即使对于非模板函数 – 2013-03-23 12:13:30

+0

该函数内部调用带有const char *类型参数的max()的二进制版本我不同意这一点。使用'const char * const&'类型的参数调用函数'max()'。 – Belloc 2013-03-23 12:14:54

0

Argument Matching - 为当前作用域中函数声明的最佳匹配选择重载函数。

If template argument deduction succeeds, then the generated function is compared with the other functions to determine the best match, following the rules for overload resolution

 

  • An exact match was found.

  • A trivial conversion was performed.

  • An integral promotion was performed.

  • A standard conversion to the desired argument type exists.

  • A user-defined conversion (either conversion operator or constructor) to the desired argument type exists.

  • Arguments represented by an ellipsis were found.

+0

对于模板功能没有转换。这就是为什么我认为它应该被称为而不是非模板。 – Belloc 2013-03-23 12:10:28