O Well refconstrói um objeto do reference_wrappertipo apropriado para manter uma referência a um objeto. O que significa quando você se inscreve:
auto r = ref(x);
Isso retorna a reference_wrappere não uma referência direta a x(ou seja T&). Este reference_wrapper(isto é r), em vez disso, é válido T&.
A reference_wrapperé muito útil quando você deseja emular a referencede um objeto que pode ser copiado (é tanto construtível por cópia quanto atribuível por cópia ).
Em C ++, uma vez que você criar uma referência (digamos y) a um objeto (digamos x), em seguida, ye xcompartilham o mesmo endereço de base . Além disso, ynão pode se referir a nenhum outro objeto. Além disso, você não pode criar uma matriz de referências, ou seja, um código como este gerará um erro:
#include <iostream>
using namespace std;
int main()
{
int x=5, y=7, z=8;
int& arr[] {x,y,z};
return 0;
}
No entanto, isso é 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;
}
Falando sobre seu problema com cout << is_same<T&,decltype(r)>::value;, a solução é:
cout << is_same<T&,decltype(r.get())>::value;
Deixe-me mostrar um 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;
}
Veja aqui, nós conhecemos três coisas:
Um reference_wrapperobjeto (aqui r) pode ser usado para criar uma matriz de referências que não foi possível com T&.
rrealmente age como uma referência real (veja como r.get()=70mudou o valor de y).
rnão é o mesmo, T&mas r.get()é. Isso significa que rmantém, T&ou seja, como o nome sugere, é um invólucro em torno de uma referência T& .
Espero que esta resposta seja mais do que suficiente para esclarecer suas dúvidas.