为什么不允许位字段作为类的静态数据成员

时间:2017-03-29 05:52:22

标签: c++ bit-fields

任何人都可以解释不允许位字段作为类的静态成员的原因吗?例如,一个类定义如下:

class A{
public:
    A() {}
    ~A(){}
private:
    static int mem :10;
};
int A::mem;

没有编译。

使用不同的编译器编译此类: -

1- g ++抛出错误: -

错误:静态成员' mem'不能是一个位字段

static int mem :10;

错误:'int A :: mem'不是'class A'

的静态数据成员

int A :: mem;

2- clang抛出错误: -

错误:静态成员' mem'不能是一个位字段

static int mem :10;

3-Visual Studio 15抛出错误: -

' A :: mem' ::非法存储类

' int A :: mem':不允许成员函数重新声明

2 个答案:

答案 0 :(得分:6)

主要原因是因为这是C ++标准明确指出的内容:

[class.bit] 12.2.4/3

  

位字段不应是静态成员。位字段应具有整数或枚举类型([basic.fundamental])。 bool值可以成功地存储在任何非零大小的位字段中。运营商的地址&不应用于位域,因此没有指向位域的指针。非const引用不应绑定到位字段([dcl.init.ref])。 [注意:如果初始化器为const T&类型的参考是一个引用位字段的左值,引用绑定到临时初始化以保存位字段的值;引用不直接绑定到位字段。见[dcl.init.ref]。 - 结束说明]

它的推理?好吧,位域是来自C的结转。它们仅允许作为结构或联合字段开始。就个人而言,我无法想到静态位字段成员可能有用的上下文。

此外,几乎所有关于位字段的内容都是已经实现定义的,并且让静态数据以完全实现定义的方式运行,恕我直言是一个非常糟糕的主意。

答案 1 :(得分:1)

标准禁止它的原因是因为静态数据成员需要在某处实例化 - 在您的示例中,某处的编译单元需要包含:

int A::mem :10;

无效,与独立的非成员位域变量相同,如:

int foo :10;

无效。

当然,人们可以问为什么这是被禁止的,但这是一个更广泛的问题,与其作为集体成员无关。