คำถามติดแท็ก move-semantics

8
initializer_list และย้ายความหมาย
ฉันได้รับอนุญาตให้ย้ายองค์ประกอบออกจากไฟล์ std::initializer_list<T> ? #include <initializer_list> #include <utility> template<typename T> void foo(std::initializer_list<T> list) { for (auto it = list.begin(); it != list.end(); ++it) { bar(std::move(*it)); // kosher? } } เนื่องจากstd::intializer_list<T>ต้องการความสนใจของคอมไพเลอร์เป็นพิเศษและไม่มีค่าความหมายเหมือนคอนเทนเนอร์ปกติของไลบรารีมาตรฐาน C ++ ฉันควรจะปลอดภัยดีกว่าขอโทษและถาม

4
ทำไมเราลอกแล้วย้าย?
ฉันเห็นรหัสที่ไหนสักแห่งที่มีคนตัดสินใจคัดลอกออบเจ็กต์แล้วย้ายไปยังสมาชิกข้อมูลของคลาส สิ่งนี้ทำให้ฉันสับสนเพราะฉันคิดว่าจุดทั้งหมดของการเคลื่อนไหวคือการหลีกเลี่ยงการคัดลอก นี่คือตัวอย่าง: struct S { S(std::string str) : data(std::move(str)) {} }; นี่คือคำถามของฉัน: ทำไมเราไม่ใช้ rvalue-reference str? สำเนาจะไม่แพงโดยเฉพาะอย่างยิ่งเช่นstd::string? อะไรคือสาเหตุที่ทำให้ผู้เขียนตัดสินใจทำสำเนาแล้วย้าย? เมื่อไหร่ที่ควรทำด้วยตัวเอง?

5
ฉันสามารถแสดงรายการ - เริ่มต้นเวกเตอร์ประเภทย้ายอย่างเดียวได้หรือไม่
ถ้าฉันส่งรหัสต่อไปนี้ผ่านสแนปชอต GCC 4.7 ของฉันมันจะพยายามคัดลอกunique_ptrs ลงในเวกเตอร์ #include <vector> #include <memory> int main() { using move_only = std::unique_ptr<int>; std::vector<move_only> v { move_only(), move_only(), move_only() }; } เห็นได้ชัดว่าไม่สามารถทำงานได้เนื่องจากstd::unique_ptrไม่สามารถคัดลอกได้: ข้อผิดพลาด: การใช้ฟังก์ชันที่ถูกลบ 'std :: unique_ptr <_Tp, _Dp> :: unique_ptr (const std :: unique_ptr <_Tp, _Dp> &) [ด้วย _Tp = int; _Dp = std :: default_delete; …

3
จะบังคับใช้ความหมายการย้ายได้อย่างไรเมื่อเวกเตอร์เติบโตขึ้น
ฉันมีstd::vectorวัตถุของชั้นAหนึ่ง คลาสไม่สำคัญและมีตัวสร้างการคัดลอกและย้ายตัวสร้างที่กำหนดไว้ std::vector<A> myvec; ถ้าฉันเติมเวกเตอร์ด้วยAวัตถุ (โดยใช้เช่นmyvec.push_back(a)) เวกเตอร์จะมีขนาดใหญ่ขึ้นโดยใช้ตัวสร้างการคัดลอกA( const A&)เพื่อสร้างอินสแตนซ์สำเนาใหม่ขององค์ประกอบในเวกเตอร์ ฉันสามารถบังคับใช้ตัวสร้างการย้ายของคลาสAแทนได้หรือไม่?

