답변:
그것은 안전하다. Const ref는 일시적인 수명을 연장시킵니다. 범위는 const ref의 범위가됩니다.
임시 객체 의 수명 은 const lvalue 참조 또는 rvalue 참조 (C ++ 11부터)에 바인딩하여 확장 할 수 있습니다 . 자세한 내용 은 참조 초기화 를 참조하십시오.
참조가 임시 또는 하위 오브젝트에 바인드 될 때마다 다음 예외를 제외 하고 임시의 수명이 참조의 수명과 일치하도록 확장됩니다 .
- return 문에서 함수의 반환 값에 대한 임시 바인딩은 확장되지 않으며 반환 식의 끝에서 즉시 삭제됩니다. 이러한 함수는 항상 매달려있는 참조를 반환합니다.
- 생성자 이니셜 라이저 목록의 참조 멤버에 대한 임시 바인딩은 오브젝트가 존재하지 않는 한 생성자가 종료 될 때까지만 지속됩니다. (참고 : 이러한 초기화는 DR 1696부터 잘못 구성되어 있습니다).
- 함수 호출에서 참조 매개 변수에 대한 임시 바인딩은 해당 함수 호출을 포함하는 전체 표현식이 끝날 때까지 존재합니다. 함수가 전체 표현식보다 오래 지속되는 참조를 리턴하면 매달려있는 참조가됩니다.
- new-expression에 사용 된 이니셜 라이저의 참조에 대한 임시 바인딩은 초기화 된 객체가 아닌 한 해당 new-expression을 포함하는 전체 표현식이 끝날 때까지 존재합니다. 초기화 된 객체가 전체 표현식보다 오래 지속되면 해당 참조 멤버가 매달려있는 참조가됩니다.
- 이니셜 라이저를 포함하는 전체 표현식의 끝까지 존재합니다.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
일반적으로 임시의 수명은 "통과"하여 연장 할 수 없습니다. 임시가 바인딩 된 참조에서 초기화 된 두 번째 참조는 수명에 영향을 미치지 않습니다.
로 @Konrad 루돌프는 지적 (위의 마지막 단락 참조)
"
c.GetSomeVariable()
로컬 객체에 대한 참조 또는 자체적으로 일부 객체의 수명을 연장하는 참조를 반환하면 수명 연장이 시작되지 않습니다"
c.GetSomeVariable()
리턴한다 참조 로컬 객체 또는 그 자체가 어떤 개체의 수명을 연장하는 것을 참조, 수명 연장은 않습니다 하지 킥.
이것은 안전합니다.
[class.temporary]/5
: 전체 표현 의 끝과 다른 지점에서 임시가 파괴되는 세 가지 컨텍스트가 있습니다 . [..]
[class.temporary]/6
: 세 번째 컨텍스트는 참조가 임시 객체에 바인딩 된 경우입니다. 참조가 바인딩 된 임시 객체 또는 참조가 바인딩 된 하위 객체의 완전한 객체 인 임시 객체는 참조가 바인딩 된 glvalue가 다음 중 하나를 통해 얻은 경우 참조 수명 동안 지속됩니다. : [여기에 많은 것들]
이 특정한 경우에 안전합니다. 그러나 모든 임시가 const 참조로 캡처하는 것이 안전하지는 않습니다.
#include <stdio.h>
struct Foo {
int member;
Foo() : member(0) {
printf("Constructor\n");
}
~Foo() {
printf("Destructor\n");
}
const Foo& method() const {
return *this;
}
};
int main() {
{
const Foo& x = Foo{}; // safe
printf("here!\n");
}
{
const int& y = Foo{}.member; // safe too (special rule for this)
printf("here (2)!\n");
}
{
const Foo& z = Foo{}.method(); // NOT safe
printf("here (3)!\n");
}
return 0;
}
명령문 z
에 도달하기 전에 전체 인스턴스의 끝에서 임시 인스턴스가 삭제되므로에 대한 참조 는 사용하기에 안전하지 않습니다 printf
. 출력은 다음과 같습니다
Constructor
here!
Destructor
Constructor
here (2)!
Destructor
Constructor
Destructor
here (3)!