2017-07-20 7 views
2

コンパイル時にサイズが既にわかっているので、私は3次元std::arrayを使用します。しかし、size()関数は静的ではなく、constexpr/template関数ではアクセスできないことに気付きました。constexprまたはテンプレート関数を介してコンパイル時に多次元std :: arrayのサイズを取得します

私はすでに1次元のサイズを推定するデモの例を見つけましたstd::array。ただし、これは2つ以上のディメンションでは機能しません。 x, y, z, ..ディメンションのテンプレートパラメータdimを追加して関数を記述して、他のディメンションを返す方法はありますか? 1次元の場合については

// 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

'array3D <フロート、3、4、5>で'サイズは何でしょうか? '3'? '4'? '5'?または '3 * 4 * 5'? –

+0

一定のサイズを提供しています。なぜあなたは個々のサイズを掛け合わせて合計サイズを得ることができませんか? –

+0

私の例では、私はちょうどXの次元を取得します:3.他の2つは含まれていません:/ – dgrat

答えて

3

、あなたにもstd::arrayのために定義されてstd::tuple_sizeを使用することができます。

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

をあなたの実際の問題について。あなたが理解していれば、サイズを返さなければならないディメンションを選択できるように、サイズ関数に追加のパラメータが必要ですか?

これは、再帰を使用することで簡単に行うことができます。ここでは実施例である:

あなたの例で
// 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

+0

これは非常に良い解決策です。 – dgrat

関連する問題