2017-11-15 3 views
13

operator<=>을 C++ 20에 추가 한 경우 간단한 멤버 별 비교가 아닌 경우에이 연산자를 구현하는 방법을 추론하고 싶습니다.선택 연산자 <=>을 구현하는 경우 <T>

어떻게 당신은 optional<U> 또는 Uoptional<T>를 비교 우주선 연산자, 우리가 어느 TU에 비교하거나 올바른 반환 유형을 받고, 상태를 기본 비교해야 할 경우가 구현하는 것이? latest paper에는 그러한 예가 없습니다.

+0

현재이 기능은 현재 유효 할 수있는'>> 연산자 >><=>> c;와 호환되지 않습니다. –

+2

@ JohannesSchaub-litb 예, 그렇습니다. 이것은 또한 제안서에서 언급했습니다 : "토큰 화는 평소대로 최대 벙어리를 따른다. [...] 이것은 유일한 알려진 역방향 소스 비 호환성이며 의도적입니다. (우리는 공간을 사용하지 않고 이러한 코드를 유지하는 특수 구문 분석 규칙을 채택 할 수 있지만 문제가 너무 적어서 을 막을 것입니다.) ". 어쨌든 거기에 공백이나 괄호가있는 것처럼 보아도, 나는 여기에있는 제안에 동의한다. –

+0

@Barry 제안에서 언급 한 바와 같이, 내가 볼 수있는 한 (다음과 같은 비교 만 제공하지만 뒤 따르지 않는 스위치는 제공하지 않습니다. 그리고 이것은 "알려진 유일한 역방향 소스 비 호환성"입니다) –

답변

6

올바른 구현 방법은 std::compare_3way() 함수 템플릿을 사용하여 (1) 그러한 비교가 실행 가능한지와 (2) 비교 카테고리가 실제로 무엇인지 모두를 처리하는 것입니다.

template <typename T> 
class optional { 
public: 
    // ... 

    template <typename U> 
    constexpr auto operator<=>(optional<U> const& rhs) const 
     -> decltype(compare_3way(**this, *rhs)) 
    { 
     if (has_value() && rhs) { 
      return compare_3way(**this, *rhs); 
     } else { 
      return has_value() <=> rhs.has_value(); 
     } 
    } 

    template <typename U> 
    constexpr auto operator<=>(U const& rhs) const 
     -> decltype(compare_3way(**this, rhs)) 
    { 
     if (has_value()) { 
      return compare_3way(**this, rhs); 
     } else { 
      return strong_ordering::less; 
     } 
    } 

    constexpr strong_ordering operator<=>(nullopt_t) const { 
     return has_value() ? strong_ordering::greater 
          : strong_ordering::equal; 
    } 
}; 

3 방향 bool 비교 수율 std::strong_ordering, 다른 네 비교 범주에 암시 적으로 변환됩니다 매우 컴팩트 한 모든 비교 연산자의 구현을하게

.

마찬가지로 strong_ordering::less 적절하게, weak_ordering::less, partial_ordering::less, strong_equality::unequal 또는 weak_equality::nonequivalent에 암시 적으로 변환되고.

+0

여기서'* lhs'와'* rhs'를 호출합니다. 그 중 하나가 비어 있다는 것을 알 때. 또한 '운영자 <=>'을 회원으로 구현할 때 비회원으로 구현하는 이유는 무엇입니까? –

+0

@DanielH 2 차 비교에서 오타를 수정했습니다 – Yakk

+0

('has_value'가 'bool'에 대한 명시 적 캐스팅보다 명확 하긴하지만 그 스타일의 문제입니다) –