![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Changing the Policy DefaultsBoost , Math Toolkit 2.5.0 , Policy Tutorial
|
![]() |
Tip |
---|---|
Для Microsoft Visual Studio вы можете добавить на Страницу свойств проекта, C/C++, Preprocessor, Preprocessor определения, такие как: BOOST_MATH_ASSERT_UNDEFINED_POLICY=0 BOOST_MATH_OVERFLOW_ERROR_POLICY=errno_on_error Это может быть полезно, чтобы избежать осложнений с предварительно скомпилированными заголовками, которые могут означать, что эквивалентные определения в исходном коде: #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false #define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error Может быть, не. Командная строка компилятора показывает: /D "BOOST_MATH_ASSERT_UNDEFINED_POLICY=0" /D "BOOST_MATH_OVERFLOW_ERROR_POLICY=errno_on_error" |
Однако есть очень важный нюанс в этом:
![]() |
Important |
---|---|
Политика по умолчанию, измененная путем настройки макросов конфигурации, должна быть изменена равномерно в каждом блоке перевода в программе. Несоблюдение этого правила может привести к нарушению «Правила одного определения» и непредсказуемому поведению программы. |
Это означает, что есть только два безопасных способа использования этих макросов:
Что вы должны делать, а не, так это:
#define
>, так как это почти наверняка нарушит вашу программу, если вы не уверены, что программа ограничена одним блоком перевода.И да, вы найдете примеры в наших тестовых программах, где мы нарушаем это правило: но только потому, что мы знаем, что всегда будет только один перевод:не говорите, что вас не предупредили!
Следующий пример демонстрирует эффект установки макроса BOOST_MATH_DOMAIN_ERROR_POLICY Когда возникает неверный аргумент. Для целей этого примера мы передаем отрицательный параметр степеней свободы распределению t ученика.
Поскольку мы знаем, что это одна файловая программа, мы можем просто добавить:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
в верхней части исходного файла изменить политику по умолчанию на ту, которая просто возвращает NaN, когда происходит ошибка домена. В качестве альтернативы мы можем использовать:
#define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
Чтобы убедиться, что<::errno
>установлен, когда происходит ошибка домена, а также возвращает NaN.
Это безопасно при условии, что программа состоит из одного блока переводаи, мы размещаем определениепередлюбыми #включает. Обратите внимание, что если мы добавим определение после включения, то оно не будет иметь никакого эффекта! Предупреждение, такое как:
warning C4005: 'BOOST_MATH_OVERFLOW_ERROR_POLICY' : macro redefinition
Это является определенным признаком того, что оннебудет иметь желаемый эффект.
Мы начнем нашу выборочную программу с необходимых включений:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error // Boost #include <boost/math/distributions/students_t.hpp> using boost::math::students_t; // Probability of students_t(df, t). // std #include <iostream> using std::cout; using std::endl; #include <stdexcept> #include <cstddef> // using ::errno
Далее мы определим основной() программы, чтобы назвать распределение студента t с недействительным параметром степеней свободы, программа настроена для обработки либо исключения, либо NaN:
int main() { cout << "Example error handling using Student's t function. " << endl; cout << "BOOST_MATH_DOMAIN_ERROR_POLICY is set to: " << BOOST_STRINGIZE(BOOST_MATH_DOMAIN_ERROR_POLICY) << endl; double degrees_of_freedom = -1; // A bad argument! double t = 10; try { errno = 0; // Clear/reset. students_t dist(degrees_of_freedom); // exception is thrown here if enabled. double p = cdf(dist, t); // Test for error reported by other means: if((boost::math::isnan)(p)) { cout << "cdf returned a NaN!" << endl; if (errno != 0) { // So errno has been set. cout << "errno is set to: " << errno << endl; } } else cout << "Probability of Student's t is " << p << endl; } catch(const std::exception& e) { std::cout << "\n""Message from thrown exception was:\n " << e.what() << std::endl; } return 0; } // int main()
Вот как выглядит вывод программы при сборке по умолчанию (тот, которыйделает исключения):
Example error handling using Student's t function. BOOST_MATH_DOMAIN_ERROR_POLICY is set to: throw_on_error Message from thrown exception was: Error in function boost::math::students_t_distribution<double>::students_t_distribution: Degrees of freedom argument is -1, but must be > 0 !
В качестве альтернативы давайте построим с:
#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
Теперь выход программы:
Example error handling using Student's t function. BOOST_MATH_DOMAIN_ERROR_POLICY is set to: ignore_error cdf returned a NaN!
И, наконец, давайте строить с:
#define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
Что дает выход шоу errno:
Example error handling using Student's t function. BOOST_MATH_DOMAIN_ERROR_POLICY is set to: errno_on_error cdf returned a NaN! errno is set to: 33
Статья Changing the Policy Defaults раздела Math Toolkit 2.5.0 Policy Tutorial может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Policy Tutorial ::
реклама |