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