정수 비교 in C++20

14305 단어 C++cpp20tech
C++는 부호와 무기호 정수의 비교에 문제가 있습니다.
#include <iostream>

int main() {
  std::cout << std::boolalpha;
  
  int n = -1;
  unsigned int m = 0;
  
  std::cout << (n < m) << '\n';  // false
  std::cout << (-1 < 0) << '\n'; // true
}
[Wandbox] 3(՞ਊ ՞)하하 < 연산자의 양쪽 조작수의 유형이 다르기 때문에 은식 변환의 결과로 양쪽 모두unsigned int(가능), 결과int-1unsigned int4294967295이기 때문에 위의 코드n < mfalse이다.
또한 상수식이라면 의도에 부합된다.
이렇게 기호가 다른 정수형을 비교하는 것은 매우 위험하다. C++20의 <=>에서 기호가 있는 것과 기호가 없는 정수를 비교하는 것은 컴파일 오류(비상수식)이다.
많은 컴파일러들이 이런 비교에 대해 경고를 하지만, 대부분의 경우 방법이 없고, 실제적인 위해가 없기 때문에 무시당한다.
C++20에서는 이러한 비교를 안전하게 수행하기 위해 경고를 제거하기 위해 정수형 비교 함수를 추가했습니다.
namespace std {
  template <class T, class U>
  constexpr bool cmp_equal(T t, U u) noexcept;
  template <class T, class U>
  constexpr bool cmp_not_equal(T t, U u) noexcept;
  template <class T, class U>
  constexpr bool cmp_less(T t, U u) noexcept;
  template <class T, class U>
  constexpr bool cmp_greater(T t, U u) noexcept;
  template <class T, class U>
  constexpr bool cmp_less_equal(T t, U u) noexcept;
  template <class T, class U>
  constexpr bool cmp_greater_equal(T t, U u) noexcept;
}
이 비교 함수들은 이름에 따라 정수 유형의 값을 비교한다.그리고 이 두 매개 변수형의 기호가 다르든 안 다르든 아까처럼 은식 변환을 하지 않고 그 값에 따라 정확하게 비교한다.
#include <iostream>
#include <utility>

int main() {
  std::cout << std::boolalpha;
  
  int n = -1;
  unsigned int m = 0;
  
  std::cout << std::cmp_less(n, m) << '\n';  // true 
  std::cout << std::cmp_less(-1, 0) << '\n'; // true
}
[Wandbox] 3(՞ਊ ՞)하하
너무 편리하니 C++20 앞으로 적극 활용하세요!
그나저나 지정된 정수를 지정된 정수형으로 표시할 수 있는지를 판정하는 함수in_range도 추가됐다.
#include <iostream>
#include <utility>

int main() {
  std::cout << std::boolalpha;
  
  std::cout << std::in_range<std::uint32_t>(-1) << '\n';        // false
  std::cout << std::in_range<std::int32_t>(-1) << '\n';         // true
  std::cout << std::in_range<std::int32_t>(4294967295) << '\n';  // false
  std::cout << std::in_range<std::uint32_t>(4294967295) << '\n'; // true 
}
[Wandbox] 3(՞ਊ ՞)하하
  • P0586R2 Safe integral comparisons
  • std::cmp_equal, cmp_not_equal, cmp_less, cmp_greater, cmp_less_equal, cmp_greater_equal - cppreference.com
  • 좋은 웹페이지 즐겨찾기