可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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; }