본문 바로가기
프로그래밍 언어/C++

C++ 11 / 보편적 참조(universal reference)와 forward

by Nighthom 2023. 2. 15.

1. 보편적 참조 선언

template <typename T>
void wrapper(T&& t);

어떠한 템플릿에 대해 위와 같이 선언하는 것을 보편적 참조라고 한다. 

 

2. 왜 보편적 레퍼런스인가? 

컴파일러가 참조 겹침 규칙을 활용해서 t가 rvalue일 경우 rvalue 참조로 타입 추론을, lvalue일 경우 lvalue참조로 타입 추론을 해 주기 때문이다. 참조 겹침 규칙은 아래와 같은 식이라고 보면 된다.

typedef int& T;
T& r1;   // int& &; r1 은 int&
T&& r2;  // int & &&;  r2 는 int&

typedef int&& U;
U& r3;   // int && &; r3 는 int&
U&& r4;  // int && &&; r4 는 int&&​

& & -> &

& && -> &

&& & -> &

&& && -> &&

&&으로 선언했을 경우 &이 넘어오면 & &&이 되므로 &으로 추론, &&이 넘어올 경우 && &&이 되므로 &&으로 추론

 

3. 보편적 레퍼런스를 활용해 전달받은 rvalue, lvalue를 그대로 전달하고 싶을 경우

보편적 레퍼런스를 활용해서 내부적으로 함수를 호출할 때, 만약 rvalue로 넘어온 파라미터는 rvalue로 전달하고, lvalue로 넘어온 파라미터는 lvalue로 전달하고 싶은 경우가 있을 수 있다. 그럴 때 활용할 수 있는 함수가 바로 forward이다. 

template <typename T>
void wrapper(T&& t) {
	wrap(std::forward(a));	// rvalue일 경우 move처럼 동작하고, lvalue일경우 그냥 파라미터 전달!
}​

forward 함수는 rvalue를 넘기면 move 함수를 호출하고, 그렇지 않다면 move 함수를 호출하지 않는다. 따라서 rvalue로 넘어온 파라미터는 rvalue로, lvalue로 넘어온 파라미터는 lvalue로 사용할 수 있다. 

 

 

'프로그래밍 언어 > C++' 카테고리의 다른 글

C++ 11 / 스마트 포인터 shared_ptr, weak_ptr  (0) 2023.02.15
C++ 11 / 스마트 포인터 unique_ptr  (0) 2023.02.15
C++ 11 / move함수  (0) 2023.02.15
C++ 11 / Rvalue 참조  (0) 2023.02.15
C++ 문법 / 예외  (0) 2023.02.15

댓글