0

当出现许多问题时,我正在研究具有非类型参数的模板函数(以避免动态分配数组)。我的第一个问题是关于编译时变量赋值。这源于以下对模板函数的调用尝试:

template<int n>
int *getDegrees(int A[][n]) {
  //return degrees
}

int main(int argc, char **argv) {
  int n = 10;
  int A[n][n];
  int *degs = getDegrees<n>(A);
}

在这里,我们有两个错误:首先,编译器无法解析对 的调用getDegrees(A)

main.cc:27: error: no matching function for call to ‘getDegrees(int [(((long unsigned int)(((long int)n) + -0x00000000000000001)) + 1)][(((long unsigned int)(((long int)n) + -0x00000000000000001)) + 1)])’

其次,我们无法n在模板调用中使用,因为它不是常量表达式。简单地n保持不变确实可以解决问题

const int n = 10;

但是,如果我要这样做

int m = 10;
const int n = m; 

我们得到同样的错误。虽然编译器可能允许第二次赋值,但这样做是否被认为是不好的形式?此外,为什么让n常量在解决函数调用时会有所不同?

我的另一个问题是关于 vlas:是在堆栈还是堆上为它们分配了内存(并且这个编译器依赖于)?甚至在 C++ 中允许它们似乎也存在一些争议,是否应该避免它们以支持向量(或类似容器)?

欣赏任何见解!

4

1 回答 1

5

我会尽量回答我能从你的问题中得到的任何信息。
您可以更改函数原型以通过引用接收数组:

template<size_t n> // see the type
int *getDegrees(int (&A)[n][n]) {  // see the signature
  // ...
}

在上面的代码中,我们利用了数组具有相同维度的事实。
但是,一般情况下应该是:

template<size_t n1, size_t n2> // see the type
int *getDegrees(int (&A)[n1][n2]) {  // see the signature
  // ...
}

如果大小太大,则编译器会发出错误通知您。例如(来自 g++):

错误:数组“A”的大小太大

现在来到另一个关于常量整数赋值的区别的问题。
在 C++ 中,数组大小必须是编译时间常数,并且

const int n = 10;

满足这个要求。因为编译器可以看出,10 是分配给的文字数字n

的情况下,

int m = 10;
const int n = m;

编译器发现的来源n不是编译时间常数本身。因此它使代码格式不正确。

于 2013-07-15T18:40:02.120 回答