utility_intcmp

utility_intcmp (정수 비교 함수)

이 페이지에서는 C++20부터 <utility> 헤더에 추가된 정수 비교 함수들(cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal, cmp_greater_equal)을 다뤄요. 이 함수들은 부호 있는 정수와 부호 없는 정수를 안전하게 비교할 수 있도록 도와줘요. 내장 비교 연산자와 달리 음수 부호 정수가 항상 부호 없는 정수보다 작다고 판단해서, 값이 보존되지 않는 변환으로 인한 문제를 피할 수 있어요.

출처: cppreference

본문

개요

<utility> 헤더에 정의되어 있어요.

정의 번호 (C++20부터)
template < class T , class U > constexpr bool cmp_equal ( T t , U u ) noexcept ; (1) (since C++20)
template < class T , class U > constexpr bool cmp_not_equal ( T t , U u ) noexcept ; (2) (since C++20)
template < class T , class U > constexpr bool cmp_less ( T t , U u ) noexcept ; (3) (since C++20)
template < class T , class U > constexpr bool cmp_greater ( T t , U u ) noexcept ; (4) (since C++20)
template < class T , class U > constexpr bool cmp_less_equal ( T t , U u ) noexcept ; (5) (since C++20)
template < class T , class U > constexpr bool cmp_greater_equal ( T t , U u ) noexcept ; (6) (since C++20)

두 정수 tu의 값을 비교해요. 내장 비교 연산자와 달리, 음수 부호 정수는 항상 부호 없는 정수보다 작다고(그리고 같지 않다고) 비교돼요. 이 비교는 값이 보존되지 않는 정수 변환에 대해 안전해요.

-1 > 0u; // true
std::cmp_greater(-1, 0u); // false

T 또는 U가 정수 타입이 아니거나, 문자 타입이거나, bool이면 컴파일 타임 오류가 발생해요.

매개변수

이름 설명
t 왼쪽 인수
u 오른쪽 인수

반환값

비교 결과에 따라 bool 값을 반환해요.

가능한 구현

template < class T , class U > constexpr bool cmp_equal ( T t , U u ) noexcept
{
    if constexpr ( std :: is_signed_v < T > == std :: is_signed_v < U > )
        return t == u;
    else if constexpr ( std :: is_signed_v < T > )
        return t >= 0 && std :: make_unsigned_t < T > ( t ) == u;
    else
        return u >= 0 && std :: make_unsigned_t < U > ( u ) == t;
}

template < class T , class U > constexpr bool cmp_not_equal ( T t , U u ) noexcept
{
    return ! cmp_equal ( t , u );
}

template < class T , class U > constexpr bool cmp_less ( T t , U u ) noexcept
{
    if constexpr ( std :: is_signed_v < T > == std :: is_signed_v < U > )
        return t < u;
    else if constexpr ( std :: is_signed_v < T > )
        return t < 0 || std :: make_unsigned_t < T > ( t ) < u;
    else
        return u >= 0 && t < std :: make_unsigned_t < U > ( u );
}

template < class T , class U > constexpr bool cmp_greater ( T t , U u ) noexcept
{
    return cmp_less ( u , t );
}

template < class T , class U > constexpr bool cmp_less_equal ( T t , U u ) noexcept
{
    return ! cmp_less ( u , t );
}

template < class T , class U > constexpr bool cmp_greater_equal ( T t , U u ) noexcept
{
    return ! cmp_less ( t , u );
}

참고 사항

이 함수들은 열거형(std::byte 포함), char, char8_t, char16_t, char32_t, wchar_t, bool을 비교하는 데 사용할 수 없어요.

기능 테스트 매크로 표준 기능
__cpp_lib_integer_comparison_functions 202002L (C++20) 정수 비교 함수

예제

아래 예제는 적절한 경고 억제 플래그(예: -Wno-sign-compare, gcc/clang에서 -Wall -Wextra와 함께 사용) 없이 컴파일하면 부호 비교 경고가 발생할 수 있어요.

#include <utility>

// Uncommenting the next line will disable "signed/unsigned comparison" warnings:
// #pragma GCC diagnostic ignored "-Wsign-compare"

int main()
{
    static_assert(sizeof(int) == 4); // precondition

    // Quite surprisingly
    static_assert(-1 > 1U); //< warning: sign-unsign comparison
    // because after implicit conversion of -1 to the RHS type (`unsigned int`)
    // the expression is equivalent to:
    static_assert(0xFFFFFFFFU > 1U);
    static_assert(0xFFFFFFFFU == static_cast<unsigned>(-1));

    // In contrast, the cmp_* family compares integers as most expected -
    // negative signed integers always compare less than unsigned integers:
    static_assert(std::cmp_less(-1, 1U));
    static_assert(std::cmp_less_equal(-1, 1U));
    static_assert(!std::cmp_greater(-1, 1U));
    static_assert(!std::cmp_greater_equal(-1, 1U));

    static_assert(-1 == 0xFFFFFFFFU); //< warning: sign-unsign comparison
    static_assert(std::cmp_not_equal(-1, 0xFFFFFFFFU));
}

같이 보기

이름 설명
equal_to x == y를 구현하는 함수 객체 (클래스 템플릿)
not_equal_to x != y를 구현하는 함수 객체 (클래스 템플릿)
less x < y를 구현하는 함수 객체 (클래스 템플릿)
greater x > y를 구현하는 함수 객체 (클래스 템플릿)
less_equal x <= y를 구현하는 함수 객체 (클래스 템플릿)
greater_equal x >= y를 구현하는 함수 객체 (클래스 템플릿)
ranges::equal_to (C++20) x == y를 구현하는 제약된 함수 객체 (클래스)
ranges::not_equal_to (C++20) x != y를 구현하는 제약된 함수 객체 (클래스)
ranges::less (C++20) x < y를 구현하는 제약된 함수 객체 (클래스)
ranges::greater (C++20) x > y를 구현하는 제약된 함수 객체 (클래스)
ranges::less_equal (C++20) x <= y를 구현하는 제약된 함수 객체 (클래스)
ranges::greater_equal (C++20) x >= y를 구현하는 제약된 함수 객체 (클래스)
compare_three_way (C++20) x <=> y를 구현하는 제약된 함수 객체 (클래스)
in_range (C++20) 정수 값이 주어진 정수 타입의 범위 안에 있는지 확인하는 함수 템플릿
numeric_limits 모든 기본 수치 타입의 속성을 조회하는 인터페이스를 제공하는 클래스 템플릿

더 알아보기 (Learn more)

cppreference