【问题标题】:Variable array dimension at runtime C++运行时的可变数组维度 C++
【发布时间】:2023-03-11 14:20:01
【问题描述】:

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

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

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

我首先想到的是用旧的方式来做,把一个指针放到存储类中,然后创建一些循环(= 到维度)来创建一个新数组(新数组[大小])。 但我不认为这是一种非常干净的方式。

我也想过堆叠std::vector,但是我不知道运行前的维度。

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

或者还有其他方法可以做到这一点吗? 我的最终目标是在运行时创建一个多维数组,我可以在我的所有班级中访问它。

谢谢。

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

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

这样,我还可以模板化数据的维度,并创建一个多维数组(例如使用 boost)。 我会让你知道它是否有效。 谢谢。

更新 2: 显然这是不可能的,因为模板需要常量表达式。我无法传递变量“维度”(即使在这种情况下它是一个固定值,但它不是在编译时定义的)。 所以我想我最好的选择是在自定义存储类中创建一个可变参数getter,并返回相应的值。问题是可变参数方法涉及解析参数,并且由于这是一个经常被调用的方法,它不是最佳的。

【问题讨论】:

    标签: c++ boost multidimensional-array runtime


    【解决方案1】:

    可能需要创建一个自定义类。 一种想法是让它包含两个主要成员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中的代码

    【讨论】:

    • 谢谢。问题是我已经将所有数据都放在了一个巨大的缓冲区(单维数组)中,但现在我想将它们组织在一个多维数组中,以便能够返回这个多维数组的指针(例如使用 getData() ) 所以我可以在别处轻松访问这些数据。一种解决方案是在存储类中实现一个可变参数方法,例如double getData(x,y,z,c,dim5,dim6,....),但由于我可能会经常访问这些数据,我不确定这样做是否是最佳选择。我宁愿返回一个指向数组的指针并像这样访问d=storage.getData(); value=d[0][0][0]...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多