0

我知道强类型的枚举器可以转换为它的基础类型:

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

但是,这是在运行时工作的。

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

4

2 回答 2

2

正如以下链接中提到的草本萨特,

constexpr 函数何时在编译时进行评估?

constexpr当函数的所有参数都是常量表达式并且结果也用于常量表达式时,函数将在编译时进行评估。常量表达式可以是文字(如 42)、非类型模板参数(如模板类数组中的 N;)、enum元素声明(如枚举 Color { Red, Blue, Green }; 中的 Blue),另一个声明为 constexpr 的变量, 等等。

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

于 2018-08-08T07:14:32.773 回答
1

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

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 来强制它们对其进行优化,而不管成本如何。

于 2018-08-08T06:34:00.850 回答