이상한 행동과 운영자>=오버로드
-
23-08-2019 - |
문제
나는 이상한 행동과 운영자 과부하에서는 C++.내가 있는 클래스가 필요한지 확인하려면 해당 내용이 더 크거나 같은 두 배 긴.나는 과부>=연산자를 확인할,나의 선언은 다음과 같습니다:
bool MyClass::operator>=(long double value) const;
나는 나는 또한 캐스트-긴 두 번 운영자를 위해 my class,작동하는 예외없이 특정 조건에서만.지금 할 때,내가 이 연산자를 사용하여 컴파일러는 불평가의 모호한의 사용자>=및 대안은:
- 내입니다.
- 내장
operator>=(long double, int)
.
지금,나는 어떻게 프로그램을 사용하여 내 operator?
해결책
2015 업데이트: 또는,당신은 유지하려는 경우 변환 기능을 사용하여 (double)obj
구문을 대신 obj.to_double()
구문,변환 기능을 explicit
붙임으로써는 키워드를 사용합니다.야 할 명시적인 던지기 위해 다음 변환 트리거입니다.개인적으로 선호하는 .to_double
구문을하지 않는 한,변환 것을 bool
기 때문에 이 경우 전환에 의해 사용됩 if(obj)
는 경우에도 explicit
, 는 상당히 더 읽보 if(obj.to_bool())
다.
드롭 변환 연산자입니다.그것이 문제가 발생합니다.가 같은 기능
to_double()
또는 이와 유사한 반환하는 두 가치와 통화하는 기능을 명시적으로 얻을 수 있습니다.
문제를 손에,이 문제가:
obj >= 10
을 고려하는 표현이다.내장 운영자과 일치하는 첫 번째 인자는 사용자에 의해 정의된 변환 시퀀스에 대한 귀하의 입력을 사용하여 변환자 장블().그러나 당신의 기능과 일치하는 두 번째 인수 표준에서 변환 시퀀스에서 int 긴블(필수적인 부동 소수점 전환).그것은 항상 모 있을 경우 변환해 두 개의 인수,하지만 적어도 하나의 인자로 변환할 수 있는 더 나은 나머지 인자로 변환되지 않 악화에 대한 이야기를 알려줍니다.귀하의 경우에는,내장 일 두 번째 인수 하지만 더 나은 첫 번째 나빠지만,당신의 기능과 일치하는 첫 번째 인수 하지만 더 나은 두 번째 나쁘다.
그것은 복잡,그래서 여기에 몇 가지 예입니다(변환 char int 는 호출 프로모션보다 나은 변환 char 에서 뭔가 다른 것보다 int,호출되는 변환):
void f(int, int);
void f(long, long);
f('a', 'a');
전화 번 버전입니다.기 때문에 모든 논쟁을 위한 첫 번째 변환될 수 있는 더 낫습니다.마찬가지로,다음과 같은 여전히 첫 번째 전화:
void f(int, long);
void f(long, long);
f('a', 'a');
기 때문에 첫째로 변환할 수 있는 더 나은,그리고 두 번째로 변환되지 않습 악화됩니다.그러나 다음 모:
void f(char, long);
void f(int, char);
f('a', 'a'); // ambiguous
그것의 더 흥미로운 경우에.첫번째 버전지 첫 번째 인수에 의해 정확하게 일치합니다.두번째 버전은지의 두 번째 인수에 의해 정확하게 일치합니다.그러나 두 버전을 모두 받아들이지 않는 다른 인수에는 적어도 똑같습니다.첫번째 버전이 필요합 변환을 위한 두 번째 인수하면서,두번째 버전을 필요로 승진한다.그렇더라도 프로모션은 더 이상 변환,통화를 두번째 버전은 실패합니다.
그것은 매우 비슷한 경우이다.에도 불구하는 표준 전환 시퀀스(에서 변환 int/float/double long double)가 나 보다는 사용자 정의 변환 시퀀스(에서 변환하는 MyClass long double)운영자 버전이 선택하지 않기 때문에,다른 매개 변수(long double)를 변환해야에서 논쟁보다 더 무엇을 제공 운영자의 요구에 적합한 인수(완벽하게 일치).
과부하를 해결책은 복잡한 문제에서는 C++,그래서 하나할 수 있는 엄청나게 기억하는 모든 미묘한 규칙에 있습니다.그러나 점점 거칠 계획입니다 매우 가능하다.내가 당신을 도움이되기를 바랍니다.
다른 팁
a로 암시 적 변환을 제공함으로써 double
당신은 효과적으로 진술하고 있습니다. 내 수업은 double
그리고 이런 이유로 내장 운영자가> = double
S가 사용됩니다. 만약 너라면 하다 케어, 그러면 당신의 수업은 실제로 '동등한'것이 아닙니다. double
그리고 당신은 제공하지 않는 것을 고려해야합니다 절대적인 전환 double
, 대신에 명백한 getAsdouble 또는 convertTodouble 멤버 함수.
현재 모호성이있는 이유는 표현을 위해 t >= d
어디 t
수업의 사례입니다 d
더블이면 컴파일러는 항상 왼쪽 또는 오른쪽의 변환을 제공하여 표현이 실제로 모호합니다. 어느 하나 t
'에스 operator double
호출되고 내장 연산자> = for double
s는 사용되거나 d를 홍보해야합니다. long double
회원 연산자> =가 사용됩니다.
편집, 귀하는 귀하의 전환이 긴 두 배로되고 비교는 int에 대한 것임을 제안하기 위해 질문을 업데이트했습니다. 이 경우 마지막 단락을 읽어야합니다.
현재 모호성이있는 이유는 표현을 위해 t >= d
어디 t
수업의 사례입니다 d
이다 int
, 컴파일러는 항상 왼쪽 또는 오른쪽의 변환을 제공하여 표현이 실제로 모호합니다. 어느 하나 t
'에스 operator long double
호출되고 내장 연산자> = for long double
그리고 int
사용되거나 D를 홍보해야합니다. long double
회원 연산자> =가 사용됩니다.
나는 당신이 문자 그대로 비교하고 있다고 가정합니다 int
, 그리고, 그리고 long double
:
MyClass o;
if (o >= 42)
{
// ...
}
이 경우 두 대안 모두 양호/복잡합니다.
당신의 사용 operator long double()
:
MyClass::operator long double()
- 내장
operator>=(long double, int)
당신의 사용 MyClass::operator>=(long double)
:
- 내장 변환
int
에게long double
MyClass::operator>=(long double)
당신이있어 long double
선언에서. 변경해보십시오 double
.
커스텀 캐스팅과 결합 된 운영자 과부하를 사용하는 것은 클래스 사용자에게 매우 혼란 스러울 수 있습니다. 이 수업의 사용자에게 스스로에게 물어보십시오 예상하다 두 배로 변환하거나 더블과 비교할 수 있습니까? .greaterthan (Double) 기능이 동일한 목표를 달성하지 못하고 사용자를 놀라게하지 않습니까?
모호성을 피하기 위해 비교하기 전에 항상 객체를 두 배로 명시 적으로 캐스트 할 수 있다고 생각합니다. 그러나 내가 당신이라면 위의 접근 방식을 재고하고 멋진 유형 캐스팅 및 운영자 과부하 대신 직관적이고 놀랍지 않은 방식으로 직관적이고 행동하는 코드 작성에 중점을 둘 것입니다.
(FQA의 Wonderful에서 영감을 얻었습니다 운영자 과부하에 대해 언급합니다)
- 내장 연산자> = (긴 이중, int).
정의한 것 같습니다.
bool class::operator>=(long double value) { return value >= classValue; }
그리고 당신은 실종되었습니다 :
bool class::operator>=(double value) { return value >= classValue; }
bool class::operator>=(int value) { return value >= classValue; }
따라서 컴파일러는 어떤 방법을 변환 할 것인지 결정할 수 없습니다. (모호합니다.)
아마도 템플릿 함수 (또는 방법)가 도움이 될까요?
상황을 조심하십시오 a> = b 다른 방법을 호출합니다 b> = a.