Como passar um tamanho de matriz como um modelo com o tipo de modelo?

Meu compilador se comporta de maneira estranha quando tento passar uma matriz de tamanho fixo para uma função de modelo. O código é o seguinte:

#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)
}

Ele produz o seguinte erro de compilação no 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)]’

Observe que a primeira chamada é compilada e bem-sucedida. Isso parece implicar que, emboraint é integral,unsigned int não é.

No entanto, se eu alterar a declaração do meu modelo de função acima para

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

o problema simplesmente desaparece! Observe que a única alteração aqui é deTSize N paraunsigned int N.

Seção [dcl.type.simple] no rascunho final da ISO / IEC FDIS 14882: 1998 parece implicar que um "tipo integral" seja assinado ou não:

osigned forças especificadoraschar objetos e campos de bits a serem assinados; é redundante com outros tipos integrais.

Em relação às declarações de matriz de tamanho fixo, o rascunho diz [dcl.array]:

Se oexpressão constante (expr.const) estiver presente, deve ser uma expressão constante integral e seu valor deve ser maior que zero.

Então, por que meu código funciona com um explícitounsigned tamanho, com um valor inferidosigned tamanho, mas não com um valor inferidounsigned Tamanho Tipo?

EDITAR Serge quer saber onde eu precisaria da primeira versão. Primeiro, este exemplo de código é obviamente simplificado. Meu código real é um pouco mais elaborado. A matriz é na verdade uma matriz de índices / compensações em outra matriz.Portanto, logicamente, o tipo da matriz deve ser o mesmo que o tamanho, para máxima correção. Caso contrário, posso obter uma incompatibilidade de tipo (por exemplo, entreunsigned int estd::size_t) É certo que isso não deve ser um problema na prática, pois o compilador converte implicitamente no maior dos dois tipos.

EDIT 2 Eu permaneço corrigido (obrigado, litb): tamanho e deslocamento são logicamente tipos diferentes, e deslocamentos para matrizes C em particular são do tipostd::ptrdiff_t.

questionAnswers(1)

yourAnswerToTheQuestion