developer tip

A () = A ()-왜 컴파일됩니까?

copycodes 2020. 9. 19. 11:29
반응형

A () = A ()-왜 컴파일됩니까?


class A {};

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

이 코드가 컴파일되는 이유는 무엇입니까? 할당 연산자의 왼쪽에 lvalue를 배치해야한다는 오류가 없어야합니까? A () lvalue입니까? g ++ 4.7 버전


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

그러나 이것은 내장 연산자를 사용하는 것이 아니라 클래스에 의해 암시 적으로 선언 된 오버로드입니다. 이것은 다음과 같은 멤버 함수입니다.

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

멤버 함수는 rvalue에서 호출 될 수 있습니다 .


정말로 원한다면 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; 
}

( 실제 예 )

다양한 형식 의 선언 끝에 있는 &and &&(일명 ref 한정자)에 유의하십시오 operator=. 이렇게하면 각각 lvalue 및 rvalue에 대해 이러한 선언이 선택됩니다. 그러나 rvalue 버전을 과부하 해결로 선택하면 프로그램이 삭제되어 잘못된 형식이됩니다.

그러나 기본적으로 생성 된 operator =에는 ref 한정자가 없습니다. 즉, lvalue와 rvalue 모두에 대해 호출 될 수 있습니다. 이것이 A()rvalue 임에도 불구하고 질문의 코드가 컴파일되는 이유 입니다.


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

참고 URL : https://stackoverflow.com/questions/16303175/aa-why-does-it-compile

반응형