티스토리 뷰
보편 참조는 참조 정보에 대해 부호화가 된다. 왼값의 경우에는 왼값 참조로 연역되고 오른값의 경우에는 비참조 형식으로 연역된다.
Widget widgetFactory(); // 오른값을 돌려주는 함수
Widget w;
func(w);
func(widgetFactory());
보편 참조를 사용하는 func 함수는 인수에 따라 연역되는 형식이 달라진다. func 함수에 왼값을 넘겨주면 다음과 같이 된다.
void func(Widget& && param);
// 최종 결과
void func(Widget& param);
Widget& && 에서 Widget& 로 변경되는데 그 이유는 바로 참조 죽약 때문이다. 참조에 대한 참조를 사용하게 되면 참조 축약이 일어나는데 다음의 경우의 수가 있다.
- 왼값에 대한 왼값
- 오른값에 대한 왼값
- 왼값에 대한 오른값
- 오른값에 대한 오른값
위 경우들에서 참조 축약을 적용하면 오른값 참조는 오직 오른값에 대한 오른값 뿐이다. 나머지는 모두 왼값 참조이다. std::forward 또한 위와 같이 동작한다. 간단하게 구현하면 다음과 같다.
template<typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
여기서 T 가 Widget& 라고 생각해보자 다음과 같이 된다.
Widget& && forward(typename remove_reference<Widget&>::type& param)
{
return static_cast<Widget& &&>(param);
}
// 참조 축약 적용
Widget& forward(Widget& param)
{
return static_cast<Widget&>(param);
}
오른값이 전달되는 경우에는 아래와 같다.
Widget&& forward(typename remove_reference<Widget>::type& param)
{
return static_cast<Widget&&>(param);
}
// 참조 축약 적용
Widget&& forward(Widget& param)
{
return static_cast<Widget&&>(param);
}
참조 축약 덕분에 왼값의 경우에는 왼값으로 오른값인 경우에는 오른값으로 캐스팅된다.
위에서 사용한 함수외에도 auto에도 적용이 가능하다.
Widget widgetFactory(); // 오른값을 돌려주는 함수
Widget w;
func(w);
func(widgetFactory());
auto&& w1 = w;
Widget& && w1 = w;
Widget& w1 = w;
auto&& w2 = widgetFactory();
Widget&& w2 = WidgetFactory();
typedef 에서도 적용이 가능하다.
template<typename T>
class Widget {
public:
typedef T&& RvalueRefToT;
...
};
Widget<int&> w; // int&로 선언
typedef int& && RvalueRefToT;
typedef int& RvalueRefToT;
참고 서적
스콧 마이어스, Effective Modern C++
'C++ > Effective Modern C++' 카테고리의 다른 글
[Effective Modern C++] 항목 30. 완벽 전달이 실패하는 경우들을 잘 알아두라. (0) | 2019.12.15 |
---|---|
[Effective Modern C++] 항목 29. 이동 연산이 존재하지 않고, 저렴하지 않고, 적용되지 않는다고 가정하라 (0) | 2019.12.14 |
[Effective Modern C++] 항목 27. 보편 참조에 대한 중복적재 대신 사용할 수 있는 기법들을 알아 두라 (0) | 2019.12.08 |
[Effective Modern C++] 항목 26. 보편 참조에 대한 중복적재를 피하라 (0) | 2019.12.01 |
[Effective Modern C++] 항목 25. 오른값 참조에는 std::move를, 보편 참조에는 std::forward를 사용하라 (0) | 2019.11.30 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Overloading
- Modern
- Unreal
- auto
- async
- C++14
- 보편참조
- C++
- 다이소
- 발아시기
- Effective Modern C++
- MOVE
- Join
- Future
- Forwarding
- 람다
- C
- thread
- const
- detach
- Effective
- 보편 참조
- std::move
- Perfect
- Override
- C++11
- CPP
- forward
- 포인터
- std::forward
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함