나는 이것을 보았다 : 기본 생성자 Move Constructor를 호출하는 Move Constructor
누군가 설명 할 수 있습니까?
- 차이
std::move
와std::forward
, 바람직하게는 일부 코드 예에? - 쉽게 생각하는 방법과 사용시기
move
시기 " 가치 를 옮기고forward
싶을 때 와 완벽한 전달을 원할 때 사용합니다. 이것은 로켓 과학이 아닙니다.;)
나는 이것을 보았다 : 기본 생성자 Move Constructor를 호출하는 Move Constructor
누군가 설명 할 수 있습니까?
std::move
와 std::forward
, 바람직하게는 일부 코드 예에?move
시기 " 가치 를 옮기고forward
싶을 때 와 완벽한 전달을 원할 때 사용합니다. 이것은 로켓 과학이 아닙니다.;)
답변:
std::move
객체를 가져 와서 임시 (rvalue)로 처리 할 수있게합니다. 시맨틱 요구 사항은 아니지만 일반적으로 rvalue에 대한 참조를 승인하는 함수는이를 무효화합니다. 이 표시되면 std::move
나중에 개체 값을 사용해서는 안되지만 새 값을 할당하고 계속 사용할 수 있습니다.
std::forward
호출자가 전달하는 데 사용한 템플릿 함수 매개 변수 (함수 내부)를 값 범주 (lvalue 또는 rvalue)로 캐스팅하는 단일 사용 사례가 있습니다. 이를 통해 rvalue 인수는 rvalue로 전달되고 lvalue는 "완벽한 전달"이라는 스키마 인 lvalue로 전달됩니다.
하려면 설명 :
void overloaded( int const &arg ) { std::cout << "by lvalue\n"; }
void overloaded( int && arg ) { std::cout << "by rvalue\n"; }
template< typename t >
/* "t &&" with "t" being template param is special, and adjusts "t" to be
(for example) "int &" or non-ref "int" so std::forward knows what to do. */
void forwarding( t && arg ) {
std::cout << "via std::forward: ";
overloaded( std::forward< t >( arg ) );
std::cout << "via std::move: ";
overloaded( std::move( arg ) ); // conceptually this would invalidate arg
std::cout << "by simple passing: ";
overloaded( arg );
}
int main() {
std::cout << "initial caller passes rvalue:\n";
forwarding( 5 );
std::cout << "initial caller passes lvalue:\n";
int x = 5;
forwarding( x );
}
Howard가 언급했듯이이 두 함수가 단순히 참조 유형으로 캐스트되기 때문에 유사성이 있습니다. 그러나 rvalue 참조 캐스트의 유용성의 99.9 %를 다루는 이러한 특정 사용 사례를 제외하고 static_cast
직접 사용 하고 수행중인 작업에 대한 적절한 설명을 작성해야합니다.
std::forward
'의 유일한 사용 사례는 함수 인수의 완벽한 전달입니다. 객체 멤버와 같은 다른 것을 완벽하게 전달하려는 상황에 처했습니다.
모두 std::forward
와 std::move
아무것도하지만, 캐스트를하지 않습니다.
X x;
std::move(x);
위의 내용 x
은 X 유형 의 lvalue 표현식 을 X 유형의 rvalue 표현식 (정확한 xvalue)으로 캐스트합니다. move
rvalue를받을 수도 있습니다 :
std::move(make_X());
이 경우 항등 함수입니다. X 유형의 rvalue를 가져 와서 X 유형의 rvalue를 반환합니다.
함께 std::forward
사용하면 어느 정도 대상을 선택할 수 있습니다 :
X x;
std::forward<Y>(x);
x
X 유형 의 lvalue 표현식 을 Y 유형의 표현식으로 캐스트합니다 . Y에 대한 제한 사항이 있습니다.
Y는 액세스 가능한 X의 Base이거나 X의 Base에 대한 참조 일 수 있습니다. Y는 X 또는 X에 대한 참조 forward
일 수 있습니다. Y는 액세스 가능한 Base 변환을 통한 경우를 제외하고 X에서 간단히 변환 가능한 유형이 될 수 없습니다.
Y가 lvalue 참조이면 결과는 lvalue 표현식이됩니다. Y가 lvalue 참조가 아닌 경우 결과는 rvalue (정확한 xvalue)식이됩니다.
forward
Y가 lvalue 참조가 아닌 경우에만 rvalue 인수를 사용할 수 있습니다. 즉, rvalue를 lvalue로 캐스트 할 수 없습니다. 이는 안전상의 이유로 일반적으로 매달려있는 참조로 이어지기 때문입니다. 그러나 rvalue를 rvalue로 캐스팅하는 것은 괜찮으며 허용됩니다.
허용되지 않는 것으로 Y를 지정하려고하면 런타임이 아닌 컴파일시 오류가 발생합니다.
std::forward
해당 함수가 실행 된 후 해당 객체를 사용할 수 있습니까? std::move
의 경우 정의되지 않은 동작 이라는 것을 알고 있습니다.
move
: stackoverflow.com/a/7028318/576911 를 들어 forward
, 당신은 좌변에 전달하는 경우가 좌변을받는 것처럼, 당신의 API가 반응한다. 일반적으로 이는 값이 수정되지 않음을 의미합니다. 그러나 그것이 상수가 아닌 lvalue이면 API가 수정했을 수 있습니다. rvalue를 전달하면 일반적으로 API에서 API가 이동했을 수 있으므로 stackoverflow.com/a/7028318/576911 이 적용됩니다.
std::forward
함수에 전달 된 방식대로 매개 변수 를 전달 하는 데 사용됩니다 . 여기에 표시된 것처럼 :
언제 std :: forward를 사용하여 인수를 전달합니까?
사용 std::move
,를 rvalue로 이벤트를 객체 것은 아마도 이동 생성자 또는 우변을 받아들이는 기능을 개발하였습니다. 그것은을위한 것이 않는 std::move(x)
경우에도이 x
그 자체에 의해를 rvalue 없습니다.