Well ref
создает объект соответствующего reference_wrapper
типа для хранения ссылки на объект. Что означает, когда вы подаете заявку:
auto r = ref(x);
Это возвращает a, reference_wrapper
а не прямую ссылку на x
(т.е. T&
). Это reference_wrapper
(т.е. r
) вместо этого выполняется T&
.
A reference_wrapper
очень полезен, когда вы хотите имитировать 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&
.
Надеюсь, этого ответа более чем достаточно, чтобы объяснить ваши сомнения.