float - c++ std:: numeric_limits
¿Por qué std:: numeric_limits<seconds>:: max() devuelve 0? (2)
Encontré un gotcha interesante con std::numeric_limits<seconds>::max()
devolviendo 0. La respuesta es usar seconds::max()
o std::numeric_limits<seconds::rep>::max()
lugar, Pero me interesa saber por qué sucede esto. Espero que falle en el momento de la compilación o simplemente funcione. El siguiente código demuestra el problema con gcc 4.9.3.
#include <iostream>
#include <limits>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main(int /*argc*/, const char* /*argv*/[])
{
const auto maxSeconds = std::numeric_limits<seconds>::max();
std::cerr << maxSeconds.count() << "/n";
const auto maxSeconds2 = seconds::max();
std::cerr << maxSeconds2.count() << "/n";
return 0;
}
No puedo ver ninguna conversión implícita en el archivo de encabezado chrono . Si una duration
hubiera convertido implícitamente en un tipo numérico y se perdiera el signo o un bool
usted podría terminar con un mínimo de cero, pero un máximo de cero no tiene sentido.
Como TartanLlama señala que la especialización predeterminada usa el constructor predeterminado y, por lo tanto, devuelve 0.
Profundizando en una copia antigua del standard veo los siguientes dictados:
18.3.2.3 Plantilla de clase
numeric_limits
[numeric.limits]Los tipos estándar no aritméticos, como el
complex<T>
(26.4.2), no deben tener especializaciones.
Y un poco más tarde:
La
numeric_limits<T>
defecto denumeric_limits<T>
tendrá todos los miembros, pero con 0 o valores falsos.El valor de cada miembro de una especialización de
numeric_limits
en un tipo cv-calificadocv T
será igual al valor del miembro correspondiente de la especialización en el tipoT
no calificado.
Lo que falta es una explicación de por qué el comité consideró que era una mejor idea que un fallo de compilación. ¿Se justifica un informe de defectos de la biblioteca?
Actualización: he planteado esto como un problema con el comité de ISO
std::chrono::seconds
sí no es un tipo aritmético estándar, por lo tanto, std::numeric_limits
no está especializado para ello. Así que solo ves algunos valores por defecto bastante inútiles.
Para consultar el rango del tipo subyacente utilizado para contar las marcas (que, en gcc, es el long int
64 bits), use
std::numeric_limits<seconds::rep>::max();
en lugar.
std::numeric_limits
no está especializado para std::chrono::seconds
. Las definiciones predeterminadas se dan para todos los miembros de datos y funciones en std::numeric_limits
para evitar errores de compilación para tipos no especializados. La versión predeterminada de numeric_limits<T>::max()
simplemente devuelve T()
, que es 0
en este caso.
Puede verificar si std::numeric_limits
está especializado para una T
dada en el momento de la compilación marcando std::numeric_limits<T>::is_specialized
, que por defecto es false
.