สั้น ๆ (ที่ชัดเจน) การสร้างสตริงสไตล์ C ก่อนจากนั้นจึงใช้สิ่งนั้นเพื่อสร้างสตริง std :: มีวิธีที่เร็วกว่า / ทางเลือก / "ดีกว่า" ในการเริ่มต้นสตริงจากเวกเตอร์ของอักขระหรือไม่?
สั้น ๆ (ที่ชัดเจน) การสร้างสตริงสไตล์ C ก่อนจากนั้นจึงใช้สิ่งนั้นเพื่อสร้างสตริง std :: มีวิธีที่เร็วกว่า / ทางเลือก / "ดีกว่า" ในการเริ่มต้นสตริงจากเวกเตอร์ของอักขระหรือไม่?
คำตอบ:
วิธีที่ดีที่สุดคือใช้ตัวสร้างต่อไปนี้:
template<class InputIterator> string (InputIterator begin, InputIterator end);
ซึ่งจะนำไปสู่บางสิ่งเช่น:
std::vector<char> v;
std::string str(v.begin(), v.end());
ฉันคิดว่าคุณสามารถทำได้
std::string s( MyVector.begin(), MyVector.end() );
โดยที่ MyVector คือ std :: vector ของคุณ
_ITERATOR_DEBUG_LEVEL=1(ซึ่งในกรณีนี้ดูเหมือนว่าจะทำงานได้ดี)
ด้วย C ++ 11 ที่คุณสามารถทำได้std::string(v.data())หรือหากเวกเตอร์ของคุณไม่ได้มีที่สิ้นสุด'\0'std::string(v.data(), v.size())
string(&v[0], v.size())ควรใช้งานได้เช่นกัน แต่หลังจากassert(not v.empty());นั้นเนื่องจากถ้าเวกเตอร์ว่างเปล่าทั้งสองอย่างv[0]และv.front()จะเรียกใช้พฤติกรรมที่ไม่ได้กำหนด นอกเหนือจากความเรียบง่ายทางวากยสัมพันธ์ที่ไม่ต้องใช้แอดเดรสของตัวดำเนินการแล้วยังเป็นประโยชน์ที่แท้จริงของdata()ฟังก์ชันC ++ 11 ซึ่งทำงานได้แม้ในเวกเตอร์ว่างเปล่า
std::string(v.data())อาจทำให้สตริงยาวขึ้น ดังนั้นอย่าใช้วิธีนี้
std::string(v.data(), v.size())ซึ่งได้รับการกล่าวถึงอย่างชัดเจนในคำตอบด้วยเหตุผลที่แท้จริง?
std::string s(v.begin(), v.end());
โดยที่ v เป็นอะไรที่ทำซ้ำได้ (โดยเฉพาะ start () และ end () ต้องส่งคืน InputIterators)
เพื่อความสมบูรณ์อีกวิธีหนึ่งคือstd::string(&v[0])(แม้ว่าคุณจะต้องแน่ใจว่าสตริงของคุณสิ้นสุดด้วยค่าว่างและstd::string(v.data())โดยทั่วไปเป็นที่ต้องการ
ความแตกต่างคือคุณสามารถใช้เทคนิคเดิมในการส่งเวกเตอร์ไปยังฟังก์ชันที่ต้องการแก้ไขบัฟเฟอร์ซึ่งคุณไม่สามารถทำได้ด้วย. data ()
data()ถึงใช้เพื่อแก้ไขบัฟเฟอร์ไม่ได้? สำหรับฉันดูเหมือนว่าถ้าคุณเรียกdata()ใช้เวกเตอร์ที่ไม่ใช่ const มันจะส่งกลับ a T *(และถ้าเวกเตอร์ของคุณเป็น const 'v [0] `ก็จะส่งกลับค่าT const &)
vเป็นสตริง แต่ประเภทเป้าหมายเป็นสตริงและvเป็นเวกเตอร์ (แต่เป็นเรื่องดีที่เห็นว่า C ++ 17 จะให้ความเท่าเทียมกันของสตริงกับเวกเตอร์)
ฉันชอบคำตอบของสเตฟาน (11 ก.ย. 56) แต่อยากจะทำให้เข้มแข็งขึ้นอีกหน่อย:
หากเวกเตอร์ลงท้ายด้วยตัวยุติโมฆะคุณไม่ควรใช้ (v.begin (), v.end ()): คุณควรใช้ v.data () (หรือ & v [0] สำหรับสิ่งที่อยู่ก่อน C ++ 17) .
ถ้า v ไม่มีเทอร์มิเนเตอร์ว่างคุณควรใช้ (v.begin (), v.end ())
หากคุณใช้ start () และ end () และเวกเตอร์มีศูนย์การยุติคุณจะลงท้ายด้วยสตริง "abc \ 0" ซึ่งมีความยาว 4 แต่ควรเป็น "abc" เท่านั้น
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());
std::vector<char> v2(std::move(v))แต่std::stringเป็นวัตถุใหม่