Почему не работает
Я ожидаю, что компилятор будет разрешен f()по типу итератора. По-видимому, он (gcc 4.1.2) этого не делает.
Было бы здорово, если бы это было так! Тем не менее, for_eachэто шаблон функции, объявленный как:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
Шаблон вычета должен выбрать тип для UnaryFunctionв точке вызова. Но fне имеет определенного типа - это перегруженная функция, есть много fs с разными типами. В настоящее время нет способа for_eachпомочь процессу вывода шаблонов, указав, чего fон хочет, поэтому вывод шаблонов просто не удался. Для успешного вывода шаблона вам нужно проделать дополнительную работу на сайте вызовов.
Общее решение для его устранения
Прыгнул сюда через несколько лет, а C ++ 14 позже. Вместо того, чтобы использовать static_cast(который позволил бы вывести шаблон успешно, путем «исправления», который fмы хотим использовать, но требует, чтобы вы вручную сделали разрешение перегрузки, чтобы «исправить» правильное), мы хотим заставить компилятор работать на нас. Мы хотим fпривести некоторые аргументы. В наиболее общем виде это:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
Это много, чтобы напечатать, но такого рода проблемы возникают раздражающе часто, поэтому мы можем просто обернуть это в макрос (вздох):
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
а затем просто используйте его:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
Это будет делать именно то, что вы хотели, чтобы компилятор делал - выполнял разрешение перегрузки для самого имени fи просто делал правильные вещи. Это будет работать независимо от того, fявляется ли свободная функция или функция-член.