Pourquoi ne peut-struct définie à l'intérieur d'une fonction est utilisée comme foncteur à std :: for_each?
-
13-10-2019 - |
Question
Le code suivant ne compile pas. Le compilateur se plaint * pas de fonction concordante pour appel à for_each *. Pourquoi est-ce donc?
#include <map>
#include <algorithm>
struct Element
{
void flip() {}
};
void flip_all(std::map<Element*, Element*> input)
{
struct FlipFunctor
{
void operator() (std::pair<Element* const, Element*>& item)
{
item.second->flip();
}
};
std::for_each(input.begin(), input.end(), FlipFunctor());
}
Quand je me déplace struct FlipFunctor
avant que la fonction flip_all
, les compiles de code.
message d'erreur complète:
pas de fonction concordante pour appel à « for_each (std :: _ Rb_tree_iterator
>, std :: _ Rb_tree_iterator >, flip_all (std :: map , std :: allocateur >>) :: FlipFunctor) '
La solution
std::for_each
est un modèle de fonction; l'un des paramètres de modèle est le type de l'argument de la fonction.
Vous ne pouvez pas utiliser un type local comme un argument de modèle. Il est juste une restriction actuellement dans la langue. Dans la prochaine révision de C ++, C ++ 0x, cette restriction est supprimée, de sorte que vous pouvez utiliser les types locaux comme arguments de modèle.
Visual C ++ 2010 prend déjà en charge l'utilisation des classes locales comme arguments de modèle; le soutien dans d'autres compilateurs peut varier. Je suppose que tout compilateur C ++ 0x supports lambdas soutiendrait également l'utilisation des classes locales comme arguments de modèle (cela peut ne pas être tout à fait vrai, mais il serait logique).
Autres conseils
je reçois une autre erreur lorsque je tente de compiler votre code:
erreur: 'flip_all (__ gnu_debug_def :: carte, std :: allocateur>>) :: FlipFunctor' utilise un type local 'flip_all (__ gnu_debug_def :: carte, std :: allocateur>>) :: FlipFunctor'
qui est en fait à attendre, car une fonction de type local (tel que votre FlipFunctor ici) a une liaison interne, et un type de modèle doit avoir une liaison externe. Depuis le troisième paramètre de std :: for_each un modèle, vous ne pouvez pas passer quelque chose d'une fonction de type local il.