이동 의미론

C++ move 의미론 점검

std::move는 객체를 이동시키는 함수가 아니라 rvalue로 취급하라는 캐스팅이다. 실제 이동은 이동 생성자나 이동 대입 연산자가 수행하며, moved-from 객체의 유효하지만 미정인 상태, self-move, noexcept 여부가 컨테이너 성능과 안전성에 영향을 준다.

01

값 범주 확인

이름 있는 객체는 보통 lvalue이고, std::move로 xvalue로 캐스팅할 수 있다.

move라는 이름과 실제 이동은 다르다
02

오버로드 선택

T&& 매개변수와 const T& 매개변수 중 어떤 함수가 선택되는지 확인한다.

const 객체는 이동이 제한될 수 있다
03

자원 이전

이동 생성자는 포인터나 handle 소유권을 새 객체로 넘기고 원본을 안전한 빈 상태로 둔다.

원본은 파괴 가능해야 한다
04

noexcept 표시

이동 연산이 예외를 던지지 않으면 noexcept를 붙여 vector 재배치에서 이동을 활용하게 한다.

예외 가능 이동은 복사로 대체될 수 있다
05

moved-from 사용 제한

이동된 객체는 재대입이나 소멸은 가능하지만 값 내용에 기대지 않는다.

비어 있다고 보장하지 않는다
std::move
rvalue 캐스팅 객체를 이동 가능 후보로 만들 뿐 실제 자원 이전은 생성자나 대입이 한다.
이후 원본 사용을 조심한다
Move ctor
새 객체 생성 기존 객체의 자원을 새 객체가 가져오며 원본을 안전한 상태로 둔다.
RAII 자원에서 중요하다
Move assign
기존 객체 교체 자기 자원을 정리한 뒤 다른 객체의 자원을 가져온다.
self-move 안전성을 본다
noexcept
컨테이너 최적화 조건 vector 재할당 같은 상황에서 이동 사용 여부에 영향을 준다.
가능하면 이동 연산에 붙인다

이동 확인

원본 상태 std::move 이후 원본 값을 읽는 코드가 의미에 기대지 않는지 확인한다.
noexcept 이동 생성자와 이동 대입이 예외를 던지지 않으면 noexcept인지 본다.
const move const 객체에 std::move를 적용해 실제 이동이 막히지 않는지 확인한다.