class A {};
int main() {
A() = A();
return 0;
}
왜이 코드가 컴파일됩니까? 할당 연산자의 왼쪽에 lvalue를 두어야한다는 오류가 있어서는 안됩니까? A() lvalue입니까? g ++ 4.7 버전A() = A() - 왜 컴파일됩니까?
class A {};
int main() {
A() = A();
return 0;
}
왜이 코드가 컴파일됩니까? 할당 연산자의 왼쪽에 lvalue를 두어야한다는 오류가 있어서는 안됩니까? A() lvalue입니까? g ++ 4.7 버전A() = A() - 왜 컴파일됩니까?
기본 제공 유형의 경우 기본 제공 할당 연산자 왼쪽에 수정 가능한 왼쪽 값이 필요합니다.
그러나 내장 연산자는 사용하고 있지 않지만 클래스에 의해 암시 적으로 선언 된 오버로드가 있습니다. 이것은 우변 호출 할 수
A().operator=(A());
부재의 기능에 해당 멤버 함수이다.
당신이 정말로 원하는 경우, 당신이 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;
}
참고 &
및 &&
의 끝에 (REF-예선 일명) 다양한 operator=
양식의 선언 이렇게하면 lvalues 및 rvalues에 대해 해당 선언이 각각 선택됩니다. 그러나 rvalue 버전은 과부하 해결 방법으로 선택하면 프로그램이 삭제되어 잘못 작성됩니다.
그러나 기본 생성 연산자 =에는 ref-qualifier가 없으므로 lvalues와 rvalues 모두에 대해 호출 할 수 있습니다. 그것이 A()
이 rvalue인데도 문제의 코드가 컴파일되는 이유입니다.
C++ 컴파일러는 모든 클래스에 기본 생성자를 제공합니다. 이는 코드와 관련하여 일어나는 일입니다. A() = A(); 이름없는 객체로 생성자를 호출하고 함수는 생성 된 객체에 대한 참조를 반환합니다 (암시 적). 그게 다야 ...
A (A())를 사용하지 않습니까? – stardust
복사 초기화가 아닌가요? – stardust
@Named : 호출시'operator ='on A –