static constexpr variable vs function
constexpr
functions
Functions have an advantage that free variables do not have (until C++14 that is): they can easily be templated without some class boilerplate. That means you can have your pi
with a precision depending on a template argument:
template<typename T>
constexpr T pi();
template<>
constexpr float pi() { return 3.14f; }
template<>
constexpr double pi() { return 3.1415; }
int main()
{
constexpr float a = pi<float>();
constexpr double b = pi<double>();
}
However, if you decide to use a static
member function instead of a free function, it won't be shorter nor easier to write than a static
member variable.
constexpr
variables
The main advantage of using a variable is that... well. You want a constant, right? It clarifies the intent and that may be one of the most important points here.
You could still have an equivalent behaviour with a class, but then, you would have to use it like this if your class is a class containing miscellaneous mathematics constants:
constexpr float a = constants<float>::pi;
Or like this if your class is only meant to represent pi
:
constexpr double = pi<double>::value;
In the first case, you may prefer to use variables since it will be shorter to write and that will really show that you are using a constant and not trying to compute something. If you just have a class representing pi, you could however go with a free constexpr
function instead of a whole class. It would IMHO be simpler.
C++14: constexpr
variable templates
However, note that if you choose to use C++14 instead of C++11, you will be able to write the following kind of constexpr
variable templates:
template<typename T>
constexpr T pi = T(3.1415);
That will allow you to write your code like this:
constexpr float a = pi<float>;
Starting from C++14, this may be the preferred way to do things. If you are using an older version of the standard, the first two paragraphs still hold.