¿Cómo pasar un tamaño de matriz como plantilla con tipo de plantilla?

Mi compilador se comporta de manera extraña cuando intento pasar una matriz de tamaño fijo a una función de plantilla. El código tiene el siguiente aspecto:

#include <algorithm>
#include <iostream>
#include <iterator>

template <typename TSize, TSize N>
void f(TSize (& array)[N]) {
    std::copy(array, array + N, std::ostream_iterator<TSize>(std::cout, " "));
    std::cout << std::endl;
}

int main() {
    int x[] = { 1, 2, 3, 4, 5 };
    unsigned int y[] = { 1, 2, 3, 4, 5 };
    f(x);
    f(y); //line 15 (see the error message)
}

Produce el siguiente error de compilación en GCC 4.1.2:

test.cpp|15| error: size of array has non-integral type ‘TSize’
test.cpp|15| error: invalid initialization of reference of type
  ‘unsigned int (&)[1]’ from expression of type ‘unsigned int [5]’
test.cpp|6| error: in passing argument 1 of ‘void f(TSize (&)[N])
  [with TSize = unsigned int, TSize N = ((TSize)5)]’

Tenga en cuenta que la primera llamada se compila y tiene éxito. Esto parece implicar que mientrasint es integralunsigned int no lo es

Sin embargo, si cambio la declaración de mi plantilla de función anterior a

template <typename TSize, unsigned int N>
void f(TSize (& array)[N])

¡el problema simplemente desaparece! Tenga en cuenta que el único cambio aquí es deTSize N aunsigned int N.

Sección [dcl.type.simple] en el borrador final ISO / IEC FDIS 14882: 1998 parece implicar que un "tipo integral" está firmado o no firmado:

lossigned fuerzas especificadoraschar objetos y campos de bits a firmar; es redundante con otros tipos integrales.

Con respecto a las declaraciones de matriz de tamaño fijo, el borrador dice [dcl.array]:

Si elexpresión constante (expr.const) está presente, será una expresión constante integral y su valor será mayor que cero.

Entonces, ¿por qué mi código funciona con un código explícito?unsigned tipo de tamaño, con un inferidosigned tipo de tamaño pero no con un inferidounsigned ¿tipo de letra?

EDITAR Serge quiere saber dónde necesitaría la primera versión. Primero, este ejemplo de código obviamente está simplificado. Mi código real es un poco más elaborado. La matriz es en realidad una matriz de índices / compensaciones en otra matriz.Entonces, lógicamente, el tipo de matriz debe ser el mismo que su tipo de tamaño para una máxima corrección. De lo contrario, podría obtener una falta de coincidencia de tipos (por ejemplo, entreunsigned int ystd::size_t) Es cierto que esto no debería ser un problema en la práctica ya que el compilador se convierte implícitamente al mayor de los dos tipos.

EDITAR 2 Estoy corregido (gracias, litb): el tamaño y el desplazamiento son, por supuesto, tipos lógicamente diferentes, y las compensaciones en matrices C en particular son de tipostd::ptrdiff_t.

Respuestas a la pregunta(1)

Su respuesta a la pregunta