refCấu trúc tốt một đối tượng có reference_wrapperkiểu thích hợp để chứa một tham chiếu đến một đối tượng. Có nghĩa là khi bạn đăng ký:
auto r = ref(x);
Điều này trả về a reference_wrappervà không phải là tham chiếu trực tiếp đến x(tức là T&). Điều này reference_wrapper(tức là r) thay vì giữ T&.
A reference_wrapperrất hữu ích khi bạn muốn mô phỏng một referenceđối tượng có thể được sao chép (nó vừa có thể sao chép-xây dựng vừa có thể sao chép-gán được ).
Trong C ++, khi bạn tạo một tham chiếu (nói y) đến một đối tượng (nói x), sau đó yvà xchia sẻ cùng một địa chỉ cơ sở . Hơn nữa, ykhông thể tham chiếu đến bất kỳ đối tượng nào khác. Ngoài ra, bạn không thể tạo một mảng tham chiếu, tức là mã như thế này sẽ gây ra lỗi:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z};
return 0;
}
Tuy nhiên điều này là hợp pháp:
#include <iostream>
#include <functional> // for reference_wrapper
using namespace std;
int main()
{
int x=5, y=7, z=8;
reference_wrapper<int> arr[] {x,y,z};
for (auto a: arr)
cout << a << " ";
return 0;
}
Nói về vấn đề của bạn với cout << is_same<T&,decltype(r)>::value;, giải pháp là:
cout << is_same<T&,decltype(r.get())>::value;
Hãy để tôi cho bạn xem một chương trình:
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
int main()
{
cout << boolalpha;
int x=5, y=7;
reference_wrapper<int> r=x;
cout << is_same<int&, decltype(r.get())>::value << "\n";
cout << (&x==&r.get()) << "\n";
r=y;
cout << (&y==&r.get()) << "\n";
r.get()=70;
cout << y;
return 0;
}
Xem ở đây, chúng ta biết ba điều:
Một reference_wrapperđối tượng (ở đây r) có thể được sử dụng để tạo một mảng tham chiếu mà không thể với T&.
rthực sự hoạt động như một tham chiếu thực (xem r.get()=70giá trị của đã thay đổi như thế nào y).
rkhông giống như T&nhưng r.get()là. Điều này có nghĩa rằng rgiữ T&nghĩa như tên gọi của nó cho thấy là một wrapper xung quanh một tài liệu tham khảo T& .
Tôi hy vọng câu trả lời này là quá đủ để giải thích những nghi ngờ của bạn.