-
[Rvalue reference] Rvalue Reference(3)개발/C·C++ 2021. 5. 21. 17:53
>> 번역글입니다
>> 의역은 있고 오역이 있을 수 있습니다
>> 출처 http://thbecker.net/articles/rvalue_references/section_03.html
X
가 어떤 타입이라고 할 때X&&
는X
에 대한 rvalue reference라고 합니다.X&
는 lvalue reference입니다. rvalue reference는 lvalue reference인X&
와 비슷하게 동작합니다. 여러 예외 상황과 함께요. 함수 오버로딩 문제에서 가장 중요한 점은 rvalue는 새로운 rvalue reference를 선택하고 lvalue는 lvalue reference를 선택한다는 것입니다.void foo(X& x); // lvalue reference overload void foo(X&& x); // rvalue reference overload X x; X foobar(); foo(x); // argument is lvalue: calls foo(X&) foo(foobar()); // argument is rvalue: calls foo(X&&)
요지는 다음과 같습니다.
Rvalue reference는 "lvalue와 rvalue 중에 어느 쪽으로 호출될 것인가" 하는 조건에 대해, 컴파일 타임에 함수가 분기되도록 합니다.
위에서 봤던 것처럼 이 방법을 이용하면 어느 함수든 오버로드할 수 있는 건 사실입니다. 하지만 압도적으로 많은 경우, 이런 종류의 오버로드는 이동 의미론을 위해 복사 생성자와 할당 연산자에 한해 이뤄져야 합니다.
X& X::operator=(X const & rhs); // classical implementation X& X::operator=(X&& rhs) { // Move semantics: exchange content between this and rhs return *this; }
복사 생성자에 대해 rvalue reference를 실행하는 것은 비슷합니다.
주의사항: C++에서 꽤 가끔 일어나는 일인데, 처음에는 괜찮아 보이는 것은 여전히 완벽함에서 조금 모자랍니다. 일부 사례에서 알려진 것으로, 위에 복사 생성자에서 단순한 'exchange content between this and rhs'는 보완이 필요합니다. 이 문제 대해선 네 번째 섹션 "Forcing Move Semantics"에서 다루겠습니다.
Note: 다음을 구현한다면 void foo(X&); 다음이 아니라 void foo(X&&); 당연히 아무 것도 바뀌지 않습니다: foo는 lvalue에 대해서 호출될 겁니다. 다음이 아니라 void foo(X&&); 다음과 같이 구현해도 void foo(X const &); 역시 변화가 없습니다: foo는 lvalue에도 rvalue에도 호출됩니다. lvalue와 rvalue를 구분하는 것이 불가능한 일이 아닙니다. 다음과 같이 구현해야만 가능합니다. void foo(X&&); 다음의 두 경우가 아니라, void foo(X&); void foo(X const &); 다음처럼 구현해야만 void foo(X&&); foo는 rvalue에 대해 호출됩니다. lvalue에 대해 호출하려고 하면 컴파일 에러가 날 것입니다.
'개발 > C·C++' 카테고리의 다른 글
[Pointer] 정수형을 문자형으로 (0) 2021.05.28 IOCP(1) (0) 2021.05.25 [Rvalue reference] Move Semantics(2) (0) 2021.05.12 [Rvalue reference] Introduction(1) (0) 2021.05.12 번역 예정 아티클 / 정리할 개념 (0) 2021.05.07