2014-07-18 6 views
3

C++ 11 오른쪽 값을 이해하려고하며 코드에서 최적의 성능을 위해이를 어떻게 사용하는지 이해하려고합니다.rvalue reference를 const lvalue reference paremeter로 넘기기

많은 양의 동적 할당 된 데이터에 대한 멤버 포인터가있는 클래스 A이 있다고 가정 해 보겠습니다.

foo(const A& a) 또한 A 클래스의 개체를 사용하는 방법이 있습니다. 내가 원하는

A의 대상이 기능 foo에 전달 될 때이 경우는 기본 힙 데이터의 깊은 복사를 수행하기 때문에,라는 것을 A의 복사 생성자를 방지합니다.

A a; 
    foo(a); 

과를 rvalue 참조를 전달 :

내가 좌변 기준을 통과 시험 복사 생성자가 있었다 두 경우 모두

foo(A()); 

호출되지.

이것은 내 컴파일러 (Apple LLVM 5.1)의 최적화로 인한 것입니까? 이것에 대한 사양이 있습니까?

답변

11

예상됩니다. 참조 유형 매개 변수 (lvalue 또는 rvalue 참조)에 인수를 전달하면 객체가 복사되지 않습니다. 이것이 참조 점의 전체입니다.

혼란은 꽤 흔합니다. 복사 또는 이동 생성자의 선택은 객체를 값으로 전달할 때만 발생합니다. 예를 들어 :

void foo(A a); 

이 기능에 A 객체를 전달, 컴파일러는 복사본을 사용하거나 전달하는 식 좌변 또는를 rvalue 발현 여부에 따라 생성자를 이동할지 여부를 결정합니다.

한편

, 다음과 같은 기능의 어떤 것도, 심지어 복사본을 호출하거나 어떤 객체가 건설되고 있지 때문에 생성자를 이동하려고하지 않을 것이다 :

void foo(A& a); 
void foo(const A& a); 
void foo(A&& a); 
void foo(const A&& a); 

그것은주의하는 것이 중요합니다 (만약 당신이 거의해야 적)는 이동 생성자/대입 연산자가 아닌 rvalue 참조를 사용하는 함수를 작성해야하는 이유가 있습니다. 당신은 const 좌변 참조 값과 통과하여 지나가는 사이에 결정해야합니다

  1. 어쨌든 (당신이 사본을 수정하거나 전달하려는 아마도 때문에 함수 내부의 객체의 복사본을 필요 해요 경우 다른 함수로), 값 (A)으로 가져옵니다. 이 방법은, 당신이 lvalue 주어진 경우, 복사해야합니다 (당신은 이것을 피할 수 없다),하지만 당신이 rvalue 주어진 경우, 그것은 최적으로 당신의 기능으로 이동됩니다.

  2. 개체 복사본이 필요하지 않은 경우 const 왼쪽 값 참조 (const A&)로 가져옵니다. 이 방법은, 당신이 lvalue 또는 rvalue 주어진 여부에 관계없이 복사본이 자리를 차지할 것입니다.이동 의미를 사용하지 못하기 때문에 복사해야 할 때 이것을 사용해서는 안됩니다. 그것의 소리에서

, 당신은 사본 전혀, 그래서 const A& 매개 변수가 작동 할 수 있도록 않을거야.

+0

나는 단지 [starius] (http://stackoverflow.com/users/1293417/starius) '를 편집하여 별다른 변경을하지 않았다. 중요한 것은 그의 편집 내용입니다. 그러한 변경에 대해 원저자의 이름을 사용하는 방법이 있어야합니다. – bogdan

+0

@bogdan 편집자는 마지막으로 편집자 였기 때문에 보여줍니다.하지만 starius는 편집 목록에 있습니다 ("편집 된 1 시간 전"텍스트를 클릭하면). –

+0

그래, 나는 그것을 보았지만 여전히 ... "개선"이 별도의 편집으로 나타나는 것을 알았다면 나는 원래의 변화를 그대로 남겨 두었을 것이다. 처음에는 버전 관리에 대해서는별로 생각하지 않았습니다. 되돌아 보면 두 가지 변경 사항을 연결하지만 병합하지는 않습니다. 어쨌든, 소음 때문에 유감입니다. – bogdan