我要运行以下代码:
struct A {
static const string d[] = {"1", "2"};
};
并得到一个错误:
error: in-class initialization of static data member ‘const string A::d []’ of incomplete type
static const string d[] = {"1", "2"};
^
error: non-constant in-class initialization invalid for non-inline static member ‘A::d’
static const string d[] = {"1", "2"};
^
note: (an out of class initialization is required)
Here我发现了一些信息,现在我可以初始化自己想要的了。那是什么问题呢?
如果我添加inline
,它将起作用:
struct A {
static const inline string d[] = {"1", "2"};
};
UPD:我知道解决方法,但是为什么c ++会那样工作?
答案 0 :(得分:1)
您注意到您可以使用inline
或以下命令:
struct A {
static const string d[];
};
和
const string A::d[] = {"1", "2"};
在专用的编译单元中(仅一次)。
答案 1 :(得分:1)
该标准明确指出,类的非内联静态数据成员仅是声明,并且必须在名称空间范围内进行后续定义:class.static.data#3
3: 非内联静态数据成员的类定义中的声明不是定义,并且可以是cv void以外的不完整类型。在类定义中未内联定义的静态数据成员的定义应出现在包含该成员的类定义的名称空间范围中。在名称空间范围的定义中,静态数据成员的名称应使用``::''运算符通过其类名称进行限定。静态数据成员的定义中的初始化器表达式在其类([basic.scope.class])的范围内。
然后进一步完善这些规则,以便可以初始化整数或枚举类型的非易失性非内联const静态数据成员(实际上是在声明时定义变量):class.static.data#4 >
4:如果非易失性非内联const静态数据成员为整数或枚举类型,则其在类定义中的声明可以指定大括号或相等初始化器,其中每个作为赋值的初始化器子句-expression是一个常数表达式([expr.const])。如果在程序中对成员进行了odr-used([basic.def.odr]),则该成员仍应在命名空间范围中定义,并且命名空间范围定义不应包含初始化程序。内联静态数据成员可以在类定义中定义,并且可以指定大括号或等于初始化器。
用非标准语言来说,这意味着您必须与定义分开定义静态成员变量,但整数或枚举除外,这说明了示例为何失败。