-
항목23. std::move와 std::forward를 숙지하라Effective Modern C++ 2022. 8. 20. 23:37
std::move 와 std::forward 는 그냥 캐스팅을 수행하는 함수이다. std::move는 주어진 인수를 무조건 오른값으로 캐스팅하고, std::forward는 특정 조건이 만족될 때에만 그런 캐스팅을 수행한다. 즉 std::move 자체는 이동이 아니라 캐스팅을 시켜 이동에 적합하다는 것을 말해주는 것이다. 하지만 std::move() 로 오른값 캐스팅을 해도 이동이 아닌 복사가 되는 경우도 있다. 바로 const 객체를 오른값 캐스팅해도 const 객체여서 복사 연산이 된다.
즉 const 객체는 이동 요청을 해도 복사 연산으로 변환된다.
std::forward<T>()는 조건부 캐스팅이다. forward의 인수가 오른값으로 초기화 되었으면 오른값으로 캐스팅하고, 왼값으로 초기화 되었으면 그냥왼값 그대로이다.
void process(const Widget& lvalArg); // 왼값들을 처리하는 함수 void process(Widget&& rvalArg); // 오른값들을 처리하는 함수 template<typename T> void longAndProcess(T&& param) { process(std::forward<T>(param)); } ... Widget w; longAndProcess(w); // 왼값으로 호출 longAndProcess(std::move(w)); // 오른값으로 호출호출된 longAndprocess에서 param은 왼값으로 호출되든 오른값으로 호출되든 하나의 왼값이다. (함수 매개변수는 언제나 왼값)
하지만 템플릿 매개변수 T에 부호화되어 있는 정보를 이용해 std::forward(param)을 사용하면 오른값으로 초기화됐던 값만 오른값으로 캐스팅할 수 있다!
'Effective Modern C++' 카테고리의 다른 글
항목25. 오른값 참조에는 std::move를, 보편 참조에는 std::forward를 사용하라 (0) 2022.08.27 항목24. 보편 참조와 오른값 참조를 구별하라 (0) 2022.08.27 항목22. Pimpl 관용구를 사용할 때에는 특수 멤버 함수들을 구현 파일에서 정의하라 (0) 2022.08.16 항목21. new를 직접 사용하는 것보다 std::make_unique와 std::make_shared를 선호하라 (0) 2022.08.11 항목20. std::shared_ptr처럼 작동하되 대상을 잃을 수도 있는 포인터가 필요하면 std::weak_ptr을 사용하라 (0) 2022.08.11