2017-04-18 4 views
-2

나는 rvalue 참조를 반환하는 함수를 가지고 있습니다. 이제std :: vector :: push_back (T &&)는 T &&를 반환하는 함수가 직접 전달 될 때 T의 기본 생성 값을 만듭니다.

auto function() -> int&& { 
    int x{10}; 
    std::cout << x << std::endl; // to check the value of x 
    return std::move(x); 
} 

, 나는 다음과 같은 코드를 사용할 때 :

이 다음과 같은 출력이 기능()가를 rvalue 참조를 반환하더라도처럼 보이는

10 
0 

결과

std::cout << function() << std::endl; 
std::vector<int> v; 
v.push_back(function()); 
std::cout << v[0] << std::endl; 

, 벡터가 기본 생성 된 int를 다시 푸시합니다. 나는이 같은 코드가있는 경우

흥미롭게 :

auto x = function(); 
v.push_back(std::move(x)); 

이 완벽하게 작동합니다.

단순히 함수에서 로컬 변수를 반환했다면 RVO가 복사 제거를 수행했을 것입니다. 하지만 내가 임시 변통을하고 있기 때문에 :: move() 나는 임시 변수가 반환되는 RVO를 트립하고있다.

이제 v.push_back (function())에서 vector :: push_back (T & &) 함수를 호출하여 임시 변수에 대한 참조를 참조합니다. 이 경우 항상 쓰레기가 아닌 0이됩니다 (최적화가 설정되어 있기 때문에 추측합니다).

그러나 로컬 변수에서 function()의 반환 값을 캡처하려고하면 반환 값의 프로세스에서 생성 된 임시 변수의 값이이 로컬 변수에 복사되기 때문에 작동합니다. 이것은 내가 정의되지 않은 행동으로 행운아처럼 보이지 않습니다.

답변

6

이 함수는 함수 로컬 변수에 대한 참조를 반환합니다.이 함수 로컬 변수는 누구나 사용할 수 있기 전에 소멸됩니다. (왼쪽 값 참조를 사용하는 것과 마찬가지로 rvalue 참조를 사용하는 것은 유효하지 않습니다.)

+0

이것은 약간 이해하기 쉽습니다. 'auto x = function()'과 같은 것을 사용할 때 x는 실제로 값 10을 가지며 기본값으로 생성 된 값이나 쓰레기 값이 아닌 것을 볼 수 있습니다. 나는 std :: move가 로컬 객체의 소유권을 이전 할 것이므로 자동적으로 파괴되지 않을 것이라고 예상했다. – abhijit

+1

아니요,'x'의 수명은 함수로 끝납니다. 때로는 제대로 작동하지 않는 것만 알면 정의되지 않은 동작입니다. – aschepler

관련 문제