枚举 class 的 C 风格转换为基础类型 char 的引用

C-style cast of enum class to reference of underlying type char

这是合法的 C++ (>=14),导致 char 被读取并保存到 aCode 中吗?

enum class ECode : char { Code1 = 'a' };
std::istream& operator>>(std::istream& aIn, ECode& aCode)
{
  return aIn >> (std::underlying_type_t<ECode>&)aCode;
}

我更喜欢 return aIn >> static_cast<std::underlying_type_t<ECode>&>(aCode),这似乎是不合法的 ("cannot cast to reference of unrelated type".)

然而,这条非常相似的行是合法的,并且是我的 C 风格转换应该相同的行:

return aIn >> *static_cast<char*>(static_cast<void*>(&aCode))

如评论中所述,不存在严格的别名违规,因为 char 可以为任何类型起别名。

实际上,我怀疑任何真正的编译器都会做除 "obvious" 实现之外的任何事情,即为枚举提供与基础类型相同的大小和表示形式。在这种情况下,您的 reinterpret_cast 将被明确定义并按预期运行。

然而,标准(自 C++17 起)似乎并不能保证这一点。

据我所知,它只是规定了底层类型的任何值都可以存储在枚举对象中,并且static_cast可以无损地用于底层类型范围内的值.

关于 sizeof(ECode) == sizeof(char) 是否必须成立,有 a language lawyer question here,虽然答案似乎是 "the standard doesn't actually say so but they probably meant it"。

但即使大小相同,也没有代表保证,例如这些位可以以某种不同的顺序存储,并且 static_cast 转换这些位。

在指定整数类型表示的[basic.fundamental]中,它甚至有一个明确的脚注说枚举不是整数类型。