C++ 11 po raz pierwszy wprowadzono obsługę definiowania nowych literałów w C++ za pomocą zdefiniowanych przez użytkownika literałów zdefiniowanych przez użytkownika. Czy C++ 11 lub nowszy również predefiniuje przyrostki dla literałów całkowitych o stałej szerokości dla typów w <cstdint>
?Litery integerowe o stałej szerokości w C++?
Odpowiedz
nr jako C++ 14 tylko dosłownych sufiksami zdefiniowaną przez standard są przez <chrono>
, <complex>
i <string>
nagłówkami w standardowej biblioteki. Nagłówek <chrono>
określa h
, min
, s
, ms
, us
, ns
przyrostki czasów trwania, <complex>
określa i
, il
if
przyrostków i liczb urojonych, i <string>
określa s
przyrostkiem basic_string
literałach.
Można jednak łatwo definiować własne literały stałej szerokości tak:
#include <cstdint>
constexpr std::int8_t operator "" _int8(unsigned long long v)
{ return static_cast<std::int8_t>(v); }
constexpr std::uint8_t operator "" _uint8(unsigned long long v)
{ return static_cast<std::uint8_t>(v); }
constexpr std::int16_t operator "" _int16(unsigned long long v)
{ return static_cast<std::int16_t>(v); }
constexpr std::uint16_t operator "" _uint16(unsigned long long v)
{ return static_cast<std::uint16_t>(v); }
constexpr std::int32_t operator "" _int32(unsigned long long v)
{ return static_cast<std::int32_t>(v); }
constexpr std::uint32_t operator "" _uint32(unsigned long long v)
{ return static_cast<std::uint32_t>(v); }
constexpr std::int64_t operator "" _int64(unsigned long long v)
{ return static_cast<std::int64_t>(v); }
constexpr std::uint64_t operator "" _uint64(unsigned long long v)
{ return static_cast<std::uint64_t>(v); }
constexpr std::int_fast8_t operator "" _int_fast8(unsigned long long v)
{ return static_cast<std::int_fast8_t>(v); }
constexpr std::uint_fast8_t operator "" _uint_fast8(unsigned long long v)
{ return static_cast<std::uint_fast8_t>(v); }
constexpr std::int_fast16_t operator "" _int_fast16(unsigned long long v)
{ return static_cast<std::int_fast16_t>(v); }
constexpr std::uint_fast16_t operator "" _uint_fast16(unsigned long long v)
{ return static_cast<std::uint_fast16_t>(v); }
constexpr std::int_fast32_t operator "" _int_fast32(unsigned long long v)
{ return static_cast<std::int_fast32_t>(v); }
constexpr std::uint_fast32_t operator "" _uint_fast32(unsigned long long v)
{ return static_cast<std::uint_fast32_t>(v); }
constexpr std::int_fast64_t operator "" _int_fast64(unsigned long long v)
{ return static_cast<std::int_fast64_t>(v); }
constexpr std::uint_fast64_t operator "" _uint_fast64(unsigned long long v)
{ return static_cast<std::uint_fast64_t>(v); }
constexpr std::int_least8_t operator "" _int_least8(unsigned long long v)
{ return static_cast<std::int_least8_t>(v); }
constexpr std::uint_least8_t operator "" _uint_least8(unsigned long long v)
{ return static_cast<std::uint_least8_t>(v); }
constexpr std::int_least16_t operator "" _int_least16(unsigned long long v)
{ return static_cast<std::int_least16_t>(v); }
constexpr std::uint_least16_t operator "" _uint_least16(unsigned long long v)
{ return static_cast<std::uint_least16_t>(v); }
constexpr std::int_least32_t operator "" _int_least32(unsigned long long v)
{ return static_cast<std::int_least32_t>(v); }
constexpr std::uint_least32_t operator "" _uint_least32(unsigned long long v)
{ return static_cast<std::uint_least32_t>(v); }
constexpr std::int_least64_t operator "" _int_least64(unsigned long long v)
{ return static_cast<std::int_least64_t>(v); }
constexpr std::uint_least64_t operator "" _uint_least64(unsigned long long v)
{ return static_cast<std::uint_least64_t>(v); }
constexpr std::intmax_t operator "" _intmax(unsigned long long v)
{ return static_cast<std::intmax_t>(v); }
constexpr std::uintmax_t operator "" _uintmax(unsigned long long v)
{ return static_cast<std::uintmax_t>(v); }
constexpr std::intptr_t operator "" _intptr(unsigned long long v)
{ return static_cast<std::intptr_t>(v); }
constexpr std::uintptr_t operator "" _uintptr(unsigned long long v)
{ return static_cast<std::uintptr_t>(v); }
Ostrzeżenie: Powyższy kod dyskretnie dać zły wynik, jeżeli są stosowane na literały, które nie pasują do unsigned long long
, jak również przepełnienie, jeśli wartość literalna, nie pasuje do żądanego typu, np 999_int8
. A better implementation (na licencji GPL-3) prawdopodobnie musiałby przeanalizować literalny znak po znaku i static_assert
na przepełnieniu, na przykład this.
Wadą używania literałów zdefiniowanych przez użytkownika jest to, że należy poprzedzić przyrostki znakiem podkreślenia _
, ponieważ sufiksy bez podkreślenia są zarezerwowane dla przyszłej standaryzacji zgodnie z §17.6.4.3.4.
Co powiesz na [wyrzucenie wyjątku na przepełnienie, kompilacja nie powiedzie się] (http://stackoverflow.com/a/8626450/256138)? – rubenvb