我变了
MultiArray
How to allocate & access 3D, 4D, 5D arrays?
有一些静态大小
std::array
template <typename T, std::size_t Dim>
class MultiArray
{
public:
explicit MultiArray(const std::array<std::size_t, Dim>& dimensions) :
dimensions(dimensions),
values(computeTotalSize(dimensions))
{
assert(!values.empty());
}
const T& get(const std::array<std::size_t, Dim>& indexes) const
{
return values[computeIndex(indexes)];
}
T& get(const std::array<std::size_t>& indexes)
{
return values[computeIndex(indexes)];
}
std::size_t computeIndex(const std::array<std::size_t, Dim>& indexes) const
{
size_t index = 0;
size_t mul = 1;
for (size_t i = 0; i != dimensions.size(); ++i) {
assert(indexes[i] < dimensions[i]);
index += indexes[i] * mul;
mul *= dimensions[i];
}
assert(index < values.size());
return index;
}
std::array<std::size_t, Dim> computeIndexes(std::size_t index) const
{
assert(index < values.size());
std::array<std::size_t, Dim> res;
std::size_t mul = values.size();
for (std::size_t i = dimensions.size(); i != 0; --i) {
mul /= dimensions[i - 1];
res[i - 1] = index / mul;
assert(res[i - 1] < dimensions[i - 1]);
index -= res[i - 1] * mul;
}
return res;
}
private:
std::size_t computeTotalSize(const std::array<std::size_t, Dim>& dimensions) const
{
std::size_t totalSize = 1;
for (auto i : dimensions) {
totalSize *= i;
}
return totalSize;
}
private:
std::array<std::size_t, Dim> dimensions;
std::vector<T> values;
};
然后添加层以使其适应您的界面(
多阵列
可能写的和
storage_impl
转变
array<std::size_t, N>
std::size_t, .., std::size_t
,我们使用
std::index_sequence<0, 1, 2, .., N - 1>
允许可变膨胀。然后我们只需将其转换为类型:
template <std::size_t, typename T>
using always_type = T;
template <std::size_t n, typename Seq, typename Number>
class storage_impl;
template <std::size_t n, typename Number, std::size_t ... Is>
class storage_impl<n, std::index_sequence<Is...>, Number>
{
public:
storage_impl(always_type<Is, std::size_t>... dims) : array{{{dims...}}} ()
std::array<Number, n>&
operator()(always_type<Is, std::size_t>... indexes)
{
return array.get({{indexes...}});
}
const std::array<Number, n>&
operator()(always_type<Is, std::size_t>... indexes) const
{
return array.get({{indexes...}});
}
private:
MultiArray<std::array<Number, n>, sizeof...(Is)> array;
};
template <std::size_t n, std::size_t d, typename Number>
using storage = storage_impl<n, std::make_index_sequence<d>, Number>;
用法类似于:
// define a 2D matrix of three doubles
storage<3, 2, double> storageobj(2, 4); // matrix 2x4 of std::array<double, 3>
auto&& block = storageobj(0, 1); // std::array<double, 3>&
std::get<0>(block) = -123.456; // or block[0] = -123.456