2013-03-23 8 views
8

Dlaczego rozdzielczość przeciążenia dla połączenia max(x, y) w wyrażeniu return max(max(x, y), z); poniżej powoduje wywołanie funkcji innej niż szablon char const* max(char const*, char const*)?Dlaczego poniższa rozdzielczość przeciążania wywołuje funkcję inną niż szablon?

O ile mogę zrozumieć, funkcja max<const char*>(x, y) jest lepsze dopasowanie niż poprzednio, jak x jest const char* const& i y jest 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); 
} 
+0

@BoPersson dwóch funkcji w tym przykładzie nie mają ten sam podpis. – Belloc

Odpowiedz

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*) ?

Gdy wywoływanie tej funkcji:

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

T wyprowadza się const char*. Dlatego ten podpis jest tworzony:

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

Funkcja wewnętrznie wywołuje wersji binarnej max() z argumentami typu const char*. Zarówno szablon, jak i non-template overload są opłacalne dla argumentu typu const char*.

Jednak, gdy dwie funkcje są opłacalne dla rozwiązania połączenia i jeden z nich nie jest szablonem, wersja non-szablon jest uważana za najlepiej pasuje.

zgodnie z pkt 13.3.3/1 o C++ 11 Standard:

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.

To wyjaśnia, dlaczego przeciążenie non-szablon jest zrywane.

+0

Brak konwersji dla funkcji szablonu – Belloc

+0

@ user1042389: Nawet dla funkcji bez szablonu –

+0

'Funkcja wewnętrznie wywołuje binarną wersję max() z argumentami typu const char *' Nie zgadzam się z tym. Funkcja 'max()' jest wywoływana z argumentami typu "const char * const &". – Belloc

0

Argument Matching - Funkcje przeciążone są wybierane dla najlepszego dopasowania deklaracji funkcji w bieżącym zakresie.

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

Dla funkcji szablonu nie ma konwersji. Dlatego myślę, że powinno się to nazywać zamiast bez szablonu. – Belloc

Powiązane problemy