Comment passer une taille de tableau en tant que modèle avec le type de modèle?

Mon compilateur se comporte bizarrement quand j'ai essayer de passer un tableau de taille fixe d'une fonction de modèle. Le code se présente comme suit:

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

Il produit l'erreur de compilation suivante dans 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)]’

Noter que le premier appel compile et réussit. Cela semble impliquer que tout int est partie intégrante, unsigned int ne l'est pas.

Cependant, si je change la déclaration de ma fonction ci-dessus modèle à

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

le problème, tout s'en va! Notez que le seul changement est ici de TSize N à unsigned int N.

Section [dcl.type.simple] dans le projet final de norme ISO/IEC FDIS 14882:1998 semble sous-entendre qu'une "intégrale" est signé ou non signé:

La signed spécificateur de forces char des objets et des bits de champs à être signé; il est redondant avec d'autres types intégraux.

Concernant le tableau de taille fixe déclarations, le projet dit [dcl.array]:

Si le constante de l'expression (expr.const) est présent, il doit être une expression constante et sa valeur doit être supérieure à zéro.

Pourquoi mon code de travail explicite unsigned de type taille, avec une déduit signed la taille du type, mais pas avec une déduit unsigned de type taille?

MODIFIER Serge veut savoir où j'avais besoin de la première version. Tout d'abord, cet exemple de code est évidemment simplifiée. Mon code est un peu plus élaboré. Le tableau est en fait un tableau d'indices/décalages dans un autre tableau. Donc, logiquement, le type de la matrice doit être le même que son type taille pour un maximum d'exactitude. Sinon, j'aurais peut-être une incompatibilité de type (par exemple, entre unsigned int et std::size_t). Certes, cela ne devrait pas être un problème dans la pratique, car le compilateur convertit implicitement à la plus grande des deux types.

EDIT 2 je suis corrigé (merci, litb): la taille et le décalage sont bien sûr logiquement différents types, et les décalages en C des tableaux, en particulier, sont de type std::ptrdiff_t.

source d'informationauteur Konrad Rudolph | 2009-01-23