2012-04-19 1 views
12

나는 다음 (g ++ 4.6.3) 나는 오류를 얻을C++ 연산자 오버로딩 : 개체에서 참조로의 변환이 알려져 있지 않습니까?

class A {}; 

A& operator*=(A& a, const A& b) 
{ 
    return a; 
} 

A operator*(const A& a, const A& b) 
{ 
    return A(a) *= b; 
} 

int main(int, char*[]) 
{ 
    A a, b; 

    a = a*b; 

    return 0; 
} 

를 컴파일하려고

/tmp/test.cxx: In function ‘A operator*(const A&, const A&)’: 
/tmp/test.cxx:14:20: error: no match for ‘operator*=’ in ‘(* & a) *= b’ 
/tmp/test.cxx:14:20: note: candidate is: 
/tmp/test.cxx:6:1: note: A& operator*=(A&, const A&) 
/tmp/test.cxx:6:1: note: no known conversion for argument 1 from ‘A’ to ‘A&’ 

이 나를 퍼즐 - 어떻게 그 클래스에 대한 참조로 클래스의 전환 알 수 없습니까?

영향이없는 다음과 같이 클래스 A의 선언을 변경 :

class A 
{ 
public: 
    A() {} 
    A(const A&) {} 
}; 

같은 오류가 발생했습니다.

여기에 무슨 일이 일어나고 있는지에 대한 힌트가 있으면 매우 감사하게 생각합니다.

+0

r 값에 대한 자세한. 그런 다음 메서드 서명은 다음과 같습니다. 'A operator * (const A & rhs) const;' 'return * this * = rhs' – Paranaix

+0

@Paranaix : 아니요,'const * '안에'* this'에'operator * ='를 사용할 수 없습니다. 멤버 함수가'* this'를 수정할 것이므로. –

+0

@BenVoigt : 맞습니다. 나는 그것을 하나의 라이너로 쓰고 실수로 전체 마법을 제거하려고했다. 트릭은 'this'에서 사본을 만드는 것입니다. 예 : 'ret = * this; ret * = rhs; return ret; – Paranaix

답변

13

Lucian이 말했듯이 임시 객체를 비 const 참조에 바인딩 할 수 없습니다. 컴파일러의 기대는 표현식 뒤에 객체가 존재하지 않게되므로 수정하는 것이 이해가되지 않는다는 것입니다. 복사 당신이 A(a)을 쓸 때

A operator*(A a, const A& b) 
{ 
    return a *= b; 
} 
+0

@Ben 나는 커피가 필요합니다 ... 내 명예를 지키기 위해,이 (가치 전달)은 제가 깨어 났을 때 평상시에 쓰는 방법입니다. –

+0

훨씬 간단합니다. 실제 매개 변수가 x 값일 때 이동할 수 있기 때문에 더욱 최적화되었습니다. –

5

, 당신은 A 형 (A를 rvalue)의 임시을 만듭니다

는 (인수 const&operator *=에서 말이 안 만드는) 임시을 제거, 코드를 수정하려면 a으로 구성하십시오. C++에서는 rvalue가 비 const 참조로 전달 될 수 없다고 명시합니다. Visual Studio는이 규칙에 대해 약간 엉성하지만 gcc와 같은 사람들이이 규칙을 시행합니다.

수정하려면이 방법을 사용하십시오 (정확히 동일하지만 해당 변수의 이름을 지정하면 lvalue가 생성됩니다). 1- 그리고 당신은 클래스의 범위에 연산자를 선언함으로써이 문제를 해결할 수 here

A operator*(A a, const A& b) 
{ 
    return a *= b; 
} 
+2

Konrad의 답변에 게시 한 것과 같은 반대입니다. –

+0

둘 다 맞습니다. 그러나 때로는 * 작업을 수행하기 위해 사본을 만들 필요가 없습니다. 예 : Vector * 연산자는 * =를 사용하여 * – crazyjul

+0

을 표현하지 않습니다. "Visual Studio는이 규칙에 대해 조금 싫어합니다 ...": Visual Studio는 경고 수준 4에서 실행 중일 때 경고를 오류로 처리합니다 (현명한 경우와 같이) . – mwigdahl