Arbitrary dimensional array using Variadic templates

后端 未结 2 1260
时光取名叫无心
时光取名叫无心 2020-12-21 09:22

How can I create an Array class in C++11 which can be used like

Array < int, 2, 3, 4> a, b; 
Array < char, 3, 4> d; 
Array < short, 2> e;
         


        
相关标签:
2条回答
  • 2020-12-21 10:17

    The simplest way to do this is by nesting std::array:

    #include<array>
    
    template<class T, size_t size, size_t... sizes>
    struct ArrayImpl {
        using type = std::array<typename ArrayImpl<T, sizes...>::type, size>;
    };
    
    template<class T, size_t size>
    struct ArrayImpl<T, size> {
        using type = std::array<T, size>;
    };
    
    template<class T, size_t... sizes>
    using Array = typename ArrayImpl<T, sizes...>::type;
    

    In this solution Array<char, 3, 4> is the same as std::array<std::array<char, 4>, 3> - array consisting of arrays of smaller dimension.

    This also shows how you can implement operator[] for many dimensions. operator[] of your object needs to return object for which operator[] is also defined. In this case it is reference to an array of smaller dimension.

    0 讨论(0)
  • 2020-12-21 10:25

    Try this:

    #include <iostream>
    
    template <typename T, int N1, int... N2>
    class Array
    {
    
    public:
    
        Array() {}
    
        ~Array() {}
    
        Array<T,N2...>& operator[](int index)
        {
            return data[index];
        }
    
    private:
    
        Array<T,N2...> data[N1];
    };
    
    template<typename T, int N>
    class Array<T,N>
    {
    
    public:
    
        Array() {}
    
        ~Array() {}
    
        T& operator[](int index)
        {
            return data[index];
        }
    
    private:
    
        T data[N];
    };
    
    int main()
    {
        Array < int, 2, 3, 4> a, b;
        Array < char, 3, 4> d;
        Array < short, 2> e;
    
        a[0][1][2] = 15;
        d[1][2]    = 'a';
    
        std::cout << "a[0][1][2] = " << a[0][1][2] << std::endl;
        std::cout << "d[1][2]    = " << d[1][2]    << std::endl;
    
        return 0;
    }
    

    You might also want to throw in range checking and perhaps some iterators to be fancy :)

    0 讨论(0)
提交回复
热议问题