> 백엔드 개발 > C++ > rvalue 참조가 rvalue에만 바인딩되어야 할 때 std::move()는 lvalue에 어떻게 바인딩됩니까?

rvalue 참조가 rvalue에만 바인딩되어야 할 때 std::move()는 lvalue에 어떻게 바인딩됩니까?

DDD
풀어 주다: 2024-11-14 10:46:01
원래의
1034명이 탐색했습니다.

How does std::move() bind to lvalues when rvalue references are supposed to only bind to rvalues?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