std::reference_wrapper
มีประโยชน์เมื่อใช้ร่วมกับเทมเพลต มันห่อหุ้มวัตถุโดยการจัดเก็บตัวชี้ไว้เพื่อให้สามารถกำหนดใหม่และคัดลอกในขณะที่เลียนแบบความหมายตามปกติ นอกจากนี้ยังสั่งให้เทมเพลตไลบรารีบางรายการจัดเก็บการอ้างอิงแทนอ็อบเจ็กต์
พิจารณาอัลกอริทึมใน STL ซึ่งคัดลอก functors: คุณสามารถหลีกเลี่ยงการคัดลอกนั้นได้โดยเพียงแค่ส่งกระดาษห่ออ้างอิงที่อ้างอิงถึง functor แทน functor เอง:
unsigned arr[10];
std::mt19937 myEngine;
std::generate_n( arr, 10, std::ref(myEngine) );
ได้ผลเพราะ ...
… reference_wrapper
s โอเวอร์โหลดoperator()
ดังนั้นจึงสามารถเรียกได้เช่นเดียวกับอ็อบเจ็กต์ฟังก์ชันที่อ้างถึง:
std::ref(myEngine)()
… (un) เหมือนกับการอ้างอิงทั่วไปการคัดลอก (และการกำหนด) reference_wrappers
เพียงแค่กำหนดผู้ชี้
int i, j;
auto r = std::ref(i);
r = std::ref(j);
r = std::cref(j);
การคัดลอก Wrapper อ้างอิงนั้นเทียบเท่ากับการคัดลอกตัวชี้ซึ่งมีราคาถูกพอ ๆ กับที่ได้รับ ฟังก์ชันทั้งหมดที่เรียกใช้โดยธรรมชาติในการใช้งาน (เช่นฟังก์ชัน to operator()
) ควรอยู่ในแนวเดียวเนื่องจากเป็นแบบเส้นเดียว
reference_wrapper
s ถูกสร้างขึ้นผ่านstd::ref
และstd::cref
:
int i;
auto r = std::ref(i);
auto r2 = std::cref(i);
อาร์กิวเมนต์แม่แบบระบุประเภทและคุณสมบัติ CV ของวัตถุที่อ้างถึง r2
อ้างถึงconst int
และจะให้การอ้างอิงconst int
เท่านั้น การเรียกใช้ wrapper ที่มีconst
functors อยู่ในนั้นจะเรียกเฉพาะconst
ฟังก์ชัน member operator()
s
Rvalue initializers ไม่ได้รับอนุญาตเนื่องจากการอนุญาตให้ทำอันตรายมากกว่าผลดี เนื่องจากค่า rvalues จะถูกย้ายไป (และด้วยการรับประกันสำเนาถึงแม้ว่าจะหลีกเลี่ยงได้บางส่วนก็ตาม) เราจึงไม่ได้ปรับปรุงความหมาย เราสามารถแนะนำพอยน์เตอร์ห้อยได้เนื่องจากกระดาษห่อหุ้มอ้างอิงไม่ได้ยืดอายุการใช้งานของพอยน์ตี้
ปฏิสัมพันธ์ของห้องสมุด
ดังที่ได้กล่าวไว้ก่อนหน้านี้เราสามารถสั่งmake_tuple
ให้จัดเก็บข้อมูลอ้างอิงในผลลัพธ์tuple
โดยส่งผ่านอาร์กิวเมนต์ที่เกี่ยวข้องผ่านreference_wrapper
:
int i;
auto t1 = std::make_tuple(i);
auto t2 = std::make_tuple(std::ref(i));
โปรดทราบว่าสิ่งนี้แตกต่างเล็กน้อยforward_as_tuple
: ที่นี่ไม่อนุญาตให้ใช้ rvalues เป็นอาร์กิวเมนต์
std::bind
แสดงพฤติกรรมเดียวกัน: จะไม่คัดลอกอาร์กิวเมนต์ แต่เก็บข้อมูลอ้างอิงหากเป็นไฟล์reference_wrapper
. มีประโยชน์หากไม่จำเป็นต้องคัดลอกอาร์กิวเมนต์นั้น (หรือ functor!) แต่อยู่ในขอบเขตขณะที่ใช้bind
-functor
ความแตกต่างจากพอยน์เตอร์ธรรมดา
ไม่มีการกำหนดทิศทางเชิงไวยากรณ์ในระดับเพิ่มเติม พอยน์เตอร์จะต้องถูกอ้างถึงเพื่อให้ได้ค่า lvalue ไปยังอ็อบเจ็กต์ที่อ้างถึง reference_wrapper
s มีตัวดำเนินการแปลงโดยนัยและสามารถเรียกได้เหมือนวัตถุที่ห่อหุ้ม
int i;
int& ref = std::ref(i);
reference_wrapper
s ไม่เหมือนพอยน์เตอร์ไม่มีสถานะว่าง พวกเขาจะต้องเริ่มต้นด้วยการอ้างอิงหรืออื่นreference_wrapper
ๆ
std::reference_wrapper<int> r;
ความคล้ายคลึงกันคือความหมายของสำเนาตื้น: ตัวชี้และreference_wrapper
s สามารถกำหนดใหม่ได้
.
แทน->