I want to create a 2D array populated with some well-known function without any investment in execution time.
To have an example, suppose that the function f(x, y) = 10 * y + x , let x be in {1, 2, 3} and y in {4, 5, 6} . I want to create a 2D array with content
41 42 43 51 52 53 61 62 63
Now the easiest way is to simply adjust the values โโdirectly in my sources. And it really suits my task, so the question is just out of curiosity.
I would like to create a metafunction and a structure that has some kind of black magic, which allows me to define an array of given sets of values โโfor x and y . Like this:
template<int X> struct Func { template<int Y> struct over { static const int value = 10 * Y + X; // f(x, y) }; }; template<int... args1> struct Rows { template<int... args2> struct Cols { static const int data[sizeof...(args1)][sizeof...(args2)]; }; }; template<int... args1> template<int... args2> const int Rows<args1...>::Cols<args2...>::data[sizeof...(args1)][sizeof...(args2)] = { { Func<args1>::over<args2>::value... } // This does not do what I want :( // Need some black magic here }; // Here is my precious table const auto& table = Rows<1, 2, 3>::Cols<4, 5, 6>::data;
If I print the values โโfrom a table, I have this:
41 52 63 0 0 0 0 0 0
I understand what is happening, the term Func<args1>::over<args2>::value has two parameter packages in it, args1 and args2 , so applying ... on it expands them at the same time, and I have only 3 members instead nine.
If you have reached so far, you already understand what I want. So the question is, how do I do this? How to apply an ellipsis separately to both packages of parameters so that I can have a Cartesian combination in the initializer? Or maybe there are other ways to do this?
I know this answer and which answers . They use std::array instead of a simple array, so they first build 1D arrays and then initialize a 2D array with the number of 1D array. But if I understood correctly, this initialization should be done at runtime. I want to avoid this. However, I have no objection to std::array . I believe that with the right compiler, they are as fast as simple arrays.
By the way, here is my possible solution using a generic constexpr from C ++ 14 and a question about it. Any ideas on how to solve the problem using constexpr from C ++ 11 are also welcome.