Warum funktioniert es nicht?
Ich würde erwarten, dass der Compiler nach f()dem Iteratortyp aufgelöst wird. Anscheinend macht es (gcc 4.1.2) es nicht.
Es wäre großartig, wenn das der Fall wäre! Es handelt sich jedoch for_eachum eine Funktionsvorlage, die wie folgt deklariert ist:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Der Vorlagenabzug muss zum UnaryFunctionZeitpunkt des Aufrufs einen Typ auswählen . Hat faber keinen bestimmten Typ - es ist eine überladene Funktion, es gibt viele fs mit jeweils unterschiedlichen Typen. Es gibt derzeit keine Möglichkeit for_each, den Prozess des Vorlagenabzugs zu unterstützen, indem angegeben wird, was fgewünscht wird. Daher schlägt der Vorlagenabzug einfach fehl. Damit der Vorlagenabzug erfolgreich ist, müssen Sie mehr Arbeit auf der Anrufseite leisten.
Generische Lösung zur Behebung
Ein paar Jahre hier und später C ++ 14. Anstatt eine zu verwenden static_cast(die den Abzug von Vorlagen durch "Fixieren" erfolgreich machen würde, was fwir verwenden möchten, aber Sie müssen die Überladungsauflösung manuell durchführen, um die richtige zu "reparieren"), möchten wir, dass der Compiler für uns funktioniert. Wir wollen feinige Argumente anrufen . Auf die allgemeinste Art und Weise ist das:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
Das ist eine Menge zu tippen, aber diese Art von Problem tritt ärgerlich häufig auf, so dass wir das einfach in ein Makro einwickeln können (Seufzer):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
und dann benutze es einfach:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Dies macht genau das, was Sie sich vom Compiler gewünscht haben - führen Sie eine Überladungsauflösung für den Namen fselbst durch und tun Sie einfach das Richtige. Dies funktioniert unabhängig davon, ob fes sich um eine freie Funktion oder eine Mitgliedsfunktion handelt.