Is is possible to use boost math constants in constexpr?
For example, the following line:
static constexpr double SEC3 = static_cast<double>(45)/180*boost::math::double_constants::pi;
gives me error
Error - constexpr variable 'SEC3' must be initialized by a constant expression
But if I replace the boost code with simple M_PI, it works fine.
I suspect this may be the reason. Coliru gives this error:
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; } \
If it's defined as const
and not constexpr
, that may be why it's rejecting the code. To reassure ourselves that is the source of the issue, we can reproduce the error with this testcase:
// 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;
So how do we fix this? Don't use the non-templated version. Boost provides a templated version that we can use instead.
static constexpr double SEC3 = static_cast<double>(45)/180*boost::math::constants::pi<double>();
clang 3.5 also implements variable templates with C++1y mode:
template <class T>
static constexpr T SEC3 = static_cast<T>(45)/180*boost::math::constants::pi<T>();
int main()
{
std::cout << SEC3<double>;
}
I saw this post when I was looking for the cleanest way to define pi as a constexpr double using the boost library. The following code snippet works well for me in Visual Studio 2017 using boost 1_66_0:
#include <boost/math/constants/constants.hpp>
constexpr double pi = boost::math::constants::pi<double>();