numeric_limits float c++ language-lawyer

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 de numeric_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-calificado cv T será igual al valor del miembro correspondiente de la especialización en el tipo T 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

https://issues.isocpp.org/show_bug.cgi?id=186


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 .