wrapper(lval)
T = int&
forward 결과가 lvalue 참조로 남아
process(int&)가 선택됩니다.
T&& 매개변수는 호출자가 lvalue를 줬는지
rvalue를 줬는지 기억하고, std::forward<T>가 그
정보를 다음 함수 호출에 다시 적용합니다.
template<class T>
void wrapper(T&& arg)
process(std::forward<T>(arg));
wrapper(lval)
T = int&
forward 결과가 lvalue 참조로 남아
process(int&)가 선택됩니다.
wrapper(20)
T = int
임시 값의 범주가 유지되어 process(int&&)
오버로드로 전달됩니다.
wrapper(std::move(lval))
T = int
이동 가능 표시가 유지되어 rvalue 참조 오버로드를 호출합니다.
arg는 lvalue
process(arg)라고 쓰면 호출자가 rvalue를 줬더라도
arg 자체는 이름이 있어 lvalue처럼 전달됩니다.
std::move
forwarding wrapper에서는 보존이 목적이고, 더 이상 원본을 쓰지 않을 때만 move가 자연스럽습니다.
기억할 문장: std::forward는 완벽 전달용
조건부 캐스팅이고, std::move는 이 객체를 이동 대상으로
삼겠다는 명시적 선택입니다.