Ну ref
конструює об'єкт відповідного reference_wrapper
типу для зберігання посилання на об'єкт. Що означає, коли ви подаєте заявку:
auto r = ref(x);
Це повертає a, reference_wrapper
а не пряме посилання на x
(тобто T&
). Це reference_wrapper
(тобто r
) натомість справедливо T&
.
A reference_wrapper
дуже корисний, коли ви хочете емулювати a reference
об'єкта, який можна скопіювати (він одночасно може бути створений для копіювання та призначений для копіювання) ).
У C ++, як тільки ви створюєте посилання (скажімо y
) на об'єкт (скажімо x
), тоді y
і x
надаєте ту саму базову адресу . Крім того, y
не може посилатися на будь-який інший об'єкт. Крім того, ви не можете створити масив посилань, тобто такий код викличе помилку:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z};
return 0;
}
Однак це законно:
#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;
}
Говорячи про вашу проблему cout << is_same<T&,decltype(r)>::value;
, рішення:
cout << is_same<T&,decltype(r.get())>::value;
Дозвольте показати програму:
#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;
}
Дивіться тут, ми дізнаємось про три речі:
reference_wrapper
Об'єкт (тут r
) можна використовувати для створення масиву посилань , які не вдалися з T&
.
r
насправді діє як справжнє посилання (подивіться, як r.get()=70
змінилося значення y
).
r
не те саме, що є, T&
але r.get()
є. Це означає, що r
має місце, T&
тобто, як випливає з назви, є обгорткою навколо посилання T&
.
Сподіваюся, цієї відповіді більш ніж достатньо, щоб пояснити ваші сумніви.