หากมีความเกี่ยวข้องกัน
Let 's สำหรับช่วงเวลาที่คิดว่าเป็นจริงฐานของB
D
แล้วสำหรับการเรียกร้องให้check
ทั้งสองรุ่นจะทำงานได้เพราะHost
สามารถแปลงและD*
B*
เป็นลำดับการแปลงที่ผู้ใช้กำหนดตามที่อธิบายโดย13.3.3.1.2
จากHost<B, D>
ถึงD*
และB*
ตามลำดับ สำหรับการค้นหาฟังก์ชันการแปลงที่สามารถแปลงคลาสฟังก์ชันตัวเลือกต่อไปนี้จะถูกสังเคราะห์สำหรับcheck
ฟังก์ชันแรกตาม13.3.1.5/1
D* (Host<B, D>&)
ฟังก์ชั่นแปลงแรกไม่ได้เป็นผู้สมัครเพราะไม่สามารถแปลงเป็นB*
D*
สำหรับฟังก์ชันที่สองมีตัวเลือกดังต่อไปนี้:
B* (Host<B, D> const&)
D* (Host<B, D>&)
นี่คือตัวเลือกฟังก์ชันการแปลงสองตัวที่ใช้วัตถุโฮสต์ ครั้งแรกใช้โดยการอ้างอิง const และครั้งที่สองไม่ได้ ดังนั้นประการที่สองจึงเป็นการจับคู่ที่ดีกว่าสำหรับ*this
วัตถุที่ไม่ใช่ const ( อาร์กิวเมนต์ของวัตถุโดยนัย ) โดย13.3.3.2/3b1sb4
และใช้เพื่อแปลงB*
เป็นcheck
ฟังก์ชันที่สอง
หากคุณจะลบ const เราจะมีตัวเลือกดังต่อไปนี้
B* (Host<B, D>&)
D* (Host<B, D>&)
นี่หมายความว่าเราไม่สามารถเลือกตาม constness ได้อีกต่อไป ในสถานการณ์การแก้ปัญหาโอเวอร์โหลดแบบธรรมดาการโทรจะไม่ชัดเจนเพราะโดยปกติประเภทการส่งคืนจะไม่เข้าร่วมในการแก้ปัญหาโอเวอร์โหลด อย่างไรก็ตามสำหรับฟังก์ชันการแปลงมีแบ็คดอร์ 13.3.3/1
หากทั้งสองฟังก์ชั่นการแปลงเป็นสิ่งที่ดีอย่างเท่าเทียมกันแล้วประเภทการกลับมาของพวกเขาตัดสินใจที่จะดีที่สุดตาม ดังนั้นถ้าคุณจะเอา const แล้วคนแรกที่จะได้รับเพราะB*
แปลงดีกว่าที่จะB*
กว่าจะD*
B*
ตอนนี้ลำดับการแปลงที่ผู้ใช้กำหนดไว้แบบใดดีกว่า หนึ่งสำหรับฟังก์ชั่นตรวจสอบที่สองหรือครั้งแรก? 13.3.3.2/3b2
กฎคือการที่ผู้ใช้กำหนดลำดับการแปลงเท่านั้นที่สามารถเทียบหากพวกเขาใช้ฟังก์ชั่นการแปลงเดียวกันหรือคอนสตรัคตาม นี่เป็นกรณีตรงนี้: ทั้งสองใช้ฟังก์ชันการแปลงที่สอง สังเกตว่าconstมีความสำคัญเนื่องจากบังคับให้คอมไพเลอร์รับฟังก์ชันการแปลงที่สอง
เนื่องจากเราสามารถเปรียบเทียบได้ - อันไหนดีกว่ากัน? กฎคือการแปลงที่ดีกว่าจากประเภทผลตอบแทนของฟังก์ชันการแปลงไปยังประเภทปลายทางจะชนะ (อีกครั้งโดย13.3.3.2/3b2
) ในกรณีนี้D*
แปลงดีกว่าที่จะไปกว่าการD*
B*
ดังนั้นฟังก์ชันแรกจึงถูกเลือกและเรารับรู้ถึงการสืบทอด!
สังเกตว่าเนื่องจากเราไม่จำเป็นต้องแปลงเป็นคลาสพื้นฐานจริง ๆเราจึงสามารถรับรู้การสืบทอดส่วนตัวได้เพราะการที่เราจะแปลงจาก a D*
เป็น a B*
ได้นั้นไม่ได้ขึ้นอยู่กับรูปแบบของการสืบทอดตาม4.10/3
หากไม่เกี่ยวข้องกัน
ตอนนี้สมมติว่าพวกเขาไม่เกี่ยวข้องกับการถ่ายทอดทางพันธุกรรม ดังนั้นสำหรับฟังก์ชันแรกเราจึงมีผู้สมัครดังต่อไปนี้
D* (Host<B, D>&)
และสำหรับวินาทีนี้เรามีอีกชุดหนึ่ง
B* (Host<B, D> const&)
เนื่องจากเราไม่สามารถแปลงD*
เป็นB*
ถ้าเราไม่มีความสัมพันธ์ทางมรดกตอนนี้เราจึงไม่มีฟังก์ชันการแปลงร่วมกันระหว่างลำดับการแปลงที่ผู้ใช้กำหนดสองลำดับ! ดังนั้นเราจะคลุมเครือหากไม่ใช่เพราะความจริงที่ว่าฟังก์ชันแรกเป็นเทมเพลต 13.3.3/1
แม่แบบทางเลือกที่สองเมื่อมีฟังก์ชั่นที่ไม่ใช่แม่แบบที่เป็นสิ่งที่ดีอย่างเท่าเทียมกันตาม ดังนั้นเราจึงเลือกฟังก์ชันที่ไม่ใช่เทมเพลต (อันที่สอง) และเรารับรู้ว่าไม่มีการสืบทอดระหว่างB
และD
!