2013-03-23 39 views
8

Tại sao độ phân giải quá tải cho cuộc gọi max(x, y) trong biểu thức return max(max(x, y), z); bên dưới dẫn đến cuộc gọi đến chức năng không phải mẫu char const* max(char const*, char const*)?Tại sao độ phân giải quá tải bên dưới gọi hàm không phải mẫu?

Theo như tôi có thể hiểu được, hàm max<const char*>(x, y) là một phù hợp tốt hơn so với trước đây, như là một xconst char* const&y là một 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 Hai chức năng trong ví dụ này không có chữ ký giống nhau. – Belloc

Trả lời

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

Khi gọi chức năng này:

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

T được suy luận là const char*. Do đó, chữ ký này được khởi tạo:

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

Chức năng nội bộ gọi là phiên bản nhị phân của max() với các tham số kiểu const char*. Cả mẫu và quá tải mẫu không khả thi đối với một đối số kiểu const char*.

Tuy nhiên, khi hai chức năng là khả thi để giải quyết các cuộc gọi một trong số họ không phải là một mẫu, phiên bản không mẫu được coi là một tốt nhất phù hợp.

mỗi khoản 13.3.3/1 của C++ 11 Tiêu chuẩn:

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.

Điều này giải thích lý do tại sao không mẫu quá tải được chọn.

+0

Không có chuyển đổi cho chức năng mẫu – Belloc

+0

@ user1042389: Ngay cả đối với chức năng không phải mẫu –

+0

'Hàm bên trong gọi phiên bản nhị phân của max() với các đối số của kiểu const char *' Tôi không đồng ý với điều này. Hàm 'max()' được gọi với các đối số của kiểu 'const char * const &'. – Belloc

0

Argument Matching - Chức năng quá tải được chọn cho phù hợp nhất với khai báo hàm trong phạm vi hiện tại.

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

Đối với chức năng mẫu không có chuyển đổi. Đó là lý do tại sao tôi nghĩ nó nên được gọi thay vì không phải mẫu. – Belloc

Các vấn đề liên quan