【问题标题】:Why are bit fields not allowed as static data members of a class为什么不允许位字段作为类的静态数据成员
【发布时间】:2017-03-29 05:52:21
【问题描述】:

谁能解释不允许位字段作为类的静态成员的原因?例如,一个类定义如下:

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':不允许成员函数重声明

【问题讨论】:

标签: c++ bit-fields


【解决方案1】:

主要原因是因为这是 C++ 标准明确规定的:

[class.bit] 12.2.4/3

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

原因是什么?好吧,位域是从 C 中继承而来的。它们只允许作为结构或联合域开始。就个人而言,我想不出一个静态位域成员有用的上下文。

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

【讨论】:

  • @StorTeller,正如您所说“几乎所有关于位域的内容都是实现定义的”,但是标准明确提到“位域不应是静态成员”。所以标准委员会必须有一些理由禁止静态位字段成员。可能是杰里米提到的内容。
  • @DineshMaurya - 标准禁止它,因为允许它比它的价值更麻烦。位域在 C 中的用途有限,在 C++ 中甚至更少。如果您想要命名“位”,您可以使用固定宽度整数的联合和封装对特定位的访问的类来实现它(如 C++11 允许的那样)。
【解决方案2】:

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

int A::mem :10;

这是无效的,就像一个独立的非成员位域变量一样:

int foo :10;

无效。

当然有人可以问为什么禁止这样做,但这是一个更广泛的问题,与它是否是班级成员无关。

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 2016-01-31
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多