-1

Please find my code snippet below:

std::vector<int> idx1;
std::vector<int> idx2;
framx[0].get_idx_of(atm1,idx1);
framx[0].get_idx_of(atm2,idx2);
std::vector<bool> iniz;
const int sz1=idx1.size();
const int sz2=idx2.size();
array<array<array<double,7>,sz2>,sz1> lnmat;

An please find the error during compiling with both C++ and clang++.

analysis.cpp:408:33: error: the value of ‘sz2’ is not usable in a constant expression
     array<array<array<double,7>,sz2>,sz1> lnmat;
                                 ^~~
analysis.cpp:407:15: note: ‘sz2’ was not initialized with a constant expression
     const int sz2=idx2.size();
               ^~~
analysis.cpp:408:36: error: the value of ‘sz2’ is not usable in a constant expression
     array<array<array<double,7>,sz2>,sz1> lnmat;
                                    ^
analysis.cpp:407:15: note: ‘sz2’ was not initialized with a constant expression
     const int sz2=idx2.size();
               ^~~
analysis.cpp:408:36: note: in template argument for type ‘long unsigned int’ 
     array<array<array<double,7>,sz2>,sz1> lnmat;
                                    ^
analysis.cpp:408:38: error: the value of ‘sz1’ is not usable in a constant expression
     array<array<array<double,7>,sz2>,sz1> lnmat;
                                      ^~~
analysis.cpp:406:15: note: ‘sz1’ was not initialized with a constant expression
     const int sz1=idx1.size();
               ^~~
analysis.cpp:408:41: error: template argument 1 is invalid
     array<array<array<double,7>,sz2>,sz1> lnmat;
                                         ^
analysis.cpp:408:41: error: the value of ‘sz1’ is not usable in a constant expression
analysis.cpp:406:15: note: ‘sz1’ was not initialized with a constant expression
     const int sz1=idx1.size();
               ^~~
analysis.cpp:408:41: note: in template argument for type ‘long unsigned int’ 
     array<array<array<double,7>,sz2>,sz1> lnmat;

Can you please let me know the reasong for this error in assignment of the variable lnmat? It seems that proably the array declaration is not identifying the constant or there is some problem with its declaration.

P.S.: Please do not refer me answer to this question.

  • 2
    Can you explain why you don't think the linked question is relevant? Do you understand why the size of your vector is not generally available at compile-time? – Useless Mar 13 '18 at 13:49
  • 1
    Template arguments must be known at compile time. `const` doesn't guarantee that, as is your case for `sz1` and `sz2`. `const` only mean that the object is immutable. In C++11, there is `constexpr` to define a compile-time constant. However, you still cannot assign a runtime value to it. – Daniel Langr Mar 13 '18 at 13:49

1 Answers1

0

std::array second template parameter must be known at compile time.

You are using constants that are only known at run-time, namely:

const int sz1=idx1.size();
const int sz2=idx2.size();

So std::array<array<array<double,7>,sz2>,sz1> lnmat; is invalid.

Unless you know at compile time what are the values of sz1 and sz2 (before running the program) you can't use std::array.

You may want to use std::vector instead. Like std::vector<std::vector<std::array<double,7>>> lnmat; but be aware that vectors are empty at initialization unlike std::array.

Also as @NathanOliver mentioned, using vectors of vectors for multidimensional arrays may not be very efficient (because cache locality), if your code is performance sensitive consider using a single std::vector that can be used as a multidimensional array, more details here.

RandomGuy
  • 648
  • 6
  • 21
  • Can you kindly let me know how to proceed in such case? Shall I go for vector instead? – Mitradip Das Mar 13 '18 at 13:50
  • Yes, use `std::vector`. Note that for higher efficiency (and better memory usage), use might want to define a plain 1-D `std::vector lnmat(sz1*sz2*7);` and use it as a 3-D array then. – Daniel Langr Mar 13 '18 at 13:54
  • @MitradipDas Unless you know at compile time what are the values of sz1 and sz2 (before running the program) you can't use std::array. Use std::vector instead. Like std::vector>> lnmat; – RandomGuy Mar 13 '18 at 13:54
  • @RandomGuy Don't suggest using nested vectors. They have no guaranteed locality between the nested vectors data. Abstracting the 2d structure in a flat vector is the preferred method. – NathanOliver Mar 13 '18 at 14:02
  • Thanks @NathanOliver, I have added your alternative to the answer. – RandomGuy Mar 13 '18 at 14:19