สั้น ๆ (ที่ชัดเจน) การสร้างสตริงสไตล์ 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
เป็นวัตถุใหม่