3

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

在理想情况下,这将是非常有用的,它返回的大小的功能的内置阵列具有任意数量的维度。我以为variadic模板可能会有所帮助,但我无法看到解压缩模板参数的方法,因为只有一个参数被传递。这样的功能可能吗?

在此先感谢。

+0

三个工作答案好评,所有不同的:)。我认为KennyTM是最优雅的,所以我接受了他的答案,紧接着是Johannes's。 – Ricky65

回答

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

使用,也来自于标准,前缀extentstd::需要:

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