C ++ 11使用向量/初始化列表的任何类型的动态多维数组 [英] C++11 dynamic multidimensional array of any type using vector/initilizer list

查看:272
本文介绍了C ++ 11使用向量/初始化列表的任何类型的动态多维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建尺寸在运行时确定的多维数组(矩阵)。

How do you create a multidimensional array (matrix) whose dimensions are determined at runtime.

最好的方法似乎是创建一个维度的向量,也是访问个体元素的偏移向量

The best way seems to be to take a vector of dimensions for construction and also a vector of offsets to access individual elements

这也允许使用初始化器列表:

This will also allow using initializer lists:

在编译时确定的类型矩阵,所以模板有意义

This should take a matrix of types determined at compile time, so templates make sense

C ++ 11功能应适当使用,lambdas的奖励点

C++11 features should be used as appropriate, bonus points for lambdas

用法示例:

int main(int, char **)
{
        static const std::size_t d1{2};
        static const std::size_t d2{3};
        static const std::size_t d3{4};
        multi_vec<std::size_t> q({d1,d2,d3});

        for (std::size_t i1=0; i1 < d1; ++i1)
                for (std::size_t i2=0; i2 < d2; ++i2)
                        for (std::size_t i3=0; i3 < d3; ++i3)
                                q[{i1,i2,i3}]=foo(i1,i2,i3);

        for (std::size_t i1=0; i1 < d1; ++i1)
                for (std::size_t i2=0; i2 < d2; ++i2)
                        for (std::size_t i3=0; i3 < d3; ++i3)
                                std::cout << "{"
                                        << i1 << ","
                                        << i2 << ","
                                        << i3 << "}=> "
                                        << foo(i1,i2,i3) << "=="
                                        << q[{i1,i2,i3}]
                                        << ((foo(i1,i2,i3) == q[{i1,i2,i3}])
                                              ? " good" : " ERROR")
                                << std::endl;
};


推荐答案

这实际上是一个使用lambdas std :: for_each 和unique_ptr用于内存管理:

This is actually a good place to use lambdas with std::for_each and unique_ptr for memory management:

template <class T>
class multi_vec
{
public:
    using param=std::vector<size_t>;

    explicit multi_vec(const param& dimensions)
        : dim{dimensions}, prod {1}
    {
        std::for_each(dim.begin(), dim.end(), [this] (std::size_t val)
        {
            mult.emplace_back(prod);
            prod *= val;
        } );
        ptr.reset(new T[prod]);
    }
    std::size_t capacity() const { return prod; }

    // undefined if elements in lookup != elemenets in dim
    // undefined if any element in lookup
        // is greater than or equal to corresponding dim element
    T& operator[](const param& lookup)
    {
        return ptr[get_offset(lookup)];
    }
    const T operator[](const param& lookup) const
    {
        return ptr[get_offset(lookup)];
    }
private:
    std::size_t get_offset(const param& lookup) const
    {
        std::size_t offset=0;
        auto mit=mult.begin();
        std::for_each(lookup.begin(), lookup.end(), [&offset, &mit] (std::size_t val)
        {
            offset+=*mit * val;
           ++mit;
        } );
        return offset;
    }
    param dim;
    param mult;
    std::size_t prod;
    std::unique_ptr<T[]> ptr;
};

这使用一维数组来存储实际存储,并使用缓存乘法器进行重用
多维数组 x [2] [3] [4] 不限制检查,超出范围被视为未定义,而不是不断检查可能有效的值。以同样的方式,不检查查找的diminsionality,如果需要,可以添加一个静态成员来检查参数是否有效,在边界或维度。

This uses a single dimensional array for actual storage and caches multipliers for reuse Since a normal multidimension array e.g. x[2][3][4] does not bounds check, going out of bounds is deemed undefined instead of constantly checking values that are probably valid. In the same way diminsionality is not checked for lookups, if required, a static member can be added to check if a parameter is valid, in terms of bounds or dimensionality.

这篇关于C ++ 11使用向量/初始化列表的任何类型的动态多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