Использование математических констант повышения в 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>();
Другие вопросы по тегам