지노윈 2020. 8. 15. 13:33
반응형

 

glvalue(generalized lvalue)는 일반화된 좌측값

rvalue는 우측값

lvalue는 좌측값

xvalue(eXpiring value)는 소멸하는 값

prvalue(pure rvalue)는 순수 우측값

 

C++에서 타입 카테고리를 따질 때 크게 두 가지로 구분 합니다.

  • Identity(정체를 알 수 있는가?)
  • Movable(이동 시킬 수 있는가?)

모든 타입은 다음과 같이 다섯 가지고 구분 할 수 있어요.

lvalue

 

Identity && Not Movable

즉, 정체를 알 수 있고 이동 시킬 수 없습니다.

 

 

 

int n;
int m;

n과 m은 정체를 알 수 있나요? n와 m은 다른 주소를 가지고 있고 이 주소값들에 의해서 구분 됩니다.

즉, 정체를 알 수 있습니다.

 

그렇다면 이동은 가능한가요? 

int n = 1;
int&& x = n;

이 코드는 컴파일 오류가 발생합니다. &&는 rvalue reference입니다.

즉, 이동 시킬 수 없습니다.

 

lvalue는 접근할 수 있는 주소를 가진 변수입니다. 이동 연산을 할 수 없습니다.(형 변환을 하면 가능)

 

  • 이름이 있는 변수, 함수
    int n
    &foo()
  • 전위 증감 연산자
    ++a, --b
  • 배열 참조식
    a[n]
  • 복합 대입 연산식들
    a = b, a += b, a *= b
  • 스트링 리터럴 
    "hello"

[객체 지향 프로그래밍/C++ 프로그래밍] - 문자열 리터럴이 lvalue인 이유

 

 

& 연산자를 이용해 주소값을 얻을 수 있어야 합니다. 
예를 들어 &++a, &"hello" 모두 올바른 주소를 얻을 수 있습니다.

 

prvalue(pure rvalue)

 

Not Identity && Movable

즉, 정체를 알 수 없고 이동 시킬 수 있습니다.

 

 

 

prvalue는 접근 할 수 있는 주소가 없는 표현식입니다. 이동 연산이 가능합니다.

  • 후위 증감 연산자
    a++, b--
  • 스트링 리터럴을 제외한 모든 리터럴
    1, true, nullptr
  • 산술/논리 연산자 식들
    a + b, a && b, a < b

& 연산자를 이용해 주소값을 얻을 수 없습니다.

예를 들어 &a++, &true 모두 오류입니다. 그리고 할당 연산에서 좌측에 올 수 없습니다.

xvalue

 

Identity && Movable

즉, 정체를 알 수 있고 이동 시킬 수 있습니다.

 

 

 

xvalue 표현식의 일반적인 아이디어는 어떠한 오브젝트가 곧 소멸될 예정이므로 이 오브젝트는 move 해줘야 한다는 것을 명시적으로 표현하는 것입니다.

struct X { int n; };
extern X x;

4; // prvalue가 없음
x; // lvalue
x.n; // lvalue
std::move(x); // xvalue

X{4}; // prvalue: identity가 없으므로
X{4}.n; // xvalue: identity가 있고 리소스가 재사용 될 수 있음

lvalue와 prvalue 두 가지만 있다면 좌측 값을 이동 시킬 방법이 없기에 xvalue가 있어야 합니다.

std::move 함수는 우측값 레퍼런스를 리턴합니다.

 

https://docs.microsoft.com/ko-kr/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=vs-2019
https://docs.microsoft.com/ko-kr/windows/uwp/cpp-and-winrt-apis/cpp-value-categories