สมมติว่าเรามี string_view และ string_view อีกอันที่เป็นส่วนย่อยของ string_view แรก:
using namespace std; // just to shorten the example...
string_view s{"abc def"};
auto t = s.substr(4);
auto u = s.substr(0, 4);
cout << *(s.begin() + 4) << " " << *t.begin() << '\n';
cout << ((s.begin() + 4) == t.begin());
cout << (s.end() == t.end());
cout << ((s.begin() +5) == t.begin());
cout << ((s.begin() +5) == (t.begin() + 1));
cout << ((s.begin() + 4) == u.end()); // true
การเปรียบเทียบทั้งหมดจะทำงานบน Linux ภายใต้ gcc (9 HEAD) และ clang (8 HEAD) ภายใต้ Windows Visual c++ (15.7.6) ไม่อนุญาตให้ทำการเปรียบเทียบตัววนซ้ำสองตัว (ในโหมดแก้ไขข้อบกพร่องคุณจะได้รับข้อผิดพลาดในการยืนยัน cannot compare incompatible string_view iterators for equality
)
ถัดไปคือการเปรียบเทียบตัวชี้:
string_view s{"abc def"};
char const*& it{...}; // contains pointer to some location in s
auto t = s.substr(4);
it == s.end(); // works in gcc/clang - fails to compile in Visual studio
ดังนั้นเมื่อคุณพยายามแก้ไขใน Visual C++ คุณต้องการเปรียบเทียบที่อยู่ it == &*s.end()
แต่สิ่งนี้ล้มเหลวเนื่องจากตัววนซ้ำ end()
ไม่ควรถูกยกเลิกการอ้างอิง (UB ถ้าฉันจำได้อย่างถูกต้อง) ดังนั้นคุณจะได้รับ cannot dereference end string_view iterator
boost::string_view รองรับการเปรียบเทียบ it == s.end()
ดังนั้นฉันจึงแปลกใจที่การใช้งาน std นั้นมีข้อ จำกัด มากกว่า (และด้วยเหตุนี้จึงเป็นมิตรกับผู้ใช้น้อยกว่ามากสำหรับงานข้ามแพลตฟอร์ม)
ฉันเข้าใจว่าการเปรียบเทียบตัววนซ้ำของสองคอนเทนเนอร์ที่แตกต่างกันคือ UB แต่ string_view ไม่ใช่คอนเทนเนอร์ (ไม่มีหน่วยความจำพื้นฐาน) มันเป็นตัวชี้อัจฉริยะบางรูปแบบ ดังนั้นฉันคาดหวังว่าภาษาจะช่วยให้ฉันสามารถเปรียบเทียบตัววนซ้ำดังกล่าวเชื่อใจฉันว่า มุมมองกำลังชี้ไปยังชุดย่อยอื่น (หรือเหมือนกัน) ของคอนเทนเนอร์เดียวกัน
ดังนั้นคำถามของฉันคือฉันจะทำให้สิ่งนี้ใช้ได้กับ string_view เท่านั้นได้อย่างไร
(หมายถึงโดยไม่จำเป็นต้องสร้างคลาสช่วงที่กำหนดเองซึ่งจะมีตัววนซ้ำสองตัวเนื่องจากจะทำให้วัตถุประสงค์ของการใช้ std::string_view หมดไปตั้งแต่แรก)
it == s.end()
ส่วนที่เปลี่ยนเป็นit == &*s.end()
ทำให้เกิดข้อผิดพลาดในการยืนยันรันไทม์ซึ่งไม่ควรยกเลิกการอ้างอิงตัววนซ้ำ (สำหรับส่วนที่เหลือของพอยน์เตอร์ระหว่าง start และ end-1 ที่จะใช้งานได้) - person Domen Vrankar   schedule 24.09.2018