运行时C ++中的变量数组维度

时间:2016-05-07 14:41:45

标签: c++ boost multidimensional-array runtime

我试图创建一个可以从2个文件中读取一些数据的程序。 第一个文件是标题,用于描述数据结构(维度,数据类型,范围等),第二个文件是原始数据。

为了在运行时处理不同的数据类型,我创建了一个模板化的类,它将用作数据的容器。根据标题中读取的数据类型,我将创建一个容器的专用类来存储数据。

然而,现在我面临另一个问题。如何在运行时创建动态多维数组?

我首先想到的是旧时尚方式,并将指针放入存储类,并创建一些循环(=维度)来创建一个新数组(new array [size])。 但我不认为这是一种非常干净的方式。

我还考虑过堆叠std :: vector,但我不知道运行前的维度。

然后我考虑使用boost来创建multi_array,并使用resize()在运行时更新我的​​数组的范围,但是在创建数组时需要知道维度(multi_array< type,dim>变量) 。 因为我希望能够在我的所有课程中访问它(以便将来处理等等),所以我不知道如何将它放在我的课堂上,因为我只会在运行时知道维度。 是否可以在我的类中创建multi_array的基指针,并在以后声明它(当我知道所需的维度时)?

还是有另一种方法吗? 我的最终目标是在运行时创建一个多维数组,我可以在我的所有类中访问它。

谢谢。

编辑:我读到的大多数主题都是针对固定维数组的,具有不同的大小。但就我而言,维度也各不相同。

更新:你的回答激发了我一个想法Hugues。 我已经有一个模板化的类来读取数据,但是现在它只作为参数,即数据类型。 我正在考虑为它添加维度,并创建一个类: storageClass< data_type, data_dimension > myStorage(filename, data_extent, data_endian, data_encoding);

这样,我也可以模拟数据的维度,并创建一个多维数组(例如使用boost)。 我会告诉你它是否有效。 谢谢。

更新2:显然它不可能导致模板期望持续表达。我无法通过变量&#39;维度&#39; (即使它在这种情况下是固定值,但它没有在编译时定义)。 所以我想我最好的选择是在自定义存储类中创建一个可变参数getter,并返回相应的值。问题是可变方法涉及解析参数,并且因为这是一种经常被调用的方法,所以它不是最优的。

1 个答案:

答案 0 :(得分:0)

可能需要创建自定义类。 一个想法是让它包含两个主要成员m_dimsm_data

#include <vector>
#include <cassert>

using std::size_t;

template<typename T> class MultiArray {
 public:
    MultiArray(const std::vector<int>& dims)
        : m_dims(dims), m_data(product(m_dims)) { }
    const std::vector<int>& dims() const { return m_dims; }
    const T& operator[](const std::vector<int>& indices) const {
        return m_data[index(indices)];
    }
    T& operator[](const std::vector<int>& indices) {
        return m_data[index(indices)];
    }
 private:
    std::vector<int> m_dims;
    std::vector<T> m_data;
    static size_t product(const std::vector<int>& dims) {
        size_t result = 1;
        for (size_t i = 0; i<dims.size(); ++i) result *= size_t(dims[i]);
        return result;
    }
    size_t index(const std::vector<int>& indices) const {
        size_t v = 0;
        for (size_t i = 0; i<m_dims.size(); ++i) {
            assert(indices[i]>=0 && indices[i]<m_dims[i]);
            if (i) v *= size_t(m_dims[i]);
            v += size_t(indices[i]);
        }
        return v;
    }
};

int main() {
    MultiArray<float> ar{std::vector<int>{2, 3}};
    ar[std::vector<int>{0, 0}] = 1.f;
    ar[std::vector<int>{0, 1}] = 2.f;
    ar[std::vector<int>{0, 2}] = 3.f;
    ar[std::vector<int>{1, 0}] = 4.f;
    ar[std::vector<int>{1, 1}] = 5.f;
    ar[std::vector<int>{1, 2}] = 6.f;
}

请参阅http://coliru.stacked-crooked.com/a/92e597d4769f9cad

中的代码