在struct/class中使用静态const int

Pra*_*yot 10 c++

struct A {
    static const int a = 5;

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

 };

 int main() {
   return A::B::b;
 }
Run Code Online (Sandbox Code Playgroud)

上面的代码编译.但是,如果你选择Scott Myers的Effective C++书籍(第14页); 除声明外,我们还需要一个定义.任何人都可以解释为什么这是一个例外?

Wal*_*t W 20

C++编译器允许静态const整数(和仅整数)在声明它们的位置指定它们的值.这是因为变量基本上不需要,并且仅存在于代码中(通常是编译出来的).

其他变量类型(例如static const char*)通常不能在声明它们的地方定义,并且需要单独的定义.

有关更多解释,请注意,访问全局变量通常需要在较低级别的代码中进行地址引用.但是你的全局变量是一个整数,其大小通常在地址大小附近,编译器意识到它永远不会改变,那么为什么还要加入指针抽象呢?


Joh*_*itb 19

通过非常迂腐的规则,是的,您的代码需要该静态整数的定义.但是根据实际规则,以及所有编译器实现的内容,因为C++ 03的规则是如何实现的 - 不,你不需要定义.

如果仅在立即读取值的情况下使用整数,并且静态成员可用于常量表达式,则此类静态常量整数的规则旨在允许您省略定义.

在return语句中,会立即读取成员的值,因此您可以省略静态常量整数成员的定义(如果这是它的唯一用途).但是,以下情况需要定义:

struct A {
    static const int a = 5;

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

 };

 int main() {
   int *p = &A::B::b;
 }
Run Code Online (Sandbox Code Playgroud)

这里没有读取任何值 - 而是采用它的地址.因此,C++ 03标准的目的是您必须在某些实现文件中为成员提供如下所示的定义.

const int A::B::b;
Run Code Online (Sandbox Code Playgroud)

需要注意的是实际出现在C++标准03规则说,只有当其中一个常量表达式中使用的变量的定义不需要要求.但是,如果严格适用,该规则过于严格.它只允许你省略像数组维这样的情况的定义 - 但是在返回语句的情况下需要定义.相应的缺陷报告在这里.

C++ 0x的措辞已更新,包括该缺陷报告解析,并允许您的代码编写.