2014-12-11 5 views
2

:함수에서 명명되지 않은 객체를 반환합니다. RVO가 아직 시작되는 이유는 무엇입니까? 이에 대해

:

그러나 나는 GCC와 약간의 테스트를했다 "는 표현이 경우에 따라서 return 문 복사 생략 만 지역 변수의 이름 발생할 수 있습니다"Why does std::move prevent RVO? 사람이 썼다

class X 
{ 
public: 
    X() 
    { 
     cout << "def" << endl; 
    } 
    X(const X& x) 
    { 
     cout << "copy" << endl; 
    } 
    X(X&& x) 
    { 
     cout << "move" << endl; 
    } 
}; 

X produceX() 
{ 
    return X(); 
} 

int main() 
{ 
    X x{produceX()}; 
    return 0; 
} 

produceX 함수는 명명 된 값을 반환하지 않습니다. 이름이 지정되지 않은 임시 객체를 반환합니다. 그러나 RVO는 여전히 발 차고 카피 나 이동 건설은 없습니다. main의 x 객체는 내부에서 생성됩니다. 내가 이와 같이 produceX를 쓰면 :

X produceX() 
{ 
    X localNamedObject; 
    return localNamedObject; 
} 

예상대로 작동합니다. 그런데 왜 RVO가 허용됩니까?

+2

C++ 표준에 따르면 허용됩니다. 변수는 * 지명되지 않습니다. 따옴표가 잘못되었거나 문맥에서 벗어났습니다. – juanchopanza

+3

"따라서 return 문에서 복사본 elision은식이 로컬 변수의 이름 인 경우에만 발생할 수 있기 때문에"는 사실이 아닙니다. –

답변

7

이 진술은 지나치게 단순화되었지만, 실제로이 질문에 답을 얻었을 때 표준에서 관련 텍스트를 제공하지만이 진술은 단순화되었습니다.

로컬 변수를 반환 할 때뿐 아니라 임시 (같은 유형의 객체를 초기화하는 데 임시를 사용하는 일반적인 경우)를 반환 할 때 elion이 허용됩니다.

값으로 예외를 던지고 잡는 경우에도 허용되지만이 질문의 범위를 벗어납니다.

+0

누군가가 임시로 반환 할 때 RVO를 적용 할 수 있다는 표준의 특정 문장을 지적 할 수 있습니까? 또한 이것은 std :: move가 RVO를 막지 못한다는 것을 의미합니까? –

+1

@rubix_addict : 당신이 그 인용문에서 대답을 얻었습니다. C++ 11 [class.copy] 12.8/31, 세 번째 글 머리 기호. –

+3

"또한 이것은 std :: move가 RVO를 막지 않는다는 것을 의미합니까? - 아니요, 조건은"임시 클래스 객체 ...가 복사/이동 될 것 "입니다. 'std :: move'의 결과는 임시 객체가 아닌 참조이므로 elision은 적용되지 않습니다. –

3

RVO는 "반환 값 최적화"의 약자이며 반환 값 공간에서 직접 반환 식 결과를 구성하는 기술을 나타냅니다. 반환식이 rvalue 일 때 적용됩니다.

NRVO는 "명명 된 반환 값 최적화"의 약자이며 결국 반환 값 공간에서 직접 반환되는 명명 된 개체를 구성하는 기술을 나타냅니다. 반환식이 lvalue 일 때 적용됩니다.