Nếu chúng có liên quan
Chúng ta hãy giả sử rằng đó B
thực sự là một cơ sở của D
. Sau đó, đối với cuộc gọi đến check
, cả hai phiên bản đều khả thi vì Host
có thể được chuyển đổi thành D*
và B*
. Đó là một chuỗi chuyển đổi do người dùng xác định như được mô tả bởi 13.3.3.1.2
từ Host<B, D>
đến D*
và B*
tương ứng. Để tìm các hàm chuyển đổi có thể chuyển đổi lớp, các hàm ứng cử viên sau đây được tổng hợp cho check
hàm đầu tiên theo13.3.1.5/1
D* (Host<B, D>&)
Hàm chuyển đổi đầu tiên không phải là một ứng cử viên vì B*
không thể chuyển đổi thành D*
.
Đối với chức năng thứ hai, tồn tại các ứng cử viên sau:
B* (Host<B, D> const&)
D* (Host<B, D>&)
Đó là hai ứng cử viên chức năng chuyển đổi lấy đối tượng chủ. Đầu tiên lấy nó bằng tham chiếu const, và thứ hai thì không. Do đó, đối tượng thứ hai là đối sánh tốt hơn cho *this
đối tượng không phải const ( đối số đối tượng ngụ ý ) bởi 13.3.3.2/3b1sb4
và được sử dụng để chuyển đổi thành hàm B*
thứ hai check
.
Nếu bạn xóa const, chúng tôi sẽ có các ứng cử viên sau
B* (Host<B, D>&)
D* (Host<B, D>&)
Điều này có nghĩa là chúng ta không thể chọn theo hằng số nữa. Trong một kịch bản giải quyết quá tải thông thường, lệnh gọi bây giờ sẽ không rõ ràng vì thông thường kiểu trả về sẽ không tham gia vào giải quyết quá tải. Đối với các chức năng chuyển đổi, tuy nhiên, có một cửa sau. Nếu hai hàm chuyển đổi tốt như nhau, thì kiểu trả về của chúng sẽ quyết định xem ai là tốt nhất theo 13.3.3/1
. Vì vậy, nếu bạn loại bỏ const, thì đầu tiên sẽ được sử dụng, bởi vì B*
chuyển đổi tốt B*
hơn D*
thành B*
.
Bây giờ chuỗi chuyển đổi do người dùng xác định là tốt hơn? Một cho chức năng kiểm tra thứ hai hay đầu tiên? Quy tắc là các chuỗi chuyển đổi do người dùng xác định chỉ có thể được so sánh nếu họ sử dụng cùng một hàm chuyển đổi hoặc phương thức khởi tạo theo 13.3.3.2/3b2
. Đây chính xác là trường hợp ở đây: Cả hai đều sử dụng hàm chuyển đổi thứ hai. Lưu ý rằng do đó, const rất quan trọng vì nó buộc trình biên dịch thực hiện chức năng chuyển đổi thứ hai.
Vì chúng ta có thể so sánh chúng - cái nào tốt hơn? Quy tắc là chuyển đổi tốt hơn từ kiểu trả về của hàm chuyển đổi thành kiểu đích sẽ thắng (một lần nữa bằng cách 13.3.3.2/3b2
). Trong trường hợp này, D*
chuyển đổi tốt D*
hơn thành B*
. Do đó, chức năng đầu tiên được chọn và chúng tôi nhận ra sự kế thừa!
Lưu ý rằng vì chúng ta không bao giờ cần thực sự chuyển đổi sang lớp cơ sở, do đó chúng ta có thể nhận ra kế thừa riêng vì liệu chúng ta có thể chuyển đổi từ a D*
sang a B*
không phụ thuộc vào hình thức kế thừa theo4.10/3
Nếu chúng không liên quan
Bây giờ hãy giả sử chúng không có quan hệ thừa kế. Vì vậy, đối với chức năng đầu tiên, chúng tôi có các ứng cử viên sau
D* (Host<B, D>&)
Và lần thứ hai, chúng tôi có một bộ khác
B* (Host<B, D> const&)
Vì chúng ta không thể chuyển đổi D*
thành B*
nếu chúng ta không có mối quan hệ kế thừa, nên bây giờ chúng ta không có hàm chuyển đổi chung giữa hai chuỗi chuyển đổi do người dùng xác định! Vì vậy, chúng ta sẽ mơ hồ nếu không vì thực tế là hàm đầu tiên là một mẫu. Mẫu là lựa chọn thứ hai khi có một chức năng không phải mẫu cũng tốt theo 13.3.3/1
. Do đó, chúng tôi chọn hàm không phải mẫu (hàm thứ hai) và chúng tôi nhận ra rằng không có sự kế thừa giữa B
và D
!