c++ - g++、位域和 ADL

标签 c++ argument-dependent-lookup

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);
}

它给出的错误如下

In function 'bool check()': 15 : error: 'test' was not declared in this scope return test(zz.x.y); ^ 15 : note: suggested alternative: 3 : note: 'X::test' bool test(En e); ^~~~ Compilation failed

如果我使 y 成为常规成员,而不是位域,代码将成功编译。调用 namespace test 也可以。 Clang 按原样编译程序,没有任何提示。

抛开位域业务(我一点也不喜欢它,但代码库有它)并且不关注我是否保证将枚举放入 16 位成员中,关于位域有什么特别之处吗阻止 ADL 像我预期的那样启动?

最佳答案

普通枚举的底层类型是实现定义的:

C++03 标准 7.2/5

The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. It is implementation-defined which integral type is used as the underlying type for an enumeration except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int

struct bitfield 枚举的底层时间也是实现定义的:

C++03 标准 9.6/3

A bit-field shall have integral or enumeration type (3.9.1). It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned.

所以因为 X::En y:16X::En 的类型都是实现定义的,所以它们之间的隐式转换也是实现定义的,我认为这解释了您在不同编译器中看到的 ADL 差异。

关于c++ - g++、位域和 ADL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38706287/

相关文章:

c++ - vtkobject 中使用的宏是什么?

c++ - 结构 vector 上的 MemCpy

c++ - 如果类型来自 std,是否可以创建一个特征来回答?

c++ - 如何选择正确的运算符重载

c++ - 关于友元函数定义和命名空间范围

c++ - 使用 gmock Matchers 将 std::function 设置为 EXPECT_CALL 中的方法参数

C++枚举标志与位集

c++ - 我可以在 Windows 上使用 _bstr_t 类在多字节和 Unicode 之间进行转换吗? (C++)

c++ - C++ 中的参数相关查找

c++ - 为什么编译器找不到这个 operator<< 重载?