Я понимаю, что строго типизированный перечислитель может быть преобразован в его базовый тип как:
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);
}
Тем не менее, это работает во время выполнения.
Поскольку перечислители уже находятся во время компиляции, есть ли способ сделать такое преобразование во время компиляции?
Функция, которую вы написали, подходит для использования во время компиляции.
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);
Это должно скомпилировать, указывая, что функция может быть запущена во время компиляции.
Однако функции constexpr указывают только на то, что функция соответствует всем требованиям, которые должны быть выполнены во время компиляции. Чтобы обеспечить вычисление этого значения (даже при -O0), вам необходимо сделать ваши переменные также constexpr.
constexpr auto i = to_integral(A::a);
i = 42;
Для переменной constexpr просто означает: инициализировать во время компиляции. После этого вы можете использовать его так, как если бы он был во время выполнения.
В приведенном выше примере я убежден, что большинство компиляторов оптимизируют код независимо от ключевого слова constexpr. (Учитывая -O2 или -O3) Однако, если код становится более сложным, constexpr должен заставить их оптимизировать его, независимо от стоимости.
В качестве травяного саттера, упомянутого в приведенной ниже ссылке,
Когда функция constexpr оценивается во время компиляции?
constexpr
Функции будут оцениваться во время компиляции, когда все его аргументы являются константными выражениями, а результат также используется в константном выражении. Константное выражение может быть литералом (например, 42), нетиповым аргументом шаблона (например, N в массиве шаблонного класса;), enum
объявление элемента (например, Blue в enum Color {Red, Blue, Green}; другая объявленная переменная constexpr и т. д.).
Они могут быть оценены, когда все его аргументы являются константными выражениями, а результат не используется в константном выражении, но это зависит от реализации.