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) |
두 정수 t와 u의 값을 비교해요. 내장 비교 연산자와 달리, 음수 부호 정수는 항상 부호 없는 정수보다 작다고(그리고 같지 않다고) 비교돼요. 이 비교는 값이 보존되지 않는 정수 변환에 대해 안전해요.
-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 |
모든 기본 수치 타입의 속성을 조회하는 인터페이스를 제공하는 클래스 템플릿 |