g ++无法编译以下代码片段:
namespace X {
enum En {A, B};
bool test(En e);
}
bool check() {
union {
struct {
X::En y:16;
X::En z:16;
} x;
int z;
} zz;
return test(zz.x.y);
}
它给出的错误是
在功能' bool check()':15:错误:'测试'未被宣布 此范围返回测试(zz.x.y); ^ 15:注意:建议替代方案:3 :注意:' X :: test'布尔试验(En e); ^ ~~~编译失败
如果我使y
成为常规成员而不是位域,则代码会成功编译。调用名称间隔test
也可以。 Clang按原样编译程序,没有任何抱怨。
把bitfield业务放在一边(我根本不喜欢它,但代码库有它)而不关注我是否有保证将枚举安装到16位成员中,是否有一些关于位域的特殊内容防止ADL像我期望的那样踢进去?
答案 0 :(得分:1)
普通枚举的基础类型是实现定义的:
C ++ 03 standard 7.2 / 5
枚举的基础类型是一个整数类型,可以表示枚举中定义的所有枚举器值。它是实现定义的,使用整数类型作为枚举的基础类型,除了基础类型不应大于int,除非枚举器的值不能适合int或unsigned int
struct bitfield枚举的基础时间也是实现定义的:
C ++ 03 standard 9.6 / 3
位域应具有整数或枚举类型(3.9.1)。它是实现定义的是明文(既未明确签名也未签名)char,short,int或long位字段是有符号还是无符号。
因为X::En y:16
和X::En
的类型都是实现定义的,它们之间的隐式转换也是实现定义的,我认为这解释了你在编译器中看到的ADL差异