2010-06-13 6 views
3

Rvalues ​​IMHO는 C++에서 큰 발전을 가져 왔지만, 처음에는 상당히 보였습니다. 원래 message 객체의 마지막 소유자가 오른쪽 foo()에 의해 반환되는C++의 r-value에 관한 질문 0x

#include <string> 

std::string && foo (void) 
{ 
    std::string message ("Hello!"); 

    return std::move (message); 
} 

void bar (const std::string &message2) 
{ 
    if (message2 == "Bye Bye!") 
     return; 
} 

int main() 
{ 
    bar (foo()); 
} 

참조 message2 : 아래 코드를 보면하세요?

+0

구피, 토마스에게 정확한 답변을 선택해주세요. 옳은 것으로 표시된 잘못된 대답을 보는 것은 매우 짜증나게합니다. – fredoverflow

답변

9

아니요, 올바르지 않습니다. Rottue reference를 발견했을 때 일반적인 트랩 하나에 빠졌습니다. 승인 된 답변에서 Motti처럼! 대부분의 경우

, 기능 :

당신이 RREF를 처리 할 때 발에서 당신을 촬영하지 않으려면,이 내면화 (그리고 나는 RREF 내 이전 테스트도이 실수를했다) rvalue 참조를 반환하는 것은 일반적인 참조를 반환하는 함수만큼 어리 석다.

rvalue references은 ... 참조입니다. 따라서 "메시지"에 참조 값 또는 반올림 값을 반환하면 범위를 벗어 났으므로 방금 파괴 된 객체에 대한 참조가 반환되므로 매달린 참조가 반환됩니다. 그것은 버그입니다.

또한 컴파일러에서 "메시지"가 임시 (값)임을 이미 알고 있으므로 std :: move (메시지)를 반환하지 마십시오. 따라서 std :: move로 다시 채울 필요가 없습니다. 실제로, return std :: move (something)를 쓰면 최적화를 방지 할 수 있습니다.

#include <string> 
std::string foo (void) 
{ 
    std::string message ("Hello!"); 
    return message; 
} 

void bar (const std::string& message2) 
{ 
    if (message2 == "Bye Bye!") 
     return; 
} 

int main() 
{ 
    bar (foo()); 
} 

그리운 C++ 03 :
NRVO가에서 차기 때문에이 더 :

그래서, 정확하고 가장 효율적인 방법은 (적어도 MSVC10에이 망막 정맥 폐쇄를 해제하지 보인다) 복사, 이동 금지, 단 하나의 구성.

1

편집 : r- 값 참조를 반환하는 것은 사용자가 원하는 작업이 아닙니다. 이 대답은 원래 C++ 11-r 값 참조로 파악하려고 할 때 작성되었습니다.


네 말이 맞아

message2 그러나 이것은 small string optimization에 대한 다음 이동 생성자를 사용하는 경우 발생하지 않을 수 있습니다, 그것은 foomessage에 의해 할당 된 메모리를 잠식 할 수 있도록 이동 생성자를 사용하여 구성됩니다 짧은 문자열은 복사 생성자보다 효율적이지 않습니다.

또 다른주의 할 점은 std::move을 명시 적으로 사용할 필요가 없다는 것입니다. 반환 값은 r 값 참조로 알려져 있습니다.