Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否在编译时将强类型枚举数转换为其基础类型?_C++_C++11_Strongly Typed Enum - Fatal编程技术网

C++ 是否在编译时将强类型枚举数转换为其基础类型?

C++ 是否在编译时将强类型枚举数转换为其基础类型?,c++,c++11,strongly-typed-enum,C++,C++11,Strongly Typed Enum,我知道强类型枚举数可以转换为其基础类型,如下所示: 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 constexpr 自动到_积分(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);
}
template constexpr
自动到_积分(E)->typename std::底层_type::type
{
返回静态_-cast(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的简单意思是:在编译时初始化。之后,您可以像运行时一样使用它


在上面的示例中,我确信大多数编译器都会优化代码,而不考虑constexpr关键字。(给定-O2或-O3)但是,如果代码变得更复杂,则需要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的简单意思是:在编译时初始化。之后,您可以像运行时一样使用它


在上面的示例中,我确信大多数编译器都会优化代码,而不考虑constexpr关键字。(给定-O2或-O3)但是,如果代码变得更复杂,则需要constexpr强制他们进行优化,而不考虑成本。

如下面链接中提到的herb sutter

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


当其所有参数都是常量表达式且结果未在常量表达式中使用时,可能会对其求值,但这取决于实现。

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

constexpr
函数的所有参数都是常量表达式且结果也用于常量表达式时,将在编译时对其求值。常量表达式可以是文字(如42)、非类型模板参数(如模板类数组中的N)、元素声明(就像枚举颜色{Red,Blue,Green};)中的蓝色一样,另一个变量声明为constexpr,依此类推


当其所有参数都是常量表达式且结果不用于常量表达式时,可能会对其进行计算,但这取决于实现。

“但是,这在运行时起作用。”你为什么这么认为?@cppleener这是一个函数调用,函数调用在运行时起作用,对吗?标准没有这种概念“编译时间”,所以它不能保证任何东西。它有一个“常量表达式”的概念。如果编译器不完全优化调用,它不会优化任何东西。我在godbolt上玩了你的示例。为此,我在不带
constexpr
gcc 8.1
--std=c++17
const int i=to_integral(E::E123);
mov
调用to_integral\u rt()编译一个
mov
mov
用于非
constexpr
风格。但是,添加
-O2
两个调用都被优化掉了-这两个常量都直接设置到输出命令中。(我希望像过去一样处理类似的事情。)“但是,这在运行时起作用。“你为什么这么认为?@cppleener这是一个函数调用,函数调用在运行时工作,对吗?标准根本没有“编译时间”的概念,所以它不能保证任何东西。它有一个“常量表达式”的概念。”相反,如果编译器没有完全优化调用,它将不会优化任何东西。我在godbolt上玩了你的示例。为此,我添加了第二个
到_integral_rt()
,没有
constexpr
(查看差异)。gcc 8.1
--std=c++17
const int I=to _integral>编译一个
mov
(E::E123);
,和
mov
调用非
constexpr
风格的_integral_rt()
mov
。但是,添加
-O2
两个调用都被优化掉了-两个常量都直接设置到输出命令中。(我希望这和我过去处理类似事情一样。)