Operator Overload

연산자 오버로딩 한계

기호를 빌리면 호출자는 수학적 또는 표준 라이브러리 관례를 기대한다. 새 값 생성과 기존 값 변경, 비교 기준을 분명히 나눠야 한다.

01

관례 우선 확인

+가 값을 바꾸거나 ==가 일부 상태만 비교하면 호출자 기대와 어긋난다.

02

복합 대입을 기준으로 둔다

+=를 구현하고 +를 그 위에 얹으면 변경 연산과 새 값 연산을 나누기 쉽다.

03

비교 규칙을 테스트한다

정렬 컨테이너에 들어갈 타입은 strict weak ordering을 만족해야 한다.

+
새 값 두 피연산자를 바꾸지 않고 결과를 만든다는 기대가 강하다.
변경은 +=가 맡는다.
==
동등성 관찰 가능한 상태 전체인지 식별자만인지 기준을 정한다.
hash와도 맞춰야 한다.
<
정렬 기준 추이성과 비대칭성을 만족해야 sort와 set이 안정된다.
tie로 구현하면 실수가 줄어든다.
<<
출력 표현 ostream이 왼쪽이므로 비멤버 함수가 자연스럽다.
필요하면 friend를 좁게 연다.

부작용 · 비교 일관성 · 기호 남용 점검

부작용 비변경처럼 보이는 연산자가 내부 상태를 바꾸지 않는가.
비교 일관성 ==와 정렬 비교가 같은 동등성 개념과 충돌하지 않는가.
기호 남용 도메인 동사를 쓰는 편이 더 명확한 연산자가 아닌가.

복합 대입 기반

Value& operator+=(const Value& rhs);
friend Value operator+(Value lhs, const Value& rhs) {
    return lhs += rhs;
}