Perché non funziona?
Mi aspetto che il compilatore si risolva in f()base al tipo di iteratore. Apparentemente, (gcc 4.1.2) non lo fa.
Sarebbe bello se fosse così! Tuttavia, for_eachè un modello di funzione, dichiarato come:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
La detrazione del modello deve selezionare un tipo per UnaryFunctionnel punto della chiamata. Ma fnon ha un tipo specifico - è una funzione sovraccarica, ce ne sono molti fciascuno con tipi diversi. Non esiste un modo attuale per for_eachaiutare il processo di detrazione del modello dichiarando ciò fche desidera, quindi la detrazione del modello semplicemente fallisce. Affinché la deduzione del modello abbia esito positivo, è necessario svolgere più lavoro sul sito di chiamata.
Soluzione generica per risolverlo
Saltando qui qualche anno e C ++ 14 più tardi. Invece di usare un static_cast(che consentirebbe alla deduzione del modello di avere successo "riparando" che fvogliamo usare, ma richiede che tu faccia manualmente la risoluzione del sovraccarico per "riparare" quella corretta), vogliamo far funzionare il compilatore per noi. Vogliamo chiamare falcuni argomenti. Nel modo più generico possibile, questo è:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
È molto da scrivere, ma questo tipo di problema si presenta fastidiosamente frequentemente, quindi possiamo semplicemente avvolgerlo in una macro (sospiro):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
e poi basta usarlo:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Questo farà esattamente quello che vorresti fosse fatto dal compilatore: esegui la risoluzione del sovraccarico sul nome fstesso e fai semplicemente la cosa giusta. fFunzionerà indipendentemente dal fatto che sia una funzione libera o una funzione membro.