2017-02-19 3 views
0

다음과 같은 컴파일 : 뭔가에 const를 참조를 반환경고 : 로컬 임시 객체에 대한 참조를 반환

namespace platform { 
    struct event {}; 
    struct keyboard_event : public event {}; 

    const platform::event& wait_event() 
    { 
    return platform::keyboard_event(); 
    } 
} 

int main(int argc, const char* argv[]) 
{ 
    const platform::event& event = platform::wait_event(); 
    return 0; 
} 

는 그 소리와 함께 다음과 같은 경고를 얻을 수

main.cc:7:12: warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return platform::keyboard_event(); 
      ^~~~~~~~~~~~~~~~~~~~~~~~~~ 

그러나 그것은 수명을하지 않는 확장 ? 현재 초안 나를 위해로드되지

그래서 내가 대신 cppreference.com를 인용하겠습니다하십시오 CONST 좌변 참조에 또는를 rvalue 참조 바인딩에 의해 연장 될 수있다

임시 개체의 수명을 (C++ 11 이후), 자세한 내용은 참조 초기화를 참조하십시오.

동일한 효과가 있지만 경고가 표시되지 않도록하려면 어떻게 다시 쓸 수 있습니까?

+0

'platform :: keyboard_event()'는 r 값입니다. 그것을'const &'로 바인드하여 리턴한다. 하지만 temp, const 또는 not에 대한 참조를 반환 할 수는 없습니다. 고전적인 "임시 참조로 복귀"경고입니다. – xinaiz

+0

"참조 초기화를 참조하십시오"에서 링크를 따라 간다면 cppreference가 "반환 문에서 함수의 반환 값에 대한 임시 바인딩이 확장되지 않았습니다"라고 계속 말합니다. – Cubbi

답변

2

아니요, "참조를 반환합니다"는 마술처럼 평생을 연장하지 않습니다.

struct Foo{}; 

{ 
    const auto & r = Foo{}; // Foo object not destroyed at semicolon... 
    // ... 
} 
// ... but is destroyed only here. 

내 prvalue 바운드되지는 다음과 prvalue는 기준 변수에 결합되고, prvalue의 수명 변수의 연장 될 때 수명 연장

유일한 시간은 어떤 변수 에라도 적용되므로 수명이 연장되지 않습니다.

비 정적 클래스 데이터 멤버는이 고려 사항에 대해 "변수"로 계산되지 않으므로 클래스에 참조 멤버가있는 경우 생성자 이니셜 라이저 목록을 통해 수명을 연장 할 수 없습니다.

+0

알 수 없으므로 정의되지 않은 동작까지 수행했습니다./스택이 변경되지 않은 행운. 따라서 const l-value 또는 r-value 참조로 수명을 연장하는 것은 어떤 시나리오에서든 참조로 반환하는 데 사용할 수 없습니까? –

+0

@CasperBeyer 아니오, 값에 의해서만 반환됩니다.이 경우에는 –

+0

이 값으로 돌아 오면 괜찮을까요? (구조체마다 다른 데이터 세트가 있다고 가정) –

관련 문제