ใช้นามแฝงเทมเพลตมากกว่าเทมเพลต

Jan 09 2021

การอ่านหนังสือการแนะนำ c ++ (พิมพ์ครั้งที่สอง) ปี 2018ฉันไม่เข้าใจคำอธิบายเกี่ยวกับเทมเพลต (ฉันจะอธิบายด้านล่าง)

ลายเซ็นสองฟังก์ชั่นจะได้รับสำหรับfind_allฟังก์ชั่นที่ส่งกลับvectorของที่จะเกิดขึ้นทั้งหมดของค่าที่กำหนดในที่กำหนดiteratorcontainer

# 1:

template<typename C, typename V>
vector<typename C::iterator> find_all(C& c, V v);

# 2:

template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>> find_all(C& c, V v) ;

สามารถใช้ได้ทั้งสองแบบดังนี้:

string m {"Mary had a little lamb"};
for (auto p : find_all(m,'a')) // here p is a string::iterator
    cout << *p << endl; // spoiler alert : this will print 'a's

มีการกล่าวถึง # 2 โดยใช้เทมเพลตนามแฝง

ซ่อนรายละเอียดการใช้งานโดยการแนะนำประเภทนามแฝงสำหรับ Iterator

โดยผู้เขียน

แม้ว่าฉันคิดว่าฉันเข้าใจการใช้เทมเพลตทั้งสองอย่าง แต่ฉันไม่เข้าใจว่าทำไม # 2 ถึง "ซ่อนรายละเอียดการใช้งาน" และทำไมจึงเป็นที่ต้องการ ...

ขอบคุณ!

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

คำตอบ

6 NathanOliver Jan 09 2021 at 05:54

สมมติว่าคุณมีฐานรหัสเช่น

template<typename C, typename V>
vector<typename C::iterator> first(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> second(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> third(C& c, V v);
template<typename C, typename V>
vector<typename C::iterator> fourth(C& c, V v);
...

หากคุณตัดสินใจว่าต้องการเปลี่ยนเพื่อส่งคืนเวกเตอร์const_iteratorแทนคุณiteratorจะต้องเปลี่ยนฟังก์ชันเหล่านั้นทั้งหมด เมื่อใช้

template<typename T>
using Iterator = typename T::iterator;
template<typename C, typename V>
vector<Iterator<C>>  first(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>>  second(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>>  third(C& c, V v);
template<typename C, typename V>
vector<Iterator<C>>  fourth(C& c, V v);

สิ่งที่คุณต้องทำคือการเปลี่ยนแปลง

template<typename T>
using Iterator = typename T::iterator;

ถึง

template<typename T>
using Iterator = typename T::const_iterator;

และคุณทำเสร็จแล้ว นี่คือวิธี "ซ่อนรายละเอียดการใช้งาน"