มีอยู่ครั้งหนึ่งที่ยังไม่ได้กล่าวถึงใน C ++ และนั่นไม่ได้หมายถึงวัตถุของตัวเองหรือทำให้สมาชิกจากตัวแปรที่ได้รับมีความไม่ชัดเจน
คุณสามารถใช้this
ในการแปลงชื่อที่ไม่ขึ้นอยู่กับชื่อขึ้นอยู่กับอาร์กิวเมนต์ภายในชั้นเรียนแม่แบบที่รับมาจากแม่แบบอื่น ๆ
template <typename T>
struct base {
void f() {}
};
template <typename T>
struct derived : public base<T>
{
void test() {
//f(); // [1] error
base<T>::f(); // quite verbose if there is more than one argument, but valid
this->f(); // f is now an argument dependent symbol
}
}
เทมเพลตจะถูกคอมไพล์ด้วยกลไกการส่งผ่านสองแบบ ในระหว่างการส่งผ่านครั้งแรกเฉพาะชื่อที่ไม่ใช้อาร์กิวเมนต์จะได้รับการแก้ไขและตรวจสอบในขณะที่ชื่อที่ขึ้นต่อกันจะได้รับการตรวจสอบเพื่อความสอดคล้องเท่านั้นโดยไม่ต้องแทนที่อาร์กิวเมนต์เท็มเพลตจริง
ในขั้นตอนนั้นหากไม่มีการแทนที่ชนิดจริงคอมไพเลอร์ก็แทบจะไม่มีข้อมูลของสิ่งที่base<T>
จะเป็น (โปรดทราบว่าความเชี่ยวชาญของเทมเพลตฐานสามารถเปลี่ยนให้เป็นประเภทที่แตกต่างอย่างสิ้นเชิงแม้แต่ประเภทที่ไม่ได้กำหนด) ดังนั้นมันจึงสันนิษฐานว่าเป็นประเภท . ในขั้นตอนนี้การโทรf
ที่ไม่ขึ้นกับที่ดูเหมือนเป็นธรรมชาติกับโปรแกรมเมอร์คือสัญลักษณ์ที่คอมไพเลอร์ต้องค้นหาในฐานะสมาชิกของderived
หรือในการปิดล้อมเนมสเปซ - ซึ่งไม่ได้เกิดขึ้นในตัวอย่าง - และมันจะบ่น
การแก้ปัญหาคือการเปลี่ยนชื่อไม่ขึ้นอยู่กับชื่อf
ขึ้นอยู่กับ สิ่งนี้สามารถทำได้สองวิธีโดยระบุประเภทที่มีการนำไปใช้อย่างชัดเจน (- base<T>::f
การเพิ่มbase<T>
ทำให้สัญลักษณ์ขึ้นอยู่กับT
ผู้แปลและคอมไพเลอร์จะคิดว่ามันจะมีอยู่และเลื่อนการตรวจสอบจริงสำหรับรอบที่สองหลังจาก การทดแทนอาร์กิวเมนต์
วิธีที่สองคือตัวเรียงลำดับที่มากถ้าคุณสืบทอดจากเทมเพลตที่มีอาร์กิวเมนต์มากกว่าหนึ่งตัวหรือชื่อแบบยาวเพียงแค่เพิ่มthis->
สัญลักษณ์ก่อนหน้า เนื่องจากคลาสเทมเพลตที่คุณใช้อยู่นั้นขึ้นอยู่กับอาร์กิวเมนต์ (ซึ่งสืบทอดมาจากbase<T>
) this->
นั้นขึ้นอยู่กับอาร์กิวเมนต์และเราได้รับผลลัพธ์เดียวกัน: this->f
ถูกตรวจสอบในรอบที่สองหลังจากการแทนที่พารามิเตอร์เทมเพลต
this
ที่ MSDN โปรดไปที่ลิงก์นี้ ... ;-)