Question

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.

Was it helpful?

Solution

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>;
}

OTHER TIPS

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>();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top