Why does the overload resolution below call a function without a pattern?

Why overload resolution for calling max(x, y) in the expression return max(max(x, y), z); below leads to a function call without a char const* max(char const*, char const*) pattern char const* max(char const*, char const*) ?

As far as I understand, the function max<const char*>(x, y) better than the first, since x is const char* const& and y is 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); } 
+8
c ++ overloading templates
source share
2 answers

Why overload resolution for calling max(x, y) in the expression return max(max(x, y), z); below leads to a function call without a char const* max(char const*, char const*) pattern char const* max(char const*, char const*) ?

When calling this function:

 template <typename T> T const& max (T const& x, T const& y, T const& z) { return max (max(x, y), z); } 

T is output as const char* . Therefore, this signature is created:

 const char* const& max ( const char* const& x, const char* const& y, const char* const& z ) 

The function internally calls the binary version of max() with arguments of type const char* . Both the pattern and the abnormal overload are viable for an argument of type const char* .

However, when two functions are viable for call resolution, and one of them is not a template, a version other than the template is considered the most suitable .

In paragraph 13.3.3 / 1 of the C ++ 11 standard:

Given these definitions, ** a viable function F1 is defined as a better function than another viable function F2 if ** for all arguments i, ICSi (F1) is no worse than the conversion scheme than ICSi (F2), and then

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

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

- F1 is a function without a template, and F2 is a specialized function of a template , or, if not this,

- F1 and F2 are specialized function templates, and the function template for F1 is more specialized than the template for F2 in accordance with the partial ordering rules described in 14.5.6.2.

This explains why non-template overloading is selected.

+4
source share

Match Argument - Overloaded functions are selected to best match function declarations in the current area.

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

  • An exact match was found.

  • The trivial transformation is carried out.

  • An entire action was held.

  • There is a standard conversion to the type of argument you need.

  • Defines a custom conversion (conversion operator or constructor) to the desired argument type.

  • The arguments presented by the ellipsis were found.

0
source share

All Articles