quantlib — Умножение Enum в переполнении стека

У меня есть код, который умножает перечисление на целое число:

QuantLib::Date date2 = date + 12 * QuantLib::Months;

Где QuantLib :: Months определяется как:

enum TimeUnit { Days,
Weeks,
Months,
Years
};

Это дает мне желаемый результат date2 быть один год с Дата. Однако я не могу понять, как это достигается.

Я думал, что это не скомпилируется. Теперь я чувствую, что достигаю объекта «двенадцать месяцев», который затем обрабатывается перегрузкой оператора QuantLib :: Date ‘+’, но я никогда раньше не видел этот стиль.

Я пришел из C # фона, поэтому может быть что-то, о чем я не знаю, на работе здесь. Кто-нибудь может объяснить, что происходит? Любая справочная документация будет оценена.

3

Решение

Здесь действует одно из следующих:

  1. В C ++ тип перечисления может быть неявно преобразован в целочисленный тип. Если это происходит здесь, date + 12 * QuantLib::Months будет так же, как date + 12 * 2,

  2. Также возможно перегрузить операторы для типов перечисления. В этом случае, возможно, библиотека определяет operator* (int, QuantLib::TimeUnit) который возвращает что-то совместимое с + ты делаешь.

Я не знаю QuantLib, но я предполагаю, что # 2 — это то, что происходит. QuantLib документация подтверждает это (спасибо @DaliborFrivaldsky за ссылку).

4

Другие решения

По умолчанию все перечисления в основном являются целочисленными константами, и как все целочисленные значения вы можете использовать их в арифметических выражениях.

В вашем случае постоянная QuantLib::Months имеет значение 2, так как перечисления начинаются с нуля и просто увеличиваются.


Однако, если вы иметь чтобы сделать ваши собственные функции данных / времени, я предлагаю вам использовать функции, доступные в стандартная библиотека <chrono> заголовок (или же Повысить хроно если у вас нет компилятора / библиотеки, поддерживающей C ++ 11). Он имеет всю эту встроенную функциональность.

Вот пример, похожий на ваш код

auto now = std::chrono::system_clock::now();  // The current time at the moment
auto then = now + std::chrono::hours(24 * 365);

Переменная then теперь будет time_point 24 * 365 часов в будущем от now,

1

В вашем примере вы используете так называемое перечисление с незаданной областью. Каждое перечисление имеет базовый целочисленный тип (необязательно тип int Нет такого правила по умолчанию для перечислений в C ++).
Согласно пункту 4.5.3 Стандарта C ++ (вы просили некоторую ссылку на документацию):

3 Значение типа перечисления с незаданной областью, базовый тип которого
не фиксированный (7.2) может быть преобразован в значение первого из
следующие типы, которые могут представлять все значения перечисления
(то есть значения в диапазоне от bmin до bmax, как описано в 7.2): int,
unsigned int, long int, unsigned long int, long long int или unsigned
длинный длинный инт. Если ни один из типов в этом списке не может представлять все
значения перечисления, prvalue типа перечисления с незаданной областью
может быть преобразовано в значение расширенного целочисленного типа с наименьшим
Целочисленный конверсионный ранг (4.13) больше ранга long long в
которые могут быть представлены все значения перечисления. Если там
Два таких расширенных типа, подписанный выбирается.

Так в вашем примере QuantLib::Months преобразуется в int, поскольку все значения перечисления могут храниться в объекте типа int. Затем обычные арифметические преобразования выполняются в мультипликативной операции.

0
По вопросам рекламы [email protected]