C ++ std :: ref (T)와 T &의 차이점은 무엇입니까?
이 프로그램에 대해 몇 가지 질문이 있습니다.
#include <iostream>
#include <type_traits>
#include <functional>
using namespace std;
template <typename T> void foo ( T x )
{
auto r=ref(x);
cout<<boolalpha;
cout<<is_same<T&,decltype(r)>::value;
}
int main()
{
int x=5;
foo (x);
return 0;
}
출력은 다음과 같습니다.
false
std::ref
객체의 참조를 반환하지 않으면 무엇을하는지 알고 싶습니다 . 기본적으로 다음의 차이점은 무엇입니까?
T x;
auto r = ref(x);
과
T x;
T &y = x;
또한이 차이가 존재하는 이유를 알고 싶습니다. 왜 우리가 참조 가 필요 std::ref
하거나 std::reference_wrapper
(예 :) 때 T&
필요한가?
Well ref
은 객체에 reference_wrapper
대한 참조를 보유하기 위해 적절한 유형의 객체를 생성합니다. 즉, 신청할 때 :
auto r = ref(x);
이것은 (즉 )에 reference_wrapper
대한 직접 참조가 아닌 a를 반환합니다 . 이것은 (즉 ) 대신 유지 됩니다.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}; // 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
*/
여기에서 우리는 세 가지를 알게됩니다.
A
reference_wrapper
object (herer
) can be used to create an array of references which was not possible withT&
.r
actually acts like a real reference (see howr.get()=70
changed the value ofy
).r
is not same asT&
butr.get()
is. This means thatr
holdsT&
ie as its name suggests is a wrapper around a referenceT&
.
I hope this answer is more than enough to explain your doubts.
std::reference_wrapper
is recognized by standard facilities to be able to pass objects by reference in pass-by-value contexts.
For example, std::bind
can take in the std::ref()
to something, transmit it by value, and unpacks it back into a reference later on.
void print(int i) {
std::cout << i << '\n';
}
int main() {
int i = 10;
auto f1 = std::bind(print, i);
auto f2 = std::bind(print, std::ref(i));
i = 20;
f1();
f2();
}
This snippet outputs :
10
20
The value of i
has been stored (taken by value) into f1
at the point it was initialized, but f2
has kept an std::reference_wrapper
by value, and thus behaves like it took in an int&
.
A reference (T&
or T&&
) is a special element in C++ language. It allows to manipulate an object by reference and has special use cases in the language. For example, you cannot create a standard container to hold references: vector<T&>
is ill formed and generates a compilation error.
A std::reference_wrapper
on the other hand is a C++ object able to hold a reference. As such, you can use it in standard containers.
std::ref
is a standard function that returns a std::reference_wrapper
on its argument. In the same idea, std::cref
returns std::reference_wrapper
to a const reference.
One interesting property of a std::reference_wrapper
, is that it has an operator T& () const noexcept;
. That means that even if it is a true object, it can be automatically converted to the reference that it is holding. So:
- as it is a copy assignable object, it can be used in containers or in other cases where references are not allowed
- thanks to its
operator T& () const noexcept;
, it can be used anywhere you could use a reference, because it will be automatically converted to it.
참고URL : https://stackoverflow.com/questions/33240993/c-difference-between-stdreft-and-t
'developer tip' 카테고리의 다른 글
챗봇 개발을위한 튜토리얼이 있습니까? (0) | 2020.10.29 |
---|---|
angularjs ui-router의 상태간에 $ scope 데이터를 공유하려면 어떻게해야합니까? (0) | 2020.10.29 |
JavaScript에서 Array.map으로 요소 제거 (0) | 2020.10.29 |
JMS의 장점은 무엇입니까? (0) | 2020.10.29 |
WPF 확인란 바인딩 (0) | 2020.10.29 |