ทั้งสองstd::forward
และstd::move
ไม่ได้เป็นเพียงแค่ร่าย
X x;
std::move(x);
ด้านบนปลดเปลื้องการแสดงออก lvalue x
ของประเภท X เพื่อการแสดงออก rvalue ของประเภท X (xvalue ที่จะต้องแน่นอน) move
ยังสามารถยอมรับค่า rvalue:
std::move(make_X());
และในกรณีนี้มันเป็นฟังก์ชั่นระบุตัวตน: รับค่า rvalue ของประเภท X และส่งกลับค่า rvalue ของประเภท X
ด้วยstd::forward
คุณสามารถเลือกปลายทางได้:
X x;
std::forward<Y>(x);
ปลดล็อกนิพจน์ lvalue x
ของ type X ไปยังนิพจน์ประเภท Y มีข้อ จำกัด เกี่ยวกับสิ่งที่ Y สามารถเป็นได้
Y สามารถเป็นฐานของ X ที่สามารถเข้าถึงได้หรือการอ้างอิงไปยังฐานของ X. Y สามารถเป็น X หรืออ้างอิงถึง X หนึ่งไม่สามารถทิ้งตัวระบุ cv-qualifier ด้วยforward
แต่สามารถเพิ่ม cv-qualifier ได้ Y ไม่สามารถเป็นประเภทที่แปลงได้จาก X เท่านั้นยกเว้นผ่านการแปลงฐานที่สามารถเข้าถึงได้
ถ้า Y เป็นการอ้างอิง lvalue ผลลัพธ์จะเป็นนิพจน์ lvalue หาก Y ไม่ใช่การอ้างอิง lvalue ผลลัพธ์จะเป็นนิพจน์ rvalue (xvalue ที่จะแม่นยำ)
forward
สามารถรับอาร์กิวเมนต์ rvalue ก็ต่อเมื่อ Y ไม่ใช่การอ้างอิง lvalue นั่นคือคุณไม่สามารถใช้ค่า rvalue เป็น lvalue ได้ นี่คือเหตุผลด้านความปลอดภัยเนื่องจากการทำเช่นนั้นมักนำไปสู่การอ้างอิงที่ห้อยอยู่ แต่การส่งค่า rvalue ไปยัง rvalue นั้นใช้ได้และอนุญาต
หากคุณพยายามระบุ Y ให้กับบางสิ่งที่ไม่ได้รับอนุญาตข้อผิดพลาดจะถูกดักจับในเวลารวบรวมไม่ใช่เวลาทำงาน