อะไรคือความแตกต่างระหว่างคลาสเทมเพลตและเทมเพลตคลาส


88

อะไรคือความแตกต่างระหว่างคลาสเทมเพลตและเทมเพลตคลาส

คำตอบ:


127

นี่เป็นจุดทั่วไปของความสับสนสำหรับหลาย ๆ คน (รวมถึงหน้า Generic Programming บน Wikipedia บทแนะนำ C ++ และคำตอบอื่น ๆ ในหน้านี้) เท่าที่เกี่ยวข้องกับ C ++ ไม่มี "คลาสเทมเพลต" มีเพียง "เทมเพลตคลาส" เท่านั้น วิธีอ่านวลีนั้นคือ "เทมเพลตสำหรับคลาส" ซึ่งตรงข้ามกับ "เทมเพลตฟังก์ชัน" ซึ่งเป็น "เทมเพลตสำหรับฟังก์ชัน" อีกครั้ง: คลาสไม่ได้กำหนดแม่แบบแม่แบบกำหนดคลาส (และฟังก์ชัน) ตัวอย่างเช่นนี้เป็นแม่แบบโดยเฉพาะแม่แบบชั้นแต่มันเป็นไม่ได้ชั้นเรียน :

template<typename T> class MyClassTemplate
{ 
    ...
};

การประกาศMyClassTemplate<int> เป็นคลาสหรืออวดอ้างคลาสที่ยึดตามเทมเพลต ไม่มีคุณสมบัติพิเศษของคลาสที่ยึดตามเทมเพลตเทียบกับคลาสที่ไม่ได้ใช้เทมเพลต คุณสมบัติพิเศษของแม่ตัวเอง

วลี "template class" ไม่มีความหมายเนื่องจากคำว่า "template" ไม่มีความหมายเป็นคำคุณศัพท์เมื่อใช้กับคำนาม "class" เท่าที่ C ++ เกี่ยวข้อง มันแสดงถึงการมีอยู่ของคลาสที่เป็น (หรือกำหนด) แม่แบบซึ่งไม่ใช่แนวคิดที่มีอยู่ใน C ++

ฉันเข้าใจถึงความสับสนทั่วไปเนื่องจากน่าจะเป็นไปตามข้อเท็จจริงที่ว่าคำที่ปรากฏในลำดับ "template class" ในภาษาจริงซึ่งเป็นเรื่องราวอื่น ๆ ทั้งหมด


+1. บางครั้งอาจมีประโยชน์ไม่ว่าจะด้วยเหตุผลใดในการแยกแยะ "ต้นกำเนิด" ของคลาสซึ่งในกรณีนี้คุณสามารถใช้คำว่า "คลาสเทมเพลต" ได้อย่างสมเหตุสมผล - แต่ด้วยเหตุผลที่คุณให้มาคุณควรกำหนดอย่างรอบคอบว่าคุณหมายถึงอะไร .
j_random_hacker

1
@j_random_hacker - ดูคำตอบของ litb ด้านล่าง แต่ในระยะสั้นคำที่ต้องการสำหรับคำนั้นคือ "class template specialization"
ไม่แน่ใจว่า

@ ไม่แน่ใจ: ที่จริงแล้วฉันพบว่า "ความเชี่ยวชาญพิเศษของเทมเพลตคลาส" มีความคลุมเครือเล็กน้อยเนื่องจากยังสามารถอ้างถึงกระบวนการในการกำหนดความเชี่ยวชาญเฉพาะด้านอย่างชัดเจนหรือบางส่วนสำหรับเทมเพลตซึ่งเป็นสิ่งที่ไม่จำเป็นในการสร้าง "คลาส" ที่แท้จริง :) IMHO "class template instantiation" เป็นคำที่ชัดเจนที่สุด
j_random_hacker

2
@j_random_hacker: มีคำที่เหมาะสมสำหรับคำนี้คือ "Explicit class template specialization" และ "partial Explicit template template specialization" ยุ่งยาก แต่ไม่คลุมเครือ :)
ไม่แน่ใจ

1
−1คำศัพท์หมายถึงความหมายสำหรับผู้ที่ใช้คำศัพท์ การเริ่มวิเคราะห์ความหมายตามตัวอักษรไม่มีความหมาย เพียงแค่ลองใช้คำศัพท์อื่น ๆ จากชีวิตประจำวันหรือวิศวกรรม สรุปคำตอบนี้คือ hogwash คำตอบของ SHHโดยอ้างถึง Bjarne ก็โอเค
ไชโยและ hth - Alf

15

Bjarne Stroustrup ผู้สร้าง C ++ กล่าวในหนังสือของเขาThe C ++ Programming Language 4th edition , 23.2.1 การกำหนดเทมเพลท:

