Info
해당 글에서는 C++에서 사용되는 rvalue형식과 lvalue형식의 함침(collapsing)규칙에 대해서 간단하게 다룬다.
만약 템플릿을 사용해서 타입을 넘겼을 때, 내부적으로 해당 타입을 레퍼런스 형식으로 사용한다고 가정해보자.
template<T>
void test(T&& b) {
T& a = b;
...
...
...
}
int main() {
test(10);
}이럴 경우 int&&형식으로 템플릿 내부에서 처리되게 되는데 C++에서는 이때 ‘참조 함침’으로 이를 처리한다.
구체적인 규칙은 다음과 같다.
& &→&& &&→&&& &→&&& &&→&&
구체적인 예시는 다음과 같다.
#include <type_traits>
#include <iostream>
template<class T>
void test_forward(T&&) {
// T&& 형식을 출력해 보자 (C++ 타입 트레잇 + 문자열)
if (std::is_lvalue_reference<T&&>::value) std::cout<<"T&& is lvalue reference\n";
else if (std::is_rvalue_reference<T&&>::value) std::cout<<"T&& is rvalue reference\n";
else std::cout<<"T&& is not a reference?\n";
}
int main(){
int x = 0;
// 1) T = int
test_forward<int>(std::move(x)); // T&& → int&& → rvalue reference
// 2) T = int&
test_forward<int&>(std::move(x)); // T&& → int& && → 참조 합침 → int& → lvalue reference
}
----------------------------------------------
/* 출력 */
T&& is rvalue reference
T&& is lvalue reference
----------------------------------------------위 예제를 통해서 rvalue reference형식을 의도해서 전달해도 lvalue reference와 함침이 발생하여 의도치 않은 동작을 발생시킬 수 있게된다.
위 예제를 주의깊게 보면 금방 이해할 것이라 생각한다.