Getting the sum of the variational parameter size_t ... in a variational pattern in C ++

I am trying to create an n-dimensional array template template (as a wrapper for std::array

or c ++ arrays) in c ++ that allocates a single block array for the entire n-dimensional array (to avoid the overhead of using n arrays with n indices) ...

That being said, I want my template to be in the following format, which sizes

represents the size of each dimension.

template <class Type, size_t...  sizes>
class array_dimensional{
private:
    std::array<Type, /*here is the problem, how do 
       I get the product of all the sizes?*/> allocated_array;
...

      

My problem is that I'm not sure how to get the product in all sizes.

Can this be done, and if so, how?

+3


source to share


3 answers


This would be one way to do it:



template<size_t size, size_t... sizes>
struct size_product
{
    static const size_t value = size * size_product<sizes...>::value;
};

template<size_t size>
struct size_product<size>
{
    static const size_t value = size;
};

...

std::array<Type, size_product<sizes...>::value> allocated_array;

      

+3


source


In C ++ 14, the function constexpr

may be easier to read:

template<size_t... S>
constexpr size_t multiply() {
    size_t result = 1;
    for(auto s : { S... }) result *= s;
    return result;
}

      



In C ++ 17, just use the fold: expression (... * sizes)

.

+5


source


I don't know what your goal is for dimensions

, but I think this is what you intend to do. You can accomplish this with a product-generating template that rips apart sizes...

and combines it together by multiplication:

#include <iostream>
#include <array>

template<size_t N, size_t... M>
struct product_of
{
    static constexpr size_t size = N *  product_of<M...>::size;
};

template<size_t N>
struct product_of<N>
{
    static constexpr size_t size = N;
};

template <class Type, size_t...  sizes>
struct array_dimensional
{
    static std::array<size_t, sizeof...(sizes)> dims;
    std::array<Type, product_of<sizes...>::size> ar;
};

template<class Type, size_t... sizes>
std::array<size_t, sizeof...(sizes)> array_dimensional<Type,sizes...>::dims{sizes...};

int main()
{
    array_dimensional<int, 2,3,4,5> ar;

    std::cout << ar.dims.size() << '\n';
    for (auto x : ar.dims)
        std::cout << x << ' ';
    std::cout << '\n';
    std::cout << ar.ar.size() << '\n';
}

      

Output

4
2 3 4 5 
120

      

Note. I made null values ​​for zero detection or overflow. Regardless, I hope this helps.

Good luck

+1


source







All Articles