2013-04-30 3 views
84
class A {}; 

int main() { 
A() = A(); 
return 0; 
} 

왜이 코드가 컴파일됩니까? 할당 연산자의 왼쪽에 lvalue를 두어야한다는 오류가 있어서는 안됩니까? A() lvalue입니까? g ++ 4.7 버전A() = A() - 왜 컴파일됩니까?

답변

87

기본 제공 유형의 경우 기본 제공 할당 연산자 왼쪽에 수정 가능한 왼쪽 값이 필요합니다.

그러나 내장 연산자는 사용하고 있지 않지만 클래스에 의해 암시 적으로 선언 된 오버로드가 있습니다. 이것은 우변 호출 할 수

A().operator=(A()); 

부재의 기능에 해당 멤버 함수이다.

+0

A (A())를 사용하지 않습니까? – stardust

+7

복사 초기화가 아닌가요? – stardust

+0

@Named : 호출시'operator ='on A –

32

당신이 정말로 원하는 경우, 당신이 C++ (11)와 함께 컴파일 할 수 있습니다 :

class A { 
    template <typename T> 
    void operator=(T&&) && = delete; // no op= for rvalues 

    // generate other special members normally 
    A() = default; 
    A(A const&) = default; 
    A(A&&) = default; 
    ~A() = default; 
    // op= only for lvalues 
    A& operator=(A&&) & = default; 
    A& operator=(A const&) & = default; 
}; 

int main() { 
A() = A(); // error 
return 0; 
} 

(live example)

참고 &&&의 끝에 (REF-예선 일명) 다양한 operator= 양식의 선언 이렇게하면 lvalues ​​및 rvalues에 대해 해당 선언이 각각 선택됩니다. 그러나 rvalue 버전은 과부하 해결 방법으로 선택하면 프로그램이 삭제되어 잘못 작성됩니다.

그러나 기본 생성 연산자 =에는 ref-qualifier가 없으므로 lvalues와 rvalues ​​모두에 대해 호출 할 수 있습니다. 그것이 A()이 rvalue인데도 문제의 코드가 컴파일되는 이유입니다.

1

C++ 컴파일러는 모든 클래스에 기본 생성자를 제공합니다. 이는 코드와 관련하여 일어나는 일입니다. A() = A(); 이름없는 객체로 생성자를 호출하고 함수는 생성 된 객체에 대한 참조를 반환합니다 (암시 적). 그게 다야 ...