C++17 Update:
static constexpr
variables are implicitly inline
so there\'s no external definition necessary.
Original qu
One difference is that you can take the address of a static constexpr
but not of an enum
.
Another is that constexpr
isn't supported by older versions of the language (it was introduced in C++11).
I'd use enum
only if the values belong together. I'd also give the enum
a name that describes that relationship. I wouldn't use an enum
for defining unrelated constants.
The reason I would give you is that using enum { }
for constants is a misuse of the term enum
. You're not enumerating anything. It's a common misuse, granted; it has its practical advantages; but it's just kind of wrong. There should be a way to say "this is just a compile-time constant and nothing else". constexpr isn't that thing either, but it's closer than enum. And it's rightly the case that you can't enum floating-point values.
That being said - I often use enums for constants myself, when I want to protect myself against people writing something like void* ptr = &some_constant_value; std::cout << ptr;
Perhaps no advantage for your usage because you're just using simple fixed integer values.
But, [AFAIK] constexpr
can be more general as it allows initialization from anything that can be evaluated at compile time.
From type_traits
:
/// integral_constant template<typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() const { return value; } #if __cplusplus > 201103L #define __cpp_lib_integral_constant_callable 201304 constexpr value_type operator()() const { return value; } #endif };
Thus, constexpr
has usage in metaprogramming.
The following is a bit rough.
If you had a function like:
constexpr unsigned
bitmask(int bitno)
{
return 1u << bitno;
}
You might find a usage such as:
constexpr unsigned BIT_0 = bitmask(0);
constexpr unsigned BIT_1 = bitmask(1);