std::in_range în C++

Verifică dacă un număr întreg încape în alt tip întreg, fără capcanele conversiilor cu semn.

Sintaxă
#include <utility>
template<class R, class T>
constexpr bool in_range(T t) noexcept;

Ce face std::in_range

std::in_range<R>(x) returnează true dacă valoarea lui x poate fi reprezentată exact în tipul R. De exemplu, -1 nu încape într-un unsigned, iar 300 nu încape într-un std::uint8_t.

Comparația se face corect matematic, chiar și între tipuri cu semn și fără semn. Familia include și std::cmp_less, std::cmp_equal etc. Funcționează doar cu tipuri întregi (nu cu bool, char sau numere reale).

Parametri

Parametru Descriere
R Tipul țintă.
t Valoarea verificată.

Ce returnează

true dacă valoarea încape în R, altfel false.

Exemple

Exemplul 1: Verificări înainte de conversie

#include <cstdint>
#include <print>
#include <utility>

int main() {
    std::println("-1 în unsigned: {}", std::in_range<unsigned>(-1));
    std::println("200 în uint8_t: {}", std::in_range<std::uint8_t>(200));
    std::println("300 în uint8_t: {}", std::in_range<std::uint8_t>(300));
    std::println("3 miliarde în int: {}", std::in_range<int>(3'000'000'000LL));
}

Rezultat

-1 în unsigned: false
200 în uint8_t: true
300 în uint8_t: false
3 miliarde în int: false

Exemplul 2: Comparația -1 < 1u

Cu operatorul obișnuit, -1 ar fi convertit în unsigned și ar deveni un număr uriaș. std::cmp_less compară valorile reale.

#include <print>
#include <utility>

int main() {
    int a = -1;
    unsigned b = 1;
    std::println("cmp_less(-1, 1u): {}", std::cmp_less(a, b));
    std::println("-1 ca unsigned: {}", static_cast<unsigned>(a));
}

Rezultat

cmp_less(-1, 1u): true
-1 ca unsigned: 4294967295

Greșeli frecvente

  • Compari direct un int cu un size_t (de exemplu i < v.size() cu i negativ). -1 devine un număr foarte mare și comparația dă rezultat greșit; folosește std::cmp_less sau tipuri potrivite.

Comenzi înrudite