6

我想制作一个NDArray具有固定尺寸但可以在每个尺寸上调整大小的模板。

我的问题是如何使它能够根据使用了多少对来推断构造函数中的尺寸{}?构造函数中的元素将用于初始化一些元素。

#include <array>
#include <iostream>

template<typename T, size_t Dimension>
class NDArray
{
    T* buffer = nullptr; //flattened buffer for cache locality
    std::array<size_t, Dimension> dimension;    //keep the current sizes of each dimension
public:
    NDArray(std::initializer_list<T> elements) : dimension{elements.size()}   //for 1D
    {
        std::cout << "Dimension = " << Dimension << '\n';
    }
    NDArray(std::initializer_list<NDArray<T, Dimension-1>> list) //how to make this works???
    {
        std::cout << "Dimension = " << Dimension << '\n';
    }
};

template<typename T, size_t N>
NDArray(const T(&)[N]) -> NDArray<T, 1>;

int main()
{
    NDArray a{ {3,4,5} };//OK, NDArray<int, 1> because of the deduction guide
    NDArray b{ {{1,2,3}, {4,5,6}} };//Nope, I want: NDArray<int, 2>
}
4

2 回答 2

4
于 2020-09-02T14:00:28.373 回答
3

如果您可以通过以下方式显式创建 NDArray,那么您几乎可以实现您想要std::initialize_list

int main()
{
    NDArray a{3,4,5}; // would be deduced to NDArray<int, 1>
    NDArray b{ NDArray{1,2,3}, {4,5,6} }; // would be deduced to NDArray<int, 2>
}

请注意,仅在每个维度的第一次出现时显式添加NDArray就足够了。例如,对于 3D NDArray

NDArray c { NDArray{ NDArray{8, 3}, {1, 2}, {1, 2, 3} }, 
                   {        {4, 5}, {8, 9, 7}, {2, 5} } };

要实现这一点,您需要有以下两个扣除指南:

template<typename T>
NDArray(const std::initializer_list<T>&)
                -> NDArray<T, 1>;

template<typename T, size_t DIMENSIONS>
NDArray(const std::initializer_list<NDArray<T, DIMENSIONS>>&) 
                -> NDArray<T, DIMENSIONS + 1>;

代码示例:http ://coliru.stacked-crooked.com/a/1a96b1eaa0717a67

于 2020-09-02T16:55:06.117 回答