มีคนที่ทำให้ความแตกต่างความหมายระหว่างคำที่มีแม่แบบชั้นเรียนและแม่แบบเรียน ฉันไม่; มันจะละเอียดเกินไป: โปรดพิจารณาคำเหล่านั้นแทนกันได้ ในทำนองเดียวกันผมคิดว่าฟังก์ชั่นแม่แบบกันกับฟังก์ชั่นแม่แบบ


13

ความแตกต่างก็คือคำว่า "template class" ไม่มีอยู่ใน C ++ Standard เป็นคำที่ผู้คนส่วนใหญ่คิดว่าคำว่า "แม่แบบคลาส" สร้างความสับสน (เช่น บริษัท Qt Nokia และเดิมชื่อ Trolltech)

มาตรฐานไม่มีแนวคิดเกี่ยวกับเรื่องนี้ดังนั้นจึงขึ้นอยู่กับคนอื่น ๆ ที่จะสร้างความแตกต่าง บางคนใช้คำพ้องความหมายและบางคนบอกว่าคำว่า "คลาสเทมเพลต" หมายถึงเทมเพลตคลาสที่สร้างอินสแตนซ์หรือเฉพาะอย่างชัดเจนซึ่งจะทำให้เทียบเท่ากับคำว่า "class template specialization" ตามประวัติศาสตร์แล้วมันมีความหมายนี้ ข้อเขียน Reference Manualกำหนดได้ที่หน้า 343

คลาสที่สร้างจากเทมเพลตคลาสเรียกว่าคลาสเทมเพลตเนื่องจากคลาสที่กำหนดโดยเฉพาะโดยมีtemplate-class-nameเป็นชื่อ

ไม่ใช่ขั้วแม่แบบชั้นชื่อเทียบเท่ากับที่ไม่ใช่ขั้วแม่แบบ-IDtemplate-name < arguments >ที่ใช้ในปัจจุบันมาตรฐานและลงมา


เพื่อให้คุณคุ้นเคยกับข้อกำหนดในปัจจุบันซึ่งสำคัญกว่าการใช้คำศัพท์เก่าที่น่าสงสัย

// (1) defines a class template
template<typename T> class A { }; 

// (2) defines a class template explicit specialization 
template<> class A<int> { };

// (3) defines a class template partial specialization
template<typename T> class A<T*> { };

// (4) explicitly instantiates A<char>. 
template class A<char>;

// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
  • แขนเรียกว่าชั้น (2) และชั้นเรียนที่สร้างขึ้นโดย (4) และ (5) แม่แบบเรียน ฉันไม่แน่ใจว่า ARM รู้เรื่องเฉพาะบางส่วนแล้วหรือยัง แต่ถ้าเป็นเช่นนั้น (3) ไม่ถูกเรียกว่าคลาสเทมเพลตเนื่องจาก (3) ไม่ได้กำหนดคลาส แต่กำหนดเทมเพลต
  • ปัจจุบันมาตรฐานระดับสาย (2) และคนที่สร้างขึ้นโดย (4) และ (5) เฉพาะแม่แบบเรียน และ (3) จะเรียกว่าเป็นความเชี่ยวชาญบางส่วน , เมื่อเทียบกับความเชี่ยวชาญอย่างชัดเจน บางครั้งก็เรียก (3) ความเชี่ยวชาญ (3.2 / 5 - อย่างไรก็ตามการอธิบายลิงก์ข้ามอย่างชัดเจน) แม้ว่าฉันจะพบว่าสิ่งนี้ไม่ชัดเจนสำหรับฉันเพราะมันกำหนด "ความเชี่ยวชาญ" ว่าเป็น "คลาสฟังก์ชันหรือคลาส สมาชิก "ซึ่ง (3) ไม่พอใจ

3
ฮิฮิ. ใช่และอีกหลายคนยังคงมีส่วนร่วมในชุดนั้น โดยเฉพาะอย่างยิ่ง C ++ Faq lite และเอกสาร Qt ผู้เขียนคำถามที่พบบ่อยบอกฉันทางไปรษณีย์ว่าเขาต้องการใส่รายการคำถามที่พบบ่อยอื่นเพื่ออธิบายว่าการใช้คำว่า "ความเชี่ยวชาญพิเศษ" นั้นดีกว่าเนื่องจากจะทำให้เกิดความสับสนน้อยกว่า (การใช้ "ความเชี่ยวชาญเฉพาะด้าน" สำหรับประเภทของความเชี่ยวชาญพิเศษที่เขียนโดยผู้ใช้ แล้ว). พวก Qt บอกฉันว่าพวกเขาไม่ต้องการใช้คำว่า "class template" .... พวกเขาคิดว่ามัน "ผิดธรรมชาติ" เกินไป เลวมาก.
Johannes Schaub - litb

