我了解强类型枚举器可以转换为以下类型:
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);
}
但是,这在运行时有效。
由于枚举器已经在编译时存在,有没有办法在编译时进行这种转换?
答案 0 :(得分:2)
正如下面链接中提到的草药一样,
When does a constexpr function get evaluated at compile time?
当 SQLite3
函数的所有参数均为常量表达式时,将在编译时对其求值,并且结果也将在常量表达式中使用。常量表达式可以是文字(如42),非类型模板自变量(如模板类数组中的N;),$db = new SQLite3('mysqlitedb.db');
$results = $db->query('SELECT bar FROM foo');
while ($row = $results->fetchArray()) {
var_dump($row);
}
元素声明(如枚举中的Blue Color {Red,Blue,Green}; ,另一个声明为constexpr的变量,依此类推。
当它们的所有参数都是常量表达式并且结果未在常量表达式中使用时,可能会对它们求值,但这取决于实现。
答案 1 :(得分: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强制其对其进行优化。