Я был удивлен, что std::numeric_limits<std::byte>::digits
возвращается 0
, когда я ожидал 8
. Я считаю, что это связано с отсутствием специализации для std::byte
, следовательно, по умолчанию используется реализация по умолчанию, которая возвращает 0
в этом случае.
Поскольку стандарт, похоже, этого не делает, безопасно ли специализировать std::numeric_limits
для std::byte
себя для своего кода?
@freakish В моем общем шаблоне используется std::numeric_limits
. Я верю, что это сработает и для других целочисленных типов, а также std::byte
.
Используйте std::numeric_limit<std::underlying_type_t<std::byte>>
или напрямую std::numeric_limit<unsigned char>
.
Специализация стандартного шаблона возможна/законна только для некоторых шаблонов, и лучше это делать для ваших собственных типов.
std::byte
не считается арифметическим типом, поэтому std::numeric_limits<std::byte>
нет, а std::to_integer
необходим для присвоения ему целого числа.
std::byte
кажется странным животным, вообще не относящимся к числу числовых типов. Таким образом, numeric_limits
не определяется для него на этом основании. Вместо этого я бы использовал uint8_t
.
Да, IFF на самом деле не объявлен вашей стандартной библиотекой. (Я думаю!) en.cppreference.com/w/cpp/language/extending_std (Но я только что увидел, что std::byte
не является арифметикой, так что... нет. Фууи.
Возможно, лучше использовать std::uint8_t
или std::int8_t
, если его следует использовать в качестве арифметического типа, или создать собственный шаблон числовых ограничений, который перенаправляет на std::numeric_limits
в случаях, отличных от std::byte
.
Обратите внимание, что std::byte "... но в отличие от unsigned char, это не символьный тип и не арифметический тип. std::byte моделирует простой набор битов, поддерживая только операции побитового сдвига с целым числом, а также побитовые операции и операции сравнения с другим std::byte.". Поэтому специализация std::numeric_limit
не имеет смысла.
Это небезопасно, более того, это запрещено. [namespace.std]/2 утверждает
Если явно не запрещено, программа может добавить специализацию шаблона для любого шаблона класса стандартной библиотеки в пространство имен std при условии, что
- добавленное объявление зависит как минимум от одного типа, определяемого программой, и
- специализация соответствует требованиям стандартной библиотеки для исходного шаблона.155
и это первый пункт, который запрещает это. std::byte
— это библиотечный тип, а не программно-определяемый тип.
Что вы можете сделать, так это использовать underlying_type_t<std::byte>
, так как это будет встроенный арифметический тип. Это даст вам:
std::numeric_limits<std::underlying_type_t<std::byte>>::digits
std::numeric_limits<std::underlying_type_t<std::byte>>::digits
немного излишне сложен. Это всегда гарантированно CHAR_BIT
.
@user17732522 user17732522 В данном случае да, но если у пользователя другой тип перечисления, это все равно работает.
Да, но необходимо следить за тем, чтобы это не было перечислением с незаданной областью действия без фиксированного базового типа. В этом случае базовый тип может иметь более широкий диапазон значений, чем тип перечисления.
Почему бы тебе не создать свой
numeric_limits
? Почему вы хотите связываться сstd::numeric_limits
?