Итак, ref
создает объект соответствующего типа reference_wrapper
для хранения ссылки на объект. Это означает, что при подаче заявления:
auto r = ref(x);
Это возвращает reference_wrapper
, а не прямую ссылку на x
(т.е. T&
). Это reference_wrapper
(т.е. r
) вместо этого содержит T&
.
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}; // error: declaration of 'arr' as array of references
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;
}
/* OUTPUT:
5 7 8
*/
Говоря о вашей проблеме с cout << is_same<T&,decltype(r)>::value;
, решение таково:
cout << is_same<T&,decltype(r.get())>::value; // will yield true
Позвольте мне показать вам программу:
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
int main()
{
cout << boolalpha;
int x=5, y=7;
reference_wrapper<int> r=x; // or auto r = ref(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;
}
/* Ouput:
true
true
true
70
*/
Смотрите, здесь мы узнаем три вещи:
Объект reference_wrapper
(здесь r
) можно использовать для создания массива ссылок, что было невозможно с T&
.
r
на самом деле действует как реальная ссылка (посмотрите, как r.get()=70
изменило значение y
).
r
не то же самое, что T&
, но r.get()
есть. Это означает, что r
содержит T&
, т.е., как следует из названия, является оболочкой вокруг ссылки T&
.
Я надеюсь, что этого ответа более чем достаточно, чтобы объяснить ваши сомнения.
person
Ankit Acharya
schedule
20.10.2015
x = y;
в обоих случаях? - person juanchopanza   schedule 20.10.2015