กลับไปหน้าบทความ

อ่าน 3 นาที

การปรับแต่งแม่แบบบางส่วน

การกำหนดค่าเฉพาะของเทมเพลตบางส่วน (Partial template specialization ) เป็นรูปแบบเฉพาะของ การกำหนดค่าเฉพาะของเทมเพลต คลาส (Class template specialization ) โดยปกติจะใช้ใน ภาษาโปรแกรม...

การปรับแต่งแม่แบบบางส่วน

การกำหนดค่าเฉพาะของเทมเพลตบางส่วน (Partial template specialization ) เป็นรูปแบบเฉพาะของการกำหนดค่าเฉพาะของเทมเพลต คลาส (Class template specialization ) โดยปกติจะใช้ในภาษาโปรแกรมC++ ซึ่งช่วยให้นักเขียนโปรแกรมสามารถกำหนดค่าเฉพาะของอาร์กิวเมนต์บางส่วนของเทมเพลตคลาสได้เท่านั้น ต่างจากการกำหนดค่าเฉพาะแบบเต็มรูปแบบ (Explicit full specialization) ที่ต้องระบุอาร์กิวเมนต์ทั้งหมดของเทมเพลต

แม่แบบและความเชี่ยวชาญเฉพาะด้าน

คลาสเทมเพลตนั้นแท้จริงแล้วคือเมตาคลาส: มันคือชนิดข้อมูลนามธรรมบางส่วนที่ให้คำแนะนำแก่คอมไพเลอร์เกี่ยวกับวิธีการสร้างคลาสที่มีสมาชิกข้อมูลที่เหมาะสม ตัวอย่างเช่น คอนเทนเนอร์มาตรฐานของ C++ คือคลาสเทมเพลต เมื่อโปรแกรมเมอร์ใช้เวกเตอร์ พวกเขาจะสร้างอินสแตนซ์ของมันด้วยชนิดข้อมูล เฉพาะ เช่น int, string หรือ double เวกเตอร์แต่ละชนิดจะส่งผลให้เกิดคลาสที่แตกต่างกันในโค้ดออบเจ็กต์ ของคอมไพเลอร์ โดยแต่ละคลาสจะทำงานกับชนิดข้อมูลที่แตกต่างกัน กระบวนการนี้เรียกว่าการทำให้เป็นโมโนมอร์ฟิซึมของเจเนริก

หากทราบว่าเทมเพลตคลาสจะถูกใช้กับชนิดข้อมูลเฉพาะค่อนข้างบ่อย และชนิดข้อมูลนั้นอนุญาตให้มีการปรับแต่งบางอย่าง (เช่น การเลื่อนบิตกับจำนวนเต็ม แทนที่จะเป็นการคูณหรือหารด้วย 2) เราอาจสร้างเทมเพลตคลาสเฉพาะที่มีการตั้งค่าพารามิเตอร์เทมเพลตบางส่วนไว้ล่วงหน้า เมื่อคอมไพเลอร์เห็นอินสแตนซ์ของเทมเพลตคลาสดังกล่าวในโค้ด โดยทั่วไปแล้วมันจะเลือกคำจำกัดความเทมเพลตที่เฉพาะเจาะจงที่สุดที่ตรงกับอินสแตนซ์นั้น ดังนั้น การกำหนดค่าเฉพาะแบบเต็มรูปแบบอย่างชัดเจน (ที่ระบุอาร์กิวเมนต์เทมเพลตทั้งหมด) จะเป็นที่ต้องการมากกว่าการกำหนดค่าเฉพาะแบบบางส่วน หากอาร์กิวเมนต์เทมเพลตทั้งหมดตรงกัน

ความเชี่ยวชาญเฉพาะด้าน

เทมเพลตสามารถมีประเภทพารามิเตอร์ได้มากกว่าหนึ่งประเภท คอมไพเลอร์รุ่นเก่าบางตัวอนุญาตให้กำหนดค่าเฉพาะให้กับพารามิเตอร์ของเทมเพลตได้เพียงอย่างใดอย่างหนึ่งเท่านั้น คอมไพเลอร์ที่รองรับการกำหนดค่าเฉพาะบางส่วนจะอนุญาตให้โปรแกรมเมอร์กำหนดค่าเฉพาะให้กับพารามิเตอร์บางตัวในขณะที่ปล่อยให้พารามิเตอร์อื่นๆ เป็นแบบทั่วไป

ตัวอย่าง

