std::move의 변환 마법 미스터리 풀기
std::move()를 호출할 때 참조된 내용을 관찰하는 것은 어리둥절합니다. rvalue 매개변수는 lvalue에 바인딩될 수 있으며 일반적으로 rvalue 참조에 연결하는 것이 제한됩니다. std::move() 구현을 자세히 살펴보면 이 명백한 역설의 핵심이 드러납니다.
std::move() 구현 분석
세련된 것부터 시작 std::move() 버전:
template <typename T> typename remove_reference<T>::type&& move(T&& arg) { return static_cast<typename remove_reference<T>::type&&>(arg); }
사례 1: Rvalue로 move() 호출
move()가 rvalue와 함께 사용되는 경우: 임시 객체:
Object a = std::move(Object()); // Object() is temporary, hence prvalue
결과 템플릿 인스턴스화는 다음과 같습니다.
remove_reference<Object>::type&& move(Object&& arg) { return static_cast<remove_reference<Object>::type&&>(arg); }
remove_reference는 T&를 T로 또는 T&&를 T로 변환하고 Object는 일반 값이므로 최종 함수 형태는 됩니다:
Object&& move(Object&& arg) { return static_cast<Object&&>(arg); }
이름이 지정된 rvalue 참조는 lvalue로 처리되므로 캐스트가 중요합니다.
사례 2: Lvalue로 move() 호출
move()가 lvalue로 호출되는 경우:
Object a; // a is an lvalue Object b = std::move(a);
결과 move() 인스턴스화는 다음과 같습니다.
remove_reference<Object&>::type&& move(Object& && arg) { return static_cast<remove_reference<Object&>::type&&>(arg); }
다시, Remove_reference는 Object&를 Object로 변환하여 다음을 생성합니다.
Object&& move(Object& && arg) { return static_cast<Object&&>(arg); }
참조 축소의 본질
Object& &&와 lvalue에 바인딩하는 기능을 이해하는 것이 수수께끼를 푸는 열쇠입니다. C 11에는 다음과 같은 참조 축소에 대한 특수 규칙이 도입되었습니다.
Object & && = Object & Object & &&& = Object & Object && & = Object & Object && &&& = Object &&
따라서 Object& &&는 실제로 lvalue에 쉽게 바인딩되는 일반적인 lvalue 참조인 Object&로 변환됩니다.
결과 함수
이러한 규칙이 적용된 최종 함수는 다음과 같습니다.
Object&& move(Object& arg) { return static_cast<Object&&>(arg); }
rvalue에 대한 인스턴스화를 미러링하여 인수를 rvalue 참조로 캐스팅하여 균일한 동작을 보장합니다. .
remove_reference의 중요성
remove_reference의 목적은 대체 함수를 검토할 때 분명해집니다.
template <typename T> T&& wanna_be_move(T&& arg) { return static_cast<T&&>(arg); }
lvalue로 인스턴스화하는 경우:
Object& && wanna_be_move(Object& && arg) { return static_cast<Object& &&&>(arg); }
참조 축소 규칙을 적용하면 lvalue 인수에 대해 lvalue를 반환하는 사용할 수 없는 move-like 함수가 드러납니다. 그 원인은 rvalue 참조로의 적절한 변환을 방해하는 Remove_reference가 없기 때문입니다.
위 내용은 rvalue 참조가 rvalue에만 바인딩되어야 할 때 std::move()는 lvalue에 어떻게 바인딩됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!