首页 > 解决方案 > 通过 initializer-list 初始化一个 n 维数组

问题描述

我总是对 C++ 中默认数组的初始化感到不安,所以我想在 python 中创建一个 ndarray 类。

但是我遇到了一个障碍,我找不到任何关于如何制作这种代码的信息

...
// for 1-d
ndArray(std::initializer_list<T> list){
   ...
}
// for 2-d
ndArray(std::initializer_list<std::initializer_list<T>> list){
   ...
}
// for 3-d
ndArray(std::initializer_list<std::initializer_list<std::initializer_list<T>>> list){
   ...
}
...

任何嵌套初始化列表的通用(!)

期望的结果是以下列方式构造 ndarray:

ndArray arr = {{1,0,0},{0,1,0},{0,0,1}};

编辑:我认为我把正确的重点放在正确的词上有点不好,但是我想在没有明确为每个维度编写代码的情况下概括这一点

编辑:

我想我现在得到了正确的想法,但还没有完全做到。感谢@Nicholas Pilotto,但在你的情况下,它会产生这些类

// one-dimensional
ndArray<int> first;

// two-dimensional
ndArray<ndArray<int>> second; 

// .. and so on 

如果您需要 3 维数组,则需要嵌套这些数组。这对用户来说是不可取的。我认为它以某种方式涉及模板构造函数

template<typename T>
class ndArray {
    template<typename N>
    ndArray(std::initializer_list<N> list) {
        // do stuff there
    }
}

但它以某种方式涉及知道模板 N 的“深度”以确定 ndArray 的维数。也许有办法用模板做到这一点?

标签: c++templatescontainersinitializer-list

解决方案


您必须定义一个接受std::initializer_list<std::initializer_list<T>>

template <class T>
class ndArray {
    public:
    T* p;
    ndArray(initializer_list<initializer_list<T>> l) : p(new T[l.size() * l.begin()->size()]) {
        unsigned int i = 0;
        unsigned int j = 0;
        auto it = l.begin();
        auto end = l.end();
        for (; it != end; it++) {
            auto iit = (*it).begin();
            auto iend = (*it).end();
            for (; iit != iend; iit++) {
                *(p + i + j) = *iit;
                j++;
            }
            i++;
            j = i;
        }
    }
}

推荐阅读