สมมติว่ามีKeyValuePairคลาสหนึ่งที่มีพารามิเตอร์เทมเพลตสองตัว ดังต่อไปนี้

template < typename K , typename V > class KeyValuePair {};

ต่อไปนี้เป็นตัวอย่างของคลาสที่กำหนดการกำหนดค่าเฉพาะของเทมเพลตแบบเต็มรูปแบบอย่างชัดเจนKeyValuePairโดยการจับคู่จำนวนเต็มกับสตริง ประเภทของคลาสยังคงใช้ชื่อเดียวกันกับเวอร์ชันดั้งเดิม

โดยใช้std :: string ;template <> class KeyValuePair < ​​int , string > {};

ต่อไปนี้เป็นตัวอย่างของการกำหนดค่าเฉพาะบางส่วน โดยKeyValuePairใช้ชื่อเดียวกันกับเวอร์ชันดั้งเดิม และมีพารามิเตอร์เทมเพลตเฉพาะหนึ่งตัว

template < typename K > class KeyValuePair < ​​K , string > {};

คลาสตัวอย่างถัดไปKeyStringPairสืบทอดมาจากคลาสเดิมKeyValuePairโดยใช้ชื่อใหม่ และกำหนดการกำหนดค่าเฉพาะของเทมเพลตบางส่วน แตกต่างจากการกำหนดค่าเฉพาะแบบชัดเจนข้างต้น ตรงที่เฉพาะVพารามิเตอร์เทมเพลตของคลาสแม่ เท่านั้น ที่จะถูกกำหนดค่าเฉพาะ ในขณะที่Kพารามิเตอร์เทมเพลตยังคงเป็นแบบทั่วไป

template < typename K > class KeyStringPair : public KeyValuePair < ​​K , string > {};

ไม่สำคัญว่าพารามิเตอร์ของเทมเพลตตัวใดจะเป็นแบบเฉพาะเจาะจงและตัวใดจะยังคงเป็นแบบทั่วไป ตัวอย่างเช่น ตัวอย่างต่อไปนี้ก็เป็นตัวอย่างที่ถูกต้องของการกำหนดพารามิเตอร์เฉพาะเจาะจงบางส่วนของKeyValuePairคลาส เดิมเช่นกัน

template < typename V > class IntegerValuePair : public KeyValuePair < ​​int , V > {};

ข้อควรระวัง

เทมเพลต C++ ไม่ได้จำกัดอยู่แค่คลาสเท่านั้น แต่ยังสามารถใช้เพื่อกำหนดเทมเพลตฟังก์ชันได้อีกด้วย แม้ว่าเทมเพลตฟังก์ชันจะสามารถกำหนดค่าเฉพาะได้อย่างสมบูรณ์ แต่ไม่สามารถกำหนดค่าเฉพาะบางส่วนได้ ไม่ว่าจะเป็นเทมเพลตฟังก์ชันสมาชิกหรือเทมเพลตฟังก์ชันที่ไม่ใช่สมาชิกก็ตาม ซึ่งอาจเป็นประโยชน์ต่อผู้เขียนคอมไพเลอร์ แต่ส่งผลกระทบต่อความยืดหยุ่นและความละเอียดของสิ่งที่นักพัฒนาสามารถทำได้[ 1 ]แต่เทมเพลตฟังก์ชันสามารถโอเวอร์โหลดได้ซึ่งให้ผลเกือบเหมือนกับการกำหนดค่าเฉพาะบางส่วนของเทมเพลตฟังก์ชัน[ 2 ]ตัวอย่างต่อไปนี้มีไว้เพื่อแสดงให้เห็นถึงประเด็นเหล่านี้

