the "why" here is that template argument deduction never performs type conversion (give or take things like const): the compiler is trying to come up with a type to substitute for "Iterator" in the template parameter list such that the function parameter type "std::function <std::string( Iterator )>" becomes exactly the same type as the type of the argument you're calling it with (the lambda's type), and that can't happen.

Either make functor a template parameter as Catfish did (it's the usual approach)

the version that takes a std::function
brace-init list has no type and does not participate in the deduction, it's a bit of a language hack i guess. There are other ways to exclude arguments from deduction, I couldn't think of another simple one that fits here