warning: ISO C++ forbids variable length array

匿名 (未验证) 提交于 2019-12-03 10:24:21

问题:

I have a function that takes a pointer to a floating point array. Based on other conditions, I know that pointer is actually pointing to a 2x2 OR 3x3 matrix. (in fact the memory was initially allocated as such, e.g. float M[2][2] ) The important thing is I want to make this determination in the function body, not as the function argument.

void calcMatrix( int face, float * matrixReturnAsArray ) {     // Here, I would much rather work in natural matrix notation     if( is2x2 )     {         // ### cast matrixReturnAsArray to somethingAsMatrix[2][2]         somethingAsMatrix[0][1] = 2.002;         // etc..     }     else if(is3x3)     { //etc...     }  }  float (somethingAsMatrix)[2] = (float ()[2]) matrixReturnAsArray;  

this works fine.

here if i want mention value in subscript as a variable which will change based on some conditions.

If i do this, it showing warning: ISO C++ forbids variable length array. From this how can i dynamically create something?

回答1:

Array in C++ must have a size defined at compile-time.

If you want variable length array, use std::vector instead.

In your case, I would use template for Matrix Size and have different implementation for different matrix size (unless I misunderstood your intentions).

template<int SIZE>      struct Matrix {     std::array<std::array<float, SIZE>,SIZE> m;     std::array<float,SIZE>& operator[](int a) {         if(a>=SIZE) {             throw std::out_of_range("Out of range exception");         }         return m[a];     } };  template<int SIZE> void calcMatrix(Matrix<SIZE>& matrixReturnAsArray );   template<> void calcMatrix<2>(Matrix<2>& matrixReturnAsArray ) {      // Code for 2x2 Matrix     std::cout << "<2>" << std::endl;     std::cout << matrixReturnAsArray[1][1] << std::endl; }  template<> void calcMatrix<3>(Matrix<3>& matrixReturnAsArray ) {      // Code for 3x3 matrix         std::cout << "<3>" << std::endl;         std::cout << matrixReturnAsArray[2][2] << std::endl; }  int main() {    std::array<float,2> a={1,2};    Matrix<2> m2;    m2.m = {a,a};    std::array<float,3> b={1,2,3};    Matrix<3> m3;    m3.m = {b,b,b};    calcMatrix(m3);     calcMatrix(m2); } 

Since I did not defined the generic template, using any other value than 2 or 3 for size will result in an error at compile time.

Edit : Used reference to std::array instead of pointer after @Caleth's suggestion

Edit 2: Added operator [] for easy access and exception for safety



回答2:

You can pass an array by reference.

void calcMatrix(float (&matrix)[2][2])   // Only binds to 2*2 matrix { } void calcMatrix(float (&matrix)[3][3])   // Only binds to 3*3 matrix { }  int main() {    float a[2][2] ={{1,2} , {3,4}};    calcMatrix(a);      float b[3][3] ={{1,2,3} , {4,5,6}, {7,8,9}};    calcMatrix(b);  } 

If you want a function that works for varying sizes you can templatize it:

template<int S> void calcMatrix(float (&matrix)[S][S])   // Only binds to S*S matrix { } 


回答3:

The following shows how to do the casts.

#include <stdio.h>  typedef float t2[2][2]; typedef float t3[3][3];  static void test(int is2, void * p) {     if(is2)     {         t2 *a = (t2 *)p;         (*a)[1][1] = 1.23;     }     else     {         (*((t3*)p))[1][1] = 2.34;     } }  int main() {     printf("Hello World\n");     t2 test2 = {{1,2},{3,4}};     t3 test3 = {{1,2,3},{4,5,6},{7,8,9}};      test(1,(void *)test2);     printf("%g\n",test2[1][1]);      test(0,(void *)test3);     printf("%g\n",test3[1][1]);      return 0; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!