gli*_*nka 0 c++ templates const variable-length-array
当出现一些问题时,我正在研究一个带有非类型参数的模板函数(以避免数组的动态分配).我的第一个问题是编译时变量赋值.这是因为以下尝试调用模板函数:
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);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们有两个错误:第一,编译器无法解析对以下内容的调用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)])’
Run Code Online (Sandbox Code Playgroud)
其次,我们无法n
在模板调用中使用,因为它不是常量表达式.简单地n
保持不变可以解决问题
const int n = 10;
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做的话
int m = 10;
const int n = m;
Run Code Online (Sandbox Code Playgroud)
我们得到了同样的错误.虽然编译器可能允许第二个赋值,但它是否被认为是不好的形式?另外,为什么n
在解决函数调用时不断有所作为呢?
我的另一个问题是关于vlas:在堆栈或堆上为它们分配的内存(并且这是依赖于编译器的)?即使在C++中允许它们似乎也存在争议,是否应该避免使用向量(或类似的容器)?
欣赏任何见解!
我会尽力回答你从问题中得到的任何问题.
您可以通过引用更改函数原型以接收数组:
template<size_t n> // see the type
int *getDegrees(int (&A)[n][n]) { // see the signature
// ...
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们正在利用数组具有相同维度的事实.
但是,一般情况下应该是:
template<size_t n1, size_t n2> // see the type
int *getDegrees(int (&A)[n1][n2]) { // see the signature
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果大小太大,编译器会发出错误通知您.例如(来自g ++):
错误:数组'A'的大小太大
现在讨论关于常数整数赋值之间差异的另一个问题.
在C++中,数组大小必须是编译时间常量和
const int n = 10;
Run Code Online (Sandbox Code Playgroud)
满足这个要求.因为编译器可以知道,10是分配给的文字编号n
.
的情况下,
int m = 10;
const int n = m;
Run Code Online (Sandbox Code Playgroud)
编译器发现该源n
是不是一个编译时间常数本身.因此它使代码生成错误.