ใน C++ คลาสเทมเพลต std::reference_wrapper ช่วยให้สามารถห่อหุ้มอ้างอิง (reference) ไว้ในออบเจกต์ที่สามารถสร้างสำเนา (copy constructible) และมอบหมายค่า (copy assignable) ได้ ซึ่งเป็นสิ่งที่อ้างอิงทั่วไปทำไม่ได้โดยตรง
คุณสมบัติหลัก
- อินสแตนซ์ของ
std::reference_wrapperเป็นออบเจกต์ทั่วไป แต่สามารถแปลงเป็นT&ได้โดยอัตโนมัติ - ช่วยให้ส่งอ้างอิงไปยังฟังก์ชันที่รับพารามิเตอร์เป็น reference ได้ แม้ในบริบทที่ต้องการค่าที่คัดลอกได้ (เช่น การเก็บในคอนเทนเนอร์มาตรฐาน)
- รองรับการใช้งานกับ
std::bind,std::functionและอัลกอริทึมของ STL ที่ต้องการประเภทที่คัดลอกได้
ตัวอย่างโค้ด
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using namespace std;
void printChar(char& c) {
cout << c;
}
int main() {
char a = 'h', b = 'e', c = 'l', d = 'l', e = 'o';
char f = 'W', g = 'o', h = 'r', i = 'l', j = 'd';
// สร้างอาร์เรย์ของ reference_wrapper
reference_wrapper<char> refs[] = {a, b, c, d, e, f, g, h, i, j};
// ใช้งานเหมือนอ้างอิงทั่วไป
for (char& ch : refs) {
cout << ch;
}
cout << endl;
// ตัวอย่างการใช้กับ STL algorithm
vector<reference_wrapper<int>> vec;
int x = 10, y = 20, z = 30;
vec.push_back(x);
vec.push_back(y);
vec.push_back(z);
// แก้ไขค่าผ่าน reference_wrapper
for (auto& ref : vec) {
ref.get() *= 2;
}
cout << "ค่าหลังคูณ 2: " << x << " " << y << " " << z << endl;
return 0;
}
ผลลัพธ์
helloWorld ค่าหลังคูณ 2: 20 40 60
ข้อดีของการใช้ reference_wrapper
- เก็บอ้างอิงในคอนเทนเนอร์: ทำให้สามารถเก็บอ้างอิงใน
std::vector,std::listได้ - หลีกเลี่ยงการคัดลอก: เหมาะสำหรับออบเจกต์ขนาดใหญ่ที่ไม่ต้องการคัดลอก
- ความปลอดภัย: ไม่สามารถเป็น null ได้ (ต่างจาก pointer) และมี lifetime ที่ชัดเจน
การเข้าถึงค่า
ใช้เมธอด .get() เพื่อเข้าถึงอ้างอิงต้นฉบับ หรือใช้การแปลงแบบอัตโนมัติไปเป็น T&