C++:在函数内部声明数组时,表达式必须具有常量值

vas*_*cur 0 c++ arrays pointers const

我查看了所有其他类似主题的帖子,没有任何帮助,所以请不要标记为重复.

我正在定义main()一个const int SIZE = 20;.然后,我将此作为参数传递给我的函数Mode:

int* Mode(int* numbers, int & mode, const int SIZE)
 {
     int occurences[SIZE];

     // Calcualte mode
 }
Run Code Online (Sandbox Code Playgroud)

但是,我得到了错误expression must have a constant value.

我的函数调用(在main中)看起来像这样:

int* occurencesPtr = Mode(numbersPtr, mode, SIZE);
Run Code Online (Sandbox Code Playgroud)

有了SIZE开头的文字被定义20.

我理解错误是因为函数的版本SIZE仅在调用函数时获取其值(?),但我不知道如何解决这个问题.

我甚至尝试过传递给函数a const int * const SIZEPtr = &SIZE,但这也没有用.救命?

编辑:我不是想使用可变大小!! 请注意,我做了SIZE一个const无处不在!我只想使用相同的SIZE常量来声明我的数组.

编辑:动态数组不是我需要的.我只想要一个普通的,命名的数组,用传递给函数的常量大小值定义.

Bar*_*rry 6

这里有一种误解const,可能是因为这有点令人困惑:

const int SIZE = 20;
int array[SIZE];
Run Code Online (Sandbox Code Playgroud)

但这不是:

void foo(const int SIZE) {
    int array[SIZE];
    // ...
}

const int SIZE = 20;
foo(SIZE);
Run Code Online (Sandbox Code Playgroud)

问题是数组声明中的数组大小必须是核心常量表达式.简化,这意味着在编译时可评估的表达式是常量.在第一种情况是真实的(你可以看到,SIZE是积分常数20),但是这是不是真的在第二种情况下.在那里,SIZE函数参数只是const- 在某种意义上它是不可修改的 - 而不是核心常量表达式.您可以看到区别在于我可以foo()使用在运行时之前明显不可知的内容调用:

int x;
if (std::cin >> x) {
    foo(x);
}
Run Code Online (Sandbox Code Playgroud)

为了传递参数进入foo,并有这样的说法可以作为约束阵列,这是不够的,它是const-实际积分值必须被编码成式(除非你打电话foo()constexpr这我假设是不这里的情况).在这种情况下,您必须执行以下操作:

template <int SIZE>
void foo() { ... }

const int SIZE = 20;
foo<SIZE>();
Run Code Online (Sandbox Code Playgroud)

要么:

template <int SIZE>
void foo(std::integral_constant<int, SIZE > ) { ... }

const int SIZE = 20;
foo(std::integral_constant<int, SIZE>{} );
Run Code Online (Sandbox Code Playgroud)

或者只是SIZE一个全局常量,或者以foo()一种与其参数无关的方式访问.


或者,总有一个简单的选择:使用std::vector:

void foo(const int SIZE) {
    std::vector<int> v(SIZE);
    ...
}
Run Code Online (Sandbox Code Playgroud)


R S*_*ahu 5

我知道该错误是因为函数的 SIZE 版本仅在调用函数时才获取其值 (?),但我不知道如何解决此问题。

选项1

添加一个函数,而不是定义SIZEin 。使用函数而不是传递大小。mainconstexprconstexpr

constexpr int getSize()
{
   return 20;
}

int* Mode(int* numbers, int & mode)
{
   int occurences[getSize()];

   // ...

}
Run Code Online (Sandbox Code Playgroud)

选项 2

使用std::vector代替数组。

int* Mode(int* numbers, int & mode, int size)
{
   std::vector<int> occurences[size];

   // ...

}
Run Code Online (Sandbox Code Playgroud)

选项 3

使用函数模板。

template <size_t SIZE>
int* Mode(int* numbers, int & mode, int size)
{
   int occurences[SIZE];

   // ...

}
Run Code Online (Sandbox Code Playgroud)

选项 4

使用函数模板和std::array.

template <size_t SIZE>
int* Mode(int* numbers, int & mode, int size)
{
   std::array<int, SIZE> occurences;

   // ...

}
Run Code Online (Sandbox Code Playgroud)