기초 공부할때 Lvalue & Rvalue는 Left-value(왼쪽값), Right-value(오른쪽값)으로 이해하고 있었습니다.
( 연산자 ( = ) 를 기준으로 왼쪽에있다면 lvalue, 오른쪽에있다면 rvalue )
기본 C언어에서의 개념은 위처럼 볼 수 있더라도 C++에서는 좀더 확장적인 의미를 가지고 있어 정리를 해보도록 한다.
C++에서의 Lvalue, Rvalue 의 구분
우선 C++에서 모든 표현식은 Lvalue 또는 Rvalue 로 구분 됩니다.
Lvalue는 단일 표현식 이후에 사라지지 않고 계속 남아있는 객체를 의미 합니다.
이와 반대로 Rvalue는 표현식 이후에 더이상 존재하지 않는 임시적인 값을 의미 합니다.
위의 코드에서 밑줄로 표현되어 있는 부분들이 Rvalue 입니다.
x, y, z, p 등의 변수 이름들은 모두 Lvalue 이지만 3처럼 이름이아닌 상수값 혹은 임시객체 string("one") 은 표현식이 종료된후 더이상 참조할 수 없기 때문에 Rvalue 입니다.
마찬가지로 x+y, &x 또한 표현식이후 참조할 수 없는 Rvalue 입니다.
여기서 유심하게 보아야 할 부분은 전위증감, 후위증감 에 대한 값 입니다.
전위증감 ++x 는 Lvalue 이지만
후위증감 x++ 는 Rvalue 입니다.
증감 위치에 따라 Lvalue, Rvalue가 변하는 이유는 전위증감은 우선 ++를 사용하여 증가된 결과 값을 리턴 시키고난뒤 표현식을 실행하기떄문에 Lvalue 입니다.
반대로 후위증감의 경우 연산된 x본인이 아닌 연산후의 ++된 x를 복사하여 반환하기 때문에 Rvalue 입니다.
C++에서의 Lvalue Reference
위처럼 대략적으로 보았을때 Lvalue 인지 Rvalue 인지 모르는 경우도 있을 것 입니다.
그런경우 & 연산자를 사용하여 확인이 가능합니다.
&연산자는 Lvalue를 요구하기 때문에 표현식이 Rvalue일 경우 컴파일 오류를 반환합니다.
&(++x); // Lvalue 정상 작동
&(x++); // Rvalue 컴파일 오류!
기본적으로 사용하는 int& a = b; 의 형태의 사용법에서 참조자는 Lvalue 참조자 입니다.
즉, 좌측값(Lvalue)는 어떠한 메모리 위치를 가리키는데, & 참조연산자를 통하여 그 위치를 참조할 수 있는 것입니다.
C++에서의 Rvalue Reference
Visual Studio 2010 이상의 버전에서는 참조자 &&를 사용하여 Rvalue 참조자를 사용할 수 있습니다.
Rvalue Reference는 사용할때 타입에 &&를 붙여 사용합니다.
이름 그대로 Rvalue에 대한 참조를 가능하게 해줍니다.
우측값 참조가 왜 사용되는지에 대한 이유는 대표적으로 두가지를 볼 수 있습니다.
- move 의 구현 (move semantics)
- 와벽 전달 (perfect forwarding)
#include <iostream>
#include <string>
std::string& GetStringAddress(std::string&& String)
{
std::cout << "Address Of Param Instance On Function Stack : " << &(String) << std::endl;
return String;
}
int main()
{
std::string Hello = "Hello";
std::string World = " World!";
std::string&& HelloWorld = (std::string&&)GetStringAddress(Hello + World);
//rvalue reference를 수행하기를 원한다.
//Hello + World의 결과 값이 저장된 스택영역에 대해 정리X
std::cout << "Address Of Rvalue In Stack : " << &HelloWorld << std::endl;
}
위의 코드를 예시로보자면 기존에 Rvalue는 연산후 사라지게되는 것으로 알고있었으나 참조를 이용하여 사라지지않고 남아있는 모습을 볼 수 있습니다.
우측값 연산자에대한 상세한 예시는 다른 블로그를 한번 더 참조하도록 합니다.
아래의 블로그가 아주아주 상세하기때문에 몇번 정독해야 할 듯 합니다!
댓글