我知道强类型的枚举器可以转换为它的基础类型:
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);
}
但是,这是在运行时工作的。
由于枚举器已经存在于编译时,有没有办法在编译时进行这种转换?
正如以下链接中提到的草本萨特,
constexpr
当函数的所有参数都是常量表达式并且结果也用于常量表达式时,函数将在编译时进行评估。常量表达式可以是文字(如 42)、非类型模板参数(如模板类数组中的 N;)、enum
元素声明(如枚举 Color { Red, Blue, Green }; 中的 Blue),另一个声明为 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 来强制它们对其进行优化,而不管成本如何。