将整数类型转换为枚举:功能强制转换与初始化

时间:2018-04-27 20:51:01

标签: c++ enums casting initialization

假设有一个这样的枚举:

enum foo: int {
    first,
    second
}

然后我按如下方式使用它:

foo f(1); // error: cannot initialize a variable of type 'foo' with an rvalue of type 'int'
foo f = foo(1); // OK !

我想知道两者有什么区别? 我知道第二个版本可以看作是一个功能风格的演员,但为什么会有所不同呢?

例如,如果我这样做:

class Bar {};
Bar b = Bar(1); // no matching conversion for functional-style cast from 'int' to 'Bar'

我显然得到一个有意义的错误。因此,这让我相信,为了使上面foo示例的第二个版本起作用,必须在某处定义从intenum的转换,但如果有这样的转换那么为什么呢?我在第一个版本中收到错误?

如果这是重复,我会道歉。我怀疑它是。 这似乎很相关:Is this a cast or a construction? ......但不要退出。

提前致谢!

1 个答案:

答案 0 :(得分:3)

是的,这两种形式是微妙的。让我们看看第一个,这会导致错误。它来自f的{​​{1}}类型foo的初始化。它在这里描述,强调我的:

  

[dcl.init]/17.8

     

否则,正在初始化的对象的初始值是   (可能已转换)初始化表达式的值。 标准   如有必要,将使用转换来转换初始值设定项   表达式到目标类型的cv-nonqualified版本;没有   考虑用户定义的转换。 如果转换不能   完成后,初始化是不正确的

在这种情况下,相关的转换是完整的转换,主要是由以下指定的转换:

  

[conv.integral]/1

     

未范围的枚举类型的prvalue可以转换为a   整数类型的prvalue。

因此,一个无范围的枚举可以隐式转换为整数,但反之则不然。这就是初始化不正确的原因。但是,功能样式的强制转换符号本质上是一个静态强制转换。还有一个static cast can perform the inverse of (almost) any valid standard conversion。因此,使用已投标的int初始化1,但此时我们正在从f prvalue进行初始化,这当然完全没问题。