C++ 为什么不';本地类中是否允许t个静态数据成员?

C++ 为什么不';本地类中是否允许t个静态数据成员?,c++,static,static-members,local-class,C++,Static,Static Members,Local Class,为什么静态常量成员不能存在于本地类中,原因是什么?这似乎是一个相当愚蠢的限制 例如: 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 q

为什么
静态常量
成员不能存在于本地类中,原因是什么?这似乎是一个相当愚蠢的限制

例如:

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):

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


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

  abc.h

   class myClass {
   static int number;
  };
     abc.cpp

   int myClass::number = 314;

现在,由于voidabc(intx)中的作用域不是全局的,因此没有定义静态成员的作用域

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


另外,不要忘记,您可以在.class外部创建一个局部常量变量,只要您只读取它的值(即,只要您不接受.its.address),就可以在类内部使用该变量。

来自标准第9.4.2节:

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

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

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


我猜理论上,它们可以允许您在本地类中使用静态常量整型,只要它们只用于整型常量表达式中,但这可能会给标准体和编译器供应商带来太多负担,使他们无法区分实际价值;局部静态变量可以从局部类访问,因此使用局部静态常量也应该一样好。

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

class test
{
public:
    const int FOO = 123;

    [...snip...]
};
这在使用C++11编译时有效。请注意,
static
关键字未被使用。在启用优化的情况下编译时,这些变量很可能都会得到优化。但在调试中,它们在结构中显示为正则变量成员

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


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

静态常量可以在非本地类定义中定义。它们不能被定义。inclass初始化不是定义在命名空间作用域类内声明和初始化的静态常量成员可以在没有外部定义的情况下使用,只要它们从未用作l值(需要地址)。如果你试图将它们传递给一个引用或指针的函数或方法,你将(应该)得到一个链接器错误,虽然你链接的那一个是在问其他问题。Iirc规范有一个关于该规则的脚注。解释原因如果像我这样的人因为编译器的错误提示而来到这里,并且不知道如何识别错误。相对长度单位。。。您还可以尝试验证头文件。我不小心在一个函数声明的末尾放了一个
{
。。希望这能对您有所帮助:))gcc5报告了这种情况,而clang和icc则没有。