1

I have an N-dimensional Matrix class that has a constructor with a parameter pack. Is it possible to set the size of the std::array member variable depending on the values in the parameter pack? As far as I understand the values in the parameter pack should be known at compile time.

template<size_t N>
class Matrix {
public:
    template<typename... Exts>
    Matrix(Exts... exts) : dimSizes{exts...} { }

private:
    std::array<size_t, N> dimSizes;
    std::array<float, N> data;
    // e.g something like this: std::array<float, dimSizes[0]> data;
};

int main(void) {
    Matrix<3> mat(2, 3, 2);
    return 0;
}
max66
  • 65,235
  • 10
  • 71
  • 111
SPA
  • 77
  • 1
  • 4
  • Can't you use the initialisation list of the constructor? – Jesper Juhl Nov 25 '18 at 18:11
  • Sort of in c++17, no (mostly) before. Unless I warp your question. – Yakk - Adam Nevraumont Nov 25 '18 at 18:13
  • 3
    You can't have `sizeof(Matrx<3>)` magically vary depending on how an instance was constructed. – Igor Tandetnik Nov 25 '18 at 18:14
  • @JesperJuhl I don't think so. I have to specify the size of the `std::array` via a template argument. So I have to specify the size as soon as I declare it. – SPA Nov 25 '18 at 18:15
  • @SPA what stops you from using `std::vector(dimSizes[0])` ? – Piotr Skotnicki Nov 25 '18 at 18:23
  • @PiotrSkotnicki main reason is that `std::array` should be more efficient + I want to prevent that `Matrix::data` can change in size. – SPA Nov 25 '18 at 18:27
  • @SPA then you will probably have to use `Matrix<3, 2> mat(3, 2);` instead – Piotr Skotnicki Nov 25 '18 at 18:30
  • @SPA - If the `vector` is a private member, only your class or a `friend` will be able to change it. Both cases should be under your control when defining the class. And, unless you've measured or memory is VERY tight on your target system, your claim of "efficiency" is spurious. – Peter Nov 25 '18 at 18:35

1 Answers1

1

Is it possible to set the size of the std::array member variable depending on the values in the parameter pack?

// e.g something like this: std::array<float, dimSizes[0]> data;

No, as far I know is impossible exactly as you want.

Because, this way, different instances of the same class would contain members with same name but different types. Strictly forbidden in a strongly typed language as C++.

If you want a std::array with different size, you have to differentiate the types; so the dimension for the second std::array has to be a template parameter.

Obviously you can substitute the std::array with a container that doesn't depend from the size; as suggested by Piotr Skotnicki a possible solution is std::vector

Community
  • 1
  • 1
max66
  • 65,235
  • 10
  • 71
  • 111
  • 2
    _"Because, this way, different instances of the same class would contain members with same name but different types."_ Good argument. I completly missed that. – SPA Nov 25 '18 at 18:39