본문 바로가기
Language/C++

참조 전달 문법 std::move, std::forward

by W00gie 2022. 1. 13.

https://dev-record.tistory.com/62?category=956403 

 

이동생성자와 보편참조법(universal ref)

https://dev-record.tistory.com/56?category=956403 lvalue와 rvalue + 우측값 참조법 * lvalue와 rvalue란? C++ 내에서 모든 식들은 카테고리라는 부가적인 정보를 포함하고 있다. l-value와 r-value가 이에 해..

dev-record.tistory.com

 지난 포스팅에서 rvalue와 보편축약 등에 대해 정리해보았다. 이번 포스팅은 이를 응용한 forward 함수의 사용에 대해 알아본다. 지금까지 정리한 내용은 다음과 같다.

 c++에서 참조는 &와 &&으로 표현된다. &는 lvalue 참조를 의미하며, &&은 문맥에 따라서 rvalue 참조 또는 보편 참조를 뜻하며, 보편참조는 lvalue또는 rvalue가 될 수 있음을 의미한다. 

 

하지만 이런 참조형식의 데이터를 전달하기 위해선 어떻게 해야할까?

 

 

rvalue의 전달

이전 포스팅에서 소개한 move함수를 이용한다.

template< class T >
constexpr std::remove_reference_t<T>&& move( T&& t ) noexcept;

인자를 보편참조하고 있는 함수이기 때문에 lvalue 혹은 rvalue로 해석될 수 있지만 내부적으로 remove_reference_t 함수가 적용되어 있기 때문에 lvalue와 rvalue 모두 대응이 가능하다. 전달된 파라미터를 강제로 rvalue 참조로 캐스팅하여 리턴하는 기능을 수행한다.

 

보편참조의 전달

C++11 에서 forward 함수를 제공한다. move 와 다르게 무조건 rvalue가 아닌 함수가 호출될 때 인자가 가지고 있었던 타입 정보를 전달하는 기능을 한다.  타입정보란 C++ 내에 value category 로 불리는 lvalue, prvalue, xvalue 등을 의미한다.

template <class T>
constexpr T&& forward(std::remove_reference_t<T>& t) noexcept;  // (1)

template <class T>
constexpr T&& forward(std::remove_reference_t<T>&& t) noexcept;  // (2)

forward 함수는 파라미터값이  lvalue 참조일때 lvalue를 그대로 리턴하고 rvalue 참조가 파라미터일 경우 rvalue 참조로 캐스팅하여 move 연산을 수행한다. 다만 같은 rvalue가 아닌 move를 지원하는 rvalue로 캐스팅해준다. 이는 rvalue가 lvalue로 전달되는 상황을 방지하는 역할도 한다.

 

참조전달 문법의 필요성

1. 함수 템플릿을 정의하려고 한다.
2. 이 함수 템플릿 내부에 어떤 함수 X를 호출하는데 X의 인자 타입이 rvalue참조인것과 그렇지 않은 여러버전의 오버로딩이 존재하고 우리 함수의 인자에 따라 X의 오버로딩중 적절한 것을 선택해 호출할 필요가 있다.