2017-08-04 46 views
6

我用下面的模板函數計算數組項:如何使用模板函數算C++數組項,同時允許空數組

#include <stdio.h> 

template<typename T, size_t N> constexpr 
size_t countof(T(&)[N]) 
{ 
    return N; 
} 

int main(void) 
{ 
    struct {} arrayN[] = {{}, {}, {}}; 
    printf("%zu\n", countof(arrayN)); 
    return 0; 
} 

它的工作原理,但不是一個空數組:

struct {} array0[] = {}; 
printf("%zu\n", countof(array0)); 

GCC 5.4輸出:

error: no matching function for call to ‘countof(main()::<anonymous struct> [0])’ 
note: candidate: template<class T, long unsigned int N> constexpr size_t countof(T (&)[N]) 
note: template argument deduction/substitution failed: 

如果我嘗試添加一個專業化:

template<typename T> constexpr 
size_t countof(T(&)[0]) 
{ 
    return 0; 
} 

它甚至變得怪異:

error: no matching function for call to ‘countof(main()::<anonymous struct> [0])’ 
note: candidate: template<class T, long unsigned int N> constexpr size_t countof(T (&)[N]) 
note: template argument deduction/substitution failed: 
note: candidate: template<class T> constexpr size_t countof(T (&)[0]) 
note: template argument deduction/substitution failed: 
note: template argument ‘-1’ does not match ‘#‘integer_cst’ not supported by dump_decl#<declaration error>’ 

我在做什麼錯?

+2

根據[該數組聲明引用(http://en.cppreference.com/w/cpp/language/array)大小表達式的值必須「到大於零的值」。簡而言之,零大小的數組無效。 –

+0

討論編譯器錯誤信息! –

+0

你可以用'std :: array'代替。 –

回答

6

根據2011標準第8.5.1節的規定,「空的初始化程序列表{}不應該用作未知邊界數組的初始化子句」,注意:「該語法提供了空初始化程序 - 列表,但是C++沒有零長度數組「。

現在我不知道爲什麼聲明被編譯...

+0

允許在GNU C中使用變長對象。 https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html –

+0

@jeffrycopps:看起來像我絆倒了一個GNU擴展......有趣的是,有一個C宏,如「#define countof(array )(sizeof(array)/ sizeof((array)[0]))「,所有內容都編譯並且宏給出正確的結果... – airman