Well ref
konstruuje obiekt odpowiedniego reference_wrapper
typu, aby przechowywać odwołanie do obiektu. Co oznacza, że kiedy aplikujesz:
auto r = ref(x);
Zwraca reference_wrapper
a nie bezpośrednie odwołanie do x
(tj T&
.). To reference_wrapper
(tj. r
) Zamiast tego utrzymuje T&
.
A reference_wrapper
jest bardzo przydatne, gdy chcesz emulować a reference
obiektu, który można skopiować (można go zarówno konstruować, jak i przypisywać do kopii ).
W C ++, po utworzeniu odniesienia (powiedzmy y
) do obiektu (powiedzmy x
), to y
i x
dzielić ten sam adres bazowy . Ponadto y
nie może odnosić się do żadnego innego przedmiotu. Nie możesz również utworzyć tablicy referencji, tj. Kod taki jak ten spowoduje błąd:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z};
return 0;
}
Jednak jest to zgodne z prawem:
#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;
}
Mówiąc o Twoim problemie cout << is_same<T&,decltype(r)>::value;
, rozwiązaniem jest:
cout << is_same<T&,decltype(r.get())>::value;
Pokażę wam program:
#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;
}
Tutaj poznajemy trzy rzeczy:
reference_wrapper
Przedmiotu (tutaj r
) mogą być wykorzystywane do tworzenia szereg odnośników , których nie było możliwe T&
.
r
faktycznie działa jak prawdziwe odniesienie (zobacz, jak r.get()=70
zmieniła się wartość y
).
r
to nie to samo, co T&
ale r.get()
jest. Oznacza to, że r
hold T&
ie, jak sama nazwa wskazuje, jest opakowaniem wokół referencji T&
.
Mam nadzieję, że ta odpowiedź jest więcej niż wystarczająca, aby wyjaśnić Twoje wątpliwości.