在编译时将强类型枚举器转换为其基础类型?



我知道强类型枚举器可以转换为其基础类型,如下所示:

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

但是,这在运行时工作。

由于枚举器已经在编译时存在,有没有办法在编译时进行这种转换?

正如 herb sutter 在下面的链接中提到的,

什么时候在编译时计算 constexpr 函数?

constexpr函数的所有参数都是常量表达式并且结果也用于常量表达式时,将在编译时计算函数。常量表达式可以是文字(如 42(、非类型模板参数(如模板类数组中的 N;(、enum元素声明(如枚举颜色中的蓝色 { 红色、蓝色、绿色 };(、另一个声明 constexpr 的变量,等等。

当其所有参数都是常量表达式并且结果未在常量表达式中使用时,可能会对它们进行评估,但这取决于实现。

你写的函数可以在编译时使用。

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 来强制他们优化它,而不考虑成本。

最新更新