【问题标题】:Why aren't static data members allowed in local classes?为什么本地类中不允许使用静态数据成员?
【发布时间】:2011-12-31 01:41:17
【问题描述】:

static const 成员不能存在于本地类中的原因是什么?这似乎是一个相当愚蠢的限制。

例子:

void foo() {
  struct bar {
    int baz() { return 0; }   // allowed
    static const int qux = 0; // not allowed?!?
  };
}

struct non_local_bar {
  int baz() { return 0; }   // allowed
  static const int qux = 0; // allowed
};

引用标准 (9.8.4):

本地类不应有静态数据成员。

【问题讨论】:

  • @JosephH 这可能是重复的,虽然你链接的那个在问别的东西。
  • Iirc 规范对该规则有一个脚注。解释原因
  • 如果像我这样的人因为编译器的错误提示而来到这里,并且不知道如何识别错误。 em...您也可以尝试验证您的头文件。我不小心在一个函数声明的末尾放了一个{。 ... ...希望这可以帮助你:)))

标签: c++ static static-members local-class


【解决方案1】:

来自标准部分 9.4.2:

如果静态数据成员是 const 整数或 const 枚举 类型,它在类定义中的声明可以指定一个 常量初始化器,它应该是一个整数常量表达式。 在这种情况下,成员可以出现在整型常量表达式中 在其范围内。 成员仍应在命名空间中定义 范围如果在程序和命名空间范围定义中使用 不应包含初始化程序。

基本上,本地类没有链接,静态数据成员需要链接。

由于无法在命名空间范围内定义本地类的静态数据成员(带有初始化程序的声明不是定义),因此不允许使用它们,无论它们是否为 const 整数类型。从表面上看,编译器似乎应该能够内联该值,但是如果您尝试访问指向该成员的指针会发生什么?使用命名空间范围的类,您只会得到一个链接器错误,但本地类没有链接。

我猜理论上它们可以只允许您在本地类中使用静态 const 整数类型,只要它们仅用于整数常量表达式,但这可能会给标准机构和编译器带来太多负担供应商为了很少的实际价值而进行差异化;本地静态变量可以从本地类中访问,因此使用本地静态常量应该一样好。

【讨论】:

  • gcc5 会报告此类情况,而 clang 和 icc 不会。
【解决方案2】:

我不认为有什么原因。不允许使用普通静态数据成员,因为在声明后无法定义它们。

另外别忘了你可以在.class之外创建一个局部const变量,你可以在类内部使用,只要你只读取它的值(也就是说,只要你不取.its.address)。

【讨论】:

    【解决方案3】:

    类的静态成员需要在全局范围内定义,例如

      abc.h
    
       class myClass {
       static int number;
      };
         abc.cpp
    
       int myClass::number = 314;
    

    现在,由于 void abc(int x) 内部的范围不是全局的,因此没有定义静态成员的范围。

    【讨论】:

    • static const 成员可以在非本地类定义中定义。
    • 它们无法定义。类内初始化不是定义
    • 在命名空间范围类中声明和初始化的静态 const 成员可以在没有外部定义的情况下使用,只要它们从不用作左值(需要地址)。如果您尝试将它们传递给采用引用或指针的函数或方法,您将(应该)收到链接器错误。
    【解决方案4】:

    随着事情的发展,我们现在有了 C++11,你可以在你的类中定义整型常量变量成员。

    class test
    {
    public:
        const int FOO = 123;
    
        [...snip...]
    };
    

    当您使用 C++11 编译时,它可以工作。请注意,未使用 static 关键字。在打开优化的情况下进行编译时,这些变量可能都会被优化掉。但在调试中,它们作为常规变量成员出现在您的结构中。

    但是请注意,类/结构的大小仍将包含该变量。所以这里变量 FOO 可能是 4 个字节。

    但是,在大多数情况下,函数中定义的类将被完全优化,因此这是一种很好的处理方式(我的 50% 的类都有这样的变量成员!)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 2016-01-31
      • 2012-01-21
      • 2011-01-28
      • 1970-01-01
      • 2015-08-09
      相关资源
      最近更新 更多