I have a template class which does some computation and returns multi_array, a bit oversimplified like this:
template <typename T>
class C
{
public:
typedef boost::multi_array<T, 2> result_type;
void do_something(T const& data, unsigned i, unsigned j); // add result to R[i][j]
result_type R;
};
Instantiating the class with a simple type T=double
works fine. Now, I want to instantiate with "T=boost::multi_array<double, 1>
", but such that the result type is boost::multi_array<double, 3>
.
The definition multi_array<multi_array<T, N>, M>>
does clearly not result in multi_array<T, N+M>
, it is just a N-dimensional multi_array with elements being M-dimensional multi_arrays ...
The idea to generate such a type is motivated by the Boost manual saying
MultiArray is recursively defined; the containers at each level of the container hierarchy model MultiArray as well. Actually, it turns out that the "elements" of the intermediate
multi_array
levels are of typesubarray
.
Can one use subarray
to generate a multi_array
type with an effective dimensionality N+M
? Maybe somehow along the following lines:
typedef typename boost::multi_array<double, 3>::subarray<1>::type value_type;
boost::multi_array<value_type, 2> a;
I'm looking for a relatively clean solution (not a lengthy hack), if this is not possible with the multi_array interface I will better rethink the design of what I'm going to implement.
I think it makes no sense to instantiate multi_array
with elements of type multi_array
(although it might compile). For example, it would not lead to a contiguous memory layout since the elements manage memory themselves.
To solve the problem that motivated my question, I came up with the following solution:
template <typename T>
class C
{
enum { extra_rank = get_rank<T>() };
public:
typedef boost::multi_array<T, 2 + extra_rank> result_type;
}
The class defines a multi_array
with extra dimensions depending on the type of T
. The helper function get_rank
checks whether T
is multi_array
and returns its dimensionality
, otherwise it returns 0.