How to pass an array size as a template with template type? How to pass an array size as a template with template type? arrays arrays

How to pass an array size as a template with template type?


Hmm, the Standard says in 14.8.2.4 / 15:

If, in the declaration of a function template with a non-type template-parameter, the non-type template-parameter is used in an expression in the function parameter-list and, if the corresponding template-argument is deduced, 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.

Providing this example:

template<int i> class A { /* ... */ };template<short s> void f(A<s>);void k1() {    A<1> a;    f(a);    // error: deduction fails for conversion from int to short    f<1>(a); // OK}

That suggests that the compilers that fail to compile your code (apparently GCC and Digital Mars) do it wrong. I tested the code with Comeau, and it compiles your code fine. I don't think there is a different to whether the type of the non-type template parameter depends on the type of the type-parameter or not. 14.8.2.4/2 says the template arguments should be deduced independent from each other, and then combined into the type of the function-parameter. Combined with /15, which allows the type of the dimension to be of different integral type, i think your code is all fine. As always, i take the c++-is-complicated-so-i-may-be-wrong card :)

Update: I've looked into the passage in GCC where it spits out that error message:

  ...  type = TREE_TYPE (size);  /* The array bound must be an integer type.  */  if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))    {      if (name)    error ("size of array %qD has non-integral type %qT", name, type);      else    error ("size of array has non-integral type %qT", type);      size = integer_one_node;      type = TREE_TYPE (size);    }  ...

It seems to have missed to mark the type of the size as dependent in an earlier code block. As that type is a template parameter, it is a dependent type (see 14.6.2.1).

Update: GCC developers fixed it: Bug #38950