2017-09-04 68 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