Déduire paramètre de modèle non de type
-
27-10-2019 - |
Question
Est-il possible d'en déduire un paramètre de modèle non-type à partir d'un paramètre de fonction de modèle?
Considérez ce modèle simple:
template <int N> constexpr int factorial()
{
return N * factorial<N - 1>();
}
template <> constexpr int factorial<0>()
{
return 1;
}
template <> constexpr int factorial<1>()
{
return 1;
}
Je voudrais être en mesure de changer factorial
afin que je puisse l'appeler alternativement comme ceci:
factorial(5);
et laisser le chiffre du compilateur sur la valeur de N au moment de la compilation. Est-ce possible? Peut-être avec un peu de fantaisie C ++ 11 plus?
La solution
ne peut pas être fait, sauf si vous avez une machine à temps.
Le paramètre de la fonction est traitée lors de l'exécution. Oui, dans votre cas, il est une constante littérale, mais c'est un cas particulier.
Dans les définitions de fonctions, le paramètre types sont fixées au moment de la compilation (et donc, peut être utilisé pour des paramètres de modèle DEDUCE), mais paramètre valeurs ne sont fixés à exécution.
Pourquoi avez-vous besoin? Est-il juste pour que vous ne pas taper du <>
?
Autres conseils
Votre code actuel devrait normalement être écrit comme suit, je crois:
constexpr factorial (int n)
{
return n > 0 ? n * factorial( n - 1 ) : 1;
}
Si vous l'appelez avec une expression constante, comme factorial(5)
, puis toute la magie du compilateur entrera en jeu. Mais si vous le faites int a = 3; factorial(a)
, alors je pense que ça va se replier sur une fonction classique -. À-dire qu'elle ne sera pas ont construit une table de consultation des réponses pré-calculées
En général, vous devez marquer toutes les fonctions et le constructeur comme constexpr
si vous le pouvez. Vous ne perdez rien, le compilateur traitera comme une fonction normale si nécessaire.
Je ne pense pas que vous pouvez le faire; la seule façon que vous pourriez faire cela serait d'avoir un paramètre de fonction constexpr
qui serait passé alors que le paramètre template
pour la version du modèle de factorial
, mais les paramètres de la fonction constexpr
ne sont pas admis.
Non, il est impossible, sauf si vous voulez créer une instruction énorme commutateur:
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 cela. Les arguments de modèle ne peuvent être déduites de la type de l'argument de la fonction, pas valeur , qui ne sera pas en général être connu au moment de la compilation.
Bien sûr, vous pouvez réécrire factorial
en fonction de constexpr
non-modèle; alors il serait évalué au moment de la compilation si l'argument est alors connu.
Utilisez une macro mal:
#define factorial(X) factorial<X>()