C++ 언어에서 l-value와 r-value 라 불리는 표현이 있다.
l-value와 r-value는 연산 결과에 따른 대입 연산에서 비롯된다.
l-value는 대입 연산에서 왼쪽과 오른쪽 모두 올 수 있는 표현이고
r-value는 대입 연산에서 오른쪽에만 올 수 있는 표현이다.
int a = 23;
int b = 12;
// 둘 다 모두 가능
a = b;
b = a;
// 산술 연산 결과는 r-value
a = 7 * 9; // l-value = r-value
7 * 9 = b; // error
위의 예시에서 7*9는 "연산 결과"로 오른쪽에만 올 수 있는 표현이다.
C++에서 둘을 구분할 수 있는 방법은 l-value는 실제로 메모리 상에 존재하는 객체를 가리키는 표현이고
&연산을 통해 주소를 접근할 수 있다. r-value는 l-value가 아닌 모든 나머지로 잠시 생성되고 없어지기 때문에 코드 상에서 실체가 없다.
l-value 예시
일반 변수, 포인터 변수, 참조자
int i = 40;
// 일반 변수 i
i = 40;
// 포인터 변수 p
int* p = &i;
int& foo();
// 참조자를 반환하는 foo()
foo() = 42;
// 참조자도 l-value이므로 주소를 대입할 수 있다.
int* p1 = &foo();
r-value 예시
(*) 레퍼런스 타입이 아닌 값을 반환하는 함수
리티럴 상수
산술 연산 결과
int foobar();
int j = 0;
int result = foobar(); // 함수 결과는 r-value
int *p2 = &foobar() // error, r-value의 주소는 없음
j = 42; // 리터럴 상수는 r-value
(*) 레퍼런스 타입이 아닌 값을 반환하는 함수
반환 값이 존재하는 함수는 대입을 위해 존재하고 식에서 주로 오른쪽에 온다고 보기 때문에 r-value로 보는 것이 바람직하다.
정확히는 함수 반환시 r-value 타입의 return시 생성되고 대입되자마자 소멸되는 임시 객체가 반환된다.
포인터가 반환된다면 r-value 타입의 포인터 "임시" 객체가 반환된다.
물론 레퍼런스 타입을 반환한다면 l-value가 될 수 있다.
'Advanced C++' 카테고리의 다른 글
[C++] 예외 처리 Exception (0) | 2021.02.20 |
---|---|
[C++ 클래스] 순수 가상 소멸자 (0) | 2021.02.18 |
[C++ 클래스] 가상 함수 테이블 (0) | 2021.01.29 |
[C++ 클래스] 가상 함수 (0) | 2021.01.29 |
[C++] 이동 시맨틱과 r-value 참조형 (0) | 2021.01.28 |