I understand that a strongly typed enumerator can be converted to its underlying type as:
template<typename E> constexpr
auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename std::underlying_type<E>::type>(e);
}
However, this is working in run-time.
Since enumerators are there already in compilation time, is there a way to do such conversion during compilation time?
The function you wrote is OK to be used at compile time.
template<typename E> constexpr
auto to_integral(E e) -> typename std::underlying_type<E>::type
{
return static_cast<typename> std::underlying_type<E>::type>(e);
}
enum class A : int { a };
static_assert(to_integral(A::a) == 0);
This should compile, indicating that the function can be ran at compile time. However, constexpr functions only indicate that the function complies with all requirements to be executed at compile time. To enforce this being calculated (even at -O0), you need to make your variables also constexpr.
constexpr auto i = to_integral(A::a);
i = 42;
For a variable, the constexpr simply means: initialize at compile time. Afterwards, you can use it as if it was runtime.
In the example above, I'm convinced that most compilers will optimize the code regardless of the constexpr keyword. (Given -O2 or -O3) However if the code becomes more complex the constexpr is required to force them to optimize it, regardless of the cost.