1 minute read

lvalue

  • 메모리 주소가 존재하며 식별자가 있는 표현식
  • 참조나 대입이 가능, &연산자로 주소를 가져올 수 있음
  • 변수 이름, 배열요소, 반환값이 참조형인 함수 등은 lvalue의 대표적인 예시임
int x = 10; // x -> lvalue
int* p = &x; // x의 주소를 받아 올 수 있음

rvalue

  • 메모리 주소가 없거나 사용자가 접근할 수 없는 임시 값
  • 대부분의 리터럴, 임시 계산 결과, 덧셈 등의 연산 결과에서 생성된 값
  • 참조할 수 없으며 대입의 오른쪽에만 올 수 있음
int y = 5 + x; // 5와 x+5는 rvalue
  • lvalue는 rvalue로 변환될 수 있음
    • x + y에서 x, y는 lvalue지만 덧셈의 결과는 rvalue
    int x = 5; // x -> lvalue
    int y = x + 2; // x + 2 연산 시 x는 rvalue로 변환 됨
    
    • 모든 lvalue가 항상 변환되는 것이 아닌 변환이 필요한 시점에만 변환이 일어남
  • 반대로 rvalue를 lvalue로 변환하는 것은 불가능, 변환 시 임시 객체가 생성 됨
  • rvalue 참조(T&&)는 rvalue에 대해서 참조할 수 있게 하며 이동 의미론 등 자원 관리에 쓰임

rvalue 참조

  • 임시 값(rvalue)만을 참조할 수 있는 참조 타입으로 문법은 T&&로 표기함
  • rvalue는 보통 표현식에서 생성된 값, 리터럴 등 일회성 값을 의미하며 등호(=)의 우측에만 올 수 있어 수정이 불가능함
  • rvalue 참조 타입으로 선언하면 기존에는 접근 할 수 없었던 임시 객체를 참조할 수 있음
    • 이동 생성자와 이동 연산자 등에 활용
int&& c = a + 1; // a + 1의 결과 rvalue를 c가 참조
  • rvalue 참조는 이동 의미론과 함께 사용되어 std::move를 통해 자원을 효율적으로 이전하는 것에 활용됨

특징과 역할

  • 이름이 없는 임시 객체와 리터럴 등의 rvalue만을 참조할 수 있음
    • int&& a = 3; 처럼 rvalue 만 할당 가능
  • lvalue 에는 rvalue 참조를 할당할 수 없음
    • int&& c = a; 와같은 문법은 오류임
  • rvalue 참조의 주된 목적은 임시 객체에 대한 자원 이동을 가능하게 하여 불필요한 복사 비용을 줄이고 성능을 개선하는 데 있음

장점

  • 복사 대신 이동이 가능해져 컨테이너, 함수 반환값 등에서 불필요한 복사 오버헤드를 줄임
  • 함수 오버로딩 시 lvalue참조(T&)와 rvalue참조(T&&)의 구분이 가능해져 상황에 맞는 최적화 함수 제공 가능
  • 임시 객체를 수정하거나 자원을 옮기는 이동 생성자 / 이동 대입 연산자의 구현에 필수적

Comments