J'ai le code suivant: dans la fonction (BTW: J'utilise actuellement Visual Studio 2010 et je reçois l'erreur C2896, si je quitte le foo () code> J'ai besoin de spécifier l'argument de modèle, même si
f1 (t) code> est une expression valide. C'est un peu détruisant certaines possibilités de mon code. Mes questions: p>
6 Réponses :
F1 code> n'est pas une fonction, c'est un modèle. Vous ne pouvez pas transmettre un modèle en tant qu'argument de la fonction. P>
F1
Cette la limitation em> Vous parlez est une conséquence directe de la vérification du type de temps de compilation. Si vous connaissez le type d'argument de FOO au moment de la compilation, il n'y a pas de limitation, puisque vous l'ajoutez facilement. Si vous ne connaissez pas le type de l'argument, vous devrez peut-être utiliser un modèle de classe dérivé au lieu d'une idée template. P> F1 (t) code> n'est pas une expression valide, car il n'y a pas de fonction
F1 code>. Il n'y a que un modèle em> nommé
F1 code> à partir de laquelle une fonction
f1
Bien sûr, F1 (t) code> est une expression valide à l'intérieur
foo () code>. Il compile bien.
Le modèle de déduction par paramètre de modèle ne fonctionne pas dans des modèles spécifiques, peut-être que cette question répond à votre question: Stackoverflow.com/Questtions/1268504/...
@AlphTeTzky: Peu importe ce que pourrait I> une expression valide tel qu'il est utilisé à l'intérieur de FOO code>. Les modèles sont pas de macros i>; Ils ne prennent rien et collez les jetons ensemble après. Votre fonction de modèle prend un
f && f code>. C'est un paramètre de fonction; Ce doit être une valeur i>, qui a un type i>. Les modèles ne sont pas des valeurs ni n'ont des types. Par conséquent, ils ne peuvent pas être transmis en tant que paramètres de fonction.
@AlphTeTezky: Oui, F1 (t) code> est une expression valide en raison de la déduction de l'argument de modèle de fonction. Le compilateur peut en déduire, basé sur le type du paramètre
t code>, quelle instanciation de la template de fonction
F1 code> Pour appeler - il remplace le
F1 (t) Code> avec
F1
F1 code> autour du modèle, le compilateur ne peut pas vous aider et vous devez spécifier lequel vous voulez.
L'explication Pourquoi cela ne fonctionne pas a été donné par angew et . Ce que j'essaie d'offrir est une solution de contournement possible pour votre problème. Cependant, je ne peux pas dire exactement si cela est approprié ou non pour votre cas puisque l'OP offre des informations limitées sur vos exigences de conception spécifiques. P> La première étape consiste à transformer (similaire pour Notez que Enfin, F1 code> et
F2 code> dans les classes de foncteur de modèle: p>
F2 code>.) De cette manière, vous pouvez passer
F1 code> (et pas
f1
appel code> qui est maintenant défini de cette manière: p>
f code> est un paramètre de modèle de modèle qui se lie à une classe de modèle en prenant un paramètre de type de modèle (par exemple,
F1 code>). P>
foo code> devient ceci: p>
bar code> est laissé comme avant. P> p>
Vous pouvez essayer d'envelopper les fonctions modèles F1 et F2 dans des classes non modèles et des instances de passage (ou même des types) autour, par exemple qui produit la sortie: P> f1 :: opérateur () (1) appelé p> f2 :: opérateur () (1) appelé p> p>
+1 C'est une belle variation de la même idée que j'ai utilisée dans ma réponse. Toutefois, cela pourrait être utile (cela dépend des exigences de l'OP) pour effectuer appel code>, au lieu de recevoir un
f code>, créez une instanciation locale construite par défaut de celle-ci. Ensuite, dans
foo code>, nous pourrions utiliser
appel
Eh bien, Utilisez un objet avec un opérateur et de même pour F1 code> n'est pas un objet, mais un modèle de fonction. Vous ne pouvez transmettre que des objets à des fonctions. P>
modèles () code>. Il suffit de remplacer la définition de
F1 () code> avec p>
f2 () code>. En C ++ 14, vous pouvez l'écrire même plus agréable p>
Grâce à tous les autres intervenants pour leurs intrants inspirants.
Il existe un moyen d'imiter les modèles de fonctions de passage (ou des ensembles de surcharge) en tant que valeurs de première classe: "les réinservent" en les transformant en objets de la fonction. Votre code pourrait être réécrit comme celui-ci:
struct F1 { template <typename T> void operator ()( T t ) { std::cout << "f1( " << t << " ) called." << endl; } } f1; struct F2 { template <typename T> void operator ()( T t ) { std::cout << "f2( " << t << " ) called." << endl; } } f2; // Note that this function didn't change at all! template <typename F, typename T> void call( F && f, T t ) { f( t ); } // Neither did this, expect that now you don't need the <T> template <typename T> void foo( T t ) { call( f1, t ); call( f2, t ); } void bar() { foo( 1 ); foo( 3.14 ); foo( "Hello World" ); }