2017-08-04 97 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