Get the size of multi dimensional std::array at compile time via constexpr or template function

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-10 23:21:11

问题


I use a three dimensional std::array, because the size is already known at compile. However, I noticed that the size() function is not static, and thus, inaccessible for constexpr/template functions.

I already found the demo example below, which estimates the size of a one dimensional std::array. However, this does not work for two or more dimensions. Is there a way to return the other dimensions by writing a function with an additional template parameter dim for the x, y, z, .. dimension?

// Example program
#include <iostream>
#include <string>
#include <array>

// typedefs for certain container classes
template<class T, size_t x>
using array1D = std::array<T, x>;
template<class T, size_t x, size_t y>
using array2D = std::array<std::array<T, y>, x>;
template<class T, size_t x, size_t y, size_t z>
using array3D = std::array<std::array<std::array<T, z>, y>, x>;


template<class T, std::size_t N>
auto array_size_helper(const array1D<T, N>&) -> std::integral_constant<std::size_t, N>;

template<class Array>
using array_size = decltype(array_size_helper(std::declval<const Array&>()));

template<class Array>
constexpr auto static_size() -> decltype(array_size<Array>::value) {
  return array_size<Array>::value;
}
template<class Array>
constexpr auto static_size(Array const&) -> decltype(static_size<Array>()) {
  return static_size<Array>();
}

int main()
{
    std::cout << static_size<array3D<float, 3, 4, 5>>();
}

回答1:


For the one dimensional case, you could use std::tuple_size which is defined for std::array as well:

int main()
{
    std::cout << std::tuple_size<array3D<float, 3, 4, 5>>();
}

Regarding your actual problem. If I understand you right you want to have an additional parameter on your size function with which you can select the dimension for which the size should be returned, right?

This can be done easily by using recursion. Here is a working example:

// Example program
#include <iostream>
#include <string>
#include <array>

// typedefs for certain container classes
template<class T, size_t x>
using array1D = std::array<T, x>;

template<class T, size_t x, size_t y>
using array2D = std::array<std::array<T, y>, x>;

template<class T, size_t x, size_t y, size_t z>
using array3D = std::array<std::array<std::array<T, z>, y>, x>;


template <size_t dim, typename Array>
struct size_of_dim;

// specialization for std array and first dimension
template <typename T, size_t N>
struct size_of_dim<0, std::array<T,N>> : std::integral_constant<size_t, N> {};

// specialization for std array and dimension > 0 → recurse down in dim
template <size_t dim, typename InnerArray, size_t N>
struct size_of_dim<dim, std::array<InnerArray,N>> : size_of_dim<dim-1,InnerArray> {};



int main()
{
    std::cout << size_of_dim<0,array3D<float, 3, 4, 5>>() << std::endl;
    std::cout << size_of_dim<1,array3D<float, 3, 4, 5>>() << std::endl;
    std::cout << size_of_dim<2,array3D<float, 3, 4, 5>>() << std::endl;
}

DEMO



来源:https://stackoverflow.com/questions/45209995/get-the-size-of-multi-dimensional-stdarray-at-compile-time-via-constexpr-or-te

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!