La multiplicación de una Enumeración en C++
Pregunta
Tengo un código que es la multiplicación de una enumeración por un número entero:
QuantLib::Date date2 = date + 12 * QuantLib::Months;
Donde QuantLib::Meses se define como:
enum TimeUnit { Days,
Weeks,
Months,
Years
};
Esto me da el resultado deseado de date2 siendo un año de fecha.Sin embargo, no soy capaz de comprender cómo es que se logra.
Yo pensaba que esto no iba a compilar.Ahora siento que estoy llegando a un "doce meses" objeto, que el se gestiona por la QuantLib::Date '+' sobrecarga de operadores, pero nunca he visto este estilo de antes.
He venido de un C# de fondo, por lo que también puede ser algo que yo no soy consciente de que en el trabajo aquí.¿Alguien puede explicar qué está pasando?Cualquier documentación de referencia se agradece.
Solución
Uno de los siguientes es, en efecto, aquí:
En C++, un tipo de enumeración se puede convertir implícitamente un tipo integral.Si esto está ocurriendo aquí,
date + 12 * QuantLib::Months
sería el mismodate + 12 * 2
.También es posible la sobrecarga de operadores para los tipos de enumeración.En ese caso, podría ser que la biblioteca se define una
operator* (int, QuantLib::TimeUnit)
que devuelve algo compatible con la+
que estás haciendo.
No sé QuantLib
, pero me imagino #2 es lo que está sucediendo. QuantLib documentación corrobora esta (gracias a @DaliborFrivaldsky para el enlace).
Otros consejos
By default, all enumerations are basically integer constants, and as all integer values you can use them in arithmetic expressions.
In your case the constant QuantLib::Months
has the value 2
, as enumerations starts from zero and are simply increased.
However, unless you have to make your own data/time functionality, I suggest you use the functionality available in the standard library <chrono>
header (or Boost chrono if you don't have a C++11 capable compiler/library). It has all this functionality built-in.
Here is an example similar to your code
auto now = std::chrono::system_clock::now(); // The current time at the moment
auto then = now + std::chrono::hours(24 * 365);
The variable then
will now be a time_point
24 * 365
hours in the future from now
.
In your example you are using a so-called unscoped enumeration. Each enumeration has an underlying integral type (that is not necessary the type int
There is no such a default rule for enumerations in C++).
According to paragraph 4.5.3 of the C++ Standard (you asked some reference to documentation):
3 A prvalue of an unscoped enumeration type whose underlying type is not fixed (7.2) can be converted to a prvalue of the first of the following types that can represent all the values of the enumeration (i.e., the values in the range bmin to bmax as described in 7.2): int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int. If none of the types in that list can represent all the values of the enumeration, a prvalue of an unscoped enumeration type can be converted to a prvalue of the extended integer type with lowest integer conversion rank (4.13) greater than the rank of long long in which all the values of the enumeration can be represented. If there are two such extended types, the signed one is chosen.
So in your example QuantLib::Months
is converted to int because all values of the enumeration can be stored in an object of type int. Then usual arithmetic conversions are performed in the multiplicative operation.