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


85
class A {};

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

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

답변:


88

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

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

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

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


7
복사 초기화 아닌가요?
stardust 2013-04-30

13
@Named : 아니요, 초기화가 아닌 할당입니다.
Mike Seymour 2013

1
@ paul23 : 그것은 사실입니다 (당신이 의미 operator=하지 않는다고 가정 할 때 operator()), 그러나 질문과 많은 관련이 없습니다. 이 예제는 할당의 결과로 아무것도하지 않습니다.
Mike Seymour 2013

3
@ paul23 A()은을 호출하지 않고 operator()유형의 객체를 생성합니다 A.
interjay 2015

3
선언이 없기 때문에 초기화 할 수 없습니다.
Kos 2015

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; 
}

( 실제 예 )

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

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


1

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.