¿Cuál es la diferencia entre los tipos / valores de crono C ++ 20 month{7}
y months{7}
? ¿No es confuso tener dos nombres tan similares?
¿Cuál es la diferencia entre los tipos / valores de crono C ++ 20 month{7}
y months{7}
? ¿No es confuso tener dos nombres tan similares?
Respuestas:
Sí, puede ser confuso tener ambos month
y months
cuando se encuentra por primera vez con esta biblioteca. Sin embargo, existen convenciones de nomenclatura coherentes en esta biblioteca para ayudar a reducir esa confusión. Y el beneficio es tener una clara separación de las distintas semánticas mientras se conservan los nombres intuitivos cortos.
months
Todos los chrono::duration
tipos "predefinidos" son plurales:
nanoseconds
microseconds
milliseconds
seconds
minutes
hours
days
weeks
months
years
Entonces months
es un chrono::duration
tipo :
usando meses = duración < tipo entero con signo de al menos 20 bits , ratio_divide <años :: período, ratio <12> >>;
Y es exactamente 1 / 12 de years
.
static_assert(12*months{1} == years{1});
Puedes imprimirlo así:
cout << months{7} << '\n';
Y la salida es:
7[2629746]s
Esto se lee como 7 unidades de 2.629.746. Resulta que 2.629.746 segundos es la duración media del mes en el calendario civil. Dicho de otra manera:
static_assert(months{1} == 2'629'746s);
(el número exacto no es particularmente importante, excepto para las apuestas de barra ganadoras)
month
month
(singular) por otro lado no es un chrono::duration
. Es un especificador calendárico para un mes del año en el calendario civil. O:
static_assert(month{7} == July);
Esto se puede usar para formar una fecha como esta:
auto independence_day = month{7}/4d/2020y;
El álgebra de month
y months
refleja estas diferentes semánticas. Por ejemplo, "julio + julio" no tiene sentido y, por lo tanto, es un error en tiempo de compilación:
auto x = month{7} + month{7};
~~~~~~~~ ^ ~~~~~~~~
error: invalid operands to binary expression ('std::chrono::month' and 'std::chrono::month')
Pero esto tiene mucho sentido:
auto constexpr x = month{7} + months{7};
static_assert(x == February);
Y esto:
auto constexpr x = months{7} + months{7};
static_assert(x == months{14});
Y todavía:
auto b = February == months{14};
~~~~~~~~ ^ ~~~~~~~~~~
error: invalid operands to binary expression ('const std::chrono::month' and 'std::chrono::months')
Es decir, month
y months
no solo no son iguales, ni siquiera son comparables. Son manzanas y naranjas, si te gustan las analogías con las frutas. ;-)
Existe una relación similar entre day
y days
. Y entre year
y years
.
Si es plural, es a
chrono::duration
.
Y solo <chrono>
tiene la seguridad de tipos para ayudarlo a garantizar que estos dos conceptos semánticamente distintos pero similares no se confundan entre sí en su código.
12*x
desborda, tiene un comportamiento indefinido allí mismo (antes de que se months
ejecute el constructor). Sin embargo, si el valor de months
es un múltiplo de 12 (positivo o negativo), entonces sí, la suma (o resta) es esencialmente una operación no válida. Obtendría lo mismo que July == July + years(x)
.
July == July + months(12*x)
independientemente de x? ¿Incluso para que x sea INT_MAX?