Sizeof()函数不能在常量数组C ++上工作

时间:2015-08-06 15:49:35

标签: c++ arrays const sizeof

在开始之前,我正在使用VS2015 C ++语言编译程序。当我尝试确定两个常量数组的大小时,问题是编译错误。涉及该问题的班级:

标题文件:

#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 []操作数sizeof无效。

     

不允许使用不完整的类型。

     

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

     

不允许使用不完整的类型。

我可以使用extern来解决问题吗?如果是这样,我应该如何使用它?

3 个答案:

答案 0 :(得分:3)

问题是你已经声明数组,但是在你调用sizeof运算符的时候你还没有定义

此外,您不能只将您的定义移动到标题,因为只能以这种方式定义整数类型:

  

如果非易失性const静态数据成员是整数类型或枚举类型,则其在类定义中的声明可以指定一个大括号或大小为初始化器,其中作为赋值表达式的每个initializer子句都是一个常量表达。可以使用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在评论中建议的内容,并使用vector。初始化和查看大小的运行时成本非常小,但这并不重要。

答案 1 :(得分:1)

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

  

除非另有说明,否则如果省略常量表达式,则表示类型   D的标识符是“T的未知边界的derived-declarator-type-list数组”,不完整的对象类型

和[expr.sizeof]:

  

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

没有常量表达式大小的数组的例外是当您提供初始值设定项(例如int a[] = {1, 2})或者先前使用大小声明数组时。因此,在这种情况下,您可以提供标题的大小或初始化程序:

static const int PILOT_POINTS[10];    
static const int PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };

或者只是使用vector,因此您可以在源代码中初始化它,并获得vector优于原始C数组的所有其他优点:

static const std::vector<int> PILOT_POINTS;

答案 2 :(得分:1)

其他答案已经解决了您需要定义数组的事实。为了完整起见,我想提一下你获取数组大小的方法是“the C version”。 C ++有更好的方式std::extent

#include <iostream>
#include <type_traits>

struct Race
{
    static const int PILOT_POINTS[];
    static const double TEAM_AWARDS[];
};

const int Race::PILOT_POINTS[] = { 25, 18, 15, 12, 10, 8, 6, 4, 2, 1 };
const double Race::TEAM_AWARDS[] = { 100000, 75000, 50000, 25000, 15000, 10000 };

int main()
{
    ::std::wcout << ( sizeof( Race::PILOT_POINTS ) / sizeof( Race::PILOT_POINTS[ 0 ] ) ) << L' '
        << ( sizeof( Race::TEAM_AWARDS ) / sizeof( Race::TEAM_AWARDS[ 0 ] ) ) << L'\n'
        << std::extent< decltype( Race::PILOT_POINTS ) >::value << L' '
        << std::extent< decltype( Race::TEAM_AWARDS ) >::value;
    return 0;
}