l-values ส่งผ่านไปยัง std :: make_pair ได้อย่างไร
ในstd::make_pair
มีเพียงหนึ่งการดำเนินงาน C ++ 14 เป็นต้นไป
เทมเพลต <class T1, class T2> constexpr std :: pair <V1, V2> make_pair (T1 && t, T2 && u);
พารามิเตอร์ทั้งสองคือการอ้างอิงค่า R และตามนี้
การอ้างอิงค่า R ไม่สามารถเริ่มต้นด้วยค่า l
int i = 1;
char ch = 'a';
std::unordered_map<int, char> mp;
mp.insert(make_pair<int,char>(i, ch));
ดังนั้นเมื่อผมพยายามที่จะใช้ make_pair error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
ในรหัสดังกล่าวข้างต้นได้อย่างถูกต้องโยนข้อผิดพลาด
อย่างไรก็ตามมันทำงานได้อย่างสมบูรณ์แบบสำหรับโค้ดด้านบนหากฉันเปลี่ยนการวางอาร์กิวเมนต์ของเทมเพลตและเรียกมันว่า
mp.insert(make_pair(i, ch));
ฉันสับสนว่ามันทำงานอย่างไรi
และch
ทั้งสองเป็นค่า L ความละเอียดของอาร์กิวเมนต์แม่แบบแปลงค่า L เป็นค่า R หรือไม่หรือชอบวิธีการนี้
คำตอบ
พารามิเตอร์ของmake_pair
ยังไม่ได้ประกาศเป็น rvalue อ้างอิง แต่อ้างอิงส่งต่อ
การอ้างอิงการส่งต่อเป็นการอ้างอิงชนิดพิเศษที่เก็บรักษาหมวดหมู่ค่าของอาร์กิวเมนต์ของฟังก์ชันทำให้สามารถส่งต่อได้โดยใช้ std :: forward การอ้างอิงการส่งต่อ ได้แก่ :
- พารามิเตอร์ฟังก์ชันของเทมเพลตฟังก์ชันที่ประกาศเป็นการอ้างอิง rvalue ไปยังพารามิเตอร์เทมเพลตชนิด cv-unqualified ของเทมเพลตฟังก์ชันเดียวกันนั้น:
การส่งผลงาน referece กับทั้ง lvalues และ rvalues ด้วยความช่วยเหลือของแม่แบบหักข้อโต้แย้ง เมื่อส่งผ่าน lvalue พารามิเตอร์ template จะถูกอนุมานเป็น lvalue-reference หลังจากการยุบการอ้างอิงพารามิเตอร์ของฟังก์ชันคือ lvalue-reference ด้วย เมื่อส่งผ่าน rvalue พารามิเตอร์ template จะถูกอนุมานว่าไม่อ้างอิงพารามิเตอร์ของฟังก์ชันคือ rvalue-reference
ในทางกลับกันถ้าคุณระบุอาร์กิวเมนต์แม่แบบอย่างชัดเจนmake_pair<int,char>(...)
พารามิเตอร์ฟังก์ชันจะกลายเป็น rvalue-reference ตาม
คำตอบโดย songyuanyaoแล้วอธิบายว่าส่วนใหญ่ของสิ่งที่เกิดขึ้น แม้ว่าฉันอยากจะมีส่วนร่วมในการทำให้สิ่งนี้ทำงานได้โดยใช้อาร์กิวเมนต์เทมเพลตที่ชัดเจน คุณอยู่ที่นั่นเกือบทั้งหมด แต่ไม่ได้ทำตามขั้นตอนสุดท้าย
ฉันสับสนว่ามันทำงานอย่างไร
i
และch
ทั้งสองเป็นค่า L
ตรง คุณต้องการค่า l ซึ่งเป็นสิ่งที่คุณสามารถระบุได้ในอาร์กิวเมนต์ของเทมเพลต:
std::make_pair<int &, char &>(i, ch)
หรือรูปแบบที่ใช้ได้ในหลายกรณี:
std::make_pair<const int &, const char &>(i, ch)
การเขียนเพิ่มเติมเล็กน้อย แต่จำเป็นหากการหักอาร์กิวเมนต์ล้มเหลวด้วยเหตุผลบางประการ