Pourquoi ça ne marche pas
Je m'attendrais à ce que le compilateur résolve f()
par le type d'itérateur. Apparemment, cela (gcc 4.1.2) ne le fait pas.
Ce serait génial 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 de modèle doit sélectionner un type pour UnaryFunction
au moment de l'appel. Mais f
n'a pas de type spécifique - c'est une fonction surchargée, il y en a beaucoup f
avec chacun des types différents. Il n'existe actuellement aucun moyen pour for_each
faciliter le processus de déduction du modèle en indiquant ce f
qu'il veut, donc la déduction du 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
Sauter ici quelques années et C ++ 14 plus tard. Plutôt que d'utiliser un static_cast
(qui permettrait à la déduction de modèle de réussir en "corrigeant" ce que f
nous voulons utiliser, mais vous oblige à faire manuellement une résolution de surcharge pour "corriger" la bonne), nous voulons que le compilateur fonctionne pour nous. Nous voulons faire appel f
à certains arguments. 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 survient fréquemment, nous pouvons donc 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)...); }
puis utilisez-le simplement:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Cela fera exactement ce que vous souhaitez que le compilateur fasse - effectuer une résolution de surcharge sur le nom f
lui-même et faire ce qu'il faut. Cela fonctionnera indépendamment du fait qu'il s'agisse d' f
une fonction libre ou d'une fonction membre.