Bạn đang chuyển một int
vào chức năng quá tải này.
Mặc dù trực giác của con người nói rằng ambig(signed long)
nên được ưa thích vì đầu vào của bạn là số nguyên âm (không thể được biểu diễn như vậy bởi một unsigned long
), hai chuyển đổi trên thực tế tương đương trong "ưu tiên" trong C++.
Đó là, việc chuyển đổi int
→ unsigned long
được coi là chỉ có giá trị như int
→ signed long
, và không được ưa thích để người kia.
Mặt khác, nếu tham số của bạn đã là một long
chứ không phải là một int
, sau đó là một so khớp chính xác-signed long
, không có chuyển đổi cần thiết. This avoids the ambiguity.
void ambig( signed long) { }
void ambig(unsigned long) { }
int main(void) { ambig(static_cast<long>(-1)); return 0; }
"Chỉ một trong những điều đó".
[C++11: 4.13/1]:
("rank chuyển đổi Integer")
Mỗi kiểu dữ liệu integer đã rank chuyển đổi số nguyên quy định như sau:
- [..]
- Xếp hạng của loại số nguyên đã ký phải lớn hơn xếp hạng của bất kỳ loại số nguyên nào có dấu có kích thước nhỏ hơn.
- Xếp hạng của
long long int
sẽ lớn hơn cấp bậc long int
, mà sẽ lớn hơn cấp bậc int
, mà phải lớn hơn cấp bậc short int
, mà phải lớn hơn cấp bậc ký char.
- Thứ hạng của bất kỳ loại số nguyên không dấu nào sẽ bằng với thứ hạng của loại số nguyên đã ký tương ứng.
- [..]
[Lưu ý: Xếp hạng chuyển đổi số nguyên được sử dụng trong định nghĩa của các chương trình khuyến mãi không thể thiếu (4.5) và chuyển đổi số học thông thường (Điều 5). —thêm ghi chú]
Độ phân giải quá tải phức tạp và được xác định trong [C++11: 13.3]
; Tôi không thể mang bạn bằng cách trích dẫn phần lớn nó ở đây.
Dưới đây là một điểm nhấn, mặc dù:
[C++11: 13.3.3.1/8]:
Nếu không chuyển đổi được yêu cầu để phù hợp với một cuộc tranh cãi với một loại tham số, trình tự chuyển đổi ngầm là trình tự chuyển đổi tiêu chuẩn bao gồm việc chuyển đổi danh tính (13.3.3.1. 1).
[C++11: 13.3.3.1/9]:
Nếu không có chuỗi chuyển đổi nào có thể được tìm thấy để chuyển đổi một đối số thành loại thông số hoặc chuyển đổi không đúng định dạng, chuỗi chuyển đổi ẩn không thể được tạo thành.
[C++11: 13.3.3.1/10]:
Nếu một vài chuỗi chuyển đổi khác nhau tồn tại mà mỗi chuyển đổi đối số cho loại tham số, chuỗi chuyển đổi ngầm được kết hợp với tham số được xác định là chuỗi chuyển đổi duy nhất được chỉ định chuỗi chuyển đổi không rõ ràng. Với mục đích xếp thứ tự chuyển đổi ngầm như được mô tả trong 13.3.3.2, chuỗi chuyển đổi mơ hồ được coi là chuỗi do người dùng xác định, không thể phân biệt được với bất kỳ chuỗi chuyển đổi được người dùng xác định11 nào khác. Nếu một hàm sử dụng chuỗi chuyển đổi không rõ ràng được chọn là hàm khả thi tốt nhất, cuộc gọi sẽ bị hỏng do việc chuyển đổi một trong các đối số trong cuộc gọi không rõ ràng.
/10
là trường hợp bạn đang gặp phải; /8
là trường hợp bạn sử dụng với đối số long
.
Đợi, nhưng 'int' →' long' luôn là một chuyển đổi không mất mát. 'int' →' unsigned long' mất một nửa thời gian. Làm thế nào/tại sao họ cùng một thứ hạng ?! – Mehrdad
Chỉ cần tò mò: bất kỳ lý do nào không sử dụng chỉ '-1L' thay vì dàn diễn viên đó? – Mat
@Mat: Không, không. –