简体   繁体   English

编译时大小未知的数组类的实例化

[英]Instantiation of array class of size unknown at compile time

Below is a small script that prints the sums of the numbers 1 to n, for n = 1,...,20.下面是一个小脚本,用于打印数字 1 到 n 的总和,因为 n = 1,...,20。

#include <iostream>
#include <array>

using namespace std;

int test(int n)
{
    array<int,n> myArray;

    for (int iii = 0; iii < n; iii++)
        myArray[iii] = iii+1;

    int nSum;

    for (int iii = 0; iii < n; iii++)
        nSum += myArray[iii];

    return nSum;
}


int main()
{
    for (int n = 1; n <= 20; n++)
        cout << test(n) << endl;

    return 0;
}

Of course, this won't compile:当然,这不会编译:

Main.cpp: In function ‘int test(long unsigned int)’:
Main.cpp:9:13: error: ‘n’ is not a constant expression
  array<int,n> myArray;
         ^
Main.cpp:9:13: note: in template argument for type ‘long unsigned int’ 
Main.cpp:9:22: error: invalid type in declaration before ‘;’ token
  array<int,n> myArray;
                  ^
Main.cpp:11:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int iii = 0; iii < n; iii++)
                      ^
Main.cpp:12:14: error: invalid types ‘int[int]’ for array subscript
   myArray[iii] = iii+1;
          ^
Main.cpp:16:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int iii = 0; iii < n; iii++)
                      ^
Main.cpp:17:22: error: invalid types ‘int[int]’ for array subscript
   nSum += myArray[iii];
                  ^
make: *** [Main.o] Error 1

The problem seems to be (among other things) that n isn't a constant expression, and I get why that is a problem, but I have no idea how to solve it.问题似乎是(除其他外) n不是一个常量表达式,我明白为什么这是一个问题,但我不知道如何解决它。

I know how to instantiate "regular" arrays with the new function, but I don't understand how it is possible with the array class.我知道如何使用新函数实例化“常规”数组,但我不明白如何使用数组类。

How do I make the test function treat n as a constant?如何让test函数将n视为常量?

You have basically two options.您基本上有两种选择。

  1. As you already mentioned, std::array needs a compile-time size.正如您已经提到的, std::array需要一个编译时大小。 So make it known at compile-time!所以在编译时让它知道! This can be done by converting it to a template parameter .这可以通过将其转换为模板参数来完成。

    Change改变

    int test(int n) { . . . }

    to

    template<int n> int test() { . . . }

    The problem is that it then has to be called with test<n>() instead of test(n) and this again requires the n in the caller code to be known at compile-time, too, which is not the case with a for -loop.问题是它然后必须用test<n>()而不是test(n)来调用,这又要求调用者代码中的n在编译时也是已知的,这不是for循环。 If you know your loop's upper bound during compile-time (like in your current code snippet), it can be done, but it's a bit complicated.如果您在编译时知道循环的上限(例如在您当前的代码片段中),则可以完成,但有点复杂。 And if it's not known, ie a user input, you can't use this solution at all.如果它是未知的,即用户输入,则根本无法使用此解决方案。

    So this is not a good option here.所以这在这里不是一个好的选择。

  2. Don't use std::array but a container type which doesn't require the size at compile-time but during runtime .不要使用std::array而是一种容器类型,它在编译时不需要大小,但在运行时 A heap-allocated raw array ( new int[n] ), as you mentioned, is an option, but it's not very C++-ish.正如您所提到的,堆分配的原始数组( new int[n] )是一种选择,但它不是很 C++-ish。 Use std::vector instead !改用std::vector

    For this, simply change为此,只需更改

    array<int,n> myArray;

    to

    vector<int> myArray(n);

    PS.附注。 In the future, there probably will be std::dynarray (proposed container type) which fits exactly that purpose a bit better than std::vector currently does.将来,可能会出现std::dynarray (提议的容器类型) ,它比目前的std::vector更适合该目的。 It's reflecting the purpose of new int[n] where n is known at runtime but constant during the lifetime of the array, filling the gap between std::array and std::vector .它反映了new int[n]的目的,其中n在运行时已知,但在数组的生命周期内保持不变,填补了std::arraystd::vector之间的空白。 Yet in almost all cases std::vector will do just fine!然而在几乎所有情况下std::vector都可以正常工作!

You can use a vector instead;您可以改用向量

#include <vector>

vector<int> myArray (n); // n zero-initialized elements

use the operator[] like you are using the array.像使用数组一样使用运算符 []

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM