С++ 11 впервые представил поддержку для определения новых литералов в С++ с помощью пользовательских литералов. С++ 11 или более поздняя версия также предопределяет суффиксы для целочисленных литералов фиксированной ширины для типов в <cstdint>
?
Линейные числа с фиксированной шириной в С++?
Ответ 1
Нет.. С С++ 14 только стандартные суффиксы, определенные стандартом, предоставляются заголовками <chrono>
, <complex>
и <string>
в стандартной библиотеке. Заголовок <chrono>
определяет суффиксы h
, min
, s
, ms
, us
, ns
для продолжительности времени, <complex>
определяет i
, il
и if
суффиксами для мнимых чисел, а <string>
определяет суффикс s
для basic_string
литералов.
Однако можно легко определить собственные литералы с фиксированной шириной:
#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); }
Предупреждение:. Вышеприведенный код будет давать неверный результат, если он используется в литералах, которые не вписываются в unsigned long long
, а также при переполнении, если буквальное значение не вписывается в запрошенный тип, например 999_int8
. A более эффективная реализация (лицензия GPL-3), вероятно, придется анализировать буквальный характер за символом и static_assert
при переполнении, например this.
Недостатком использования пользовательских литералов является то, что для суффиксов необходимо подчеркнуть знак подчеркивания _
, поскольку суффиксы без подчеркивания зарезервированы для будущей стандартизации в соответствии с §17.6.4.3.4.