@ JohannesSchaub-litb: ARM เขียนโดย Bjarne Stroustrup และ Margaret Ellis ประมาณปี 1991 IIRC คำพูดของคุณจาก ARM ขัดแย้งอ้าง SHH จาก Bjarne ของ TCPPL 4 ฉบับ ดังนั้นจึงเป็นการดีที่คุณจะแยกความแตกต่างระหว่างคำศัพท์เก่า (ก่อนมาตรฐาน) และคำศัพท์ปัจจุบัน
ไชโยและ hth - Alf



0

คลาสเทมเพลต: คลาสที่มีนิยามทั่วไปหรือคลาสที่มีพารามิเตอร์ซึ่งไม่ได้สร้างอินสแตนซ์จนกว่าไคลเอ็นต์จะให้ข้อมูล มันถูกอ้างถึงศัพท์แสงสำหรับเทมเพลตธรรมดาคลาสเดียวกับเทมเพลตคำนำหน้าและการใช้ T เทมเพลตคลาส: การสร้างคลาสแต่ละคลาสถูกระบุโดยเทมเพลตคลาสซึ่งเกือบจะคล้ายกับวิธีการสร้างอ็อบเจ็กต์แต่ละรายการโดยใช้คลาส มันถูกอ้างถึงวัตถุของคลาสเทมเพลต Ex- classname objectname (รายการอาร์กิวเมนต์)


0

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


0

ดูบทความนี้ (จาก wg21 และตีพิมพ์ในปี 1992) :

คำศัพท์ที่สอดคล้องกัน

การโต้แย้งและความไม่เห็นด้วยส่วนใหญ่จนถึงปัจจุบันเกี่ยวข้องกับคำศัพท์ที่ใช้ในบทที่อธิบายแม่แบบ บ่อยที่สุดคือการใช้'function-template'และ'template-function'ที่แตกต่างกันเพื่อแสดงความคิดและความตั้งใจที่แตกต่างกัน เนื่องจากไม่มีการใช้การตั้งชื่อที่สอดคล้องกันผลลัพธ์คือความสับสนและการโต้แย้ง

สำหรับวัตถุประสงค์ของเอกสารนี้เป็นข้อเสนอสำหรับการนำไปใช้อย่างเป็นทางการโดยคณะกรรมการในการอภิปรายเกี่ยวกับแม่แบบและเพื่อวัตถุประสงค์ในการชี้แจงเอกสาร ฉันขอเสนอให้เราใช้การทำให้เป็นทางการโดยที่'-template' ต่อท้ายจะอธิบายถึงชุดประเภทหรือฟังก์ชันที่อธิบายโดยเทมเพลต และที่นำหน้า 'template-'ใช้เพื่ออธิบายนิยามเทมเพลตของส่วนหนึ่งของ'-template'เช่น a 'template-member-function'. ดังนั้น: -

  • 'function-template':ชุดของฟังก์ชันที่อธิบายโดยเทมเพลตซึ่งเป็นพารามิเตอร์สำหรับข้อมูลบางประเภทที่ให้ไว้เป็นอาร์กิวเมนต์ของเทมเพลตนั้น ตัวอย่างเช่น :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
  • 'class-template':ชุดของคลาสที่อธิบายโดยเทมเพลตซึ่งเป็นพารามิเตอร์สำหรับข้อมูลบางประเภทที่ให้ไว้เป็นอาร์กิวเมนต์ของเทมเพลตนั้น ตัวอย่างเช่น :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
  • 'template-function':ไม่อนุญาตให้ใช้คำนี้อีกต่อไป **
  • 'template-class':ไม่อนุญาตให้ใช้คำนี้ **

  • 'member-function-template':ไม่อนุญาตให้ใช้คำนี้เนื่องจากอธิบายถึงคุณสมบัติที่ไม่ได้รับการสนับสนุนโดยข้อกำหนดของเทมเพลต การใช้หลักการคำศัพท์ข้างต้นนี้จะอธิบายถึงสมาชิกของเทมเพลตที่ไม่ใช่คลาสซึ่งมีคำจำกัดความว่าเป็นเทมเพลต ตัวอย่างเช่น :-

class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};

อย่างไรก็ตามเนื่องจากขณะนี้เทมเพลตถูก จำกัด ไว้ในขอบเขตส่วนกลางเทมเพลตดังกล่าวจึงไม่ถูกต้อง

  • 'template-static-member-function':
  • 'template-member-function':
  • 'template-static-member':
  • 'template-static-data-member ' template-member ': เงื่อนไขทางเลือกสำหรับคำจำกัดความของสมาชิกที่ปรากฏแยกจาก' class-template 'ที่เป็นสมาชิก ตัวอย่างเช่น :-
template<class T> int S<T>::sep_member()
{ return i; }

เกี่ยวกับNormalคลาสที่คุณอธิบายข้างต้น: ฉันไม่ทราบว่าแม่แบบสมาชิกฟังก์ชันดังกล่าวถูกห้าม เป็นที่ยอมรับโดยคอมไพเลอร์ทั้งหมดที่ฉันพยายาม ฉันขาดอะไรไป?
dan_din_pantelimon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.