4
เหตุใดจึงไม่มีการกำหนดค่าการย้าย / ย้ายตัวสร้างเริ่มต้น
ฉันเป็นโปรแกรมเมอร์ธรรมดา ๆ ตัวแปรสมาชิกชั้นเรียนของฉันส่วนใหญ่มักประกอบด้วยประเภท POD และ STL-container ด้วยเหตุนี้ฉันจึงแทบไม่ต้องเขียนตัวดำเนินการกำหนดหรือคัดลอกตัวสร้างเนื่องจากจะใช้งานโดยค่าเริ่มต้น เพิ่มสิ่งนี้ถ้าฉันใช้std::moveกับวัตถุที่ไม่สามารถเคลื่อนย้ายได้มันจะใช้ตัวดำเนินการกำหนดหมายความว่าstd::moveปลอดภัยอย่างสมบูรณ์ เนื่องจากฉันเป็นโปรแกรมเมอร์ธรรมดาฉันจึงต้องการใช้ประโยชน์จากความสามารถในการย้ายโดยไม่ต้องเพิ่มตัวสร้างการย้าย / ตัวดำเนินการกำหนดให้กับทุกชั้นเรียนที่ฉันเขียนเนื่องจากคอมไพเลอร์สามารถนำไปใช้เป็น " this->member1_ = std::move(other.member1_);..." แต่มันไม่มี (อย่างน้อยก็ไม่ใช่ใน Visual 2010) มีเหตุผลพิเศษสำหรับสิ่งนี้หรือไม่? ที่สำคัญกว่า; มีวิธีใดบ้างที่จะหลีกเลี่ยงสิ่งนี้? อัปเดต: หากคุณมองลงไปที่คำตอบของ GManNickG เขาให้มาโครที่ยอดเยี่ยมสำหรับสิ่งนี้ และหากคุณไม่ทราบหากคุณใช้การย้ายความหมายคุณสามารถลบฟังก์ชัน swap member ได้

2
ประสิทธิภาพของ C ++ 11 push_back () พร้อม std :: move เทียบกับ emplace_back () สำหรับอ็อบเจ็กต์ที่สร้างไว้แล้ว
emplace_back()โดยทั่วไปแล้วใน C ++ 11 เป็นที่ต้องการ (ในแง่ของประสิทธิภาพ) push_back()เนื่องจากอนุญาตให้มีการก่อสร้างในสถานที่แต่ก็ยังคงเป็นเช่นนี้เมื่อใช้push_back(std::move())กับวัตถุที่สร้างไว้แล้วหรือไม่ ตัวอย่างเช่นemplace_back()ยังคงเป็นที่ต้องการในกรณีต่อไปนี้? std::string mystring("hello world"); std::vector<std::string> myvector; myvector.emplace_back(mystring); myvector.push_back(std::move(mystring)); // (of course assuming we don't care about using the value of mystring after) นอกจากนี้มีประโยชน์ในตัวอย่างข้างต้นหรือไม่ที่จะทำ: myvector.emplace_back(std::move(mystring)); หรือการย้ายที่นี่ซ้ำซ้อนทั้งหมดหรือไม่มีผล?

4
ขโมยทรัพยากรจาก std :: อนุญาตให้ใช้กุญแจของแผนที่ได้หรือไม่
ใน C ++ ตกลงเพื่อขโมยทรัพยากรจากแผนที่ที่ฉันไม่ต้องการอีกต่อไปหรือไม่? แม่นยำมากขึ้นถือว่าผมมีstd::mapกับstd::stringกุญแจและฉันต้องการที่จะสร้างเวกเตอร์ออกมาจากมันโดยการขโมยทรัพยากรของmapปุ่ม s std::moveใช้ โปรดทราบว่าการเข้าถึงเพื่อเขียนไปยังคีย์จะทำลายโครงสร้างข้อมูลภายใน (การเรียงลำดับคีย์) ของmapแต่ฉันจะไม่ใช้มันในภายหลัง คำถาม : ฉันสามารถทำสิ่งนี้ได้โดยไม่มีปัญหาหรือสิ่งนี้จะนำไปสู่ข้อผิดพลาดที่ไม่คาดคิดเช่นในตัวทำลายของmapเพราะฉันเข้าถึงมันในแบบที่std::mapไม่ได้ตั้งใจหรือไม่? นี่คือตัวอย่างโปรแกรม: #include<map> #include<string> #include<vector> #include<iostream> using namespace std; int main(int argc, char *argv[]) { std::vector<std::pair<std::string,double>> v; { // new scope to make clear that m is not needed // after the resources were stolen std::map<std::string,double> m; m["aLongString"]=1.0; …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.