Pourquoi ça ne marche pas
Je m'attendrais à ce que le compilateur résolve f()
par le type d'itérateur. Apparemment, il (gcc 4.1.2) ne le fait pas.
Ce serait formidable si c'était le cas ! Cependant, for_each
est un modèle de fonction, déclaré comme :
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
La déduction du modèle doit sélectionner un type de UnaryFunction
au moment de l'appel. Mais f
n'a pas de type spécifique - il s'agit d'une fonction surchargée, il existe de nombreuses f
chacun avec des types différents. Il n'existe actuellement aucun moyen pour for_each
d'aider le processus de déduction du modèle en indiquant quel f
qu'il veut, donc la déduction par modèle échoue tout simplement. Pour que la déduction du modèle réussisse, vous devez travailler davantage sur le site d'appel.
Solution générique pour le réparer
Je fais un saut ici quelques années et C++14 plus tard. Plutôt que d'utiliser un static_cast
(ce qui permettrait à la déduction des modèles de réussir en "fixant" ce qui est nécessaire à la réussite de l'opération). f
que nous voulons utiliser, mais qui vous oblige à faire manuellement une résolution de surcharge pour "fixer" la bonne), nous voulons faire travailler le compilateur pour nous. Nous voulons appeler f
sur certains args. De la manière la plus générique possible, c'est :
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
C'est beaucoup à taper, mais ce genre de problème se pose fréquemment, alors nous pouvons simplement l'envelopper dans une macro (soupir) :
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
et ensuite l'utiliser :
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Cela fera exactement ce que vous souhaiteriez que le compilateur fasse - effectuer la résolution de surcharge sur le nom f
et faire ce qui est juste. Cela fonctionnera indépendamment du fait que f
est une fonction libre ou une fonction membre.
3 votes
fr.cppreference.com/w/cpp/language/adresse_surchargée