แรงจูงใจสำหรับส่วนขยายนี้ซึ่งตรวจพบได้โดยโปรแกรมที่สอดคล้องและไม่เป็นไปตามนั้นคือการทำให้vector<bool>พฤติกรรมเหมือนมากขึ้นvector<char>เมื่อเทียบกับการอ้างอิง (const และอื่น ๆ )
บทนำ
ตั้งแต่ปี 1998 vector<bool>ถูกเยาะเย้ยว่า "ไม่ใช่ตู้คอนเทนเนอร์" LWG 96ซึ่งเป็นหนึ่งในปัญหา LWG แรกเริ่มการอภิปราย วันนี้ 17 ปีต่อมาvector<bool>ส่วนใหญ่ยังคงไม่เปลี่ยนแปลง
บทความนี้กล่าวถึงตัวอย่างที่เฉพาะเจาะจงเกี่ยวกับลักษณะการทำงานของvector<bool>ความแตกต่างจากการสร้างอินสแตนซ์อื่น ๆ ทั้งหมดvectorซึ่งส่งผลต่อรหัสทั่วไป อย่างไรก็ตามเอกสารฉบับเดียวกันกล่าวถึงในระยะยาวคุณสมบัติด้านประสิทธิภาพที่ดีvector<bool>สามารถมีได้หากนำไปใช้อย่างเหมาะสม
สรุป : vector<bool>ไม่ใช่คอนเทนเนอร์ที่ไม่ดี มันมีประโยชน์มาก มันมีแค่ชื่อเสีย
กลับไปยัง const_reference
ตามที่แนะนำไว้ข้างต้นและมีรายละเอียดที่นี่สิ่งที่ไม่ดีเกี่ยวกับการvector<bool>ทำงานในโค้ดทั่วไปแตกต่างจากvectorอินสแตนซ์อื่น ๆ นี่คือตัวอย่างที่เป็นรูปธรรม:
#include <cassert>
#include <vector>
template <class T>
void
test(std::vector<T>& v)
{
using const_ref = typename std::vector<T>::const_reference;
const std::vector<T>& cv = v;
const_ref cr = cv[0];
assert(cr == cv[0]);
v[0] = 1;
assert(true == cv[0]);
assert(cr == cv[0]);
}
int
main()
{
std::vector<char> vc(1);
test(vc);
std::vector<bool> vb(1);
test(vb);
}
ข้อกำหนดมาตรฐานระบุว่าการยืนยันที่ทำเครื่องหมาย// Fires!จะทริกเกอร์ แต่เมื่อtestรันด้วยไฟล์vector<bool>. เมื่อรันด้วยvector<char>(หรือvectorอื่นๆboolเมื่อมีการกำหนดค่าที่ไม่ใช่ค่าเริ่มต้นที่เหมาะสมT) การทดสอบจะผ่านไป
การใช้ libc ++ พยายามลดผลกระทบเชิงลบของการvector<bool>ทำงานที่แตกต่างกันในโค้ดทั่วไป สิ่งหนึ่งที่ทำได้เพื่อให้บรรลุเป้าหมายนี้คือการสร้าง vector<T>::const_referenceการอ้างอิงพร็อกซีเช่นเดียวกับที่ระบุvector<T>::referenceยกเว้นว่าคุณไม่สามารถกำหนดผ่านมันได้ นั่นคือบน libc ++ โดยvector<T>::const_referenceพื้นฐานแล้วจะเป็นตัวชี้ไปที่บิตภายในตัวvectorแทนที่จะเป็นสำเนาของบิตนั้น
บน libc ++ ข้างต้นtestส่งผ่านสำหรับทั้งสองvector<char>และvector<bool>.
ราคาเท่าไหร่?
ข้อเสียคือส่วนขยายนี้ตรวจพบดังที่แสดงในคำถาม อย่างไรก็ตามมีโปรแกรมเพียงไม่กี่โปรแกรมเท่านั้นที่สนใจเกี่ยวกับประเภทของนามแฝงนี้และโปรแกรมอื่น ๆ ก็ให้ความสำคัญกับพฤติกรรม
อะไรคือแรงจูงใจสำหรับการไม่ปฏิบัติตามนี้?
เพื่อให้ไคลเอ็นต์ libc ++ มีพฤติกรรมที่ดีขึ้นในโค้ดทั่วไปและบางทีหลังจากการทดสอบภาคสนามเพียงพอแล้วให้เสนอส่วนขยายนี้เป็นมาตรฐาน C ++ ในอนาคตเพื่อการปรับปรุงอุตสาหกรรม C ++ ทั้งหมด
ข้อเสนอดังกล่าวอาจมาในรูปแบบของคอนเทนเนอร์ใหม่ (เช่นbit_vector) ที่มี API แบบเดียวกับปัจจุบันvector<bool>แต่มีการอัปเกรดเล็กน้อยเช่นที่const_referenceกล่าวถึงในที่นี้ ตามด้วยการเลิกใช้งาน (และการนำออกในที่สุด) ของvector<bool>ความเชี่ยวชาญพิเศษ bitsetยังสามารถใช้การอัปเกรดเล็กน้อยในแผนกนี้เช่นเพิ่มconst_referenceและชุดตัวทำซ้ำ
นั่นคือในการหวนbitsetคือการvector<bool>(ซึ่งควรจะเปลี่ยนชื่อไปbit_vector- หรืออะไรก็ตาม) เป็นคือการarray vectorและการเปรียบเทียบควรจะถือเป็นจริงหรือไม่ที่เรากำลังพูดถึงboolเป็นvalue_typeของและvectorarray
มีหลายตัวอย่างของคุณลักษณะ C ++ 11 และ C ++ 14 ที่เริ่มต้นเป็นส่วนขยายใน libc ++ นี่คือการพัฒนามาตรฐาน ประสบการณ์ด้านบวกที่แสดงให้เห็น จริงมีอิทธิพลอย่างมาก พื้นบ้านมาตรฐานเป็นกลุ่มที่อนุรักษ์นิยมเมื่อต้องเปลี่ยนข้อกำหนดที่มีอยู่ (ตามที่ควรจะเป็น) การเดาแม้ว่าคุณจะแน่ใจว่าคุณเดาถูก แต่ก็เป็นกลยุทธ์ที่มีความเสี่ยงในการพัฒนามาตรฐานที่เป็นที่ยอมรับในระดับสากล
vector<bool>รากฐานชั้นหนึ่งได้หรือไม่?