Dlaczego to nie działa
Spodziewałbym się, że kompilator rozwiąże f()typ iteratora. Najwyraźniej to (gcc 4.1.2) tego nie robi.
Byłoby wspaniale, gdyby tak było! Jednak for_eachjest to szablon funkcji zadeklarowany jako:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Odliczenie szablonowe należy wybrać typ UnaryFunctionw momencie połączenia. Ale fnie ma określonego typu - jest to przeciążona funkcja, istnieje wiele ftypów, z których każdy ma inny typ. Obecnie nie ma sposobu, for_eachaby wspomóc proces odliczania według szablonu, określając, czego fchce, więc odliczenie szablonowe po prostu się nie udaje. Aby odliczenie szablonu zakończyło się sukcesem, musisz wykonać więcej pracy w witrynie wezwania.
Ogólne rozwiązanie tego problemu
Wskoczę tutaj kilka lat i C ++ 14 później. Zamiast używać a static_cast(co pozwoliłoby na pomyślną dedukcję szablonu przez „naprawienie”, którego fchcemy użyć, ale wymaga ręcznego rozwiązania problemu z przeciążeniem, aby „naprawić” poprawne), chcemy, aby kompilator działał za nas. Chcemy wywołać fkilka argumentów. W najbardziej ogólny sposób jest to:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
To dużo do pisania, ale tego rodzaju problem pojawia się irytująco często, więc możemy po prostu zawrzeć to w makro (westchnienie):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
a potem po prostu go użyj:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Zrobi to dokładnie to, co chcesz, aby zrobił kompilator - wykona rozwiązanie przeciążenia na fsamej nazwie i po prostu zrób to, co trzeba. Będzie to działać niezależnie od tego, czy fjest to funkcja wolna, czy funkcja składowa.