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

Variable array dimension at runtime C++

本文关键字:数组 变量 C++ 运行时      更新时间:2023-10-16

我正在尝试创建一个可以从两个文件中读取一些数据的程序。第一个文件是头,用于描述数据结构(维度、数据类型、扩展数据块等),第二个文件是原始数据。

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

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

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

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

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

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

谢谢。

编辑:我读到的关于它的大多数主题都是关于固定维数组的,它的大小是可变的。但就我而言,维度也各不相同。

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

通过这种方式,我还可以对数据的维度进行模板化,并创建一个多维数组(例如使用boost)。如果有效的话,我会告诉你的。非常感谢。

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

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