Well ref
construye un objeto del reference_wrapper
tipo apropiado para contener una referencia a un objeto. Lo que significa que cuando aplicas:
auto r = ref(x);
Esto devuelve a reference_wrapper
y no una referencia directa a x
(ie T&
). En cambio, esto reference_wrapper
(es decir r
) se mantiene T&
.
Una reference_wrapper
es muy útil cuando se desea emular una reference
de un objeto que se puede copiar (que es a la vez -construible copia y copiar asignable ).
En C ++, una vez que crea una referencia (digamos y
) a un objeto (digamos x
), entonces y
y x
comparte la misma dirección base . Además, y
no puede referirse a ningún otro objeto. Además, no puede crear una matriz de referencias, es decir, un código como este arrojará un error:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z};
return 0;
}
Sin embargo, esto es legal:
#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;
}
Hablando de tu problema con cout << is_same<T&,decltype(r)>::value;
, la solución es:
cout << is_same<T&,decltype(r.get())>::value;
Déjame mostrarte un programa:
#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;
}
Mira aquí llegamos a saber tres cosas:
Un reference_wrapper
objeto (aquí r
) se puede usar para crear una matriz de referencias que no era posible con T&
.
r
en realidad actúa como una referencia real (vea cómo r.get()=70
cambió el valor de y
).
r
no es lo mismo que T&
pero r.get()
es. Esto significa que se r
mantiene, T&
es decir, como sugiere su nombre, es un envoltorio alrededor de una referencia T&
.
Espero que esta respuesta sea más que suficiente para explicar tus dudas.