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를 반환합니다 . 이것은 (즉 ) 대신 유지 됩니다.xT&reference_wrapperrT&
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_wrapperobject (herer) can be used to create an array of references which was not possible withT&.ractually acts like a real reference (see howr.get()=70changed the value ofy).ris not same asT&butr.get()is. This means thatrholdsT&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 |