#include <vector>
#include <algorithm>
void foo( int )
{
}
int main()
{
std::vector< int > v( { 1,2,3 } );
std::for_each( v.begin(), v.end(), []( auto it ) { foo( it+5 ); } );
}
When compiled, the example above starts the error output like this :
h4.cpp: In function 'int main()':
h4.cpp:13:47: error: parameter declared 'auto'
h4.cpp: In lambda function:
h4.cpp:13:59: error: 'it' was not declared in this scope
Does it mean that the keyword auto
should not be used in lambda expressions?
This works :
std::for_each( v.begin(), v.end(), []( int it ) { foo( it+5 ); } );
Why the version with the auto keyword doesn't work?
auto keyword does not work as a type for function arguments. If you don't want to use the actual type in lambda functions, then you could use the code below.
for_each(begin(v), end(v), [](decltype(*begin(v)) it ){
foo( it + 5);
});
This was discussed briefly by Herb Sutter during an interview. Your demand for auto
arguments is in fact no different from demanding that any function should be declarable with auto
, like this:
auto add(auto a, auto b) -> decltype(a + b) { return a + b; }
However, note that this isn't really a function at all, but rather it's a template function, akin to:
template <typename S, typename T>
auto add(S a, T b) -> decltype(a + b) { return a + b; }
So you are essentially asking for a facility to turn any function into a template by changing its arguments. Since templates are a very different sort of entity in the type system of C++ (think of all the special rules for templates, like two-phase look-up and deduction), this would be radical design change with unforeseeable ramifications, which certainly isn't going to be in the standard any time soon.
C++14 allows lambda function (Generic lambda function) parameters to be declared with the auto.
auto multiply = [](auto a, auto b) {return a*b;};
For details: http://en.cppreference.com/w/cpp/language/lambda
The type of the lambda needs to be known before the compiler can even instantiate std::for_each
. On the other hand, even if it were theoretically possible, that auto
could only be deduced after for_each
has been instantiated by seeing how the functor is invoked.
If at all possible, forget about for_each
, and use range-based for loops which are a lot simpler:
for (int it : v) {
foo(it + 5);
}
This should also cope nicely with auto
(and auto&
and const auto&
).
for (auto it : v) {
foo(it + 5);
}