下面是一个小脚本,打印数字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
作为常量?
答案 0 :(得分:4)
你基本上有两种选择。
正如您已经提到的,std::array
需要编译时大小。所以在编译时告诉它!这可以通过将其转换为模板参数来完成。
更改
int test(int n)
到
template<int n>
int test()
问题是必须使用test<n>()
而不是test(n)
来调用它,这也需要在编译时知道调用者代码中的n
,这不是for
- 循环的情况。如果您在编译时知道循环的上限(就像在当前的代码片段中一样),那么可以完成它,但它有点复杂。如果不知道,即用户输入,则根本无法使用此解决方案。
所以这不是一个好选择。
不要使用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::array
和std::vector
之间的差距。然而,几乎在所有情况下std::vector
都会做得很好!
答案 1 :(得分:1)
您可以改为使用vector;
#include <vector>
vector<int> myArray (n); // n zero-initialized elements
像使用数组一样使用operator[]。