2017-09-24 24 views
9

Đối với đoạn mã sau:gọi mơ hồ của mẫu quá tải với tham số (const T &, const T &) hoặc (const char (&) [N], const char (&) [M])

#include <iostream> 
using std::cout; using std::endl; 

template <typename T> 
int compare(const T&, const T&) { 
    cout << __PRETTY_FUNCTION__ << endl; 
    return 0; 
} 
template <size_t N, size_t M> 
int compare(const char (&)[N], const char (&)[M]) { 
    cout << __PRETTY_FUNCTION__ << endl; 
    return 0; 
} 

int main(int argc, char *argv[]) { 
    compare("hi", "is"); 
} 

Khi tôi biên dịch mã với g++ -std=c++1y, nó than phiền:

error: call of overloaded ‘compare(const char [3], const char [3])’ is ambiguous 
    compare("hi", "is"); 

Theo các quy tắc của mẫu quá tải, chức năng khả thi là:

compare(const T&, const T&) with T = char [3] 
compare(const char (&)[N], const char (&)[M]) with N = 3ul, M = 3ul 

Cả hai đều cung cấp một kết quả tương đương tốt (tức là chính xác) cho cuộc gọi. Vì vậy, tôi nên kiểm tra xem cái nào là chuyên biệt hơn.

Nhưng theo kiến ​​thức hạn chế của tôi, const T& tổng quát hơn const char (&)[N]. Vì vậy, tôi nghĩ rằng compare(const char (&)[N], const char (&)[M]) là chuyên biệt hơn. Nhưng tại sao cuộc gọi này lại mơ hồ?

Trả lời

10

Quá tải đầu tiên compare(const T&, const T&) buộc cả hai tham số phải cùng loại, trong khi quá tải thứ hai thì không. Vì vậy, trong vấn đề này quá tải đầu tiên là cụ thể hơn.

Tuy nhiên, quá tải thứ hai buộc cả hai tham số là char mảng, do đó, nó cụ thể hơn trong vấn đề đó.

Vì vậy, không quá tải có thể được cho là chuyên biệt hơn so với khác, và kết quả là lỗi mơ hồ.

Một cách khác để xem xét là mỗi quá tải có thể chấp nhận đầu vào mà phương thức kia không: Chỉ quá tải đầu tiên sẽ chấp nhận cuộc gọi trong đó cả hai đối số là int&. Và chỉ quá tải thứ hai sẽ chấp nhận một cuộc gọi trong đó các đối số là char (&)[2]char (&)[3].

Nếu bạn thay đổi tình trạng quá tải thứ hai để

template <size_t N> int compare(const char (&)[N], const char (&)[N]) 

nó sẽ sửa chữa các lỗi, như thế này tại là Nghiêm cụ thể hơn tình trạng quá tải đầu tiên.

+0

Tôi đồng ý về giải thích, nhưng giải pháp giới hạn việc sử dụng chuỗi 'so sánh' thứ hai với các chuỗi có kích thước bằng nhau. – xtofl

+0

Cảm ơn bạn. Tôi có thể đã hiểu ý nghĩa của từ "chuyên ngành". Nhưng quy tắc chính xác của "chuyên ngành" trong C++ là gì? Tôi chưa đọc đặc tả của C++. Và tôi đang đọc cuốn sách C++ Primer. – zhenguoli

+0

@xtofl Đó là một ví dụ cho cách khắc phục lỗi. Một ví dụ khác sẽ thay đổi quá tải đầu tiên để có hai loại khác nhau. Không biết các yêu cầu tôi không thể đưa ra một giải pháp thỏa mãn chúng. – interjay

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