티스토리 뷰

 보편 참조는 참조 정보에 대해 부호화가 된다. 왼값의 경우에는 왼값 참조로 연역되고 오른값의 경우에는 비참조 형식으로 연역된다.

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++
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함