4

C ++ 11では、constexprを使用して、コンパイル時に組み込みの1次元配列のサイズ(要素数)を返す関数を作成できます。以下の例:

template <typename T, std::size_t N>
constexpr std::size_t size(T (&array)[N])
{
     return N;
}

これは、ARRAY_SIZEおよび同様のマクロimoの優れた代替手段です。

ただし、これは組み込みの多次元配列の最上位次元のサイズのみを返します。

組み込みの2次元配列のサイズを決定するために、次の関数を使用します。

template <typename T, std::size_t N, std::size_t N2>
constexpr std::size_t size(T (&array)[N][N2])
{
     return N * N2;
}

理想的には、任意の次元数の組み込み配列のサイズを返す関数があると非常に便利です。可変個引数テンプレートが役立つと思いましたが、引数が1つしか渡されないため、テンプレートパラメーターを解凍する方法がわかりませんでした。そのような機能は可能ですか?

前もって感謝します。

4

3 に答える 3

5
#include <type_traits>
#include <cstdlib>

template <typename T>
constexpr size_t size(const T&) noexcept
{
    return sizeof(T)/sizeof(typename std::remove_all_extents<T>::type);
}

例:

#include <cstdio>
int main()
{
    int a[3][4][7][12];
    char f[6];

    printf("%lu == %ld ?\n", size(a), 3*4*7*12);
    printf("%lu == %ld ?\n", size(f), 6);

    return 0;
}
于 2011-11-28T18:30:33.387 に答える
3
template<typename T> constexpr int size(T const&) { 
  return 1; 
}

template<typename T, int N> constexpr int size(T const (&a)[N]) { 
  return N * size(a[0]); 
} 
于 2011-11-28T19:53:12.987 に答える
2

あなたが探してstd::extentいる。C ++11§20.9.5:

template <class T, unsigned I = 0> struct extent;

Tが配列型でない場合、またはランクがI以下の場合、またはIが0で、Tの型が「Uの未知の境界の配列」である場合、0。それ以外の場合は、TのI番目の次元の境界(8.3.4)で、Iのインデックス付けはゼロベースです。

使用法も、標準から、必要に応じて接頭辞extentを付けstd::ます。

assert((extent<int[2][4], 1>::value) == 4);

sizeまた、おそらくこれを使用してカスタム関数を置き換える必要があります。

編集:おっと、質問の最後まで読んだ:vP。また、が必要std::remove_extentです。

template< typename multi_array, bool = std::is_array< multi_array >::value >
struct total_extent;

template< typename multi_array >
struct total_extent< multi_array, false > {
    enum { value = 1 };
};

template< typename multi_array >
struct total_extent< multi_array, true > {
    enum {
        value = std::extent< multi_array >::value
              * total_extent< typename std::remove_extent< multi_array >
                              ::type >::value
    };
};
于 2011-11-28T15:54:35.690 に答える