#include <array> template <int n> void f(std::array<int,n> const&) {} int main() { std::array<int,3> arr; f(arr); }
这是因为std :: array声明为
template <typename T,std::size_t n> class array;
而不是
template <typename T,int n> class array;
但是,要捕获内置数组的大小,似乎任何整数类型都可以.以下所有关于GCC,clang和VC的工作:
template <typename T,char n > void f(T (&)[n]); template <typename T,short n> void f(T (&)[n]); template <typename T,int n> void f(T (&)[n]); ...
那么,严重的是,内置数组的大小类型是否超载?
解决方法
17 – […] [The] template-argument type shall match the type of the template-parameter exactly,except that a template-argument deduced from an array bound may be of any integral type.
在http://wg21.cmeerw.net/cwg/issue1770,这是改进到更一般:
17 – If
P
has a form that contains<i>
,and if the type of the corresponding value ofA
differs from the type ofi
,deduction fails. IfP
has a form that contains[i]
,and if the type ofi
is not an integral type,deduction fails.
因此,可以将数组边界推导为任何整数类型,但必须将非类型模板参数推导为模板定义中的实际类型.
实际上,标准的C 11版本中没有任何地方指定数组边界的首选类型;指定数组绑定(在[dcl.array]中)为“整数常量表达式,其值应大于零”.在最近的C 14草案中,这被修改为“std :: size_t […]类型的转换常量表达式(5.19)”;改变后的定义可以追溯到n3306.有点奇怪的是,为了一致性,这种变化表现为“相应的调整[…]”,这意味着编辑们认为size_t是正确的类型是显而易见的.