2017-09-04 110 views
2

我写等于输入std::array的维数的函数,它接受一个N维std::array和参数包(坐标) 。我已经可以使用元函数估计std :: array的每个维度的大小,并且我编写了一个函数来计算包中的参数。初始化constexpr的std ::阵列的n维STD的大小::阵列

我想要1)生成一个新的constexpr std::array,其大小等于输入std::array的维数。 2)数组应该用输入std :: array的每个维度的大小进行初始化。 是否有人提示如何仅用C++ 11填充std::array

E.g.这个代码

using array3d = std::array<std::array<std::array<int, 4>, 4>, 4>; 
3d_helper<array3d>(array3d(), 0,0,0); 

应该产生:

constexpr std::array<int, 3> array = { 4, 4, 4 }; 

这是我到目前为止有:

//! Static estimation of std::array container size 
// Declare a generic template (which is called initially) 
template <size_t dim, class Array> 
struct static_size; 

// specialization for std::array and first dimension 
// creates a struct with a static member "value = N" 
template <class T, size_t N> 
struct static_size<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, class InnerArray, size_t N> 
struct static_size<dim, std::array<InnerArray, N>> : static_size<dim - 1, InnerArray> {}; 

template <class FIRST, class... OTHER> 
size_t num_args() { 
    return 1 + num_args<OTHER...>(); 
} 

template <class FIRST> 
size_t num_args() { 
    return 1; 
} 

template <class ARRAY, class... ARGS> 
struct 3d_helper { 
    static glm::vec3 at_t(const ARRAY &points, ARGS... args) { 
     constexpr size_t nargs = num_args<ARGS...>(); 
     /* 
     constexpr size_t n1 = static_size<0, ARRAY>::value - 1; 
     constexpr size_t n2 = static_size<1, ARRAY>::value - 1; 
     */ 
     // ... 
     using array_t = std::array<size_t, nargs>; 
     // fill it somehow 
    } 
}; 
+0

它应该生成'array3d'还是'array '? –

+0

array ,array ,array ,...取决于输入是否为1d,2d,3d,.. – dgrat

+0

是的,那么你的问题中的例子是错误的。 –

回答

2

基于我在这里this相关问题的解决方案是一个办法做到这一点

// 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> {}; 



template <typename Array> 
struct cardinality : std::integral_constant<size_t, 0> {}; 

template <typename T, size_t N> 
struct cardinality<std::array<T,N>> : std::integral_constant<size_t, cardinality<T>::value + 1> {}; 

template <typename Array> 
auto constexpr cardinality_v = cardinality<Array>::value; 


template <typename Array, size_t... Ns > 
constexpr auto dimensions_impl(std::index_sequence<Ns...>) { 
    std::array<size_t, cardinality_v<Array>> result = { size_of_dim<Ns,Array>::value... }; 
    return result; 
} 


template <typename Array> 
constexpr auto dimensions() { 
    return dimensions_impl<Array>(std::make_index_sequence<cardinality_v<Array>>()); 
} 



int main() 
{ 
    auto test = [](auto arr){ 
     constexpr auto dims = dimensions<decltype(arr)>(); 
     for (auto d : dims) 
      std::cout << d << ", "; 
     std::cout << std::endl; 
    }; 
    test(array1D<float, 1337>()); 
    test(array2D<float, 7357, 17>()); 
    test(array3D<float, 3, 4, 5>()); 
} 

DEMO