std::array 비교 연산자

std::array 비교 연산자 (operator==, <=> 등)

std::array의 내용물을 비교하는 관계 연산자들이에요. 원소 단위로 같음과 사전식 순서를 판정해요. C++11부터 ==, !=, <, <=, >, >=가, C++20부터 세 방향 비교 <=>가 제공돼요.

출처: cppreference

본문

std::array는 기본 내장 배열과 달리 자체 비교 연산자를 가지지 않고, 아래처럼 비멤버 함수 템플릿으로 정의돼 있어요.

template< class T, std::size_t N >
bool operator==( const std::array<T, N>& lhs,
                 const std::array<T, N>& rhs );   // (1)

template< class T, std::size_t N >
bool operator!=( const std::array<T, N>& lhs,
                 const std::array<T, N>& rhs );   // (2) (until C++20)

template< class T, std::size_t N >
bool operator<( const std::array<T, N>& lhs,
                const std::array<T, N>& rhs );    // (3) (until C++20)

// ... <=, >, >= (4)(5)(6) (until C++20) ...

template< class T, std::size_t N >
constexpr synth-three-way-result<T>
    operator<=>( const std::array<T, N>& lhs,
                 const std::array<T, N>& rhs );   // (7) (since C++20)

두 배열의 내용물을 비교해요.

  • (1,2) lhsrhs의 내용물이 같은지 확인해요. 원소 개수가 같고, 같은 위치에 있는 각 원소가 서로 같으면 같다고 판정해요.
  • (3-6) lhsrhs의 내용물을 사전식(lexicographical)으로 비교해요. std::lexicographical_compare와 같은 함수로 비교가 수행돼요.
  • (7) lhsrhs의 내용물을 사전식으로 비교하는데, std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), synth-three-way)를 호출한 것처럼 동작해요. 반환 타입은 synth-three-way의 반환 타입, 즉 synth-three-way-result<T>예요.

C++20부터 <, <=, >, >=, != 연산자는 각각 operator<=>operator==로부터 합성(synthesized)돼요.

  • 매개변수 lhs, rhs: 비교할 배열들이에요.

  • (1,2)를 쓰려면 TEqualityComparable 요구사항을 만족해야 해요.

  • (3-6)을 쓰려면 TLessThanComparable 요구사항을 만족해야 하고, 순서 관계가 전순서(total order)를 이뤄야 해요.

  • 반환 값:

    • (1) 내용물이 같으면 true, 아니면 false.
    • (2) 내용물이 같지 않으면 true, 아니면 false.
    • (3) lhs 내용물이 rhs 내용물보다 사전식으로 작으면 true.
    • (4) lhs 내용물이 rhs 내용물보다 사전식으로 작거나 같으면 true.
    • (5) lhs 내용물이 rhs 내용물보다 사전식으로 크면 true.
    • (6) lhs 내용물이 rhs 내용물보다 사전식으로 크거나 같으면 true.
    • (7) 같지 않은 첫 원소 쌍이 있으면 그 상대적 순서를, 없으면 lhs.size() <=> rhs.size()를 돌려줘요.
  • 복잡도: 배열 크기에 선형이에요.

참고로 (C++20 이전) 관계 연산자는 원소 타입의 operator<로 정의됐어요. C++20 이후엔 synth-three-way를 쓰는데, 가능하면 operator<=>를, 아니면 operator<를 사용해요. 원소가 operator<=>를 제공하지 않지만 세 방향 비교 가능한 타입으로 암시적 변환된다면, operator< 대신 그 변환이 쓰이기도 해요.

예제를 확인하면요.

#include <cassert>
#include <compare>
#include <array>

int main()
{
    const std::array
        a{1, 2, 3},
        b{1, 2, 3},
        c{7, 8, 9};

    assert
    (""
        "Compare equal containers:" &&
        (a != b) == false &&
        (a == b) == true &&
        // ... 모든 비교 결과 확인 ...
    "");
}

결함 보고로 LWG 3431이 있어요. C++20에서 operator<=>Tthree_way_comparable이기를 요구하지 않았던 문제가 수정됐어요.

더 알아보기 (Learn more)

cppreference