Использование математических констант повышения в constexpr
Можно ли использовать математические константы boost в constexpr?
Например, следующая строка:
static constexpr double SEC3 = static_cast<double>(45)/180*boost::math::double_constants::pi;
дает мне ошибку
Error - constexpr variable 'SEC3' must be initialized by a constant expression
Но если я заменю код повышения на простой M_PI, он будет работать нормально.
2 ответа
Я подозреваю, что это может быть причиной. Колиру дает эту ошибку:
clang++ -std=c++1y -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/usr/local/include/boost/math/constants/constants.hpp:248:52: note: expanded from macro 'BOOST_DEFINE_MATH_CONSTANT'
namespace double_constants{ static const double name = x; } \
Если это определено как const
и не constexpr
Это может быть причиной того, что он отклоняет код. Чтобы убедиться, что это является источником проблемы, мы можем воспроизвести ошибку с помощью этого теста:
// This code fails
#include <boost/math/constants/constants.hpp>
namespace double_constants{ static const double name = 25; }
static constexpr double SEC3 = static_cast<double>(45)/180*double_constants::name;
Так как же это исправить? Не используйте версию без шаблонов. Boost предоставляет шаблонную версию, которую мы можем использовать вместо.
static constexpr double SEC3 = static_cast<double>(45)/180*boost::math::constants::pi<double>();
Clang 3.5 также реализует шаблоны переменных в режиме C++1y:
template <class T>
static constexpr T SEC3 = static_cast<T>(45)/180*boost::math::constants::pi<T>();
int main()
{
std::cout << SEC3<double>;
}
Я увидел этот пост, когда искал самый простой способ определить число pi как constexpr double, используя библиотеку boost. Следующий фрагмент кода хорошо работает для меня в Visual Studio 2017 с использованием boost 1_66_0:
#include <boost/math/constants/constants.hpp>
constexpr double pi = boost::math::constants::pi<double>();