2012-06-23 3 views
3

R 값 참조없이 완벽한 전달은 C++에서 불가능하다는 것을 알고 있습니다.R 값 참조는 언제 필요합니까?

그러나 알고 싶습니다. 이 필요합니까? 예를 들어


이 예 아웃 this page 포인트가되는 R 값 참조 명백하게 필요하다 :

X foo(); 
    X x; 
    // perhaps use x in various ways 
    x = foo(); 

마지막 줄 이상 : 의해 유지

  • 자폭 자원 x,
  • temporal에서 자원을 복제합니다. y가 foo에 의해 반환 된 경우
  • 임시를 삭제하고 리소스를 해제합니다.

    X foo(); 
    X x; 
    // perhaps use x in various ways 
    { 
        X y = foo(); 
        swap(x, y); 
    } 
    

    는 그래서 나에게 필요한 을 그 r 값 참조를하지 같다 :

그러나 swap가 제대로 구현된다면 간단한 변화 문제를 해결 한 것이 나에게 보인다 이 최적화를 위해. (맞습니까?)

따라서 이 아닌은 r 값 참조로 해결할 수 있습니다 (완벽한 전달은 제외하고 이미 알고 있습니다).

+0

의미 이동? 실제로 완벽한 전달에는 참조 값 자체가 필요하지 않으며 다른 형식 공제 규칙 만 있으면됩니다. 그것들은 편리함 때문에 새로운 규칙을 위해 rvalue reference를 사용했습니다. –

+0

@ R.MartinhoFernandes : "이동 의미론"이란 정확히 무엇을 의미합니까? 위에 보여준 것과 다른 것입니까? (또한, 내가 말하고자하는 것은 완벽한 전달은 * before *이 아니지만 R- 값 참조 때문에 가능하다는 것입니다.)이 – Mehrdad

+0

스왑은'X x = std :: move (y);'. –

답변

12

따라서 r- 값 참조로 해결할 수없는 몇 가지 문제가 있습니다 (완벽한 전달은 제외).

예. swap 트릭이 작동하도록 (또는 적어도 최적으로 작동하도록) 구성 될 때 클래스는 빈 상태로 설계되어야합니다. 완전히 비어있는 상태로 시작하기보다는 항상 몇 가지 요소를 예약 한 vector 구현을 생각해보십시오. 이러한 디폴트에서 구성된 vector을 이미 존재하는 vector으로 바꾼다는 것은 추가 할당을한다는 것을 의미합니다 (이 vector 구현의 기본 생성자에서).

실제 이동에서는 기본 생성 개체가 데이터를 할당 할 수 있지만 이동 된 개체는 할당되지 않은 상태로 남겨 둘 수 있습니다.

또한,이 코드를 고려하십시오

std::unique_ptr<T> make_unique(...) {return std::unique_ptr<T>(new T(...));} 

std::unique_ptr<T> unique = make_unique(); 

이 언어 수준의 이동 의미없이 수 없습니다. 왜? 두 번째 성명서 때문에. 표준에 따르면, 이것은 복사 초기화입니다. 이름에서 알 수 있듯이 유형이 이어야 복사 가능합니다.. 그리고 unique_ptr의 요지는 그것이 독특하고 독특하다는 것입니다. IE : 복사 할 수 없습니다.

이동 의미가 없으면 반환 할 수 없습니다. 오 그래, 당신은 복사 elision에 대해 이야기 할 수 있지만, 기억해 : elision은 입니다. 일치하는 컴파일러는 여전히 복사 생성자가 존재하고 호출 가능함을 감지해야합니다. 컴파일러는 단순히 호출하지 않을 수있는 옵션이 있습니다.

그래서 아니요, 이동 의미를 swap으로 에뮬레이션 할 수 없습니다. 그리고 솔직히, 비록 할 수 있더라도, 왜 을 원하십니까에?

swap 구현을 직접 작성해야합니다. 따라서 6 명의 멤버가있는 클래스가 있다면 swap 함수는 각 멤버를 차례로 바꿔야합니다. 재귀 적으로 모든 기본 클래스 등을 통해.

(비록 VC10 또는 VC2012가 아님) 컴파일러는의 이동 생성자 을 쓸 수 있습니다.

네, 네가 빠져 나갈 수있는 상황이 있습니다. 그러나 그들은 믿을 수 없을만큼 해커처럼 보이고, 왜 그런 식으로 일하는지, 그리고 무엇보다 중요한 것은 독자와 작가 모두에게 어려운 일이라는 것을 알기가 어렵습니다.

코드를 읽기가 어렵고 쓰기가 어려우며 관리하기가 쉽지 않은 퍼포먼스를 위해 많은 것을하고 싶다면 (예 : swap 함수에 코드를 추가하지 않고 클래스에 다른 멤버를 추가하십시오.), 그러면 아마도 언어의 일부가되어야 할 무언가를보고있는 것입니다. 특히 컴파일러가 아주 쉽게 처리 할 수있는 경우입니다.

+0

끔찍한 답변! 단지 후속 조치 : 포괄적 인 아이디어라면? (즉, 언급하지 않은 다른 이유는 무엇입니까?) – Mehrdad

+0

+1, Bjarne Stroustrup은 * rvalue-ref *없이 move semantics *를 구현하고 동일한 목적으로 'swap'트릭을 사용했습니다 , * 완벽한 포워딩 *은 많은 고통을 통해 이론적으로 구현 될 수 있습니다 (인수의 수에 기하 급수적 인 폭발). 그러나 * rvalue-semantics *는 수동으로 구현함으로써 발생하는 비용 (및/또는 위험)이 실제로는 불가능 *하기 때문에 가능하게하는 기능입니다. 나는 C++ 03에서'unique_ptr'을 전혀 구현할 수 없다고 생각합니다. 그러나 이것을 람다 (lambdas)와 같이 생각하십시오. 이전에는 할 수 없었던 일을 당신이하도록 두지 않았습니다. 유용성이 향상되었습니다. –

+1

+1, more info : 일반 벡터' :: erase (iterator)'멤버 구현을 고려하십시오. 배열의 요소를 1 씩 뒤로 "이동"시켜야합니다. "스왑"으로 "move"를 구현하면 '벡터 :: 지우기 (반복자)'를 크게 벌했습니다. 복사 할당으로 "이동"을 구현한다면, 당신은'vector > :: erase (iterator)'를 크게 처벌했습니다. 이 두 가지 경우를 모두 최적화하려면 한 가지 경우에는 "스왑 형"을 의미하고 다른 경우에는 "사본과 유사"를 의미하는 "이동"이 필요합니다. 계속 ... –

관련 문제