import std ;โดยใช้std :: string ;// ถูกต้องตามกฎหมาย: เทมเพลตฟังก์ชันพื้นฐานtemplate < typename Ret , typename Arg > Ret Foo ( Arg arg );// ถูกต้องตามกฎหมาย: เทมเพลตฟังก์ชันแบบชัดเจน/เต็มรูปแบบtemplate <> string Foo < string , char > ( char arg ) { return "Full" ; }// ผิดกฎหมาย: การกำหนดค่าเฉพาะของเทมเพลตฟังก์ชันบางส่วนของประเภทการส่งคืน// การกำหนดค่าเฉพาะของเทมเพลตฟังก์ชันบางส่วนไม่ได้รับอนุญาต// template <typename Arg> // void Foo<void, Arg>(Arg arg);// ถูกต้องตามกฎหมาย: โอเวอร์โหลดเทมเพลตพื้นฐานสำหรับประเภทอาร์กิวเมนต์แบบพอยเตอร์template < typename Ret , typename Arg > Ret Foo ( Arg * argPtr ) { return "PtrOverload" ; }// ถูกต้องตามกฎหมาย: ใช้ชื่อฟังก์ชันพื้นฐานซ้ำ ไม่ถือว่าเป็นโอเวอร์โหลด ผิดรูปแบบ: การประกาศที่ไม่สามารถโอเวอร์โหลดได้ (ดูด้านล่าง) template < typename Arg > string Foo ( Arg arg ) { return "Return1" ; }// ถูกต้องตามกฎหมาย: ใช้ชื่อฟังก์ชันพื้นฐานซ้ำ ไม่ถือว่าเป็นโอเวอร์โหลด ไม่ถูกต้องตามรูปแบบ: การประกาศที่ไม่สามารถโอเวอร์โหลดได้ (ดูด้านล่าง) template < typename Ret > Ret Foo ( char arg ) { return "Return2" ; }

ในตัวอย่างที่แสดงข้างต้น โปรดสังเกตว่าในขณะที่คำจำกัดความสองรายการสุดท้ายของฟังก์ชันนั้นFooถูกต้องตามมาตรฐาน C++ แต่ถือว่าไม่ถูกต้องตามมาตรฐานเนื่องจากเป็นการประกาศที่ไม่สามารถโอเวอร์โหลดได้[ 3 ]ทั้งนี้เนื่องจากคำจำกัดความของการโอเวอร์โหลดฟังก์ชันจะพิจารณาเฉพาะชื่อฟังก์ชัน รายการประเภทพารามิเตอร์ และเนมสเปซที่ครอบคลุม (ถ้ามี) เท่านั้น ไม่ได้พิจารณาประเภทการส่งคืน[ 4 ]อย่างไรก็ตาม ฟังก์ชันเหล่านี้ยังคงสามารถเรียกได้โดยการระบุลายเซ็นให้กับคอมไพเลอร์อย่างชัดเจน ดังที่แสดงโดยโปรแกรมต่อไปนี้

import std ;โดยใช้std :: string ;int main ( int argc , char * argv []) { char c = 'c' ; // ให้คอมไพเลอร์ทำการเรียกstring r0 = Foo ( c ); // ระบุฟังก์ชันที่จะเรียกอย่างชัดเจนstring r1 = Foo < string > ( c ); string r2 = Foo < string , char > ( c ); string r3 = Foo < string , char > ( & c );// สร้างเอาต์พุต: // Return1, Return2, Full, PtrOverload std :: println ( "{}, {}, {}, {}" , r0 , r1 , r2 , r3 ); }
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Partial_template_specialization&oldid=1352218344 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การปรับแต่งแม่แบบบางส่วน

การกำหนดค่าเฉพาะของเทมเพลตบางส่วน (Partial template specialization ) เป็นรูปแบบเฉพาะของ การกำหนดค่าเฉพาะของเทมเพลต คลาส (Class template specialization ) โดยปกติจะใช้ใน ภาษาโปรแกรม...

แม่แบบและความเชี่ยวชาญเฉพาะด้าน

คลาสเทมเพลตนั้นแท้จริงแล้วคือเมตาคลาส: มันคือชนิดข้อมูลนามธรรมบางส่วนที่ให้คำแนะนำแก่คอมไพเลอร์เกี่ยวกับวิธีการสร้างคลาสที่มีสมาชิกข้อมูลที่เหมาะสม ตัวอย่างเช่น คอนเทนเนอร์มาตรฐานของ C++ คือคลาสเทมเพลต เมื่อโปรแกรมเมอร์ใช้เวกเตอร์...

ความเชี่ยวชาญเฉพาะด้าน

เทมเพลตสามารถมีประเภทพารามิเตอร์ได้มากกว่าหนึ่งประเภท คอมไพเลอร์รุ่นเก่าบางตัวอนุญาตให้กำหนดค่าเฉพาะให้กับพารามิเตอร์ของเทมเพลตได้เพียงอย่างใดอย่างหนึ่งเท่านั้น...

ตัวอย่าง

สมมติว่ามี KeyValuePair คลาสหนึ่งที่มีพารามิเตอร์เทมเพลตสองตัว ดังต่อไปนี้