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

时间:2014-07-20 13:28:05

标签: c++ arrays class instantiation dynamic-arrays

下面是一个小脚本,打印数字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;
}

当然,这不会编译:

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

问题似乎是(除其他事项外)n不是一个常量表达式,我明白为什么这是一个问题,但我不知道如何解决它。

我知道如何使用new函数实例化“常规”数组,但我不明白数组类是如何实现的。

如何将test功能视为n作为常量?

2 个答案:

答案 0 :(得分:4)

你基本上有两种选择。

  1. 正如您已经提到的,std::array需要编译时大小。所以在编译时告诉它!这可以通过将其转换为模板参数来完成。

    更改

    int test(int n)
    

    template<int n>
    int test()
    

    问题是必须使用test<n>()而不是test(n)来调用它,这也需要在编译时知道调用者代码中的n,这不是for - 循环的情况。如果您在编译时知道循环的上限(就像在当前的代码片段中一样),那么可以完成它,但它有点复杂。如果不知道,即用户输入,则根本无法使用此解决方案。

    所以这不是一个好选择。

  2. 不要使用std::array,而是在编译时但在运行时期间不需要大小的容器类型。正如您所提到的,堆分配的原始数组(new int[n])是一个选项,但它不是非常C ++ - ish。 使用std::vector代替

    为此,只需更改

    即可
    array<int,n> myArray;
    

    vector<int> myArray(n);
    

    PS。在将来,可能std::dynarray (proposed container type)恰好与std::vector目前相比,恰好适合这个目的。它反映了new int[n]在运行时已知n但在数组生命周期内保持不变的目的,填补了std::arraystd::vector之间的差距。然而,几乎在所有情况下std::vector都会做得很好!

答案 1 :(得分:1)

您可以改为使用vector;

#include <vector>

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

像使用数组一样使用operator[]