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 forceschar
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
Vous devez vous connecter pour publier un commentaire.
Hmm, que dit la Norme en
14.8.2.4 /15
:Fournir cet exemple:
Qui suggère que les compilateurs qui ne parviennent pas à compiler votre code (apparemment GCC et de Numérique, Mars) faire de mal. J'ai testé avec le code Comeau, et il compile le code de l'amende. Je ne pense pas qu'il y est une autre de savoir si le type de la non-type de paramètre du modèle dépend du type du type de paramètre ou pas.
14.8.2.4/2
dit les arguments de modèle il faut déduire les indépendants les uns des autres, et ensuite combinés dans le type de la fonction du paramètre. Combiné avec /15, qui permet le type de la dimension de différents type intégral, je pense que ton code est bon. Comme toujours, je prends le c++est-compliqué-donc-je-peut-être-mauvaise carte 🙂Mise à jour: j'ai regardé dans le passage du CCAG où il crache ce message d'erreur:
Il semble avoir manqué de marquer le type de la taille comme dépendante dans une version antérieure du bloc de code. Tant que ce type est un paramètre du modèle, c'est un type de charge (voir
14.6.2.1
).Mise à jour: les développeurs de GCC, il fixe: Bug #38950