¿Está bien definido el valor std::is unsigned:?


Me pregunto si

std::is_unsigned<bool>::value

Está bien definido de acuerdo con el estándar o no?

Hago la pregunta porque typename std::make_unsigned<bool>::type no está bien definido.

Author: Columbo, 2016-01-05

4 answers

No hay concepto de signedness para bool. De [básico.fundamental]/6:

Los Valores de tipo bool son true de false. [Nota: no Hay signed, unsigned, short, o long bool o tipos de valores. - nota final] Valores de tipo bool participar en promociones integrales (4.5).

Por el contrario, la signedness se llama explícitamente para los tipos enteros con signo (párrafo 2) y tipos enteros sin signo (párrafo 3).

Ahora para los rasgos is_signed y is_unsigned. En primer lugar, los rasgos siempre están bien definidos, pero solo son interesantes para los tipos aritméticos. bool es un tipo aritmético, y is_signed<T>::value se define (véase la tabla 49) como T(-1) < T(0). Al usar las reglas de conversión booleana y conversiones aritméticas estándar, vemos que esto es false para T = bool (porque bool(-1) es true, que se convierte en 1). Del mismo modo, is_unsigned<T>::value se define como T(0) < T(-1), que es true para T = bool.

 63
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-05 14:03:28

is_unsigned se define en [meta.unary.comp] / 2 as

Si is_arithmetic<T>::value es true, el mismo resultado que
bool_constant<T(0) < T(-1)>::value; de lo contrario, false

bool es claramente un tipo aritmético (siendo integral). Ahora considere [conv.bool] / 1:

Un valor cero, un valor de puntero nulo o un valor de puntero de miembro nulo se convierte en false; cualquier otro valor se convierte en true.

Es decir, bool(0) < bool(-1) es equivalente a false < true, y este último se mantiene ya que los valores son promovido a 0 y 1, respectivamente.

Así, is_unsigned<bool>::value es true (y, por el contrario, is_signed es false), debido al hecho de que bool los valores ean corresponden a los valores sin signo 0 y 1 durante las operaciones aritméticas. Sin embargo, realmente no tiene sentido evaluar la signedness de bool, y mucho menos realizar make_unsigned en él, ya que no representa enteros, sino estados.


: El hecho de que esta plantilla sea aplicable a bool en el primer el lugar está determinado por su cláusula de Requerimiento siendo inexistente, bool no siendo un tipo incompleto ([res.on.functions] / (2.5)) y no se mencionan otros requisitos en [meta.rqmts] for UnaryTypeTraits.
 23
Author: Columbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-05 14:02:53

Sí, está bien definido, al igual que cualquier otro rasgo de tipo unario.

C++14 (n4140) 20.10.4/2 Mandatos de "Rasgos de tipo único":

Cada una de estas plantillas será untrait UnaryTypeTrait (20.10.1) con una característica base de true_type si el la condición correspondiente es verdadera, de lo contrario false_type.

20.10.1/1:

A UnaryTypeTrait describe una propiedad de un tipo. Será una plantilla de clase que tome un tipo de plantilla argumento y, opcionalmente, argumentos adicionales que ayudan a definir la propiedad que se describe. Será DefaultConstructible, CopyConstructible, y derivados pública e inequívocamente, directa o indirectamente, de su característica base, que es una especialización de la plantilla integral_constant (20.10.3), con los argumentos a la plantilla integral_constant determinados por los requisitos para el particular propiedad que se describe. Los nombres de los miembros de la BaseCaracterística no se ocultarán y serán disponible sin ambigüedades en el UnaryTypeTrait.

De esto se deduce que la construcción std::is_unsigned<T>::value tiene que estar bien definida para cualquier tipo T, ya sea que el concepto de "signedness" tenga sentido para el tipo o no.

 10
Author: Angew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-05 13:09:43

Sí está bien definido y el resultado debe ser std::is_unsigned<bool>::value == true

La documentación para std::is_signed dice

Si T es un tipo aritmético con signo, proporciona el valor de la constante del miembro igual a true. Para cualquier otro tipo, el valor es false.

Entonces, si nos fijamos en std::is_arithmetic

Si T es un tipo aritmético (es decir, un tipo integral o un tipo de coma flotante), proporciona el valor de la constante miembro igual a true. Para cualquier otro tipo, el valor es false.

Que finalmente conduce a std::is_integral

Comprueba si T es un tipo integral. Proporciona el valor de la constante miembro que es igual a true, si T es el tipo bool, char, char16_t, char32_t, wchar_t, short, int, long, long long, o cualquier tipo entero extendido definido por la implementación, incluidas las variantes signed, unsigned y cv-qualified. De lo contrario, el valor es igual a false.

Curiosamente, hay otra función std::numeric_limits::is_signed que establece

El valor de std::numeric_limits<T>::is_signed es true para todos los tipos aritméticos con signo T y false para los tipos sin signo. Esta constante es significativa para todas las especializaciones.

Donde la especialización para bool se enumera como false, lo que también confirma que bool se considera sin firmar.

 9
Author: CoryKramer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-05 13:53:08