원래는 보편 참조(universal reference)였으나 C++17로 넘어오며 명칭이 변경 되었다.

활용할 일이 많지는 않다고 한다.

 

&&는 무조건 오른값 참조인가? -> X

template, auto같은 형식 연역(type deduction)이 발생할 때만 등장한다.

 

왼값 참조로 전달하면 왼값 참조, 오른값 참조로 전달하면 오른값 참조로 동작한다.

단, const 같은 키워드가 붙으면 오른값 참조로만 작동한다.

template<typename T>
void Test_ForwardingRef(T&& param) // 전달 참조
// ----
template<typename T>
void Test_ForwardingRef(const T&& param) // 오른값 참조만 가능

 

오른값 참조에 관한 추가사항

 

void TestRvalueRef(Knight&& knight) {}

Knight k1;
Knight&& k2 = k1;
Test_RValueRef(k2); // 오류!

 

k2는 오른값 참조 타입임에도 불구하고 정작 함수에는 넘겨줄수 없다.

그 이유는 오른값 참조 타입은 맞지만 k2자체는 왼값이기 때문이다.

왼값과 오른값의 정의를 잘 생각해보면 무리없이 이해할 수 있다. (왼값: 단일식을 벗어나도 유지되는 값)

 

void TestRvalueRef(Knight&& knight) {}

Knight k1;
Knight&& k2 = k1;
Test_RValueRef(move(k2)); // OK!

 

또한, 함수 호출시에 move로 오른값 참조로 만들어서 넘겨줘도 매개변수로 사용할 때 다시 왼값이 되어버린다.

 

인자로 왼값 참조, 오른값 참조를 넘겨주면 무조건 왼값 참조로 변경된다.

해당 함수 내에서 전달 받았던 그대로 왼값 참조, 오른값 참조로 다른 함수를 호출하려면 forward를 이용하면 된다.

 

class Knight
{
public:
	Knight() { cout << "기본 생성자" << endl; }
	Knight(const Knight&) { cout << "복사 생성자" << endl; }
	Knight(Knight&&) noexcept { cout << "이동 생성자" << endl; }
};

void Test_Copy(Knight knight)
{
	// do something
}

template<typename T>
void Test_ForwardingRef(T&& param) // 전달 참조
{
	Test_Copy(forward<T>(param));
}

int main()
{
	Knight k1; // 기본 생성자

	Test_ForwardingRef(k1); // 복사 생성자
	Test_ForwardingRef(move(k1)); // 이동 생성자

	return 0;
}

 

앞으로 전달 참조는 무조건 forward로 받아주면 된다.

'C++ > Rookiss C++' 카테고리의 다른 글

[Modern C++] 스마트 포인터 (smart pointer) -完-  (0) 2022.09.01
[Modern C++] 람다 (lambda)  (0) 2022.08.31
[Modern C++] 오른값 참조 (rvalue reference)  (0) 2022.08.31
[Modern C++] #2  (0) 2022.08.31
[Modern C++] #1  (0) 2022.08.31

+ Recent posts