C++ 我可以初始化静态常量类成员吗?

C++ 我可以初始化静态常量类成员吗?,c++,static,initialization,c++17,inline,C++,Static,Initialization,C++17,Inline,我想运行以下代码: 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&

我想运行以下代码:

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)
我发现信息,现在我可以初始化我想要的。那么问题出在哪里呢

如果我添加
inline
,那么它将工作:

struct A {
    static const inline string d[] = {"1", "2"};    
};

UPD:我知道解决方法,但为什么C++会这样工作?

< P>正如你注意到的,你可以使用<代码>内联< /C> >或以下:

struct A {
    static const string d[];    
};

在专用编译单元中(仅一次)


正如您所注意到的,您可以使用
内联
或以下选项:

struct A {
    static const string d[];    
};

在专用编译单元中(仅一次)


该标准明确规定,类的非内联静态数据成员仅为声明,必须在名称空间范围内进行定义:

3: 非内联静态数据成员在其类定义中的声明不是定义,可能是cv void以外的不完整类型。未在类定义中内联定义的静态数据成员的定义应出现在包含该成员的类定义的命名空间范围中。在命名空间范围的定义中,静态数据成员的名称应使用​::​操作人员静态数据成员定义中的初始值设定项表达式位于其类的作用域([basic.scope.class])

然后进一步细化这些规则,以便可以初始化整型或枚举类型的非易失性非内联常量静态数据成员(实际上是在声明点定义变量):

4:如果非易失性非内联常量静态数据成员是整数或枚举类型,则其在类定义中的声明可以指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式([expr.const])。如果程序中使用odr([basic.def.odr]),则仍应在名称空间范围中定义该成员,并且名称空间范围定义不应包含初始值设定项。内联静态数据成员可以在类定义中定义,并可以指定大括号或相等的初始值设定项


在非标准语言中,这表示您必须与定义分开定义静态成员变量,整数或枚举除外,这解释了示例失败的原因。

标准明确规定类的非内联静态数据成员仅为声明,并且必须在名称空间范围中的定义之后:

3: 非内联静态数据成员在其类定义中的声明不是定义,可能是cv void以外的不完整类型。未在类定义中内联定义的静态数据成员的定义应出现在包含该成员的类定义的命名空间范围中。在命名空间范围的定义中,静态数据成员的名称应使用​::​操作人员静态数据成员定义中的初始值设定项表达式位于其类的作用域([basic.scope.class])

然后进一步细化这些规则,以便可以初始化整型或枚举类型的非易失性非内联常量静态数据成员(实际上是在声明点定义变量):

4:如果非易失性非内联常量静态数据成员是整数或枚举类型,则其在类定义中的声明可以指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式([expr.const])。如果程序中使用odr([basic.def.odr]),则仍应在名称空间范围中定义该成员,并且名称空间范围定义不应包含初始值设定项。内联静态数据成员可以在类定义中定义,并可以指定大括号或相等的初始值设定项


在非标准语言中,这意味着您必须与定义分开定义静态成员变量,整数或枚举除外,这解释了您的示例失败的原因。

您找到的信息肯定并不意味着您可以不使用
inline
。公认的答案非常清楚地表明整数是一种特殊情况。即使它被允许,显然这个编译器说你不能这样做,并且最终编译器总是正确的。C++11没有内联变量。这是C++17您找到的信息肯定并不意味着您可以不使用
内联
来完成它。公认的答案非常清楚地表明整数是一种特殊情况。即使它被允许,显然这个编译器说你不能这样做,并且最终编译器总是正确的。C++11没有内联变量。这是C++17@dasfex因为它在C++标准中定义了。原因可能是强制一个定义规则(ODR)。但是如果在中间使用变量,则它不适用于<代码>内联<代码>。@ dasfx,因为它定义为C++标准中的。原因可能是强制一个定义规则(ODR)。但是如果在中间使用变量,则它不适用于<代码>内联< /代码>。