이 데이터에 이름이 있고 주소를 취할 수 있는가(정체성) / 이동시킬 수 있는가(이동 생성자, 이동 대입 연산자등 사용여부)에 대한 분류이다.
정의: 이름을 가지고 있으며, 메모리 주소를 얻을 수 있는 대상
특징: 표현식이 끝나도 사라지지 않고 유지
예시: 변수 이름(x), 객체의 멤버(p.hp), 역참조된 포인터(*ptr)
정의: 이름이 없고 곧 사라질 임시 값
특징: 주소를 취할 수 없으며, 보통 리터럴이나 함수의 반환값(값 타입)
예시: 42, true, a + b, getNumber()
정의: 이름은 있을 수 있지만, 곧 사라질 것이니 자원을 뺏어가도(Move) 좋다고 표시된 값
특징: std::move()를 사용했을 때의 결과물이 대표적
예시: std::move(x)
위의 세 가지를 묶어서 부르는 '그룹명', 컴파일러가 규칙을 적용할 때 주로 사용
정체성(Identity)을 가진 모든 것 (lvalue + xvalue)
"메모리에 실체가 있으니, 다형성(가상 함수)을 쓸 수 있음
이동(Movability)이 가능한 모든 것 (prvalue + xvalue)
(Move 생성자/대입 연산자 호출)
class Vector3 {
public:
float x, y, z;
Vector3(float x, float y, float z) : x(x), y(y), z(z) {}
};
Vector3 make_forward_vector() { return Vector3(0, 0, 1); }
int main() {
Vector3 v1(1, 0, 0); // v1은 lvalue
Vector3 v2 = make_forward_vector(); // prvalue (공간에 떠 있는 임시 값)
Vector3 v3 = std::move(v1); // xvalue (v1이라는 실체가 있지만 이동 허락됨)
float z = make_forward_vector().z; // xvalue입니다!
// (prvalue인 임시 객체의 멤버에 접근하는 순간, 메모리 실체가 필요해져서 xvalue로 승격됨)
}