加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C 11使用vector / initilizer列表的任何类型的动态多维数组

发布时间:2020-12-16 05:06:23 所属栏目:百科 来源:网络整理
导读:如何创建一个多维数组(矩阵),其维度在运行时确定. 最好的方法似乎是采用建筑尺寸向量,并采用偏移矢量来访问单个元素 这也将允许使用初始化列表: 这应该采用在编译时确定的类型矩阵,因此模板是有意义的 应适当使用C 11特征,为lambdas提供奖励积分 用法示例:
如何创建一个多维数组(矩阵),其维度在运行时确定.

最好的方法似乎是采用建筑尺寸向量,并采用偏移矢量来访问单个元素

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

这应该采用在编译时确定的类型矩阵,因此模板是有意义的

应适当使用C 11特征,为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,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,i3) << "=="
                                        << q[{i1,i3}]
                                        << ((foo(i1,i3) == q[{i1,i3}])
                                              ? " good" : " ERROR")
                                << std::endl;
};

解决方法

这实际上是使用lambdas和std :: for_each以及unique_ptr进行内存管理的好地方:
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的查找,如果需要,可以添加静态成员来检查参数是否有效,就边界或维度而言.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读