다음 코드는 처음에는 무해한 것으로 보입니다. 사용자는이 기능 bar()
을 사용하여 일부 라이브러리 기능과 상호 작용합니다. (이것은 bar()
비 일시적 값 또는 이와 유사한 것에 대한 참조를 반환 한 이후 로 오랫동안 작동했을 수도 있습니다 .) 그러나 이제는 단순히의 새로운 인스턴스를 반환합니다 B
. B
다시 반복 a()
가능한 유형의 객체에 대한 참조를 반환 하는 함수 가 A
있습니다. 사용자는이 객체를 쿼리하려고합니다.이 객체 는 반복이 시작되기 전에 B
반환 된 임시 객체 bar()
가 소멸 되므로 segfault로 이어집니다 .
나는 누구 (도서관 또는 사용자)가 이것을 비난 해야하는지 결정적입니다. 모든 라이브러리 제공 클래스는 깨끗해 보였으며 확실히 다른 코드와는 다른 (멤버에 대한 참조 반환, 스택 인스턴스 반환 등) 아무것도하지 않습니다. 사용자는 아무 것도 잘못하지 않는 것 같습니다. 그는 객체의 수명과 관련하여 아무것도하지 않고 일부 객체를 반복하고 있습니다.
(관련 질문은 다음과 같습니다. 코드가 루프 헤더에서 둘 이상의 체인 호출에 의해 검색된 항목에 대해 코드가 "범위에 따라 범위를 정하지 않아야"한다는 일반적인 규칙을 설정해야합니다. rvalue?)
#include <algorithm>
#include <iostream>
// "Library code"
struct A
{
A():
v{0,1,2}
{
std::cout << "A()" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
int * begin()
{
return &v[0];
}
int * end()
{
return &v[3];
}
int v[3];
};
struct B
{
A m_a;
A & a()
{
return m_a;
}
};
B bar()
{
return B();
}
// User code
int main()
{
for( auto i : bar().a() )
{
std::cout << i << std::endl;
}
}