"Rvalue reference"는 C++11에서 도입된 기능으로 오로지 Rvalue에만 할당될 수 있는 새로운 레퍼런스이다.
이를 선언하는 방법은 다음과 같다.
T&& // where T is non-template type parameter (such as int, or a user-defined type)
그럼 "Rvalue reference"가 어떻게 바인딩되는지 확인해보자.
#include <iostream>
int main(void)
{
int x = 0; // `x` is an lvalue of type `int`
int& xl = x; // `x1` is an lvalue of type `int&`
int&& xr = x; // error -- `x` is an lvalue
int&& xr2 = 0; // `xr2` is an lvalue of type `int&&` -- binds to the rvalue temporary, `0`
void f(int& x) {}
void f(int&& x) {}
f(x); // calls f(int&)
f(xl); // calls f(int&)
f(3); // calls f(int&&)
f(std::move(x)); // calls f(int&&)
f(xr2); // calls f(int&)
f(std::move(xr2)); // calls f(int&&)
return 0;
}
"Rvalue Reference"는 위와 같은 규칙을 가지게 된다.
그럼 다음과 같은 의문점이 생길 수 있다. 왜 `f(xr2)`는 `f(int&)` 함수를 호출하는 것일까? 분명한 것은 `xr2`의 타입이 `int&&`로 선언되었는데 말이다.
우선 Rvalue와 Lvalue의 차이점을 알 필요가 있다.
Rvalue와 Lvalue는 이름에서도 나오듯이 차이점이 뚜렷한 "값 카테고리"다.
그럼 어떤 부분에서 차이가 있을까?
그럼 이제 위의 예제에서 `int&& z = 0`에서 `f(z)`를 호출할 때 `f(int&)`가 호출되는지 설명하도록 하겠다.
앞서 설명했듯이, rvalue는 임시적인 값(메모리에서 위치를 가지지 않는 값)을 의미했다.
하지만 `main` 함수의 scope에서는 "rvalue"의 타입으로 선언된 변수 `z`는 더 이상 임시적인 값이 아니다. 즉, 메모리에서 위치를 가지고 있는 것이다. 이 말은 변수 `z`는 "rvalue"의 타입으로 초기화되었지만 "lvalue"의 속성을 가지게 된다.
그러므로 `f(int&)`가 호출되는 것이다.
[C++11 - library features] std::begin/end (0) | 2023.08.28 |
---|---|
[C++11] Move Semantics (0) | 2023.08.28 |
[C++11] Forwarding References(Universal References) (0) | 2023.08.28 |
[C++11] Variadic templates (0) | 2023.08.28 |
[C++11] Initializer lists (0) | 2023.08.28 |