简体   繁体   English

在struct / class中使用静态const int

[英]using a static const int in a struct/class

struct A {
    static const int a = 5;

    struct B {
       static const int b = a;
    };

 };

 int main() {
   return A::B::b;
 }

The above code compiles. 上面的代码编译。 However if you go by Effective C++ book by Scott Myers(pg 14); 但是,如果你选择Scott Myers的Effective C ++书籍(第14页); We need a definition for a in addition to the declaration. 除声明外,我们还需要一个定义。 Can anyone explain why this is an exception? 任何人都可以解释为什么这是一个例外?

C++ compilers allow static const integers (and integers only) to have their value specified at the location they are declared. C ++编译器允许静态const整数(和仅整数)在声明它们的位置指定它们的值。 This is because the variable is essentially not needed, and lives only in the code (it is typically compiled out). 这是因为变量基本上不需要,并且仅存在于代码中(通常是编译出来的)。

Other variable types (such as static const char*) cannot typically be defined where they are declared, and require a separate definition. 其他变量类型(例如static const char *)通常不能在声明它们的地方定义,并且需要单独的定义。

For a tiny bit more explanation, realize that accessing a global variable typically requires making an address reference in the lower-level code. 有关更多解释,请注意,访问全局变量通常需要在较低级别的代码中进行地址引用。 But your global variable is an integer whose size is this typically around the size of an address, and the compiler realizes it will never change, so why bother adding the pointer abstraction? 但是你的全局变量是一个整数,其大小通常在地址大小附近,编译器意识到它永远不会改变,那么为什么还要加入指针抽象呢?

By really pedantic rules, yes, your code needs a definition for that static integer. 通过非常迂腐的规则,是的,您的代码需要该静态整数的定义。 But by practical rules, and what all compilers implement because that's how the rules of C++03 are intended - no, you don't need a definition. 但是根据实际规则,以及所有编译器实现的内容,因为C ++ 03的规则是如何实现的 - 不,你不需要定义。

The rules for such static constant integers are intended to allow you to omit the definition if the integer is used only in such situations where a value is immediately read, and if the static member can be used in constant expressions. 如果仅在立即读取值的情况下使用整数,并且静态成员可用于常量表达式,则此类静态常量整数的规则旨在允许您省略定义。

In your return statement, the value of the member is immediately read, so you can omit the definition of the static constant integer member if that's the only use of it. 在return语句中,会立即读取成员的值,因此您可以省略静态常量整数成员的定义(如果这是它的唯一用途)。 The following situation needs a definition, however: 但是,以下情况需要定义:

struct A {
    static const int a = 5;

    struct B {
       static const int b = a;
    };

 };

 int main() {
   int *p = &A::B::b;
 }

No value is read here - but instead the address of it is taken. 这里没有读取任何值 - 而是采用它的地址。 Therefore, the intent of the C++03 Standard is that you have to provide a definition for the member like the following in some implementation file. 因此,C ++ 03标准的目的是您必须在某些实现文件中为成员提供如下所示的定义。

const int A::B::b;

Note that the actual rules appearing in the C++03 Standard says that a definition is not required only where the variable is used where a constant expression is required . 需要注意的是出现在C ++标准03 实际的规则说,只有哪里哪里需要常量表达式中使用的变量的定义不是必需的。 That rule, however, if strictly applied, is too strict. 但是,如果严格适用,该规则过于严格。 It would only allow you to omit a definition for situation like array-dimensions - but would require a definition in cases like a return statement. 它只允许你省略像数组维这样的情况的定义 - 但是在返回语句的情况下需要定义。 The corresponding defect report is here . 相应的缺陷报告在这里

The wording of C++0x has been updated to include that defect report resolution, and to allow your code as written. C ++ 0x的措辞已更新,包括该缺陷报告解析,并允许您的代码编写。

However, if you try the ternary operand without "defining" static consts, you get a linker error in GCC 4x: 但是,如果在没有“定义”静态consts的情况下尝试三元操作数,则会在GCC 4x中出现链接器错误:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13795 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13795

So, although constructs like int k = A::CONSTVAL; 所以,虽然像int k = A::CONSTVAL; are illegal in the current standard, they are supported. 在当前标准中是非法的,它们是受支持的。 But the ternary operand is not. 但三元操作数不是。 Some operators are more equal than others, if you get my drift :) 有些运营商比其他运营商更平等,如果你让我的漂移:)

So much for "lax" rules. 对于“宽松”规则来说太多了。 I suggest you write code conforming to the standard if you do not want surprises. 如果你不想要惊喜,我建议你编写符合标准的代码。

In general, most (and recent) C++ compilers allow static const ints 通常,大多数(和最近的)C ++编译器允许静态const int

You just lucky, perhaps not. 你很幸运,也许不是。 Try older compiler, such as gcc 2.0 and it will vehemently punish you with-less-than-pretty error message. 尝试较旧的编译器,例如gcc 2.0,它会严重惩罚你的错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM