使用可变模板函数确定内置多维数组的大小

4

在C++11中,可以使用constexpr创建一个函数,以在编译时返回内置一维数组的大小(元素数量)。以下是示例:

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

在我看来,这是ARRAY_SIZE和类似宏的一个更好的替代方案。

但是,这只会返回内置多维数组中最重要的维度的大小。

我使用以下函数来确定内置二维数组的大小:

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

理想情况下,拥有一个函数能够返回任意维度内置数组的大小是非常有用的。我认为可变参数模板可以帮助实现,但我无法解压缩模板参数,因为只有一个参数被传递。这样的函数是否可能存在?
提前致谢。

收到了三个可行的答案,而且都不同 : )。我认为 KennyTM 的最优雅,所以我接受了他的答案,其次是 Johannes 的。 - Ricky65
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;
}

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]); 
} 

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的索引基于零。

使用方法也来自标准,在需要时使用std::前缀来调用extent

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接