est-il possible de déduire un paramètre de modèle non de type à partir d'un paramètre de fonction de modèle?
Considérez ce modèle simple: P>
factorial(5);
7 Réponses :
Je ne pense pas que vous puissiez faire cela; La seule façon dont vous pouvez le faire serait d'avoir un paramètre ConstexPR CODE> ConstexPR CODE> comme paramètre code> modèle code> pour la version de modèle de
factorielle code> , mais
consexpr code> Les paramètres de fonction ne sont pas admis. p>
ne peut pas être fait, sauf si vous avez une machine de temps. P>
Le paramètre à la fonction est traité au moment de l'exécution. Oui, dans votre cas em> C'est une constante littérale, mais c'est un cas particulier. P>
Dans les définitions de la fonction, les paramètres types em> sont fixés au moment de la compilation (et peuvent donc être utilisés pour déduire des paramètres de modèle), mais les paramètres les valeurs em> sont uniquement fixes à Runtime. p>
Pourquoi avez-vous besoin de cela? Est-ce juste pour que vous n'ayez pas à taper le <> code> 's? P>
À peu près, j'ai une base de code énorme avec des appels à plusieurs fonctions que j'ai réécrit en tant que modèle. Remplacer les noms est trivial, mais tournant tout f (2, 3, "abc", vrai) code> dans
f <2, 3, true> ("ABC") code> est un peu plus délicat.
Que diriez-vous d'une macro pour convertir f (2, 3, "abc", true) code> dans
f_impl <2, 3, true> ("abc") code>?
Non, ce n'est pas possible, sauf si vous souhaitez créer un énoncé d'interrupteur énorme:
int getFactorial( const int v ) { switch ( v ) { case 1 : return factorial<1>(); case 2 : return factorial<2>(); //etc default: ; } return 0; }
Non, vous ne pouvez pas faire ça. Les arguments de modèle ne peuvent être déduits que du type em> de l'argument de la fonction, pas la valeur em>, qui ne sera pas connue en général à l'heure de la compilation. P>
Bien sûr, vous pouvez réécrire factorial code> comme non-modèle
consexpr code> fonction; Ensuite, il serait évalué à la compilation si l'argument est connu alors. P>
Votre code actuel serait normalement écrit comme suit, je pense: si vous l'appelez avec une expression constante, telle que En général, vous devriez marquer chaque fonction et constructeur comme factorielle (5) code> , alors toute la magie du compilateur entrera en jeu. Mais si vous faites
int A = 3; factorielle (a) code>, alors je pense que cela tombera sur une fonction conventionnelle - c'est-à-dire qu'il n'aura pas construit une table de recherche de réponses précontrictées. P>
consexpr code> si vous le pouvez. Vous ne perdez rien, le compilateur le traitera comme une fonction normale si nécessaire. P> p>
Je ne savais pas que Constexpr okspr works opt-out comme ça. Malheureusement, le code n'est qu'un exemple et j'ai besoin d'une matrice de taille fixe à l'intérieur de la fonction réelle, donc j'ai besoin d'un modèle avec la taille de la matrice en tant que paramètre.
Créer peut-être une gamme de pointeurs de la fonction aux fonctions modèles à la compilation, et regardez-les au moment de l'exécution? Factorial [3] (.. Autres args ..) code>
@PEZCODE: Modifiez la factorielle sur une macro qui appelle le code de modèle, Aaron: vous ferez mieux de construire une gamme des résultats
@MOOINGDUCK, YEP, mais voir le commentaire de PezCode sur cette réponse - Je pense que la vraie application est plus compliquée que cela. J'ai l'impression d'avoir l'impression que certains arguments doivent être ces modèles-Ints, alors que leur peut être d'autres paramètres également.
Si vous pouvez marquer chaque fonction et tout constructeur comme consexpr code> sans aucune conséquence négative, cela soulève (encore) la question de savoir pourquoi ce n'est pas la valeur par défaut des compilateurs C ++ 11 ... Je suppose que c'est le Problème sacré de la compatir de retour sacré à nouveau.
Je ne suis pas expert @codygray, mais je pense que le seul inconvénient avec Parfait Constexpr pour tout est que la compilation pourrait être beaucoup plus lente ou peut-être même être bloquée dans une boucle infinie. PS: I> Et peut-être que vous dites des problèmes de compatibilité, certains logiciels pourraient supposer qu'ils traitent des fonctions «réelles».
Une fonction marquée comme consexpr code> est limitée dans ce que vous pouvez faire à l'intérieur de celui-ci pour limiter le fardeau des écrivains compilateurs pour pouvoir le calculer au moment de la compilation. Vous marquez des fonctions avec
consexpr code> pour dire au compilateur qu'il devrait se plaindre si vous ne répondez pas à ces restrictions afin que votre code soit portable à d'autres compilateurs.
Utilisez une macro maléfique:
Une solution de contournement possible pour ce type de problème consiste à utiliser certains alors nous pouvons avoir une surcharge sur Utilisation de la valeur de struct code> comme ceci:
constante
x code> au temps de compilation et surcharges d'exécution
f (int) code>. La partie agaçante est qu'elle nécessite une certaine discipline sur le site d'appel, car chaque constante littérale doit être enveloppée comme
constante
Pourquoi voudriez-vous faire cela? La fonction
factorielle code> n'accepte aucun paramètre. Quel est l'avantage de
factorial (5) code> sur le bon
factorial <5> () code>?
@Codygray: Je pense que l'idée serait de créer une fonction générique
factorielle code> capable de calculer le résultat au moment de la compilation s'il reçoit une expression hélice de la compilation, mais aussi capable de le calculer au moment de l'exécution. Si l'entrée est une variable normale.
@Matteo: Autant que je sache, rien n'est calculé au moment de l'exécution, car l'expression est déclarée
consexpr code>. Et de toute façon, je ne comprends pas pourquoi il y aurait un problème de passage d'une "variable normale" au lieu des 5 à l'aide de la syntaxe standard. La question ici est "Comment puis-je éviter de taper des crochets d'angle" et je ne comprends pas la motivation.
Je veux éviter de devoir changer beaucoup de code. En outre, je trouve que c'est plus idiomatique, mais c'est quelque chose que je peux facilement passer;)
@Codygray:
consexpr code> fonctionne comme @Matteo dit: Si tous les arguments dans un
Constexpr CODE> Constances sont des constantes de la compilation, l'appel sera évalué au moment de la compilation, sinon, autrement, Il est exécuté à l'exécution comme toute autre fonction.