2022. 4. 8. 00:23ㆍProgramming language/C, C++
- 목차
이 글은 이전에 운영하던 깃 블로그에서 옮겨온 글입니다.
서론
이전 글인 [C/C++]이동의미론(Move Semantics) 에서 언급한 L-Value 와 R-Value 에 관한 내용입니다.
L/R 은 화면 기준 왼쪽(Left) 에 오는 값이냐 오른쪽(Right)의 차이입니다.
L-Value와 R-Value
L-Value Reference(좌측값 참조)와 R-Value Reference(우측 값 참조)에 관한 간단한 정리
L-Value Reference(좌측값 참조)
- 이름이 있고 '계속 남아있는 값' 이 L-Value(좌측 값)
- 좌측 값 참조는 좌측 값만을 참조
- '&' (레퍼런스 연산자)를 이용함, 즉 대입받은 값을 참조
- 임시 값은 좌측 값 참조를 할 수 없음
- L-value 참조 생성자/할당자 연산은 복사 연산이라 한다=> 연산 후에도 매개 인자가 남음
R-Value Reference(우측 값 참조)
- '임시 값', 해당 줄에서만 남아있는 값이 R-Value(우측 값)
- 우측 값 참조는 우측 값만을 참조
- '&&' 연사자를 이용
- R-value 참조 생성자/할당자 연산은 이동 연산이라 함
=> 연산 후에 매개 인자가 남아있지 않음 (임시 값이기 때문) - 우측 값이 임시 객체여서 대입 이후 소멸할 경우, 컴파일러가 이동 대입 연산자를 적용하여
객체 내용을 이동시킴으로써 오버헤드 방지(불필요한 복사를 하지 않음)
아래는 예시입니다.
int num = 10; // num: 좌측값, 10이라는 값이 저장되어 해당 줄이 지나고도 남는것
// 10: 우측값, num에 대입되고 나서 해당 줄이 지나면 사라지는 값
C++11과 STL을 처음 공부할 때 처음 조사하게 되었는데, R-Value의 도입과 이동 의미론의 등장으로 성능 향상을 이룩했다는 내용이 기억납니다.
하지만, 이때 조사를 하면서 느꼈던 의문점이 있는데… R-Value Reference를 이용한 이동연산…
"이게 정말로 진짜 이동 연산인가? 그냥 좀 특이한 복사 연산이 아닌가?"
그렇다면 왜 저런 의문을 가지게 되었을까요? 일단 우측 값 참조의 형태를 보겠습니다.
Type&& refRvalue = R-Value;
R-Value를 참조하고 있는 refRvalue는 L-Value입니다. 왜? 저 줄이 지나도 남아 있으니까! 음… R-Value를 참조하고 있으니까 R-Value로써 사용하고자 하는데 L-Value 라니… 이 의문에 대한 해결은 std::move() 와 std::forward()를 통한 R-Value 캐스팅이었습니다.
좌측 값인 우측 값 참조를 우측 값으로 사용하기 위해서는 좌측 값 속성을 우측 값 속성으로
두 함수에 대한 간단한 설명은 다음과 같다.
- 두 함수 모두 인자로 넘어오는 값을 R-value로 캐스팅시켜주는 함수 템플릿
- std::move() : 무조건 R-value로 캐스팅
- std::forward() : 조건에 맞을 경우 R-value로 캐스팅
- 캐스팅을 시행할 뿐 실제로 이동을 시키지는 않는다
- 실행 시점에서는 아무 일도 발생하지 않는다
- 이동할 객체(인자로 넘겨줄 객체)는 const 여서는 안된다 => const일 경우 이동이 아닌 복사가 일어난다
- 작동 방식(코드)
template < typename T > decltype(auto) move(T&& param)
{
using returnType = std::remove_reference_t<T>&&;
return static_cast<returnType>(param);
}
위 설명중 '실제로 이동을 시키지 않는다'는 부분을 보면 이동은 직접 구현해야 합니다.
"이동을 구현하지 않으면 복사 연산일 뿐이잖아?"라는 것이 의문이었던 거 같아요.
결론, 이동 연산을 쓸 수 있는 부분은 기능을 구현해서 성능을 향상하자라는 의미가 아닐까 싶습니다.
'Programming language > C, C++' 카테고리의 다른 글
[C/C++] 캐스팅연산자 (0) | 2022.04.08 |
---|---|
[C/C++]STL 컨테이너 - std::map/std::set 그리고 std::deque (0) | 2022.04.08 |
[C/C++]STL 컨테이너 - std::vector 와 std::list (0) | 2022.04.08 |
[C/C++]이동의미론(Move Semantics) (0) | 2022.04.08 |
[C/C++]입력 예외 처리(Handling input exceptions) (0) | 2022.04.07 |