Je comprends que le paramètre de modèle non-type doit être une expression intégrale constante. Quelqu'un peut-il nous expliquer pourquoi?
template <std::string temp>
void foo()
{
// ...
}
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.
Je comprends ce qu'est une expression intégrale constante. Quelles sont les raisons de ne pas autoriser les types non constants comme std::string
dans l'extrait de code ci-dessus?
Réponses:
La raison pour laquelle vous ne pouvez pas faire cela est que les expressions non constantes ne peuvent pas être analysées et substituées pendant la compilation. Ils pourraient changer pendant l'exécution, ce qui nécessiterait la génération d'un nouveau modèle pendant l'exécution, ce qui n'est pas possible car les modèles sont un concept de compilation.
Voici ce que la norme autorise pour les paramètres de modèle non de type (14.1 [temp.param] p4):
la source
Cela n'est pas autorisé.
Cependant, ceci est autorisé:
Voir §14.1 / 6,7,8 dans C ++ Standard (2003).
Illustration:
Production:
la source
std::string
pointeur ou objet de référence. Si cette variable était locale, vous obtiendriez probablement des adresses différentes à chaque fois que la fonction est appelée.Vous devez pouvoir modifier les arguments du modèle
Maintenant, un impl devrait proposer une séquence unique de caractères pour un
std::string
ou, d'ailleurs, toute autre classe arbitraire définie par l'utilisateur, stockant une valeur particulière, dont la signification n'est pas connue de l'implémentation. De plus, la valeur des objets de classe arbitraires ne peut pas être calculée au moment de la compilation.Il est prévu d'envisager d'autoriser les types de classe littéraux en tant que types de paramètres de modèle pour post-C ++ 0x, qui sont initialisés par des expressions constantes. Ceux-ci pourraient être mutilés en ayant les membres de données mutilés de manière récursive en fonction de leurs valeurs (pour les classes de base, par exemple, nous pouvons appliquer la profondeur d'abord, de gauche à droite). Mais cela ne fonctionnera certainement pas pour les classes arbitraires.
la source
Un argument de modèle non-type fourni dans une liste d'arguments de modèle est une expression dont la valeur peut être déterminée au moment de la compilation. Ces arguments doivent être:
En outre, les littéraux de chaîne sont des objets avec un lien interne, vous ne pouvez donc pas les utiliser comme arguments de modèle. Vous ne pouvez pas non plus utiliser de pointeur global. Les littéraux à virgule flottante ne sont pas autorisés, étant donné la possibilité évidente d'erreurs d'arrondi.
la source