为什么本地类中不允许使用静态数据成员?

发布于 2024-12-16 14:08:02 字数 403 浏览 1 评论 0原文

为什么 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):

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

What is the reasoning to why static const members cannot exist in local classes? It seems like a rather silly restriction.

Example:

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

Quote from standard (9.8.4):

A local class shall not have static data members.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

静赏你的温柔 2024-12-23 14:08:02

根据标准第 9.4.2 节:

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

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

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

我想从理论上讲,它们可以允许您在本地类中使用静态常量整型,只要它们仅在整型常量表达式中使用,但这可能会给标准机构和编译器供应商带来太大的负担来区分实用价值很小;局部静态变量可以从局部类访问,因此使用局部静态常量应该同样好。

From the standard section 9.4.2:

If a static data member is of const integral or const enumeration
type, its declaration in the class definition can specify a
constant-initializer which shall be an integral constant expression.
In that case, the member can appear in integral constant expressions
within its scope. The member shall still be defined in a namespace
scope
if it is used in the program and the namespace scope definition
shall not contain an initializer.

Basically, local classes have no linkage, and static data members require a linkage.

Since there's no way to define a static data member of a local class in namespace scope (a declaration with an initializer is not a definition), they are not allowed, whether they are of const integral type or not. On the surface it may seem like the compiler should just be able to inline the value, but then what happens if you try to access a pointer to the member? With namespace scoped classes you'd just get a linker error, but local classes have no linkage.

I guess in theory they could just allow you to use static const integral types in local classes as long as they are only used in integral constant expressions, but it would probably just put too much of a burden on the standards body and compiler vendors to differentiate for very little practical value; local static variables are accessible from local classes, so using a local static const should be just as good.

z祗昰~ 2024-12-23 14:08:02

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

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

I dont think there is a.reason. Normal static datamembers are disallowed because there is no way to define them after being declared.

Also dont forget you can create a local const variable outside the.class that you can use inside the class as long as you only read its value (that is, as long as you dont take.its.address).

ゃ人海孤独症 2024-12-23 14:08:02

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

  abc.h

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

   int myClass::number = 314;

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

Static members of a class need to be defined in global scope, e.g.

  abc.h

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

   int myClass::number = 314;

Now, since the scope inside void abc(int x) is not global, there is no scope to define the static member.

心意如水 2024-12-23 14:08:02

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

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

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

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

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

As things progress, we now have C++11 and with that you can define integral constants variable members in your classes.

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

That works when you compile with C++11. Notice that the static keyword is not used. When compiling with optimizations turned on, those variables will likely all get optimized out. In debug, though, they appear in your structure as regular variable members.

Note, however, that the size of the class/structure will still include that variable. So here it is likely 4 bytes for the variable FOO.

However, in most cases, classes defined in a function will completely be optimized out so this is a great way of doing things (a good 50% of my classes have such variable members!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文