2

에 대한 솔루션은 다음 코드를 살펴 보자 나는에 두 줄을 생각C++ strage 컴파일 오류

struct s 
{ 
    s& operator+() {return*this;} 
}; 

void foo(s &) {} 

s bar() {} 

int main() 
{ 
    foo(bar());  //comp error 
    foo(+bar()); //ok 
} 

를 주 (컴파일러가 오른쪽 연산자 +()를 멀리 최적화 때문에), 동일해야? 어떤 것을 받아 들일 수는 있지만 다른 것은 받아들이지 않는 것이 무슨 의미입니까?

+0

컴파일러가 무엇을 최적화할지 여부에 관계없이 (예 : 거의 모든 함수 호출이 아무 것도하지 않는 등) 코드에서 잘못된 코드를 받아 들일 수 없습니다. –

답변

6

라인 foo(bar())s에 비 const 좌변 참조 (foo()의 인자)에 입력 s (bar() 의해 반환 임시) r- 수치의 결합을 시도한다. 이것은 불법입니다. 따라서 컴파일 오류입니다. rvalues는 rvalue 참조 또는 const lvalue 참조에만 바인딩 할 수 있습니다.

발현 +bar() 반면에, foo()의 좌변의 기준 파라미터로 결합 될 수있다 (즉 operator +()의 복귀 형이다) 좌변의 참조를 반환한다.

참고 : 왼쪽 값 참조는 임시으로 반환됩니다. foo()을 내부에서 사용하는 동안 (임시 표현식은 완전 표현식이 완전히 평가 될 때 파괴됩니다. 따라서 foo()이 반환 된 후에) 정의되지 않은 동작 어딘가에 해당 참조를 저장하고 역 참조하면 후에. 당신이 문제에 몰래 무료입니다 있도록

따라서, 대신 "컴파일 오류에 솔루션"로이에 대한, 당신은 그것을 컴파일러 눈가리개 할 수있는 방법을 고려해야합니다.

+0

'foo' 안에서's &'를 사용하는 것은 괜찮습니다; 임시는 그것이 만들어진 곳의 문장의 끝까지 존재한다. ** foo가 ** 돌아온 후에 **이다. 나중에 사용하기 위해 저장하면 문제가 발생할 수 있습니다. –

+0

@PeteBecker : 네 말이 맞아, 나는 이것을 간과했다. 정정 해줘서 고마워, 내 대답을 편집 했어. –