On this page
article
C++ Value Categories
Value Category의 기본 개념
C++에서 모든 표현식(expression)은 두 가지 특성을 가집니다:
- 타입(Type):
int
,double
,std::string
등 - 값 분류(Value Category): 표현식이 어떻게 메모리에 관련되는지 설명
전통적인 분류: lvalue와 rvalue
lvalue (left value)
- 정의: 메모리 상에 위치를 가지며, 식별자(identifier)로 참조할 수 있는 표현식
- 특징:
- 주소를 취할 수 있음 (
&
연산자 적용 가능) - 대입 연산자의 왼쪽에 올 수 있음 (이름의 유래)
- 지속성이 있는 값
- 주소를 취할 수 있음 (
- 예시:
rvalue (right value)
- 정의: 임시적이고 식별자가 없는 표현식
- 특징:
- 일반적으로 주소를 취할 수 없음
- 대입 연산자의 오른쪽에만 올 수 있음
- 임시 값, 리터럴, 계산 결과 등
- 예시:
C++11 이후의 확장된 분류
5가지 값 범주
C++11에서는 더 정교한 값 분류 체계가 도입되었습니다:
- lvalue: 전통적 의미의 lvalue
- xvalue (eXpiring value): 수명이 끝나가는(만료되는) 객체에 대한 참조
- prvalue (Pure Rvalue): 순수한 임시 값
- glvalue (Generalized Lvalue): lvalue와 xvalue를 포함하는 상위 개념
- rvalue: xvalue와 prvalue를 포함하는 상위 개념
각 분류의 상세 설명
lvalue
- 특징: 지속적인 메모리 위치를 가지며 식별자로 참조 가능
- 예시:
xvalue (eXpiring value)
- 특징:
- 이동 가능한 객체 (리소스를 빼앗길 수 있는 객체)
- 곧 소멸될 객체에 대한 참조
- 예시:
prvalue (Pure Rvalue)
- 특징:
- 순수한 임시 값으로 메모리 위치가 없음
- C++17부터 “임시 구체화(temporary materialization)“를 통해 xvalue로 변환 가능
- 예시:
glvalue (Generalized Lvalue)
- lvalue와 xvalue의 상위 개념
- 메모리에 위치가 있는 모든 표현식 (식별자로 직/간접 참조 가능)
rvalue
- xvalue와 prvalue의 상위 개념
- lvalue가 아닌 모든 표현식
값 범주의 의미와 필요성
왜 값 범주가 중요한가?
참조 바인딩 규칙:
T&
(lvalue reference)는 lvalue에만 바인딩 가능T&&
(rvalue reference)는 주로 rvalue에 바인딩 (단, 포워딩 참조 제외)
함수 오버로딩:
이동 의미론(Move Semantics):
- rvalue reference를 통해 객체의 내용을 효율적으로 이동
- 복사 비용 감소, 성능 향상
완벽한 전달(Perfect Forwarding):
- 템플릿에서 인자의 값 범주를 보존하여 전달
실용적 예시
이동 생성자 구현
표현식의 값 범주 결정 예제
immutable lvalue expression
정의: 수정할 수 없는 lvalue 표현식
예시:
const
타입의 변수는 여전히 lvalue지만, 값 수정은 불가능합니다.메모리에 위치하고 식별자가 있어 lvalue이지만, 내용이 불변(immutable)입니다.