본문 바로가기

C++

C++ 배우기 26(LValue / RValue)

C++ 이전에 C에서의 LValue와 RValue는 코드 연산 중에 대입 연산자(=)를 기준으로 왼쪽으로 올 수 있는 값이 LValue,

오른쪽에 존재하는 값이 RValue로 구분했다. 말 그대로 LeftValue / RightValue의 뜻을 가지고 있었다는 것이다.

하지만 지금 배우고있는 C++에서는 다른 관점으로 사용이 되고 있으므로 주의해야 한다고 한다.

 

LValue와 RValue

C++에서의 모든 표현식은 전부 Lvalue와 Rvalue로 나타낸다.

LValue는 단일 표현식 이후에도 사라지지 않고 지속되는 객체를 말한다. 한마디로 이름을 가지고 있는 객체를 뜻한다.

때문에 const 타입, 그리고 모든 변수들이 바로 LValue라고 할 수 있다.

 

RValue는 표현식이 종료된 후에 사라져서 더 이상 존재하지 않는 임시적인 값을 말한다.

상수 또는 임시 객체들이 RValue라고 할 수 있다.

 

밑의 예시를 보면 이해하기 쉬울 것이다.

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int x = 3;
    const int y = x;
    int z = x + y;
    int* p = &x;

    cout << string("one");

    ++x;
    x++;
}

밑에 밑줄이 그어진 것들이 RValue라는 것을 말하는 것이다.

x, y, z, p같은 변수들은 모두 LValue를 나타내고 있지만, 상수 3, x + y, &x, 임시 객체 string("one")은 표현식이 종료되면 사라져서 더 이상 참조할 수 없는 값이 돼버리기 때문에 RValue를 나타낸다.

 

증감 연산자 ++x는 LValue, x++는 RValue인 것을 볼 수 있다. 결과적으로 둘 다 증가된 값을 리턴하는 것은 같지만,

++x는 증가된 자신을 리턴하여서 LValue이고, x++은 증가된 자신의 복사본을 리턴하여서 RValue라고 한다.

 

또한 & 주소 연산자를 표현식 앞에 붙여보면, LValue는 오류가 안나지만, RValue는 컴파일 오류가 나는 것을 볼 수 있다.

&(++x); //LValue는 정상
&(x++); //RValue는 오류

RValue 참조자 &&

우리가 사용했던 참조자 int& a = b;와 같은 것들은 모두 LValue 참조자를 뜻하고 있었다.

하지만 RValue 참조자 또한 존재하는데, RValue 참조자는 RValue만 참조하고 LValue 참조자는 LValue만 참조하는 특징을

가지고 있다. 밑의 예시를 한번 보자.

#include<iostream>

int rvalue()
{
    return 10;
}

int main()
{
    int lvalue = 10;

    int& a = lvalue;
    int& b = rvalue();	//LValue 참조자에 RValue를 참조할 수 없다.

    int&& c = lvalue;	//RValue 참조자에 LValue를 참조할 수 없다.
    int&& d = rvalue();
}

위 예시처럼 각각의 참조자에는 서로 맞는 표현식을 대입해주어야 오류가 발생하지 않는 것을 볼 수 있다.


참고 자료

https://effort4137.tistory.com/entry/Lvalue-Rvalue

 

Lvalue Rvalue

C++ Lvalue와 Rvalue에 대한 오해Lvalue와 Rvalue는 보통 Left-value(왼쪽값)과 Right-value(오른쪽값)로 풀어서 씁니다. 이 때문에 대입 연산자(=)를 기준으로 왼쪽에 위치하는 값이 Lvalue이고 오른쪽에 위치하

effort4137.tistory.com

 

https://effort4137.tistory.com/entry/C11-Rvalue-Reference-2-Move-Semantics?category=466054 

 

[C++11] Rvalue Reference #2 - Move Semantics

Move Semantics Move Semantics란 객체의 리소스(동적으로 할당 된 메모리와 같은)를 또 다른 객체로 전송(이동)하는 것을 의미합니다. 앞에서 살펴보았던 Rvalue 참조자는 Move Semantics의 구현을 가능하게

effort4137.tistory.com

 

https://assortrock.com/236

 

C/C++ 모던) LValue RValue 임시객체 개념파악하기

학생들이 간간히 LValue RValue에 대해서 물어볼 때가 있습니다. 그때마다 기본적으로 C++11 이전과 그 이후로 해서 설명할 필요가 생겼기 때문에 이렇게 정리한 글을 올립니다. 프로그래밍을 공부하

assortrock.com