Move Semantics

move는 복사가 아니라 소유권을 옮겨도 된다는 표시다

std::move는 객체를 이동하지 않고 rvalue로 캐스팅한다. 실제 이동은 이동 생성자나 이동 대입이 실행될 때 일어나며, 이동 후 객체는 파괴 가능한 상태여야 한다.

01

값 범주 확인

이름 있는 변수는 타입이 T&&여도 표현식으로는 lvalue다.

02

소유권 이전 명시

더 이상 원래 값을 쓰지 않는 지점에서 std::move로 이동 후보를 만든다.

03

이후 상태를 제한한다

move 후 객체는 대입이나 소멸 외의 의미 있는 사용을 피하거나 문서화한다.

move constructor
새 객체로 빼앗기 원본의 리소스 핸들을 새 객체가 가져가고 원본은 빈 상태로 남긴다.
noexcept이면 컨테이너가 선호한다.
move assignment
기존 객체 갱신 기존 리소스를 정리한 뒤 원본의 리소스를 가져온다.
self move도 견딜지 결정한다.
forward
값 범주 보존 템플릿에서 받은 인자를 원래 값 범주대로 전달한다.
std::forward<T>는 forwarding reference와 함께 쓴다.
copy fallback
이동 불가 타입 move 생성자가 없거나 noexcept가 아니면 컨테이너가 복사를 택할 수 있다.
성능 결과를 측정한다.

move 후 사용 · const move · noexcept 점검

move 후 사용 std::move한 변수를 값이 보존된 것처럼 다시 읽고 있지 않은가.
const move const 객체에 move를 걸어 실제로는 복사가 일어나지 않는가.
noexcept 리소스 소유 타입의 move 연산이 noexcept로 선언 가능한가.

이동 의도

std::vector<std::string> names;
std::string name = read_name();
names.push_back(std::move(name));
// 이후 name은 비어 있다고 가정하지 말고 대입 또는 소멸만 기대한다.