Sizeof()函数不适用于常量数组C++; 开始之前,我用VS2015 C++语言编写程序。当我试图确定两个常量数组的大小时,问题是编译错误。涉及该问题的类别:

Sizeof()函数不适用于常量数组C++; 开始之前,我用VS2015 C++语言编写程序。当我试图确定两个常量数组的大小时,问题是编译错误。涉及该问题的类别:,c++,arrays,constants,sizeof,C++,Arrays,Constants,Sizeof,头文件: #ifndef RACE_H_ #define RACE_H_ class Race { private: static const int PILOT_POINTS[]; static const double TEAM_AWARDS[]; } #endif 源文件: #include "Race.h" const int PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 }; cons

头文件:

#ifndef RACE_H_
#define RACE_H_
class Race
{
    private:
        static const int PILOT_POINTS[];
        static const double TEAM_AWARDS[];
}
#endif
源文件:

#include "Race.h"
const int PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
const double TEAM_AWARDS[] = { 100000, 75000, 50000, 25000, 15000, 10000 };
部分错误:

sizeof(TEAM_AWARDS) / sizeof(TEAM_AWARDS[0]))
sizeof(PILOT_POINTS) / sizeof(PILOT_POINTS[0]))
编者说:

错误2070 const int[]操作数大小无效

不允许使用不完整的类型

错误2070 const double[]操作数sizeof无效

不允许使用不完整的类型


我能用extern解决这个问题吗?如果是,我应该如何使用它?

您只需要在声明中提供大小。从[dcl.array]:

除非如下所述,否则如果省略常量表达式,则 D的标识符是“T的未知边界的派生声明器类型列表数组”,这是一种不完整的对象类型

和[expr.sizeof]:

sizeof
运算符不得应用于具有函数或不完整类型[…]的表达式

没有常量表达式大小的数组的例外情况是,当您提供初始值设定项(例如,
inta[]={1,2}
)时,或者当数组之前声明了大小时。因此,在本例中,您可以提供标题的大小或初始值设定项:

static const int PILOT_POINTS[10];    
static const int PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
或者只需使用
向量
,就可以在源代码中对其进行初始化,并获得
向量
相对于原始C数组的所有其他优点:

static const std::vector<int> PILOT_POINTS;
静态常数std::向量导频点;

您只需在声明中提供大小即可。从[dcl.array]:

除非如下所述,否则如果省略常量表达式,则 D的标识符是“T的未知边界的派生声明器类型列表数组”,这是一种不完整的对象类型

和[expr.sizeof]:

sizeof
运算符不得应用于具有函数或不完整类型[…]的表达式

没有常量表达式大小的数组的例外情况是,当您提供初始值设定项(例如,
inta[]={1,2}
)时,或者当数组之前声明了大小时。因此,在本例中,您可以提供标题的大小或初始值设定项:

static const int PILOT_POINTS[10];    
static const int PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
或者只需使用
向量
,就可以在源代码中对其进行初始化,并获得
向量
相对于原始C数组的所有其他优点:

static const std::vector<int> PILOT_POINTS;
静态常数std::向量导频点;

问题在于您已经声明了数组,但在调用
sizeof
操作符时尚未定义它们

此外,您不能将定义移到标题,因为只有整数类型可以这样定义:

如果非易失性const静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式。可以使用constexpr说明符在类定义中声明文本类型的静态数据成员;如果是这样,其声明应指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式。。。(§9.4.2/3)

C样式的可变长度数组不是整数,因为它们的长度在定义之前是未知的

要解决此问题,需要在数组中使用长度说明符:

#ifndef RACE_H_
#define RACE_H_
class Race
{
    private:
        static const int PILOT_POINTS[10];
        static const double TEAM_AWARDS[6];
}
#endif
这是额外的麻烦,因为现在如果数组改变大小,您必须更改长度,但这是必要的

或者,您可以使用
constexpr
,将整个定义放在标题中。这样,就可以省略数组长度

#ifndef RACE_H_
#define RACE_H_
class Race
{
    private:
        static constexpr int PILOT_POINTS[]
                = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
        static constexpr double TEAM_AWARDS[]
                = { 100000, 75000, 50000, 25000, 15000, 10000 };
}
#endif

此外,您可以尝试@CoryKramer在注释中的建议,并使用
向量
。初始化数组和查找大小的运行时开销很小,但这并不重要。

问题是您已经声明了数组,但在调用
sizeof
操作符时还没有定义它们

此外,您不能将定义移到标题,因为只有整数类型可以这样定义:

如果非易失性const静态数据成员是整型或枚举类型,则其在类定义中的声明可以指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式。可以使用constexpr说明符在类定义中声明文本类型的静态数据成员;如果是这样,其声明应指定一个大括号或相等的初始值设定项,其中作为赋值表达式的每个初始值设定项子句都是常量表达式。。。(§9.4.2/3)

C样式的可变长度数组不是整数,因为它们的长度在定义之前是未知的

要解决此问题,需要在数组中使用长度说明符:

#ifndef RACE_H_
#define RACE_H_
class Race
{
    private:
        static const int PILOT_POINTS[10];
        static const double TEAM_AWARDS[6];
}
#endif
这是额外的麻烦,因为现在如果数组改变大小,您必须更改长度,但这是必要的

或者,您可以使用
constexpr
,将整个定义放在标题中。这样,就可以省略数组长度

#ifndef RACE_H_
#define RACE_H_
class Race
{
    private:
        static constexpr int PILOT_POINTS[]
                = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
        static constexpr double TEAM_AWARDS[]
                = { 100000, 75000, 50000, 25000, 15000, 10000 };
}
#endif

此外,您可以尝试@CoryKramer在注释中的建议,并使用
向量
。初始化它和查找大小的运行时开销很小,但这并不重要。

其他答案解决了需要定义数组的问题。为了完整性起见,我要提到获取数组大小的方法是“”。C++有更好的方法:

#包括
#包括
结构竞赛
{
静态常数int PILOT_点[];
静态常数双团队奖[];
};
const int Race::PILOT_POINTS[]={25,18,15,12,10,8,6,4,2,1};
康斯特双人赛:团队奖[]={100000、75000、50000、25000、15000、10000};
int main()
{
::圣