Подтвердить что ты не робот

Является ли std:: is_unsigned <bool>:: значение определено?

Мне интересно,

std::is_unsigned<bool>::value

хорошо определен в соответствии со стандартом или нет?

Я задаю вопрос, потому что typename std::make_unsigned<bool>::type не определен.

4b9b3361

Ответ 1

Нет понятия подписи для bool. Из [basic.fundamental]/6:

Значения типа bool являются либо true of false. [Примечание. Нет типов signed, unsigned, short или long bool bool. - end note] Значения типа bool участвуют в интегральных акциях (4.5).

В отличие от этого подпись явно вызывается для целочисленных типов со знаком (параграф 2) и целых типов без знака (пункт 3).

Теперь для признаков is_signed и is_unsigned. Во-первых, черты всегда хорошо определены, но интересны только для арифметических типов. bool является арифметическим типом, а is_signed<T>::value определяется (см. таблицу 49) как T(-1) < T(0). Используя правила логического преобразования и стандартные арифметические преобразования, мы видим, что это false для T = bool (потому что bool(-1) есть true, который преобразуется в 1). Аналогично, is_unsigned<T>::value определяется как T(0) < T(-1), который true для T = bool.

Ответ 2

is_unsigned определяется в [meta.unary.comp]/2 как

Если is_arithmetic<T>::value - true, тот же результат, что и bool_constant<T(0) < T(-1)>::value; в противном случае false

bool явно является арифметическим типом (являющимся интегралом). Теперь рассмотрим [conv.bool]/1:

Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в false; любое другое значение преобразуется в true.

т.е. bool(0) < bool(-1) эквивалентно false < true, и последнее выполняется, поскольку значения повышаются до 0 и 1 соответственно.

Таким образом, is_unsigned<bool>::value является true (и, наоборот, is_signed является false), из-за того, что значения bool ean соответствуют беззнаковым значениям 0 и 1 во время арифметических операций, Тем не менее, нет смысла оценивать подпись bool, а тем более выполнять make_unsigned на ней, поскольку она не представляет целые числа, а скорее состояния.


: тот факт, что этот шаблон применим к bool, в первую очередь определяется его предложением Требование несуществующим, bool не являющимся неполным типом ([res.on.functions ]/(2.5)) и других требований, упомянутых в [meta.rqmts] для UnaryTypeTraits.

Ответ 3

Да, он четко определен, как и любой другой унарный тип.

С++ 14 (n4140) 20.10.4/2 "Унарные типы признаков":

Каждый из этих шаблонов должен быть UnaryTypeTrait (20.10.1) с BaseCharacteristic true_type, если соответствующее условие истинно, иначе false_type.

20.10.1/1:

В UnaryTypeTrait описывается свойство типа. Это шаблон класса, который принимает один тип шаблона аргумент и, необязательно, дополнительные аргументы, которые помогают определить описываемое свойство. Это должно быть DefaultConstructible, CopyConstructible и публично и однозначно выведенные, прямо или косвенно, из его BaseCharacteristic, который является специализацией шаблона integral_constant (20.10.3), с аргументами к шаблону integral_constant, определяемым требованиями для конкретного описывается свойство. Имена членов BaseCharacteristic не должны быть скрыты и должны быть недвусмысленно доступны в UnaryTypeTrait.

Из этого следует, что конструкция std::is_unsigned<T>::value должна быть хорошо определена для любого типа T, имеет ли смысл понятие "подпись" смысл для типа или нет.

Ответ 4

Да, это хорошо определено, и результат должен быть std::is_unsigned<bool>::value == true

Документация для std::is_signed говорит

Если T - это арифметический тип с подпиской, значение константы элемента равно true. Для любого другого типа значение равно false.

Итак, если вы посмотрите std::is_arithmetic

Если T является арифметическим типом (т.е. интегральным типом или типом с плавающей запятой), значение константы элемента равно true. Для любого другого типа значение равно false.

Что в конечном итоге приводит к std::is_integral

Проверяет, является ли T интегральным типом. Предоставляет постоянное значение члена, которое равно true, если T является типом bool, char, char16_t, char32_t, wchar_t, short, int, long, long long или любых расширенных целочисленных типов, определенных для реализации, включая любые подписанные, неподписанные и cv-квалификационные варианты. В противном случае значение равно false.

Интересно, что есть еще одна функция std::numeric_limits::is_signed, которая гласит

Значение std::numeric_limits<T>::is_signed равно true для всех подписанных арифметических типов T и false для неподписанных типов. Эта константа имеет смысл для всех специализаций.

Если специализация для bool указана как false, что также подтверждает, что bool считается беззнаковым.