แรงจูงใจสำหรับส่วนขยายนี้ซึ่งตรวจพบได้โดยโปรแกรมที่สอดคล้องและไม่เป็นไปตามนั้นคือการทำให้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
ของและvector
array
มีหลายตัวอย่างของคุณลักษณะ C ++ 11 และ C ++ 14 ที่เริ่มต้นเป็นส่วนขยายใน libc ++ นี่คือการพัฒนามาตรฐาน ประสบการณ์ด้านบวกที่แสดงให้เห็น จริงมีอิทธิพลอย่างมาก พื้นบ้านมาตรฐานเป็นกลุ่มที่อนุรักษ์นิยมเมื่อต้องเปลี่ยนข้อกำหนดที่มีอยู่ (ตามที่ควรจะเป็น) การเดาแม้ว่าคุณจะแน่ใจว่าคุณเดาถูก แต่ก็เป็นกลยุทธ์ที่มีความเสี่ยงในการพัฒนามาตรฐานที่เป็นที่ยอมรับในระดับสากล
vector<bool>
รากฐานชั้นหนึ่งได้หรือไม่?